@charset "UTF-8";
:root{
  --ink:#1c1d1b; --ink-soft:#4a4a46;
  --paper:#ededE7; --paper-2:#f7f6f2;
  --line:#d3d1c6; --line-strong:#b3b0a2;
  --amber:#e8a93b; --amber-dark:#8a5f13; --amber-bg:#fbeed0;
  --steel:#42606d; --steel-light:#dde7ea;
  --red:#b3402f; --red-bg:#f6e4e0;
  --green:#2f9e44; --green-bg:#e6ecda;
  /* LOT UX1 (refonte visuelle du Planning opérationnel, 2026-08-30) --
     seule couleur réellement absente du design system existant : la
     maquette de référence (docs/inspirations/planning operationnel.png)
     distingue la phase Démontage par une teinte violette dans TOUTES les
     lignes, quel que soit le statut du projet -- Montage/Permanence
     réutilisent respectivement --steel/--green (déjà existants), voir le
     rapport du lot pour la justification complète du changement de
     convention (couleur de phase plutôt que couleur de statut projet).
     Même triplet base/dark/bg EXACTEMENT que --amber ci-dessus. */
  --violet:#7c5cad; --violet-dark:#4a3568; --violet-bg:#ece4f5;
  /* Fonds des blocs de phase de la timeline (texte blanc dessus, voir
     .ptl-bar) -- volontairement FIXES (jamais redéfinis dans le bloc thème
     sombre ci-dessous), contrairement à --steel/--green/--violet qui
     s'éclaircissent en mode sombre pour rester lisibles comme TEXTE sur le
     fond de page (voir .phase-montage/.phase-permanence/.phase-demontage
     plus bas dans ce fichier) -- réutiliser ces variantes éclaircies comme
     fond de bloc casserait le contraste du texte blanc en thème sombre. Un
     bloc de timeline reste une couleur de donnée, pas un texte : elle doit
     rester également vive dans les deux thèmes, comme un badge de statut. */
  --phase-montage-bg:#3f6a83; --phase-permanence-bg:#2f9e44; --phase-demontage-bg:#7c5cad; --phase-autre-bg:#c2702c;
  --nav-bg:#1c1d1b; --nav-border:#3a3a37; --nav-text:#c9c8c0; --nav-text-hover:#fff;
  --shadow-card:0 2px 8px rgba(28,29,27,0.07);
  --radius:9px; --radius-sm:6px; --radius-pill:20px;
  --brand:#b73818; --brand-hover:#8f2b12;
  --nav-accent:#e0724a;
  /* Orange EXACT du jeu d'icônes (`assets/icons/orange/*.svg`, stroke #FF8A3D).
     Ce n'est pas une couleur inventée : c'est celle des fichiers, reprise ici
     pour qu'un texte posé à côté d'une icône orange soit du MÊME orange.
     Volontairement identique dans les deux thèmes — les icônes, elles, ne
     changent pas de couleur selon le thème. */
  --icon-orange:#FF8A3D;
  /* Triplet RGB de --brand, pour les fonds teintés translucides (fiche
     projet, assets/css/project-hero.css) -- rgba() ne peut pas dériver une
     opacité depuis une couleur hex existante, donc dupliqué ici plutôt que
     de tout recalculer en color-mix() (non utilisé ailleurs dans ce fichier). */
  --brand-rgb:183,56,24;
}
[data-theme-mode="dark"]{
  --ink:#ededE7; --ink-soft:#a8a79c;
  --paper:#17171a; --paper-2:#201f22;
  --line:#38373a; --line-strong:#4d4c4a;
  --amber:#e8a93b; --amber-dark:#f0c069; --amber-bg:#3d2f14;
  --steel:#8fb2c2; --steel-light:#233038;
  --red:#e0776a; --red-bg:#3a2320;
  --green:#3ddc63; --green-bg:#28311d;
  --violet:#b79ae0; --violet-dark:#d8c7ef; --violet-bg:#332845;
  --nav-bg:#0e0e10; --nav-border:#2c2c2f; --nav-text:#a8a79c; --nav-text-hover:#fff;
  --shadow-card:0 2px 10px rgba(0,0,0,0.45);
  --brand:#e0724a; --brand-hover:#ea8a66;
  --brand-rgb:224,114,74;
}

/* ============================================================
   Thème Neumorphism — mêmes tokens de base, surface unique
   (fond = carte) et relief obtenu par paires d'ombres claire/
   foncée plutôt que par bordures. Les tableaux de données
   restent volontairement sobres : le neumorphism sur des lignes
   denses nuit à la lisibilité, donc on garde ces zones-là proches
   du style Flat.
   ============================================================ */
[data-theme-style="neumorphism"]{
  --paper:#e3e1d8; --paper-2:#e3e1d8;
  --line:transparent; --line-strong:#c9c7bb;
  --radius:18px; --radius-sm:12px; --radius-pill:24px;
  --neu-hi:#ffffff; --neu-lo:#bcbaae;
  --shadow-card:8px 8px 16px var(--neu-lo), -8px -8px 16px var(--neu-hi);

  --neu-confirme-bg:#dbe6ea; --neu-confirme-hi:#f2f8fa; --neu-confirme-lo:#b9ccd2; --neu-confirme-text:#2d5563;
  --neu-encours-bg:#f2e4c6; --neu-encours-hi:#fdf6e6; --neu-encours-lo:#d1bd94; --neu-encours-text:#7a5411;
  --neu-termine-bg:#dde8cf; --neu-termine-hi:#f0f7e8; --neu-termine-lo:#b9caa4; --neu-termine-text:#42611f;
  --neu-annule-bg:#f2d9d3;  --neu-annule-hi:#faeae6;  --neu-annule-lo:#d1aca3;  --neu-annule-text:#8a3223;
  --neu-brand-bg:#eed2c4;   --neu-brand-hi:#fbe9dd;   --neu-brand-lo:#cba58e;   --neu-brand-text:#8a3714;
}
[data-theme-style="neumorphism"][data-theme-mode="dark"]{
  /* Sans ceci, le fond autofill imposé par Chrome restait clair (couleur fixe,
     indépendante du thème) alors que le texte de nos champs passe clair en
     thème sombre : texte clair sur fond resté clair, illisible — confirmé en
     conditions réelles (autofill sur login.php). Chrome adapte son fond
     autofill une fois color-scheme:dark déclaré (vérifié : passe de
     rgb(232,240,254) à rgba(70,90,126,.4)). Signalé uniquement en
     Neumorphism sombre ; les autres thèmes n'ont pas ce problème et
     n'ont donc pas reçu ce correctif. */
  color-scheme: dark;
  --paper:#232326; --paper-2:#232326;
  --line:transparent; --line-strong:#38383c;
  --neu-hi:#302f34; --neu-lo:#131315;
  --shadow-card:8px 8px 16px var(--neu-lo), -8px -8px 16px var(--neu-hi);

  --neu-confirme-bg:#233038; --neu-confirme-hi:#2c3b44; --neu-confirme-lo:#161f24; --neu-confirme-text:#a9cdd9;
  --neu-encours-bg:#3a2f18; --neu-encours-hi:#493c1f; --neu-encours-lo:#241d0f; --neu-encours-text:#e8c583;
  --neu-termine-bg:#28311d; --neu-termine-hi:#333e24; --neu-termine-lo:#181f11; --neu-termine-text:#b7cf98;
  --neu-annule-bg:#3d241e;  --neu-annule-hi:#4c2e26;  --neu-annule-lo:#241512;  --neu-annule-text:#e8a08f;
  --neu-brand-bg:#3d2a1f;   --neu-brand-hi:#4c3527;   --neu-brand-lo:#251a13;   --neu-brand-text:#eeaa82;
}
*{ box-sizing:border-box; }
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:'Inter',sans-serif; padding-bottom:60px;
}
h1,h2,h3{ font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase; margin:0; }
a{ color:var(--brand); }
.wrap{ max-width:1180px; margin:0 auto; padding:0 24px; }
[data-layout="fluid"] .wrap{ max-width:none; padding:20px; }

/* ---------- Navigation ---------- */
.nav{ background:var(--nav-bg); color:var(--paper-2); }
.nav-inner{ max-width:1180px; margin:0 auto; padding:0 24px; display:flex; align-items:center; justify-content:space-between; height:56px; }
[data-layout="fluid"] .nav-inner{ max-width:none; padding:0 20px; }
.nav-brand{ display:flex; align-items:center; padding-bottom:4px; border-bottom:2px solid transparent; text-decoration:none; }
.nav-logo{ height:22px; width:auto; display:block; }
.nav-links{ display:flex; align-items:center; gap:4px; flex:1; margin-left:34px; }
.nav-links a{ color:var(--nav-text); text-decoration:none; font-size:13px; font-weight:500; padding:8px 12px; border-bottom:2px solid transparent; }
.nav-links a:hover{ color:var(--nav-text-hover); }
.nav-links a.active{ color:var(--nav-text-hover); border-bottom-color:var(--nav-accent); }
.nav-links span.disabled{ color:#6b6a63; font-size:13px; padding:8px 12px; cursor:default; }
.nav-dropdown{ position:relative; display:flex; align-items:center; }
.nav-dropdown-toggle{ display:inline-block; box-sizing:border-box; color:var(--nav-text); font-size:13px; font-weight:500; padding:8px 12px; border-bottom:2px solid transparent; cursor:pointer; user-select:none; line-height:1.4; }
.nav-dropdown-toggle:hover{ color:var(--nav-text-hover); }
.nav-dropdown-toggle.active{ color:var(--nav-text-hover); border-bottom-color:var(--nav-accent); }
.nav-dropdown-menu{
  display:none; position:absolute; top:100%; left:0; min-width:160px;
  background:var(--nav-bg); border:1px solid var(--nav-border); border-radius:var(--radius-sm); z-index:20; box-shadow:0 6px 16px rgba(0,0,0,0.3);
  overflow:hidden;
}
.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu{ display:block; }
.nav-dropdown-menu a{ display:block; color:var(--nav-text); text-decoration:none; font-size:13px; padding:9px 14px; border-bottom:none !important; }
.nav-dropdown-menu a:hover{ background:rgba(255,255,255,0.08); color:var(--nav-text-hover); }
.nav-dropdown-menu a.active{ color:var(--nav-accent); }
.nav-user-dropdown{ position:relative; }
.nav-user-toggle{
  font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--nav-text); white-space:nowrap;
  cursor:pointer; user-select:none; padding:8px 4px;
}
.nav-user-toggle:hover{ color:var(--nav-text-hover); }
.nav-user-menu{
  display:none; position:absolute; top:100%; right:0; min-width:230px; margin-top:0;
  background:var(--nav-bg); border:1px solid var(--nav-border); border-radius:var(--radius-sm); z-index:20; box-shadow:0 6px 16px rgba(0,0,0,0.3);
  padding:6px 0; overflow:hidden;
}
.nav-user-dropdown:hover .nav-user-menu,
.nav-user-dropdown:focus-within .nav-user-menu{ display:block; }
.nav-user-menu-link{ display:block; color:var(--nav-text); text-decoration:none; font-size:13px; padding:9px 14px; }
.nav-user-menu-link:hover{ background:rgba(255,255,255,0.08); color:var(--nav-text-hover); }
.nav-user-menu-link.logout{ color:var(--red); border-top:1px solid var(--nav-border); margin-top:6px; padding-top:10px; }
/* LA CLOCHE DES NOTIFICATIONS (2026-10-10) — à gauche du menu utilisateur.
   Badge = notifications NON LUES encore visibles (masqué à 0, « 99+ »). Le
   panneau s'ouvre au clic (jamais au survol), se ferme par Échap ou clic
   extérieur ; mêmes couleurs que les menus de la barre (tous thèmes). */
.nav-right{ display:flex; align-items:center; gap:6px; }
.nav-bell{ position:relative; }
.nav-bell-btn{
  position:relative; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px;
  background:transparent; border:1px solid transparent; border-radius:50%; cursor:pointer; color:var(--nav-text); padding:0;
}
.nav-bell-btn:hover, .nav-bell-btn[aria-expanded="true"]{ background:rgba(255,255,255,0.08); }
.nav-bell-btn:focus-visible{ outline:2px solid var(--nav-accent); outline-offset:1px; }
.nav-bell-badge{
  position:absolute; top:1px; right:-2px; min-width:17px; height:17px; padding:0 4px; box-sizing:border-box;
  border-radius:9px; background:var(--red); color:#fff; font:700 10px/17px 'Inter',sans-serif; text-align:center;
}
.nav-bell-badge[hidden]{ display:none; }
.nav-bell-panel{
  position:absolute; top:calc(100% + 6px); right:-8px; width:360px; max-width:calc(100vw - 16px); box-sizing:border-box; max-height:min(70vh, 520px); display:flex; flex-direction:column;
  background:var(--nav-bg); border:1px solid var(--nav-border); border-radius:var(--radius-sm); z-index:30; box-shadow:0 8px 22px rgba(0,0,0,0.35);
  color:var(--nav-text); font-size:13px;
}
.nav-bell-panel[hidden]{ display:none; }
.nav-bell-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border-bottom:1px solid var(--nav-border); }
.nav-bell-head strong{ color:var(--nav-text-hover); font-size:13px; }
.nav-bell-action{ background:transparent; border:0; color:var(--nav-accent); font-size:12px; cursor:pointer; padding:4px 2px; }
.nav-bell-action:hover{ text-decoration:underline; }
.nav-bell-action[disabled]{ opacity:.45; cursor:default; text-decoration:none; }
.nav-bell-items{ overflow:auto; flex:1 1 auto; }
.nav-bell-list{ list-style:none; margin:0; padding:4px 0; }
.nav-bell-item form{ margin:0; }
.nav-bell-entry{
  display:flex; gap:9px; width:100%; text-align:left; background:transparent; border:0; color:var(--nav-text);
  padding:9px 12px; cursor:pointer; font:inherit;
}
.nav-bell-entry:hover, .nav-bell-entry:focus-visible{ background:rgba(255,255,255,0.08); color:var(--nav-text-hover); outline:none; }
.nav-bell-dot{ flex:0 0 8px; width:8px; height:8px; margin-top:5px; border-radius:50%; background:transparent; }
.nav-bell-item.is-unread .nav-bell-dot{ background:var(--nav-accent); }
.nav-bell-text{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.nav-bell-title{ overflow-wrap:anywhere; }
.nav-bell-item.is-unread .nav-bell-title{ font-weight:600; color:var(--nav-text-hover); }
.nav-bell-body{ font-size:12px; opacity:.8; overflow-wrap:anywhere; }
.nav-bell-when{ font-size:11px; opacity:.6; }
.nav-bell-empty, .nav-bell-error{ padding:14px 12px; margin:0; opacity:.8; }
.nav-bell-all{ display:block; padding:10px 12px; border-top:1px solid var(--nav-border); color:var(--nav-accent); text-decoration:none; text-align:center; }
.nav-bell-all:hover{ background:rgba(255,255,255,0.06); }
.nav-bell .sr-only{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
/* Rattaché à <body> par le script : position fixe, placé sous la cloche
   d'après la zone visible de l'écran (bureau et mobile). */
.nav-bell-panel.is-portal{ position:fixed; max-height:calc(100vh - 80px); }
/* Un ÉTAT dans le menu, pas une commande : même gabarit que les entrées
   voisines pour ne pas casser la colonne, mais rien de cliquable — pas de
   survol, pas de curseur main, et une teinte plus discrète que les liens.
   Cette teinte est celle de `.nav-user-menu-label` juste en dessous : dans ce
   menu, c'est déjà la couleur de « ce qui se lit » par opposition à « ce qui
   se clique ». Valable en Flat comme en Neumorphism, qui ne retouchent ni
   l'un ni l'autre ce menu. */
/* `.nav-user-menu-state` a été retirée le 2026-09-15 : elle n'existait que pour
   rendre « MCP actif » visiblement NON cliquable (couleur éteinte, curseur par
   défaut, survol neutralisé). L'entrée est devenue un lien vers le suivi des
   coûts IA et reprend donc `.nav-user-menu-link`, comme les autres. Garder ces
   deux règles sans usage aurait laissé croire à un état qui n'existe plus. */
.nav-user-menu-label{ font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; color:#8a8980; padding:10px 14px 4px; }
.theme-grid{ padding:2px 10px 8px; display:grid; grid-template-columns:1fr 1fr; gap:6px; }
.theme-swatch{
  display:flex; align-items:center; gap:7px; width:100%; border:1px solid var(--nav-border); background:transparent; border-radius:var(--radius-sm);
  color:var(--nav-text); font-family:'Inter',sans-serif; font-size:11px; padding:6px 8px; cursor:pointer; text-align:left;
}
.theme-swatch:hover{ border-color:var(--nav-accent); color:var(--nav-text-hover); }
.theme-swatch.current{ border-color:var(--nav-accent); color:var(--nav-text-hover); }
.theme-swatch.disabled{ opacity:.4; cursor:default; }
.theme-swatch-preview{ width:14px; height:14px; flex:0 0 auto; border-radius:3px; border:1px solid rgba(255,255,255,0.25); }
.theme-swatch.light .theme-swatch-preview{ background:#ededE7; }
.theme-swatch.dark .theme-swatch-preview{ background:#17171a; }
.page-body{ padding:28px 0 0; }

/* ---------- Sections / titles ---------- */
section{ margin-bottom:32px; }
.section-title{ font-size:14px; color:var(--ink-soft); letter-spacing:.04em; margin-top:28px; margin-bottom:14px; display:flex; align-items:center; justify-content:space-between; }
/* Un titre qui OUVRE sa section n'a pas besoin de cette marge : `section` porte
   déjà son propre `margin-bottom:32px`, et l'ajouter ici décollerait le premier
   titre de chaque onglet/page sans raison. La marge ne sert qu'aux titres qui
   suivent un bloc à l'intérieur d'une même section. */
.section-title:first-child{ margin-top:0; }

/* ---------- Buttons ---------- */
/* ---------------------------------------------------------------------------
   `[hidden]` DOIT GAGNER — toujours.
   ---------------------------------------------------------------------------
   L'attribut natif `hidden` ne tient que par une règle `display:none` de la
   feuille du NAVIGATEUR, que n'importe quelle règle de cette feuille bat par
   simple spécificité. `.btn{ display:inline-block }` suffisait : un bouton
   `<button class="btn" hidden>` restait visible ET cliquable.

   Le piège avait déjà été rencontré une fois et corrigé localement
   (`.info-box[hidden]`, plus bas). Un correctif par composant laisse le suivant
   retomber dedans — d'où cette règle GLOBALE, la seule façon de rendre
   `hidden` fiable partout, y compris pour les composants à venir.

   `!important` est ici légitime : « cet élément n'existe pas pour
   l'utilisateur » ne se négocie pas avec la mise en page.
   --------------------------------------------------------------------------- */
[hidden]{ display:none !important; }

/* Bouton DÉSACTIVÉ — visible, mais visiblement inutilisable.
   Cacher une action prive l'utilisateur de l'information qu'elle existe ; la
   désactiver avec une infobulle lui dit à la fois qu'elle existe ET ce qui
   manque pour y accéder. `cursor:not-allowed` et l'opacité le disent avant
   même le survol. */
.btn[disabled], .btn:disabled{
  opacity:.5; cursor:not-allowed; pointer-events:auto;
}
.btn[disabled]:hover, .btn:disabled:hover{
  background:var(--paper-2); color:var(--ink); border-color:var(--line-strong);
}
.btn.primary[disabled]:hover, .btn.primary:disabled:hover{
  background:var(--brand); color:#fff; border-color:var(--brand);
}

.btn{
  display:inline-block; font-family:'Inter',sans-serif; font-weight:600; font-size:13px;
  border:1.5px solid var(--line-strong); background:var(--paper-2); color:var(--ink); border-radius:var(--radius-sm);
  padding:8px 14px; cursor:pointer; text-decoration:none; line-height:1.2; transition:background .12s, border-color .12s, color .12s;
}
.btn:hover{ background:var(--ink); color:var(--paper-2); border-color:var(--ink); }
.btn.primary{ background:var(--brand); color:#fff; border-color:var(--brand); box-shadow:0 2px 6px rgba(183,56,24,0.28); }
.btn.primary:hover{ background:var(--brand-hover); border-color:var(--brand-hover); }
.btn.danger{ border-color:var(--red); color:var(--red); background:transparent; }
.btn.danger:hover{ background:var(--red); color:#fff; }
.btn.small{ padding:5px 10px; font-size:12px; }

/* ---------- Cards / KPI ---------- */
.kpi-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:14px; }
.kpi-card{ background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-card); padding:16px 18px; border-left:4px solid var(--line-strong); }
.kpi-card.accent{ border-left-color:var(--brand); }
.kpi-card.steel{ border-left-color:var(--steel); }
.kpi-card .label{ font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); margin-bottom:8px; }
.kpi-card .value{ font-family:'JetBrains Mono',monospace; font-size:24px; font-weight:700; }

/* ---------- Panels ---------- */
.panel{ background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-card); padding:18px 20px; }
.empty-state{ color:var(--ink-soft); font-size:13px; font-style:italic; padding:10px 2px; }
.note-panel{ background:var(--paper-2); border:1px dashed var(--line-strong); border-radius:var(--radius-sm); padding:12px 16px; font-size:12px; color:var(--ink-soft); font-style:italic; margin-top:8px; }

/* ---------- Pagination ---------- */
.pagination{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px; margin-top:16px; padding-top:14px; border-top:1px solid var(--line); }
.pagination-info{ font-size:12px; color:var(--ink-soft); font-family:'JetBrains Mono',monospace; }
.pagination-links{ display:flex; gap:4px; flex-wrap:wrap; align-items:center; }
.pagination-ellipsis{ padding:0 4px; color:var(--ink-soft); font-size:12px; }

/* ---------- Tables ---------- */
table.data{ width:100%; border-collapse:collapse; }
table.data th{ text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); padding:8px 10px; border-bottom:1px solid var(--line-strong); }
table.data td{ padding:10px; border-bottom:1px solid var(--line); font-size:13.5px; vertical-align:middle; }
table.data tr:last-child td{ border-bottom:none; }
table.data tr:hover td{ background:rgba(0,0,0,0.02); }

/* ---------- Page Tarifs (finance_tarifs.php) : structure commune ----------
   Chantier "Refonte UI Tarifs" (2026-08-27) : remplace les dizaines de
   `style="width:...; padding-left:...; padding-right:..."` inline
   auparavant divergents entre les 4 familles (RH/Produits/Véhicules/
   Prestations & consommables) par un système de classes unique. Scopé sous
   `.tariffs-page` pour ne jamais affecter les autres tableaux `.data` de
   l'ERP -- réutilise les mêmes variables de thème (clair/sombre/
   neumorphism corrects sans règle dédiée). */
.tariffs-page .tariff-section{ margin-top:20px; }
.tariffs-page .tariff-status{
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:400;
  color:var(--ink-soft); text-transform:none; letter-spacing:normal; flex-shrink:0;
}

.tariffs-page .tariff-table{ width:100%; table-layout:fixed; border-collapse:collapse; }
.tariffs-page .tariff-table th{ text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); padding:8px 6px; border-bottom:1px solid var(--line-strong); }
.tariffs-page .tariff-table td{ padding:6px; border-bottom:1px solid var(--line); vertical-align:top; }
.tariffs-page .tariff-table th:first-child, .tariffs-page .tariff-table td:first-child{ padding-left:0; }
.tariffs-page .tariff-table th:last-child, .tariffs-page .tariff-table td:last-child{ padding-right:0; }
.tariffs-page .tariff-table tr:last-child td{ border-bottom:none; }
.tariffs-page .tariff-table input, .tariffs-page .tariff-table select{
  width:100%; box-sizing:border-box; border:1.5px solid transparent; border-bottom:1.5px solid var(--line-strong);
  background:transparent; font-family:'Inter',sans-serif; font-size:13.5px; padding:7px 2px; color:var(--ink); border-radius:0;
}
.tariffs-page .tariff-table input:focus, .tariffs-page .tariff-table select:focus{ outline:none; border-color:var(--brand); }
.tariffs-page .tariff-subtext{ font-size:10.5px; color:var(--ink-soft); margin-top:3px; }

.tariffs-page .tariff-col-name{ width:22%; }
.tariffs-page .tariff-col-label{ width:18%; }
.tariffs-page .tariff-col-detail{ /* pas de largeur fixe : occupe l'espace restant (table-layout:fixed) -- "le détail doit avoir de la place" */ }
.tariffs-page .tariff-col-price{ width:110px; }
.tariffs-page .tariff-col-unit{ width:90px; }
.tariffs-page .tariff-col-actions{ width:44px; text-align:center; }

.tariffs-page .tariff-add-form{ display:grid; gap:12px; margin-top:16px; align-items:end; }
.tariffs-page .tariff-add-form .field{ margin:0; min-width:0; }
.tariffs-page .tariff-add-form--rh{ grid-template-columns:22% 18% 1fr 110px auto; }
/* Chercher/Nom : deux champs plus étroits côte à côte, tout sur une seule
   ligne avec Détail/Prix/Unité/Ajouter (2026-08-27, demande explicite). */
.tariffs-page .tariff-add-form--products{ grid-template-columns:.8fr .8fr 1.2fr 110px 90px auto; }
.tariffs-page .tariff-add-form--simple{ grid-template-columns:22% 1fr 110px 90px auto; }
@media (max-width: 900px){
  .tariffs-page .tariff-add-form--rh, .tariffs-page .tariff-add-form--products, .tariffs-page .tariff-add-form--simple{
    grid-template-columns:1fr 1fr;
  }
}

/* Chantier "Catégories Produits" (2026-08-28) : filtre secondaire, volontairement
   plus discret que .tab-nav/.tab-btn (familles principales) pour ne pas créer
   une deuxième rangée d'onglets de même poids visuel. */
.tariffs-page .tariff-category-nav{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:16px; }
.tariffs-page .tariff-category-btn{
  background:none; border:1.5px solid var(--line-strong); border-radius:var(--radius-pill);
  padding:5px 14px; font-family:'Inter',sans-serif; font-size:12.5px; font-weight:500;
  color:var(--ink-soft); text-decoration:none; display:inline-block;
}
.tariffs-page .tariff-category-btn:hover{ color:var(--ink); border-color:var(--ink-soft); }
.tariffs-page .tariff-category-btn.active{ color:#fff; background:var(--brand); border-color:var(--brand); }
.tariffs-page .tariff-category-select-form{ display:flex; align-items:center; gap:8px; margin-bottom:16px; }
.tariffs-page .tariff-category-select{
  font-family:'Inter',sans-serif; font-size:13px; padding:6px 10px; border-radius:var(--radius-sm);
  border:1.5px solid var(--line-strong); background:transparent; color:var(--ink);
}

/* ---------- Icônes WABU (wabu_icon(), includes/icon_helpers.php) ----------
   display:inline-block + vertical-align évite le décalage classique d'un
   <svg> injecté au fil du texte (baseline différente d'un caractère) ;
   flex-shrink:0 pour ne jamais se faire écraser dans une rangée flex. */
.wabu-icon{ display:inline-block; vertical-align:-3px; flex-shrink:0; }

/* ---------- Badges (statuts) ---------- */
/* `inline-flex` + `white-space:nowrap` + `width:max-content` : un badge est une
   étiquette d'un seul tenant. En `inline-block`, une cellule de tableau étroite
   le compressait à la largeur de la colonne et coupait « Brouillon » mot par
   mot — parfois une lettre par ligne. `align-items:center` garde le texte
   centré quelle que soit la hauteur de ligne de la cellule. */
.badge{ display:inline-flex; align-items:center; width:max-content; max-width:100%; white-space:nowrap;
  font-size:11px; font-weight:600; padding:4px 11px; border-radius:var(--radius-pill); text-transform:uppercase; letter-spacing:.02em; }
.badge.prospect{ background:transparent; border:1.5px dashed var(--line-strong); color:var(--ink-soft); }
.badge.confirme{ background:var(--steel-light); color:var(--steel); }
.badge.en_cours{ background:var(--amber-bg); color:var(--amber-dark); }
.badge.termine{ background:var(--green-bg); color:var(--green); }
.badge.annule{ background:var(--red-bg); color:var(--red); }
/* Priorité Tâche (module Tâches, 2026-08-24) — mêmes tokens de couleur que
   les badges ci-dessus, jamais une nouvelle palette : urgente = rouge (comme
   .badge.annule), importante = ambre (comme .badge.en_cours), normale =
   neutre (comme .badge.confirme). */
.badge.task-priority-urgente{ background:var(--red-bg); color:var(--red); }
.badge.task-priority-importante{ background:var(--amber-bg); color:var(--amber-dark); }
.badge.task-priority-normale{ background:var(--steel-light); color:var(--steel); }

/* ---------- Forms ---------- */
.form-grid{ display:grid; grid-template-columns:1fr 1fr; gap:18px 24px; }
.form-grid .full{ grid-column:1 / -1; }
.field label{ display:block; font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); margin-bottom:5px; }
.field input[type=text], .field input[type=number], .field input[type=date], .field input[type=datetime-local],
.field input[type=email], .field input[type=password], .field input[type=url], .field input[type=month],
.field input[type=tel],
.field input[type=time], .field input[type=search], .field select, .field textarea{
  width:100%; border:1.5px solid transparent; border-bottom:1.5px solid var(--line-strong); background:transparent;
  font-family:'Inter',sans-serif; font-size:14px; padding:8px 2px; color:var(--ink); border-radius:0;
}
.field textarea{ border:1px solid var(--line-strong); border-radius:var(--radius-sm); padding:8px; min-height:70px; resize:vertical; }
.field input:focus, .field select:focus, .field textarea:focus{ outline:none; border-color:var(--brand); }
/* Valeur NON SAISISSABLE affichée à la place d'un champ (ex. la version d'un
   devis, imposée par le serveur). Même gabarit qu'un input de `.field` — même
   hauteur, même ligne de base, même soulignement — pour que la ligne du
   formulaire reste alignée ; simplement, il n'y a rien à saisir. */
.field-static{
  border:1.5px solid transparent; border-bottom:1.5px solid var(--line-strong);
  font-family:'Inter',sans-serif; font-size:14px; padding:8px 2px; color:var(--ink);
}
/* Mention discrète sous un champ (ex. « Imposé par le projet lié. »).
   Aucune déclaration `display` : l'attribut natif [hidden] doit suffire. */
.field-hint{ font-size:11px; color:var(--ink-soft); margin-top:4px; font-style:italic; }
/* `input[type=search]` était absent des sélecteurs ci-dessus : il tombait donc
   sur le rendu natif du navigateur (bordure inset, aucun rayon, padding de
   2px), visuellement étranger au reste des formulaires. Ajouté à la liste
   plutôt que redéclaré à part : un champ de recherche est un champ comme les
   autres. Les deux règles suivantes ne concernent QUE ses ornements natifs. */
.field input[type=search]{ -webkit-appearance:none; appearance:none; }
.field input[type=search]::-webkit-search-cancel-button{
  -webkit-appearance:none; appearance:none; width:14px; height:14px; cursor:pointer;
  /* Croix dessinée en CSS pur : la bibliothèque d'icônes WABU ne peut pas être
     injectée dans un pseudo-élément natif. Aucune icône officielle n'est
     détournée ici. */
  background:
    linear-gradient(45deg, transparent 45%, var(--ink-soft) 45%, var(--ink-soft) 55%, transparent 55%),
    linear-gradient(-45deg, transparent 45%, var(--ink-soft) 45%, var(--ink-soft) 55%, transparent 55%);
  opacity:.6;
}
.field input[type=search]::-webkit-search-cancel-button:hover{ opacity:1; }
/* Lisibilité des <option> dans le menu natif ouvert (tout <select> de l'ERP,
   pas seulement .field) -- sans ceci, un <select> stylé avec un fond sombre
   (ex. .cat-head sur fond nav-bg) laisse le navigateur choisir lui-même les
   couleurs du menu déroulant natif, parfois illisibles selon l'OS/navigateur.
   Réutilise les mêmes variables de thème que tout le reste de l'ERP, donc
   correct nativement en clair/sombre/neumorphism sans règle dédiée par page. */
select option{ color:var(--ink); background:var(--paper-2); }
.checkbox-list{ border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--paper); padding:10px 12px; max-height:180px; overflow-y:auto; }
.checkbox-list label{ display:flex; align-items:center; gap:8px; font-size:13px; padding:4px 0; color:var(--ink); text-transform:none; letter-spacing:0; }
.checkbox-list.columns{ max-height:none; overflow:visible; display:grid; grid-template-columns:repeat(6, 1fr); gap:2px 16px; }
.checkbox-list.columns-4{ max-height:none; overflow:visible; display:grid; grid-template-columns:repeat(4, 1fr); gap:2px 16px; }

/* ============================================================
   Sélecteur RH par avatar — remplace visuellement les checkboxes
   classiques dans les listes d'équipe (responsables, architectes,
   graphistes 2D, montage/démontage/permanence). La checkbox native
   reste dans le DOM (visually-hidden, jamais display:none) : c'est
   elle qui porte l'état, jamais une classe pilotée par du JS — le
   moteur d'auto-save existant (assets/js/autosave.js) et FormData
   continuent de fonctionner sans aucune modification.
   ============================================================ */
