    :root {
      --font-main: Calibri, Arial, sans-serif;
      --text-size: 11pt;
      --blue: #0f5ea8;
      --blue-dark: #084d8f;
      --blue-soft: #e8f2ff;
      --bg: #f3f6fa;
      --card: #ffffff;
      --text: #172033;
      --muted: #64748b;
      --border: rgba(15, 23, 42, 0.11);
      --shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
      --radius: 18px;
    }

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

    body {
      font-family: var(--font-main);
      font-size: var(--text-size);
      background: var(--bg);
      color: var(--text);
    }

    button,
    input,
    select,
    textarea {
      font-family: inherit;
      font-size: inherit;
      resize: vertical;
      min-height: 28px;
    }

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

    .app-shell {
      min-height: 100vh;
      display: grid;
      grid-template-columns: 250px 1fr;
    }

    .sidebar {
      background: #ffffff;
      border-right: 1px solid var(--border);
      padding: clamp(9px, 1.3vh, 14px) 10px;
      position: sticky;
      top: 0;
      height: 100vh;
      display: flex;
      flex-direction: column;
      overflow: visible;
    }

    .brand {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 0 6px clamp(8px, 1.2vh, 14px);
      border-bottom: 1px solid rgba(15, 23, 42, 0.08);
      margin-bottom: clamp(6px, 1.1vh, 12px);
    }

    .brand-logo {
      width: clamp(30px, 4.2vh, 42px);
      height: clamp(30px, 4.2vh, 42px);
      border-radius: clamp(10px, 1.3vh, 13px);
      display: grid;
      place-items: center;
      background: white;
      border: 1px solid rgba(15, 23, 42, 0.10);
      overflow: hidden;
      flex: 0 0 auto;
    }

    .brand-logo img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }

    .brand h1 {
      font-size: clamp(16px, 1.9vh, 19px);
      line-height: 1.05;
      letter-spacing: -0.02em;
    }

    .brand p {
      font-size: 11px;
      color: var(--muted);
      margin-top: 3px;
    }

    /* ── LE MENU TIENT SANS DÉFILEMENT (décision Philippe, 2026-09-14) ──────────────────
       À 19 entrées + Administration + profil, le menu réclamait 777 px : sur un portable
       (768 px de fenêtre, 561 px utiles) les six dernières — Texto jusqu'à Notification —
       n'étaient atteignables qu'en faisant défiler, donc oubliées.
       Les entrées se PARTAGENT la hauteur restante : `flex: 0 1` les fait rétrécir
       ensemble entre un plafond (38 px, l'espacement d'origine sur grand écran) et un
       plancher (24 px). Tout ce qui n'est PAS une entrée (logo, filets, pied, avatar)
       rétrécit en `clamp(… vh …)` pour leur laisser la place.
       ⚠️ Ne jamais redonner une hauteur FIXE à `.nav-item` (ni un `padding` vertical, qui
       en est une) : c'est exactement ce qui rouvrirait le défilement au module suivant.
       `overflow-y: auto` reste un filet pour une fenêtre vraiment minuscule — mieux vaut
       une barre de défilement qu'une entrée rognée, donc invisible et inaccessible. */
    .nav {
      display: flex;
      flex-direction: column;
      gap: clamp(1px, 0.3vh, 2px);
      flex: 1 1 auto;
      min-height: 0;
      overflow-y: auto;
      overflow-x: hidden;
    }

    .nav-item {
      display: flex;
      align-items: center;
      gap: 11px;
      flex: 0 1 38px;
      min-height: 24px;
      padding: 0 12px;
      border-radius: 10px;
      color: #334155;
      text-decoration: none;
      font-weight: 800;
      transition: background 0.15s ease, color 0.15s ease;
      position: relative;
    }

    .nav-item:hover,
    .nav-item.active {
      background: var(--blue-soft);
      color: var(--blue);
    }

    .nav-item.active::before {
      content: "";
      position: absolute;
      left: 0;
      /* En % : le liseré suit la hauteur de l'entrée, qui n'est plus fixe. */
      top: 18%;
      bottom: 18%;
      width: 3px;
      border-radius: 999px;
      background: var(--blue);
    }

    .nav-icon {
      width: clamp(17px, 2.2vh, 20px);
      height: clamp(17px, 2.2vh, 20px);
      color: currentColor;
      flex: 0 0 auto;
      opacity: 0.92;
    }

    .nav-icon svg {
      width: clamp(17px, 2.2vh, 20px);
      height: clamp(17px, 2.2vh, 20px);
      display: block;
      stroke: currentColor;
      fill: none;
      stroke-width: 2;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    .nav-label {
      flex: 1;
      white-space: nowrap;
      transition: opacity 0.2s ease;
      display: flex;
      align-items: center;
    }

    .nav-badge {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      min-width: 18px;
      height: 18px;
      padding: 0 5px;
      background: #dc2626;
      color: #fff;
      border-radius: 9px;
      font-size: 7.5pt;
      font-weight: 700;
      margin-left: auto;
      line-height: 1;
      flex-shrink: 0;
    }

    .sidebar-collapsed .nav-badge { display: none; }

    /* Bouton repli sidebar */
    .sidebar-toggle {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 28px;
      height: 28px;
      border-radius: 8px;
      border: 1px solid var(--border);
      background: white;
      cursor: pointer;
      color: var(--muted);
      flex-shrink: 0;
      transition: background 0.15s;
    }
    .sidebar-toggle:hover { background: var(--blue-soft); color: var(--blue); }
    .sidebar-toggle svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; display: block; }

    /* État replié */
    .app-shell.sidebar-collapsed {
      grid-template-columns: 62px 1fr;
    }
    /* Replié, la marque s'EMPILE (logo au-dessus du bouton) : elle coûte le double de
       hauteur au moment où le menu en a le moins. Elle suit donc la fenêtre comme le
       reste — sans ça, le menu replié débordait là où le menu déployé tenait. */
    .sidebar-collapsed .sidebar {
      padding: clamp(9px, 1.3vh, 18px) 10px;
      overflow: visible;
    }
    .sidebar-collapsed .brand {
      flex-direction: column;
      gap: clamp(4px, 0.8vh, 8px);
      padding-bottom: clamp(7px, 1.1vh, 14px);
    }
    .sidebar-collapsed .brand-text { display: none; }
    .sidebar-collapsed .brand-toggle { margin: 0 auto; }
    .sidebar-collapsed .nav-label { display: none; }

    .sidebar-collapsed .nav-item {
      justify-content: center;
      padding: 0 10px;
      position: relative;
    }
    .sidebar-collapsed .nav-item::before { display: none; }
    .sidebar-collapsed .admin-label { display: none; }
    .sidebar-collapsed .nav { gap: 1px; scrollbar-width: none; }
    .sidebar-collapsed .nav::-webkit-scrollbar { display: none; }

    /* Pied du menu : Administration · Notification · profil employé */
    /* Séparateur entre les deux groupes du menu (décision Philippe, 2026-09-01) : même filet que
       celui du pied, pour que les deux coupures se lisent comme la même idée. */
    .nav-sep {
      height: 1px;
      background: var(--border);
      margin: clamp(4px, 0.8vh, 8px) 6px;
      flex: 0 0 auto;
    }

    .sidebar-footer {
      flex-shrink: 0;
      margin-top: clamp(6px, 1vh, 10px);
      padding-top: clamp(6px, 1vh, 10px);
      border-top: 1px solid var(--border);
      display: grid;
      gap: 2px;
    }

    /* Le pied est une grille, pas le flex du menu : sans hauteur propre, « Administration »
       retomberait à la taille de son icône (le padding vertical a quitté `.nav-item`). */
    .sidebar-footer .nav-item {
      min-height: clamp(28px, 3.7vh, 38px);
    }

    .sidebar-profile {
      position: relative;
      margin-top: 2px;
    }

    /* Avatar réduit DANS LE MENU seulement : `.avatar` sert aussi à l'agenda et à la liste
       des employés, où la hauteur de la fenêtre n'a rien à voir avec sa taille. */
    .sidebar .avatar {
      width: clamp(24px, 3.1vh, 29px);
      height: clamp(24px, 3.1vh, 29px);
    }

    .sidebar-profile-pill {
      width: 100%;
      border: 1px solid var(--border);
      background: white;
      border-radius: 10px;
      padding: clamp(5px, 0.8vh, 8px) 10px;
      display: flex;
      align-items: center;
      gap: 10px;
      cursor: pointer;
      font-weight: 800;
      color: #334155;
    }

    .sidebar-profile-pill:hover {
      background: var(--blue-soft);
      border-color: rgba(15, 94, 168, 0.25);
    }

    .sidebar-profile-name {
      flex: 1;
      text-align: left;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .sidebar-profile-caret {
      flex: 0 0 auto;
      display: flex;
      color: var(--muted);
    }

    .sidebar-profile-caret svg {
      width: 14px;
      height: 14px;
      stroke: currentColor;
      fill: none;
      stroke-width: 2;
      stroke-linecap: round;
      stroke-linejoin: round;
      display: block;
    }

    /* Le menu profil s'ouvre vers le haut (il est au bas du menu).
       Sélecteur à double classe pour battre `.dropdown-menu { top: 100% }`
       quelle que soit la position des règles dans le fichier.
       padding-bottom bride le gap entre le bouton et le menu pour que
       le :hover ne se perde pas quand la souris traverse l'espace. */
    .dropdown-menu.sidebar-profile-menu {
      top: auto;
      bottom: 100%;
      left: 0;
      right: auto;
      min-width: 210px;
      padding-bottom: 14px;
    }

    /* Sidebar repliée : le menu s'ouvre à droite de l'avatar (sinon il
       passe derrière le contenu principal qui commence à 62px). */
    .sidebar-collapsed .dropdown-menu.sidebar-profile-menu {
      bottom: 0;
      top: auto;
      left: calc(100% + 6px);
      padding-bottom: 8px;
    }

    /* Sidebar repliée : profil = avatar seul, pastille de notif en coin */
    .sidebar-collapsed .sidebar-profile-name,
    .sidebar-collapsed .sidebar-profile-caret { display: none; }
    .sidebar-collapsed .sidebar-profile-pill { justify-content: center; padding: 8px; }
    .sidebar-collapsed .sidebar-footer .notification-bubble {
      position: absolute;
      top: 3px;
      right: 6px;
      min-width: 16px;
      height: 16px;
      font-size: 9px;
    }

    /* Tooltips gérés par JS (sidebar.blade.php) — voir #sidebar-tooltip */

    .main {
      min-width: 0;
      transition: none;
    }

    /* Barre mobile (ouverture du menu) — masquée sur desktop, visible ≤ 900px */
    .mobile-topbar {
      display: none;
    }

    .global-search {
      position: relative;
      max-width: 620px;
    }

    .global-search input {
      width: 100%;
      border: 1px solid var(--border);
      border-radius: 12px;              /* aligné sur .form-input (plus de pilule 999px) */
      height: 34px;                     /* même hauteur que les filtres/recherches des autres pages */
      padding: 0 15px 0 38px;           /* 38px à gauche pour la loupe */
      outline: none;
      background: #f8fafc;
      color: var(--text);
    }

    .global-search input:focus {
      border-color: rgba(15, 94, 168, 0.45);
      box-shadow: 0 0 0 4px rgba(15, 94, 168, 0.08);
      background: white;
    }

    .global-search span {
      position: absolute;
      left: 16px;
      top: 50%;
      transform: translateY(-50%);
      color: var(--muted);
      font-weight: 900;
    }

    .dropdown {
      position: relative;
    }

    .dropdown-menu {
      position: absolute;
      right: 0;
      top: 100%;
      width: 235px;
      background: white;
      border: 1px solid var(--border);
      border-radius: 16px;
      box-shadow: var(--shadow);
      padding: 18px 8px 8px;
      margin-top: 0;
      display: none;
      z-index: 100;
    }

    .dropdown:hover .dropdown-menu {
      display: grid;
      gap: 4px;
    }

    .dropdown-item {
      border: 0;
      background: transparent;
      color: #334155;
      border-radius: 12px;
      padding: 10px 12px;
      text-align: left;
      cursor: pointer;
      font-weight: 800;
      display: flex;
      justify-content: space-between;
      gap: 10px;
    }

    .dropdown-item:hover {
      background: var(--blue-soft);
      color: var(--blue);
    }

    .btn {
      border: 0;
      cursor: pointer;
      border-radius: 999px;
      padding: 11px 15px;
      font-weight: 900;
      display: inline-flex;
      align-items: center;
      gap: 7px;
      white-space: nowrap;
      position: relative;
      text-decoration: none;
    }

    /* Boutons principaux du CORPS des pages : identiques aux boutons d'en-tête (même couleur/taille/forme).
       Couleur partagée avec l'en-tête (--btn-header-bg) ; arrondi propre configurable (--btn-body-radius).
       Les boutons de tableaux gardent leurs styles inline (padding/arrondi) ; l'en-tête garde son arrondi
       via .page-actions .btn (plus spécifique). Tokens pilotés par Admin → Apparence (App\Support\Theme). */
    .btn-primary {
      background: var(--btn-header-bg, var(--blue));
      color: white;
      border: 0;
      border-radius: var(--btn-body-radius, 10px);
      padding: 8px 14px;
      font-size: 9.5pt;
      font-weight: 800;
    }

    .btn-primary:hover {
      background: var(--btn-header-hover, var(--blue-dark));
    }

    /* Boutons SECONDAIRES — UN SEUL style (décision Philippe). .btn-white ET .btn-light sont rendus
       identiques (couleur ET taille/forme) et pilotés par les mêmes variables (Admin → Apparence). Avant :
       deux styles distincts (.btn-light = bleu pâle grande pilule, .btn-white = blanc). Même compacité que
       les boutons principaux du corps (arrondi partagé --btn-body-radius). Les boutons de tableaux gardent
       leurs styles inline ; l'en-tête garde sa taille via .page-actions .btn. Ne pas réintroduire de 2ᵉ style. */
    .btn-white,
    .btn-light {
      background: var(--btn-secondary-bg, #fff);
      color: var(--btn-secondary-text, #334155);
      border: 1px solid var(--btn-secondary-border, rgba(15, 23, 42, 0.11));
      border-radius: var(--btn-body-radius, 10px);
      padding: 8px 14px;
      font-size: 9.5pt;
      font-weight: 800;
    }

    .notification-bubble {
      min-width: 20px;
      height: 20px;
      padding: 0 6px;
      border-radius: 999px;
      background: #ef4444;
      color: white;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      font-size: 10px;
      font-weight: 900;
      line-height: 1;
    }

    .avatar {
      width: 29px;
      height: 29px;
      border-radius: 999px;
      display: grid;
      place-items: center;
      background: #0f172a;
      color: white;
      font-size: 11px;
    }

    .page {
      padding: 18px 26px 22px;
      max-width: 100%;
    }

    .page-header {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      gap: 18px;
      margin-bottom: 22px;
    }

    /* ⚠️ TITRE ET DESCRIPTION SUR LA MÊME LIGNE (décision Philippe, 2026-09-02 : « on va gagner
       en hauteur »). 215 pages portent cet en-tête et 159 ont une description : la règle vit ICI,
       pas dans chaque vue.

       `align-items: baseline` et non `center` : les deux textes n'ont pas la même taille, et les
       centrer ferait flotter la description au milieu du gros titre au lieu de l'asseoir sur la
       même ligne d'écriture.

       `flex-wrap` : une description longue repasse dessous plutôt que d'écraser le titre — c'est
       le seul comportement acceptable sur une tablette. */
    .page-title {
      display: flex;
      align-items: baseline;
      flex-wrap: wrap;
      gap: 4px 10px;
      min-width: 0;
    }

    .page-title h2 {
      font-size: 31px;
      letter-spacing: -0.04em;
      margin-bottom: 0;   /* l'espacement vient du `gap` : le garder décalerait la ligne de base */
    }

    .page-title p {
      color: var(--muted);
      line-height: 1.45;
      margin: 0;
    }

    /* Ce qui PORTE un bouton d'aide « i » (voir components/aide) devient une rangée centrée, pour que le
       bouton se pose À CÔTÉ, à la même hauteur. Classe explicite plutôt que `:has()` — le CRM tourne
       aussi sur de vieux iPad.
       ⚠️ La classe va sur le PARENT COMMUN du texte et du « i ». Restreinte à `.page-title h2`, elle
       laissait les autres cas dériver : mesuré au navigateur, le « i » d'une case à cocher tombait 28 px
       trop bas (le `.form-check` est un flex de BLOC, donc le « i » passait carrément à la ligne
       suivante) et celui d'un titre de carte 1,3 px. Pour une case, envelopper l'ensemble — le « i » ne
       doit jamais être DANS le `<label>`, sinon cliquer dessus cocherait la case. */
    .h-aide {
      display: flex;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
    }

    .page-actions {
      display: flex;
      align-items: center;
      gap: 9px;
      flex-wrap: wrap;
      justify-content: flex-end;
    }

    /* Boutons de HEADER unifiés — POINT UNIQUE. Tous les boutons dans .page-actions (toutes les pages)
       adoptent la MÊME forme + taille que le bouton iA Michel (pill radius 10px, padding 8px 14px,
       texte 9,5pt/800), et les primaires reçoivent un dégradé BLEU moderne. Ne touche PAS les boutons de
       tableau/formulaire/modale (hors .page-actions) ni .michel-btn (identité mauve d'iA Michel). */
    .page-actions .btn {
      border-radius: var(--btn-header-radius, 10px);
      padding: 8px 14px;
      font-size: 9.5pt;
      font-weight: 800;
      gap: 7px;
    }
    .page-actions .btn-primary {
      background: var(--btn-header-bg, #1a4cb0);
      color: #fff;
      border: 0;
      box-shadow: 0 3px 11px rgba(29, 78, 216, 0.34);
    }
    .page-actions .btn-primary:hover {
      background: var(--btn-header-hover, #16409a);
      filter: none;
    }
    .page-actions .btn-white:hover {
      background: #f8fafc;
    }

    .card {
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      padding: 18px;
    }

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 12px;
      margin-bottom: 15px;
    }

    .card h3 {
      font-size: 18px;
      letter-spacing: -0.02em;
    }

    .muted {
      color: var(--muted);
    }

    .dashboard-grid {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      gap: 18px;
      align-items: start;
    }

    .dashboard-column {
      display: grid;
      gap: 18px;
    }

    .widget {
      min-height: 150px;
    }

    .widget-toolbar {
      display: none;
      gap: 6px;
      align-items: center;
    }

    .edit-mode .widget-toolbar {
      display: flex;
    }

    .widget-btn {
      width: 28px;
      height: 28px;
      border-radius: 9px;
      border: 1px solid var(--border);
      background: #f8fafc;
      cursor: pointer;
      color: #475569;
      font-weight: 900;
    }

    .big-number {
      font-size: 34px;
      font-weight: 900;
      letter-spacing: -0.04em;
      margin-bottom: 5px;
    }

    .widget-footer {
      margin-top: 14px;
      padding-top: 13px;
      border-top: 1px solid rgba(15, 23, 42, 0.08);
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 10px;
    }

    .link-action {
      color: var(--blue);
      text-decoration: none;
      font-weight: 900;
    }

    .link-action:hover {
      text-decoration: underline;
    }


    .status {
      border-radius: 999px;
      padding: 6px 10px;
      font-size: 10px;
      font-weight: 900;
      display: inline-flex;
      white-space: nowrap;
    }

    .green  { background: #dcfce7; color: #166534; }
    .orange { background: #ffedd5; color: #9a3412; }
    .blue   { background: #dbeafe; color: #1d4ed8; }
    .red    { background: #fee2e2; color: #991b1b; }
    .gray   { background: #f1f5f9; color: #475569; }
    .purple { background: #ede9fe; color: #6d28d9; }
    .teal   { background: #ccfbf1; color: #0f766e; }
    .yellow { background: #fef9c3; color: #854d0e; }

    .list {
      display: grid;
      gap: 11px;
    }

    .list-item {
      border-radius: 14px;
      background: #f8fafc;
      border: 1px solid rgba(15, 23, 42, 0.07);
      padding: 12px;
      display: flex;
      justify-content: space-between;
      gap: 12px;
      align-items: flex-start;
      position: relative;
      overflow: hidden;
    }

    .list-item strong {
      display: block;
      margin-bottom: 4px;
    }

    .list-item p {
      color: var(--muted);
      line-height: 1.35;
    }

    .mini-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 9pt;
    }

    .mini-table th,
    .mini-table td {
      text-align: left;
      padding: 10px 8px;
      border-bottom: 1px solid rgba(15, 23, 42, 0.08);
      vertical-align: middle;
    }

    .mini-table th {
      font-size: 10px;
      text-transform: uppercase;
      letter-spacing: 0.07em;
      color: var(--muted);
    }

    .quick-actions-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 10px;
    }

    .quick-action {
      border: 1px solid rgba(15, 23, 42, 0.08);
      background: #f8fafc;
      border-radius: 14px;
      padding: 13px;
      text-align: left;
      cursor: pointer;
      font-weight: 900;
      color: #1e293b;
    }

    .quick-action:hover {
      background: var(--blue-soft);
      color: var(--blue);
    }

    .empty-state {
      padding: 24px;
      border-radius: 15px;
      background: #f8fafc;
      border: 1px dashed rgba(15, 23, 42, 0.16);
      text-align: center;
      color: var(--muted);
      line-height: 1.4;
    }

    .empty-state strong {
      display: block;
      color: #334155;
      margin-bottom: 5px;
    }

    .mobile-menu-checkbox,
    .mobile-overlay,
    .mobile-menu-btn,
    .mobile-close {
      display: none;
    }

    .mobile-menu-btn {
      border: 1px solid var(--border);
      background: white;
      color: #334155;
      border-radius: 999px;
      padding: 11px 14px;
      font-weight: 900;
      align-items: center;
      gap: 9px;
      cursor: pointer;
      white-space: nowrap;
    }

    .mobile-menu-lines {
      width: 18px;
      display: grid;
      gap: 4px;
    }

    .mobile-menu-lines span {
      height: 2px;
      border-radius: 999px;
      background: currentColor;
      display: block;
    }

    .mobile-close {
      width: 36px;
      height: 36px;
      border-radius: 999px;
      border: 1px solid var(--border);
      background: #f8fafc;
      color: #334155;
      align-items: center;
      justify-content: center;
      font-weight: 900;
      cursor: pointer;
      margin-left: auto;
      margin-bottom: 12px;
    }

    /* ── Fiche client ───────────────────────────────────── */
    .client-header { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:18px; margin-bottom:18px; }
    .client-title-line { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:8px; }
    .client-title-line h2 { font-size:32px; letter-spacing:-.04em; }
    .client-subline { display:flex; flex-wrap:wrap; gap:10px 18px; color:var(--muted); font-weight:800; }
    .client-subline span + span::before { content:'/'; margin-right:18px; }
    .client-actions { display:flex; align-items:flex-start; justify-content:flex-end; gap:10px; flex-wrap:wrap; }

    .client-main-grid { display:grid; grid-template-columns:1.1fr .9fr; gap:18px; margin-bottom:18px; align-items:stretch; }

    .info-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
    .info-field { background:#f8fafc; border:1px solid rgba(15,23,42,.07); border-radius:12px; padding:9px 10px; min-height:56px; }
    .info-field.full { grid-column:1/-1; }
    .info-field label { display:block; font-size:9.5px; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); font-weight:900; margin-bottom:4px; }
    .info-field div { color:#1e293b; font-weight:800; line-height:1.25; }

    .map-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
    .map-card { display:flex; flex-direction:column; }
    .map-box { border-radius:16px; overflow:hidden; border:1px solid rgba(15,23,42,.1); background:#f8fafc; min-height:255px; position:relative; flex:1; }
    .map-box iframe { width:100%; height:100%; min-height:255px; border:0; display:block; }
    .streetview-preview { height:255px; display:flex; flex-direction:column; justify-content:space-between; background:linear-gradient(135deg,#e8f2ff,#ffffff); padding:16px; }
    .streetview-preview h4 { font-size:18px; margin-bottom:8px; }
    .streetview-preview p { color:var(--muted); line-height:1.4; }
    .streetview-frame { flex:1; border-radius:14px; border:1px dashed rgba(15,94,168,.35); display:grid; place-items:center; text-align:center; padding:12px; margin:14px 0; color:#0f5ea8; font-weight:900; background:rgba(255,255,255,.55); }

    /* ── Onglets CSS-only ────────────────────────────────── */
    .tabs-card { padding:0; overflow:hidden; }
    .tabs-input { display:none; }
    .tabs-nav { display:flex; gap:0; overflow-x:auto; border-bottom:1px solid rgba(15,23,42,.09); background:#fff; }
    .tab-label { flex:0 0 auto; padding:15px 16px; font-weight:900; color:#475569; cursor:pointer; border-bottom:3px solid transparent; white-space:nowrap; }
    .tab-label:hover { color:var(--blue); background:#f8fafc; }
    .tabs-content { padding:18px; }
    .tab-panel { display:none; }

    #tab-resume:checked ~ .tabs-nav label[for="tab-resume"],
    #tab-notes:checked ~ .tabs-nav label[for="tab-notes"],
    #tab-rv:checked ~ .tabs-nav label[for="tab-rv"],
    #tab-soumissions:checked ~ .tabs-nav label[for="tab-soumissions"],
    #tab-factures:checked ~ .tabs-nav label[for="tab-factures"],
    #tab-services:checked ~ .tabs-nav label[for="tab-services"],
    #tab-fichiers:checked ~ .tabs-nav label[for="tab-fichiers"],
    #tab-commandes:checked ~ .tabs-nav label[for="tab-commandes"],
    #tab-communications:checked ~ .tabs-nav label[for="tab-communications"],
    /* Onglet Texto — séparé du Courriel le 2026-09-01 (décision Philippe). Ces règles ÉNUMÈRENT
       chaque onglet : en ajouter un sans l'inscrire ICI donne un onglet qui ne s'ouvre jamais et
       dont l'étiquette ne s'allume pas — sans la moindre erreur nulle part. */
    #tab-textos:checked ~ .tabs-nav label[for="tab-textos"],
    #tab-automatisations:checked ~ .tabs-nav label[for="tab-automatisations"],
    #tab-actions:checked ~ .tabs-nav label[for="tab-actions"] { color:var(--blue); border-bottom-color:var(--blue); background:#f8fafc; }

    #tab-resume:checked ~ .tabs-content #panel-resume,
    #tab-notes:checked ~ .tabs-content #panel-notes,
    #tab-rv:checked ~ .tabs-content #panel-rv,
    #tab-soumissions:checked ~ .tabs-content #panel-soumissions,
    #tab-factures:checked ~ .tabs-content #panel-factures,
    #tab-services:checked ~ .tabs-content #panel-services,
    #tab-fichiers:checked ~ .tabs-content #panel-fichiers,
    #tab-commandes:checked ~ .tabs-content #panel-commandes,
    #tab-communications:checked ~ .tabs-content #panel-communications,
    #tab-textos:checked ~ .tabs-content #panel-textos,
    #tab-automatisations:checked ~ .tabs-content #panel-automatisations,
    #tab-actions:checked ~ .tabs-content #panel-actions { display:block; }

    .panel-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
    .panel-list { display:grid; gap:11px; }
    .row-item { border-radius:14px; background:#f8fafc; border:1px solid rgba(15,23,42,.07); padding:12px; display:flex; justify-content:space-between; gap:12px; align-items:flex-start; }
    .row-item strong { display:block; margin-bottom:4px; }
    .row-item p { color:var(--muted); line-height:1.35; }
    .note-box { background:#fffbeb; border:1px solid #fde68a; color:#92400e; border-radius:14px; padding:14px; line-height:1.4; }
    .tab-panel-header { display:flex; justify-content:space-between; align-items:center; gap:12px; margin-bottom:14px; }
    .tab-panel-header h3 { font-size:18px; letter-spacing:-.02em; }
    .tab-actions { display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-end; }

    .communication-layout { display:grid; grid-template-columns:280px 1fr; gap:14px; }
    .message-list { display:grid; gap:10px; }
    .message-card { border-radius:14px; background:#f8fafc; border:1px solid rgba(15,23,42,.07); padding:12px; cursor:pointer; }
    .message-card.active,.message-card:hover { background:var(--blue-soft); color:var(--blue); }
    .message-card strong { display:block; margin-bottom:4px; }
    .message-card p { color:var(--muted); line-height:1.35; }
    .message-preview { border-radius:14px; background:#f8fafc; border:1px solid rgba(15,23,42,.07); padding:16px; min-height:220px; }
    .message-preview-header { display:flex; justify-content:space-between; gap:12px; margin-bottom:14px; padding-bottom:12px; border-bottom:1px solid rgba(15,23,42,.08); }
    .message-body { color:#334155; line-height:1.5; }

    .automation-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
    .automation-card { border-radius:14px; background:#f8fafc; border:1px solid rgba(15,23,42,.07); padding:14px; display:flex; justify-content:space-between; gap:12px; align-items:flex-start; }
    .automation-card strong { display:block; margin-bottom:5px; }
    .automation-card p { color:var(--muted); line-height:1.35; }
    .toggle { width:46px; height:26px; border-radius:999px; background:#cbd5e1; padding:3px; flex:0 0 auto; display:block; }
    .toggle::before { content:""; width:20px; height:20px; border-radius:50%; background:white; display:block; box-shadow:0 2px 6px rgba(15,23,42,.18); }
    .toggle.on { background:var(--blue); }
    .toggle.on::before { transform:translateX(20px); }

    .gray { background:#f1f5f9; color:#475569; }

    /* ── Auth pages ─────────────────────────────────────── */
    .auth-page {
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 24px;
      background: var(--bg);
    }

    .auth-card {
      width: 100%;
      max-width: 420px;
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      padding: 40px 36px 36px;
    }

    .auth-brand {
      display: flex;
      align-items: center;
      gap: 12px;
      margin-bottom: 32px;
    }

    .auth-brand-logo {
      width: 44px;
      height: 44px;
      border-radius: 13px;
      overflow: hidden;
      border: 1px solid var(--border);
      flex: 0 0 auto;
    }

    .auth-brand-logo img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }

    .auth-brand h1 {
      font-size: 18px;
      line-height: 1.1;
      letter-spacing: -0.02em;
    }

    .auth-brand p {
      font-size: 11px;
      color: var(--muted);
      margin-top: 2px;
    }

    .auth-title {
      font-size: 22px;
      font-weight: 900;
      letter-spacing: -0.03em;
      margin-bottom: 6px;
    }

    .auth-subtitle {
      color: var(--muted);
      font-size: 11.5pt;
      margin-bottom: 28px;
      line-height: 1.4;
    }

    .form-group {
      margin-bottom: 8px;
    }

    .form-label {
      display: block;
      font-weight: 800;
      /* 9pt = la taille COMPACTE, désormais le défaut de TOUT le CRM (décision Philippe
         2026-08-03 : « je voulais normaliser ça partout »). Avant, 11.5pt : seuls les modules
         portant `.form-compact` étaient à la bonne taille, les autres paraissaient énormes. */
      font-size: 9pt;
      margin-bottom: 3px;
      color: var(--text);
    }

    /* Astérisque rouge « champ obligatoire » — POINT UNIQUE, réutilisable partout
       (labels, titres de section, boutons). Usage : <span class="req">*</span>. */
    .req { color: #dc2626; font-weight: 700; }

    .form-input {
      width: 100%;
      border: 1px solid var(--border);
      border-radius: 12px;
      /* Compact par défaut (voir .form-label). Les <input>/<select> gardent leur hauteur
         uniforme de 34px juste en dessous ; seuls les <textarea> suivent ce padding. */
      font-size: 9.5pt;
      padding: 6px 8px;
      outline: none;
      background: #f8fafc;
      color: var(--text);
      transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
    }

    /* Hauteur UNIFORME (34px) des champs de recherche + selects, alignée sur la hauteur ORIGINALE des
       filtres (.color-select-trigger) → barre de filtres cohérente sur TOUTES les pages. Padding vertical
       réduit pour que le texte ne soit pas rogné (11pt ~18px dans une zone de 20px). Les <textarea>
       (hauteur libre) ne sont PAS ciblés. */
    input.form-input,
    select.form-input {
      height: 34px;
      padding-top: 6px;
      padding-bottom: 6px;
    }

    .form-input:focus {
      border-color: rgba(15, 94, 168, 0.45);
      box-shadow: 0 0 0 4px rgba(15, 94, 168, 0.08);
      background: white;
    }

    .form-input.is-invalid {
      border-color: #ef4444;
    }

    .form-error {
      margin-top: 6px;
      color: #dc2626;
      font-size: 10.5pt;
    }

    /* ─── Color Select (menus déroulants avec pastilles colorées) ────────── */
    .color-select-wrap { position: relative; display: block; }
    .color-select-wrap select.native-select { display: none !important; }

    .color-select-trigger {
      display: flex;
      align-items: center;
      gap: 6px;
      width: 100%;
      background: white;
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 5px 8px 5px 10px;
      cursor: pointer;
      font-family: inherit;
      font-size: 9.5pt;
      font-weight: 700;
      color: #334155;
      text-align: left;
      white-space: nowrap;
      height: 34px;
      box-sizing: border-box;
    }
    .color-select-trigger:hover { border-color: rgba(15,94,168,.4); background: #f8fafc; }

    /* SANS CADRE AU REPOS — pour un select posé dans une LIGNE DE LISTE (`data-color-plain`).
       Le cadre reste utile dans une barre de filtres, où le select est un champ parmi d'autres ;
       répété sur quinze lignes, il fait lire un formulaire au lieu d'une liste.
       ⚠️ `transparent` et non `border: none` : la bordure garde sa place, donc rien ne saute d'un
       pixel quand elle réapparaît au survol. */
    .color-select-wrap--plain .color-select-trigger {
      border-color: transparent;
      background: transparent;
      /* Largeur AJUSTÉE au contenu : sans cadre, un bouton pleine largeur laisse le chevron
         flotter loin de la pastille, comme s'il appartenait à la colonne d'à côté. Collé, il se
         lit comme le chevron DE ce statut. */
      width: auto;
      max-width: 100%;
      /* ⚠️ HAUTEUR LIBRE — les 34 px du select sont la hauteur d'un CHAMP DE FORMULAIRE, faite
         pour s'aligner sur les barres de filtres. Sans cadre, il ne reste qu'une pastille de
         20 px dans une boîte de 34 : ces 14 px de vide sont précisément ce qui rendait une ligne
         avec sous-statut plus haute que les autres. */
      height: auto;
      padding-top: 0;
      padding-bottom: 0;
      line-height: 1;
      /* Le retrait à gauche est partagé avec le sous-statut, qui doit s'aligner sur la pastille —
         d'où la variable : deux valeurs écrites séparément finiraient par se désaccorder. */
      padding-left: var(--cs-indent, 10px);
    }
    .color-select-wrap--plain .color-select-trigger:hover,
    .color-select-wrap--plain .color-select-trigger.is-open {
      border-color: rgba(15,94,168,.4);
      background: #fff;
    }
    /* ⚠️ Le REMBOURRAGE ne change pas entre les deux états, et c'est délibéré : le faire varier
       déplacerait la pastille sous le curseur à l'instant du survol — on cliquerait sur une cible
       qui vient de bouger. Seules la bordure et le fond apparaissent.
       Le chevron reste visible, simplement atténué : sans cadre ni chevron, un statut modifiable
       serait indiscernable d'un badge en lecture seule (c'est précisément ce que sont les badges
       de statut des Factures). C'est lui qui porte l'invitation à cliquer. */
    .color-select-wrap--plain .cs-caret { opacity: .4; transition: opacity .12s; }
    .color-select-wrap--plain .color-select-trigger:hover .cs-caret,
    .color-select-wrap--plain .color-select-trigger.is-open .cs-caret { opacity: 1; }
    .color-select-trigger.is-open {
      border-color: rgba(15,94,168,.6);
      box-shadow: 0 0 0 3px rgba(15,94,168,.08);
    }
    .cs-caret {
      width: 14px; height: 14px;
      stroke: #94a3b8; fill: none;
      stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
      flex-shrink: 0; margin-left: auto;
      transition: transform .15s; display: block;
    }
    .color-select-trigger.is-open .cs-caret { transform: rotate(180deg); }

    /* ⚠️ `position: fixed`, PAS `absolute` — sinon le menu est DÉCOUPÉ par le premier ancêtre à
       `overflow: hidden` (bug vécu, mesuré sur /pipeline : `.pl-list` coupait 367 px des 375 du
       menu — il n'en restait que 8, soit une lamelle de deux statuts). Le même défaut guettait
       toute carte à coins arrondis, puisque l'arrondi EXIGE l'`overflow: hidden`.
       Le placement (et le retournement vers le haut quand le bas manque) est délégué au POINT
       UNIQUE `MphMenu.place()` — le même que les menus « Actions ▾ » des listes. */
    .color-select-dropdown {
      display: none;
      position: fixed;
      background: white;
      border: 1px solid var(--border);
      border-radius: 12px;
      box-shadow: 0 8px 24px rgba(0,0,0,.12);
      padding: 6px;
      z-index: 600;
      max-height: 400px;
      overflow-y: auto;
    }
    /* `block` et non `grid` : `MphMenu.place()` mesure le menu en `display:block` pour choisir son
       côté — un `gap` de grille ajouté APRÈS la mesure le ferait déborder de ce qu'on vient de
       calculer. L'écart entre options passe donc par une marge, qui, elle, est mesurée. */
    .color-select-dropdown.is-open { display: block; }
    .cs-option + .cs-option { margin-top: 2px; }

    .cs-option {
      display: flex;
      align-items: center;
      padding: 4px 6px;
      border-radius: 8px;
      cursor: pointer;
      transition: background .1s;
    }
    .cs-option:hover { background: var(--blue-soft); }
    .cs-option.is-selected { background: #f1f5f9; }
    .cs-option.is-disabled { opacity: .5; cursor: default; }

    .cs-pill {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      padding: 3px 10px 3px 7px;
      border-radius: 999px;
      font-size: 9pt;
      font-weight: 700;
      white-space: nowrap;
      line-height: 1.4;
    }
    .cs-dot {
      width: 7px; height: 7px;
      border-radius: 50%;
      flex-shrink: 0;
      display: inline-block;
    }
    .cs-plain {
      font-size: 9pt;
      font-weight: 700;
      color: #64748b;
    }

    /* Étape (stage) — rectangle avec bordure gauche colorée, distinct de la pilule statut */
    .cs-stage {
      display: inline-flex;
      align-items: center;
      padding: 3px 10px 3px 8px;
      border-radius: 5px;
      font-size: 9pt;
      font-weight: 700;
      white-space: nowrap;
      line-height: 1.4;
    }

    /* ─── Info-tip : pastille « i » discrète + bulle blanche (survol desktop + focus/tap mobile) ─── */
    .info-tip {
      position: relative;
      display: inline-flex;
      align-items: center;
      background: none; border: 0; padding: 0;
      font-family: inherit; font-size: 9pt; font-weight: 700;
      color: var(--blue);
      cursor: pointer;
      text-decoration: underline; text-underline-offset: 2px;
      flex-shrink: 0; vertical-align: middle;
      transition: color .15s ease;
    }
    .info-tip:hover, .info-tip:focus, .info-tip:focus-visible {
      color: #0b4a85; outline: none;
    }

    .info-tip-bubble {
      position: absolute;
      top: calc(100% + 11px);
      left: -4px;
      width: 340px; max-width: 84vw;
      background: #fff; color: #475569;
      font-size: 9pt; font-weight: 400; line-height: 1.6;
      font-family: inherit;
      text-align: left;
      padding: 14px 16px;
      border: 1px solid #e2e8f0;
      border-radius: 12px;
      box-shadow: 0 14px 38px rgba(15, 23, 42, .16);
      opacity: 0; visibility: hidden; transform: translateY(-4px);
      transition: opacity .16s ease, visibility .16s ease, transform .16s ease;
      z-index: 1000; white-space: normal; pointer-events: none;
    }
    .info-tip-bubble::before {
      content: ''; position: absolute; bottom: 100%; left: 12px;
      width: 12px; height: 12px; background: #fff;
      border-left: 1px solid #e2e8f0; border-top: 1px solid #e2e8f0;
      transform: translateY(50%) rotate(45deg);
    }
    .info-tip-title {
      display: block; font-size: 8pt; font-weight: 800; letter-spacing: .04em;
      text-transform: uppercase; color: var(--blue); margin-bottom: 7px;
    }
    .info-tip-bubble strong { color: #0f172a; font-weight: 700; }
    .info-tip-warn {
      display: block; margin-top: 11px;
      background: #fffbeb; border: 1px solid #fde68a; border-radius: 9px;
      padding: 9px 11px; color: #92400e; font-size: 8.5pt; line-height: 1.5;
    }
    .info-tip-warn strong { color: #92400e; }
    .info-tip:hover .info-tip-bubble,
    .info-tip:focus .info-tip-bubble,
    .info-tip:focus-visible .info-tip-bubble {
      opacity: 1; visibility: visible; transform: translateY(0);
    }
    @media (max-width: 640px) {
      .info-tip-bubble { left: auto; right: -4px; }
      .info-tip-bubble::before { left: auto; right: 12px; }
    }

    .form-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      margin-top: 24px;
    }

    .form-check {
      display: flex;
      align-items: center;
      gap: 8px;
      cursor: pointer;
      font-size: 11pt;
      color: var(--muted);
    }

    .form-check input[type="checkbox"] {
      width: 16px;
      height: 16px;
      cursor: pointer;
      accent-color: var(--blue);
    }

    .auth-link {
      color: var(--blue);
      text-decoration: none;
      font-weight: 800;
      font-size: 11pt;
    }

    .auth-link:hover {
      text-decoration: underline;
    }

    .auth-alert {
      padding: 12px 15px;
      border-radius: 12px;
      margin-bottom: 18px;
      font-size: 11pt;
      line-height: 1.4;
    }

    .auth-alert-success {
      background: #dcfce7;
      color: #166534;
      border: 1px solid #bbf7d0;
    }

    .btn-auth {
      width: 100%;
      justify-content: center;
      border-radius: 12px;
      padding: 13px;
      font-size: 12pt;
    }

    /* ───────────────────────────────────────────────────── */

    @media (max-width: 1200px) {
      .dashboard-grid { grid-template-columns: 1fr 1fr; }
      .client-main-grid,.panel-grid { grid-template-columns: 1fr; }
      .map-grid { grid-template-columns: 1fr; }
    }

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

      .mobile-menu-btn {
        display: inline-flex;
      }

      .mobile-close {
        display: flex;
      }

      .mobile-overlay {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, 0.38);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.18s ease;
        z-index: 80;
      }

      .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: min(86vw, 320px);
        height: 100vh;
        z-index: 90;
        border-right: 1px solid var(--border);
        border-bottom: 0;
        transform: translateX(-105%);
        transition: transform 0.22s ease;
        box-shadow: 20px 0 55px rgba(15, 23, 42, 0.22);
      }

      .mobile-menu-checkbox:checked ~ .app-shell .sidebar {
        transform: translateX(0);
      }

      .mobile-menu-checkbox:checked ~ .mobile-overlay {
        opacity: 1;
        pointer-events: auto;
      }

      /* Tiroir mobile : on retrouve une vraie zone de doigt et on laisse le menu défiler —
         un tiroir plein écran qui glisse est normal, la règle « sans défilement » vise
         l'écran d'ordinateur, où le menu est là en permanence. */
      .nav-item {
        flex: 0 0 auto;
        min-height: 44px;
        padding: 0 12px;
      }

      .mobile-topbar {
        display: flex;
        align-items: center;
        padding: 10px 14px;
        background: rgba(255, 255, 255, 0.95);
        border-bottom: 1px solid var(--border);
        position: sticky;
        top: 0;
        z-index: 50;
        backdrop-filter: blur(10px);
      }

      /* Marque dans la barre mobile : sur téléphone la barre latérale est repliée, donc le logo
         n'apparaît nulle part tant qu'on n'ouvre pas le menu. Poussée à droite (le bouton Menu
         garde la gauche, là où le pouce le cherche). */
      .mobile-brand {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-left: auto;
        text-decoration: none;
        color: #1e293b;
        font-weight: 800;
        font-size: 13px;
        letter-spacing: -0.01em;
      }

      .mobile-brand img {
        display: block;
        width: 28px;
        height: 28px;
        border-radius: 8px;
        object-fit: cover;
        border: 1px solid var(--border);
      }

      .global-search {
        max-width: none;
      }

      .dropdown-menu {
        left: 0;
        right: auto;
        width: min(100%, 280px);
      }

      .page {
        padding: 18px 14px;
      }

      .page-header {
        flex-direction: column;
        gap: 12px;
      }

      .page-title h2 {
        font-size: 26px;
      }

      /* Sous cette largeur, côte à côte ne laisse de place ni au titre ni à la description :
         on repasse en colonne, comme avant la mise sur une ligne. */
      .page-title {
        flex-direction: column;
        gap: 3px;
      }

      .page-actions {
        justify-content: flex-start;
        width: 100%;
        display: grid;
        grid-template-columns: 1fr 1fr;
      }

      .page-actions .btn {
        justify-content: center;
      }

      .dashboard-grid,
      .quick-actions-grid {
        grid-template-columns: 1fr;
      }

      .dashboard-grid {
        gap: 14px;
      }

      .dashboard-column {
        gap: 14px;
      }

      .card {
        border-radius: 16px;
        padding: 15px;
      }

      .list-item {
        flex-direction: column;
        gap: 8px;
      }

      .widget-footer {
        align-items: flex-start;
        flex-direction: column;
      }

      .mini-table { display: block; overflow-x: auto; white-space: nowrap; }
      .client-header { grid-template-columns: 1fr; }
      .client-actions { justify-content: flex-start; }
      .info-grid { grid-template-columns: 1fr; }
      .client-title-line h2 { font-size: 26px; }
      .tabs-content { padding: 14px; }
      .row-item { flex-direction: column; }
      .communication-layout,.automation-grid { grid-template-columns: 1fr; }
      .tab-panel-header { align-items: flex-start; flex-direction: column; }
      .tab-actions { width: 100%; display: grid; grid-template-columns: 1fr; }
      .tab-actions .btn { justify-content: center; }
      .message-preview-header { flex-direction: column; }
    }

/* ── Surlignage des lignes nouvellement créées / dupliquées ──────────
   Utilisé par toutes les listes après une duplication ou une création :
   le contrôleur fait back()->with('new_xxx_ids', [...]) et la vue ajoute
   la classe .row-new-highlight aux lignes concernées (fond vert qui s'estompe). */
.row-new-highlight {
    background: #f0fdf4;
    animation: fadeHighlight 4s ease forwards;
}
@keyframes fadeHighlight {
    0%   { background: #bbf7d0; }
    100% { background: #f0fdf4; }
}

/* ── Disposition d'une ligne de soumission / produit ─────────────────
   Ligne 1 : [Type] [Note optionnelle]    ·    Ligne 2 : [Description (large)] [Prix]
   Utilisé par _line.blade.php (produit) et _line-row.blade.php (soumission). */
.line-head { display: flex; gap: 10px; align-items: flex-end; margin-bottom: 8px; }
.line-head-type { width: 150px; flex-shrink: 0; }
.line-head-note { flex: 1; min-width: 0; }
.line-body { display: grid; grid-template-columns: 1fr 360px; gap: 10px; align-items: stretch; }
/* Chaque colonne est une sous-grille [label auto] + [boîte 1fr] ; un label invisible au-dessus
   de la boîte prix compense le label « Description ». */
.line-body .line-desc,
.line-body .line-price-col { display: grid; grid-template-rows: auto 1fr; }
.line-body .line-desc .line-desc-input,
.line-body .line-price-col .line-price-box { min-height: 0; }
/* La description fait la hauteur de SON TEXTE, pas celle de la boîte prix (décision Philippe) :
   deux lignes de texte dans une boîte calée sur la colonne prix laissaient un grand vide.
   `align-self: start` est ce qui le permet — sans lui la grille étire le textarea, et l'auto-hauteur
   de `partials/_autogrow` se mesure elle-même : elle pose height:auto pour mesurer, la grille
   l'étire aussitôt à la hauteur de la colonne, et scrollHeight renvoie cette hauteur-là (vécu).
   La hauteur réelle est ensuite posée en ligne par ce partial ; `rows` n'est que le plancher. */
.line-body .line-desc .line-desc-input { height: auto; align-self: start; box-sizing: border-box; }
/* Travail du CATALOGUE : sa composition se pose SOUS la description (colonne de gauche, décision
   Philippe — sous les coûts internes elle allongeait une ligne déjà haute). Les rangées repassent en
   `auto` : sans ça, la rangée du textarea garde le `1fr` et pousse la composition tout en bas, laissant
   un grand vide au milieu. */
.line-body .line-desc-recipe { grid-template-rows: auto auto; align-content: start; }
/* Petit libellé au-dessus d'un champ (style premium de la boîte prix) */
.line-field-label { font-size: 7.5pt; letter-spacing: .6px; text-transform: uppercase; color: #94a3b8; font-weight: 700; margin-bottom: 3px; }
@media (max-width: 820px) {
    .line-head { flex-wrap: wrap; }
    .line-head-note { flex: 1 1 100%; }
    .line-body { grid-template-columns: 1fr; }
}
/* Poignée de glisser-déposer des lignes */
.drag-handle { cursor: grab; color: #94a3b8; user-select: none; font-size: 16px; line-height: 1; padding: 2px 6px 2px 0; flex-shrink: 0; align-self: flex-end; margin-bottom: 2px; }
.drag-handle:active { cursor: grabbing; }
/* Bouton réduire/développer une ligne */
.line-collapse-btn { background: none; border: 1px solid var(--border); border-radius: 6px; padding: 3px 8px; font-size: 10px; color: #94a3b8; cursor: pointer; flex-shrink: 0; line-height: 1.4; align-self: flex-end; margin-bottom: 1px; }
.line-collapse-btn:hover { background: #f1f5f9; color: #475569; }
/* Ligne réduite : cache le corps, montre le résumé */
.q-line-row.is-collapsed .line-body,
.quote-line-row.is-collapsed .line-body { display: none !important; }
/* Barre résumé (visible seulement quand réduit) */
.line-summary-bar { display: none; align-items: center; gap: 12px; padding: 4px 0 2px; overflow: hidden; }
.q-line-row.is-collapsed .line-summary-bar,
.quote-line-row.is-collapsed .line-summary-bar { display: flex; }
.line-summary-desc { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #64748b; font-size: 9pt; }
.line-summary-total { font-weight: 700; color: #0f172a; font-size: 10pt; white-space: nowrap; }
/* ── Tableau de bord Soumissions (quotes/dashboard) ──────────────── */
.qd-period { display: inline-flex; flex-wrap: wrap; gap: 4px; background: #f1f5f9; border: 1px solid var(--border); border-radius: 10px; padding: 4px; }
.qd-period a, .qd-period button { padding: 6px 14px; border: none; background: none; border-radius: 7px; font-size: 9.5pt; font-weight: 600; color: var(--muted); text-decoration: none; cursor: pointer; font-family: inherit; transition: all .15s; }
.qd-period a:hover, .qd-period button:hover { color: var(--blue); }
.qd-period a.active, .qd-period button.active { background: #fff; color: var(--blue); box-shadow: 0 1px 3px rgba(0,0,0,.10); }

/* Dropdowns Mois / Année de la barre de période (partials/_period-bar) */
.pb-dd { position: relative; display: inline-flex; }
/* `fixed` + `data-mph-anchor` : en `absolute`, ces menus étaient rognés dès que la barre de période
   vivait dans une carte à `overflow:hidden`. Placement par MphMenu (POINT UNIQUE). */
.pb-dd-menu { display: none; position: fixed; flex-direction: column; gap: 2px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.13);
  padding: 4px; z-index: 600; min-width: 130px; }
.pb-dd-menu.open { display: flex; }
.pb-dd-menu button { padding: 6px 12px; border: 0; background: none; border-radius: 7px; text-align: left; white-space: nowrap;
  font-size: 9.5pt; font-weight: 600; color: var(--muted); cursor: pointer; font-family: inherit; width: 100%; }
.pb-dd-menu button:hover { background: var(--blue-soft); color: var(--blue); }
.pb-dd-menu button.active { background: #f1f5f9; color: var(--blue); }
.pb-custom { align-items: center; gap: 6px; }

.qd-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 18px; }
/* Variante 5 colonnes (dashboard Facture = 10 cartes → exactement 2 lignes sur grand écran).
   Gagne sur le `repeat(4)` de base (déclarée après) ; en dessous de 1400px les media queries
   partagées `.qd-kpis` reprennent la main (4 → 2 → 1 col) — donc responsive préservé. */
.qd-kpis--5 { grid-template-columns: repeat(5, 1fr); }
.qd-kpi { position: relative; overflow: hidden; border-radius: 14px; padding: 13px 15px; color: #fff; box-shadow: 0 5px 14px rgba(0,0,0,.10); transition: transform .12s, box-shadow .12s; display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
a.qd-kpi { text-decoration: none; color: #fff; cursor: pointer; }
a.qd-kpi:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(0,0,0,.16); }
.qd-kpi.is-active { box-shadow: 0 0 0 3px #0f172a, 0 8px 22px rgba(0,0,0,.18); }
.qd-kpi-main { min-width: 0; }
.qd-kpi-icon { flex: 0 0 auto; opacity: .5; margin-top: 1px; }
.qd-kpi-icon svg { width: 24px; height: 24px; display: block; }
.qd-kpi-value { font-size: 25px; font-weight: 900; line-height: 1.05; letter-spacing: -.5px; }
.qd-kpi-label { font-size: 9.5pt; font-weight: 700; opacity: .95; margin-top: 3px; }
.qd-kpi-sub { font-size: 8pt; opacity: .82; margin-top: 2px; }
.qd-kpi-warn { display: inline-flex; align-items: center; gap: 4px; margin-top: 6px; font-size: 8pt; font-weight: 700; background: rgba(255,255,255,.22); padding: 3px 8px; border-radius: 7px; }
.qd-kpi-warn svg { width: 12px; height: 12px; flex: 0 0 auto; }
.qd-kpi-sellers { margin-top: 8px; padding-top: 7px; border-top: 1px solid rgba(255,255,255,.22); display: grid; gap: 3px; }
.qd-kpi-seller-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 8pt; }
.qd-kpi-seller-name { opacity: .9; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.qd-kpi-seller-val { font-weight: 800; white-space: nowrap; flex-shrink: 0; }
.qd-kpi--green  { background: linear-gradient(135deg, #16a34a, #0f7a37); }
.qd-kpi--blue   { background: linear-gradient(135deg, #2563eb, #1d4ed8); }
.qd-kpi--amber  { background: linear-gradient(135deg, #f59e0b, #d97706); }
.qd-kpi--violet { background: linear-gradient(135deg, #7c3aed, #6d28d9); }
.qd-kpi--red    { background: linear-gradient(135deg, #ef4444, #dc2626); }
.qd-kpi--teal   { background: linear-gradient(135deg, #0d9488, #0f766e); }
.qd-kpi--rose   { background: linear-gradient(135deg, #e11d48, #9f1239); }
.qd-kpi--slate  { background: linear-gradient(135deg, #64748b, #475569); }
.qd-kpi--yellow { background: linear-gradient(135deg, #eab308, #ca8a04); }
.qd-kpi--cyan    { background: linear-gradient(135deg, #06b6d4, #0891b2); }
.qd-kpi--fuchsia { background: linear-gradient(135deg, #d946ef, #a21caf); }

/* Liste détaillée du dashboard : accordéon par client + soumissions (statut modifiable) */
.qd-client { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: #fff; }
.qd-client-head { display: flex; align-items: center; gap: 12px; padding: 10px 14px; cursor: pointer; background: #f8fafc; transition: background .12s; }
.qd-client-head:hover { background: #f1f5f9; }
.qd-client-chevron { flex: 0 0 auto; color: var(--muted); font-size: 11px; transition: transform .15s; }
.qd-client.open .qd-client-chevron { transform: rotate(90deg); }
.qd-client-name { font-size: 10pt; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qd-client-addr { font-size: 9pt; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qd-client-body { display: none; padding: 2px 12px 8px; }
.qd-client.open .qd-client-body { display: block; }
.qd-quote-row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-top: 1px solid var(--border); }
.qd-quote-num { flex: 0 0 auto; font-weight: 800; font-size: 9.5pt; color: var(--blue); text-decoration: none; white-space: nowrap; }
.qd-quote-num:hover { text-decoration: underline; }
.qd-quote-title { flex: 1; min-width: 0; font-size: 9.5pt; color: #475569; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qd-quote-status { flex: 0 0 auto; width: auto; min-width: 150px; font-size: 9pt; padding: 5px 8px; }
.qd-quote-reason { margin: 2px 4px 8px 4px; padding: 9px 12px; background: #fef2f2; border: 1px solid #fecaca; border-left: 3px solid #dc2626; border-radius: 8px; font-size: 9pt; line-height: 1.5; color: #7f1d1d; white-space: pre-wrap; }
.qd-quote-reason-label { display: block; font-size: 8pt; font-weight: 800; letter-spacing: .3px; color: #dc2626; margin-bottom: 3px; text-transform: uppercase; }
.qd-quote-reason--wait { background: #f8fafc; border-color: #e2e8f0; border-left-color: #64748b; color: #334155; }
.qd-quote-reason--wait .qd-quote-reason-label { color: #475569; }

/* ── Réglages des relances (Admin → Automatisations → Relances) ── */
.rem-head { display: flex; align-items: flex-start; gap: 14px; }
.rem-head-icon { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--blue-soft); color: var(--blue); }
.rem-head-icon svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.rem-head-text { flex: 1; min-width: 0; }
.rem-head-text h3 { margin: 0 0 4px; font-size: 13pt; font-weight: 800; color: #0f172a; }
.rem-head-text p { margin: 0; font-size: 9pt; color: var(--muted); line-height: 1.55; }
/* INTERRUPTEUR — POINT UNIQUE de tout le CRM (règle 14).
   Il n'existait que sous le nom `rem-switch`, dans la feuille des relances : la page des préférences de
   notification en avait besoin, et un second interrupteur aurait dérivé (taille, couleur, animation).
   `.rem-switch` reste un alias pour ne pas toucher aux trois pages qui l'employaient déjà. */
.mph-switch, .rem-switch { position: relative; display: inline-block; width: 46px; height: 26px; flex: 0 0 auto; cursor: pointer; }
.rem-switch { margin-top: 4px; }
.mph-switch input, .rem-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.mph-switch .mph-slider, .rem-switch .rem-slider { position: absolute; inset: 0; background: #cbd5e1; border-radius: 999px; transition: background .2s; }
.mph-switch .mph-slider::before, .rem-switch .rem-slider::before { content: ""; position: absolute; height: 20px; width: 20px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.25); }
/* ALLUMÉ = LE BLEU MPH, partout et sans exception (décision Philippe).
   Les interrupteurs de la page Paramètres portaient la couleur de leur module : neuf teintes pour dire
   la même chose — « c'est activé ». La couleur du module reste là où elle informe (le liseré et l'icône
   de la ligne) ; l'interrupteur, lui, ne dit qu'un état, donc une seule couleur.
   `var(--blue)` et non un hex : la couleur principale est réglable dans Admin → Apparence ({@see Theme}). */
.mph-switch input:checked + .mph-slider, .rem-switch input:checked + .rem-slider { background: var(--blue); }
.mph-switch input:checked + .mph-slider::before, .rem-switch input:checked + .rem-slider::before { transform: translateX(20px); }
.mph-switch input:focus-visible + .mph-slider, .rem-switch input:focus-visible + .rem-slider { outline: 2px solid var(--blue); outline-offset: 2px; }
.rem-steps { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; transition: opacity .2s; }
.rem-steps.rem-disabled { opacity: .45; }
.rem-step { display: flex; align-items: center; gap: 14px; padding: 13px 16px; border: 1px solid var(--border); border-radius: 12px; background: #f8fafc; }
.rem-step-badge { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--blue); color: #fff; font-weight: 800; font-size: 10pt; }
.rem-step-label { flex: 1; min-width: 0; }
.rem-step-label .t { font-weight: 700; font-size: 10.5pt; color: #0f172a; }
.rem-step-label .s { font-size: 8.5pt; color: var(--muted); margin-top: 1px; }
.rem-input-group { display: flex; align-items: stretch; flex: 0 0 auto; }
.rem-input-group input.form-input { width: 76px; text-align: center; font-weight: 700; border-radius: 9px 0 0 9px; border-right: none; }
.rem-input-group .unit { display: grid; place-items: center; padding: 0 13px; background: #eef2f7; border: 1px solid var(--border); border-left: none; border-radius: 0 9px 9px 0; font-size: 9pt; color: #475569; font-weight: 600; white-space: nowrap; }
@media (max-width: 540px) {
    .rem-step { flex-wrap: wrap; }
    .rem-step-label { flex: 1 1 60%; }
    .rem-input-group { margin-left: auto; }
}

.qd-accepted-row { display: flex; align-items: center; gap: 12px; padding: 11px 14px; border-radius: 10px; background: #f8fafc; border: 1px solid var(--border); border-left: 4px solid #16a34a; text-decoration: none; color: inherit; transition: background .15s; }
.qd-accepted-row:hover { background: #eef6f0; }
.qd-accepted-num { font-weight: 800; font-size: 10pt; color: var(--blue); white-space: nowrap; }
.qd-accepted-amount { font-weight: 900; font-size: 12pt; color: #16a34a; white-space: nowrap; }

/* BARRE DE PROGRESSION — POINT UNIQUE du CRM (classement, objectifs, répartitions).
   ⚠️ La largeur se borne EN BAS autant qu'en haut : `max(0, min(100, $pct))`. Les lignes du CRM
   acceptent des montants NÉGATIFS (rabais, crédits) ; `width:-14%` est une déclaration invalide que le
   navigateur IGNORE, et le div retombe alors sur `width:auto` — soit TOUT le rail. Vécu au module
   Statistiques : la pire performance s'affichait en barre pleine, l'inverse du chiffre écrit à côté. */
.qd-bar-track { flex: 1; height: 10px; background: #eef2f7; border-radius: 999px; overflow: hidden; }
.qd-bar-fill { height: 100%; border-radius: 999px; transition: width .3s ease; }

/* ── Module Statistiques de vente ─────────────────────────────────────────────────────
   Histogramme mensuel en CSS pur : aucune bibliothèque de graphiques n'est chargée dans le CRM,
   et en ajouter une pour douze colonnes ferait entrer un CDN (interdit) ou 60 Ko de JS pour ce
   qu'un `height:%` fait déjà. Les barres HORIZONTALES, elles, réutilisent `.qd-bar-track` /
   `.qd-bar-fill` du tableau de bord des soumissions — POINT UNIQUE, pas une seconde barre.  */
.ss-scroll { overflow-x: auto; }
.ss-chart { display: flex; align-items: flex-end; gap: 10px; min-width: 620px; height: 200px; padding: 6px 2px 0; }
/* ⚠️ `height: 100%` INDISPENSABLE (défaut vécu, histogramme plat dans DEUX modules). `.ss-chart`
   aligne ses colonnes en `flex-end`, donc elles ne s'étirent PAS : la colonne prenait la hauteur de
   son contenu, `.ss-bars { flex: 1 }` n'avait alors aucune hauteur définie à remplir, et le
   `height: 84%` d'une barre se résolvait contre « auto » — c'est-à-dire rien. Toutes les barres
   tombaient à leur `min-height` de 2 px, y compris celles à 100 %. Le balisage et les pourcentages
   calculés étaient parfaitement justes : rien à trouver en relisant le PHP. */
.ss-col { flex: 1 1 0; height: 100%; display: flex; flex-direction: column; align-items: center; gap: 7px; min-width: 0; }
.ss-bars { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; gap: 3px; }
.ss-bar { flex: 1 1 0; max-width: 15px; border-radius: 4px 4px 0 0; min-height: 2px; transition: height .3s ease; }
.ss-bar--vendu   { background: linear-gradient(180deg, #22c55e, #15803d); }
.ss-bar--facture { background: linear-gradient(180deg, #3b82f6, #1d4ed8); }
.ss-bar--paye    { background: linear-gradient(180deg, #a78bfa, #6d28d9); }
.ss-col-label { font-size: 7.5pt; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .3px; white-space: nowrap; }
.ss-col--now .ss-col-label { color: var(--blue); }
.ss-legend { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; font-size: 8.5pt; color: var(--muted); }
.ss-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; font-style: normal; }

/* Ligne d'un objectif : la barre de progression + le REPÈRE du temps écoulé. Le repère est ce qui
   rend la barre lisible — 60 % au 10 du mois et 60 % au 28 ne racontent pas la même chose.

   ⚠️ La barre elle-même reste `.qd-bar-track` / `.qd-bar-fill` (le POINT UNIQUE du CRM) : cette classe
   ne fait que l'ADAPTER. Elle en avait d'abord recopié le fond et l'arrondi — quatre lignes sous le
   commentaire qui jurait le contraire — et une future retouche du style de barre n'en aurait touché
   qu'une des deux. `overflow:visible` est nécessaire ici, et seulement ici : le repère dépasse
   volontairement du rail, et l'`overflow:hidden` de `.qd-bar-track` le rognerait. */
.ss-goal-track { position: relative; height: 12px; overflow: visible; }
.ss-goal-mark { position: absolute; top: -4px; bottom: -4px; width: 2px; background: #0f172a; opacity: .5; border-radius: 2px; }

/* Ventilation vente / service : une seule barre empilée, plus lisible que deux camemberts. */
.ss-split { display: flex; height: 26px; border-radius: 8px; overflow: hidden; background: #eef2f7; }
.ss-split span { display: grid; place-items: center; font-size: 8pt; font-weight: 800; color: #fff; white-space: nowrap; overflow: hidden; transition: width .3s ease; }

@media (max-width: 1400px) {
    .qd-kpis { grid-template-columns: repeat(4, 1fr); }
}
@media (max-width: 900px) {
    .qd-kpis { grid-template-columns: 1fr 1fr; }
    .qd-two-col { grid-template-columns: 1fr !important; }
}
@media (max-width: 520px) {
    .qd-kpis { grid-template-columns: 1fr; }
}

/* ── Onglet Fichiers (fiche client) ──────────────────────────────── */
.cf-folder { border:1px solid var(--border); border-radius:10px; overflow:hidden; background:#fff; margin-bottom:6px; }
.cf-folder-head { width:100%; display:flex; align-items:center; gap:10px; padding:7px 11px; background:#f8fafc; border:0; cursor:pointer; text-align:left; font:inherit; }
.cf-folder-head:hover { background:#f1f5f9; }
.cf-folder-ico { display:grid; place-items:center; width:26px; height:26px; border-radius:8px; flex:0 0 auto; }
.cf-folder-ico svg { width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; display:block; }
.cf-folder-name { font-weight:800; color:#1e293b; flex:0 1 auto; font-size:10pt; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cf-count { background:#e2e8f0; color:#475569; border-radius:999px; padding:1px 9px; font-size:8.5pt; font-weight:800; flex:0 0 auto; }
.cf-chevron { color:#94a3b8; transition:transform .2s; flex:0 0 auto; font-size:10pt; margin-left:auto; }
.cf-folder.open .cf-chevron { transform:rotate(180deg); }
.cf-folder-body { display:none; padding:5px 6px 8px 30px; }
.cf-folder.open .cf-folder-body { display:block; }
.cf-empty { color:var(--muted); font-size:9pt; padding:6px 10px; }

.cf-file { display:flex; align-items:center; gap:10px; padding:5px 8px; border-radius:8px; background:#f8fafc; border:1px solid var(--border); margin-bottom:4px; }
.cf-file:last-child { margin-bottom:0; }
.cf-file:hover { background:#f1f5f9; }
.cf-file-ico { display:grid; place-items:center; width:30px; height:30px; border-radius:7px; background:#eef2f7; color:#475569; font-size:6.5pt; font-weight:900; letter-spacing:.3px; flex:0 0 auto; text-decoration:none; }
a.cf-file-ico { cursor:pointer; }
.cf-file-main { flex:1; min-width:0; }
.cf-file-name { font-weight:700; color:#1e293b; text-decoration:none; display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-size:9.5pt; }
.cf-file-name:hover { color:var(--blue); text-decoration:underline; }
.cf-file-meta { font-size:8pt; color:var(--muted); margin-top:1px; }
.cf-file-actions { display:flex; gap:6px; flex:0 0 auto; }

/* Pastilles de type de fichier */
.cf-ext-pdf { background:#fee2e2; color:#dc2626; }
.cf-ext-jpg, .cf-ext-jpeg, .cf-ext-png, .cf-ext-gif, .cf-ext-webp, .cf-ext-heic { background:#dcfce7; color:#16a34a; }
.cf-ext-doc, .cf-ext-docx { background:#dbeafe; color:#2563eb; }
.cf-ext-xls, .cf-ext-xlsx, .cf-ext-csv { background:#dcfce7; color:#15803d; }

/* Jeton de fichier sélectionné (modale de téléversement) */
.cf-chip { display:flex; align-items:center; gap:6px; background:#f1f5f9; border:1px solid var(--border); border-radius:6px; padding:4px 10px; font-size:9pt; }
.cf-chip button { background:none; border:none; color:#dc2626; cursor:pointer; font-size:11px; padding:0 2px; }
#cf-drop { transition:border-color .15s, background .15s, box-shadow .15s; }
#cf-drop > * { pointer-events:none; } /* évite le scintillement dragleave sur les enfants */
#cf-drop.drag { border-color:#2563eb !important; background:#dbeafe !important; box-shadow:inset 0 0 0 3px rgba(37,99,235,.18); }
#cf-drop.drag * { color:#1d4ed8 !important; }
.cf-cam-row { display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; }
.cf-cam-row .btn { flex:1 1 auto; min-width:150px; justify-content:center; }

/* Visionneuse photo (lightbox) */
#photo-viewer { position:fixed; inset:0; background:rgba(15,23,42,.94); z-index:1100; display:none; align-items:center; justify-content:center; }
#pv-img { max-width:92vw; max-height:86vh; border-radius:8px; box-shadow:0 10px 40px rgba(0,0,0,.5); user-select:none; }
.pv-btn { position:absolute; background:rgba(255,255,255,.12); color:#fff; border:0; cursor:pointer; display:grid; place-items:center; border-radius:999px; transition:background .15s; }
.pv-btn:hover { background:rgba(255,255,255,.25); }
.pv-prev, .pv-next { top:50%; transform:translateY(-50%); width:48px; height:48px; font-size:30px; line-height:1; }
.pv-prev { left:18px; } .pv-next { right:18px; }
.pv-close { top:16px; right:18px; width:40px; height:40px; font-size:24px; line-height:1; }
.pv-caption { position:absolute; bottom:18px; left:0; right:0; text-align:center; color:#e2e8f0; font-size:10pt; font-weight:600; padding:0 70px; }

@media (max-width:600px) {
    .cf-file { flex-wrap:wrap; }
    .cf-file-actions { flex:1 1 100%; justify-content:flex-end; }
    .pv-prev { left:6px; } .pv-next { right:6px; }
}

/* ═══════════════════════════════════════════════════════════════
   PIPELINE — Barre de filtres
   ═══════════════════════════════════════════════════════════════ */

.pl-filter-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

/* ⚠️ MÊME FACTURE QUE LES AUTRES MODULES (décision Philippe, 2026-08-14). C'était un interrupteur
   segmenté maison — fond gris, pastille blanche active — qui ne ressemblait à aucun autre écran :
   soumissions, factures et facture fournisseur utilisent tous `btn btn-primary` / `btn btn-white`
   dans une carte. Un module qui invente son propre style oblige l'œil à réapprendre à chaque page. */
.pl-tabs {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    flex-shrink: 0;
}

.pl-filter-select {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 9pt;
    color: #334155;
    background: #fff;
    cursor: pointer;
    height: 34px;
}
.pl-filter-select:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(14,90,168,.1); }

.pl-filter-clear {
    font-size: 8.5pt;
    color: #ef4444;
    text-decoration: none;
    padding: 6px 10px;
    border: 1px solid #fecaca;
    border-radius: 8px;
    background: #fef2f2;
    font-weight: 600;
    white-space: nowrap;
}
.pl-filter-clear:hover { background: #fee2e2; }

/* ═══════════════════════════════════════════════════════════════
   PIPELINE — Liste
   ═══════════════════════════════════════════════════════════════ */

.pl-list {
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    background: #fff;
}

.pl-list-header,
.pl-row {
    display: grid;
    /**
     * ⚠️ DEUX COLONNES ÉTAIENT TROP ÉTROITES POUR LEUR CONTENU (mesuré, pas estimé) :
     *
     *   — « Activité » : 80 px pour « il y a 15 heures ». Elle débordait sur le Statut.
     *     Corrigé à 110 px ET par un format court dans la vue (« il y a 15 h »).
     *   — « Actions » : 76 px pour TROIS boutons de 28 px plus les gouttières et le rembourrage,
     *     soit 114 px nécessaires. Avec `justify-content: flex-end`, le débordement partait vers la
     *     GAUCHE : le bouton « Appeler » se dessinait 28 px hors de sa colonne, par-dessus le menu de
     *     statut. `scrollWidth` ne le signalait même pas — il a fallu comparer les positions réelles.
     *
     * Toute action ajoutée à la ligne exige de recompter cette largeur.
     */
    /* 9 colonnes : case · nom · contact · type · origine · assigné · activité · statut · actions */
    grid-template-columns: 36px 1.9fr 1.5fr 1fr 1.2fr .9fr 110px 160px 116px;
    align-items: center;
    gap: 0;
}

.pl-list-header {
    background: #f8fafc;
    border-bottom: 1px solid var(--border);
    padding: 0 6px;
}
.pl-list-header > div {
    padding: 9px 10px;
    font-size: 8pt;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #94a3b8;
}

/* ⚠️ HAUTEUR UNIFORME (décision Philippe) — sans elle, chaque ligne prend la hauteur de son
   contenu : une adresse sur deux lignes, un nom qui passe à la ligne, un sous-statut sous le
   statut, et la liste ondule. `min-height` plutôt qu'une hauteur fixe : rien n'est jamais rogné
   si un contenu devait dépasser. */
.pl-row {
    border-bottom: 1px solid #f1f5f9;
    min-height: 44px;
    padding: 0 6px;
    cursor: pointer;
    transition: background .1s;
}
.pl-row:last-child { border-bottom: none; }
.pl-row:hover { background: #f8fafc; }
/* ⚠️ ON RÉDUIT L'ESPACE, JAMAIS LA TAILLE DU TEXTE (demande Philippe : voir plus de leads sans
   défiler). Rogner les caractères ferait gagner les mêmes pixels en rendant la liste pénible à
   lire toute la journée — c'est le rembourrage et les interlignes qui partent, pas la lisibilité. */
.pl-row > div { padding: 6px 10px; }

/* Colonnes */
.pl-col-name {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.pl-col-contact { min-width: 0; }
.pl-col-type    { min-width: 0; }
.pl-col-assigned { color: #64748b; font-size: 9pt; }
.pl-col-time     { color: #94a3b8; font-size: 8.5pt; white-space: nowrap; }
/* `--cs-indent` : le retrait qui aligne la pastille de statut ET le sous-statut écrit dessous.
   Le bouton du select coloré porte ce rembourrage à gauche ; sans la même valeur sur le
   sous-statut, le texte commençait 11 px à gauche de la pastille — deux informations de la même
   cellule qui ne partaient pas du même bord. */
.pl-col-status   { padding: 2px 10px !important; --cs-indent: 10px; }
/* Le `+ 1px` n'est pas un ajustement à l'œil : c'est la bordure du bouton, transparente mais bien
   présente (elle garde sa place pour que rien ne saute au survol). La pastille commence donc un
   pixel plus loin que le seul rembourrage.

   ⚠️ La marge du haut est NÉGATIVE, et ce n'est pas un bricolage : le bouton du select mesure
   28 px pour une pastille de 22, donc il reste 3 px de jeu SOUS la pastille avant même que la
   marge commence. À quoi s'ajoutent 2 px de demi-interligne au-dessus des lettres. Le texte
   paraissait donc décollé de 7 px alors que la marge n'en déclarait que 2 — mesuré, pas estimé.
   On reprend ce jeu ici, et seulement dans la LIGNE de liste : dans le panneau du lead, la
   pastille n'est pas dans un bouton, il n'y a pas de jeu à reprendre. */
.pl-col-status .pl-sous-statut {
    margin-left: calc(var(--cs-indent) + 1px);
    margin-top: -3px;
}
.pl-col-check    { display: flex; align-items: center; justify-content: center; padding: 0 !important; }
.pl-col-check input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--blue, #2563eb); }

/* ORIGINE — deux lignes : la page, puis la publicité. La seconde est volontairement discrète :
   on la lit quand on la cherche, elle n'entre pas en concurrence avec le nom du client. */
.pl-col-origin      { min-width: 0; }
.pl-origin-page     { font-size: 9pt; color: #334155; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-origin-ad       { font-size: 8pt; color: #94a3b8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
.pl-origin-vide     { color: #cbd5e1; }

.pl-col-actions  { display: flex; align-items: center; gap: 4px; justify-content: flex-end; padding-right: 12px !important; }

/* Avatar initiales */
/* Repère de ligne NEUTRE — même icône pour tous les leads (décision Philippe).
   Les initiales prenaient la couleur du statut, ce qui créait un second langage de couleur
   à deux colonnes du badge de statut, qui dit déjà la même chose en toutes lettres. */
/* 28 px et non 34 : c'est une icône de repère, et à 34 px elle imposait à elle seule la hauteur
   de la colonne Client — plus haute que le nom qu'elle accompagne. */
.pl-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: #f1f5f9;
    color: #94a3b8;
}

.pl-name-block { min-width: 0; }
/* Le nom PASSE À LA LIGNE, il n'est pas rogné — même raison que le téléphone et l'adresse
   (demande Philippe) : « Martin Léves… » oblige à ouvrir la fiche pour savoir qui appelle. */
.pl-name {
    display: block;
    font-size: 9.5pt;
    font-weight: 700;
    color: #1e293b;
    line-height: 1.25;
    word-break: break-word;
}

.pl-contact-link {
    display: block;
    font-size: 9pt;
    color: var(--blue);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pl-contact-link:hover { text-decoration: underline; }
.pl-email { color: #64748b; }

/* ⚠️ CE BADGE NE SE TRONQUE PAS, et ce n'est pas une question de confort :
   « Thermopompe centrale » et « Thermopompe murale » se réduisaient TOUTES DEUX à
   « Thermopom… ». Deux projets différents devenaient identiques à l'écran — l'ellipse ne
   raccourcissait pas l'information, elle la supprimait. La pastille passe donc à la ligne. */
/* ⚠️ `white-space: normal` EST INDISPENSABLE ICI (bug vécu).
   Depuis que ce badge passe par le composant partagé, l'élément porte AUSSI la classe `.status`,
   qui impose `white-space: nowrap`. `word-break` seul ne sert alors à rien : on n'autorise pas la
   coupure d'un mot si le retour à la ligne lui-même est interdit. Résultat, « Thermopompe
   centrale » débordait de sa pastille au lieu de passer sur deux lignes.
   Toute classe passée à `<x-badge>` qui attend un retour à la ligne doit le redire. */
.pl-badge {
    display: inline-block;
    border: 1px solid;
    border-radius: 12px;
    /* Serré verticalement : « Thermopompe centrale » tient sur DEUX lignes par décision (une
       ellipse supprimerait l'information au lieu de la raccourcir), et c'est cette pastille à deux
       lignes qui fixait la hauteur de presque toutes les lignes de la liste. */
    padding: 2px 9px;
    font-size: 8pt;
    font-weight: 600;
    line-height: 1.15;
    max-width: 100%;
    white-space: normal;
    word-break: break-word;
}

/* ─── Panneau d'un lead (glisse depuis la droite) ────────────────────────────────────────
   LA MOITIÉ de l'écran (décision Philippe) — il faisait 480 px fixes, puis les deux tiers,
   jugés trop larges à l'essai.

   `max()` et non `50vw` seul : sur un portable de 1280 px, la moitié fait 640 px, mais sur un
   écran étroit la même règle rétrécirait le panneau SOUS sa largeur d'origine. Le plancher à
   480 px garantit qu'il ne devient jamais plus serré qu'avant, et `max-width: 100vw` le laisse
   prendre tout l'écran d'un téléphone. */
.pl-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: max(480px, 50vw);
    max-width: 100vw;
    background: #fff;
    box-shadow: -6px 0 32px rgba(0, 0, 0, .1);
    z-index: 201;
    overflow-y: auto;
}

/* ─── Conversation de Sophie dans le panneau d'un lead ───────────────────────────────────
   Le VIOLET est le repère de Sophie dans tout le CRM (#7c3aed) — le client reste en gris.
   Deux couleurs suffisent : on doit voir d'un coup d'œil qui parle, sans lire.

   ⚠️ Le corps SCROLLE (max-height) au lieu d'allonger le panneau : un échange de qualification
   fait facilement vingt répliques, et le journal d'activité vit juste en dessous — sans borne,
   il devient inatteignable. */
.sph-fil {
    border: 1px solid #ede9fe;
    border-radius: 10px;
    margin-bottom: 16px;
    overflow: hidden;
}

.sph-fil-titre {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    background: #f5f3ff;
    border-bottom: 1px solid #ede9fe;
    font-size: 8.5pt;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #6d28d9;
}

.sph-pastille {
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: #7c3aed;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 8pt;
    font-weight: 800;
    flex-shrink: 0;
}

/* La hauteur suit celle de l'écran : le panneau occupe les deux tiers de la largeur, mais
   c'est la VERTICALE qui manque quand on lit un fil. Bornée en dur aussi, pour que le journal
   d'activité juste dessous reste atteignable sans un long défilement. */
.sph-fil-corps {
    max-height: min(50vh, 520px);
    overflow-y: auto;
    padding: 10px 12px;
    background: #fff;
}

.sph-canal {
    text-align: center;
    font-size: 7.5pt;
    font-weight: 700;
    color: #94a3b8;
    text-transform: uppercase;
    letter-spacing: .04em;
    margin: 6px 0 10px;
}

/* ⚠️ COLONNE, pas rangée — depuis que l'heure accompagne chaque message. En rangée, l'heure
   devenait un deuxième élément flex POSÉ À CÔTÉ de la bulle : collée au bord du panneau, séparée
   de son message par tout le blanc de la ligne, et donc impossible à rattacher à l'un ou l'autre.
   En colonne, elle se range sous sa bulle et du même côté qu'elle. */
.sph-msg { display: flex; flex-direction: column; margin-bottom: 9px; }
.sph-msg--client { align-items: flex-start; }
.sph-msg--sophie { align-items: flex-end; }

/* L'heure de chaque message : discrète, on la lit quand on la cherche. */
.sph-heure {
    margin-top: 2px;
    font-size: 7.5pt;
    color: #94a3b8;
    font-variant-numeric: tabular-nums;
}

/* ⚠️ PLAFOND EN PIXELS, pas seulement en pourcentage. Depuis que le panneau prend les deux
   tiers de l'écran, 84 % faisaient des bulles de 1000 px sur un grand écran : une réplique de
   texto étalée sur une seule ligne interminable, qu'on relit deux fois pour ne pas perdre la
   ligne. Un fil se lit en colonne étroite — le pourcentage sert les petits écrans, le plafond
   sert les grands. */
.sph-bulle {
    max-width: min(84%, 480px);
    padding: 7px 11px;
    border-radius: 13px;
    font-size: 9pt;
    line-height: 1.4;
    word-break: break-word;
}

.sph-msg--client .sph-bulle {
    background: #f1f5f9;
    color: #1e293b;
    border-bottom-left-radius: 4px;
}

.sph-msg--sophie .sph-bulle {
    background: #ede9fe;
    color: #4c1d95;
    border-bottom-right-radius: 4px;
}

/* Ce que Sophie a réellement ACCOMPLI (rendez-vous pris, soumission envoyée) — un fait,
   pas une réplique : il vit hors du fil pour ne pas se lire comme un message. */
.sph-faits {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 9px 12px;
    background: #f8fafc;
    border-top: 1px solid #ede9fe;
}

.sph-fait {
    background: #dcfce7;
    color: #166534;
    border-radius: 20px;
    padding: 2px 9px;
    font-size: 8pt;
    font-weight: 700;
}

/* ── Journal des actions de la fiche client ──────────────────────────────────
   UNE LIGNE PAR CHOSE QUI S'EST PASSÉE, qu'on ouvre pour voir le détail
   (décision Philippe) : une conversation de Sophie dépliée d'office, c'est
   dix-sept bulles avant d'atteindre l'entrée suivante. Le journal se PARCOURT
   d'abord, se lit ensuite. */
.cli-action {
    border-bottom: 1px solid var(--border);
}
.cli-action:last-child { border-bottom: none; }

.cli-action-ligne {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 4px;
    cursor: pointer;
    list-style: none;
    font-size: 9.5pt;
}
.cli-action-ligne::-webkit-details-marker { display: none; }
.cli-action-ligne:hover { background: #f8fafc; }

/* Le chevron dit qu'il y a quelque chose dessous, et qu'il est ouvert. */
.cli-action-ligne::after {
    content: '›';
    color: #94a3b8;
    font-size: 14pt;
    line-height: 1;
    transition: transform .15s;
}
.cli-action[open] > .cli-action-ligne::after { transform: rotate(90deg); }

/* ── La conversation de Sophie MISE EN AVANT (fiche du lead) ─────────────────
   Dans le journal de la fiche client, une conversation est une entrée parmi
   d'autres — ligne grise discrète. Dans la fiche du LEAD, c'est L'INFORMATION
   qu'on vient chercher : elle prend les couleurs de Sophie et porte un aperçu
   du dernier message, pour se lire sans être ouverte. */
.sph-section-titre {
    font-size: 8.5pt;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
    margin-bottom: 8px;
}

.cli-action.sph-avant {
    border: 1px solid #ede9fe;
    border-radius: 12px;
    background: #f5f3ff;
    margin-bottom: 10px;
}
.cli-action.sph-avant > .cli-action-ligne {
    align-items: flex-start;
    padding: 12px 14px;
}
.cli-action.sph-avant > .cli-action-ligne:hover { background: #ede9fe; border-radius: 12px; }
.cli-action.sph-avant[open] > .cli-action-ligne { border-radius: 12px 12px 0 0; }
.cli-action.sph-avant > .cli-action-ligne::after { color: #7c3aed; align-self: center; }
.cli-action.sph-avant > div { padding: 0 14px 12px; }

/* L'aperçu du dernier message : deux lignes au plus, jamais de pavé. */
.sph-apercu {
    margin-top: 3px;
    font-size: 9pt;
    color: #475569;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.sph-apercu strong { color: #6d28d9; font-weight: 700; }

/* ── Répondre DANS le fil de Sophie ──────────────────────────────────────────
   Le champ était une section séparée sous la conversation repliée : « ça a l'air
   d'une autre plateforme et on ne peut pas suivre » (Philippe). On lisait les
   messages à un endroit et on répondait à un autre, sans voir à quoi on
   répondait. Le champ se rattache donc visuellement aux bulles — même colonne,
   collé dessous, comme la barre de saisie d'une messagerie. */
.sph-repondre {
    margin-top: -6px;
    padding: 10px 12px 12px;
    background: #f8fafc;
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 12px 12px;
}

.sph-repondre textarea {
    width: 100%;
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 8px 10px;
    font: inherit;
    font-size: 9.5pt;
    line-height: 1.45;
    resize: vertical;
    background: #fff;
}
.sph-repondre textarea:focus { outline: none; border-color: var(--blue); }

.sph-repondre-boutons {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 8px;
}
.sph-repondre-boutons .btn {
    padding: 6px 11px;
    border-radius: 9px;
    font-size: 9pt;
}

/* Le SOUS-STATUT, sous la pastille de statut. `.pl-nq-raison` est conservé en ALIAS : c'était le
   nom du seul cas d'origine (la raison d'un « Non qualifié »), avant que la même ligne serve aussi
   à « texto impossible », « désabonné », « sans réponse » et « conversation arrêtée ».

   ⚠️ UNE SEULE COULEUR, GRISE (décision Philippe). Les sous-statuts ont d'abord été peints par
   famille — ambre pour un canal bloqué, rouge pour un lead écarté. Trois couleurs pour une
   annotation de deux mots, dans une cellule qui porte DÉJÀ une pastille colorée juste au-dessus :
   c'était un second langage de couleur en concurrence avec le statut lui-même. Ce que le
   sous-statut a à dire tient dans ses mots, et dans l'explication dépliée à l'ouverture du lead. */
/* ⚠️ `margin-top` et `line-height` SERRÉS : c'est la hauteur de cette ligne de 8 pt qui décide
   si une ligne à sous-statut dépasse les autres. Chaque pixel repris ici en est un de moins
   d'écart avec une ligne ordinaire. */
/* Le petit lien contre le numéro : discret au repos, il ne concurrence pas la valeur qu'il
   accompagne — c'est une exception qu'on pose une fois sur mille leads, pas un geste courant. */
.pl-lien-texto {
    background: none;
    border: none;
    padding: 0 0 0 6px;
    font: inherit;
    font-size: 8pt;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.pl-lien-texto:hover { color: var(--blue, #2563eb) !important; }

/* « Origine et suivi interne » — le repli de la fiche d'un lead. `<details>` natif : le panneau
   est injecté par innerHTML, où aucun <script> ne s'exécute. */
.pl-plus { margin-top: 10px; }
.pl-plus > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    width: 100%;
    font-size: 8pt;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: #94a3b8;
}
.pl-plus > summary::-webkit-details-marker { display: none; }
/* Le chevron pivote : l'état ouvert/fermé se lit sans avoir à comparer avec autre chose. */
.pl-plus > summary::after {
    content: '';
    width: 7px; height: 7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    margin-left: 2px;
    transition: transform .15s;
}
.pl-plus[open] > summary::after { transform: rotate(-135deg); }
.pl-plus > summary:hover { color: var(--blue, #2563eb); }

.pl-sous-statut,
.pl-nq-raison {
    display: block;
    margin-top: 2px;
    font-size: 8pt;
    color: #64748b;
    font-weight: 600;
    line-height: 1.3;
    word-break: break-word;
}




/* ─── L'explication du sous-statut, dans le panneau d'un lead ────────────────────────────────
   Le bandeau ne se replie pas : on vient ici pour décider quoi faire, et c'est précisément ce
   qu'il explique. */
.pl-explication {
    border: 1px solid;
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 16px;
    font-size: 9pt;
    line-height: 1.5;
}
.pl-explication strong { color: #334155; }
.pl-explication strong { display: block; margin-bottom: 2px; font-weight: 700; }

/* Un seul ton, neutre — le bandeau suit le sous-statut : si la petite ligne de la liste est grise,
   ouvrir le lead sur un encadré ambre ferait douter d'être au bon endroit. Ce qu'il y a à
   comprendre est dans le texte, pas dans la couleur. */
.pl-explication { background: #f8fafc; border-color: var(--border); color: #475569; }

/* LA CONSIGNE DE REPRISE — ce que le vendeur doit savoir avant de composer le numéro.
   Plus appuyée que `.pl-explication` (fond neutre) parce qu'elle ne CONSTATE pas un blocage :
   elle demande une action. Le liseré porte la couleur, pas tout le bloc — un aplat mauve pleine
   largeur en tête de fiche écraserait le nom du client, qui reste l'information première. */
.pl-reprise {
    border: 1px solid #ddd6fe;
    border-left: 3px solid #7c3aed;
    background: #faf8ff;
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 16px;
}
.pl-reprise-titre {
    font-size: 7.5pt;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #7c3aed;
    margin-bottom: 3px;
}
.pl-reprise-puce { font-style: normal; }
.pl-reprise-raison {
    font-size: 10.5pt;
    font-weight: 700;
    color: #4c1d95;
    line-height: 1.35;
}
.pl-reprise-explication {
    margin-top: 4px;
    font-size: 9pt;
    line-height: 1.5;
    color: #64748b;
}

.pl-user-chip {
    display: inline-block;
    background: #f1f5f9;
    color: #475569;
    border-radius: 20px;
    padding: 3px 9px;
    font-size: 8pt;
    font-weight: 600;
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Select de statut */
.pl-status-select {
    border: 1px solid;
    border-radius: 20px;
    padding: 4px 26px 4px 10px;
    font-size: 8pt;
    font-weight: 700;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='5'%3E%3Cpath d='M0 0l4.5 5L9 0z' fill='%2364748b'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 9px center;
    background-color: transparent;
    width: 100%;
    max-width: 150px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pl-status-select:focus { outline: none; }
.pl-status-select:disabled { opacity: .5; cursor: not-allowed; }

/* Boutons d'action */
.pl-action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: #fff;
    color: #64748b;
    cursor: pointer;
    text-decoration: none;
    transition: background .1s, color .1s, border-color .1s;
    flex-shrink: 0;
}
.pl-action-btn:hover { background: var(--blue); color: #fff; border-color: var(--blue); }
.pl-open-btn:hover { background: #f1f5f9; color: #334155; border-color: #cbd5e1; }

/* ⚠️ ANCIEN BLOC RESPONSIVE DU PIPELINE — RETIRÉ (audit, M-8).
   Il décrivait une grille de 5 puis 3 pistes pour des colonnes qui ne sont plus rendues
   (`.pl-col-assigned`, `.pl-col-time`). À spécificité égale, la grille appliquée venait du bloc
   courant plus bas, mais son `display:none` sur `.pl-col-contact` sous 600 px, lui, n'était
   réécrit nulle part : sur un téléphone, le numéro et le courriel — « en entier, jamais tronqués »
   selon la vue — étaient tout simplement INVISIBLES. Quatre cellules occupaient cinq pistes, la
   piste vide restait là, et la colonne de statut faisait déborder la grille hors de la carte que
   `.pl-list { overflow:hidden }` rognait : le bouton « Appeler » devenait à moitié inatteignable.
   Le responsive du pipeline vit désormais à un seul endroit, avec le reste de `.pl-row`. */

/* ═══════════════════════════════════════════════════════════════
   PIPELINE — Kanban (conservé, non utilisé)
   ═══════════════════════════════════════════════════════════════ */
.pipeline-board { padding-bottom: 8px; }

.pipeline-columns {
    display: flex;
    gap: 12px;
    height: 100%;
    min-height: calc(100vh - 200px);
    padding-bottom: 4px;
    align-items: flex-start;
}

.pipeline-col {
    flex: 0 0 260px;
    background: #f8fafc;
    border-radius: 12px;
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 200px);
    overflow: hidden;
}

.pipeline-col-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    border-radius: 11px 11px 0 0;
    flex-shrink: 0;
}

.pipeline-col-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.pipeline-col-count {
    font-size: 8pt;
    font-weight: 700;
    border-radius: 20px;
    padding: 1px 7px;
    flex-shrink: 0;
}

.pipeline-col-body {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-height: 48px;
}

.pipeline-col-footer {
    padding: 6px 8px 8px;
    flex-shrink: 0;
}

.pipeline-add-btn {
    width: 100%;
    background: none;
    border: 1px dashed var(--border);
    border-radius: 8px;
    padding: 6px;
    font-size: 8.5pt;
    color: var(--muted);
    cursor: pointer;
    transition: background .12s, color .12s;
}
.pipeline-add-btn:hover { background: #e2e8f0; color: #334155; }

/* ── Carte de lead ─────────────────────────────────────────── */
.pipeline-card {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 9px;
    padding: 10px 12px;
    cursor: pointer;
    transition: box-shadow .15s, border-color .15s, transform .1s;
    user-select: none;
}
.pipeline-card:hover {
    box-shadow: 0 3px 12px rgba(0,0,0,.09);
    border-color: #cbd5e1;
    transform: translateY(-1px);
}
.pipeline-card-ghost { opacity: .4; background: #e2e8f0 !important; }
.pipeline-card-drag  { box-shadow: 0 8px 24px rgba(0,0,0,.14); transform: rotate(1.5deg); }

.pipeline-card-name {
    font-weight: 700;
    font-size: 9.5pt;
    color: #1e293b;
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pipeline-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
    margin-top: 6px;
    flex-wrap: wrap;
}

@media (max-width: 768px) {
    .pipeline-columns { flex-direction: column; min-height: unset; }
    .pipeline-col { flex: none; width: 100%; max-height: unset; }
    .pipeline-col-body { max-height: 300px; }
}

/* ──────────────── Étapes de préparation des factures (checklist simple) ────────────────
   Visuel volontairement sobre : pas de couleur d'accent. Texte foncé + ✓ vert quand c'est complété. */
.prep-list { display: flex; flex-direction: column; gap: 8px; }
/* Une étape ajoutée = une petite carte, fond vert pâle quand complétée */
.prep-step { border: 1px solid #e2e8f0; border-radius: 10px; padding: 9px 11px; background: #fff; display: flex; flex-direction: column; gap: 8px; transition: background .25s ease, border-color .25s ease; }
.prep-step.is-complete { border-color: #bbf7d0; background: #f0fdf4; }
.prep-step-head { display: flex; align-items: center; gap: 8px; }
.prep-step-name { font-size: 9.5pt; font-weight: 700; color: #1e293b; }
.prep-step-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.prep-step-status { font-size: 7.5pt; font-weight: 800; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.prep-step-status--done { background: #dcfce7; color: #15803d; }
.prep-step-status--todo { background: #fef3c7; color: #b45309; }
.prep-step-flag { color: #16a34a; font-weight: 800; font-size: 10.5pt; line-height: 1; }
.prep-step-remove { background: none; border: none; color: #cbd5e1; cursor: pointer; font-size: 10pt; line-height: 1; padding: 0 2px; }
.prep-step-remove:hover { color: #dc2626; }
/* + Ajouter une étape → chips sélectionnables (pastille avec « + » vert) */
.prep-add { margin-top: 2px; }
.prep-add-btn { background: none; border: 1px dashed #cbd5e1; color: #475569; padding: 6px 12px; border-radius: 8px; font-size: 8.5pt; font-weight: 600; cursor: pointer; }
.prep-add-btn:hover { background: #f8fafc; border-color: #94a3b8; }
.prep-add-menu { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.prep-add-item { background: #fff; border: 1.5px solid #e2e8f0; color: #1e293b; padding: 6px 12px; border-radius: 999px; font-size: 8.5pt; font-weight: 600; cursor: pointer; }
.prep-add-item::before { content: '+ '; color: #16a34a; font-weight: 800; }
.prep-add-item:hover { border-color: #16a34a; background: #f0fdf4; color: #15803d; }

.prep-ms-list { display: flex; flex-direction: column; gap: 1px; padding-left: 24px; margin-top: 4px; }
.prep-ms {
    display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
    background: none; border: none; padding: 4px 6px; border-radius: 7px; cursor: pointer;
    font-size: 9pt; color: #334155;
}
.prep-ms:hover { background: #f1f5f9; }
.prep-ms-box {
    width: 18px; height: 18px; flex-shrink: 0; border: 1.5px solid #cbd5e1; border-radius: 5px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 9pt; font-weight: 800; color: #fff; line-height: 1; background: #fff;
}
.prep-ms.is-done .prep-ms-box  { background: #16a34a; border-color: #16a34a; }
.prep-ms.is-done .prep-ms-name { color: #64748b; }   /* fait = atténué, l'œil se porte sur ce qui reste */
.prep-empty { font-size: 8.5pt; color: #94a3b8; }
.prep-empty a { color: var(--blue); text-decoration: none; }

/* Colonne de liste : badge + popover */
.prep-cell { position: relative; display: inline-block; }
/* Pastille d'état de préparation : vert = rien à faire, jaune = étapes à faire */
.prep-dot {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border: none; background: none; cursor: pointer; padding: 0; vertical-align: middle;
}
.prep-dot::before { content: ''; width: 13px; height: 13px; border-radius: 50%; background: var(--prep-dot-c, #cbd5e1); }
.prep-dot--ok   { --prep-dot-c: #16a34a; }   /* vert : préparation complétée */
.prep-dot--todo { --prep-dot-c: #eab308; }   /* jaune : étapes à faire */
.prep-dot--none { --prep-dot-c: #94a3b8; }   /* gris : aucune préparation (distinct du vert « complétée ») */
.prep-dot--static { cursor: default; }
/* Modale centrée de la colonne « Préparation » (clic sur le badge → popup au milieu de la page) */
.prep-modal {
    position: fixed; inset: 0; z-index: 2000; background: rgba(15, 23, 42, .45);
    align-items: center; justify-content: center; padding: 24px 16px;
}
.prep-modal-card {
    background: #fff; border-radius: 16px; width: 100%; max-width: 420px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, .25); max-height: 85vh; overflow-y: auto;
    padding: 18px 20px; text-align: left;
}
.prep-modal-head {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    font-size: 11pt; font-weight: 800; color: #1e293b; margin-bottom: 14px;
}
.prep-modal-close { background: none; border: none; font-size: 20pt; line-height: 1; cursor: pointer; color: #94a3b8; padding: 0 4px; }

/* ──────────────── Section « Commande » (commandes fournisseur) ──────────────── */
.order-list { display: flex; flex-direction: column; gap: 8px; }
.order-check { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
.order-check input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; flex-shrink: 0; accent-color: #16a34a; }
.order-type-name { font-size: 9.5pt; font-weight: 700; color: #1e293b; }
.order-type-head { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.order-type-status { display: none; font-size: 7.5pt; font-weight: 800; padding: 2px 8px; border-radius: 999px; background: #dcfce7; color: #15803d; white-space: nowrap; }
.order-type.is-complete .order-type-status { display: inline-flex; }
.order-type-lines { padding-left: 24px; margin-top: 6px; display: flex; flex-direction: column; gap: 6px; }
/* La boîte de chaque ligne prend la couleur de son statut (bleu/jaune/vert) — fond+bordure posés en
   inline (couleur du bouton actif + alpha). « À commander » = neutre. Transition douce. */
.order-line { display: flex; flex-direction: column; gap: 6px; border: 1px solid #e2e8f0; border-radius: 9px; padding: 8px 10px; background: #fff; transition: background .25s ease, border-color .25s ease; }
.order-line-top { display: flex; align-items: center; gap: 8px; }
.order-line-btns { display: flex; flex-wrap: wrap; gap: 6px; }
.order-num { flex: 1; min-width: 0; font-size: 9pt; padding: 5px 8px; }
.order-recv {
    --recv-c: #2563eb;
    border: 1.5px solid #cbd5e1; background: #fff; color: #64748b;
    padding: 3px 9px; border-radius: 999px; font-size: 8.5pt; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.order-recv.is-on { border-color: var(--recv-c); background: var(--recv-c); color: #fff; }   /* bouton actif = sa couleur */
.order-line-del { background: none; border: none; color: #cbd5e1; cursor: pointer; font-size: 11pt; line-height: 1; }
.order-line-del:hover { color: #dc2626; }
.order-add-line { background: none; border: 1px dashed #cbd5e1; color: #475569; padding: 5px 10px; border-radius: 8px; font-size: 8.5pt; cursor: pointer; align-self: flex-start; }
.order-empty { font-size: 8.5pt; color: #94a3b8; }
.order-empty a { color: var(--blue); text-decoration: none; }

/* Pastille d'état de commande : rouge = à commander, jaune = commandé/partiel, vert = reçu (ou rien) */
.order-cell { position: relative; display: inline-block; }
.order-dot {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border: none; background: none; cursor: pointer; padding: 0; vertical-align: middle;
}
.order-dot::before { content: ''; width: 13px; height: 13px; border-radius: 50%; background: var(--order-dot-c, #cbd5e1); }
.order-dot--static { cursor: default; }

/* Modale centrée de la colonne « Commande » (réutilise .prep-modal-card/head/close) */
.order-modal {
    position: fixed; inset: 0; z-index: 2000; background: rgba(15, 23, 42, .45);
    align-items: center; justify-content: center; padding: 24px 16px;
}

/* ──────────────── Notes internes des factures ──────────────── */
.inote-wrap { display: flex; flex-direction: column; gap: 8px; }
.inote { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 9px; padding: 8px 10px; }
.inote-body { font-size: 9.5pt; color: #1e293b; white-space: pre-wrap; word-break: break-word; }
.inote-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 5px; font-size: 8pt; color: #94a3b8; }
.inote-actions { display: inline-flex; gap: 8px; }
.inote-actions button { background: none; border: none; color: #64748b; cursor: pointer; font-size: 8pt; text-decoration: underline; padding: 0; }
.inote-actions button:hover { color: #2563eb; }
.inote-edit-input { font-size: 9.5pt; padding: 6px 8px; width: 100%; }
.inote-edit-btns { display: flex; gap: 6px; margin-top: 6px; }
.inote-empty { font-size: 8.5pt; color: #94a3b8; }
.inote-add { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.inote-add .inote-input { font-size: 9.5pt; padding: 6px 8px; }
.inote-add .btn { align-self: flex-start; }

/* Colonne « Notes » de la liste : icône + compteur, popup centrée */
.inote-cell { position: relative; display: inline-block; }
.inote-badge { display: inline-flex; align-items: center; gap: 3px; background: none; border: none; cursor: pointer; padding: 3px 6px; border-radius: 7px; color: #cbd5e1; }
.inote-badge.has-notes { color: #d97706; }
.inote-badge:hover { background: #f1f5f9; }
.inote-badge svg { width: 16px; height: 16px; }
.inote-count { font-size: 8pt; font-weight: 800; line-height: 1; }
.inote-modal { position: fixed; inset: 0; z-index: 2000; background: rgba(15, 23, 42, .45); align-items: center; justify-content: center; padding: 24px 16px; }

/* Notes : ligne discrète dans la sidebar de la fiche facture — ouvre la même modale que la liste */
.inote-cell:has(.inote-trigger-btn) { display: block; }
.inote-trigger-btn {
    display: flex; align-items: center; gap: 8px; width: 100%;
    background: #fff; border: 1px solid var(--border); border-radius: 10px;
    padding: 9px 12px; cursor: pointer; text-align: left;
    color: #475569; font-size: 9.5pt; font-weight: 700;
    transition: background .12s, border-color .12s;
}
.inote-trigger-btn:hover { background: #f8fafc; border-color: #cbd5e1; }
.inote-trigger-btn svg { width: 15px; height: 15px; flex-shrink: 0; color: #94a3b8; }
.inote-trigger-label { flex: 1; }
/* Note présente = ambre « note » (même palette que .note-box / .order-note-btn.has-note) — plus visible
   que le bleu ; l'état SANS note (base ci-dessus) reste inchangé. */
.inote-trigger-btn.has-notes { color: #d97706; border-color: #fcd34d; background: #fffbeb; }
.inote-trigger-btn.has-notes svg { color: #d97706; }
.inote-trigger-btn .inote-count { margin-left: auto; background: #d97706; color: #fff; border-radius: 999px; padding: 1px 8px; font-size: 8.5pt; font-weight: 800; }

/* Badge de paiement cliquable (colonne « Paiement » de la liste) → ouvre le popup d'enregistrement */
.inv-pay-badge-btn { background: none; border: none; padding: 2px; cursor: pointer; border-radius: 7px; line-height: 1; }
.inv-pay-badge-btn:hover { background: #f1f5f9; }

/* ──────────────── Cartes repliables (sidebar soumission / facture) ──────────────── */
.collapse-head {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    cursor: pointer; user-select: none; margin-bottom: 12px;
}
.collapse-card.is-collapsed .collapse-head { margin-bottom: 0; }
.collapse-card.is-collapsed .collapse-body { display: none; }
.collapse-chevron { font-size: 11px; color: var(--muted); transition: transform .15s; flex-shrink: 0; }
.collapse-card.is-collapsed .collapse-chevron { transform: rotate(-90deg); }

/* ── Pagination MPH Core (vue vendor/pagination/mph) ── */
.mph-pagination { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: 9.5pt; }
.mph-pagination .mph-info { color: var(--muted); margin-right: auto; font-size: 9pt; white-space: nowrap; }
.mph-pagination .mph-page {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 30px; padding: 0 9px; line-height: 1;
  border: 1px solid var(--border); border-radius: 8px;
  background: #fff; color: #334155; text-decoration: none; font-weight: 600;
  transition: background .12s, border-color .12s, color .12s;
}
.mph-pagination a.mph-page:hover { background: #f1f5f9; border-color: #cbd5e1; }
.mph-pagination .mph-page.is-active { background: var(--blue); border-color: var(--blue); color: #fff; }
.mph-pagination .mph-page.is-disabled { color: #cbd5e1; background: #fff; cursor: default; }
.mph-pagination .mph-sep { display: inline-flex; align-items: center; padding: 0 4px; color: var(--muted); font-weight: 700; }
@media (max-width: 640px) {
  .mph-pagination { gap: 3px; font-size: 9pt; }
  .mph-pagination .mph-info { width: 100%; margin-bottom: 6px; }
  .mph-pagination .mph-page { min-width: 28px; height: 28px; padding: 0 7px; }
}

/* ═══════════════════════════════════════════════════════════════════
   Module Service (Phase 7) — formulaire technicien + dashboard + fiche
   ═══════════════════════════════════════════════════════════════════ */

/* Pastille « R » des retours (liste des rapports) — rond PLEIN, lettre blanche : même parti pris que le
   compteur des pilules de filtre (vif, pas translucide). Volontairement minuscule : la pastille
   « Retour » pleine largeur encombrait la liste (décision Philippe), une lettre ne la gêne pas.
   Rouge = retour d'INSTALLATION (faute d'installateur) · Mauve = retour de SERVICE (faute de technicien).
   Le `title` porte le sens — « R » seul est cryptique. */
.svc-return-dot {
    display:inline-flex; align-items:center; justify-content:center;
    width:17px; height:17px; border-radius:999px;
    color:#fff; font-size:8pt; font-weight:900; line-height:1;
    margin-left:6px; vertical-align:middle; flex-shrink:0;
}
.svc-return-dot--install { background:#dc2626; }
.svc-return-dot--service { background:#7c3aed; }

/* ── Formulaire technicien (mobile-first) ── */
.svc-form { max-width: 860px; margin: 0 auto; display: grid; gap: 16px; align-content: start; }
/* Résumé des erreurs de validation (haut du formulaire technicien) — chaque ligne défile vers le champ. */
.svc-error-summary { background:#fff1f2; border:1px solid #fecdd3; color:#9f1239; border-radius:14px; padding:14px 16px; margin-bottom:14px; font-size:10.5pt; line-height:1.4; }
.svc-error-list { list-style:none; margin:8px 0 0; padding:0; display:grid; gap:5px; }
.svc-error-list li { display:flex; align-items:flex-start; gap:7px; }
.svc-error-list li::before { content:"•"; color:#dc2626; font-weight:900; line-height:1.2; }
.svc-error-jump { background:none; border:0; padding:0; margin:0; color:#9f1239; text-decoration:underline; cursor:pointer; font-size:10pt; text-align:left; font-family:inherit; }
.svc-error-jump:hover { color:#dc2626; }
.svc-plate-error { margin-top:8px; }
.svc-section-title { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:14px; }
/* 14px (et non 14pt ≈ 18.7px) : c'est la taille des titres de carte de TOUS les autres modules —
   le module Service, porté de l'ancien système autonome, avait gardé les siennes, 33 % plus grosses. */
.svc-section-title h3 { margin:0; font-size:14px; font-weight:800; color:#07375f; letter-spacing:-.3px; }
.svc-pill { background:#e9f5ff; color:#0f4c81; border-radius:999px; padding:6px 11px; font-weight:700; font-size:9pt; white-space:nowrap; }
.svc-grid { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:12px; }
.svc-grid .full { grid-column:1 / -1; }
.svc-hint { color:var(--muted, #64748b); font-size:9.5pt; line-height:1.35; margin-top:8px; }
.svc-note-box { border-radius:14px; padding:13px 15px; margin-top:12px; line-height:1.45; font-size:10pt; }
.svc-note-box.amber { background:linear-gradient(135deg,#fff8e8,#fff3d6); border:1px solid #f7d794; color:#8a5a00; }
.svc-note-box.red   { background:linear-gradient(135deg,#fff1f2,#ffe4e6); border:1px solid #fecdd3; color:#991b1b; }

/* Équipements */
.svc-equip-grid { display:grid; gap:14px; }
.svc-equip-card { border:1px solid var(--border, #dbe4ef); background:#fbfdff; border-radius:16px; padding:14px; }
.svc-equip-title { font-weight:800; color:#0f4c81; margin-bottom:10px; display:flex; align-items:center; justify-content:space-between; gap:8px; }
.svc-remove-btn { width:30px; height:30px; min-height:30px; padding:0; border-radius:9px; background:#fff1f2; color:#dc2626; border:1px solid #fecdd3; font-size:15pt; line-height:1; cursor:pointer; }
.svc-plate-preview { display:grid; grid-template-columns:repeat(2,1fr); gap:8px; margin-top:10px; }
.svc-plate-thumb, .svc-media-thumb { position:relative; border-radius:12px; overflow:hidden; border:1px solid var(--border,#dbe4ef); background:#f8fafc; min-height:90px; }
.svc-plate-thumb img { width:100%; height:90px; object-fit:cover; display:block; }
.svc-media-thumb img, .svc-media-thumb video { width:100%; height:115px; object-fit:cover; display:block; background:#0f172a; }
.svc-thumb-x { position:absolute; right:6px; bottom:6px; width:28px; height:28px; min-height:28px; padding:0; border-radius:9px; background:rgba(220,38,38,.92); color:#fff; font-size:15pt; line-height:1; border:0; cursor:pointer; z-index:5; }
.svc-media-preview { display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-top:12px; }
.svc-upload-status { position:absolute; left:6px; right:6px; top:6px; background:rgba(15,23,42,.82); color:#fff; border-radius:10px; padding:6px 8px; font-size:8.5pt; line-height:1.25; z-index:2; text-align:center; }
.svc-upload-status.error { background:rgba(220,38,38,.92); }
.svc-upload-status.waiting { background:rgba(37,99,235,.92); }         /* réseau faible : bleu, pas rouge (pas une vraie erreur) */
.svc-upload-status button { background:#fff; color:#0f4c81; font-weight:800; }

/* Bannière récap des envois (au-dessus du bouton « Envoyer ») — réseau faible. */
.svc-upload-banner { border-radius:14px; padding:12px 15px; margin-bottom:14px; display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; font-weight:700; font-size:10pt; }
.svc-upload-banner.is-wait { background:#e0edff; border:1px solid #bfdbfe; color:#1e40af; }
.svc-upload-banner.is-error { background:#fff1f2; border:1px solid #fecdd3; color:#9f1239; }
.svc-progress { width:100%; height:6px; background:rgba(255,255,255,.25); border-radius:999px; overflow:hidden; margin-top:4px; }
.svc-progress > span { display:block; height:100%; width:0; background:#22c55e; border-radius:999px; transition:width .2s ease; }
.svc-file-btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; width:100%; cursor:pointer; }

/* Facturation */
.svc-bill-row { display:grid; grid-template-columns:2fr 100px 120px 120px 46px; gap:10px; margin-bottom:12px; align-items:end; }
.svc-bill-custom { display:none; grid-column:1 / -1; grid-template-columns:2fr 140px; gap:10px; margin-top:-4px; }
.svc-bill-custom.show { display:grid; }
.svc-bill-summary { margin-top:14px; border:1px solid var(--border,#dbe4ef); border-radius:14px; background:#fbfdff; overflow:hidden; }
.svc-bill-summary-row { display:flex; justify-content:space-between; gap:12px; padding:10px 14px; border-bottom:1px solid var(--border,#dbe4ef); font-weight:700; }
.svc-bill-summary-row:last-child { border-bottom:0; background:#eafff1; color:#166534; font-size:12pt; font-weight:900; }
.svc-readonly { background:#f8fafc; }

/* Recherche client (autocomplete) */
.svc-client-search { position:relative; }
.svc-client-results { position:fixed; z-index:900; background:#fff; border:1px solid var(--border,#dbe4ef); border-radius:12px; box-shadow:0 12px 30px rgba(15,23,42,.14); max-height:280px; overflow-y:auto; display:none; }
.svc-client-results.show { display:block; }
.svc-client-opt { padding:10px 13px; cursor:pointer; border-bottom:1px solid #f1f5f9; }
.svc-client-opt:hover { background:#f0f7ff; }
.svc-client-opt small { display:block; color:var(--muted,#64748b); font-size:9pt; }
.svc-client-chip { display:inline-flex; align-items:center; gap:8px; background:#e9f5ff; color:#0f4c81; border-radius:999px; padding:6px 12px; font-weight:700; font-size:9.5pt; margin-top:8px; }
.svc-client-chip button { border:0; background:transparent; color:#0f4c81; cursor:pointer; font-size:12pt; line-height:1; padding:0; }

@media (max-width:640px) {
  .svc-grid, .svc-bill-row, .svc-bill-custom { grid-template-columns:1fr; }
  .svc-media-preview { grid-template-columns:repeat(2,1fr); }
  .svc-section-title { flex-direction:column; align-items:flex-start; }
}

/* ── Dashboard service (temps réel) — pastilles de filtre. Couleurs = LA MÊME palette que le reste du
   CRM (classes .status .green/.orange/.gray/.blue/.teal, ligne ~609 de ce fichier — badges Soumissions/
   Factures/Agenda), pas les tons pastel de l'ancien dashboard-service (jugés trop fades). ── */
.svc-filter-pills { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:16px; }
.svc-pill-btn {
    border:1px solid #e2e8f0;   /* léger contour gris pâle UNIFORME (pas de bordure colorée par catégorie) */
    border-radius:12px;
    min-height:36px;
    padding:9px 13px;
    font-weight:900;
    cursor:pointer;
    font-size:10pt;
    background:#fff;
    color:#475569;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:8px;
    transition:.15s;
}
/* Compteur = rond plein de la couleur de la catégorie, chiffre blanc — vif, pas translucide. */
.svc-pill-btn strong {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:24px;
    min-height:24px;
    border-radius:999px;
    background:#94a3b8;
    color:#fff;
    padding:2px 8px;
    font-size:9pt;
}

/* État actif : anneau bleu doux (indicateur de sélection) — sans contour sur la pastille elle-même. */
.svc-pill-btn.active { outline:3px solid rgba(15,76,129,.28); outline-offset:1px; }

/* Une couleur par pastille — mêmes valeurs EXACTES que .green/.orange/.gray/.blue/.teal (ligne ~609). */
.svc-pill-new           { background:#dcfce7; color:#166534; }
.svc-pill-new strong    { background:#166534; }

.svc-pill-processing        { background:#ffedd5; color:#9a3412; }
.svc-pill-processing strong { background:#9a3412; }

.svc-pill-done          { background:#f1f5f9; color:#475569; }
.svc-pill-done strong   { background:#475569; }

.svc-pill-all           { background:#fff; color:#1d4ed8; }
.svc-pill-all strong    { background:#1d4ed8; }

.svc-pill-invoice          { background:#ccfbf1; color:#0f766e; }
.svc-pill-invoice strong   { background:#0f766e; }

.svc-live-dot { width:9px; height:9px; border-radius:50%; background:#16a34a; display:inline-block; box-shadow:0 0 0 0 rgba(22,163,74,.5); animation:svcPulse 2s infinite; }
@keyframes svcPulse { 0%{box-shadow:0 0 0 0 rgba(22,163,74,.45);} 70%{box-shadow:0 0 0 8px rgba(22,163,74,0);} 100%{box-shadow:0 0 0 0 rgba(22,163,74,0);} }
.svc-row-new { animation:svcRowNew 2.4s ease; }
@keyframes svcRowNew { 0%{background:#dcfce7;} 100%{background:transparent;} }
.svc-toast { position:fixed; right:18px; bottom:18px; z-index:900; background:#0f4c81; color:#fff; padding:13px 18px; border-radius:12px; box-shadow:0 12px 30px rgba(15,23,42,.25); font-weight:700; font-size:10pt; display:flex; align-items:center; gap:10px; cursor:pointer; }

/* Popup de succès du formulaire technicien (reste sur place après l'enregistrement + choix de l'action). */
.svc-success-modal { position:fixed; inset:0; z-index:2000; background:rgba(15,23,42,.55); display:none; align-items:center; justify-content:center; padding:24px 16px; }
.svc-success-modal.show { display:flex; }
.svc-success-card { position:relative; background:#fff; border-radius:20px; padding:30px 26px; max-width:420px; width:100%; text-align:center; box-shadow:0 25px 60px rgba(15,23,42,.35); }
/* Le X : cible de 40px, doigt ganté sur un chantier — pas une croix de 16px au coin. */
.svc-success-close { position:absolute; top:10px; right:10px; width:40px; height:40px; border:0; border-radius:50%; background:transparent; color:#94a3b8; font-size:26px; line-height:1; cursor:pointer; }
.svc-success-close:hover, .svc-success-close:focus-visible { background:#f1f5f9; color:#334155; }
.svc-success-check { width:66px; height:66px; margin:0 auto 16px; border-radius:50%; background:#16a34a; color:#fff; font-size:34px; line-height:66px; font-weight:900; }
.svc-success-card h3 { margin:0 0 8px; color:#07375f; font-size:16pt; }
.svc-success-msg { margin:0 0 22px; color:#475569; font-size:11pt; line-height:1.5; }
.svc-success-actions { display:flex; flex-direction:column; gap:10px; }
.svc-success-actions .btn { width:100%; padding:14px; font-size:11.5pt; }

/* ─────────────────────────────  iA Michel — assistant de diagnostic CVC  ───────────────────────────── */
/* Bouton d'ouverture (dashboard + ligne « Notes de service ») */
.michel-btn { display:inline-flex; align-items:center; gap:7px; background:var(--accent,#7c3aed); color:#fff; border:0; border-radius:10px; padding:8px 14px; font-size:9.5pt; font-weight:800; cursor:pointer; box-shadow:0 3px 10px rgba(124,58,237,.30); white-space:nowrap; }
.michel-btn:hover { filter:brightness(1.08); }
.michel-btn small { font-weight:500; opacity:.8; font-size:8pt; }

/* CTA de la page d'accueil technicien (Nouveau rapport + iA Michel) — même ligne, plus compacts sur mobile */
.tech-cta-row { display:flex; gap:12px; margin-bottom:18px; }
.tech-cta { flex:1; min-width:0; display:flex; align-items:center; justify-content:center; gap:10px; text-align:center; padding:20px 16px; border-radius:14px; color:#fff; text-decoration:none; border:0; cursor:pointer; font-size:13.5pt; font-weight:800; line-height:1.2; }
.tech-cta:hover { filter:brightness(1.06); }
.tech-cta--report { background:linear-gradient(135deg,#34d399,#059669); box-shadow:0 6px 18px rgba(5,150,105,.30); }
.tech-cta--michel { flex-direction:column; gap:2px; background:var(--accent,#7c3aed); box-shadow:0 6px 18px rgba(124,58,237,.32); }
.tech-cta--michel small { font-size:9pt; font-weight:500; opacity:.9; }
@media (max-width:640px) {
    .tech-cta-row { gap:8px; margin-bottom:14px; }
    .tech-cta { padding:12px 8px; font-size:10.5pt; border-radius:12px; gap:6px; }
    .tech-cta--michel small { font-size:7.5pt; }
}

/* Overlay + carte (mobile d'abord, en-tête/pied fixes, corps scrollable) */
.michel-modal { position:fixed; inset:0; z-index:2100; background:rgba(15,23,42,.55); display:none; align-items:flex-start; justify-content:center; padding:24px 14px; overflow-y:auto; }
.michel-modal.show { display:flex; }
.michel-card { background:#fff; border-radius:18px; width:100%; max-width:640px; display:flex; flex-direction:column; max-height:92vh; overflow:hidden; box-shadow:0 25px 70px rgba(15,23,42,.4); }
.michel-head { flex-shrink:0; display:flex; align-items:center; justify-content:space-between; gap:12px; padding:15px 18px; background:var(--accent,#7c3aed); color:#fff; }
.michel-head-id { display:flex; align-items:center; gap:12px; }
.michel-avatar { width:40px; height:40px; border-radius:11px; background:rgba(255,255,255,.16); display:flex; align-items:center; justify-content:center; font-size:18pt; }
.michel-head h3 { margin:0; font-size:14pt; line-height:1.1; }
.michel-head small { opacity:.82; font-size:8.5pt; }
.michel-close { background:none; border:0; color:#fff; font-size:24pt; line-height:1; cursor:pointer; padding:0 4px; opacity:.85; }
.michel-close:hover { opacity:1; }
.michel-body { flex:1; overflow-y:auto; padding:16px 18px; }
.michel-foot { flex-shrink:0; display:flex; gap:10px; justify-content:flex-end; padding:12px 18px; border-top:1px solid var(--border); background:#f8fafc; }

.michel-section { margin-bottom:16px; }
.michel-section-label { font-size:8.5pt; font-weight:800; text-transform:uppercase; letter-spacing:.04em; color:#6d28d9; margin-bottom:8px; }
.michel-grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.michel-grid-2 .field { margin:0; }
.michel-hint { font-size:8.5pt; color:var(--muted); margin-top:6px; line-height:1.4; }
.michel-plate-btn { width:100%; margin-top:10px; }

.michel-toggle { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.michel-toggle-btn { border:1px solid var(--border); background:#fff; border-radius:10px; padding:10px 8px; font-size:9pt; font-weight:700; color:#475569; cursor:pointer; text-align:center; }
.michel-toggle-btn.is-active { border-color:#7c3aed; background:#f5f0ff; color:#5b21b6; box-shadow:inset 0 0 0 1px #7c3aed; }

.michel-run-wrap { margin-top:4px; }
.michel-loading { display:flex; align-items:center; gap:10px; color:#7c3aed; font-weight:700; font-size:10pt; padding:14px 0; }
.michel-spin { width:16px; height:16px; border:3px solid #ddd6fe; border-top-color:#7c3aed; border-radius:50%; animation:michelspin .8s linear infinite; }
@keyframes michelspin { to { transform:rotate(360deg); } }
.michel-note { background:#fff7ed; border:1px solid #fed7aa; color:#9a3412; border-radius:10px; padding:12px 14px; font-size:9.5pt; }

.michel-result { margin-top:6px; }
.michel-source-tag { font-size:8.5pt; color:#0f5132; background:#e7f5ec; border:1px solid #b7e0c4; border-radius:8px; padding:7px 10px; margin-bottom:12px; }
.michel-source-tag.warn { color:#9a3412; background:#fff7ed; border-color:#fed7aa; }
.michel-source-tag a { color:#7c3aed; font-weight:700; }
.michel-resume { font-size:10.5pt; color:#1e293b; line-height:1.5; margin-bottom:14px; font-weight:600; }
.michel-safety { background:#fef2f2; border:1px solid #fecaca; border-radius:11px; padding:11px 14px; margin-bottom:14px; }
.michel-safety strong { color:#b91c1c; font-size:9.5pt; }
.michel-safety ul { margin:6px 0 0; padding-left:18px; color:#7f1d1d; font-size:9pt; }
.michel-block-title { font-size:9pt; font-weight:800; color:#6d28d9; text-transform:uppercase; letter-spacing:.03em; margin:12px 0 8px; }
.michel-cause { border:1px solid var(--border); border-radius:11px; padding:11px 13px; margin-bottom:9px; background:#fff; }
.michel-cause-head { display:flex; justify-content:space-between; align-items:center; gap:10px; }
.michel-cause-name { font-weight:700; color:#1e293b; font-size:10pt; }
.michel-cause-pct { font-weight:800; color:#7c3aed; font-size:9.5pt; }
.michel-bar { height:6px; border-radius:4px; background:#e2e8f0; margin:7px 0; overflow:hidden; }
.michel-bar span { display:block; height:100%; background:linear-gradient(90deg,#a855f7,#7c3aed); }
.michel-cause-line { font-size:9pt; color:#475569; margin-top:3px; line-height:1.4; }
.michel-cause-line b { color:#334155; }
.michel-next { background:#f5f0ff; border:1px solid #ddd6fe; border-radius:11px; padding:11px 14px; margin:12px 0; font-size:9.5pt; color:#5b21b6; line-height:1.5; }
.michel-questions { margin:0; padding-left:18px; color:#475569; font-size:9pt; }
.michel-questions li { margin-bottom:3px; }
.michel-sources { margin-top:12px; font-size:8pt; color:#94a3b8; font-style:italic; }

@media (max-width:640px) {
    .michel-grid-2, .michel-toggle { grid-template-columns:1fr; }
    .michel-modal { padding:0; }
    .michel-card { max-width:100%; max-height:100vh; border-radius:0; }
}

/* ── PROPORTIONS STANDARD des champs de formulaire — POINT UNIQUE (règle 14) ──
   Labels 9pt, champs 9.5pt, padding resserré : c'est la taille de TOUS les modules métier
   (Soumission, Facture, Commande, Service). La hauteur 34px des input/select vient de la règle
   `input.form-input` plus haut et reste commune.

   Sans `.form-compact`, un champ hérite de la police par défaut du navigateur (~12pt) : c'est ce qui
   faisait paraître le module Service nettement plus gros que le reste du CRM (décision Philippe
   2026-07-15 — « ça doit être uniforme comme mes autres modules »). Toute NOUVELLE page de formulaire
   met cette classe sur son conteneur ; ne jamais recopier ces valeurs ailleurs.

   (Anciennement `.order-form-compact`, propre au module Commande — renommée en la généralisant ; aucun
   gabarit ne la porte plus.) */
/* `.form-compact` n'a PLUS d'effet : ses valeurs sont devenues le défaut de `.form-label` /
   `.form-input` (2026-08-03). Conservée comme alias inoffensif — une dizaine de vues la portent, et
   la retirer partout serait du bruit sans bénéfice. NE PAS y remettre de valeurs : ce serait rouvrir
   deux tailles de formulaire dans le CRM, exactement ce qu'on vient de supprimer. */
.form-compact .form-label { }
.form-compact .form-input { }

/* EXCEPTION — formulaire technicien sur mobile (décision Philippe 2026-07-15).
   iOS Safari ZOOME automatiquement sur un champ dont la police fait moins de 16px, et ne dézoome pas
   en sortant : le technicien verrait l'écran sauter à chaque champ, sur le terrain, une main occupée.
   9.5pt = 12.7px déclenche donc le zoom. On repasse à 16px sous 640px, où le formulaire technicien vit
   réellement ; au bureau il reste compact comme tous les autres modules.

   Ne cible QUE `.svc-form` (le formulaire technicien) : les autres modules — y compris la FICHE de
   service (`.svc-edit-grid`) — sont des outils de bureau, et doivent rester compacts partout.
   Les labels ne sont pas touchés : ils ne reçoivent pas le focus, donc ne déclenchent aucun zoom. */
@media (max-width: 640px) {
    .svc-form .form-input { font-size: 16px; }
}

/* Adresse liée d'une commande : texte + mini-flèche (▾) + menu déroulant si ≥2 adresses
   (sidebar client de /commandes/nouvelle et /modifier). */
.ord-addr-line { position: relative; margin-top: 2px; }
/* Adresse liée sur 2 lignes (rue+ville, puis province+code postal + flèche) — tient dans le sidebar étroit. */
.ord-addr-l1 { display: block; }
.ord-addr-l2 { display: block; color: #64748b; }
.ord-addr-toggle { background: none; border: none; color: var(--blue); cursor: pointer; font-size: 11pt; line-height: 1; padding: 0 3px; vertical-align: middle; }
.ord-addr-toggle:hover { color: var(--blue-dark, #1d4ed8); }
.ord-addr-menu { display: none; position: fixed; z-index: 900; background: #fff; border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 6px 24px rgba(0,0,0,.14); min-width: 200px; max-width: 320px; overflow: hidden; }
.ord-addr-menu.is-open { display: block; }
.ord-addr-opt { padding: 7px 10px; cursor: pointer; font-size: 9pt; border-bottom: 1px solid #f1f5f9; }
.ord-addr-opt:last-child { border-bottom: none; }
.ord-addr-opt:hover { background: #f8fafc; }
.ord-addr-opt.is-sel { background: #eff6ff; font-weight: 600; }

/* Carte « Client » d'une commande (fiche/création) — visuel soigné (avatar + coordonnées).
   Le bloc #order-cust-coords est re-rendu à l'identique par le JS orderCustCoordsHtml() à la sélection. */
/* Carte client condensée (sans avatar) : nom/entreprise, puis coordonnées qui s'écoulent en ligne
   (flex-wrap) au lieu d'une par ligne — pour prendre le moins de hauteur possible. */
.ord-client-card { position: relative; background: linear-gradient(180deg, #f8fafc, #ffffff); border: 1px solid var(--border); border-radius: 12px; padding: 11px 14px; max-width: 520px; box-shadow: 0 1px 3px rgba(15,23,42,.05); }
.ord-client-change { position: absolute; top: 9px; right: 12px; background: none; border: none; color: #dc2626; cursor: pointer; font-size: 8.5pt; font-weight: 600; }
.ord-client-change:hover { text-decoration: underline; }
.ord-client-head { padding-right: 64px; }
.ord-client-name { font-weight: 700; font-size: 11pt; color: var(--blue); text-decoration: none; line-height: 1.25; }
.ord-client-name:hover { text-decoration: underline; }
.ord-client-company { display: block; font-size: 9pt; color: #94a3b8; margin-top: 1px; }
.ord-client-info { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); display: flex; flex-wrap: wrap; gap: 4px 16px; }
.ord-client-row { display: flex; align-items: flex-start; gap: 7px; font-size: 9.5pt; color: #334155; line-height: 1.4; }
.ord-client-ico { flex: none; width: 15px; color: #94a3b8; display: inline-flex; margin-top: 1px; }

/* Mini-éditeur d'un nouveau numéro de référence nommé (avant enregistrement ✓). */
.order-ref-editing { background: #f8fafc; border: 1px dashed var(--border); border-radius: 10px; padding: 8px; }

/* Groupe d'un équipement (Marque/Modèle/Série + ses pièces imbriquées) dans le formulaire de commande. */
/* Équipements et pièces — lisibilité : chaque équipement est un panneau gris et ses champs sont BLANCS,
   pour bien ressortir (avant : champs #f8fafc sur groupe #f8fafc → tout se fondait, dur à lire). */
.order-equip-group { border: 1px solid #d7dee7; border-radius: 10px; padding: 12px 14px; background: #f1f5f9; }
.order-equip-group .form-input { background: #fff; border-color: #cbd5e1; }
.order-equip-group .form-input:focus { border-color: rgba(15, 94, 168, 0.45); }

/* Boutons d'état de réception d'une pièce de commande (Commandé / Partiellement reçu / Reçu).
   La couleur active vient de la variable inline --st-c. */
.part-state-btn { border: 1px solid var(--border); background: #fff; color: #64748b; border-radius: 7px; padding: 4px 10px; font-size: 8.5pt; cursor: pointer; transition: background .12s, color .12s, border-color .12s; white-space: nowrap; }
.part-state-btn:hover { border-color: var(--st-c); color: var(--st-c); }
.part-state-btn.is-on { background: var(--st-c); border-color: var(--st-c); color: #fff; font-weight: 700; }

/* Icône « note » d'une pièce de commande (ouvre un popup ; infobulle native au survol si une note existe).
   État muet par défaut, ambre lorsqu'une note est présente (.has-note). */
.order-note-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; border: 1px solid var(--border); background: #fff; color: #94a3b8; border-radius: 9px; cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
.order-note-btn:hover { border-color: #64748b; color: #64748b; }
.order-note-btn.has-note { background: #fffbeb; border-color: #fcd34d; color: #d97706; }

/* Icône (i) « suivi des dates » d'une pièce (dates/heures des clics Commandé/Reçu ; popup + infobulle).
   Muette par défaut, bleutée lorsqu'au moins une date existe (.has-info). */
.order-info-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; border: 1px solid var(--border); background: #fff; color: #94a3b8; border-radius: 9px; cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
.order-info-btn:hover { border-color: #64748b; color: #64748b; }
.order-info-btn.has-info { background: #eff6ff; border-color: #93c5fd; color: #2563eb; }

/* ─────────── Alertes personnalisées d'une commande (date d'activation + note) ─────────── */
/* Bannière en haut de /commandes : toutes les alertes actives, très visible pour tous les employés. */
.oalert-banner { background: #fef2f2; border: 1px solid #fca5a5; border-left: 4px solid #dc2626; border-radius: 12px; padding: 12px 14px; margin-bottom: 16px; }
.oalert-banner-title { font-weight: 800; font-size: 10.5pt; color: #b91c1c; margin-bottom: 8px; }
.oalert-banner-list { display: grid; gap: 8px; }
.oalert-banner-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; background: #fff; border: 1px solid #fecaca; border-radius: 9px; padding: 8px 11px; }
.oalert-banner-main { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 9.5pt; color: #334155; min-width: 0; }
.oalert-banner-num { font-weight: 800; color: var(--blue); text-decoration: none; white-space: nowrap; }
.oalert-banner-num:hover { text-decoration: underline; }
.oalert-banner-h { color: #b91c1c; }
.oalert-banner-since { color: #94a3b8; font-size: 8.5pt; white-space: nowrap; }
.oalert-banner-btns { display: flex; gap: 6px; flex-shrink: 0; }
.oalert-banner-resolve { background: #dc2626; color: #fff; border: none; border-radius: 8px; padding: 4px 11px; font-size: 8.5pt; font-weight: 700; cursor: pointer; }
.oalert-banner-resolve:hover { background: #b91c1c; }
.oalert-banner-resolve:disabled { opacity: .5; cursor: default; }

/* Pastille 🔔 dans la colonne « Alerte » de la liste. */
.oalert-badge { display: inline-flex; align-items: center; gap: 3px; background: #fef2f2; color: #b91c1c; border: 1px solid #fca5a5; border-radius: 999px; padding: 2px 9px; font-size: 8.5pt; font-weight: 800; text-decoration: none; white-space: nowrap; }
.oalert-badge:hover { background: #fee2e2; }

/* Ligne « Alertes » de la fiche (trigger façon Notes) : rouge quand une alerte est active + pastille compteur. */
.inote-trigger-btn.oalert-has-active { color: #b91c1c; border-color: #fca5a5; background: #fef2f2; }
.inote-trigger-btn.oalert-has-active svg { color: #dc2626; }
.oalert-count-pill { margin-left: auto; background: #dc2626; color: #fff; border-radius: 999px; padding: 1px 8px; font-size: 8.5pt; font-weight: 800; }

/* ─────────── Cloche d'alertes de commandes (dans la barre d'onglets, à DROITE, animée pour attirer l'œil) ─────────── */
.oabell { position: relative; display: inline-flex; align-items: center; margin-left: auto; }
/* Bandeau rouge « N alertes actives — commandes » collé à la cloche : rend l'alerte impossible à manquer. */
.oabell-banner { display: inline-flex; align-items: center; margin-right: 9px; padding: 7px 14px; border-radius: 999px; background: #dc2626; color: #fff; font-size: 9pt; font-weight: 800; white-space: nowrap; cursor: pointer; box-shadow: 0 2px 9px rgba(220,38,38,.3); animation: oabell-pulse 2.4s ease-in-out infinite; }
.oabell-banner:hover { background: #b91c1c; }
.oabell-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; background: #fff; border: 1px solid #fca5a5; color: #dc2626; cursor: pointer; box-shadow: 0 2px 9px rgba(220,38,38,.26); animation: oabell-pulse 2.4s ease-in-out infinite; }
.oabell-btn:hover { background: #fef2f2; }
.oabell-ic { animation: oabell-ring 2.4s ease-in-out infinite; transform-origin: 50% 5px; }
.oabell-count { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 999px; background: #dc2626; color: #fff; font-size: 8pt; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; border: 2px solid #fff; }
@keyframes oabell-ring { 0%, 50%, 100% { transform: rotate(0); } 5%, 15%, 25%, 35% { transform: rotate(13deg); } 10%, 20%, 30%, 40% { transform: rotate(-11deg); } 45% { transform: rotate(0); } }
@keyframes oabell-pulse { 0% { box-shadow: 0 3px 12px rgba(220,38,38,.28), 0 0 0 0 rgba(220,38,38,.45); } 70% { box-shadow: 0 3px 12px rgba(220,38,38,.28), 0 0 0 12px rgba(220,38,38,0); } 100% { box-shadow: 0 3px 12px rgba(220,38,38,.28), 0 0 0 0 rgba(220,38,38,0); } }
@media (prefers-reduced-motion: reduce) { .oabell-btn, .oabell-ic, .oabell-banner { animation: none; } }

.oabell-panel { position: fixed; z-index: 900; width: 340px; max-width: 86vw; max-height: 70vh; overflow-y: auto; background: #fff; border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 12px 40px rgba(15,23,42,.22); display: none; }
.oabell-panel.is-open { display: block; }
.oabell-head { padding: 10px 13px; font-weight: 800; font-size: 9.5pt; color: #b91c1c; background: #fef2f2; border-bottom: 1px solid #fee2e2; border-radius: 12px 12px 0 0; position: sticky; top: 0; }
.oabell-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 13px; border-bottom: 1px solid #f1f5f9; }
.oabell-item:last-child { border-bottom: none; }
.oabell-item-main { display: flex; flex-direction: column; gap: 2px; font-size: 9pt; color: #334155; min-width: 0; }
.oabell-num { font-weight: 800; color: var(--blue); text-decoration: none; }
.oabell-num:hover { text-decoration: underline; }
.oabell-title { color: #b91c1c; font-size: 9pt; }
.oabell-note { color: #475569; }
.oabell-since { color: #94a3b8; font-size: 8pt; }
.oabell-item-btns { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.oabell-resolve { width: 26px; height: 26px; border-radius: 7px; border: none; background: #dc2626; color: #fff; font-weight: 800; cursor: pointer; line-height: 1; }
.oabell-resolve:hover { background: #b91c1c; }
.oabell-resolve:disabled { opacity: .5; cursor: default; }

/* Carte « Alertes » de la fiche : compteur d'en-tête + liste (active rouge / programmée ambre) + ajout. */
.oalert-count-badge { background: #dc2626; color: #fff; border-radius: 999px; padding: 2px 9px; font-size: 8pt; font-weight: 800; white-space: nowrap; }
.oalert-wrap { display: grid; gap: 10px; }
.oalert { border: 1px solid var(--border); border-radius: 10px; padding: 9px 11px; }
.oalert--active { background: #fef2f2; border-color: #fca5a5; border-left: 3px solid #dc2626; }
.oalert--scheduled { background: #fffbeb; border-color: #fde68a; border-left: 3px solid #d97706; }
.oalert-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.oalert-state { font-size: 8.5pt; font-weight: 800; }
.oalert--active .oalert-state { color: #b91c1c; }
.oalert--scheduled .oalert-state { color: #b45309; }
.oalert-date { font-size: 8.5pt; color: #64748b; font-weight: 700; }
.oalert-title { font-weight: 700; font-size: 9.5pt; color: #1e293b; margin-top: 4px; }
.oalert-note { font-size: 9pt; color: #334155; margin-top: 2px; line-height: 1.4; white-space: pre-wrap; }
.oalert-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 6px; }
.oalert-by { font-size: 8pt; color: #94a3b8; }
.oalert-actions { display: flex; gap: 8px; }
.oalert-actions button { background: none; border: none; padding: 0; font-size: 8.5pt; color: #64748b; cursor: pointer; font-weight: 600; }
.oalert-actions button:hover { color: #dc2626; text-decoration: underline; }
.oalert-empty { font-size: 8.5pt; color: #94a3b8; }
.oalert-add { border-top: 1px dashed var(--border); padding-top: 10px; margin-top: 2px; }
.oalert-add .form-input { font-size: 9pt; }

/* Popup d'édition de la note / popup (i) de suivi d'une pièce (superposition centrée). */
.order-note-modal { position: fixed; inset: 0; z-index: 2200; background: rgba(15,23,42,.45); display: flex; align-items: center; justify-content: center; padding: 20px; }
.order-note-card { background: #fff; border-radius: 14px; box-shadow: 0 20px 60px rgba(0,0,0,.28); padding: 18px; width: 100%; max-width: 460px; }

/* Lignes du popup (i) de suivi (Commandé / Reçu + date). */
.order-info-line { display: flex; align-items: center; gap: 8px; padding: 8px 0; font-size: 10pt; border-bottom: 1px solid var(--border); }
.order-info-line:last-child { border-bottom: 0; }
.order-info-line strong { min-width: 78px; }
.order-info-line span:last-child { margin-left: auto; color: #334155; }
.order-info-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }

/* Popup (i) — HISTORIQUE des changements d'une pièce (chaque entrée : état, date/heure, employé). */
.order-hist-item { display: flex; align-items: flex-start; gap: 9px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.order-hist-item:last-child { border-bottom: 0; }
.order-hist-item .order-info-dot { margin-top: 5px; }
.order-hist-body { flex: 1; min-width: 0; }
.order-hist-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.order-hist-head strong { font-size: 10pt; color: #0f172a; }
.order-hist-when { font-size: 8.5pt; color: #64748b; white-space: nowrap; }
.order-hist-by { font-size: 9pt; color: #475569; margin-top: 1px; }

/* Popup des notes de pièce : chaque note = une carte horodatée séparée. */
.order-note-item { background: #f8fafc; border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; margin-bottom: 8px; }
.order-note-item-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.order-note-when { font-size: 8.5pt; color: #64748b; font-weight: 600; }
.order-note-del { background: none; border: 0; color: #dc2626; cursor: pointer; font-size: 10pt; line-height: 1; padding: 0 2px; }
.order-note-text { font-size: 9.5pt; color: #334155; white-space: pre-wrap; word-break: break-word; }
.order-note-empty { font-size: 9pt; color: #94a3b8; padding: 6px 2px; }

/* ─────────────────────────────────────────────────────────────────────────────
   ENCADRÉ D'INFORMATION d'une fiche — POINT UNIQUE.

   Un bloc de texte libre qu'on veut voir sans le chercher : consigne de scan d'un
   produit, note interne… Le même visuel vivait déjà en dur dans trois vues
   (formulaire produit, fiche produit, scanner) et aurait dérivé à la première
   retouche de couleur.

   `.info-box`        = note interne (ardoise, discret)
   `.info-box.blue`   = consigne d'action, celle que l'employé DOIT lire
   ───────────────────────────────────────────────────────────────────────────── */
.info-box { background: #f8fafc; border: 1px solid var(--border); border-left: 4px solid #94a3b8;
            border-radius: 10px; padding: 10px 12px; }
.info-box-title { font-size: 8.5pt; font-weight: 800; text-transform: uppercase; letter-spacing: .4px;
                  color: #475569; margin-bottom: 3px; }
.info-box-body { white-space: pre-line; line-height: 1.4; }

.info-box.blue { background: #eff6ff; border-color: #bfdbfe; border-left-color: #0f5ea8; }
.info-box.blue .info-box-title { color: #0f5ea8; }

/* Le même encadré sert aussi de conteneur de CHAMP dans un formulaire : ce qu'on saisit ici est
   exactement ce qui s'affichera dans l'encadré de la fiche et du scanner. Une classe séparée pour
   la version "formulaire" aurait dérivé de la version "lecture" à la première retouche. */
.info-box .form-label { color: #475569; font-weight: 700; }
.info-box .form-input { background: #fff; }
.info-box.blue .form-label { color: #0f5ea8; }
.info-box.blue .form-input { border-color: #bfdbfe; }


/* ═══ PIPELINE — LA CONSOLE ═══════════════════════════════════════════════════
   Une ligne par lead, avec TOUT ce qu'il faut pour décider sans ouvrir la fiche :
   téléphone et courriel entiers, adresse cliquable vers Google Maps, page d'origine,
   régie payée, et l'heure exacte de réception.

   ⚠️ RIEN N'EST TRONQUÉ dans les colonnes de contact et d'adresse (décision Philippe) :
   une valeur coupée par « … » oblige à ouvrir la fiche pour la lire, donc elle ne rend
   pas le service qu'on attend d'une colonne. Elle passe à la ligne à la place.

   Le VIOLET est réservé à Sophie ; le vert / ambre / rouge parlent de l'état du lead.
   Deux langages séparés, pour que « À reprendre » saute aux yeux. */

.pk-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; display: inline-block; }
.pk-age { font-size: 8pt; color: #94a3b8; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pk-age.urgent { color: #b91c1c; font-weight: 700; }



/* ── La ligne : 9 colonnes ── */
.pl-list-header,
.pl-row {
    display: grid;
    align-items: center;
    /* check · client · adresse · contact · projet · origine · reçu · statut · actions
       « Projet » est FIXE et non en fraction : mesuré, « Thermopompe » réclame 117 px (75 px de
       texte + les deux rembourrages) et la colonne en faisait 116. Un seul pixel manquait, et la
       pastille se coupait en plein mot — « Thermopomp / e centrale ». Une pastille n'a aucune
       raison de s'étirer sur grand écran : la largeur du mot le plus long suffit, avec sa marge. */
    grid-template-columns: 34px 1.35fr 1.45fr 1.5fr 124px 118px 116px 150px 116px;
    gap: 0;
}
@media (max-width: 1300px) {
    /* Sous cette largeur, le projet et l'origine cèdent la place : l'adresse et le contact
       restent entiers, c'est ce qui a été demandé. */
    .pl-list-header, .pl-row { grid-template-columns: 34px 1.35fr 1.45fr 1.5fr 116px 150px 116px; }
    .pl-col-type, .pl-col-origin { display: none; }
}
@media (max-width: 900px) {
    .pl-list-header, .pl-row { grid-template-columns: 34px 1.4fr 1.6fr 150px 116px; }
    .pl-col-adr, .pl-col-recu { display: none; }
}
/* Sur un téléphone, ce qu'on vient chercher dans la liste c'est le NUMÉRO — il reste, et c'est le
   nom qui cède du terrain. La colonne de statut garde une largeur fixe, sinon elle pousse la
   grille hors de la carte. */
@media (max-width: 600px) {
    /* Quatre pistes : coche · nom · contact · actions. C'est le STATUT qui cède — il se lit dans
       le panneau du lead, alors que le nom et le numéro sont ce qu'on vient chercher dans la liste
       quand on a le téléphone à la main. La colonne d'actions garde sa largeur fixe, sinon elle
       pousse la grille hors de la carte que `.pl-list { overflow:hidden }` rogne. */
    .pl-list-header, .pl-row { grid-template-columns: 30px 1.25fr 1fr 104px; }
    .pl-col-status { display: none; }
    .pl-col-contact { display: block; }
    /* L'icône de client est décorative : sur 375 px elle coûtait assez de largeur pour casser
       « Nathalie Bergeron » en trois morceaux. Le nom passe avant le pictogramme. */
    .pl-avatar { display: none; }
    .pl-row > div { padding: 6px 6px; }
}

.pl-col-check { display: flex; align-items: center; justify-content: center; padding: 0 !important; }
.pl-col-check input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--blue, #2563eb); }

.pl-col-contact, .pl-col-adr, .pl-col-origin, .pl-col-recu { min-width: 0; }
.pl-tel, .pl-mail, .pl-adr { display: block; text-decoration: none; word-break: break-word; }
.pl-tel  { font-size: 9pt; font-weight: 700; color: #0f172a; font-variant-numeric: tabular-nums; line-height: 1.3; }
.pl-tel:hover { color: var(--blue, #0f5ea8); }
.pl-mail { font-size: 8.5pt; color: var(--muted); margin-top: 0; line-height: 1.3; }
.pl-mail:hover { color: var(--blue, #0f5ea8); text-decoration: underline; }
.pl-adr  { font-size: 8.75pt; color: #334155; line-height: 1.3; }
.pl-adr:hover { color: var(--blue, #0f5ea8); text-decoration: underline; }
.pl-vide { color: #cbd5e1; font-size: 9pt; }

/* Origine : la page lue, puis la régie payée. */
.pl-page { display: inline-block; font-size: 8.25pt; font-weight: 700; color: #334155;
           background: #f1f5f9; border-radius: 6px; padding: 2px 7px; white-space: nowrap; }
.pl-page--none { background: transparent; color: var(--muted); font-weight: 600; padding-left: 0; }
.pl-regie { display: flex; align-items: center; gap: 4px; font-size: 8pt; font-weight: 700; margin-top: 1px; }

.pl-date { display: block; font-size: 8.5pt; font-weight: 600; color: #334155;
           font-variant-numeric: tabular-nums; white-space: nowrap; }


/* ─── Admin → Pipeline → Suivi automatique ───────────────────────────────────────────────
   Une carte par STATUT surveillé, et dedans une séquence d'étapes numérotées : les règles d'un
   groupe se suivent dans le temps, elles ne sont pas des lignes interchangeables. */
/* ─── Admin → Pipeline → Suivi automatique ───────────────────────────────────────────────
   Une carte, une ligne par règle, les colonnes nommées une seule fois en en-tête — le patron
   de l'écran Notifications, qui règle le même genre de matière. */
.pa-carte { padding: 0; overflow: hidden; }

.pa-tete,
.pa-ligne {
    display: grid;
    grid-template-columns: 62px minmax(0, 1fr) 140px 210px;
    gap: 0 14px;
    align-items: start;
}

.pa-tete {
    background: #f8fafc;
    border-bottom: 1px solid var(--border);
    padding: 9px 16px;
    font-size: 8pt;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted);
    align-items: center;
}

.pa-ligne { padding: 14px 16px; border-bottom: 1px solid var(--border); }
.pa-ligne:last-child { border-bottom: none; }

/* Champs SANS CADRE au repos : quatre cadres gris alignés donnaient l'air d'un formulaire brut.
   Ils se dessinent au survol et à la saisie — même choix que l'écran Notifications. */
.pa-nom, .pa-desc, .pa-sous, .pa-c-delai input {
    width: 100%;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 5px 8px;
    font-family: inherit;
    background: transparent;
    transition: border-color .12s, background .12s;
}
.pa-nom:hover, .pa-desc:hover, .pa-sous:hover, .pa-c-delai input:hover,
.pa-nom:focus, .pa-desc:focus, .pa-sous:focus, .pa-c-delai input:focus {
    border-color: var(--border);
    background: #fff;
    outline: none;
}
.pa-nom:focus, .pa-desc:focus, .pa-sous:focus, .pa-c-delai input:focus { border-color: var(--blue, #2563eb); }

.pa-nom  { font-size: 10pt; font-weight: 700; color: #1e293b; }
.pa-desc { font-size: 9pt; color: var(--muted); resize: vertical; line-height: 1.4; }

/* Ce que le CODE possède : visible, jamais modifiable. */
.pa-fixe {
    display: flex;
    flex-wrap: wrap;
    align-items: center;      /* le badge est plus haut que le texte : sans ça, la ligne décroche */
    gap: 7px;
    padding: 6px 8px 0;
    font-size: 8.5pt;
    color: #94a3b8;
}
.pa-fixe strong { color: #64748b; }
/* Le badge reste un vrai badge, juste un cran plus petit que dans les listes — il illustre,
   il n'est pas l'information principale de la ligne. */
.pa-fixe .status { font-size: 8pt; padding: 2px 9px; }

.pa-c-delai { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.pa-c-delai input { width: 62px; text-align: center; font-weight: 700; font-size: 10pt; }
.pa-c-delai span  { font-size: 8pt; color: var(--muted); line-height: 1.25; }

.pa-c-vers select { width: 100%; }


/* En-tête d'un GROUPE de règles : tout ce qui arrive à un lead resté sur le même statut. */
.pa-groupe {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 13px 16px; background: #f8fafc; border-bottom: 1px solid var(--border);
}
.pa-groupe-t { font-size: 9.5pt; font-weight: 700; color: #1e293b; }
.pa-groupe-n { font-size: 8.5pt; color: var(--muted); margin-left: auto; }

/* ⚠️ `flex-basis: 100%` : la cellule du délai est un conteneur FLEX, donc un `display:block` ne
   suffit pas — le rappel devenait un 3e élément sur la même ligne et écrasait « h ouvrables de
   silence » sur quatre lignes. */
.pa-jours { flex-basis: 100%; margin-top: 2px; font-size: 8pt; color: #94a3b8; }

/* Le TEXTO d'une règle : un bouton qui ouvre une fenêtre (décision Philippe). Il vivait dans la
   colonne de 200 px, où un message de deux phrases se lisait par une fente de trois lignes. */
.pa-sms-btn {
    display: flex; align-items: center; gap: 6px; width: 100%;
    margin-top: 8px; padding: 6px 9px;
    border: 1px solid var(--border); border-radius: 8px; background: #fff;
    font-family: inherit; font-size: 8.5pt; font-weight: 700; color: #334155;
    text-align: left; cursor: pointer; transition: border-color .12s, background .12s;
}
.pa-sms-btn:hover { border-color: rgba(15,94,168,.45); background: #f8fafc; }
.pa-sms-btn svg { flex-shrink: 0; color: #94a3b8; }
/* L'aperçu dit qu'il Y A un texte sans ouvrir — « texte par défaut » quand le champ est vide. */
.pa-sms-apercu {
    margin-left: auto; max-width: 55%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-weight: 400; font-size: 8pt; color: #94a3b8;
}
.pa-sous { margin-top: 4px; font-size: 8pt; font-weight: 600; color: #64748b; }

/* La fenêtre du texto — mêmes mesures que les autres modales du CRM. */
.pa-modale {
    position: fixed; inset: 0; z-index: 2200;
    background: rgba(15, 23, 42, .45);
    display: flex; align-items: center; justify-content: center; padding: 20px;
}
.pa-modale-boite {
    background: #fff; border-radius: 14px; width: 100%; max-width: 560px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .25); overflow: hidden;
}
.pa-modale-tete {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 15px 18px; border-bottom: 1px solid var(--border); font-size: 11pt;
}
.pa-modale-x { background: none; border: none; font-size: 21px; line-height: 1; color: var(--muted); cursor: pointer; }
.pa-modale-corps { padding: 16px 18px; }
.pa-modale-pied {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 12px 18px; border-top: 1px solid var(--border); background: #f8fafc;
}
.pa-texto-pied {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
    margin-top: 8px; font-size: 8.5pt; color: var(--muted); line-height: 1.45;
}
/* Au-delà de 160 caractères, Twilio facture deux messages au lieu d'un. */
.pa-texto-compte { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pa-texto-compte.depasse { color: #b45309; font-weight: 700; }



/* En-tête d'un GROUPE de règles : tout ce qui arrive à un lead resté sur le même statut. */

/* ─── UNE ÉTAPE ────────────────────────────────────────────────────────────────────────────
   Le numéro et le trait vertical font la séquence : on lit « d'abord ceci, ensuite cela » sans
   avoir à comparer deux lignes de tableau. */



/* Le délai DANS la phrase : « Après [16] h ouvrables de silence ». */

/* ─── CE QUE L'ÉTAPE FAIT ──────────────────────────────────────────────────────────────────
   Encadré et titré : c'est la question qu'on se pose en arrivant sur la page. Éparpillés, un
   envoi de texto et un changement de statut se lisaient comme deux réglages sans rapport. */


/* Le courriel se règle ailleurs : un lien, pas un champ. */
/* ⚠️ `flex-basis: 100%` : la cellule du délai est un conteneur FLEX, donc un `display:block`
   ne suffit pas — le rappel devenait un 3ᵉ élément sur la même ligne et écrasait
   « h ouvrables de silence » sur quatre lignes. La base pleine largeur le renvoie dessous. */


/* Champs SANS CADRE au repos : quatre cadres gris alignés donnaient l'air d'un formulaire brut.
   Ils se dessinent au survol et à la saisie — même choix que l'écran Notifications. */

/* Rendu comme il apparaîtra sous la pastille du lead : même taille, même gris. */
/* Le texto : rendu comme une bulle de message, pour qu'on juge le texte tel qu'il partira. */
/* Le TEXTO d'une règle : un bouton qui ouvre une fenêtre. Il vivait dans la colonne de 200 px,
   où un message de deux phrases se lisait par une fente de trois lignes avec ascenseur. */
/* L'aperçu dit qu'il Y A un texte sans ouvrir — « texte par défaut » quand le champ est vide. */

/* La fenêtre — mêmes mesures que les autres modales du CRM. */
.pa-modale {
    position: fixed;
    inset: 0;
    z-index: 2200;
    background: rgba(15, 23, 42, .45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.pa-modale-boite {
    background: #fff;
    border-radius: 14px;
    width: 100%;
    max-width: 560px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .25);
    overflow: hidden;
}
.pa-modale-tete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 15px 18px;
    border-bottom: 1px solid var(--border);
    font-size: 11pt;
}
.pa-modale-x {
    background: none;
    border: none;
    font-size: 21px;
    line-height: 1;
    color: var(--muted);
    cursor: pointer;
}
.pa-modale-corps { padding: 16px 18px; }
.pa-modale-pied {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    background: #f8fafc;
}
.pa-texto-pied {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-top: 8px;
    font-size: 8.5pt;
    color: var(--muted);
    line-height: 1.45;
}
.pa-texto-compte { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pa-texto-compte.depasse { color: #b45309; font-weight: 700; }

/* Ce que le CODE possède : visible, jamais modifiable. */
/* Le badge reste un vrai badge, juste un cran plus petit que dans les listes — il illustre,
   il n'est pas l'information principale de la ligne. */



/* Le rappel des heures ouvrables — une information de contexte, pas un avertissement. */
.pa-fenetre {
    background: #f8fafc;
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 14px;
    margin-bottom: 14px;
    font-size: 9pt;
    color: #475569;
    line-height: 1.5;
}
.pa-fenetre span { color: var(--muted); }

/* AVERTISSEMENT : ambre et jamais replié — il doit être lu avant d'allumer une règle. */
.pa-avis {
    background: #fffbeb;
    border: 1px solid #fcd34d;
    border-radius: 10px;
    padding: 11px 14px;
    margin-bottom: 14px;
    font-size: 9pt;
    color: #92400e;
    line-height: 1.5;
}
.pa-avis a { color: #92400e; font-weight: 700; }

.pa-note { margin-top: 12px; font-size: 8.5pt; color: var(--muted); line-height: 1.55; }

@media (max-width: 900px) {
    .pa-tete { display: none; }
    .pa-ligne { grid-template-columns: 1fr; gap: 10px; }
    .pa-c-delai, .pa-c-vers { padding-left: 8px; }
}

/* ─── Les deux couleurs d'un badge, en administration (admin/partials/_badge-colors) ───── */
.bc {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 18px;
    padding: 12px 14px;
    background: #f8fafc;
    border: 1px solid var(--border);
    border-radius: 10px;
}
.bc-champs { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; }
.bc-champ  { display: flex; flex-direction: column; gap: 4px; }
.bc-champ input[type="color"] {
    height: 38px; width: 76px; padding: 2px 4px; cursor: pointer;
    border: 1px solid var(--border); border-radius: 8px; background: #fff;
}
.bc-champ input[type="color"]:disabled { opacity: .45; cursor: not-allowed; }

.bc-auto { display: flex; align-items: center; gap: 7px; padding-bottom: 9px; font-size: 9pt; color: #475569; cursor: pointer; }
.bc-auto input { width: 15px; height: 15px; accent-color: var(--blue, #2563eb); cursor: pointer; }

.bc-apercu { display: flex; flex-direction: column; gap: 4px; margin-left: auto; }
.bc-badge  { align-self: flex-start; }

@media (max-width: 640px) {
    .bc-apercu { margin-left: 0; }
}

/* ── La carte du territoire, et son plein écran ──────────────────────────────
   Tracer un contour demande de voir la rivière, les autoroutes et les limites
   de ville en même temps : dans un cadre de 460 px, on zoome, on perd le nord,
   on redessine. Le plein écran n'est pas un confort, c'est ce qui rend le
   tracé possible.

   ⚠️ En `position: fixed` plutôt que par l'API Fullscreen du navigateur : les
   boutons Dessiner / Enregistrer restent visibles et cliquables. En plein écran
   natif, la barre d'outils sort du contexte et Échap referme tout, tracé
   compris. */
#terr-carte {
    height: 460px;
    border-radius: 12px;
    border: 1px solid var(--border);
}

#terr-zone.terr-plein {
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: #fff;
    padding: 14px 16px 16px;
    display: flex;
    flex-direction: column;
}
#terr-zone.terr-plein #terr-carte {
    flex: 1;
    height: auto;
    border-radius: 10px;
}

/* ── Onglet « Automatisations » de la fiche client ───────────────────────────
   Même facture que la page « Ce que Sophie utilise » : un libellé à gauche, un
   état à droite. Ces écrans répondent à la même question — « qu'est-ce qui est
   réglé, et où » — donc ils se lisent pareil. */
.ca-groupe {
    padding: 11px 16px;
    border-bottom: 1px solid var(--border);
    background: #f8fafc;
    font-size: 8.5pt;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
}

.ca-ligne {
    display: flex;
    gap: 16px;
    align-items: flex-start;
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
}
.ca-ligne:last-child { border-bottom: none; }

.ca-titre  { flex: 0 0 180px; font-size: 9pt; color: var(--muted); padding-top: 2px; }
.ca-valeur { flex: 1; min-width: 0; font-size: 9.5pt; line-height: 1.6; }
.ca-note   { display: block; margin-top: 3px; font-size: 8.5pt; color: #94a3b8; }
.ca-vide   { color: #94a3b8; }
.ca-pause  { margin-top: 3px; }

@media (max-width: 760px) {
    .ca-ligne { flex-direction: column; gap: 5px; }
    .ca-titre { flex: none; font-weight: 600; }
}

/* ── Historique de la fiche client ───────────────────────────────────────────
   COMPACT ET REPLIÉ : plus de cent lignes par client, et Philippe s'en sert pour
   retracer un dossier — « qui a fait quoi, quelle heure ». On PARCOURT d'abord,
   on lit ensuite : le détail s'ouvre au clic, et seules les entrées qui en ont un
   portent un chevron. Qui et quand vivent sur la ligne du titre plutôt que dans
   une colonne à droite, qui forçait chaque entrée à deux lignes de haut. */
.hi-ligne {
    border-bottom: 1px solid #f1f5f9;
}
.hi-ligne:last-child { border-bottom: none; }

.hi-tete {
    display: flex;
    gap: 9px;
    align-items: center;
    padding: 5px 4px;
    list-style: none;
}
.hi-tete::-webkit-details-marker { display: none; }
.hi-ouvrable > .hi-tete { cursor: pointer; }
.hi-ouvrable > .hi-tete:hover { background: #f8fafc; }

.hi-puce {
    flex: 0 0 19px;
    height: 19px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.hi-titre {
    flex: 1;
    min-width: 0;
    font-size: 9pt;
    font-weight: 600;
    line-height: 1.35;
}
.hi-doc { margin-left: 5px; font-weight: 700; color: var(--blue); text-decoration: none; }
.hi-doc:hover { text-decoration: underline; }

.hi-quand {
    flex: 0 0 auto;
    font-size: 8pt;
    color: #b0bccb;
    white-space: nowrap;
}

/* Le chevron dit qu'il y a quelque chose dessous — et il n'apparaît que là où c'est vrai. */
.hi-ouvrable > .hi-tete::after {
    content: '›';
    flex: 0 0 auto;
    color: #cbd5e1;
    font-size: 12pt;
    line-height: 1;
    transition: transform .15s;
}
.hi-ouvrable[open] > .hi-tete::after { transform: rotate(90deg); }

.hi-detail {
    font-size: 8.75pt;
    color: #475569;
    line-height: 1.5;
    padding: 4px 4px 9px 32px;
    white-space: pre-line;   /* les notes multi-lignes gardent leurs retours */
    word-break: break-word;
}

@media (max-width: 760px) {
    .hi-tete  { flex-wrap: wrap; }
    .hi-quand { flex: 1 0 100%; margin-left: 28px; }
}

/* ── Articles à commander, dans le popup de commande d'une facture (fiche facture) ──
   Bloc de LECTURE au-dessus d'un formulaire : fond gris, aucun cadre de champ — il ne doit pas
   ressembler à une saisie de plus. Le modèle est en monospace et `user-select:all` pour qu'un seul
   clic le sélectionne en entier (copier-coller vers le portail du fournisseur). */
.oc-items { background:#f8fafc; border:1px solid var(--border); border-radius:12px; padding:12px 14px; margin-bottom:18px; }
.oc-items-head { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:8px; font-size:9pt; color:#475569; font-weight:700; }
.oc-copy-all { border:1px solid var(--border); background:#fff; color:var(--blue); border-radius:8px; padding:4px 10px; font-size:8.5pt; font-weight:700; cursor:pointer; }
.oc-copy-all:hover { background:#eff6ff; }
.oc-item { display:grid; grid-template-columns:auto 1fr auto; align-items:baseline; gap:10px; padding:4px 0; font-size:9pt; }
.oc-model { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:9pt; font-weight:700; color:#07375f; background:#fff; border:1px solid var(--border); border-radius:6px; padding:2px 7px; cursor:pointer; user-select:all; -webkit-user-select:all; white-space:nowrap; }
.oc-model:hover { border-color:var(--blue); }
.oc-model.is-copied { background:#dcfce7; border-color:#16a34a; color:#166534; }
.oc-name { color:#64748b; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.oc-qty { color:#334155; font-weight:700; }
@media (max-width: 560px) {
    .oc-item { grid-template-columns:auto auto; }
    .oc-name { grid-column:1 / -1; white-space:normal; }
}

/* ── Avertissement « quantité ≠ appareils suivis » (fiche facture + modale des séries) ──
   Ambre : c'est un avertissement, il ne se replie pas et ne se ferme pas — il disparaît quand
   l'écart est corrigé. Voir Invoice::quantityMismatchLines(). */
.qty-mismatch { margin-top:10px; background:#fffbeb; border:1px solid #fcd34d; border-left:3px solid #d97706; border-radius:10px; padding:10px 12px; }
.qty-mismatch-head { font-size:9pt; font-weight:800; color:#92400e; margin-bottom:6px; }
.qty-mismatch-line { font-size:8.5pt; color:#78350f; line-height:1.45; margin-bottom:4px; }
.qty-mismatch-fix { font-size:8pt; color:#92400e; line-height:1.5; margin-top:6px; padding-top:6px; border-top:1px solid #fde68a; }

/* ── Bouton de création à deux choix : « + Nouvelle facture ▾ » (partials/_new-doc-button) ──
   `<details>` natif : le marqueur par défaut est retiré, le <summary> porte les classes `btn` du
   CRM pour rester identique aux autres boutons d'action de page. */
.nd { position:relative; display:inline-block; }
.nd-btn { list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.nd-btn::-webkit-details-marker { display:none; }
.nd-chev { font-size:8pt; opacity:.85; }
.nd[open] .nd-chev { transform:rotate(180deg); }
/* `fixed` et NON `absolute` : accroché au bouton, le menu se faisait rogner par l'overflow de la
   carte (onglet Soumissions d'une fiche client). Position posée par MphMenu.place(). */
/* `display:none` au repos : le menu est piloté par le JS du toggle (display:block via
   MphMenu.place), pas par le masquage natif du <details> — voir le partial pour le pourquoi. */
.nd-menu { display:none; position:fixed; z-index:1000; min-width:250px; background:#fff; border:1px solid var(--border); border-radius:12px; box-shadow:0 8px 28px rgba(0,0,0,.13); overflow:hidden; }
.nd-item { display:block; padding:10px 14px; text-decoration:none; border:0; background:none; text-align:left; width:100%; cursor:pointer; }
.nd-item + .nd-item { border-top:1px solid var(--border); }
.nd-item:hover { background:#f4f4f5; }
.nd-item b { display:block; font-size:9.5pt; color:#07375f; font-weight:700; }
.nd-item span { display:block; font-size:8.5pt; color:var(--muted); margin-top:1px; }

/* ═══════════════════════════════════════════════════════════════════════════
   COURRIEL — l'écran trois colonnes qui remplace Outlook
   Rail des boîtes · liste des messages · volet de lecture.
   La hauteur est calée sur la fenêtre (pas sur le contenu) : chaque colonne
   défile SÉPARÉMENT, sinon on perdrait le rail en descendant dans un message.
   ═══════════════════════════════════════════════════════════════════════════ */

/* En-tête du module Courriel : plus ramassée que celle des autres pages — voir la note dans la vue. */
/* Modale générique du module Courriel (envois programmés, gestion des dossiers, blocage d'expéditeur). */
.mail-modale {
    position: fixed; inset: 0; z-index: 3500; display: flex; align-items: center; justify-content: center;
    background: rgba(15, 23, 42, .45); padding: 16px;
}
.mail-modale[hidden] { display: none; }
.mail-modale-boite {
    background: #fff; border-radius: 16px; width: 100%; max-width: 520px; max-height: 85vh;
    display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 20px 60px rgba(0, 0, 0, .3);
}
.mail-modale-tete {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 20px; border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.mail-modale-corps { padding: 14px 20px; overflow-y: auto; }
.mail-prog-item {
    display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid #f1f5f9;
}
.mail-prog-item:last-child { border-bottom: 0; }

/* Actions CRM depuis un courriel (rattacher client, créer une tâche). */
.mail-crm { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.mail-crm-btn {
    min-height: 0; padding: 5px 11px; font-size: 8.5pt; font-weight: 600;
    color: #475569; background: #fff; border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
}
.mail-crm-btn:hover { color: var(--blue); border-color: var(--blue); }
.mail-crm-etat { font-size: 8.5pt; }
.mail-lier-item { padding: 8px 10px; border-radius: 8px; cursor: pointer; }
.mail-lier-item:hover { background: var(--blue-soft); }

/* Étiquettes (locales) — pastilles cliquables sous le message. */
.mail-etiq { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.mail-etiq-chip {
    padding: 3px 10px; border-radius: 999px; font-size: 8.5pt; font-weight: 600; cursor: pointer;
    background: #fff; border: 1px dashed #cbd5e1; color: #64748b;
}
.mail-etiq-chip:hover { border-color: var(--et); color: var(--et); }
.mail-etiq-chip.est-actif { border-style: solid; }

/* Contrôle de rappel daté dans la barre d'actions du message. */
.mail-rappel { display: inline-flex; align-items: center; gap: 5px; font-size: 9pt; color: #475569; }
.mail-rappel input[type="datetime-local"] {
    border: 1px solid var(--border); border-radius: 8px; padding: 4px 6px; font-size: 8.5pt; color: #475569;
}
.mail-rappel-x { background: none; border: 0; cursor: pointer; color: #b91c1c; font-size: 10px; padding: 2px; }

/* Bannière « boîte décrochée » — ambre, ne se replie jamais (avertissement). */
.mail-sync-alerte {
    display: flex; align-items: flex-start; gap: 9px; margin: 0 0 12px;
    padding: 10px 14px; border-radius: 10px;
    background: #fffbeb; border: 1px solid #f59e0b; color: #78350f;
    font-size: 9.5pt; line-height: 1.5;
}
.mail-sync-alerte[hidden] { display: none; }
.mail-sync-ic { font-size: 12pt; line-height: 1; flex: 0 0 auto; }

.mail-header {
    align-items: center; margin-bottom: 12px;
    /* L'ENTÊTE a le droit de passer à la ligne, PAS les outils. Sans ce `wrap`, la rangée unique
       finissait par se superposer au titre quand la place manquait (vécu à 1400 px : le champ de
       recherche recouvrait « Boîte de réception »). Ici, quand ça ne rentre plus, le bloc d'outils
       descend d'une rangée — mais il reste, lui, sur UNE seule ligne, ce qui était la demande. */
    flex-wrap: wrap;
}
/* Le titre ne se comprime jamais sous sa taille naturelle : c'est lui qui dit où l'on est. */
.mail-header > .page-title { flex: 0 0 auto; }

.mail-shell {
    display: grid;
    /* Les deux premières largeurs sont pilotées par des variables : les poignées de redimensionnement
       (`.mail-sep`) les réécrivent, et la largeur choisie est retenue par navigateur (localStorage),
       comme Outlook. Le `gap` a disparu : ce sont les poignées qui font l'espace, sinon on aurait
       14 px de vide en plus de la zone de saisie. */
    grid-template-columns: var(--mail-w-rail, 232px) 10px var(--mail-w-list, 390px) 10px minmax(0, 1fr);
    /* La hauteur est MESURÉE au chargement (voir `ajusterHauteur()` dans l'écran) : le chrome au-dessus
       varie selon l'écran et selon que le titre passe sur une ou deux lignes. Le `calc` codé en dur
       réservait 210 px là où il n'en fallait que 124 — 86 px de vide sous les panneaux, sur chaque
       écran, en permanence. La valeur ci-dessous n'est plus qu'un repli avant que le script passe. */
    height: var(--mail-h, calc(100vh - 150px));
    min-height: 460px;
}

/* ── « UN SEUL MESSAGE » : le module encadré dans le popup d'une fiche client ──
   Une seule colonne, sur toute la hauteur du cadre. On masque le rail, la liste et leurs poignées :
   la coquille compte CINQ enfants, et en laisser un visible relancerait la dislocation déjà vécue
   quand deux colonnes seulement recevaient cinq éléments. */
/* ⚠️ IL REMPLIT EXACTEMENT LE CADRE. `100vh` PLUS le padding de `.page` (18/26/22 px) déborde et
   fabrique une deuxième barre de défilement à l'intérieur du popup — celle qu'on voyait sur la
   capture. On annule donc le padding de la page et on prend toute la hauteur, ni plus ni moins. */
body:has(.mail-shell--seul) { overflow: hidden; }
body:has(.mail-shell--seul) .page { padding: 0; height: 100vh; display: flex; flex-direction: column; }
/* ⚠️ DOUBLE CLASSE — `.mail-shell.mail-shell--seul` ET NON `.mail-shell--seul` (défaut vécu le
   2026-09-01, deux fois de suite). Trois MÉDIA-REQUÊTES redéfinissent `.mail-shell` PLUS BAS dans ce
   fichier (1180 px, puis plus petit). À spécificité égale (0,1,0), c'est l'ORDRE qui tranche : elles
   gagnaient. Le cadre du popup fait 1150 px — donc sous 1180 — et la règle « 210px minmax(0,1fr) »
   s'appliquait : le seul enfant visible atterrissait dans la piste de 210 px, à gauche, avec tout le
   reste blanc. Exactement la capture que Philippe a envoyée deux fois.
   Deux classes = (0,2,0), qui bat (0,1,0) quel que soit l'ordre et quelle que soit la largeur.
   Y ajouter une média-requête plus bas ne pourra plus le casser. */
.mail-shell.mail-shell--seul { grid-template-columns: minmax(0, 1fr); height: 100%; flex: 1; min-height: 0; }
/* Le volet de lecture respire : sans le rail ni la liste, sa bordure de gauche n'a plus d'objet.
   `display: block` explicite : une média-requête le masque sous 1180 px (`.mail-shell .mail-col-read
   { display: none }`), ce qui viderait le popup — la moitié invisible du même défaut. */
.mail-shell.mail-shell--seul .mail-col-read { display: block; border-left: 0; padding-left: 14px; }
.mail-shell.mail-shell--seul .mail-col-rail,
.mail-shell.mail-shell--seul .mail-col-list,
.mail-shell.mail-shell--seul .mail-sep { display: none; }

/* ── Poignées de redimensionnement ──
   Larges de 10 px pour être attrapables à la souris, mais ne montrant qu'un trait de 1 px au survol :
   une barre visible en permanence entre trois colonnes déjà bordées faisait un écran quadrillé. */
.mail-sep {
    cursor: col-resize;
    position: relative;
    touch-action: none;
}
.mail-sep::after {
    content: '';
    position: absolute;
    top: 0; bottom: 0; left: 50%;
    width: 1px;
    background: transparent;
    transform: translateX(-50%);
    transition: background .12s;
}
.mail-sep:hover::after,
.mail-sep.is-active::after { background: var(--blue); width: 2px; }

/* Pendant le glissement : le curseur reste « col-resize » partout et rien ne se sélectionne. */
body.mail-resizing { cursor: col-resize; user-select: none; }
body.mail-resizing iframe { pointer-events: none; }   /* le corps HTML d'un courriel avalait le glissement */
.mail-col {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: auto;
    min-height: 0;               /* sans ça, une grille refuse de laisser défiler son enfant */
}

/* ── Rail des boîtes ── */
.mail-rail { padding: 10px; }
.mail-rail-box + .mail-rail-box { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px; }

/* Poignée de réordonnancement des boîtes (glisser-déposer, ordre propre à chaque employé).
   Posée en ABSOLU pour ne rien déplacer dans l'entête de la boîte : en flux, elle décalait le titre
   et cassait l'alignement de la pastille de non-lus. */
/* Poignée À GAUCHE (demande Philippe) : le contenu de la boîte est décalé d'un cran vers la droite pour
   lui laisser la place ; la poignée reste en ABSOLU (elle ne pousse donc pas le titre). */
.mail-rail-box { position: relative; padding-left: 16px; }
.mail-rail-poignee { position: absolute; top: 6px; left: 0; z-index: 2; }
/* « Gérer les dossiers » : une ligne discrète en bas de la liste des dossiers d'une boîte, alignée
   avec eux (contextuel, ne se bat plus avec la poignée de glissement du coin). */
.mail-rail-gerer {
    display: flex; align-items: center; gap: 6px; width: 100%; text-align: left;
    background: none; border: 0; cursor: pointer; color: #94a3b8;
    font-size: 8.5pt; font-weight: 600; padding: 5px 8px; margin-top: 2px; border-radius: 7px;
}
.mail-rail-gerer:hover { color: var(--blue); background: var(--blue-soft); }
.mail-rail-gerer-ic {
    display: inline-grid; place-items: center; width: 15px; height: 15px; border-radius: 4px;
    background: #e2e8f0; color: #64748b; font-weight: 700; line-height: 1; flex: 0 0 auto;
}
.mail-rail-gerer:hover .mail-rail-gerer-ic { background: var(--blue); color: #fff; }
.mail-rail-box + .mail-rail-box .mail-rail-poignee { top: 18px; }   /* la bordure + le padding du haut décalent l'entête */
@media (hover: hover) {
    /* Sur un appareil qui SURVOLE, la poignée reste discrète — sept poignées grises en permanence,
       c'est tout le bruit du rail. Au tactile (pas de survol), elle reste visible, sinon elle serait
       inatteignable. */
    .mail-rail-poignee { opacity: 0; transition: opacity .15s; }
    .mail-rail-box:hover .mail-rail-poignee { opacity: 1; }
}

/* ── Boîte repliable (volet Outlook) ── */
.mail-rail-toggle {
    width: 100%;
    background: none;
    border: 0;
    padding: 0 0 2px;
    cursor: pointer;
    text-align: left;
    /* `mph-core.css` impose min-height:28px à TOUT bouton (zone de clic des formulaires) : ici on
       veut la hauteur d'un titre de rail, pas celle d'un champ. */
    min-height: 0;
}
.mail-rail-chevron {
    flex: none;
    font-size: 13px;
    line-height: 1;
    color: #94a3b8;
    transform: rotate(90deg);            /* déplié : le chevron pointe vers le bas */
    transition: transform .15s;
}
.mail-rail-box.est-repliee .mail-rail-chevron { transform: rotate(0deg); }
.mail-rail-box.est-repliee .mail-rail-dossiers { display: none; }

/* Le compte de non-lus de la boîte n'apparaît QUE repliée : dépliée, il ferait doublon avec les
   pastilles de chaque dossier, juste en dessous. */
.mail-rail-n-boite { display: none; }
.mail-rail-box.est-repliee .mail-rail-n-boite { display: inline-block; }

/* La boîte qui contient le dossier affiché, quand elle est REPLIÉE. Tout étant replié par défaut,
   un lien direct vers un dossier laisserait sinon le rail entièrement fermé, sans dire où l'on
   est : le `is-active` du dossier, lui, est caché avec la liste. On ne la déplie pas de force
   (un repli qu'on défait au rechargement suivant est pire que pas de repli) — on la désigne. */
.mail-rail-box.porte-actif.est-repliee .mail-rail-title { background: #eaf3fb; border-radius: 8px; }
.mail-rail-title {
    display: flex; align-items: center; gap: 8px;
    font-size: 9pt; font-weight: 700; color: #07375f;
    padding: 4px 8px; text-transform: none;
}
.mail-rail-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.mail-rail-link {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 7px 10px; border-radius: 10px; text-decoration: none;
    color: #1f2937; font-size: 9.5pt;
}
.mail-rail-link:hover { background: #f1f5f9; }
.mail-rail-link.is-active { background: var(--blue); color: #fff; font-weight: 600; }
/* Compte de non-lus : un CHIFFRE BLEU aligné à droite, pas une pastille grise.
   La pastille grise faisait lire « (2) » comme une note de bas de page — on ne voyait pas qu'il y
   avait du courrier. Le bleu du CRM dit « à traiter » d'un coup d'œil, et le nom du dossier passe en
   gras : les deux repères se renforcent au lieu de se concurrencer (demande Philippe, 2026-08-24). */
.mail-rail-link .n {
    font-size: 9pt; font-weight: 800; color: var(--blue); background: none;
    padding: 0; flex: none; font-variant-numeric: tabular-nums; letter-spacing: -.2px;
}
.mail-rail-link:has(.n) { font-weight: 700; color: #0f172a; }
.mail-rail-link.is-active .n { color: #fff; }

/* Le total d'une BOÎTE repliée reste une pastille : là, il compte plusieurs dossiers et doit se
   distinguer d'un compte de dossier. */
.mail-rail-n-boite {
    font-size: 8pt; font-weight: 700; background: var(--blue); color: #fff;
    border-radius: 999px; padding: 1px 7px; flex: none;
}

/* ── Liste des messages ── */
.mail-search { padding: 10px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--card); z-index: 2; }
/* ── En-tête de groupe de dates ──
   Un repère collant : en faisant défiler, on sait toujours de quelle période on lit. */
.mail-groupe {
    position: sticky; top: 0; z-index: 3;
    padding: 7px 14px 5px;
    font-size: 8pt; font-weight: 700; text-transform: uppercase; letter-spacing: .6px;
    color: #64748b; background: #f8fafc; border-bottom: 1px solid var(--border);
}

/* ── Une ligne de la liste ── */
.mail-item {
    display: flex; align-items: flex-start; gap: 10px;
    width: 100%; text-align: left; background: none; border: 0;
    border-bottom: 1px solid var(--border); padding: 10px 12px; cursor: pointer;
    position: relative;
    transition: background .12s;
}
.mail-item:hover { background: #f8fafc; }
.mail-item:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.mail-item.is-open { background: #eef4fb; box-shadow: inset 3px 0 0 var(--blue); }
.mail-item.est-cochee { background: #eff6ff; }
/* Message en cours de traitement (le serveur n'a pas encore répondu) : on ne bloque pas, on atténue. */
.mail-item.est-occupee { opacity: .45; pointer-events: none; }

.mail-item-corps { flex: 1; min-width: 0; }

/* Initiales de l'expéditeur : on reconnaît un correspondant habituel à sa couleur avant de lire. */
.mail-item-inits {
    flex: none; width: 32px; height: 32px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 8.5pt; font-weight: 700; letter-spacing: .3px;
    margin-top: 1px; user-select: none;
}

/* La case ne se montre qu'au survol, au focus, ou quand une sélection est en cours : cinquante cases
   grises en permanence font tout le bruit de la colonne. */
.mail-item-choix { flex: none; display: flex; align-items: center; padding-top: 9px; margin-left: -2px; }
.mail-item-choix input { width: 15px; height: 15px; cursor: pointer; opacity: 0; transition: opacity .12s; }
.mail-item:hover .mail-item-choix input,
.mail-item.est-cochee .mail-item-choix input,
.mail-col-list.est-en-selection .mail-item-choix input,
.mail-item-choix input:focus-visible { opacity: 1; }

.mail-item-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.mail-item-who { font-size: 9.5pt; color: #0f172a; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-item-date { font-size: 8.5pt; color: var(--muted); flex: none; font-variant-numeric: tabular-nums; }
.mail-item-subject { font-size: 9.5pt; color: #1f2937; margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-item-preview { font-size: 8.5pt; color: var(--muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-item-tags { display: flex; gap: 6px; align-items: center; margin-top: 5px; flex-wrap: wrap; }
.mail-item-pj { color: #94a3b8; display: inline-flex; }
/* Répondu / transféré : discret mais net — un message traité doit se distinguer sans crier. */
.mail-item-verbe { color: #7c3aed; display: inline-flex; vertical-align: -2px; margin-right: 3px; }
.mail-verbe-bandeau {
    display: inline-flex; align-items: center; gap: 5px; margin-bottom: 8px;
    padding: 2px 9px; border-radius: 999px;
    font-size: 8.5pt; font-weight: 600; color: #6d28d9; background: #f5f3ff;
}

/* Dossier survolé pendant qu'on y traîne un message. */
.mail-rail-link.est-cible { background: var(--blue); color: #fff; box-shadow: 0 0 0 2px rgba(15,94,168,.25); }
.mail-item.est-tiree { opacity: .4; }
/* Le compte de messages d'un fil : une pastille, pas un « (4) » perdu dans le texte. */
.mail-item-fil {
    display: inline-block; margin-left: 5px; padding: 0 6px;
    font-size: 7.5pt; font-weight: 700; color: #475569;
    background: #e2e8f0; border-radius: 9px; vertical-align: 1px;
}

/* NON LU : le gras seul se remarque mal dans une longue liste — une pastille bleue tient lieu de
   marque, comme le point de couleur d'Outlook. */
.mail-item.is-unread { background: #fdfdff; }
.mail-item.is-unread::before {
    content: ''; position: absolute; left: 3px; top: 50%; transform: translateY(-50%);
    width: 4px; height: 22px; border-radius: 3px; background: var(--blue);
}
.mail-item.is-unread .mail-item-who,
.mail-item.is-unread .mail-item-subject { font-weight: 700; color: #07375f; }

/* Gestes au survol : traiter sans ouvrir. */
.mail-item-gestes {
    position: absolute; right: 8px; top: 7px;
    display: flex; gap: 2px; opacity: 0; transition: opacity .12s;
    background: linear-gradient(90deg, transparent, #f8fafc 22%);
    padding-left: 22px;
}
.mail-item:hover .mail-item-gestes { opacity: 1; }
.mail-geste {
    width: 26px; height: 26px; min-height: 0; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: #fff; border: 1px solid var(--border); border-radius: 7px;
    color: #64748b; cursor: pointer;
}
.mail-geste:hover { color: var(--blue); border-color: var(--blue); }
.mail-geste.est-marque { color: #ea580c; }
.mail-geste[data-geste="supprimer"]:hover { color: #dc2626; border-color: #dc2626; }
/* Sur tactile il n'y a pas de survol : les gestes restent visibles plutôt qu'inatteignables. */
@media (hover: none) {
    .mail-item-gestes { opacity: 1; position: static; padding-left: 0; background: none; }
    .mail-item-choix input { opacity: 1; }
}

/* ── Barre d'outils de la liste ── */
.mail-avancee {
    display: flex; flex-wrap: wrap; gap: 7px; align-items: flex-end;
    padding: 9px 10px; background: #f8fafc; border-bottom: 1px solid var(--border);
}
.mail-avancee[hidden] { display: none; }
.mail-avancee label { display: flex; flex-direction: column; gap: 3px; font-size: 8pt; font-weight: 600; color: #64748b; }
.mail-avancee input {
    height: 26px; padding: 0 7px; font-size: 8.5pt;
    border: 1px solid var(--border); border-radius: 7px; background: #fff; min-width: 118px;
}
.mail-avancee-vider { font-size: 8.5pt; color: #64748b; text-decoration: none; padding-bottom: 5px; }
.mail-avancee-vider:hover { color: #dc2626; }
.mail-mini-bouton.est-actif { background: var(--blue); border-color: var(--blue); color: #fff; }
.mail-search { display: flex; gap: 6px; align-items: center; }
.mail-search .form-input { flex: 1; min-width: 0; }

.mail-barre {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 7px 10px; border-bottom: 1px solid var(--border); background: #fff; flex-wrap: wrap;
}
.mail-filtres { display: flex; gap: 3px; }
.mail-filtre {
    min-height: 0; padding: 4px 10px; font-size: 8.5pt; font-weight: 600;
    background: none; border: 1px solid transparent; border-radius: 999px;
    color: #64748b; cursor: pointer;
}
.mail-filtre:hover { background: #f1f5f9; color: #0f172a; }
.mail-filtre.est-actif { background: var(--blue); border-color: var(--blue); color: #fff; }
.mail-barre-fin { display: flex; align-items: center; gap: 6px; }
.mail-mini-select {
    height: 26px; padding: 0 5px; font-size: 8.5pt; color: #475569;
    border: 1px solid var(--border); border-radius: 7px; background: #fff; cursor: pointer;
}
.mail-mini-bouton {
    min-height: 0; height: 26px; padding: 0 10px; font-size: 8.5pt; font-weight: 600;
    color: #475569; background: #fff; border: 1px solid var(--border); border-radius: 7px; cursor: pointer;
}
.mail-mini-bouton:hover { color: var(--blue); border-color: var(--blue); }

/* ── Barre de sélection multiple ──
   Même visuel que les listes du CRM (fond ardoise, boutons blancs translucides, « Supprimer » en
   contour rouge et jamais en rouge plein) : le module ne réinvente pas sa propre barre. */
/* Barre de sélection multiple = barre FIXE EN BAS de l'écran, comme partout dans le CRM (soumissions,
   factures — demande Philippe : elle s'ouvrait en haut de la liste et la poussait). Elle couvre la
   jauge de stockage (`.mail-pied`) le temps de la sélection, ce qui est le comportement voulu. */
.mail-lot {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 500;
    display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
    padding: 10px 24px; background: #1e293b; color: #fff;
    box-shadow: 0 -6px 20px rgba(15, 23, 42, .28);
}
.mail-lot[hidden] { display: none; }
/* Dégage la dernière ligne de la liste au-dessus de la barre fixe pendant la sélection (la classe est
   posée par `rafraichirLot()`) — sans ça, si la barre passe sur deux rangées, elle couvrirait le dernier
   courriel. */
.mail-col-list.est-en-selection { padding-bottom: 56px; }
.mail-lot-tous { display: flex; align-items: center; gap: 7px; font-size: 8.5pt; font-weight: 600; white-space: nowrap; }
.mail-lot-actions { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.mail-lot-actions button {
    min-height: 0; height: 26px; padding: 0 10px; font-size: 8.5pt; font-weight: 600;
    color: #fff; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.22);
    border-radius: 7px; cursor: pointer;
}
.mail-lot-actions button:hover { background: rgba(255,255,255,.22); }
.mail-lot-actions button.est-danger { background: none; border-color: rgba(248,113,113,.55); color: #fca5a5; }
.mail-lot-actions button.est-danger:hover { background: rgba(220,38,38,.18); color: #fecaca; }
.mail-lot-actions button.est-attenue { background: none; border-color: transparent; color: rgba(255,255,255,.55); }
.mail-lot-actions .mail-mini-select { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.22); color: #fff; }
.mail-lot-actions .mail-mini-select option { color: #0f172a; }

/* ── Volet de lecture ── */
.mail-read-head { padding: 16px 18px; border-bottom: 1px solid var(--border); }
.mail-read-subject { font-size: 13pt; font-weight: 700; color: #07375f; margin: 0 0 8px; }
.mail-read-meta { font-size: 9pt; color: var(--muted); line-height: 1.7; }
/* Le panneau de lecture s'organise en colonne : l'en-tête du message garde sa taille, le corps prend
   TOUT le reste. Sans ça, l'iframe restait à 460 px avec sa propre barre de défilement, et le bas du
   panneau était du blanc perdu — d'autant plus visible depuis que le module a gagné en hauteur. */
.mail-col-read { display: flex; flex-direction: column; }

/* `min-height: 0` est indispensable : sans lui, un enfant flex refuse de descendre sous la hauteur de
   son contenu et l'iframe repousserait le panneau au lieu de défiler. */
.mail-read-body { width: 100%; border: 0; flex: 1; min-height: 0; background: #fff; }
.mail-back { display: none; }

/* ── Gestes du volet de lecture (lot 2) ──
   Une rangée d'actions courtes, au-dessus des coordonnées : ce sont les gestes qu'on répète cent
   fois par jour, ils doivent être atteignables sans chercher. */
.mail-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin: 0 0 10px; }
.mail-actions .mail-act { padding: 5px 10px; border-radius: 9px; font-size: 8.5pt; }
.mail-actions .mail-act.est-marque { color: #b45309; border-color: #fcd34d; background: #fffbeb; }
.mail-actions .mail-act[disabled] { opacity: .55; cursor: progress; }

/* Taille UNIFORME des boutons du volet (les gros « pills » de .btn seraient trop lourds ici). */
.mail-actions .btn { padding: 7px 13px; border-radius: 9px; font-size: 9pt; font-weight: 700; }
/* Sorties du menu en COULEUR (demande Philippe) : archiver = bleu, bloquer = orange, supprimer = rouge. */
.mail-actions .mail-btn { border: 1px solid transparent; }
.mail-actions .mail-btn-archive { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }
.mail-actions .mail-btn-archive:hover { background: #dbeafe; border-color: #93c5fd; }
.mail-actions .mail-btn-block { background: #fff7ed; border-color: #fed7aa; color: #c2410c; }
.mail-actions .mail-btn-block:hover { background: #ffedd5; border-color: #fdba74; }
.mail-actions .mail-btn-danger { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }
.mail-actions .mail-btn-danger:hover { background: #fee2e2; border-color: #fca5a5; }
.mail-actions .mail-btn-notjunk { background: #f0fdf4; border-color: #bbf7d0; color: #15803d; }
.mail-actions .mail-btn-notjunk:hover { background: #dcfce7; border-color: #86efac; }
.mail-act-etat { font-size: 8.5pt; color: var(--muted); }
.mail-act-etat.echec { color: #b91c1c; }

/* ── Pièces jointes reçues ──
   De vrais fichiers ouvrables, plus une étiquette grise : l'extension à gauche pour reconnaître un
   PDF d'un coup d'œil, le nom au milieu (tronqué, jamais replié sur trois lignes), le poids à droite
   — c'est lui qui dit tout de suite si la pièce vaut la peine sur un téléphone en chantier. */
.mail-pieces { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.mail-piece  { display: inline-flex; align-items: center; gap: 8px; min-width: 0;
               max-width: min(320px, 100%); padding: 6px 10px; border: 1px solid var(--border);
               border-radius: 10px; background: #fff; text-decoration: none; color: #1f2937;
               font-size: 9pt; }
.mail-piece:hover { border-color: var(--blue); background: #f2f8fd; }
.mail-piece-ext    { flex: none; font-size: 7.5pt; font-weight: 700; letter-spacing: .3px;
                     color: #fff; background: var(--blue); border-radius: 5px; padding: 2px 5px; }
.mail-piece-nom    { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-piece-taille { flex: none; color: var(--muted); font-size: 8.5pt; }
.mail-pieces-echec { margin-top: 12px; font-size: 8.5pt; color: #b45309; }

/* ── Fenêtre de rédaction (lot 3) ── */
/* Écrire un courriel est une VRAIE tâche, pas une confirmation : la fenêtre prend l'écran comme le
   ferait Outlook (demande Philippe). `min()` plutôt qu'une largeur fixe — sur un portable, 1160 px
   déborderaient, et la fenêtre doit rester à l'aise sur toutes les machines du bureau. */
/* Taille par DÉFAUT généreuse (demande Philippe) : écrire un courriel occupe l'essentiel de l'écran.
   Les deux variables sont réécrites par la poignée du coin, et retenues par navigateur. */
.mc-boite   { background: #fff; border-radius: 16px; margin: auto;
              width: var(--mc-w, min(1500px, 96vw));
              height: var(--mc-h, min(94vh, 1180px));
              max-width: 96vw; max-height: 94vh;
              display: flex; flex-direction: column; position: relative;
              overflow: hidden; box-shadow: 0 8px 48px rgba(0,0,0,.25); }

/* Plein écran : la fenêtre mange tout, poignée et arrondis en moins. */
.mc-boite.est-plein { width: 100vw; height: 100vh; max-width: 100vw; max-height: 100vh; border-radius: 0; }
.mc-boite.est-plein .mc-poignee { display: none; }
/* Le fond garde un rembourrage de 24 px : en plein écran il volerait 32 px de largeur. La classe est
   posée par le JS sur le conteneur — `:has()` marchait sur le papier mais laissait la bande visible. */
#mail-compose.plein-ecran { padding: 0; }

/* Poignée de redimensionnement, coin bas-droit — deux traits obliques, discrets mais attrapables. */
.mc-poignee {
    position: absolute; right: 0; bottom: 0; width: 20px; height: 20px;
    cursor: nwse-resize; touch-action: none; z-index: 2;
    background:
        linear-gradient(135deg, transparent 46%, var(--border) 46%, var(--border) 54%, transparent 54%),
        linear-gradient(135deg, transparent 70%, var(--border) 70%, var(--border) 78%, transparent 78%);
}
body.mc-resizing { cursor: nwse-resize; user-select: none; }
/* Le rembourrage vit ICI et non en style inline : inline, il battait la règle du plein écran et
   laissait une bande de 32 px sur les côtés (vécu au banc). */
#mail-compose { display: none; padding: 24px 16px; }
#mail-compose.est-ouvert { display: flex !important; }
.mc-tete    { flex-shrink: 0; padding: 16px 20px; display: flex; align-items: center;
              justify-content: space-between; border-bottom: 1px solid var(--border); }
.mc-x       { background: none; border: 0; font-size: 20pt; line-height: 1; cursor: pointer;
              color: #94a3b8; padding: 0 4px; min-height: 0; }
/* Le corps occupe toute la hauteur restante et se répartit en colonne : les champs gardent leur
   taille, l'éditeur prend TOUT le reste (voir `.mc-editeur`). Sans ça, la fenêtre s'agrandissait mais
   la zone de frappe, elle, restait la même — on gagnait du vide. */
.mc-corps   { padding: 14px 20px 0; overflow-y: auto; flex: 1; display: flex; flex-direction: column; min-height: 0; }
.mc-champ   { margin-bottom: 10px; }
.mc-liens { display: flex; gap: 4px; }
.mc-liens button {
    min-height: 0; padding: 2px 8px; font-size: 8.5pt; font-weight: 600;
    color: #64748b; background: none; border: 1px solid var(--border); border-radius: 6px; cursor: pointer;
}
.mc-liens button:hover { color: var(--blue); border-color: var(--blue); }
.mc-outils  { margin-bottom: 0; border-radius: 10px 10px 0 0; flex-wrap: wrap; }
/* Les menus de la barre d'outils : la hauteur d'un bouton, pas celle d'un champ de formulaire
   (`mph-core.css` impose min-height:28px à tout <button>, et un <select> voisin doit s'aligner). */
.mc-select { height: 26px; padding: 0 4px; font-size: 8.5pt; border: 1px solid var(--border);
             border-radius: 6px; background: #fff; color: #475569; cursor: pointer; }
/* L'éditeur prolonge la barre d'outils : un seul bloc à l'œil, comme un vrai champ de saisie. */
.mc-editeur { border: 1px solid var(--border); border-top: 0; border-radius: 0 0 10px 10px;
              padding: 12px 14px; min-height: 220px; overflow-y: auto;
              /* `flex: 1` remplace l'ancien plafond de 40vh : la zone de frappe grandit avec la
                 fenêtre au lieu de laisser du blanc en dessous. */
              flex: 1;
              font-size: 10pt; line-height: 1.6; background: #fff; }
.mc-editeur:focus { outline: 2px solid var(--blue); outline-offset: -2px; }
/* ── Image sélectionnée dans l'éditeur, et sa poignée ── */
.mc-editeur img { cursor: pointer; }
.mc-editeur img.est-choisie { outline: 2px solid var(--blue); outline-offset: 1px; }
.mc-img-poignee {
    position: fixed; z-index: 2400; width: 14px; height: 14px;
    background: var(--blue); border: 2px solid #fff; border-radius: 3px;
    cursor: nwse-resize; touch-action: none; box-shadow: 0 1px 4px rgba(0,0,0,.3);
}
.mc-img-taille {
    position: fixed; z-index: 2400; background: #0f172a; color: #fff;
    font-size: 8.5pt; padding: 2px 7px; border-radius: 5px; pointer-events: none;
}

/* Zone de dépôt : retour visuel pendant qu'on traîne un fichier au-dessus de la fenêtre. */
.mc-boite.est-survolee { outline: 3px dashed var(--blue); outline-offset: -6px; }

.mc-pieces  { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.mc-pieces .status button { background: none; border: 0; cursor: pointer; color: inherit;
                            min-height: 0; padding: 0 0 0 6px; font-weight: 700; }
.mc-pied    { display: flex; align-items: center; justify-content: space-between; gap: 10px;
              padding: 14px 20px 18px; flex-wrap: wrap; }
.mc-etat    { font-size: 8.5pt; color: var(--muted); }
.mc-etat.echec  { color: #b91c1c; }
.mc-etat.reussi { color: #16a34a; }

/* Autocomplétion des destinataires (À/Cc/Cci). Ancrée au `body` en position fixe pour ne pas être
   rognée par la fenêtre de rédaction ; z-index au-dessus de la fenêtre (elle-même très haute). */
.mc-ac {
    position: fixed; z-index: 4000; max-height: 240px; overflow-y: auto;
    background: #fff; border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 10px 30px rgba(15, 23, 42, .16); padding: 4px;
}
.mc-ac-item { padding: 6px 9px; border-radius: 7px; cursor: pointer; display: flex; flex-direction: column; gap: 1px; }
.mc-ac-item.est-actif, .mc-ac-item:hover { background: var(--blue-soft); }
.mc-ac-nom  { font-size: 9pt; font-weight: 600; color: #0f172a; }
.mc-ac-mail { font-size: 8.5pt; color: #64748b; }

/* La barre d'outils de rédaction : même dessin que celle des gabarits, sans ses modes. */
.mc-outils, .editor-toolbar.mc-outils {
    display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
    padding: 6px 8px; background: #f8fafc; border: 1px solid var(--border);
}
.mc-outils button { background: #fff; border: 1px solid var(--border); border-radius: 7px;
                    padding: 3px 9px; font-size: 9pt; cursor: pointer; min-height: 0; }
.mc-outils button:hover { background: #e2e8f0; }
.mc-outils .sep { width: 1px; height: 18px; background: var(--border); margin: 0 3px; }

/* ── Écrans étroits : une seule colonne à la fois ──
   Sur un téléphone, la lecture prend tout l'écran et un bouton « ‹ Retour » ramène à la liste
   (règle 12 : une vue qui ne marche que sur ordinateur n'est pas terminée). */
@media (max-width: 1180px) {
    .mail-shell { grid-template-columns: 210px minmax(0, 1fr); }
    /* ⚠️ MASQUER LES POIGNÉES, sinon la grille se disloque (défaut vécu, 2026-08-27).
       La coquille compte CINQ enfants : rail, poignée, liste, poignée, lecture. Avec deux colonnes
       seulement, ils débordent en rangées — le rail occupe la colonne 1 de la première rangée, la
       LISTE la colonne 1 de la deuxième. Résultat : liste et rail empilés dans 210 px, objets
       tronqués à une lettre, et 60 % de l'écran vide. Ça touchait toutes les tablettes et les
       petits portables (861–1180 px). Les colonnes ne sont de toute façon plus redimensionnables
       à cette largeur : la poignée n'a plus rien à faire là. */
    .mail-sep { display: none; }
    .mail-shell .mail-col-read { display: none; }
    .mail-shell.is-reading .mail-col-list { display: none; }
    .mail-shell.is-reading .mail-col-read { display: block; }
}
@media (max-width: 860px) {
    .mail-shell { grid-template-columns: minmax(0, 1fr); height: auto; min-height: 0; }
    .mail-col { max-height: 72vh; }
    .mail-shell .mail-col-rail { max-height: 210px; }
    .mail-shell.is-reading .mail-col-rail { display: none; }
    .mail-back { display: inline-flex; }
}

/* ── Outils de la liste remontés dans l'entête (recherche, filtres, tri) ──
   Ils vivaient en haut de la colonne du milieu, où ils mangeaient trois rangées de la seule zone
   dont la hauteur sert à voir des messages. Ici, il faut leur retirer tout ce qui les habillait en
   bandeau de colonne : bordures, fond, position collante et rembourrage. */
.mail-outils {
    display: flex; align-items: center; gap: 8px; min-width: 0;
    /* Pousse le bloc contre les boutons d'action : « en haut à DROITE » du titre. */
    flex: 1 1 auto; justify-content: flex-end;
    /* UNE SEULE LIGNE (demande Philippe) : sur deux ou trois rangées, ces outils reprenaient à
       l'entête la hauteur qu'ils venaient de rendre à la liste — le déplacement n'aurait servi à
       rien. C'est le champ de recherche qui absorbe le manque de place, pas les boutons. */
    flex-wrap: nowrap;
}
.mail-outils .mail-search,
.mail-outils .mail-barre {
    padding: 0; border: 0; background: none; position: static; flex: 0 1 auto;
}

.mail-outils .mail-search .form-input { font-size: 9pt; }
/* HAUTEUR UNIQUE de toute la rangée (demande Philippe : « pas aligné ») — recherche, filtres, tri,
   « Tout lire » ET les boutons d'action partagent la même hauteur, sinon leurs bords haut/bas se
   décalent bien qu'ils soient centrés. `box-sizing:border-box` pour que la bordure d'un mini-bouton
   ne le rende pas 2 px plus haut que le champ sans bordure. */
.mail-outils .mail-search .form-input,
.mail-outils .mail-mini-select,
.mail-outils .mail-mini-bouton,
.mail-outils .mail-filtre,
.mail-header .page-actions .btn {
    height: 32px;
    box-sizing: border-box;
    display: inline-flex; align-items: center; justify-content: center;
}
/* Le padding vertical des boutons d'action est remplacé par la hauteur fixe : sinon `8px` + la hauteur
   du texte le repousserait au-dessus de 32 px. */
.mail-header .page-actions .btn { padding-top: 0; padding-bottom: 0; }
/* Dans la colonne, la barre écartait filtres et tri aux deux bouts (`space-between`). Ici elle
   n'occupe plus toute la largeur : tout se suit, sinon un vide s'ouvrirait au milieu de l'entête. */
.mail-outils .mail-barre { gap: 8px; justify-content: flex-start; flex-wrap: nowrap; }
/* Les libellés ne se cassent JAMAIS en deux : comprimés, « Pièces jointes » passait sur deux lignes
   et faisait grandir tout l'entête. Ils gardent leur largeur, et c'est la barre qui passe à la
   ligne s'il le faut. */
.mail-outils .mail-filtre,
.mail-outils .mail-mini-bouton { white-space: nowrap; }
.mail-outils .mail-filtres { flex-wrap: nowrap; }
/* Barre de recherche SOIGNÉE (demande Philippe) : un vrai champ arrondi, loupe à gauche, bouton de
   recherche avancée en icône à droite, halo bleu au focus. Elle s'étire pour remplir l'espace. */
.mail-outils .mail-search {
    flex: 1 1 300px; min-width: 190px; gap: 8px; height: 32px; padding: 0 6px 0 12px;
    background: #fff; border: 1px solid var(--border); border-radius: 999px; position: static;
    transition: border-color .15s, box-shadow .15s;
}
.mail-outils .mail-search:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
.mail-search-ic { width: 15px; height: 15px; color: #94a3b8; flex: 0 0 auto; }
.mail-search-input {
    flex: 1; min-width: 0; border: 0; outline: 0; background: none; height: 100%;
    font-size: 9.5pt; color: var(--text);
}
.mail-search-input::placeholder { color: #94a3b8; }
.mail-search-plus {
    display: inline-grid; place-items: center; width: 26px; height: 26px; flex: 0 0 auto;
    border: 0; border-radius: 999px; background: none; color: #94a3b8; cursor: pointer; transition: .15s;
}
.mail-search-plus svg { width: 15px; height: 15px; }
.mail-search-plus:hover { background: var(--blue-soft); color: var(--blue); }
.mail-search-plus.est-actif { background: var(--blue); color: #fff; }

/* ── Dropdowns du header (filtres, actions) ── */
.mail-dd { position: relative; display: inline-block; }
.mail-dd-btn { display: inline-flex; align-items: center; gap: 5px; }
.mail-dd-caret { font-size: 8pt; opacity: .7; }
.mail-dd-menu {
    position: absolute; top: calc(100% + 4px); left: 0; z-index: 600; display: none;
    min-width: 170px; padding: 5px; background: #fff; border: 1px solid var(--border);
    border-radius: 10px; box-shadow: 0 12px 30px rgba(15, 23, 42, .16);
}
.mail-dd-menu.mail-dd-droite { left: auto; right: 0; }
.mail-dd.est-ouvert .mail-dd-menu { display: block; }
/* Chaque item du menu = une ligne pleine largeur (on écrase le style « pastille » des .mail-filtre ET
   l'uniformisation de hauteur `.mail-outils .mail-filtre` — d'où la spécificité renforcée). */
.mail-dd .mail-dd-menu > a,
.mail-dd .mail-dd-menu > button {
    display: block; width: 100%; height: auto; text-align: left; box-sizing: border-box;
    padding: 7px 10px; border: 0; border-radius: 8px; background: none; cursor: pointer;
    font-size: 9pt; font-weight: 600; color: #334155; text-decoration: none; white-space: nowrap;
}
.mail-dd .mail-dd-menu > a:hover,
.mail-dd .mail-dd-menu > button:hover { background: var(--blue-soft); color: var(--blue); }
.mail-dd .mail-dd-menu > .mail-filtre.est-actif { background: var(--blue); color: #fff; }

/* Menu « ⋯ Plus » du volet de lecture : items + rangées à contrôle (rappel, déplacer, étiquettes). */
.mail-menu-actions { min-width: 216px; max-height: 62vh; overflow-y: auto; }
.mail-dd-sep { height: 1px; background: var(--border); margin: 5px 4px; }
.mail-dd .mail-dd-menu > .mail-dd-danger { color: #b91c1c; }
.mail-dd .mail-dd-menu > .mail-dd-danger:hover { background: #fef2f2; color: #b91c1c; }
.mail-dd-row { display: flex; align-items: center; gap: 8px; padding: 5px 10px; }
.mail-dd-lbl { font-size: 8.5pt; font-weight: 600; color: #64748b; white-space: nowrap; }
.mail-dd-row .mail-deplacer,
.mail-dd-row input[type="datetime-local"] {
    flex: 1; min-width: 0; height: 28px; border: 1px solid var(--border); border-radius: 7px;
    padding: 0 6px; font-size: 8.5pt; color: #475569; background: #fff;
}
.mail-dd-etiq { display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 10px 8px; }

/* La recherche avancée se déplie SOUS l'entête, sur toute la largeur : son bouton est maintenant en
   haut, un panneau qui s'ouvrirait au milieu de la colonne n'aurait plus de rapport avec lui. */
.mail-avancee { margin: 0 0 12px; }

@media (max-width: 1100px) {
    /* Sous cette largeur, l'entête ne tient plus sur une ligne : les outils passent dessous et
       prennent toute la largeur plutôt que de comprimer le titre à trois lettres. */
    .mail-outils { width: 100%; }
}
@media (max-width: 900px) {
    /* ⚠️ LA LIGNE UNIQUE S'ARRÊTE ICI. Sur un téléphone, `nowrap` ne comprime pas : il DÉBORDE, et
       la moitié gauche des filtres sortait de l'écran, hors d'atteinte (vécu à 430 px). La demande
       « tout sur une ligne » vise l'écran de bureau ; sur mobile, on empile. */
    .mail-outils,
    .mail-outils .mail-barre,
    .mail-outils .mail-filtres { flex-wrap: wrap; }
    .mail-outils .mail-search { flex: 1 1 100%; }
}

/* ── Pied du module courriel : l'espace occupé par la boîte ouverte ──
   Posé dans la bande vide sous la coquille : l'information est utile tous les jours mais n'a pas à
   disputer sa place aux outils de la liste. */
.mail-pied {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-top: 8px; padding: 7px 12px;
    background: var(--card); border: 1px solid var(--border); border-radius: 10px;
    font-size: 8.5pt; color: #475569;
}
.mail-pied-nom   { font-weight: 700; color: #0f172a; }
.mail-pied-barre { width: 120px; height: 6px; background: #e2e8f0; border-radius: 99px; overflow: hidden; flex: none; }
.mail-pied-barre > span { display: block; height: 100%; }
.mail-pied-libre { color: #64748b; }
/* Poussée à droite : c'est une note de bas de page, pas une donnée qu'on lit. */
.mail-pied-date  { margin-left: auto; color: #94a3b8; }
@media (max-width: 700px) {
    .mail-pied-date { margin-left: 0; }
}

/* ── Éditeur HTML partagé (`partials/_html-editor`) ──
   Trois onglets : on écrit, on voit le code, on voit le résultat. Les classes remplacent les ids de
   l'éditeur des gabarits de notification : il ne pouvait exister qu'une fois par page, or l'écran
   des boîtes courriel en porte deux. */
.eh-onglets { display: flex; gap: 3px; border-bottom: 1px solid var(--border); }
.eh-onglet {
    padding: 6px 16px; border: 1px solid var(--border); border-bottom: none;
    background: #f8fafc; color: #64748b; border-radius: 8px 8px 0 0;
    cursor: pointer; font-size: 9.5pt; min-height: 0;
}
.eh-onglet.est-actif { background: #fff; color: #0f172a; font-weight: 600; margin-bottom: -1px; }
.eh-barre {
    display: flex; gap: 5px; flex-wrap: wrap; align-items: center;
    padding: 6px 10px; background: #f8fafc; border: 1px solid var(--border); border-top: none;
}
.eh-barre button {
    padding: 2px 9px; border: 1px solid var(--border); background: #fff; border-radius: 5px;
    cursor: pointer; font-size: 9.5pt; line-height: 1.4; min-height: 0;
}
.eh-barre button:hover { background: #e2e8f0; }
.eh-sep { width: 1px; align-self: stretch; background: var(--border); margin: 2px 3px; }

.eh-visuel, .eh-html, .eh-apercu {
    width: 100%; box-sizing: border-box;
    border: 1px solid var(--border); border-top: none; border-radius: 0 0 9px 9px;
    background: #fff;
}
.eh-visuel {
    padding: 12px 14px; outline: none; overflow: auto;
    font-family: Arial, sans-serif; font-size: 11pt; line-height: 1.7; color: #1e293b;
    overflow-wrap: break-word;
}
.eh-visuel:focus { border-color: var(--blue); }
.eh-visuel p { margin: .4em 0; }
.eh-visuel ul, .eh-visuel ol { padding-left: 1.4em; margin: .4em 0; }
/* Le CODE se lit en chasse fixe : c'est tout l'intérêt de l'onglet HTML. */
.eh-html {
    padding: 12px 14px; resize: vertical; outline: none;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 9.5pt; line-height: 1.6; color: #0f172a;
}
.eh-html:focus { border-color: var(--blue); }
.eh-apercu { display: block; }

/* ── Choix d'un créneau : calendrier du mois + colonne d'heures ──────────────────────────────
   POINT UNIQUE du visuel « quand » côté CRM. C'est le MÊME format que le widget public
   (`public/js/mph-reservation.js`, décision Philippe) : le bureau et le client regardent la même
   chose, donc on décrit un rendez-vous au téléphone sans traduire d'un écran à l'autre.
   La liste verticale d'avant demandait vingt jours de défilement pour trouver une heure.
   Les couleurs viennent des variables du CRM — pas du thème du widget, qui est réglable par
   l'admin et n'a rien à faire dans une page interne. */
/* ⚠️ Le calendrier est BORNÉ. Ses cases sont en `aspect-ratio:1` : laissées en `1fr` sur une carte
   pleine largeur, sept colonnes donnent des cases de 125 px — un mois qui remplit l'écran pour
   trente chiffres. Le widget public tient dans ~430 px, on garde la même échelle. Les heures, elles,
   prennent le reste et s'étalent sur plus de colonnes. */
.bkc-quand { display: grid; grid-template-columns: minmax(0, 440px); gap: 16px; justify-content: start; }
/* Côte à côte seulement quand la carte est vraiment large : la requête média mesure la FENÊTRE,
   pas la carte, et une carte étroite écraserait le mois à des cases de 40 px. En dessous, le
   calendrier passe au-dessus des heures — comme le widget sur téléphone. */
@media (min-width: 1024px) {
    .bkc-quand { grid-template-columns: minmax(320px, 440px) minmax(240px, 520px); align-items: start; }
}

.bkc-cal { background: #fff; border: 1px solid var(--border); border-radius: 13px; padding: 14px; }
.bkc-cal-tete { display: flex; align-items: center; justify-content: center; gap: 14px; margin-bottom: 12px; }
.bkc-cal-tete b { font-size: 11pt; font-weight: 750; min-width: 140px; text-align: center; text-transform: capitalize; }
.bkc-nav-m {
    width: 30px; height: 30px; border-radius: 9px; border: 1.5px solid var(--border);
    background: #fff; cursor: pointer; color: var(--muted); font-size: 13pt; line-height: 1;
    transition: all .15s; padding: 0;
}
.bkc-nav-m:hover:not(:disabled) { border-color: var(--blue); color: var(--blue); }
.bkc-nav-m:disabled { opacity: .35; cursor: not-allowed; }

.bkc-grille-j { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.bkc-jn {
    text-align: center; font-size: 8pt; font-weight: 750; color: var(--muted);
    padding: 5px 0; text-transform: uppercase; letter-spacing: .3px;
}
.bkc-c {
    position: relative; aspect-ratio: 1; border: 0; background: 0; border-radius: 9px;
    cursor: pointer; font-size: 10pt; font-weight: 700; color: #0f172a; transition: all .14s;
    padding: 0; min-height: 0;   /* mph-core impose min-height:28px à tout <button> */
}
.bkc-c.vide { visibility: hidden; }
.bkc-c.off { color: #c3c9d4; cursor: not-allowed; }
/* Le trait vert sous un jour offert : on voit d'un coup d'œil où il reste de la place. */
.bkc-c.libre:after {
    content: ""; position: absolute; left: 22%; right: 22%; bottom: 5px;
    height: 3px; border-radius: 3px; background: #12b76a;
}
.bkc-c.libre:hover { background: #eaf3fb; }
/* ⚠️ La date CHOISIE doit battre le survol — même piège que dans le widget : le sélecteur de
   survol porte une classe de plus, donc il gagnait, et le jour cliqué restait pâle tant que la
   souris était dessus, c'est-à-dire juste au moment où on regarde. */
.bkc-c.libre.on, .bkc-c.libre.on:hover { background: var(--blue); color: #fff; }
.bkc-c.libre.on:after, .bkc-c.libre.on:hover:after { background: rgba(255,255,255,.9); }

.bkc-heures-p { background: #fff; border: 1px solid var(--border); border-radius: 13px; padding: 14px; }
.bkc-heures-t {
    text-align: center; font-size: 9pt; font-weight: 750; color: var(--blue);
    padding-bottom: 10px; border-bottom: 1px solid var(--border); margin-bottom: 10px;
    text-transform: capitalize;
}
.bkc-heures { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 7px; }
.bkc-h {
    padding: 9px 6px; border: 1.5px solid var(--border); border-radius: 9px; background: #fff;
    cursor: pointer; font-size: 9.5pt; font-weight: 750; line-height: 1.35; transition: all .13s;
}
.bkc-h span { display: block; font-size: 8pt; font-weight: 600; color: var(--muted); }
.bkc-h:hover { border-color: var(--blue); color: var(--blue); background: #eaf3fb; }
.bkc-h:hover span { color: var(--blue); }
.bkc-h.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.bkc-h.on span { color: rgba(255,255,255,.85); }
