/* ============================================================================
   JTI Terrain — Design System « Clair & net » (Direction B)
   Phase 1 : peau appliquée PAR-DESSUS le template existant (chargée en dernier).
   Tokens d'abord, composants ensuite. Aucune vue existante n'est modifiée.
   ========================================================================== */

:root {
  /* -- couleurs -- */
  --jti-bg:        #F2F5F9;   /* fond application */
  --jti-surface:   #FFFFFF;   /* cartes, topbar, sidebar */
  --jti-ink:       #182234;   /* texte principal */
  --jti-muted:     #64748B;   /* texte secondaire */
  --jti-faint:     #94A3B8;   /* placeholders, désactivé */
  --jti-border:    #E2E8F2;   /* bordures de cartes */
  --jti-hair:      #EDF1F7;   /* séparateurs de lignes */
  --jti-primary:   #2050C7;   /* cobalt — le seul accent */
  --jti-primary-d: #1A42A6;   /* cobalt hover */
  --jti-primary-t: #E8EEFA;   /* teinte cobalt (fonds actifs) */
  --jti-focus:     rgba(32, 80, 199, .18);
  /* -- sémantique (états, jamais décoratif) -- */
  --jti-ok:        #0E9F6E;
  --jti-ok-t:      #E3F5EE;
  --jti-warn:      #B45309;
  --jti-warn-t:    #FCF0DF;
  --jti-danger:    #C22C2C;
  --jti-danger-t:  #FBE9E9;
  /* -- barre latérale sombre --
     La barre de navigation est le seul bloc sombre de l'application : ses
     couleurs vivent donc dans leur propre jeu de jetons, pour ne pas avoir à
     retoucher chacune des règles si la teinte doit bouger. Les états (survol,
     actif, séparateurs) sont exprimés en blanc transparent : ils suivent
     automatiquement le fond, quelle que soit sa valeur. */
  --jti-side-bg:      #141C2E;   /* fond de la barre */
  --jti-side-panel:   #1E2942;   /* panneaux flottants, carte du groupe ouvert */
  --jti-side-ink:     #FFFFFF;   /* libellés */
  --jti-side-ink-2:   rgba(255, 255, 255, .82);  /* sous-menus, menu profil */
  --jti-side-icon:    rgba(255, 255, 255, .72);  /* icônes au repos */
  --jti-side-faint:   rgba(255, 255, 255, .48);  /* intitulés de section, placeholders */
  --jti-side-hover:   rgba(255, 255, 255, .09);  /* survol */
  --jti-side-line:    rgba(255, 255, 255, .11);  /* séparateurs, bordures */
  --jti-side-field:   rgba(255, 255, 255, .07);  /* champ de recherche */
  --jti-side-accent:  #8FB2FF;   /* cobalt éclairci : lisible sur fond sombre */
  --jti-side-accent-t: rgba(143, 178, 255, .16);
  --jti-side-focus:   rgba(143, 178, 255, .30);
  --jti-side-danger:  #FF9B9B;
  --jti-side-danger-t: rgba(255, 155, 155, .16);
  /* Pilule de l'élément actif : le dégradé de marque (--jti-grad) éclairci d'un
     cran, sans quoi le bleu se fondrait dans le fond sombre. */
  --jti-side-grad: linear-gradient(180deg, #3E6FE6 0%, #2F5FD8 55%, #2A55C8 100%);
  /* -- géométrie -- */
  --jti-r-sm: 7px;
  --jti-r:    10px;
  --jti-r-lg: 13px;
  --jti-shadow:    0 1px 2px rgba(24,34,52,.05), 0 6px 20px rgba(24,34,52,.05);
  --jti-shadow-lg: 0 12px 30px rgba(24,34,52,.10);
  /* -- typo -- */
  --jti-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
              "Helvetica Neue", "Open Sans", Arial, sans-serif;
  --jti-mono: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
}

/* ============================== base ==================================== */

html { background: var(--jti-bg); }
body {
  background: var(--jti-bg) !important;
  color: var(--jti-ink);
  font-family: var(--jti-font);
  font-size: 14px;
}
.page-wrapper { background: var(--jti-bg) !important; }

h1, h2, h3, h4, h5, h6,
.card-title { color: var(--jti-ink); font-family: var(--jti-font); }
a { color: var(--jti-primary); }
a:hover { color: var(--jti-primary-d); }
.text-muted { color: var(--jti-muted) !important; }
.text-themecolor { color: var(--jti-primary) !important; }

/* Le préchargeur du template est supprimé des layouts (cf. default.ctp).
   Cette règle reste comme filet de sécurité si une vue en réintroduit un. */
.preloader { display: none !important; }

/* ============================== topbar ================================== */

.topbar { background: var(--jti-surface) !important; box-shadow: none;
  border-bottom: 1px solid var(--jti-border); }
.topbar .navbar-header,
.topbar .top-navbar .navbar-header { background: var(--jti-surface) !important; }
.topbar .top-navbar .navbar-header .navbar-brand .dark-logo { display: inline-block !important; }
.topbar .top-navbar .navbar-header .navbar-brand .light-logo { display: none !important; }
.topbar .navbar-nav .nav-item > a.nav-link {
  color: var(--jti-muted) !important; }
.topbar .navbar-nav .nav-item > a.nav-link:hover,
.topbar .navbar-nav .nav-item > a.nav-link:focus { color: var(--jti-primary) !important; }
.topbar .profile-pic { border: 2px solid var(--jti-border); }

/* pastille de notification */
.topbar .badge-danger { background: var(--jti-danger); }

/* Nom du produit dans la barre supérieure (remplace l'ancienne image « Admin ») */
.topbar .navbar-brand .jti-wordmark {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--jti-ink);
  vertical-align: middle;
  white-space: nowrap;
}

/* sélecteur de langue (FR / EN / AR) */
.jti-langs { display: flex; align-items: center; gap: 2px; padding: 0 10px; }
.jti-lang {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--jti-muted);
  padding: 4px 9px;
  border-radius: 6px;
  text-decoration: none;
  transition: background .15s ease, color .15s ease;
}
.jti-lang:hover { background: var(--jti-bg); color: var(--jti-ink); text-decoration: none; }
.jti-lang.on { background: var(--jti-primary-t); color: var(--jti-primary); }
@media (max-width: 575px) { .jti-langs { padding: 0 4px; } .jti-lang { padding: 4px 6px; } }

/* menus déroulants du topbar */
.dropdown-menu { border: 1px solid var(--jti-border); border-radius: var(--jti-r);
  box-shadow: var(--jti-shadow-lg); }
.mailbox .drop-title { color: var(--jti-ink); font-weight: 600;
  border-bottom: 1px solid var(--jti-hair); }
.mailbox .message-center a:hover { background: var(--jti-bg); }

/* ============================== sidebar ================================= */

.left-sidebar,
.card-no-border .left-sidebar { background: var(--jti-side-bg) !important;
  border-right: 1px solid var(--jti-side-line); box-shadow: none; }
.scroll-sidebar { background: transparent; }
.sidebar-nav,
.card-no-border .sidebar-nav { background: var(--jti-side-bg) !important; }
.sidebar-nav ul { background: var(--jti-side-bg); }

.sidebar-nav #sidebarnav li a {
  display: flex;
  align-items: center;
  gap: 11px;
  color: var(--jti-side-ink) !important;
  border-radius: 9px;
  margin: 1px 10px;
  padding: 9px 11px;
  font-size: 13px;
  font-weight: 500 !important;
  line-height: 1.35;
  border-left: 0 !important;
  opacity: 1;
  position: relative;
  transition: background .14s ease, color .14s ease;
}
/* Les libellés étaient tronqués à 20 caractères (« DEMANDES SUPERVIS… ») :
   plusieurs modules devenaient indistinguables. On les laisse tenir sur deux
   lignes plutôt que de les couper. */