.employee-avatar-grid{
  display:flex; flex-wrap:wrap; gap:10px 6px;
  border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--paper); padding:12px;
}
.employee-avatar-choice__input.visually-hidden{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0; outline:none;
}
.employee-avatar-grid .employee-avatar-choice{
  display:flex; flex-direction:column; align-items:center; justify-content:flex-start;
  gap:8px; width:66px; padding:6px 4px; margin-bottom:0; border-radius:var(--radius-sm);
  cursor:pointer; user-select:none; text-align:center; -webkit-tap-highlight-color:transparent;
  text-transform:none; letter-spacing:normal; font-size:inherit;
  transition:background-color .12s ease;
}
.employee-avatar-choice:hover{ background:var(--paper-2); }
.employee-avatar-choice:active{ transform:scale(0.97); }
.employee-avatar-choice__avatar{
  position:relative; width:46px; height:46px; min-width:46px; min-height:46px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
  background:var(--paper-2); overflow:hidden;
  outline:2px solid transparent; outline-offset:2px;
  transition:outline-color .12s ease, box-shadow .12s ease;
}
.employee-avatar-choice__avatar img{
  position:absolute; inset:0; width:100%; height:100%; aspect-ratio:1; object-fit:cover; display:block;
  border-radius:50%; opacity:0; transition:opacity 180ms ease;
}
.employee-avatar-choice__avatar img.is-loaded{ opacity:1; }
/* Pendant le chargement d'une photo connue (document trouvé, requête vers
   employee_avatar.php en cours) : le "W" Wabu animé (signature déjà utilisée
   pour la liste de print, voir plus bas) remplace visuellement les initiales
   — fond opaque pour ne jamais laisser les deux se superposer. Retiré par
   onload/onerror (voir employee_avatar_choice_html()) : jamais visible une
   fois la photo affichée ou en cas d'échec (les initiales, jamais retirées
   du DOM, redeviennent alors seules visibles). aria-hidden : l'identité de
   l'employé reste portée par le nom déjà affiché sous l'avatar, jamais par
   cet indicateur transitoire — évite aussi une announce "status" par tuile
   dans une grille qui peut en compter plusieurs dizaines.
   ============================================================ */
.employee-avatar-choice__loader{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  background:var(--paper-2); border-radius:50%;
}
.employee-avatar-choice__initials{
  font-family:'JetBrains Mono',monospace; font-size:14px; font-weight:600; color:var(--ink-soft);
}
.employee-avatar-choice__name{
  font-size:10.5px; line-height:1.3; color:var(--ink); width:100%;
  overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2;
  -webkit-box-orient:vertical; word-break:break-word;
}
/* Sélectionné : anneau orange = --nav-accent, la variable d'accent déjà
   utilisée pour les états actifs de la nav (jamais une couleur inventée). */
.employee-avatar-choice__input:checked ~ .employee-avatar-choice__avatar{
  outline-color:var(--nav-accent); background:var(--paper);
}
/* Focus clavier : anneau --steel, volontairement différent de --nav-accent
   (identique à --brand en thème sombre, ce qui rendrait focus et sélection
   indiscernables) — reste distinguable même quand les deux états se
   cumulent (tuile sélectionnée ET focusée au clavier). */
.employee-avatar-choice__input:focus-visible ~ .employee-avatar-choice__avatar{
  box-shadow:0 0 0 2px var(--paper), 0 0 0 4.5px var(--steel);
}
@media (prefers-reduced-motion: reduce){
  .employee-avatar-choice, .employee-avatar-choice *{ transition:none !important; }
  .employee-avatar-choice:active{ transform:none; }
}
[data-theme-style="neumorphism"] .employee-avatar-grid{
  border:none; box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .employee-avatar-choice__avatar{
  box-shadow:4px 4px 8px var(--neu-lo), -4px -4px 8px var(--neu-hi);
}
[data-theme-style="neumorphism"] .employee-avatar-choice__input:focus-visible ~ .employee-avatar-choice__avatar{
  box-shadow:4px 4px 8px var(--neu-lo), -4px -4px 8px var(--neu-hi), 0 0 0 2px var(--paper), 0 0 0 4.5px var(--steel);
}
@media (max-width:600px){
  .employee-avatar-choice{ width:60px; }
  .employee-avatar-choice__avatar{ width:40px; height:40px; min-width:40px; min-height:40px; }
}
/* Tuile désactivée (ex. participant Réunion déjà clôturé, voir
   employee_avatar_choice_html()) : reste cochée/visible (jamais masquée,
   la participation ne doit jamais devenir invisible) mais non interactive. */
.employee-avatar-choice--disabled{ cursor:default; opacity:.55; }
.employee-avatar-choice--disabled:hover{ background:none; }
.employee-avatar-choice--disabled:active{ transform:none; }

/* ============================================================
   Signature Wabu — loader "W" réutilisable. Déplacé ici depuis
   assets/css/project-dropbox-explorer.css (déjà documenté comme "pensé
   pour être chargé ailleurs dans l'ERP plus tard" — désormais réutilisé
   tel quel par les tuiles avatar RH ci-dessus, jamais dupliqué) : ce
   fichier global est chargé sur toutes les pages (includes/head.php),
   contrairement au CSS spécifique à l'explorateur Dropbox.
   ============================================================ */
.wabu-loader{
  --wabu-loader-length: 100;
  display:inline-flex; align-items:center; justify-content:center;
  width:var(--wabu-loader-size, 22px); height:calc(var(--wabu-loader-size, 22px) * 22 / 34);
  color:var(--ink-soft);
  vertical-align:middle;
}
.wabu-loader svg{ width:100%; height:100%; display:block; }
.wabu-loader path{
  fill:none; stroke:currentColor; stroke-width:2.6; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:var(--wabu-loader-length);
  stroke-dashoffset:var(--wabu-loader-length);
  animation:wabu-loader-draw 1.7s ease-in-out infinite, wabu-loader-breathe 2.6s ease-in-out infinite;
}
@keyframes wabu-loader-draw{
  0%{ stroke-dashoffset:var(--wabu-loader-length); }
  60%{ stroke-dashoffset:0; }
  100%{ stroke-dashoffset:0; }
}
@keyframes wabu-loader-breathe{
  0%, 100%{ opacity:.55; }
  50%{ opacity:1; }
}
@media (prefers-reduced-motion: reduce){
  .wabu-loader path{ animation:none !important; stroke-dashoffset:0; opacity:.8; }
}

/* ---------- Miniatures Repérage (chargement dynamique, Sprint correctif) ----------
   Même recette que .employee-avatar-choice__avatar ci-dessus (placeholder
   toujours présent, "W" Wabu animé pendant le chargement réel, fondu à
   l'apparition, jamais d'icône cassée) — voir field_session_media_thumb_html()
   (includes/field_session_helpers.php). */
.fs-thumb{
  position:relative; width:var(--fs-thumb-size,140px); height:var(--fs-thumb-size,140px);
  border-radius:var(--radius-sm); overflow:hidden; background:var(--paper-2); flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
}
.fs-thumb-loader{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  background:var(--paper-2);
}
.fs-thumb img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
  opacity:0; transition:opacity 180ms ease;
}
.fs-thumb img.is-loaded{ opacity:1; }
.fs-thumb-play{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  color:#fff; background:rgba(0,0,0,.18); font-size:20px; pointer-events:none;
}
@media (prefers-reduced-motion: reduce){
  .fs-thumb img{ transition:none; }
}
[data-theme-style="neumorphism"] .fs-thumb{
  box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi);
}

/* Bouton de suppression superposé sur la miniature (photo/vidéo, onglet
   Repérages et fiche repérage) — même principe que .fs-media-delete côté
   Companion, jamais un bouton texte séparé sous l'image. AJAX (voir le
   <script> en bas de field_session_view.php), jamais un <form> séparé. */
.fs-thumb-delete-btn{
  position:absolute; top:4px; right:4px;
  width:24px; height:24px; border-radius:50%; border:none; cursor:pointer;
  background:rgba(0,0,0,.55); color:#fff; font-size:12px; line-height:1;
  display:flex; align-items:center; justify-content:center;
}
.fs-thumb-delete-btn:hover{ background:rgba(0,0,0,.75); }
.fs-thumb-delete-btn:disabled{ opacity:.6; cursor:default; }

/* Avatar rond avec initiales/photo (person_avatar_name_html(), nav.php,
   team-avatar) — bordure plate remplacée par un relief en neumorphism,
   ce thème n'utilisant jamais de bordure pour marquer un contour. */
[data-theme-style="neumorphism"] .person-avatar-circle{
  border:none;
  box-shadow:3px 3px 6px var(--neu-lo), -3px -3px 6px var(--neu-hi);
}
/* Exception : dans la nav, l'avatar garde la bordure plate même en
   neumorphism — effet retiré uniquement ici, inchangé partout ailleurs. */
[data-theme-style="neumorphism"] .nav-user-toggle .person-avatar-circle{
  border:1px solid var(--line-strong);
  box-shadow:none;
}

/* Croix de suppression d'une note de terrain (fiche repérage), à côté de la
   date — pas un bouton texte "Supprimer" séparé. */
.fs-note-delete-x{
  width:20px; height:20px; border-radius:50%; border:none; cursor:pointer;
  background:transparent; color:var(--ink-soft); font-size:11px; line-height:1;
  display:flex; align-items:center; justify-content:center;
}
.fs-note-delete-x:hover{ background:var(--red-bg); color:var(--red); }

.error-box{ background:var(--red-bg); color:var(--red); font-size:13px; padding:10px 12px; margin-bottom:18px; border-left:3px solid var(--red); border-radius:0 var(--radius-sm) var(--radius-sm) 0; }
.success-box{ background:var(--green-bg); color:var(--green); font-size:13px; padding:10px 12px; margin-bottom:18px; border-left:3px solid var(--green); border-radius:0 var(--radius-sm) var(--radius-sm) 0; }
.info-box{ background:var(--steel-light); color:var(--steel); font-size:13px; padding:10px 12px; margin-bottom:18px; border-left:3px solid var(--steel); border-radius:0 var(--radius-sm) var(--radius-sm) 0; display:flex; gap:9px; align-items:flex-start; }
.info-box > .wabu-icon{ flex:0 0 auto; margin-top:1px; opacity:.75; }
.info-box p{ margin:0; }
.info-box p + p{ margin-top:5px; }
.info-box strong{ color:var(--ink); }
/* `display:flex` ci-dessus bat l'attribut natif [hidden] : sans cette règle,
   une info-box marquée `hidden` resterait visible. */
.info-box[hidden]{ display:none; }
/* Panneau de maintenance (page de connexion) — famille « en cours » (--amber),
   jamais le rouge d'erreur : une maintenance annoncée n'est pas une panne. */
.maintenance-box{ background:var(--amber-bg); border-left:3px solid var(--amber); border-radius:0 var(--radius-sm) var(--radius-sm) 0; padding:14px 16px; display:flex; gap:12px; align-items:flex-start; }
.maintenance-box > .wabu-icon{ flex:0 0 auto; margin-top:1px; }
.maintenance-box h2{ font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase; font-size:14px; letter-spacing:.03em; margin:0 0 5px; color:var(--amber-dark); }
/* overflow-wrap : un message collé sans espace ne fait jamais déborder le panneau. */
.maintenance-box p{ margin:0; font-size:13px; line-height:1.55; color:var(--ink); overflow-wrap:anywhere; }
/* Bandeau d'une section PLANIFIÉE d'un devis multidates (type, intitulé,
   période et lieu). Les sections ordinaires gardent leur `.section-title`. */
.prestation-band{ border-left:3px solid var(--brand); padding:8px 0 8px 12px; margin:18px 0 8px; }
.prestation-band .prestation-type{ font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase; font-size:13px; letter-spacing:.06em; color:var(--brand); }
.prestation-band .prestation-label{ font-size:14.5px; font-weight:600; color:var(--ink); margin-top:1px; overflow-wrap:anywhere; }
.prestation-band .prestation-meta{ font-size:12.5px; color:var(--ink-soft); margin-top:2px; overflow-wrap:anywhere; }
/* Panneau de saisie d'une prestation, dans le formulaire du devis. */
.prestation-panel{ background:var(--paper-2); border-left:3px solid var(--line-strong); padding:10px 12px; margin:0 0 10px; border-radius:0 var(--radius-sm) var(--radius-sm) 0; }
.prestation-panel.is-prestation{ border-left-color:var(--brand); }
/* Les champs sont des `.field` : c'est le SEUL endroit où cette feuille style
   les input/select (bordure basse, focus, variantes de thème). Des champs nus
   tombaient sur le rendu natif du navigateur et échappaient au neumorphism. */
.prestation-fields{ display:flex; flex-wrap:wrap; gap:8px 16px; align-items:flex-end; }
.prestation-fields > .field{ flex:0 1 170px; min-width:0; }
/* Aucune règle `display` n'est posée sur `.field` ici : l'attribut natif
   [hidden] doit continuer de suffire. Cette règle n'est qu'un garde-fou —
   une déclaration `display` explicite battrait [hidden] en silence, et
   « Date de fin » resterait visible case décochée. */
.prestation-fields > .field[hidden]{ display:none; }
.prestation-fields label.prestation-multiday{ display:flex; align-items:center; gap:6px; font-size:12px; color:var(--ink-soft); padding-bottom:8px; }
.prestation-fields > .field.prestation-location{ flex:1 1 220px; }
.prestation-summary{ font-size:11.5px; color:var(--ink-soft); margin-top:8px; }
.prestation-summary:empty{ display:none; }
/* Coefficient dérivé des dates : non modifiable, et visiblement tel. */
input.coef-derived{ background:var(--paper); color:var(--ink-soft); cursor:not-allowed; }

/* ---------- Gantt (dashboard) ---------- */
.gantt-panel{ overflow-x:auto; }
.gantt-months{ display:grid; grid-template-columns:200px repeat(12,1fr); font-family:'JetBrains Mono',monospace; font-size:10.5px; color:var(--ink-soft); text-transform:uppercase; border-bottom:1px solid var(--line-strong); padding-bottom:6px; margin-bottom:6px; min-width:900px; }
.gantt-months .month{ text-align:center; }
.gantt-row{ display:grid; grid-template-columns:200px repeat(12,1fr); align-items:center; min-height:34px; border-bottom:1px solid var(--line); min-width:900px; }
.gantt-row:last-child{ border-bottom:none; }
.gantt-label b{ display:block; font-size:12.5px; }
.gantt-label .client{ font-size:11px; color:var(--ink-soft); }
.gantt-track{ grid-column:span 12; position:relative; height:22px; }
.gantt-bar{ position:absolute; top:0; height:22px; border-radius:var(--radius-sm); font-size:10.5px; display:flex; align-items:center; padding:0 8px; white-space:nowrap; overflow:hidden; font-weight:500; }
.gantt-bar.prospect{ background:transparent; border:1.5px dashed var(--line-strong); color:var(--ink-soft); }
.gantt-bar.confirme{ background:var(--steel); color:#fff; }
.gantt-bar.en_cours{ background:var(--amber); color:var(--ink); }
.gantt-bar.termine{ background:var(--line-strong); color:var(--ink-soft); }

/* ---------- Team chips ---------- */
.team-project{ margin-bottom:16px; }
.team-project:last-child{ margin-bottom:0; }
.team-project h3{ font-family:'Barlow Condensed',sans-serif; text-transform:uppercase; font-size:14px; color:var(--ink-soft); margin:0 0 8px; }
.team-member{ display:inline-block; background:var(--steel-light); color:var(--steel); font-size:12px; padding:5px 10px; margin:0 6px 6px 0; border-radius:var(--radius-sm); }
.team-member small{ display:block; font-size:10px; opacity:.85; }

/* ---------- Calendrier mensuel (Agenda global agenda.php + widget Dashboard) ----------
   Source UNIQUE des styles de grille/cellule/événement — agenda.php (page complète)
   ET le widget Agenda du Dashboard (includes/dashboard/dashboard_calendar.php)
   réutilisent exactement ces classes, jamais une seconde interprétation graphique
   qui pourrait diverger au fil du temps (2026-08-21). agenda.php ne redéfinit plus
   ces règles localement dans un <style> de page. */
.cal-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:1px; background:var(--line); border:1px solid var(--line); }
.cal-dow{ background:var(--paper-2); text-align:center; font-size:10.5px; text-transform:uppercase; color:var(--ink-soft); padding:6px 0; }
/* L'en-tête de la colonne du jour porte le MÊME repère que sa colonne — la
   teinte s'arrête donc net en haut de la grille, comme dans Coordination.
   En vue Mois, l'en-tête nomme un jour de la SEMAINE : il n'est marqué que si
   le mois affiché contient réellement aujourd'hui, sinon il désignerait un
   mercredi quelconque. */
.cal-dow.today{ background:color-mix(in srgb, rgb(var(--brand-rgb)) 6%, var(--paper-2)); font-weight:700; }
.cal-cell{ background:var(--paper-2); min-height:100px; min-width:0; padding:6px; overflow:hidden; }
.cal-cell.empty{ background:var(--paper); }
/* La cellule du jour : la MÊME teinte de marque très diluée que la colonne
   « aujourd'hui » de Coordination et que la timeline du Planning
   (`.ptl-daycol.today`) — un accent discret qui suit le thème, plutôt que
   l'ambre, qui portait une couleur de STATUT (en cours, indisponibilité,
   déplacement) et faisait lire une alerte là où il n'y a qu'un repère.
   `color-mix` plutôt qu'un `rgba` : la grille laisse voir `--line` entre les
   cellules, une couleur translucide prendrait donc cette teinte-là. Le mélange,
   lui, reste opaque et se pose sur le même papier que les autres jours. */
.cal-cell.today{ background:color-mix(in srgb, rgb(var(--brand-rgb)) 6%, var(--paper-2)); }
/* Jours hors mois affiché — variante Dashboard uniquement (grille complète avec
   quantième atténué plutôt qu'une cellule totalement vide comme agenda.php,
   qui n'a pas ce besoin sur une page pleine largeur) : additive, agenda.php ne
   pose jamais cette classe, donc son rendu est strictement inchangé. */
.cal-cell.cal-cell-outside{ background:var(--paper); opacity:.55; }
/* Cellule Semaine (widget Dashboard) — plus haute qu'une cellule Mois classique
   pour laisser respirer moins de jours affichés simultanément ; additive, ne
   change rien à .cal-cell de base (agenda.php n'utilise jamais ce modificateur). */
.cal-cell.cal-cell-week{ min-height:170px; max-height:340px; overflow-y:auto; }
.cal-daynum{ font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--ink-soft); margin-bottom:4px; }
/* Libellé du jour affiché uniquement dans la vue Semaine du Dashboard en
   mobile empilé (voir media query plus bas) — masqué par défaut. */
.cal-cell-weekday-label{ display:none; text-transform:uppercase; letter-spacing:.03em; }
.cal-item{ display:block; font-size:10px; padding:2px 5px; border-radius:2px; margin-bottom:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-decoration:none; color:inherit; }
.cal-item:hover{ text-decoration:underline; }
.cal-item.vehicle{ background:var(--green-bg); color:var(--green); }
.cal-item.reunion{ background:var(--steel-light); color:var(--steel); border-left:2px solid var(--steel); }
.cal-item.conge{ background:var(--red-bg); color:var(--red); border-left:2px solid var(--red); }
.cal-item.deplacement{ background:var(--amber-bg); color:var(--amber-dark); border-left:2px solid var(--amber-dark); }
.cal-item.tache{ background:var(--steel-light); color:var(--steel); border-left:2px solid var(--steel); }
.cal-item.autre{ background:var(--line); color:var(--ink-soft); }
.cal-item.reperage{ background:var(--green-bg); color:var(--green); border-left:2px solid var(--green); }
/* Événements projet (complément Agenda, 2026-08-25) — couleur = STATUT du
   projet, jamais son type de phase (§9 du complément) : réutilise
   EXACTEMENT la palette déjà définie par PROJECT_STATUS_BADGE_CLASS/.badge.*
   (includes/project_status_helpers.php), jamais une seconde palette.
   'confirme'/'en_cours' existaient déjà ci-dessus (repris tels quels) ;
   'prospect'/'termine' complètent l'ensemble des 5 classes possibles
   ('annule' n'apparaît jamais : filtré à la source, un projet annulé ne
   génère aucun événement Agenda, §10 du complément). */
.cal-item.confirme{ background:var(--steel-light); color:var(--steel); }
.cal-item.en_cours{ background:var(--amber-bg); color:var(--amber-dark); }
.cal-item.prospect{ background:transparent; border:1.5px dashed var(--line-strong); color:var(--ink-soft); }
.cal-item.termine{ background:var(--green-bg); color:var(--green); }
/* Congés/Indisponibilités (Planning V1, 2026-08-25) — 'conge_attente' reprend
   la palette rouge de 'conge' ci-dessus mais en pointillé, même convention
   EXACTEMENT que .badge.prospect (ligne 180) pour "pas encore confirmé".
   'indisponibilite' réutilise la palette ambre déjà partagée par
   déplacement/montage (couleur reprise entre types, déjà la norme dans ce
   fichier, cf. reunion/tache identiques ci-dessus). */
.cal-item.conge_attente{ background:var(--red-bg); color:var(--red); border-left:2px dashed var(--red); }
.cal-item.indisponibilite{ background:var(--amber-bg); color:var(--amber-dark); border-left:2px solid var(--amber-dark); }
/* "+N de plus" (widget Dashboard uniquement, plafond d'items/cellule — agenda.php
   n'a pas cette limite sur sa page pleine largeur). */
.cal-more{ font-size:10.5px; color:var(--ink-soft); padding:2px 5px; }

/* ---------- Planning opérationnel — Timeline multi-projets ----------
   LOT UX1 (refonte visuelle, 2026-08-30) -- remplace intégralement la
   présentation du LOT 3/4 pour se conformer à la maquette de référence
   (docs/inspirations/planning operationnel.png) : colonne projets à gauche
   (sticky au scroll horizontal, §31 du lot), grille jour à droite, UN SEUL
   panneau de détail sous la timeline pour le projet sélectionné (jamais
   plus un dépliage par ligne). Grille jour (7 colonnes) partagée par
   l'en-tête (.ptl-days-header) et chaque ligne projet (.ptl-row-head),
   toutes deux avec EXACTEMENT le même grid-template-columns (colonne
   libellé fixe + 7 colonnes jour égales) pour garantir l'alignement visuel.
   Couleur des blocs de phase : DEVENUE une couleur PAR TYPE DE PHASE
   (.ptl-bar.phase-montage/permanence/demontage), plus une couleur de
   statut projet réutilisée à tort d'un onglet à l'autre -- changement de
   convention documenté et justifié dans le rapport du lot (§15 de la
   demande) : la maquette distingue les 3 phases de façon constante quel
   que soit le statut du projet, le statut reste visible séparément (badge
   dans la colonne projet). */
.ptl-panel{ overflow-x:auto; padding:0; }

