/* Polices auto-hébergées (v1.37.0, licence SIL OFL, cf. assets/polices) :
   Barlow Semi Condensed pour les titres et les chiffres — le dessin des
   panneaux et tableaux de départs —, Source Sans 3 pour le texte, très
   lisible en petite taille sur les écrans de guichet et les téléphones.
   Servies par Billetix : rien ne dépend d'un service externe. */
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:500;font-display:swap;src:url('assets/polices/barlow-semi-condensed-latin-500-normal.woff2') format('woff2');}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:600;font-display:swap;src:url('assets/polices/barlow-semi-condensed-latin-600-normal.woff2') format('woff2');}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:700;font-display:swap;src:url('assets/polices/barlow-semi-condensed-latin-700-normal.woff2') format('woff2');}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:400;font-display:swap;src:url('assets/polices/source-sans-3-latin-400-normal.woff2') format('woff2');}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:600;font-display:swap;src:url('assets/polices/source-sans-3-latin-600-normal.woff2') format('woff2');}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:700;font-display:swap;src:url('assets/polices/source-sans-3-latin-700-normal.woff2') format('woff2');}

/* Identité Billetix (v1.37.0) — tirée du logo : bleu nuit, bleu, lagune.
   Noms de variables conservés pour la personnalisation par compagnie
   (Paramètres : --emerald = couleur d'accent, --ink = barre latérale). */
:root{
  --police-titre:'Barlow Semi Condensed','Arial Narrow',system-ui,sans-serif;
  --police-texte:'Source Sans 3',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --ink:#0C2340;          /* Bleu nuit — barre latérale, titres */
  --ink-2:#13305A;
  --paper:#F3F5F8;        /* Fond de l'espace de travail */
  --paper-2:#FFFFFF;      /* Cartes, panneaux */
  --text-on-paper:#14233B;
  --muted:#56667B;
  --muted-on-ink:#A9B6C8;
  --line-on-paper:#DCE2EA;
  --line-on-ink:#1E3658;
  --emerald:#1457B8;      /* Bleu Billetix — actions, élément actif (personnalisable) */
  --emerald-deep:#0E4290;
  --repere:#43C6B4;       /* Repère de l'élément actif sur fond sombre (vert lagune du logo) */
  --amber:#A86A08;        /* Alerte — lisible sur blanc */
  --amber-deep:#8A5606;
  --turquoise:#0A7380;    /* Lagune — accent secondaire */
  --succes:#1E7A4E;
  --danger:#B83232;
  --hausse:#1E7A4E;
  --baisse:#B83232;
}
*{box-sizing:border-box;}
html,body{height:100%;}
body{margin:0;font-family:var(--police-texte);background:var(--paper);color:var(--text-on-paper);}

/* CORRECTIF : .ecran-login et .app fixent chacun leur propre `display`
   (flex), ce qui — en CSS — l'emporte sur la règle du navigateur
   `[hidden]{display:none}` (une règle d'auteur bat toujours une règle de
   feuille de style par défaut du navigateur, à spécificité égale). Sans
   cette règle explicite, poser `element.hidden = true` en JS n'a AUCUN
   effet visuel sur ces deux éléments — l'écran de connexion restait donc
   affiché même après une connexion réussie. */
[hidden]{display:none !important;}
h1,h2,h3{font-family:var(--police-titre);letter-spacing:-0.01em;margin:0 0 4px;}
button{font-family:inherit;cursor:pointer;}
input,select{font-family:inherit;}