.sidebar-nav #sidebarnav li a .hide-menu {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.sidebar-nav #sidebarnav li a i {
  flex: 0 0 auto;
  width: 20px;
  text-align: center;
  color: var(--jti-side-icon);
  font-size: 15px;
  transition: color .14s ease;
}
.sidebar-nav #sidebarnav li a:hover {
  background: var(--jti-side-hover); color: var(--jti-side-ink) !important; }
.sidebar-nav #sidebarnav li a:hover i { color: var(--jti-side-ink); }
.sidebar-nav #sidebarnav li a:focus-visible {
  outline: 2px solid var(--jti-side-accent); outline-offset: -2px; }

/* État actif : pastille cobalt + repère vertical, pour se repérer d'un coup
   d'œil dans une liste longue. */
.sidebar-nav #sidebarnav li a.active,
.sidebar-nav #sidebarnav > li > a.active {
  background: var(--jti-side-accent-t) !important;
  color: var(--jti-side-accent) !important;
  font-weight: 600 !important;
  border-left: 0 !important;
}
.sidebar-nav #sidebarnav li a.active::before {
  content: "";
  position: absolute;
  inset-inline-start: -10px;
  top: 50%; transform: translateY(-50%);
  width: 3px; height: 20px;
  border-radius: 0 3px 3px 0;
  background: var(--jti-side-accent);
}
[dir="rtl"] .sidebar-nav #sidebarnav li a.active::before { border-radius: 3px 0 0 3px; }
.sidebar-nav #sidebarnav li a.active i { color: var(--jti-side-accent); }

/* Sous-menus : filet de rattachement pour montrer la hiérarchie. */
.sidebar-nav #sidebarnav li ul { background: transparent; position: relative; }
.sidebar-nav #sidebarnav li ul::before {
  content: "";
  position: absolute;
  inset-inline-start: 30px;
  top: 4px; bottom: 4px;
  width: 1px;
  background: var(--jti-side-line);
}
.sidebar-nav #sidebarnav li ul li a {
  padding-inline-start: 42px;
  font-size: 12.5px;
  color: var(--jti-side-ink-2) !important;
}
.sidebar-nav #sidebarnav li ul li a.active::before { inset-inline-start: 26px; height: 16px; }

/* La flèche des groupes suit l'état ouvert/fermé. */
.sidebar-nav #sidebarnav li a.has-arrow::after {
  border-color: var(--jti-side-faint);
  inset-inline-end: 14px;
}
.sidebar-nav #sidebarnav li a.has-arrow:hover::after { border-color: var(--jti-side-ink); }

/* Séparateurs du gabarit : simples espaces. */
.sidebar-nav ul li.nav-devider { background: transparent; height: 4px; margin: 0; }

/* Intitulé de section. */
.sidebar-nav #sidebarnav li.jti-navlabel {
  padding: 16px 21px 6px;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--jti-side-faint);
}

/* ------------------------------ recherche ------------------------------- */
.sidebar-nav #sidebarnav li.jti-navsearch { padding: 4px 10px 10px; }
.jti-navsearch-box { position: relative; display: flex; align-items: center; }
.jti-navsearch-box > i {
  position: absolute; inset-inline-start: 11px;
  font-size: 12px; color: var(--jti-side-faint); pointer-events: none;
}
.jti-navsearch-box input {
  width: 100%;
  padding: 8px 11px;
  padding-inline-start: 31px;
  padding-inline-end: 30px;
  font-family: inherit; font-size: 12.5px;
  color: var(--jti-side-ink);
  background: var(--jti-side-field);
  border: 1px solid transparent;
  border-radius: 8px;
  outline: none;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.jti-navsearch-box input::placeholder { color: var(--jti-side-faint); }
.jti-navsearch-box input:focus {
  background: var(--jti-side-hover);
  border-color: var(--jti-side-accent);
  box-shadow: 0 0 0 3px var(--jti-side-focus);
}
.jti-navsearch-box input::-webkit-search-cancel-button { display: none; }
.jti-navsearch-box button {
  position: absolute; inset-inline-end: 6px;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent;
  color: var(--jti-side-faint); font-size: 11px;
  border-radius: 5px; cursor: pointer;
}
.jti-navsearch-box button:hover { color: var(--jti-side-ink); background: var(--jti-side-hover); }

.sidebar-nav #sidebarnav li.jti-navempty {
  padding: 14px 21px;
  font-size: 12.5px;
  color: var(--jti-side-faint);
  font-style: italic;
}

/* En mode réduit, il ne reste que les icônes : le champ et les intitulés de
   section n'auraient plus de sens. */
.mini-sidebar .jti-navsearch,
.mini-sidebar .jti-navlabel,
.mini-sidebar .jti-navempty { display: none !important; }

/* ------------------------- bloc utilisateur (pied) ----------------------
   Le profil est ancré en bas de la barre latérale (comme Metronic demo8) et
   reste visible pendant que la liste des modules défile. Il est placé HORS de
   .scroll-sidebar : son menu déroulant n'est donc pas rogné par le conteneur
   de défilement. On réduit la hauteur de .scroll-sidebar d'autant, plutôt que
   de passer .left-sidebar en flex, pour ne pas perturber perfectScrollbar qui
   mesure ce conteneur à l'initialisation. */

.left-sidebar { --jti-sideuser-h: 68px; }
.scroll-sidebar { height: calc(100% - var(--jti-sideuser-h)) !important; }

.jti-sideuser {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: var(--jti-sideuser-h);
  display: flex;
  align-items: center;
  padding: 0 10px;
  background: var(--jti-side-bg);
  border-top: 1px solid var(--jti-side-line);
}

.jti-sideuser-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  padding: 8px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: background .14s ease;
}
.jti-sideuser-btn:hover,
.jti-sideuser-btn[aria-expanded="true"] { background: var(--jti-side-hover); }
.jti-sideuser-btn:focus { outline: 0; box-shadow: 0 0 0 3px var(--jti-side-focus); }

.jti-sideuser-avatar {
  width: 34px; height: 34px;
  flex: 0 0 34px;
  border-radius: 100%;
  object-fit: cover;
  border: 2px solid var(--jti-side-line);
}

