/* Palette inspirée des maquettes (sidebar navy, accent bleu, fond gris clair) */
:root {
  /* Navy : tons un cran plus clairs qu'a l'origine (#1a2340/#2d3a5e) pour
     adoucir l'impression "trop sombre" du header / sidebar / total bars.
     Garde un contraste AAA avec texte blanc (#fff). */
  --navy: #2a3656;
  --navy-2: #3d4a6e;
  /* Sidebar : palette dediee plus sombre (slate-800-ish), inspiree d'Intus.
     Decouple du `--navy` global qui sert aussi de couleur de texte ailleurs. */
  --sidebar-bg: #1e293b;
  --sidebar-bg-2: #334155;
  --blue: #3b6ef5;
  --blue-2: #2d5dd4;
  --bg: #f4f6f9;
  --surface: #ffffff;
  /* Texte principal : reste sur l'ancien navy foncé pour la lisibilité du
     corps de texte sur fond clair (le navy clair serait trop pâle). */
  --text: #1a2340;
  --muted: #888;
  --border: #dde1ea;
  --danger: #d64545;
  --danger-bg: #fdecec;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

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

/* ----- Page de login (centrée verticalement) ----- */
.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.login-card {
  background: var(--surface);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(26, 35, 64, 0.08);
  padding: 40px 36px;
  width: 100%;
  max-width: 400px;
}

.login-card h1 {
  font-size: 22px;
  font-weight: 700;
  margin-bottom: 6px;
  color: var(--navy);
}

.login-card .subtitle {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 28px;
}

.login-footer {
  margin-top: 18px;
  text-align: center;
  font-size: 13px;
}
.login-footer a { color: var(--blue); }

.field {
  margin-bottom: 18px;
}

.field label {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 6px;
}

.field input[type="text"],
.field input[type="password"],
.field input[type="email"] {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.field input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.15);
}

.btn {
  display: inline-block;
  background: var(--blue);
  color: #fff;
  border: none;
  padding: 11px 22px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  text-decoration: none;
  transition: background 0.15s;
}

.btn:hover { background: var(--blue-2); text-decoration: none; }
.btn-block { display: block; width: 100%; }
.btn-ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
}
.btn-ghost:hover { background: var(--bg); color: var(--text); }
/* Variante verte : actions de validation / archivage / cloture. Echo
   du V vert dans la sidebar lots et du bouton "Valider le chiffrage". */
.btn-success {
  background: #1f8a4c;
  color: #fff;
}
.btn-success:hover { background: #176c3a; }
/* Variante rouge : actions destructives (suppression, revert avec
   perte de donnees). Usage rare, exige `hx-confirm` cote template. */
.btn-danger {
  background: var(--danger);
  color: #fff;
}
.btn-danger:hover { background: #b53838; }
/* Variante orange : actions semi-destructives mais recuperables
   (revert vers une version archivee : on perd la modif live, mais
   la version archivee de depart reste intacte). */
.btn-warning {
  background: #d6841a;
  color: #fff;
}
.btn-warning:hover:not(:disabled) { background: #b56d10; }
.btn-warning:disabled {
  background: #e8d6b7;
  color: #fff;
  cursor: not-allowed;
}

.alert {
  background: var(--danger-bg);
  color: var(--danger);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  margin-bottom: 16px;
  border: 1px solid rgba(214, 69, 69, 0.2);
}

/* ----- App layout (sidebar + main) ----- */
.app {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

/* Side panel calqué sur Intus : dégradé slate vertical (700 -> 800 -> 900),
   nav à icônes avec barre d'accent bleu/violet sur l'item actif. */
.sidebar {
  background: linear-gradient(to bottom, #334155 0%, #1e293b 55%, #0f172a 100%);
  color: #fff;
  padding: 24px 0;
  display: flex;
  flex-direction: column;
}
/* En-tête : logo, filet bas discret (comme le header Intus). */
.sidebar-header {
  padding: 4px 22px 18px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.18);
}

/* Brand : logotype Quanto en haut de la sidebar. Le "Q" est mis en
   valeur (gros, gradient bleu cyan, weight extra-bold) et "uanto"
   l'accompagne en regular weight. Pas de container/box autour du Q --
   c'est juste une lettre stylee qui sert de marque visuelle.
   Cliquable -> retour au dashboard. */
.sidebar .brand {
  display: flex;
  align-items: baseline;        /* baseline pour aligner le Q et uanto sur la meme ligne typo */
  gap: 0;                       /* Q et uanto collés, c'est un logotype unifie */
  text-decoration: none;
  user-select: none;
}
.sidebar .brand:hover { text-decoration: none; }
/* Logotype : rebrand charte Batiprisme 2026-07 -> composant .bp-logo
   (static/batiprisme/css/logo.css : Poppins self-host, "Q" orange plein,
   sans degrade). Les anciennes regles .brand-mark / .brand-name (Q gradient
   bleu, Helvetica Neue) ont ete retirees. On garde juste le hover du wrapper. */
.sidebar .brand .bp-logo__ini {
  transition: filter 0.2s, transform 0.2s;
}
.sidebar .brand:hover .bp-logo__ini {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.sidebar nav {
  margin-top: 16px;
  padding: 0 12px;            /* insets pour que la pastille active ne touche pas les bords */
}

/* Nav à icônes (Heroicons) + libellé. Item actif = barre d'accent à gauche
   (bleu -> violet) + léger voile blanc (UI Intus). */
.sidebar nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  margin-bottom: 2px;
  border-radius: 8px;
  color: #cbd5e1;
  font-size: 14px;
  transition: background 0.12s, color 0.12s;
}
/* Barre d'accent à gauche : hauteur 0 par défaut, grandit sur l'item actif. */
.sidebar nav a::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 0;
  background: linear-gradient(to bottom, #3b82f6, #8b5cf6);
  border-radius: 0 3px 3px 0;
  transition: height 0.2s ease;
}
.sidebar nav a.active::before { height: 60%; }
.sidebar nav a .ic {
  width: 1.05em;
  height: 1.05em;
  flex: none;
  opacity: 0.92;
  transition: transform 0.15s ease;
}
.sidebar nav a:hover .ic { transform: scale(1.1); }

.sidebar nav a:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  text-decoration: none;
}
.sidebar nav a.active {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  text-decoration: none;
}
.sidebar nav a.active:hover { background: rgba(255, 255, 255, 0.09); }

/* Bloc bas du sidebar (Utilisateurs + carte user). margin-top: auto pousse
   tout le bloc en bas du sidebar, juste au-dessus du bord, sans qu'on ait
   besoin de combiner plusieurs `margin-top: auto` qui se feraient
   concurrence sur la repartition du flex remaining-space. */
.sidebar-bottom-block {
  margin-top: auto;
}

/* Le nav "secondaire" (Utilisateurs) reutilise le styling du nav principal
   pour la coherence visuelle. Petit separateur subtil au-dessus pour
   marquer la rupture entre les sections fonctionnelles (Projets/Annuaire/
   Bibliotheque) et l'administration (Utilisateurs). */
/* Le nav du bas (Utilisateurs) est aussi un <nav> dans .sidebar : il hérite
   donc du style "bullet list" + pastille bleue de `.sidebar nav a` ci-dessus.
   On ne garde ici que le séparateur + les insets horizontaux pour aligner
   la pastille sur celle du nav principal. */
.sidebar-bottom-nav {
  border-top: 1px solid rgba(148, 163, 184, 0.18);
  padding: 8px 12px 0;
  margin-top: 0;
}

/* User card en bas de sidebar : avatar avec initiales + pastille de presence
   verte pulsante, nom + statut (fonction / role), bouton "Deconnexion" avec
   cadenas. Inspire de la design Intus (Tailwind reecrit en CSS custom).
   Classes prefixees `sidebar-` pour eviter le conflit avec `.user-card` /
   `.user-avatar` / `.user-name` deja utilises sur la page Utilisateurs. */
.sidebar-user-card-wrap {
  /* margin-top: auto vit desormais sur .sidebar-bottom-block (le parent),
     qui pousse l'ensemble (utilisateurs nav + carte user) en bas du sidebar.
     Cf. _sidebar.html. */
  padding: 12px;
  border-top: 1px solid rgba(148, 163, 184, 0.18);
}
.sidebar-user-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 8px;
  background: transparent;
}
.sidebar-user-avatar-wrap {
  position: relative;
  flex-shrink: 0;
}
.sidebar-user-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, #5dade2 0%, #3b6ef5 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
  user-select: none;
}
.sidebar-user-status-dot {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 12px;
  height: 12px;
  background: #22c55e;
  border-radius: 50%;
  border: 2px solid #0f172a;
  animation: userStatusPulse 2s ease-in-out infinite;
}
@keyframes userStatusPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
.sidebar-user-info {
  flex: 1;
  min-width: 0;
}
.sidebar-user-name {
  font-size: 13px;
  color: #fff;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.3;
}
.sidebar-user-status {
  font-size: 10px;
  color: #cbd5e0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 2px;
  line-height: 1.3;
}
.sidebar-user-card-wrap .logout-form {
  display: block;
  margin-top: 6px;
}
.btn-logout {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  background: transparent;
  border: none;
  color: #cbd5e0;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  border-radius: 8px;
  transition: background 0.15s, color 0.15s;
}
.btn-logout:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}
.btn-logout-icon {
  width: 14px;
  height: 14px;
  transition: transform 0.15s;
}
.btn-logout:hover .btn-logout-icon { transform: scale(1.1); }

.main { padding: 32px; }

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 28px;
}
.topbar h1 { font-size: 22px; font-weight: 700; }

.card {
  background: var(--surface);
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  padding: 24px;
}

.empty-state {
  text-align: center;
  padding: 48px 24px;
  color: var(--muted);
}

.empty-state .icon { font-size: 36px; margin-bottom: 12px; }

.project-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.project-list li {
  padding: 14px 18px;
  border: 1px solid var(--border);
  border-radius: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.project-list .ref { color: var(--muted); font-size: 12px; }
.project-list .name { font-weight: 600; }
.project-list .meta { font-size: 13px; color: var(--muted); }

/* ----- Dashboard : stats cards ----- */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 28px;
}

.stat-card {
  background: var(--surface);
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.stat-card .label {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}

.stat-card .value {
  font-size: 22px;
  font-weight: 700;
  color: var(--navy);
  line-height: 1.2;
}

.stat-card .sub {
  font-size: 12px;
  color: var(--blue);
  margin-top: 4px;
}

@media (max-width: 1100px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
}

/* ----- Filtres ----- */
.filters {
  display: flex;
  gap: 10px;
  margin-bottom: 18px;
  flex-wrap: wrap;
  align-items: center;
}

.filters input[type="text"],
.filters select {
  height: 38px;          /* hauteur uniforme : aligne le select natif sur l'input */
  padding: 0 14px;       /* horizontal seul, le vertical est gere par height */
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  background: var(--surface);
  font-family: inherit;
  color: var(--text);
}

.filters input[type="text"] {
  width: 280px;
  max-width: 100%;
}

.filters input[type="text"]:focus,
.filters select:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.15);
}

.filters .btn { padding: 9px 18px; }

/* Indicateur HTMX pendant le filtrage live */
.htmx-indicator {
  opacity: 0;
  transition: opacity 0.2s;
  font-size: 16px;
  color: var(--blue);
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; }