/* Barre de contrôle (§6 de la demande) */
.ptl-controlbar{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:14px; padding:16px 18px; border-bottom:1px solid var(--line); }
.ptl-controlbar-left{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.ptl-view-switch{ display:flex; gap:2px; background:var(--paper); border-radius:var(--radius-sm); padding:3px; }
.ptl-view-btn{ border:none; background:transparent; padding:6px 13px; font-size:12.5px; border-radius:4px; cursor:pointer; color:var(--ink-soft); font-family:inherit; }
.ptl-view-btn.active{ background:var(--paper-2); color:var(--ink); font-weight:600; box-shadow:var(--shadow-card); }
.ptl-view-btn:disabled{ cursor:not-allowed; opacity:.4; }
.ptl-nav-controls{ display:flex; align-items:center; gap:10px; }
/* Vue Jour : le retour au Planning general se detache de la navigation entre
   journees par un simple espace. Un filet 1px a ete essaye puis abandonne :
   invisible sur les themes sombres neumorphiques, donc du markup mort. */
.ptl-back-link{ font-weight:600; margin-right:8px; }
.ptl-period{ font-weight:700; font-size:14px; white-space:nowrap; }
.ptl-week-num{ color:var(--ink-soft); font-size:12px; white-space:nowrap; }
.ptl-search-controls{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.ptl-search-controls input[type="text"]{ min-width:220px; }
.ptl-goto{ font-size:13px; color:var(--ink-soft); }
.ptl-goto summary{ cursor:pointer; }

/* Grille (en-tête + lignes) */
.ptl-timeline-scroll{ overflow-x:auto; }
.ptl-days-header{ display:grid; grid-template-columns:260px repeat(7,1fr); gap:0; border-bottom:1.5px solid var(--line-strong); min-width:1080px; }
.ptl-days-header-corner{ position:sticky; left:0; z-index:3; background:var(--paper-2); }
.ptl-daycol{ text-align:center; font-size:11px; text-transform:uppercase; letter-spacing:.03em; color:var(--ink-soft); padding:8px 2px; border-left:1px solid var(--line); }
.ptl-daycol.today{ color:var(--ink); font-weight:700; background:rgba(var(--brand-rgb),.08); }
.ptl-daycol.weekend:not(.today){ opacity:.65; }
.ptl-today-label{ display:block; font-size:9px; font-weight:600; letter-spacing:.02em; text-transform:none; color:var(--brand); margin-top:1px; }
.ptl-daynum{ font-family:'JetBrains Mono',monospace; font-size:13px; color:var(--ink); font-weight:600; }

.ptl-rows{ min-width:1080px; }
.ptl-row{ border-bottom:1px solid var(--line); cursor:pointer; }
.ptl-row:hover .ptl-row-info{ background:var(--paper); }
.ptl-row.selected .ptl-row-info{ background:rgba(var(--brand-rgb),.07); box-shadow:inset 3px 0 0 var(--brand); }
.ptl-row-head{ display:grid; grid-template-columns:260px repeat(7,1fr); align-items:stretch; min-height:74px; }
.ptl-row-info{ position:sticky; left:0; z-index:2; background:var(--paper-2); padding:10px 14px; display:flex; flex-direction:column; justify-content:center; gap:2px; border-right:1px solid var(--line); }
.ptl-row-ref{ font-weight:700; font-size:12.5px; }
.ptl-row-name{ font-weight:600; font-size:13.5px; line-height:1.25; }
.ptl-row-client{ color:var(--ink-soft); font-size:11.5px; }
.ptl-row-rh{ display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--ink-soft); margin-top:2px; flex-wrap:wrap; }
.ptl-row-rh .missing{ color:var(--red); font-weight:600; display:inline-flex; align-items:center; gap:3px; }
.ptl-row-rh .covered{ color:var(--green); font-weight:600; display:inline-flex; align-items:center; gap:3px; }
.ptl-row-conflict{ color:var(--red); font-weight:600; font-size:11px; display:inline-flex; align-items:center; gap:3px; }

.ptl-track{ grid-column:2 / -1; display:grid; grid-template-columns:repeat(7,1fr); grid-auto-rows:1fr; position:relative; border-left:1px solid var(--line); }
.ptl-daybg{ grid-row:1; border-right:1px solid var(--line); }
.ptl-daybg.weekend{ background:var(--paper); }
.ptl-daybg.today{ background:rgba(var(--brand-rgb),.05); }
.ptl-bar{ position:static; grid-row:1; align-self:center; margin:3px 3px; padding:5px 9px; border-radius:var(--radius-sm); text-decoration:none; display:flex; flex-direction:column; justify-content:center; gap:1px; min-height:38px; box-sizing:border-box; overflow:hidden; }
.ptl-bar-label{ font-size:11.5px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ptl-bar-ratio{ font-size:11px; font-weight:700; opacity:.92; }
.ptl-bar.phase-montage{ background:var(--phase-montage-bg); color:#fff; }
.ptl-bar.phase-permanence{ background:var(--phase-permanence-bg); color:#fff; }
.ptl-bar.phase-demontage{ background:var(--phase-demontage-bg); color:#fff; }
.ptl-bar.highlight{ outline:2px solid var(--brand); outline-offset:1px; }
.ptl-row-empty{ grid-column:2/-1; grid-row:1; align-self:center; text-align:center; font-size:12px; color:var(--ink-soft); font-style:italic; }

/* Légende + total (§33-34 de la demande) */
.ptl-legend{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:12px; padding:12px 18px; border-top:1px solid var(--line); font-size:12px; color:var(--ink-soft); }
.ptl-legend-items{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.ptl-legend-item{ display:flex; align-items:center; gap:6px; }
.ptl-legend-swatch{ width:11px; height:11px; border-radius:3px; display:inline-block; }
.ptl-legend-swatch.phase-montage{ background:var(--phase-montage-bg); }
.ptl-legend-swatch.phase-permanence{ background:var(--phase-permanence-bg); }
.ptl-legend-swatch.phase-demontage{ background:var(--phase-demontage-bg); }
.ptl-legend-swatch.phase-none{ background:var(--line-strong); }
.ptl-legend-total{ font-size:13px; color:var(--ink); }
.ptl-legend-total .missing{ color:var(--red); font-weight:700; }

/* Panneau de détail du projet sélectionné (§18-25 de la demande) */
.ptl-detail-head{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:10px; padding:16px 18px; border-bottom:1px solid var(--line); }
.ptl-detail-head-info{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
.ptl-detail-head-info .client{ font-size:12.5px; color:var(--ink-soft); }
.ptl-detail-columns{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:0; align-items:start; }
.ptl-detail-col{ padding:16px 18px; border-right:1px solid var(--line); min-width:0; }
.ptl-detail-col:last-child{ border-right:none; }
.ptl-detail-col-title{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin-bottom:10px; display:flex; align-items:center; justify-content:space-between; }
.ptl-mini-table{ width:100%; border-collapse:collapse; font-size:12.5px; }
.ptl-mini-table th{ text-align:left; font-size:10px; text-transform:uppercase; letter-spacing:.03em; color:var(--ink-soft); padding:4px 6px 6px 0; border-bottom:1px solid var(--line-strong); }
.ptl-mini-table td{ padding:6px 6px 6px 0; border-bottom:1px solid var(--line); vertical-align:middle; }
.ptl-mini-table tr.total td{ font-weight:700; border-bottom:none; padding-top:8px; }
.ptl-mini-table .num{ font-family:'JetBrains Mono',monospace; text-align:right; }
/* Couleur de texte par type de phase -- réutilisée à la fois par les libellés
   du tableau "Besoins RH par phase" et par la colonne Phase du tableau
   "Affectations" (même 3 couleurs EXACTEMENT que les blocs de la timeline
   ci-dessus, jamais une seconde palette). */
.phase-montage{ color:var(--steel); }
.phase-permanence{ color:var(--green); }
.phase-demontage{ color:var(--violet); }
.ptl-employee-cell{ display:flex; align-items:center; gap:6px; }
.ptl-detail-empty{ font-size:12px; color:var(--ink-soft); font-style:italic; padding:6px 0; }
.ptl-detail-actions{ display:flex; gap:6px; flex-wrap:wrap; }
.ptl-see-all{ display:inline-block; margin-top:8px; font-size:12px; }
.ptl-status-legend{ display:flex; gap:14px; flex-wrap:wrap; padding:10px 18px; border-top:1px solid var(--line); font-size:11.5px; color:var(--ink-soft); }
.ptl-status-legend-item{ display:flex; align-items:center; gap:5px; }
.ptl-status-dot{ width:9px; height:9px; border-radius:50%; display:inline-block; }
.ptl-status-dot.termine{ background:var(--green); }
.ptl-status-dot.en_cours{ background:var(--amber); }
.ptl-status-dot.annule{ background:var(--red); }
.ptl-status-dot.hors-besoin{ background:var(--line-strong); }

@media (max-width: 1100px){
  .ptl-detail-columns{ grid-template-columns:1fr; }
  .ptl-detail-col{ border-right:none; border-bottom:1px solid var(--line); }
}

/* ============================================================
   VUE JOUR — timeline horaire + blocs d'équipes RH (2026-08-30, refonte
   complète remplaçant l'essai "pool RH + besoins-slots" du lot précédent).
   Horizontal = heures, vertical = projets, chaque projet = une piste-grille
   partageant EXACTEMENT les mêmes colonnes que l'en-tête (repeat(N,
   minmax(18px,1fr)) des deux côtés) pour un alignement pixel-perfect, même
   technique que .ptl-track/.ptl-days-header (LOT UX1).
   ============================================================ */

.pjt-timeline-scroll{ overflow-x:auto; padding-top:22px; }
.pjt-board{ display:grid; grid-template-columns:160px 1fr; position:relative; }

.pjt-corner{ position:sticky; left:0; top:0; z-index:4; background:var(--paper-2); border-right:1px solid var(--line); border-bottom:1px solid var(--line); padding:8px 10px; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--ink-soft); display:flex; align-items:center; }
.pjt-hours-header{ position:sticky; top:0; z-index:3; background:var(--paper-2); border-bottom:1px solid var(--line); display:grid; }
.pjt-hour-label{ font-size:11px; color:var(--ink-soft); padding:8px 0 8px 4px; border-left:1px solid var(--line); font-family:'JetBrains Mono',monospace; }
.pjt-hour-nextday{ margin-left:3px; font-size:8.5px; font-weight:700; letter-spacing:.02em; color:var(--amber-dark); background:var(--amber-bg); border-radius:2px; padding:0 3px; vertical-align:1px; }
/* Repere de minuit (§5) : un peu plus marque que les lignes horaires, jamais
   une rupture -- la journee operationnelle continue apres minuit. */
.ptl-nav-controls .btn.disabled{ opacity:.4; cursor:default; pointer-events:none; } /* plus aucune journée opérationnelle de ce côté */
.pjt-day-break{ grid-column:2; position:relative; z-index:1; pointer-events:none; }
.pjt-day-break[hidden]{ display:none; }
.pjt-day-break-line{ position:absolute; top:0; bottom:0; width:2px; background:var(--line-strong); }

.pjt-project-label{ position:sticky; left:0; z-index:2; background:var(--paper-2); border-right:1px solid var(--line); border-bottom:1px solid var(--line); padding:8px 10px; display:flex; flex-direction:column; justify-content:center; gap:2px; min-width:0; }
.pjt-project-head{ display:flex; align-items:center; gap:6px; min-width:0; }
.pjt-project-ref{ font-weight:700; font-size:13px; color:var(--ink); text-decoration:none; }
/* Ce qui est prévu ce jour-là : mêmes pastilles EXACTEMENT que la légende
   (.pjt-legend-swatch), jamais une seconde palette. */
.pjt-project-phases{ display:flex; align-items:center; gap:3px; flex-shrink:0; }
.pjt-project-phases .pjt-legend-swatch{ width:9px; height:9px; border-radius:2px; }
.pjt-project-ref:hover{ text-decoration:underline; color:var(--brand); }
.pjt-project-name{ font-size:11px; color:var(--ink-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pjt-project-count{ font-size:11px; color:var(--ink-soft); font-family:'JetBrains Mono',monospace; opacity:.85; } /* remplace le ratio qui était affiché dans chaque bloc */

.pjt-project-track{
  position:relative; border-bottom:1px solid var(--line); display:grid; row-gap:6px; padding:4px 0;
}

/* Grille horaire verticale (2026-08-30) -- UNE seule couche pour toute la
   zone Planning, à la place de l'ancien fond répété piste par piste (qui
   s'arrêtait à chaque ligne projet). Même colonne de grille (2) et même
   largeur que les pistes, donc EXACTEMENT le même alignement que les libellés
   d'heures de l'en-tête (.pjt-hour-label, border-left au début de chaque
   heure) -- alignement conservé au scroll horizontal puisque tout est dans la
   même grille .pjt-board. Rendue AVANT les pistes dans le DOM et laissée en
   z-index:0 : les blocs (position:relative) restent toujours au premier plan,
   la ligne "heure actuelle" (.pjt-now-line, z-index:10, couleur --brand)
   reste nettement plus visible. Jamais posée sur la colonne projet sticky. */
.pjt-grid-lines{
  grid-column:2; position:relative; z-index:0; pointer-events:none;
  /* --line-strong et non --line : --line vaut volontairement `transparent` en
     thème Neumorphism (clair comme sombre), où la grille serait alors
     totalement invisible. --line-strong est défini dans les quatre thèmes et
     y reste un trait doux : discret sans disparaître, et jamais une couleur
     codée en dur. */
  background-image:repeating-linear-gradient(to right, var(--line-strong) 0, var(--line-strong) 1px, transparent 1px, transparent calc(100% / var(--pjt-hours, 16)));
}
/* Demi-heures : même trait, simplement atténué (pas de color-mix(), non
   utilisé dans ce fichier ; pas de couleur codée en dur non plus) : les
   demi-heures restent nettement plus discrètes que les heures pleines. */
.pjt-grid-lines::before{
  content:''; position:absolute; inset:0; opacity:.45;
  background-image:repeating-linear-gradient(to right,
    transparent 0,
    transparent calc(50% / var(--pjt-hours, 16)),
    var(--line-strong) calc(50% / var(--pjt-hours, 16)),
    var(--line-strong) calc(50% / var(--pjt-hours, 16) + 1px),
    transparent calc(50% / var(--pjt-hours, 16) + 1px),
    transparent calc(100% / var(--pjt-hours, 16)));
}

.pjt-block{
  position:relative; display:flex; flex-direction:row; align-items:center; gap:10px;
  height:54px; box-sizing:border-box; border-radius:8px; padding:3px 8px 3px 12px; color:#fff; overflow:hidden;
  cursor:grab; user-select:none; border:1px solid transparent;
  /* Dégradé vertical très léger (un peu plus clair en haut, plus foncé en
     bas) posé PAR-DESSUS la couleur de phase : les couleurs de type restent
     celles du design system, aucune n'est redéfinie ici. Aucune ombre portée
     (et aucune ombre neumorphism : aucun thème n'en applique aux blocs). */
  background-image:linear-gradient(to bottom, rgba(255,255,255,.10), rgba(0,0,0,.10));
}
.pjt-block.readonly{ cursor:default; }
.pjt-block.phase-montage{ background-color:var(--phase-montage-bg); }
.pjt-block.phase-permanence{ background-color:var(--phase-permanence-bg); }
.pjt-block.phase-demontage{ background-color:var(--phase-demontage-bg); }
.pjt-block.phase-autre{ background-color:var(--phase-autre-bg); } /* type additionnel (libellé libre) -- orange de la légende */
/* Survol : mise en évidence très sobre (bordure + fond à peine plus clair). */
.pjt-block:not(.readonly):hover{ border-color:rgba(255,255,255,.35); background-image:linear-gradient(to bottom, rgba(255,255,255,.18), rgba(0,0,0,.06)); }
.pjt-block.dragging, .pjt-block.resizing{ z-index:50; box-shadow:0 4px 14px rgba(0,0,0,.45); cursor:grabbing; }
.pjt-block.continuation{ cursor:pointer; } /* segment de fin d'un creneau commence la veille : ni drag ni resize ici */
.pjt-block-cross{
  display:inline-block; font-size:9.5px; font-weight:700; letter-spacing:.02em; text-transform:uppercase;
  background:rgba(0,0,0,.28); border-radius:3px; padding:0 4px; vertical-align:1px;
}
.pjt-block.cut{ opacity:.55; outline:1px dashed rgba(255,255,255,.55); outline-offset:-3px; } /* coupé : en attente de collage, AUCUNE donnée modifiée */
.pjt-block.saving{ opacity:.75; } /* enregistrement en cours : le bloc reste A SA NOUVELLE POSITION, jamais masque ni remis a l'ancienne */
.pjt-block-main{ display:flex; flex-direction:column; justify-content:center; gap:2px; min-width:0; flex-shrink:0; }
/* Dégradation progressive du contenu selon la largeur RÉELLE du bloc
   (assets/js/planning-day-timeline.js, layoutBlockContent()) : la géométrie
   temporelle n'est jamais modifiée, seul le contenu s'efface. Le menu ⋮ est le
   dernier élément à survivre. */
.pjt-block.is-hide-avatars .pjt-block-avatars{ display:none; }
.pjt-block.is-hide-time .pjt-block-time{ display:none; }
.pjt-block.is-ellipsis .pjt-block-main{ display:none; }
.pjt-block.is-ellipsis::before{ content:'…'; font-size:13px; line-height:1; opacity:.85; }
.pjt-block.is-menu-only{ padding-left:2px; padding-right:2px; gap:0; }
.pjt-block.is-menu-only::before{ content:none; }
/* Zone cliquable préservée sur un bloc minuscule, sans toucher à sa largeur. */
.pjt-block.is-menu-only .pjt-block-menu{ margin:0; width:100%; height:100%; padding:0; } /* toute la surface du bloc devient la zone cliquable du menu */
.pjt-block-type{ font-weight:700; font-size:11px; letter-spacing:.04em; text-transform:uppercase; white-space:nowrap; }
.pjt-block-menu{
  background:none; border:none; color:#fff; opacity:.75; cursor:pointer; padding:0 2px; font-size:15px;
  line-height:1; flex-shrink:0; margin-left:auto; border-radius:4px;
}
.pjt-block-menu:hover, .pjt-block-menu[aria-expanded="true"]{ opacity:1; background:rgba(0,0,0,.22); }
/* Menu ⋮ d'une LIGNE PROJET : même dessin que celui d'un bloc, mais posé sur la
   colonne projet (fond --paper-2) et non sur la couleur de phase. Il lui faut
   donc l'encre du thème -- le blanc de .pjt-block-menu le rendait invisible en
   thème clair. Déclaré APRÈS et plus spécifique pour que l'intention gagne
   quel que soit l'ordre de lecture. */
.pjt-project-head .pjt-project-menu{ margin-left:auto; color:var(--ink-soft); opacity:1; font-size:14px; }
.pjt-project-head .pjt-project-menu:hover,
.pjt-project-head .pjt-project-menu[aria-expanded="true"]{ color:var(--ink); background:var(--paper); }
.pjt-block-time{ font-size:11px; opacity:.92; white-space:nowrap; font-family:'JetBrains Mono',monospace; }
/* Menu d'actions du bloc -- rendu dans <body> (le bloc est en overflow:hidden). */
.pjt-block-actions{
  position:fixed; z-index:120; min-width:170px; padding:5px; background:var(--paper-2);
  border:1px solid var(--line-strong); border-radius:var(--radius-sm); box-shadow:var(--shadow-card);
}
/* Les entrées de menu sont des <button> OU des <a> (« Voir le projet » reste un
   vrai lien : clic milieu, nouvel onglet). Elles doivent être indiscernables. */
.pjt-block-actions button,
.pjt-block-actions a{
  display:block; width:100%; text-align:left; background:none; border:none; cursor:pointer;
  padding:7px 10px; font:inherit; font-size:13px; color:var(--ink); border-radius:var(--radius-sm);
  text-decoration:none; box-sizing:border-box;
}
.pjt-block-actions button:hover,
.pjt-block-actions a:hover{ background:var(--paper); color:var(--ink); }
.pjt-block-actions button.danger{ color:var(--red); }
.pjt-block-avatars{ display:flex; align-items:center; gap:4px; overflow:hidden; white-space:nowrap; flex:1; min-width:0; position:relative; justify-content:flex-end; }
.pjt-block-avatar{ flex-shrink:0; line-height:0; }
.pjt-block-avatar .person-avatar-circle{ border-color:rgba(255,255,255,.7); }
/* Même exception que .nav-user-toggle plus haut : dans un bloc de la timeline,
   l'avatar garde sa bordure plate et PERD le relief neumorphism (§1 de la
   demande : aucune ombre neumorphism sur les blocs -- posé sur la couleur de
   phase, ce relief remplissait les angles et faisait lire l'avatar comme un
   carré arrondi). Portée limitée au bloc, avatars inchangés partout ailleurs. */
[data-theme-style="neumorphism"] .pjt-block-avatar .person-avatar-circle{
  border:1px solid rgba(255,255,255,.7);
  box-shadow:none;
}
.pjt-block-more{ flex-shrink:0; background:rgba(0,0,0,.4); color:#fff; border-radius:50%; width:28px; height:28px; display:flex; align-items:center; justify-content:center; font-size:10px; font-weight:700; cursor:pointer; } /* survol = liste complète des personnes */
.pjt-block-more[hidden]{ display:none; }
/* Liste des personnes du bloc ouverte par le badge "+N". Celle rendue DANS le
   bloc ne sert que de gabarit (toujours masquée) : le bloc est en
   overflow:hidden, une popover posée à l'intérieur était rognée par ses bords
   et restait donc illisible. Le JS en place une copie dans <body>
   (.pjt-block-popover--floating, position:fixed), au-dessus ou en dessous du
   badge selon la place disponible. */
.pjt-block-popover{ position:absolute; bottom:100%; left:0; margin-bottom:6px; background:var(--paper-2); border:1px solid var(--line-strong); border-radius:var(--radius-sm); box-shadow:var(--shadow-card); padding:8px 12px; z-index:30; min-width:170px; color:var(--ink); }
.pjt-block-popover-item{ padding:3px 0; font-size:12px; white-space:nowrap; }
/* Toute l'équipe lisible d'un coup : les noms se répartissent en colonnes
   (nombre de lignes posé par le JS selon l'effectif) plutôt que dans une
   petite fenêtre à faire défiler. Les limites de viewport ci-dessous ne
   servent que de garde-fou pour un effectif hors norme. */
.pjt-block-popover--floating{
  position:fixed; bottom:auto; left:auto; margin:0; z-index:130;
  display:grid; grid-auto-flow:column; grid-template-rows:repeat(var(--pjt-popover-rows, 1), auto);
  column-gap:22px; align-content:start;
  max-height:calc(100vh - 24px); max-width:calc(100vw - 24px); overflow:auto;
}
/* ============================================================================
   PLANNING OPÉRATIONNEL — DASHBOARD GÉNÉRALE
   ----------------------------------------------------------------------------
   Refonte visuelle du 2026-08-31, d'après docs/inspirations/planning-prompt-2.png :
   grandes cartes, sous-cartes, hiérarchie des chiffres, timeline verticale,
   indicateurs circulaires. Densité maîtrisée, pas de décoration.

   Tout vient des variables de thème (--ink, --paper, --line-strong, --red,
   --green, --phase-*) : clair, sombre et neumorphisme suivent sans une seule
   règle dédiée, et aucune couleur n'est écrite en dur ici.
   ========================================================================== */
/* En-tête de page du module Planning — PARTAGÉ par la dashboard et la Vue Jour :
   titre à gauche, date à droite. Une seule règle, donc les deux pages ne
   peuvent pas diverger. */
.pplan-head{ display:flex; align-items:baseline; justify-content:space-between; gap:16px; flex-wrap:wrap; margin-bottom:16px; }
.pplan-title{ font-size:19px; font-weight:700; letter-spacing:.02em; margin:0; }
.pplan-date{ font-size:12px; letter-spacing:1.2px; color:var(--ink-soft); }

.pdash .panel{ margin-bottom:18px; }
.pdash-kicker{ font-size:11px; letter-spacing:1.6px; text-transform:uppercase; color:var(--ink-soft); margin-bottom:16px; }
.pdash-empty{ font-size:13px; color:var(--ink-soft); font-style:italic; }
.pdash-note{ font-size:12px; color:var(--ink-soft); }
/* `align-self` : dans une colonne flex, un bouton s'étirerait sur toute la
   largeur du panneau -- une action doit rester de la taille de son libellé. */
.pdash-action{ display:inline-flex; align-self:flex-start; align-items:center; gap:6px; margin-top:14px; }

/* --- Colonnes : « Prochainement » domine, la colonne secondaire empile ----- */
.pdash-columns{ display:grid; grid-template-columns:minmax(0, 1.9fr) minmax(320px, 1fr); gap:18px; align-items:start; }
.pdash-side{ display:flex; flex-direction:column; gap:18px; }
.pdash-side .panel{ margin-bottom:0; }
@media (max-width:1180px){ .pdash-columns{ grid-template-columns:1fr; } }

/* ============================== AUJOURD'HUI ============================== */
.pdash-today-grid{ display:grid; grid-template-columns:minmax(280px, 0.9fr) minmax(0, 2fr); gap:26px; align-items:start; }
@media (max-width:900px){ .pdash-today-grid{ grid-template-columns:1fr; } }

.pdash-stats{ display:flex; flex-wrap:wrap; gap:12px; align-items:stretch; }
/* Sous-cartes : c'est la hiérarchie des chiffres de la référence -- un grand
   nombre, une étiquette discrète, une icône officielle. */
.pdash-stat{ flex:1 1 110px; display:flex; flex-direction:column; gap:2px; padding:14px;
             background:var(--paper); border:1px solid var(--line-strong); border-radius:var(--radius-sm); }
.pdash-stat-icon{ display:inline-flex; margin-bottom:6px; opacity:.75; }
.pdash-stat-figure{ font-size:26px; font-weight:700; line-height:1; }
.pdash-stat-label{ font-size:11.5px; color:var(--ink-soft); line-height:1.35; }
/* Le donut occupe toute la largeur de la colonne, à l'horizontale : la colonne
   de gauche est trop étroite pour aligner trois sous-cartes comme sur la
   référence, et l'empiler verticalement doublerait la hauteur de la carte. */
.pdash-stat-donut{ flex:1 1 100%; flex-direction:row; align-items:center; gap:14px; }
.pdash-stat-donut .pdash-stat-label{ font-size:12px; }

.pdash-today-projects{ display:flex; flex-direction:column; gap:14px; }
.pdash-today-project{ border-left:2px solid var(--line-strong); padding-left:16px; }
.pdash-live{ display:inline-flex; align-items:center; gap:6px; font-size:11px; letter-spacing:1.2px;
             text-transform:uppercase; color:var(--green); margin-bottom:6px; }
.pdash-live-dot{ width:7px; height:7px; border-radius:50%; background:var(--green); }
.pdash-today-ref{ font-size:18px; font-weight:700; }
.pdash-today-name{ font-size:13px; color:var(--ink-soft); margin-top:1px; }
.pdash-today-meta{ display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; }

/* Progression temporelle : elle n'apparaît QUE si l'instant présent tombe dans
   l'amplitude réelle des blocs -- le curseur n'est jamais posé au hasard. */
.pdash-progress{ display:flex; align-items:center; gap:12px; margin-top:12px; max-width:520px; }
.pdash-progress-time{ font-family:'JetBrains Mono',monospace; font-size:11.5px; color:var(--ink-soft); white-space:nowrap; }
.pdash-progress-rail{ position:relative; flex:1; height:4px; border-radius:2px; background:var(--line-strong); }
.pdash-progress-done{ position:absolute; left:0; top:0; bottom:0; border-radius:2px; background:var(--green); }
.pdash-progress-cursor{ position:absolute; top:50%; width:11px; height:11px; margin-left:-5.5px;
                        transform:translateY(-50%); border-radius:50%; background:var(--green); }
/* Même repère « +1j » que la Vue Jour (.pjt-hour-nextday) : mêmes tokens,
   pour que le passage de minuit se lise pareil dans tout le module. */
.pdash-nextday{ margin-left:5px; font-size:9px; font-weight:700; color:var(--amber-dark);
                background:var(--amber-bg); border-radius:2px; padding:0 3px; }

.pdash-people{ display:flex; align-items:center; gap:8px; margin-top:12px; flex-wrap:wrap; }
.pdash-avatar{ display:inline-flex; }
.pdash-people-count{ font-size:12px; color:var(--ink-soft); }

/* ============================= PROCHAINEMENT ============================= */
/* Timeline VERTICALE : une date, un point sur un rail continu, une carte. On
   doit sentir que les journées arrivent dans le temps, pas lire un tableau. */
.pdash-timeline, .pagenda-timeline, .pops-timeline, .prh-timeline, .roadmap-timeline{ list-style:none; margin:0; padding:0; }
.pdash-tl-item, .pagenda-tl-item, .pops-tl-item, .prh-tl-item{ display:grid; grid-template-columns:62px 22px minmax(0, 1fr); gap:0 12px; }
.pdash-tl-date{ display:flex; flex-direction:column; align-items:center; padding-top:14px; text-align:center; }
.pdash-tl-dow{ font-size:10px; letter-spacing:.8px; color:var(--ink-soft); }
.pdash-tl-day{ font-size:23px; font-weight:700; line-height:1.05; }
.pdash-tl-month{ font-size:10px; letter-spacing:.8px; color:var(--ink-soft); }
/* Année : affichée seulement quand « Prochainement » traverse plusieurs
   années. Volontairement plus petite et plus effacée que le mois -- c'est
   une levée d'ambiguïté, pas une information de premier plan. */
.pdash-tl-year{ font-size:9px; letter-spacing:.6px; color:var(--ink-soft); opacity:.7; margin-top:1px; }
/* Le rail est porté par la colonne du point : un simple fond, plus un point
   coloré par la phase (mêmes couleurs que les blocs de la Vue Jour). */
.pdash-tl-rail{ position:relative; display:flex; justify-content:center; }
.pdash-tl-rail::before{ content:''; position:absolute; top:0; bottom:0; width:2px; background:var(--line-strong); }
.pdash-tl-item.last .pdash-tl-rail::before,
.roadmap-tl-item.last .pdash-tl-rail::before{ bottom:calc(100% - 34px); }
.pdash-tl-item:first-child .pdash-tl-rail::before,
.roadmap-tl-item:first-child .pdash-tl-rail::before{ top:20px; }
.pdash-tl-dot{ position:relative; width:11px; height:11px; border-radius:50%; margin-top:20px;
               box-shadow:0 0 0 3px var(--paper-2); }
.pdash-tl-dot.phase-montage{ background:var(--phase-montage-bg); }
.pdash-tl-dot.phase-permanence{ background:var(--phase-permanence-bg); }
.pdash-tl-dot.phase-demontage{ background:var(--phase-demontage-bg); }
.pdash-tl-dot.phase-autre{ background:var(--phase-autre-bg); }

.pdash-tl-card{ display:flex; align-items:center; gap:14px; text-decoration:none; color:inherit;
                background:var(--paper); border:1px solid var(--line-strong);
                border-radius:var(--radius-sm); padding:13px 15px; margin:8px 0; }
.pdash-tl-card:hover{ border-color:var(--ink-soft); }
.pdash-tl-projects{ flex:1; display:flex; flex-direction:column; gap:11px; min-width:0; }
.pdash-tl-project-head{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.pdash-tl-project-meta{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:4px; }
.pdash-open{ display:inline-flex; opacity:.55; flex-shrink:0; }
.pdash-tl-card:hover .pdash-open{ opacity:1; }

/* ===========================================================================
   TIMELINE DE L'ONGLET AGENDA D'UN PROJET (2026-09-01)
   Même famille visuelle que la timeline « Prochainement » du dashboard
   Planning : les règles structurelles (liste, grille date/rail/contenu, rail
   vertical, pastilles de phase) sont LITTÉRALEMENT les mêmes — .pagenda-* a
   été ajouté aux sélecteurs .pdash-* ci-dessus plutôt que recopié. Seules les
   règles réellement propres à cet écran vivent ici, et uniquement avec des
   tokens du design system : dark/light suivent sans règle dédiée.
   =========================================================================== */
.pagenda-actions{ display:inline-flex; gap:8px; }
/* Le bloc « Prochaine étape » est une lecture À PART, pas la première ligne
   de la timeline : il lui faut une vraie respiration en dessous, sinon les
   deux panels se lisent comme un seul. 18px = la même respiration que les
   panels empilés du dashboard Planning (.pdash .panel). */
.pagenda-next{ display:flex; flex-direction:column; gap:4px; margin-bottom:18px; }
.pagenda-next-kicker{ font-size:10.5px; letter-spacing:.8px; text-transform:uppercase; color:var(--ink-soft); }
.pagenda-next-line{ display:flex; align-items:center; gap:9px; font-size:15px; }
.pagenda-next-when{ color:var(--ink-soft); font-size:13px; }
.pagenda-next-title{ font-size:12.5px; color:var(--ink-soft); }
.pagenda-next-empty{ font-size:13px; color:var(--ink-soft); font-style:italic; }
.pagenda-dot{ width:9px; height:9px; border-radius:50%; display:inline-block; flex-shrink:0; background:var(--phase-autre-bg); }
.pagenda-dot.phase-montage{ background:var(--phase-montage-bg); }
.pagenda-dot.phase-permanence{ background:var(--phase-permanence-bg); }
.pagenda-dot.phase-demontage{ background:var(--phase-demontage-bg); }

/* Une journée peut porter plusieurs événements : ils s'empilent dans la même
   colonne, sous un seul point de rail — le rail reste la lecture du TEMPS,
   pas des cartes. */
.pagenda-tl-events{ display:flex; flex-direction:column; gap:8px; padding:14px 0 4px; min-width:0; }
/* Fond `--paper` + bordure `--line-strong`, comme .pdash-tl-card : deux des
   quatre thèmes posent `--line: transparent` et `--paper-2` = fond du panel,
   une carte en `--line`/`--paper-2` y serait donc littéralement invisible. */
.pagenda-tl-card{ display:flex; flex-direction:column; gap:3px; text-decoration:none; color:inherit;
  border:1px solid var(--line-strong); border-radius:var(--radius-sm); padding:9px 12px; background:var(--paper); }
.pagenda-tl-card:hover{ border-color:var(--ink-soft); }
.pagenda-tl-head{ display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.pagenda-tl-type{ font-size:10.5px; letter-spacing:.6px; text-transform:uppercase; color:var(--ink-soft); }
.pagenda-tl-time{ font-family:'JetBrains Mono',monospace; font-size:11.5px; color:var(--ink-soft); }
.pagenda-tl-title{ font-size:13.5px; font-weight:600; line-height:1.35; }
.pagenda-tl-people{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-top:4px; }
.pagenda-tl-more{ font-size:11px; color:var(--ink-soft); }

/* Position dans le temps — atténuation douce du passé, mise en avant discrète
   d'aujourd'hui et du prochain événement. Aucune couleur agressive : c'est
   l'opacité et une bordure qui portent l'information. */
.pagenda-tl-item.is-past{ opacity:.55; }
.pagenda-tl-item.is-past:hover{ opacity:1; }
.pagenda-tl-item.is-today .pdash-tl-day{ color:var(--brand); }
.pagenda-tl-item.is-today .pdash-tl-dot{ box-shadow:0 0 0 3px var(--paper-2), 0 0 0 6px color-mix(in srgb, var(--brand) 30%, transparent); }
.pagenda-tl-item.is-next .pagenda-tl-card{ border-color:var(--ink-soft); }

@media (max-width: 700px){
  .pdash-tl-item, .pagenda-tl-item{ grid-template-columns:46px 18px minmax(0, 1fr); gap:0 8px; }
  .pagenda-actions{ display:flex; flex-wrap:wrap; }
}

/* Assignés d'une tâche dans une cellule du calendrier global — étiquette
   discrète, jamais une carte. */
/* `.cal-item` tronque sa ligne (nowrap + ellipsis) : des assignés placés à la
   suite du titre disparaîtraient dans une cellule de semaine étroite. Ils
   prennent donc leur PROPRE ligne sous le titre, qui reste tronqué — le nom
   d'une tâche se devine, une personne prévue doit se voir. */
.cal-item-label{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cal-item-people{ display:flex; flex-wrap:wrap; align-items:center; gap:3px 6px; margin-top:2px; }
.cal-item-person{ font-size:10px; line-height:1.2; }
.cal-item-more{ font-size:10px; color:var(--ink-soft); }

.pdash-more{ display:flex; justify-content:center; margin-top:10px; }
/* « Voir plus de journées » en AJAX (2026-09-05) : le bouton se neutralise
   pendant le chargement, et SEULES les journées nouvellement ajoutees
   apparaissent en fondu -- celles deja affichees ne clignotent jamais.
   Regles ADDITIVES : aucune regle .pdash-* existante n'est modifiee. */
.pdash-more.is-loading{ opacity:.55; pointer-events:none; }
.pdash-tl-item.pdash-tl-in{ animation:pdash-tl-fade .32s ease-out both; }
@keyframes pdash-tl-fade{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion: reduce){ .pdash-tl-item.pdash-tl-in{ animation:none; } }

.pdash-ref{ font-weight:700; font-size:13.5px; }
.pdash-name{ font-size:12.5px; color:var(--ink-soft); }
.pdash-chip{ display:inline-flex; align-items:center; gap:5px; font-size:11.5px; color:var(--ink-soft); }
.pdash-rh{ font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--ink-soft); }
.pdash-rh.covered{ color:var(--green); }
.pdash-rh.missing{ color:var(--red); }
/* Sur-affectation : ni un manque (rouge) ni un état nominal (vert) -- le
   token d'alerte douce déjà utilisé par les avertissements du Planning. */
.pdash-rh.over{ color:var(--amber-dark); }
.pdash-todo{ font-size:12px; color:var(--red); }

/* ============================== À SURVEILLER ============================= */
/* Sous-cartes « chiffre + explication ». L'orange/rouge est réservé à ce qui
   demande vraiment une action ; le vert dit qu'un état est sain, sans allumer
   toute la page. */
.pdash-watch-card{ display:flex; align-items:flex-start; gap:16px; padding:14px 16px; margin-bottom:12px;
                   background:var(--paper); border:1px solid var(--line-strong);
                   border-radius:var(--radius-sm); border-left-width:2px; }
.pdash-watch-card:last-child{ margin-bottom:0; }
.pdash-watch-card.warn{ border-left-color:var(--red); }
.pdash-watch-card.ok{ border-left-color:var(--green); }
.pdash-watch-figure{ flex:0 0 84px; text-align:center; }
.pdash-watch-number{ display:block; font-size:30px; font-weight:700; line-height:1; }
.pdash-watch-card.warn .pdash-watch-number{ color:var(--red); }
.pdash-watch-unit{ display:block; font-size:11px; color:var(--ink-soft); line-height:1.35; margin-top:4px; }
.pdash-watch-body{ flex:1; min-width:0; }
.pdash-watch-project{ margin-bottom:10px; }
.pdash-watch-project:last-child{ margin-bottom:0; }
.pdash-watch-project-name{ font-size:12.5px; font-weight:600; }
.pdash-watch-dates{ font-size:12px; color:var(--ink-soft); margin-top:2px; }
.pdash-watch-dates a{ color:inherit; text-decoration:none; border-bottom:1px dotted var(--line-strong); }
.pdash-watch-dates a:hover{ color:var(--ink); }
.pdash-watch-ok{ font-size:13px; font-weight:600; color:var(--green); }
.pdash-watch-sub{ font-size:12px; color:var(--ink-soft); margin-top:2px; }
.pdash-watch-mark{ display:inline-flex; flex-shrink:0; align-self:center; }

/* ================================= ÉQUIPE =============================== */
.pdash-donut-wrap{ display:flex; align-items:center; gap:16px; margin-bottom:18px; }
.pdash-donut{ flex-shrink:0; }
/* --line-strong et jamais --paper : sur les thèmes sombres, --paper est presque
   la couleur du panneau et la portion NON couverte disparaîtrait. */
.pdash-donut-track{ stroke:var(--line-strong); }
.pdash-donut-value{ stroke:var(--green); }
.pdash-donut-figure{ fill:var(--ink); font-size:9px; font-weight:700; }
.pdash-donut-title{ font-size:13px; font-weight:600; }
.pdash-donut-legend{ display:flex; flex-direction:column; gap:3px; }

.pdash-team-figures{ display:grid; grid-template-columns:repeat(auto-fit, minmax(92px, 1fr)); gap:10px; }
.pdash-team-figure{ display:flex; flex-direction:column; gap:2px; padding:12px 10px;
                    background:var(--paper); border:1px solid var(--line-strong); border-radius:var(--radius-sm); }
.pdash-team-icon{ display:inline-flex; margin-bottom:5px; opacity:.75; }
.pdash-team-number{ font-size:20px; font-weight:700; line-height:1; }
.pdash-team-label{ font-size:10.5px; color:var(--ink-soft); line-height:1.35; }
.pdash-team-figure.alert .pdash-team-number{ color:var(--red); }
/* Emplacement réservé à la future détection de fatigue : visiblement inactif,
   et sans chiffre -- un « 0 » laisserait croire qu'une analyse a eu lieu. */
.pdash-team-figure.future{ opacity:.5; }
.pdash-team-figure.future .pdash-team-number{ color:var(--ink-soft); }

/* Étiquette de survol des blocs trop étroits pour afficher libellé + horaire
   (niveaux C/D/E du rendu adaptatif). Même habillage que la popover « +N »
   ci-dessus -- une seule identité visuelle pour tout ce qui flotte au-dessus
   de la timeline. `pointer-events:none` : elle suit le survol du bloc et ne
   peut jamais le lui voler. */
.pjt-block-tip{
  position:fixed; z-index:130; pointer-events:none;
  display:grid; gap:2px; padding:8px 12px;
  background:var(--paper-2); border:1px solid var(--line-strong);
  border-radius:var(--radius-sm); box-shadow:var(--shadow-card); color:var(--ink);
}
.pjt-block-tip strong{ font-size:12.5px; font-weight:700; white-space:nowrap; }
.pjt-block-tip span{ font-size:12px; color:var(--ink-soft); white-space:nowrap; font-family:'JetBrains Mono',monospace; }
.pjt-block-resize{
  position:absolute; top:0; bottom:0; width:8px; cursor:ew-resize; z-index:2;
  opacity:0; transition:opacity .12s ease;
  background:linear-gradient(to bottom, transparent 18%, rgba(255,255,255,.55) 18%, rgba(255,255,255,.55) 82%, transparent 82%);
  background-size:2px 100%; background-repeat:no-repeat;
}
.pjt-block:hover .pjt-block-resize{ opacity:1; } /* discrètes tant que le bloc n'est pas survolé (§1) */
.pjt-block-resize.left{ left:0; background-position:3px 0; }
.pjt-block-resize.right{ right:0; background-position:3px 0; }
.pjt-block-livetime{ position:absolute; top:-24px; left:0; background:var(--ink); color:var(--paper); font-size:11px; font-weight:700; padding:2px 7px; border-radius:4px; white-space:nowrap; font-family:'JetBrains Mono',monospace; z-index:60; pointer-events:none; }

.pjt-now-col{ grid-column:2; grid-row:1 / -1; position:relative; pointer-events:none; }
.pjt-now-line{ position:absolute; top:0; bottom:0; width:1px; background:var(--brand); z-index:10; }
.pjt-now-label{ position:absolute; top:0; transform:translate(-50%, -100%); background:var(--brand); color:#fff; font-size:11px; font-weight:700; padding:2px 7px; border-radius:4px; font-family:'JetBrains Mono',monospace; white-space:nowrap; z-index:11; }

.pjt-legend{ display:flex; gap:16px; flex-wrap:wrap; padding:10px 18px; font-size:12px; color:var(--ink-soft); border-top:1px solid var(--line); }
.pjt-legend-item{ display:flex; align-items:center; gap:6px; }
.pjt-legend-swatch{ width:12px; height:12px; border-radius:3px; display:inline-block; }
.pjt-legend-swatch.phase-montage{ background:var(--phase-montage-bg); }
.pjt-legend-swatch.phase-permanence{ background:var(--phase-permanence-bg); }
.pjt-legend-swatch.phase-demontage{ background:var(--phase-demontage-bg); }
.pjt-legend-swatch.phase-autre{ background:var(--phase-autre-bg); }

.pjt-rh-list{ max-height:260px; overflow-y:auto; margin-top:6px; }
.pjt-modal-actions{ display:flex; justify-content:space-between; align-items:center; margin-top:14px; }
.pjt-label-field[hidden]{ display:none; } /* .field{display:...} bat sinon [hidden], même correctif que .pjt-block-more[hidden] */
.pjt-next-day{ margin-left:6px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--amber-dark); background:var(--amber-bg); border-radius:3px; padding:1px 5px; }
.pjt-phase-warning{ margin-top:6px; font-size:11.5px; color:var(--ink-soft); font-style:italic; }
/* Qualification du poste par personne dans la modale de bloc (2026-09-01) —
   n'apparaît que si la phase du jour compte plusieurs besoins. */
.pjt-need-list{ display:flex; flex-direction:column; gap:6px; margin-top:6px; max-height:200px; overflow-y:auto; }
.pjt-need-row{ display:flex; align-items:center; gap:10px; }
.pjt-need-person{ flex:1 1 auto; min-width:0; font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pjt-need-row select{ flex:0 0 auto; max-width:52%; }
.pjt-need-summary{ display:inline-flex; flex-wrap:wrap; gap:8px; margin-left:6px;
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:400; text-transform:none; color:var(--ink-soft); }
.pjt-need-tally.missing{ color:var(--red); font-weight:600; }
.pjt-modal-actions .btn[hidden]{ display:none; } /* .btn{display:inline-block} bat sinon [hidden] (règle UA), même correctif que .pjt-block-more[hidden] plus haut */

/* ============================================================
   Neumorphism — surcharges de composants
   ============================================================ */

/* Boutons : relief pressé dans la matière */
[data-theme-style="neumorphism"] .btn{
  border:none; background:var(--paper-2); color:var(--ink-soft);
  box-shadow:5px 5px 10px var(--neu-lo), -5px -5px 10px var(--neu-hi);
}
[data-theme-style="neumorphism"] .btn:hover{
  background:var(--paper-2); color:var(--ink); border:none;
  box-shadow:3px 3px 6px var(--neu-lo), -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .btn:active{
  box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .btn.primary{
  background:var(--neu-confirme-bg); color:var(--neu-confirme-text); border:none;
  box-shadow:5px 5px 10px var(--neu-confirme-lo), -5px -5px 10px var(--neu-confirme-hi);
}
[data-theme-style="neumorphism"] .btn.primary:hover{
  background:var(--neu-confirme-bg); color:var(--neu-confirme-text);
  box-shadow:3px 3px 6px var(--neu-confirme-lo), -3px -3px 6px var(--neu-confirme-hi);
}
[data-theme-style="neumorphism"] .btn.danger{
  background:var(--neu-annule-bg); color:var(--neu-annule-text); border:none;
  box-shadow:5px 5px 10px var(--neu-annule-lo), -5px -5px 10px var(--neu-annule-hi);
}
[data-theme-style="neumorphism"] .btn.danger:hover{ background:var(--neu-annule-bg); color:var(--neu-annule-text); }

/* Cartes / panels : relief sortant, pas de bordure */
[data-theme-style="neumorphism"] .panel,
[data-theme-style="neumorphism"] .kpi-card{ border:none; }
[data-theme-style="neumorphism"] .kpi-card{ border-left:none; }
[data-theme-style="neumorphism"] .note-panel{ border:none; box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi); }

/* Badges de statut : relief coloré par statut */
[data-theme-style="neumorphism"] .badge{ border:none; }
[data-theme-style="neumorphism"] .badge.prospect{
  background:var(--paper-2); color:var(--ink-soft);
  box-shadow:3px 3px 6px var(--neu-lo), -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .badge.confirme{
  background:var(--neu-confirme-bg); color:var(--neu-confirme-text);
  box-shadow:3px 3px 6px var(--neu-confirme-lo), -3px -3px 6px var(--neu-confirme-hi);
}
[data-theme-style="neumorphism"] .badge.en_cours{
  background:var(--neu-encours-bg); color:var(--neu-encours-text);
  box-shadow:3px 3px 6px var(--neu-encours-lo), -3px -3px 6px var(--neu-encours-hi);
}
[data-theme-style="neumorphism"] .badge.termine{
  background:var(--neu-termine-bg); color:var(--neu-termine-text);
  box-shadow:3px 3px 6px var(--neu-termine-lo), -3px -3px 6px var(--neu-termine-hi);
}
[data-theme-style="neumorphism"] .badge.annule{
  background:var(--neu-annule-bg); color:var(--neu-annule-text);
  box-shadow:3px 3px 6px var(--neu-annule-lo), -3px -3px 6px var(--neu-annule-hi);
}

/* Champs de formulaire : creusés dans la matière plutôt que soulignés */
[data-theme-style="neumorphism"] .field input[type=text],
[data-theme-style="neumorphism"] .field input[type=number],
[data-theme-style="neumorphism"] .field input[type=date],
[data-theme-style="neumorphism"] .field input[type=datetime-local],
[data-theme-style="neumorphism"] .field input[type=email],
[data-theme-style="neumorphism"] .field input[type=tel],
[data-theme-style="neumorphism"] .field input[type=password],
[data-theme-style="neumorphism"] .field input[type=url],
[data-theme-style="neumorphism"] .field input[type=month],
[data-theme-style="neumorphism"] .field input[type=time],
[data-theme-style="neumorphism"] .field input[type=search],
[data-theme-style="neumorphism"] .field select,
[data-theme-style="neumorphism"] .field textarea{
  border:none; border-radius:var(--radius-sm); background:var(--paper); padding:9px 12px;
  box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .field input:focus,
[data-theme-style="neumorphism"] .field select:focus,
[data-theme-style="neumorphism"] .field textarea:focus{
  box-shadow:inset 2px 2px 4px var(--neu-lo), inset -2px -2px 4px var(--neu-hi), 0 0 0 2px var(--neu-brand-text);
}
[data-theme-style="neumorphism"] .checkbox-list{
  border:none; box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .error-box{
  background:var(--neu-annule-bg); color:var(--neu-annule-text); border:none;
  box-shadow:inset 3px 3px 6px var(--neu-annule-lo), inset -3px -3px 6px var(--neu-annule-hi);
}
[data-theme-style="neumorphism"] .success-box{
  background:var(--neu-termine-bg); color:var(--neu-termine-text); border:none;
  box-shadow:inset 3px 3px 6px var(--neu-termine-lo), inset -3px -3px 6px var(--neu-termine-hi);
}
[data-theme-style="neumorphism"] .info-box{
  background:var(--neu-confirme-bg); color:var(--neu-confirme-text); border:none;
  box-shadow:inset 3px 3px 6px var(--neu-confirme-lo), inset -3px -3px 6px var(--neu-confirme-hi);
}
[data-theme-style="neumorphism"] .info-box strong{ color:var(--neu-confirme-text); }
[data-theme-style="neumorphism"] .maintenance-box{
  background:var(--neu-encours-bg); border:none;
  box-shadow:inset 3px 3px 6px var(--neu-encours-lo), inset -3px -3px 6px var(--neu-encours-hi);
}
[data-theme-style="neumorphism"] .maintenance-box h2,
[data-theme-style="neumorphism"] .maintenance-box p{ color:var(--neu-encours-text); }

/* Tableaux, Gantt et calendrier : traitement volontairement sobre.
   Le relief neumorphique sur des lignes denses nuit à la lecture rapide,
   donc ces zones restent proches du style Flat (juste les coins arrondis
   hérités des variables --radius-*). */
[data-theme-style="neumorphism"] table.data td{ border-bottom-color:var(--line-strong); }
[data-theme-style="neumorphism"] .cal-grid{ background:var(--line-strong); border-color:var(--line-strong); }
[data-theme-style="neumorphism"] .team-member{
  border:none; box-shadow:2px 2px 4px var(--neu-confirme-lo), -2px -2px 4px var(--neu-confirme-hi);
  background:var(--neu-confirme-bg); color:var(--neu-confirme-text);
}

/* ---------- Devis : prévenir le client par e-mail (#215) ---------- */
.portal-notice-flash{ flex-basis:100%; font-size:12.5px; color:var(--green, var(--ink)); }
.portal-notice-flash.is-error{ color:var(--red); font-weight:600; }
.portal-notice-history{ flex-basis:100%; list-style:none; margin:4px 0 0; padding:0; display:flex; flex-direction:column; gap:6px;
  font-size:12px; color:var(--ink-soft); }
.portal-notice-history li{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; overflow-wrap:anywhere; }
.portal-notice-history li.is-error{ color:var(--red); font-weight:600; }
/* Plus précis que `.modal-box` (400 px), déclaré plus bas dans la feuille. */
.modal-box.portal-notice-box{ max-width:820px; width:calc(100% - 24px); max-height:calc(100dvh - 24px); overflow:auto; }
.portal-notice-title{ margin:0 0 6px; font-size:16px; display:flex; align-items:center; gap:8px; }
.portal-notice-lead{ margin:0 0 12px; font-size:12.5px; color:var(--ink-soft); }
.portal-notice-meta{ display:grid; grid-template-columns:max-content 1fr; gap:4px 12px; margin:0 0 12px; font-size:13px; }
.portal-notice-meta dt{ color:var(--ink-soft); }
.portal-notice-meta dd{ margin:0; overflow-wrap:anywhere; }
.portal-notice-meta small{ display:block; color:var(--ink-soft); font-size:11.5px; }
.portal-notice-blocks{ margin:0 0 12px; padding:10px 12px; border-radius:var(--radius-sm, 8px); border:1px solid var(--red);
  color:var(--red); font-size:12.5px; }
.portal-notice-blocks ul{ margin:6px 0 0; padding-left:18px; }
.portal-notice-box .field{ margin-bottom:10px; }
.portal-notice-box textarea{ width:100%; min-height:150px; resize:vertical; }
.portal-notice-hint{ margin:4px 0 0; font-size:11.5px; color:var(--ink-soft); }
.portal-notice-fixed{ margin:6px 0 12px; font-size:11.5px; color:var(--ink-soft); }
.portal-notice-fixed pre{ margin:4px 0 0; padding:8px 10px; white-space:pre-wrap; overflow-wrap:anywhere; font-family:inherit;
  font-size:12px; color:var(--ink-soft); background:var(--paper); border-radius:var(--radius-sm, 8px); }
@media (max-width: 480px){
  .modal-box.portal-notice-box{ padding:16px 14px; }
  .portal-notice-meta{ grid-template-columns:1fr; gap:0 0; }
  .portal-notice-meta dd{ margin-bottom:6px; }
  .portal-notice-box .modal-actions{ flex-wrap:wrap; }
  .portal-notice-box .modal-actions .btn{ flex:1 1 auto; justify-content:center; }
}

/* ---------- Modal (popup de confirmation / création rapide) ---------- */
.modal-overlay{
  display:none; position:fixed; inset:0; background:rgba(0,0,0,0.5); z-index:100;
  align-items:center; justify-content:center;
}
.modal-overlay.open{ display:flex; }
.modal-box{
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-card);
  padding:22px 24px; max-width:400px; width:90%; color:var(--ink);
}
/* Neumorphism (clair et foncé) : la fenêtre de modale n'a pas d'ombre extérieure.
   Fond de superposition, bordure et arrondi inchangés ; les autres thèmes aussi. */
[data-theme-style="neumorphism"] .modal-box{ box-shadow:none; }
.modal-actions{ display:flex; gap:10px; justify-content:flex-end; margin-top:6px; }

/* ---------- Autofill navigateur ----------
   Chrome/Firefox forcent un fond clair sur les champs autofillés (email, mot de
   passe...), en ignorant le CSS du site. La technique du box-shadow habituelle
   entre en conflit avec les ombres du Neumorphism (qui utilisent aussi box-shadow) :
   on utilise donc plutôt une transition de couleur de fond volontairement énorme,
   qui empêche le navigateur d'appliquer visuellement sa couleur avant des heures —
   sans jamais toucher à box-shadow. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus{
  -webkit-text-fill-color: var(--ink);
  transition: background-color 9999s ease-in-out 0s, color 9999s ease-in-out 0s;
  -webkit-transition: background-color 9999s ease-in-out 0s, color 9999s ease-in-out 0s;
}

/* ---------- Onglets (fiche projet) ---------- */
.tab-nav{ display:flex; gap:4px; border-bottom:1.5px solid var(--line); margin:24px 0 20px; }
.tab-btn{
  background:none; border:none; padding:10px 18px; font-family:'Barlow Condensed',sans-serif; font-weight:700;
  text-transform:uppercase; letter-spacing:.03em; font-size:14px; color:var(--ink-soft); cursor:pointer;
  border-bottom:2.5px solid transparent; margin-bottom:-1.5px; text-decoration:none; display:inline-block;
}
.tab-btn:hover{ color:var(--ink); }
.tab-btn.active{ color:var(--brand); border-bottom-color:var(--brand); }
[data-tab]{ display:none; }
[data-tab].tab-active{ display:block; }

/* ---------- Timeline financière horizontale ---------- */
.timeline-h-line{
  position:absolute; left:0; right:0; top:50%; height:3px; transform:translateY(-50%);
  background:linear-gradient(90deg, var(--line-strong), var(--brand) 50%, var(--line-strong));
  border-radius:2px; opacity:.5;
}
.timeline-h-tick{ position:absolute; top:calc(50% - 9px); width:1px; height:18px; background:var(--line-strong); }
.timeline-h-month{
  position:absolute; top:calc(50% + 14px); transform:translateX(-50%); font-size:11px; color:var(--ink-soft);
  text-transform:uppercase; letter-spacing:.04em; font-weight:600;
}
.timeline-h-dot{
  position:absolute; transform:translate(-50%, -50%); border-radius:50%; border:2.5px solid var(--paper-2);
  box-shadow:0 3px 8px rgba(0,0,0,.28); cursor:pointer; transition:transform .18s cubic-bezier(.34,1.56,.64,1), box-shadow .18s ease;
  z-index:2;
}
.timeline-h-dot:hover, .timeline-h-dot:focus-visible{ transform:translate(-50%, -50%) scale(1.4); box-shadow:0 6px 16px rgba(0,0,0,.35); z-index:6; }
.timeline-h-dot:focus-visible{ outline:2px solid var(--brand); outline-offset:3px; }
.timeline-h-tooltip{
  display:none; position:absolute; bottom:135%;
  background:var(--nav-bg); color:#f4f3ee; padding:9px 12px; border-radius:8px; font-size:11.5px; line-height:1.5;
  white-space:nowrap; box-shadow:0 10px 24px rgba(0,0,0,.35); z-index:10; pointer-events:none;
}
.timeline-h-tooltip.tooltip-align-center{ left:50%; transform:translateX(-50%); }
.timeline-h-tooltip.tooltip-align-left{ left:0; }
.timeline-h-tooltip.tooltip-align-right{ right:0; }
.timeline-h-tooltip::after{
  content:''; position:absolute; top:100%; border:6px solid transparent; border-top-color:var(--nav-bg);
}
.timeline-h-tooltip.tooltip-align-center::after{ left:50%; transform:translateX(-50%); }
.timeline-h-tooltip.tooltip-align-left::after{ left:10px; }
.timeline-h-tooltip.tooltip-align-right::after{ right:10px; }
.timeline-h-dot:hover .timeline-h-tooltip, .timeline-h-dot:focus .timeline-h-tooltip{ display:block; }

/* ---------- Sélecteur d'année (fiche Timeline) ---------- */
.year-select-wrap{ position:relative; display:inline-block; }
.year-select{
  appearance:none; -webkit-appearance:none; -moz-appearance:none;
  background:var(--paper-2); border:1.5px solid var(--line-strong); border-radius:var(--radius-pill);
  padding:7px 34px 7px 16px; font-family:'JetBrains Mono',monospace; font-size:13px; font-weight:700;
  color:var(--ink); cursor:pointer; box-shadow:var(--shadow-card); transition:border-color .15s ease, transform .1s ease;
}
.year-select:hover{ border-color:var(--brand); }
.year-select:focus{ outline:none; border-color:var(--brand); }
.year-select:active{ transform:scale(.97); }
.year-select-wrap::after{
  content:'▾'; position:absolute; right:14px; top:50%; transform:translateY(-50%);
  font-size:11px; color:var(--brand); pointer-events:none;
}

/* ---------- Recherche instantanée dans un tableau (Reporting) ---------- */
.table-search-input{
  background:var(--paper-2); border:1.5px solid var(--line-strong); border-radius:8px;
  padding:7px 12px; font-size:13px; color:var(--ink); min-width:220px;
  transition:border-color .15s ease;
}
.table-search-input:hover{ border-color:var(--brand); }
.table-search-input:focus{ outline:none; border-color:var(--brand); }

.cat-footer{ display:flex; gap:8px; margin-top:8px; }

/* Listing projets -- icône stockage discrète devant le nom (jamais une
   capsule .badge : simple préfixe visuel, le nom du projet reste l'élément
   principal). */
.project-storage-icon{ display:inline-flex; align-items:center; font-size:13px; margin-right:4px; vertical-align:middle; }

.stock-warning{ cursor:help; font-size:14px; line-height:1; }
.stock-warning-wrap{ position:relative; display:inline-flex; align-items:center; }
.stock-warning-wrap .stock-warning{
  position:absolute; left:8px; top:50%; margin-top:-7px; z-index:1;
}
.stock-warning-wrap input[type="text"]{ padding-left:28px; }

/* Icône du sélecteur date/mois, invisible par défaut (noire) sur fond sombre. */
[data-theme-mode="dark"] .field input[type=date]::-webkit-calendar-picker-indicator,
[data-theme-mode="dark"] .field input[type=datetime-local]::-webkit-calendar-picker-indicator,
[data-theme-mode="dark"] .field input[type=month]::-webkit-calendar-picker-indicator,
[data-theme-mode="dark"] .field input[type=time]::-webkit-calendar-picker-indicator{
  filter: invert(1);
}

/* ---------- Champ avec icône intégrée (ex. lien externe QR code) ---------- */
.input-icon-wrap{ position:relative; display:flex; align-items:center; }
.input-icon-wrap .input-icon{
  position:absolute; left:9px; font-size:13px; line-height:1; pointer-events:none; opacity:.7;
}
.input-icon-wrap input{ width:100%; padding-left:34px; }
.input-icon-wrap:focus-within .input-icon{ opacity:1; }

/* ---------- Sections regroupées dans un formulaire (ex. facture) ---------- */
.form-section-label{
  font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase;
  font-size:13px; letter-spacing:.04em; color:var(--brand); margin:0 0 12px;
  padding-bottom:8px; border-bottom:1px solid var(--line);
}
.form-section-row{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:24px; margin-bottom:26px; }
.form-section-row:last-child{ margin-bottom:0; }
.form-section-row .full{ grid-column:1 / -1; }
.form-section-auto{
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:18px 20px; margin-bottom:26px;
}
.form-section-auto .form-section-label{ border-bottom-color:var(--line-strong); }

/* ---------- Dashboard (grille de widgets) ---------- */
.dash-grid{
  display:grid; grid-template-columns:repeat(12, 1fr); gap:20px; align-items:start;
}
.dash-card{ grid-column:span 12; }
.dash-card-head{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase; letter-spacing:.02em;
  font-size:15px; margin-bottom:14px; padding-bottom:10px; border-bottom:1px solid var(--line);
}
.dash-card-link{ font-family:'Inter',sans-serif; text-transform:none; font-weight:600; font-size:12.5px; letter-spacing:0; }
.dash-card-alerts{ border-left:4px solid var(--line-strong); }

/* ---------- Dashboard GOD MODE — six accès directs (V1, 2026-09-06) ----------
   MÊME DESIGN que les cartes de création de l'Agenda (`.agenda-create-card`,
   sous le calendrier) : mêmes fond, bordure, rayon, ombre, mêmes hauteur et
   respiration, même filet de marque en haut, même survol. C'est délibéré —
   deux écrans qui proposent « aller quelque part » n'ont aucune raison de le
   dire de deux façons. Les valeurs sont reprises telles quelles ; si l'Agenda
   change un jour, ces deux blocs se rapprocheront dans un composant commun,
   pas ici au milieu d'une V1.

   La grille suit les MÊMES paliers que celle de l'Agenda (1180/900/600px) :
   six colonnes en grand écran, puis quatre, trois, deux. Un `auto-fit` aurait
   été plus court à écrire, mais il produit des cartes de largeurs variables
   d'un écran à l'autre, là où l'Agenda garde des rangées régulières. */
.dash-admin{ grid-column:span 12; padding:20px; }
.dash-admin-grid{ display:grid; grid-template-columns:repeat(6, 1fr); gap:12px; }
@media (max-width: 1180px){ .dash-admin-grid{ grid-template-columns:repeat(4, 1fr); } }
@media (max-width: 900px){  .dash-admin-grid{ grid-template-columns:repeat(3, 1fr); } }
@media (max-width: 600px){  .dash-admin-grid{ grid-template-columns:repeat(2, 1fr); } }
.dash-admin-btn{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:var(--shadow-card);
  padding:26px 16px; min-height:130px; text-align:center; text-decoration:none; color:var(--ink);
  box-sizing:border-box; transition:border-color .12s, box-shadow .12s, transform .12s;
  /* Le filet de marque en haut : sur l'Agenda il distingue une carte ACTIVE
     d'un module « bientôt disponible ». Ici les six destinations existent
     toutes, donc toutes le portent. */
  border-top:3px solid var(--brand); cursor:pointer;
}
.dash-admin-btn:hover, .dash-admin-btn:focus-visible{
  border-color:var(--brand); box-shadow:0 6px 16px rgba(0,0,0,.1); transform:translateY(-2px);
}
.dash-admin-btn-icon{ display:flex; align-items:center; justify-content:center; height:34px; line-height:1; }
.dash-admin-btn-label{ font-size:14.5px; font-weight:700; }

/* Bouton EN ALERTE — aujourd'hui seulement « Maintenance », quand une fenêtre
   est ouverte. Le filet de marque passe au rouge et un badge le dit en toutes
   lettres : la couleur seule ne suffit pas, ni pour un daltonien, ni pour un
   œil pressé. Le bouton reste un lien ordinaire vers `maintenance.php` — on
   signale, on ne bloque pas. Rouge du thème (`--red`, `--red-bg`), celui que
   l'ERP emploie déjà partout ailleurs pour dire « attention ». */
/* Le FOND teinté fait le gros du travail : dans les deux thèmes, `--red` et
   `--brand` sont presque la même teinte (#b3402f contre #b73818 en clair,
   #e0776a contre #e0724a en sombre), donc un simple filet rouge à la place du
   filet de marque ne se verrait pas. Le fond, lui, se voit du premier coup
   d'œil, sans rien changer à la forme de la carte. */
.dash-admin-btn--alert{ background:var(--red-bg); border-top-color:var(--red); border-color:var(--red); }
.dash-admin-btn--alert:hover, .dash-admin-btn--alert:focus-visible{ border-color:var(--red); }
.dash-admin-btn-badge{
  display:inline-block; margin-top:2px; padding:2px 8px;
  background:var(--red-bg); color:var(--red); border-radius:var(--radius-pill);
  font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.03em;
}

/* Les CHIFFRES des statistiques reprennent l'orange des icônes, et seulement
   sous `.dash-grid-god` : le widget Statistiques est partagé avec tous les
   rôles, sa règle générale ne bouge pas d'un pixel. Les libellés restent en
   gris — c'est le chiffre qu'on vient lire. */
.dash-grid-god .dash-stat-value{ color:var(--icon-orange); }

/* Widget "Réunion imminente" — carte par réunion (Lot UI/UX, 2026-08-23,
   aéré/agrandi le 2026-08-24 sur retour de test manuel : le premier rendu
   compressait tout dans le coin supérieur gauche malgré un widget en pleine
   largeur — davantage d'air entre état/titre/métadonnées/participants/bouton,
   et le titre devient la clé visuelle principale de la carte). */
.dash-meeting-card{ margin-bottom:12px; padding:18px 20px; }
.dash-meeting-phase{ font-family:'JetBrains Mono',monospace; font-size:11.5px; font-weight:700; color:var(--brand); text-transform:uppercase; letter-spacing:.03em; }
.dash-meeting-title{ font-size:17px; font-weight:700; margin-top:6px; }
.dash-meeting-meta{ font-size:12.5px; color:var(--ink-soft); margin-top:4px; }
.dash-meeting-join-btn{ margin-top:18px; padding:10px 22px; font-size:13.5px; }

/* Zone participants — avatars agrandis (48–56px desktop, cf. .person-avatar-circle
   ci-dessous) + nom complet centré en dessous (jamais l'email/la fonction/le
   statut de clôture, réservés à meeting_view.php). Rangée qui exploite la
   largeur disponible (widget en pleine largeur, span 12) et retombe
   proprement à la ligne sur petit écran (flex-wrap, jamais de scroll
   horizontal, jamais un participant tronqué "de manière catastrophique"). */
.dash-meeting-participants-label{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin-top:18px; margin-bottom:8px; }
.dash-meeting-avatars{ display:flex; align-items:flex-start; flex-wrap:wrap; gap:16px; }
.dash-meeting-participant{ display:flex; flex-direction:column; align-items:center; gap:5px; width:78px; text-align:center; }
.dash-meeting-participant__name{ font-size:12px; font-weight:600; line-height:1.25; color:var(--ink); word-break:break-word; }
.dash-meeting-participant__you{ font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
/* Cercle avatar agrandi (52px desktop) — variante CSS scoped à CE widget
   uniquement (jamais une modification globale de .person-avatar-circle,
   utilisée telle quelle par ex. sur meeting_view.php/field_session_view.php
   avec sa taille par défaut de 26px, section 16 du lot). person_avatar_name_html()
   (includes/employee_helpers.php) fixe la taille en style INLINE (paramètre
   $size) — un !important est ici la SEULE façon de la faire varier par
   media query sans dupliquer le composant ni le rendre responsive lui-même
   (usage volontaire et scopé, jamais un override généralisé). */
.dash-meeting-participant .person-avatar-circle{ width:52px !important; height:52px !important; font-size:18.7px !important; }
.dash-meeting-avatars__more{
  display:inline-flex; align-items:center; justify-content:center;
  width:52px; height:52px; border-radius:50%; background:var(--paper); border:1px solid var(--line-strong);
  font-size:15px; font-weight:700; color:var(--ink-soft); flex-shrink:0; box-sizing:border-box;
}

@media (max-width: 900px){
  .dash-meeting-participant .person-avatar-circle{ width:44px !important; height:44px !important; font-size:15.8px !important; }
  .dash-meeting-avatars__more{ width:44px; height:44px; font-size:13px; }
  .dash-meeting-participant{ width:68px; }
}
@media (max-width: 600px){
  .dash-meeting-card{ padding:14px 16px; }
  .dash-meeting-title{ font-size:15.5px; }
  .dash-meeting-avatars{ gap:12px; }
  .dash-meeting-participant .person-avatar-circle{ width:36px !important; height:36px !important; font-size:13px !important; }
  .dash-meeting-avatars__more{ width:36px; height:36px; font-size:11px; }
  .dash-meeting-participant{ width:58px; }
  .dash-meeting-participant__name{ font-size:11px; }
}

.dash-kpi-row{ display:grid; grid-template-columns:repeat(6, 1fr); gap:14px; margin-bottom:16px; }
.dash-kpi{
  background:var(--paper); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:12px 14px; min-height:2.6em;
}
.dash-kpi-lead{ border-left:3px solid var(--brand); }
.dash-kpi-label{ font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin-bottom:6px; }
.dash-kpi-value{ font-family:'JetBrains Mono',monospace; font-size:18px; font-weight:700; }

.dash-chart-legend{ display:flex; gap:16px; font-size:11px; color:var(--ink-soft); margin-top:4px; }
.dash-chart-legend .item{ display:flex; align-items:center; gap:5px; }
.dash-swatch{ display:inline-block; width:10px; height:10px; border-radius:2px; }
.dash-swatch-encaisse{ background:var(--green); }
.dash-swatch-prevu{ background:var(--paper-2); border:1.5px solid var(--ink-soft); }
.dash-swatch-cumul{ width:14px; height:2px; border-radius:0; background:var(--steel); }
.dash-chart-note{ font-size:12px; color:var(--ink-soft); font-style:italic; margin-top:10px; padding-top:10px; border-top:1px solid var(--line); }

.dash-sub-label{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin:14px 0 6px; }
.dash-sub-label:first-of-type{ margin-top:0; }
.dash-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:7px; font-size:13px; }
.dash-list li{ display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; }
.dash-list-meta{ color:var(--ink-soft); font-size:11.5px; margin-left:auto; white-space:nowrap; }

.dash-stat-row{ display:flex; gap:14px; }
.dash-stat-row-wide{ flex-wrap:wrap; }
.dash-stat{ flex:1; min-width:100px; text-align:center; background:var(--paper); border:1px solid var(--line); border-radius:var(--radius-sm); padding:12px 10px; }
.dash-stat-value{ font-family:'JetBrains Mono',monospace; font-size:20px; font-weight:700; }
.dash-stat-label{ font-size:11px; color:var(--ink-soft); margin-top:4px; }

.dash-gauge-list{ display:flex; flex-direction:column; gap:8px; }
.dash-gauge-row{ display:flex; align-items:center; gap:8px; font-size:12.5px; }
.dash-gauge-label{ flex:0 0 110px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dash-gauge-track{ flex:1; background:var(--line); border-radius:4px; height:10px; overflow:hidden; }
.dash-gauge-fill{ display:block; height:100%; background:var(--steel); border-radius:4px; }
.dash-gauge-value{ flex:0 0 auto; font-family:'JetBrains Mono',monospace; color:var(--ink-soft); white-space:nowrap; }

.dash-alert-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.dash-alert{
  display:flex; align-items:center; gap:8px; font-size:13px; padding:9px 12px;
  border-radius:var(--radius-sm); border-left:3px solid var(--line-strong); background:var(--paper);
}
.dash-alert-critical{ border-left-color:var(--red); }
.dash-alert-warn{ border-left-color:var(--amber); }
.dash-alert-info{ border-left-color:var(--steel); }
.dash-alert-link{ margin-left:auto; font-size:12px; font-weight:600; white-space:nowrap; }

/* ---------- Dashboard — notifications persistantes (Roadmap #206) ----------
   Même grammaire que les alertes : liseré à gauche, fond papier. Une
   notification NON LUE porte le liseré et la pastille de marque ; une lue
   s'efface sans disparaître. Toutes les couleurs sont des jetons du thème. */
.dash-notif-count{ display:inline-flex; align-items:center; justify-content:center; min-width:20px; height:20px;
  padding:0 6px; margin-left:6px; border-radius:10px; background:var(--brand); color:#fff;
  font-family:'Inter',sans-serif; font-size:11.5px; font-weight:700; letter-spacing:0; }
.dash-notif-form{ margin:0; }
.dash-notif-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.dash-notif{ display:flex; align-items:flex-start; gap:10px; padding:10px 12px; font-size:13px;
  border-radius:var(--radius-sm); border-left:3px solid var(--line-strong); background:var(--paper); }
.dash-notif.is-unread{ border-left-color:var(--brand); }
.dash-notif-dot{ flex:none; width:8px; height:8px; margin-top:6px; border-radius:50%; background:transparent; }
.dash-notif.is-unread .dash-notif-dot{ background:var(--brand); }
.dash-notif-text{ flex:1 1 auto; min-width:0; }
.dash-notif-title{ font-weight:600; color:var(--ink); overflow-wrap:anywhere; }
/* Le titre est un bouton (ouvrir = POST qui marque lue) dessiné comme un lien. */
button.dash-notif-title{ background:none; border:0; padding:0; margin:0; font:inherit; font-weight:600;
  text-align:left; cursor:pointer; text-decoration:underline; text-underline-offset:2px; color:var(--ink); }
button.dash-notif-title:hover, button.dash-notif-title:focus-visible{ color:var(--brand); }
.dash-notif-flash{ margin:0 0 10px; padding:8px 10px; font-size:13px; border-radius:var(--radius-sm);
  border-left:3px solid var(--amber); background:var(--paper); color:var(--ink); }
.dash-notif-history{ margin-top:12px; }
.dash-notif-head-actions{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; font-family:'Inter',sans-serif;
  text-transform:none; letter-spacing:0; }
.dash-notif-empty{ margin:0; padding:10px 12px; font-size:13px; color:var(--ink-soft);
  border-radius:var(--radius-sm); background:var(--paper); }
.notif-page{ max-width:900px; margin:0 auto; }
.notif-tabs{ display:flex; gap:8px; flex-wrap:wrap; margin:0 0 14px; }
.notif-page .pagination{ margin-top:14px; }
.dash-notif-history > summary{ cursor:pointer; font-size:12.5px; font-weight:600; color:var(--ink-soft); margin-bottom:8px; }
.dash-notif:not(.is-unread) .dash-notif-title{ font-weight:500; color:var(--ink-soft); }
.dash-notif-body{ margin:3px 0 0; color:var(--ink-soft); overflow-wrap:anywhere; white-space:pre-line; }
.dash-notif-when{ margin:3px 0 0; font-size:11.5px; color:var(--ink-soft); }
.dash-notif .btn{ flex:none; }
/* PETIT ÉCRAN : le titre d'abord, les actions dessous ; la pastille reste sur la
   ligne de son texte, le bouton « Marquer comme lue » passe en dessous. */
.dash-card-notifs .dash-card-head{ flex-wrap:wrap; }
.dash-notif-head-actions{ margin-left:auto; }
@media (max-width: 600px){
  .dash-card-notifs .dash-card-head > span:first-child{ flex:1 1 100%; }
  .dash-notif-head-actions{ margin-left:0; }
  .dash-notif{ flex-wrap:wrap; }
  .dash-notif-text{ flex:1 1 calc(100% - 24px); }
  .dash-notif > .dash-notif-form{ margin-left:18px; }
}

@media (max-width: 900px){
  .dash-grid > *{ grid-column:span 12 !important; }
  .dash-kpi-row{ grid-template-columns:repeat(2, 1fr); }
  .dash-stat-row{ flex-wrap:wrap; }
  .dash-gauge-label{ flex-basis:80px; }
}

/* ---------- Widget Agenda du Dashboard : panel Aujourd'hui + vues Semaine/Mois ----------
   Widget passé en pleine largeur (grid-column: span 12, includes/dashboard/dashboard_calendar.php)
   plutôt que span 4 partagé avec le widget Finance (span 8) : c'est ce partage qui causait
   l'effet "petite liste tassée en haut d'un grand container" (grille .dash-grid en
   align-items:start, le widget le plus court d'une même ligne ne s'étire jamais pour
   combler la hauteur du plus grand). En pleine largeur, le widget n'a plus de voisin de
   ligne plus haut que lui — la grille n'a donc plus besoin d'être modifiée globalement
   (align-items reste "start" pour tous les autres widgets, inchangé). Effet de bord accepté
   et documenté (rapport du lot) : la ligne du widget Finance (span 8) laisse désormais 4
   colonnes vides à sa droite, faute d'un widget span 4 pour la compléter — non corrigé ici
   (toucherait un widget hors périmètre de ce lot). */
.dcal-today{ margin-bottom:16px; }
.dcal-today-head{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin-bottom:8px; }
.dcal-today-empty{ padding:8px 0; }
/* Hauteur auto sur le contenu (retour de test manuel, 2026-08-23) : le
   `max-height:180px; overflow-y:auto;` d'origine datait de l'époque où ce
   widget partageait sa ligne de grille avec le widget Finance (span 4,
   voir le commentaire ci-dessus) — une scrollbar interne évitait alors que
   la liste "Aujourd'hui" ne pousse artificiellement la hauteur de toute la
   ligne. Depuis le passage en pleine largeur (span 12, plus aucun voisin de
   ligne plus haut), cette contrainte n'a plus aucune raison d'être : la
   liste doit toujours afficher l'intégralité des événements du jour, quel
   que soit leur nombre, la page utilisant simplement le scroll principal du
   navigateur au-delà. Jamais de scrollbar interne ici, jamais un événement
   masqué. */
.dcal-today-list{ display:flex; flex-direction:column; gap:4px; }
/* Séparation visuelle entre le bloc "En retard" et le titre "Aujourd'hui"
   qui le suit (retour explicite, 2026-08-25) — jamais le gap:4px entre
   lignes d'une même section (inchangé), jamais le margin-bottom:8px de
   .dcal-today-head (partagé avec la séparation titre/liste de CHAQUE
   section, "Aujourd'hui" y compris — le modifier aurait aussi resserré ou
   élargi l'espace titre/liste partout). Valeur réutilisée telle quelle de
   .dcal-today ci-dessus (16px, déjà la séparation entre ce panel et le
   reste du widget) plutôt qu'une valeur inventée. */
.dcal-today-list.dcal-overdue{ margin-bottom:16px; }

.dcal-item{ display:flex; align-items:baseline; gap:8px; font-size:12.5px; padding:4px 8px; border-radius:var(--radius-sm); border-left:3px solid var(--line-strong); background:var(--paper); }
/* Widget Agenda de la Dashboard UNIQUEMENT (retour explicite, 2026-08-25) :
   lignes légèrement plus épaisses, contenu centré verticalement. .dcal-item
   n'est utilisé nulle part ailleurs aujourd'hui (uniquement le panel
   Aujourd'hui/En retard de ce widget — jamais la grille Semaine/Mois, qui
   utilise .cal-item), mais reste scopé à #agenda par prudence explicite,
   pour ne jamais affecter une éventuelle réutilisation future ailleurs.
   .dcal-item est déjà display:flex — seuls align-items (baseline -> center)
   et min-height changent ici ; couleurs/bordures/rayons/typographie/
   largeurs/logique des boutons restent ceux de la règle ci-dessus, jamais
   dupliqués. */
#agenda .dcal-item{ min-height:30px; align-items:center; }
.dcal-item-time{ flex:0 0 auto; font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--ink-soft); min-width:58px; }
.dcal-item-title{ flex:1; min-width:0; color:inherit; text-decoration:none; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
a.dcal-item-title:hover{ text-decoration:underline; }
.dcal-item.dcal-allday .dcal-item-time{ font-style:italic; }

.dcal-item.dcal-reunion, .dcal-item.dcal-tache{ border-left-color:var(--steel); background:var(--steel-light); }
.dcal-item.dcal-conge{ border-left-color:var(--red); background:var(--red-bg); }
.dcal-item.dcal-reperage{ border-left-color:var(--green); background:var(--green-bg); }
.dcal-item.dcal-deplacement{ border-left-color:var(--amber-dark); background:var(--amber-bg); }
.dcal-item.dcal-autre{ border-left-color:var(--line-strong); background:var(--paper); }
/* Événements projet (complément Agenda, 2026-08-25) — mêmes 4 classes
   statut EXACTEMENT que .cal-item.confirme/.en_cours/.prospect/.termine
   ci-dessus (jamais une seconde palette), voir agenda.php pour le détail. */
.dcal-item.dcal-confirme{ border-left-color:var(--steel); background:var(--steel-light); }
.dcal-item.dcal-en_cours{ border-left-color:var(--amber-dark); background:var(--amber-bg); }
.dcal-item.dcal-prospect{ border-left-color:var(--line-strong); background:transparent; }
.dcal-item.dcal-termine{ border-left-color:var(--green); background:var(--green-bg); }
/* Congés/Indisponibilités (Planning V1, 2026-08-25) — mêmes couleurs
   EXACTEMENT que .cal-item.conge_attente/.indisponibilite ci-dessus, jamais
   une seconde palette pour le widget Dashboard. */
.dcal-item.dcal-conge_attente{ border-left-color:var(--red); background:var(--red-bg); }
.dcal-item.dcal-indisponibilite{ border-left-color:var(--amber-dark); background:var(--amber-bg); }

/* Avertissement de conflit de disponibilité — composant partagé (Planning V1,
   complément 2026-08-25), voir assets/js/availability-conflict-warning.js.
   Jamais bloquant : purement informatif, mêmes tons que le reste des
   avertissements de l'ERP (amber, jamais rouge — un conflit n'est pas une
   erreur de saisie). */
.availability-warning{ margin-top:10px; padding:10px 14px; border-radius:var(--radius-sm); background:var(--amber-bg); color:var(--amber-dark); font-size:13px; }
.availability-warning-title{ font-weight:700; margin-bottom:4px; }
.availability-warning-line{ line-height:1.5; }

.dcal-switch{ display:flex; gap:6px; margin:14px 0 10px; }
.dcal-switch-btn{
  font-family:'Inter',sans-serif; font-size:12.5px; font-weight:600; padding:6px 14px;
  border-radius:var(--radius-pill); border:1px solid var(--line-strong); background:var(--paper); color:var(--ink-soft); cursor:pointer;
  text-decoration:none; display:inline-block;
}
.dcal-switch-btn.active{ background:var(--brand); border-color:var(--brand); color:#fff; }
.dcal-hidden{ display:none; }

/* Grille Semaine/Mois du widget Dashboard : réutilise directement .cal-grid/
   .cal-dow/.cal-cell/.cal-daynum/.cal-item (voir plus haut, "Calendrier mensuel")
   — même langage graphique que agenda.php, aucune grille parallèle ici. */
.dcal-nav{ display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.dcal-nav-period{ font-family:'JetBrains Mono',monospace; font-size:12.5px; color:var(--ink-soft); flex:1; text-align:center; }
.dcal-month-scroll{ overflow-x:auto; }
.dcal-month-scroll .cal-grid{ grid-template-columns:repeat(7, minmax(92px, 1fr)); }

/* État de chargement discret pendant une navigation AJAX (Semaine/Mois) —
   la grille déjà affichée reste visible et lisible, jamais remplacée avant
   d'avoir une réponse exploitable. */
.dcal-loading{ opacity:.55; pointer-events:none; transition:opacity .15s ease; }
.dcal-ajax-error{
  font-size:12px; color:var(--red); background:var(--red-bg); border-left:3px solid var(--red);
  border-radius:var(--radius-sm); padding:6px 10px; margin-bottom:8px;
}

@media (max-width: 900px){
  /* Semaine : 7 colonnes minuscules illisibles sur tablette/mobile -> jours
     empilés (une seule colonne), même balisage .cal-grid/.cal-cell qu'en
     desktop (aucune duplication HTML) — seul l'en-tête .cal-dow (Lun/Mar/...)
     est masqué au profit du libellé de jour intégré à chaque cellule. */
  .dcal-week .cal-grid{ grid-template-columns:1fr; }
  .dcal-week .cal-dow{ display:none; }
  .cal-cell-weekday-label{ display:inline; }
  .cal-cell.cal-cell-week{ max-height:none; }
  /* Mois : grille 7 colonnes conservée (structure calendrier reconnaissable)
     mais rendue défilable horizontalement plutôt qu'écrasée illisible —
     aucun débordement horizontal de la page (.dcal-month-scroll contient
     le scroll, jamais le body). */
  .dcal-nav-period{ font-size:11.5px; }
}

/* =====================================================================
   Centre d'aide — mise en page 3 colonnes (navigation | contenu | sommaire),
   typographie de lecture, blocs encadrés, images, recherche.
   Réutilise exclusivement les tokens de thème existants (--paper, --ink,
   --brand, --line...) : fonctionne dans les 4 combinaisons thème déjà
   supportées par l'ERP (clair/sombre × flat/neumorphism) sans code spécifique.
   ===================================================================== */

.hc-page{ padding-top:20px; }

.hc-mobile-menu-btn{
  display:none; align-items:center; gap:8px; margin-bottom:14px;
  font-family:'Inter',sans-serif; font-weight:600; font-size:13px;
  border:1.5px solid var(--line-strong); background:var(--paper-2); color:var(--ink);
  border-radius:var(--radius-sm); padding:9px 14px; cursor:pointer;
}
.hc-overlay{ display:none; position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:29; }
.hc-overlay-visible{ display:block; }

.hc-layout{
  display:grid; grid-template-columns:230px minmax(0,1fr) 220px; gap:28px; align-items:start;
}

/* ---------- Ascenseurs fins, discrets, aux couleurs du thème (colonnes
   défilantes du Centre d'aide : catégories, sommaire, résultats de recherche,
   défilement horizontal des blocs de code, la liste d'éléments de la
   modal de traduction des devis, ET le défilement horizontal de la timeline
   Vue Jour du Planning — même skin partout, jamais un second style) ---------- */
.hc-sidebar, .hc-toc, .hc-search-results, .hc-article pre, #translate-items-list, .pjt-timeline-scroll{
  scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent;
}
.hc-sidebar::-webkit-scrollbar, .hc-toc::-webkit-scrollbar, .hc-search-results::-webkit-scrollbar, #translate-items-list::-webkit-scrollbar{
  width:6px;
}
.hc-article pre::-webkit-scrollbar{
  width:6px; height:6px;
}
/* Timeline : ascenseur horizontal seul, 8px -- c'est ici un vrai moyen de
   navigation (la journée dépasse souvent la largeur écran), pas un simple
   débordement de contenu. */
.pjt-timeline-scroll::-webkit-scrollbar{
  height:8px;
}
.hc-sidebar::-webkit-scrollbar-track, .hc-toc::-webkit-scrollbar-track, .hc-search-results::-webkit-scrollbar-track, .hc-article pre::-webkit-scrollbar-track, #translate-items-list::-webkit-scrollbar-track, .pjt-timeline-scroll::-webkit-scrollbar-track{
  background:transparent;
}
.hc-sidebar::-webkit-scrollbar-thumb, .hc-toc::-webkit-scrollbar-thumb, .hc-search-results::-webkit-scrollbar-thumb, .hc-article pre::-webkit-scrollbar-thumb, #translate-items-list::-webkit-scrollbar-thumb, .pjt-timeline-scroll::-webkit-scrollbar-thumb{
  background-color:var(--line-strong); border-radius:var(--radius-pill);
}
.hc-sidebar:hover::-webkit-scrollbar-thumb, .hc-toc:hover::-webkit-scrollbar-thumb, .hc-search-results:hover::-webkit-scrollbar-thumb, .hc-article pre:hover::-webkit-scrollbar-thumb, #translate-items-list:hover::-webkit-scrollbar-thumb, .pjt-timeline-scroll:hover::-webkit-scrollbar-thumb{
  background-color:var(--ink-soft);
}

/* ---------- Colonne gauche : recherche + catégories ---------- */
.hc-sidebar{
  position:sticky; top:20px; max-height:calc(100vh - 40px); overflow-y:auto;
  display:flex; flex-direction:column; gap:16px; padding-right:4px;
}
.hc-sidebar-head{ display:none; align-items:center; justify-content:space-between; margin-bottom:4px; }
.hc-sidebar-title{ display:flex; align-items:center; gap:8px; font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase; letter-spacing:.03em; font-size:15px; color:var(--ink); }
.hc-sidebar-close{ background:none; border:none; color:var(--ink-soft); cursor:pointer; padding:4px; }

.hc-search{ position:relative; }
.hc-search-input-wrap{
  display:flex; align-items:center; gap:8px; border:1.5px solid var(--line-strong); border-radius:var(--radius-sm);
  background:var(--paper-2); padding:8px 10px; color:var(--ink-soft);
}
.hc-search-input-wrap input{
  border:none; background:none; outline:none; color:var(--ink); font-family:'Inter',sans-serif; font-size:13px; width:100%;
}
.hc-search-results{
  display:none; position:absolute; left:0; right:0; top:calc(100% + 6px); z-index:25;
  background:var(--paper-2); border:1px solid var(--line-strong); border-radius:var(--radius-sm);
  box-shadow:var(--shadow-card); max-height:60vh; overflow-y:auto; padding:6px;
}
.hc-search-results-visible{ display:block; }
.hc-search-result{ display:block; padding:8px 10px; border-radius:var(--radius-sm); text-decoration:none; }
.hc-search-result:hover{ background:var(--paper); }
.hc-search-result-title{ font-size:13px; font-weight:600; color:var(--ink); }
.hc-search-result-group{ font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--brand); margin:2px 0; }
.hc-search-result-excerpt{ font-size:11.5px; color:var(--ink-soft); line-height:1.4; }
.hc-search-empty{ padding:10px; font-size:12.5px; color:var(--ink-soft); font-style:italic; }

.hc-groups{ display:flex; flex-direction:column; gap:4px; }
.hc-group-title{
  display:flex; align-items:center; gap:7px; width:100%; font-size:11px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--ink-soft); font-weight:600; margin:0; padding:8px 4px; border:none; background:none; cursor:pointer;
  font-family:'Inter',sans-serif; text-align:left; border-radius:var(--radius-sm);
}
.hc-group-title:hover{ color:var(--ink); background:var(--paper-2); }
.hc-group-title-label{ display:flex; align-items:center; gap:7px; flex:1; }
.hc-group-chevron{ flex-shrink:0; transition:transform .18s ease; opacity:.7; }
.hc-group-open .hc-group-chevron{ transform:rotate(90deg); }

/* Accordéon : une seule catégorie ouverte à la fois, sous-liste repliée par
   défaut. Technique CSS grid (0fr → 1fr) pour une animation de hauteur
   fluide sans mesurer le DOM en JS. */
.hc-group-items-wrap{ display:grid; grid-template-rows:0fr; transition:grid-template-rows .2s ease; }
.hc-group-open .hc-group-items-wrap{ grid-template-rows:1fr; }
.hc-group-items-wrap > ul{ overflow:hidden; min-height:0; }

.hc-group-items{ list-style:none; margin:4px 0 0; padding:0; display:flex; flex-direction:column; gap:1px; }
.hc-group-items a{
  display:flex; align-items:center; gap:9px; padding:7px 10px 7px 20px; border-radius:var(--radius-sm);
  color:var(--ink-soft); text-decoration:none; font-size:13px; line-height:1.3;
}
.hc-group-items a:hover{ background:var(--paper-2); color:var(--ink); }
.hc-group-items a.active{ background:var(--steel-light); color:var(--steel); font-weight:600; }
.hc-empty-note{ font-size:12.5px; color:var(--ink-soft); font-style:italic; }

/* ---------- Colonne centrale : contenu ---------- */
.hc-content{ min-width:0; }

.hc-notfound{ text-align:center; padding:60px 20px; }
.hc-notfound-icon{ color:var(--ink-soft); margin-bottom:14px; display:flex; justify-content:center; }
.hc-notfound h1{ font-size:22px; margin-bottom:8px; }
.hc-notfound p{ color:var(--ink-soft); margin-bottom:20px; }

.hc-breadcrumb{ display:flex; align-items:center; flex-wrap:wrap; gap:6px; font-size:12px; color:var(--ink-soft); margin-bottom:14px; }
.hc-breadcrumb a{ color:var(--ink-soft); text-decoration:none; }
.hc-breadcrumb a:hover{ color:var(--brand); }
.hc-breadcrumb-sep{ display:inline-flex; opacity:.6; }
.hc-breadcrumb-current{ color:var(--ink); font-weight:600; }

.hc-title{ font-size:30px; margin-bottom:8px; text-transform:none; letter-spacing:0; }
.hc-description{ font-size:15px; color:var(--ink-soft); margin:0 0 16px; max-width:70ch; }

.hc-meta-bar{ display:flex; flex-wrap:wrap; gap:16px; padding-bottom:16px; margin-bottom:24px; border-bottom:1px solid var(--line); }
.hc-meta-item{ display:flex; align-items:center; gap:6px; font-size:12px; color:var(--ink-soft); }

/* ---------- Typographie de l'article rendu (Markdown → HTML) ---------- */
.hc-article{ font-size:15px; line-height:1.7; color:var(--ink); max-width:74ch; }
.hc-article h2{ font-size:22px; text-transform:none; letter-spacing:0; margin:38px 0 14px; scroll-margin-top:20px; }
.hc-article h3{ font-size:17px; text-transform:none; letter-spacing:0; margin:26px 0 10px; scroll-margin-top:20px; }
.hc-article h2:first-child, .hc-article h3:first-child{ margin-top:0; }
.hc-article p{ margin:0 0 16px; }
.hc-article ul, .hc-article ol{ margin:0 0 16px; padding-left:22px; }
.hc-article li{ margin-bottom:6px; }
.hc-article li input[type=checkbox]{ margin-right:8px; }
.hc-article a{ color:var(--brand); text-decoration:underline; text-decoration-color:var(--line-strong); text-underline-offset:2px; }
.hc-article a:hover{ text-decoration-color:var(--brand); }
.hc-article code{ font-family:'JetBrains Mono',monospace; font-size:.88em; background:var(--paper-2); border:1px solid var(--line); border-radius:4px; padding:1px 5px; }
.hc-article pre{ background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius-sm); padding:14px 16px; overflow-x:auto; margin:0 0 16px; }
.hc-article pre code{ background:none; border:none; padding:0; }
.hc-article blockquote{ margin:0 0 16px; padding:2px 16px; border-left:3px solid var(--line-strong); color:var(--ink-soft); }
.hc-article table{ width:100%; border-collapse:collapse; margin:0 0 20px; font-size:13.5px; }
.hc-article th{ text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); padding:8px 10px; border-bottom:1px solid var(--line-strong); }
.hc-article td{ padding:9px 10px; border-bottom:1px solid var(--line); }
.hc-article hr{ border:none; border-top:1px solid var(--line); margin:28px 0; }
.hc-article .hc-heading-anchor{
  margin-right:8px; color:var(--line-strong); text-decoration:none; font-weight:400; font-size:.85em;
  transition:color .12s;
}
.hc-article .hc-heading-anchor:hover{ color:var(--brand); }

/* ---------- Blocs encadrés (info/astuce/attention/important/bonne pratique/exemple/faq) ---------- */
.hc-admonition{
  margin:0 0 20px; padding:14px 16px 14px 16px; border-radius:var(--radius-sm);
  border:1px solid var(--line); border-left:4px solid var(--line-strong); background:var(--paper-2);
}
.hc-admonition-title{ display:flex; align-items:center; gap:9px; font-weight:700; font-size:13.5px; margin-bottom:8px; }
.hc-admonition-body{ font-size:14px; color:var(--ink); }
.hc-admonition-body > *:last-child{ margin-bottom:0; }
.hc-admonition-info{ border-left-color:var(--steel); } .hc-admonition-info .hc-admonition-title{ color:var(--steel); }
.hc-admonition-tip{ border-left-color:var(--green); } .hc-admonition-tip .hc-admonition-title{ color:var(--green); }
.hc-admonition-warning{ border-left-color:var(--amber); } .hc-admonition-warning .hc-admonition-title{ color:var(--amber-dark); }
.hc-admonition-important{ border-left-color:var(--red); } .hc-admonition-important .hc-admonition-title{ color:var(--red); }
.hc-admonition-practice{ border-left-color:var(--brand); } .hc-admonition-practice .hc-admonition-title{ color:var(--brand); }
.hc-admonition-example{ border-left-color:var(--ink-soft); } .hc-admonition-example .hc-admonition-title{ color:var(--ink-soft); }
.hc-admonition-faq{ border-left-color:var(--steel); } .hc-admonition-faq .hc-admonition-title{ color:var(--steel); }

/* ---------- Images : responsive + agrandissement ---------- */
.hc-article .hc-img{ max-width:100%; height:auto; border-radius:var(--radius-sm); border:1px solid var(--line); display:block; margin:8px 0 20px; }
.hc-lightbox{
  position:fixed; inset:0; background:rgba(0,0,0,.82); z-index:60;
  display:none; align-items:center; justify-content:center; padding:40px; cursor:zoom-out;
}
/* [hidden] seul seul ne suffit pas : la règle .hc-lightbox ci-dessus (même
   spécificité qu'un attribut, mais définie après dans la cascade) l'emporterait
   sinon sur la règle UA display:none des navigateurs, laissant le calque
   visible en permanence. */
.hc-lightbox:not([hidden]){ display:flex; }
.hc-lightbox img{ max-width:100%; max-height:100%; border-radius:var(--radius-sm); box-shadow:0 10px 40px rgba(0,0,0,.5); }
.hc-lightbox-close{ position:absolute; top:20px; right:24px; background:none; border:none; color:#fff; cursor:pointer; padding:6px; }

/* ---------- Précédent / suivant ---------- */
.hc-prevnext{ display:flex; justify-content:space-between; gap:16px; margin-top:36px; padding-top:20px; border-top:1px solid var(--line); }
.hc-prevnext-link{
  display:flex; align-items:center; gap:10px; text-decoration:none; color:var(--ink); max-width:48%;
  border:1px solid var(--line); border-radius:var(--radius-sm); padding:10px 14px; background:var(--paper-2);
}
.hc-prevnext-link:hover{ border-color:var(--line-strong); }
.hc-prevnext-next{ margin-left:auto; text-align:right; }
.hc-prevnext-label{ display:block; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
.hc-prevnext-title{ display:block; font-size:13.5px; font-weight:600; }

/* ---------- Colonne droite : sommaire ---------- */
.hc-toc{ position:sticky; top:20px; max-height:calc(100vh - 40px); overflow-y:auto; font-size:12.5px; }
.hc-toc-title{ font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); font-weight:600; margin-bottom:10px; }
.hc-toc ul{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:2px; border-left:1.5px solid var(--line); }
.hc-toc li a{
  display:block; padding:5px 0 5px 12px; color:var(--ink-soft); text-decoration:none; line-height:1.35;
  border-left:1.5px solid transparent; margin-left:-1.5px;
}
.hc-toc li.hc-toc-level-3 a{ padding-left:24px; font-size:11.5px; }
.hc-toc li a:hover{ color:var(--ink); }
.hc-toc li a.hc-toc-active{ color:var(--brand); border-left-color:var(--brand); font-weight:600; }

/* ---------- Bouton d'aide contextuelle (infrastructure, pas encore utilisé) ---------- */
.hc-help-button{
  display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px;
  border-radius:50%; border:1.5px solid var(--line-strong); color:var(--ink-soft); text-decoration:none; flex-shrink:0;
}
.hc-help-button:hover{ border-color:var(--brand); color:var(--brand); }

/* ---------- Responsive ---------- */
@media (max-width: 1180px){
  .hc-layout{ grid-template-columns:210px minmax(0,1fr); }
  .hc-toc{ display:none; }
}

@media (max-width: 880px){
  .hc-mobile-menu-btn{ display:inline-flex; }
  .hc-layout{ display:block; }
  .hc-sidebar{
    position:fixed; top:0; left:0; bottom:0; width:280px; max-width:82vw; max-height:none;
    background:var(--paper); border-right:1px solid var(--line-strong); z-index:30; padding:18px;
    transform:translateX(-100%); transition:transform .18s ease; box-shadow:0 0 30px rgba(0,0,0,.25);
  }
  .hc-sidebar-open{ transform:translateX(0); }
  .hc-sidebar-head{ display:flex; }
  .hc-prevnext{ flex-direction:column; }
  .hc-prevnext-link{ max-width:100%; }
  .hc-prevnext-next{ margin-left:0; text-align:left; }
}

/* ===========================================================================
   ONGLET RH DE LA FICHE PROJET — « BESOINS RH » (2026-09-01)
   Même famille visuelle que le Dashboard Planning et la Vue Jour : cartes
   plates, hiérarchie forte, aucun panneau décoratif. Uniquement des tokens du
   design system — dark/light suivent donc sans règle dédiée.
   Le ROUGE ne signale qu'un manque réel appelant une action ; le VERT ne sert
   qu'à une couverture réellement complète, jamais en décoration.
   =========================================================================== */
.prh-lead{ font-size:12.5px; color:var(--ink-soft); margin:0 0 10px; line-height:1.5; }

/* Groupes de devis d'un projet (onglet Devis) et blocs RH par devis.
   Aucune couleur inventée : mêmes variables que le reste de la fiche. */
/* Chaque proposition est une CARTE distincte : une simple bordure fine se
   perdait sur fond sombre, et deux propositions se lisaient comme une seule
   longue liste — exactement ce que cet écran doit éviter. */
.quote-group{ background:var(--paper-2); border:1px solid var(--line-strong); border-left:3px solid var(--brand);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0; padding:14px 16px; margin-bottom:18px; }
/* Devenue une CARTE REPLIABLE (2026-09-04). Le fond, la bordure et la barre
   orange restent EXACTEMENT ceux de `.quote-finance-group` (stratégie
   d'acomptes) : c'est le même composant, il doit se présenter pareil. Seule
   l'espacement suit celui des cartes. */
.quote-group.fin-card{ margin-bottom:10px; }
/* Actions du bas de carte : historique et création d'une nouvelle version. */
.qv-actions{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:10px; }
.qv-history{ margin-top:12px; }
/* L'historique est un second niveau de lecture : il s'annonce comme tel plutôt
   que de se présenter à égalité avec les versions qui comptent. */
.qv-history .quote-version-table{ opacity:.92; }
.quote-group:last-child{ margin-bottom:0; }
.quote-group-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:12px; }
.quote-group-head > div:first-child{ flex:1 1 260px; min-width:0; }
.quote-group-base{ display:block; font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase;
  font-size:17px; letter-spacing:.04em; color:var(--brand); }
.quote-group-meta{ display:block; font-size:12px; color:var(--ink-soft); margin-top:2px; }
.quote-group-warn{ font-size:12px; color:var(--amber-dark); margin-top:4px; }
.quote-group-subject{ display:block; font-size:13.5px; font-weight:600; color:var(--ink); margin-top:1px; }
.quote-group table.data{ background:var(--paper); border-radius:var(--radius-sm); }
.quote-group table.data tr.is-current > td{ font-weight:600; }

/* ---------------------------------------------------------------------------
   TABLEAU DES VERSIONS D'UN DEVIS (onglet Devis de la fiche projet)
   ---------------------------------------------------------------------------
   Répartition VOULUE de la largeur : « Objet / référence » prend tout l'espace
   restant, parce que c'est la colonne qu'on lit pour savoir de quoi il s'agit.
   Les autres sont dimensionnées par leur contenu réel (`min-width` + `width`
   sur un tableau `auto`), jamais par une largeur rigide en pixels : un objet
   long ou un libellé français plus long doit pouvoir respirer.               */
.quote-table-scroll{ overflow-x:auto; }
.quote-version-table{ min-width:760px; }
.quote-version-table th, .quote-version-table td{ vertical-align:top; }
.quote-version-table th.qvt-version,   .quote-version-table td.qvt-version{ width:1%; min-width:120px; white-space:nowrap; }
.quote-version-table th.qvt-subject{ width:auto; }
.quote-version-table td.qvt-subject{ min-width:200px; }
.quote-version-table th.qvt-status,    .quote-version-table td.qvt-status{ width:1%; min-width:104px; }
.quote-version-table th.qvt-amount,    .quote-version-table td.qvt-amount{ width:1%; min-width:104px; white-space:nowrap; }
.quote-version-table th.qvt-translation, .quote-version-table td.qvt-translation{ width:1%; min-width:56px; text-align:center; }
.quote-version-table th.qvt-date,      .quote-version-table td.qvt-date{ width:1%; min-width:92px; white-space:nowrap; }
.quote-version-table th.qvt-pdf,       .quote-version-table td.qvt-pdf{ width:1%; min-width:84px; white-space:nowrap; }

/* Ligne principale / ligne secondaire d'une cellule : la version et la
   référence en évidence, leur précision juste en dessous. C'est ce qui remplace
   les piles de pastilles — du texte, lisible, jamais dépendant de la couleur
   pour être compris. */
.quote-version-table .qvt-version-main{ display:block; font-weight:600; }
.quote-version-table .qvt-ref{ display:block; font-weight:600; }
.quote-version-table .qvt-sub{ display:block; font-size:12px; color:var(--ink-soft); margin-top:2px; line-height:1.35; }
.quote-cell-fallback{ color:var(--ink-soft); font-style:italic; }

/* État de traduction : un mot lisible, pas une pastille. La couleur ne fait
   que RENFORCER un libellé déjà explicite. */
/* Cible de survol confortable autour d'une icône seule : sans elle,
   l'infobulle — qui porte ici tout le texte de l'état — serait difficile à
   atteindre. */
.qvt-trad{ display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px; cursor:help; }
.qvt-trad .wabu-icon{ flex:0 0 auto; }
/* « Non nécessaire » : la bibliothèque n'a pas de variante grise, l'icône suit
   donc le thème et c'est cette atténuation qui la fait lire comme neutre. */
.qvt-trad.is-na{ color:var(--ink-soft); font-weight:500; }
.qvt-trad.is-na .wabu-icon{ opacity:.45; }
.qvt-trad.is-ready{ color:var(--green); }
.qvt-trad.is-todo{ color:var(--amber-dark); }
.qvt-trad.is-stale{ color:var(--red); }

/* Action PDF : icône + texte, jamais l'icône seule. Cible de clic large. */
.qvt-pdf-btn{ display:inline-flex; align-items:center; gap:6px; padding:5px 10px; line-height:1.2; }
.qvt-pdf-btn .wabu-icon{ flex:0 0 auto; }
.qvt-pdf-btn[disabled]{ opacity:.6; cursor:progress; }
.qvt-pdf-btn.is-guarded{ border-style:dashed; color:var(--ink-soft); }

/* Largeur réduite : le tableau devient une pile de cartes libellées plutôt
   qu'une grille écrasée. Chaque cellule porte son intitulé via `data-label`,
   donc aucune information d'en-tête n'est perdue, et plus aucune colonne
   n'impose sa largeur au contenu. */
@media (max-width: 720px){
  .quote-table-scroll{ overflow-x:visible; }
  .quote-version-table{ min-width:0; }
  .quote-version-table thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
  .quote-version-table, .quote-version-table tbody, .quote-version-table tr, .quote-version-table td{ display:block; width:auto; }
  .quote-version-table tr{ border:1px solid var(--line); border-radius:var(--radius-sm); padding:10px 12px; margin-bottom:10px; }
  .quote-version-table tr:last-child{ margin-bottom:0; }
  .quote-version-table td{ border-bottom:none; padding:3px 0; min-width:0 !important; white-space:normal; }
  .quote-version-table td[data-label]::before{
    content:attr(data-label) " : "; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em;
    color:var(--ink-soft); margin-right:6px;
  }
  /* Version, référence et objet n'ont pas besoin de leur intitulé : ils
     ouvrent la carte et se lisent seuls. */
  .quote-version-table td.qvt-version::before, .quote-version-table td.qvt-subject::before{ content:none; }
  .quote-version-table td.qvt-version{ white-space:normal; }
  .quote-version-table td.qvt-pdf{ margin-top:6px; }
  .quote-version-table td.qvt-translation{ text-align:left; }
  .quote-version-table td.qvt-translation .qvt-trad{ width:auto; height:auto; vertical-align:middle; }
}

/* Bloc financier d'un devis (onglet Financier). Même gabarit que .quote-group,
   classe distincte : l'onglet Devis et l'onglet Financier montrent le même
   devis sous deux angles, et rien ne doit les confondre. */
.quote-finance-group{ background:var(--paper-2); border:1px solid var(--line-strong); border-left:3px solid var(--brand);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0; padding:14px 16px; }

.quote-rh-block{ border:1px solid var(--line); border-radius:var(--radius-sm); padding:12px 14px; margin-bottom:12px; }
/* Un devis qui contribue au VENDU se distingue de ceux qui ne pèsent que sur la
   prévision — même repère visuel que .quote-group, jamais une couleur inventée. */
.quote-rh-block.is-source{ border-left:3px solid var(--brand); }
.quote-rh-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:8px; }

/* Les deux synthèses (vendu / prévision) : deux blocs de même forme, pour que
   la comparaison soit immédiate et qu'aucun des deux ne passe pour l'autre. */
.quote-synthese{ background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:12px 14px; margin-bottom:12px; }
.quote-synthese-title{ font-family:'Barlow Condensed',sans-serif; font-weight:700; text-transform:uppercase;
  font-size:14px; letter-spacing:.05em; color:var(--brand); margin-bottom:6px; }
.quote-synthese .prh-lead{ margin:0; }
.quote-synthese .empty-state{ padding:8px 0; }

/* Historique des versions d'un devis, sous son bloc RH : lisible sans tableau,
   chaque version gardant son statut réel et son éventuel repère « remplacée ». */
.quote-version-list{ list-style:none; margin:10px 0 0; padding:10px 0 0; border-top:1px dashed var(--line);
  font-size:12px; color:var(--ink-soft); }
.quote-version-list li{ padding:2px 0; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.prh-muted{ color:var(--ink-soft); font-size:12px; }
.prh-hint{ font-size:11.5px; color:var(--ink-soft); margin-top:4px; line-height:1.45; }
.prh-hint-inline{ font-weight:400; color:var(--ink-soft); font-size:11px; }

.prh-summary{ display:flex; flex-wrap:wrap; align-items:center; gap:20px; }
.prh-summary-figures{ display:flex; gap:22px; }
.prh-figure{ display:flex; flex-direction:column; gap:2px; }
.prh-figure-value{ font-size:26px; font-weight:700; line-height:1; }
.prh-figure-label{ font-size:11.5px; color:var(--ink-soft); }
.prh-figure.missing .prh-figure-value{ color:var(--red); }
.prh-summary-note{ flex:1 1 220px; min-width:200px; display:flex; flex-direction:column; gap:3px;
  font-size:11.5px; color:var(--ink-soft); line-height:1.45; }

.prh-warn{ display:flex; align-items:flex-start; gap:9px; font-size:12.5px; line-height:1.5; }

.prh-phase-tag{ display:inline-flex; align-items:center; gap:5px;
  padding:2px 8px; border-radius:999px; font-size:10.5px;
  font-weight:700; text-transform:uppercase; letter-spacing:.03em;
  background:var(--line); color:var(--ink-soft); }
/* L'icône prend la couleur de la pastille : elle appartient au libellé, elle
   ne s'annonce pas comme un élément à part. */
.prh-phase-tag .wabu-icon{ flex:0 0 auto; color:currentColor; }
/* MÊMES COULEURS DE PHASE que le Planning opérationnel (2026-09-04).
   Le fond reprend le jeton `--phase-*-bg` des blocs de la Vue Jour et des
   pastilles de timeline, en teinte ; le TEXTE prend l'équivalent sémantique
   déjà défini plus bas (.phase-montage/.phase-permanence/.phase-demontage),
   qui suit le thème — écrire `--phase-*-bg` en texte serait illisible sur
   fond sombre. Montage était orange et Démontage gris : deux couleurs qui ne
   correspondaient à rien ailleurs dans l'ERP. */
.prh-phase-tag.montage{ background:color-mix(in srgb, var(--phase-montage-bg) 18%, transparent); color:var(--steel); }
.prh-phase-tag.permanence{ background:color-mix(in srgb, var(--phase-permanence-bg) 18%, transparent); color:var(--green); }
.prh-phase-tag.demontage{ background:color-mix(in srgb, var(--phase-demontage-bg) 18%, transparent); color:var(--violet); }
.prh-phase-tag.autre{ background:color-mix(in srgb, var(--phase-autre-bg) 18%, transparent); color:var(--orange); }

.prh-needs{ display:flex; flex-direction:column; gap:12px; }
.prh-need-group{ border:1px solid var(--line); border-radius:8px; padding:10px 12px; }
.prh-need-head{ display:flex; align-items:center; gap:8px; margin-bottom:6px; font-size:13.5px; }
.prh-need-lines{ display:flex; flex-direction:column; gap:4px; }
.prh-need-line{ display:flex; align-items:center; gap:10px; font-size:12.5px; }
.prh-need-line.prh-need-exception{ padding-left:12px; border-left:2px solid var(--line-strong); }
.prh-need-scope{ flex:1 1 auto; color:var(--ink-soft); }
.prh-need-qty{ font-family:'JetBrains Mono',monospace; font-weight:600; }
.prh-need-actions{ display:inline-flex; gap:6px; flex-shrink:0; }
/* Boutons d'action d'une ligne de besoin : convention EXACTE du Planning
   opérationnel (`btn small` / `btn small danger` + icône 'standard'), simplement
   resserrés pour tenir dans une ligne dense. Aucune classe de bouton inventée. */
.prh-need-actions .btn.small{ padding:3px 7px; line-height:1; display:inline-flex; align-items:center; }

.prh-days{ display:flex; flex-direction:column; gap:12px; }
.prh-day{ display:flex; flex-direction:column; gap:10px; }
.prh-day.has-missing{ border-left:3px solid var(--red); }
.prh-day-head{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px; }
.prh-day-when{ display:flex; align-items:center; gap:8px; font-size:13.5px; }
.prh-day-actions{ display:flex; align-items:center; gap:10px; }
.prh-day-total{ font-family:'JetBrains Mono',monospace; font-size:13px; font-weight:700; }
.prh-day-total.missing{ color:var(--red); }
.prh-day-total.covered{ color:var(--green); }
.prh-day-table{ margin:0; }
.prh-day-table td, .prh-day-table th{ font-size:12.5px; }
.prh-day-table .missing{ color:var(--red); font-weight:700; }
.prh-row-missing td:first-child{ font-weight:600; }
.prh-day-people{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; padding-top:8px;
  border-top:1px solid var(--line); }
.prh-badge{ display:inline-block; margin-left:5px; padding:0 6px; border-radius:999px;
  background:var(--line); color:var(--ink-soft); font-size:10.5px; font-weight:600; }

.prh-interventions{ display:flex; flex-direction:column; gap:10px; }
.prh-intervention{ border:1px solid var(--line); border-radius:8px; padding:10px 12px; }
.prh-intervention-head{ display:flex; flex-wrap:wrap; align-items:baseline; gap:8px; margin-bottom:6px; }
.prh-intervention-lines{ display:flex; flex-direction:column; gap:4px; font-size:12.5px; }
.prh-intervention-lines > div{ display:flex; align-items:center; gap:8px; }

.prh-form-actions{ display:flex; justify-content:flex-end; margin-top:14px; }

@media (max-width: 700px){
  .prh-summary{ gap:14px; }
  .prh-summary-figures{ gap:16px; }
  .prh-day-head{ align-items:flex-start; }
}

/* ============================================================
   STRATÉGIES D'ACOMPTES — onglet Financier (2026-09-04)

   L'écran empilait, par famille : un titre, la référence, le numéro complet du
   devis, sa version, son PO, son objet, trois phrases de montants, deux badges
   en capitales et DEUX tableaux complets. À trois familles il fallait parcourir
   toute la page pour retrouver un seul devis.

   La hiérarchie tient désormais en cinq niveaux, et un seul par ligne :
     référence/objet → résumé chiffré → onglets → échéancier → actions.

   Les champs passent par `.field`, le gabarit d'input partagé de l'ERP : rien
   n'est restylé ici. Une première version posait sa propre bordure
   `var(--line)` — invisible dans les deux thèmes où cette variable vaut
   `transparent`, où les champs se lisaient alors comme du texte plat.
   ============================================================ */

/* ---- Synthèse du projet : trois valeurs, pas une phrase en italique ---- */
.fin-summary{
  display:flex; align-items:baseline; gap:22px; flex-wrap:wrap;
  padding:12px 14px; margin-bottom:16px;
  border:1px solid var(--line-strong); border-radius:var(--radius-sm);
  background:var(--paper-2);
}
.fin-summary-title{
  font-size:11.5px; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-soft);
}
.fin-summary-figures{ display:flex; gap:22px; flex-wrap:wrap; }
.fin-summary-figures > div{ display:flex; flex-direction:column; gap:2px; }
.fin-summary-label{ font-size:10.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--ink-soft); }
.fin-summary-value{ font-family:'JetBrains Mono',monospace; font-size:14px; font-weight:600; color:var(--ink); }

/* ---- Carte de famille, repliable ---- */
.fin-card{ margin-bottom:10px; }
.fin-card-head{
  display:flex; align-items:center; gap:14px; width:100%;
  padding:11px 14px; text-align:left; cursor:pointer;
  background:var(--paper-2); color:var(--ink);
  border:1px solid var(--line-strong); border-radius:var(--radius-sm);
  font-family:inherit; font-size:13px;
}
.fin-card.is-open .fin-card-head{ border-bottom-left-radius:0; border-bottom-right-radius:0; }
.fin-card-head:hover{ border-color:var(--brand); }
/* Le focus clavier doit se voir : cet en-tête EST le contrôle d'ouverture. */
.fin-card-head:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }

/* Chevron dessiné en CSS — aucune icône WABU ne le fournit, et en créer un
   fichier pour un triangle serait une icône de plus à maintenir. */
.fin-chevron{
  flex:0 0 auto; width:8px; height:8px;
  border-right:1.5px solid var(--ink-soft); border-bottom:1.5px solid var(--ink-soft);
  transform:rotate(-45deg); transition:transform .15s ease; margin-left:2px;
}
.fin-card.is-open .fin-chevron{ transform:rotate(45deg); }

.fin-card-id{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; min-width:0; flex:1 1 auto; }
.fin-ref{ font-family:'JetBrains Mono',monospace; font-weight:600; color:var(--brand); }
.fin-subject{ color:var(--ink-soft); font-size:12.5px; }

/* La RÉPARTITION des acomptes, lisible carte repliée : c'est la première chose
   qu'on vient vérifier sur un devis. Monospace pour que les pourcentages
   s'alignent d'une carte à l'autre. */
/* Code de langue du projet, dans le panneau d'en-tête : une pastille discrète
   à côté du nom en toutes lettres — « Français FR ». Monospace pour qu'elle se
   lise comme un code et non comme un mot de plus. */
.lang-chip{
  display:inline-block; margin-left:6px; padding:1px 6px;
  border:1px solid var(--line-strong); border-radius:3px;
  font-family:'JetBrains Mono',monospace; font-size:10.5px; font-weight:600;
  letter-spacing:.04em; color:var(--ink-soft); vertical-align:middle;
}

.fin-split{
  font-family:'JetBrains Mono',monospace; font-size:11.5px;
  color:var(--ink-soft); white-space:nowrap;
}

.fin-figures{ display:flex; gap:16px; flex-wrap:wrap; font-size:12px; color:var(--ink-soft); }
.fin-figures strong{ font-family:'JetBrains Mono',monospace; color:var(--ink); font-weight:600; }

.fin-card-body{
  padding:14px; border:1px solid var(--line-strong); border-top:none;
  border-bottom-left-radius:var(--radius-sm); border-bottom-right-radius:var(--radius-sm);
}

/* ---- Onglets Applicable / Prévision ---- */
.fin-tabs{ display:flex; gap:4px; margin-bottom:12px; border-bottom:1px solid var(--line-strong); }
.fin-tab{
  padding:7px 14px; cursor:pointer; font-family:inherit; font-size:12.5px;
  background:none; border:none; border-bottom:2px solid transparent;
  color:var(--ink-soft); margin-bottom:-1px; white-space:nowrap;
}
.fin-tab:hover{ color:var(--ink); }
.fin-tab.is-active{ color:var(--brand); border-bottom-color:var(--brand); font-weight:600; }
.fin-tab:focus-visible{ outline:2px solid var(--brand); outline-offset:-2px; }

/* Ligne de contexte discrète : « Basé sur le devis … », « Base : … » */
.fin-context{
  display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  margin:0 0 10px; font-size:12px; color:var(--ink-soft);
}
/* L'icône d'aide portait `opacity:.75` : à 14 px sur un fond clair elle
   devenait un rond fantôme qu'on ne pensait pas à survoler. Elle garde donc sa
   pleine opacité — c'est déjà une icône discrète. */
.fin-info{ display:inline-flex; cursor:help; }
.fin-info:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; border-radius:2px; }
.fin-help{ margin:8px 0 0; font-size:11.5px; color:var(--ink-soft); }

/* ---- Tableau éditable ---- */
.inst-table .field{ margin:0; }
.inst-table input[type="number"]{ font-family:'JetBrains Mono',monospace; text-align:right; }

/* Un champ en lecture seule ne doit pas ressembler à un champ saisissable :
   il porte un solde final calculé par le serveur. */
.inst-table input[readonly]{ color:var(--ink-soft); cursor:not-allowed; border-bottom-style:dotted; }

.inst-table .inst-amount{ white-space:nowrap; font-size:12.5px; }

/* Date FIGÉE par une facture envoyée : c'est la date d'émission du document,
   plus une prévision. Elle se distingue des champs saisissables voisins. */
.fin-date-frozen{ color:var(--ink-soft); cursor:help; }
.inst-table .inst-remove{ line-height:1; padding:4px 9px; }
.inst-row .badge{ margin-left:6px; }

.inst-actions{ display:flex; gap:10px; align-items:center; margin-top:10px; flex-wrap:wrap; }

/* Le SOLDE FINAL n'est pas une échéance de plus : c'est ce qui reste. Rien de
   ce qui le définit ne se saisit — libellé, position, pourcentage — et la ligne
   le dit visuellement au lieu de laisser croire à une saisie possible. */
.inst-row.is-final-row .inst-label{ font-weight:600; }

/* État d'autosauvegarde — même vocabulaire que partout dans l'ERP. */
.inst-status{ font-size:11.5px; color:var(--ink-soft); }
.inst-status.is-saving{ color:var(--ink-soft); }
.inst-status.is-saved{ color:var(--green, #4a7c59); }
.inst-status.is-error{ color:var(--red, #b3261e); font-weight:600; }


/* Un badge conservé garde une largeur naturelle : `white-space: nowrap` et un
   padding lisible, pour qu'il ne se ratatine jamais dans une cellule étroite. */
.inst-row .badge, .fin-card-id .badge{ white-space:nowrap; }

/* En écran étroit, le tableau défile dans son conteneur plutôt que de pousser
   la page entière à défiler horizontalement, et l'en-tête s'empile. */
@media (max-width: 900px){
  .inst-table{ min-width:640px; }
  .fin-card-head{ flex-wrap:wrap; }
  .fin-figures{ width:100%; padding-left:22px; }
}

/* ===========================================================================
   ARBITRAGE OPÉRATIONNEL — TIMELINE VERTICALE (project_operations_diff.php)
   ---------------------------------------------------------------------------
   Même famille visuelle que « Prochainement » du dashboard Planning et que la
   timeline de l'onglet Agenda : la grille date/rail/carte, le rail et les
   pastilles de phase sont LITTÉRALEMENT les mêmes règles — `.pops-timeline` et
   `.pops-tl-item` ont été ajoutés aux sélecteurs `.pdash-*` plus haut, et les
   classes `pdash-tl-date/dow/day/month/rail/dot` sont réutilisées telles
   quelles. Seule la CARTE est propre à cet écran : elle porte une décision,
   pas un lien.

   Tout vient des tokens du thème (--paper, --line-strong, --green, --red,
   --amber, --phase-*) : clair, sombre et neumorphisme suivent sans une seule
   règle dédiée.
   =========================================================================== */
.pops-tl-card{
  background:var(--paper); border:1px solid var(--line-strong);
  border-radius:var(--radius-sm); padding:14px 16px; margin:8px 0 14px;
  border-left-width:3px; border-left-color:var(--line-strong);
}
/* La couleur du liseré dit la NATURE du changement, avant même de lire. */
.pops-tl-card.kind-added{ border-left-color:var(--green); }
.pops-tl-card.kind-removed{ border-left-color:var(--red); }
.pops-tl-card.kind-changed{ border-left-color:var(--steel); }
.pops-tl-card.kind-unchanged{ background:transparent; border-style:dashed; border-left-color:var(--line); }
/* Une décision OBLIGATOIRE se voit de loin : c'est elle qui bloque l'envoi. */
.pops-tl-card.is-required{ border-color:var(--amber-dark); border-left-color:var(--amber-dark);
  box-shadow:0 0 0 1px var(--amber-bg); }

.pops-card-head{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
.pops-card-title{ font-size:14.5px; font-weight:700; }
.pops-card-sub{ font-size:12px; color:var(--ink-soft); }
.pops-kind{ font-size:10px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  padding:2px 7px; border-radius:2px; white-space:nowrap; }
.pops-kind-added{ background:var(--green-bg); color:var(--green); }
.pops-kind-removed{ background:var(--red-bg); color:var(--red); }
.pops-kind-changed{ background:var(--steel-light); color:var(--steel); }
.pops-kind-required{ background:var(--amber-bg); color:var(--amber-dark); }

/* --- Les écarts : une ligne lisible, pas un tableau à trois colonnes ------ */
.pops-changes{ list-style:none; margin:12px 0 0; padding:0; display:flex; flex-direction:column; gap:7px; }
.pops-change{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; font-size:13px; }
.pops-change-field{ min-width:96px; font-size:11px; letter-spacing:.05em; text-transform:uppercase; color:var(--ink-soft); }
/* La valeur sortante est barrée : on voit ce qu'on abandonne, pas seulement
   ce qu'on adopte. */
.pops-change-from{ color:var(--ink-soft); text-decoration:line-through; text-decoration-thickness:1px; }
.pops-change-arrow{ color:var(--ink-soft); }
.pops-change-to{ font-weight:600; }
.pops-change-flag{ font-size:10.5px; color:var(--amber-dark); background:var(--amber-bg);
  border-radius:2px; padding:1px 5px; }

/* --- Journées concernées ------------------------------------------------- */
.pops-days{ margin-top:12px; padding-top:10px; border-top:1px dashed var(--line); font-size:12.5px; }
.pops-day{ display:flex; flex-direction:column; gap:5px; padding:7px 0; }
.pops-day + .pops-day{ border-top:1px dashed var(--line); }
.pops-day-sub{ font-size:12px; color:var(--ink-soft); }

/* --- La décision : deux faces côte à côte, pas deux phrases empilées ------
   Le bouton radio reste le contrôle réel (clavier, `required`, POST) ; il est
   seulement rendu invisible et habillé par son libellé. */
.pops-choice{ display:flex; gap:8px; flex-wrap:wrap; margin-top:13px; }
.pops-opt{ position:relative; display:inline-flex; cursor:pointer; }
.pops-opt input{ position:absolute; opacity:0; width:0; height:0; }
.pops-opt-face{ display:inline-flex; align-items:center; gap:7px; padding:7px 13px;
  border:1px solid var(--line-strong); border-radius:var(--radius-sm);
  font-size:12.5px; color:var(--ink-soft); background:var(--paper-2); transition:none; }
.pops-opt:hover .pops-opt-face{ border-color:var(--ink-soft); color:var(--ink); }
.pops-opt input:checked + .pops-opt-face{ border-color:var(--brand); color:var(--ink);
  font-weight:600; box-shadow:inset 0 0 0 1px var(--brand); }
.pops-opt input:focus-visible + .pops-opt-face{ outline:2px solid var(--brand); outline-offset:2px; }
/* L'explication ne prend la place d'une phrase que lorsqu'elle est utile. */
.pops-opt-hint{ font-size:11.5px; color:var(--ink-soft); margin-top:6px; }

/* --- Repères du fil ------------------------------------------------------ */
.pops-tl-dot.kind-unchanged{ background:transparent; box-shadow:0 0 0 2px var(--line-strong), 0 0 0 5px var(--paper-2); }
.pops-note{ font-size:12px; color:var(--ink-soft); margin-top:8px; }

@media (max-width:640px){
  .pops-tl-item{ grid-template-columns:44px 18px minmax(0, 1fr); }
  .pops-change-field{ min-width:0; }
}

/* L'action d'application : une ligne, pas un panneau. La timeline au-dessus
   tient déjà lieu de récapitulatif. */
.pops-apply{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:18px; }
.pops-apply-hint{ font-size:12px; color:var(--ink-soft); }

/* Le panneau d'en-tête ne colle pas au bandeau qui le suit : `.info-box` ne
   porte qu'une marge basse, et un `.panel` n'en porte aucune. */
.pops-head{ margin-bottom:18px; padding:22px 24px; }
/* Trois lectures côte à côte, qui ont besoin de respirer : l'étiquette est
   décollée de sa valeur, et les colonnes ne se touchent plus. */
.pops-head-grid{ display:flex; gap:52px; flex-wrap:wrap; align-items:flex-start; row-gap:20px; }
.pops-head-label{ font-size:10.5px; letter-spacing:.08em; text-transform:uppercase;
                  color:var(--ink-soft); margin-bottom:11px; }
.pops-head-value{ font-size:15px; font-weight:600; line-height:1.45; }

/* Timeline des prestations d'un devis, onglet RH d'un projet multidates.
   Structure partagée avec le Planning (sélecteurs ci-dessus) ; seule la carte
   est propre au RH, parce qu'elle porte l'EFFECTIF vendu. */
.prh-tl-card{ background:var(--paper); border:1px solid var(--line);
              border-radius:var(--radius-sm); padding:11px 14px; margin:6px 0 12px; }
.prh-tl-head{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.prh-tl-meta{ display:flex; align-items:baseline; gap:14px; flex-wrap:wrap;
              margin-top:6px; font-size:12.5px; color:var(--ink-soft); }
.prh-tl-people{ font-weight:700; color:var(--ink); }
/* Le lien vers le Planning respire : il n'appartient pas à la ligne
   période/effectif, c'est une action distincte sous l'information. */
.prh-tl-action{ margin-top:14px; }

/* ==========================================================================
   MES APPAREILS — sessions Companion, dans « Mon compte » (#76).
   Aucune couleur en dur : uniquement les variables de thème déjà en place,
   pour que le clair, le sombre et les variantes suivent sans retouche.
   ========================================================================== */
.devices-list{ display:flex; flex-direction:column; gap:10px; }

/* Fond transparent : la carte vit DANS un .panel, qui porte déjà --paper-2.
   Réintroduire une couleur ici la ferait diverger du panneau au moindre
   ajustement de thème. */
.device-card{ border:1px solid var(--line); border-radius:var(--radius-sm);
              padding:12px 14px; background:transparent; }
.device-card.is-revoked{ opacity:.72; }

.device-head{ display:flex; align-items:center; justify-content:space-between;
              gap:12px; flex-wrap:wrap; }
.device-name{ display:flex; align-items:center; gap:8px; flex-wrap:wrap;
              font-size:14px; }

/* Les deux repères de temps : lisibles, jamais présentés comme une présence. */
.device-meta{ display:flex; gap:18px; flex-wrap:wrap; margin-top:8px;
              font-size:12.5px; color:var(--ink-soft); }
.device-meta strong{ color:var(--ink); font-weight:600; }

.device-details{ margin-top:10px; }
.device-details summary{ cursor:pointer; font-size:12.5px; color:var(--ink-soft);
                         width:max-content; }
.device-details summary:hover{ color:var(--ink); }
.device-details summary:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.device-details dl{ margin:10px 0 0; display:grid; grid-template-columns:auto 1fr;
                    gap:6px 14px; font-size:12.5px; }
.device-details dt{ color:var(--ink-soft); }
.device-details dd{ margin:0; }
.device-details code{ font-family:'JetBrains Mono', monospace; font-size:11.5px;
                      word-break:break-all; }

/* L'historique : séparé de la liste active par un filet, pour qu'on voie
   qu'on change de nature d'information. */
.devices-history{ margin-top:14px; padding-top:14px; border-top:1px solid var(--line); }
.devices-history-note{ font-size:12.5px; color:var(--ink-soft); margin:10px 0; }
.devices-history .devices-list{ margin-top:10px; }
.devices-history [data-devices-history-more]{ margin-top:10px; }

.devices-status{ font-size:12.5px; margin-bottom:10px; }
.devices-status.is-saving{ color:var(--ink-soft); }
.devices-status.is-saved{ color:var(--green); }
.devices-status.is-error{ color:var(--red); }

/* Sous 640 px, l'action passe sous le nom plutôt que de le comprimer. */
@media (max-width: 640px){
  .device-head{ align-items:flex-start; }
  .device-head .btn{ width:100%; }
  .device-meta{ gap:4px; flex-direction:column; }
  .device-details dl{ grid-template-columns:1fr; gap:2px 0; }
  .device-details dt{ margin-top:8px; }
}

/* « Aucun besoin défini » — remplace le donut quand la progression n'est pas
   calculable (#86, 2026-09-08). Même encombrement que le donut (84 px) pour
   que la synthèse ne saute pas quand un besoin est enfin créé. */
.prh-no-need{ width:84px; min-width:84px; height:84px; display:flex; flex-direction:column;
              align-items:center; justify-content:center; gap:3px; text-align:center;
              border:1px dashed var(--line-strong); border-radius:50%;
              color:var(--ink-soft); font-size:9.5px; line-height:1.15; padding:4px; }
.prh-no-need svg{ width:16px; height:16px; }
.prh-no-need span{ display:block; max-width:64px; }

/* ===========================================================================
   PORTAIL CLIENT — gestion des accès depuis la fiche client et le projet.
   Roadmap CH-71. Rendu par includes/client_portal_ui.php, piloté par
   assets/js/client-portal-access.js.

   Aucune couleur en dur : tout suit les variables du thème, comme le reste de
   l'ERP. Présentation compacte — ce panneau vit dans une modale, pas sur une
   page entière.
   =========================================================================== */
.cportal{ display:flex; flex-direction:column; gap:16px; font-size:13px; }

/* L'EN-TÊTE d'identité de la modale : une seule ligne, comme les cartes du
   panneau — même avatar, mêmes coordonnées secondaires, même état. */
.cportal-id{ display:flex; align-items:center; gap:14px; }
.cportal-id-avatar{ flex-shrink:0; display:flex; }
.cportal-id-main{ flex:1 1 auto; min-width:0; }
.cportal-id-name{ font-size:14px; font-weight:600; color:var(--ink); line-height:1.3; }
.cportal-id-meta{ font-size:10px; color:var(--ink-soft); line-height:1.5;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* La note d'état : une ligne, jamais un paragraphe — mais elle ne disparaît
   pas, car c'est elle qui empêche « Accès préparé » de passer pour un envoi. */
.cportal-note{ font-size:11px; color:var(--ink-soft); line-height:1.5;
  background:var(--paper); border-radius:var(--radius-sm); padding:8px 10px; }

/* LES DROITS EN COLONNES. Empilés, la fenêtre tenait sur deux écrans et on ne
   voyait jamais les trois portées ensemble. */
/* Trois colonnes de largeurs INÉGALES, réglées sur la longueur réelle des
   libellés : « Actions » porte les plus longs (« Déposer des fichiers et
   commenter »), « Équipe » n'en porte qu'un, très court. Des colonnes égales
   cassaient les premiers sur deux lignes tout en laissant la dernière à moitié
   vide. En dessous de 720 px la grille retombe sur une colonne. */
.cportal-grid{ display:grid; grid-template-columns:1fr 1.4fr 0.58fr; gap:12px; }
@media (max-width: 720px){ .cportal-grid{ grid-template-columns:1fr; } }
/* Le droit et sa délégation sur la MÊME ligne : indentée dessous, la case
   « déléguer » doublait la hauteur du bloc.
   Le groupe est une GRILLE à deux colonnes, la première dimensionnée sur le
   libellé le plus long du groupe (`max-content`) : « déléguer » se pose juste
   après lui, aligné d'une ligne à l'autre. Poussé au bord droit par un
   `space-between`, il s'éloignait de son droit dès que la colonne s'élargissait
   — on ne voyait plus à quoi il se rapportait. */
/* `align-content:start` : le groupe « Équipe » n'a qu'une ligne, et comme les
   trois colonnes s'étirent sur la hauteur de la plus haute, son unique droit se
   retrouvait centré — donc visuellement sur la DEUXIÈME ligne. Les lignes
   partent maintenant du haut dans les trois groupes. `align-items:center` reste
   pour centrer le libellé et sa case l'un par rapport à l'autre. */
.cportal-group{ display:grid; grid-template-columns:max-content max-content;
  column-gap:14px; row-gap:2px; align-items:center; align-content:start; }
/* Chaque ligne s'efface pour que ses deux enfants deviennent les cellules. */
.cportal-line{ display:contents; }
.cportal-line .cportal-check{ min-width:0; padding:2px 0; }
.cportal-deleg{ display:inline-flex; align-items:center; gap:4px; flex:0 0 auto;
  font-size:10px; color:var(--ink-soft); cursor:pointer; }
.cportal-deleg input{ margin:0; }
.cportal-deleg input:disabled{ opacity:.4; }

/* LE CONTEXTE, REPLIÉ : les autres projets de la personne ne doivent pas
   pousser la tâche principale hors de l'écran. */
.cportal-fold > summary{ list-style:none; cursor:pointer; font-size:12px; font-weight:600;
  text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft);
  padding:8px 0; border-top:1px solid var(--line); display:flex; align-items:center; gap:8px; }
.cportal-fold > summary::-webkit-details-marker{ display:none; }
.cportal-fold > summary::before{ content:'▸'; font-size:10px; transition:transform 120ms ease; }
.cportal-fold[open] > summary::before{ transform:rotate(90deg); }
.cportal-count-inline{ font-size:10px; font-weight:400; text-transform:none;
  border:1px solid var(--line); border-radius:999px; padding:1px 7px; }

/* LE PIED : l'action de compte, à part du reste, parce que sa portée dépasse
   ce projet. */
.cportal-foot{ display:flex; align-items:center; flex-wrap:wrap; gap:10px;
  border-top:1px solid var(--line); padding-top:12px; }
.cportal-foot .cportal-muted{ flex:1 1 200px; }
/* Portail fournisseur : deux gestes de portée différente (retirer chez CE
   fournisseur / désactiver partout), chacun sur sa ligne avec sa portée. */
.cportal-foot > .cportal-actions{ flex:1 1 100%; }

.cportal-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.cportal-who strong{ font-size:14px; }
.cportal-muted{ color:var(--ink-soft); font-size:12px; }
.cportal-detail{ margin:0; color:var(--ink-soft); font-size:12px; line-height:1.5; }

/* Un blocage n'est pas une erreur : c'est une étape manquante, et elle
   s'explique. Même habillage que les avertissements de l'ERP. */
.cportal-blocage{
  background:var(--amber-bg); border:1px solid var(--amber); border-radius:var(--radius);
  padding:10px 12px; font-size:12px; line-height:1.5; color:var(--ink);
}
.cportal-blocage svg{ vertical-align:-2px; margin-right:4px; }

.cportal-block{ border-top:1px solid var(--line); padding-top:12px; }
.cportal-block-title{ font-weight:600; font-size:12px; text-transform:uppercase;
  letter-spacing:.04em; color:var(--ink-soft); margin-bottom:8px; }

.cportal-table{ width:100%; font-size:12px; }
.cportal-table th{ font-size:11px; }
/* Le projet depuis lequel on a ouvert le panneau, repéré sans couleur criarde. */
.cportal-current{ background:rgba(var(--brand-rgb), .06); }

/* LES TROIS GROUPES DE DROITS. Ils n'ont pas la même portée : consulter, agir,
   gérer l'équipe. Les séparer évite de cocher l'un en croyant cocher l'autre. */
.cportal-group{
  border:1px solid var(--line); border-radius:var(--radius);
  padding:8px 10px 10px; margin:0;
}
/* La légende traverse les deux colonnes : sans cela elle en occuperait une
   seule et décalerait la première ligne. */
.cportal-group legend{ font-size:11px; font-weight:600; text-transform:uppercase;
  letter-spacing:.04em; color:var(--ink-soft); padding:0 4px; grid-column:1 / -1; }
.cportal-check{ display:flex; align-items:center; gap:6px; padding:3px 0; cursor:pointer; }
.cportal-check input{ margin:0; }
/* La délégation est indentée sous le droit qu'elle concerne. */
.cportal-deleg{ margin-left:22px; padding-top:0; }
.cportal-deleg input:disabled + span{ opacity:.5; }

.cportal-actions{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
/* Les deux actions se décollent de la grille des droits : depuis que la phrase
   explicative a été retirée, elles la touchaient — et un bouton collé à des
   cases à cocher se clique par accident. */
[data-cportal-form] .cportal-actions{ margin-top:18px; }
.cportal-actions .cportal-muted{ flex:1 1 220px; }

/* ---------------------------------------------------------------------------
   LE MENU « ⋯ » PARTAGÉ (`.actions-menu`).

   Ces règles existaient en DEUX exemplaires — dans `assets/css/roadmap.css` et
   dans le `<style>` de `quote_form.php` — et le commentaire de roadmap.css
   annonçait lui-même leur destin : « les règles sont recopiées ici parce que
   celles du devis vivent dans le <style> de sa propre page, jamais dans une
   feuille partagée — le jour où elles le seront, ce bloc disparaîtra au profit
   d'elles. » Ce jour-ci : le panneau Portail client est la troisième page à en
   avoir besoin, et une troisième copie aurait été une copie de trop.

   `style.css` est chargé AVANT les feuilles de page : les deux copies
   existantes continuent donc de primer, à l'identique, et rien ne change pour
   la Roadmap ni pour le devis. Elles pourront être retirées à tête reposée.
   --------------------------------------------------------------------------- */
.actions-menu{ position:relative; flex:none; }
.actions-menu summary{
  list-style:none; cursor:pointer; display:inline-flex; align-items:center;
  padding:4px 7px; border-radius:var(--radius-sm); color:var(--ink-soft);
  line-height:1;
}
.actions-menu summary::-webkit-details-marker{ display:none; }
.actions-menu summary:hover,
.actions-menu[open] summary{ color:var(--ink); background:rgba(var(--brand-rgb), .12); }
.actions-menu summary:focus-visible{ outline:2px solid var(--brand); outline-offset:1px; }
.actions-menu-panel{
  position:absolute; right:0; top:100%; z-index:6; margin-top:2px; padding:4px;
  min-width:190px; background:var(--paper); border:1px solid var(--line-strong);
  border-radius:var(--radius-sm); box-shadow:0 3px 10px rgba(0,0,0,.18);
}
.actions-menu-item{
  display:block; width:100%; text-align:left; background:transparent; border:none;
  padding:6px 10px; font:inherit; font-size:12.5px; color:var(--ink);
  cursor:pointer; border-radius:3px; white-space:nowrap;
}
.actions-menu-item:hover{ background:rgba(var(--brand-rgb), .12); }
.actions-menu-item:focus-visible{ outline:2px solid var(--brand); outline-offset:-2px; }
.actions-menu-item.danger{ color:var(--red); }

/* ---------------------------------------------------------------------------
   LE PANNEAU « PORTAIL CLIENT » du formulaire projet.

   Posé sur `.panel`, qui porte déjà le fond et les ombres du thème — en
   neumorphisme, le relief vient de `.panel` et AUCUNE bordure extérieure n'est
   ajoutée ici. Seules les cartes intérieures portent un filet fin, pour se
   détacher du fond sans l'encadrer.

   L'orange est réservé à l'icône d'en-tête et aux actions : jamais un contour
   permanent sur les cartes.
   --------------------------------------------------------------------------- */
/* LA MARGE AU-DESSUS. Les autres panneaux reçoivent leur air de leur
   `.section-title` (28 px avant, 14 après). Celui-ci porte son titre À
   L'INTÉRIEUR : sans marge, il se collerait au panneau précédent. On lui rend
   donc l'espace que le titre aurait occupé, pour qu'il respire comme ses
   voisins. */
.cportal-panel-wrap{ padding:24px; margin-top:36px; }
/* LE SÉLECTEUR de contact responsable vit dans ce panneau. Sa carte en lecture
   seule ferait double emploi avec la carte du portail, qui dit la même identité
   ET l'état de l'accès : on la masque, sans toucher au mécanisme. La RECHERCHE,
   elle, reste visible — c'est par elle qu'on attache un responsable quand il
   n'y en a pas. */
/* La carte brute du sélecteur ne s'affiche JAMAIS ici : la carte du panneau dit
   la même identité ET l'état de l'accès portail. Le rattachement étant
   enregistré dès qu'on choisit quelqu'un, le panneau est rechargé dans la
   foulée (voir `wabu:contact-responsable`) — il n'y a pas d'entre-deux. */
.cportal-panel-wrap #ccontact-card{ display:none !important; }
.cportal-panel-wrap #client-contact-field{ margin:0 0 4px; }
/* Le libellé du champ dirait « Contact responsable » juste sous la section du
   même nom : on le masque pour les yeux, jamais pour les lecteurs d'écran —
   l'étiquette reste rattachée à la recherche. */
.cportal-panel-wrap #client-contact-field > label{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.cportal-panel-wrap #client-contact-field{ position:relative; }
.cportal-panel{ display:flex; flex-direction:column; }

.cportal-panel-head{ display:flex; align-items:flex-start; justify-content:space-between;
  gap:12px; margin-bottom:26px; }
.cportal-panel-title{ display:flex; align-items:center; gap:10px; min-width:0; }
/* L'icône « personne + cadenas » est COMPOSÉE de deux icônes de la
   bibliothèque : il n'en existe pas de combinée, et on n'en dessine pas une
   nouvelle. Le cadenas se pose en bas à droite de la personne. */
.cportal-panel-icon{ position:relative; display:inline-flex; flex-shrink:0; }
.cportal-panel-lock{ position:absolute; right:-3px; bottom:-2px; display:inline-flex;
  line-height:0; background:var(--paper-2); border-radius:50%; padding:1px; }
.cportal-panel-texts{ display:flex; flex-direction:column; gap:1px; min-width:0; }
/* Échelle de l'ERP : un titre de section, pas une bannière. */
.cportal-panel-h{ font-size:14px; font-weight:600; color:var(--ink); }
.cportal-panel-sub{ font-size:11px; color:var(--ink-soft); }

.cportal-count{ display:inline-flex; align-items:center; gap:5px; flex-shrink:0;
  font-size:11px; color:var(--ink-soft); border:1px solid var(--line);
  border-radius:999px; padding:3px 9px; line-height:1; }
.cportal-count svg{ display:block; }

.cportal-section-label{ font-size:10px; font-weight:600; text-transform:uppercase;
  letter-spacing:.06em; color:var(--ink-soft); margin-bottom:12px; }

/* Le séparateur entre le responsable et l'équipe : assez pour marquer la
   rupture, pas assez pour qu'elle paraisse être une autre section de la page.
   Les deux blocs se lisent ensemble. */
.cportal-sep{ height:1px; background:var(--line); margin:16px 0; }

/* LA CARTE. Fond légèrement différencié, filet intérieur fin et discret. */
.cportal-card{
  display:flex; align-items:center; gap:18px;
  background:var(--paper); border:1px solid var(--line); border-radius:var(--radius);
  padding:16px 18px; margin-bottom:12px;
}
.cportal-card:last-child{ margin-bottom:0; }
.cportal-card-avatar{ flex-shrink:0; display:flex; }
.cportal-card-main{ flex:1 1 auto; min-width:0; }
.cportal-card-name{ font-size:13px; font-weight:600; color:var(--ink); line-height:1.35;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* L'e-mail et la dernière connexion, sur la MÊME ligne : deux informations
   secondaires de la même personne. L'adresse est la seule à se rétrécir — la
   connexion est courte, et la tronquer ne rendrait service à personne.
   Une adresse longue se tronque à l'écran, jamais dans la donnée : le `title`
   porte la valeur entière, lisible au survol. */
/* UNE SEULE TAILLE pour toute la ligne : poste, e-mail, téléphone et dernière
   connexion sont des informations secondaires de même rang. En déplaçant la
   connexion ici, je l'avais fait passer de 10 à 11 px — elle repasse à la
   taille des autres, et la ligne redevient discrète sous le nom. */
.cportal-card-meta{ display:flex; align-items:baseline; gap:0; margin-top:2px; min-width:0;
  font-size:10px; color:var(--ink-soft); line-height:1.5; }
.cportal-card-mail{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  min-width:0; flex:0 1 auto; }
/* Le point médian sépare les deux sans ajouter de balise. Il prend la couleur
   du texte secondaire, sinon il disparaît sur les fonds sombres — `--line-strong`
   était trop discret pour être vu. */
.cportal-card-login::before{ content:'|'; margin:0 9px; color:var(--ink-soft); opacity:.45; }
/* L'identité — poste · e-mail · téléphone — occupe la place disponible et c'est
   l'adresse, en son sein, qui se tronque. */
.cportal-card-ident{ display:flex; align-items:baseline; min-width:0; overflow:hidden; }
.cportal-dot{ margin:0 6px; opacity:.55; flex:0 0 auto; }
.cportal-card-role, .cportal-card-tel{ white-space:nowrap; flex:0 0 auto; }
.cportal-card-side{ display:flex; flex-direction:column; align-items:flex-end; gap:7px;
  flex-shrink:0; text-align:right; }
.cportal-card-login{ white-space:nowrap; flex:0 0 auto; }
/* « Gérer l'accès » et le détachement sont deux gestes de portée très
   différente : un écart franc évite de cliquer l'un pour l'autre. */
.cportal-card-action{ flex-shrink:0; display:flex; align-items:center; gap:14px; }

/* LES BADGES DE DROITS — informatifs, jamais des boutons : ni curseur main, ni
   effet de survol, ni couleur d'action. */
.cportal-rights{ display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.cportal-right-badge{
  font-size:10px; line-height:1; padding:4px 9px; border-radius:999px;
  background:var(--paper-2); border:1px solid var(--line); color:var(--ink-soft);
  cursor:default;
}

.cportal-empty{ font-size:12px; color:var(--ink-soft); padding:4px 0 6px; }

/* NEUMORPHISME — ce thème ne connaît pas la bordure plate : toute profondeur
   vient d'une ombre. `.panel` y perd déjà la sienne (règle plus haut) ; les
   cartes et pastilles intérieures suivent la même logique, en creux, comme
   `.note-panel`. Aucune bordure extérieure n'est ajoutée au panneau. */
[data-theme-style="neumorphism"] .cportal-card{
  border:none; background:var(--paper-2);
  box-shadow:inset 3px 3px 6px var(--neu-lo), inset -3px -3px 6px var(--neu-hi);
}
[data-theme-style="neumorphism"] .cportal-right-badge,
[data-theme-style="neumorphism"] .cportal-count{
  border:none; background:var(--paper-2);
  box-shadow:2px 2px 4px var(--neu-lo), -2px -2px 4px var(--neu-hi);
}
[data-theme-style="neumorphism"] .cportal-sep{ background:transparent;
  box-shadow:0 1px 2px var(--neu-lo), 0 -1px 2px var(--neu-hi); }
[data-theme-style="neumorphism"] .cportal-panel-lock{ background:var(--paper-2); }

/* PETIT ÉCRAN — tout passe sur plusieurs lignes, rien ne déborde. */
@media (max-width: 720px){
  .cportal-panel-wrap{ padding:18px; }
  .cportal-card{ flex-wrap:wrap; align-items:flex-start; gap:12px; padding:14px 15px; }
  .cportal-card-main{ flex:1 1 160px; }
  .cportal-card-side{ align-items:flex-start; text-align:left; flex:1 1 100%; order:3;
    flex-direction:row; flex-wrap:wrap; align-items:center; gap:8px; }
  .cportal-card-action{ order:2; margin-left:auto; }
}

/* =====================================================================
   TRANSMISSIONS FOURNISSEUR DU PRINT — production_print_transmission*.php
   Variables du thème uniquement : clair, foncé et neumorphique suivent.
   ===================================================================== */
.dispatch-page .dispatch-lead{ color:var(--ink-soft); margin:0 0 16px; max-width:900px; }
.dispatch-page .panel{ margin-bottom:16px; }
.dispatch-h2{ font-size:15px; margin:0 0 10px; }
.dispatch-select-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
/* Le fournisseur de la préparation : une ligne (un seul) ou un select court (plusieurs). */
.dispatch-supplier{ margin:4px 0 12px; }
.dispatch-supplier-field{ max-width:420px; margin:4px 0 12px; }
.dispatch-nosupplier p{ margin:0 0 12px; }
/* Vérifier en AJAX : le panneau de sélection replié en un en-tête compact. */
.dispatch-select-summary{ display:inline-flex; align-items:center; gap:10px; flex-wrap:wrap; margin-right:auto; font-size:13px; }
.dispatch-select-summary[hidden]{ display:none; }
.dispatch-select.is-collapsed .dispatch-select-head{ margin:0; }
.dispatch-select.is-collapsed .dispatch-select-head .dispatch-h2{ margin:0; }
.dispatch-select[aria-busy="true"] .dispatch-select-body{ opacity:.65; }
.dispatch-select [data-pp-dverifier] .wabu-loader{ margin-right:8px; vertical-align:-3px; }
.dispatch-recap{ margin-top:16px; }
.dispatch-recap h2:focus{ outline:none; }
.dispatch-recap h2:focus-visible{ outline:2px solid var(--brand); outline-offset:3px; border-radius:4px; }
.dispatch-table-wrap{ overflow-x:auto; margin-bottom:14px; }
.dispatch-table td.num, .dispatch-table th.num{ text-align:right; white-space:nowrap; }
.dispatch-table .dispatch-check{ width:34px; }
.dispatch-table .dispatch-ref{ font-weight:600; white-space:nowrap; }
.dispatch-table .dispatch-file{ word-break:break-all; min-width:180px; }
.dispatch-table tr.is-blocked td{ color:var(--ink-soft); }
.dispatch-table tr.is-refused td{ background:var(--red-bg); }
.dispatch-reason{ color:var(--amber-dark); font-size:12.5px; }
.dispatch-muted{ color:var(--ink-soft); font-size:12px; margin-top:2px; }
/* Portail fournisseur — destinataires d’une transmission (aucun coché par défaut). */
.dispatch-recipients{ border:1px solid var(--line); border-radius:var(--radius-sm, 8px); padding:8px 12px 10px; margin:10px 0; min-width:0; }
.dispatch-recipients legend{ font-size:12px; font-weight:600; padding:0 4px; }
.dispatch-recipient{ display:flex; gap:8px; align-items:flex-start; padding:5px 0; font-size:13px; overflow-wrap:anywhere; }
.dispatch-recipient input{ margin-top:3px; flex-shrink:0; }
.dispatch-recipient .dispatch-muted{ display:block; }
.dispatch-recipient.is-off{ opacity:.65; }
.dispatch-recipient-list{ margin:6px 0 0; padding-left:18px; font-size:13px; }
/* Portail fournisseur — suivi par destinataire et avis par e-mail. */
.dispatch-recipient-list li{ margin-bottom:6px; overflow-wrap:anywhere; }
.dispatch-recipient-track{ display:flex; flex-wrap:wrap; gap:2px 14px; font-size:12px; color:var(--ink-soft); }
.dispatch-notice-off{ margin:8px 0 0; padding-left:18px; font-size:12px; }
.dispatch-inline-form{ margin:0; }
.dispatch-notice-to{ display:block; }
.dispatch-notice-to small{ display:inline; margin-left:6px; }
.dispatch-notice-lang{ border:none; margin:0 0 6px; padding:0; min-width:0; }
.dispatch-notice-lang legend{ font-size:12.5px; font-weight:600; padding:0; margin-bottom:6px; }
.dispatch-note{ color:var(--ink-soft); font-size:13px; }
/* Préparation de lot : prints rouverts, qui repartent par un remplacement
   (2026-10-05) — à part du tableau, sans case à cocher, avec leur lien. */
.dispatch-replace{ margin:14px 0 4px; padding:10px 12px; border:1px dashed var(--line); border-radius:8px; }
.dispatch-replace-title{ font-weight:600; font-size:13px; margin:0; }
.dispatch-replace-list{ margin:8px 0; padding-left:18px; font-size:13px; }
.dispatch-replace-list li{ margin:3px 0; }
.dispatch-replace-list .dispatch-reason{ display:block; }
.dispatch-actions{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-top:10px; }
.dispatch-error ul, .dispatch-flash ul{ margin:6px 0 0 18px; padding:0; }
.dispatch-facts{ display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:10px 18px; margin-bottom:12px; }
.dispatch-facts .dispatch-wide{ grid-column:1 / -1; }
.dispatch-label{ display:block; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
.dispatch-state{ background:var(--amber-bg); color:var(--amber-dark); padding:10px 12px; border-radius:var(--radius-sm); margin:0 0 12px; }
.dispatch-downloads{ display:flex; gap:8px; flex-wrap:wrap; }
.dispatch-warning{ color:var(--red); font-size:13px; }
.dispatch-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:16px; }
.dispatch-grid .panel{ margin-bottom:0; }
.dispatch-grid + .dispatch-grid{ margin-top:16px; }
.dispatch-pages summary{ cursor:pointer; color:var(--ink-soft); font-size:12px; }
.dispatch-pages ul{ margin:4px 0 0 16px; padding:0; font-size:12px; }
.dispatch-page .field textarea, .dispatch-page .field select, .dispatch-page .field input{ max-width:640px; }
/* La note au fournisseur prend toute la largeur du bloc de sélection. */
.dispatch-page .dispatch-select #pp-dnote{ max-width:none; width:100%; box-sizing:border-box; }
@media (max-width: 640px){
  .dispatch-page .section-title{ flex-wrap:wrap; gap:8px; }
  .dispatch-actions .btn{ flex:1 1 100%; justify-content:center; }
}
/* Téléphone : les tableaux de transmission deviennent des fiches empilées —
   case à cocher à gauche, chaque valeur sur sa ligne, nombres étiquetés. */
@media (max-width: 640px){
  .dispatch-table thead{ display:none; }
  .dispatch-table, .dispatch-table tbody, .dispatch-table tr, .dispatch-table td{ display:block; width:auto; }
  .dispatch-table tr{ position:relative; padding:10px 0 10px 34px; border-bottom:1px solid var(--line); }
  .dispatch-table td{ border:none !important; padding:2px 0 !important; text-align:left !important; white-space:normal !important; }
  .dispatch-table td.dispatch-check{ position:absolute; left:0; top:10px; width:auto; }
  .dispatch-table td[data-label]::before{ content:attr(data-label) " : "; color:var(--ink-soft); font-size:12px; }
  .dispatch-table .dispatch-file{ min-width:0; }
  .dispatch-page{ padding-left:12px; padding-right:12px; box-sizing:border-box; }
}

/* Projet, onglet Fournisseurs — panneau « Fournisseurs de production ». */
.pps-title{ display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
.pps-muted{ color:var(--ink-soft); font-size:12px; }
.pps-table-wrap{ position:relative; }
.pps-table td{ vertical-align:top; }
.pps-table th.pps-actions, .pps-table td.pps-actions{ width:44px; text-align:right; }
.pps-contacts{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px; }
.pps-contacts li{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 10px; overflow-wrap:anywhere; }
.pps-inline{ margin:0; }
/* Menu « ⋯ » — même composant que la Liste print et la Roadmap (`.actions-menu`),
   dont les règles vivent dans leurs feuilles propres, pas chargées ici. */
.pps-menu{ position:relative; display:inline-block; }
.pps-menu summary{ list-style:none; cursor:pointer; display:inline-flex; align-items:center; padding:4px 7px;
  border-radius:var(--radius-sm, 6px); color:var(--ink-soft); line-height:1; }
.pps-menu summary::-webkit-details-marker{ display:none; }
.pps-menu summary:hover, .pps-menu[open] summary{ color:var(--ink); background:rgba(var(--brand-rgb), .12); }
.pps-menu summary:focus-visible{ outline:2px solid var(--brand); outline-offset:1px; }
.pps-menu .actions-menu-panel{ position:absolute; right:0; top:100%; z-index:6; margin-top:2px; padding:4px; min-width:220px;
  background:var(--paper); border:1px solid var(--line-strong); border-radius:var(--radius-sm, 6px);
  box-shadow:0 3px 10px rgba(0,0,0,.18); text-align:left; }
.pps-menu .actions-menu-item{ display:block; width:100%; text-align:left; background:transparent; border:none; padding:6px 10px;
  font:inherit; font-size:12.5px; color:var(--ink); border-radius:var(--radius-sm, 6px); cursor:pointer; }
.pps-menu .actions-menu-item:hover{ background:rgba(var(--brand-rgb), .12); }
.pps-menu .actions-menu-item:focus-visible{ outline:2px solid var(--brand); outline-offset:-2px; }
.pps-menu .actions-menu-item.danger{ color:var(--red); }
.pps-trace{ margin:2px 10px 6px; font-size:11.5px; color:var(--ink-soft); }
/* Fenêtre d'ajout : un select des imprimeurs disponibles. */
.pps-add-host{ margin-top:14px; }
.pps-add .field{ margin:0; }
.pps-add select{ width:100%; }
.pps-add-actions{ display:flex; justify-content:flex-end; margin-top:12px; }
@media (max-width: 640px){
  .pps-table thead{ display:none; }
  .pps-table, .pps-table tbody, .pps-table tr, .pps-table td{ display:block; width:auto; }
  .pps-table tr{ position:relative; padding:10px 40px 10px 0; border-bottom:1px solid var(--line); }
  .pps-table td{ border:none !important; padding:3px 0 !important; }
  .pps-table td[data-label]::before{ content:attr(data-label) " : "; color:var(--ink-soft); font-size:12px; }
  .pps-table td.pps-actions{ position:absolute; top:6px; right:0; width:auto; }
}

/* Fiche fournisseur, colonne « Portail » : badge de statut et bouton côte à
   côte, centrés sur la même ligne, alignés sous l'en-tête ; passage à la
   ligne propre quand la place manque. */
.sp-contact-portail-box{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; }
.sp-contact-portail-box .badge, .sp-contact-portail-box .btn{ margin:0; }

/* ===================== PORTAIL FOURNISSEUR — transmissions (pages partner_*) =====================
   Même famille que le portail client (habillage cp-*), quelques blocs propres. */
.sp-section{ font-size:13px; font-weight:600; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin:18px 0 8px; }
.sp-downloads{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin:6px 0 4px; }

/* ---------- Portail fournisseur — détail d'un lot (maquette projet-fournisseur.png, 2026-10-03) ---------- */
.sp-lot-head{ display:flex; flex-wrap:wrap; align-items:flex-start; justify-content:space-between; gap:12px 20px; margin:4px 0 8px; }
.sp-lot-ident{ min-width:0; }
.sp-lot-project{ margin:0; overflow-wrap:anywhere; }
.sp-lot-project-ref{ font-weight:400; color:var(--ink-soft); font-size:.7em; white-space:nowrap; }
.sp-lot-place{ margin:4px 0 0; font-size:13px; letter-spacing:.04em; text-transform:uppercase; color:var(--ink-soft); overflow-wrap:anywhere; }
.sp-lot-montage{ display:flex; align-items:center; gap:12px; padding:10px 16px; border:1px solid var(--line); border-radius:var(--radius-sm, 10px); }
.sp-lot-montage svg{ color:var(--brand); flex:none; }
.sp-lot-montage-label{ display:block; font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); }
.sp-lot-montage strong{ font-size:16px; }
.sp-lot-more{ margin:0 0 10px; font-size:13px; }
.sp-lot-more > summary{ cursor:pointer; color:var(--ink-soft); }
.sp-lot-more[open] > summary{ margin-bottom:8px; }
.sp-lot-bar{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:12px 18px; margin-top:12px; padding:12px 16px;
  border:1px solid var(--line); border-radius:var(--radius-sm, 10px); }
.sp-lot-bar-facts{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 14px; color:var(--ink-soft); font-size:14px; }
.sp-lot-bar-facts > * + *{ padding-left:14px; border-left:1px solid var(--line); }
.sp-lot-number{ font-size:18px; color:var(--ink); }
.sp-lot-bar-actions{ display:flex; flex-wrap:wrap; align-items:flex-start; gap:6px; }
.sp-lot-bar-actions .btn{ display:inline-flex; align-items:center; gap:6px; padding:6px 11px; font-size:13px; }
.sp-lot-main-dl{ display:flex; flex-direction:column; align-items:center; gap:3px; }
.sp-lot-dl-meta{ font-size:11.5px; color:var(--ink-soft); }
.sp-lot-dl-list{ position:relative; }
.sp-lot-dl-list > summary{ list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:7px; }
.sp-lot-dl-list > summary::-webkit-details-marker{ display:none; }
.sp-lot-dl-panel{ position:absolute; right:0; z-index:5; margin-top:6px; width:max-content; min-width:300px; max-width:min(520px, calc(100vw - 32px)); padding:10px;
  display:flex; flex-direction:column; gap:6px; background:var(--paper-2); border:1px solid var(--line); border-radius:var(--radius-sm, 10px); }
.sp-lot-dl-item{ display:flex; align-items:center; gap:8px; padding:7px 8px; border-radius:8px; color:var(--ink); text-decoration:none; overflow-wrap:anywhere; }
.sp-lot-dl-item:hover, .sp-lot-dl-item:focus-visible{ background:rgba(var(--brand-rgb), .08); }
.sp-lot-dl-item .sp-lot-sub{ margin-left:auto; white-space:nowrap; }
/* Le tableau reprend les valeurs du tableau « Prints du lot » de l'ERP
   (.dispatch-lot-table) : cellules 12/14 px, en-tête 8/14 px et filet plus
   marqué, filet entre les lignes, référence orange en ligne avec le nom,
   secondaires en 12 px. Panneau intérieur, comme le panneau de l'ERP. */
.sp-lot-section{ padding-top:0; }
.sp-lot-page + .sp-lot-section{ margin-top:0; }
.sp-lot-panel{ margin-top:24px; border:1px solid var(--line); border-radius:var(--radius-sm, 10px); padding:14px 4px 4px; background:var(--paper-2, transparent); }
.sp-lot-h2{ display:flex; align-items:center; gap:10px; margin:0 14px 10px; font-family:inherit; text-transform:none; letter-spacing:normal; font-size:16px; font-weight:600; color:var(--ink); }
.sp-lot-table{ width:100%; border-collapse:collapse; font-size:13.5px; }
.sp-lot-table thead th{ text-align:left; white-space:nowrap; font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft);
  padding:8px 14px; border-bottom:1px solid var(--line-strong, var(--line)); }
.sp-lot-table td, .sp-lot-table th[scope="row"]{ padding:12px 14px; vertical-align:top; text-align:left; font-weight:400; color:var(--ink); }
/* Bordures = celles du tableau ERP « Prints du lot » : sous l'en-tête --line-strong ;
   UN séparateur entre deux prints, APRÈS la consigne ; rien entre un print et sa
   consigne ; aucun trait vertical. */
.sp-lot-item:not(:last-child) > tr:last-child > *{ border-bottom:1px solid var(--line); }
[data-theme-style="neumorphism"] .sp-lot-item:not(:last-child) > tr:last-child > *{ border-bottom:1px solid var(--neu-lo); box-shadow:0 1px 0 var(--neu-hi); }
.sp-lot-print{ min-width:200px; max-width:320px; }
.sp-lot-title{ display:block; font-weight:600; overflow-wrap:anywhere; }
.sp-lot-ref{ color:var(--brand); font-weight:600; margin-right:4px; }
.sp-lot-name{ font-weight:600; }
.sp-lot-main{ display:block; color:var(--ink); overflow-wrap:anywhere; }
.sp-lot-sub{ display:block; margin-top:2px; font-size:12px; color:var(--ink-soft); overflow-wrap:anywhere; }
.sp-lot-nowrap{ white-space:nowrap; }
.sp-lot-count{ font-size:15px; font-weight:600; }
.sp-lot-table thead abbr{ text-decoration:none; cursor:help; }
.sp-lot-filename{ font-size:11.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:240px; border-radius:3px; }
.sp-lot-filename:focus{ white-space:normal; overflow:visible; overflow-wrap:anywhere; outline:2px solid var(--brand); outline-offset:1px; }
.sp-lot-action{ text-align:right; white-space:nowrap; width:1%; }
.sp-lot-action > * + *{ margin-top:6px; }
.sp-lot-action{ display:table-cell; }
.sp-lot-h2-row{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 12px; margin:0 14px 10px; }
.sp-lot-h2-row .sp-lot-h2{ margin:0; }
/* Commandes d'une ligne : icône de téléchargement + statut déroulant, discrets. */
.sp-lot-mark-all{ display:inline-flex; align-items:center; gap:5px; font-size:13px; font-weight:600; color:var(--ink-soft);
  padding:4px 10px; border:1px solid var(--line); border-radius:999px; text-decoration:none; background:none; }
.sp-lot-mark-all:hover{ color:var(--ink); border-color:var(--ink-soft); }
.sp-lot-controls{ display:inline-flex; align-items:center; gap:8px; }
.sp-lot-dl-icon{ display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; border-radius:8px;
  border:1px solid var(--line); color:var(--ink); background:none; text-decoration:none; }
.sp-lot-dl-icon:hover{ border-color:var(--ink-soft); }
.sp-lot-status-menu{ position:relative; display:inline-block; }
.sp-lot-status-menu > summary{ list-style:none; cursor:pointer; }
.sp-lot-status-menu > summary::-webkit-details-marker{ display:none; }
.sp-lot-status{ display:inline-flex; align-items:center; gap:4px; height:32px; padding:0 10px; border-radius:8px; font-size:13px; font-weight:600;
  border:1px solid var(--line); color:var(--ink); background:none; white-space:nowrap; }
.sp-lot-status.is-printed{ color:var(--green); border-color:color-mix(in srgb, var(--green) 45%, transparent); background:var(--green-bg); }
.sp-lot-status.is-static{ cursor:default; }
.sp-lot-caret{ font-size:11px; opacity:.7; }
.sp-lot-dl-icon:focus-visible, .sp-lot-status-menu > summary:focus-visible, .sp-lot-mark-all:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.sp-lot-status-menu .cp-menu-liste{ right:0; left:auto; top:38px; }
.sp-lot-printed-by{ text-align:right; margin-top:4px; }
/* Neumorphism : --line y est transparent ; trait gravé fin comme les tableaux, sans ombre portée. */
[data-theme-style="neumorphism"] .sp-lot-dl-icon, [data-theme-style="neumorphism"] .sp-lot-status, [data-theme-style="neumorphism"] .sp-lot-mark-all{ border-color:var(--neu-lo); box-shadow:0 1px 0 var(--neu-hi); }
[data-theme-style="neumorphism"] .sp-lot-status.is-printed{ border-color:color-mix(in srgb, var(--green) 45%, transparent); }
.sp-lot-row:has(+ .sp-lot-consigne) > *{ padding-bottom:6px; }
.sp-lot-consigne td{ padding:0 14px 12px; font-size:13px; background:none; border-radius:0; }
.sp-lot-consigne-label{ font-size:12px; font-weight:600; margin-right:12px; vertical-align:top; }
.sp-lot-consigne-texte{ display:inline-block; max-width:calc(100% - 110px); overflow-wrap:anywhere; vertical-align:top; }
.sp-lot-table.is-stop .sp-lot-ref{ color:var(--ink-soft); }
.sp-lot-place{ display:flex; align-items:center; gap:6px; }
.sp-lot-place svg{ flex:none; color:var(--ink-soft); }
.sp-lot-head-side{ display:flex; flex-direction:column; align-items:flex-end; gap:10px; }
.sp-lot-back{ white-space:nowrap; }
@media (max-width:720px){
  .sp-lot-table thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
  .sp-lot-table, .sp-lot-table tbody, .sp-lot-table tr, .sp-lot-table td, .sp-lot-table th{ display:block; width:auto; max-width:none; }
  .sp-lot-item{ border:1px solid var(--line); border-radius:var(--radius-sm, 10px); padding:10px 12px; margin-bottom:10px; }
  .sp-lot-item + .sp-lot-item .sp-lot-row > *{ border-top:0; }
  .sp-lot-item:not(:last-child) > tr:last-child > *, [data-theme-style="neumorphism"] .sp-lot-item:not(:last-child) > tr:last-child > *{ border-bottom:0; box-shadow:none; }
  .sp-lot-table td, .sp-lot-table th[scope="row"]{ padding:4px 0; }
  .sp-lot-panel{ padding:12px 10px 2px; }
  .sp-lot-h2{ margin:0 0 10px; }
  .sp-lot-h2-row{ margin:0 0 10px; }
  .sp-lot-status-menu .cp-menu-liste{ right:auto; left:0; }
  .sp-lot-head{ flex-direction:column-reverse; }
  .sp-lot-head-side{ width:100%; flex-direction:row; flex-wrap:wrap; align-items:flex-start; justify-content:space-between; }
  .sp-lot-table td[data-label]::before{ content:attr(data-label); display:block; font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); }
  .sp-lot-action{ text-align:left; padding-top:8px; }
  .sp-lot-printed-by{ text-align:left; }
  .sp-lot-consigne td{ padding:8px 10px; margin-top:6px; }
  .sp-lot-consigne-label{ display:block; border-right:0; padding:0; margin:0 0 3px; }
  .sp-lot-consigne-texte{ display:block; max-width:none; }
  .sp-lot-filename{ max-width:100%; }
  .sp-lot-main-dl{ align-items:flex-start; }
  .sp-lot-dl-panel{ right:auto; left:0; }
  /* Mobile : la répartition est STABLE dès l'affichage — le téléchargement sur
     toute la largeur, PDF et Excel côte à côte dessous ; jamais provoquée par un clic. */
  .sp-lot-bar-actions{ display:grid; grid-template-columns:1fr 1fr; width:100%; }
  .sp-lot-main-dl{ grid-column:1 / -1; align-items:stretch; }
  .sp-lot-main-dl > .btn, .sp-lot-main-dl > .sp-lot-dl-list > summary, .sp-lot-bar-actions > .sp-lot-recap{ width:100%; justify-content:center; }
}
[data-theme-style="neumorphism"] .sp-lot-montage, [data-theme-style="neumorphism"] .sp-lot-bar,
[data-theme-style="neumorphism"] .sp-lot-item, [data-theme-style="neumorphism"] .sp-lot-dl-panel,
[data-theme-style="neumorphism"] .sp-lot-panel{ border-color:var(--neu-lo, rgba(0,0,0,.12)); }


/* Portail partenaire — barre de navigation (composant .cp-tabs du portail). */
.sp-tabs{ margin-top:-4px; }
.sp-team-switch{ display:flex; flex-wrap:wrap; gap:8px; margin:0 0 14px; }
.sp-project-open{ color:inherit; text-decoration:none; }
.sp-project-open:hover{ text-decoration:underline; }
.sp-project-open:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; border-radius:4px; }
.sp-project-page{ margin-top:6px; }
.sp-project-page .sp-project-name{ font-size:20px; }
/* Calendrier partenaire : une liste par mois, lisible à 360 px. */
/* Calendrier partenaire — la timeline des mois (défile seule, jamais la page). */
.sp-sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
.sp-tl{ margin:2px 0 16px; min-width:0; }
.sp-tl-list{ list-style:none; margin:0; padding:20px 2px 8px; display:flex; overflow-x:auto; overscroll-behavior-x:contain; scroll-snap-type:x proximity;
  -webkit-overflow-scrolling:touch; scrollbar-width:thin; }
.sp-tl-item{ position:relative; flex:none; scroll-snap-align:center; }
.sp-tl-item.is-year:not(:first-child){ margin-left:10px; padding-left:10px; border-left:1px dashed var(--line-strong, var(--line)); }
.sp-tl-year{ position:absolute; top:-18px; left:8px; font-size:11px; font-weight:700; letter-spacing:.05em; color:var(--ink-soft); }
.sp-tl-item.is-year:not(:first-child) .sp-tl-year{ left:18px; }
.sp-tl-month{ position:relative; display:flex; flex-direction:column; align-items:center; gap:6px; min-width:56px; padding:6px 8px;
  border-radius:10px; text-decoration:none; color:var(--ink); font-size:13px; font-weight:600; line-height:1.2; }
/* Le fil qui relie les mois, à hauteur des pastilles. */
.sp-tl-month::before{ content:''; position:absolute; left:0; right:0; bottom:18px; height:1px; background:var(--line-strong, var(--line)); }
.sp-tl-month:hover{ background:color-mix(in srgb, var(--brand) 7%, transparent); }
.sp-tl-month:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.sp-tl-dot{ position:relative; width:22px; height:22px; border-radius:50%; display:grid; place-items:center; box-sizing:border-box;
  font-size:11px; font-weight:700; color:var(--brand); background:var(--paper); border:1.5px solid var(--brand); }
.sp-tl-month.is-empty{ color:var(--ink-soft); font-weight:400; }
.sp-tl-month.is-empty .sp-tl-dot{ width:10px; height:10px; margin:6px 0; border:1.5px solid var(--line-strong, var(--line)); }
.sp-tl-month.is-on{ background:color-mix(in srgb, var(--brand) 12%, transparent); color:var(--brand); font-weight:700; }
.sp-tl-month.is-on .sp-tl-dot{ background:var(--brand); color:#fff; }
.sp-tl-month.is-on.is-empty .sp-tl-dot{ border-color:var(--brand); }
.sp-cal{ list-style:none; margin:0 0 14px; padding:0; display:flex; flex-direction:column; gap:10px; }
.sp-cal-link{ display:flex; align-items:center; gap:12px; padding:10px 12px; border-radius:var(--radius, 12px); text-decoration:none; color:inherit;
  background:var(--paper); border:1px solid var(--line-strong, var(--line));
  box-shadow:3px 3px 8px var(--neu-lo, rgba(0,0,0,.1)), -3px -3px 8px var(--neu-hi, rgba(255,255,255,.6)); min-width:0; }
.sp-cal-link:hover{ border-color:var(--brand); }
.sp-cal-link:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.sp-cal-day{ flex:none; width:48px; text-align:center; display:flex; flex-direction:column; line-height:1.1; }
.sp-cal-num{ font-size:20px; font-weight:700; color:var(--ink); }
.sp-cal-mon{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
.sp-cal-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; overflow-wrap:anywhere; }
.sp-cal-lead{ font-size:15px; font-weight:700; color:var(--brand); }
.sp-cal-lead .sp-tbc{ font-weight:600; }
.sp-cal-day.is-tbc .sp-cal-num{ color:var(--ink-soft); font-weight:400; }
.sp-cal-dates{ display:flex; flex-wrap:wrap; gap:2px 14px; margin-top:2px; font-size:12px; color:var(--ink-soft); }
.sp-cal-date{ white-space:normal; }
.sp-cal-k{ font-weight:600; color:var(--ink); }
.sp-cal-name{ font-size:14.5px; font-weight:600; color:var(--ink); }
.sp-cal-ref{ font-weight:400; font-size:12px; color:var(--ink-soft); }
.sp-cal-place{ font-size:12.5px; color:var(--ink-soft); }
.sp-cal-go{ flex:none; color:var(--ink-soft); }
.sp-cal-tbc{ margin-top:18px; }

/* Menu du compte partenaire — « Notifications sur cet appareil ». */
.sp-push{ margin:12px 0 0; padding:12px 0 0; border-top:1px solid var(--line); }
[data-theme-style="neumorphism"] .sp-push{ border-top-color:var(--neu-lo); box-shadow:inset 0 1px 0 var(--neu-hi); }
.sp-push-title{ font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); }
.sp-push-state{ margin-top:4px; font-size:13px; font-weight:600; color:var(--ink); overflow-wrap:anywhere; }
.sp-push[data-etat="actif"] .sp-push-state{ color:var(--green); }
.sp-push[data-etat="bloque"] .sp-push-state, .sp-push[data-etat="absent"] .sp-push-state,
.sp-push[data-etat="indisponible"] .sp-push-state, .sp-push[data-etat="ios"] .sp-push-state{ font-weight:400; color:var(--ink-soft); }
.sp-push-hint{ margin:4px 0 0; font-size:12px; color:var(--ink-soft); }
.sp-push .btn{ margin-top:8px; width:100%; justify-content:center; }

/* Accueil partenaire — « Projets ». */
.sp-home-title{ margin:0; }
.sp-home-bar{ display:flex; align-items:baseline; justify-content:space-between; gap:8px 14px; flex-wrap:wrap; margin:6px 0 16px; }
/* Panneau « Historique » sous les projets courants : tableau compact, paginé
   (le panneau seul est remplacé). Sous 720 px, une carte par projet. */
.sp-history{ margin-top:24px; border:1px solid var(--line); border-radius:var(--radius-sm, 10px); padding:14px 4px 6px; background:var(--paper-2, transparent); scroll-margin-top:16px; }
.sp-history[aria-busy="true"]{ opacity:.6; }
.sp-history-head{ display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:4px 12px; margin:0 14px 10px; }
.sp-history-head .sp-lot-h2{ margin:0; }
.sp-history-head .sp-lot-h2:focus{ outline:none; }
.sp-history-head .sp-lot-h2:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.sp-history-count{ font-size:12px; color:var(--ink-soft); }
.sp-history-table{ width:100%; border-collapse:collapse; font-size:13.5px; }
.sp-history-table thead th{ text-align:left; white-space:nowrap; font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft);
  padding:8px 14px; border-bottom:1px solid var(--line-strong, var(--line)); }
.sp-history-table td, .sp-history-table th[scope="row"]{ padding:10px 14px; vertical-align:top; text-align:left; font-weight:400; color:var(--ink); }
.sp-history-table tbody tr:not(:last-child) > *{ border-bottom:1px solid var(--line); }
[data-theme-style="neumorphism"] .sp-history-table tbody tr:not(:last-child) > *{ border-bottom:1px solid var(--neu-lo); box-shadow:0 1px 0 var(--neu-hi); }
.sp-history-project a{ color:var(--ink); text-decoration:none; overflow-wrap:anywhere; border-radius:3px; }
.sp-history-project a:hover .sp-history-name{ text-decoration:underline; }
.sp-history-project a:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.sp-history-name{ font-weight:600; }
.sp-history-pager{ display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:8px; margin:10px 14px 8px; }
.sp-history-pager > :first-child{ justify-self:start; }
.sp-history-pager > :last-child{ justify-self:end; }
.sp-history .badge.cloture{ background:transparent; border:1px solid var(--line-strong, var(--line)); color:var(--ink-soft); }
.sp-history-pos{ font-size:13px; color:var(--ink-soft); white-space:nowrap; }
@media (max-width:720px){
  .sp-history{ padding:12px 10px 4px; }
  .sp-history-head, .sp-history-pager{ margin-left:0; margin-right:0; }
  .sp-history-table thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
  .sp-history-table, .sp-history-table tbody, .sp-history-table tr, .sp-history-table td, .sp-history-table th{ display:block; width:auto; }
  /* Compact : le projet sur toute la largeur, puis montage | lieu, puis le statut. */
  .sp-history-table tbody tr{ display:grid; grid-template-columns:1fr 1fr; gap:2px 12px; padding:10px 0; }
  .sp-history-table tbody tr > th[scope="row"], .sp-history-table tbody tr > td:last-child{ grid-column:1 / -1; }
  .sp-history-table tbody tr > td:last-child::before{ display:none; }
  .sp-history-table td, .sp-history-table th[scope="row"]{ padding:3px 0; border-bottom:0 !important; box-shadow:none !important; }
  .sp-history-table tbody tr:not(:last-child){ border-bottom:1px solid var(--line); }
  .sp-history-table td[data-label]::before{ content:attr(data-label); display:block; font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); }
}
.sp-projects{ list-style:none; margin:0 0 14px; padding:0; display:flex; flex-direction:column; gap:12px; }
.sp-project{ border:1px solid var(--line-strong, var(--line)); border-radius:var(--radius, 12px); padding:14px 16px; min-width:0; overflow-wrap:anywhere;
  background:var(--paper); box-shadow:4px 4px 10px var(--neu-lo, rgba(0,0,0,.12)), -4px -4px 10px var(--neu-hi, rgba(255,255,255,.6)); }
.sp-project-head{ display:flex; align-items:center; gap:12px; }
.sp-project-top{ display:flex; justify-content:flex-end; margin:4px 0 10px; }
.sp-project-name{ margin:2px 0 0; font-size:17px; font-weight:600; line-height:1.3; text-transform:none; letter-spacing:normal; font-family:inherit; color:var(--ink); }
.sp-project-facts{ display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:8px 18px; margin:10px 0 0; }
.sp-project-facts dt{ font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.03em; }
.sp-project-facts dd{ margin:2px 0 0; font-size:13.5px; }
.sp-fact-line{ display:block; }
.sp-fact-line + .sp-fact-line{ margin-top:4px; }
.sp-fact-sub{ display:block; font-size:12px; color:var(--ink-soft); }
.sp-tbc{ color:var(--ink-soft); font-style:italic; }
.sp-project-files{ margin-top:12px; padding-top:10px; border-top:1px solid var(--line); }
.sp-project-files-title{ font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.03em; margin-bottom:6px; }
.sp-project-nofiles{ margin:0; font-size:13px; color:var(--ink-soft); }
.sp-project-dispatches{ margin:0; }
.sp-lines{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:10px; }
/* Correction en cours (CH-51, 2026-10-03) : l'avertissement du lot et du projet, et l'historique. */
.sp-corr-banner{ display:flex; flex-direction:column; gap:8px; }
.sp-corr-banner > strong{ font-size:14.5px; }
.sp-project-page .sp-corr-banner{ margin:24px 0 12px; }
.sp-corr-answer{ display:flex; flex-direction:column; gap:6px; margin-top:6px; }
.sp-corr-answer-title{ font-size:13px; font-weight:600; }
.sp-corr-answer-comment{ display:flex; flex-direction:column; gap:3px; font-size:12.5px; }
.sp-corr-answer-comment textarea{ width:100%; box-sizing:border-box; }
.sp-corr-answer-actions{ display:flex; flex-wrap:wrap; gap:8px; }
.sp-corr-status{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; margin:8px 0; font-size:13px; color:var(--ink-soft); overflow-wrap:anywhere; }
.dispatch-corr-list{ list-style:none; margin:4px 0 12px; padding:0; display:flex; flex-direction:column; gap:10px; overflow-wrap:anywhere; }
.dispatch-corr-list > li + li{ border-top:1px solid var(--line); padding-top:10px; }
.sp-corr-event{ display:flex; flex-direction:column; gap:2px; overflow-wrap:anywhere; }
.sp-corr-banner .sp-corr-event a{ color:inherit; text-decoration:underline; }
.sp-corr-meta{ font-size:13px; }
.sp-corr-message{ font-size:13px; white-space:normal; }
.sp-corr-history{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:12px; }
.sp-corr-history > li + li{ border-top:1px solid var(--line); padding-top:12px; }
.sp-corr-history .sp-corr-meta{ color:var(--ink-soft); }
.sp-corr-items{ margin:6px 0 0; padding-left:18px; font-size:13px; overflow-wrap:anywhere; }
.sp-line{ border:1px solid var(--line); border-radius:var(--radius-sm, 8px); padding:10px 12px; min-width:0; overflow-wrap:anywhere; }
.sp-line.is-stop{ border-color:var(--red); background:rgba(var(--brand-rgb), .04); }
.sp-line-head{ display:flex; flex-wrap:wrap; gap:6px 10px; align-items:center; }
.sp-line-head .badge{ margin-left:auto; white-space:normal; max-width:100%; text-align:center; }
.sp-line-file{ font-size:12.5px; color:var(--ink-soft); margin:4px 0 6px; }
.sp-line-specs{ display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:6px 14px; margin:0 0 8px; }
.sp-line-specs dt{ font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.03em; }
.sp-line-specs dd{ margin:0; font-size:13px; }
.sp-line-specs .cp-legal-meta{ display:block; }
/* Préparation : le récapitulatif replié en résumé, une fois le brouillon créé. */
.dispatch-recap.is-collapsed .dispatch-h2{ margin-bottom:4px; }
.dispatch-recap.is-collapsed p{ margin:4px 0 0; }
[data-pp-dtransmission-slot] > [data-pp-dtransmission]{ margin-top:22px; }
[data-pp-dtransmission][aria-busy="true"]{ cursor:progress; }
.dispatch-uncertain{ margin:0 0 14px; }

/* « VÉRIFIER LE LOT » (maquette docs/inspirations/print-01.png) — bandeau
   « Sélection » replié, tableau aéré à cinq colonnes, une action principale. */
.dispatch-select.is-collapsed{ padding-top:12px; padding-bottom:12px; }
.dispatch-select.is-collapsed .dispatch-select-head{ gap:12px; }
.dispatch-select-summary .badge{ text-transform:none; letter-spacing:0; }
.dispatch-select-sep{ width:1px; height:18px; background:var(--line-strong, var(--line)); }
/* Le bandeau porte déjà le fournisseur et « Modifier » : pas de répétition. */
.dispatch-select.is-collapsed ~ [data-pp-drecap] .dispatch-recap-supplier,
.dispatch-select.is-collapsed ~ [data-pp-drecap] .dispatch-recap-modify{ display:none; }
.dispatch-recap-note .dispatch-label{ display:block; }
.dispatch-recap-note{ margin:4px 0 12px; white-space:normal; }
.dispatch-lot-table{ width:100%; border-collapse:collapse; }
.dispatch-lot-table th, .dispatch-lot-table td{ vertical-align:top; padding:12px 14px; text-align:left; }
.dispatch-lot-table thead th{ white-space:nowrap; }
.dispatch-lot-table tbody th{ font-weight:400; }
.dispatch-lot-table tbody tr + tr > *{ border-top:1px solid var(--line); }
.dispatch-lot-print{ min-width:200px; max-width:320px; }
.dispatch-lot-title{ display:block; font-weight:600; color:var(--ink); }
.dispatch-lot-main{ display:block; color:var(--ink); }
.dispatch-lot-sub{ display:block; margin-top:2px; font-size:12px; color:var(--ink-soft); }
.dispatch-lot-nowrap{ white-space:nowrap; }
.dispatch-lot-file{ display:flex; align-items:center; gap:6px; margin-top:4px; font-size:12px; color:var(--ink-soft); min-width:0; }
.dispatch-lot-file .wabu-icon{ flex:none; }
.dispatch-lot-filename{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dispatch-lot-notes{ min-width:200px; white-space:normal; overflow-wrap:anywhere; }
.dispatch-lot-actions{ justify-content:flex-end; margin-top:4px; padding-top:14px; border-top:1px solid var(--line); }
@media (max-width: 640px){
  .dispatch-lot-wrap{ overflow-x:visible; }
  .dispatch-lot-table tr{ padding:12px 0 !important; }
  .dispatch-lot-table tbody th{ display:block; padding:0 0 6px !important; max-width:none; min-width:0; }
  .dispatch-lot-table td{ padding:4px 0 !important; }
  .dispatch-lot-table tbody tr + tr > *{ border-top:none; }
  .dispatch-lot-table td[data-label]::before{ display:block; content:attr(data-label); font-size:11px; text-transform:uppercase; letter-spacing:.04em; }
  .dispatch-lot-notes{ min-width:0; }
  .dispatch-lot-filename{ white-space:normal; overflow-wrap:anywhere; }
}
/* La colonne « Print » est un en-tête de LIGNE (accessibilité) : elle reprend
   l'apparence d'une cellule, pas celle des en-têtes de colonnes. */
table.data.dispatch-lot-table th, table.data.dispatch-lot-table td{ vertical-align:top; padding:12px 14px; border-bottom:1px solid var(--line); }
table.data.dispatch-lot-table thead th{ padding:8px 14px; border-bottom:1px solid var(--line-strong); }
table.data.dispatch-lot-table tbody th{ text-transform:none; letter-spacing:normal; font-size:13.5px; color:var(--ink); }
table.data.dispatch-lot-table tbody tr + tr > *{ border-top:none; }
table.data.dispatch-lot-table tbody tr:last-child > *{ border-bottom:none; }
@media (max-width: 640px){
  table.data.dispatch-lot-table th, table.data.dispatch-lot-table td{ border-bottom:none; }
  table.data.dispatch-lot-table tbody tr{ border-bottom:1px solid var(--line); }
}

/* PRÉPARER UN LOT — retouche limitée à cette page (.dispatch-prep) : vrai
   titre, projet à part, titres de panneaux en police standard semi-grasse,
   références en orange Wabu, colonnes rééquilibrées. Aucun style global. */
.dispatch-prep .dispatch-prep-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; flex-wrap:wrap; margin:4px 0 6px; }
.dispatch-prep .dispatch-prep-title{ font-family:inherit; text-transform:none; letter-spacing:normal; font-size:24px; font-weight:600; line-height:1.2; margin:0; color:var(--ink); }
.dispatch-prep .dispatch-prep-project{ margin:4px 0 0; font-size:14px; color:var(--ink-soft); }
.dispatch-prep .dispatch-lead{ margin:0 0 16px; }
.dispatch-prep .dispatch-h2{ font-family:inherit; text-transform:none; letter-spacing:normal; font-size:16px; font-weight:600; color:var(--ink); }
.dispatch-lot-table .dispatch-lot-ref{ color:var(--brand); font-weight:600; margin-right:4px; }
.dispatch-lot-table .dispatch-lot-title{ font-weight:600; }
table.data.dispatch-lot-table tbody tr > *{ border-bottom:1px solid var(--line); }
table.data.dispatch-lot-table tbody tr:last-child > *{ border-bottom:none; }
.dispatch-lot-table .dispatch-lot-count{ font-size:15px; font-weight:600; }
@media (min-width: 641px){
  .dispatch-lot-table .dispatch-lot-qty, .dispatch-lot-table .dispatch-lot-dim{ white-space:nowrap; width:1%; }
  .dispatch-lot-table .dispatch-lot-qty .dispatch-lot-sub, .dispatch-lot-table .dispatch-lot-dim .dispatch-lot-sub{ white-space:nowrap; }
  table.data.dispatch-lot-table th.dispatch-lot-notes, .dispatch-lot-table .dispatch-lot-notes{ width:28%; min-width:180px; }
  .dispatch-lot-table .dispatch-lot-filename{ max-width:240px; }
}
.dispatch-lot-table .dispatch-lot-file{ font-size:11.5px; }
.dispatch-lot-table .dispatch-lot-filename{ border-radius:3px; }
.dispatch-lot-table .dispatch-lot-filename:focus{ outline:2px solid var(--brand); outline-offset:1px; white-space:normal; overflow:visible; overflow-wrap:anywhere; }
.dispatch-lot-table .dispatch-lot-notes{ white-space:normal; overflow-wrap:anywhere; }
/* Moins de vide avant « Préparer le lot ». */
.dispatch-prep .dispatch-lot-wrap{ margin-bottom:0; }
.dispatch-prep .dispatch-lot-actions{ margin-top:0; padding-top:12px; }
.dispatch-prep .dispatch-recap{ padding-bottom:14px; }
.dispatch-lot-table th abbr{ text-decoration:none; cursor:help; }
/* PRÉPARER UN LOT — en-tête du panneau de sélection : titre, séparateur,
   « Fournisseur : nom » (ou le select), l'action à droite ; identique replié. */
.dispatch-prep .dispatch-select-head{ display:flex; align-items:center; justify-content:space-between; gap:10px 16px; flex-wrap:wrap; margin-bottom:16px; }
.dispatch-prep .dispatch-select.is-collapsed .dispatch-select-head{ margin-bottom:0; }
.dispatch-prep .dispatch-head-main{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; min-width:0; }
.dispatch-prep .dispatch-head-main .dispatch-h2{ margin:0; }
.dispatch-prep .dispatch-head-count[hidden]{ display:none; }
.dispatch-prep .dispatch-head-supplier{ display:inline-flex; align-items:center; gap:6px; min-width:0; font-size:14px; }
.dispatch-prep .dispatch-head-label{ color:var(--ink-soft); font-weight:400; margin:0; font-size:14px; text-transform:none; letter-spacing:normal; }
.dispatch-prep .dispatch-head-name{ color:var(--ink); font-weight:400; }
.dispatch-prep .dispatch-head-name[hidden], .dispatch-prep .dispatch-head-select[hidden]{ display:none; }
.dispatch-prep .dispatch-head-select{ min-width:200px; max-width:100%; }
@media (max-width: 640px){
  .dispatch-prep .dispatch-head-main{ flex-direction:column; align-items:flex-start; gap:6px; width:100%; }
  .dispatch-prep .dispatch-head-main .dispatch-select-sep{ display:none; }
  .dispatch-prep .dispatch-head-supplier{ flex-wrap:wrap; width:100%; }
  .dispatch-prep .dispatch-head-select{ flex:1 1 100%; min-width:0; }
}
.dispatch-prep .dispatch-head-count{ text-transform:none; letter-spacing:0; }
.dispatch-prep .dispatch-head-supplier.field{ display:inline-flex; flex-direction:row; align-items:center; margin:0; }
.dispatch-prep .dispatch-head-supplier.field .dispatch-head-label{ display:inline; }
.dispatch-prep .dispatch-head-supplier.field select{ width:auto; }
@media (max-width: 640px){
  .dispatch-prep .dispatch-head-supplier.field{ flex-wrap:wrap; }
  .dispatch-prep .dispatch-head-supplier.field select{ width:100%; }
}

/* TRANSMISSION — tableau « Éléments figés », aligné sur le récapitulatif de
   préparation (mêmes classes .dispatch-lot-*), plus les cases et l'état. */
.dispatch-lot-heading{ display:flex; align-items:center; gap:10px; margin:0 0 12px; font-family:inherit; text-transform:none;
  letter-spacing:normal; font-size:16px; font-weight:600; color:var(--ink); }
.dispatch-lot-heading-count{ text-transform:none; letter-spacing:0; font-weight:600; }
table.data.dispatch-lot-table th.dispatch-check, table.data.dispatch-lot-table td.dispatch-check{ width:34px; padding-right:0; }
.dispatch-lot-table .dispatch-lot-state{ width:1%; }
.dispatch-lot-table .dispatch-lot-state .badge{ white-space:nowrap; font-size:10.5px; padding:2px 8px; }
.dispatch-lot-table .dispatch-lot-state .dispatch-lot-sub{ min-width:140px; }
.dispatch-lot-table details.dispatch-pages summary{ cursor:pointer; }
.dispatch-lot-table details.dispatch-pages ul{ margin:4px 0 0; padding-left:16px; }
@media (max-width: 640px){
  .dispatch-lot-table.has-check tr{ padding-left:34px !important; }
  .dispatch-lot-table.has-check td.dispatch-check{ top:12px; }
  .dispatch-lot-table .dispatch-lot-state{ width:auto; }
  .dispatch-lot-table .dispatch-lot-state .dispatch-lot-sub{ min-width:0; }
}

/* DÉTAIL D'UN LOT (maquette docs/inspirations/transmission.png) — en-tête
   compact, faits regroupés, « Prints du lot » avec téléchargements, pied
   d'actions du brouillon, panneau unique « Publier le lot ». */
.dispatch-tr-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; flex-wrap:wrap; margin:4px 0 14px; }
.dispatch-tr-title{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0; font-family:inherit; text-transform:none;
  letter-spacing:normal; font-size:24px; font-weight:600; line-height:1.2; color:var(--ink); }
.dispatch-tr-title .badge{ font-size:11px; }
.dispatch-tr-project{ margin:4px 0 0; font-size:14px; color:var(--ink-soft); }
/* La transmission posée sous la préparation : la page a déjà son titre. */
[data-pp-dtransmission-slot] .dispatch-tr-head{ display:none; }
.dispatch-page .dispatch-head .dispatch-facts{ grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); }
.dispatch-lots-head{ display:flex; align-items:center; justify-content:space-between; gap:10px 16px; flex-wrap:wrap; margin-bottom:12px; }
.dispatch-lots-head .dispatch-lot-heading{ margin:0; }
.dispatch-lots-head .dispatch-downloads{ display:flex; gap:8px; flex-wrap:wrap; margin:0; }
.dispatch-lots-head .dispatch-downloads .btn{ display:inline-flex; align-items:center; gap:6px; }
.dispatch-lot-foot{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:4px; padding-top:12px; border-top:1px solid var(--line); }
.dispatch-lot-refresh{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0; }
.dispatch-lot-refresh .dispatch-muted{ font-size:12px; }
.dispatch-more .actions-menu-panel{ right:0; left:auto; min-width:220px; }
.dispatch-publish-panel{ display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:16px 20px; margin-top:16px; }
.dispatch-publish-icon{ display:inline-flex; padding-right:18px; border-right:1px solid var(--line); }
.dispatch-publish-text p{ margin:4px 0 0; }
.dispatch-publish-text .dispatch-muted{ font-size:12.5px; }
.dispatch-publish-none{ color:var(--ink); }
.dispatch-publish-action{ display:flex; flex-direction:column; align-items:flex-end; gap:6px; text-align:right; }
.dispatch-publish-action .dispatch-muted{ font-size:12px; }
@media (max-width: 640px){
  .dispatch-tr-title{ font-size:20px; }
  .dispatch-lot-foot{ flex-wrap:wrap; }
  .dispatch-publish-panel{ grid-template-columns:1fr; }
  .dispatch-publish-icon{ display:none; }
  .dispatch-publish-action{ align-items:stretch; text-align:left; }
  .dispatch-lots-head .dispatch-downloads{ width:100%; }
}
.dispatch-refresh-btn{ display:inline-flex; align-items:center; gap:6px; }
/* Le ⋯ reste au bord droit, même sur téléphone : son menu s'ouvre vers la gauche, dans l'écran. */
.dispatch-lot-foot .dispatch-lot-refresh{ flex:1 1 auto; min-width:0; }
.dispatch-lot-foot .dispatch-more{ margin-left:auto; align-self:flex-start; }
.dispatch-portal-head{ display:flex; align-items:center; gap:10px; }
/* Suivi fournisseur (maquette suivis-fournisseur.png) */
.dispatch-follow{ display:flex; flex-direction:column; gap:14px; }
/* Préparation des archives : fenêtre de suivi (animation sobre, mesures réelles). */
.dispatch-archives-box{ max-width:440px; display:flex; flex-direction:column; gap:12px; }
.dispatch-archives-anim{ display:flex; gap:6px; }
.dispatch-archives-anim span{ width:8px; height:8px; border-radius:50%; background:var(--brand, #c2410c); animation:pp-archives-pulse 1.2s infinite ease-in-out; }
.dispatch-archives-anim span:nth-child(2){ animation-delay:.2s; }
.dispatch-archives-anim span:nth-child(3){ animation-delay:.4s; }
@keyframes pp-archives-pulse{ 0%, 80%, 100%{ opacity:.25; } 40%{ opacity:1; } }
@media (prefers-reduced-motion: reduce){ .dispatch-archives-anim span{ animation:none; opacity:.6; } }
.dispatch-archives-step{ margin:0; font-weight:600; }
.dispatch-archives-result{ margin:0; padding:8px 10px; border-radius:var(--radius-sm, 8px); background:var(--green-bg); color:var(--green); font-weight:600; }
.dispatch-archives-facts{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; margin:0; }
.dispatch-archives-facts dt{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
.dispatch-archives-facts dd{ margin:0; font-size:14px; }
.dispatch-publish-action .dispatch-inline-form{ display:inline; }
.dispatch-follow-head{ display:flex; align-items:center; gap:10px; }
.dispatch-follow-head .dispatch-lot-heading-count{ margin-left:auto; }
.dispatch-follow-contact{ display:flex; flex-direction:column; gap:12px; min-width:0; }
.dispatch-follow-contact + .dispatch-follow-contact{ border-top:1px solid var(--line); padding-top:14px; }
.dispatch-follow-id{ display:flex; align-items:center; gap:12px; min-width:0; }
.dispatch-follow-avatar{ flex:0 0 auto; width:40px; height:40px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
  background:var(--brand, #c2410c); color:#fff; font-weight:600; font-size:14px; }
.dispatch-follow-name{ display:flex; flex-direction:column; min-width:0; }
.dispatch-follow-name strong, .dispatch-follow-name span{ overflow-wrap:anywhere; }
.dispatch-follow-name span{ font-size:12.5px; color:var(--ink-soft); }
.dispatch-follow-id .dispatch-more{ margin-left:auto; }
.dispatch-follow-facts{ display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:10px 0; margin:0; }
.dispatch-follow-facts > div{ display:grid; grid-template-columns:auto 1fr; column-gap:10px; align-items:center; padding:0 14px; min-width:0; }
.dispatch-follow-facts > div:first-child{ padding-left:0; }
.dispatch-follow-facts > div + div{ border-left:1px solid var(--line); }
.dispatch-follow-facts .wabu-icon{ grid-row:span 2; }
.dispatch-follow-facts dt{ font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
.dispatch-follow-facts dd{ margin:0; font-size:13.5px; overflow-wrap:anywhere; }
.dispatch-follow-facts .is-off dd{ color:var(--ink-soft); }
.dispatch-follow-last{ display:flex; align-items:center; gap:8px; margin:0; font-size:12.5px; color:var(--ink-soft); overflow-wrap:anywhere; }
.dispatch-follow-last.is-error{ color:var(--red); }
.dispatch-follow-retry{ margin:0; }
.dispatch-follow-history{ border-top:1px solid var(--line); padding-top:10px; }
.dispatch-follow-history > summary{ cursor:pointer; font-weight:600; display:inline-flex; align-items:center; gap:8px; }
.dispatch-follow-history[open] > summary{ margin-bottom:8px; }
@media (max-width:720px){
  .dispatch-follow-facts{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .dispatch-follow-facts > div{ padding:0 10px; }
  .dispatch-follow-facts > div:nth-child(odd){ padding-left:0; border-left:0; }
}
[data-theme-style="neumorphism"] .dispatch-follow-contact + .dispatch-follow-contact,
[data-theme-style="neumorphism"] .dispatch-follow-history{ border-top-color:var(--neu-lo, rgba(0,0,0,.12)); }
[data-theme-style="neumorphism"] .dispatch-follow-facts > div + div{ border-left-color:var(--neu-lo, rgba(0,0,0,.12)); }
.dispatch-portal-head .dispatch-more{ margin-left:auto; }
.dispatch-reopen-message{ width:100%; max-width:none; }
.dispatch-reopen-lead{ margin:0 0 12px; }
.dispatch-reopen-note{ margin:4px 0 0; font-size:12.5px; }
.dispatch-follow-subtitle{ margin:12px 0 6px; font-family:inherit; text-transform:none; letter-spacing:normal; font-size:13.5px; font-weight:600; color:var(--ink); }
.dispatch-page .dispatch-zone-warning .dispatch-reopen-message textarea{ width:100%; max-width:none; box-sizing:border-box; }
.dispatch-zone-warning .field > small{ display:block; flex-basis:100%; width:100%; margin:4px 0 10px; }
@media (max-width: 640px){
  .dispatch-lot-foot{ flex-wrap:nowrap; align-items:flex-start; }
  .dispatch-more .actions-menu-panel{ max-width:calc(100vw - 48px); }
  .dispatch-more .actions-menu-item{ white-space:normal; }
}
/* L'icône « publication » dans un carré teinté de la couleur Wabu. */
.dispatch-publish-panel .dispatch-publish-icon{ width:48px; height:48px; padding:0; border-right:none; border-radius:var(--radius-sm, 8px);
  display:inline-flex; align-items:center; justify-content:center; background:rgba(var(--brand-rgb), .12); }
/* « Par » : l'avatar et le pseudo seuls, alignés sur les autres faits. */
.dispatch-fact-author{ display:flex; align-items:center; }
/* Panneau du haut de la transmission : les faits séparés par un filet vertical
   (maquette transmission.png) ; les lignes longues (note, remplacement…)
   passent dessous, séparées par un filet horizontal. Sur téléphone, empilés. */
.dispatch-page .dispatch-head .dispatch-facts{ display:flex; flex-wrap:wrap; gap:12px 0; margin-bottom:0; }
.dispatch-page .dispatch-head .dispatch-facts > div{ flex:1 1 180px; min-width:0; padding:0 18px; border-left:1px solid var(--line); }
.dispatch-page .dispatch-head .dispatch-facts > div:first-child{ padding-left:0; border-left:none; }
.dispatch-page .dispatch-head .dispatch-facts > .dispatch-wide{ flex-basis:100%; padding:12px 0 0; border-left:none; border-top:1px solid var(--line); }
@media (max-width: 640px){
  .dispatch-page .dispatch-head .dispatch-facts > div{ flex-basis:100%; padding:10px 0 0; border-left:none; border-top:1px solid var(--line); }
  .dispatch-page .dispatch-head .dispatch-facts > div:first-child{ padding-top:0; border-top:none; }
}

/* NEUMORPHISM : --line y est transparent. Les séparateurs de la préparation et
   du détail d'un lot deviennent des filets GRAVÉS (ombre + reflet), dans
   l'esprit du thème, au lieu de disparaître. */
[data-theme-style="neumorphism"] .dispatch-page .dispatch-head .dispatch-facts > div:not(:first-child):not(.dispatch-wide){
  border-left:1px solid var(--neu-lo); box-shadow:inset 1px 0 0 var(--neu-hi);
}
[data-theme-style="neumorphism"] .dispatch-page .dispatch-head .dispatch-facts > .dispatch-wide{
  border-top:1px solid var(--neu-lo); box-shadow:inset 0 1px 0 var(--neu-hi);
}
[data-theme-style="neumorphism"] table.data.dispatch-lot-table tbody tr:not(:last-child) > *{
  border-bottom:1px solid var(--neu-lo); box-shadow:0 1px 0 var(--neu-hi);
}
[data-theme-style="neumorphism"] .dispatch-lot-foot,
[data-theme-style="neumorphism"] .dispatch-lot-actions{ border-top:1px solid var(--neu-lo); box-shadow:inset 0 1px 0 var(--neu-hi); }
[data-theme-style="neumorphism"] .dispatch-select-sep{ background:var(--neu-lo); box-shadow:1px 0 0 var(--neu-hi); }
@media (max-width: 640px){
  [data-theme-style="neumorphism"] .dispatch-page .dispatch-head .dispatch-facts > div:not(:first-child){
    border-left:none; box-shadow:inset 0 1px 0 var(--neu-hi); border-top:1px solid var(--neu-lo);
  }
  [data-theme-style="neumorphism"] table.data.dispatch-lot-table tbody tr > *{ box-shadow:none; border-bottom:none; }
  [data-theme-style="neumorphism"] table.data.dispatch-lot-table tbody tr:not(:last-child){ border-bottom:1px solid var(--neu-lo); }
}
/* Portail fournisseur, « Mon équipe » : la case « Recevoir les e-mails ». */
.sp-pref-check{ display:inline-flex; align-items:center; gap:6px; font-size:12.5px; color:var(--ink-soft); margin-right:8px; }
.sp-pref-check-bloc{ display:flex; align-items:flex-start; gap:8px; margin:6px 0 12px; color:var(--ink); font-size:13.5px; }
.sp-pref-check-bloc small{ display:block; color:var(--ink-soft); font-size:12px; }
/* « Publier le lot » allégé : titre au format des panneaux, texte secondaire discret, hauteur réduite. */
.dispatch-publish-panel{ padding-top:14px; padding-bottom:14px; gap:10px 16px; }
.dispatch-publish-panel .dispatch-publish-icon{ width:40px; height:40px; }
.dispatch-publish-panel .dispatch-lot-heading{ font-size:15px; margin:0; }
.dispatch-publish-text .dispatch-publish-lead{ margin:2px 0 0; font-size:12.5px; color:var(--ink-soft); }
.dispatch-publish-panel .dispatch-publish-action{ gap:0; }