/* min-width:0 permet à l'ellipse de fonctionner dans un conteneur flex. */
.jti-sideuser-id { display: block; flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.jti-sideuser-name,
.jti-sideuser-sub {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.jti-sideuser-name { color: var(--jti-side-ink); font-size: 13px; font-weight: 600; }
.jti-sideuser-sub  { color: var(--jti-side-faint); font-size: 11.5px; font-weight: 500; }
.jti-sideuser-caret { color: var(--jti-side-faint); font-size: 14px; flex: 0 0 auto; }

/* Le menu du profil s'ouvre dans le prolongement de la barre : il reste donc
   sombre lui aussi, sinon une carte blanche surgirait du pied du menu. */
.jti-sideuser-menu {
  width: calc(100% - 20px);
  min-width: 0;
  margin-bottom: 6px;
  padding: 6px;
  background: var(--jti-side-panel);
  border-color: var(--jti-side-line);
}
.jti-sideuser-menu .dropdown-item {
  display: flex; align-items: center; gap: 10px;
  border-radius: 8px;
  padding: 9px 11px;
  font-size: 13px;
  font-weight: 500;
  color: var(--jti-side-ink-2);
}
.jti-sideuser-menu .dropdown-item i { width: 16px; text-align: center; }
.jti-sideuser-menu .dropdown-item:hover { background: var(--jti-side-hover); color: var(--jti-side-ink); }
.jti-sideuser-menu .jti-sideuser-logout:hover { background: var(--jti-side-danger-t); color: var(--jti-side-danger); }
.jti-sideuser-menu .dropdown-divider { margin: 5px 2px; border-color: var(--jti-side-line); }

/* Barre réduite : il ne reste que l'avatar, centré. .hide-menu est déjà
   masqué par le thème dans cet état. */
.mini-sidebar .left-sidebar { --jti-sideuser-h: 60px; }
.mini-sidebar .jti-sideuser { padding: 0 6px; }
.mini-sidebar .jti-sideuser-btn { justify-content: center; gap: 0; padding: 8px 0; }
.mini-sidebar .jti-sideuser-menu { width: 200px; }

/* L'onde de clic du gabarit (waves-dark) est noire : invisible sur un fond
   sombre. On l'éclaircit, seulement à l'intérieur de la barre. */
.sidebar-nav .waves-effect .waves-ripple { background: rgba(255, 255, 255, .22) !important; }

/* Ascenseur discret propre à la barre latérale. Le curseur natif ET celui de
   perfectScrollbar (noir à 20 % dans le gabarit, donc invisible ici) passent
   en blanc transparent. */
.scroll-sidebar::-webkit-scrollbar { width: 6px; }
.scroll-sidebar::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .20); border: none; border-radius: 100px; }
.scroll-sidebar .ps-scrollbar-y,
.scroll-sidebar:hover .ps-scrollbar-y-rail > .ps-scrollbar-y,
.scroll-sidebar.ps-in-scrolling .ps-scrollbar-y-rail > .ps-scrollbar-y {
  background-color: rgba(255, 255, 255, .24) !important;
}

/* ============================ fil d'ariane ============================== */

.page-titles { background: transparent !important; box-shadow: none !important;
  margin: 6px 0 2px; padding: 12px 0 6px; }
.page-titles .breadcrumb { background: transparent; padding: 0; }
.page-titles .breadcrumb .breadcrumb-item a { color: var(--jti-muted); font-weight: 500; }
.page-titles .breadcrumb .breadcrumb-item a:hover { color: var(--jti-primary); }
.page-titles .breadcrumb .breadcrumb-item.active,
.page-titles .breadcrumb .breadcrumb-item span { color: var(--jti-ink); }

/* =============================== cartes ================================= */

.card {
  border: 1px solid var(--jti-border) !important;
  border-radius: var(--jti-r-lg) !important;
  box-shadow: var(--jti-shadow) !important;
  margin-bottom: 22px;
}
.card .card-body { padding: 20px; }
.card .card-title { font-size: 15px; font-weight: 600; }
.card .card-subtitle { color: var(--jti-muted); }

/* ============================== boutons ================================= */

.btn { border-radius: var(--jti-r-sm) !important; font-weight: 600;
  letter-spacing: .01em; box-shadow: none !important; }
.btn:focus { box-shadow: 0 0 0 3px var(--jti-focus) !important; }

/* primaires — tout converge vers le cobalt */
.btn-primary, .btn-info, .btn-themecolor,
.btn-primary.disabled, .btn-info.disabled {
  background: var(--jti-primary) !important;
  border-color: var(--jti-primary) !important;
  color: #fff !important;
}
.btn-primary:hover, .btn-info:hover, .btn-themecolor:hover,
.btn-primary:active, .btn-info:active {
  background: var(--jti-primary-d) !important;
  border-color: var(--jti-primary-d) !important;
}

