/* 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;
}

.sidebar {
  background: var(--sidebar-bg);
  color: #fff;
  padding: 24px 0;
  display: flex;
  flex-direction: column;
}

/* 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 */
  padding: 4px 22px 22px;
  border-bottom: 1px solid var(--sidebar-bg-2);
  text-decoration: none;
  user-select: none;
}
.sidebar .brand:hover { text-decoration: none; }
.sidebar .brand:hover .brand-mark {
  filter: brightness(1.1);
  transform: translateY(-1px);
}

/* Le "Q" : grosse lettre avec gradient bleu->cyan en text-clip. Tilt
   leger pour donner du mouvement. */
.sidebar .brand-mark {
  font-family: "Helvetica Neue", "Inter", -apple-system, sans-serif;
  font-weight: 800;
  font-size: 34px;
  line-height: 1;
  background: linear-gradient(135deg, #5dade2 0%, #3b6ef5 60%, #2d5dd4 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;           /* fallback non-webkit */
  letter-spacing: -0.04em;      /* serre, comme un logotype */
  transition: filter 0.2s, transform 0.2s;
  display: inline-block;
}

/* "uanto" : suit immediatement le Q, weight regular, blanc casse.
   Letter-spacing legerement aere pour respirer apres le Q tres serre. */
.sidebar .brand-name {
  font-family: "Helvetica Neue", "Inter", -apple-system, sans-serif;
  font-weight: 500;
  font-size: 22px;
  letter-spacing: 0.02em;
  color: #eef2ff;
  line-height: 1;
}

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

/* Nav "bullet list" : puce carrée + libellé, item actif en pastille pleine.
   Les liens sont en flex pour aligner la puce (.nav-ico) et le texte. */
.sidebar nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  margin-bottom: 2px;
  border-radius: 8px;
  color: #a0aec0;
  font-size: 14px;
  transition: background 0.12s, color 0.12s;
}

/* Puce carrée arrondie : prend la couleur courante du lien, attenuee
   quand inactif, pleine quand actif/hover. */
.sidebar nav a .nav-ico {
  width: 9px;
  height: 9px;
  border-radius: 2.5px;
  background: currentColor;
  opacity: 0.4;
  flex-shrink: 0;
  transition: opacity 0.12s;
}

.sidebar nav a:hover {
  background: var(--sidebar-bg-2);
  color: #fff;
  text-decoration: none;
}
.sidebar nav a:hover .nav-ico { opacity: 0.7; }

/* Item actif : pastille bleue pleine (accent), texte + puce blancs. */
.sidebar nav a.active {
  background: var(--blue);
  color: #fff;
  text-decoration: none;
}
.sidebar nav a.active .nav-ico { opacity: 1; }
.sidebar nav a.active:hover { background: var(--blue-2); }

/* 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 var(--sidebar-bg-2);
  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 var(--sidebar-bg-2);
}
.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 var(--sidebar-bg);
  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: 8px;
}
.projet-tabs-bar .ptab {
  padding: 0 28px;
  display: flex;
  align-items: center;
  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 14px;
  border-radius: 1px;
}

.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;
  padding: 8px 12px 8px 20px;   /* +left pour laisser place au liseré de statut (10px) */
  border-bottom: 1px solid #f3f4f7;
  position: relative;
  transition: background 0.12s;
}
/* Liseré de statut à gauche (10px) : SEUL indicateur d'état (refonte 2026-05-26,
   remplace les fonds colorés + texte rouge). Couleur posée par .status-* ci-dessous. */
.lot-item-wrapper::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 10px;
  background: #e6e8ee;          /* neutre par défaut */
}
.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 { filter: brightness(0.95); }
.lot-toggle:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* 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: #e04444; }   /* rouge */
.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;
}

.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; }

