/* ============================================================
   Logiciel de production événementielle — feuille de style
   Système de thèmes commutables : clair · console · editorial
   Le thème est piloté par l'attribut  data-theme  sur <html>.
   ============================================================ */

/* Police de drapeaux : Windows/Chrome ne rendent pas les emojis-drapeaux —
   cette police (limitée aux indicateurs régionaux) force leur affichage en couleur. */
@font-face {
  font-family: "Twemoji Country Flags";
  src: url("../fonts/TwemojiCountryFlags.a19faae092f7.woff2") format("woff2");
  unicode-range: U+1F1E6-1F1FF;
  font-display: swap;
}

/* ---------- Thème par défaut : CLAIR & PRO ---------- */
/* Force le rendu clair (empêche iOS Safari / Dark Mode d'ajuster les couleurs). */
:root { color-scheme: light; }
:root { --sidebar-w: 246px; }
:root,
[data-theme="clair"] {
  --bg: #eef0f3;
  --surface: #ffffff;
  --surface-2: #f5f6f8;
  --border: #dce0e6;
  --text: #1a1d21;
  --text-muted: #6b7280;
  --accent: #d64500;
  --accent-hover: #b83a00;
  --accent-contrast: #ffffff;
  --danger: #d64545;
  --success: #1a9d63;
  --warning: #c77700;
  --radius: 6px;
  --font: system-ui, "Segoe UI", -apple-system, sans-serif;
  --font-head: system-ui, "Segoe UI", sans-serif;
  --label-spacing: 0.5px;
  --shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
}

/* Thème unique : Clair & pro. Les thèmes alternatifs (sombre « console » / éditorial)
   ont été retirés — le site s'affiche toujours en clair. */

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Twemoji Country Flags", var(--font);
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
}

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

/* `hidden` doit TOUJOURS l'emporter : la règle de style d'un composant (label,
   flex…) écrase sinon le `display: none` par défaut du navigateur, et un champ
   qu'on croit masqué reste affiché — c'est ce qui superposait les heures et la
   case « Journée entière ». */
[hidden] { display: none !important; }

.ico { width: 18px; height: 18px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.8; }
.ico-lg { width: 24px; height: 24px; }

/* ---------- Mise en page ---------- */
.layout { display: flex; min-height: 100vh; }
.split-bar { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--border); background: var(--surface); }
.split-btn { border: 1px solid var(--border); background: var(--surface); color: var(--text); border-radius: 8px; cursor: pointer; padding: 2px 9px; font-size: 14px; line-height: 1.4; }
.split-btn:hover { background: var(--surface-2); }
.split-title { flex: 1; font-size: 12px; color: var(--text-muted); }
.pouls-banner { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 50;
  background: var(--text); color: #fff; padding: 8px 16px; border-radius: 999px; font-size: 13px;
  box-shadow: 0 6px 20px rgba(0,0,0,.25); display: flex; align-items: center; gap: 10px; }
.pouls-banner button { background: var(--accent); color: var(--accent-contrast); border: 0;
  border-radius: 999px; padding: 3px 12px; cursor: pointer; font-weight: 600; }
.periode-add > summary { display: inline-flex; list-style: none; cursor: pointer; width: auto; }
.periode-add > summary::-webkit-details-marker { display: none; }
.periode-add[open] > summary { margin-bottom: 4px; }
.pg-modes-row { display: flex; justify-content: flex-end; margin-bottom: 6px; }
/* Rectangle noir compact : jours travel/travail d'un booking. */
.travel-box { display: inline-flex; align-items: center; gap: 8px; background: #141414; color: #fff;
  border-radius: 8px; padding: 3px 9px; font-size: 11px; line-height: 1.2; }
.travel-box .tb-jour { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.travel-box label { display: inline-flex; align-items: center; gap: 1px; cursor: pointer; margin: 0; }
.travel-box input[type=checkbox] { width: auto; height: 13px; margin: 0; accent-color: var(--accent); }
.travel-box .tb-sep { opacity: .45; }
.perso-compte.incomplet { color: #ff5a5a; }
/* La pastille reste survolable même si le calque texte laisse passer les clics. */
.perso-compte { pointer-events: auto; cursor: help; margin-left: 8px; font-size: 10px; font-weight: 700; background: rgba(0,0,0,.62);
  color: #fff; border-radius: 6px; padding: 0 5px; white-space: nowrap; }
.split-nav { display: flex; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--border); background: var(--surface); overflow-x: auto; }
.split-navbtn { flex: 0 0 auto; border: 1px solid var(--border); background: var(--bg); color: var(--text); border-radius: 999px; cursor: pointer; padding: 3px 12px; font-size: 12px; white-space: nowrap; }
.split-navbtn:hover { background: var(--surface-2); }
.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 18px 0;
  display: flex;
  flex-direction: column;
  /* Toujours accessible, quelle que soit la hauteur de la page : la colonne reste
     à l'écran et défile SEULE quand son contenu dépasse (le reste de la page bouge
     indépendamment). En mobile, la media query la repasse en tiroir fixe. */
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0 20px 18px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 10px;
}
.brand .mark {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  background: var(--accent); color: var(--accent-contrast);
  border-radius: var(--radius); font-weight: 800; font-size: 15px;
}
.brand h1 { font-size: 15px; margin: 0; font-family: var(--font-head); }
.brand span { color: var(--text-muted); font-size: 11px; }

.nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 20px;
  color: var(--text-muted); font-size: 14px;
  border-left: 3px solid transparent;
}
.nav a:hover { background: var(--surface-2); color: var(--text); }
.nav a.active { color: var(--text); border-left-color: var(--accent); background: var(--surface-2); }
.nav a.muted { opacity: 0.55; cursor: default; }
/* Sous-onglets du portail perso : léger retrait sous « Mon espace ». */
.nav a.nav-sub { padding-left: 34px; font-size: 13px; }
.nav a.nav-sub .ico { width: 16px; height: 16px; }
.nav a.muted:hover { background: none; color: var(--text-muted); }
.nav .section {
  padding: 15px 20px 6px; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: var(--label-spacing);
  color: var(--text-muted); opacity: 0.7;
}

.sidebar-footer { margin-top: auto; padding: 14px 20px; border-top: 1px solid var(--border); font-size: 13px; }
.sidebar-footer .who { font-weight: 600; }
.theme-switch { margin-bottom: 12px; }
.theme-switch label { font-size: 10.5px; text-transform: uppercase; letter-spacing: var(--label-spacing); color: var(--text-muted); }

.role-badge {
  display: inline-block; padding: 2px 9px; border-radius: 20px;
  font-size: 11px; color: #fff; margin-top: 3px;
}
.role-super_admin { background: #d64545; }
.role-proprietaire { background: #8b5cf6; }
.role-admin { background: #c77700; }
.role-super_user { background: #2f6fb0; }
.role-user { background: #64748b; }

/* ---------- Contenu ---------- */
.main { flex: 1; padding: 30px 40px; max-width: 1120px; }
/* Largeur du contenu réglable (sélecteur sidebar). Défaut = 1120px.
   Les fractions sont calculées sur la ZONE DE CONTENU réelle (écran − barre latérale),
   donc exactes quelle que soit la taille d'écran (16/9, 16/10, 4K, ultrawide…).
   Plein écran = remplit toute la zone disponible, sans plafond. */
html[data-width="full"] .main { max-width: none; }
html[data-width="23"] .main { max-width: calc((100vw - var(--sidebar-w)) * 2 / 3); }
html[data-width="12"] .main { max-width: calc((100vw - var(--sidebar-w)) / 2); }
html[data-width="13"] .main { max-width: calc((100vw - var(--sidebar-w)) / 3); }
/* Position du contenu dans l'espace disponible (à droite de la barre latérale). */
html[data-align="left"] .main { margin-left: 0; margin-right: auto; }
html[data-align="center"] .main { margin-left: auto; margin-right: auto; }
.page-title { font-size: 24px; margin: 0 0 4px; font-family: var(--font-head); }
.page-subtitle { color: var(--text-muted); margin: 0 0 26px; }
.head-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
/* Entête de groupe de projets (grouper par date/client/pays/état). */
.projet-group-head { grid-column: 1 / -1; margin: 8px 0 0; padding-bottom: 5px; font-size: 13px;
  font-weight: 700; color: var(--text-muted); text-transform: capitalize; display: flex; align-items: center;
  gap: 8px; border-bottom: 1px solid var(--border); }
.projet-group-head .cnt { font-size: 11px; color: var(--accent); font-weight: 800; text-transform: none; }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow);
}
.card .icon { color: var(--accent); margin-bottom: 10px; display: block; }
.card h3 { margin: 0 0 5px; font-size: 15px; font-family: var(--font-head); }
.card p { color: var(--text-muted); font-size: 13px; margin: 0; }

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: var(--radius);
  background: var(--accent); color: var(--accent-contrast);
  border: none; font-size: 14px; font-family: var(--font); cursor: pointer;
}
.btn:hover { background: var(--accent-hover); color: var(--accent-contrast); }
.btn-secondary { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-secondary:hover { background: var(--surface-2); color: var(--text); }
.btn-danger { background: transparent; border: 1px solid #d64545; color: #d64545; }
.btn-danger:hover { background: #d64545; color: #fff; }
/* « Retour » toujours à l'extrême droite de son groupe (haut à droite), mobile + bureau. */
.btn-retour { order: 99; }

/* ---------- Tableaux ---------- */
table { width: 100%; border-collapse: collapse; margin-top: 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
th, td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--border); font-size: 14px; }
tr:last-child td { border-bottom: none; }
th { color: var(--text-muted); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: var(--label-spacing); }

/* ---------- Formulaires ---------- */
form p { margin: 0 0 15px; }
label { display: block; font-size: 12.5px; color: var(--text-muted); margin-bottom: 5px; }
input, select, textarea {
  width: 100%; padding: 10px 12px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); color: var(--text); font-size: 14px; font-family: var(--font);
}
/* Cases à cocher et radios : jamais pleine largeur (sinon elles s'étirent et écrasent
   les libellés à côté — ex. picker de personnes dans une étape sur mobile). */
input[type=checkbox], input[type=radio] { width: auto; padding: 0; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); }
.helptext { font-size: 12px; color: var(--text-muted); }
/* Bouton « Aides » : masque tous les textes d'aide (page-subtitle conservés). */
html[data-aides="off"] .helptext { display: none; }
.errorlist { color: var(--danger); list-style: none; padding: 0; font-size: 13px; margin: 0 0 12px; }

/* ---------- Messages ---------- */
.messages { list-style: none; padding: 0; margin: 0 0 20px; }
.messages li { padding: 12px 15px; border-radius: var(--radius); margin-bottom: 8px; font-size: 14px; background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--accent); }
.messages li.success { border-left-color: var(--success); }
.messages li.error { border-left-color: var(--danger); }

/* ---------- Module Personnel ---------- */
.people-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; margin-top: 8px; }
.person-card { display: flex; gap: 14px; align-items: flex-start; text-decoration: none; color: inherit; }
.avatar { width: 52px; height: 52px; border-radius: var(--radius); flex: none; object-fit: cover; background: var(--surface-2); display: grid; place-items: center; font-weight: 700; color: var(--accent); border: 1px solid var(--border); }
.alerte-repos { display: inline-grid; place-items: center; width: 19px; height: 19px; border-radius: 50%; background: var(--danger); color: #fff; font-weight: 800; font-size: 12px; line-height: 1; vertical-align: middle; }
.alerte-tri { display: inline-flex; align-items: center; color: var(--danger); vertical-align: middle; }
.alerte-tri .ico { width: 15px; height: 15px; stroke-width: 2; }
.warning-banner .alerte-tri .ico { width: 18px; height: 18px; }

.avatar-wrap { position: relative; flex: none; }
.avatar-badge { position: absolute; bottom: -5px; right: -6px; background: var(--accent); color: var(--accent-contrast); font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 20px; border: 2px solid var(--surface); line-height: 1.4; white-space: nowrap; }
.person-card h3 { margin: 0 0 3px; font-size: 15px; }
.person-meta { color: var(--text-muted); font-size: 12.5px; }

.statut-badge { display: inline-block; padding: 2px 9px; border-radius: 20px; font-size: 11px; margin-top: 5px; border: 1px solid var(--border); }
.statut-intermittent { background: rgba(214,69,0,0.12); color: var(--accent); border-color: transparent; }
.statut-freelance { background: rgba(47,111,176,0.14); color: #2f6fb0; border-color: transparent; }
.statut-salarie { background: rgba(26,157,99,0.14); color: var(--success); border-color: transparent; }
.statut-societe { background: rgba(139,92,246,0.14); color: #8b5cf6; border-color: transparent; }

/* Contacts (freelance / société) */
.contact-row { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin-bottom: 10px; }
.contact-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; align-items: end; }
.contact-flags { display: flex; gap: 14px; align-items: center; }
.contact-flags label { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--text); }
.contact-flags input { width: auto; }
/* Tarifs */
.tarif-row { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin-bottom: 10px; }
.tarif-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr auto; gap: 10px; align-items: end; }
@media (max-width: 900px) { .tarif-grid { grid-template-columns: 1fr 1fr; } }
.tarif-del { font-size: 12px; color: var(--danger); white-space: nowrap; }
.tarif-del label { display: flex; align-items: center; gap: 5px; }
.tarif-del input { width: auto; }

.contact-card { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 8px; }
.contact-card.principal { border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); }
.contact-card .badge-principal { font-size: 10.5px; text-transform: uppercase; letter-spacing: var(--label-spacing); color: var(--accent); font-weight: 600; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* Vignette personnel : compétences sur UNE seule ligne chacune (jamais coupées, jamais
   sur 2 lignes) ; 2 par ligne si ça tient, sinon la compétence prend sa propre ligne. */
.person-card .chips { display: flex; flex-wrap: wrap; gap: 5px 6px; }
.person-card .chip { white-space: nowrap; }
.chip { font-size: 11.5px; padding: 3px 9px; border-radius: 20px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted); }

.warning-banner { display: flex; gap: 10px; align-items: center; padding: 11px 14px; border-radius: var(--radius); background: rgba(199,119,0,0.12); border: 1px solid var(--warning); color: var(--warning); font-size: 13px; margin-top: 8px; }
.warning-banner--danger { background: rgba(214,69,69,0.12); border-color: var(--danger); color: var(--danger); }
.pp-conflit { outline: 2px solid var(--danger); outline-offset: -2px; background: rgba(214,69,69,0.07); }

/* Boutons segmentés (statut au clic) */
.segmented { display: flex; flex-wrap: wrap; gap: 8px; }
.segmented label { margin: 0; cursor: pointer; }
.segmented input { position: absolute; opacity: 0; width: 0; height: 0; }
.segmented .seg { display: inline-block; padding: 9px 14px; border: 1px solid var(--border); border-radius: var(--radius); font-size: 13px; color: var(--text-muted); background: var(--surface-2); }
.segmented input:checked + .seg { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }

/* Grille de cases à cocher (compétences) */
.check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; }
.check-grid label { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 13.5px; color: var(--text); cursor: pointer; }
.check-grid input { width: auto; }

/* Sections conditionnelles */
.cond-section { border-left: 3px solid var(--accent); padding: 4px 0 4px 14px; margin: 4px 0 16px; }
.form-section { margin: 22px 0 10px; font-size: 12px; text-transform: uppercase; letter-spacing: var(--label-spacing); color: var(--text-muted); border-bottom: 1px solid var(--border); padding-bottom: 6px; }
/* Titre de mois affiché (barre de recherche, mon planning, fiche perso, calendrier, projet) :
   plus gros et en gras, couleur pleine, sans majuscules — pour bien repérer le mois courant. */
.mois-titre { font-size: 20px; font-weight: 800; text-transform: none; letter-spacing: 0; color: var(--text); }

/* Pièces d'identité (formset) */
.piece-row { display: grid; grid-template-columns: 1fr 1fr auto; gap: 10px; align-items: end; margin-bottom: 10px; }
.piece-row .del { font-size: 12px; color: var(--danger); white-space: nowrap; }
.piece-row .piece-files { grid-column: 1 / -1; display: flex; gap: 12px; flex-wrap: wrap; align-items: center; font-size: 12px; color: var(--text-muted); }
.piece-row .piece-files input[type=file] { font-size: 12px; max-width: 190px; }
.piece-row .del label { display: flex; align-items: center; gap: 5px; }
.piece-row .del input { width: auto; }

/* Fiche personnel : barres projet nommées, s'étendant sur les jours consécutifs. */
.fiche-cal-cell { position: relative; min-height: 74px; }
/* Jours hors mois : PAS d'opacity (sinon crée un contexte d'empilement qui masque la
   barre débordant sur les cases suivantes) → fond estompé + numéro grisé à la place.
   L'id #fiche-cal l'emporte sur la règle globale .pp-cell.out. */