/* états sémantiques */
.btn-success { background: var(--jti-ok) !important; border-color: var(--jti-ok) !important; }
.btn-success:hover { background: #0B8259 !important; border-color: #0B8259 !important; }
.btn-danger { background: var(--jti-danger) !important; border-color: var(--jti-danger) !important; }
.btn-danger:hover { background: #A32424 !important; border-color: #A32424 !important; }
.btn-warning { background: var(--jti-warn) !important; border-color: var(--jti-warn) !important; color: #fff !important; }
.btn-secondary, .btn-inverse, .btn-default {
  background: var(--jti-surface) !important; border: 1px solid var(--jti-border) !important;
  color: var(--jti-ink) !important; }
.btn-secondary:hover, .btn-inverse:hover, .btn-default:hover {
  background: var(--jti-bg) !important; }

.btn-circle { border-radius: 100% !important; }
.btn-rounded { border-radius: 100px !important; }

/* =============================== formulaires ============================ */

.form-control {
  border: 1px solid #D7DEEA;
  border-radius: var(--jti-r-sm) !important;
  background: #FBFCFE;
  color: var(--jti-ink);
  font-size: 14px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.form-control:focus {
  border-color: var(--jti-primary);
  background: #fff;
  box-shadow: 0 0 0 3px var(--jti-focus);
}
.form-control::placeholder { color: var(--jti-faint); }
label, .col-form-label { color: var(--jti-ink); font-weight: 500; font-size: 13px; }

/* champs "material" du template : on leur redonne une vraie boîte */
.form-material .form-control,
.form-material .form-control.focus,
.form-material .form-control:focus {
  background-image: none !important;
  border: 1px solid #D7DEEA;
  border-radius: var(--jti-r-sm);
  padding: 8px 12px;
  background-color: #FBFCFE;
}
.form-material .form-control:focus {
  border-color: var(--jti-primary);
  box-shadow: 0 0 0 3px var(--jti-focus);
}

/* Tom Select harmonisé */
.ts-wrapper.single .ts-control,
.ts-wrapper.multi .ts-control {
  border: 1px solid #D7DEEA !important;
  border-radius: var(--jti-r-sm) !important;
  background: #FBFCFE !important;
  min-height: 36px;
  box-shadow: none;
}
.ts-wrapper.focus .ts-control {
  border-color: var(--jti-primary) !important;
  box-shadow: 0 0 0 3px var(--jti-focus);
}
.ts-dropdown { border: 1px solid var(--jti-border) !important;
  border-radius: var(--jti-r-sm) !important; box-shadow: var(--jti-shadow-lg); }
.ts-dropdown .option.active,
.ts-dropdown .option:hover {
  background: var(--jti-primary) !important; color: #fff !important; }

/* datepicker harmonisé */
.datepicker { border-radius: var(--jti-r) !important;
  border: 1px solid var(--jti-border) !important; box-shadow: var(--jti-shadow-lg) !important; }
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.active {
  background: var(--jti-primary) !important; background-image: none !important; }
.datepicker table tr td.today { background: var(--jti-primary-t) !important;
  background-image: none !important; color: var(--jti-primary) !important; }

/* =============================== tableaux =============================== */

.table { color: var(--jti-ink); }
.table thead th {
  background: var(--jti-bg);
  color: var(--jti-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .07em;
  border-bottom: 1px solid var(--jti-border) !important;
  border-top: none !important;
}
.table td, .table th { border-top: 1px solid var(--jti-hair);
  vertical-align: middle; padding: 10px 12px; }
.table-hover tbody tr:hover { background: #F7FAFD; }
.table-striped tbody tr:nth-of-type(odd) { background: #FAFCFE; }
.table .num, .table td[align="right"] { font-variant-numeric: tabular-nums; }

/* DataTables : contrôles harmonisés */
.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
  border: 1px solid #D7DEEA; border-radius: var(--jti-r-sm);
  background: #FBFCFE; padding: 5px 10px; }
.dataTables_wrapper .dataTables_info { color: var(--jti-muted); }

/* pagination */
.pagination > li > a, .pagination > li > span,
.page-item .page-link {
  color: var(--jti-muted); border: 1px solid var(--jti-border);
  border-radius: var(--jti-r-sm) !important; margin: 0 2px; }
.pagination > .active > a, .pagination > .active > a:hover,
.page-item.active .page-link {
  background: var(--jti-primary) !important; border-color: var(--jti-primary) !important;
  color: #fff !important; }
.page-link:hover { background: var(--jti-primary-t); color: var(--jti-primary); }

/* =============================== badges / labels ======================== */

.badge, .label { border-radius: 100px; font-weight: 600; padding: .35em .8em; }
.badge-success, .label-success { background: var(--jti-ok-t) !important; color: var(--jti-ok) !important; }
.badge-warning, .label-warning { background: var(--jti-warn-t) !important; color: var(--jti-warn) !important; }
.badge-danger, .label-danger { background: var(--jti-danger-t) !important; color: var(--jti-danger) !important; }
.badge-info, .label-info, .badge-primary, .label-primary {
  background: var(--jti-primary-t) !important; color: var(--jti-primary) !important; }

/* ============================ fiche détaillée =========================== */
/* Composant partagé par les écrans « view » (animateurs, superviseurs,
   managers, administrateurs, profil…). Colonne d'identité à gauche, onglets à
   droite. Défini ici pour que les sept vues en profitent. */

.jti-profile { padding: 22px; text-align: center; }
.jti-profile .jti-avatar {
  width: 96px; height: 96px;
  margin: 0 auto 14px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  border: 3px solid var(--jti-surface);
  box-shadow: 0 0 0 1px var(--jti-border), 0 6px 18px rgba(24,34,52,.10);
}
/* Repli sans photo : initiales sur pastille cobalt, bien plus lisible que la
   silhouette grise générique qui occupait tout l'espace. */
.jti-profile .jti-initials {
  width: 96px; height: 96px;
  margin: 0 auto 14px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; font-weight: 700; letter-spacing: .02em;
  color: var(--jti-primary);
  background: var(--jti-primary-t);
  box-shadow: 0 0 0 1px #D3DFF6;
}
.jti-profile h2 {
  font-size: 17px; font-weight: 700;
  color: var(--jti-ink);
  margin: 0 0 4px;
  line-height: 1.3;
}
.jti-profile .jti-role {
  font-size: 12.5px; color: var(--jti-muted);
  margin: 0 0 12px;
}
.jti-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em;
  padding: 5px 12px; border-radius: 100px;
}
.jti-pill::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.jti-pill.on  { background: var(--jti-ok-t);     color: var(--jti-ok); }
.jti-pill.off { background: var(--jti-danger-t); color: var(--jti-danger); }

/* Liste de caractéristiques : libellé discret au-dessus de la valeur, pour se
   lire en diagonale. */
.jti-facts { border-top: 1px solid var(--jti-hair); text-align: start; }
.jti-facts div {
  padding: 12px 22px;
  border-bottom: 1px solid var(--jti-hair);
}
.jti-facts div:last-child { border-bottom: none; }
.jti-facts small {
  display: block;
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--jti-faint);
  margin-bottom: 3px;
}
.jti-facts span {
  font-size: 13.5px; color: var(--jti-ink);
  overflow-wrap: anywhere;
}
.jti-facts span.empty { color: var(--jti-faint); }
.jti-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.jti-chips i {
  font-style: normal;
  font-size: 12px;
  background: var(--jti-bg);
  border: 1px solid var(--jti-border);
  border-radius: 100px;
  padding: 3px 10px;
  color: var(--jti-ink);
}

/* ------------------------- fiche en lecture seule ----------------------- */
/* Pour les écrans « view » qui n'affichent que des données : présenter des
   champs de formulaire désactivés est illisible (texte grisé, flèches de menu
   déroulant trompeuses) et prend trois fois la place nécessaire. */

.jti-sheet-hero {
  display: flex; align-items: flex-start; gap: 22px;
  padding: 4px 0 22px;
  border-bottom: 1px solid var(--jti-hair);
  margin-bottom: 22px;
}
.jti-sheet-hero .thumb {
  flex: 0 0 auto;
  width: 132px; height: 132px;
  border-radius: var(--jti-r);
  border: 1px solid var(--jti-border);
  background: var(--jti-surface);
  object-fit: contain;
  padding: 8px;
}
.jti-sheet-hero .meta { min-width: 0; padding-top: 4px; }
.jti-sheet-hero h1 {
  font-size: 21px; font-weight: 700;
  letter-spacing: -.01em;
  color: var(--jti-ink);
  margin: 0 0 6px;
  line-height: 1.3;
}
.jti-sheet-hero .ref {
  font-family: var(--jti-mono);
  font-size: 12.5px;
  color: var(--jti-muted);
  margin: 0 0 12px;
}
.jti-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.jti-tag {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600;
  padding: 4px 11px; border-radius: 100px;
  background: var(--jti-bg);
  border: 1px solid var(--jti-border);
  color: var(--jti-ink);
}
.jti-tag.brand { background: var(--jti-primary-t); border-color: #D3DFF6; color: var(--jti-primary); }
.jti-tag.on    { background: var(--jti-ok-t);      border-color: #C8EADD; color: var(--jti-ok); }
.jti-tag.off   { background: var(--jti-danger-t);  border-color: #F3D2D2; color: var(--jti-danger); }

/* Grille d'attributs : libellé discret au-dessus de la valeur. */
.jti-sheet {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 20px 26px;
}
.jti-sheet > div { min-width: 0; }
.jti-sheet small {
  display: block;
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--jti-faint);
  margin-bottom: 4px;
}
.jti-sheet .v {
  font-size: 14px; color: var(--jti-ink);
  overflow-wrap: anywhere;
}
.jti-sheet .v.empty { color: var(--jti-faint); }
.jti-sheet .v.num { font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  .jti-sheet-hero { flex-direction: column; gap: 16px; }
  .jti-sheet-hero .thumb { width: 108px; height: 108px; }
}

/* ------------------- règles de distribution par activation --------------- */
/* Les trois canaux (DTC / HORECA / KA) côte à côte : on voit d'un coup d'œil
   sur lesquels le cadeau est distribué, et avec quelles règles. */
.jti-actgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  gap: 14px;
}
.jti-actcard {
  border: 1px solid var(--jti-border);
  border-radius: var(--jti-r);
  background: var(--jti-bg);
  padding: 16px 18px;
}
/* Le canal actif est mis en avant ; les inactifs restent lisibles mais en retrait. */
.jti-actcard.on { background: var(--jti-surface); border-color: #C9D6EE; box-shadow: var(--jti-shadow); }
.jti-actcard .head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.jti-actcard .head .ic {
  width: 32px; height: 32px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--jti-hair); color: var(--jti-muted); font-size: 14px;
}
.jti-actcard.on .head .ic { background: var(--jti-primary-t); color: var(--jti-primary); }
.jti-actcard .head b { font-size: 14px; font-weight: 700; letter-spacing: .02em; }
.jti-actcard .head .jti-tag { margin-inline-start: auto; }
.jti-actcard .none { margin: 0; font-size: 13px; color: var(--jti-faint); }
.jti-actcard .jti-sheet { grid-template-columns: repeat(auto-fit, minmax(108px, 1fr)); gap: 14px 16px; }
.jti-actcard .pacing {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px dashed var(--jti-border);
}
.jti-actcard .pacing .ttl {
  display: block; margin-bottom: 10px;
  font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--jti-primary);
}

/* --------------------------------- onglets ------------------------------ */
.profile-tab.nav-tabs {
  border-bottom: 1px solid var(--jti-border);
  padding: 0 8px;
}
.profile-tab.nav-tabs .nav-link {
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 15px 18px;
  font-size: 13.5px; font-weight: 600;
  color: var(--jti-muted);
  transition: color .15s ease, border-color .15s ease;
}
.profile-tab.nav-tabs .nav-link:hover { color: var(--jti-ink); }
.profile-tab.nav-tabs .nav-link.active {
  color: var(--jti-primary);
  background: transparent;
  border-bottom-color: var(--jti-primary);
}

/* ================================ modales =============================== */
/* Presque tous les écrans d'ajout et de modification de l'application sont des
   fragments .modal-header / .modal-body / .modal-footer chargés en AJAX dans la
   modale #edit. Les soigner ici met à niveau la centaine de formulaires d'un
   coup, sans toucher aux vues. */

.modal-dialog { margin-top: 2rem; margin-bottom: 2rem; }
.modal-content {
  border: none;
  border-radius: 16px;
  box-shadow: 0 24px 64px rgba(15,23,42,.22), 0 2px 6px rgba(15,23,42,.06);
  overflow: hidden;                     /* les coins arrondis rognent l'en-tête */
}
.modal-backdrop.show { opacity: .45; }

/* -------------------------------- en-tête ------------------------------- */
.modal-header {
  align-items: center;
  gap: 12px;
  padding: 20px 26px;
  background: var(--jti-surface);
  border-bottom: 1px solid var(--jti-hair);
}
/* Dans les vues, le bouton de fermeture précède le titre dans le HTML ; avec
   le justify-content:space-between de Bootstrap, la croix se retrouvait à
   gauche et le titre à droite. `order` rétablit l'ordre visuel attendu sans
   toucher aux 63 vues concernées — et il suit automatiquement le sens RTL. */
.modal-header .modal-title {
  order: 1;
  margin: 0;
  margin-inline-end: auto;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--jti-ink);
  line-height: 1.35;
}
/* Le bouton de fermeture du gabarit est vide : sans glyphe il était invisible
   et donc inutilisable. On le dessine en CSS plutôt que d'éditer chaque vue. */
.modal-header .close {
  order: 2;
  width: 34px; height: 34px;
  margin: 0;
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 9px;
  background: transparent;
  color: var(--jti-muted);
  opacity: 1;
  font-size: 0;                          /* neutralise un éventuel &times; */
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.modal-header .close::before {
  content: "\f00d";                      /* Font Awesome : croix */
  font: 900 14px/1 "Font Awesome 6 Free";
}
.modal-header .close:hover { background: var(--jti-bg); color: var(--jti-ink); opacity: 1; }
.modal-header .close:focus-visible { outline: 2px solid var(--jti-primary); outline-offset: 1px; }

/* --------------------------------- corps -------------------------------- */
.modal-body { padding: 26px; background: var(--jti-surface); }
.modal-body > .row { margin-inline: 0; }

/* Libellés de formulaire : même traitement typographique que le reste du
   système, et alignés verticalement avec leur champ. */
.modal-body .control-label,
.form-horizontal .control-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--jti-muted);
  padding-top: 11px;
  margin-bottom: 4px;
  line-height: 1.4;
}
.modal-body .form-group.row { margin-bottom: 18px; }
.modal-body .form-group.row:last-child { margin-bottom: 0; }

/* Champ obligatoire : repère discret, ajouté par le CSS car les vues ne
   marquent pas les libellés. */
.modal-body .form-group.row:has(input[required], select[required], textarea[required]) .control-label::after {
  content: " *";
  color: var(--jti-danger);
  font-weight: 700;
}

/* Les champs cachés (id) ne doivent pas créer de blanc dans la grille. */
.modal-body input[type="hidden"] { display: none; }

/* -------------------------------- pied ---------------------------------- */
.modal-footer {
  gap: 10px;
  padding: 16px 26px;
  background: var(--jti-bg);
  border-top: 1px solid var(--jti-hair);
}
.modal-footer > * { margin: 0; }
/* Hiérarchie : une seule action principale, en cobalt. Le vert du gabarit
   signalait « succès », pas « action principale ». */
.modal-footer .saveBtn,
.modal-footer input[type="submit"] {
  background: var(--jti-primary) !important;
  border-color: var(--jti-primary) !important;
  color: #fff !important;
  padding: 9px 20px;
  font-weight: 600;
}
.modal-footer .saveBtn:hover,
.modal-footer input[type="submit"]:hover {
  background: var(--jti-primary-d) !important;
  border-color: var(--jti-primary-d) !important;
}
.modal-footer .btn-secondary,
.modal-footer [data-dismiss="modal"] {
  background: var(--jti-surface) !important;
  border: 1px solid var(--jti-border) !important;
  color: var(--jti-muted) !important;
  padding: 9px 18px;
  font-weight: 600;
}
.modal-footer .btn-secondary:hover,
.modal-footer [data-dismiss="modal"]:hover {
  background: var(--jti-bg) !important;
  color: var(--jti-ink) !important;
}

@media (max-width: 640px) {
  .modal-header, .modal-body, .modal-footer { padding-inline: 18px; }
  .modal-footer { flex-direction: column-reverse; align-items: stretch; }
  .modal-footer > * { width: 100%; }
}

/* ================================ alertes / toasts ====================== */

.alert { border-radius: var(--jti-r); border: 1px solid transparent; }
.alert-success { background: var(--jti-ok-t); color: var(--jti-ok); border-color: #C8EADD; }
.alert-danger { background: var(--jti-danger-t); color: var(--jti-danger); border-color: #F3D2D2; }
.alert-warning { background: var(--jti-warn-t); color: var(--jti-warn); border-color: #F3E0C2; }
.alert-info { background: var(--jti-primary-t); color: var(--jti-primary); border-color: #D3DFF6; }

/* SweetAlert2 (toasts + confirmations) aligné sur le design system */
.swal2-popup { border-radius: var(--jti-r-lg) !important;
  font-family: var(--jti-font) !important; color: var(--jti-ink) !important; }
.swal2-toast { box-shadow: var(--jti-shadow-lg) !important;
  border: 1px solid var(--jti-border) !important; }
.swal2-title { color: var(--jti-ink) !important; font-size: 19px !important; }
.swal2-html-container { color: var(--jti-muted) !important; }
.swal2-toast .swal2-title { font-size: 14px !important; font-weight: 600 !important; }
.swal2-toast .swal2-html-container { font-size: 13px !important; }
.swal2-styled.swal2-confirm { border-radius: var(--jti-r-sm) !important;
  font-weight: 600 !important; }
.swal2-styled.swal2-cancel { border-radius: var(--jti-r-sm) !important;
  background: var(--jti-surface) !important; color: var(--jti-ink) !important;
  border: 1px solid var(--jti-border) !important; font-weight: 600 !important; }
.swal2-timer-progress-bar { background: rgba(32,80,199,.35) !important; }

/* flatpickr aligné sur le design system */
.flatpickr-calendar { border: 1px solid var(--jti-border) !important;
  border-radius: var(--jti-r) !important; box-shadow: var(--jti-shadow-lg) !important;
  font-family: var(--jti-font) !important; }
.flatpickr-day.selected, .flatpickr-day.selected:hover,
.flatpickr-day.startRange, .flatpickr-day.endRange {
  background: var(--jti-primary) !important; border-color: var(--jti-primary) !important; }
.flatpickr-day.today { border-color: var(--jti-primary) !important; }
.flatpickr-day.today:hover { background: var(--jti-primary-t) !important;
  color: var(--jti-primary) !important; }
.flatpickr-day:hover { background: var(--jti-bg); }
.flatpickr-months .flatpickr-month,
.flatpickr-current-month .flatpickr-monthDropdown-months { color: var(--jti-ink); }

/* ================================ divers ================================ */

.footer { background: transparent !important; border-top: 1px solid var(--jti-border);
  color: var(--jti-faint); font-size: 12px; }

/* barres de défilement discrètes (WebKit) */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: #CBD5E1; border-radius: 100px;
  border: 2px solid var(--jti-bg); }
::-webkit-scrollbar-track { background: transparent; }

/* focus clavier visible partout */
a:focus-visible, button:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--jti-primary); outline-offset: 2px; }

/* l'ancien panneau "Service Panel" ne doit jamais réapparaître */
.right-sidebar, .right-side-toggle { display: none !important; }


/* ============================================================================
   Phase 2 — finition « premium ».
   Toujours purement additive : chargée après la phase 1, elle n'en modifie
   aucune règle, elle les raffine (dégradés cobalt, ombres teintées, micro-
   interactions). Aucune vue n'est touchée. Toutes les animations sont
   désactivées quand l'utilisateur préfère réduire les mouvements.
   ========================================================================== */

:root {
  /* dégradé de marque — le même que le bouton de connexion, pour que tout
     le système parle la même langue */
  --jti-grad: linear-gradient(180deg, #2C5DD9 0%, #2050C7 55%, #1C49B8 100%);
  --jti-grad-soft: linear-gradient(180deg, #EEF3FD 0%, #E3ECFB 100%);
  --jti-ease: cubic-bezier(.22, .61, .36, 1);
}

/* ============================ topbar : verre dépoli ======================= */
/* La barre reste blanche de loin, mais le contenu qui défile dessous affleure
   en transparence : c'est ce léger flou qui donne la sensation « premium ». */
.topbar {
  background: rgba(255, 255, 255, .86) !important;
  -webkit-backdrop-filter: saturate(1.5) blur(12px);
  backdrop-filter: saturate(1.5) blur(12px);
  border-bottom-color: rgba(226, 232, 242, .85);
}
.topbar .navbar-header,
.topbar .top-navbar .navbar-header { background: transparent !important; }

/* Les icônes de la barre deviennent des pastilles au survol. */
.topbar .navbar-nav .nav-item > a.nav-link {
  border-radius: 9px;
  transition: background .15s ease, color .15s ease;
}
.topbar .navbar-nav .nav-item > a.nav-link:hover { background: var(--jti-bg); }

/* ========================== sidebar : actif en relief ===================== */
/* L'entrée active passe de la simple teinte à une pilule en dégradé cobalt :
   c'est le repère visuel le plus fréquent de l'application, il mérite le
   traitement le plus soigné. Réservé au premier niveau ; les sous-menus
   gardent la teinte discrète de la phase 1.
   Sur le fond sombre de la barre, le dégradé de marque manquerait de
   séparation : on l'éclaircit (--jti-side-grad) pour que la pilule se détache,
   le texte restant blanc. */
.sidebar-nav #sidebarnav > li > a.active,
.sidebar-nav #sidebarnav > li > a.active:hover {
  background: var(--jti-side-grad) !important;
  color: #fff !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .18),
    0 4px 12px rgba(0, 0, 0, .35);
}
.sidebar-nav #sidebarnav > li > a.active i { color: rgba(255, 255, 255, .92); }
.sidebar-nav #sidebarnav > li > a.active.has-arrow::after { border-color: rgba(255, 255, 255, .75); }
/* Le petit trait latéral ferait doublon avec la pilule en dégradé. */
.sidebar-nav #sidebarnav > li > a.active::before { display: none; }

/* ============================ boutons : matière =========================== */
.btn { transition: transform .12s var(--jti-ease), filter .15s ease,
       box-shadow .15s ease, background-color .15s ease, color .15s ease,
       border-color .15s ease; }

/* Primaire : dégradé vertical, liseré clair en haut, ombre teintée cobalt —
   le même vocabulaire que le bouton de l'écran de connexion. */
.btn-primary, .btn-info, .btn-themecolor {
  background: var(--jti-grad) !important;
  border: none !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .18),
    0 2px 5px rgba(32, 80, 199, .24) !important;
}
.btn-primary:hover, .btn-info:hover, .btn-themecolor:hover {
  background: var(--jti-grad) !important;
  filter: brightness(1.07);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .20),
    0 5px 14px rgba(32, 80, 199, .32) !important;
}
.btn-primary:active, .btn-info:active, .btn-themecolor:active {
  transform: translateY(0);
  filter: brightness(.96);
}

/* Succès / danger : aplats conservés, mais avec une ombre de leur propre
   couleur pour rester dans la même famille de relief. */
.btn-success { box-shadow: 0 2px 5px rgba(14, 159, 110, .26) !important; }
.btn-success:hover { transform: translateY(-1px); box-shadow: 0 5px 13px rgba(14, 159, 110, .32) !important; }
.btn-danger  { box-shadow: 0 2px 5px rgba(194, 44, 44, .24) !important; }
.btn-danger:hover  { transform: translateY(-1px); box-shadow: 0 5px 13px rgba(194, 44, 44, .30) !important; }
.btn-warning { box-shadow: 0 2px 5px rgba(180, 83, 9, .24) !important; }
.btn-warning:hover { transform: translateY(-1px); box-shadow: 0 5px 13px rgba(180, 83, 9, .30) !important; }
.btn-secondary:hover, .btn-default:hover, .btn-inverse:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* Boutons d'action des tableaux : pastilles teintées discrètes plutôt que
   trois aplats criards qui se disputent l'attention à chaque ligne. */
.table td.actions .btn { border: none !important; box-shadow: none !important; transform: none; }
.table td.actions .btn-primary { background: var(--jti-primary-t) !important; color: var(--jti-primary) !important; }
.table td.actions .btn-primary:hover { background: #D9E5F9 !important; }
.table td.actions .btn-warning { background: var(--jti-warn-t) !important; color: var(--jti-warn) !important; }
.table td.actions .btn-warning:hover { background: #F8E5C8 !important; }
.table td.actions .btn-danger  { background: var(--jti-danger-t) !important; color: var(--jti-danger) !important; }
.table td.actions .btn-danger:hover  { background: #F6D5D5 !important; }
.table td.actions .btn-success { background: var(--jti-ok-t) !important; color: var(--jti-ok) !important; }
.table td.actions .btn-success:hover { background: #CCEEDF !important; }

/* ============================== cartes : élévation ======================== */
.card { transition: box-shadow .22s var(--jti-ease); }
.card:hover {
  box-shadow:
    0 1px 2px rgba(24, 34, 52, .05),
    0 10px 28px rgba(24, 34, 52, .09) !important;
}

/* Le filet d'accent devant les titres (dashboard, rapports) passe au dégradé
   de marque, coins arrondis. */
.lstick {
  width: 4px;
  height: 22px;
  background: var(--jti-grad);
  border-radius: 4px;
}

/* Panneau de filtres : un socle discret qui sépare la zone de recherche du
   tableau de résultats. */
.formFilter {
  background: var(--jti-bg);
  border: 1px solid var(--jti-hair);
  border-radius: var(--jti-r);
  padding: 14px 14px 0;
  margin-bottom: 18px;
}

/* ============================== tableaux ================================== */
/* Conteneur arrondi : défilement horizontal quand le tableau dépasse,
   les coins restent rognés proprement par le border-radius. */
.table-scrollable {
  border: 1px solid var(--jti-border);
  border-radius: var(--jti-r);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table-scrollable .table { margin-bottom: 0; }
.table tbody tr { transition: background .13s ease; }

/* Page courante : même dégradé que les boutons primaires. */
.pagination > .active > a, .pagination > .active > a:hover,
.page-item.active .page-link {
  background: var(--jti-grad) !important;
  border: none !important;
  box-shadow: 0 2px 5px rgba(32, 80, 199, .26);
}

/* ========================= micro-interactions ============================= */
@media (prefers-reduced-motion: no-preference) {

  /* Modales : entrée douce (glissé + léger zoom) au lieu du saut brutal. */
  .modal.fade .modal-dialog {
    transform: translateY(16px) scale(.98);
    opacity: .6;
    transition: transform .26s var(--jti-ease), opacity .2s ease;
  }
  .modal.show .modal-dialog { transform: none; opacity: 1; }

  /* Menus déroulants : apparition en fondu glissé. */
  .dropdown-menu { animation: jtiDrop .17s var(--jti-ease); }
  @keyframes jtiDrop {
    from { opacity: 0; transform: translateY(-5px); }
    to   { opacity: 1; transform: none; }
  }

  /* Lignes du tableau chargé en AJAX : la page ne clignote plus, elle se pose. */
  #indexAjax { animation: jtiSettle .28s var(--jti-ease); }
  @keyframes jtiSettle {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
  }
}

/* SweetAlert2 : le bouton de confirmation rejoint la famille du primaire. */
.swal2-styled.swal2-confirm {
  background: var(--jti-grad) !important;
  border: none !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .18),
    0 2px 5px rgba(32, 80, 199, .24) !important;
}
.swal2-styled.swal2-confirm:hover { filter: brightness(1.07); }

/* Flatpickr : jour sélectionné en dégradé, cohérent avec le reste. */
.flatpickr-day.selected, .flatpickr-day.selected:hover,
.flatpickr-day.startRange, .flatpickr-day.endRange {
  background: var(--jti-grad) !important;
}

/* ======================= barre latérale « rail » ========================
   Présentation compacte façon Metronic demo8 : icône au-dessus d'un libellé
   court, élément actif en carte blanche, sous-menus en panneau flottant
   (voir webroot/js/jti-sidebar-rail.js). Tout est porté par body.jti-rail :
   retirer cette classe rend la barre classique, sans autre modification. */

/* Largeur du rail : réglée ici, une seule fois. Le panneau flottant se place
   d'après la largeur mesurée de la barre, il suit donc automatiquement.
   124px laissent tenir les libellés les plus longs du menu
   (« AUTORISATIONS », « RECUPERATION STOCK BA », « EXTRACTION SUPERVISEUR »). */
.jti-rail {
  --jti-rail-w: 124px;
  --jti-rail-bg: var(--jti-side-bg);    /* fond sombre du rail */
  --jti-rail-ink: var(--jti-side-ink);  /* icônes ET libellés : blanc */
}
.jti-rail .left-sidebar { width: var(--jti-rail-w); }
.jti-rail .page-wrapper { margin-left: var(--jti-rail-w); }

/* Sous 767px le thème repasse le rail en tiroir hors-écran (.mini-sidebar,
   voir style.css) mais notre marge fixe ci-dessus n'était pas neutralisée :
   même sidebar masquée, le contenu restait poussé de 124px, d'où le
   débordement horizontal constaté sur mobile (page-titles et tableaux
   rognés à droite). */
@media (max-width: 767px) {
  .jti-rail .page-wrapper { margin-left: 0; }
}

/* Fond sombre : c'est lui qui fait ressortir les icônes et libellés blancs.
   Le liseré de droite disparaît, le contraste des deux fonds suffit à séparer
   le rail du contenu. */
.jti-rail .left-sidebar,
.jti-rail .sidebar-nav,
.jti-rail .sidebar-nav ul,
.jti-rail.card-no-border .left-sidebar,
.jti-rail.card-no-border .sidebar-nav { background: var(--jti-rail-bg) !important; }
.jti-rail .left-sidebar { border-right: 0; }

.jti-rail .sidebar-nav #sidebarnav > li > a {
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  text-align: center;
  margin: 3px 8px;
  padding: 12px 6px;
  border-radius: 12px;
  min-height: 74px;
}
.jti-rail .sidebar-nav #sidebarnav > li > a i { font-size: 20px; width: auto; margin: 0; }
/* Libellé entier : trois lignes suffisent pour les intitulés les plus longs,
   et les mots trop larges se coupent plutôt que de déborder du rail. */
.jti-rail .sidebar-nav #sidebarnav > li > a .hide-menu {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  font-size: 11.5px;
  line-height: 1.3;
  letter-spacing: .1px;
}

/* Icône et libellé de même teinte, blancs sur le fond sombre du rail : c'est
   ce contraste qui porte la lecture. La peau générale de la barre pose un
   !important sur la couleur du lien, d'où les !important ici. */
.jti-rail .sidebar-nav #sidebarnav > li > a,
.jti-rail .sidebar-nav #sidebarnav > li > a i { color: var(--jti-rail-ink) !important; }

/* Survol : voile clair, l'équivalent sombre de la carte blanche. */
.jti-rail .sidebar-nav #sidebarnav > li > a:hover { background: var(--jti-side-hover); }
.jti-rail .sidebar-nav #sidebarnav > li > a:hover,
.jti-rail .sidebar-nav #sidebarnav > li > a:hover i { color: var(--jti-side-ink) !important; }

/* Groupe ouvert (panneau affiché) : carte franche, dans la teinte du panneau
   flottant qu'elle ouvre. */
.jti-rail .sidebar-nav #sidebarnav > li > a.jti-rail-open {
  background: var(--jti-side-panel) !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .32);
}

/* Page courante : icône ET libellé en accent, sans pastille ni carte — comme
   la démo, où seul le bleu signale l'élément actif. */
.jti-rail .sidebar-nav #sidebarnav > li > a.active,
.jti-rail .sidebar-nav #sidebarnav > li.active > a {
  background: transparent !important;
  box-shadow: none;
  font-weight: 600 !important;
}
.jti-rail .sidebar-nav #sidebarnav > li > a.active,
.jti-rail .sidebar-nav #sidebarnav > li.active > a,
.jti-rail .sidebar-nav #sidebarnav > li > a.active i,
.jti-rail .sidebar-nav #sidebarnav > li.active > a i { color: var(--jti-side-accent) !important; }

/* Le repère vertical de la barre classique n'a pas de sens sur un rail centré. */
.jti-rail .sidebar-nav #sidebarnav > li > a.active::before { display: none; }

/* Pas de place pour le chevron, et les sous-menus en ligne sont remplacés par
   le panneau flottant. */
.jti-rail .sidebar-nav #sidebarnav li a.has-arrow::after { display: none !important; }
.jti-rail .sidebar-nav #sidebarnav > li > ul { display: none !important; }

/* Intitulés de section et champ de recherche : illisibles sur 92px. Le champ
   est réinjecté par le script dans un panneau, via l'élément .jti-rail-search. */
.jti-rail .jti-navlabel,
.jti-rail .jti-navsearch { display: none !important; }

/* ------------------------------- panneau ------------------------------- */

.jti-flyout {
  position: fixed;
  z-index: 1050;
  min-width: 232px;
  max-width: 320px;
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  padding: 8px;
  background: var(--jti-side-panel);
  border: 1px solid var(--jti-side-line);
  border-radius: var(--jti-r-lg);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .40);
}
.jti-flyout-item {
  display: block;
  padding: 9px 12px;
  border-radius: 9px;
  color: var(--jti-side-ink-2);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
  text-decoration: none;
}
.jti-flyout-item:hover { background: var(--jti-side-hover); color: var(--jti-side-ink); text-decoration: none; }
.jti-flyout-item.active { background: var(--jti-side-accent-t); color: var(--jti-side-accent); font-weight: 600; }

.jti-flyout-search { min-width: 272px; }
.jti-flyout-search .jti-navsearch-box { margin: 0; }

/* --------------------------- bloc utilisateur -------------------------- */
/* Sur 92px il ne reste que l'avatar : le nom et le sous-titre sont masqués. */
.jti-rail .left-sidebar { --jti-sideuser-h: 64px; }
.jti-rail .jti-sideuser { padding: 0 6px; background: var(--jti-rail-bg); border-top: 0; }
.jti-rail .jti-sideuser-btn { justify-content: center; gap: 0; padding: 8px 0; }
.jti-rail .jti-sideuser-id,
.jti-rail .jti-sideuser-caret { display: none; }
.jti-rail .jti-sideuser-menu { width: 220px; }

/* Barre réduite (bouton hamburger) : on retombe sur les icônes seules. */
.jti-rail.mini-sidebar .sidebar-nav #sidebarnav > li > a { min-height: 46px; padding: 11px 4px; }

/* ============================ panneau de filtres =========================
   Grille auto-ajustable : les modules n'affichent pas tous le même nombre de
   champs (bloc admin conditionnel), et des colonnes Bootstrap figées
   laissaient des trous dès qu'un champ disparaissait. auto-fit + minmax
   répartit ce qui est réellement rendu, sans toucher au balisage. */

.jti-filters {
  padding: 0;
  background: var(--jti-surface);
  border: 1px solid var(--jti-border);
  border-radius: var(--jti-r-lg);
  box-shadow: var(--jti-shadow);
  overflow: hidden;   /* le liseré d'accent suit les coins arrondis */
}
/* Liseré cobalt en tête de panneau : repère visuel du bloc de recherche. */
.jti-filters::before {
  content: "";
  display: block;
  height: 3px;
  background: var(--jti-grad);
}

.jti-filters-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--jti-grad-soft);
  border-bottom: 1px solid var(--jti-border);
}
.jti-filters-title {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--jti-primary);
}
/* L'icône passe en pastille cobalt : le titre devient un repère, pas un label. */
.jti-filters-title i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  margin-inline-end: 8px;
  color: #fff;
  font-size: 11px;
  background: var(--jti-grad);
  border-radius: 6px;
  box-shadow: 0 2px 5px rgba(32, 80, 199, .24);
}