/* ---------- Login ---------- */
.ecran-login{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:var(--ink);
  padding:20px;
}
.login-card{
  background:var(--paper-2);border-radius:12px;padding:36px 32px;width:100%;max-width:380px;
  box-shadow:0 24px 64px rgba(4,14,28,0.45);
}
.login-logo{display:flex;align-items:center;gap:10px;font-family:var(--police-titre);font-weight:700;font-size:26px;color:var(--ink);}
.logo-img{width:32px;height:32px;object-fit:contain;flex-shrink:0;}
.login-sous-titre{color:var(--muted);margin:2px 0 24px;font-size:14px;}
#form-login label,#form-otp label{display:block;font-size:13px;font-weight:600;color:var(--muted);margin-bottom:14px;}
#form-login input,#form-otp input{
  display:block;width:100%;margin-top:6px;padding:11px 12px;border:1px solid var(--line-on-paper);
  border-radius:9px;font-size:15px;color:var(--text-on-paper);
}
#form-login input:focus,#form-otp input:focus{outline:2px solid var(--emerald);outline-offset:1px;}
/* v1.42.0 : le champ occupe la largeur du cadre, l'œil reste collé au champ. */
.champ-mdp{position:relative;margin-top:6px;max-width:420px;}
.champ-mdp input{margin-top:0;padding-right:40px;width:100%;box-sizing:border-box;}
.btn-oeil{
  position:absolute;top:50%;right:4px;transform:translateY(-50%);
  background:none;border:none;font-size:16px;line-height:1;padding:7px 8px;
  color:var(--muted);opacity:0.6;border-radius:6px;
}
.btn-oeil:hover{opacity:1;background:var(--paper);}
.btn-oeil.actif{opacity:1;color:var(--emerald);}
.login-erreur{background:#FDEAEA;color:var(--danger);border:1px solid #F3C6C6;border-radius:8px;padding:9px 11px;font-size:13px;margin-bottom:14px;}

.btn{border:none;border-radius:8px;padding:10px 18px;font-weight:600;font-size:14px;line-height:1.2;transition:background-color .12s ease,border-color .12s ease;}
.btn-primary{background:var(--emerald);color:#fff;}
.btn-primary:hover{background:var(--emerald-deep);}
.btn-secondary{background:var(--paper-2);color:var(--text-on-paper);border:1px solid #C9D2DE;}
.btn-secondary:hover{background:var(--paper);border-color:#AEB9C8;}
.btn-danger{background:var(--danger);color:#fff;}
.btn-danger:hover{opacity:0.85;}
.btn-block{width:100%;}
.btn:disabled{opacity:0.6;cursor:not-allowed;}

/* ---------- App shell ---------- */
/* Corrigé : la barre latérale doit rester fixe pendant que seul le
   contenu principal défile. `.app` en hauteur d'écran fixe + `overflow:hidden`
   empêche le body de défiler dans son ensemble ; `.sidebar` gère son propre
   défilement interne (menu long) et `.contenu` le sien (vue principale). */
.app{display:flex;height:100vh;overflow:hidden;}
.sidebar{
  width:250px;flex-shrink:0;height:100vh;overflow-y:auto;
  background:var(--ink);color:var(--muted-on-ink);
  display:flex;flex-direction:column;padding:20px 0;
}
.sidebar-brand{
  display:flex;align-items:center;gap:9px;
  font-family:var(--police-titre);font-weight:700;font-size:21px;letter-spacing:.005em;color:#fff;
  padding:0 20px 18px;border-bottom:1px solid var(--line-on-ink);margin-bottom:8px;
}
.sidebar-brand .logo-img{width:26px;height:26px;}
.nav-menu{flex:1;overflow-y:auto;padding:0 10px;}
.nav-section-titre{
  font-size:12.5px;font-weight:600;letter-spacing:0;
  color:#7F92AB;padding:18px 12px 6px;
}
.nav-item{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:8px 12px;border-radius:6px;font-size:14.5px;font-weight:600;color:var(--muted-on-ink);
  cursor:pointer;margin-bottom:2px;
}
.nav-item:hover{background:rgba(255,255,255,0.06);color:#fff;}
.nav-item.actif{background:rgba(255,255,255,0.10);color:#fff;box-shadow:inset 3px 0 0 var(--repere);}
.nav-badge{
  font-size:10px;font-weight:700;background:rgba(255,255,255,0.12);color:var(--muted-on-ink);
  padding:2px 7px;border-radius:999px;
}
.sidebar-footer{padding:14px 20px 0;border-top:1px solid var(--line-on-ink);margin-top:8px;}
.compagnie-nom{font-size:13px;font-weight:700;color:#fff;margin-bottom:10px;}
.btn-logout{
  background:none;border:1px solid var(--line-on-ink);color:var(--muted-on-ink);
  border-radius:8px;padding:8px 12px;font-size:13px;width:100%;
}
.btn-logout:hover{background:var(--line-on-ink);color:#fff;}

.contenu{flex:1;min-width:0;height:100vh;display:flex;flex-direction:column;overflow-y:auto;}
.topbar{
  position:sticky;top:0;z-index:1;
  display:flex;align-items:center;gap:12px;justify-content:space-between;
  padding:18px 28px;background:var(--paper-2);border-bottom:1px solid var(--line-on-paper);
}
.titre-page{font-family:var(--police-titre);font-weight:700;font-size:23px;line-height:1.1;color:var(--ink);flex:1;}
.utilisateur-info{font-size:13px;color:var(--muted);font-weight:600;}
.vue{padding:26px 28px;flex:1;}

/* Bouton hamburger : visible à toutes les tailles d'écran — sur mobile il
   ouvre/ferme le panneau glissant (.ouverte, cf. media query ci-dessous),
   sur desktop il masque/réaffiche le menu normalement fixe (.reduite,
   cf. règle juste en dessous) pour redonner de la place au contenu sur un
   écran étroit ou une fenêtre non plein écran (demande du 12/10/2026).
   #sidebar-fond (fond assombri derrière le panneau) reste invisible en
   dehors de la media query "Mobile" — inutile sur desktop. */
.btn-menu-mobile{display:inline-flex;align-items:center;background:none;border:none;font-size:22px;line-height:1;padding:4px 6px;color:var(--text-on-paper);}
.sidebar-fond{display:none;}

/* ---------- Desktop (>860px) : menu réductible ---------- */
@media (min-width:861px){
  .sidebar.reduite{display:none;}
}

/* ---------- Mobile (≤860px) ---------- */
/* Le menu latéral, en permanence visible et occupant 250px sur desktop
   (cf. .app/.sidebar plus haut), n'a pas la place de faire ça sur un
   écran de téléphone : il écraserait le contenu. En dessous de 860px, il
   devient donc un panneau qui glisse depuis le bord gauche par-dessus le
   contenu (position:fixed + transform), ouvert/fermé via la classe
   .ouverte posée par app.js (bouton ☰, clic sur le fond assombri, ou
   sélection d'un lien du menu). */
@media (max-width:860px){
  .app{overflow:visible;}
  .sidebar{
    position:fixed;top:0;left:0;z-index:30;
    transform:translateX(-100%);transition:transform 0.22s ease;
    box-shadow:0 0 40px rgba(0,0,0,0.35);
  }
  .sidebar.ouverte{transform:translateX(0);}
  .btn-menu-mobile{display:inline-flex;align-items:center;}
  .sidebar-fond{
    display:none;position:fixed;inset:0;background:rgba(6,18,34,0.5);z-index:20;
  }
  .sidebar-fond.visible{display:block;}
  .topbar{padding:14px 16px;}
  .vue{padding:18px 16px;}
}

/* ---------- Composants de vue ---------- */
.carte{background:var(--paper-2);border:1px solid var(--line-on-paper);border-radius:10px;padding:20px 22px;margin-bottom:18px;}
.carte h3{font-size:18px;font-weight:600;color:var(--ink);margin-bottom:12px;}
.grille-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:20px;}
.stat{background:var(--paper-2);border:1px solid var(--line-on-paper);border-radius:10px;padding:16px 18px;}
.stat-label{font-size:13px;color:var(--muted);font-weight:600;margin-bottom:4px;}
.stat-valeur{font-family:var(--police-titre);font-size:27px;font-weight:600;line-height:1.15;color:var(--ink);font-variant-numeric:tabular-nums;}
.stat-valeur.negatif{color:var(--danger);}
.stat-detail{font-size:12px;color:var(--muted);margin-top:4px;}

.selecteur-periode{display:flex;gap:8px;margin-bottom:18px;}
.btn-periode,.btn-filtre-colis{padding:7px 14px;border-radius:6px;border:1px solid #C9D2DE;background:var(--paper-2);color:var(--text-on-paper);font-size:13.5px;font-weight:600;cursor:pointer;}
.btn-periode.actif,.btn-filtre-colis.actif{background:var(--ink);border-color:var(--ink);color:#fff;}

.ligne-barre{display:grid;grid-template-columns:160px 1fr auto;align-items:center;gap:12px;margin-bottom:10px;font-size:13px;}
.barre-label{color:var(--ink);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.barre-fond{background:var(--line-on-paper);border-radius:6px;height:10px;overflow:hidden;}
.barre-remplie{background:var(--emerald);height:100%;border-radius:6px;}
.barre-valeur{font-weight:700;white-space:nowrap;}

.liste-alertes{margin:0;padding-left:18px;font-size:13px;color:var(--amber);}
.liste-alertes li{margin-bottom:6px;}

.tableau-entete{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px;}

/* ---------- Cartes KPI à liseré coloré (tableau de bord) ---------- */
/* (v1.37.0) Cartes blanches, chiffre en Barlow, un repère de couleur à
   gauche par famille de donnée (ventes, alertes, colis…) : les dégradés
   pleins faisaient concurrence aux chiffres et fatiguaient l'œil. */
.kpi-grille{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;margin-bottom:18px;}
.kpi{display:flex;gap:12px;align-items:flex-start;border-radius:10px;padding:16px 18px 16px 20px;color:var(--text-on-paper);background:var(--paper-2);border:1px solid var(--line-on-paper);box-shadow:inset 3px 0 0 var(--kpi-repere,var(--emerald));}
.kpi-icone{display:none;}
.kpi-label{font-size:13px;color:var(--muted);font-weight:600;margin-bottom:4px;}
.kpi-valeur{font-family:var(--police-titre);font-size:26px;font-weight:600;line-height:1.15;color:var(--ink);font-variant-numeric:tabular-nums;}
.kpi-valeur.negatif{color:var(--danger);}
.kpi-detail{font-size:12.5px;color:var(--muted);margin-top:3px;}
.kpi-emerald{--kpi-repere:var(--emerald);}
.kpi-amber{--kpi-repere:#D99A1E;}
.kpi-bleu{--kpi-repere:var(--turquoise);}
.kpi-violet{--kpi-repere:#7A8CA8;}
.kpi-rouge{--kpi-repere:var(--danger);}

.grille-deux-colonnes{display:grid;grid-template-columns:1fr 1fr;gap:18px;}
@media (max-width:900px){.grille-deux-colonnes{grid-template-columns:1fr;}}

/* ---------- Pouls de la compagnie (jauge circulaire CSS) ---------- */
.pouls-corps{display:flex;align-items:center;gap:22px;}
.pouls-jauge{width:110px;height:110px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.pouls-jauge-centre{width:82px;height:82px;border-radius:50%;background:var(--paper-2);display:flex;flex-direction:column;align-items:center;justify-content:center;}
.pouls-score{font-family:var(--police-titre);font-size:24px;font-weight:700;color:var(--ink);line-height:1;}
.pouls-sur{font-size:11px;color:var(--muted);}
.pouls-libelle{font-weight:700;font-size:14px;margin-bottom:8px;}
.pouls-liste{margin:0;padding-left:18px;font-size:13px;color:var(--muted);}
.pouls-liste li{margin-bottom:4px;}

/* ---------- Hub des modules (accès rapide) ---------- */
.hub-grille{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;}
.hub-carte{display:flex;flex-direction:column;gap:4px;background:var(--paper-2);border:1px solid var(--line-on-paper);border-radius:10px;padding:14px 16px;text-decoration:none;color:var(--ink);transition:border-color .12s ease;}
.hub-carte:hover{border-color:var(--emerald);}
.hub-icone{display:none;}
.hub-label{font-family:var(--police-titre);font-size:16px;font-weight:600;}
.hub-valeur{font-size:12px;color:var(--muted);}
.hub-emerald{border-top:3px solid var(--emerald);}
.hub-amber{border-top:3px solid var(--amber);}
.hub-bleu{border-top:3px solid var(--turquoise);}
.hub-violet{border-top:3px solid #7A8CA8;}

table{width:100%;border-collapse:collapse;font-size:14px;}
th{text-align:left;font-size:13px;font-weight:600;color:var(--muted);padding:10px 12px;border-bottom:1px solid #C9D2DE;background:#F7F9FB;}
td{font-variant-numeric:tabular-nums;}
td{padding:11px 12px;border-bottom:1px solid #E8ECF1;}
tr:last-child td{border-bottom:none;}

.construction{
  text-align:center;padding:60px 20px;color:var(--muted);
}
.construction .badge-soon{
  display:inline-block;background:#E5EEFA;color:var(--emerald-deep);font-weight:700;
  font-size:12px;padding:6px 14px;border-radius:999px;margin-bottom:14px;
}

.form-row{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:14px;}
.form-row label{flex:1;min-width:160px;font-size:13px;font-weight:600;color:var(--muted);}
.form-row input,.form-row select{display:block;width:100%;margin-top:6px;padding:9px 10px;border:1px solid var(--line-on-paper);border-radius:8px;font-size:14px;background:var(--paper-2);color:var(--ink);}

/* ---------- Guichet : plan de sièges et vente de billet ---------- */
.legende-sieges{display:flex;gap:16px;font-size:12px;color:var(--muted);margin-bottom:12px;}
.legende-sieges .pastille{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:5px;vertical-align:middle;}
.pastille-libre{background:var(--succes);}
.pastille-reserve{background:var(--amber);}
.pastille-vendu{background:var(--muted);}
.plan-sieges{display:grid;grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:8px;margin-bottom:18px;max-width:520px;}
.siege{aspect-ratio:1;border-radius:8px;border:1px solid var(--line-on-paper);font-weight:700;font-size:13px;cursor:pointer;background:var(--paper);color:var(--ink);}
.siege-libre{background:#E6F3EC;border-color:var(--succes);color:#17603D;}
.siege-libre:hover{background:var(--succes);color:#fff;}
.siege-reserve{background:rgba(200,140,20,0.14);border-color:var(--amber);color:var(--amber);cursor:not-allowed;}
.siege-vendu{background:var(--line-on-paper);color:var(--muted);cursor:not-allowed;}
.form-vente-billet{max-width:560px;margin-top:10px;padding-top:16px;border-top:1px solid var(--line-on-paper);}

/* ---------- RH : cases à cocher des modules ---------- */
.modules-par-categorie{display:flex;flex-direction:column;gap:8px;max-width:460px;}
.modules-categorie-titre{display:block;font-size:12.5px;font-weight:700;color:var(--ink);margin-top:4px;}
.modules-categorie-titre:first-child{margin-top:0;}
.modules-checkboxes{display:flex;flex-wrap:wrap;gap:8px 14px;max-width:420px;}
.ligne-nouvel-employe{background:#FFF8E8;box-shadow:inset 3px 0 0 var(--amber,#F59E0B);}
.module-checkbox{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--muted);font-weight:600;cursor:pointer;}
.module-checkbox input{margin:0;}

.badge-quota{font-size:12px;font-weight:700;padding:4px 10px;border-radius:999px;background:#E5EEFA;color:var(--emerald-deep);}
.badge-quota.depasse{background:#FDEAEA;color:var(--danger);}

/* ---------- Communication : messagerie interne ---------- */
.liste-conversations{display:flex;flex-direction:column;gap:2px;max-height:420px;overflow-y:auto;}
.conversation-item{padding:10px 12px;border-radius:9px;cursor:pointer;}
.conversation-item:hover{background:var(--paper);}
.conversation-titre{font-weight:700;font-size:14px;color:var(--ink);}
.conversation-dernier{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.liste-messages{display:flex;flex-direction:column;gap:10px;max-height:360px;overflow-y:auto;padding:4px 2px;}
.message-item{max-width:75%;background:var(--paper);border-radius:10px;padding:8px 12px;align-self:flex-start;}
.message-item.message-moi{align-self:flex-end;background:#E5EEFA;}
.message-auteur{font-size:11px;font-weight:700;color:var(--muted);margin-bottom:2px;}
.message-contenu{font-size:14px;color:var(--text-on-paper);white-space:pre-wrap;word-break:break-word;}
.message-heure{font-size:10px;color:var(--muted);margin-top:3px;}

/* ---------- Console éditeur : badges de statut & onglets ---------- */
.badge-statut{display:inline-block;font-size:12.5px;font-weight:600;padding:3px 10px;border-radius:999px;white-space:nowrap;}
.badge-statut-essai{background:#FEF6E7;color:#8A6100;}
.badge-statut-actif{background:#E6F3EC;color:#17603D;}
.badge-statut-suspendu{background:#FEF6E7;color:var(--amber-deep);}
.badge-statut-revoque,.badge-statut-supprime{background:#FDEAEA;color:var(--danger);}
.onglets-editeur{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap;}
.onglet-editeur{padding:8px 16px;border-radius:6px;border:1px solid #C9D2DE;background:var(--paper-2);color:var(--text-on-paper);font-size:14px;font-weight:600;cursor:pointer;}
.onglet-editeur.actif{background:var(--ink);border-color:var(--ink);color:#fff;}
/* Cellule d'actions : la cellule reste une cellule de tableau (sinon ses
   bordures et sa hauteur se décalent du reste de la ligne) ; seuls ses
   boutons sont disposés en flex, via la div intérieure. */
.actions-ligne > .actions-ligne-boutons{display:flex;gap:6px;flex-wrap:wrap;min-width:220px;}
.actions-ligne .btn{padding:7px 12px;font-size:12px;}
.qr-apercu{display:flex;gap:20px;flex-wrap:wrap;}
.qr-bloc{border:1px solid var(--line-on-paper);border-radius:12px;padding:16px;text-align:center;width:220px;}
.qr-bloc img{max-width:160px;width:100%;border-radius:6px;margin-bottom:10px;}
.qr-image{min-height:160px;display:flex;align-items:center;justify-content:center;margin-bottom:10px;}
.qr-image img{margin-bottom:0;}
.qr-choisir{display:flex;flex-direction:column;gap:6px;font-size:13px;font-weight:600;text-align:left;margin-bottom:8px;}
.qr-choisir input[type="file"]{font-size:12px;width:100%;font-weight:400;}
.qr-fichier{font-size:12px;color:var(--muted);margin:0 0 8px;text-align:left;overflow-wrap:anywhere;}
.qr-fichier-ko{color:var(--danger);}
.qr-bloc .qr-vide{width:160px;height:160px;margin:0 auto 10px;border:1px dashed var(--line-on-paper);border-radius:6px;display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:12px;}

.chargement{color:var(--muted);font-size:14px;padding:20px 0;}
.erreur-vue{background:#FDEAEA;color:var(--danger);border:1px solid #F3C6C6;border-radius:9px;padding:12px 14px;font-size:14px;}
.avertissement{background:#FEF6E7;color:#8A6100;border:1px solid #F5DCA0;border-radius:9px;padding:12px 14px;font-size:14px;margin-bottom:12px;}

/* ---------- Tickets imprimables (billet voyage, bagage, colis) ---------- */
/* Format "reçu" compact (80mm) — en attendant le gabarit exact fourni par
   le client, pour que le bouton Imprimer soit déjà exploitable au guichet.
   `.no-print` cache les boutons d'action à l'impression ; `@media print`
   masque tout SAUF le ticket actuellement affiché (data-impression-active). */
.ticket-imprimable{
  max-width:320px;margin:14px 0;padding:16px;border:1px dashed var(--line-on-paper);
  border-radius:10px;background:#fff;font-family:'Courier New',monospace;font-size:13px;color:#111;
}
.ticket-imprimable h4{margin:0 0 8px;font-size:15px;text-align:center;letter-spacing:0.04em;}
.ticket-imprimable .ticket-ligne{display:flex;justify-content:space-between;gap:10px;margin:3px 0;}
.ticket-imprimable .ticket-separateur{border:none;border-top:1px dashed #999;margin:8px 0;}
.ticket-imprimable .ticket-qr{display:block;margin:10px auto 4px;width:130px;height:130px;}
.ticket-imprimable .ticket-pied{text-align:center;font-size:11px;color:#555;margin-top:6px;}
@media print {
  body *{visibility:hidden;}
  .ticket-imprimable[data-impression-active], .ticket-imprimable[data-impression-active] *{visibility:visible;}
  .ticket-imprimable[data-impression-active]{position:absolute;top:0;left:0;width:100%;border:none;}
  .no-print{display:none !important;}
}

/* Compagnies & abonnements (v1.35.0) */
.sa-entete-tableau{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;}
.sa-entete-tableau h3{margin:0;}
.sa-mois{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--muted);}
.sa-mois select{padding:7px 10px;border:1px solid var(--line-on-paper);border-radius:8px;font:inherit;color:var(--ink);background:var(--paper-2);}
.sa-legende{font-size:12px;color:var(--muted);margin:8px 0 12px;}
.sa-defilant{overflow-x:auto;}
.sa-compagnies td{vertical-align:top;}
.sa-compagnies th.num,.sa-compagnies td.num{text-align:right;}
.sa-th-detail{text-transform:none;letter-spacing:0;font-weight:500;}
.sa-sous{font-size:12px;color:var(--muted);margin-top:2px;white-space:nowrap;}
.sa-nowrap{white-space:nowrap;}
.sa-compagnies td:nth-child(8) .sa-sous{white-space:normal;min-width:190px;}
table.sa-mini{width:auto;border-collapse:collapse;font-size:12.5px;font-variant-numeric:tabular-nums;}
table.sa-mini th,table.sa-mini td{padding:2px 6px;border:none;text-align:right;white-space:nowrap;}
table.sa-mini th{font-size:11px;letter-spacing:0;color:var(--muted);text-transform:none;border-bottom:1px solid var(--line-on-paper);}
table.sa-mini td.sa-mini-gare{text-align:left;font-weight:600;color:var(--ink);max-width:150px;overflow:hidden;text-overflow:ellipsis;padding-left:0;}
table.sa-mini tr.sa-mini-total td{font-weight:800;border-bottom:1px solid var(--line-on-paper);}
table.sa-mini abbr{text-decoration:none;font-size:10px;font-weight:800;color:#fff;background:var(--emerald);border-radius:4px;padding:1px 4px;margin-right:2px;}
table.sa-mini abbr.sa-abbr-nr{background:var(--muted);}

/* Espaces de travail sur petit écran (v1.36.0) : rien ne doit élargir la
   page. Les tableaux défilent dans leur cadre (cf. envelopperTableaux), les
   rangées de boutons passent à la ligne, les mots très longs (e-mails,
   références) se coupent. */
.tableau-defilant{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;}
.vue{min-width:0;overflow-wrap:anywhere;}
.vue table{overflow-wrap:normal;}
.selecteur-periode,.tableau-entete{flex-wrap:wrap;gap:8px;}
@media (max-width:860px){
  .vue .carte{padding:16px;}
  .vue .form-row label{min-width:0;flex-basis:100%;}
  .topbar .utilisateur-info{max-width:40vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
}
@media print{ .tableau-defilant{overflow:visible;} }
/* Listes déroulantes et champs hors formulaire (filtres du tableau de bord,
   choix du mois, recherches) : même apparence que ceux des formulaires.
   Spécificité nulle (:where) : tout style plus précis garde la main. */
:where(.vue) select,
:where(.vue input:not([type=checkbox],[type=radio],[type=file],[type=color],[type=range])){
  padding:8px 10px;border:1px solid var(--line-on-paper);border-radius:8px;
  background:var(--paper-2);color:var(--ink);font:inherit;font-size:13.5px;max-width:100%;
}
.sa-ancienne-grille{display:inline-block;margin-top:4px;font-size:11px;font-weight:700;color:#8A6100;background:#FEF6E7;border-radius:999px;padding:2px 8px;}

/* ---------- Identité Billetix (v1.37.0) : finitions communes ---------- */
body{font-size:15px;line-height:1.45;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}
h1,h2,h3,h4{color:var(--ink);font-weight:600;}
:focus-visible{outline:2px solid var(--emerald);outline-offset:2px;}
.sidebar :focus-visible{outline-color:var(--repere);}
.stat-valeur,.kpi-valeur,.barre-valeur,td.num,th.num{font-variant-numeric:tabular-nums;}
@media (prefers-reduced-motion:reduce){*{transition:none !important;animation:none !important;}}

/* ---------- Comptes bloqués (v1.42.0) ---------- */
.liste-tentatives{margin:0;padding-left:16px;font-size:12.5px;line-height:1.5;min-width:220px;}
.form-debloquer{display:flex;gap:8px;align-items:center;flex-wrap:wrap;min-width:260px;}
.form-debloquer .champ-mdp{margin-top:0;flex:1 1 180px;}
.login-otp-texte{font-size:14px;color:var(--muted, #5B6B7E);margin:0 0 14px;line-height:1.5;}
#form-otp .btn-secondary{margin-top:8px;}
#form-otp #login-otp{letter-spacing:6px;font-size:20px;text-align:center;}