#fiche-cal .fiche-cal-cell.out { opacity: 1; background: var(--surface-2); }
#fiche-cal .fiche-cal-cell.out .pp-num { color: var(--text-muted); opacity: 0.55; }
/* La barre reste à 100 % d'opacité et AU-DESSUS de toutes les cases. */
.pl-span {
  position: absolute; left: 4px; z-index: 3;
  top: calc(26px + var(--i, 0) * 16px); height: 14px; line-height: 14px;
  width: calc(var(--run, 1) * 100% + (var(--run, 1) - 1) * 7px - 7px);
  font-size: 10px; color: #fff; padding: 0 7px; border-radius: 4px;
  overflow: hidden; text-shadow: 0 1px 1px rgba(0,0,0,0.18); text-decoration: none;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.pl-span .pl-span-nom { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-span .pl-span-poste { white-space: nowrap; flex: 0 0 auto; font-style: italic; opacity: 0.9;
  max-width: 55%; overflow: hidden; text-overflow: ellipsis; }
.pl-span:hover { filter: brightness(1.08); }

/* Positionnement du personnel en 2 états (fiche + plannings) :
   PRÉVISIONNEL = fines rayures blanches (positionné, pas encore confirmé) ;
   CONFIRMÉ = plein + cadenas 🔒 (verrouillé par la personne). */
/* Ordre des couches : fond = couleur projet → rayures → texte/infos par-dessus. */
.pl-previsionnel::after {
  content: ""; position: absolute; inset: 0; z-index: 0; border-radius: inherit; pointer-events: none;
  background: repeating-linear-gradient(45deg, rgba(0,0,0,.5) 0 2px, rgba(0,0,0,0) 2px 5px);
}
.pl-previsionnel { box-shadow: inset 0 0 0 1px rgba(0,0,0,.35); }
.pl-span > *, .pg-bar > * { position: relative; z-index: 1; font-weight: 700; }
.pl-confirme { box-shadow: inset 0 0 0 1px rgba(0,0,0,.28); }
.pl-lock { flex: 0 0 auto; font-size: 9px; line-height: 1; margin-right: 1px; }
.pg-bar .pl-lock { font-size: 8px; }
/* Portail perso : liste des missions à confirmer + pastilles d'état. */
.mission-row { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 10px 0; border-bottom: 1px solid var(--border); }
.mission-row:last-child { border-bottom: none; }
.etat-chip { font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
.etat-prev { background: color-mix(in srgb, #f59e0b 18%, transparent); color: #b45309; }
.etat-conf { background: color-mix(in srgb, #16a34a 18%, transparent); color: #15803d; }
/* « Jours par projet » : une case par projet, bouton de validation pleine largeur en bas. */
.jpp-list .jpp-item { display: block; padding: 8px 0; border-bottom: 1px solid var(--border); }
.jpp-list .jpp-item:last-child { border-bottom: none; }
.jpp-list .jpp-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.jpp-list .jpp-form { margin: 6px 0 0; }
.jpp-list .jpp-btn { width: 100%; justify-content: center; }
/* Jour d'indisponibilité : teinte + croix ; case libre cliquable. */
/* Indispo : teinte prioritaire même sur un jour grisé (.out) d'un mois voisin. */
#fiche-cal .fiche-cal-cell.fiche-indispo { background: rgba(214,69,0,0.12); }
/* JOURNÉE ENTIÈRE (aucun horaire divulgué) : GROSSE croix qui occupe toute la case. */
.fiche-cal-cell.fiche-indispo::after {
  content: "✕"; position: absolute; inset: 0; display: grid; place-items: center;
  color: rgba(214,69,0,0.55); font-weight: 800; font-size: clamp(22px, 4.2vw, 40px);
  line-height: 1; pointer-events: none;
}
/* Indispo AVEC horaire affiché : petite croix en HAUT À DROITE (ne chevauche pas l'heure). */
.fiche-cal-cell.fiche-indispo.indispo-horaire::after {
  inset: 3px 5px auto auto; display: block; font-size: 13px; color: #d64500;
}
/* DEMI-JOURNÉE : la surbrillance ne couvre que la moitié concernée, et la petite
   croix se cale en haut à droite de CETTE moitié. Matin = haut, après-midi = bas. */
#fiche-cal .fiche-cal-cell.fiche-indispo.indispo-matin,
#fiche-cal .fiche-cal-cell.fiche-indispo.indispo-aprem { background: transparent; }
.fiche-cal-cell.fiche-indispo.indispo-matin::before,
.fiche-cal-cell.fiche-indispo.indispo-aprem::before {
  content: ""; position: absolute; left: 0; right: 0; height: 50%;
  background: rgba(214,69,0,0.12); pointer-events: none;
}
.fiche-cal-cell.fiche-indispo.indispo-matin::before { top: 0; }
.fiche-cal-cell.fiche-indispo.indispo-aprem::before { bottom: 0; }
.fiche-cal-cell.fiche-indispo.indispo-aprem::after { inset: auto 5px calc(50% - 18px) auto; }
/* L'heure se pose dans la moitié en surbrillance. */
.fiche-cal-cell.indispo-aprem .fiche-indispo-h { position: absolute; left: 5px; bottom: 4px; }
.fiche-cal-cell.indispo-matin .fiche-indispo-h { position: absolute; left: 5px; top: 20px; }
.fiche-cal-cell[data-date] { cursor: pointer; }
.fiche-cal-cell[data-date]:hover { background: rgba(214,69,0,0.08); box-shadow: inset 0 0 0 1px rgba(214,69,0,0.4); }
/* Fiche personnel : détails sur 2 colonnes (contact | reste), repliées en 1 si étroit. */
/* Affectation rapide (relais) sur le calendrier projet. */
.quick-assign { margin-bottom: 12px; }
.qa-buttons { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.jd-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px;
  padding: 10px 12px; border: 1px solid var(--accent); border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 6%, var(--surface)); font-size: 13px; }
.jd-bar[hidden] { display: none; }
.jd-alert { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px;
  padding: 10px 12px; border-radius: 10px; font-size: 13px;
  background: rgba(214,69,0,0.12); border: 1px solid #d64500; color: var(--text); }
.jd-alert[hidden] { display: none; }
body.jours-mode .pp-cell { cursor: pointer; }
body.jours-mode .pp-cell:hover { outline: 2px dashed var(--accent); outline-offset: -2px; }
.qa-panel { margin-top: 10px; padding: 12px; border: 1px solid var(--accent); border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 5%, var(--surface)); }
.qa-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.qa-row select { min-width: 220px; }
.qa-step { font-size: 13px; color: var(--text); display: flex; align-items: center; gap: 6px; }
.qa-badge { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  border-radius: 50%; background: var(--accent); color: var(--accent-contrast); font-size: 11px; font-weight: 800; }
.qa-people { display: flex; flex-wrap: wrap; gap: 6px; }
.qa-person { border: 1px solid var(--border); background: var(--surface); color: var(--text);
  border-radius: 999px; padding: 5px 12px; font-size: 13px; cursor: pointer; }
.qa-person:hover { border-color: var(--accent); }
.qa-person.qa-occupe { opacity: 0.6; }
.qa-person.qa-assigned { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }
.qa-person .qa-p-state { font-size: 10px; color: #d64500; font-weight: 700; }
.qa-person.qa-assigned .qa-p-state { color: inherit; }
.qa-hint { margin: 8px 0 0; }
body.qa-mode .pp-cell { cursor: copy; }
.pp-cell.qa-selday { position: relative; outline: 2px solid var(--accent); outline-offset: -2px; }
.pp-cell.qa-selday::after { content: "●"; position: absolute; top: 3px; right: 5px; color: var(--accent);
  font-weight: 800; font-size: 10px; }

/* Compétences liées d'un tarif (dropdown de cases à cocher). */
.tarif-comp { margin-top: 8px; }
/* Résumé « rempli » : le summary affiche les compétences cochées → accentué. */
.tarif-comp > summary.has-sel { color: var(--accent); font-weight: 600; }
.tarif-comp-panel ul { list-style: none; margin: 0; padding: 0; }
.tarif-comp-panel li { padding: 3px 4px; }
.tarif-comp-panel label { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 400; margin: 0; }
.tarif-comp-panel input { width: auto; }
.tarif-comp-actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 8px;
  padding-top: 6px; border-top: 1px solid var(--border); font-size: 11px; }
.tarif-comp-actions .lnk { font-size: 11px; }

/* Menus déroulants de filtre multi-sélection (planning global). */
.filter-dd { position: relative; }
.filter-dd > summary { list-style: none; cursor: pointer; padding: 6px 14px; border: 1px solid var(--border);
  border-radius: 999px; background: var(--surface); font-size: 13px; white-space: nowrap; user-select: none; }
.filter-dd > summary::-webkit-details-marker { display: none; }
.filter-dd > summary::after { content: " ▾"; opacity: .6; }
.filter-dd[open] > summary { border-color: var(--accent); }
.filter-dd .dd-count { color: var(--accent); font-weight: 700; }
.filter-panel { position: absolute; z-index: 50; margin-top: 6px; min-width: 240px; max-height: 340px;
  overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0,0,0,.25); padding: 8px; }
.filter-grp { font-size: 10px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-muted);
  font-weight: 700; margin: 8px 4px 3px; }
.filter-opt { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 6px;
  font-size: 13px; cursor: pointer; }
.filter-opt:hover { background: var(--surface-2); }
.filter-opt input { width: auto; }
.filter-search { width: 100%; margin-bottom: 6px; box-sizing: border-box; }
.fiche-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 28px; align-items: start; }
@media (max-width: 900px) { .fiche-2col { grid-template-columns: 1fr; } }
.compteur-dates { display: block; font-size: 11px; color: var(--text-muted); margin-top: 1px; }
/* États de cumul de jours (fiche personnel) : 3 tuiles. */
.cumuls { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.cumul-item { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); text-align: center; }
.cumul-item--accent { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.cumul-num { font-size: 24px; font-weight: 800; font-family: var(--font-head); line-height: 1; }
.cumul-lbl { font-size: 11px; color: var(--text-muted); }
/* Version compacte : 3 cumuls côte à côte au-dessus de la photo. */
.cumuls-mini { gap: 5px; margin-bottom: 6px; }
.cumuls-mini .cumul-item { padding: 6px 2px; border-radius: 8px; }
.cumuls-mini .cumul-num { font-size: 16px; }
.cumuls-mini .cumul-lbl { font-size: 9px; }
/* Tuile du cumul mensuel : flèches ‹ › FIXES aux extrémités (navigation mois),
   CENTRE cliquable = lien vers la feuille de route mensuelle (page dédiée). */
.cumul-mois { position: relative; padding: 0; }
.cumul-center { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center;
  gap: 2px; padding: 6px 26px; text-decoration: none; color: inherit; border-radius: 8px; }
.cumul-center:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.cumul-center:hover .cumul-num { color: var(--accent); }
.cumul-nav { position: absolute; top: 0; bottom: 0; width: 26px; z-index: 2; display: flex; align-items: center;
  justify-content: center; text-decoration: none; color: var(--accent); font-weight: 800; font-size: 24px;
  line-height: 1; opacity: 0.7; }
.cumul-nav:hover { opacity: 1; background: color-mix(in srgb, var(--accent) 12%, transparent); }
.cumul-nav-prev { left: 0; border-radius: 8px 0 0 8px; }
.cumul-nav-next { right: 0; border-radius: 0 8px 8px 0; }

/* Feuille de route mensuelle (page dédiée personne_mois). */
.btn-sm { padding: 4px 10px; font-size: 12px; }
.mois-nav { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 4px 0 18px; }
.mois-nav-titre { margin: 0; font-family: var(--font-head); font-size: 20px; text-transform: capitalize; }
.fdr-list { display: flex; flex-direction: column; gap: 12px; }
.fdr-card { border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; background: var(--surface); }
.fdr-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.fdr-titre { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fdr-proj { font-weight: 700; font-size: 16px; text-decoration: none; color: var(--text); }
.fdr-proj:hover { color: var(--accent); text-decoration: underline; }
.fdr-tag { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; padding: 2px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.fdr-jours { font-weight: 800; font-family: var(--font-head); white-space: nowrap; }
.fdr-jours-tot { font-weight: 500; font-size: 12px; color: var(--text-muted); }
.fdr-meta { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 6px; font-size: 13px; color: var(--text-muted); }
.fdr-note { margin-top: 6px; font-size: 13px; }
.fdr-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px;
  padding-top: 12px; border-top: 1px dashed var(--border); }
.fdr-statut { margin-left: auto; font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 999px; }
.fdr-statut--todo { background: color-mix(in srgb, var(--text-muted) 16%, transparent); color: var(--text-muted); }
.empty-state { border: 1px dashed var(--border); border-radius: 12px; padding: 30px; text-align: center; color: var(--text-muted); }
.fdr-cta { display: inline-flex; margin-top: 10px; }

/* Ligne d'infos projet (fiche) : puces auto-masquées si le champ est vide. */
.proj-infos { display: flex; flex-wrap: wrap; gap: 6px 8px; margin-top: 8px; }
.proj-infos .pi { display: inline-flex; align-items: center; gap: 5px; font-size: 13px;
  color: var(--text-muted); background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 10px; }
.proj-infos .pi b { font-weight: 600; color: var(--text); font-size: 11px; text-transform: uppercase; letter-spacing: .03em; }

/* Badge « 100% » dans la légende des filtres du calendrier (projet terminé). */
.pi-100 { font-size: 10px; font-weight: 700; color: #16a34a; background: color-mix(in srgb, #16a34a 15%, transparent);
  border-radius: 999px; padding: 1px 6px; }

/* Sélecteur de couleur réutilisable : pastille (trigger) + grille popover (~40 couleurs). */
.swatch-field { position: relative; display: inline-flex; vertical-align: middle; }
.swatch-trigger { width: 34px; height: 34px; border-radius: 8px; border: 2px solid var(--border);
  cursor: pointer; padding: 0; box-shadow: inset 0 0 0 2px var(--surface); }
.swatch-trigger:hover { border-color: var(--accent); }
.swatch-pop { position: absolute; z-index: 40; top: calc(100% + 6px); left: 0;
  display: grid; grid-template-columns: repeat(8, 22px); gap: 6px; padding: 10px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.28); }
.swatch-pop[hidden] { display: none; }
.swatch { width: 22px; height: 22px; border-radius: 6px; border: 1px solid rgba(0,0,0,.18);
  cursor: pointer; padding: 0; transition: transform .08s; }
.swatch:hover { transform: scale(1.18); }
.swatch.active { outline: 2px solid var(--text); outline-offset: 2px; }
/* Dépliant « Plus d'informations » de la fiche. */
.fiche-plus { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 6px; }
.fiche-plus > summary { cursor: pointer; font-weight: 600; font-size: 13px; color: var(--accent);
  list-style: none; padding: 4px 0; }
.fiche-plus > summary::-webkit-details-marker { display: none; }
.fiche-plus > summary::before { content: "▸ "; }
.fiche-plus[open] > summary::before { content: "▾ "; }
.lock-badge { font-size: 11px; opacity: 0.7; margin-left: 4px; vertical-align: middle; }
.pl-bars { margin-top: 4px; display: flex; flex-direction: column; gap: 3px; }
.pl-chip { display: block; font-size: 10.5px; color: #fff; padding: 2px 6px; border-radius: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 1px rgba(0,0,0,0.15); }
.pl-chip:hover { color: #fff; filter: brightness(1.08); }
/* Planning perso : le nom du projet est dans la LÉGENDE (une seule fois) ; le
   calendrier n'affiche que des blocs colorés → jamais de texte répété ni de débordement. */
.planning-legende { display: flex; flex-wrap: wrap; gap: 8px 14px; margin: 4px 0 6px; }
/* NB iOS Safari : sur les liens, `-webkit-text-fill-color` peut écraser `color`
   → on force les deux, sinon le nom du projet apparaît blanc/gris sur iPhone. */
/* Couleur LITTÉRALE (pas de var) : Safari a un bug avec var() dans color /
   -webkit-text-fill-color, qui rendait le nom du projet blanc sur iPhone. */
.pl-leg { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px;
  color: #1a1d21 !important; -webkit-text-fill-color: #1a1d21 !important; text-decoration: none; }
.pl-leg strong { color: #1a1d21 !important; -webkit-text-fill-color: #1a1d21 !important; font-weight: 700; }
/* Correctif iOS WebKit : sans promotion sur calque GPU, le nom de projet (couleur forcée)
   est peint en BLANC au premier rendu sur iPhone (computed = noir, pixels = blanc). Forcer
   l'élément sur son propre calque (translateZ) déclenche un repaint correct. Confirmé sur device. */
.pl-leg, .pl-leg > * { transform: translateZ(0); }
.pl-leg-dot { width: 13px; height: 13px; border-radius: 4px; flex: none; }
.pl-leg-past { opacity: 0.7; }
/* Encart « Centrer sur un projet » au-dessus du calendrier (staff) : liste cliquable
   qui recentre la vue sur le projet. Hauteur limitée + défilement si beaucoup de projets. */
/* Bandeau « des éléments sont masqués par vos filtres » + bouton Tout afficher. */
.cal-hidden-note { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 9px 12px;
  background: color-mix(in srgb, var(--warning) 12%, transparent); border: 1px solid var(--warning);
  border-radius: var(--radius); font-size: 13px; color: var(--text); }
.cal-hidden-note .ico { width: 17px; height: 17px; color: var(--warning); flex: none; }
.cal-hidden-note .btn { margin-left: auto; padding: 4px 12px; }
.cal-centrer { margin: 6px 0 12px; padding: 10px 12px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius); }
.cal-centrer-label { display: block; font-size: 12px; color: var(--text-muted);
  margin-bottom: 8px; font-weight: 600; }
/* Tous les projets visibles d'un coup (bureau ET mobile) : la liste passe à la ligne
   au lieu d'être enfermée dans une petite boîte à ascenseur, où la plupart des projets
   restaient cachés tant qu'on ne faisait pas défiler. */
.cal-centrer .planning-legende { max-height: none; overflow: visible; margin: 0; }
.cal-centrer .pl-leg { padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); }
.cal-centrer .pl-leg:hover { border-color: var(--accent); }
/* Indisponibilités posées par la personne : croix rouge + fond teinté. */
.cal-bgcell.rr-indispo-bg { background: rgba(214,69,69,0.12); }
.cal-num.is-indispo { color: var(--danger); font-weight: 800; }
/* Sélection manuelle d'indispos (mode « Sélection manuelle » sur Mon planning). */
body.indispo-mode .cal-num[data-date] { cursor: pointer; user-select: none; }
/* En mode sélection d'indispo, TOUTE la case du jour est cliquable (pas que le numéro). */
body.indispo-mode .cal-week, body.indispo-mode .cal-week-bg, body.indispo-mode .cal-week-lanes { cursor: pointer; }
.cal-num.indispo-sel { background: color-mix(in srgb, var(--danger) 22%, transparent);
  color: var(--danger); font-weight: 800; border-radius: 6px; box-shadow: inset 0 0 0 2px var(--danger); }
.cal-num.indispo-pending { border-radius: 6px; box-shadow: inset 0 0 0 2px var(--accent); }
.cal-num.is-indispo::after { content: "✕"; margin-left: 3px; font-size: 11px; }
body.indispo-mode .cal-num[data-date] { cursor: pointer; }
body.indispo-mode .cal-num[data-date]:hover { background: rgba(214,69,69,0.18); border-radius: 4px; }
.planning-archives { margin: 6px 0 4px; }
.planning-archives > summary { cursor: pointer; font-size: 13px; color: var(--accent); font-weight: 600; }
.pl-days { display: flex; flex-direction: column; gap: 2px; margin-top: auto; }
.pl-day { display: block; height: 7px; border-radius: 3px; }

/* Formulaire d'ajout de pièce d'identité (portail perso). */
.piece-add-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.piece-add-row input[type=text] { flex: 1; min-width: 140px; }
.piece-add-files { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.piece-file { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--text-muted); }
.piece-file input[type=file] { font-size: 12.5px; max-width: 220px; }

/* Case « Effacer » des champs photo (ClearableFileInput Django) → apparence bouton. */
input[name$="-clear"] { position: absolute; opacity: 0; width: 0; height: 0; }
input[name$="-clear"] + label { display: inline-block; padding: 5px 11px; margin-left: 4px;
  border: 1px solid var(--danger); color: var(--danger); border-radius: var(--radius);
  cursor: pointer; font-size: 12.5px; }
input[name$="-clear"] + label:hover { background: rgba(214,69,69,0.10); }
input[name$="-clear"]:checked + label { background: var(--danger); color: #fff; }
input[name$="-clear"]:checked + label::before { content: "✓ Sera effacée — "; }

.compteur-total { display: flex; align-items: baseline; gap: 8px; }
.compteur-total-num { font-size: 30px; font-weight: 700; font-family: var(--font-head); color: var(--accent); }
.compteur-total-lbl { color: var(--text-muted); font-size: 13px; }

.btn.active-archives { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }

/* Accès en temps réel */
.dot-online { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--success); box-shadow: 0 0 0 3px rgba(26,157,99,0.2); vertical-align: middle; margin-right: 4px; }
.dot-offline { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--border); vertical-align: middle; margin-right: 4px; }

/* Catalogue de compétences (toggle vert/rouge) */
.comp-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }
.comp-item { display: flex; align-items: center; gap: 8px; padding: 7px 10px 7px 8px; border: 1px solid var(--border); border-radius: 20px; background: var(--surface); }
.comp-item.off { opacity: 0.7; }
.comp-toggle { width: 16px; height: 16px; border-radius: 50%; border: none; cursor: pointer; padding: 0; display: block; }
.comp-item.on .comp-toggle { background: var(--success); box-shadow: 0 0 0 3px rgba(26,157,99,0.18); }
.comp-item.off .comp-toggle { background: var(--danger); box-shadow: 0 0 0 3px rgba(214,69,0,0.14); }
.comp-nom { font-size: 13.5px; }
.comp-item.off .comp-nom { color: var(--text-muted); }
.comp-del { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 16px; line-height: 1; padding: 0; }
.comp-del:hover { color: var(--danger); }

/* Planning global du personnel (grille personnes × jours) */
.pg-table { border-collapse: collapse; min-width: 100%; }
.pg-table th, .pg-table td { border: 1px solid var(--border); }
.pg-table thead th { background: var(--surface-2); font-size: 10.5px; color: var(--text-muted); font-weight: 600; padding: 4px 0; text-align: center; width: 26px; }
.pg-table .pg-dow { font-weight: 400; opacity: 0.7; }
/* z-index 5 : la colonne des noms (sticky) doit passer AU-DESSUS des bulles (.pg-bar,
   z-index 2) quand on scrolle horizontalement, sinon les bulles se superposent aux noms. */
.pg-perso { text-align: left; padding: 6px 12px; min-width: 170px; background: var(--surface); position: sticky; left: 0; z-index: 5; font-size: 13.5px; }
.pg-table thead .pg-perso { z-index: 6; }
.pg-perso a { color: inherit; }
/* HAUTEUR CALCULÉE, pas choisie au jugé : deux rangs de barres (3→14 et 15→26),
   deux pixels de respiration, puis la bande des voyages (17 px : l'avion et sa
   ville). À 30 px cette bande retombait sur la seconde barre — et un projet d'UNE
   SEULE JOURNÉE porte justement le départ ET le retour dans la même case, sous
   une barre. Les avions restent tels quels ; c'est la case qui grandit sous eux. */
.pg-cell { height: 46px; padding: 2px; vertical-align: middle; position: relative; }
.pg-cell.col-weekend, .pg-day.col-weekend { background: var(--surface-2); }
.pg-cell.col-ferie, .pg-day.col-ferie { background: rgba(139,92,246,0.10); }
.pg-day.col-ferie::after { content: "•"; color: #8b5cf6; font-size: 10px; display:block; line-height: 0; }
.pg-cell.col-today, .pg-day.col-today { background: rgba(214,69,0,0.12); }
.pg-day.col-today { color: var(--accent); font-weight: 700; }
/* Barre projet fusionnée : nom à GAUCHE, poste occupé à DROITE, s'étend sur les jours. */
.pg-bar {
  position: absolute; left: 1px; z-index: 2;
  top: calc(3px + var(--i, 0) * 12px); height: 11px;
  width: calc(var(--run, 1) * 100% + (var(--run, 1) - 1) * 1px - 2px);
  border-radius: 3px; color: #fff; font-size: 9.5px; font-weight: 600;
  line-height: 11px; padding: 0 5px; text-shadow: 0 1px 1px rgba(0,0,0,0.28);
  display: flex; align-items: center; justify-content: space-between; gap: 6px; overflow: hidden;
  text-decoration: none; cursor: pointer;
}
.pg-bar:hover { filter: brightness(1.1); box-shadow: 0 0 0 1px rgba(255,255,255,.5); }
.pg-bar .pg-bar-nom { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pg-bar .pg-bar-poste { white-space: nowrap; flex: 0 0 auto; font-weight: 500; opacity: 0.9;
  font-style: italic; max-width: 55%; overflow: hidden; text-overflow: ellipsis; }
/* Boutons de bascule dans une barre seg-views */
.seg-views button { padding: 8px 16px; font-size: 13.5px; color: var(--text-muted); border: none; border-right: 1px solid var(--border); background: none; cursor: pointer; font-family: var(--font); }
.seg-views button:last-child { border-right: none; }
.seg-views button:hover { background: var(--surface-2); color: var(--text); }
.seg-views button.active { background: var(--accent); color: var(--accent-contrast); }
/* Indisponibilités : grosse croix rouge sur la case */
.pg-indispo { position: relative; }
.pg-indispo::after {
  content: ""; position: absolute; inset: 3px; opacity: 0.75;
  background:
    linear-gradient(45deg, transparent calc(50% - 1.5px), var(--danger) calc(50% - 1.5px), var(--danger) calc(50% + 1.5px), transparent calc(50% + 1.5px)),
    linear-gradient(-45deg, transparent calc(50% - 1.5px), var(--danger) calc(50% - 1.5px), var(--danger) calc(50% + 1.5px), transparent calc(50% + 1.5px));
}
/* En-tête de groupe (par compétence) */
.pg-group td { background: var(--surface-2); font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: var(--label-spacing); color: var(--text-muted); padding: 6px 12px; position: sticky; left: 0; z-index: 5; }
/* Mode « Autres indispo » : cases cliquables */
.pg-table.indispo-mode .pg-free, .pg-table.indispo-mode .pg-indispo { cursor: pointer; }
.pg-table.indispo-mode .pg-free:hover { background: rgba(214,69,0,0.12); }
/* Mode Dispos : les jours libres ressortent, les jours bookés s'estompent */
.pg-table.dispo-mode .pg-free { background: rgba(26,157,99,0.22); }
.pg-table.dispo-mode .pg-free.col-today { background: rgba(26,157,99,0.34); }
.pg-table.dispo-mode .pg-bar { opacity: 0.28; }
/* Résultat de recherche : tout l'agenda de la personne surligné (ligne entière) */
.pg-match td { background-image: linear-gradient(rgba(26,157,99,0.13), rgba(26,157,99,0.13)); }
.pg-match .pg-perso { box-shadow: inset 3px 0 0 var(--success); font-weight: 600; }
.pg-match .pg-perso a { color: var(--success); }

/* Bandeau projets COMPACT (option) : une seule ligne, projets en lanes empilées.
   La hauteur suit le nombre de lanes (--lanes) → grandit/rétrécit selon les chevauchements. */
.pg-band-cell { padding: 0; height: calc(var(--lanes, 1) * 11px + 3px); }
.pg-proj-name { font-weight: 600; font-size: 11px; white-space: nowrap;
  height: calc(var(--lanes, 1) * 11px + 3px); }
.pg-band-line { position: absolute; left: 1px; top: calc(var(--lane, 0) * 11px + 2px);
  height: 9px; line-height: 9px; width: calc(var(--run, 1) * 100% - 2px);
  border-radius: 2px; overflow: hidden; font-size: 7px; color: #fff; padding: 0 3px;
  white-space: nowrap; box-shadow: 0 0 0 1px rgba(0,0,0,.2); z-index: 1; }
.pg-band-lbl { text-shadow: 0 0 2px rgba(0,0,0,.65); font-weight: 600; letter-spacing: -.2px; }
.pg-proj-row td { border-bottom: 2px solid var(--border); }

/* Postes d'un pôle (besoins) */
.poste-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.poste-logistique { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 12px; }
.poste-logistique > div { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: end; }
.poste-logistique label { grid-column: 1 / -1; }
.poste-doc { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 12px; }
.poste-doc input[type=file] { font-size: 12px; max-width: 100%; }
.poste-doc .doc-link { color: var(--accent); text-decoration: none; font-weight: 600; }
.poste-doc .doc-clear { display: inline-flex; align-items: center; gap: 4px; color: var(--text-soft); }

.etape-people { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; max-height: 180px; overflow-y: auto; margin-top: 6px;
  padding: 8px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.chk-person { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; font-size: 13px;
  white-space: nowrap; border: 1px solid var(--border); border-radius: 999px; cursor: pointer; user-select: none; }
.chk-person > input { flex: 0 0 auto; }
.chk-person:has(input:checked) { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); font-weight: 600; }

/* Sur grand écran, on évite que les blocs étape et leurs contrôles s'étirent
   sur toute la largeur : lignes plus courtes, plus lisibles. */
.etape-card { max-width: 900px; }
.etape-card .inline-add > select,
.etape-card .picker-comp-value + .etape-people,
.etape-card .etape-people,
.etape-card .picker-hint { max-width: 640px; }
.etape-besoins { margin-top: 12px; }
.besoin-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 12px; border: 1px solid var(--warning); color: var(--warning); background: rgba(199,119,0,0.08); }
.besoin-chip.besoin-ok { border-color: var(--success); color: var(--success); background: rgba(26,157,99,0.10); }
.besoin-pick { background: none; border: none; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; }
.besoin-pick:hover { text-decoration: underline; }
.besoin-nb { width: 42px; padding: 1px 4px; font: inherit; font-weight: 700; text-align: center; border: 1px solid currentColor; border-radius: 6px; background: transparent; color: inherit; }
.deadline-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; color: #8b5cf6; border: 1px solid #8b5cf6; border-radius: 999px; padding: 2px 10px; }
.pg-occupe { font-size: 11px; color: var(--danger); border: 1px solid var(--danger); border-radius: 6px; padding: 0 4px; }
.chk-person.chk-occupe { cursor: help; opacity: .8; }
.etape-edit { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }
.etape-edit input[type=text] { width: auto; flex: 0 1 auto; padding: 5px 8px; font-size: 13px; }
.etape-edit input[type=date] { width: auto; flex: 0 0 auto; padding: 5px 8px; font-size: 13px; }

.mission-row { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.mission-row:last-child { border-bottom: none; }

.detail-cols { display: grid; grid-template-columns: 240px 1fr; gap: 26px; align-items: start; }
.detail-list { list-style: none; padding: 0; margin: 0; }
.detail-list li { padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 14px; display: flex; justify-content: space-between; gap: 16px; }
.detail-list li span:first-child { color: var(--text-muted); }
.avatar-lg { width: 180px; height: 180px; font-size: 46px; }
/* Fiche : photo sur toute la largeur de la colonne (comme les compteurs). */
.detail-cols .avatar-lg { width: 100%; height: auto; aspect-ratio: 1 / 1; font-size: 52px; }
.detail-cols .fiche-contact { margin: 10px 0 0; }
/* Repli « Fiche & contact » : sur DESKTOP il est toujours déplié et son en-tête est
   masqué (aucun changement visuel) ; sur mobile il devient un vrai accordéon (voir @media). */
.fiche-fold > summary { display: none; }
.fiche-fold:not([open]) > .ff-body { display: block; }

/* ---------- Module Projets / Jauges ---------- */
.statut-projet { display:inline-block; padding:2px 10px; border-radius:20px; font-size:11px; border:1px solid var(--border); }
.sp-prospect { color: var(--text-muted); }
.sp-option { color: var(--text); background: repeating-linear-gradient(45deg, var(--warning) 0 6px, #1b1b1b 6px 12px); color:#fff; border-color:transparent; }
.sp-confirme { color:#2f6fb0; background:rgba(47,111,176,0.12); border-color:transparent; }
.sp-en_cours { color:var(--accent); background:rgba(214,69,0,0.12); border-color:transparent; }
.sp-termine  { color:var(--success); background:rgba(26,157,99,0.12); border-color:transparent; }
.sp-annule   { color:var(--danger); text-decoration:line-through; }
/* STANDBY : suspendu, pas annulé. Il doit se voir comme un arrêt — pas comme une
   nuance de « confirmé ». Les hachures disent « en attente » sans dire « perdu »,
   et la pastille reste lisible sur une carte de projet comme dans une liste. */
.sp-standby  { color:#fff; border-color:transparent; font-weight:700;
  background: repeating-linear-gradient(135deg, #6b6b6b 0 7px, #3a3a3a 7px 14px); }

/* Anneau de jauge global */
.gauge-ring {
  width: 132px; height: 132px; border-radius: 50%; flex: none;
  background: conic-gradient(var(--accent) calc(var(--pct) * 1%), var(--surface-2) 0);
  display: grid; place-items: center; position: relative;
}
.gauge-ring::before { content: ""; position: absolute; inset: 12px; border-radius: 50%; background: var(--surface); }
.gauge-ring .val { position: relative; font-size: 30px; font-weight: 700; font-family: var(--font-head); }

/* Barre de jauge (pôle) */
.gauge-bar { height: 10px; border-radius: 20px; background: var(--surface-2); overflow: hidden; }
.gauge-bar > span { display: block; height: 100%; background: var(--accent); border-radius: 20px; }
.gauge-bar.sm { height: 5px; }
.mini-gauges { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.mini-gauge { display: flex; align-items: center; gap: 8px; font-size: 11px; text-decoration: none; color: inherit;
  padding: 3px 6px; margin: 0 -6px; border-radius: 6px; transition: background 0.12s; }
a.mini-gauge:hover { background: var(--surface-2); }
a.mini-gauge:hover .mg-label { color: var(--text); }
/* Mini-jauge circulaire (donut) à gauche du nom du pôle. */
.mini-gauge .mg-ring { flex: 0 0 auto; width: 15px; height: 15px; border-radius: 50%; position: relative;
  background: conic-gradient(var(--accent) calc(var(--pct, 0) * 1%), var(--surface-2) 0); }
.mini-gauge .mg-ring::after { content: ""; position: absolute; inset: 3.5px; border-radius: 50%; background: var(--surface); }
.mini-gauge .mg-label { flex: 0 0 90px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-gauge .gauge-bar.sm { flex: 1; }
.mini-gauge .mg-pct { flex: 0 0 40px; text-align: right; color: var(--text-muted); }

.pole { padding: 16px 0; border-bottom: 1px solid var(--border); }
.pole:last-child { border-bottom: none; }
.pole-link { display: block; text-decoration: none; color: inherit; padding: 14px 10px; margin: 0 -10px; border-radius: var(--radius); }
.pole-link:hover { background: var(--surface-2); color: inherit; }
.pole-link .pct { color: var(--text-muted); }
.pole-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.pole-head .nom { font-weight: 600; }
.pole-head .pct { font-variant-numeric: tabular-nums; color: var(--text-muted); }

/* CE QUI MANQUE, au survol du pourcentage. En COLONNE : une ligne par élément.
   Alignée à DROITE sur le pourcentage, elle ne peut pas sortir de la carte. */
.pct-survol { position: relative; cursor: help; }
.pct-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  display: none; flex-direction: column; gap: 3px;
  min-width: 230px; max-width: 340px; max-height: 320px; overflow-y: auto;
  padding: 10px 12px; text-align: left; white-space: normal;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 10px 26px rgba(0,0,0,.35);
  font-size: 12.5px; font-weight: 400; font-variant-numeric: normal;
}
.pct-survol:hover .pct-pop, .pct-survol:focus-within .pct-pop { display: flex; }
.pct-pop b { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
             color: var(--text-muted); margin-bottom: 2px; }
.pct-pop i { color: var(--text-muted); font-style: italic; }
/* CE QUI N'EST PAS PARTI, JUSTE AVANT LE POURCENTAGE. L'avancement dit « 80 % » et
   ne dit rien des documents qui dorment : deux questions différentes, la seconde ne
   se posant d'elle-même qu'au moment où il est trop tard. Rouge, parce que c'est le
   genre d'oubli qui se paie au montage — un gris de plus dans une page grise ne se
   verrait pas. Posé AVANT le pourcentage et non après : la jauge reste alignée
   d'une ligne à l'autre, sinon elle glisserait sur les seules lignes en alerte. */
.pct-alerte { position: relative; cursor: help; font-size: 12px; font-weight: 700;
  color: var(--danger, #dc2626); border: 1px solid var(--danger, #dc2626);
  border-radius: 999px; padding: 0 7px; line-height: 1.6; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.pct-alerte:hover .pct-pop, .pct-alerte:focus-within .pct-pop { display: flex; }
/* Le titre à gauche, l'alerte COLLÉE au pourcentage à droite. Sans cette marge, la
   répartition en `space-between` planterait le signal au milieu de la ligne, à une
   place différente selon la longueur du nom du pôle. */
.pole-head .pct-alerte, .dep-head .pct-alerte { margin-left: auto; }
/* SUR UNE VIGNETTE DE PROJET, il se pose dans le coin haut-droit — la seule place qui
   ne bouge pas d'une carte à l'autre, quels que soient la longueur du nom, le nombre
   de pôles ou la présence d'une date.
   AU-DESSUS DU RECOUVREMENT CLIQUABLE : toute la vignette est un lien, et un signal
   qui passerait dessous n'aurait pas de survol — c'est-à-dire qu'on ne saurait jamais
   DE QUOI il parle, seulement qu'il y a quelque chose. */
.projet-card > .pct-alerte { position: absolute; top: 10px; right: 12px; z-index: 2; }
/* Le détail s'ouvre vers la GAUCHE : collé au bord droit de la carte, il sortirait
   de la grille et se ferait couper. */
.projet-card > .pct-alerte .pct-pop { right: 0; }
.pop-alerte b { color: var(--danger, #dc2626); }
.mode-tag { font-size: 10.5px; text-transform: uppercase; letter-spacing: var(--label-spacing); color: var(--text-muted); border: 1px solid var(--border); border-radius: 4px; padding: 1px 6px; margin-left: 8px; }

/* Curseur d'avancement */
input[type="range"] { width: 100%; accent-color: var(--accent); background: transparent; padding: 0; }

/* Check-list */
.tache { display: flex; align-items: center; gap: 9px; padding: 5px 0; font-size: 14px; }
/* BARRER LE NOM DE LA TÂCHE, ET LUI SEUL. Le trait disait « c'est fait » pour
   l'action ; posé sur le label entier il rayait aussi « Ouvrir », « Partager » et
   le compte de contacts — qui, eux, servent encore : un document reste à ouvrir
   et à transmettre longtemps après que la tâche a été cochée. */
.tache.done label { color: var(--text-muted); }
.tache.done .tache-nom { text-decoration: line-through; }
.tache.done .tache-piece, .tache.done .tache-contacts,
.tache.done .tache-partage { text-decoration: none; }
.tache input { width: auto; }
.inline-add { display: flex; gap: 8px; margin-top: 8px; }
.inline-add input[type="text"] { flex: 1; }

.projet-card .gauge-ring { width: 60px; height: 60px; }
.projet-card .gauge-ring::before { inset: 7px; }
.projet-card .gauge-ring .val { font-size: 15px; }

/* ---------- Dashboard : tuiles d'accès (mobile) ---------- */
/* Grille de tuiles carrées (= onglets disponibles), 2 par ligne. Masquée en desktop :
   n'apparaît qu'en mobile, où elle remplace la liste des projets. */
.home-tiles { display: none; }
/* Tuiles du portail perso (Mon espace) : visibles sur mobile ET desktop. */
.portal-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-top: 10px; }
.portal-tiles .home-tile { aspect-ratio: auto; padding: 18px 10px; }
@media (max-width: 820px), (max-height: 480px) and (orientation: landscape) {
  .portal-tiles { grid-template-columns: 1fr 1fr; }
}
.home-tile { position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 10px; aspect-ratio: 1 / 1; text-decoration: none; color: var(--text);
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); }
.home-tile:hover, .home-tile:active { border-color: var(--accent); color: var(--text); }
.home-tile .icon { width: 30px; height: 30px; color: var(--accent); }
.home-tile span { font-size: 15px; font-weight: 600; }
.home-tile-badge { position: absolute; top: 10px; right: 10px; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 10px; background: var(--accent); color: var(--accent-contrast);
  font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; }

/* ---------- Dashboard : avancement projets (dépliable) ---------- */
.proj-adv { border-bottom: 1px solid var(--border); }
.proj-adv:last-child { border-bottom: none; }
.proj-adv-head { display: flex; align-items: center; gap: 16px; padding: 14px 0; cursor: pointer; }
.proj-adv-head:hover { opacity: 0.9; }
.proj-adv-head .gauge-ring { width: 54px; height: 54px; }
.proj-adv-head .gauge-ring::before { inset: 6px; }
.proj-adv-head .gauge-ring .val { font-size: 14px; }
.proj-adv .chevron { color: var(--text-muted); transition: transform 0.15s; }
.proj-adv.open .chevron { transform: rotate(180deg); }
.proj-adv-poles { display: none; padding: 0 0 6px 70px; }
.proj-adv.open .proj-adv-poles { display: block; }

/* ---------- Recherche rapide (dispo par compétence) ---------- */
/* Accès rapide sur le dashboard : choix direct de la compétence. */
.rr-quick { margin: 6px 0 22px; padding: 14px 16px; }
.rr-quick-label { display: block; font-size: 14px; font-weight: 600; color: var(--text);
  margin-bottom: 8px; text-transform: none; letter-spacing: 0; }
.rr-quick-row { display: flex; gap: 10px; align-items: center; }
.rr-quick-row select { flex: 1; min-width: 0; }
.rr-quick-row .btn { flex: none; }
.rr-form { margin-bottom: 16px; }
.rr-fields { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }
.rr-field { display: flex; flex-direction: column; }
.rr-field select { min-width: 200px; }
.rr-field input[type=date] { width: auto; }
.rr-checkbox { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--text); }
.rr-checkbox input { width: auto; }
.rr-people { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.rr-person { display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; border: 1px solid var(--border);
  border-radius: 999px; text-decoration: none; color: var(--text); font-size: 13.5px; background: var(--surface); }
.rr-person:hover { border-color: var(--accent); color: var(--text); }
/* Case du calendrier de dispo : compteur + noms (prénom + initiale). */
.rr-cell { min-height: 84px; align-items: stretch; overflow: hidden; min-width: 0; }
.rr-cell.rr-weekend { background: var(--surface-2); }
.rr-cell.rr-empty { border: none; background: transparent; cursor: default; }
.rr-cell-top { display: flex; align-items: center; justify-content: space-between; }
.rr-count { font-size: 17px; font-weight: 800; font-family: var(--font-head); color: var(--success);
  background: color-mix(in srgb, var(--success) 15%, transparent); border-radius: 999px; min-width: 24px;
  text-align: center; padding: 0 7px; line-height: 1.5; }
.rr-cell.rr-zero .rr-count { color: var(--text-muted); background: var(--surface-2); }
.rr-names { display: flex; flex-direction: column; gap: 1px; margin-top: 4px; overflow: hidden; min-width: 0; }
.rr-name { font-size: 10px; line-height: 1.45; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rr-more { font-size: 10px; font-weight: 700; color: var(--text-muted); }
/* Sélection au clic sur le calendrier. */
.rr-cell[data-date] { cursor: pointer; user-select: none; }
.rr-cell[data-date]:hover { box-shadow: inset 0 0 0 2px var(--accent); }
.rr-cell.rr-selected { background: color-mix(in srgb, var(--accent) 14%, transparent); box-shadow: inset 0 0 0 1px var(--accent); }
.rr-cell.rr-picking { box-shadow: inset 0 0 0 2px var(--accent); }
.rr-cell.rr-selected .rr-count { color: var(--accent); background: color-mix(in srgb, var(--accent) 18%, transparent); }
/* Zones sélectionnées (multi) : chips supprimables au-dessus du calendrier. */
.rr-zones { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 10px; }
.rr-zones-label { font-size: 12px; color: var(--text-muted); font-weight: 600; }
.rr-zone-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 999px; font-size: 13px; font-weight: 600; text-decoration: none;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.rr-zone-chip:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); }
.rr-zone-x { font-size: 11px; opacity: .8; }
.rr-zones-clear { font-size: 12px; color: var(--danger); text-decoration: none; margin-left: 4px; }
.rr-zones-clear:hover { text-decoration: underline; }
/* Étiquettes de résultat (total / partiel). */
.rr-res-label { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em; font-weight: 700; margin: 6px 0; }
.rr-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.rr-dot-full { background: var(--success); }
.rr-dot-part { background: var(--warning); }
.rr-person-part { border-style: dashed; }
.rr-frac { font-size: 11px; font-weight: 700; color: var(--warning); margin-left: 2px; }

/* ---------- Types de journée ---------- */
.type-list { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.type-item { display: flex; align-items: center; gap: 9px; padding: 7px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.type-dot { width: 13px; height: 13px; border-radius: 50%; flex: none; }
.type-item form { margin: 0; }
.type-item button { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 15px; padding: 0; line-height: 1; }
.type-item button:hover { color: var(--danger); }

/* ---------- Calendrier ---------- */
.cal-toolbar { display: flex; flex-wrap: wrap; gap: 14px 20px; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.seg-views { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.seg-views a { padding: 8px 16px; font-size: 13.5px; color: var(--text-muted); border-right: 1px solid var(--border); }
.seg-views a:last-child { border-right: none; }
.seg-views a:hover { background: var(--surface-2); color: var(--text); }
.seg-views a.active { background: var(--accent); color: var(--accent-contrast); }

/* Bloc de filtres TOUJOURS visible : il prend toute la largeur du toolbar et passe
   à la ligne. Sans cela, en bureau, il était un élément flex qui s'effondrait à 0 px
   (filtres invisibles alors qu'ils s'affichaient bien en mobile). */
.cal-filters-bloc { flex: 1 1 100%; min-width: 0; }
/* Archives : encadré nettement distinct (fond neutre, trait discontinu) sous le bloc
   de centrage, pour qu'on ne confonde jamais un projet terminé avec un projet en cours. */
.cal-archives { margin: 10px 0 16px; padding: 12px 14px; border: 1px dashed var(--border);
  border-left: 3px solid var(--text-muted); border-radius: 10px; background: rgba(127,127,127,0.05); }
.cal-archives-tete { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.cal-archives .pl-leg { opacity: 0.85; }
.arch-statut { margin-left: 6px; font-size: 11px; font-weight: 700; text-transform: uppercase;
  color: var(--text-muted); letter-spacing: .3px; }
/* Centrage sur un projet : celui visé reste net, les autres sont atténués (calendrier
   ET liste de centrage). Un clic dans le vide libère l'atténuation. */
/* `.cal-ev` porte sa propre opacité et est déclarée plus bas : on double le sélecteur
   pour que l'atténuation l'emporte partout (sinon les barres du calendrier gardaient
   leur opacité d'origine et ne semblaient pas atténuées). */
.projet-attenue,
.cal-ev.projet-attenue,
.cal-ev-star.projet-attenue { opacity: 0.5; filter: grayscale(1); transition: opacity .15s ease; }
.cal-centrer .pl-leg.projet-focus { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 999px; }
.cal-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13px; }
.cal-filters-label { color: var(--text-muted); text-transform: uppercase; font-size: 11px; letter-spacing: var(--label-spacing); }
.cal-filters label { display: inline-flex; align-items: center; gap: 6px; margin: 0; color: var(--text); cursor: pointer; }
.cal-filters input { width: auto; }
.cal-filters .lnk { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 12.5px; padding: 0; }
.cal-filters .proj-check { font-size: 12.5px; }
.legend-swatch { width: 14px; height: 14px; border-radius: 3px; flex: none; display: inline-block; }

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin-bottom: 6px; }
.cal-head { margin-bottom: 6px; }
.cal-dow { text-align: center; font-size: 11px; text-transform: uppercase; letter-spacing: var(--label-spacing); color: var(--text-muted); padding: 4px; }
.cal-cell {
  min-height: 118px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 6px; display: flex; flex-direction: column; gap: 4px; overflow: hidden;
}
.cal-cell.out { opacity: 0.45; }
.cal-cell.today { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.cal-daynum { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.cal-cell.today .cal-daynum { color: var(--accent); }
.cal-chip { font-size: 11.5px; padding: 3px 7px; border-radius: 5px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-band { display: block; font-size: 11px; padding: 3px 7px; border-radius: 4px; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 500; text-shadow: 0 0 3px rgba(0,0,0,.8), 0 1px 1px rgba(0,0,0,0.6); }
.cal-band:hover { color: #fff; filter: brightness(1.08); }
.cal-deadline { font-size: 11px; font-weight: 600; }
.cal-perso { display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-muted); }

/* Calendrier propre au projet */
.pp-cell {
  min-height: 74px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 7px; display: flex; flex-direction: column;
  /* `flex-start` et non `space-between` : réparti verticalement, le contenu
     descendait plus ou moins bas selon ce que la case portait, et les barres
     d'étape ne s'alignaient plus d'une case à l'autre. On empile depuis le HAUT,
     et seuls les compteurs sont repoussés en bas (margin-top: auto). */
  justify-content: flex-start; color: inherit; text-decoration: none;
}
/* Le numéro occupe TOUJOURS la même hauteur, jalon ou pas : sans cela, une case
   portant « ★ 1er show » poussait ses étapes d'une ligne vers le bas et cassait
   l'alignement de toute la semaine. */
.pp-num { min-height: 18px; display: flex; align-items: flex-start; gap: 4px;
  flex-wrap: wrap; }
.pp-marks { margin-top: auto; }
/* Un jour HORS période reste estompé — mais pas ses VOYAGES : un déplacement qui
   tombe la veille du chantier est précisément l'information qu'on vient chercher
   là, l'estomper reviendrait à la cacher au moment où elle compte.
   L'opacité est donc posée sur CHAQUE partie plutôt que sur la case : `opacity`
   crée un contexte de composition, et un enfant ne peut jamais être plus opaque
   que son parent — remonter l'opacité du bloc de voyage n'aurait rien donné. */
.pp-cell.out { opacity: 1; }
.pp-cell.out .pp-num,
.pp-cell.out .pp-etapes,
.pp-cell.out .pp-marks,
.pp-cell.out .pp-fill { opacity: 0.4; }
.pp-cell { cursor: pointer; }
a.pp-cell:not(.actif):hover { background: var(--surface-2); box-shadow: inset 3px 0 0 var(--border); }
.pp-cell.actif:hover { filter: brightness(0.98); box-shadow: inset 3px 0 0 var(--accent), 0 1px 4px rgba(0,0,0,0.08); }
.pp-cell.today { outline: 2px solid var(--accent); outline-offset: -2px; }
.pp-num { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.pp-mois { font-size: 10px; font-weight: 800; color: var(--accent); margin-left: 1px; }
/* Calendrier nominatif de l'onglet Personnel : remplissage à 50%, noms colorés. */
.pp-cell.pp-perso { position: relative; min-height: 78px; align-items: stretch; overflow: hidden; }
/* Mois vertical À GAUCHE des jours (hors des cases), aligné sur la semaine du mois. */
.cal-week-row { display: flex; align-items: stretch; }
/* Séparation nette entre les mois sur les projets longs (vue continue). */
/* Ouverture d'un mois : séparation FRANCHE (trait accentué + respiration) pour que
   les mois se lisent d'un coup d'œil sur les calendriers continus. */
.cal-week-newmonth { margin-top: 22px; border-top: 2px solid var(--accent); padding-top: 10px; }
.cal-week-newmonth:first-of-type { margin-top: 0; border-top: 0; padding-top: 0; }
.cal-mois-gutter { flex: 0 0 22px; position: relative; }
/* Compteurs du mois : fine ligne HORIZONTALE au-dessus de la semaine qui ouvre le
   mois. Le nom du mois reste vertical dans sa gouttière étroite : aucun jour n'est
   décalé (élargir la gouttière poussait tout le calendrier vers la droite). */
.cal-mois-bandeau { display: flex; align-items: center; gap: 8px; margin: 16px 0 2px 22px;
  font-size: 11px; line-height: 1.3; }
.cal-mois-bandeau b { font-weight: 800; text-transform: uppercase; letter-spacing: .4px;
  color: var(--accent); }
.cal-mois-bandeau em { font-style: normal; font-weight: 600; color: var(--text-muted);
  background: var(--surface-2, rgba(127,127,127,.10)); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 9px; }
.cal-week-row > .cal-grid { flex: 1; min-width: 0; }
.cal-mois-vert {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); white-space: nowrap;
}
/* Remplissage du jour : très léger (25%), tout en arrière-plan. */
.pp-cell.pp-perso .pp-fill { position: absolute; inset: 0; opacity: 0.25; border-radius: inherit; z-index: 0; pointer-events: none; }
.pp-cell.pp-perso .pp-num, .pp-cell.pp-perso .pp-gens { position: relative; z-index: 1; }
.pp-cell.pp-perso .pp-num { color: var(--text); font-weight: 700; }
.pp-cell.pp-perso .pp-count { margin-left: 5px; font-size: 11px; font-weight: 800; background: var(--accent); color: var(--accent-contrast); border-radius: 20px; padding: 1px 7px; }
.pp-gens { display: flex; flex-direction: column; gap: 2px; margin-top: 3px; }
.pp-gen { font-size: 9px; line-height: 1.5; color: #fff; padding: 0 5px; border-radius: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.pp-gen-more { font-size: 9px; color: var(--text-muted); font-weight: 700; }
/* Logistique du personnel : compact, 2 lignes par personne. */
.logi-card { padding: 10px 14px; margin-bottom: 8px; }
.logi-line { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0; }
.logi-nom { font-weight: 700; margin-bottom: 6px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.logi-nom a { text-decoration: none; color: inherit; }
.logi-confirm { margin: 0; display: inline-flex; align-items: center; gap: 8px; }
.logi-sel { flex: 0 1 140px; min-width: 0; }
.logi-resa { flex: 0 1 120px; min-width: 0; }
.logi-docs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.logi-docs-lbl { font-size: 12px; color: var(--text-muted); }
.logi-check { color: var(--success); font-weight: 800; font-size: 15px; flex: none; }
.doc-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 2px 4px 2px 9px; font-size: 12px; }
.doc-chip a { text-decoration: none; color: var(--accent); max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.logi-doc-add { display: flex; align-items: center; gap: 6px; margin: 0; }
.logi-doc-add input[type=text] { width: 150px; font-size: 12px; padding: 4px 8px; }
.logi-doc-add input[type=file] { font-size: 11px; max-width: 190px; }
.alerte-row { display: flex; align-items: center; gap: 12px; padding: 12px 4px; border-bottom: 1px solid var(--border); }
.alerte-row:last-child { border-bottom: none; }
.alerte-row .alerte-tri .ico { width: 20px; height: 20px; }
.alerte-ok { opacity: 0.85; }
/* Bandeau d'information neutre (fiche : employé via société, etc.). */
.info-banner { padding: 10px 12px; border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 8px; background: var(--surface-2, rgba(127,127,127,0.06)); font-size: 0.92rem; line-height: 1.4; }
.info-banner a { color: var(--accent); font-weight: 600; }
/* Calendrier fiche : mode édition d'indispo actif → cases libres cliquables (affordance). */
#fiche-cal.edit-indispo { outline: 2px dashed var(--accent); outline-offset: 3px; border-radius: 8px; }
#fiche-cal.edit-indispo .fiche-cal-cell[data-date] { cursor: pointer; }
#fiche-cal.edit-indispo .fiche-cal-cell[data-date]:hover { box-shadow: inset 0 0 0 2px var(--accent); }
/* Horaires d'indispo divulgués (opt-in de la personne) affichés dans la case. */
.fiche-indispo-h { display:inline-block; font-size:0.62rem; font-weight:600; line-height:1.2;
  color: var(--danger); white-space:nowrap; }
.pg-cell .pg-indispo-h { display:block; font-size:0.58rem; font-weight:600; line-height:1;
  color: var(--danger); text-align:center; margin-top:1px; }
/* Filtres du calendrier : on VOIT d'un coup d'œil ce qui est affiché (vert) et ce
   qui est masqué (gris barré). S'applique aux projets, statuts et types de projet. */
.cal-filters label.filtre-on { background: rgba(26,157,99,0.14); border-color: var(--success); }
.cal-filters label.filtre-off { background: rgba(127,127,127,0.10); color: var(--text-muted); opacity: 0.6; }
.type-toggle { display: inline-flex; align-items: center; gap: 4px; margin-right: 6px; }
.filtre-chip { border: 1px solid var(--border); border-radius: 999px; padding: 4px 12px;
  font-size: 0.82rem; font-weight: 600; cursor: pointer; background: var(--surface); color: var(--text); }
.filtre-chip.filtre-on { background: rgba(26,157,99,0.16); border-color: var(--success); color: var(--success); }
.filtre-chip.filtre-off { background: rgba(127,127,127,0.10); border-color: var(--border);
  color: var(--text-muted); opacity: 0.65; text-decoration: line-through; }
/* Accord de confidentialité (NDA bêtatesteur) : texte long, lisible, défilable. */
.nda-texte { white-space: pre-wrap; font-size: 0.9rem; line-height: 1.55;
  max-height: 55vh; overflow-y: auto; padding-right: 8px; }
/* Personne libre une DEMI-journée seulement : proposée quand même, signalée ⚠⏱. */
.dispo-partielle { cursor: help; font-size: 0.85em; white-space: nowrap; letter-spacing: -1px; }
/* Grille globale — DEMI-journée : la croix ne barre que la moitié concernée, le
   reste de la case reste BLANC (lisible comme une dispo partielle, pas un blocage). */
.pg-cell.pg-demi::after { inset: 3px; }
.pg-cell.pg-demi-matin::after { inset: 2px 3px 50% 3px; }
.pg-cell.pg-demi-aprem::after { inset: 50% 3px 2px 3px; }
/* Correctif iOS WebKit (racine) : le swap de la police drapeau (font-display:swap) repeint
   le texte voisin et WebKit iOS sort le NOM de projet en BLANC au 1er rendu. On ISOLE le
   drapeau sur son propre calque GPU (inline-block + translateZ) → son repaint ne « bave »
   plus sur le nom. Marche partout, même sur du HTML en cache (ne dépend pas de :has). */
.projet-drapeau { font-family: "Twemoji Country Flags", var(--font); font-size: 1.15em;
  vertical-align: -1px; display: inline-block; transform: translateZ(0); }
/* Ceinture + bretelles : le nom lui-même sur son propre calque là où il est un span dédié. */
.pnom { display: inline-block; transform: translateZ(0); }
:has(> .projet-drapeau) { transform: translateZ(0); }
/* Grand drapeau dans le coin de la fiche projet. */
.projet-drapeau-coin { font-family: "Twemoji Country Flags", var(--font); font-size: 2.6rem; line-height: 1;
  border: 1px solid var(--border); border-radius: 12px; padding: 4px 10px; background: var(--surface); }
.pp-etapes { display: flex; flex-direction: column; gap: 2px; margin: 3px 0; }
/* Étape dans une case de calendrier : NOMMÉE, plus une simple barre de couleur.
   Le nom se tronque proprement quand la case est étroite, le survol donne l'entier. */
/* Barre d'étape : NOM calé à gauche, POURVUS/ATTENDUS calés à droite. Le compte
   ne se laisse jamais tronquer (flex-shrink: 0) — c'est le nom qui rétrécit, car
   un « 3/5 » coupé en « 3/ » induirait en erreur là où un nom coupé reste lisible. */
.pp-etape-bar { display: flex; align-items: center; gap: 4px; width: 100%; min-height: 4px;
  border-radius: 3px; font-size: 9px; line-height: 1.6; font-weight: 700; padding: 0 4px;
  color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,.35); overflow: hidden; }
.pp-etape-nom { flex: 1 1 auto; min-width: 0; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pp-etape-count { flex: 0 0 auto; margin-left: auto; white-space: nowrap;
  background: rgba(0,0,0,.28); border-radius: 20px; padding: 0 5px; }
.pp-etape-count.ok { background: var(--success); }
.pp-etape-count.manque { background: var(--danger); }
@media (max-width: 820px) {
  /* Sur un téléphone, une case fait ~45 px : le NOM n'y tiendrait pas, il se tait.
     Le POURVU/ATTENDU, lui, reste — c'est l'information qu'on vient chercher, et
     « 1/3 » tient en vingt pixels. Le masquer revenait à priver le mobile du seul
     chiffre qui dit s'il manque quelqu'un. */
  .pp-etape-bar { min-height: 13px; height: auto; padding: 0 2px; gap: 0;
    justify-content: flex-end; }
  .pp-etape-nom { font-size: 0; flex: 1 1 0; }
  .pp-etape-count { font-size: 8.5px; padding: 0 4px; line-height: 1.5; }
}
.pp-marks { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.pp-note-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--warning); display: inline-block; }
.pp-count { font-size: 11px; background: var(--accent); color: var(--accent-contrast); border-radius: 20px; padding: 1px 7px; }

/* Vue mois façon agenda : cases de fond + barres continues */
.cal-week { position: relative; margin-bottom: 6px; }
.cal-week-bg { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(7, 1fr); gap: 0 6px; }
.cal-bgcell { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.cal-bgcell.out { background: var(--surface-2); opacity: 0.6; }
.cal-bgcell.today { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.cal-week-lanes {
  position: relative; display: grid; grid-template-columns: repeat(7, 1fr);
  grid-auto-rows: 21px; gap: 7px 6px; padding: 5px 0; min-height: 116px; align-content: start;
}
/* Le numéro du jour partage sa ligne avec les déplacements : le numéro à gauche,
   l'avion et sa ville à droite, sur une case bien plus large que dans les grilles
   de production — la ville y tient en entier. */
.cal-num { font-size: 12px; font-weight: 600; color: var(--text-muted); padding: 0 8px;
  align-self: center; display: flex; align-items: center; gap: 6px; }
/* `order` : la croix d'indisponibilité (.cal-num::after) est le dernier enfant de
   la case ; sans cela elle se retrouvait APRÈS la ville, loin du numéro qu'elle
   qualifie. Les déplacements passent derrière elle et restent calés à droite. */
.cal-travels { display: flex; align-items: center; gap: 6px; margin-left: auto;
  min-width: 0; order: 9; }
.cal-travels .pg-travel { position: static; display: flex; align-items: center;
  gap: 2px; min-width: 0; font-size: 11px; }
.cal-travels .pg-travel-retour { flex-direction: row-reverse; }
.cal-travels .pg-travel-ville { font-size: 10px; font-weight: 700; }
.cal-num.out { opacity: 0.5; }
.cal-num.today { color: var(--accent); }
.cal-ev {
  align-self: stretch; border-radius: 4px; margin: 0 2px; z-index: 1;
  overflow: hidden; opacity: 0.72;   /* légère transparence : projets moins agressifs (réversible) */
}
.cal-ev:hover { filter: brightness(1.08); opacity: 1; }
/* Calque texte : TOUJOURS au-dessus (projet + étapes). Laisse passer les clics. */
.cal-ev-label {
  align-self: stretch; display: flex; align-items: center; gap: 4px;
  font-size: 11px; color: #fff; padding: 0 8px; font-weight: 500;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  text-shadow: 0 0 3px rgba(0,0,0,.85), 0 1px 2px rgba(0,0,0,.7); margin: 0 2px;
  z-index: 4; pointer-events: none;
}
.cal-ev-label .cal-ev-nom { overflow: hidden; text-overflow: ellipsis; }
.cal-ev-perso {
  align-self: center; display: flex; align-items: center; gap: 5px;
  font-size: 11px; color: var(--text-muted); padding: 0 8px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* Étapes : fine bande de couleur au BAS de la barre du projet (même ligne). */
.cal-ev-etape {
  align-self: end; height: 5px; margin: 0 2px 2px; border-radius: 3px;
  z-index: 2; box-shadow: 0 0 0 1px rgba(255,255,255,.35);
}
/* Étoile 1er show / horloge deadline POSÉE SUR la barre du projet, au jour concerné. */
.cal-ev-star {
  align-self: stretch; display: flex; align-items: center; justify-content: flex-end;
  padding-right: 4px; font-size: 14px; line-height: 1; z-index: 5; pointer-events: none;
  color: #ffd54a; text-shadow: 0 0 2px rgba(0,0,0,.9), 0 1px 2px rgba(0,0,0,.7);
}
.cal-ev-star.is-deadline { color: #fff; }
/* Adresses email cliquables → compositeur de mail. */
[data-email] { cursor: pointer; color: var(--accent); text-decoration: none; }
[data-email]:hover { text-decoration: underline; }
.mail-modal { position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,.45);
  display: flex; align-items: center; justify-content: center; padding: 20px; }
.mail-modal[hidden] { display: none; }
.mail-box { background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  width: 100%; max-width: 520px; padding: 18px 20px; box-shadow: 0 20px 60px rgba(0,0,0,.4); }
.mail-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; font-size: 16px; }
.mail-x { border: 0; background: transparent; font-size: 22px; line-height: 1; cursor: pointer; color: var(--text-muted); }
.mail-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; font-size: 12px; color: var(--text-muted); }
.mail-field input, .mail-field textarea, .mail-field select { font-size: 14px; color: var(--text); }
.mail-field textarea { resize: vertical; }
.mail-noreply { display: flex; align-items: center; gap: 6px; font-size: 13px; margin-bottom: 12px; }
.mail-noreply input { width: auto; }
.mail-actions { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
.mail-actions .person-meta { margin-right: auto; }
/* Résumé des missions (fenêtre ouverte au clic sur le nombre de jours). */
.resume-open { background: none; border: 0; color: var(--accent); font-weight: 700; cursor: pointer;
  font-size: inherit; padding: 0; font-family: inherit; }
.resume-open:hover { text-decoration: underline; }
.resume-list { max-height: 55vh; overflow-y: auto; }
.resume-item { padding: 8px 0; border-bottom: 1px solid var(--border); }
.resume-item:last-child { border-bottom: 0; }
.resume-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.resume-proj { font-weight: 600; text-decoration: none; color: var(--text); }
.resume-proj:hover { color: var(--accent); }
.resume-jours { font-weight: 700; color: var(--accent); white-space: nowrap; }

/* Étoile « 1er show » / horloge « deadline » dans les agendas — bien visibles. */
.show-star { color: #f59e0b; font-size: 18px; margin-left: 3px; vertical-align: middle; line-height: 1; text-shadow: 0 0 1px rgba(0,0,0,.3); }
.show-star-lg { font-size: 24px; margin-left: 0; margin-right: 4px; }
.show-star.is-deadline { color: #dc2626; text-shadow: none; }
.show-line { display: flex; align-items: center; font-weight: 600; color: var(--text); }

/* Étiquette du type de date clé dans le formulaire projet. */
.jalon-tag { display: inline-block; font-size: 11px; font-weight: 700; padding: 1px 8px; border-radius: 999px;
  background: color-mix(in srgb, #f59e0b 18%, transparent); color: #b45309; margin-left: 4px; }
.jalon-tag.is-deadline { background: color-mix(in srgb, #dc2626 16%, transparent); color: #b91c1c; }

/* Vignette projet entièrement cliquable : lien de recouvrement + pôles au-dessus. */
.projet-card .card-cover { position: absolute; inset: 0; z-index: 0; border-radius: inherit; }
.projet-card:hover { border-color: var(--accent); }
.projet-card .gauge-ring, .projet-card h3, .projet-card .person-meta, .projet-card .statut-projet { position: relative; z-index: 1; pointer-events: none; }
.projet-card .mini-gauges { position: relative; z-index: 1; pointer-events: none; }
.projet-card .mini-gauge { pointer-events: auto; }  /* seuls les pôles sont cliquables (→ leur page) */
/* Calendrier page info : édition du planning activable à la demande. */
#detail-cal .pp-cell { cursor: default; }
#detail-cal.cal-edit .pp-cell { cursor: pointer; }
#detail-cal.cal-edit .pp-cell:hover { outline: 2px dashed var(--accent); outline-offset: -2px; }
.cal-ev-etape { cursor: pointer; text-decoration: none; }
.cal-ev-etape:hover { height: 9px; }

/* Étape ciblée depuis le calendrier : surbrillance brève. */
.etape-focus { animation: etape-focus-pulse 2.4s ease-out; }
@keyframes etape-focus-pulse {
  0%   { box-shadow: 0 0 0 3px var(--accent); }
  60%  { box-shadow: 0 0 0 3px var(--accent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Popover au survol de la pastille personnel (noms + postes à pourvoir en rouge). */
#pc-tip {
  position: fixed; z-index: 9999; display: none; pointer-events: none;
  background: var(--surface, #1b1b1b); color: var(--text, #fff);
  border: 1px solid var(--border, #333); border-radius: 8px; padding: 8px 11px;
  font-size: 12px; line-height: 1.55; max-width: 280px;
  box-shadow: 0 10px 28px rgba(0,0,0,.45);
}
#pc-tip .pc-t {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  opacity: .6; margin-bottom: 3px;
}
#pc-tip .pc-t.pc-sep { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border, #333); }
#pc-tip .pc-nom { color: var(--text, #fff); }
#pc-tip .pc-manque { color: #ff5a5a; font-weight: 600; }

/* Vue année : 12 mois plus grands, cases carrées + lignes de projet */
.ya-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
.ya-month { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; }
.ya-title { display: block; font-weight: 800; font-family: var(--font-head); margin-bottom: 10px; font-size: 17px; }
.ya-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 4px; }
.ya-dow { margin-bottom: 6px; }
.ya-dow span { text-align: center; font-size: 10px; color: var(--text-muted); }
.ya-cell {
  position: relative; aspect-ratio: 1 / 1; border: 1px solid var(--border); border-radius: 5px;
  background: var(--surface); display: flex; flex-direction: column; padding: 3px 4px 4px;
  color: var(--text-muted); text-decoration: none; overflow: hidden;
}
a.ya-cell:hover { border-color: var(--accent); }
.ya-cell.empty { border: none; background: transparent; }
.ya-cell.today { outline: 2px solid var(--accent); outline-offset: -2px; }
.ya-num { font-size: 11px; line-height: 1; }
.ya-bars { margin-top: auto; display: flex; flex-direction: column; gap: 2px; }
.ya-bar { height: 3px; width: 100%; border-radius: 2px; }

/* ---------- Planning hebdomadaire ---------- */
.planning-table { min-width: 760px; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.planning-table th, .planning-table td { border: 1px solid var(--border); padding: 6px 8px; text-align: center; vertical-align: middle; }
.planning-table thead th { background: var(--surface-2); font-size: 11.5px; color: var(--text-muted); text-transform: none; letter-spacing: 0; padding: 8px; }
.planning-table .daynum { font-weight: 400; color: var(--text-muted); font-size: 11px; }
.planning-table .col-perso { text-align: left; min-width: 190px; background: var(--surface); font-size: 13.5px; }
.planning-table thead .col-perso { color: var(--text-muted); }
.planning-table .col-today { background: rgba(214,69,0,0.10); color: var(--accent); font-weight: 600; }
.planning-table .col-weekend { background: var(--surface-2); }
.planning-table .pcell { padding: 0; }
.planning-table .pcell form { margin: 0; }
.planning-table .pcell select {
  width: 100%; border: none; background: transparent; padding: 12px 6px;
  font-size: 12.5px; color: var(--text); cursor: pointer; text-align: center;
}
.planning-table .pcell select:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.planning-table .pcell-label { display: block; padding: 12px 6px; font-size: 12.5px; }

/* ---------- Connexion ---------- */
.login-wrap { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px; }
.login-box { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 34px; box-shadow: var(--shadow); }
.login-brand { display: flex; align-items: center; gap: 11px; margin-bottom: 6px; }
.login-box h1 { font-size: 18px; margin: 0; font-family: var(--font-head); }
.login-box .subtitle { color: var(--text-muted); font-size: 13px; margin: 4px 0 24px; }

/* ============================================================
   Console super administrateur (vue clients + modules)
   ============================================================ */
.console-stats { display: flex; gap: 22px; margin: 4px 0 20px; color: var(--text-muted); font-size: 13px; }
.console-stats b { color: var(--text); font-size: 17px; font-family: var(--font-head); margin-right: 5px; }

.client-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.client-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 12px; }
.client-card.inactif { opacity: 0.6; }
.client-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.client-head h3 { margin: 0; font-size: 16px; font-family: var(--font-head); }
.client-owner { font-size: 13px; color: var(--text-muted); }
.client-owner a { color: var(--accent); }
.client-metrics { display: flex; gap: 18px; font-size: 12.5px; color: var(--text-muted); }
.client-metrics b { color: var(--text); font-family: var(--font-head); }
.client-modules { display: flex; flex-wrap: wrap; gap: 6px; }
.client-modules .mod-label { width: 100%; font-size: 11px; text-transform: uppercase;
  letter-spacing: var(--label-spacing); color: var(--text-muted); margin-bottom: 2px; }

/* Pastille-module cliquable (ON = activé, OFF = désactivé). Tout au clic. */
.mod-toggle { border: 1px solid var(--border); background: var(--surface-2); color: var(--text-muted);
  font-size: 11.5px; padding: 4px 10px; border-radius: 20px; cursor: pointer; display: inline-flex;
  align-items: center; gap: 5px; font-family: inherit; transition: all .12s ease; }
.mod-toggle:hover { border-color: var(--accent); color: var(--text); }
.mod-toggle.on { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }
.mod-toggle.on::before { content: "✓"; font-weight: 700; }
.mod-toggle.off::before { content: "＋"; }
.mod-toggle.bientot { border-style: dashed; cursor: pointer; }

/* ============================================================
   RESPONSIVE / MOBILE — valable pour tous les rôles de compte.
   Stratégie : barre latérale → tiroir coulissant sous 820px,
   barre supérieure avec menu hamburger, tableaux défilables,
   en-têtes et grilles empilés. (Réglages fins à venir.)
   ============================================================ */

/* Barre supérieure et overlay : masqués en desktop, révélés en mobile. */
.topbar { display: none; }
.nav-overlay { display: none; }

/* Repli réutilisable « .m-fold » : sur DESKTOP toujours déplié (résumé masqué) ;
   sur mobile/paysage, accordéon tactile (voir @media). Sert à masquer les blocs
   encombrants (filtres, recherche) tant qu'on ne les active pas. */
.m-fold > summary { display: none; }
.m-fold:not([open]) > .m-fold-body { display: block; }
/* Un <details> FERMÉ garde une hauteur de 0 même si on réaffiche son contenu par CSS :
   le contenu sortait du flux et se retrouvait recouvert par le bloc suivant (filtres et
   case « Bandeau projets » invisibles en bureau). On ouvre donc VRAIMENT le details en
   bureau, via JS (cf. base.html) : la mise en page native reprend, sans bidouille. */
/* .hide-mobile : visible en desktop, masqué sur mobile/paysage (voir @media). */

/* Cible mobile : petit écran OU téléphone en PAYSAGE (hauteur réduite) — ainsi le
   style mobile (tiroir latéral, colonnes élargies…) reste actif en paysage. */
@media (max-width: 820px), (max-height: 480px) and (orientation: landscape) {
  /* --- Barre supérieure fixe (hamburger + marque) --- */
  .topbar {
    display: flex; align-items: center; gap: 12px;
    position: fixed; top: 0; left: 0; right: 0; min-height: 54px; z-index: 90;
    padding: 6px 14px; background: var(--surface); border-bottom: 1px solid var(--border);
  }
  /* LA MARQUE ET L'ÉTAT DE SYNCHRO, L'UN SOUS L'AUTRE. La hauteur de la barre suit
     son contenu (min-height plutôt que height) : sans agenda connecté, la seconde
     ligne n'existe pas et la barre garde ses 54 px. */
  .topbar-titres { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
  .topbar-maj {
    font-size: 11px; color: var(--text-muted, #64748b); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; padding-left: 37px; margin-top: 1px;
  }
  .nav-toggle {
    width: 40px; height: 40px; flex: none; display: grid; place-items: center;
    background: transparent; border: 1px solid var(--border); border-radius: var(--radius);
    color: var(--text); cursor: pointer; padding: 0;
  }
  .topbar-brand { display: flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 700; font-family: var(--font-head); }
  .topbar-brand .mark {
    width: 28px; height: 28px; flex: none; display: grid; place-items: center;
    background: var(--accent); color: var(--accent-contrast); border-radius: var(--radius);
    font-weight: 800; font-size: 13px;
  }

  /* --- Barre latérale en tiroir coulissant hors écran --- */
  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 100;
    width: 82vw; max-width: 300px; flex-basis: auto;
    transform: translateX(-100%); transition: transform .22s ease;
    box-shadow: 2px 0 16px rgba(0,0,0,.18); overflow-y: auto;
  }
  html[data-nav="open"] .sidebar { transform: translateX(0); }

  /* Voile sombre derrière le tiroir ouvert. */
  html[data-nav="open"] .nav-overlay {
    display: block; position: fixed; inset: 0; z-index: 80;
    background: rgba(0,0,0,.45);
  }

  /* --- Contenu principal : pleine largeur, dégagé sous la barre --- */
  .layout { display: block; }
  .main {
    padding: 18px 16px; max-width: none !important; margin: 0 !important;
    /* La barre peut faire deux lignes (marque + synchro) : on réserve la hauteur
       réelle, mesurée au chargement, plutôt qu'un nombre fixe qui deviendrait faux
       le jour où l'on ajoute une ligne. */
    padding-top: calc(var(--topbar-h, 54px) + 18px);
  }
  /* Les réglages de largeur/position desktop n'ont plus d'effet en mobile. */
  html[data-width] .main, html[data-align] .main { max-width: none !important; }

  /* --- En-têtes de page : titre à GAUCHE, boutons (Retour, Nouvelle fiche…) en
         HAUT À DROITE, compacts (plus empilés en pleine largeur). --- */
  .head-row { flex-direction: row; flex-wrap: wrap; align-items: flex-start;
    justify-content: space-between; gap: 8px 10px; }
  .head-row > :first-child { flex: 1 1 52%; min-width: 0; }
  .head-row .btn { width: auto; justify-content: center; }
  .page-title { font-size: 20px; }
  .page-subtitle { margin-bottom: 18px; }

  /* Utilitaire : masquer un élément sur mobile/paysage (ex. Exporter du calendrier). */
  .hide-mobile { display: none !important; }

  /* Accordéon .m-fold : le résumé devient un bouton cliquable, corps replié par défaut. */
  .m-fold > summary { display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
    list-style: none; font-weight: 600; font-size: 14px; color: var(--text);
    padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px;
    background: var(--surface); margin: 4px 0 10px; }
  .m-fold > summary::-webkit-details-marker { display: none; }
  .m-fold > summary::after { content: "▾"; margin-left: 2px; color: var(--text-muted); font-size: 12px; }
  .m-fold[open] > summary::after { content: "▴"; }
  .m-fold:not([open]) > .m-fold-body { display: none; }

  /* --- Tableaux : défilables horizontalement au doigt --- */
  table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
  th, td { padding: 9px 11px; }
  /* Tableaux-grille du planning : DÉJÀ dans un conteneur .overflow-x → garder un vrai
     layout table, sinon display:block écrase les colonnes à 0 (noms/cases/bulles empilés). */
  .pg-table, .planning-table { display: table; overflow: visible; }
  .pg-table .pg-cell, .pg-table .pg-day, .planning-table .pcell, .planning-table thead th:not(.col-perso) { padding: 2px; }

  /* --- Grilles : une seule colonne --- */
  .grid, .client-grid, .check-grid, .tarif-grid, .fiche-2col { grid-template-columns: 1fr; }
  /* Picker de personnes (besoin d'étape) : liste verticale lisible plutôt que des
     pastilles étirées qui débordent et cassent les noms sur plusieurs lignes. */
  .etape-people { flex-direction: column; align-items: stretch; max-height: 260px; overflow-x: hidden; }
  .etape-people .chk-person { width: 100%; justify-content: flex-start; white-space: normal; border-radius: 8px; }
  .etape-people .chk-person > input { flex: 0 0 auto; }
  .console-stats { flex-wrap: wrap; gap: 10px 18px; }

  /* --- Dashboard mobile : tuiles carrées (onglets) à la place de la liste projets --- */
  .home-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 10px; }
  .dash-desktop { display: none; }

  /* --- Fiche personnel : le CALENDRIER prend la vedette, pleine largeur et EN PREMIER.
         La photo/contact/compétences passent dans un repli « à la demande ». --- */
  /* `1fr` vaut `minmax(auto, 1fr)` : la colonne ne peut pas descendre sous la
     largeur minimale de son contenu, et la fiche débordait donc de l'écran.
     `minmax(0, 1fr)` l'autorise à se réduire ; `min-width: 0` fait de même pour
     les colonnes elles-mêmes. */
  .detail-cols { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .detail-cols > * { min-width: 0; }
  .detail-cols > div:last-child { order: -1; }   /* la colonne calendrier remonte en tête */

  /* Le repli devient un vrai accordéon tactile (fermé par défaut = à la demande). */
  .fiche-fold { margin-top: 14px; }
  .fiche-fold > summary {
    display: flex; align-items: center; gap: 8px; cursor: pointer; list-style: none;
    font-weight: 600; font-size: 14px; color: var(--text);
    padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px;
    background: var(--surface);
  }
  .fiche-fold > summary::-webkit-details-marker { display: none; }
  .fiche-fold > summary::before { content: "👤"; }
  .fiche-fold > summary::after { content: "▾ Afficher"; margin-left: auto; font-size: 12px; color: var(--text-muted); font-weight: 400; }
  .fiche-fold[open] > summary::after { content: "▴ Masquer"; }
  .fiche-fold[open] > summary { margin-bottom: 12px; border-radius: 12px 12px 0 0; }
  .fiche-fold:not([open]) > .ff-body { display: none; }
  /* Photo pas trop haute une fois dépliée sur petit écran. */
  .detail-cols .avatar-lg { max-width: 220px; margin: 0 auto; }

  /* Nav de mois d'un calendrier : reste en ligne (flèches compactes), pas 3 boutons empilés. */
  .head-row.cal-month-head { flex-direction: row; align-items: center; }
  .cal-nav-arrows { display: flex !important; width: auto; gap: 8px; }
  .cal-nav-arrows .btn { width: auto; padding: 8px 14px; }

  /* Calendrier de la fiche : cases un peu plus basses, texte resserré. */
  #fiche-cal .fiche-cal-cell { min-height: 58px; padding: 4px; }
  #fiche-cal .pl-span { font-size: 9px; padding: 0 4px; }

  /* --- Planning global : colonnes de jours ÉLARGIES pour que les noms de projets
         soient lisibles. Le défilement horizontal est assumé (on slide) ; la colonne
         « Personne » reste gelée à gauche (sticky, inchangée). --- */
  .pg-table td.pg-cell, .pg-table thead th.pg-day { min-width: 46px; }
  .pg-table .pg-bar { font-size: 10.5px; }
  .pg-table .pg-band-line { font-size: 8.5px; }

  /* --- Menus déroulants de filtre : bornés à l'écran, jamais coupés à droite
         (sinon on a l'impression que « ça dépasse »). --- */
  .filter-dd .filter-panel { position: fixed; left: 12px; right: 12px; top: auto;
    width: auto; min-width: 0; max-width: none; max-height: 60vh; }

  /* --- Vue double : sans objet sur mobile (écran trop étroit pour deux panneaux) --- */
  #split-toggle { display: none !important; }

  /* --- Barres segmentées défilables plutôt que débordantes --- */
  .seg-views { display: flex; overflow-x: auto; max-width: 100%; }
  .seg-views a, .seg-views button { white-space: nowrap; }

  /* --- Lignes de mission (vue-jour, planning perso, booking à confirmer…) : on empile
         infos / contrôles au lieu de laisser la rangée déborder à droite. --- */
  .mission-row { flex-direction: column; align-items: stretch; }
  .mission-row > * { min-width: 0; max-width: 100%; }
  .mission-row form, .mission-row > div { flex-wrap: wrap; }

  /* --- Grilles de formulaire à plusieurs colonnes posées en STYLE INLINE (add mission,
         add étape, périodes…) → 1 colonne. Le stylesheet !important bat le style inline
         sans !important. Les grilles à classe nommée sont gérées plus haut. --- */
  .main form [style*="grid-template-columns"] { grid-template-columns: 1fr !important; }

  /* --- Formulaires « inline » (+ Besoin, + Tâche…) : enroulement plutôt que débordement. --- */
  .inline-add { flex-wrap: wrap; }
  .inline-add > select { flex: 1 1 100%; }
}

/* Très petits écrans : on resserre encore. */
@media (max-width: 420px) {
  /* L'indicateur en ligne double celui de la barre : sur mobile on ne garde que le
     BOUTON de rafraîchissement, dont on a toujours besoin. */
  .ind-refresh .person-meta { display: none; }
  .main { padding-left: 12px; padding-right: 12px; }
  .card { padding: 15px; }
  .page-title { font-size: 18px; }
}

/* === Messagerie : pastille d'adresse copiable + badge non-lus === */
.adresse-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 10px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface-2);
  cursor: pointer; font-size: 13px; max-width: 100%;
  transition: border-color .12s, background .12s;
}
.adresse-pill:hover { border-color: var(--accent); }
.adresse-pill .ap-mono {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.adresse-pill .copy-label {
  font-size: 11px; color: var(--text-muted); text-transform: uppercase;
  letter-spacing: .04em; flex: none;
}
.badge-unread {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px;
  background: var(--accent); color: var(--accent-contrast);
  font-size: 12px; font-weight: 700;
}

/* === Mode démo LOCAL : barre de bascule de compte (DEBUG only) === */
.demo-switcher { position: fixed; left: 14px; bottom: 14px; z-index: 900; font-size: 13px; }
.demo-handle {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px; border-radius: 20px; cursor: pointer;
  background: #7c3aed; color: #fff; border: none; font-weight: 700;
  box-shadow: 0 4px 14px rgba(0,0,0,.25);
}
.demo-handle.active { background: #6d28d9; }
.demo-panel {
  position: absolute; left: 0; bottom: 46px; width: 320px; max-width: 78vw;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 34px rgba(0,0,0,.30); padding: 12px; max-height: 70vh; overflow: auto;
}
.demo-panel-head { margin-bottom: 8px; display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.demo-close { flex: none; border: none; background: var(--surface-2); color: var(--text-muted); width: 26px; height: 26px; border-radius: 50%; font-size: 18px; line-height: 1; cursor: pointer; }
.demo-close:hover { background: #7c3aed; color: #fff; }
.demo-panel-head strong { display: block; font-size: 13.5px; }
.demo-panel-head span { color: var(--text-muted); font-size: 12px; }
.demo-accts { display: flex; flex-direction: column; gap: 6px; }
.demo-acc {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-2); text-decoration: none; color: var(--text);
  transition: border-color .12s, transform .06s;
}
.demo-acc:hover { border-color: #7c3aed; transform: translateX(2px); }
.demo-acc.is-current { border-color: #7c3aed; box-shadow: inset 0 0 0 1px #7c3aed; }
.demo-acc .demo-name { flex: 1; min-width: 0; font-size: 12.5px; }
.demo-acc .demo-cur { color: #7c3aed; font-weight: 700; font-size: 11.5px; }
.demo-foot { margin: 10px 0 0; color: var(--text-muted); font-size: 11px; }

/* ===================================================================
   Messagerie — interface mail visuelle, mobile-first
   Boîtes → Boîte de réception → Fil. Tout au clic, lignes tactiles.
=================================================================== */
.mail-head { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; flex-wrap:wrap; }
.mail-head.with-av { align-items:center; }
.mail-total-unread { background:var(--accent); color:var(--accent-contrast); font-weight:700; font-size:12.5px; padding:5px 11px; border-radius:20px; white-space:nowrap; }

.mail-search { position:relative; margin:14px 0 6px; }
.mail-search svg { position:absolute; left:13px; top:50%; transform:translateY(-50%); width:18px; height:18px; fill:none; stroke:var(--text-muted); stroke-width:2; stroke-linecap:round; pointer-events:none; }
.mail-search input { width:100%; padding:12px 14px 12px 42px; border:1px solid var(--border); border-radius:12px; background:var(--surface); color:var(--text); font-size:15px; }
.mail-search input:focus { outline:none; border-color:var(--accent); }

.mbx-section { margin-top:22px; }
.mbx-h { font-size:12.5px; text-transform:uppercase; letter-spacing:.05em; color:var(--text-muted); margin:0 0 11px; display:flex; align-items:center; gap:8px; }
/* Chat : chaque projet = carte type « Mes projets », nom en noir forcé (fix Safari iOS) */
.chat-projet.card { margin-bottom:12px; }
.chat-projet-nom { font-size:16px; text-transform:none; letter-spacing:0; font-weight:700; color:#1a1d21 !important; -webkit-text-fill-color:#1a1d21 !important; transform: translateZ(0); }
.mbx-h-count { background:var(--surface-2); border:1px solid var(--border); border-radius:10px; padding:0 8px; font-size:12px; }

.mbx-grid { display:grid; grid-template-columns:1fr; gap:10px; }
.mbx { display:flex; align-items:center; gap:13px; padding:13px 14px; border:1px solid var(--border); border-radius:14px; background:var(--surface); text-decoration:none; color:var(--text); min-height:66px; min-width:0; overflow:hidden; transition:border-color .12s, transform .06s, box-shadow .12s; }
.mbx:hover { border-color:var(--accent); box-shadow:0 3px 12px rgba(0,0,0,.08); }
.mbx:active { transform:scale(.99); }
.mbx-av { flex:none; width:46px; height:46px; border-radius:12px; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:16px; color:#fff; }
.mbx-av.big { width:56px; height:56px; border-radius:14px; font-size:19px; }
.mbx-av-client { background:linear-gradient(135deg,#3b82f6,#2563eb); }
.mbx-av-projet { background:linear-gradient(135deg,#14b8a6,#0d9488); }
.mbx-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.mbx-name { font-weight:700; font-size:15.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mbx-addr { font-family:ui-monospace,Consolas,monospace; font-size:12px; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mbx-sub { font-size:12.5px; color:var(--text-muted); }
.mbx-side { flex:none; display:flex; align-items:center; gap:9px; }
.mbx-badge { background:var(--accent); color:var(--accent-contrast); font-weight:700; font-size:12px; min-width:22px; height:22px; border-radius:11px; display:flex; align-items:center; justify-content:center; padding:0 6px; }
.mbx-chev { color:var(--text-muted); font-size:24px; line-height:1; }

.mail-topbar { margin-bottom:10px; }
.mail-back { display:inline-flex; align-items:center; gap:4px; text-decoration:none; color:var(--accent); font-weight:600; font-size:14.5px; padding:6px 2px; }
.mail-addr { font-family:ui-monospace,Consolas,monospace; font-size:12.5px; }
.copy-mini { border:1px solid var(--border); background:var(--surface-2); color:var(--text-muted); border-radius:8px; font-size:11px; padding:2px 8px; cursor:pointer; margin-left:6px; }
.copy-mini:hover { border-color:var(--accent); color:var(--accent); }

.inbox { display:flex; flex-direction:column; margin-top:16px; border:1px solid var(--border); border-radius:14px; overflow:hidden; }
.inbox-row { display:flex; align-items:center; gap:12px; padding:13px 14px; text-decoration:none; color:var(--text); border-bottom:1px solid var(--border); min-height:66px; background:var(--surface); transition:background .1s; }
.inbox-row:last-child { border-bottom:none; }
.inbox-row:hover { background:var(--surface-2); }
.inbox-av { flex:none; width:42px; height:42px; border-radius:50%; background:linear-gradient(135deg,#64748b,#334155); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:16px; }
.inbox-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.inbox-top { display:flex; justify-content:space-between; gap:8px; align-items:baseline; }
.inbox-from { font-weight:600; font-size:14.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.inbox-date { flex:none; font-size:12px; color:var(--text-muted); }
.inbox-subj { font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.inbox-snippet { font-size:13px; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.inbox-row.unread { background:var(--surface-2); background:linear-gradient(90deg, color-mix(in srgb, var(--accent) 8%, transparent), transparent); }
.inbox-row.unread .inbox-from, .inbox-row.unread .inbox-subj { font-weight:800; }
.inbox-dot { flex:none; width:10px; height:10px; border-radius:50%; background:var(--accent); }

.thread-head { margin-bottom:8px; }
.thread { display:flex; flex-direction:column; gap:12px; margin-top:8px; }
.bubble { max-width:88%; padding:11px 14px; border-radius:16px; border:1px solid var(--border); }
.bubble-entrant { align-self:flex-start; background:var(--surface); border-bottom-left-radius:5px; }
.bubble-sortant { align-self:flex-end; background:var(--surface-2); background:color-mix(in srgb, var(--accent) 12%, var(--surface)); border-bottom-right-radius:5px; }
.bubble-meta { display:flex; justify-content:space-between; gap:12px; font-size:12px; color:var(--text-muted); margin-bottom:5px; }
.bubble-body { white-space:pre-wrap; font-size:14.5px; line-height:1.5; overflow-wrap:break-word; word-break:break-word; }

.thread-reply { margin-top:18px; }
.thread-reply-box { border:1px dashed var(--border); border-radius:12px; padding:15px; text-align:center; font-size:13.5px; }

.mail-empty { text-align:center; padding:40px 20px; color:var(--text-muted); }
.mail-empty-ico { font-size:40px; opacity:.5; margin-bottom:8px; }

@media (min-width:720px) {
  .mbx-grid { grid-template-columns:repeat(2,1fr); }
}
@media (min-width:1100px) {
  .mbx-grid { grid-template-columns:repeat(3,1fr); }
  .bubble { max-width:70%; }
}

/* Pièces jointes dans un message */
.bubble-pj { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.pj-chip { display:inline-flex; align-items:center; gap:4px; font-size:12.5px; padding:4px 9px; border:1px solid var(--border); border-radius:14px; background:var(--surface); color:var(--text); text-decoration:none; }
.pj-chip:hover { border-color:var(--accent); }
.pj-pending { color:var(--text-muted); border-style:dashed; }

/* Formulaires d'envoi (réponse + nouveau message) */
.thread-reply { margin-top:18px; }
.reply-form, .compose-form { display:flex; flex-direction:column; gap:10px; border:1px solid var(--border); border-radius:14px; padding:14px; background:var(--surface); }
.reply-form textarea, .compose-form textarea, .compose-form input { width:100%; border:1px solid var(--border); border-radius:10px; padding:10px 12px; background:var(--surface); color:var(--text); font-size:14.5px; font-family:inherit; }
.reply-form textarea:focus, .compose-form textarea:focus, .compose-form input:focus { outline:none; border-color:var(--accent); }
.reply-actions { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.compose { margin-top:16px; }
.compose-field { display:flex; flex-direction:column; gap:4px; font-size:12.5px; color:var(--text-muted); }
#compose-toggle.active { background:var(--surface-2); color:var(--text); border:1px solid var(--border); }

/* ===================================================================
   Chat interne 1-à-1 (messagerie instantanée entre comptes de l'espace)
=================================================================== */
/* Pastille de non-lus dans le menu latéral. */
.nav-badge { margin-left:auto; background:var(--accent); color:var(--accent-contrast);
  font-size:11px; font-weight:700; min-width:18px; height:18px; border-radius:9px;
  padding:0 6px; display:inline-flex; align-items:center; justify-content:center; }

/* En-tête d'un fil : avatar + nom de l'interlocuteur. */
.chat-head { display:flex; align-items:center; gap:14px; margin-bottom:8px; }
.chat-head .inbox-av { width:48px; height:48px; font-size:18px; }

/* Fil de discussion : bulles empilées, place réservée en bas pour la saisie. */
.chat-thread { padding-bottom:12px; }
.chat-thread .bubble { max-width:82%; }
.chat-time { font-size:11px; color:var(--text-muted); margin-top:4px; text-align:right; }
.bubble-entrant .chat-time { text-align:left; }

/* Barre de saisie collée en bas (feel messagerie instantanée). */
.chat-composer { position:sticky; bottom:0; z-index:20; display:flex; align-items:flex-end; gap:10px;
  padding:12px 0; margin-top:10px; background:linear-gradient(to top, var(--bg) 78%, transparent); }
.chat-composer textarea { flex:1; resize:none; min-height:44px; max-height:120px; padding:11px 14px;
  border:1px solid var(--border); border-radius:22px; background:var(--surface); color:var(--text);
  font-size:15px; font-family:inherit; line-height:1.35; }
.chat-composer textarea:focus { outline:none; border-color:var(--accent); }
.chat-send { flex:none; width:44px; height:44px; padding:0; justify-content:center; border-radius:50%; font-size:17px; }

@media (min-width:1100px) { .chat-thread .bubble { max-width:64%; } }

/* Objet du fil = le projet (toujours affiché, cloisonnement). */
.chat-objet { display:flex; align-items:center; gap:6px; margin:6px 0 2px; padding:7px 12px;
  font-size:13px; color:var(--text-muted); background:var(--surface-2);
  border:1px solid var(--border); border-radius:10px; }
.chat-objet strong { color:var(--text); }

/* Dépliant « Nouveau contact » du projet. */
.chat-newcontacts { margin-top:8px; }
.chat-newcontacts > summary { cursor:pointer; list-style:none; font-size:13.5px; font-weight:600;
  color:var(--accent); padding:8px 4px; display:inline-flex; align-items:center; gap:8px; }
.chat-newcontacts > summary::-webkit-details-marker { display:none; }

/* Interrupteur on/off (préférences de notification, etc.). */
.switch { position:relative; display:inline-block; width:44px; height:24px; flex:none; }
.switch input { opacity:0; width:0; height:0; position:absolute; }
.switch .slider { position:absolute; inset:0; cursor:pointer; background-color:var(--border);
  border-radius:24px; transition:background-color .15s; }
.switch .slider::before { content:""; position:absolute; height:18px; width:18px; left:3px; top:3px;
  background-color:#fff; border-radius:50%; transition:transform .15s; box-shadow:0 1px 2px rgba(0,0,0,.25); }
.switch input:checked + .slider { background-color:var(--accent); }
.switch input:checked + .slider::before { transform:translateX(20px); }
.switch input:focus-visible + .slider { outline:2px solid var(--accent); outline-offset:2px; }

/* ============================================================
   Carrousel de calendrier : les mois côte à côte, glissé au doigt
   (façon Google Agenda). Le doigt fait suivre le panneau, snap animé.
   ============================================================ */
.cal-carousel { overflow: hidden; touch-action: pan-y; }
.cal-track { display: flex; align-items: flex-start; will-change: transform; }
.cal-panel { flex: 0 0 100%; width: 100%; min-width: 100%; }

/* ---- Check-list : échéances de tâches ---------------------------------- */
/* Le bloc de check-list ne prend PAS toute la largeur : une liste de tâches
   étalée sur 1400 px est illisible. */
/* LA CHECK-LIST PREND TOUTE LA LARGEUR DE LA PAGE. Bornée à 720 puis à 1100 px,
   il n'y avait plus de place pour le nom une fois posées l'échéance, les trois
   boutons d'ouverture, les trois bulles et l'état : le nom se faisait couper, et
   les bulles débordaient du cadre. Une check-list se lit en largeur — c'est un
   tableau, pas un paragraphe. */
.tache-card { max-width: none; }
/* UNE GRILLE À COLONNES FIXES. Chaque chose a sa colonne, et chaque colonne garde
   sa largeur qu'elle soit pleine ou vide : sans quoi la place des boutons dépendait
   de la longueur du nom, de la présence d'une date ou d'un document — deux tâches
   voisines ne se lisant alors plus sur la même grille. Seul le nom s'étire et se
   tronque : c'est le seul élément dont on devine la suite. */
.tache { display: grid; align-items: center; gap: 9px; position: relative;
  grid-template-columns:
    22px            /* la case à cocher */
    minmax(200px, 1fr)  /* le nom, puis l'échéance, puis ce qu'on ouvre */
    auto                /* les trois bulles de réglage */
    var(--col-etat);    /* l'état, largeur fixe : la date n'y pousse plus rien */
}
/* Les colonnes fixes se laissent RÉTRÉCIR si l'écran ne suffit pas (minmax avec 0
   en plancher) : sans cela la grille déborde du cadre au lieu de se resserrer, et
   ce sont les bulles du bout qui sortent de la fenêtre. */
:root { --col-etat: minmax(0, 124px); }
/* Toute cellule de la grille peut se resserrer : une seule qui refuse, et c'est
   toute la ligne qui pousse au-delà du cadre. */
.tache > * { min-width: 0; }
/* LE NOM PASSE À LA LIGNE PLUTÔT QUE D'ÊTRE COUPÉ. Un intitulé de tâche tronqué
   à « Commander le prat… » ne se distingue plus de son voisin ; deux lignes de
   petit texte coûtent moins cher qu'une information perdue. */
.tache-nom { display: block; min-width: 0; overflow-wrap: anywhere; line-height: 1.3; }
/* Le nom et son échéance dans la même cellule : le badge suit le dernier mot et
   passe à la ligne avec lui, comme une mention écrite au bout d'un intitulé. */
.t-nom { min-width: 0; }
.t-nom .tache-nom { display: inline; }
.t-nom .tache-ech { margin-left: 7px; vertical-align: baseline; }
/* Ouvrir / télécharger / partager suivent l'échéance DANS LE FIL DE LA PHRASE : ils
   parlent de cette tâche-là, ils restent près d'elle. En ligne, donc, et non en
   colonne : ils passent à la ligne avec le nom quand l'intitulé est long. */
.tache-actions { display: inline-flex; align-items: center; gap: 6px;
  vertical-align: baseline; margin-left: 8px; flex-wrap: wrap; }
.tache-actions .tache-piece { margin-left: 0; }
.tache-partage { display: inline-flex; align-items: center; gap: 5px; margin: 0; }
.tache-add { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px;
  padding-top: 10px; border-top: 1px solid var(--border); }
.tache-add input[type=text] { flex: 1 1 220px; min-width: 160px; }
.tache-ech { display: inline-block; margin-left: 8px; font-size: 11px; font-weight: 700;
  padding: 1px 8px; border-radius: 999px; background: var(--surface-2, rgba(127,127,127,.10));
  border: 1px solid var(--border); color: var(--text-muted); white-space: nowrap; }
.tache-ech.urgent { color: var(--warning, #c77700); border-color: var(--warning, #c77700); }
.tache-ech.retard { color: #fff; background: var(--danger); border-color: var(--danger); }
.tache-ech-edit { margin-left: auto; }
.tache-ech-edit > summary { cursor: pointer; list-style: none; font-size: 14px; opacity: .55; }
.tache-ech-edit > summary::-webkit-details-marker { display: none; }
.tache-ech-edit[open] > summary { opacity: 1; }
.ech-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0 4px;
  padding: 8px 10px; background: var(--surface-2, rgba(127,127,127,.06)); border-radius: 8px; }
.ech-choix { display: flex; gap: 10px; flex-wrap: wrap; }
.ech-choix label { display: inline-flex; align-items: center; gap: 4px; margin: 0; font-size: 12px; }
.ech-valeurs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; }
.ech-valeurs input[type=date] { width: auto; }
.ech-retro { display: inline-flex; align-items: center; gap: 4px; }
.ech-retro input[type=number] { width: 62px; }
.ech-retro select { width: auto; }

/* Recherche SANS dates : compétent mais déjà occupé sur la période affichée. Le vert
   est réservé aux personnes réellement libres — le montrer en vert serait mensonger. */
.pg-match-occupe > td { background: rgba(199, 119, 0, 0.13); }
.pg-match-occupe .pg-perso { box-shadow: inset 3px 0 0 var(--warning, #c77700); }

/* ---- Suivi d'installation : pointage horodaté ---------------------------- */
.suivi-table { width: 100%; border-collapse: collapse; }
.suivi-table th { text-align: left; font-size: 11px; text-transform: uppercase;
  letter-spacing: .3px; color: var(--text-muted); padding: 4px 8px; border-bottom: 1px solid var(--border); }
.suivi-table td { padding: 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
.suivi-table tr.suivi-ok td { background: rgba(26,157,99,.07); }
.suivi-h { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.suivi-com { display: flex; gap: 6px; margin-top: 6px; }
.suivi-com input { font-size: 12px; padding: 3px 7px; }

/* Tâche VALIDÉE : bulle verte, même format que l'échéance pour comparer d'un coup d'œil. */
.tache-ech.valide { color: #fff; background: var(--success); border-color: var(--success); }
/* Champs d'échéance : date OU J−X, sans type à choisir ; le miroir s'affiche à côté. */
.ech-valeurs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; }
.ech-lbl { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .3px; }
.ech-ou { color: var(--text-muted); }
.ech-miroir { font-weight: 700; color: var(--accent); white-space: nowrap; }
/* Pointage : bouton GÉNÉREUX, pensé pour le doigt (usage mobile sur chantier). */
.btn-pointer { min-width: 116px; padding: 10px 16px; font-size: 15px; font-weight: 700; }
@media (max-width: 820px) {
  .btn-pointer { width: 100%; padding: 14px 16px; font-size: 16px; }
  .suivi-table thead { display: none; }
  .suivi-table, .suivi-table tbody, .suivi-table tr, .suivi-table td { display: block; width: 100%; }
  .suivi-table tr { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 10px; padding: 10px; }
  .suivi-table td { border: 0; padding: 2px 0; }
}

/* Filtre par MÉTIER au-dessus des cases de compétences : on choisit d'abord le
   métier, on ne déroule plus tout le catalogue. */
.comp-filtre { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0 4px; }
.comp-filtre .comp-filtre-sel { width: auto; min-width: 190px; }
.comp-filtre-info { font-weight: 600; color: var(--accent); }

/* ---- Fiches personnel : affichage TABLEAU (alternative aux cartes) --------
   Les mêmes cartes deviennent des lignes compactes : une personne par ligne,
   lisible d'un coup d'œil quand l'effectif est important. */
body.fiches-tableau .people-grid { display: block; }
body.fiches-tableau .person-card { display: flex; align-items: center; gap: 14px;
  padding: 7px 12px; margin: 0; border-radius: 0; border-left: 0; border-right: 0;
  border-top: 0; box-shadow: none; }
body.fiches-tableau .person-card + .person-card { border-top: 1px solid var(--border); }
body.fiches-tableau .person-card:hover { background: var(--surface-2, rgba(127,127,127,.06)); }
body.fiches-tableau .person-card .avatar-wrap { flex: 0 0 auto; }
body.fiches-tableau .person-card .avatar { width: 30px; height: 30px; font-size: 12px; }
body.fiches-tableau .person-card .avatar-badge { font-size: 9px; padding: 0 4px; }
body.fiches-tableau .person-card > div:last-child { display: flex; align-items: center;
  gap: 12px; flex: 1; min-width: 0; flex-wrap: nowrap; }
body.fiches-tableau .person-card h3 { margin: 0; font-size: 14px; flex: 0 0 190px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.fiches-tableau .person-card .person-meta { flex: 0 0 210px; font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.fiches-tableau .person-card .statut-badge { flex: 0 0 auto; }
body.fiches-tableau .person-card .chips { flex: 1; min-width: 0; display: flex;
  gap: 4px; overflow: hidden; flex-wrap: nowrap; }
body.fiches-tableau .person-card .chip { white-space: nowrap; font-size: 11px; }
@media (max-width: 820px) {
  body.fiches-tableau .person-card > div:last-child { flex-wrap: wrap; }
  body.fiches-tableau .person-card h3,
  body.fiches-tableau .person-card .person-meta { flex: 1 1 100%; }
}

/* ---- Tableau de bord des suivis de chantier (mobile d'abord) -------------- */
.suivi-choix { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.suivi-carte { display: block; text-decoration: none; color: inherit; padding: 14px 16px; }
.suivi-carte:hover { border-color: var(--accent); }
.suivi-carte-tete { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.suivi-carte h3 { margin: 0 0 2px; font-size: 16px; }
.suivi-pct { font-size: 20px; font-weight: 800; color: var(--accent); white-space: nowrap; }
.suivi-carte .gauge-bar { margin: 10px 0 8px; }
.suivi-carte-pied { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.suivi-next { font-size: 12px; font-weight: 700; color: var(--accent);
  background: var(--surface-2, rgba(127,127,127,.10)); border-radius: 999px; padding: 2px 10px; }
.suivi-next.suivi-fini { color: var(--success); }

/* Séparateur de journée dans le fil de discussion : l'heure seule ne permettait
   pas de savoir de quel jour datait un message. */
.chat-jour { display: flex; align-items: center; gap: 10px; margin: 14px 0 8px; }
.chat-jour::before, .chat-jour::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.chat-jour span { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .4px; color: var(--text-muted); white-space: nowrap; }
/* Chantier hors période (pas commencé ou terminé) : atténué, sans être masqué. */
.suivi-carte.suivi-hors { opacity: .5; filter: grayscale(1); }
.suivi-carte.suivi-hors:hover { opacity: .85; filter: none; }
.suivi-hors-tag { color: var(--text-muted) !important; }
/* Accès au suivi depuis l'accueil : bouton large, lisible au doigt. */
.btn-suivi-dash { display: block; width: 100%; max-width: 520px; margin: 0 0 18px;
  padding: 14px 18px; font-size: 16px; font-weight: 700; text-align: center; }
@media (max-width: 820px) { .btn-suivi-dash { max-width: none; padding: 16px; } }

/* ---------- Vue double : coque à deux panneaux autonomes ---------- */
.vd-body { margin: 0; overflow: hidden; }
.vd-shell { display: flex; height: 100vh; width: 100%; }
.vd-cote { display: flex; flex-direction: column; min-width: 0; flex: 1 1 50%; }
.vd-cote + .vd-cote { border-left: 1px solid var(--border); }
.vd-bar { display: flex; align-items: center; gap: 6px; padding: 5px 8px; flex: none;
  border-bottom: 1px solid var(--border); background: var(--surface); }
.vd-nav { display: flex; gap: 6px; padding: 5px 8px; flex: none; overflow-x: auto;
  border-bottom: 1px solid var(--border); background: var(--surface); }
.vd-frame { flex: 1 1 auto; width: 100%; border: 0; background: var(--bg); }
.vd-resize { flex: 0 0 6px; cursor: col-resize; background: var(--border); }
.vd-resize:hover { background: var(--accent); }
.vd-quit { white-space: nowrap; }
/* Pendant le glisser, les iframes ne doivent pas capter la souris. */
.vd-dragging .vd-frame { pointer-events: none; }
@media (max-width: 820px) {
  /* Écran étroit : les deux panneaux s'empilent au lieu de se serrer. */
  .vd-shell { flex-direction: column; }
  .vd-cote { flex: 1 1 50% !important; }
  .vd-cote + .vd-cote { border-left: 0; border-top: 1px solid var(--border); }
  .vd-resize { display: none; }
}

/* Auteur d'une indisponibilité, sous la croix : discret, lisible, jamais gênant. */
.fiche-cal-cell .indispo-auteur { position: absolute; left: 0; right: 0; bottom: 2px; z-index: 3;
  font-size: 9px; line-height: 1.1; text-align: center; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 2px;
  background: color-mix(in srgb, var(--surface) 78%, transparent); cursor: help; }

/* Archives (messagerie, fiche personnel…) : repliées, ouvertes d'un clic. */
.mbx-archives, .jpp-archives { margin-top: 18px; }
.mbx-archives > summary, .jpp-archives > summary { display: inline-flex; list-style: none; cursor: pointer; width: auto; }
.mbx-archives > summary::-webkit-details-marker, .jpp-archives > summary::-webkit-details-marker { display: none; }
.jpp-archives .jpp-item { opacity: .72; }

/* ---------- Recherche de compétence au clavier ---------- */
.comp-ac { position: relative; display: inline-block; min-width: 180px; margin-right: 6px; }
.comp-ac-champ { width: 100%; }
.comp-ac-champ-liste { margin-bottom: 8px; }
.comp-ac-liste { position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 2px);
  max-height: 280px; overflow-y: auto; background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 10px 28px rgba(0,0,0,.16); padding: 4px; min-width: 240px; }
.comp-ac-item { display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  width: 100%; text-align: left; border: 0; background: none; color: var(--text); cursor: pointer;
  padding: 6px 9px; border-radius: 7px; font-size: 13.5px; }
.comp-ac-item:hover, .comp-ac-item.on { background: var(--surface-2); }
.comp-ac-nom { font-weight: 600; }
.comp-ac-grp { font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.comp-ac-vide { padding: 8px 10px; font-size: 12.5px; color: var(--text-muted); }
@media (max-width: 820px) { .comp-ac { display: block; width: 100%; margin: 0 0 6px; } }

/* ---------- Notifications : acquittement en tête de ligne ---------- */
.notif-ligne { display: flex; align-items: stretch; gap: 0; }
.notif-ligne + .notif-ligne { border-top: 1px solid var(--border); }
.notif-ligne > .inbox-row { flex: 1; min-width: 0; border-top: 0; }
.notif-ack-form { display: flex; align-items: center; margin: 0; padding-left: 10px; }
.notif-ack { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer; font-size: 15px; line-height: 1;
  border: 1.5px solid var(--border); background: var(--surface); color: var(--text-muted); }
.notif-ack:hover { border-color: var(--success, #16a34a); color: var(--success, #16a34a); background: var(--surface-2); }
.notif-ack.fait { align-self: center; margin-left: 10px; border-color: transparent;
  color: var(--success, #16a34a); background: none; cursor: help; }
/* Ligne non acquittée : le liseré marque ce qui reste à traiter. */
.notif-ligne.unread { background: var(--surface-2); box-shadow: inset 3px 0 0 var(--accent); }
.notif-ligne.unread .inbox-from { font-weight: 700; }
@media (max-width: 820px) {
  .notif-ack { width: 36px; height: 36px; }   /* cible confortable au doigt */
}

/* Mots-clés d'une compétence : replié, ouvert d'un clic sur « + mot clé ». */
.comp-mots { position: relative; }
.comp-mots > summary { list-style: none; cursor: pointer; font-size: 11.5px; white-space: nowrap;
  color: var(--text-muted); border: 1px dashed var(--border); border-radius: 999px; padding: 2px 9px; }
.comp-mots > summary::-webkit-details-marker { display: none; }
.comp-mots > summary:hover { color: var(--accent); border-color: var(--accent); }
.comp-mots[open] > summary { color: var(--text); border-style: solid; }
.comp-mots-form { margin-top: 6px; }
.comp-mots-form input { min-width: 220px; }
@media (max-width: 820px) { .comp-mots-form input { min-width: 0; flex: 1 1 100%; } }

/* --- LE RATTACHEMENT À LA FONCTION LÉGALE ---------------------------------
   Une pastille par compétence, dont la COULEUR dit l'état : rattachée ou non. Sur
   quarante compétences, c'est ce qu'on balaie — « lesquelles bloqueront un contrat ? »
   se répond des yeux, pas en ouvrant quarante volets. */
.comp-fonction { position: relative; }
.comp-fonction > summary { list-style: none; cursor: pointer; font-size: 11.5px;
  white-space: nowrap; border-radius: 999px; padding: 2px 9px;
  border: 1px dashed var(--border); color: var(--text-muted); }
.comp-fonction > summary::-webkit-details-marker { display: none; }
.comp-fonction > summary.fct-ok { border-style: solid; border-color: var(--success, #1a9d63);
  color: var(--success, #1a9d63); }
.comp-fonction > summary.fct-vide { border-color: var(--danger, #dc2626);
  color: var(--danger, #dc2626); }
.comp-fonction > summary:hover { border-color: var(--accent); color: var(--accent); }
/* Le panneau flotte : la ligne d'une compétence est déjà pleine, et la nomenclature
   demande de la hauteur. */
.fct-form { position: absolute; z-index: 70; top: calc(100% + 6px); left: 0;
  min-width: 340px; max-width: min(520px, 92vw); padding: 10px 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 12px 30px rgba(0,0,0,.32);
  display: flex; flex-direction: column; gap: 6px; }
.fct-chercher { width: 100%; }
.fct-liste { width: 100%; font-size: 12.5px; }

/* Tableau d'expériences : dense et lisible — beaucoup de lignes d'un coup d'oeil. */
.xp-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.xp-table th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .03em;
  color: var(--text-muted); font-weight: 600; padding: 4px 6px; border-bottom: 1px solid var(--border); }
.xp-table td { padding: 2px 4px; }
.xp-table input { width: 100%; padding: 4px 7px; font-size: 12.5px; height: auto; margin: 0; }
.xp-del { border: 0; background: none; color: var(--text-muted); cursor: pointer; font-size: 16px; line-height: 1; padding: 2px 6px; }
.xp-del:hover { color: var(--danger, #dc2626); }
@media (max-width: 820px) { .xp-table { min-width: 620px; } }

/* ---------- Onglets d'un client : visible / grisé / invisible ---------- */
.mod-toggle.visible { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }
.mod-toggle.visible::before { content: "✓"; font-weight: 700; }
/* Grisé = fonctionnel mais fermé : on le montre sans le rendre appétissant. */
.mod-toggle.grise { background: var(--surface-2); border-color: var(--text-muted); color: var(--text-muted); }
.mod-toggle.grise::before { content: "🔒"; }
/* Invisible = absent chez le client : trait barré, pas d'ambiguïté. */
.mod-toggle.invisible { background: transparent; border-style: dashed; color: var(--text-muted); opacity: .6; }
.mod-toggle.invisible::before { content: "∅"; }
.mod-leg { display: inline-block; padding: 0 6px; border-radius: 999px; font-size: 10.5px; font-weight: 700; }
.mod-leg.on { background: var(--accent); color: var(--accent-contrast); }
.mod-leg.grise { background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--text-muted); }
.mod-leg.off { border: 1px dashed var(--border); color: var(--text-muted); }

/* Entrée de menu d'un module fermé : présente, non cliquable, explicite au survol. */
.nav .nav-ferme { display: flex; align-items: center; gap: 10px; padding: 9px 18px; font-size: 14px;
  color: var(--text-muted); opacity: .55; cursor: not-allowed; user-select: none; }
.nav .nav-ferme .ico { opacity: .6; }
.nav .nav-ferme .nav-cadenas { margin-left: auto; font-size: 11px; }
/* Tuile d'accueil d'un module fermé : visible, jamais cliquable. */
.home-tile.tuile-fermee { opacity: .5; cursor: not-allowed; color: var(--text-muted); }

/* ---------- Accueil réduit : la marque et les deux portes d'entrée ---------- */
.accueil-nue { min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: #fff; padding: 24px; }
.an-box { text-align: center; max-width: 460px; }
.an-mark { display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; font-size: 20px; margin-bottom: 18px; }
.an-box h2 { font-size: 30px; margin: 0 0 6px; letter-spacing: -.5px; }
.an-box p { color: var(--text-muted); margin: 0 0 26px; font-size: 15px; }
.an-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
@media (max-width: 560px) { .an-cta .btn { width: 100%; justify-content: center; } }

/* Langues parlées : drapeaux lisibles sans surcharger la fiche. */
.langues-drapeaux { margin-left: 8px; letter-spacing: 2px; font-size: 15px; }
.langue-dr { font-size: 15px; margin-right: 4px; }

/* Choix des annuaires : deux offres présentées côte à côte, sans ambiguïté. */
.an-offres { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.an-offre { display: flex; gap: 10px; align-items: flex-start; margin: 0; padding: 12px;
  border: 1px solid var(--border); border-radius: 10px; cursor: pointer; text-transform: none;
  letter-spacing: normal; font-size: 13.5px; color: var(--text); }
.an-offre:hover { border-color: var(--accent); }
.an-offre input[type=checkbox] { width: auto; margin: 2px 0 0; flex: none; }
.an-offre .helptext { display: block; margin-top: 3px; }
.an-prix { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--accent); font-weight: 700; }
@media (max-width: 700px) { .an-offres { grid-template-columns: 1fr; } }

/* Garantie « zéro consultation » : lisible, jamais en petites lettres. */
.an-garantie { display: block; margin-top: 6px; font-size: 12px; line-height: 1.35;
  color: var(--success, #16a34a); }
.an-etat { margin-top: 10px; padding: 9px 12px; border-radius: 9px; font-size: 13px;
  background: var(--surface-2); border: 1px solid var(--border); }
.an-etat.ouvert { border-color: var(--success, #16a34a); color: var(--success, #16a34a); }

/* Grille des onglets pilotables : tout se voit d'un écran, sans défilement. */
.onglets-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.onglet-case { display: flex; gap: 9px; align-items: flex-start; margin: 0; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 9px; cursor: pointer; text-transform: none;
  letter-spacing: normal; font-size: 13px; color: var(--text); }
.onglet-case:hover { border-color: var(--accent); }
.onglet-case input { width: auto; margin: 2px 0 0; flex: none; }
.onglet-case .helptext { display: block; margin-top: 2px; }
.onglet-case.eteint { opacity: .55; border-style: dashed; }

/* Pastille BÊTA à côté de la marque : présente sans écraser le nom du produit. */
.bulle-beta { display: inline-block; vertical-align: middle; padding: 1px 7px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .06em; line-height: 1.5;
  background: var(--accent); color: var(--accent-contrast); }

/* ---------- Événement personnel : saisie courte, pensée pour le pouce ---------- */
.ev-form { max-width: 560px; display: flex; flex-direction: column; gap: 10px; }
.ev-titre { font-size: 17px; font-weight: 600; padding: 12px 14px; margin: 0; }
.ev-seg { display: flex; gap: 6px; }
.ev-seg-opt { flex: 1; margin: 0; text-transform: none; letter-spacing: normal; }
.ev-seg-opt input { position: absolute; opacity: 0; pointer-events: none; }
.ev-seg-opt span { display: block; text-align: center; padding: 8px 10px; font-size: 13.5px;
  border: 1px solid var(--border); border-radius: 9px; cursor: pointer; color: var(--text-muted); }
.ev-seg-opt input:checked + span { border-color: var(--accent); color: var(--text);
  background: var(--surface-2); font-weight: 600; }
.ev-dates { display: flex; gap: 8px; align-items: flex-end; }
.ev-champ { flex: 1; margin: 0; min-width: 0; text-transform: none; letter-spacing: normal; }
.ev-champ > span { display: block; font-size: 11px; color: var(--text-muted); margin-bottom: 2px; }
.ev-champ input { margin: 0; width: 100%; }
.ev-champ.ev-h { flex: 0 0 88px; }
.ev-bascule { display: flex; align-items: center; gap: 8px; margin: 0; white-space: nowrap;
  text-transform: none; letter-spacing: normal; font-size: 13.5px; color: var(--text); cursor: pointer; }
.ev-bascule input { width: auto; margin: 0; }
.ev-bloque { padding: 9px 12px; border: 1px solid var(--border); border-radius: 9px; white-space: normal; }
.ev-bloque .helptext { display: block; }
.ev-couleurs { display: flex; gap: 10px; flex-wrap: wrap; }
.ev-pastille { margin: 0; cursor: pointer; }
.ev-pastille input { position: absolute; opacity: 0; pointer-events: none; }
.ev-pastille span { display: block; width: 30px; height: 30px; border-radius: 50%;
  background: var(--c); border: 2px solid transparent; box-shadow: 0 0 0 1px rgba(0,0,0,.08) inset; }
.ev-pastille input:checked + span { border-color: var(--text); transform: scale(1.12); }
.ev-lieu { display: flex; align-items: center; gap: 8px; margin: 0;
  border: 1px solid var(--border); border-radius: 9px; padding: 0 10px; }
.ev-lieu input { border: 0; margin: 0; padding: 10px 0; background: none; }
.ev-lieu input:focus { outline: none; }
.ev-ico { flex: none; opacity: .7; }
.ev-plus > summary { list-style: none; cursor: pointer; font-size: 13px; color: var(--accent); }
.ev-plus > summary::-webkit-details-marker { display: none; }
.ev-plus textarea { margin-top: 6px; }
.ev-actions { display: flex; gap: 10px; }
.ev-actions .btn { flex: 1; justify-content: center; }
.ev-suppr { margin-top: 18px; max-width: 560px; }
@media (max-width: 560px) {
  .ev-champ.ev-h { flex: 1 1 0; }
  .ev-pastille span { width: 34px; height: 34px; }   /* cible confortable au doigt */
}

/* Agenda perso dans le calendrier : une bande sous les barres de projet. */
.cal-week-perso { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; padding: 0 1px 3px; }
.cal-perso-jour { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cal-perso { display: block; font-size: 10.5px; line-height: 1.45; padding: 1px 5px; border-radius: 5px;
  color: #fff; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 1px rgba(0,0,0,.25); }
.cal-perso:hover { filter: brightness(1.08); color: #fff; }
.cal-perso-plus { font-size: 9.5px; color: var(--text-muted); padding-left: 5px; }
@media (max-width: 820px) { .cal-perso { font-size: 9.5px; padding: 1px 3px; } }

/* Alarme de conflit : visible sans être agressive, au-dessus du formulaire. */
.ev-conflit { max-width: 560px; margin-bottom: 12px; padding: 10px 13px; border-radius: 10px;
  border: 1px solid var(--danger, #dc2626); background: color-mix(in srgb, var(--danger, #dc2626) 8%, transparent);
  font-size: 13.5px; line-height: 1.5; }
.ev-conflit .helptext { display: block; margin-top: 4px; }

/* Carte d'événement perso dans « Ma journée » : cliquable en entier. */
.ev-carte { display: block; text-decoration: none; color: inherit; }
.ev-carte:hover { color: inherit; filter: brightness(.98); }

/* ---------- Mon agenda : liste lisible sous le calendrier ---------- */
.ag-liste { display: flex; flex-direction: column; gap: 6px; max-width: 620px; }
.ag-ligne { display: flex; align-items: center; gap: 12px; padding: 8px 12px; text-decoration: none;
  color: inherit; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.ag-ligne:hover { border-color: var(--accent); color: inherit; }
.ag-date { flex: none; width: 42px; text-align: center; line-height: 1.1;
  border-left: 4px solid var(--accent); padding-left: 8px; }
.ag-date strong { display: block; font-size: 17px; }
.ag-date span { font-size: 10px; color: var(--text-muted); text-transform: uppercase; }
.ag-corps { flex: 1; min-width: 0; }
.ag-titre { display: block; font-weight: 600; font-size: 14px; }
.ag-meta { display: block; font-size: 12px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Sur mobile, une case fait ~45 px : le titre n'y tient pas. On garde un POINT
   de couleur comme repère, et la liste ci-dessus porte le détail. */
@media (max-width: 820px) {
  .cal-week-perso { padding: 0 2px 4px; }
  .cal-perso-jour { flex-direction: row; flex-wrap: wrap; gap: 3px; justify-content: center; align-items: center; }
  .cal-perso { font-size: 0; width: 7px; height: 7px; padding: 0; border-radius: 50%;
    text-shadow: none; flex: none; }
  .cal-perso-plus { font-size: 9px; padding: 0; }
}
/* « Journée entière » sur sa propre ligne : au large, jamais collée au bord. */
.ev-journee-ligne { padding: 2px 2px 0; }

/* ---------- Calendrier : lisibilité et confort de lecture ---------- */
/* Numéros de jour et en-têtes : repères, pas du texte à sélectionner. Un appui
   long sur mobile ne doit pas déclencher la poignée de sélection du système. */
.cal-num, .cal-dow, .pp-num, .cal-perso, .cal-ev, .cal-ev-label {
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}

/* Taille du texte des événements, au choix de chacun. */
html[data-cal-txt="s"] .cal-ev-label { font-size: 9.5px; }
html[data-cal-txt="s"] .cal-perso { font-size: 9.5px; }
html[data-cal-txt="l"] .cal-ev-label { font-size: 13px; }
html[data-cal-txt="l"] .cal-perso { font-size: 12.5px; }
html[data-cal-txt="l"] .cal-week-lanes { grid-auto-rows: 24px; }
.cal-txt-select { width: auto; margin: 0; padding: 5px 8px; font-size: 12.5px; }

/* Barre de projet : cliquable, donc elle doit se comporter comme un lien. */
a.cal-ev { display: block; text-decoration: none; cursor: pointer; }

/* Aperçu flottant à l'appui long (mobile) : se ferme dès qu'on relâche. */
.cal-bulle { position: fixed; z-index: 90; max-width: 240px; padding: 8px 12px;
  border-radius: 10px; background: var(--text); color: #fff; font-size: 13px; line-height: 1.35;
  box-shadow: 0 8px 24px rgba(0,0,0,.28); pointer-events: none; }

/* iOS agrandit automatiquement la page quand on touche un champ dont le texte
   fait moins de 16 px — d'où le « zoom » sur tous les champs sauf le titre, seul
   assez grand. On force donc 16 px sur les champs de saisie en mobile ; c'est la
   seule parade qui n'interdit pas le zoom manuel (maximum-scale casse l'accessibilité). */
@media (max-width: 820px) {
  input[type="text"], input[type="search"], input[type="email"], input[type="tel"],
  input[type="url"], input[type="number"], input[type="password"],
  input[type="date"], input[type="time"], input[type="datetime-local"],
  select, textarea { font-size: 16px; }
}

/* ---------- Vue semaine du planning personnel ---------- */
.sem-grille { display: grid; gap: 8px; margin-top: 12px; }
.sem-grille.sem-empilee { grid-template-columns: 1fr; }
.sem-grille.sem-colonnes { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.sem-jour { border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  overflow: hidden; display: flex; flex-direction: column; min-width: 0; }
.sem-jour.we { background: var(--surface-2); }
.sem-jour.today { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.sem-jour.indispo .sem-entete { color: var(--danger, #dc2626); }
.sem-entete { display: flex; align-items: baseline; gap: 6px; padding: 7px 10px; text-decoration: none;
  color: inherit; border-bottom: 1px solid var(--border); font-size: 13px; }
.sem-entete span { font-size: 11px; color: var(--text-muted); }
.sem-tag { margin-left: auto; font-size: 10px; }
.sem-corps { padding: 6px; display: flex; flex-direction: column; gap: 4px; flex: 1; }
.sem-item { display: block; padding: 5px 8px; border-left: 3px solid var(--accent);
  border-radius: 6px; background: var(--surface-2); font-size: 12.5px; text-decoration: none;
  color: inherit; overflow: hidden; text-overflow: ellipsis; }
.sem-item:hover { color: inherit; filter: brightness(.97); }
.sem-h { display: block; font-size: 10.5px; color: var(--text-muted); }
.sem-vide { color: var(--text-muted); font-size: 12px; padding: 2px 8px; }
/* En colonnes sur un téléphone, sept colonnes seraient illisibles : on empile. */
@media (max-width: 820px) { .sem-grille.sem-colonnes { grid-template-columns: 1fr; } }

/* Règle horaire sur téléphone : 24 étiquettes se chevauchent. Toutes les 3 h
   restait trop serré à l'usage — on passe à toutes les 6 h (00:00, 06:00, 12:00,
   18:00). Les traits de graduation restent tous : seule l'étiquette s'espace.
   Sur ordinateur, rien ne change. */
@media (max-width: 820px) {
  .tl-tick-lbl:not(.t6), .cal-hlabel:not(.t6) { display: none; }
  .tl-tick-lbl.t6, .cal-hlabel.t6 { font-size: .7rem; }
}

/* Étapes négociées avec le client, à poser d'un clic au-dessus du formulaire. */
.etapes-client { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.etapes-client .helptext { margin: 0; }
.etape-predef { cursor: pointer; }

/* Métiers d'une étape : rappel discret, modifiable au clic. */
.etape-metiers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0; }
.etape-metiers .helptext { margin: 0; }
.etape-metiers-edit > summary { list-style: none; cursor: pointer; }
.etape-metiers-edit > summary::-webkit-details-marker { display: none; }

/* Catégorie déclarée comme métier : repère immédiat dans le catalogue. */
.tag-metier { background: var(--accent); color: var(--accent-contrast); font-size: 10px;
  padding: 1px 7px; border-radius: 999px; font-weight: 700; letter-spacing: .03em; }
.sans-cat-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }

/* Document rattaché à une tâche : discret, mais toujours à portée de clic. */
.tache-piece { font-size: 11.5px; padding: 1px 7px; margin-left: 6px; border-radius: 999px;
  border: 1px solid var(--border); text-decoration: none; color: var(--text-muted); white-space: nowrap; }
.tache-piece:hover { border-color: var(--accent); color: var(--accent); }

/* LA VERSION EN PLACE, sur la ligne. Une pastille pleine et non un contour : elle ne
   s'ouvre pas, elle se lit — c'est une MENTION au milieu de boutons, et l'oeil doit
   faire la différence sans hésiter. Orange quand cette version n'est pas partie :
   la couleur du bouton Partager, sur la chose qui n'a pas été partagée. */
.tache-version { display: inline-block; font-size: 11px; font-weight: 700; padding: 1px 7px;
  border-radius: 999px; white-space: nowrap; background: var(--surface-2, rgba(127,127,127,.10));
  border: 1px solid var(--border); color: var(--text-muted); }
.tache-version.version-attente { color: #fff; background: var(--warning, #c77700);
  border-color: var(--warning, #c77700); }
/* Le menu « étape de référence » peut être long : on le borne. */
.ech-etape, .ech-metier { max-width: 220px; }

/* Pastille personnel d'une case de calendrier : pourvus / attendus, d'un coup d'oeil. */
.pp-count { display: inline-flex; align-items: center; gap: 3px; padding: 0 6px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; line-height: 1.6; background: var(--surface-2); color: var(--text-muted); }
.pp-count-ico { width: 11px; height: 11px; }
.pp-count.ok { background: var(--success, #16a34a); color: #fff; }
.pp-count.manque { background: var(--danger, #dc2626); color: #fff; }
/* Jalon nommé dans la case : on lit « 1er show » ou « deadline », pas une étoile seule. */
.pp-jalon { font-size: 9.5px; font-weight: 700; white-space: nowrap; color: var(--accent); }
.pp-jalon.is-deadline { color: var(--danger, #dc2626); }

/* Renommer une compétence : le nom reste un simple libellé, éditable au clic. */
.comp-renom { flex: 1; min-width: 0; }
.comp-renom > summary { list-style: none; cursor: text; }
.comp-renom > summary::-webkit-details-marker { display: none; }
.comp-renom[open] > summary { color: var(--accent); }
.comp-renom-form { margin-top: 6px; }

/* Compétence VÉRIFIÉE : étoile jaune. Gage de qualité — efficacité constatée,
   pas une simple recommandation ni une liste fabricant. */
.etoile-verif { color: #f0b400; font-size: 11px; text-shadow: 0 0 1px rgba(0,0,0,.15); }
.chip.verifiee { border-color: #f0b400; }
.chip-comp { cursor: pointer; font: inherit; }
.chip-comp:hover { border-color: #f0b400; }

/* Annuaire : « signalé par un client » (cercle creux) ≠ « vérifié par Good Night
   Producer » (étoile pleine). Seul le second engage l'annuaire. */
.signale-verif { color: var(--text-muted); font-size: 12px; }

/* Compétences en colonne sur la fiche : une ligne, un nom, une bulle de vérification. */
.comp-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.comp-ligne { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 5px 2px; border-bottom: 1px solid var(--border); }
.comp-ligne:last-child { border-bottom: 0; }
.comp-ligne-nom { min-width: 0; font-size: 13.5px; }
.comp-ligne-nom .person-meta { display: block; font-size: 11px; }
/* Bulle de vérification : GRISE tant que c'est déclaré, VERTE quand c'est constaté. */
.bulle-verif { flex: none; cursor: pointer; font-size: 11px; font-weight: 700; line-height: 1.6;
  padding: 1px 10px; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-muted); }
.bulle-verif:hover { border-color: var(--success, #16a34a); color: var(--success, #16a34a); }
.bulle-verif.on { background: var(--success, #16a34a); border-color: var(--success, #16a34a); color: #fff; }
.bulle-verif.statique { cursor: default; }

/* Bookings sans étape : une anomalie, donc un cadre qui se voit — mais pas une
   erreur bloquante, donc l'ambre de l'avertissement et non le rouge du danger. */
.orph-card { border-left: 4px solid var(--warning); }
.orph-liste { display: flex; flex-direction: column; gap: 2px; max-height: 260px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px; }
.orph-ligne { display: flex; align-items: center; gap: 8px; margin: 0; font-weight: 400;
  padding: 2px 0; flex-wrap: wrap; }
.orph-nom { font-weight: 600; }
.orph-suggest { font-size: 11px; color: var(--text-muted); background: var(--bg-alt, rgba(0,0,0,.05));
  border-radius: 20px; padding: 1px 8px; }

/* FORMATION : présent sur l'étape, mais pour apprendre. Le liseré pointillé dit
   « ne compte pas dans les besoins » sans avoir à le lire quelque part. */
.bulle-formation { border: 1px dashed var(--accent); background: transparent; color: var(--accent);
  border-radius: 20px; padding: 5px 12px; font-size: 12px; font-weight: 600; cursor: pointer;
  white-space: nowrap; flex: 0 0 auto; }
.bulle-formation:hover, .bulle-formation.on { background: var(--accent); color: var(--accent-contrast); }
.formation-form { margin-top: 10px; padding: 10px; border: 1px dashed var(--accent);
  border-radius: 10px; background: var(--surface); }
.chip-formation { border: 1px dashed var(--accent); display: inline-flex; align-items: center;
  gap: 6px; padding: 4px 6px 4px 10px; }

/* Historique des formations : une ligne = un passage, annotable sur place. */
.form-liste { list-style: none; margin: 0 0 6px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.form-ligne { border-left: 2px dashed var(--accent); padding-left: 8px; }
.form-ligne-tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.form-ligne-quoi { font-weight: 600; font-size: 13px; }
.form-a-preciser { font-weight: 400; font-style: italic; color: var(--text-muted); }
.form-annot { display: flex; gap: 6px; align-items: flex-start; margin-top: 4px; }
.form-annot textarea { flex: 1; min-height: 32px; font-size: 12px; padding: 4px 6px; }

/* Étapes prédéfinies : filtres par métier au-dessus de la rangée d'intitulés.
   La liste défile plutôt que de repousser le formulaire hors de l'écran. */
.predef-filtres { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0; }
.predef-chercher { flex: 1 1 160px; min-width: 140px; max-width: 260px; font-size: 13px; padding: 4px 8px; }
.predef-liste { display: flex; flex-wrap: wrap; gap: 6px; max-height: 168px; overflow-y: auto; }

/* Bascule chronologique / par métier, et titres de groupe. */
.etapes-vue { display: flex; gap: 6px; margin-bottom: 12px; }
.etapes-vue .filtre-chip { text-decoration: none; }
.metier-groupe { margin-bottom: 8px; }

/* Ligne de formation : même gabarit que la ligne « + Besoin » juste au-dessus,
   le pointillé rappelant seul qu'on n'ajoute pas là quelqu'un qui produit. */
.ligne-formation { padding: 6px 8px; border: 1px dashed var(--accent); border-radius: 10px; }
.ligne-formation .comp-ac { flex: 1 1 140px; min-width: 0; }

/* Enregistrer en haut de page : même bouton que celui du bas, à portée de main
   quand la fiche est longue. Discret dans l'en-tête, il ne vole pas la vedette
   au bouton de validation final. */
.barre-enregistrer-haut { margin: 0 0 14px; }
.btn-enregistrer-haut { white-space: nowrap; }

/* Récapitulatif : une ligne de frais par personne, en retrait sous son étape —
   c'est le niveau auquel on vérifie une facture. */
.recap-perso > td { padding-top: 2px; padding-bottom: 2px; font-size: 12px;
  color: var(--text-muted); border-top: none; }
.recap-perso a { color: inherit; }
.recap-puce { display: inline-block; width: 14px; text-align: center; opacity: .5; }
.recap-formation > td { font-style: italic; }
.recap-etape > td { border-top: 1px solid var(--border); }
.recap-tarif { display: flex; gap: 4px; align-items: center; margin: 0; }
.recap-tarif input { width: 92px; font-size: 12px; padding: 2px 6px; }

/* Voyage / travail du 1er et du dernier jour, réglés depuis l'étape. La pastille
   résume (✈️ = voyage, 💻 = travail), le panneau détaille — replié tant qu'on n'en
   a pas besoin : il y a une pastille par personne. */
.jt-dd { display: inline; position: relative; }
.jt-dd > summary { list-style: none; cursor: pointer; }
.jt-dd > summary::-webkit-details-marker { display: none; }
.jt-badge { font-size: 11px; letter-spacing: -1px; opacity: .85; border-radius: 20px;
  padding: 0 4px; background: rgba(0,0,0,.06); }
.jt-dd[open] > .jt-badge, .jt-dd[open] > summary { opacity: 1; }
.jt-form { position: absolute; z-index: 40; top: 20px; left: 0; min-width: 230px;
  display: flex; flex-direction: column; gap: 6px; padding: 10px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  box-shadow: 0 8px 24px rgba(0,0,0,.14); }
.jt-form label { font-size: 11px; font-weight: 600; display: flex; flex-direction: column; gap: 2px; }

/* Compteur de FORMATION : à côté de l'effectif, jamais dedans. Le pointillé dit
   « présent mais ne pourvoit pas » sans avoir à lire une légende. */
.pp-count-form { background: transparent; color: var(--accent);
  border: 1px dashed var(--accent); }
.pp-etape-count.pp-count-form { background: rgba(255,255,255,.25); color: #fff;
  border: 1px dashed rgba(255,255,255,.7); margin-left: 3px; }

/* Partage externe d'un planning : le lien se copie d'un clic, et la case des NOMS
   est signalée — c'est la seule qu'on ne peut pas reprendre une fois envoyée. */
.lien-partage { display: flex; gap: 6px; align-items: center; margin-top: 10px; }
.lien-partage input { flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px; padding: 5px 8px; background: var(--bg-alt, rgba(0,0,0,.04)); }
.partage-options { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.rr-sensible { border: 1px dashed var(--danger); border-radius: 8px; padding: 2px 8px; }

/* Un destinataire = une ligne, et ses réglages propres en retrait dessous. */
.dest-ligne { list-style: none; padding: 6px 0; border-top: 1px solid var(--border); }
.dest-ligne:first-child { border-top: 0; }
.dest-reglages { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end;
  margin: 6px 0 0 14px; }
.dest-reglages label { font-size: 11px; font-weight: 600; display: flex;
  flex-direction: column; gap: 2px; margin: 0; }
.dest-reglages select { font-size: 12px; padding: 2px 6px; }

/* Accès aux MONTANTS : bulle grise quand ils sont masqués, verte quand ils sont
   visibles — même grammaire que la bulle « vérifiée » des compétences. */
.droits-form { display: flex; gap: 6px; align-items: center; margin: 0; flex-wrap: wrap; }
.droits-form select { font-size: 12px; padding: 2px 6px; }
.bulle-budget { display: inline-flex; align-items: center; font-size: 11px; font-weight: 600;
  border-radius: 20px; padding: 2px 9px; cursor: pointer; white-space: nowrap;
  background: var(--bg-alt, rgba(0,0,0,.06)); color: var(--text-muted);
  border: 1px solid var(--border); margin: 0; }
.bulle-budget.on { background: var(--success); color: #fff; border-color: var(--success); }
.bulle-budget.statique { cursor: default; }

/* Calendriers : une case de grille a `min-width: auto` par défaut, donc elle refuse
   de descendre sous la largeur de son contenu — un nom d'étape en `nowrap` poussait
   la page à 422 px sur un écran de 375, et TOUT débordait, jusqu'à la barre du haut.
   Remettre `min-width: 0` rend leur rôle aux ellipses. */
.pp-cell, .pp-etapes, .pp-etape-bar, .pp-num { min-width: 0; }
.pp-etapes { max-width: 100%; }

/* Légende des étapes sous le calendrier interne : trois lignes calées à gauche,
   comme sur le planning partagé — le nom, les dates, puis le personnel. */
.cal-legende { margin-top: 10px; padding: 10px 12px; }
.cal-legende .leg-ligne { padding: 8px 0; border-top: 1px solid var(--border); }
.cal-legende .leg-ligne:first-of-type { border-top: 0; }
.cal-legende .leg-l1 { display: flex; align-items: center; gap: 8px; }
.cal-legende .leg-l2, .cal-legende .leg-l3 { margin-left: 22px; }
.cal-legende .leg-l3 { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.cal-legende .pastille { width: 14px; height: 14px; border-radius: 4px; flex: 0 0 auto; }
.cal-legende .leg-nom { font-weight: 600; color: inherit; text-decoration: none; }
.cal-legende .leg-nom:hover { text-decoration: underline; }

/* Date de voyage personnalisée : même gabarit que les listes au-dessus. */
.jt-date input { font-size: 12px; padding: 2px 6px; }

/* Étape repliable : une ligne de résumé qui tient tout entière, le détail dessous.
   Le résumé reste lisible replié comme déplié — c'est lui qu'on parcourt. */
.etape-resume { display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; padding: 2px 0 6px; cursor: pointer; text-align: left;
  color: inherit; font: inherit; flex-wrap: wrap; }
.etape-chevron { flex: 0 0 auto; font-size: 11px; color: var(--text-muted);
  transition: transform .15s; }
.etape-card.pliee .etape-chevron { transform: rotate(-90deg); }
.etape-card.pliee .etape-resume { padding-bottom: 0; }
.etape-resume-nom { font-weight: 700; font-size: 15px; padding-left: 8px; }
.etape-resume-dates { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.etape-resume-fin { margin-left: auto; display: flex; gap: 4px; align-items: center;
  flex-wrap: wrap; }
@media (max-width: 820px) {
  .etape-resume-fin { margin-left: 0; }
  .etape-resume-nom { font-size: 14px; }
}

/* Calendrier nominatif du projet : formation et jour de voyage se distinguent de
   la présence ordinaire sans qu'on ait à lire une légende. */
.pp-gen-form { border: 1px dashed rgba(255,255,255,.85); }
.pp-gen-voyage { opacity: .72; border: 1px dotted rgba(0,0,0,.35); }

/* Chiffrage d'une formation : pastille compacte, panneau replié au clic. */
.fc-dd { display: inline; position: relative; }
.fc-dd > summary { list-style: none; cursor: pointer; }
.fc-dd > summary::-webkit-details-marker { display: none; }
.fc-badge { font-size: 10px; font-weight: 700; border-radius: 20px; padding: 0 6px;
  background: rgba(0,0,0,.08); color: var(--text-muted); }
.fc-dd[open] > .fc-badge { background: var(--accent); color: var(--accent-contrast); }
.fc-form { position: absolute; z-index: 40; top: 20px; left: 0; min-width: 250px;
  display: flex; flex-direction: column; gap: 6px; padding: 10px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  box-shadow: 0 8px 24px rgba(0,0,0,.14); }
.fc-mode { font-size: 12px; font-weight: 600; display: flex; align-items: center;
  gap: 6px; margin: 0; flex-wrap: wrap; }
.fc-mode input[type=text] { width: 74px; font-size: 12px; padding: 2px 6px; }
.fc-mode input[type=text]:disabled { opacity: .4; }

/* Horaire de l'étape : même pastille discrète que celle des besoins. */
.et-horaire { display: inline; }
.et-horaire > summary { cursor: pointer; list-style: none; font-size: .78rem;
  padding: 2px 6px; border-radius: 6px; color: var(--text-muted); }
.et-horaire > summary::-webkit-details-marker { display: none; }
.et-horaire[open] > summary { color: var(--accent); font-weight: 600; }

/* Horaire PROPRE À LA PERSONNE : l'horloge seule ne dit pas qu'il s'agit d'une
   exception. Le triangle le dit — sans lui, on croirait la consigne générale. */
.horaire-perso { color: var(--warning); font-weight: 600; white-space: nowrap; }

/* Compétences d'une étape prédéfinie. Le panneau s'ouvre DANS la cellule : le
   tableau défile horizontalement, une surcouche absolue s'y faisait couper net. */
.ec-dd > summary { cursor: pointer; list-style: none; font-size: 12px;
  padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); white-space: nowrap; display: inline-block; }
.ec-dd > summary::-webkit-details-marker { display: none; }
.ec-dd > summary::after { content: " ▾"; opacity: .6; }
.ec-dd[open] > summary { border-color: var(--accent); color: var(--accent); }
.ec-panel { margin-top: 6px; max-height: 260px; overflow-y: auto; padding: 6px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface); }
.ec-chercher { width: 100%; font-size: 12px; padding: 3px 7px; margin-bottom: 6px; }
.ec-groupe { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted); font-weight: 700; margin: 6px 2px 2px; }
.ec-opt { display: flex; align-items: center; gap: 7px; padding: 3px 4px; margin: 0;
  font-size: 12px; font-weight: 400; cursor: pointer; }
.ec-opt input { width: auto; margin: 0; }
.ec-vide { font-size: 12px; color: var(--text-muted); margin: 6px 2px; }
/* Les pastilles NOMMENT ce qui est choisi, le résumé se contente de compter :
   trois intitulés bout à bout ne tiennent dans aucune colonne de tableau. */
.ec-puces { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.ec-puce { font-size: 11px; background: var(--bg-alt, rgba(0,0,0,.06));
  border-radius: 20px; padding: 1px 8px; }

/* Besoins pré-remplis à la création d'une étape : retirables d'un clic. */
.besoins-pre { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 8px; }
.besoin-pre { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  border: 1px dashed var(--accent); border-radius: 20px; padding: 2px 6px 2px 10px; }

/* Jour de VOYAGE : il peut tomber hors des jours travaillés. Le liseré plein le
   distingue de la formation (pointillé) sans qu'on ait à lire une légende. */
/* Fond OPAQUE, pas transparent : la pastille passe désormais par-dessus les barres
   d'étape, et un fond transparent y rendait le nom illisible sur la couleur. */
.pp-count-voyage { background: var(--surface); color: var(--text-muted);
  border: 1px solid var(--border); max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }


/* Période d'une personne dans une étape : la pastille ne s'allume que si elle
   diffère de l'étape — répéter les mêmes dates pour tout le monde n'apprend rien. */
.pm-dd { display: inline; position: relative; }
.pm-dd > summary { list-style: none; cursor: pointer; }
.pm-dd > summary::-webkit-details-marker { display: none; }
.pm-badge { font-size: 11px; border-radius: 20px; padding: 0 5px; opacity: .7;
  white-space: nowrap; }
.pm-badge.on { background: var(--accent); color: var(--accent-contrast); opacity: 1;
  font-weight: 600; }
.pm-form { position: absolute; z-index: 40; top: 20px; left: 0; min-width: 230px;
  display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-end; padding: 10px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  box-shadow: 0 8px 24px rgba(0,0,0,.14); }
.pm-form label { font-size: 11px; font-weight: 600; display: flex;
  flex-direction: column; gap: 2px; margin: 0; }
.pm-form input { font-size: 12px; padding: 2px 6px; }

/* ALLER / RETOUR : le même avion, tourné d'un demi-tour pour le retour. L'emoji
   pointe le nez en haut à droite : tel quel il DÉCOLLE (aller), retourné à 180° il
   pointe le nez en bas à gauche, il ATTERRIT (retour). Une simple symétrie ne
   suffisait pas — elle mettait le nez en haut à gauche, ce qui monte encore. */
.avion { display: inline-block; }
.avion-retour { transform: rotate(180deg); }
/* Dans la case, l'aller se cale à GAUCHE et le retour à DROITE : quand un même
   jour porte les deux, on les sépare d'un coup d'œil sans les lire. */
/* UNE LIGNE PAR SENS : l'aller au-dessus, calé à gauche ; le retour en dessous,
   calé à droite. Côte à côte, deux noms de personne se chassent l'un l'autre dans
   une case de calendrier et se tronquent tous les deux. */
/* PLAQUÉS EN BAS DE LA CASE (`order`), et AU-DESSUS de tout le reste (`z-index`) :
   posés dans le flux au milieu de la case, les avions se faisaient recouvrir par
   les barres d'étape — on cherchait un départ là où on ne voyait qu'une étape. */
.pp-voyages { order: 9; position: relative; z-index: 3;
  display: flex; flex-direction: column; gap: 2px; width: 100%; min-width: 0;
  /* `align-self: stretch` : la case est elle-même un conteneur flex en colonne, et
     sans cela le bloc se réduisait à la largeur de son contenu — l'alignement
     gauche/droite n'avait alors plus aucune place pour s'exprimer. */
  align-self: stretch; }
.pp-voyages .pp-count-voyage { align-self: flex-start; max-width: 100%; margin: 0; }
.pp-voyages .pp-count-voyage.retour { align-self: flex-end; margin: 0; }

/* Pastille de voyage cliquable : elle mène à la personne concernée. */
[data-voyage] { cursor: pointer; }
[data-voyage]:hover { border-color: var(--accent); color: var(--accent); }

/* Surlignage PROVISOIRE d'une personne visée depuis le calendrier : il sert à la
   retrouver, pas à marquer sa fiche — il s'efface de lui-même. */
.logi-card.logi-surligne { box-shadow: 0 0 0 3px var(--accent); transition: box-shadow .4s; }

/* MÊME CONVENTION PARTOUT : l'aller se cale à gauche, le retour à droite, jusque
   dans les barres de projet des plannings du personnel. Une convention qui change
   d'un écran à l'autre oblige à la réapprendre à chaque fois. */
.avion-aller { margin-right: auto; }
.avion-retour { margin-left: auto; }

/* Déjà booké ailleurs : le triangle se lit comme un avertissement là où « occupé »
   seul passait pour une nuance. On peut toujours choisir la personne — on ne le
   fera simplement pas sans le savoir. */
.deja-booke { color: var(--warning); }
.chk-person.chk-occupe { border-left: 2px solid var(--warning); padding-left: 5px; }

/* Déplacement dans la feuille de route du mois : la date, avec l'avion orienté. */
.mois-voyage { font-size: 12px; white-space: nowrap; border: 1px dashed var(--border);
  border-radius: 20px; padding: 0 7px; margin-right: 4px; }


/* ------------------------------------------------------------------------- */
/* AVIONS DES PLANNINGS DU PERSONNEL : plaqués en BAS de la case et au PREMIER
   PLAN. Sans règle propre, l'avion restait dans le flux, sous les barres
   (`.pg-bar` z-index 2, `.pl-span` z-index 3) : il disparaissait derrière le
   booking, c'est-à-dire exactement là où il y en a toujours un. Aller à gauche,
   retour à droite — la même convention que partout ailleurs. */
/* EN BAS DE LA CASE, ET AU PREMIER PLAN (z-index 4, au-dessus des barres de
   booking en 2 et 3). Sans fond : l'avion se pose sur le jour, pas dans un badge.
   Aller à gauche, retour à droite — la convention de toute l'application. */
/* LA VILLE EST TOUJOURS AFFICHÉE, si petite soit-elle. Posée À CÔTÉ de l'avion,
   elle disparaissait dès que les colonnes se resserraient : sur une vue 3 mois une
   case fait 17 px, l'avion en prend 12, il ne restait rien. Posée EN DESSOUS, elle
   dispose de la case entière — minuscule, mais présente, ce qui vaut mieux que
   trois points de suspension. Le survol la donne toujours en entier, avec le sens.
   Aller à gauche, retour à droite : quand un jour porte les deux, chacun tient sa
   moitié au lieu de se recouvrir. */
/* Un jour peut porter PLUSIEURS mouvements : on rentre d'un chantier et l'on
   repart vers un autre dans la même journée. Ils se partagent alors la largeur de
   la case, chacun tronquant son nom de ville plutôt que de recouvrir le voisin. */
.pg-travels { position: absolute; left: 1px; right: 1px; bottom: 0; z-index: 4;
  display: flex; justify-content: space-between; gap: 2px; pointer-events: none; }
.pg-travels > .pg-travel { flex: 0 1 auto; }
.pg-travel { display: flex; flex-direction: column; align-items: flex-start;
  min-width: 0; line-height: 1; font-size: 9px; }
.pg-travel-retour { align-items: flex-end; margin-left: auto; }
.pg-travel .avion { text-shadow: 0 0 2px var(--surface), 0 0 3px var(--surface); }
.pg-travel-ville { font-size: 7px; font-weight: 700; letter-spacing: -.3px;
  color: var(--text); background: var(--surface); border-radius: 2px;
  max-width: 100%; margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* VOYAGE, PAS CHANTIER. Le jour de route garde la couleur de son projet — savoir
   pour QUI l'on voyage fait partie de la réponse — mais il se dessine EN CREUX :
   fond translucide, contour tireté. Plein, il se lisait comme un jour travaillé et
   la barre du chantier semblait commencer trois jours trop tôt. La case noire qui
   tenait ce rôle est retirée : elle écrasait la ligne pour une nuance de statut. */
/* JOUR DE ROUTE : ni booké, ni libre. La personne n'est pas sur un chantier —
   aucune barre ne s'y pose, sinon l'etape durerait un jour de plus — mais elle
   n'est pas davantage disponible : la peindre en vert dans le mode « Dispos »
   enverrait la booker le jour où elle est dans un avion. Case neutre, avion posé
   dessus : le trajet se signale par son logo, pas en prolongeant le travail. */
.pg-cell.pg-enroute { background: var(--surface); }
.pg-table.dispo-mode .pg-cell.pg-enroute { background: rgba(127, 127, 127, .10); }


/* PASTILLE NOIRE SOUS CHAQUE AVION. Un emoji posé à nu prend la couleur de ce qu'il
   survole : sur une barre d'étape, sur un booking coloré ou sur un fond de case
   clair, il se dissolvait — on ne le trouvait qu'en le cherchant. Le disque noir le
   détache PARTOUT de la même façon, et fait du voyage un repère qu'on reconnaît
   sans lire. Une même règle pour tous les écrans : deux traitements différents
   pour le même signe, et il faudrait le réapprendre à chaque page. */
/* Fiche personnel : la case est large, l'avion et la ville tiennent côte à côte. */
.fiche-cal-cell .pg-travels { left: 4px; right: 4px; bottom: 3px; }
.fiche-cal-cell .pg-travel { flex-direction: row; align-items: center; gap: 3px;
  font-size: 11px; }
.fiche-cal-cell .pg-travel-retour { flex-direction: row-reverse; }
.fiche-cal-cell .pg-travel-ville { font-size: 9.5px; margin-top: 0; }
.pg-travel.avion-retour, .pp-travel.avion-retour { transform: rotate(180deg); }

/* Recherche rapide du planning global : un champ, pas un menu. La croix
   n'apparaît qu'une fois qu'il y a quelque chose à effacer. */
.pg-quick { position: relative; display: flex; align-items: center; }
.pg-quick input {
  width: 210px; margin: 0; padding: 7px 26px 7px 10px; font-size: 13px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text);
}
.pg-quick input:focus { border-color: var(--accent); outline: none; }
.pg-quick input::-webkit-search-cancel-button { display: none; }
/* LA CROIX D'EFFACEMENT, ET ELLE SEULE. Écrite « .pg-quick button », la règle
   attrapait aussi les lignes de la liste de résultats — des <button> du même
   conteneur —, qui se retrouvaient empilées en absolu à 4 px du bord droit : six
   noms superposés dans dix pixels de haut, donc rien de lisible. Une règle qui vise
   un élément le NOMME ; « tous les boutons d'ici » attrape ceux qu'on ajoutera
   demain, et l'on cherche alors la faute dans le code neuf. */
#pg-quick-clear {
  position: absolute; right: 4px; border: none; background: none; cursor: pointer;
  color: var(--text-muted); font-size: 13px; line-height: 1; padding: 4px 5px;
}
#pg-quick-clear:hover { color: var(--accent); }
@media (max-width: 820px) { .pg-quick input { width: 100%; } .pg-quick { flex: 1 1 100%; } }

/* Trace d'une notification : qui l'a acquittée, qui l'a archivée. Discrète sous
   le texte — c'est une réponse à « qui a vu ça ? », pas une information de tous
   les jours, mais elle doit être lisible sans survoler quoi que ce soit. */
.notif-trace { display: block; margin-top: 3px; font-size: 11px; color: var(--text-muted); }
.notif-trace strong { font-weight: 600; color: var(--text); }

/* Voyages dans le résumé des missions : une pastille par mouvement, l'avion tourné
   selon le sens. Assez discret pour ne pas concurrencer les dates de mission juste
   au-dessus, assez net pour qu'on les distingue d'elles. */
.resume-voyages { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.resume-voy { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px;
  color: var(--text-muted); border: 1px solid var(--border); border-radius: 20px;
  padding: 1px 9px; white-space: nowrap; }
.resume-voy .avion, .resume-voy .vehic { display: inline-block; font-size: 11px; line-height: 1; }

/* UN RÔLE SE LIT COMME UN OBJET, pas comme un titre de plus. Écrits dans la même
   graisse que les intertitres de la page, les rôles créés se fondaient dans le
   texte : on ne voyait plus d'un coup d'œil combien il y en avait, ni où finissait
   l'un et où commençait l'autre — au point d'en recréer un qui existait déjà. Une
   barre nommée, encadrée, avec son liseré et son compte de comptes. */
.role-bloc { margin-bottom: 8px; }
.role-bloc > summary { cursor: pointer; list-style: none; display: flex;
  align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border: 1px solid var(--border); border-left: 4px solid var(--accent);
  border-radius: var(--radius); background: var(--surface); }
.role-bloc > summary:hover { border-color: var(--accent); }
.role-bloc[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0;
  margin-bottom: -1px; }
.role-bloc > summary::-webkit-details-marker { display: none; }
.role-bloc > summary::before { content: "▸"; color: var(--text-muted); font-size: 11px; }
.role-bloc[open] > summary::before { content: "▾"; }
.role-nom { font-weight: 700; font-size: 15px; color: var(--text); }
/* Le nombre de comptes est ce qu'on vient vérifier le plus souvent : il se lit sans
   ouvrir. « 0 compte » se distingue — un rôle que personne ne porte ne protège rien. */
.role-comptes { font-size: 11.5px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-muted); white-space: nowrap; }
.role-comptes.vide { border-style: dashed; }
.role-desc { font-size: 12px; color: var(--text-muted); flex: 1 1 200px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.role-ouvrir { margin-left: auto; font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.role-bloc[open] .role-ouvrir { visibility: hidden; }
/* Ouvert, le panneau des droits prolonge la barre : même largeur, coins du haut
   carrés, collé dessous. Sinon il paraît appartenir à autre chose qu'au rôle
   qu'on vient d'ouvrir. */
.role-carte { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0;
  border-left: 4px solid var(--accent); }

/* Ligne « départ / retour » de la logistique : les dates et heures qui décident des
   repas. Une date REPRISE du planning se distingue d'une date saisie ici — sinon on
   ne sait pas laquelle des deux fait foi. */
.logi-voyage { margin-top: 6px; }
.logi-voy-lbl { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.logi-voyage input[type="date"] { width: auto; min-width: 140px; }
.logi-voyage input[type="time"] { width: auto; min-width: 88px; }
.logi-herite { border-style: dashed; color: var(--text-muted); }
.logi-repas { font-size: 12px; font-weight: 600; white-space: nowrap; cursor: help;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 20px;
  padding: 2px 10px; }
.logi-approx { color: var(--warning); font-weight: 800; margin-left: 2px; }

/* Aide détaillée d'un bloc : un paragraphe sous la ligne qu'elle explique, jamais
   à côté — une aide qui ne touche pas ce dont elle parle oblige à faire le lien. */
.logi-aide { margin: 4px 0 0; line-height: 1.45; }

/* Véhicule du trajet : l'icône dit le MOYEN, l'orientation dit le SENS. L'avion se
   retourne (nez en bas) comme partout ailleurs dans l'application ; ce qui roule ou
   marche se regarde dans un miroir — faire pivoter une voiture la mettrait sur le
   toit, et le sens ne se lirait plus. */
.vehic { display: inline-block; }
/* Les véhicules du jeu d'emojis regardent tous à GAUCHE au repos : c'est donc le
   DÉPART qu'on retourne pour le faire pointer à droite, le retour restant tel quel.
   L'avion, lui, part déjà vers le haut à droite : c'est son RETOUR qui pivote. */
.vehic-depart { transform: scaleX(-1); }
.vehic-retour-vol { transform: rotate(180deg); }

/* Nature d'un document joint, et ce qui manque encore. Le rappel est une INVITE,
   pas une alerte : il n'y a rien de cassé, il reste une pièce à fournir. */
.doc-nature { margin-right: 3px; }
.logi-manque { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.doc-a-faire { font-size: 11.5px; color: var(--warning); border: 1px dashed var(--warning);
  border-radius: 20px; padding: 1px 9px; white-space: nowrap; }

/* Liste d'accès d'un document : elle s'ouvre AU BOUT de la ligne du document, pas
   sur un autre écran — on décide qui voit quoi en regardant la pièce concernée. */
.acces-dd { position: relative; display: inline-block; }
.acces-dd > summary { list-style: none; cursor: pointer; }
.acces-dd > summary::-webkit-details-marker { display: none; }
.acces-panel { position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  min-width: 280px; max-width: 360px; max-height: 340px; overflow-y: auto;
  padding: 12px; text-align: left; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 10px 26px rgba(0,0,0,.28); }
.acces-tete { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.acces-tout { margin-left: auto; display: flex; gap: 8px; }
.acces-liste { display: flex; flex-direction: column; gap: 2px; }

/* Carte de transport : une ligne par carte, le numéro en évidence — c'est lui
   qu'on vient chercher, le reste n'est là que pour le qualifier. */
.carte-ligne { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 7px 0; border-top: 1px solid var(--border); }
.carte-ligne:first-of-type { border-top: 0; }
.carte-cie { font-weight: 600; }
.carte-num { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 13px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 6px; padding: 1px 8px; user-select: all; }

/* Cartes de fidélité rappelées dans le booking : le numéro est sélectionnable d'un
   clic, c'est ce qu'on vient y copier au moment de réserver. */
.logi-cartes { display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin-top: 6px; }
.carte-chip { font-size: 11.5px; color: var(--text-muted); border: 1px solid var(--border);
  border-radius: 20px; padding: 1px 9px; white-space: nowrap; }
.carte-chip b { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  color: var(--text); user-select: all; }

/* Un avion cliquable doit se voir cliquable : sans cela on ne pense pas à essayer. */
.pg-travel[data-voyage] { pointer-events: auto; cursor: pointer; }
.pg-travel[data-voyage]:hover { filter: brightness(1.25); }

/* Suggestions de compagnies : sous le champ, jamais à côté. Une liste séparée
   obligerait à choisir à un endroit ce qu'on saisit à un autre. */
.cie-suggest { position: absolute; left: 0; top: 100%; z-index: 70;
  min-width: 100%; max-width: 340px; max-height: 260px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 10px 26px rgba(0,0,0,.28); }
.cie-item, .cie-vide { padding: 5px 10px; font-size: 13px; font-weight: 400; }
.cie-item { cursor: pointer; }
.cie-item:hover { background: var(--surface-2); color: var(--accent); }
.cie-vide { color: var(--text-muted); font-style: italic; }

/* Créneau de supervision : une ligne par présence, l'horaire d'abord — c'est par
   lui qu'on cherche, pas par le nom de celui qui la tient. */
.sup-creneau { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 6px 0; border-top: 1px solid var(--border); }
.sup-creneau:first-of-type { border-top: 0; }
.sup-heure { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 108px; }

/* INDISPO SUR UN JOUR BOOKÉ : la croix ne suffit pas. Elle se lit comme les autres
   croix, alors que ce cas-là est le seul qui demande une décision — quelqu'un est
   promis à un projet un jour où il s'est déclaré absent. Le fond rouge vif le sort
   du lot : on le repère en balayant la ligne, sans avoir à comparer des croix. */
.pg-cell.pg-conflit-indispo { background: rgba(214, 69, 69, .55) !important; }
.pg-cell.pg-conflit-indispo::after { opacity: 1; }
.fiche-cal-cell.pg-conflit-indispo { background: rgba(214, 69, 69, .30) !important; }

/* Rôle métier sur la ligne d'un compte : la liste et la création côte à côte, pour
   ne pas avoir à quitter la page quand le rôle voulu n'existe pas encore. */
.compte-role { display: flex; gap: 6px; align-items: center; margin: 0; }
.compte-role select { width: auto; min-width: 150px; font-size: 12.5px; }
.compte-role input { width: 130px; font-size: 12.5px; }

/* Fenêtre de chargement d'une préconfiguration : un bouton tant qu'elle est fermée,
   une carte une fois ouverte. Repliée par défaut — on ne charge un modèle qu'une
   fois par projet, elle n'a pas à occuper la page le reste du temps. */
.preconfig-fenetre > summary { display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none; }
.preconfig-fenetre > summary::-webkit-details-marker { display: none; }

/* RÉGLAGES D'UNE LIGNE DE TÂCHE : un seul volet, trois blocs, un bouton. Deux
   volets séparés (trombone, sablier) obligeaient à ouvrir l'un puis l'autre pour
   voir ce que porte la ligne, et à enregistrer deux fois. */
.tache-reglages { margin-left: auto; }
.tache-reglages > summary { cursor: pointer; list-style: none; font-size: 14px; opacity: .55; }
.tache-reglages > summary::-webkit-details-marker { display: none; }
.tache-reglages[open] > summary { opacity: 1; }
.tache-reglages > form { flex-basis: 100%; margin-top: 6px; }
/* Chaque bloc porte SON intitulé à gauche : sans lui, six champs alignés ne
   disaient plus lequel réglait quoi. */
.tr-bloc { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 7px 10px; margin-bottom: 4px; border-radius: 8px;
  background: var(--surface-2, rgba(127,127,127,.06)); }
.tr-titre { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-muted); min-width: 72px; }
.tr-bloc .ech-form { margin: 0; padding: 0; background: none; }
/* Ajout d'une tâche : le nom sur une ligne, le reste replié. */
.tache-add { display: block; }
.ta-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ta-plus > summary { cursor: pointer; font-size: 12px; color: var(--text-muted);
  margin-top: 8px; }
.ta-plus[open] > summary { margin-bottom: 6px; }
/* Partager : même pastille que « Ouvrir », c'est la même famille de gestes. */
.tache-partage { display: inline-flex; align-items: center; gap: 4px; margin: 0; }
.tache-partage input[type=email] { font-size: 11.5px; padding: 1px 6px; width: 150px; margin: 0; }
button.tache-piece { background: none; cursor: pointer; }
.tache-contacts { font-size: 11px; color: var(--text-muted); margin-left: 6px; cursor: help; }

/* Liste d'adresses : une ligne par adresse, « + » pour en ajouter. Un champ unique
   à séparer par des virgules demandait de connaître la convention, de la respecter,
   et ne disait rien quand deux adresses se retrouvaient collées en une seule. */
.contacts-liste { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.contact-ligne { display: flex; align-items: center; gap: 4px; }
.contact-ligne input[type=email] { margin: 0; min-width: 240px; }
.contact-moins { border: 1px solid var(--border); background: none; color: var(--text-muted);
  border-radius: 6px; cursor: pointer; line-height: 1; padding: 4px 8px; }
.contact-moins:hover { border-color: var(--danger); color: var(--danger); }
.contact-plus { align-self: flex-start; }
/* Le compte de contacts d'une tâche : les adresses se déplient au survol, EN
   COLONNE — trois adresses sur une ligne d'infobulle ne se lisent pas. */
.tache-contacts.pct-survol { position: relative; }

/* TROIS BULLES NOMMÉES sur une ligne de tâche : Deadline, Pièces, Alerte. Un volet
   unique marqué d'un seul pictogramme n'annonçait pas ce qu'on allait y trouver, et
   obligeait à traverser l'échéance pour corriger une adresse. */
.tache-boutons { display: flex; gap: 4px; margin-left: auto; align-items: center; }
.tache-volet > summary { list-style: none; }
.tache-volet > summary::-webkit-details-marker { display: none; }
/* UNE BULLE FAIT LA TAILLE DE SON TEXTE. Le principe par défaut, et le seul qui
   tienne hors d'une grille : « 🗑 » n'a pas besoin de la largeur de « + Pôle dans ce
   département », et ce dernier ne se laisse pas tronquer pour tenir dans la sienne. */
.tr-bulle { cursor: pointer; font-size: 11px; white-space: nowrap;
  padding: 2px 10px; border-radius: 999px; border: 1px solid var(--border);
  color: var(--text-muted); background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; }
/* SAUF SUR UNE LIGNE DE TÂCHE, où elles forment une colonne : là, « Deadline » est
   plus long qu'« Alerte », et « Alerte · 3 » plus long qu'« Alerte » — sans largeur
   commune, les bulles ondulent d'une ligne à la suivante. La contrainte appartient
   à la grille, pas à la bulle : ailleurs, elle n'a aucune raison de s'appliquer. */
.tache-boutons .tr-bulle { width: 92px; }
.tr-bulle:hover { border-color: var(--accent); color: var(--accent); }
.tache-volet[open] > summary.tr-bulle { border-color: var(--accent);
  color: var(--accent); font-weight: 600; }
/* Le panneau se déplie SOUS la ligne, sur toute sa largeur : à côté de la bulle il
   n'aurait pas la place d'un champ de date et d'un menu. */
.tache-volet > form,
.tache-volet > .tache-panneau { position: absolute; left: 0; right: 0; z-index: 20;
  margin-top: 6px; padding: 10px 12px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 10px 26px rgba(0,0,0,.28); }
/* DANS UN PANNEAU, LES BLOCS SE SUIVENT. Sans cette remise à plat, les formulaires
   qu'il contient hériteraient du positionnement absolu ci-dessus et se poseraient
   tous au même endroit — l'ajout de version par-dessus le document existant. */
.tache-panneau > form { position: static; margin: 0; padding: 0; background: none;
  border: 0; border-radius: 0; box-shadow: none; }
/* Un volet long — document, historique, ajout — doit pouvoir défiler plutôt que
   sortir de l'écran : on ne referme pas une liste de dix versions à l'aveugle. */
.tache-panneau { max-height: 70vh; overflow-y: auto; }
.tache { position: relative; }
.tr-actions { display: flex; gap: 8px; margin-top: 4px; }

/* Document et contacts d'une tâche : hors du libellé, donc hors de la case à
   cocher. Un <label> sans « for » s'attache au premier bouton qu'il contient :
   survoler « Ouvrir » allumait « Partager », et cliquer l'un pouvait cocher la
   tâche. Ils vivent maintenant à côté du nom, pas dedans. */
.tache-actions { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.tache.done .tache-actions { text-decoration: none; }

/* Tâche cochée mais pas encore clôturée : un état d'attente, ni ouvert ni fermé.
   Le même jaune que les échéances urgentes — il reste quelque chose à faire, mais
   ce n'est plus au même de le faire. */
.tache-ech.attente { color: var(--warning, #c77700); border-color: var(--warning, #c77700); }
.tache-clore:hover { border-color: var(--success); color: var(--success); }

/* L'ÉTAT D'UNE TÂCHE A UNE PLACE FIXE, juste avant les trois bulles. « Clôturer » et
   « Rouvrir » vivaient au milieu des liens et des pièces jointes : ils sautaient
   d'une ligne à l'autre selon qu'il y avait un document, et — n'étant visibles que
   des responsables — décalaient toute la ligne pour eux seuls. La colonne garde sa
   largeur même vide : les bulles restent alignées d'une ligne à l'autre. */
/* L'ÉTAT EN COLONNE FIXE : « ✓ 06/08/2026 » et « ⏸ à clôturer » n'ont pas la même
   longueur, et sans largeur imposée c'était la DATE qui décidait où s'arrêtent les
   bulles — donc un alignement différent à chaque ligne. */
.tache-etat { display: flex; justify-content: flex-end; align-items: center;
  padding-left: 14px; border-left: 1px solid var(--border); overflow: hidden; }
/* TOUS LES ÉTATS À LA MÊME LARGEUR : « ✓ 06/08/2026 » est plus long que
   « ⏸ à clôturer », et deux pastilles vertes de tailles différentes d'une ligne à
   l'autre donnent exactement l'effet d'escalier qu'on cherche à supprimer. */
.tache-etat > *, .tache-etat form { width: 100%; }
.tache-etat .tache-ech { margin-left: 0; width: 100%; box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  overflow: hidden; white-space: nowrap; }
.tache-boutons { margin-left: 0; justify-content: flex-end; }
/* La pastille EST le bouton : elle dit l'état, et se retourne au survol pour dire
   ce qu'un clic ferait. Deux objets côte à côte auraient dit deux fois la même
   chose et pris deux fois la place. */
button.tache-ech.agit { cursor: pointer; font: inherit; font-size: 11px;
  font-weight: 700; display: inline-flex; align-items: center; }
button.tache-ech.agit .etat-survol { display: none; }
button.tache-ech.agit:hover .etat-repos, button.tache-ech.agit:focus .etat-repos { display: none; }
button.tache-ech.agit:hover .etat-survol, button.tache-ech.agit:focus .etat-survol { display: inline; }
button.tache-ech.attente.agit:hover { background: var(--success); border-color: var(--success); color: #fff; }
button.tache-ech.valide.agit:hover { background: var(--surface); color: var(--text-muted);
  border-color: var(--border); }

/* Bulle « Pièces » PLEINE : une pièce est attachée. Le vert dit « il y a quelque
   chose » sans qu'on ait à ouvrir le volet ni à chercher le lien dans la ligne. */
.tr-bulle.pleine { border-color: var(--success); color: var(--success); font-weight: 600; }
.tache-volet[open] > summary.tr-bulle.pleine { background: var(--success); color: #fff; }
/* Rangement à la main : deux flèches minuscules, collées, qui ne prennent pas la
   place d'un bouton. Elles n'apparaissent que sur les tâches sans échéance. */
.tache-rang { display: inline-flex; flex-direction: column; gap: 1px; }
/* La gouttière des flèches existe même quand la tâche est datée (donc non
   rangeable) : sinon les bulles de cette ligne-là glisseraient de 14 px. */
.tache-boutons { display: flex; align-items: center; gap: 4px; }
.tache-boutons::before { content: ""; }
.tache-rang, .tache-boutons > .rang-vide { width: 14px; flex: 0 0 14px; }
.rang-fleche { border: none; background: none; cursor: pointer; padding: 0 3px;
  line-height: .9; font-size: 8px; color: var(--text-muted); }
.rang-fleche:hover { color: var(--accent); }

/* Adresses alertées : dépliées EN COLONNE au survol de la bulle. Sur une seule
   ligne d'infobulle, trois adresses se lisent mal et l'on n'y repère pas celle qui
   manque — c'est pourtant ce qu'on vient vérifier avant de partager. */
.tr-bulle { position: relative; }
.tr-pop { position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  display: none; flex-direction: column; gap: 3px; min-width: 210px; max-width: 320px;
  padding: 9px 11px; text-align: left; white-space: nowrap; cursor: default;
  background: var(--surface); color: var(--text); font-weight: 400; font-size: 12px;
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 10px 26px rgba(0,0,0,.3); }
.tr-pop b { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); font-weight: 700; }
.tr-bulle:hover .tr-pop, .tr-bulle:focus .tr-pop { display: flex; }
/* Volet ouvert : la liste dépliée ferait doublon avec le champ qu'on est en train
   de remplir juste en dessous. */
.tache-volet[open] .tr-pop { display: none !important; }

/* LE NOM D'UNE TÂCHE SE CLIQUE POUR ÊTRE RENOMMÉ. Rien ne le laissait deviner :
   le champ dormait dans un volet nommé « Deadline ». Un pointeur et un soulignement
   discret au survol suffisent à dire qu'il y a quelque chose à faire ici. */
.tache-nom.renommable { cursor: text; border-radius: 3px; padding: 0 2px; margin: 0 -2px; }
.tache-nom.renommable:hover { background: var(--surface-2, rgba(127,127,127,.14));
  box-shadow: inset 0 -1px 0 var(--text-muted); }
/* Une adresse, sa case de rappels, sa croix : tout sur la même ligne. */
.contact-rappel { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
  font-size: 11px; color: var(--text-muted); cursor: pointer; user-select: none; }
.contact-rappel input { margin: 0; }
.tr-pop i { font-style: normal; font-size: 10.5px; color: var(--text-muted);
  border-top: 1px solid var(--border); padding-top: 5px; margin-top: 2px; }

/* ─── CARNET D'HÉBERGEMENTS ET SÉJOURS ─────────────────────────────────────── */
/* Les champs d'une fiche du carnet : deux colonnes, l'adresse et les notes sur
   toute la largeur — une adresse coupée en deux se relit mal. */
.heb-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px 14px; margin: 10px 0; }
.heb-grille label { display: flex; flex-direction: column; gap: 3px; font-size: 12px;
  color: var(--text-muted); }
.heb-grille input, .heb-grille select { width: 100%; box-sizing: border-box; }
.heb-grille .heb-large { grid-column: 1 / -1; }
.heb-volet > summary { list-style: none; cursor: pointer; }
.heb-volet > summary::-webkit-details-marker { display: none; }
.heb-form { border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px 14px; margin-top: 8px; background: var(--surface); }

/* Un séjour se lit d'un coup d'œil : où, et quand. */
.sejours { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 6px 0 2px; }
.sejour-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); }
.sejour-chip em { font-style: normal; color: var(--text-muted); }
/* --- LES ALLERS-RETOURS INTERMÉDIAIRES ------------------------------------
   Même rangée de pastilles que les séjours : ce sont deux réponses à la même
   question — où est cette personne, et quand. Mais le SENS se lit à la couleur
   avant de se lire à la flèche : sur une exploitation de deux mois, une ligne de
   douze pastilles ne se déchiffre pas date par date. */
.voyages { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0 2px; }
.voyage-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); font-variant-numeric: tabular-nums; }
.voyage-chip em { font-style: normal; color: var(--text-muted); }
.voyage-aller { border-color: var(--accent); }
.voyage-retour { border-color: var(--success, #1a9d63); }
/* Le jour choisi pour un voyage : plein, comme les bornes d'une période — on ne
   distingue pas deux états d'un même calendrier par deux nuances de gris. */
.plage-jour.actif { background: var(--accent); color: #fff; border-color: var(--accent); }
/* --- LE VOLET D'UN TRAJET, EN QUATRE COLONNES -----------------------------
   Empilé, il faisait une fenêtre plus haute que l'écran : on saisissait le sens en
   haut, on descendait chercher « Enregistrer », et l'on ne voyait jamais d'un coup ce
   qu'on écrivait. Or ce sont trois choses qui se décident ENSEMBLE — dans quel sens,
   quel jour, avec quelle pièce. Le sens tient une colonne étroite (deux réponses),
   les détails la part large, la pièce la dernière. */
/* DEUX CLASSES, POUR PASSER DEVANT `.sejour-form`. Écrite avec la seule classe
   `.voyage-form`, la largeur était écrasée par celle du volet générique — déclarée
   plus bas dans la feuille, à spécificité égale — et le cadre restait à 620 px pour
   un contenu qui en demande 610 hors marges : la colonne de droite débordait. */
.sejour-form.voyage-form { min-width: min(700px, 92vw); max-width: min(760px, 94vw); }
/* LE CALENDRIER A SA COLONNE, il ne s'empile pas sous les champs : posé dessous, il
   rendait au volet les 70 pixels qu'on venait de lui retirer. Quatre colonnes de
   front — le sens, les détails, le mois, la pièce — et rien à faire défiler. */
.voy-cols { display: grid;
  grid-template-columns: 110px minmax(240px, 1fr) 232px;
  gap: 14px; align-items: start; }
.voy-col { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.voy-col > .tr-titre { margin-bottom: 1px; }
.voy-sens-opt { display: flex; align-items: center; gap: 6px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 8px; padding: 4px 8px; cursor: pointer; }
.voy-sens-opt:has(input:checked) { border-color: var(--accent); color: var(--accent);
  font-weight: 600; }
.voy-grille { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 8px; }
.voy-grille label { display: flex; flex-direction: column; gap: 2px; font-size: 11.5px;
  color: var(--text-muted); min-width: 0; }
/* DES CHAMPS SERRÉS, PARCE QU'IL Y EN A SEPT. Aux dimensions courantes du site, sept
   champs sur quatre rangées font à eux seuls la moitié de la hauteur du volet — et
   c'est cette hauteur-là qu'on cherche à réduire. Un champ de date n'a pas besoin de
   la même respiration qu'un champ de nom de projet : il se remplit d'un clic. */
.voy-grille input, .voy-grille select { min-width: 0; padding: 3px 7px;
  font-size: 12.5px; line-height: 1.25; }
.voy-cal input[type=text] { padding: 3px 7px; font-size: 12.5px; }
/* LE VOLET S'OUVRE VERS LE HAUT quand il n'y a pas la place dessous. Sur la dernière
   ligne de personnel, il se plaquait au bas de la page, sans un pixel d'aération —
   et l'on ne voyait ni le calendrier ni le bouton d'enregistrement. */
.sejour-volet > .sejour-form.vers-le-haut { top: auto; bottom: calc(100% + 6px); }
.voy-large { grid-column: 1 / -1; }
.voy-cal label { display: flex; flex-direction: column; gap: 2px; font-size: 11.5px;
  color: var(--text-muted); min-width: 0; }
/* RIEN NE DOIT DÉPASSER DU CADRE. Un champ de fichier porte le NOM du fichier choisi
   et prend, sans contrainte, la largeur qu'il lui faut — il sortait du volet dès
   qu'on déposait un billet au nom un peu long. La largeur vient de la colonne, pas
   du contenu. */
.voy-cal input, .voy-col input, .voy-col select { max-width: 100%; box-sizing: border-box; }
.voy-cal input[type=file] { width: 100%; font-size: 11px; }
.voy-piece-titre { margin-top: 8px; padding-top: 8px;
  border-top: 1px dashed var(--border); }
/* La bande de jours DÉFILE, elle ne s'enroule pas : enroulée sur trois lignes, elle
   redonnait au volet la hauteur qu'on vient de lui retirer. */
/* --- UN MOIS ENTIER, EN SEMAINES COMPLÈTES -------------------------------
   La bande des seuls jours du projet obligeait à la faire défiler pour trouver le 13,
   sans jamais dire si c'était un lundi ou un jeudi. Un mois posé en semaines se lit
   d'un coup d'œil : c'est la forme qu'on a en tête quand on pense « le week-end du
   12 ». Sept colonnes de largeur égale — la grille tient la colonne des lundis, ce
   qui est tout l'intérêt. */
.voy-mois { margin-top: 4px; }
.voy-mois-tete { display: flex; align-items: center; justify-content: space-between;
  gap: 6px; font-size: 12px; font-weight: 600; margin-bottom: 3px; }
.voy-mois-tete span { text-transform: capitalize; }
.voy-mois-jours { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.voy-jsem { font-size: 9px; text-align: center; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em; }
.voy-jour { border: 1px solid transparent; background: none; border-radius: 5px;
  padding: 3px 0; font-size: 11.5px; cursor: pointer; color: var(--text);
  font-variant-numeric: tabular-nums; }
.voy-jour:hover { border-color: var(--accent); }
/* Les jours DU CHANTIER se voient : c'est sur eux qu'on clique neuf fois sur dix. */
.voy-jour.du-projet { background: var(--surface-2); font-weight: 700; }
/* Ceux des mois voisins sont DESSINÉS et cliquables — un départ tombe la veille du
   chantier —, mais visiblement d'ailleurs. */
.voy-jour.voisin { color: var(--text-muted); opacity: .55; }
.voy-jour.actif { background: var(--accent); color: #fff; border-color: var(--accent);
  opacity: 1; font-weight: 700; }
@media (max-width: 860px) {
  .voyage-form { min-width: 0; }
  .voy-cols { grid-template-columns: 1fr; }
  .voy-grille { grid-template-columns: 1fr; }
}
/* UNE PASTILLE QUI S'OUVRE. Le chevron natif du navigateur casserait la forme
   arrondie ; le curseur main dit qu'il y a quelque chose derrière, et la bordure
   d'accent au survol le confirme avant le clic. */
.sejour-chip, .voyage-chip { cursor: pointer; list-style: none; }
.sejour-chip::-webkit-details-marker, .voyage-chip::-webkit-details-marker { display: none; }
details[open] > .sejour-chip, details[open] > .voyage-chip { border-color: var(--accent); }
.sejour-chip:hover, .voyage-chip:hover { border-color: var(--accent); }
/* Le retrait vit SOUS le formulaire, pas dans la pastille : on ouvre pour corriger
   neuf fois sur dix, et une croix collée au texte se clique par accident. */
/* Les pièces déjà jointes, en tête du volet : c'est ce qu'on vient vérifier avant
   d'en ajouter une — « est-ce que le billet retour y est déjà ? ». */
.voy-pieces { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 8px; }
.doc-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); }
.doc-chip a { text-decoration: none; color: inherit; }
.doc-chip:hover { border-color: var(--accent); }
/* LE RETRAIT, EN BAS DU PANNEAU ET DÉTACHÉ. On ouvre pour corriger neuf fois sur dix :
   il doit être atteignable sans être sur le chemin. Un filet le sépare de ce qui
   enregistre — deux boutons côte à côte, l'un qui garde et l'autre qui efface, se
   confondent au moment où l'on va vite. */
.voyage-retirer { margin: 10px 0 0; padding-top: 8px;
  border-top: 1px dashed var(--border); }
.voyage-retirer .lnk { color: var(--danger, #dc2626); font-size: 12px; }
.voyage-retirer .lnk:hover { text-decoration: underline; }
.sejour-x { border: none; background: none; cursor: pointer; color: var(--text-muted);
  font-size: 13px; line-height: 1; padding: 0 1px; }
.sejour-x:hover { color: var(--danger); }
.sejour-volet { position: relative; }
.sejour-volet > summary { list-style: none; }
.sejour-volet > summary::-webkit-details-marker { display: none; }
.sejour-form { position: absolute; z-index: 70; top: calc(100% + 6px); left: 0;
  min-width: 380px; max-width: min(620px, 92vw); padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 12px 30px rgba(0,0,0,.32); }
.sejour-form .sejour-adresse { width: 100%; box-sizing: border-box; }
.sejour-form .sejour-adresse:disabled { opacity: .55; }

/* LE CALENDRIER DEUX CLICS : les jours du projet, en bande. Un jour est une cible
   qu'on vise — pas un champ de date à taper, dont il faut connaître le format et
   compter soi-même les jours. */
.plage-jours { display: flex; flex-wrap: wrap; gap: 3px; margin: 6px 0; }
.plage-jour { display: flex; flex-direction: column; align-items: center; gap: 0;
  width: 34px; padding: 3px 0 4px; cursor: pointer; line-height: 1.15;
  border: 1px solid var(--border); border-radius: 6px; background: var(--surface);
  color: var(--text); font-size: 10px; }
.plage-jour .pj-num { font-size: 13px; font-weight: 700; }
.plage-jour .pj-nom, .plage-jour .pj-mois { color: var(--text-muted); font-size: 9px; }
.plage-jour:hover { border-color: var(--accent); }
.plage-jour.pris { background: color-mix(in srgb, var(--accent) 22%, transparent);
  border-color: var(--accent); }
.plage-jour.bout { background: var(--accent); color: #fff; border-color: var(--accent); }
.plage-jour.bout .pj-nom, .plage-jour.bout .pj-mois { color: rgba(255,255,255,.8); }
.plage-dit { margin: 2px 0 6px; }

/* DE QUELLE TÂCHE PARLE-T-ON ? Trois volets ouverts au fil d'une liste de trente
   lignes se ressemblent tous : sans titre, on règle l'échéance d'une tâche en
   croyant régler celle d'une autre. Le nom en tête, donc — dans le volet comme
   dans l'infobulle des contacts. */
.tr-tache { margin: 0 0 9px; padding-bottom: 7px; font-weight: 700; font-size: 13px;
  color: var(--text); border-bottom: 1px solid var(--border); }
.tr-pop .tr-pop-tache { font-size: 12px; text-transform: none; letter-spacing: 0;
  color: var(--text); white-space: normal; padding-bottom: 5px; margin-bottom: 3px;
  border-bottom: 1px solid var(--border); }

/* Le volet « nom et échéance » n'a plus de poignée : il s'ouvre en cliquant le nom
   de la tâche. [hidden] ne suffit pas sur un <summary> — le navigateur lui impose
   display:list-item, qui l'emporte. */
.tache-volet.volet-nom > summary[hidden] { display: none; }

/* ─── DÉPARTEMENTS : DES DOSSIERS DE PÔLES ─────────────────────────────────── */
/* Le dossier se voit comme un contenant : un liseré à gauche, un titre, sa propre
   jauge. Sans cela, une carte de plus dans une pile de cartes ne dit pas qu'elle
   contient les suivantes. */
/* DE L'AIR ENTRE LES DOSSIERS. Collés, quatre départements font un seul bloc gris
   où l'œil ne sait plus où commence le suivant — et c'est justement la frontière
   qu'on cherche en parcourant un projet. */
/* --- Bandeau des projets en cours : sauter de l'un à l'autre --------------
   Replié, il ne coûte qu'une ligne ; déplié, il donne accès à tout ce qui tourne. */
.pj-bandeau { margin-bottom: 12px; }
.pj-bandeau-poignee { background: none; border: 0; cursor: pointer; padding: 2px 0;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted); }
.pj-bandeau-liste { display: none; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.pj-bandeau.ouvert .pj-bandeau-liste { display: flex; }
/* Chaque projet à sa couleur : sur douze productions, c'est la teinte qu'on suit,
   pas le nom — on le lit ensuite, pour confirmer. */
.pj-bandeau-projet { font-size: 12px; text-decoration: none; padding: 3px 10px;
  border-radius: 999px; border: 1px solid var(--projet-couleur, var(--border));
  color: var(--text); background: var(--surface); white-space: nowrap; }
.pj-bandeau-projet:hover { background: var(--surface-2); }
/* Celui où l'on est déjà : plein, pour qu'on ne clique pas dessus par erreur. */
.pj-bandeau-projet.ici { background: var(--projet-couleur, var(--accent)); color: #fff;
  font-weight: 700; }
/* --- Le bandeau rangé par nature de chantier ------------------------------
   Chaque paquet reste SOUDÉ : ses projets ne se dispersent pas au retour à la ligne,
   sinon deux exploitations se retrouveraient de part et d'autre d'une installation et
   le rangement ne voudrait plus rien dire. Un filet à gauche marque la frontière —
   sans lui, sur douze projets, on ne voit pas où une catégorie s'arrête. */
/* UNE LIGNE PAR CATÉGORIE, TOUJOURS — même quand elle n'en contient qu'un.
   Mises bout à bout, les catégories se coupaient n'importe où au retour à la ligne :
   une exploitation seule finissait accolée à une installation, et le rangement ne se
   voyait plus. Chacune sur sa ligne, l'œil descend une colonne au lieu de relire une
   phrase — et la place d'une catégorie ne dépend plus du nombre de projets de celle
   d'au-dessus. */
.pj-bandeau-liste { flex-direction: column; align-items: stretch; gap: 4px; }
.pj-bandeau-groupe { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
/* L'étiquette tient une colonne de largeur FIXE : c'est ce qui aligne les noms de
   projets d'une ligne à l'autre. Alignée à droite, elle colle au bloc qu'elle
   annonce plutôt que de flotter au milieu du vide sur les noms courts. */
/* Le nom de la catégorie SITUE, il ne réclame pas l'attention : ce qu'on vise, ce
   sont les projets. Petit, en capitales, gris — la même écriture que les autres
   étiquettes de rangement de l'application. */
.pj-bandeau-cat { flex: 0 0 96px; text-align: right;
  font-size: 10px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-muted); white-space: nowrap; }
/* Sur un écran étroit, la colonne d'étiquettes mangerait la moitié de la largeur :
   elle repasse au-dessus de sa rangée, et l'on garde une ligne par catégorie. */
@media (max-width: 640px) {
  .pj-bandeau-groupe { flex-direction: column; align-items: flex-start; }
  .pj-bandeau-cat { flex: none; text-align: left; }
}

/* --- Barre d'onglets d'un projet : deux familles, séparées ---------------
   Les pages du projet ne bougent pas ; les pôles, eux, sont ce que CETTE production
   a monté. Un trait les sépare, et chaque dossier porte son nom et sa couleur. */
.pj-onglets { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 18px;
  margin-bottom: 18px; }
.pj-base { flex-wrap: wrap; }
.pj-groupe { display: flex; flex-direction: column; gap: 3px;
  padding-left: 18px; border-left: 1px solid var(--border); }
/* Le nom du dossier, discret mais lisible : il situe, il ne réclame pas l'attention. */
.pj-groupe-nom { font-size: 10.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .07em; color: var(--dep-couleur, var(--text-muted));
  padding-left: 4px; }
.pj-groupe .seg-views { flex-wrap: wrap; }
/* La couleur du département souligne SES onglets : on retrouve un pôle par la teinte
   de son dossier avant même d'avoir lu son nom. */
.pj-groupe[style*="--dep-couleur"] .seg-views a { border-bottom: 2px solid var(--dep-couleur); }
.pj-groupe[style*="--dep-couleur"] .seg-views a.active { background: var(--dep-couleur);
  color: #fff; border-color: var(--dep-couleur); }
/* Onglet décollé par un appui long : on doit voir ce qu'on tient. */
.seg-views a.onglet-pris { opacity: .5; transform: scale(.96); cursor: grabbing; }
.seg-views a.depose-avant { box-shadow: inset 3px 0 0 var(--accent); }
.seg-views a.depose-apres { box-shadow: inset -3px 0 0 var(--accent); }
/* Le glisser natif du navigateur — celui qui promène l'URL d'un lien — doit être
   éteint, sinon il vole l'appui long et le déplacement ne démarre jamais. La
   sélection de texte aussi : tenir un onglet enfoncé surlignait son nom en bleu. */
.pj-poles a { touch-action: none; -webkit-user-drag: none; user-select: none;
  -webkit-user-select: none; }
/* « 3/4 » à côté du pourcentage : discret, mais c'est lui qu'on lit pour savoir s'il
   reste une ligne ou trente. 75 % sur quatre tâches et sur quarante, ce n'est pas le
   même après-midi. */
.onglet-compte { font-size: 10.5px; opacity: .7; font-variant-numeric: tabular-nums; }
/* L'aperçu d'un onglet : trois états, trois couleurs. On sait en survolant s'il faut
   ouvrir ce pôle ou passer — sans quoi on l'ouvre pour rien, vingt fois par jour. */
.pj-poles a { position: relative; }
.onglet-pop { left: 0; right: auto; }
.apercu-retard { color: var(--danger, #c0392b); font-weight: 600; }
.apercu-faite { color: var(--success, #1a9d63); text-decoration: line-through;
  text-decoration-thickness: 1px; opacity: .85; }
.apercu-avenir { color: var(--text-muted, #64748b); }
.apercu-reste { color: var(--text-muted, #64748b); font-style: italic; }

.dep-card { border-left: 4px solid var(--accent); margin-bottom: 26px; }
.dep-card + .dep-card { margin-top: 0; }
/* Les pôles RENTRENT sous leur dossier : le retrait dit l'appartenance mieux qu'un
   titre, parce qu'il reste visible quand le titre a défilé hors de l'écran. */
.dep-poles { margin-left: 18px; padding-left: 12px; border-left: 1px dashed var(--border); }
.dep-pastille { display: inline-block; width: 11px; height: 11px; border-radius: 3px;
  margin-right: 7px; vertical-align: baseline; }
.dep-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dep-nom { font-weight: 700; font-size: 15px; }
/* La jauge du dossier est plus épaisse que celles qu'elle résume : on doit voir d'un
   coup laquelle est la somme et lesquelles sont les parties. */
.dep-jauge { height: 9px; margin: 7px 0 12px; }
.dep-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
/* Les actions d'un dossier sont des boutons qu'on lit avant de cliquer, pas des
   pastilles d'état : un peu plus de corps et d'air que sur une ligne de tâche. */
.dep-actions .tr-bulle, .pole-ranger > summary { font-size: 11.5px; padding: 4px 12px; }
.dep-actions form { display: inline-flex; }
/* Le menu de rangement se tient au bout de la ligne, hors du lien : cliquer « où
   ranger » ne doit pas ouvrir le pôle. */
.pole-rangee { display: flex; align-items: center; gap: 8px; }
.pole-rangee > .pole { flex: 1 1 auto; min-width: 0; }
.pole-ranger { position: relative; flex: 0 0 auto; }
.pole-ranger > summary { list-style: none; cursor: pointer; }
.pole-ranger > summary::-webkit-details-marker { display: none; }
.pole-ranger .heb-form { position: absolute; z-index: 70; top: calc(100% + 6px); right: 0;
  min-width: 300px; box-shadow: 0 12px 30px rgba(0,0,0,.32); }
.pole-ranger select, .pole-ranger input[type=text] { width: 100%; box-sizing: border-box; }

/* UNE ÉTAPE QUI DÉBORDE DU PROJET LE DIT SUR ELLE-MÊME. Un jour hors projet ne
   compte pour personne : les gens bookés dessus n'apparaissent nulle part, et l'on
   va chercher l'erreur du côté du personnel — où elle n'est pas. */
.etape-hors { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 8px 0 4px; padding: 8px 11px; font-size: 12px;
  background: color-mix(in srgb, var(--warning, #e0a800) 12%, transparent);
  border: 1px solid var(--warning, #e0a800); border-radius: var(--radius); }
.etape-hors-txt { flex: 1 1 300px; }

/* LA RECHERCHE RAPIDE PROPOSE SES RÉSULTATS. Taper « marc » laissait quatre lignes
   à l'écran sans dire lesquelles : il fallait les chercher des yeux dans le tableau,
   et rien ne permettait d'en isoler une. */
.pg-quick { position: relative; }
.pg-suggest { position: absolute; z-index: 80; top: calc(100% + 4px); left: 0;
  min-width: 240px; max-width: 340px; max-height: 320px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 12px 30px rgba(0,0,0,.32); padding: 4px; }
.pg-sg { position: static; display: flex; align-items: center;
  justify-content: space-between; gap: 10px; width: 100%; min-height: 30px;
  padding: 6px 9px; border: none; border-radius: 6px; cursor: pointer;
  background: none; color: var(--text); font: inherit; font-size: 13px; text-align: left; }
.pg-sg:hover, .pg-sg:focus { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.pg-sg em { font-style: normal; font-size: 10.5px; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; }
.pg-sg-vide { padding: 7px 9px; font-size: 12px; color: var(--text-muted); }


/* UN PROJET QUI NE CONCERNE PAS LA PERSONNE CHERCHÉE PASSE EN GRIS. Le retirer
   réglait bien la confusion, mais faisait perdre le contexte : on ne voyait plus
   que la semaine était chargée pour les autres, ni quel projet occupait le créneau
   d'à côté. Grisé, il reste là pour situer — en couleur, ceux qu'on cherche.
   `filter: grayscale` plutôt qu'une couleur imposée : la barre garde sa teinte
   d'origine, elle ne fait que la perdre — et la retrouve intacte au décochage. */
.pg-band-line.hors-selection, .pg-bar.hors-selection {
  filter: grayscale(1); opacity: .3; }
.pg-band-line.hors-selection:hover, .pg-bar.hors-selection:hover {
  filter: grayscale(.4); opacity: .75; }

/* Un titre de niveau dans la table des comptes : la pastille dit lequel, le compte
   dit combien. Sans eux, propriétaires et utilisateurs se lisaient sur la même
   lignée — et c'est la première chose à savoir avant de toucher aux droits. */
.cpt-groupe > td { padding-top: 16px; padding-bottom: 6px;
  border-bottom: 1px solid var(--border); background: none; }
.cpt-groupe .cat-count { margin-left: 8px; }

/* PERMIS, CACES, HABILITATIONS : ce qui expire se voit AVANT le reste. Un CACES
   périmé et un permis valable ne se lisent pas de la même façon — la couleur fait
   ici le travail que la date seule ne fait pas, parce qu'on ne compare pas trente
   dates de tête. */
.qualif-liste li { align-items: flex-start; gap: 12px; }
.qualif-liste .person-meta { display: block; }
.qualif-droite { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  justify-content: flex-end; }
.qualif-etat { font-size: 11.5px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-muted); white-space: nowrap; }
.qualif-expiree .qualif-etat { border-color: var(--danger); color: var(--danger);
  font-weight: 700; }
.qualif-bientot .qualif-etat { border-color: var(--warning, #e0a800);
  color: var(--warning, #e0a800); font-weight: 700; }
.qualif-expiree { border-left: 3px solid var(--danger); padding-left: 9px; }
.qualif-bientot { border-left: 3px solid var(--warning, #e0a800); padding-left: 9px; }
.qualif-volet { position: relative; display: inline-block; }
.qualif-volet > summary { list-style: none; cursor: pointer; }
.qualif-volet > summary::-webkit-details-marker { display: none; }
.qualif-volet .heb-form { position: absolute; z-index: 70; top: calc(100% + 6px); right: 0;
  min-width: 340px; max-width: min(560px, 92vw);
  box-shadow: 0 12px 30px rgba(0,0,0,.32); text-align: left; }

/* CONFORMITÉ D'UN CANDIDAT À CE QU'EXIGE LE BESOIN. Dans une petite équipe, personne
   n'est jamais exactement conforme : écarter les incomplets ne laisserait souvent
   personne. On les garde, on les classe, et l'on dit ce qui manque au survol. */
.match-etat { margin-left: 6px; font-size: 10.5px; padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-muted); white-space: nowrap; }
.match-plein .match-etat { border-color: var(--success); color: var(--success); font-weight: 700; }
.match-partiel .match-etat { border-color: var(--warning, #e0a800); color: var(--warning, #e0a800); }
.match-nul .match-etat { border-color: var(--danger); color: var(--danger); }
.match-nul { opacity: .72; }

/* ─── LES PANNEAUX FLOTTANTS SUR PETIT ÉCRAN ───────────────────────────────────
   Un panneau ancré à son bouton, large de 300 à 380 px, n'a nulle part où flotter
   sur un écran de 375 : il sortait par la droite, et la moitié de ses champs
   devenait inatteignable — la page, elle, ne débordait pas, si bien que rien ne le
   signalait. Sur mobile ils reprennent le fil : posés SOUS le bouton, pleine
   largeur, ils poussent la page vers le bas — le seul sens où un téléphone défile
   naturellement. */
@media (max-width: 700px) {
  .heb-form,
  .sejour-form,
  .qualif-volet .heb-form,
  .pole-ranger .heb-form,
  .tache-volet form {
    position: static; width: 100%; min-width: 0; max-width: 100%;
    box-sizing: border-box; box-shadow: none; }
  /* Une grille de champs à deux colonnes n'a plus de place : une par ligne. */
  .heb-grille { grid-template-columns: 1fr; }
  /* Les listes qui s'ouvrent au survol restent flottantes — elles ne portent pas de
     champs à remplir —, mais bornées à l'écran. */
  .pg-suggest, .tr-pop, .pct-pop { max-width: calc(100vw - 24px); min-width: 0; }
  /* Le calendrier des séjours : des jours plus petits, pour en voir une semaine. */
  .plage-jour { width: 30px; }
  /* Le carnet d'hébergements est un tableau : sur mobile il défile dans son cadre,
     et le panneau de correction, coincé dans une cellule étroite, devenait
     illisible. On lui rend une largeur utilisable — c'est le tableau qui défile
     jusqu'à lui, pas la page. */
  .tache-card, .card { overflow-x: auto; }
  .heb-volet .heb-form { min-width: 260px; }
}

/* UN PROJET EN STANDBY SE VOIT SUR SA BARRE DE PLANNING. Le badge ne vit que sur la
   fiche du projet ; le planning, lui, est ce qu'on ouvre le matin — un chantier
   suspendu qui s'y affiche comme les autres se prépare comme les autres. Les
   hachures disent l'arrêt sans effacer la couleur du projet, qui reste le repère. */
.pg-bar.pl-standby { background-image: repeating-linear-gradient(135deg,
  rgba(0,0,0,.32) 0 6px, rgba(255,255,255,.14) 6px 12px); }
.pg-bar.pl-standby .pg-bar-nom { text-decoration: none; opacity: .92; }