/* Compteur de filtres actifs (posé par jti-filters-active.js) : sans lui,
   impossible de savoir d'un coup d'œil ce qui restreint la liste quand une
   quinzaine de champs sont repliés au-dessus des résultats. */
.jti-filters-count {
  display: none;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 700;
  color: var(--jti-primary);
  background: var(--jti-surface);
  border: 1px solid var(--jti-primary);
  border-radius: 999px;
}
.jti-filters.has-active .jti-filters-count { display: inline-flex; }

.jti-filters-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 13px 14px;
  padding: 16px;
}

.jti-field { min-width: 0; }   /* sinon un select2 large fait déborder la grille */
.jti-field > label {
  display: flex;
  align-items: center;
  margin: 0 0 5px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--jti-muted);
  letter-spacing: .01em;
}

/* --------------------------- champ renseigné ---------------------------
   La couleur ne décore pas : elle dit « ce champ restreint le résultat ».
   Sur une grille d'une quinzaine de filtres, c'est la seule façon de voir
   ce qui est actif sans relire chaque contrôle un par un. */
.jti-field.is-active > label { color: var(--jti-primary); }
.jti-field.is-active > label::before {
  content: "";
  width: 6px; height: 6px;
  margin-inline-end: 6px;
  background: var(--jti-grad);
  border-radius: 50%;
  flex: none;
}
.jti-field.is-active .form-control,
.jti-field.is-active .ts-control {
  border-color: var(--jti-primary) !important;
  background: var(--jti-primary-t);
  box-shadow: 0 0 0 3px var(--jti-focus);
}
/* La période a besoin de deux champs côte à côte : elle occupe deux colonnes
   quand la place existe, une seule sur petit écran. */
