/* ============================================================================
   Barre de filtres unifiée du site (classes `tl-*`)
   ----------------------------------------------------------------------------
   Chargée globalement par templates/dxsite/base_standard.html : aucune page n'a
   besoin de l'inclure, il suffit de poser le balisage. Les règles ne s'appliquent
   que là où les classes `tl-` sont présentes, donc le chargement global est sans
   effet de bord sur les pages qui ne l'utilisent pas.

   Balisage attendu (voir templates/shared/_filter_bar_head.html pour l'en-tête) :

     <div class="tl-head">
       <div>
         <h4 class="tl-head-title">…</h4>
         <div class="tl-head-meta"><span class="tl-chip"><b>Label</b> valeur</span>…</div>
       </div>
       <button class="tl-filter-btn" aria-controls="…" aria-expanded="false">…</button>
     </div>

     <form method="get" class="tl-bar" id="…" hidden>
       <div class="tl-field tl-field--search">
         <label class="tl-label" for="…">Recherche</label>
         <input type="search" class="tl-input" …>
       </div>
       …
       <div class="tl-actions">
         <a class="tl-btn tl-btn--ghost" href="…">Réinitialiser</a>
         <button type="submit" class="tl-btn tl-btn--primary">Filtrer</button>
       </div>
     </form>

   Le repli/dépli du bouton est géré par static/js/filter_bar.js (via `aria-controls`),
   lui aussi chargé globalement — rien à câbler page par page.

   Historique : extrait de dxfleet/timeline.html, puis partagé via
   templates/shared/_filter_bar_styles.html (conservé en shim inoffensif), enfin
   promu en feuille de style globale pour uniformiser tout le site.
   ========================================================================= */