/* ----- 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:
    52px                 /* col-numero : élargie pour loger N° + poignée ⋮⋮ + 🗑 */
    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 */
  min-width: 1720px;     /* ref-devis fixe 120 (au lieu de min 16) -> +104 sur le min-width */
  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 { border-color: #b9c2d6; }
.q3chip.active.c { background: #ece7ff; color: #5a48b0; border-color: #cdbcff; }
.q3chip.active.e { background: #d8f5ef; color: #1b8b7f; border-color: #a6e6da; }
.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. */
.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 */
.cell.col-numero { position: relative; }
.poste-numero { display: block; white-space: nowrap; }
.poste-delete {
  display: none;
  background: transparent;
  border: 1px solid transparent;
  color: var(--danger);
  cursor: pointer;
  font-size: 12px;
  padding: 0 4px;
  border-radius: 3px;
}
.poste-delete:hover {
  background: var(--danger-bg);
  border-color: rgba(214, 69, 69, 0.3);
}
.row-poste:hover .poste-numero,
.row-option:hover .poste-numero { display: none; }
.row-poste:hover .poste-delete,
.row-option:hover .poste-delete { display: inline-block; }

/* 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; }
.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; }
/* 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;
}
.analytique-resume-6 { grid-template-columns: repeat(6, 1fr); }
.analytique-resume-4 { grid-template-columns: repeat(4, 1fr); }
.analytique-resume-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1100px) {
  .analytique-resume-6 { grid-template-columns: repeat(3, 1fr); }
  .analytique-resume-4 { grid-template-columns: repeat(2, 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;
}
.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;
}

/* =============================================================================
   Onglet Consultations : reporting entreprises consultees par lot et par
   entreprise. Layout cards (vs table classique) pour une lecture plus
   aeree, avec stats globales en haut, badges de completude par lot,
   avatars par entreprise.
   ============================================================================= */

/* Cards de stats en haut de page (similaire au dashboard mais inline). */
.consultations-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}
.consultations-stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 18px;
}
.consultations-stat-card--warn {
  background: #fef3cd;
  border-color: #f1d574;
}
.consultations-stat-card--warn .consultations-stat-value { color: #8a6814; }
.consultations-stat-card--highlight {
  background: linear-gradient(135deg, #f0f4ff 0%, #e7eeff 100%);
  border-color: #c7d4f0;
}
.consultations-stat-card--highlight .consultations-stat-value { color: #2d5dd4; }
.consultations-stat-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}
.consultations-stat-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.consultations-stat-sub {
  font-size: 14px;
  color: var(--muted);
  font-weight: 500;
}

/* Encart d'alerte "lots a completer" : visible et oriente action. */
.consultations-alert {
  background: #fef3cd;
  border: 1px solid #f1d574;
  border-left: 4px solid #c9a227;
  border-radius: 6px;
  padding: 14px 18px;
  font-size: 13px;
  color: #6e5610;
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.consultations-alert strong { font-weight: 700; color: #4a3a0a; }
.consultations-alert-icon { font-size: 22px; line-height: 1; flex-shrink: 0; }
.consultations-alert-detail { margin-top: 4px; }
.consultations-alert-chip {
  display: inline-block;
  background: rgba(201, 162, 39, 0.15);
  border: 1px solid rgba(201, 162, 39, 0.3);
  color: #4a3a0a;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  margin: 2px 4px 2px 0;
  white-space: nowrap;
}

/* Cards : conteneur grille des lots et des entreprises. minmax(340px)
   pour la section "Vue par entreprise" qui a desormais les boutons DPGF
   a droite de la liste (compact), donc on peut serrer un peu plus que
   l'ancien 380px afin d'avoir + de cards par ligne. */
.consultations-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 14px;
}

/* Card lot. */
.consultations-lot-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 18px;
}
.consultations-lot-card--empty {
  background: #fff8e1;
  border-color: #f1d574;
}
.consultations-lot-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.consultations-lot-card--empty .consultations-lot-head {
  border-bottom-color: #f1d574;
}
.consultations-lot-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.consultations-lot-num {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 24px;
}
.consultations-lot-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Badge de statut completude d'un lot. */
.consultations-status-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.consultations-status-badge--ok {
  background: #d4edda;
  color: #155724;
}
.consultations-status-badge--partial {
  background: #e8f0fe;
  color: #2d5dd4;
}
.consultations-status-badge--warn {
  background: #f8d7da;
  color: #721c24;
}

/* Card entreprise. */
.consultations-entreprise-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 18px;
}
.consultations-entreprise-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.consultations-entreprise-identity {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.consultations-avatar {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  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;
  user-select: none;
}
.consultations-entreprise-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}
.consultations-entreprise-meta {
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
}
.consultations-entreprise-montant {
  font-size: 18px;
  font-weight: 700;
  color: #2d5dd4;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Body de la card entreprise : layout VERTICAL -- liste des lots en pleine
   largeur (pour que les noms de lots ne wrap pas sur 2 lignes), boutons DPGF
   EN DESSOUS, separes par un filet. */
.consultations-entreprise-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Actions DPGF -- 2 boutons COMPACTS cote a cote sur une ligne, sous la liste,
   separes par un filet. Largeur naturelle (le plus compact possible), alignes
   a gauche. Icones : 📊 (Excel) / 📄 (PDF). */
.consultations-entreprise-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid #eef1f6;
}
.consultations-entreprise-actions .btn-dpgf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 8px;
  background: #fff;
  border: 1px solid var(--border, #dde1ea);
  color: #1A2340;
  border-radius: 5px;
  text-decoration: none;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  line-height: 1.2;
  white-space: nowrap;
}
.consultations-entreprise-actions .btn-dpgf:hover {
  background: #E8F0FE;
  border-color: #2d5dd4;
  color: #1D2A5B;
}
.consultations-entreprise-actions .dpgf-icon {
  font-size: 13px;
  line-height: 1;
}

/* Empty / placeholder dans une card lot. */
.consultations-empty {
  color: #b08800;
  font-style: italic;
  font-size: 13px;
  padding: 8px 0;
  margin: 0;
}

/* Chip entreprise / lot : badge inline (legacy, conserve pour reuse
   eventuel ailleurs si besoin d'un affichage compact horizontal). */
.consultations-chip {
  display: inline-block;
  padding: 3px 10px;
  margin: 2px 4px 2px 0;
  background: #e8f0fe;
  color: #2d5dd4;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.consultations-chip-lot {
  background: #f0f3f8;
  color: #2a3656;
}
.consultations-chip-count {
  margin-left: 4px;
  color: var(--muted);
  font-weight: 400;
}

/* Stack vertical des entreprises (vue par lot) et des lots (vue par
   entreprise). Permet de lire chaque valeur sur sa propre ligne avec
   le nb de postes aligne a droite. Plus lisible qu'un chip horizontal
   quand on a 3+ entrees. */
.consultations-stack {
  list-style: none;
  margin: 0;
  padding: 0;
}
.consultations-stack li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 3px 0;
  border-bottom: 1px dashed #e4e7ee;
}
.consultations-stack li:last-child { border-bottom: none; }
.consultations-stack-name {
  color: var(--text);
  font-size: 13px;
}
.consultations-stack-count {
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
/* Côté droit d'une ligne (montant achat + nb postes), aligné à droite. */
.consultations-stack-meta {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
}
.consultations-stack-montant {
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Barre "Total achat HT du lot" dans chaque carte de la vue par lot. */
.consultations-lot-montant-bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin: 4px 0 10px;
  padding: 7px 11px;
  background: #f4f7ff;
  border-radius: 6px;
}
.consultations-lot-montant-bar > span:first-child {
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .3px;
}
.consultations-lot-montant {
  font-size: 15px;
  font-weight: 800;
  color: var(--blue);
  font-variant-numeric: tabular-nums;
}

/* =============================================================================
   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); }
.resume-mode-toggle label.active {
  background: var(--surface);
  color: var(--navy);
  box-shadow: 0 1px 3px rgba(26, 35, 64, 0.06);
}
/* 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) ===== */
/* Layout 2 colonnes : a GAUCHE les 3 encarts aleas/remise empiles (form
   .retenue-remise-ajustements), a DROITE l'encart Retenue de garantie ->
   Aleas entreprise et RG cote a cote en haut (cf. demande 2026-06-03).
   Sous 1100px, on repasse en 1 colonne. */
.retenue-remise-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
@media (max-width: 1100px) {
  .retenue-remise-layout {
    grid-template-columns: 1fr;
  }
}
.retenue-remise-ajustements {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
/* 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;
}

/* 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;
}

/* 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);
  margin-top: 20px;
}
.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; }

.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;
}
.btn-chart-action {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 500;
}

/* === 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; }
.fb-pin {
  position: absolute;
  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;
  left: 3px;
  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° »). */
.postes-dropzone .row:hover .col-numero,
.postes-sortable .row:hover .col-numero { justify-content: flex-end; }

/* É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 61px = début aligné avec la désignation des postes (col-numero 52px
     + padding cellule). droite 40px = place pour le bouton supprimer. */
  padding: 8px 40px 8px 61px;
  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: 61px;
  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 61px */
  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; }