.jti-field-dates { grid-column: span 2; }
@media (max-width: 640px) { .jti-field-dates { grid-column: span 1; } }

.jti-filters-grid .form-control { width: 100%; }
.jti-filters-grid .input-daterange { display: flex; align-items: stretch; }
.jti-filters-grid .input-daterange .form-control { flex: 1 1 0; min-width: 0; }
.jti-filters-grid .input-daterange .input-group-addon {
  display: flex; align-items: center;
  padding: 0 10px;
  color: var(--jti-faint);
  background: var(--jti-bg);
  border: 1px solid var(--jti-border);
  border-inline-start: 0; border-inline-end: 0;
}
/* Tom Select doit suivre la largeur de sa cellule, pas son contenu. */
.jti-filters-grid .ts-wrapper { width: 100% !important; }

.jti-filters-foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 9px;
  padding: 12px 16px;
  background: var(--jti-bg);
  border-top: 1px solid var(--jti-hair);
}
.jti-filters-foot .searchBtn { min-width: 132px; }
/* L'action principale porte le dégradé de marque ; « Réinitialiser » reste
   discret pour ne pas concurrencer « Rechercher ». */
.jti-filters-foot .searchBtn,
.jti-filters-foot .btn-primary {
  background: var(--jti-grad);
  border: none;
  font-weight: 600;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .18),
    0 2px 5px rgba(32, 80, 199, .24);
}
.jti-filters-foot .searchBtn:hover,
.jti-filters-foot .btn-primary:hover { filter: brightness(1.07); }
.jti-filters-foot .btnResetFilter {
  color: var(--jti-muted);
  background: var(--jti-surface);
  border: 1px solid var(--jti-border);
  font-weight: 600;
}
.jti-filters-foot .btnResetFilter:hover {
  color: var(--jti-ink);
  border-color: var(--jti-faint);
}
@media (max-width: 640px) {
  .jti-filters-foot { padding-inline: 12px; }
  .jti-filters-foot .btn { flex: 1 1 0; }
}