/* ─── En-tête de page ─────────────────────────────────────────────────── */
.tl-head { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem; flex-wrap:wrap; margin-bottom:.75rem; }
.tl-head-title { font-size:1.05rem; font-weight:700; color:#111827; margin:0; letter-spacing:-.01em; }
.tl-head-meta { display:flex; align-items:center; flex-wrap:wrap; gap:.4rem; margin-top:.3rem; font-size:.74rem; color:#6b7280; }
.tl-chip { display:inline-flex; align-items:center; gap:.3rem; max-width:34ch; padding:.1rem .45rem;
           border:1px solid #e2e8f0; border-radius:999px; background:#f8fafc; color:#374151;
           white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tl-chip b { color:#0f766e; font-weight:600; }

/* Croix de retrait d'une puce : un lien vers la page privée de ce seul filtre,
   rendu par la vue (`chip.remove_url`). Sans elle, la seule sortie d'un filtre
   posé était « Réinitialiser », qui les jette tous d'un coup. */
.tl-chip-x { display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
             width:13px; height:13px; margin-left:.1rem; border-radius:999px;
             color:#94a3b8; font-size:.85rem; line-height:1; text-decoration:none;
             transition:background .12s ease, color .12s ease; }
.tl-chip-x:hover, .tl-chip-x:focus-visible { background:#e2e8f0; color:#b91c1c; text-decoration:none; }

/* Filtre préparé pour le retrait, pas encore appliqué : la puce reste affichée mais
   barrée. Elle continue de décrire ce que le tableau montre *aujourd'hui* — la faire
   disparaître avant l'envoi mentirait sur l'état courant — tout en montrant ce qui
   partira au prochain « Filtrer ». Recliquer la croix rétablit le filtre. */
.tl-chip.is-pending-removal { opacity:.55; text-decoration:line-through; }
.tl-chip.is-pending-removal b { text-decoration:line-through; }
.tl-chip.is-pending-removal .tl-chip-x { text-decoration:none; color:#0f766e; }

/* Croix de vidage d'un champ de la barre, posée en haut à droite du champ pour ne
   pas empiéter sur le contrôle (le chevron des `select` occupe déjà sa droite).
   Elle vide le champ sans envoyer le formulaire : on règle plusieurs filtres avant
   de cliquer « Filtrer ». Comportement dans static/js/filter_bar.js. */
.tl-field { position:relative; }
.tl-clear { position:absolute; top:.3rem; right:.35rem; z-index:1;
            display:inline-flex; align-items:center; justify-content:center;
            width:14px; height:14px; padding:0; border:0; border-radius:999px;
            background:transparent; box-shadow:none; color:#cbd5e1;
            font-size:.9rem; line-height:1; cursor:pointer;
            transition:background .12s ease, color .12s ease; }
.tl-clear:hover, .tl-clear:focus-visible { background:#f1f5f9; color:#b91c1c; }
/* La croix flotte au-dessus de la ligne du libellé : sur un champ étroit
   (« Articles », « Du ») elle se poserait sinon par-dessus le texte. */
.tl-field:has(> .tl-clear) .tl-label { padding-right:1rem; }

/* Bouton d'ouverture des filtres (coin haut-droit) */
.tl-filter-btn { display:inline-flex; align-items:center; gap:.45rem; padding:.42rem .8rem;
                 font-size:.78rem; font-weight:600; color:#334155; background:#fff;
                 border:1px solid #d8dee9; border-radius:8px; cursor:pointer;
                 box-shadow:0 1px 2px rgba(16,24,40,.05); transition:background .15s ease, border-color .15s ease, color .15s ease; }
.tl-filter-btn:hover { background:#f8fafc; border-color:#cbd5e1; color:#0f172a; }
.tl-filter-btn[aria-expanded="true"] { background:#0f766e; border-color:#0f766e; color:#fff; }
.tl-filter-btn[aria-expanded="true"] .tl-filter-count { background:rgba(255,255,255,.22); color:#fff; }
.tl-filter-btn svg { flex:0 0 auto; }
.tl-filter-count { min-width:18px; padding:0 .3rem; border-radius:999px; background:#0f766e; color:#fff;
                   font-size:.67rem; font-weight:700; line-height:18px; text-align:center; }
.tl-filter-caret { transition:transform .18s ease; }
.tl-filter-btn[aria-expanded="true"] .tl-filter-caret { transform:rotate(180deg); }

/* ─── Barre de filtres ────────────────────────────────────────────────── */
.tl-bar { display:flex; align-items:stretch; flex-wrap:wrap; margin-bottom:.85rem;
          background:#fff; border:1px solid #e2e8f0; border-radius:10px;
          box-shadow:0 1px 3px rgba(16,24,40,.06); animation:tlBarIn .18s ease; }
.tl-bar[hidden] { display:none; }
@keyframes tlBarIn { from { opacity:0; transform:translateY(-4px); } to { opacity:1; transform:none; } }

.tl-field { display:flex; flex-direction:column; justify-content:center; gap:.15rem;
            padding:.5rem .8rem; border-right:1px solid #eef2f6; min-width:0; }
.tl-field:first-child { padding-left:.95rem; }
.tl-label { font-size:.63rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
            color:#94a3b8; margin:0; line-height:1.2; }

/* Contrôles sans bordure, pour que la barre se lise comme une seule surface.
   Double-classe + !important : la règle globale `form input[type=…]` de
   modern.css est elle-même en !important et gagnerait sinon. */
.tl-bar .tl-input {
  width:auto !important; min-width:0 !important; min-height:0 !important;
  padding:.1rem 0 !important; margin:0 !important;
  background:transparent !important; border:0 !important; border-radius:0 !important;
  box-shadow:none !important; outline:none !important;
  font-size:.8rem !important; font-weight:500 !important; color:#0f172a !important; line-height:1.35 !important;
}
.tl-bar .tl-input:focus { box-shadow:none !important; }
.tl-bar .tl-input::placeholder { color:#a8b3c2 !important; font-weight:400 !important; }
.tl-bar select.tl-input { appearance:none; -webkit-appearance:none; padding-right:1rem !important;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2394a3b8' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
  background-repeat:no-repeat !important; background-position:right center !important; cursor:pointer; }
.tl-field:focus-within .tl-label { color:#0f766e; }

/* Champ de saisie multi-ligne (rare, ex. liste de références collée) */
.tl-bar textarea.tl-input { resize:vertical; min-height:1.6rem !important; }

/* Case à cocher inline dans la barre (ex. « Tous les articles »,
   « Inclure les achats soldés »). */
.tl-check { display:flex; align-items:center; gap:.35rem; margin:0; cursor:pointer;
            font-size:.78rem; font-weight:500; color:#0f172a; white-space:nowrap; }
.tl-bar .tl-check input { width:14px !important; height:14px !important; min-height:0 !important;
            margin:0 !important; padding:0 !important; accent-color:#0f766e; cursor:pointer;
            box-shadow:none !important; flex:0 0 auto; }

/* Plusieurs cases à cocher dans un même champ (ex. « Statuts ») */
.tl-checks { display:flex; align-items:center; flex-wrap:wrap; gap:.15rem .7rem; }

/* Largeurs de champ génériques. Une page qui a besoin d'une largeur
   particulière la déclare chez elle plutôt que d'ajouter un modificateur ici
   pour un seul appelant. */
.tl-field--scope  { width:auto; }
.tl-field--date   { width:135px; }
.tl-field--depot  { width:150px; }
.tl-field--sm     { width:150px; }
.tl-field--md     { width:190px; }
.tl-field--group  { width:210px; }
.tl-field--lg     { width:240px; }
.tl-field--search { flex:1 1 190px; min-width:170px; }
.tl-bar .tl-field--search .tl-input { width:100% !important; }

/* Déclencheur de menu déroulant stylé comme les autres contrôles sans bordure */
.tl-groupbtn { display:flex; align-items:center; justify-content:space-between; gap:.4rem;
               width:100% !important; text-align:left; cursor:pointer; }
.tl-groupbtn::after { content:''; width:10px; height:6px; flex:0 0 auto;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2394a3b8' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center; }
.tl-groupbtn span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tl-groupbtn.is-active span { color:#0f766e; font-weight:600; }

/* Bloc d'actions, collé au bord droit de la barre */
.tl-actions { display:flex; align-items:center; flex-wrap:wrap; justify-content:flex-end;
              gap:.4rem; margin-left:auto; padding:.5rem .7rem; border-right:0; }

/* Bandeau « pas encore appliqué », au-dessus des boutons.
   `flex:1 0 100%` lui donne sa propre ligne dans `.tl-actions` : il se pose ainsi
   au-dessus de « Filtrer » sans sortir le bloc de la barre. Affiché par
   static/js/filter_bar.js dès que la barre diffère de ce que la page montre —
   croix de puce, croix de champ, ou saisie directe. */
.tl-pending { flex:1 0 100%; margin:0; text-align:right; line-height:1.25;
              font-size:.68rem; font-weight:600; color:#b45309; }
.tl-pending[hidden] { display:none; }
.tl-btn--primary.is-dirty { box-shadow:0 0 0 3px rgba(180,83,9,.22); }

/* ─── Zone de résultats en cours de rafraîchissement ──────────────────
   Le tableau précédent reste lisible sous un voile plutôt que d'être vidé : sur une
   page qui met plusieurs secondes à répondre, un grand rectangle blanc donne
   l'impression que tout a disparu. Le voile et la roue ne concernent que cette zone,
   la barre de filtres reste utilisable pendant le calcul. */
.tl-results-busy { position:relative; }
.tl-results-busy > * { opacity:.45; transition:opacity .12s ease; }
.tl-results-busy::before { content:''; position:absolute; inset:0; z-index:5;
  background:rgba(255,255,255,.35); cursor:progress; }
.tl-results-busy::after { content:''; position:absolute; z-index:6;
  top:60px; left:50%; width:26px; height:26px; margin-left:-13px;
  border:3px solid #0f766e; border-right-color:transparent; border-radius:50%;
  animation:tlResultsSpin .7s linear infinite; }
@keyframes tlResultsSpin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .tl-results-busy::after { animation-duration:2.4s; } }
.tl-btn { display:inline-flex; align-items:center; gap:.35rem; padding:.38rem .8rem; border-radius:7px;
          font-size:.76rem; font-weight:600; line-height:1.2; cursor:pointer; text-decoration:none;
          border:1px solid transparent; transition:background .15s ease, border-color .15s ease, color .15s ease; }
.tl-btn--primary { background:#0f766e; border-color:#0f766e; color:#fff; }
.tl-btn--primary:hover { background:#0d5f59; border-color:#0d5f59; color:#fff; }
.tl-btn--ghost { background:#fff; border-color:#e2e8f0; color:#64748b; }
.tl-btn--ghost:hover { background:#f8fafc; border-color:#cbd5e1; color:#0f172a; }

@media (max-width: 991.98px) {
  .tl-field { border-right:0; border-bottom:1px solid #eef2f6; width:100% !important; flex:1 1 100%; }
  .tl-actions { width:100%; margin-left:0; justify-content:flex-end; }
}