/* ----- Tableau projets ----- */
.projets-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.projets-table thead { background: #f8f9fb; }

.projets-table th {
  padding: 13px 16px;
  text-align: left;
  font-size: 11px;
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
/* En-tete colonne Actions aligne a droite, comme les boutons Accéder /
   Modifier (cf. .actions-row justify-content: flex-end). Meme padding
   horizontal (16px) -> le mot "ACTIONS" tombe au-dessus des boutons. */
.projets-table th.th-actions { text-align: right; }

.projets-table td {
  padding: 14px 16px;
  font-size: 14px;
  border-top: 1px solid #f0f2f6;
  vertical-align: middle;
}

.projets-table tr:hover td { background: #fafbfc; }

/* Colonne actions du tableau des projets.
   Le <td.actions> reste en table-cell standard (centrage vertical via td).
   Un wrapper interne `.actions-row` fait le flex pour pousser "Modifier"
   tout a droite -- mettre flex sur le td casserait son comportement de
   cellule (laisse un blanc en bas quand la row est plus haute). */
.projets-table .actions-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;   /* les 2 actions regroupees a droite */
  gap: 14px;                    /* condense (etait 16px + space-between) */
}
.projets-table .actions a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--blue);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
/* Icone SVG sobre (oeil / crayon), alignee au texte. */
.projets-table .action-ico {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}
.projets-table .action-modifier {
  color: var(--muted);
}
.projets-table .action-modifier:hover {
  color: var(--blue);
}

/* ----- Badges statut ----- */
.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Palette des badges statut projet. 3 statuts uniquement (Consultation a ete
   fusionne dans Chiffrage en 2026-05). Logique des couleurs :
   - Chiffrage : bleu doux -> phase d'exploration / pre-chantier (par defaut).
   - Travaux   : gold -> phase active / chantier en cours (attire l'attention).
   - Clos      : navy fonce -> projet finalise / archive. */
.badge-chiffrage { background: #e8f0fe; color: #2d5dd4; }
.badge-travaux   { background: #fdf2cc; color: #8a6814; }
.badge-clos      { background: #2a3656; color: #ffffff; }

/* ----- Petits utilitaires partagés ----- */
.muted { color: var(--muted); }
.muted.small, .small { font-size: 12px; }

.back-link {
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.back-link:hover { color: var(--blue); text-decoration: none; }

.page-head { margin-bottom: 22px; }
.page-head h1 { font-size: 22px; font-weight: 700; margin-top: 8px; }
.page-head p { margin-top: 6px; }

/* ----- Project header (commun aux pages projet) ----- */
.project-header {
  background: var(--surface);
  border-radius: 12px 12px 0 0;
  padding: 18px 24px 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  margin-bottom: 0;
}

.project-header-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding-bottom: 14px;
}

.project-header-top h1 {
  font-size: 20px;
  font-weight: 700;
  margin-top: 6px;
}

.project-subtitle {
  font-size: 13px;
  color: var(--muted);
  margin-top: 4px;
}

.tabs {
  display: flex;
  gap: 0;
  border-top: 1px solid #eef0f5;
  margin: 0 -24px;
  padding: 0 24px;
}

.tab {
  padding: 12px 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.tab:hover { color: var(--text); text-decoration: none; }
.tab.active { color: var(--blue); border-bottom-color: var(--blue); }

/* ----- Bandeau de méta projet (style tableur compact) ----- */
.project-meta-strip {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  background: var(--surface);
  border-top: 1px solid #eef0f5;
  border-radius: 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  margin-bottom: 24px;
}

.meta-cell {
  padding: 14px 20px;
  border-right: 1px solid #f0f2f6;
}
.meta-cell:last-child { border-right: none; }

.meta-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 2px;
}
.meta-value {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy);
}

@media (max-width: 1100px) {
  .project-meta-strip { grid-template-columns: repeat(2, 1fr); }
  .meta-cell { border-bottom: 1px solid #f0f2f6; }
}

/* ----- Formulaire dense ----- */
.form-card {
  background: var(--surface);
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  padding: 8px 24px 24px;
  /* pas de margin-top pour s'aligner avec .form-aside-card en grid */
}

.form-section {
  border-top: 1px solid #f0f2f6;
  padding: 28px 0 0;     /* gros espace au-dessus du titre */
  margin: 0;
}
.form-section:first-of-type { border-top: none; padding-top: 8px; }

.form-section .form-section-title {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--navy);
  font-weight: 700;
  margin: 0 0 10px 0;
  padding-bottom: 6px;
  border-bottom: 1px solid #e0e4eb;
}

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

.form-field { display: flex; flex-direction: column; min-width: 0; }
.form-field.span-2 { grid-column: span 2; }

.form-field label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 4px;
}

.form-field input[type="text"],
.form-field input[type="number"],
.form-field input[type="date"],
.form-field input[type="email"],
.form-field input[type="password"],
.form-field input[type="tel"],
.form-field select,
.form-field textarea {
  width: 100%;
  height: 36px;          /* hauteur uniforme : aligne select et input[type=date] sur Mac */
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  box-sizing: border-box;
  line-height: 1.4;
}
/* Suppression des fleches natives sur les inputs number (surface, etc.) */
.form-field input[type="number"]::-webkit-outer-spin-button,
.form-field input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.form-field input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.form-field textarea { height: auto; padding: 8px 12px; }

/* === Page Informations (lecture seule) ===
   Reprend le visuel de form-grid mais sans inputs (dt/dd). */
.form-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.form-card-title { margin: 0; font-size: 18px; font-weight: 700; color: var(--text); }

.info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 18px;
  margin: 0;
}
.info-field { display: flex; flex-direction: column; min-width: 0; }
.info-field.span-2 { grid-column: span 2; }
.info-field dt {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
  margin: 0 0 4px;
}
.info-field dd {
  margin: 0;
  font-size: 14px;
  color: var(--text);
  /* Coupe les valeurs trop longues proprement (ex : noms d'immeuble interminables). */
  word-break: break-word;
}

.info-zones-list { list-style: none; padding: 0; margin: 0; }
.info-zone-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.info-zone-row:last-child { border-bottom: none; }
.info-zone-name { color: var(--text); }
.info-zone-surface { color: var(--muted); font-variant-numeric: tabular-nums; }
.info-empty { color: var(--muted); font-style: italic; font-size: 13px; margin: 0; }
.form-field select {
  /* Retire le styling natif du <select> pour avoir la même hauteur que les autres inputs */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='%23888' d='M0 0l5 6 5-6z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.15);
}

.field-error {
  color: var(--danger);
  font-size: 12px;
  margin-top: 4px;
}

.form-help {
  display: block;
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
}

/* ----- Autocomplete adresse (BAN) ----- */
.ban-autocomplete-wrapper {
  position: relative;
}

.ban-suggestions {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  list-style: none;
  padding: 4px 0;
  margin: 0;
  max-height: 260px;
  overflow-y: auto;
  z-index: 100;
  box-shadow: 0 4px 16px rgba(26, 35, 64, 0.10);
}
.ban-suggestions[hidden] { display: none; }

.ban-suggestion {
  display: block;
  padding: 7px 12px;
  cursor: pointer;
  font-size: 13px;
  border-bottom: 1px solid #f3f4f7;
  line-height: 1.35;
}
.ban-suggestion:last-child { border-bottom: none; }
.ban-suggestion:hover { background: #f5f8ff; }

.ban-suggestion strong { display: block; color: var(--text); font-weight: 600; }
.ban-suggestion .ban-meta { color: var(--muted); font-size: 11.5px; }

/* Flash visuel quand un champ est auto-rempli */
.ban-filled {
  background: #e7f3ff !important;
  transition: background 0.8s ease-out;
}

/* Paragraphe descriptif sous le titre d'une section (compact, pas de marges
   parasites du navigateur qui creeraient un espace bizarre avec le titre) */
.form-section-description {
  font-size: 12px;
  color: var(--muted);
  margin: 0 0 10px 0;
  line-height: 1.4;
}

/* ----- Sélection utilisateurs (cards cliquables avec avatar) ----- */
.users-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 8px;
}

.user-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.user-card:hover {
  border-color: var(--blue);
  background: #fafbff;
}

/* Checkbox custom : on cache la native, on la remplace par un carré coloré
   avec un check SVG-like fait en CSS. */
.user-card input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid var(--border);
  border-radius: 4px;
  background: #fff;
  position: relative;
  flex-shrink: 0;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.user-card input[type="checkbox"]:checked {
  background: var(--blue);
  border-color: var(--blue);
}
.user-card input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 5px;
  width: 4px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* Highlight de la carte quand sa checkbox est cochée (modern CSS, supporté
   par Safari 15.4+, Chrome 105+, Firefox 121+ — largement assez récent). */
.user-card:has(input:checked) {
  border-color: var(--blue);
  background: #eef3ff;
}

.user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, #3b6ef5, #1a2340);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
  text-transform: uppercase;
}

.user-name {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Checkbox-card simple : utilisé pour les choix isolés (ex: "Charger lots standard") */
.checkbox-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.checkbox-card:hover { border-color: var(--blue); background: #fafbff; }
.checkbox-card input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid var(--border);
  border-radius: 4px;
  background: #fff;
  position: relative;
  flex-shrink: 0;
  cursor: pointer;
}
.checkbox-card input[type="checkbox"]:checked { background: var(--blue); border-color: var(--blue); }
.checkbox-card input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  top: 2px; left: 5px;
  width: 4px; height: 9px;
  border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.checkbox-card:has(input:checked) { border-color: var(--blue); background: #eef3ff; }

/* ----- Section Zones (colonne aside) ----- */
.zones-section .form-section-title { margin-bottom: 4px; }
.zones-section .form-section-description { margin-bottom: 14px; }

.zones-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 10px;
}

.zone-row,
.zone-add-form {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
}

.zone-add-form {
  border-top: 1px dashed var(--border);
  padding-top: 12px;
  margin-top: 4px;
}

.zones-empty {
  padding: 12px 0;
  font-style: italic;
}

/* Inputs in-row, façon tableur */
.zone-nom,
.zone-surface {
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 5px;
  font-size: 13px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  box-sizing: border-box;
}

/* Suppression des fleches haut/bas natives sur les inputs number */
.zone-surface::-webkit-outer-spin-button,
.zone-surface::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.zone-surface { -moz-appearance: textfield; appearance: textfield; }

/* Drag handle pour le reordonnancement des zones */
.zone-drag-handle {
  cursor: grab;
  color: var(--muted);
  font-size: 14px;
  padding: 0 2px;
  user-select: none;
  flex-shrink: 0;
  letter-spacing: -3px;
  font-weight: 700;
}
.zone-drag-handle:hover { color: var(--text); }
.zone-drag-handle:active { cursor: grabbing; }

/* Etats SortableJS pendant le drag */
.zone-row-ghost { opacity: 0.4; background: #eef3ff; }
.zone-row-chosen { background: #fafbff; }
.zone-row-dragging { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); }
.zone-nom:focus,
.zone-surface:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.12);
}

.zone-nom { flex: 1; min-width: 0; }
.zone-surface-wrapper {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.zone-surface { width: 70px; text-align: right; }
.zone-surface-wrapper .suffix { font-size: 11px; color: var(--muted); }

/* Bouton supprimer (rouge discret) */
.zone-delete {
  width: 28px;
  height: 28px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.zone-delete:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: rgba(214, 69, 69, 0.3);
}

/* Bouton ajouter (vert discret) */
.zone-add-btn {
  width: 32px;
  height: 32px;
  background: #eef7ee;
  border: 1px solid #c8e0c8;
  border-radius: 5px;
  color: #2e7d2e;
  cursor: pointer;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
  transition: background 0.12s, border-color 0.12s;
}
.zone-add-btn:hover { background: #d8ecd8; border-color: #2e7d2e; }

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid #f0f2f6;
}

@media (max-width: 720px) {
  .form-grid { grid-template-columns: 1fr; }
  .form-field.span-2 { grid-column: span 1; }
}

/* ----- Placeholder vue chiffrage ----- */
.placeholder-card {
  background: var(--surface);
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  padding: 40px 28px;
  text-align: center;
}
.placeholder-icon { font-size: 40px; margin-bottom: 12px; }
.placeholder-card h2 { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.placeholder-card p { color: var(--text); margin-bottom: 6px; }
.placeholder-card details { text-align: left; max-width: 720px; margin: 24px auto 0; }
.placeholder-card summary { cursor: pointer; font-weight: 600; color: var(--blue); }

/* =========================================================================
   VUE CHIFFRAGE — densité tableur
   ========================================================================= */

body.chiffrage-page {
  font-size: 13px;
}

/* ----- Header navy plein écran ----- */
.chiffrage-header {
  background: var(--navy);
  color: #fff;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 14px;
  height: 52px;
  border-bottom: 1px solid #0d1426;
}

.back-btn {
  background: var(--navy-2);
  color: #ccd;
  border: none;
  padding: 6px 12px;
  border-radius: 5px;
  font-size: 14px;
  text-decoration: none;
  line-height: 1;
}
.back-btn:hover { background: #3a4d70; color: #fff; text-decoration: none; }

.chiffrage-header-title { line-height: 1.2; }
.chiffrage-header-title { flex: 1; min-width: 0; }
.chiffrage-header-title .project-name { font-size: 15px; font-weight: 700; }
.chiffrage-header-title .project-meta {
  font-size: 12px;
  color: #8899aa;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Barre d'onglets sous le header navy : centree, plus aeree (refonte v28).
   La densite du header progresse au fil des features, on contrebalance ici
   par une bande blanche generique avec onglets espaces et centres. */
.projet-tabs-bar {
  display: flex;
  justify-content: center;
  background: #f8f9fb;
  border-bottom: 1px solid #dde3ea;
  height: 52px;
  align-items: stretch;
}
.projet-tabs-inner {
  display: flex;
  align-items: stretch;
  gap: 4px;
}
.projet-tabs-bar .ptab {
  padding: 0 16px;
  display: flex;
  align-items: center;
  /* Labels multi-mots (« Aléas et Remise »…) : centrés et équilibrés pour
     tenir sur 2 lignes max quand la barre se resserre (portables ~1024px).
     Le liant est figé côté template avec &nbsp; pour empêcher une 3e ligne. */
  text-align: center;
  text-wrap: balance;
  line-height: 1.15;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s, border-bottom-color 0.15s, background 0.15s;
}
.projet-tabs-bar .ptab:hover {
  color: var(--text);
  background: #eef1f5;
  text-decoration: none;
}
.projet-tabs-bar .ptab.active {
  color: var(--blue);
  border-bottom-color: var(--blue);
  background: #fff;
}
/* Onglet "à venir" : visible mais désactivé (feature pas encore livrée).
   On garde la place dans le bandeau pour signaler le périmètre futur. */
.projet-tabs-bar .ptab-soon {
  color: #b0b6c2;
  cursor: not-allowed;
  font-weight: 500;
  font-style: italic;
}
.projet-tabs-bar .ptab-soon:hover {
  color: #b0b6c2;
  background: transparent;
}
/* Separateur visuel entre les 3 groupes d'onglets (pre-chantier / chantier
   / metadonnees). Trait vertical bien marque, prend toute la hauteur du
   bandeau pour signaler clairement la rupture entre phases du projet. */
.projet-tabs-bar .ptab-group-sep {
  align-self: stretch;
  width: 2px;
  background: #9ca3b0;
  margin: 8px 9px;
  border-radius: 1px;
}

/* =========================================================================
   Icônes Heroicons (inline SVG, variante outline)
   -------------------------------------------------------------------------
   Rendues via {% heroicon_outline "name" class="ic" %}. La variante outline
   utilise stroke=currentColor : l'icône hérite donc de la couleur du texte
   ambiant. La taille CSS (em) prime sur l'attribut width/height du SVG ->
   l'icône suit la taille de police du contexte, cohérente partout.
   ========================================================================= */
.ic {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.2em;
  flex: none;
  /* 1.25 : trait fin. On etait a 1.6, soit PLUS gras que le 1.5 natif
     d'Heroicons -> les pictos denses (table-cells) paraissaient en gras. */
  stroke-width: 1.25;
}
.ic-sm {
  width: 0.95em;
  height: 0.95em;
}
.ic-lg {
  width: 1.35em;
  height: 1.35em;
}
.ic-xl {
  width: 2em;
  height: 2em;
  /* Plus l'icone est grande, plus le trait doit etre fin pour rester elegant. */
  stroke-width: 1.1;
}
/* Icône seule dans un bouton d'action (pas de texte à côté) : on neutralise
   l'alignement baseline et on centre via le flux flex du bouton parent. */
.btn-icon .ic,
.ic-solo {
  vertical-align: middle;
}

.chiffrage-header-totals {
  margin-left: auto;
  display: flex;
  gap: 22px;
  font-size: 12px;
}

/* Toggle master "Retenue de garantie" dans le navbar header projet.
   Pose entre le titre et les totaux. Wrappe la checkbox + le label
   "RG 5%" en une zone cliquable cohesive. */
.header-rg-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 6px;
  background: var(--navy-2);
  color: #cfd6e6;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  user-select: none;
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.header-rg-toggle:hover { background: #4a5780; color: #fff; }
.header-rg-toggle input[type="checkbox"] {
  accent-color: #5dade2;
  cursor: pointer;
  margin: 0;
}
.header-rg-toggle-form { margin: 0; }
.chiffrage-header-totals .lbl { color: #8899aa; margin-right: 6px; }
.chiffrage-header-totals .val { font-weight: 700; color: #fff; }
/* Pastilles colorees pour les totaux "hors operation principale" :
   Options en orange (supplements), Variantes en violet (alternatives),
   Total HT client en bleu clair (resultat final, echo du footer total-lot-bar). */
.chiffrage-header-totals .val-options { color: #ffb878; }
.chiffrage-header-totals .val-variantes { color: #d8b4e4; }
.chiffrage-header-totals .val-highlight { color: #5dade2; }

.chiffrage-logout button {
  background: var(--navy-2);
  border: none;
  color: #8899aa;
  padding: 6px 10px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 14px;
}
.chiffrage-logout button:hover { color: #fff; background: #3a4d70; }

/* ----- Layout 2 colonnes plein écran ----- */
.chiffrage-layout {
  display: flex;
  /* 52px header navy + 53px barre d'onglets (52px + 1px border) */
  height: calc(100vh - 105px);
}

/* Conteneur de la page formulaire (édition / création projet) */
.form-page-main {
  background: var(--bg);
  padding: 24px;
  min-height: calc(100vh - 93px);
}

/* Grid 2 colonnes : formulaire à gauche, zones à droite (mode edition).
   Dans la version creation, on tombe sur 1 colonne centrée (.no-aside) */
.form-page-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 20px;
  max-width: 1320px;
  margin: 0 auto;
  align-items: start;
}
.form-page-grid.no-aside {
  grid-template-columns: minmax(0, 920px);
  justify-content: center;
}

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

/* Card de la colonne aside (zones du projet) */
.form-aside-card {
  background: var(--surface);
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
  padding: 8px 24px 24px;     /* meme padding que .form-card pour aligner top */
  position: sticky;
  top: 16px;     /* reste visible au scroll */
}

/* Banniere de bienvenue (apres creation projet) */
.welcome-banner {
  max-width: 1320px;
  margin: 0 auto 16px;
  padding: 12px 18px;
  background: linear-gradient(90deg, #e7f3ff, #f0f8ff);
  border: 1px solid #c5d9f5;
  border-radius: 10px;
  font-size: 13.5px;
  color: var(--navy);
  line-height: 1.4;
}

/* ----- Sidebar lots ----- */
.lots-sidebar {
  width: 430px;          /* Place pour les controles (toggle, V validation, RG)
                            + nom de lot long sans le serrer. */
  min-width: 430px;
  background: #fff;
  border-right: 1px solid #dde3ea;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.lots-sidebar-head {
  padding: 10px 14px;
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  border-bottom: 1px solid #eee;
  background: #fafbfc;
}

/* Legende du code couleur des statuts de lot (juste sous le header "Lots").
   Trois rectangles equilarges aux memes teintes (fond + texte) que les
   statuts correspondants dans la liste des lots, pour une lecture immediate. */
.lots-legend {
  display: flex;
  gap: 6px;
  padding: 10px 12px 12px;
  background: #fafbfc;
  border-bottom: 1px solid #eee;
}
.lots-legend .legend-item {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 6px;
  border-radius: 5px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
/* Pastille = couleur EXACTE du liseré de statut correspondant (mapping direct
   avec .lot-item-wrapper.status-*::before). */
.lots-legend .legend-item::before {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}
.lots-legend .legend-validated {
  background: #eef7f1;
  color: #157a43;
}
.lots-legend .legend-validated::before { background: #18a05a; }   /* = liseré verrouillé */
.lots-legend .legend-in-progress {
  background: #fdf3e6;
  color: #a8650f;
}
.lots-legend .legend-in-progress::before { background: #e88a1e; }  /* = liseré en cours */
.lots-legend .legend-todo {
  background: #fdeeee;
  color: #c0352f;
}
.lots-legend .legend-todo::before { background: #e04444; }         /* = liseré à chiffrer */

.lots-list { flex: 1; overflow-y: auto; }

/* Wrapper d'une ligne de lot : contient le bouton toggle + le lien de sélection */
.lot-item-wrapper {
  display: flex;
  align-items: center;
  gap: 10px;
  /* min-height + box-sizing : hauteur de ligne CONSTANTE. Les lots actifs
     portent le cluster contrôles (verrou/RG, ~22px) + le montant, absents des
     lots inactifs -> sans ça, les lignes grisées faisaient 35px vs 41px. */
  min-height: 41px;
  box-sizing: border-box;
  padding: 9px 12px 9px 18px;   /* +left pour laisser place à la pastille de statut */
  border-bottom: 1px solid #f5f6f9;
  position: relative;
  transition: background 0.12s;
}
/* Pastille de statut à gauche : SEUL indicateur d'état (couleur posée par
   .status-* ci-dessous). Refonte 2026-07-21 : ex-liseré pleine hauteur à bords
   carrés -> pilule arrondie insérée (rendu plus moderne). */
.lot-item-wrapper::before {
  content: '';
  position: absolute;
  left: 7px;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: calc(100% - 16px);
  min-height: 14px;
  border-radius: 4px;
  background: #d4d7de;          /* neutre par défaut */
  transition: background 0.12s, height 0.15s ease;
}
/* Lot ouvert : la pastille s'étire un peu (feedback visuel). */
.lot-item-wrapper.active::before { height: calc(100% - 10px); }
.lot-item-wrapper:hover { background: #f8fafe; }
/* Lot ouvert (courant) : surlignage de fond bleu doux. Le liseré gauche garde
   la couleur du statut (pas de barre bleue qui écraserait l'info de statut). */
.lot-item-wrapper.active { background: #eef3ff; }
.lot-item-wrapper.inactive .lot-link { opacity: 0.45; }

/* Lien de sélection (nom du lot + total). Le toggle reste à pleine opacité même
   si le lot est inactif, sinon on ne peut plus le voir/cliquer pour réactiver. */
.lot-link {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  /* Rapproche le bloc n°+nom du toggle (réduit l'espace toggle↔texte
     sans toucher au gap des contrôles à droite). */
  margin-left: -4px;
  text-decoration: none;
  color: var(--text);
  min-width: 0;
}
.lot-link:hover { text-decoration: none; }

/* Bouton toggle (ex-span, devenu <button> pour cliquer en HTMX) */
.lot-toggle {
  width: 28px;
  height: 16px;
  background: #c5cad3;
  border-radius: 8px;
  position: relative;
  flex-shrink: 0;
  transition: background 0.18s;
  border: none;
  padding: 0;
  cursor: pointer;
}
.lot-toggle.on { background: var(--blue); }
.lot-toggle::after {
  content: '';
  position: absolute;
  width: 12px;
  height: 12px;
  background: #fff;
  border-radius: 50%;
  top: 2px;
  left: 2px;
  transition: left 0.18s;
}
.lot-toggle.on::after { left: 14px; }
.lot-toggle:hover:not(:disabled) { filter: brightness(0.95); }
.lot-toggle:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* Chiffrage figé : le toggle d'activation et le cadenas par lot ne répondent
   plus (leur POST `lot_update` est refusé par ChiffrageLockMiddleware). Sans
   cette règle ils gardaient leur aspect cliquable, curseur main compris. */
.lot-toggle:disabled,
.lot-lock:disabled {
  opacity: .45;
  cursor: not-allowed;
}

/* Cluster de contrôles à droite (verrou + RG), juste avant le montant. */
.lot-ctrls {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
}

/* Verrou du lot (refonte 2026-05-26) :
   - .is-locked  : 🔒 vert PERMANENT (lot verrouillé) -> clic = déverrouille
   - .lock-add   : 🔒 gris révélé AU SURVOL de la ligne -> clic = verrouille
   Au repos, un lot non verrouillé n'affiche donc rien (propre). */
.lot-lock {
  width: 22px;
  height: 22px;
  border-radius: 4px;
  border: 1px solid transparent;
  background: #fff;
  padding: 0;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.12s;
}
.lot-lock.is-locked {
  background: #e6f7ec;
  border-color: #b8e3c6;
  color: #1f8a4c;
}
.lot-lock.is-locked:hover {
  background: #d0eedb;
  border-color: #82c69b;
}
.lot-lock.lock-add {
  border-color: #d6d9e0;
  color: var(--muted);
  opacity: 0;
}
.lot-item-wrapper:hover .lot-lock.lock-add { opacity: 1; }
.lot-lock.lock-add:hover {
  border-color: #1f8a4c;
  color: #1f8a4c;
  background: #e6f7ec;
}
.lot-lock:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* Contrôle RG par lot (refonte 2026-05-26). Visible seulement quand le master
   RG projet est actif (cf. _lot_item.html). Deux états :
   - .rg-add : bouton "RG" gris révélé AU SURVOL (RG appliquée -> clic = exclut).
     Au repos rien -> fini le "mur d'or" (la RG appliquée est la norme).
   - .rg-off : "SANS RG" doré PERMANENT (lot exclu -> clic = réinclut).
     C'est le seul cas où l'or apparaît au repos : l'exception saute aux yeux. */
.lot-rg {
  height: 22px;
  border-radius: 4px;
  border: 1px solid transparent;
  background: #fff;
  cursor: pointer;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  padding: 0 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.12s;
}
.lot-rg.rg-add {
  border-color: #d6d9e0;
  color: var(--muted);
  opacity: 0;
  text-decoration: line-through;   /* RG barré = "on enlève la RG de ce lot" */
}
.lot-item-wrapper:hover .lot-rg.rg-add { opacity: 1; }
.lot-rg.rg-add:hover {
  border-color: #8b6914;
  color: #8b6914;
  background: #f5ecd9;
}
.lot-rg.rg-off {
  border: 1px dashed #c9a875;
  background: #f5ecd9;
  color: #8b6914;
}
.lot-rg.rg-off:hover {
  background: #ebdbb8;
  border-color: #a88b50;
}
.lot-rg:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* =========================================================================
   STATUTS DE LOT EN SIDEBAR
   Le statut renseigne d'un coup d'oeil ou en est le chiffrage du lot.
   Couleurs tres faibles, juste pour un reperage visuel.
     - a_chiffrer : actif + aucun poste                  → rouge tres faible
     - en_cours   : actif + au moins un poste, non verrouille → orange tres faible
     - verrouille : chiffrage finalise                   → vert (cf. .locked)
     - inactif    : toggle off                           → grise (cf. .inactive)
   .active (lot ouvert dans le main) renforce la teinte avec une bordure laterale
   de la couleur du statut, pour rester coherent (et non bleue).
   ========================================================================= */
/* Refonte 2026-05-26 : le statut se lit UNIQUEMENT via la couleur du liseré
   gauche (.lot-item-wrapper::before). Plus de fond coloré ni de texte rouge :
   les lignes restent blanches/neutres, la liste respire. */
.lot-item-wrapper.status-a-chiffrer::before { background: #cc1030; }   /* rouge foncé (distinct de l'orange) */
.lot-item-wrapper.status-en-cours::before   { background: #e88a1e; }   /* orange */
.lot-item-wrapper.status-verrouille::before { background: #18a05a; }   /* vert */
.lot-item-wrapper.status-inactif::before    { background: #cfd3da; }   /* gris */

/* Tag "désactivé" à côté du nom du lot dans la zone principale */
.lot-inactif-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #888;
  background: #f0f0f0;
  padding: 2px 8px;
  border-radius: 12px;
  margin-left: 10px;
  vertical-align: middle;
}

/* Tag "verrouillé" : pendant vert du tag desactive */
.lot-verrouille-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #1f8a4c;
  background: #e6f7ec;
  padding: 2px 8px;
  border-radius: 12px;
  margin-left: 10px;
  vertical-align: middle;
}

/* Banniere read-only en haut de la zone principale quand le lot est non-editable.
   Couleur differente selon la cause : verrouille (vert) ou desactive (gris). */
.lot-readonly-banner {
  padding: 10px 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 12px;
  border: 1px solid transparent;
}
.lot-readonly-banner.is-locked {
  background: #e6f7ec;
  color: #1f8a4c;
  border-color: #b8e3c6;
}
.lot-readonly-banner.is-inactive {
  background: #f3f4f7;
  color: #6b6f78;
  border-color: #dadde4;
}

/* Quand le lot courant est non-editable, on grise la zone principale (sauf la
   banniere) et on bloque tout pointeur. Les inputs ont aussi un disabled cote
   HTML, donc double protection : visuelle + fonctionnelle. */
.chiffrage-layout.lot-inactive .chiffrage-main .postes-grid,
.chiffrage-layout.lot-locked .chiffrage-main .postes-grid,
.chiffrage-layout.lot-inactive .chiffrage-main .lot-title-bar,
.chiffrage-layout.lot-locked .chiffrage-main .lot-title-bar,
.chiffrage-layout.lot-inactive .chiffrage-main .total-lot-bar,
.chiffrage-layout.lot-locked .chiffrage-main .total-lot-bar,
.chiffrage-layout.lot-inactive .chiffrage-main .postes-actions-top,
.chiffrage-layout.lot-locked .chiffrage-main .postes-actions-top,
.chiffrage-layout.lot-inactive .chiffrage-main .legend,
.chiffrage-layout.lot-locked .chiffrage-main .legend {
  opacity: 0.55;
}
.chiffrage-layout.lot-inactive .chiffrage-main .postes-actions-top button,
.chiffrage-layout.lot-locked .chiffrage-main .postes-actions-top button,
.chiffrage-layout.lot-inactive .chiffrage-main .marge-inline-input,
.chiffrage-layout.lot-locked .chiffrage-main .marge-inline-input,
.chiffrage-layout.lot-inactive .chiffrage-main .cell-input,
.chiffrage-layout.lot-locked .chiffrage-main .cell-input {
  cursor: not-allowed;
  background: #fafafa;
}

.lot-name {
  flex: 1;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);              /* encre neutre, plus de rouge */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* N° aligné à droite sur une colonne fixe. Police de l'app (pas de mono) ;
   chiffres alignés via tabular-nums pour garder une colonne propre. */
.lot-num {
  font-size: 12px;
  color: var(--muted);
  font-weight: 600;
  min-width: 22px;
  text-align: right;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.custom-tag {
  font-size: 10px;
  color: #8e44ad;
  background: #f3e6f8;
  padding: 1px 6px;
  border-radius: 3px;
  margin-left: 6px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Montant à l'extrême droite : colonne fixe alignée et scannable. Police de
   l'app (pas de mono), chiffres alignés via tabular-nums. */
.lot-total {
  font-size: 12.5px;
  color: var(--text);
  font-weight: 600;
  min-width: 72px;
  text-align: right;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

/* Separateur entre lots standard et lots custom */
.lots-section-separator {
  padding: 14px 14px 6px;
  margin-top: 6px;
  border-top: 1px dashed var(--border);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 700;
}

/* Lot custom : nom en italique violet pour le distinguer visuellement */
.lot-item-wrapper:has(.lot-link) .lot-link .lot-name { /* default */ }
/* Pas de class JS pour le moment — on style via .lot-link a partir de la classe parent */
.lots-list .lot-item-wrapper.lot-custom .lot-name {
  color: #8e44ad;
  font-style: italic;
}

/* Form de création de lot custom dans la sidebar */
.lot-custom-add-form {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  border-top: 1px dashed var(--border);
  background: #fafbfc;
}

.lot-custom-add-form input[type="text"] {
  flex: 1;
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 5px;
  font-size: 12px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  min-width: 0;
}

.lot-custom-add-form input[type="text"]:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.12);
}

.lot-custom-add-form button {
  width: 28px;
  height: 28px;
  background: #eef7ee;
  border: 1px solid #c8e0c8;
  border-radius: 5px;
  color: #2e7d2e;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
}
.lot-custom-add-form button:hover { background: #d8ecd8; border-color: #2e7d2e; }

/* Bouton "Modifier les lots" en bas de sidebar (mode normal) */
.lots-edit-trigger {
  display: block;
  padding: 10px 14px;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  text-decoration: none;
  border-top: 1px solid var(--border);
  background: #fafbfc;
  font-weight: 500;
  cursor: pointer;
}
.lots-edit-trigger:hover {
  background: #f0f4ff;
  color: var(--blue);
  text-decoration: none;
}

/* Mode édition : grise le main area pour focus sur la sidebar */
.chiffrage-layout.edit-mode .chiffrage-main {
  pointer-events: none;
  opacity: 0.35;
  filter: grayscale(0.4);
  transition: opacity 0.15s, filter 0.15s;
}

/* Form d'édition des lots */
.lots-edit-form {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
}

.lots-edit-help {
  padding: 10px 14px;
  font-size: 11.5px;
  color: var(--muted);
  background: #fffbe7;
  border-bottom: 1px solid #f5e9b8;
  margin: 0;
  line-height: 1.4;
}

.lots-edit-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px 10px;
}

.lot-edit-row {
  display: grid;
  grid-template-columns: 60px 1fr;
  gap: 6px;
  margin-bottom: 6px;
  align-items: center;
}

.lot-edit-row.has-error .lot-edit-numero,
.lot-edit-row.has-error .lot-edit-nom {
  border-color: var(--danger);
  background: var(--danger-bg);
}

.lot-edit-row .lot-edit-error {
  grid-column: 1 / -1;
  font-size: 11px;
  color: var(--danger);
  padding: 2px 4px;
}

.lot-edit-numero,
.lot-edit-nom {
  height: 28px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 12px;
  font-family: inherit;
  background: #fff;
  color: var(--text);
  box-sizing: border-box;
}
.lot-edit-numero { font-weight: 700; text-align: center; }
.lot-edit-numero:focus,
.lot-edit-nom:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.12);
}

.lots-edit-actions {
  display: flex;
  gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
  background: #fafbfc;
}
.lots-edit-actions .btn-cancel,
.lots-edit-actions .btn-validate {
  flex: 1;
  padding: 8px 12px;
  border: none;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
}
.lots-edit-actions .btn-cancel {
  background: #fff;
  border: 1px solid var(--border);
  color: var(--muted);
}
.lots-edit-actions .btn-cancel:hover { background: var(--bg); color: var(--text); }
.lots-edit-actions .btn-validate {
  background: var(--blue);
  color: #fff;
}
.lots-edit-actions .btn-validate:hover { background: var(--blue-2); }

/* Input marge inline dans la barre titre du lot (a cote du recap chiffres) */
.marge-inline {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
.marge-inline-input {
  width: 56px;
  padding: 3px 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
  color: var(--blue);
  background: #fff;
  text-align: right;
  box-sizing: border-box;
}
.marge-inline-input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.15);
}
/* Supprimer les fleches natives sur ce input number */
.marge-inline-input::-webkit-outer-spin-button,
.marge-inline-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.marge-inline-input { -moz-appearance: textfield; appearance: textfield; }

/* ----- Main content chiffrage -----
   Layout vertical : seul le tableau .postes-grid scrolle (sticky header inside).
   Le bandeau lot, la legende, les boutons + et la barre de total restent figes.
   La sidebar a son propre scroll. */
.chiffrage-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;     /* indispensable pour que le child overflow auto fonctionne */
  overflow: hidden;
  padding: 16px 20px;
}

/* Vue PAR ZONE : meme principe que le mode par poste (header du lot fige en
   haut, total fige en bas, scroll au milieu), mais le conteneur scrollable est
   .zones-scroll (qui enveloppe les N sections de zones) au lieu d'une unique
   .postes-grid. Les sections s'y enchainent a hauteur naturelle ; sans ce
   wrapper, chaque section etait un flex-child de .chiffrage-main qui se faisait
   ecraser (flex-shrink) -> ~4 lignes visibles, scroll impossible (bug 2026-06-02).
   .chiffrage-main reste flex column overflow:hidden -> le header (lot-title-bar,
   selecteur de mode, legende) NE defile PAS, seul .zones-scroll defile. */
.zones-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;     /* indispensable pour que l'overflow auto fonctionne en flex */
}
/* En vue par zone, la grille ne doit defiler QU'EN HORIZONTAL : son contenu
   tient en hauteur (c'est .zones-scroll qui gere le defilement vertical de
   toutes les zones). Si on laissait overflow-y:auto, la grille deviendrait un
   conteneur scrollable qui capte la molette verticale SANS pouvoir defiler
   (0 debordement vertical) et SANS la propager a .zones-scroll -> scroll
   vertical mort des qu'une zone a beaucoup de lignes (bug 2026-06-02).
   overflow-y:hidden la rend non-scrollable verticalement -> la molette est
   propagee au parent. overflow-x:auto conserve le scroll horizontal du tableau
   large. (overflow-y:hidden ne masque rien : la grille fait la hauteur de son
   contenu.) */
.zones-scroll .postes-grid {
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 10px;
}

/* Barre de defilement horizontale de la vue PAR ZONE, posee en bas de
   .chiffrage-main (hors du conteneur scrollable) -> toujours visible, quelle
   que soit la position dans la liste des zones. Elle pilote le scroll
   horizontal de toutes les grilles de zone (cf. chiffrage-scroll.js).
   Creee/dimensionnee en JS ; absente en vue par poste (barre native deja en bas
   du viewport) et sur les ecrans assez larges pour tout afficher. */
.zones-hbar {
  flex: none;
  overflow-x: scroll;
  overflow-y: hidden;
  height: 12px;
  margin-top: 3px;
}
.zones-hbar > div {
  height: 1px; /* seule la LARGEUR compte : elle cree le debordement a defiler */
}
/* macOS/WebKit : sans -webkit-appearance:none la barre est en mode "overlay",
   donc invisible au repos -> impossible a saisir a la souris. On force une
   barre permanente et visible, c'est tout l'interet de ce composant.
   ⚠️ NE PAS ajouter `scrollbar-width` ici : dans Chromium la propriete standard
   DESACTIVE ::-webkit-scrollbar et on retombe en overlay invisible (mesure le
   2026-09-07 : 0px consomme avec, 10px sans). Elle est donc reservee a Firefox
   plus bas, qui lui ignore ::-webkit-scrollbar. */
.zones-hbar::-webkit-scrollbar {
  -webkit-appearance: none;
  height: 10px;
}
.zones-hbar::-webkit-scrollbar-track {
  background: #eef1f6;
  border-radius: 5px;
}
.zones-hbar::-webkit-scrollbar-thumb {
  background: #b6bfd2;
  border-radius: 5px;
  border: 2px solid #eef1f6;
}
.zones-hbar::-webkit-scrollbar-thumb:hover {
  background: #8e9cba;
}
/* Firefox : ignore ::-webkit-scrollbar -> proprietes standard, scopees ici pour
   ne pas neutraliser le bloc WebKit ci-dessus (cf. avertissement). */
@supports not selector(::-webkit-scrollbar) {
  .zones-hbar {
    scrollbar-width: thin;
    scrollbar-color: #b6bfd2 #eef1f6;
  }
}

.lot-title-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  min-height: 28px;        /* hauteur stable, evite le saut quand le badge */
                           /* desactive apparait/disparait */
}
.lot-title-bar h2 {
  font-size: 15px;
  font-weight: 700;
  color: var(--navy);
  line-height: 1.6;        /* assez d'espace vertical pour contenir le badge */
                           /* sans pousser le contenu vers le bas */
}
.lot-title-bar .lot-summary {
  display: flex;
  align-items: center;     /* centre verticalement Prix achat / Marge / Total */
  gap: 22px;
  font-size: 12px;
}
.lot-summary .s-item { color: var(--muted); }
.lot-summary .s-val { font-weight: 700; color: var(--navy); }
.lot-summary .s-val.blue { color: var(--blue); }

/* Selecteur de template par lot : visible juste sous la lot-title-bar.
   Toggle entre "Par poste" (template historique, matrice) et "Par zone"
   (postes regroupes par zone). Verrouille des qu'un poste est cree. */
.lot-template-selector {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px 0;
  flex-wrap: wrap;
}
.lot-template-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}
.lot-template-toggle {
  display: inline-flex;
  background: #eef0f5;
  border-radius: 999px;
  padding: 3px;
  margin: 0;
}
.lot-template-toggle label {
  cursor: pointer;
  padding: 5px 14px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 999px;
  color: var(--muted);
  transition: background 0.15s, color 0.15s;
  user-select: none;
}
.lot-template-toggle label.active {
  background: var(--surface);
  color: var(--blue);
  box-shadow: 0 1px 2px rgba(26, 35, 64, 0.08);
}
.lot-template-toggle label input { display: none; }
.lot-template-hint {
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
}
.lot-template-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
}
.lot-template-badge--poste { background: #eef3ff; color: var(--blue); }
.lot-template-badge--zone  { background: #fef3cd; color: #8a6814; }

/* Bouton "Importer Excel" : placeholder feature Phase 3, desactive
   visuellement pour signaler le perimetre. Pousse a droite via
   margin-left:auto pour finir la rangee proprement. */
.lot-template-import-btn {
  margin-left: auto;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  background: var(--bg);
  color: var(--muted);
  border: 1px dashed var(--border);
  border-radius: 6px;
  cursor: not-allowed;
  opacity: 0.7;
}

/* Bouton "↩ Annuler" (undo de la derniere edition de cellule). Cliquable,
   pousse a droite (avant le bouton import, lui aussi margin-left:auto). */
.chiffrage-undo-btn {
  margin-left: auto;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.chiffrage-undo-btn:hover {
  background: #eef3ff;
  border-color: var(--blue);
  color: var(--blue-2);
}
.chiffrage-undo-btn:active { background: #e2ebff; }
/* Quand le bouton undo est present, le bouton import n'a plus besoin de l'auto
   (l'undo l'a deja pousse a droite) : ils se suivent a droite. */
.chiffrage-undo-btn + .lot-template-import-btn { margin-left: 8px; }

/* ----- Menu "Valider" de la barre d'outils du chiffrage -------------------
   Raccourci vers les 2 actions de fin de chiffrage (valider une version /
   passer en facturation), sinon disponibles seulement sur Resume & Exports.
   Bati sur <details>/<summary> natif : l'ouverture ne coute pas de JS, ce qui
   compte ici car #chiffrage-content est re-rendu en boucle par HTMX. */
.chiffrage-actions {
  position: relative;
  margin-left: auto;      /* pousse le groupe a droite si "Annuler" est absent */
}
/* "Annuler" porte deja margin-left:auto : deux `auto` cote a cote se
   partageraient l'espace libre et decolleraient les boutons l'un de l'autre.
   Le premier element a droite garde l'auto, les suivants un simple gap. */
.chiffrage-undo-btn + .chiffrage-actions { margin-left: 8px; }
.chiffrage-actions + .lot-template-import-btn { margin-left: 8px; }

/* Declencheur : meme gabarit que le bouton "Annuler" voisin, teinte vert au
   survol / a l'ouverture pour annoncer la couleur des actions du menu. */
.chiffrage-actions-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  user-select: none;
  list-style: none;       /* retire le triangle natif du <summary> (Firefox) */
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.chiffrage-actions-trigger::-webkit-details-marker { display: none; }
.chiffrage-actions-trigger:hover,
.chiffrage-actions[open] .chiffrage-actions-trigger {
  background: #e6f7ec;
  border-color: #82c69b;
  color: #136634;
}
/* Chevron du declencheur (heroicon micro, dessine plein). Taille FIXE en px et
   non en em comme .ic : un chevron est un affordance de menu, il ne doit pas
   grossir avec le libelle. La regle vient apres .ic dans la feuille, elle gagne
   donc a specificite egale. Legerement estompe au repos pour rester en retrait
   du libelle, plein a l'ouverture. */
.chiffrage-actions-caret {
  width: 12px;
  height: 12px;
  margin-left: 1px;
  opacity: 0.55;
  transition: transform .12s ease, opacity .12s ease;
}
.chiffrage-actions[open] .chiffrage-actions-caret {
  transform: rotate(180deg);
  opacity: 1;
}

/* Panneau : meme langage visuel que .poste-insert-menu, l'autre menu
   contextuel du chiffrage. Ancre a droite, le declencheur etant colle au bord
   droit de la barre. z-index 60 = au-dessus d'une cellule focus (50), sous les
   modales (1000). */
.chiffrage-actions-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 60;
  min-width: 232px;
  padding: 4px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(26, 35, 64, 0.14);
}
.chiffrage-actions-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
/* Memes couleurs que les boutons .resume-action-* de Resume & Exports : c'est
   la meme action, elle doit se reconnaitre d'un ecran a l'autre. */
.chiffrage-actions-item--validate { color: #1f8a4c; }
.chiffrage-actions-item--validate:hover { background: #e6f7ec; color: #136634; }
.chiffrage-actions-item--facturation { color: #8a6814; }
.chiffrage-actions-item--facturation:hover { background: #fdf2cc; color: #6b5010; }

/* ----- Légende ----- */
.legend {
  display: flex;
  gap: 18px;
  margin-bottom: 10px;
  font-size: 11px;
  color: var(--muted);
  align-items: center;
}
.legend-item { display: flex; align-items: center; gap: 6px; }
.legend-dot { width: 11px; height: 11px; border-radius: 2px; }
.legend-dot.visible { background: #eef3ff; border: 1px solid var(--blue); }
.legend-dot.internal { background: #fff8f2; border: 1px solid #e67e22; }
.legend-dot.option { background: #fffbf0; border: 1px solid #f39c12; }

/* =========================================================================
   POSTES — CSS GRID (refonte from scratch)
   Chaque ligne est une grid avec exactement les memes 10 colonnes.
   Alignement deterministe par construction, plus de quirks de table HTML.
   ========================================================================= */

.postes-grid {
  background: #fff;
  border: 1px solid #eaecef;
  border-radius: 4px;
  overflow: auto;          /* x ET y : scroll local au tableau */
  width: 100%;
  flex: 1 1 auto;          /* prend tout l'espace restant dans .chiffrage-main */
  min-height: 0;           /* permet au container flex de retreindre la hauteur */
}

.row {
  display: grid;
  grid-template-columns:
    76px                 /* col-numero : + (inserer) | N° cliquable | ⋮⋮ | 🗑 */
    350px                /* col-designation : largeur FIXE (+20) ; texte long -> wrap 2 lignes */
    60px                 /* col-unite */
    334px                /* col-qte : P2 -> 3 sous-colonnes Chrome / Entr. / Retenue (+5 chacune) */
    110px                /* col-pu */
    130px                /* col-total */
    130px                /* col-achat (bumpe pour eviter wrap des montants honoraires) */
    110px                /* col-marge (checkbox + input + %, evite la troncature) */
    minmax(140px, 1fr)   /* col-fournisseur : flex (grandit avec la fenêtre) */
    120px                /* col-ref-devis : largeur FIXE (ne grandit jamais avec la fenêtre) */
    minmax(140px, 1fr)   /* col-commentaire : flex (grandit avec la fenêtre) */
    44px;                /* col-flag : checkbox surligner */
  /* DOIT valoir EXACTEMENT la somme des colonnes ci-dessus (les deux `1fr`
     comptant pour leur minimum de 140) :
       76+350+60+334+110+130+130+110+140+120+140+44 = 1744
     Si min-width est INFERIEUR a cette somme, la grille deborde de sa propre
     boite sur ecran etroit (13", ou les `1fr` sont a leur minimum) : le fond de
     la ligne s'arrete avant la derniere colonne et la case "surligner" se
     retrouve sur bande blanche au lieu du jaune. C'etait le cas a 1720 (24 px
     de trop peu). A recalculer a chaque ajout/redimensionnement de colonne. */
  min-width: 1744px;
  width: 100%;
}

/* ===== P2 : colonne Qté = 3 sous-parties Chrome / Entreprise / Retenue ===== */
.qte3 { display: flex; gap: 3px; width: 100%; align-items: center; justify-content: flex-end; }
.qte3 > * { flex: 0 0 auto; }
/* Chrome / Entreprise : input qté + bouton ƒx (calcul minute) côte à côte.
   Bande de couleur derrière chaque sous-colonne (violet pâle Chrome / vert pâle
   Entreprise) reprise de la maquette pour bien distinguer les deux colonnes. */
.q3-chrome,
.q3-entre  { width: 102px; display: flex; align-items: center; gap: 3px; justify-content: flex-end;
             border-radius: 6px; padding: 1px 3px; }
.q3-chrome { background: #ece5ff; }   /* bande violet pâle (Chrome) — couleur maquette */
.q3-entre  { background: #d8f5ec; }   /* bande vert pâle (Entreprise) */
.q3-ret    { width: 120px; display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
.qte3 input.cell-input-num { width: 100%; }
/* dans Chrome/Entr : l'input prend la place restante, le ƒx garde sa largeur.
   On ne force AUCUN fond : `.cell-input` est déjà transparent (bordure
   transparente, texte bleu, focus jaune pâle) -> la bande colorée de la
   sous-colonne transparaît à travers l'input, pas de boîte blanche. */
.q3-chrome > input.cell-input-num,
.q3-entre  > input.cell-input-num { flex: 1 1 auto; width: auto; min-width: 0; text-align: right; }
/* en-tête (fond navy) : pas de bande colorée derrière les sous-libellés. */
.row-header .q3-chrome,
.row-header .q3-entre { background: transparent; padding: 0; }
/* input piloté par un métré (readonly) : on garde la bande de la colonne
   (fond transparent, pas de boîte ni de liseré) ; le repère « piloté » = valeur
   en gras + ƒx bleu. */
.qte3 input.cell-input-num[readonly] { background: transparent; font-weight: 700;
                                       color: var(--navy); cursor: pointer; }
/* bouton ƒx : ouvre la modale Calcul minute ; bleu quand un métré pilote la cellule. */
.metre-fx { flex: 0 0 auto; font-size: 9px; font-weight: 700; line-height: 1.4; cursor: pointer;
            border: 1px solid #d4d9e6; background: #fff; color: #8a93a6; border-radius: 4px;
            padding: 1px 3px; user-select: none; }
.metre-fx:hover { border-color: #b9c2d6; color: #5a48b0; }
.metre-fx.driven { background: #2d5bff; color: #fff; border-color: #2d5bff; }
/* en-tête : sous-libellés colorés (sur fond navy) */
.row-header .qte3 > span { font-size: 10.5px; letter-spacing: .04em; text-align: right; line-height: 1.1; white-space: nowrap; }
.q3lab-chrome { color: #cdbcff; }
.q3lab-entre  { color: #9fe6d8; }
.q3lab-ret    { color: #fff; }
/* sommes (ligne poste, lecture seule) */
.q3sum { font-weight: 700; }
.q3sum.c { color: #5a48b0; }
.q3sum.e { color: #1b8b7f; }
.q3sum.r { color: var(--navy); }
.q3sum.r.low { color: #c0392b; }
/* retenue : valeur + chips C/E */
.q3ret-val { font-weight: 700; color: var(--navy); }
.q3ret-val.low { color: #c0392b; }
.q3chip { font-size: 9px; font-weight: 800; border-radius: 4px; padding: 0 4px; cursor: pointer;
          border: 1px solid #d4d9e6; background: #fff; color: #8a93a6; line-height: 1.6; user-select: none; }
.q3chip:hover:not(.is-readonly) { border-color: #b9c2d6; }
.q3chip.active.c { background: #ece7ff; color: #5a48b0; border-color: #cdbcff; }
.q3chip.active.e { background: #d8f5ef; color: #1b8b7f; border-color: #a6e6da; }
/* Lot non éditable : les puces ne restent qu'un indicateur (quelle quantité est
   retenue). Ce sont des <span>, pas des <button> — `disabled` glisse dessus, le
   partial _q3_chips.html rend donc une variante sans attribut hx-*. */
.q3chip.is-readonly { cursor: default; }
.q3warn { color: #c0392b; font-weight: 800; cursor: help; margin-right: 2px; }

/* Cellules numeriques : pas de wrap, sinon les montants longs (honoraires
   a 15 000 €) s'affichent sur 2 lignes et cassent l'alignement vertical. */
.cell.col-num {
  white-space: nowrap;
}

/* Colonne "surligner" : checkbox centree, header avec icone. */
.cell.col-flag {
  justify-content: center;
  padding: 7px 4px;
}
.row-header .cell.col-flag {
  color: #f0c869;       /* warning subtil dans le header */
  font-size: 14px;
}
.flag-cell .flag-checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: #d4a017;  /* jaune-orange pour la coherence visuelle avec le highlight */
  margin: 0;
}

/* Ligne surlignee : fond jaune subtil, plus marque au hover. */
.row.is-flagged {
  background: #fff8dc !important;
}
.row.is-flagged:hover {
  background: #fdf3c3 !important;
}
/* Les cells "internal" (oranges) gardent leur teinte mais en jaunatre.
   Ici on force la cellule a heriter du fond de la ligne pour eviter le
   patchwork visuel (orange melange avec jaune). */
.row.is-flagged .cell.cell-internal {
  background: transparent;
}

.cell {
  padding: 7px 9px;
  font-size: 12.5px;
  border-bottom: 1px solid #f0f2f6;
  display: flex;
  align-items: center;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ---- Colonnes alignees a droite (chiffres) ---- */
.cell.col-num { justify-content: flex-end; }

/* ---- Header (navy) ---- */
.row-header {
  background: var(--navy);
  color: #fff;
  /* Reste fige en haut du tableau pendant le scroll vertical des postes.
     z-index 5 pour passer au-dessus des inputs/cellules qui scrollent dessous. */
  position: sticky;
  top: 0;
  z-index: 5;
}
.row-header .cell {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: none;
  border-right: 1px solid #2a3550;
}
.row-header .cell:last-child { border-right: none; }
.row-header .cell.cell-internal {
  background: #3d2800;
  color: #ffa94d;
  border-right-color: #4d3500;
}
.row-header .cell.cell-internal-first { border-left: 3px solid #e67e22; }

/* ---- Numero d'item ---- */
.cell.col-numero {
  justify-content: center;
  font-size: 11px;
  color: var(--muted);
  font-weight: 600;
}
.row-header .cell.col-numero { color: #fff; }

/* ---- Lignes postes ---- */
.row-poste,
.row-option {
  background: #fff;
  border-top: 2px solid #c5cad3;     /* separation marquee entre groupes poste/option */
}
.row-poste:hover { background: #fafbff; }

/* Vue par zone (.postes-dropzone) : separation entre postes plus fine et plus
   claire. La vue par poste (.poste-block) garde le 2px marque ci-dessus. */
.postes-dropzone .row-poste {
  border-top-width: 1px;
  border-top-color: #dce0ea;
}

/* ---- Cellules internes (oranges, masquees export) ---- */
.cell.cell-internal {
  background: #fff8f2;
  border-left: 1px solid #fde0c0;
}
.cell.cell-internal-first {
  border-left: 3px solid #e67e22;
}

/* ---- Cellules calculees (non-editables) : NOIR ---- */
.qte-cell { font-weight: 700; color: var(--text); }       /* somme des qty zones (vue par poste) */
/* Vue par zone : Chrome / Entreprise sont des champs éditables (pas une somme)
   -> poids NORMAL. Le gras .qte-cell reste réservé aux sommes de la vue par
   poste ; la retenue garde son gras (.q3ret-val). */
.qte-cell.zone-qty .q3-chrome,
.qte-cell.zone-qty .q3-entre,
.qte-cell.zone-qty .q3-chrome input,
.qte-cell.zone-qty .q3-entre input,
.qte-cell.zone-qty .q3-chrome input[readonly],
.qte-cell.zone-qty .q3-entre input[readonly] { font-weight: 400; }
.total-cell { font-weight: 700; color: var(--navy); }     /* qty * PU */
.option-total { color: #c0392b; }                          /* exception : option en rouge */
.marge-auto { font-size: 11px; color: #c07000; font-weight: 600; }

/* ---- Lignes zones (compactes, plus serrees que les postes) ---- */
.row-zone {
  background: #f7f9ff;
}
.row-zone .cell {
  padding: 2px 9px;                /* tres compact, feeling tableur dense */
  font-size: 11px;
  color: #555;
  border-bottom: 1px solid #eef0f5;
}
.row-zone .cell-input {
  padding: 2px 6px;
  height: auto;
}
.row-zone .zone-label {
  padding-left: 24px;
  color: var(--text);              /* nom zone non-editable = noir */
  font-weight: 500;
  white-space: nowrap;
}
.row-zone .zone-qty {
  font-weight: 700;
  color: var(--blue);              /* qty zone editable = bleu */
}
.row-zone-empty .zone-empty-cell {
  color: var(--muted);
  font-style: italic;
}

/* ---- Section row (banner "Options du lot") ---- */
.row-section {
  display: block;        /* pas de grid : c'est une banniere full-width */
  background: #fef9f0;
  padding: 6px 12px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #c07000;
  font-weight: 700;
  border-top: 2px solid #f39c12;
  border-bottom: 1px solid #fdecc8;
}

/* ---- Lignes options ---- */
.row-option {
  background: #fffbf0;
  border-bottom: 1px solid #fdecc8;
  font-style: italic;
}
.row-option .cell { color: #7d5a00; }
.row-option .cell.cell-internal { background: #fff8e8; }
.row-option .cell:first-child { border-left: 3px solid #f39c12; }

/* ============= EDITION INLINE DES POSTES (iter 4a) ============= */

/* Regle generale : tout ce qui est editable (cell-input) en BLEU.
   Les cellules calculees (qte sum, PU client, total) en NOIR. */
.cell-input {
  width: 100%;
  border: 1px solid transparent;
  background: transparent;
  font: inherit;
  color: var(--blue);          /* editable = bleu */
  padding: 4px 6px;
  border-radius: 3px;
  box-sizing: border-box;
  outline: none;
}
.cell-input:hover:not(:disabled) {
  background: #fafbff;
  border-color: #e0e4eb;
}
.cell-input:focus {
  background: #fffbe7;
  border-color: var(--blue);
  box-shadow: 0 0 0 2px rgba(59, 110, 245, 0.15);
}
.cell-input:disabled {
  color: #aaa;
  cursor: not-allowed;
}
.cell-input-num { text-align: right; }
.cell-input-num::-webkit-outer-spin-button,
.cell-input-num::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.cell-input-num { -moz-appearance: textfield; appearance: textfield; }

/* Designation = <textarea> : largeur fixe (colonne), auto-hauteur 1 -> 2 lignes
   quand le texte est long (field-sizing), puis scroll au-delà. Pas de poignée
   de resize, retour à la ligne sur mots longs. */
/* Texte d'aide de la designation : une ligne neuve n'a plus la vraie valeur
   "Nouveau poste" qu'il fallait effacer avant de saisir (remonte 2026-09-07),
   mais un placeholder -- il s'efface donc tout seul a la frappe, et n'apparait
   JAMAIS sur une ligne deja renseignee. En italique + gris clair pour qu'on
   voie au premier coup d'oeil que c'est une aide, pas un contenu. */
.cell-input-designation::placeholder {
  color: #a9b0be;
  font-style: italic;
  opacity: 1;   /* Firefox applique une opacite par defaut */
}

.cell-input-designation {
  resize: none;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  line-height: 1.3;
  field-sizing: content;     /* auto-grandit avec le contenu (Chrome ≥ 123) */
  min-height: 1.55em;        /* ~1 ligne */
  max-height: 2.85em;        /* ~2 lignes, puis overflow */
  overflow-y: auto;
}

/* Custom dropdown unite : long form en dropdown, short form en cellule.
   Trick : <select> rendu transparent par CSS, <span> superpose montre la
   forme courte. Le dropdown deplie reste en long form (lisible). */
.unite-picker {
  position: relative;
  width: 100%;
  height: 100%;
}
.unite-short {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: 4px 8px;
  pointer-events: none;
  color: var(--blue);
  font-weight: 500;
  z-index: 1;
}
.unite-select {
  width: 100%;
  border: 1px solid transparent;
  background: transparent;
  font: inherit;
  padding: 4px 18px 4px 6px;
  border-radius: 3px;
  box-sizing: border-box;
  outline: none;
  color: transparent;          /* cache le texte de la valeur selectionnee */
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'><path fill='%233b6ef5' d='M0 0l4 5 4-5z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 4px center;
}
.unite-select option {
  color: var(--text);          /* long form en noir dans le dropdown deplie */
  background: #fff;
}
.unite-select:hover {
  background-color: #fafbff;
  border-color: #e0e4eb;
}
.unite-select:focus {
  background-color: #fffbe7;
  border-color: var(--blue);
  box-shadow: 0 0 0 2px rgba(59, 110, 245, 0.15);
}

.marge-cell {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 6px;
}
.forcer-marge-toggle {
  display: flex;
  align-items: center;
  cursor: pointer;
}
.forcer-marge-toggle input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  border: 1.5px solid var(--border);
  border-radius: 2px;
  background: #fff;
  position: relative;
  flex-shrink: 0;
}
.forcer-marge-toggle input[type="checkbox"]:checked {
  background: #c07000;
  border-color: #c07000;
}
.forcer-marge-toggle input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  top: 1px; left: 3px;
  width: 3px; height: 6px;
  border: solid #fff; border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}
.cell-input-marge {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  text-align: right;
  /* color: hérite de .cell-input (bleu si editable, gris si disabled) */
}
.marge-cell .suffix {
  font-size: 11px;
  color: var(--muted);
  flex-shrink: 0;
}

/* Cellule N° avec bouton supprimer au hover de la ligne */
/* Cellule N° = petite barre d'outils de ligne :
     [+]  N°  [⋮⋮]                        [🗑]
   Le "+" et la corbeille sont en position absolue (donc sans effet sur la
   largeur) et n'apparaissent qu'au survol ; les paddings reservent leur place
   pour que le numero ne se decale pas quand ils apparaissent. */
.cell.col-numero {
  position: relative;
  padding-left: 30px;
  padding-right: 20px;
}
.poste-numero {
  display: block;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Numero cliquable (changement de position). Se donne des airs de simple texte
   au repos : c'est un numero avant d'etre un bouton. */
.poste-numero-btn {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 1px 4px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.row-poste:hover .poste-numero-btn,
.row-option:hover .poste-numero-btn {
  border-color: #d3d9e4;
  background: #fff;
  color: var(--navy);
}
.poste-numero-btn:hover {
  border-color: var(--primary, #3b6ef5);
  color: var(--primary, #3b6ef5);
}
/* Champ de saisie de la position (remplace le bouton le temps de la saisie). */
.poste-numero-input {
  width: 34px;
  padding: 1px 2px;
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: center;
  border: 1px solid var(--primary, #3b6ef5);
  border-radius: 4px;
  background: #fff;
  color: var(--navy);
  -moz-appearance: textfield;
  appearance: textfield;
}
.poste-numero-input::-webkit-outer-spin-button,
.poste-numero-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* Bouton "+" d'insertion contextuelle, a l'extreme gauche de la ligne. */
.poste-insert {
  display: none;
  position: absolute;
  left: 1px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid #d3d9e4;
  border-radius: 4px;
  background: #fff;
  color: var(--muted);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
.poste-insert:hover {
  border-color: var(--primary, #3b6ef5);
  color: var(--primary, #3b6ef5);
}
/* Menu "au-dessus / en dessous". Rattache au <body> (et non a la cellule) pour
   echapper au clipping du tableau scrollable -> positionne en JS. */
.poste-insert-menu {
  position: absolute;
  z-index: 60;
  min-width: 168px;
  padding: 4px;
  background: #fff;
  border: 1px solid var(--border, #dde1ea);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(26, 35, 64, 0.14);
}
.poste-insert-menu button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font: inherit;
  font-size: 12.5px;
  color: var(--navy, #1a2340);
  text-align: left;
  cursor: pointer;
}
.poste-insert-menu button:hover {
  background: #eef2fb;
  color: var(--primary, #3b6ef5);
}
/* Corbeille : posee a DROITE de la cellule N° (donc entre le numero et la
   designation). Elle remplacait le numero au survol ; le numero etant devenu
   cliquable, il doit rester visible -> elle prend sa propre place. */
.poste-delete {
  display: none;
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  color: var(--danger);
  cursor: pointer;
  font-size: 12px;
  padding: 0 2px;
  border-radius: 3px;
}
.poste-delete:hover {
  background: var(--danger-bg);
  border-color: rgba(214, 69, 69, 0.3);
}
/* Le numero RESTE visible au survol : il est cliquable (changement de
   position). La corbeille ne le remplace donc plus -- elle est posee a droite
   de la cellule, et le "+" d'insertion a gauche ; les deux n'apparaissent qu'au
   survol pour garder la colonne calme au repos. */
.row-poste:hover .poste-delete,
.row-option:hover .poste-delete,
.row-poste:hover .poste-insert,
.row-option:hover .poste-insert { display: inline-flex; }

/* Boutons ajouter poste / option */
/* Barre des boutons "+ Ajouter poste/option" AU-DESSUS de la table postes */
.postes-actions-top {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  align-items: center;
}

/* Template par zone : sections groupant les postes par zone du projet.
   Chaque section a un header avec le nom de zone + surface, suivi de la
   grille de postes (meme structure que template par poste), puis des
   boutons "+ Ajouter un poste" / "+ Ajouter une option" specifiques a
   cette zone. */
.lot-zone-section {
  margin-bottom: 26px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface);
}
.lot-zone-header {
  padding: 8px 16px;
  background: #f4f6fa;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.lot-zone-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--navy);
  margin: 0;
  /* baseline interne pour aligner nom + surface sur la meme ligne de texte */
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.lot-zone-surface {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* Boutons d'ajout : a droite du nom de zone (dans le header). */
.lot-zone-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
/* Rappel d'ajout en bas de zone : deux boutons pleine largeur a bordure
   pointillee, sobres, texte centre nommant la zone (style maquette 2026-06-02).
   Hors de la .postes-grid -> restent fixes pendant le scroll horizontal. */
.lot-zone-footer {
  display: flex;
  gap: 10px;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--border);
}
.zone-footer-add {
  flex: 1;
  padding: 11px 14px;
  text-align: center;
  border-radius: 8px;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: 600;
  font-family: inherit;
  color: var(--muted);
  background: transparent;
  border: 1px dashed #c8d0dc;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.zone-footer-add:hover:not(:disabled) {
  color: var(--blue);
  border-color: var(--blue);
  background: #f5f9ff;
}
.zone-footer-add--option:hover:not(:disabled) {
  color: #c47d1a;
  border-color: #e0a64d;
  background: #fff9f0;
}
.zone-footer-add:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.row-empty {
  display: flex;
  padding: 24px 14px;
  align-items: center;
  justify-content: center;
}
.btn-add-poste, .btn-add-option {
  padding: 6px 14px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  border: 1px dashed;
}
.btn-add-poste {
  background: #eef3ff;
  border-color: var(--blue);
  color: var(--blue);
}
.btn-add-poste:hover { background: #dce8ff; }
/* Desactives (lot verrouille/desactive, ou projet fige apres passage en
   facturation) : sans ca ils gardaient leur aspect cliquable et seul le
   curseur trahissait l'etat -- on cliquait pour rien. Meme traitement que
   .btn-add-texte, leur voisin de barre. */
.btn-add-poste:disabled,
.btn-add-option:disabled {
  opacity: .5;
  cursor: not-allowed;
}
.btn-add-poste:disabled:hover { background: #eef3ff; }
.btn-add-option:disabled:hover { background: #fffbf0; }
.btn-add-option {
  background: #fffbf0;
  border-color: #f39c12;
  color: #c07000;
}
.btn-add-option:hover { background: #fff3d6; }

/* Input quantité par zone (inline dans la ligne zone) */
.cell-input-zone-qte {
  font-weight: 700;
  color: var(--blue);
  text-align: right;
}

/* Alerte marge forcée dans le recap lot */
.marge-forcee-alert {
  display: inline-flex;
  align-items: center;
  background: #fff3cd;
  color: #856404;
  border: 1px solid #ffe89e;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 11.5px;
  font-weight: 600;
  cursor: help;
}

/* Total lot bar (footer navy) */
.total-lot-bar {
  display: flex;
  justify-content: flex-end;
  gap: 28px;
  margin-top: 14px;
  padding: 12px 18px;
  background: var(--navy);
  color: #fff;
  border-radius: 6px;
}
.total-lot-bar .t-item { font-size: 11px; color: #8899aa; margin-right: 6px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.total-lot-bar .t-val { font-size: 14px; font-weight: 700; color: #fff; }
.total-lot-bar .t-val.highlight { color: #5dade2; }
/* Options : orange (suppléments, hors total operation principale). Echo du
   header navy. Pas de pastille Variantes ici : le footer est scopé au lot
   courant, les variantes sont au niveau projet (cf. header). */
.total-lot-bar .t-val-options { color: #ffb878; }

/* =============================================================================
   Page Utilisateurs
   ============================================================================= */

/* Tableau des utilisateurs : meme structure visuelle que .projets-table */
.utilisateurs-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(26,35,64,0.05);
}
.utilisateurs-table thead { background: #f8f9fb; }
.utilisateurs-table th {
  text-align: left;
  padding: 12px 16px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
}
.utilisateurs-table td {
  padding: 14px 16px;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.utilisateurs-table tr:last-child td { border-bottom: none; }
.utilisateurs-table tr:hover td { background: #fafbfc; }
.utilisateurs-table tr.row-disabled td { opacity: 0.55; }

/* Badges roles + statuts (s'ajoute aux .badge existants pour les projets).
   Un badge par role applicatif (cf. UserProfile.Role) : la valeur du role
   (charge/economiste/admin) est utilisee comme suffixe de classe cote template
   -> .badge-charge / .badge-economiste / .badge-admin. */
.badge-super      { background: #ede7f6; color: #5e35b1; }   /* violet  - super admin */
.badge-admin      { background: #fff3e0; color: #e65100; }   /* orange  - admin */
.badge-economiste { background: #e0f2f1; color: #00897b; }   /* teal    - economiste */
.badge-charge     { background: #e3f2fd; color: #1565c0; }   /* bleu    - charge d'operation */
.badge-actif      { background: #d4edda; color: #155724; }
.badge-inactif    { background: #f0f0f0; color: #666; }

/* Boutons-icones dans la colonne actions du tableau */
.utilisateurs-table .actions { white-space: nowrap; }
.link-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 16px;
  padding: 4px 8px;
  border-radius: 4px;
  line-height: 1;
}
.link-btn:hover { background: var(--bg); }
.link-btn-disabled {
  display: inline-block;
  padding: 4px 8px;
  color: var(--muted);
  cursor: not-allowed;
}

/* Variants alert (succes / info), en complement du .alert danger par defaut */
.alert-success {
  background: #e6f4ea;
  color: #1e6c2c;
  border-color: rgba(30, 108, 44, 0.2);
}
.alert-info {
  background: #e8f0fe;
  color: #1c4ba0;
  border-color: rgba(28, 75, 160, 0.2);
}
.alert-error {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: rgba(214, 69, 69, 0.2);
}
.messages-zone { margin-bottom: 16px; }

/* =============================================================================
   Modal HTMX (utilisee pour creation/edition utilisateur)
   ============================================================================= */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(26, 35, 64, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
  backdrop-filter: blur(2px);
}
.modal {
  background: var(--surface);
  border-radius: 12px;
  box-shadow: 0 20px 50px rgba(26, 35, 64, 0.25);
  width: 100%;
  max-width: 580px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
}
.modal-header h2 {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
}
.modal-close {
  background: transparent;
  border: none;
  font-size: 24px;
  color: var(--muted);
  cursor: pointer;
  line-height: 1;
  padding: 4px 10px;
  border-radius: 4px;
}
.modal-close:hover { background: var(--bg); color: var(--text); }
/* `.modal` est en flex column avec `max-height: 90vh`. Quand le contenu est
   wrappe dans un `<form>` (cas des modals utilisateur / poste / etc), le
   form doit aussi etre un flex item qui prend la hauteur restante pour que
   `.modal-body { overflow-y: auto }` puisse declencher le scroll. Sans ca,
   le form garde sa hauteur de contenu et le body deborde sans scroll. */
.modal > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.modal-body {
  padding: 20px 24px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1 1 auto;
  min-height: 0;
}
.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 14px 24px;
  border-top: 1px solid var(--border);
  background: #fafbfc;
}

/* ===== Modale « Calcul minute » (P2/B2) ===== */
.metre-modal { width: 460px; max-width: 94vw; }
/* en-tête sur 3 niveaux : titre / poste · zone / badge du champ edite */
.metre-modal-header { align-items: flex-start; }
.metre-modal-titles { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.metre-modal-titles h2 { margin: 0; }
.metre-modal-loc { margin: 0; font-size: 13px; font-weight: 500; color: var(--muted); }
.metre-loc-sep { color: #c8cedb; margin: 0 4px; }
.metre-modal-champ { align-self: flex-start; font-size: 11px; font-weight: 800; padding: 2px 9px;
                     border-radius: 6px; text-transform: uppercase; letter-spacing: .03em; }
.metre-champ-chrome     { background: #ece7ff; color: #5a48b0; }
.metre-champ-entreprise { background: #d8f5ef; color: #1b8b7f; }
.metre-form { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
/* champ « quantité retenue » : libellé à gauche, valeur à droite (même ligne) ;
   le hint passe sous la ligne quand un métré pilote la cellule. */
.metre-direct { display: flex; flex-direction: row; align-items: center; justify-content: space-between;
                gap: 12px; flex-wrap: wrap; }
.metre-direct > label { font-size: 13px; font-weight: 600; color: var(--text); }
.metre-direct .metre-valeur { width: 120px; font-size: 16px; font-weight: 700; text-align: right; padding: 6px 8px; }
.metre-direct .metre-valeur[readonly] { background: #eef3ff; border-style: dashed; color: var(--navy); cursor: default; }
.metre-driven-hint { display: none; flex-basis: 100%; font-size: 11px; color: #2d5bff; font-weight: 600; }
.metre-modal.is-driven .metre-driven-hint { display: block; }
/* tableau du métré */
.metre-table { width: 100%; border-collapse: collapse; }
.metre-table th { font-size: 9.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted);
                  text-align: left; font-weight: 600; padding: 0 4px 5px; }
.metre-table th.r { text-align: right; }
.metre-table td { padding: 2px 4px; vertical-align: middle; }
.metre-table input { width: 100%; border: 1px solid var(--border); border-radius: 5px; padding: 4px 7px;
                     font: inherit; font-size: 12px; }
.metre-table input.metre-formule { text-align: right; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.metre-table td.metre-st { text-align: right; font-weight: 700; color: var(--navy); white-space: nowrap;
                           min-width: 54px; font-size: 12px; }
.metre-table td.metre-st.err { color: #c0392b; }
.metre-del { color: #c0392b; cursor: pointer; font-weight: 700; padding: 0 4px; user-select: none; }
.metre-del:hover { color: #e05a4a; }
.metre-actions { display: flex; gap: 14px; margin-top: 4px; }
.metre-addrow { font-size: 12px; color: #2d5bff; cursor: pointer; font-weight: 600; }
.metre-clear  { font-size: 12px; color: #c0392b; cursor: pointer; }
.metre-sum { display: flex; justify-content: space-between; align-items: baseline; font-weight: 700;
             color: var(--navy); border-top: 1px solid var(--border); padding-top: 8px; margin-top: 4px; }
.metre-sum .metre-total { font-size: 17px; }
.metre-help { font-size: 11px; margin: 0; }
.metre-help code { font-size: 11px; }

/* ===== Multi-fournisseurs : cellule Px Achat (bouton ⊞ + somme verrouillée) ===== */
/* bouton ⊞ Détail du prix d'achat ; bleu plein quand >=2 fournisseurs. */
.achats-detail-btn { flex: 0 0 auto; font-size: 12px; line-height: 1; cursor: pointer;
                     border: 1px solid #d4d9e6; background: #fff; color: #8a93a6;
                     border-radius: 5px; padding: 2px 5px; margin-left: 3px; }
.achats-detail-btn:hover { border-color: #b9c2d6; color: var(--blue); }
.achats-detail-btn.on { background: var(--blue); color: #fff; border-color: var(--blue); }
/* Px Achat piloté par le détail (>=2 fournisseurs) : somme verrouillée, fond bleuté. */
.px-driven { display: inline-flex; align-items: center; justify-content: flex-end; min-width: 56px;
             font-weight: 700; color: var(--navy); border: 1px dashed #b9c6ef; background: #eef3ff;
             border-radius: 5px; padding: 3px 6px; }
/* noms de fournisseurs (lecture seule) quand multi-fournisseurs. */
/* Multi-fournisseurs : tags en scroll horizontal (option « scroll »).
   cf. _poste_row.html (.ftags-wrap) + fournisseurs-scroll.js. */
.ftags-wrap { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: center; }
.ftags { display: flex; gap: 5px; overflow-x: auto; scrollbar-width: none; padding: 1px 0; width: 100%; }
.ftags::-webkit-scrollbar { display: none; }
.fchip { flex: 0 0 auto; display: inline-flex; align-items: center; font-size: 11px; font-weight: 600;
         border-radius: 10px; padding: 2px 9px; background: #eef1f8; color: #3a4566;
         border: 1px solid #dfe4f0; white-space: nowrap; }
.fchip .fmeta { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
.fchip .frole { font-size: 8.5px; font-weight: 700; color: #7a5cff; text-transform: uppercase;
                letter-spacing: .02em; margin-top: 1px; }
/* flèches ‹ › : cachées par défaut, montrées par JS (.show) quand ça déborde. */
.fnav { position: absolute; top: 0; bottom: 0; width: 22px; display: flex; align-items: center;
        justify-content: center; border: none; cursor: pointer; opacity: 0; pointer-events: none;
        transition: opacity .15s; z-index: 3; font-size: 15px; color: #5a6b8c; padding: 0; }
.fnav.show { opacity: 1; pointer-events: auto; }
.fnav:hover { color: var(--blue); }
.fnav-l { left: 0; background: linear-gradient(90deg, #fff8f2 62%, rgba(255, 248, 242, 0)); }
.fnav-r { right: 0; background: linear-gradient(270deg, #fff8f2 62%, rgba(255, 248, 242, 0)); }

/* ===== Modale « Détail du prix d'achat » (multi-fournisseurs) ===== */
.achats-modal { width: 660px; max-width: 95vw; }
.achats-table input.ach-refdevis { font-size: 11.5px; }
/* La modale Détail du prix d'achat héberge des autocompletes annuaire dont le
   menu (position:absolute) serait clippé par le scroll du body / l'overflow du
   modal. On laisse déborder : la liste de fournisseurs est courte par nature,
   donc pas besoin de scroll interne ici. Sans ça, le dropdown (suggestions ou
   message « Annuaire indisponible… ») reste invisible. */
.achats-modal { overflow: visible; }
.achats-modal .modal-body { overflow: visible; }
.achats-modal-titles h2 { margin: 0; }
.achats-modal-sub { margin: 2px 0 0; font-size: 12px; color: var(--muted); }
.achats-form { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.achats-table { width: 100%; border-collapse: collapse; }
.achats-table th { font-size: 9.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted);
                   text-align: left; font-weight: 600; padding: 0 5px 5px; }
.achats-table th.r { text-align: right; }
.achats-table td { padding: 3px 5px; vertical-align: middle; }
.achats-table input { width: 100%; border: 1px solid var(--border); border-radius: 6px; padding: 5px 7px;
                      font: inherit; font-size: 12px; }
.achats-table input.ach-prix { text-align: right; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.achats-table td.ach-st { text-align: right; font-weight: 700; color: var(--navy); white-space: nowrap;
                          min-width: 68px; font-size: 12px; }
.achats-table td.ach-st.err { color: #c0392b; }
.ach-del { color: #c0392b; cursor: pointer; font-weight: 700; padding: 0 4px; user-select: none; }
.ach-del:hover { color: #e05a4a; }
.achats-actions { margin-top: 4px; }
.achats-addrow { font-size: 12px; color: var(--blue); cursor: pointer; font-weight: 600; }
.achats-sum { display: flex; justify-content: space-between; align-items: baseline; font-weight: 700;
              color: var(--navy); border-top: 1px solid var(--border); padding-top: 9px; margin-top: 6px; }
.achats-sum .achats-total { font-size: 16px; }
.achats-help { font-size: 11px; margin: 6px 0 0; }
.achats-help code { font-size: 11px; }
/* Modale Achats en mode ré-imputation (chiffrage figé) : bandeau d'info. */
.achats-verrou-hint { background: #fdf3e7; border: 1px solid #f0c896; color: #8a5a12; border-radius: 8px; padding: 8px 12px; font-size: 12.5px; margin: 0 0 12px; }

/* Modale « Passer en facturation » (honoraires déjà facturés avant travaux). */
.fact-warn { background: #fdf3e7; border: 1px solid #f0c896; color: #8a5a12; border-radius: 8px; padding: 9px 12px; font-size: 13px; margin: 0 0 14px; }
.fact-h3 { font-size: 13.5px; font-weight: 700; margin: 6px 0 4px; }
.fact-help { font-size: 12px; margin: 0 0 10px; }
.fact-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.fact-table th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: #94a0b8; padding: 6px 8px; border-bottom: 1px solid #e6e9f0; }
.fact-table th.r, .fact-table td.r { text-align: right; }
.fact-table td { padding: 6px 8px; border-bottom: 1px solid #f2f4f9; }
.fact-in { width: 84px; text-align: right; padding: 5px 8px; border: 1px solid #d8dce6; border-radius: 7px; font: inherit; }
.fact-unit { padding: 5px 6px; border: 1px solid #d8dce6; border-radius: 7px; font: inherit; margin-left: 5px; }
/* cellule Fournisseur de la modale : ancre le dropdown autocomplete annuaire. */
.ach-fournisseur-cell { position: relative; }
/* Modale empilee (#modal-container-2 : ex. « + Ajouter a l'annuaire » depuis la
   modale Detail) -> au-dessus de la modale d'origine. */
#modal-container-2 .modal-overlay { z-index: 1100; }

/* Radio group pour le role (super admin / charge) :
   options affichees comme des cards cliquables, plus grosses et visibles. */
.radio-group {
  display: flex;
  gap: 12px;
  margin-top: 6px;
}
.radio-option {
  flex: 1;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  padding: 12px 14px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.radio-option:hover {
  border-color: var(--blue);
  background: #f6f9ff;
}
.radio-option input[type="radio"] {
  /* Radio plus gros et plus visible */
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--blue);
  cursor: pointer;
  flex-shrink: 0;
}
/* Card "selectionnee" : bordure bleue + halo discret */
.radio-option:has(input[type="radio"]:checked) {
  border-color: var(--blue);
  background: #f0f5ff;
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.12);
}

/* Champ readonly stylise (ex: username affiche en mode edition) */
.readonly-field {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--muted);
  font-family: -apple-system, BlinkMacSystemFont, monospace;
}

.field-help {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--muted);
}

/* =============================================================================
   Page Analytique projet (resume financier + ratios + camemberts)
   ============================================================================= */
.analytique-main {
  padding: 24px 32px 40px;
  max-width: 1400px;
  margin: 0 auto;
}

.analytique-section {
  margin-bottom: 32px;
  background: var(--surface);
  border-radius: 10px;
  padding: 20px 24px;
  box-shadow: 0 1px 4px rgba(26, 35, 64, 0.05);
}

.analytique-section-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 16px;
  letter-spacing: -0.01em;
}

/* --- Section 1 : Resume financier (3 sous-blocs Generalites/Hono/Travaux) --- */
.analytique-resume-block {
  margin-bottom: 18px;
}
.analytique-resume-block:last-child {
  margin-bottom: 0;
}
.analytique-resume-subtitle {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid #eef0f4;
}
.analytique-resume-subtitle-honoraires {
  color: #a05a14;
  border-bottom-color: #f0e1b6;
}
.analytique-resume-subtitle-travaux {
  color: #1565c0;
  border-bottom-color: #cfdaf7;
}
.analytique-resume-subtitle-options {
  /* Orange : echo de la couleur "Options du lot" dans le chiffrage. */
  color: #c67100;
  border-bottom-color: #f5d9b2;
}
.analytique-resume-subtitle-rg {
  /* Bronze : assorti a la pastille RG par lot dans la sidebar chiffrage. */
  color: #8b6914;
  border-bottom-color: #c9a875;
}
.analytique-resume-subtitle-variantes {
  color: #6a1b9a;
  border-bottom-color: #e1bee7;
}
.analytique-resume-subtitle-note {
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  font-size: 11px;
  color: var(--muted);
  margin-left: 8px;
}

.analytique-resume {
  display: grid;
  gap: 10px;
}
/* auto-fit + minmax : le nombre de colonnes s'adapte a la place disponible,
   au lieu d'un nombre fige qui deborde entre deux points de rupture (la rangee
   a 6 colonnes debordait deja son conteneur autour de 1100-1300px, et les
   montants a 7 chiffres — desormais insecables — l'accentuaient). */
/* Dernier bloc de la colonne financiere (Resume & Exports) : sa marge basse
   (32px) creait un espace MORT en bas de colonne, qui s'ajoutait au row-gap de
   la grille (28px) -> 60px avant l'« Historique des versions ». */
.resume-financier-col > .analytique-section:last-child {
  margin-bottom: 0;
}

/* Plancher 176px : un montant a 7 chiffres (« 12 345 678,90 € » = 142px de
   texte) + 28px de padding + 2px de bordure = 172px. En dessous, le montant
   — desormais insecable — depassait le bord droit de la tuile. */
.analytique-resume-6 { grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); }
.analytique-resume-4 { grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); }
.analytique-resume-2 { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.ar-card {
  background: #f8f9fb;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
}
.ar-card .label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 6px;
}
.ar-card .value {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
}
.ar-card-vente {
  background: #eef3ff;
  border-color: #cfdaf7;
}
.ar-card-vente .value { color: var(--blue); }
.ar-card-marge {
  background: #f4fbf6;
  border-color: #d6ecde;
}
.ar-card-marge .value { color: #1f8a4c; }
.ar-card-honoraires {
  background: #fdf6e7;
  border-color: #f0e1b6;
}
.ar-card-honoraires .value { color: #a05a14; }
.ar-card-operation {
  background: #ede7f6;
  border-color: #c9bce6;
}
.ar-card-operation .value { color: #5e35b1; }
.ar-card .sub {
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
  font-style: italic;
}

/* --- Sections 2 & 3 : Tableau a gauche, camembert a droite --- */
.analytique-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 24px;
  align-items: start;
}
@media (max-width: 1100px) {
  .analytique-grid { grid-template-columns: 1fr; }
}

.analytique-table-wrap { overflow-x: auto; }
.analytique-table-wrap-full { overflow-x: auto; }

.analytique-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.analytique-table th,
.analytique-table td {
  padding: 9px 12px;
  border-bottom: 1px solid #eef0f4;
  text-align: left;
}
.analytique-table thead th {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: #fafbfc;
  border-bottom: 1px solid var(--border);
}
.analytique-table tfoot th {
  background: #f4f6fa;
  font-weight: 700;
  color: var(--text);
  border-top: 2px solid var(--border);
}
.analytique-table .num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.analytique-table tbody tr:hover td {
  background: #fafbfc;
}
.analytique-table .lot-num {
  display: inline-block;
  min-width: 24px;
  padding-right: 6px;
  color: var(--muted);
  font-weight: 600;
  font-size: 11.5px;
}

/* Matrice lot x zone : un peu plus compact pour gerer la largeur. */
.analytique-matrice th,
.analytique-matrice td {
  padding: 7px 10px;
  font-size: 12.5px;
}

.analytique-chart-wrap {
  background: #fafbfc;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.analytique-chart-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 12px;
  align-self: flex-start;
}
/* Boite qui BORNE la taille du donut.
   Chart.js est en `responsive: true` : il dimensionne le canvas sur son parent.
   Tant que ce parent etait la carte entiere, le donut suivait la largeur de la
   carte — et quand la grille passe en une colonne (<= 1100 px), il s'etalait
   sur toute la page. On lui donne donc un parent plafonne a sa taille de
   reference (l'attribut width=320 du canvas) : le diagramme reste petit, la
   legende en dessous garde la pleine largeur de la carte. */
.analytique-chart-canvas {
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
}
.analytique-chart-wrap canvas {
  max-width: 100%;
}

.analytique-empty {
  padding: 24px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  background: #fafbfc;
  border-radius: 6px;
}

/* =============================================================================
   Sidebar chiffrage : tabs Lots | Honoraires
   ============================================================================= */
.sidebar-tabs {
  display: flex;
  background: #f8f9fb;
  border-bottom: 1px solid #eee;
}
.sidebar-tab {
  flex: 1;
  text-align: center;
  padding: 10px 12px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.sidebar-tab:hover {
  color: var(--text);
  background: #f0f2f6;
  text-decoration: none;
}
.sidebar-tab.active {
  color: var(--blue);
  border-bottom-color: var(--blue);
  background: var(--surface);
}

/* Pied de sidebar honoraires : total HT */
.honoraires-sidebar-footer {
  padding: 12px 14px;
  background: #f4f6fa;
  border-top: 1px solid var(--border);
  font-size: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.honoraires-sidebar-footer .t-item {
  color: var(--muted);
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.honoraires-sidebar-footer .t-val {
  font-weight: 700;
  color: var(--text);
  font-size: 13px;
}

/* Cellule en lecture seule (typiquement un PU achat agrege au niveau
   intervenant -- l'edition se fait sur les lignes phase en dessous). */
.cell-readonly {
  display: inline-block;
  color: var(--muted);
  font-style: italic;
  font-size: 13px;
  padding: 0 4px;
}

/* Dropdown "+ Ajouter une phase" inline en haut du tableau honoraires */
.phase-add-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
}
.phase-add-inline select {
  height: 32px;
  padding: 0 10px;
  font-size: 12.5px;
  border: 1px dashed var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
.phase-add-inline button {
  height: 32px;
  width: 32px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--blue);
  font-weight: 700;
  cursor: pointer;
}
.phase-add-inline button:hover {
  background: #eef3ff;
}

/* =============================================================================
   Page Resume & Exports (onglet entre Chiffrage et Analytique)
   ============================================================================= */

.resume-main {
  padding: 24px 32px;
  max-width: 1400px;
  margin: 0 auto;
}

/* Layout : 3 blocs editables a gauche, synthese sticky a droite */
.resume-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 28px;
  align-items: start;
}
@media (max-width: 1100px) {
  .resume-layout {
    grid-template-columns: 1fr;
  }
}

.resume-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.resume-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 22px;
  box-shadow: 0 1px 3px rgba(26, 35, 64, 0.04);
}
.resume-block-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--navy);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eef0f4;
}
.resume-block-note {
  display: block;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
}

/* Toggle 3 modes : radios stylises en pills */
.resume-mode-toggle {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
  background: #f4f6f9;
  padding: 4px;
  border-radius: 8px;
  width: max-content;
}
.resume-mode-toggle label {
  display: flex;
  align-items: center;
  padding: 6px 14px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  border-radius: 6px;
  transition: background 0.15s, color 0.15s;
}
.resume-mode-toggle label:hover { color: var(--text); }
/* L'état ACTIF est piloté par :has(:checked) ci-dessous (fiable, suit le radio
   coché côté client). Les formulaires RG / aléas re-rendent en hx-swap="none"
   -> la classe serveur .active devient obsolète après un clic (les DEUX
   libellés restaient surlignés). On force donc l'état INACTIF des libellés dont
   le radio n'est pas coché, ce qui neutralise un .active resté figé. */
.resume-mode-toggle label:not(:has(input[type="radio"]:checked)) {
  background: transparent;
  color: var(--muted);
  box-shadow: none;
}
/* Feedback optimiste : on cible aussi `:has(:checked)` directement —
   le highlight apparait des le clic, sans attendre le round-trip serveur
   qui re-render le partial avec .active applique cote Django.
   Cf. rapport Cowork Campagne 2 bug n°19 (sensation que le clic ne fait rien). */
.resume-mode-toggle label:has(input[type="radio"]:checked) {
  background: var(--surface);
  color: var(--navy);
  box-shadow: 0 1px 3px rgba(26, 35, 64, 0.06);
}
.resume-mode-toggle input[type="radio"] {
  display: none;
}

/* Sous-bloc : reste visible mais grise quand le mode courant ne le selectionne pas */
.resume-subblock {
  transition: opacity 0.15s;
}
.resume-subblock.is-disabled {
  opacity: 0.45;
  pointer-events: none;
}
/* Stage 2 OOB : le serveur ne re-rend plus la classe .is-disabled quand on
   change de mode (il ne renvoie que les montants par lot). On grise donc
   chaque sous-bloc gate PAR DEFAUT en CSS (selon data-mode) ; les regles
   :has() ci-dessous le degrisent instantanement quand le bon mode/toggle est
   coche. Sans ca, un sous-bloc reste fige dans l'etat (grise/actif) du
   chargement de page -> le toggle "ne verrouille plus" la table par lot. */
.resume-subblock[data-mode="global"],
.resume-subblock[data-mode="par_lot"],
.resume-subblock[data-mode="non-aucun"],
.resume-subblock[data-mode="non-aucune"],
.resume-subblock[data-mode="rg"] {
  opacity: 0.45;
  pointer-events: none;
}
/* Sous-blocs : annule .is-disabled des le clic sur le radio correspondant,
   sans attendre le re-render serveur. Les <input> n'ont plus de HTML
   `disabled` (cf. resume_content.html) donc le user peut taper
   instantanement et la valeur est bien dans le POST suivant.
   Cf. rapport Cowork Campagne 3 bug n°31 (valeur saisie retombait a 0). */
.resume-block:has(input[name="aleas_mode"][value="global"]:checked)
  .resume-subblock[data-mode="global"],
.resume-block:has(input[name="aleas_mode"][value="par_lot"]:checked)
  .resume-subblock[data-mode="par_lot"],
.resume-block:has(input[name="aleas_moa_type"]:not([value="aucun"]):checked)
  .resume-subblock[data-mode="non-aucun"],
.resume-block:has(input[name="remise_type"]:not([value="aucune"]):checked)
  .resume-subblock[data-mode="non-aucune"] {
  opacity: 1;
  pointer-events: auto;
}

/* ===== Onglet Retenue & Remise (refonte 2026-06-03) ===== */
/* La Retenue de garantie a quitté cet onglet (-> Situations, bloc 4.1) : le
   conteneur remplit désormais toute la largeur, la mise en 2 colonnes se joue
   à l'intérieur du form (cf. .retenue-remise-ajustements). */
.retenue-remise-layout {
  display: block;
}
/* Form ajustements en 2 colonnes : à GAUCHE « Aléas entreprise » (avec sa
   table par lot, colonne plus large), à DROITE « Aléas MOA » + « Remise »
   empilés (cf. demande 2026-07-21). Sous 1100px -> 1 colonne. */
.retenue-remise-ajustements {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
.ar-col-side {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
@media (max-width: 1100px) {
  .retenue-remise-ajustements {
    grid-template-columns: 1fr;
  }
}
/* Sous-bloc RG : se de-grise des que "RG applicable" est coche (meme pattern
   :has() que les aleas, sans disabled HTML -> saisie instantanee). */
.retenue-rg-block:has(input[name="retenue_garantie_applicable"][value="1"]:checked)
  .resume-subblock[data-mode="rg"] {
  opacity: 1;
  pointer-events: auto;
}

/* ----- Bascule pourcent / forfait des champs "Valeur" (cote client) -----
   Stage 2 OOB : les vues ne renvoient plus que les montants calcules, elles
   ne re-rendent plus les <input>. On rend donc les DEUX variantes (% et €) et
   on n'affiche que celle du type coche, en CSS pur (meme philosophie :has()
   que le gating ci-dessus). Bonus : bascule instantanee, sans round-trip. */
.resume-val-forfait { display: none; }   /* defaut : variante pourcent visible */
.resume-block:has(input[name="aleas_moa_type"][value="forfait"]:checked) .resume-val-pourcent,
.resume-block:has(input[name="remise_type"][value="forfait"]:checked) .resume-val-pourcent {
  display: none;
}
.resume-block:has(input[name="aleas_moa_type"][value="forfait"]:checked) .resume-val-forfait,
.resume-block:has(input[name="remise_type"][value="forfait"]:checked) .resume-val-forfait {
  display: flex;
}
/* Aleas par lot : la valeur (%/€) d'une ligne bascule selon SON <select>.
   Scope a .resume-lots-table ; la table RG (meme classe) n'a pas de select. */
.resume-aleas-frf { display: none; }
.resume-lots-table tr:has(select option[value="forfait"]:checked) .resume-aleas-pct {
  display: none;
}
.resume-lots-table tr:has(select option[value="forfait"]:checked) .resume-aleas-frf {
  display: inline-block;
}
.rg-derogation-note {
  margin: 12px 0 8px;
}
.rg-lot-toggle {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}
.rg-lot-toggle input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--blue, #2563eb);
}

.resume-field-row {
  margin-bottom: 10px;
}
.resume-field-row:last-child { margin-bottom: 0; }

.resume-field-inline {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--text);
}
.resume-field-inline > span:first-child {
  min-width: 110px;
  font-weight: 500;
}
.resume-field-inline .suffix {
  color: var(--muted);
  font-weight: 600;
}
.resume-num {
  width: 100px;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 8px;
  text-align: right;
}
.resume-num:disabled {
  background: #f4f6f9;
  color: #999;
  cursor: not-allowed;
}

/* Tableau aleas par lot */
.resume-lots-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-top: 10px;
}
.resume-lots-table th {
  text-align: left;
  padding: 8px 10px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
  background: #fafbfc;
}
.resume-lots-table th.num { text-align: right; }
.resume-lots-table td {
  padding: 8px 10px;
  border-bottom: 1px solid #eef0f4;
  vertical-align: middle;
}
.resume-lots-table td.num { text-align: right; }
.resume-lots-table tr:last-child td { border-bottom: none; }
.resume-num-cell {
  width: 80px;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 6px;
  text-align: right;
}
.resume-num-cell:disabled,
.resume-lots-table select:disabled {
  background: #f4f6f9;
  color: #999;
  cursor: not-allowed;
}
.resume-lots-table select {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 6px;
  font-size: 12.5px;
}
.resume-lot-montant {
  font-weight: 600;
  color: var(--navy);
}

/* Aside : synthese sticky a droite */
.resume-synthese {
  background: var(--navy);
  color: #fff;
  border-radius: 10px;
  padding: 22px 24px;
  position: sticky;
  top: 16px;
  box-shadow: 0 2px 8px rgba(26, 35, 64, 0.1);
}
.resume-synthese-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #8899aa;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #3d4a6e;
}
.resume-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0;
  font-size: 13px;
}
.resume-line .val {
  font-weight: 700;
  font-size: 14px;
}
.resume-line.is-subtotal {
  border-top: 1px solid #3d4a6e;
  padding-top: 8px;
  margin-top: 4px;
  font-weight: 600;
  color: #cfd6e6;
}
.resume-line.is-final {
  border-top: 2px solid #5dade2;
  margin-top: 8px;
  padding-top: 12px;
  font-size: 14px;
  font-weight: 700;
}
.resume-line.is-final .val {
  color: #5dade2;
  font-size: 18px;
}
.resume-line-aleas .val { color: #ffb878; }
.resume-line-remise .val { color: #ff9090; }
.resume-line-moa {
  font-size: 11.5px;
  color: #99a3b8;
  border-top: 1px dashed #3d4a6e;
  margin-top: 10px;
  padding-top: 10px;
  font-style: italic;
}

/* Boutons exports */
.resume-exports {
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid #3d4a6e;
}
.resume-exports h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #8899aa;
  margin: 0 0 10px;
}
.resume-export-btn {
  display: block;
  width: 100%;
  padding: 9px 12px;
  margin-bottom: 8px;
  border: 1px solid #3d4a6e;
  border-radius: 6px;
  background: transparent;
  color: #cfd6e6;
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.resume-export-btn:hover:not(:disabled) {
  background: #3d4a6e;
  color: #fff;
}
.resume-export-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
/* Variante "available" : pour les <a> qui downloadent vraiment un fichier.
   Override la couleur disabled, marque visuellement comme actionnable. */
.resume-export-btn--available {
  text-decoration: none;
  color: #cfd6e6;
  cursor: pointer;
}
.resume-export-btn--available:hover {
  background: #3d4a6e;
  color: #fff;
  text-decoration: none;
}

/* ===== Section Exports (pleine largeur, EN TETE du layout) =================
   Sortie de l'aside synthese (312px, trop etroit pour 2 colonnes lisibles) et
   placee au-dessus de la Synthese financiere. Deux groupes cote a cote :
   INTERNE (ambre) / CLIENT (bleu). Sous 900px -> une seule colonne. */
.resume-exports-section {
  grid-column: 1 / -1;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #dde1ea);
  border-radius: 12px;
  padding: 20px 22px 22px;
  /* Pas de margin-bottom : la grille .resume-layout a deja un row-gap (28px).
     Ajouter une marge doublait l'espace sous la section (48px). */
  box-shadow: 0 1px 3px rgba(26, 35, 64, 0.04);
}
.resume-exports-section-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy, #1a2340);
  margin: 0 0 16px;
  letter-spacing: -0.01em;
}
.resume-exports-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: 22px;
  align-items: start;
}
@media (max-width: 900px) {
  .resume-exports-cols { grid-template-columns: 1fr; }
}
.resume-exports-group-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted, #5b6580);
  margin: 0 0 12px;
}
/* Pastille de couleur : repere immediat interne (ambre) / client (bleu). */
.resume-exports-group-dot {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  flex: none;
}
.resume-exports-group--interne .resume-exports-group-dot { background: #d79a2c; }
.resume-exports-group--client .resume-exports-group-dot { background: #3b6ef5; }
.resume-exports-group-note {
  flex-basis: 100%;
  font-size: 11.5px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--muted, #94a0b8);
}
.resume-exports-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 10px;
}
/* Carte d'export : plus imposante que l'ancien bouton (icone en pastille +
   nom + format), et cliquable sur toute sa surface. */
.resume-export-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border, #dde1ea);
  border-radius: 10px;
  background: #fff;
  text-decoration: none;
  color: var(--text, #1a2340);
  transition: border-color 0.14s, box-shadow 0.14s, transform 0.14s;
}
.resume-export-card:hover {
  text-decoration: none;
  border-color: #b9c8ea;
  box-shadow: 0 2px 4px rgba(26, 35, 64, 0.06), 0 8px 20px rgba(26, 35, 64, 0.08);
  transform: translateY(-1px);
}
.resume-export-card-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 9px;
  background: #eef2fb;
  color: #3b6ef5;
  font-size: 18px;
}
.resume-exports-group--interne .resume-export-card-ic {
  background: #fbf1de;
  color: #b5811f;
}
.resume-export-card-txt {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.resume-export-card-nom {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--navy, #1a2340);
  line-height: 1.25;
}
.resume-export-card-fmt {
  font-size: 11.5px;
  color: var(--muted, #94a0b8);
  margin-top: 2px;
}

/* Bloc "Actions" (Valider le chiffrage) : pose au-dessus du bloc Exports
   dans l'aside synthese. Bouton vert pour marquer l'action principale. */
.resume-actions {
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid #3d4a6e;
}
.resume-actions h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #8899aa;
  margin: 0 0 10px;
}
.resume-action-btn {
  display: block;
  width: 100%;
  padding: 11px 12px;
  margin-bottom: 8px;
  border: 1px solid;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.resume-action-validate {
  background: #e6f7ec;
  color: #1f8a4c;
  border-color: #b8e3c6;
}
.resume-action-validate:hover {
  background: #d0eedb;
  border-color: #82c69b;
  color: #136634;
}
/* Bouton "Passer en facturation" : palette gold qui matche le badge
   `.badge-travaux`. Signal visuel fort = decision metier importante
   (bascule en phase chantier, modules Pilotage/Situations actifs). */
.resume-action-facturation {
  background: #fdf2cc;
  color: #8a6814;
  border-color: #e8d68a;
}
.resume-action-facturation:hover {
  background: #fae8a4;
  border-color: #c9a227;
  color: #6b5010;
}
/* `<form>` wrapper du bouton "Passer en facturation" : pas de margin,
   le bouton interieur conserve sa taille block + mb existante. */
.resume-action-form {
  margin: 0;
}
/* Info statut affichee a la place du bouton "Passer en facturation"
   quand le projet n'est plus en CHIFFRAGE. Cosmetique uniquement,
   pas une action (pas de bouton). */
.resume-phase-info {
  padding: 11px 12px;
  margin-bottom: 8px;
  border: 1px solid #e8d68a;
  border-radius: 6px;
  font-size: 13px;
  text-align: center;
  background: #fdf2cc;
  color: #8a6814;
}
.resume-phase-info strong { font-weight: 700; }
.resume-phase-info-clos {
  background: #2a3656;
  color: #ffffff;
  border-color: #1d2a5b;
}

/* Bandeau verrou du chiffrage (bloc 2 volet 2) : haut des onglets Chiffrage +
   Aléas et Remise quand le projet est passé en facturation. */
.chiffrage-verrou {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 14px 20px;
  padding: 11px 16px;
  border: 1px solid;
  border-radius: 10px;
  font-size: 13.5px;
}
.chiffrage-verrou .cv-ico { font-size: 16px; flex: 0 0 auto; }
.chiffrage-verrou .cv-txt { flex: 1; min-width: 200px; }
.chiffrage-verrou .cv-btn {
  flex: 0 0 auto;
  border: 0;
  border-radius: 8px;
  padding: 7px 14px;
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  color: #fff;
}
.chiffrage-verrou-locked { background: #fdf3e7; border-color: #f0c896; color: #8a5a12; }
.chiffrage-verrou-locked .cv-btn { background: #bf7a08; }
.chiffrage-verrou-locked .cv-btn:hover { background: #a56906; }
.chiffrage-verrou-open { background: #eef3ff; border-color: #b9cdf7; color: #2f4a86; }
.chiffrage-verrou-open .cv-btn { background: #3b6ef5; }
.chiffrage-verrou-open .cv-btn:hover { background: #2f5fd6; }

/* Modal validation version : reprend la palette `.modal` existante.
   Class supplementaire `.version-modal` pour ajuster la largeur. */
.version-modal {
  max-width: 480px;
}
/* Numero auto-calcule, non-modifiable : visuel "lecture seule" pour
   signaler qu'il n'est pas saisi par l'utilisateur. La valeur change
   au change de phase (cf. script de sync dans le modal). */
.version-numero-auto {
  background: #f4f6f9;
  color: var(--navy);
  font-weight: 700;
  font-size: 16px;
  text-align: center;
  cursor: default;
  width: 100px;
}
.version-numero-auto:focus {
  outline: none;
  box-shadow: none;
}

/* Historique des versions : tableau pleine largeur sous le layout 2 colonnes
   du Resume. Le grid `.resume-layout` n'a que 2 colonnes, on etale via
   grid-column: 1 / -1 pour traverser les 2. */
.resume-historique {
  grid-column: 1 / -1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 22px;
  box-shadow: 0 1px 3px rgba(26, 35, 64, 0.04);
  /* Pas de margin-top : la grille .resume-layout a deja un row-gap (28px).
     La marge s'y ajoutait -> 48px d'espace au-dessus de l'historique. */
}
.resume-historique-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--navy);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eef0f4;
}
.resume-historique-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.resume-historique-table thead {
  background: #fafbfc;
}
.resume-historique-table th {
  padding: 8px 10px;
  text-align: left;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.resume-historique-table th.num,
.resume-historique-table td.num {
  text-align: right;
}
.resume-historique-table td {
  padding: 8px 10px;
  border-bottom: 1px solid #eef0f4;
  vertical-align: middle;
}
.resume-historique-table tr:last-child td {
  border-bottom: none;
}
.resume-historique-table tr:hover td {
  background: #fafbfc;
}
.resume-historique-final {
  font-weight: 700;
  color: var(--blue);
}
.resume-historique-moa {
  color: var(--muted);
  font-style: italic;
}
.resume-historique-commentaire {
  color: var(--muted);
  font-style: italic;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Ligne historique : la cellule Phase est cliquable (ouvre le detail),
   la cellule Actions porte les boutons Voir / Restaurer / Supprimer. */
.resume-historique-row {
  transition: background 0.12s;
}
.resume-historique-row:hover td {
  background: #fafbfc;
}
/* Premiere cellule (Phase) cliquable + curseur pointer = signal d'affordance. */
.resume-historique-row td:first-child {
  cursor: pointer;
  color: var(--blue);
}
.resume-historique-row td:first-child:hover {
  text-decoration: underline;
}
.resume-historique-actions {
  display: flex;
  gap: 4px;
  align-items: center;
  white-space: nowrap;
}
.resume-historique-actions .link-btn {
  font-size: 14px;
  padding: 4px 6px;
  background: transparent;
  border: none;
  cursor: pointer;
  border-radius: 4px;
}
.resume-historique-actions .link-btn:hover {
  background: #eef3ff;
}
.resume-historique-empty {
  padding: 24px 8px;
  text-align: center;
}

/* Modal detail version : reprend la palette modale, plus large pour
   accommoder les 2 tableaux financiers + metadonnees. */
.version-detail-modal {
  max-width: 620px;
}
.version-detail-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 3px 10px;
  border-radius: 999px;
  background: #eef3ff;
  color: var(--blue);
  font-size: 12px;
  font-weight: 600;
  vertical-align: middle;
}
.version-detail-meta {
  display: flex;
  gap: 24px;
  padding-bottom: 12px;
  border-bottom: 1px solid #eef0f4;
  margin-bottom: 12px;
}
.version-detail-meta .lbl {
  display: block;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 2px;
}
.version-detail-meta .val {
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
}
.version-detail-commentaire {
  padding-bottom: 12px;
  border-bottom: 1px solid #eef0f4;
  margin-bottom: 12px;
}
.version-detail-commentaire .lbl {
  display: block;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 4px;
}
.version-detail-commentaire p {
  margin: 0;
  font-size: 13px;
  color: var(--text);
  font-style: italic;
}
.version-detail-section {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
  margin: 14px 0 6px;
}
.version-detail-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-bottom: 8px;
}
.version-detail-table td {
  padding: 6px 8px;
  border-bottom: 1px solid #eef0f4;
}
.version-detail-table td.num {
  text-align: right;
  font-weight: 600;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.version-detail-table tr:last-child td {
  border-bottom: none;
}
.version-detail-aleas td.num { color: #c67100; }
.version-detail-remise td.num { color: #c0392b; }
.version-detail-final {
  background: #eef3ff;
}
.version-detail-final td {
  font-weight: 700;
  font-size: 15px;
  padding: 10px 8px;
}
.version-detail-final td.num { color: var(--blue); }
.version-detail-moa td {
  color: var(--muted);
  font-style: italic;
}
.version-detail-moa td.num { color: var(--muted); }
.version-detail-note {
  font-size: 11.5px;
  color: var(--muted);
  font-style: italic;
  margin: 14px 0 0;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
/* Section Exports dans le modal detail : 3 boutons cote a cote.
   Disabled pour l'instant (Round 4). Garde le scaffolding visible pour
   que l'utilisateur comprenne qu'on pourra exporter une version archivee. */
.version-detail-exports {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid #eef0f4;
}
.version-detail-exports-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.version-detail-export-btn {
  flex: 1;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.version-detail-export-btn:hover:not(:disabled) {
  background: #eef3ff;
  border-color: var(--blue);
}
.version-detail-export-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Footer du modal detail : actions destructives/recuperatrices a gauche
   (Supprimer + Revenir), action neutre (Fermer) a droite.
   `justify-content: space-between` pour clairement separer les 2 zones
   -- l'utilisateur ne clique pas sur l'un par erreur en visant l'autre. */
.version-detail-footer {
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.version-detail-actions-left {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* =============================================================================
   Autocomplete entreprise (annuaire partage F8)
   Pose sur les cellules Fournisseur des postes et intervenants.
   Le dropdown est en position:absolute pour flotter au-dessus du tableau.
   ============================================================================= */
.entreprise-autocomplete-wrapper {
  position: relative;       /* base d'ancrage pour le dropdown absolu */
}
.entreprise-autocomplete-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 50;             /* au-dessus des autres cellules + bordures */
  /* Vide par defaut (innerHTML="") -> le children .dropdown porte les styles */
}
.entreprise-autocomplete-dropdown {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(26, 35, 64, 0.12);
  max-height: 260px;
  overflow-y: auto;
  min-width: 240px;
  padding: 4px 0;
}
.entreprise-autocomplete-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  padding: 6px 10px;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: var(--text);
  border-bottom: 1px solid #f0f2f6;
}
.entreprise-autocomplete-item:last-child {
  border-bottom: none;
}
.entreprise-autocomplete-item:hover {
  background: #eef3ff;
}
.entreprise-autocomplete-item .ent-name {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.2;
}
.entreprise-autocomplete-item .ent-meta {
  font-size: 11px;
  color: var(--muted);
  margin-top: 1px;
}
/* Badge "kind" coloré : palette discrete par type d'entreprise. */
.ent-kind {
  display: inline-block;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ent-kind-moa { background: #fde7ec; color: #b8254b; }
.ent-kind-moe { background: #e0e8f7; color: #1e3a8a; }
.ent-kind-moex { background: #e8eaf6; color: #3949ab; }
.ent-kind-entreprise { background: #e7f3ec; color: #1b5e2c; }
.ent-kind-autre { background: #efefef; color: #555; }

.entreprise-autocomplete-empty {
  padding: 8px 10px;
  font-size: 12px;
  font-style: italic;
}
/* Bouton "+ Ajouter ..." en pied du dropdown : ouvre le modal de creation. */
.entreprise-autocomplete-add {
  width: 100%;
  padding: 8px 10px;
  margin-top: 4px;
  background: #fef9f0;
  border: none;
  border-top: 1px solid #fde0c0;
  color: #c67100;
  font-weight: 700;
  font-size: 12px;
  cursor: pointer;
  text-align: left;
}
.entreprise-autocomplete-add:hover {
  background: #fdecc8;
  color: #a05a14;
}

/* Modal de creation entreprise (annuaire partage). Reprend les classes
   `.modal` / `.modal-overlay` / `.modal-body` / `.modal-footer`. Plus
   large que la modal version pour laisser respirer les 12 champs. */
.entreprise-create-modal {
  max-width: 720px;
}
/* Ligne de plusieurs champs cote a cote (SIRET + contact ; CP + ville + pays...). */
.form-field-row {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}
.form-field-row > .form-field {
  flex: 1;
  margin-bottom: 0;       /* le row gere deja le margin-bottom */
}

/* =============================================================================
   Page Annuaire entreprises -- refonte UI 2026-05-25 inspiree d'Intus
   (cf. /Users/thibautmartel/DEV/Intus/backend/templates/partners/).
   Reproduit le look "Tailwind stone" en CSS vanilla : palette grise douce,
   rounded-2xl sur la card de la table, header sticky, badges arrondis,
   icones SVG pour les actions. Toutes les classes sont prefixees `.ann-*`
   pour eviter les collisions avec les anciens styles `.annuaire-*` qui
   restent en place tant qu'on n'a pas migre tous les usages.
   ============================================================================= */

/* Header sticky : titre + sous-titre count + bouton primaire a droite */
.ann-header {
  background: #fff;
  border-bottom: 1px solid #e7e5e4;
  padding: 24px 32px;
  position: sticky;
  top: 0;
  z-index: 10;
  margin: -20px -20px 0;   /* compense le padding de .main pour aller bord a bord */
}
.ann-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 16px;
  flex-wrap: wrap;
}
.ann-header-title h1 {
  font-size: 22px;
  font-weight: 600;
  color: #292524;
  margin: 0;
  line-height: 1.2;
}
.ann-header-title .ann-subtitle {
  font-size: 13px;
  color: #a8a29e;
  margin-top: 2px;
}
.ann-btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  background: #2563eb;
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s ease;
}
.ann-btn-primary:hover { background: #1d4ed8; }
.ann-btn-primary:disabled,
.ann-btn-primary[disabled] {
  background: #d4d4d4;
  cursor: not-allowed;
}

/* Form de filtres : ligne horizontale recherche + selects + indicator + reset */
.ann-filters {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.ann-search {
  flex: 1;
  min-width: 280px;
  height: 36px;
  padding: 0 14px;
  border: 1px solid #e7e5e4;
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
  color: #292524;
}
.ann-search::placeholder { color: #a8a29e; }
.ann-search:focus {
  outline: none;
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.ann-select {
  height: 36px;
  padding: 0 12px;
  border: 1px solid #e7e5e4;
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
  color: #292524;
  cursor: pointer;
}
.ann-select:focus {
  outline: none;
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.ann-htmx-indicator {
  opacity: 0;
  transition: opacity 0.2s ease;
  color: #2563eb;
  font-size: 13px;
}
.htmx-request .ann-htmx-indicator { opacity: 1; }
.ann-reset {
  padding: 7px 12px;
  color: #78716c;
  font-size: 13px;
  text-decoration: none;
  border-radius: 6px;
  transition: background 0.12s ease, color 0.12s ease;
}
.ann-reset:hover {
  background: #f5f5f4;
  color: #292524;
}

/* Body de la page : zone sous le header sticky avec padding lateral */
.ann-body {
  padding: 24px 32px;
}

/* Card englobant la table : bord arrondi 16px + bordure stone */
.ann-table-card {
  background: #fff;
  border: 1px solid #e7e5e4;
  border-radius: 16px;
  overflow: hidden;
}
.ann-table {
  width: 100%;
  border-collapse: collapse;
}
.ann-table thead tr {
  border-bottom: 1px solid #f5f5f4;
}
.ann-table th {
  padding: 12px 20px;
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  color: #57534e;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ann-table th.ann-th-right { text-align: right; }
.ann-table tbody tr {
  border-bottom: 1px solid #fafaf9;
  transition: background 0.1s ease;
}
.ann-table tbody tr:last-child { border-bottom: none; }
.ann-table tbody tr:hover { background: #fafaf9; }
.ann-table tbody tr.is-inactive { opacity: 0.6; }
.ann-table td {
  padding: 14px 20px;
  font-size: 13px;
  color: #57534e;
  vertical-align: middle;
}
.ann-table td.ann-td-right { text-align: right; white-space: nowrap; }
.ann-table .ann-cell-name {
  font-size: 13px;
  font-weight: 500;
  color: #292524;
}
.ann-table .ann-cell-name-meta {
  font-size: 11px;
  color: #a8a29e;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  margin-top: 2px;
}
.ann-table .ann-cell-email a {
  color: #2563eb;
  text-decoration: none;
}
.ann-table .ann-cell-email a:hover { text-decoration: underline; }
.ann-table .ann-cell-empty { color: #d6d3d1; }

/* Badge "Rôle" -- garde la palette existante (.ent-kind-*) pour cohérence
   visuelle, mais on neutralise text-transform pour un rendu plus moderne. */
.ann-table .ent-kind {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}

/* Badge statut : pill arrondie type Intus */
.ann-badge-statut {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
}
.ann-badge-actif {
  background: #d1fae5;
  color: #047857;
}
.ann-badge-inactif {
  background: #f5f5f4;
  color: #78716c;
}

/* Boutons d'action en icones SVG -- carre 32x32, hover colorise */
.ann-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: #a8a29e;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}
.ann-icon-btn:hover { background: #f5f5f4; color: #57534e; }
.ann-icon-btn-edit:hover { background: #eff6ff; color: #2563eb; }
.ann-icon-btn-danger:hover { background: #fef2f2; color: #dc2626; }
.ann-icon-btn-success:hover { background: #ecfdf5; color: #059669; }
.ann-icon-btn[disabled],
.ann-icon-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.ann-icon-btn svg { width: 16px; height: 16px; }

/* Form inline pour la toggle (action POST) : evite que le <form> default
   prenne toute la largeur et casse l'alignement des icones. */
.ann-action-form { display: inline-block; }
.ann-readonly-tag {
  display: inline-block;
  padding: 3px 8px;
  background: #f5f5f4;
  color: #a8a29e;
  border-radius: 4px;
  font-size: 11px;
  font-style: italic;
}

/* Etat vide stylise : icone + message centres dans la card */
.ann-empty {
  padding: 56px 24px;
  text-align: center;
}
.ann-empty .ann-empty-icon {
  font-size: 40px;
  margin-bottom: 8px;
  opacity: 0.5;
}
.ann-empty .ann-empty-title {
  font-size: 14px;
  font-weight: 600;
  color: #292524;
  margin-bottom: 4px;
}
.ann-empty .ann-empty-msg {
  font-size: 13px;
  color: #78716c;
}
.ann-empty a {
  color: #2563eb;
  text-decoration: none;
  font-weight: 500;
}
.ann-empty a:hover { text-decoration: underline; }

/* Alerte annuaire indisponible : carte rouge clair en haut de body */
.ann-alert {
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 12px;
  padding: 16px 20px;
  font-size: 13px;
  color: #991b1b;
  margin-bottom: 16px;
}

/* ----- Anciennes classes .annuaire-* conservees pour fallback si d'autres
        pages les utilisent. A retirer dans un coup de balai futur. ----- */
.annuaire-filters {
  display: flex;
  gap: 12px;
  align-items: center;
  margin: 16px 0 12px;
  flex-wrap: wrap;
}
.annuaire-search {
  flex: 1;
  min-width: 240px;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
}
.annuaire-search:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, 0.12);
}
.annuaire-kind-filter {
  height: 38px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  background: var(--surface);
  cursor: pointer;
}
.annuaire-toggle-inactive {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
}
.annuaire-toggle-inactive input { margin: 0; }
.annuaire-reset {
  font-size: 13px;
  color: var(--muted);
  text-decoration: underline;
}
.annuaire-reset:hover { color: var(--text); }

/* Bouton-icone "disabled" : actions pas encore disponibles, on garde la
   place pour eviter le shift visuel quand on les activera en Sub 3 et 4. */
.link-btn-disabled {
  opacity: 0.3;
  cursor: not-allowed;
  display: inline-block;
  margin: 0 4px;
}

/* Titre de section dans un modal (standalone, hors .form-section).
   Reprend les codes typo des sections de form mais sans le wrapper. */
.modal-body .form-section-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-weight: 700;
  margin: 18px 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid #eef0f4;
}
.modal-body .form-section-help {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
  margin: -4px 0 12px;
}
/* Liste de cases a cocher pour les permissions par groupe (page Utilisateurs).
   Chaque option = checkbox + intitule (titre + description en italique). */
.perm-checkboxes {
  gap: 8px;
}
.perm-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.perm-option:hover {
  border-color: #c7cdd8;
  background: #fafbfc;
}
.perm-option input[type="checkbox"] {
  margin: 2px 0 0 0;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  cursor: pointer;
}
.perm-option span {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perm-option strong {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.perm-option em {
  font-size: 12px;
  color: var(--muted);
  font-style: normal;
}

/* =============================================================================
   Diagramme surface par zone (modal popup pour copier-coller en présentation).
   ============================================================================= */
.modal-overlay[hidden] { display: none; }

/* Selecteur de tri de la vue par entreprise, pose dans le titre de section
   a cote du bouton "Afficher diagramme". Discret : c'est un reglage de lecture,
   pas une action. */
.analytique-tri {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 12px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--muted);
}
.analytique-tri select {
  padding: 5px 8px;
  font: inherit;
  font-weight: 500;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
}
.analytique-tri select:hover {
  background: #eef0f4;
}
.analytique-tri select:focus-visible {
  outline: 2px solid var(--primary, #3b6ef5);
  outline-offset: 1px;
}

.zone-diag-trigger {
  margin-left: 12px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  vertical-align: middle;
}
.zone-diag-trigger:hover {
  background: #eef0f4;
  border-color: #d4d7df;
}

.zone-diag-modal { max-width: 880px; }
.zone-diag-modal:has(.zone-diag-table--quad) { max-width: 1080px; }
.zone-diag-modal .modal-body { padding: 28px 32px; gap: 0; }

.zone-diag-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  color: #1a2340;
}
.zone-diag-table thead th {
  background: #1d2a5b;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 14px 16px;
  text-align: left;
}
.zone-diag-table thead th.num { text-align: right; }
.zone-diag-table thead th:last-child { text-align: left; }

.zone-diag-table tbody tr { background: #f4f6fa; }
.zone-diag-table tbody tr:nth-child(even) { background: #fff; }
.zone-diag-table tbody td {
  padding: 14px 16px;
  border-bottom: 1px solid #e4e7ee;
}
.zone-diag-table tbody td.num { text-align: right; font-variant-numeric: tabular-nums; }

.zone-diag-bar-cell { width: 45%; min-width: 280px; }
/* Variante 4 colonnes (2 barres : surface + cout) : on retrecit chaque
   barre pour tenir dans la largeur du modal sans casser la mise en page. */
.zone-diag-table--quad .zone-diag-bar-cell { width: 30%; min-width: 220px; }
.zone-diag-bar-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.zone-diag-bar-track {
  flex: 1;
  height: 22px;
  background: #e4e9f2;
  border-radius: 3px;
  overflow: hidden;
}
.zone-diag-bar-fill { height: 100%; border-radius: 3px; }
.zone-diag-bar-fill--gold  { background: #c9a227; }
.zone-diag-bar-fill--navy  { background: #1d2a5b; }
.zone-diag-bar-fill--blue  { background: #4a73a8; }
.zone-diag-bar-fill--light { background: #b3cbe4; }
.zone-diag-bar-label {
  min-width: 60px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: #6a7080;
}
.zone-diag-bar-label--strong { color: #1a2340; font-weight: 700; }

.zone-diag-table tfoot tr { background: #c9a227; color: #fff; }
.zone-diag-table tfoot th {
  padding: 14px 16px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.zone-diag-table tfoot th.num { text-align: right; font-variant-numeric: tabular-nums; }
.zone-diag-table tfoot th:last-child { text-align: left; }

/* Boutons d'export image dans le footer du modal (taille reduite pour ne pas
   ecraser visuellement le contenu printable au-dessus). */
.zone-diag-modal .modal-footer { padding: 14px 24px; }
.zone-diag-modal .modal-footer .btn {
  padding: 8px 16px;
  font-size: 13px;
}
.zone-diag-feedback {
  font-size: 13px;
  color: #1f8a4c;
  font-weight: 500;
  align-self: center;
  margin-right: auto;
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
}
.zone-diag-feedback.show { opacity: 1; }
.zone-diag-feedback--err { color: var(--danger); }

/* Actions Copier / PNG sous chaque camembert pour export direct du
   graphe (sans passer par le modal diagramme barres). */
.analytique-chart-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  width: 100%;
  justify-content: flex-end;
  /* Si la carte est vraiment trop etroite, les deux BOUTONS passent l'un sous
     l'autre -- jamais l'icone au-dessus de son propre libelle. */
  flex-wrap: wrap;
}
/* inline-flex + nowrap : l'icone et le libelle restent TOUJOURS sur une seule
   ligne. Sans ca (bouton en `display:block`, `white-space:normal`), le libelle
   passait sous l'icone des que la carte se resserrait -- fenetre PWA, petit
   ecran (mesure : 42px de haut au lieu de 28px). */
.btn-chart-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  flex: none;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 500;
}
/* Meme garde-fou pour les boutons d'export des modals (icone + libelle). */
.modal-footer .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
/* Titre de section portant des actions a droite (ex. Croisement Lot x Zone). */
.analytique-section-title--actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.analytique-title-actions {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* === Toasts (notifications transitoires) ===
   Floating en haut a droite. CSS = animation + couleurs.
   JS = static/js/toasts.js (auto-dismiss + click-to-close). */
.toast-container {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none; /* le conteneur lui-meme ne capture pas les clicks */
  max-width: 380px;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 10px 14px;
  border-radius: 8px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #dde1ea);
  box-shadow: 0 4px 16px rgba(15, 26, 61, 0.15);
  font-size: 13.5px;
  color: var(--text, #1A2340);
  opacity: 0;
  transform: translateX(20px);
  transition: opacity 200ms ease, transform 200ms ease;
}
.toast.show { opacity: 1; transform: translateX(0); }
.toast.hide { opacity: 0; transform: translateX(20px); }
.toast-msg { flex: 1; line-height: 1.35; }
.toast-close {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--muted, #6A7080);
  font-size: 20px;
  line-height: 1;
  padding: 0 4px;
}
.toast-close:hover { color: var(--text, #1A2340); }
/* Barre coloree a gauche selon le niveau (Django messages tags). */
.toast-success { border-left: 4px solid #2A9D8F; }
.toast-info    { border-left: 4px solid #5C7AEA; }
.toast-warning { border-left: 4px solid #F4A261; }
.toast-error   { border-left: 4px solid #E76F51; }

/* === Pages d'erreur 404/500 (audit Cowork F-001) === */
.error-page-body { margin: 0; background: var(--bg, #f4f6fa); }
.error-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.error-page-card {
  max-width: 500px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #dde1ea);
  border-radius: 12px;
  padding: 40px;
  text-align: center;
  box-shadow: 0 4px 20px rgba(15, 26, 61, 0.08);
}
.error-page-code {
  font-size: 64px;
  font-weight: 800;
  color: var(--navy, #1D2A5B);
  line-height: 1;
  margin-bottom: 8px;
  letter-spacing: -0.02em;
}
.error-page-title {
  font-size: 22px;
  font-weight: 700;
  margin: 0 0 12px;
  color: var(--text, #1A2340);
}
.error-page-msg {
  font-size: 14px;
  color: var(--muted, #6A7080);
  line-height: 1.5;
  margin: 0 0 24px;
}
.error-page-actions { display: flex; justify-content: center; gap: 12px; }

/* Banner warning surface != zones (audit Cowork v2 F-003) */
.surface-mismatch-banner {
  margin: 0 0 18px;
  padding: 12px 16px;
  border-radius: 6px;
  font-size: 13.5px;
  line-height: 1.5;
}

/* === Responsive guard (audit Cowork v2 R-001/R-002) ===
   En dessous de 1024px, on masque le contenu et on affiche un message
   bloquant. L'app est desktop-only, refactor responsive en backlog. */
.responsive-guard {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: var(--bg, #f4f6fa);
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.responsive-guard-card {
  max-width: 420px;
  text-align: center;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #dde1ea);
  border-radius: 12px;
  padding: 32px 28px;
  box-shadow: 0 4px 20px rgba(15, 26, 61, 0.08);
}
.responsive-guard-icon { font-size: 56px; margin-bottom: 8px; }
.responsive-guard-card h1 {
  font-size: 20px;
  font-weight: 700;
  margin: 0 0 12px;
  color: var(--text, #1A2340);
}
.responsive-guard-card p {
  font-size: 14px;
  line-height: 1.5;
  color: var(--muted, #6A7080);
  margin: 0 0 8px;
}
.responsive-guard-meta { font-size: 12.5px; font-style: italic; opacity: 0.8; }

/* Active la garde sous 1024px et masque tout le reste du body. */
@media (max-width: 1023.98px) {
  .responsive-guard { display: flex; }
  body > *:not(.responsive-guard):not(script) {
    display: none !important;
  }
}

/* === Skip-link accessibilité (audit Cowork v2 A-003) ===
   Lien "Aller au contenu principal" placé tout en haut du <body>.
   Invisible par défaut (positionné hors viewport), il apparaît dès
   qu'il prend le focus clavier (Tab depuis le début de page). Permet
   aux utilisateurs clavier / lecteur d'écran de sauter la sidebar et
   la navbar pour atterrir directement sur le <main id="main-content">. */
.skip-link {
  position: absolute;
  top: -100px;
  left: 12px;
  z-index: 100000;
  background: var(--accent, #2D5BFF);
  color: #fff;
  padding: 10px 16px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  box-shadow: 0 4px 12px rgba(15, 26, 61, 0.15);
  transition: top 0.15s ease-out;
}
.skip-link:focus {
  top: 12px;
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* =============================================================================
   Page Informations projet -- refonte 2026-05-26 (hero + cartes + zones bars)
   ============================================================================= */
.infos-page {
  padding: 24px 32px 48px;
  max-width: 1100px;
  margin: 0 auto;
  width: 100%;
}

/* --- HERO --- */
.infos-hero {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 24px;
  background: var(--navy);
  color: #fff;
}
.infos-hero-bg {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 140% at 88% -10%, rgba(59, 110, 245, 0.55) 0%, transparent 55%),
    linear-gradient(135deg, #2a3656 0%, #1e2740 100%);
}
.infos-hero-content { position: relative; padding: 26px 30px; }
.infos-hero-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.infos-hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
  font-weight: 600;
}
.infos-hero-name {
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 6px 0 4px;
  line-height: 1.1;
}
.infos-hero-sub { font-size: 13.5px; color: rgba(255, 255, 255, 0.75); }
.infos-edit-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  flex-shrink: 0;
  transition: background 0.12s, border-color 0.12s;
}
.infos-edit-btn:hover { background: var(--blue); border-color: var(--blue); text-decoration: none; }
.infos-edit-btn svg { width: 15px; height: 15px; }

/* KPI chips dans le hero */
.infos-hero-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin-top: 22px;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  overflow: hidden;
}
.infos-kpi {
  background: rgba(15, 22, 45, 0.35);
  padding: 13px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.infos-kpi-lbl {
  font-size: 10px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
.infos-kpi-val {
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.infos-kpi-val.accent { color: #8fb0ff; }

/* --- Badge statut (hero + section Planning) --- */
.infos-status-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.infos-status-chiffrage { background: #e8f0fe; color: #2d5dd4; }
.infos-status-travaux   { background: #fdf0d8; color: #a8650f; }
.infos-status-clos      { background: #e3ebe5; color: #2f6b43; }
/* Dans le hero (fond sombre), versions plus lumineuses. */
.infos-hero-eyebrow .infos-status-chiffrage { background: rgba(143, 176, 255, 0.2); color: #bcd0ff; }
.infos-hero-eyebrow .infos-status-travaux   { background: rgba(240, 200, 120, 0.2); color: #f2d39b; }
.infos-hero-eyebrow .infos-status-clos      { background: rgba(160, 220, 180, 0.2); color: #bfe6cd; }

/* --- Grille sections + aside --- */
.infos-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 20px;
  align-items: start;
}
.infos-col-main { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.infos-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 20px 20px;
}
.infos-card-title {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
}
.infos-card-count {
  margin-left: auto;
  background: var(--bg);
  color: var(--muted);
  border-radius: 10px;
  padding: 1px 9px;
  font-size: 11px;
}

/* Champs clé/valeur en grille 2 colonnes interne. */
.infos-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 18px;
}
.infos-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.infos-field-wide { grid-column: 1 / -1; }
.infos-field dt {
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.infos-field dd {
  font-size: 14px;
  color: var(--text);
  font-weight: 500;
  word-break: break-word;
}
.infos-respos { display: flex; flex-wrap: wrap; gap: 6px; }
.infos-respo-chip {
  display: inline-block;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 3px 11px;
  font-size: 12.5px;
  font-weight: 500;
}

/* --- Aside zones avec barres --- */
.infos-col-aside .infos-card { position: sticky; top: 16px; }
.infos-zones { list-style: none; display: flex; flex-direction: column; gap: 13px; }
.infos-zone-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 5px;
}
.infos-zone-name { font-size: 13px; font-weight: 500; color: var(--text); }
.infos-zone-surface { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.infos-zone-bar {
  height: 7px;
  background: var(--bg);
  border-radius: 4px;
  overflow: hidden;
}
.infos-zone-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #5dade2, var(--blue));
  border-radius: 4px;
}
.infos-zones-total {
  display: flex;
  justify-content: space-between;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.infos-empty { color: var(--muted); font-style: italic; font-size: 13px; padding: 8px 0; }

/* Responsive : sous 980px, une seule colonne. */
@media (max-width: 980px) {
  .infos-grid { grid-template-columns: 1fr; }
  .infos-col-main { grid-template-columns: 1fr; }
  .infos-hero-kpis { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   Feedbacks dashboard (admin tech) — bug reports + annotations
   ============================================================
   Réutilise massivement les styles `.ann-*` (header sticky,
   filtres, table card, actions) pour cohérence cross-app.
   Spécifique ici : badges type/severite/statut, page détail,
   capture d'écran avec pin, panneau résolution. */

/* --- Liste : ajustements colonne ID + lignes ----------------- */
.fb-table th.fb-th-id { width: 56px; text-align: right; padding-right: 12px; }
.fb-table td.fb-cell-id {
  text-align: right;
  padding-right: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: var(--muted);
}
/* Ligne cliquable : curseur pointer si data-row-link est set (cf. handler
   JS dans feedbacks_list.html qui délègue le click au document). */
.fb-row[data-row-link] { cursor: pointer; }
.fb-row:hover { background: #f8fafc; }
.fb-row-resolu { opacity: .65; }
.fb-row-rejete { opacity: .55; }
.fb-cell-title {
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  display: block;
  line-height: 1.3;
}
.fb-cell-title:hover { color: var(--blue); text-decoration: underline; }
.fb-cell-excerpt {
  color: var(--muted);
  font-size: 12px;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 380px;
}
.fb-cell-user { font-size: 13px; }
.fb-cell-projet {
  color: var(--muted);
  text-decoration: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
}
.fb-cell-projet:hover { color: var(--blue); text-decoration: underline; }
.fb-cell-date {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* --- Badges Type --------------------------------------------- */
.fb-type {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}
.fb-type-bug         { background: #fde2dd; color: #b3261e; }
.fb-type-annotation  { background: #ede7f6; color: #5e35b1; }
.fb-type-suggestion  { background: #e1f0fa; color: #0c6cb3; }

/* --- Badges Sévérité (bugs uniquement) ----------------------- */
.fb-severite {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 4px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-left: 4px;
}
.fb-severite-bloquant { background: #fee2e2; color: #b91c1c; }
.fb-severite-gene     { background: #fef3c7; color: #92400e; }
.fb-severite-info     { background: #f1f5f9; color: #64748b; }

/* --- Badges Statut ------------------------------------------- */
.fb-statut {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}
.fb-statut-nouveau  { background: #dbeafe; color: #1d4ed8; }
.fb-statut-en_cours { background: #fef3c7; color: #92400e; }
.fb-statut-resolu   { background: #d1fae5; color: #065f46; }
.fb-statut-rejete   { background: #e5e7eb; color: #4b5563; }

/* --- Empty state liste --------------------------------------- */
.fb-empty {
  text-align: center;
  padding: 64px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
}
.fb-empty-icon { font-size: 40px; margin-bottom: 12px; opacity: .6; }
.fb-empty h2 { margin: 0 0 6px; font-size: 18px; color: var(--text); font-weight: 700; }
.fb-empty p { margin: 0; color: var(--muted); font-size: 14px; }
.fb-empty a { color: var(--blue); }

/* --- Page détail : header ------------------------------------ */
.fb-detail-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bg);
  padding: 18px 28px 14px;
  border-bottom: 1px solid var(--border);
}
.fb-detail-header-row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  max-width: 1200px;
  margin: 0 auto;
}
.fb-back-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  transition: background .15s;
}
.fb-back-btn:hover { background: #eef2f7; }
.fb-back-btn svg { width: 18px; height: 18px; }
.fb-detail-titles { flex: 1; min-width: 0; }
.fb-detail-eyebrow {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.fb-detail-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  color: var(--muted);
}
.fb-detail-title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.3;
}

/* --- Page détail : grille ------------------------------------ */
.fb-detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
  max-width: 1200px;
  margin: 0 auto;
}
.fb-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 20px;
}
.fb-card-meta { grid-column: 1 / -1; }
.fb-card-actions { grid-column: 1 / -1; }
.fb-card-title {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
}
.fb-description {
  color: var(--text);
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.fb-empty-inline { color: var(--muted); font-style: italic; font-size: 13px; margin: 0; }

/* --- Capture + pin ------------------------------------------- */
.fb-screenshot-wrap {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: #f8fafc;
}
.fb-screenshot { display: block; width: 100%; height: auto; }

/* Capture cliquable -> lightbox plein ecran (CSS :target, cf. feedbacks_detail.html).
   Retour Thibaut 2026-07-07 : la miniature etait illisible, il faut pouvoir
   l'agrandir au clic. */
.fb-screenshot-link { display: block; cursor: zoom-in; }
.fb-screenshot-hint { display: block; margin-top: 8px; font-size: 12px; color: #6a7080; }
.fb-lightbox { display: none; }
.fb-lightbox:target {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  inset: 0;
  z-index: 1000;
  padding: 28px;
  background: rgba(9, 14, 30, 0.92);
  cursor: zoom-out;
}
.fb-lightbox img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.6);
}
.fb-lightbox-close {
  position: fixed;
  top: 16px;
  right: 26px;
  color: #fff;
  font-size: 34px;
  line-height: 1;
  text-decoration: none;
}
.fb-pin {
  position: absolute;
  pointer-events: none;
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  border-radius: 50%;
  background: #b3261e;
  border: 3px solid #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
  animation: fb-pin-pulse 1.8s ease-in-out infinite;
}
@keyframes fb-pin-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.18); }
}

/* --- Métadonnées --------------------------------------------- */
.fb-meta { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 24px; }
.fb-meta-row { display: flex; flex-direction: column; gap: 2px; }
.fb-meta-row dt {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}
.fb-meta-row dd { margin: 0; font-size: 13px; color: var(--text); }
.fb-meta-row dd a { color: var(--blue); text-decoration: none; }
.fb-meta-row dd a:hover { text-decoration: underline; }
.fb-meta-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
.fb-meta-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-meta-empty { color: var(--muted); font-style: italic; }

/* --- Résolution : panneau de statut + note ------------------- */
.fb-form-statut { display: flex; flex-direction: column; gap: 14px; }
.fb-statut-choices {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 0;
  margin: 0;
  border: none;
}
.fb-statut-legend {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  margin-bottom: 8px;
  width: 100%;
}
.fb-statut-choice {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  transition: all .15s;
}
.fb-statut-choice input { margin: 0; }
.fb-statut-choice:hover { background: #f1f5f9; }
.fb-statut-choice:has(input:checked) { border-color: var(--blue); background: #eff6ff; color: var(--blue); font-weight: 600; }
.fb-statut-choice.is-current { box-shadow: inset 0 0 0 1px var(--blue); }

.fb-note-label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}
.fb-note-input {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--text);
  font-family: inherit;
  resize: vertical;
  min-height: 70px;
  background: var(--surface);
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}
.fb-note-input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, .15);
}

.fb-form-actions { display: flex; justify-content: flex-end; }
.fb-btn-primary {
  background: var(--blue);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s;
}
.fb-btn-primary:hover { background: var(--blue-2); }

.fb-form-delete {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
  display: flex;
  justify-content: flex-end;
}
.fb-btn-danger {
  background: var(--surface);
  color: var(--danger);
  border: 1px solid var(--danger);
  border-radius: 10px;
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s;
}
.fb-btn-danger:hover { background: var(--danger-bg); }

/* --- Responsive feedbacks ------------------------------------ */
@media (max-width: 980px) {
  .fb-detail-grid { grid-template-columns: 1fr; }
  .fb-meta { grid-template-columns: 1fr; }
  .fb-cell-excerpt { max-width: 200px; }
}

/* ============================================================
   Feedback report — bouton flottant + modal de saisie
   ============================================================
   JS = static/js/feedback-report.js (html2canvas + submit AJAX).
   Visible a tout user authentifie sur toutes les pages. */

/* --- FAB (bouton flottant bottom-right) ---------------------- */
.fbr-fab {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 9000;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  border: none;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .18), 0 2px 4px rgba(0, 0, 0, .12);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.fbr-fab svg { width: 24px; height: 24px; }
.fbr-fab:hover {
  background: var(--navy-2);
  transform: translateY(-1px) scale(1.04);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .22), 0 3px 6px rgba(0, 0, 0, .14);
}
.fbr-fab:active { transform: scale(0.97); }

/* --- Modal overlay ------------------------------------------- */
.fbr-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(15, 23, 42, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  transition: opacity .18s ease;
}
.fbr-overlay.is-open { opacity: 1; }
.fbr-overlay[hidden] { display: none; }

.fbr-modal {
  background: var(--surface);
  border-radius: 16px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, .25), 0 6px 12px rgba(0, 0, 0, .1);
  width: 100%;
  max-width: 540px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  transform: translateY(8px) scale(0.98);
  transition: transform .2s ease;
}
.fbr-overlay.is-open .fbr-modal { transform: translateY(0) scale(1); }

.fbr-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px 12px;
  border-bottom: 1px solid var(--border);
}
.fbr-modal-title {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
}
.fbr-close {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.fbr-close:hover { background: #f1f5f9; color: var(--text); }

/* --- Form layout --------------------------------------------- */
.fbr-form {
  padding: 16px 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.fbr-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border: none;
  padding: 0;
  margin: 0;
}
.fbr-field legend, .fbr-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  padding: 0;
}
.fbr-label em { color: var(--danger); font-style: normal; margin-left: 2px; }

.fbr-field-type, .fbr-field-severite {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.fbr-field-type legend, .fbr-field-severite legend {
  width: 100%;
  margin-bottom: 4px;
}
.fbr-radio {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
  transition: all .15s;
}
.fbr-radio input { margin: 0; }
.fbr-radio:hover { background: #f1f5f9; }
.fbr-radio:has(input:checked) {
  border-color: var(--blue);
  background: #eff6ff;
  color: var(--blue);
  font-weight: 600;
}

.fbr-input, .fbr-textarea {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  font-family: inherit;
}
.fbr-textarea { resize: vertical; min-height: 84px; }
.fbr-input:focus, .fbr-textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, .15);
}

/* --- Capture preview (definition complete plus bas avec ovelray annoter) */
.fbr-field-capture { gap: 8px; }
.fbr-capture-status {
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
}
.fbr-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
}

/* --- Actions ------------------------------------------------- */
.fbr-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 6px;
}
.fbr-btn {
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 9px 18px;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.fbr-btn-primary {
  background: var(--blue);
  color: #fff;
}
.fbr-btn-primary:hover { background: var(--blue-2); }
.fbr-btn-primary:disabled { opacity: 0.6; cursor: wait; }
.fbr-btn-ghost {
  background: transparent;
  color: var(--muted);
  border-color: var(--border);
}
.fbr-btn-ghost:hover { background: #f1f5f9; color: var(--text); }

.fbr-form-error {
  background: var(--danger-bg);
  color: var(--danger);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 13px;
  margin-top: 6px;
}

/* --- Responsive ---------------------------------------------- */
@media (max-width: 600px) {
  .fbr-fab { right: 16px; bottom: 16px; }
  .fbr-overlay { padding: 12px; }
}

/* --- Preview cliquable (bouton "Annoter") -------------------- */
.fbr-capture-preview {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  max-height: 180px;
  background: transparent;
  cursor: pointer;
  transition: opacity .15s, border-color .15s, box-shadow .15s;
}
.fbr-capture-preview:hover {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59, 110, 245, .15);
}
.fbr-capture-preview img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 180px;
  object-fit: cover;
  object-position: top;
}
.fbr-capture-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: rgba(15, 23, 42, .55);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  transition: opacity .15s;
  pointer-events: none;
}
.fbr-capture-overlay svg { width: 18px; height: 18px; }
.fbr-capture-preview:hover .fbr-capture-overlay { opacity: 1; }
.fbr-capture-preview.is-annotated { border-color: var(--blue); }
.fbr-capture-preview.is-annotated::before {
  content: "✏️ Annoté";
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
  padding: 3px 9px;
  background: var(--blue);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
  letter-spacing: .02em;
}

/* ============================================================
   Annotation editor — overlay full-screen au-dessus du modal
   ============================================================
   JS = static/js/feedback-annotate.js. Toolbar haut, canvas
   centré, actions bas. Outils : crayon / rect / flèche / texte. */

.fbra-overlay {
  position: fixed;
  inset: 0;
  z-index: 11000;  /* au-dessus du fbr-overlay (10000) */
  background: rgba(15, 23, 42, .85);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 16px;
  gap: 14px;
  opacity: 0;
  transition: opacity .18s ease;
}
.fbra-overlay.is-open { opacity: 1; }
.fbra-overlay[hidden] { display: none; }

/* --- Toolbar -------------------------------------------------- */
.fbra-toolbar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
  background: var(--surface);
  border-radius: 14px;
  padding: 8px 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .2);
}
.fbra-tools, .fbra-colors, .fbra-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.fbra-tool, .fbra-action {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background .12s, border-color .12s, color .12s;
}
.fbra-tool svg, .fbra-action svg { width: 18px; height: 18px; }
.fbra-tool:hover, .fbra-action:hover { background: #f1f5f9; }
.fbra-tool.is-active {
  background: #eff6ff;
  border-color: var(--blue);
  color: var(--blue);
}
.fbra-sep {
  width: 1px;
  height: 24px;
  background: var(--border);
}
.fbra-color {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid transparent;
  background: var(--c);
  cursor: pointer;
  padding: 0;
  transition: transform .12s, border-color .12s;
}
.fbra-color:hover { transform: scale(1.08); }
.fbra-color.is-active {
  border-color: var(--text);
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--c);
}

/* --- Canvas wrapper ------------------------------------------ */
.fbra-canvas-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 0;
}
.fbra-canvas-wrap canvas {
  max-width: 100%;
  max-height: 100%;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .3);
  cursor: crosshair;
}
.fbra-canvas-wrap canvas[data-tool="text"] { cursor: text; }
.fbra-canvas-wrap canvas[data-tool="eraser"] { cursor: cell; }

/* --- Widget texte flottant (wrapper draggable + input editable) ---- */
/* Le cadre dashed = move handle (cursor move). L'input interne = saisie
   (cursor text). User drague le cadre pour repositionner avant Enter. */
.fbra-text-widget {
  position: absolute;
  z-index: 2;
  padding: 4px;
  border: 2px dashed rgba(255, 255, 255, .9);
  background: rgba(15, 23, 42, .5);
  border-radius: 4px;
  cursor: move;
  min-width: 120px;
  transition: border-color .12s, background .12s;
}
.fbra-text-widget.is-dragging,
.fbra-text-widget:hover {
  border-color: var(--blue);
  background: rgba(15, 23, 42, .7);
}
.fbra-text-input {
  display: block;
  width: 100%;
  border: none;
  background: transparent;
  outline: none;
  padding: 0;
  font-family: system-ui, sans-serif;
  cursor: text;
}
.fbra-text-input::placeholder { color: rgba(255, 255, 255, .55); font-size: 14px; }

/* --- Bottom bar ---------------------------------------------- */
.fbra-bottombar {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* ============================================================
   Page Offline (PWA Bloc B)
   ============================================================
   Rendue par le SW en fallback navigation HTML quand reseau KO.
   Pre-cachee a l'install du SW (cf. templates/sw.js APP_SHELL).
   Volontairement minimaliste, identite Quanto preservee. */

body.offline-page {
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  margin: 0;
}
.offline-main { width: 100%; max-width: 480px; }
.offline-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 36px 32px 28px;
  text-align: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .06);
}
.offline-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto 18px;
  color: var(--muted);
}
.offline-icon svg { width: 100%; height: 100%; }
.offline-title {
  margin: 0 0 12px;
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
}
.offline-text {
  margin: 0 0 22px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
}
.offline-retry {
  background: var(--blue);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 11px 22px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s;
}
.offline-retry:hover { background: var(--blue-2); }
.offline-meta {
  margin: 22px 0 0;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}

/* ============================================================
   Push notifications toggle (PWA Bloc C)
   ============================================================
   Bouton dans la sidebar bottom-block. Style cohérent avec les
   autres nav-links de la sidebar (couleur cassée sur fond
   transparent, bordure gauche -> blue quand actif). */
.sidebar-push-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  margin: 4px 12px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: rgba(255, 255, 255, .55);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s, color .15s;
  font-family: inherit;
  width: calc(100% - 24px);
  text-align: left;
}
.sidebar-push-toggle svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.sidebar-push-toggle:hover {
  background: rgba(255, 255, 255, .06);
  color: rgba(255, 255, 255, .85);
}
.sidebar-push-toggle[data-fbp-subscribed="1"] {
  color: #5dade2;  /* cyan brand-mark */
}
.sidebar-push-toggle[data-fbp-subscribed="1"] svg {
  /* Petit point indicateur "actif" sur l'icone (bordure subtile en glow). */
  filter: drop-shadow(0 0 4px rgba(93, 173, 226, .6));
}
.sidebar-push-toggle:disabled { opacity: .5; cursor: wait; }
.sidebar-push-toggle[hidden] { display: none; }

/* ============================================================
   Suppression projet : zone danger (page Informations) + corbeille
   ============================================================ */
.infos-danger {
  margin-top: 24px;
  padding: 18px 22px;
  border: 1px solid #f0c9c4;
  background: #fdf3f1;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
/* Zone danger (suppression projet) DANS la grille du formulaire d'edition :
   calee en colonne 1 -> meme largeur que la carte formulaire, pas toute la
   grille (qui inclut l'aside Zones a droite). Le row-gap de la grille gere
   l'espacement, on annule donc le margin-top par defaut de .infos-danger. */
.form-page-grid .infos-danger {
  grid-column: 1;
  margin-top: 0;
}
.infos-danger-title {
  margin: 0 0 4px;
  font-size: 14px;
  font-weight: 700;
  color: #b3261e;
}
.infos-danger-text p {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
  max-width: 60ch;
}
.infos-danger-text a { color: var(--blue); }
.infos-danger-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border-radius: 10px;
  background: var(--surface);
  color: var(--danger);
  border: 1px solid var(--danger);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.infos-danger-btn svg { width: 16px; height: 16px; }
.infos-danger-btn:hover { background: var(--danger); color: #fff; }

/* Corbeille : bouton Restaurer (vert, sobre). */
.corbeille-restore-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 13px;
  border-radius: 8px;
  background: #ecfdf5;
  color: #047857;
  border: 1px solid #6ee7b7;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background .15s;
}
.corbeille-restore-btn svg { width: 15px; height: 15px; }
.corbeille-restore-btn:hover { background: #d1fae5; }

/* ---------------------------------------------------------------------------
   Banniere de mise a jour PWA (injectee par sw-register.js quand un nouveau
   Service Worker est pret). Persiste jusqu'au clic sur "Actualiser".
   --------------------------------------------------------------------------- */
.sw-update-banner {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translate(-50%, 140%);
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: calc(100vw - 32px);
  padding: 11px 12px 11px 18px;
  border-radius: 12px;
  background: var(--sidebar-bg);
  color: #fff;
  box-shadow: 0 10px 30px rgba(15, 23, 42, .28);
  font-size: 14px;
  opacity: 0;
  transition: transform .28s cubic-bezier(.2, .8, .2, 1), opacity .28s ease;
}
.sw-update-banner.show {
  transform: translate(-50%, 0);
  opacity: 1;
}
.sw-update-banner-label { font-weight: 600; white-space: nowrap; }
.sw-update-banner-btn {
  flex: none;
  padding: 7px 16px;
  border: 0;
  border-radius: 8px;
  background: var(--blue);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  transition: background .15s;
}
.sw-update-banner-btn:hover { background: var(--blue-2); }
.sw-update-banner-btn:disabled { opacity: .65; cursor: default; }

@media (max-width: 480px) {
  .sw-update-banner { left: 16px; right: 16px; bottom: 16px; transform: translateY(140%); }
  .sw-update-banner.show { transform: translateY(0); }
}

/* ---------------------------------------------------------------------------
   Drag & drop des postes (postes-sortable.js).
   - Vue par zone  : conteneur .postes-dropzone (1 par zone × principaux/options),
     items = lignes .row déplaçables entre zones.
   - Vue par poste : conteneur .postes-sortable (principaux/options), items =
     blocs .poste-block (poste + ses sous-lignes zones).
   On glisse par la poignée ⋮⋮ (handle) ; les autres cellules restent éditables.
   --------------------------------------------------------------------------- */
.postes-dropzone,
.postes-sortable,
.poste-block {
  /* S'aligne sur la largeur des .row (même min-width) pour rester collé au
     header pendant le scroll horizontal de .postes-grid. */
  min-width: 1396px;
}
/* TOUJOURS visible, calée tout à gauche de la ligne : position absolue dans la
   cellule N° (1re colonne, position:relative). Hors flux -> ne pousse ni le
   numéro ni la poubelle, qui restent centrés. C'est le handle SortableJS. */
.poste-drag-handle {
  position: absolute;
  /* Centree VISUELLEMENT entre le "+" (finit a 16px) et le numero (debute a
     35px) : boite de 12,7px dont 1px de letter-spacing en trainee a droite,
     d ou 20px plutot que 19,25px (centrage de boite). Mesure 2026-09-07. */
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  cursor: grab;
  color: #c2c8d2;
  font-size: 13px;
  line-height: 1;
  letter-spacing: 1px;        /* 2 colonnes de points distinctes (effet grip ⋮⋮) */
  user-select: none;
}
.poste-drag-handle:hover { color: var(--muted); }
.poste-drag-handle:active { cursor: grabbing; }
/* Le 🗑 reste un bouton cliquable (handle distinct = la poignée ⋮⋮). */
.postes-dropzone .row .poste-delete { cursor: pointer; }
/* Au survol, la poubelle file à droite de la cellule N° -> elle ne chevauche
   pas la poignée (absolue à gauche). Au repos, le numéro reste centré (aligné
   avec l'en-tête « N° »). */

/* États visuels SortableJS pendant le glisser. */
.poste-row-ghost {
  opacity: .45;
  background: #eef3ff;
}
.poste-row-chosen { background: #f4f7ff; }
.poste-row-dragging { box-shadow: 0 6px 18px rgba(15, 23, 42, .18); }

/* Zone vide : reste une cible de drop visible + invite explicite. */
.postes-dropzone--empty {
  min-height: 40px;
  margin: 2px 0;
  border: 1px dashed var(--border);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.postes-dropzone--empty::after {
  content: "Glissez un poste ici, ou « + Ajouter un poste »";
  color: var(--muted);
  font-size: 12px;
  font-style: italic;
}

/* ---------------------------------------------------------------------------
   Lignes de texte libre intercalées entre les postes (modèle LigneTexte).
   .row-texte = ligne pleine largeur (override de la grille .row) : poignée +
   barre G/I/S/taille + éditeur contenteditable + suppression.
   --------------------------------------------------------------------------- */
.row.row-texte {
  display: block;
  position: relative;
  min-width: 1396px;
  /* gauche 85px = début aligné avec la désignation des postes (col-numero 76px
     + padding cellule). droite 40px = place pour le bouton supprimer. */
  padding: 8px 40px 8px 85px;
  background: #fff;           /* fond blanc (choix utilisateur) */
  border-top: 1px solid #f0f2f6;
  border-bottom: 1px solid #f0f2f6;
}
/* Poignée de glisse à l'extrême gauche (zone du N°), toujours visible. */
.row-texte .poste-drag-handle {
  position: absolute;
  left: 3px;          /* aligné sur la poignée des postes (offset 3px) */
  top: 50%;
  transform: translateY(-50%);
  display: block;
  cursor: grab;
}
/* Barre de mise en forme : flottante, révélée UNIQUEMENT pendant l'édition
   (focus dans la ligne) -> ne pousse plus le texte. Posée sous le début du
   texte. */
.rt-toolbar {
  position: absolute;
  left: 85px;
  bottom: calc(100% - 5px);   /* AU-DESSUS du texte -> ne masque pas les boutons
                                 d'ajout en bas de zone (vue par zone). */
  z-index: 6;
  display: none;
  align-items: center;
  gap: 3px;
  padding: 4px 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 5px 16px rgba(15, 23, 42, 0.16);
}
.row-texte:focus-within .rt-toolbar { display: inline-flex; }
.rt-btn {
  width: 22px;
  height: 22px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  color: var(--text);
  font-family: inherit;
  padding: 0;
}
.rt-btn:hover { background: #eef3ff; border-color: var(--blue); }
.rt-size {
  width: 46px;
  height: 22px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 11px;
  padding: 0 4px;
  font-family: inherit;
}
/* Sélecteur de couleur du texte : pastille carrée alignée sur la barre. */
.rt-color {
  width: 24px;
  height: 22px;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px;
  cursor: pointer;
  background: var(--surface);
}
.rt-color::-webkit-color-swatch-wrapper { padding: 0; }
.rt-color::-webkit-color-swatch { border: none; border-radius: 2px; }
.rt-color::-moz-color-swatch { border: none; border-radius: 2px; }
.rt-editor,
.rt-content {
  font-size: 13px;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
}
.rt-editor {
  min-height: 22px;
  padding: 2px 6px;
  margin-left: -6px;          /* compense le padding -> texte calé sur 85px */
  border: 1px dashed transparent;
  border-radius: 4px;
  outline: none;
}
.rt-editor:hover { border-color: #cdd9f5; }
.rt-editor:focus { border-color: var(--blue); border-style: solid; background: #fff; }
.rt-editor:empty::before {
  content: attr(data-placeholder);
  color: var(--muted);
  font-style: italic;
}
.ligne-texte-delete {
  position: absolute;
  left: 21px;        /* aligné sur la poubelle des postes (offset 21px au survol) */
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 1px solid transparent;
  color: var(--danger);
  cursor: pointer;
  font-size: 12px;
  padding: 1px 3px;
  border-radius: 3px;
  line-height: 1;
  opacity: 0;                       /* visible uniquement au survol de la ligne */
  transition: opacity 0.12s ease;
}
.row-texte:hover .ligne-texte-delete { opacity: 1; }
.ligne-texte-delete:hover { background: var(--danger-bg); border-color: rgba(214, 69, 69, 0.3); }

/* Bouton "+ Insérer texte" (barre d'ajout poste + header de zone). */
.btn-add-texte {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  background: #f4f7ff;
  color: var(--blue-2);
  border: 1px solid #cdd9f5;
  border-radius: 6px;
  cursor: pointer;
}
.btn-add-texte:hover { background: #e6eeff; border-color: var(--blue); }
.btn-add-texte:disabled { opacity: .5; cursor: not-allowed; }

/* ============================================================
   PILOTAGE PROJET (phase Travaux) — 5 briques colorées + édition inline.
   Design porté de la maquette validée (maquettes/pilotage-projet.html).
   Tout est scopé sous .pilotage pour éviter les collisions globales.
   ============================================================ */
.pilotage {
    --pil-line: #e2e7f1;
    --pil-line2: #eef1f7;
    --pil-ink: #182034;
    --pil-ink2: #5b6580;
    --pil-ink3: #94a0b8;
    --pil-card2: #f7f9fc;
}
.pilotage .t-exc { color: #0f7a37; }
.pilotage .t-good { color: #4f9d2b; }
.pilotage .t-low { color: #c07d0a; }
.pilotage .t-neg { color: #d42a2a; }

/* KPIs */
.pil-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 18px 0 20px; }
.pil-kpi { background: #fff; border: 1px solid var(--pil-line); border-radius: 14px; padding: 15px 17px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); }
.pil-kpi .l { font-size: 12.5px; color: var(--pil-ink2); }
.pil-kpi .v { font-size: 23px; font-weight: 600; margin-top: 7px; letter-spacing: -.5px; font-variant-numeric: tabular-nums; }
.pil-kpi .sub { font-size: 12px; color: var(--pil-ink3); margin-top: 3px; }
.pil-kpi.brut { background: #e7f5ec; border-color: transparent; }
.pil-kpi.brut .l, .pil-kpi.brut .v, .pil-kpi.brut .sub { color: #1f8a4c; }

/* Légende marge (4 paliers) : en colonne (aligne les 2 lignes de bascules). */
.pil-legend { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; font-size: 12px; color: var(--pil-ink2); background: #fff; border: 1px solid var(--pil-line); border-radius: 10px; padding: 10px 14px; }
.pil-legend b { color: var(--pil-ink); font-weight: 600; margin-bottom: 1px; }
.pil-legend .lg { display: inline-flex; align-items: center; gap: 7px; }
.pil-legend .lg i { width: 24px; height: 7px; border-radius: 4px; display: inline-block; }
.g-exc { background: #21a34a; }
.g-good { background: #7ab52f; }
.g-low { background: #e08a0b; }
.g-neg { background: #e04747; }

/* Briques (tuiles indépendantes) — couleur d'identité par brique */
.pilotage .brique { background: #fff; border: 1px solid var(--pil-line); border-left: 5px solid var(--acc, var(--pil-line)); border-radius: 14px; overflow: hidden; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); margin-bottom: 18px; }
.pilotage .brique-head { display: flex; align-items: center; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--pil-line); background: var(--accbg, var(--pil-card2)); }
.pilotage .brique-title { font-size: 16px; font-weight: 600; color: var(--acc, var(--pil-ink)); display: flex; align-items: center; gap: 10px; margin: 0; }
.pilotage .brique-title::before { content: ""; width: 11px; height: 11px; border-radius: 3px; background: var(--acc, var(--pil-ink3)); flex: 0 0 auto; }
.br-tr { --acc: #2f6df0; --accbg: #eef3ff; }
.br-ftm { --acc: #0e93a3; --accbg: #e3f5f7; }
.br-hon { --acc: #7a53e3; --accbg: #f0ebfd; }
.br-ass { --acc: #bf7a08; --accbg: #faefd6; }
.br-div { --acc: #586576; --accbg: #eceff4; }
.grand-brique { --acc: #1f8a4c; --accbg: #e7f5ec; }

/* Table */
.pil-tablewrap { overflow-x: auto; }
.pil-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.pil-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--pil-ink3); font-weight: 500; text-align: right; padding: 10px 14px; background: var(--pil-card2); border-bottom: 1px solid var(--pil-line); white-space: nowrap; }
.pil-table th.l { text-align: left; }
.pil-table td { padding: 6px 14px; border-bottom: 1px solid var(--pil-line2); font-size: 13.5px; text-align: right; vertical-align: middle; color: var(--pil-ink); }
.pil-table td.l { text-align: left; }
.pil-table td.num { white-space: nowrap; }
.pil-table td.neg { color: #d42a2a; }
.pil-table tbody tr:last-child td { border-bottom: 0; }
.pil-lg > td { padding: 9px 14px; }
.pil-lg .pil-badge { font-size: 10.5px; color: var(--pil-ink3); font-weight: 400; margin-left: 3px; }
/* Repli/dépli des lignes portant des dépenses (chevron devant la désignation).
   CSS aligné sur la maquette (.ln flex + gap 9px ; chevron .chev ▶ qui pivote
   à 90° quand déplié). État déplié par défaut -> chevron pointe vers le bas. */
.pil-ln { display: flex; align-items: center; gap: 9px; }
.pil-chev { color: var(--pil-ink3); font-size: 11px; transition: transform .18s; width: 10px; display: inline-block; flex: 0 0 auto; transform: rotate(90deg); border: 0; background: transparent; padding: 0; line-height: 1; cursor: pointer; text-align: left; }
.pil-chev:hover { color: var(--pil-ink); }
.pil-lg.is-collapsed .pil-chev { transform: none; }
.pil-chev-spacer { width: 10px; flex: 0 0 auto; display: inline-block; }
/* Seules les colonnes Marge € / % sont en gras (les autres restent normales). */
.pil-mg { font-weight: 700; }
.pil-dep > td { background: var(--pil-card2); }
.pil-dep td.l1 { padding-left: 30px; }
/* Montant d'une dépense (Tableau) : italique + fin du nombre alignée sur la
   colonne Achat. Les nombres statiques sont à 14px du bord de cellule ; l'input
   a 7px de padding + 1px de bordure -> on le décale de 8px vers la droite. */
.pil-dep .pil-in.num.r { font-style: italic; margin-right: -8px; }
/* Sous-total : même hauteur de ligne que l'en-tête de tuile (.brique-head). */
.pil-sub > td { padding: 13px 14px; border-top: 2px solid var(--pil-line); background: var(--accbg, var(--pil-card2)); }
.pil-sub > td.l { font-weight: 700; }
.pil-grand > td { font-weight: 600; font-size: 14.5px; background: var(--accbg); padding: 12px 14px; }
.pil-empty td { color: var(--pil-ink3); font-style: italic; text-align: center; padding: 12px; }
/* États vides des cartes : ligne discrète + bloc « riche » (honoraires). */
.pil-cardsec p.pil-empty { padding: 12px 18px; margin: 0 12px; color: var(--pil-ink3); font-style: italic; font-size: 12.5px; }
.pil-empty-rich { display: flex; align-items: center; gap: 13px; margin: 4px 12px 8px; padding: 15px 18px; background: var(--pil-card2); border: 1px dashed var(--pil-line); border-radius: 12px; }
.pil-empty-ic { width: 26px; height: 26px; fill: none; stroke: var(--pil-ink3); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; flex: 0 0 auto; }
.pil-empty-txt { display: flex; flex-direction: column; gap: 2px; }
.pil-empty-title { font-weight: 600; color: var(--pil-ink); font-size: 13.5px; }
.pil-empty-sub { font-size: 12px; color: var(--pil-ink3); line-height: 1.4; max-width: 60ch; }
.pil-addrow > td { background: var(--pil-card2); padding: 4px 14px 8px 30px; }
.pil-lg.alerte > td { background: #fcf4f4; }
.pilotage .vfy.ok { color: #1f8a4c; }
.pilotage .vfy.err { color: #d42a2a; }

/* Inputs inline */
.pil-in { border: 1px solid transparent; background: transparent; font: inherit; color: inherit; padding: 4px 7px; border-radius: 7px; font-variant-numeric: tabular-nums; max-width: 100%; }
.pil-in:hover { background: #fff; border-color: var(--pil-line); }
.pil-in:focus { outline: none; background: #fff; border-color: #3b6ef5; box-shadow: 0 0 0 3px #eaf0ff; }
.pil-in.num.r { text-align: right; width: 120px; }
.pil-in.gname { font-weight: 500; min-width: 160px; }
.pil-in.pil-ent { min-width: 150px; }
.pil-in.pil-cmd { width: 120px; }
.pil-in.pil-cmt { min-width: 180px; font-style: italic; }
.pil-meta { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; font-size: 12px; color: var(--pil-ink3); }
.pil-pfx { color: var(--pil-ink3); font-size: 11px; }

/* Statut (select pilule) */
.pil-statut { border: 0; border-radius: 20px; padding: 4px 9px; font-size: 11px; font-weight: 500; font-family: inherit; cursor: pointer; -webkit-appearance: none; appearance: none; }
.pil-statut.s-valide { background: #e7f5ec; color: #1f8a4c; }
.pil-statut.s-commander { background: #e8f0fe; color: #2f6df0; }
.pil-statut.s-negociation { background: #f9f0dc; color: #b0730a; }
.pil-statut.s-clarifier { background: #fcebeb; color: #d92d2d; }
.pil-statut.s-previsionnel { background: #f0ebfd; color: #7a53e3; }

/* Boutons ajouter / supprimer */
/* « Ajouter … » : pastille « + » RONDE blanche sur fond bleu + libellé bleu
   sans fond (moins massif). Le « + » est dessiné par 2 barres blanches en
   dégradé -> centrage géométrique parfait (le glyphe "+" apparaît décalé). */
.pil-add { display: inline-flex; align-items: center; gap: 8px; background: transparent; border: 0; color: #3b6ef5; font-size: 12.5px; padding: 4px 8px 4px 4px; border-radius: 8px; cursor: pointer; font-family: inherit; }
.pil-add::before { content: ""; flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%; background: linear-gradient(#fff, #fff) center / 9px 2px no-repeat, linear-gradient(#fff, #fff) center / 2px 9px no-repeat, #3b6ef5; }
.pil-add:hover { background: var(--pil-card2); }
.pil-add:hover::before { background: linear-gradient(#fff, #fff) center / 9px 2px no-repeat, linear-gradient(#fff, #fff) center / 2px 9px no-repeat, #2f5fd6; }
.pil-add.head { margin-left: auto; }
/* « + dépense » compact dans la barre du lot (Travaux / Honoraires) :
   + blanc sur fond bleu plein, aligné à droite dans la dernière colonne. */
.pil-adddep { display: inline-flex; align-items: center; gap: 5px; background: #3b6ef5; border: 0; color: #fff; font-size: 12px; padding: 5px 11px; border-radius: 8px; cursor: pointer; font-family: inherit; white-space: nowrap; }
.pil-adddep:hover { background: #2f5fd6; }
.pil-del { background: transparent; border: 0; color: var(--pil-ink3); cursor: pointer; font-size: 14px; padding: 3px 6px; line-height: 1; }
.pil-del:hover { color: #d42a2a; }
.pil-actions { white-space: nowrap; }
.pil-flag { white-space: nowrap; }

@media (max-width: 900px) {
    .pil-kpis { grid-template-columns: repeat(2, 1fr); }
}

/* Pilotage — bascules Tableau/Cartes + Par lot/entreprise */
/* Barre d'outils : bascules sur 2 lignes à gauche + légende à droite. */
.pil-toolbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px 24px; flex-wrap: wrap; margin: 4px 0 16px; }
.pil-toolbar-segs { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.pil-seg { display: inline-flex; background: var(--pil-card2); border: 1px solid var(--pil-line); border-radius: 10px; padding: 3px; gap: 3px; }
/* Toggle « Par lot / Par entreprise » posé dans l'en-tête de la tuile Travaux
   (le groupement ne concerne que cette section) : à droite, fond blanc, compact. */
.pil-seg-head { margin-left: auto; background: #fff; }
.pil-seg-head .pil-segbtn { font-size: 12px; padding: 4px 11px; }
.pil-segbtn { border: 0; background: transparent; color: var(--pil-ink2); font-size: 13px; padding: 6px 13px; border-radius: 7px; cursor: pointer; font-family: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 7px; }
.pil-segico { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.4; flex: 0 0 auto; }
.pil-segbtn.on { background: #fff; color: var(--pil-ink); font-weight: 500; box-shadow: 0 1px 2px rgba(20,27,46,.08); }
.pil-segbtn:hover:not(.on):not(.disabled) { color: var(--pil-ink); }
.pil-segbtn.disabled { color: var(--pil-ink3); opacity: .5; cursor: not-allowed; pointer-events: none; }

/* Pilotage — vue CARTES */
.pil-cardsec { background: #fff; border: 1px solid var(--pil-line); border-left: 5px solid var(--acc, var(--pil-line)); border-radius: 14px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); margin-bottom: 18px; padding-bottom: 6px; overflow: hidden; }
.pil-cardsec-head { display: flex; align-items: center; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--pil-line); background: var(--accbg, var(--pil-card2)); }
.pil-cardsec-sub { padding: 10px 18px 4px; font-size: 12.5px; color: var(--pil-ink2); }
.pil-cardsec-sub b { color: var(--pil-ink); }
.pil-card { border-bottom: 1px solid var(--pil-line2); margin: 0 12px; }
.pil-card:last-of-type { border-bottom: 0; }
.pil-card-head { display: flex; align-items: center; gap: 14px; padding: 11px 6px; cursor: pointer; list-style: none; }
.pil-card-head::-webkit-details-marker { display: none; }
.pil-card-head::before { content: "▸"; color: var(--pil-ink3); font-size: 11px; transition: transform .15s; flex: 0 0 auto; }
details.pil-card[open] > .pil-card-head::before { transform: rotate(90deg); }
.pil-card-title { font-weight: 500; flex: 1; min-width: 0; }
.pil-card-kpi { font-size: 12.5px; color: var(--pil-ink2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.pil-card-kpi .k { color: var(--pil-ink3); font-size: 11px; text-transform: uppercase; letter-spacing: .03em; margin-right: 3px; }
.pil-card-marge { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pil-card-body { padding: 4px 6px 12px 22px; display: flex; flex-direction: column; gap: 6px; }
/* Bouton « ＋ Ajouter » dans une carte : compact, aligné à gauche (sinon le
   flex-column l'étire sur toute la largeur). */
.pil-card-body .pil-add { align-self: flex-start; font-size: 12px; }
.pil-cdep, .pil-cftm, .pil-ccout { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pil-cdep-lot { min-width: 150px; color: var(--pil-ink2); }
/* Ligne dépense carte : N° (compact) + commentaire (extensible pousse montant/
   statut à droite). Ordre partout : entité / N° / commentaire / montant / statut. */
.pil-cdep-num { display: inline-flex; align-items: center; gap: 4px; }
.pil-cdep-cmt { display: inline-flex; align-items: center; gap: 4px; flex: 1; min-width: 160px; }
.pil-cdep-cmt .pil-cmt { flex: 1; }
.pil-ccout .pil-cmt { flex: 1; }
.pil-vendu { font-size: 12px; color: var(--pil-ink3); display: inline-flex; align-items: center; gap: 4px; }
.pil-card.alerte > .pil-card-head { background: #fcf4f4; }

/* Vue « Par entreprise » : sélecteur de lot inline + ligne d'ajout (affecte
   une nouvelle dépense à une entreprise + un lot). */
.pil-dep-arrow { color: var(--pil-ink3); margin-right: 2px; }
.pil-lotsel { min-width: 150px; -webkit-appearance: menulist; appearance: menulist; cursor: pointer; }
.pil-addent { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 2px 0; }
.pil-addent .pil-ent { min-width: 180px; }
.pil-addent .pil-lotsel { min-width: 170px; }

/* ============================================================
   FTM — Fiches de Travaux Modificatifs (phase Travaux, bloc 3).
   Mini-chiffrage isolé d'un avenant. Identité teal (dito brique
   FTM du Pilotage). Scopé sous .ftm-page / .ftm-editor.
   ============================================================ */
.ftm-page {
    --ftm-acc: #0e93a3;
    --ftm-acc-2: #0b7d8a;
    --ftm-accbg: #e3f5f7;
    --ftm-line: #e2e7f1;
    --ftm-line2: #eef1f7;
    --ftm-ink: #182034;
    --ftm-ink2: #5b6580;
    --ftm-ink3: #94a0b8;
    --ftm-card2: #f7f9fc;
}

/* ---- Liste des FTM ---- */
.ftm-list { max-width: 1080px; margin: 0 auto; }
.ftm-list-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin: 20px 0 22px; }
.ftm-list-title { font-size: 20px; font-weight: 700; color: var(--ftm-ink); margin: 0 0 4px; letter-spacing: -.3px; }
.ftm-list-sub { font-size: 13px; color: var(--ftm-ink2); margin: 0; max-width: 560px; line-height: 1.5; }
.ftm-create-form { flex: 0 0 auto; }

.ftm-btn-primary { display: inline-flex; align-items: center; gap: 8px; background: var(--ftm-acc); color: #fff; border: 0; border-radius: 10px; padding: 10px 16px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 1px 2px rgba(20,27,46,.08), 0 4px 14px rgba(14,147,163,.22); transition: background .12s; }
.ftm-btn-primary:hover { background: var(--ftm-acc-2); }
.ftm-btn-plus { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: rgba(255,255,255,.22); font-size: 15px; line-height: 1; }

.ftm-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 15px; }
.ftm-card { position: relative; background: #fff; border: 1px solid var(--ftm-line); border-left: 5px solid var(--ftm-acc); border-radius: 13px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); overflow: hidden; transition: box-shadow .12s, transform .12s; }
.ftm-card:hover { box-shadow: 0 2px 4px rgba(20,27,46,.08), 0 8px 24px rgba(20,27,46,.10); transform: translateY(-1px); }
.ftm-card-main { display: block; padding: 15px 16px 16px; text-decoration: none; color: inherit; }
.ftm-card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.ftm-card-num { font-size: 13px; font-weight: 700; color: var(--ftm-acc-2); letter-spacing: .01em; }
.ftm-card-libelle { font-size: 15px; font-weight: 600; color: var(--ftm-ink); margin-bottom: 14px; line-height: 1.35; min-height: 20px; }
.ftm-card-total { display: flex; align-items: baseline; justify-content: space-between; border-top: 1px solid var(--ftm-line2); padding-top: 10px; }
.ftm-card-total .lbl { font-size: 11.5px; color: var(--ftm-ink3); }
.ftm-card-total .val { font-size: 17px; font-weight: 700; color: var(--ftm-ink); font-variant-numeric: tabular-nums; }
.ftm-card-del { position: absolute; top: 10px; right: 10px; }
.ftm-card-del button { background: transparent; border: 0; cursor: pointer; font-size: 14px; opacity: .35; padding: 4px; border-radius: 6px; transition: opacity .12s, background .12s; }
.ftm-card-del button:hover { opacity: 1; background: var(--danger-bg); }

/* Badge statut */
.ftm-badge { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 3px 8px; border-radius: 20px; white-space: nowrap; }
.ftm-badge--brouillon { background: #eef1f7; color: #6b7690; }
.ftm-badge--valide { background: #e2f5ea; color: #1f8a4c; }

/* État vide */
.ftm-empty { text-align: center; padding: 56px 20px; background: #fff; border: 1px dashed var(--ftm-line); border-radius: 14px; color: var(--ftm-ink2); }
.ftm-empty-ico { font-size: 34px; margin-bottom: 10px; }
.ftm-empty-title { font-size: 16px; font-weight: 600; color: var(--ftm-ink); margin: 0 0 5px; }
.ftm-empty-sub { font-size: 13px; margin: 0 auto; max-width: 420px; line-height: 1.5; }

/* ---- Éditeur d'une FTM ---- */
.ftm-editor { max-width: 1180px; margin: 0 auto; }
.ftm-ed-head { margin: 18px 0 14px; }
.ftm-back { display: inline-block; font-size: 12.5px; color: var(--ftm-ink2); text-decoration: none; margin-bottom: 10px; }
.ftm-back:hover { color: var(--ftm-acc-2); }
.ftm-ed-titlerow { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.ftm-ed-num { font-size: 20px; font-weight: 700; color: var(--ftm-ink); letter-spacing: -.3px; }
.ftm-ed-libelle { width: 100%; max-width: 640px; font-size: 15px; padding: 9px 13px; border: 1px solid var(--ftm-line); border-radius: 9px; color: var(--ftm-ink); background: #fff; }
.ftm-ed-libelle:focus { outline: none; border-color: var(--ftm-acc); box-shadow: 0 0 0 3px rgba(14,147,163,.14); }

/* Bandeau de totaux */
.ftm-ed-totals { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 0 0 20px; }
.ftm-tot { background: #fff; border: 1px solid var(--ftm-line); border-radius: 12px; padding: 12px 15px; }
.ftm-tot .l { display: block; font-size: 11.5px; color: var(--ftm-ink2); margin-bottom: 5px; }
.ftm-tot .v { font-size: 19px; font-weight: 700; color: var(--ftm-ink); font-variant-numeric: tabular-nums; letter-spacing: -.4px; }
.ftm-tot--hl { background: var(--ftm-accbg); border-color: transparent; }
.ftm-tot--hl .l, .ftm-tot--hl .v { color: var(--ftm-acc-2); }

/* Tuiles */
.ftm-tuile { background: #fff; border: 1px solid var(--ftm-line); border-radius: 14px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); padding: 16px 18px 18px; margin-bottom: 18px; }
.ftm-tuile-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.ftm-tuile-head h3 { font-size: 15px; font-weight: 700; color: var(--ftm-ink); margin: 0; display: flex; align-items: center; gap: 9px; }
.ftm-tuile-head h3::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--ftm-acc); }
.ftm-tuile-hint { font-size: 12px; color: var(--ftm-ink3); }
.ftm-tuile-empty { font-size: 13px; color: var(--ftm-ink3); font-style: italic; padding: 10px 2px; margin: 0; }
.ftm-warn { font-size: 12.5px; color: #9a6a00; background: #fbf3e0; border: 1px solid #f0e0bb; border-radius: 9px; padding: 9px 13px; margin: 0 0 14px; }

/* Lot FTM */
.ftm-lot { border: 1px solid var(--ftm-line); border-radius: 11px; margin-bottom: 14px; overflow: hidden; }
.ftm-lot-head { display: flex; align-items: center; gap: 12px; background: var(--ftm-card2); padding: 9px 13px; border-bottom: 1px solid var(--ftm-line); }
.ftm-lot-nom { font-size: 13.5px; font-weight: 700; color: var(--ftm-ink); flex: 1 1 auto; }
.ftm-lot-total { font-size: 13.5px; font-weight: 700; color: var(--ftm-acc-2); font-variant-numeric: tabular-nums; }
.ftm-lot-del { background: transparent; border: 0; cursor: pointer; font-size: 13px; opacity: .4; padding: 3px 5px; border-radius: 6px; }
.ftm-lot-del:hover { opacity: 1; background: var(--danger-bg); }
.ftm-lot-tablewrap { overflow-x: auto; }

/* Table des postes */
.ftm-postes-table { width: 100%; border-collapse: collapse; }
.ftm-postes-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--ftm-ink3); font-weight: 600; text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--ftm-line); white-space: nowrap; }
.ftm-postes-table td { padding: 5px 10px; border-bottom: 1px solid var(--ftm-line2); vertical-align: middle; }
.ftm-postes-table tbody tr:last-child td { border-bottom: 0; }
.ftm-postes-table .c-pu, .ftm-postes-table th.c-pu, .ftm-postes-table .c-marge, .ftm-postes-table th.c-marge, .ftm-postes-table .c-qte, .ftm-postes-table th.c-qte, .ftm-postes-table .c-total, .ftm-postes-table th.c-total { text-align: right; }
.ftm-postes-table .c-qte { font-variant-numeric: tabular-nums; color: var(--ftm-ink2); font-size: 13px; }
.ftm-postes-table .c-total { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ftm-ink); font-size: 13.5px; white-space: nowrap; }

.ftm-postes-table input[type="text"], .ftm-postes-table select { width: 100%; border: 1px solid transparent; border-radius: 7px; padding: 6px 8px; font-size: 13px; color: var(--ftm-ink); background: transparent; }
.ftm-postes-table input[type="text"]:hover, .ftm-postes-table select:hover { border-color: var(--ftm-line); }
.ftm-postes-table input[type="text"]:focus, .ftm-postes-table select:focus { outline: none; border-color: var(--ftm-acc); background: #fff; box-shadow: 0 0 0 3px rgba(14,147,163,.12); }
.ftm-postes-table .c-desig { min-width: 200px; }
.ftm-postes-table .c-desig input { font-weight: 500; }
.ftm-postes-table .c-pu input, .ftm-postes-table .c-marge input, .ftm-postes-table .c-qte { text-align: right; }
.ftm-postes-table .c-pu { width: 100px; }
.ftm-postes-table .c-marge { width: 78px; }
.ftm-postes-table .c-unite { width: 92px; }

/* Grille de saisie qté par zone */
.ftm-zones-cell.c-zones { min-width: 220px; }
.ftm-zonegrid { display: flex; flex-wrap: wrap; gap: 6px; }
.ftm-zoneinp { display: inline-flex; flex-direction: column; gap: 2px; }
.ftm-zoneinp .z { font-size: 10px; color: var(--ftm-ink3); padding-left: 2px; max-width: 74px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ftm-zoneinp input { width: 62px; text-align: right; border: 1px solid var(--ftm-line) !important; border-radius: 6px; padding: 4px 6px; font-size: 12.5px; background: #fff; }
.ftm-zoneinp input:focus { border-color: var(--ftm-acc) !important; box-shadow: 0 0 0 2px rgba(14,147,163,.14); }
.ftm-zones-none { color: var(--ftm-ink3); }

/* Flags ±value / option */
.ftm-postes-table .c-flags { white-space: nowrap; }
.ftm-flag { border: 1px solid var(--ftm-line); background: #fff; color: var(--ftm-ink2); border-radius: 7px; padding: 4px 8px; font-size: 12px; font-weight: 600; cursor: pointer; margin-right: 3px; transition: all .1s; }
.ftm-flag:hover { border-color: var(--ftm-ink3); }
.ftm-flag.on { background: var(--ftm-acc); border-color: var(--ftm-acc); color: #fff; }
.ftm-poste-row.is-mv .c-total { color: var(--danger); }
.ftm-poste-row.is-opt { background: #fbfbf4; }
.ftm-poste-del, .ftm-hono-del { background: transparent; border: 0; cursor: pointer; font-size: 13px; opacity: .4; padding: 4px 5px; border-radius: 6px; }
.ftm-poste-del:hover, .ftm-hono-del:hover { opacity: 1; background: var(--danger-bg); }
.ftm-poste-empty td { color: var(--ftm-ink3); font-style: italic; font-size: 12.5px; }

/* Boutons fantômes (ajout) */
.ftm-btn-ghost { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 1px dashed var(--ftm-line); color: var(--ftm-acc-2); border-radius: 9px; padding: 7px 13px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all .12s; }
.ftm-btn-ghost:hover { border-color: var(--ftm-acc); background: var(--ftm-accbg); }
.ftm-addposte { margin: 10px 13px 12px; }

/* Barre d'ajout de lot */
.ftm-addlot { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; margin-top: 6px; padding-top: 14px; border-top: 1px dashed var(--ftm-line); }
.ftm-addlot-select { border: 1px solid var(--ftm-line); border-radius: 9px; padding: 8px 11px; font-size: 13px; color: var(--ftm-ink); background: #fff; min-width: 220px; }
.ftm-addlot-select:focus { outline: none; border-color: var(--ftm-acc); }
.ftm-addlot-sep { font-size: 12px; color: var(--ftm-ink3); }
.ftm-addlot-custom { border: 1px solid var(--ftm-line); border-radius: 9px; padding: 8px 11px; font-size: 13px; color: var(--ftm-ink); background: #fff; min-width: 170px; }
.ftm-addlot-custom:focus { outline: none; border-color: var(--ftm-acc); }

/* Table honoraires */
.ftm-hono-table { width: 100%; border-collapse: collapse; margin-bottom: 12px; }
.ftm-hono-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--ftm-ink3); font-weight: 600; text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--ftm-line); }
.ftm-hono-table th.ftm-th-montant { text-align: right; }
.ftm-hono-table td { padding: 5px 10px; border-bottom: 1px solid var(--ftm-line2); vertical-align: middle; }
.ftm-hono-table tbody tr:last-child td { border-bottom: 0; }
.ftm-hono-table .ftm-th-desig { min-width: 260px; }
.ftm-hono-table .ftm-th-montant { width: 150px; }
.ftm-hono-table .ftm-th-act { width: 40px; }
.ftm-hono-table input { width: 100%; border: 1px solid transparent; border-radius: 7px; padding: 6px 8px; font-size: 13px; color: var(--ftm-ink); background: transparent; }
.ftm-hono-table input:hover { border-color: var(--ftm-line); }
.ftm-hono-table input:focus { outline: none; border-color: var(--ftm-acc); background: #fff; box-shadow: 0 0 0 3px rgba(14,147,163,.12); }
.ftm-hono-table .ftm-th-montant input { text-align: right; font-variant-numeric: tabular-nums; }

@media (max-width: 720px) {
    .ftm-list-head { flex-direction: column; }
    .ftm-ed-totals { grid-template-columns: repeat(2, 1fr); }
}

/* FTM — cycle validation (bloc 3.3) : barre d'action + verrou visuel. */
.ftm-actions { display: flex; align-items: center; gap: 14px; margin: 0 0 18px; flex-wrap: wrap; }
.ftm-lockbanner { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: #1f8a4c; background: #e2f5ea; border: 1px solid #b8e6cb; border-radius: 9px; padding: 8px 13px; }
.ftm-lockbanner .ico { font-size: 14px; }
.ftm-btn-validate { background: #1f8a4c; color: #fff; border: 0; border-radius: 9px; padding: 9px 16px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 1px 2px rgba(20,27,46,.08), 0 4px 14px rgba(31,138,76,.20); transition: background .12s; }
.ftm-btn-validate:hover { background: #18733f; }
.ftm-btn-outline { background: #fff; color: var(--ftm-acc-2); border: 1px solid var(--ftm-acc); border-radius: 9px; padding: 8px 15px; font-size: 13px; font-weight: 600; cursor: pointer; transition: background .12s; }
.ftm-btn-outline:hover { background: var(--ftm-accbg); }

/* Verrou visuel d'une FTM validée : saisies figées, contrôles d'ajout masqués.
   La garde serveur (ftm_edit._editable_or_403) est la vraie barrière ; ceci
   n'est que l'indication d'interface. La barre .ftm-actions reste active. */
.ftm-editor--locked .ftm-ed-libelle,
.ftm-editor--locked .ftm-postes-table input,
.ftm-editor--locked .ftm-postes-table select,
.ftm-editor--locked .ftm-zoneinp input,
.ftm-editor--locked .ftm-hono-table input,
.ftm-editor--locked .ftm-flag { pointer-events: none; opacity: .7; background: #f7f9fc; }
.ftm-editor--locked .ftm-poste-del,
.ftm-editor--locked .ftm-lot-del,
.ftm-editor--locked .ftm-hono-del,
.ftm-editor--locked .ftm-btn-ghost,
.ftm-editor--locked .ftm-addlot { display: none; }

/* Pilotage: FTM en lecture seule (bloc 3.4) — badge validée + lien éditeur. */
.pil-badge--ok { color: #1f8a4c; font-weight: 600; }
a.pil-add.head { text-decoration: none; }
.pil-ftm-edit { display: inline-block; font-size: 12px; color: #0e93a3; text-decoration: none; margin: 2px 0 8px; }
.pil-ftm-edit:hover { text-decoration: underline; }

/* FTM — choix de trame par lot (poste/zone), dito chiffrage. */
.ftm-trame { display: inline-flex; align-items: center; gap: 9px; padding: 6px 11px; border: 1px solid var(--ftm-line); border-radius: 9px; background: var(--ftm-card2); }
.ftm-trame-lbl { font-size: 12px; color: var(--ftm-ink3); }
.ftm-trame-opt { font-size: 12.5px; color: var(--ftm-ink2); display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.ftm-trame-opt input { accent-color: var(--ftm-acc); }
.ftm-lot-trame { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--ftm-acc-2); background: var(--ftm-accbg); padding: 2px 7px; border-radius: 6px; margin-right: auto; cursor: help; }
/* Toggle de trame PAR LOT (segmented control compact) : visible quand le lot
   est encore vide. margin-right:auto -> pousse total + suppression à droite. */
.ftm-lot-trametog { display: inline-flex; gap: 2px; margin-right: auto; padding: 2px; background: var(--ftm-card2); border: 1px solid var(--ftm-line); border-radius: 7px; }
.ftm-lot-trametog label { display: inline-flex; align-items: center; font-size: 11px; font-weight: 600; color: var(--ftm-ink3); padding: 2px 9px; border-radius: 5px; cursor: pointer; transition: background .12s, color .12s; }
.ftm-lot-trametog label:hover { color: var(--ftm-ink); }
.ftm-lot-trametog input { position: absolute; opacity: 0; pointer-events: none; }
.ftm-lot-trametog label:has(input:checked) { background: var(--ftm-acc); color: #fff; }
.ftm-zonegroup { border-top: 1px solid var(--ftm-line); }
.ftm-zonegroup-head { font-size: 12px; font-weight: 700; color: var(--ftm-ink2); background: #fafbfd; padding: 7px 13px; }
.ftm-postes-table .c-qte1, .ftm-postes-table th.c-qte1 { width: 120px; text-align: right; }
.ftm-postes-table .c-qte1 input { text-align: right; border: 1px solid var(--ftm-line) !important; border-radius: 6px; background: #fff; }
.ftm-postes-table .c-qte1 input:focus { border-color: var(--ftm-acc) !important; box-shadow: 0 0 0 2px rgba(14,147,163,.14); }

/* ============================================================
   SITUATIONS — facturation à l'avancement (phase Travaux, bloc 4).
   Onglet + panneau « Paramètres du marché » (RG déplacée, acompte, paliers).
   ============================================================ */
.situations-page {
    --situ-acc: #5b57d6;
    --situ-acc-2: #4a46b8;
    --situ-accbg: #edecfb;
    --situ-line: #e2e7f1;
    --situ-line2: #eef1f7;
    --situ-ink: #182034;
    --situ-ink2: #5b6580;
    --situ-ink3: #94a0b8;
    --situ-card2: #f7f9fc;
}
/* 2 colonnes : à GAUCHE la liste des situations (cartes empilées à la
   verticale), à DROITE les paramètres du marché (RG, acompte, paliers).
   Sous 900px -> 1 colonne (cf. demande 2026-07-21). */
.situ-layout { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 24px; align-items: start; }
.situ-layout > #modal-container { grid-column: 1 / -1; }
@media (max-width: 900px) { .situ-layout { grid-template-columns: 1fr; } }

/* Liste des situations (placeholder 4.1 -> saisie en 4.2) */
.situ-list-head { margin: 20px 0 14px; }
.situ-list-title { font-size: 20px; font-weight: 700; color: var(--situ-ink); margin: 0 0 4px; letter-spacing: -.3px; }
.situ-list-sub { font-size: 13px; color: var(--situ-ink2); margin: 0; max-width: 620px; line-height: 1.5; }
.situ-empty { text-align: center; padding: 40px 20px; background: #fff; border: 1px dashed var(--situ-line); border-radius: 14px; color: var(--situ-ink2); margin-bottom: 26px; }
.situ-empty-ico { font-size: 30px; margin-bottom: 8px; }
.situ-empty-title { font-size: 15px; font-weight: 600; color: var(--situ-ink); margin: 0 0 4px; }
.situ-empty-sub { font-size: 12.5px; margin: 0; }

/* Panneau Paramètres du marché */
.situ-params { display: block; }
/* Espace sous l'encart Retenue de garantie (sinon collé à « Acompte »). */
#situations-params .retenue-rg-block { margin-bottom: 16px; }
.situ-params-title { font-size: 16px; font-weight: 700; color: var(--situ-ink); margin: 0 0 14px; display: flex; align-items: center; gap: 9px; }
.situ-params-title::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--situ-acc); }

.situ-tuile { background: #fff; border: 1px solid var(--situ-line); border-radius: 14px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); padding: 16px 18px 18px; margin-bottom: 16px; }
.situ-tuile-title { font-size: 14.5px; font-weight: 700; color: var(--situ-ink); margin: 0 0 4px; }
.situ-tuile-hint { font-size: 12px; color: var(--situ-ink3); margin: 0 0 12px; line-height: 1.45; }
.situ-tuile-empty { font-size: 13px; color: var(--situ-ink3); font-style: italic; margin: 0 0 12px; }

/* Acompte */
.situ-check { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 600; color: var(--situ-ink); cursor: pointer; }
.situ-check input { accent-color: var(--situ-acc); width: 16px; height: 16px; }
.situ-acompte-sub { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; transition: opacity .12s; }
.situ-acompte-sub.is-disabled { opacity: .45; pointer-events: none; }
.situ-field-row { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-end; }
.situ-field { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--situ-ink2); }
.situ-num { width: 78px; text-align: right; border: 1px solid var(--situ-line); border-radius: 8px; padding: 6px 9px; font-size: 13px; color: var(--situ-ink); font-variant-numeric: tabular-nums; }
.situ-num:focus { outline: none; border-color: var(--situ-acc); box-shadow: 0 0 0 3px rgba(91,87,214,.14); }
.situ-select { border: 1px solid var(--situ-line); border-radius: 8px; padding: 6px 9px; font-size: 13px; color: var(--situ-ink); background: #fff; }
.situ-select:focus { outline: none; border-color: var(--situ-acc); }
.situ-field .suffix { color: var(--situ-ink3); font-size: 12.5px; }

/* Paliers */
.situ-paliers-table { width: 100%; border-collapse: collapse; margin-bottom: 12px; }
.situ-paliers-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--situ-ink3); font-weight: 600; text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--situ-line); }
.situ-paliers-table th.num { text-align: right; }
.situ-paliers-table td { padding: 5px 8px; border-bottom: 1px solid var(--situ-line2); vertical-align: middle; }
.situ-paliers-table td.num { text-align: right; }
.situ-paliers-table tbody tr:last-child td { border-bottom: 0; }
.situ-palier-lib { width: 100%; border: 1px solid transparent; border-radius: 7px; padding: 6px 8px; font-size: 13px; color: var(--situ-ink); background: transparent; }
.situ-palier-lib:hover { border-color: var(--situ-line); }
.situ-palier-lib:focus { outline: none; border-color: var(--situ-acc); background: #fff; box-shadow: 0 0 0 3px rgba(91,87,214,.12); }
.situ-del { background: transparent; border: 0; cursor: pointer; font-size: 13px; opacity: .4; padding: 4px 5px; border-radius: 6px; }
.situ-del:hover { opacity: 1; background: var(--danger-bg); }
.situ-palier-add { display: flex; align-items: center; gap: 9px; padding-top: 12px; border-top: 1px dashed var(--situ-line); }
.situ-palier-add .situ-palier-lib { flex: 1 1 auto; border: 1px solid var(--situ-line); background: #fff; }
.situ-btn-ghost { background: transparent; border: 1px dashed var(--situ-line); color: var(--situ-acc-2); border-radius: 9px; padding: 7px 13px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: all .12s; }
.situ-btn-ghost:hover { border-color: var(--situ-acc); background: var(--situ-accbg); }

/* SITUATIONS — liste + éditeur d'avancement (bloc 4.2). */
.situ-list-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 14px; margin: 20px 0 16px; }
.situ-create-form { flex: 0 0 auto; }
.situ-btn-primary { display: inline-flex; align-items: center; gap: 8px; background: var(--situ-acc); color: #fff; border: 0; border-radius: 10px; padding: 10px 16px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 1px 2px rgba(20,27,46,.08), 0 4px 14px rgba(91,87,214,.22); transition: background .12s; }
.situ-btn-primary:hover { background: var(--situ-acc-2); }
.situ-btn-plus { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: rgba(255,255,255,.22); font-size: 15px; line-height: 1; }

.situ-cards { display: flex; flex-direction: column; gap: 12px; margin-bottom: 0; }
.situ-card { position: relative; background: #fff; border: 1px solid var(--situ-line); border-left: 5px solid var(--situ-acc); border-radius: 13px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); overflow: hidden; transition: box-shadow .12s, transform .12s; }
.situ-card:hover { box-shadow: 0 2px 4px rgba(20,27,46,.08), 0 8px 24px rgba(20,27,46,.10); transform: translateY(-1px); }
.situ-card-main { display: block; padding: 14px 16px 15px; text-decoration: none; color: inherit; }
/* padding-right : réserve la place du bouton corbeille (absolu, en haut à
   droite) pour que le badge « Validée » / « Brouillon » ne passe plus dessous. */
.situ-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; padding-right: 26px; }
.situ-card-num { font-size: 13px; font-weight: 700; color: var(--situ-acc-2); }
.situ-card-date { font-size: 12.5px; color: var(--situ-ink2); }
.situ-card-del { position: absolute; top: 9px; right: 9px; }
.situ-card-del button { background: transparent; border: 0; cursor: pointer; font-size: 13px; opacity: .35; padding: 4px; border-radius: 6px; transition: opacity .12s, background .12s; }
.situ-card-del button:hover { opacity: 1; background: var(--danger-bg); }
.situ-badge { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 3px 8px; border-radius: 20px; background: #eef1f7; color: #6b7690; white-space: nowrap; }
.situ-badge--valide { background: #e2f5ea; color: #1f8a4c; }

/* Éditeur */
.situ-editor { max-width: 1080px; margin: 0 auto; }
.situ-ed-head { margin: 18px 0 14px; }
.situ-back { display: inline-block; font-size: 12.5px; color: var(--situ-ink2); text-decoration: none; margin-bottom: 10px; }
.situ-back:hover { color: var(--situ-acc-2); }
.situ-ed-titlerow { display: flex; align-items: center; gap: 12px; }
.situ-ed-num { font-size: 20px; font-weight: 700; color: var(--situ-ink); letter-spacing: -.3px; }
.situ-ed-date { font-size: 13px; color: var(--situ-ink2); }
.situ-ed-totals { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 14px 0 20px; }
.situ-tot { background: #fff; border: 1px solid var(--situ-line); border-radius: 12px; padding: 12px 15px; }
.situ-tot .l { display: block; font-size: 11.5px; color: var(--situ-ink2); margin-bottom: 5px; }
.situ-tot .v { font-size: 18px; font-weight: 700; color: var(--situ-ink); font-variant-numeric: tabular-nums; letter-spacing: -.4px; }
.situ-tot--hl { background: var(--situ-accbg); border-color: transparent; }
.situ-tot--hl .l, .situ-tot--hl .v { color: var(--situ-acc-2); }

.situ-lot { border: 1px solid var(--situ-line); border-radius: 11px; margin-bottom: 14px; overflow: hidden; }
.situ-lot-head { display: flex; align-items: center; gap: 12px; background: var(--situ-card2); padding: 9px 13px; border-bottom: 1px solid var(--situ-line); flex-wrap: wrap; }
.situ-lot-nom { font-size: 13.5px; font-weight: 700; color: var(--situ-ink); flex: 1 1 auto; }
.situ-lot-pct { font-size: 13px; font-weight: 700; color: var(--situ-acc-2); font-variant-numeric: tabular-nums; }
.situ-lot-montant { font-size: 12.5px; color: var(--situ-ink2); font-variant-numeric: tabular-nums; }
.situ-lot-montant .sur { color: var(--situ-ink3); }
.situ-lot-apply { display: inline-flex; align-items: center; gap: 5px; }
.situ-num-sm { width: 58px; padding: 5px 7px; }
.situ-btn-mini { background: #fff; border: 1px solid var(--situ-acc); color: var(--situ-acc-2); border-radius: 7px; padding: 5px 9px; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.situ-btn-mini:hover { background: var(--situ-accbg); }
.situ-lot-tablewrap { overflow-x: auto; }
.situ-postes-table { width: 100%; border-collapse: collapse; }
.situ-postes-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--situ-ink3); font-weight: 600; text-align: left; padding: 7px 12px; border-bottom: 1px solid var(--situ-line); white-space: nowrap; }
.situ-postes-table td { padding: 5px 12px; border-bottom: 1px solid var(--situ-line2); vertical-align: middle; font-size: 13px; }
.situ-postes-table tbody tr:last-child td { border-bottom: 0; }
.situ-postes-table .c-desig { min-width: 220px; color: var(--situ-ink); }
.situ-postes-table .c-tot, .situ-postes-table th.c-tot, .situ-postes-table .c-mont, .situ-postes-table th.c-mont, .situ-postes-table .c-pct, .situ-postes-table th.c-pct { text-align: right; }
.situ-postes-table .c-tot, .situ-postes-table .c-mont { font-variant-numeric: tabular-nums; white-space: nowrap; }
.situ-postes-table .c-mont { font-weight: 600; color: var(--situ-ink); }
.situ-postes-table .c-pct { width: 92px; }
.situ-postes-table .c-pct .situ-num { width: 100%; text-align: right; }

/* SITUATIONS — certificat de paiement (bloc 4.3). */
.situ-cert { background: #fff; border: 1px solid var(--situ-line); border-left: 5px solid var(--situ-acc); border-radius: 14px; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); padding: 16px 18px 18px; margin-bottom: 20px; }
.situ-cert-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; }
.situ-cert-title { font-size: 15px; font-weight: 700; color: var(--situ-ink); margin: 0; }
.situ-cert-sub { font-size: 12px; color: var(--situ-ink3); }
.situ-cert-wrap { overflow-x: auto; }
.situ-cert-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.situ-cert-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--situ-ink3); font-weight: 600; padding: 8px 12px; border-bottom: 1px solid var(--situ-line); text-align: right; white-space: nowrap; }
.situ-cert-table th.l { text-align: left; }
.situ-cert-table td { padding: 7px 12px; border-bottom: 1px solid var(--situ-line2); font-size: 13.5px; text-align: right; color: var(--situ-ink); white-space: nowrap; }
.situ-cert-table td.l { text-align: left; color: var(--situ-ink); }
.situ-cert-table td.l .mut { color: var(--situ-ink3); font-size: 11.5px; font-weight: 400; }
.situ-cert-ded td { color: var(--situ-ink2); }
.situ-cert-ded td.num { color: var(--danger); }
.situ-cert-net td { border-top: 2px solid var(--situ-line); border-bottom: 0; font-weight: 800; font-size: 15px; color: var(--situ-acc-2); padding-top: 10px; }

/* SITUATIONS — paliers bloquants + déverrouillage (bloc 4.4). */
.situ-paliers-table .c-lock { text-align: center; white-space: nowrap; }
.situ-lock { background: #fbf3e0; border: 1px solid #f0e0bb; color: #9a6a00; border-radius: 7px; padding: 4px 9px; font-size: 11.5px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: all .12s; }
.situ-lock:hover { border-color: #d9b04e; }
.situ-lock.on { background: #e2f5ea; border-color: #b8e6cb; color: #1f8a4c; }
.situ-plafond { font-size: 12.5px; color: #9a6a00; background: #fbf3e0; border: 1px solid #f0e0bb; border-radius: 9px; padding: 9px 13px; margin: 0 0 14px; }
.situ-plafond a { color: var(--situ-acc-2); font-weight: 600; }

/* SITUATIONS — cycle validation / gel (bloc 4.5). */
.situ-ed-actions { display: flex; align-items: center; gap: 14px; margin: 12px 0 18px; flex-wrap: wrap; }
.situ-frozen { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: #1f8a4c; background: #e2f5ea; border: 1px solid #b8e6cb; border-radius: 9px; padding: 8px 13px; }
.situ-frozen-note { font-size: 12.5px; color: var(--situ-ink3); }
.situ-btn-validate { background: #1f8a4c; color: #fff; border: 0; border-radius: 9px; padding: 9px 16px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 1px 2px rgba(20,27,46,.08), 0 4px 14px rgba(31,138,76,.20); transition: background .12s; }
.situ-btn-validate:hover { background: #18733f; }
.situ-btn-outline { display: inline-flex; align-items: center; gap: 8px; background: #fff; color: var(--situ-acc-2); border: 1px solid var(--situ-acc); border-radius: 10px; padding: 9px 15px; font-size: 14px; font-weight: 600; cursor: pointer; transition: background .12s; }
.situ-btn-outline:hover { background: var(--situ-accbg); }
.situ-btn-outline .situ-btn-plus { background: var(--situ-accbg); color: var(--situ-acc-2); }

/* ===== Onglet Situations : 2 panneaux distincts (demande 2026-07-21) ===== */
/* GAUCHE « Situations » / DROITE « Paramètres du marché », chacun dans un
   cadre teinté avec ses items (cartes / tuiles) blancs par-dessus. */
.situ-panel,
.situ-layout > #situations-params {
  background: var(--situ-card2);
  border: 1px solid var(--situ-line);
  border-radius: 16px;
  padding: 20px;
}
.situ-panel .situ-list-head { margin: 0 0 16px; }
.situ-layout > #situations-params .situ-params-title { margin-top: 0; }
.situ-layout > #situations-params > *:last-child { margin-bottom: 0; }
/* Boutons « + Acompte » / « + Nouvelle situation » : même largeur, empilés,
   pleine largeur du panneau (≈278px). */
.situ-head-actions { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.situ-head-actions form { width: 100%; }
.situ-head-actions .situ-btn-primary,
.situ-head-actions .situ-btn-outline { width: 100%; justify-content: center; }
/* Acompte verrouillé (des situations existent) : cadenas non cliquable à la
   place de la corbeille, aligné comme elle. */
.situ-card-lock { position: absolute; top: 9px; right: 9px; padding: 4px; color: var(--situ-ink3); opacity: .8; cursor: not-allowed; display: inline-flex; }
/* Montant HT de l'acompte (tuile Paramètres) : récap sous les seuils. */
.situ-acompte-total { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--situ-line); display: flex; flex-direction: column; gap: 2px; }
.situ-acompte-total-lbl { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--situ-ink3); }
.situ-acompte-total-val { font-size: 18px; font-weight: 800; color: var(--situ-ink); letter-spacing: -.3px; }
.situ-acompte-total-note { font-size: 11.5px; color: var(--situ-ink3); }

/* Carte « Acompte » en tête de liste : accent ambre pour la distinguer des
   situations (mauve), montant mis en avant. Non cliquable (pas de hover). */
.situ-card--acompte { border-left-color: #d79a2c; cursor: default; }
.situ-card--acompte:hover { transform: none; box-shadow: 0 1px 2px rgba(20,27,46,.05), 0 4px 16px rgba(20,27,46,.05); }
.situ-badge--acompte { background: #fbeecf; color: #a26c14; }
.situ-card-montant { font-size: 17px; font-weight: 800; color: var(--situ-ink); letter-spacing: -.3px; margin-bottom: 3px; }
/* Verrou visuel d'une situation validée : saisies figées (garde serveur en plus). */
.situ-editor--locked .situ-num,
.situ-editor--locked .situ-btn-mini,
.situ-editor--locked .situ-lot-apply { pointer-events: none; opacity: .6; }

/* =========================================================================
   Consultations — œil « détail du chiffrage » + groupes de DPGF
   ========================================================================= */

/* Utilitaire a11y : texte lu par les lecteurs d'écran, invisible à l'œil.
   Sert aux en-têtes de colonne purement décoratifs (colonne d'icônes). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* =========================================================================
   Legende HTML des diagrammes (Analytique)
   -------------------------------------------------------------------------
   Chart.js dessine sa legende DANS le canvas : avec ~15 lots elle depassait
   du carre et se faisait couper net. On la rend donc en HTML sous le canvas
   (cf. renderLegend dans projet_analytique.html) : le texte s'enroule, la
   carte grandit, plus rien n'est tronque. html2canvas la capture aussi, donc
   les boutons Copier / PNG restent complets.
   ========================================================================= */

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2px 16px;
  width: 100%;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}
.chart-legend-item {
  display: inline-flex;
  align-items: flex-start;
  gap: 7px;
  max-width: 100%;
  padding: 3px 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: 12px;
  line-height: 1.35;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.chart-legend-swatch {
  width: 12px;
  height: 12px;
  margin-top: 2px;
  border-radius: 3px;
  flex-shrink: 0;
}
/* Le libelle peut s'enrouler sur plusieurs lignes : c'est tout l'interet. */
.chart-legend-label { min-width: 0; }
.chart-legend-item:hover .chart-legend-label { text-decoration: underline; }
.chart-legend-item:focus-visible {
  outline: 2px solid var(--accent, #3b6ef5);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Part masquee (clic sur la legende) : meme convention que Chart.js. */
.chart-legend-item.is-hidden { opacity: 0.45; }
.chart-legend-item.is-hidden .chart-legend-label { text-decoration: line-through; }