/* Tom Select : le dropdown reste au-dessus du header fixe et du panneau
   latéral (z-index 1050) quand il bascule vers le haut dans une fenêtre courte. */
.ts-dropdown { z-index: 1080; }

/* ---------------------------------------------------------------------------
   Filtre multi-sélection « façon Excel » (.jti-excel-filter + jti-excel-filter.js)

   Le champ BA des extractions liste plusieurs dizaines d'animateurs : les
   étiquettes Tom Select une par une feraient grandir le champ et décaleraient
   toute la grille de filtres. Au-delà de trois sélections, le script bascule
   .ts-control en mode résumé (« N sélectionné(s) »), le détail restant visible
   et modifiable dans le menu à cases à cocher.
--------------------------------------------------------------------------- */
.jti-xf.ts-wrapper .ts-control { max-height: 74px; overflow-y: auto; }

.jti-xf-collapsed .ts-control > .item { display: none !important; }
.jti-xf-collapsed .ts-control::before {
  content: attr(data-summary);
  color: var(--jti-ink);
  font-weight: 600;
  font-size: 12.5px;
  line-height: 22px;
  padding-inline-end: 6px;
}

/* Barre d'actions du menu : posée en tête du dropdown par le script. */
.jti-xf-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--jti-border);
  background: var(--jti-bg);
  border-radius: var(--jti-r-sm) var(--jti-r-sm) 0 0;
}
.jti-xf-btn {
  border: 1px solid var(--jti-border);
  background: #fff;
  color: var(--jti-primary);
  font-size: 11.5px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  cursor: pointer;
}
.jti-xf-btn:hover { border-color: var(--jti-primary); background: var(--jti-focus); }
.jti-xf-count { margin-inline-start: auto; color: var(--jti-muted); font-size: 11.5px; }

/* Liste : une ligne = une case + un libellé, sans le fond plein bleu du thème
   qui rendait la case cochée illisible au survol. */
.jti-xf-dropdown .option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: 12.5px;
}
.jti-xf-dropdown .option input[type="checkbox"] {
  margin: 0;
  flex: 0 0 auto;
  accent-color: var(--jti-primary);
}
.jti-xf-dropdown .option.active,
.jti-xf-dropdown .option:hover {
  background: var(--jti-focus) !important;
  color: var(--jti-ink) !important;
}
.jti-xf-dropdown .ts-dropdown-content { max-height: 260px; }

/* Rechargement de la liste (changement de région) : le champ reste lisible
   mais montre qu'il n'est pas encore à jour. */
.jti-xf-busy { opacity: .55; pointer-events: none; }
