/* ------------------------------------------
   COULEUR DE TEXTE GLOBALE
   Le texte heritait du noir pur (#000) du navigateur (aucune couleur body
   n'etait definie). On aligne sur la couleur de texte du design system
   (--text = #1f2a37, cf. docs/DESIGN_SYSTEM.html, CLAUDE.md §17) : plus doux
   que le noir. N'affecte QUE le texte qui herite (les couleurs explicites
   restent inchangees). Teinte "encre/slate", pas une couleur emeraude (§1 OK).
   ------------------------------------------ */
body { color: #1f2a37; }

/* ------------------------------------------
   ANIMATIONS KEYFRAMES
   ------------------------------------------ */
@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50% { transform: translateY(-8px); }
}

/* ------------------------------------------
   ETAT VIDE "AUCUN RESULTAT" PARTAGE (eqm-empty)
   Design unique pour les resultats de recherche sans correspondance.
   Ne controle PAS l'affichage (chaque module garde son toggle :
   .visible / .hidden / display:none). Supporte <svg> et <i>.
   ------------------------------------------ */
@keyframes eqmEmptyIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}
.eqm-empty {
    text-align: center;
    padding: 64px 24px 72px;
    animation: eqmEmptyIn .4s cubic-bezier(.22, 1, .36, 1);
}
.eqm-empty-icon {
    width: 92px;
    height: 92px;
    margin: 0 auto 24px;
    border-radius: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--primary);
    background: linear-gradient(145deg, var(--primary-50b), var(--primary-100));
    box-shadow:
        0 14px 32px -12px rgba(var(--primary-rgb), .38),
        inset 0 0 0 1px rgba(var(--primary-rgb), .12);
    position: relative;
}
.eqm-empty-icon::after {
    content: '';
    position: absolute;
    inset: -9px;
    border-radius: 32px;
    border: 1.5px dashed rgba(var(--primary-rgb), .22);
}
.eqm-empty-icon svg { width: 42px; height: 42px; }
.eqm-empty-icon i   { font-size: 36px; line-height: 1; }
.eqm-empty-title {
    font-family: 'Outfit', sans-serif;
    font-size: 21px;
    font-weight: 600;
    color: #1e293b;
    margin: 0 0 8px;
}
.eqm-empty-text {
    font-size: 15px;
    color: #64748b;
    font-weight: 400;
    max-width: 360px;
    margin: 0 auto;
    line-height: 1.5;
}

@keyframes slideUp {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes scaleIn {
    from { opacity: 0; transform: scale(0.95); }
    to { opacity: 1; transform: scale(1); }
}

@keyframes pulse-soft {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

/* Modals : keyframes de base dans css/eqm-modal.css */

/* ------------------------------------------
   CLASSES D'ANIMATION
   ------------------------------------------ */
.animate-float { animation: float 5s ease-in-out infinite; }
.animate-slide-up { animation: slideUp 0.6s ease-out forwards; }
.animate-scale-in { animation: scaleIn 0.4s ease-out forwards; }
.animate-pulse-soft { animation: pulse-soft 2s ease-in-out infinite; }

/* Delais d'animation echelonnes */
.stagger-1 { animation-delay: 0.05s; }
.stagger-2 { animation-delay: 0.1s; }
.stagger-3 { animation-delay: 0.15s; }
.stagger-4 { animation-delay: 0.2s; }
.stagger-5 { animation-delay: 0.25s; }
.stagger-6 { animation-delay: 0.3s; }
.animate-on-load { opacity: 0; }

/* ------------------------------------------
   SCROLLBAR PERSONNALISEE (visible pour listes/tableaux)
   ------------------------------------------ */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track {
    background: #f1f5f9;
    border-radius: 10px;
}
::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, var(--primary), var(--primary-dark));
    border-radius: 10px;
    border: 2px solid #f1f5f9;
}
::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, var(--primary-dark), var(--primary-darker));
}
/* Firefox */
* { scrollbar-width: thin; scrollbar-color: var(--primary) #f1f5f9; }

/* ------------------------------------------
   CARTES NEUMORPHIQUES
   ------------------------------------------ */
.neu-card {
    background: linear-gradient(145deg, #ffffff, #f8faf9);
    box-shadow:
        8px 8px 20px rgba(0, 0, 0, 0.05),
        -8px -8px 20px rgba(255, 255, 255, 0.9),
        inset 0 0 0 1px rgba(255, 255, 255, 0.5);
}

/* ------------------------------------------
   ELEMENTS DECORATIFS (BLOBS)
   ------------------------------------------ */
.blob {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.4;
    pointer-events: none;
}

/* ------------------------------------------
   PATTERN DE FOND
   ------------------------------------------ */
.pattern-bg {
    background-image: radial-gradient(
        circle at 1px 1px,
        rgba(var(--primary-rgb), 0.03) 1px,
        transparent 0
    );
    background-size: 32px 32px;
}

/* ------------------------------------------
   EFFET GLOW SUR ICONES
   ------------------------------------------ */
.icon-glow { position: relative; }
.icon-glow::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: inherit;
    background: inherit;
    filter: blur(12px);
    opacity: 0.4;
    z-index: -1;
}

/* ------------------------------------------
   NAVIGATION - ELEMENT ACTIF
   ------------------------------------------ */
.nav-active {
    position: relative;
    background-color: rgba(var(--primary-rgb), 0.12);
    color: var(--primary-darker);
    font-weight: 500;
}
.nav-active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 15%;
    height: 70%;
    width: 3px;
    background: linear-gradient(180deg, var(--primary), var(--primary-light));
    border-radius: 0 4px 4px 0;
}

/* Survol : la couleur du thème, jamais le gris.
   Les entrées portent un `hover:bg-slate-50` de Tailwind (spécificité 0,0,2,0) ;
   l'identifiant #mainNavigation (0,1,1,1) passe devant sans avoir à éditer les
   ~50 attributs class du header. Les pastilles d'icônes gardent leur couleur de
   module (group-hover:bg-teal-100, amber-100...) : c'est leur identité. */
#mainNavigation a:hover,
#mainNavigation button:hover {
    background-color: rgba(var(--primary-rgb), 0.08);
    color: var(--primary-darker);
}

/* Survol de l'entrée déjà courante : un cran au-dessus, sinon le survol
   l'éclaircirait au lieu de la marquer. */
#mainNavigation .nav-active:hover,
#mainNavigation .submenu-link-active:hover {
    background-color: rgba(var(--primary-rgb), 0.18);
}

/* ------------------------------------------
   SOUS-MENUS
   ------------------------------------------ */
.submenu {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
}
.submenu.open {
    max-height: 60vh;
    overflow-y: auto;
}
.submenu::-webkit-scrollbar { width: 4px; }
.submenu::-webkit-scrollbar-track { background: transparent; }
.submenu::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
.submenu::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

.submenu-toggle .chevron { transition: transform 0.3s ease; }

/* Lien du sous-menu actif (page courante) */
.submenu-link-active {
    background-color: rgba(var(--primary-rgb), 0.10);
    color: var(--primary-darker);
    font-weight: 600;
}
.submenu-toggle.open .chevron { transform: rotate(180deg); }

/* ============================================================================
   « ACTIVEZ VOTRE COMPTE OPADDOCK » -- LE RAPPEL DU MENU (12/09/2026)
   ----------------------------------------------------------------------------
   Demande du client : « il faudrait que tu les sollicite pour qu'il active leur
   compte, mettre un petit truc en rouge, un truc clinquant ».

   POURQUOI DU ROUGE, alors que le §1 impose la couleur du theme. Le §1 interdit
   d'ecrire la couleur EMERAUDE en dur -- celle qui doit suivre le theme du
   centre. Ce rappel dit exactement le contraire : il doit se detacher du menu,
   quel que soit le theme choisi. Un rappel a la couleur du theme dans un menu a
   la couleur du theme ne signale rien -- c'est le constat qui a fait passer le
   compteur de messages non lus en rouge le meme jour (§86.9). C'est la meme
   famille de rouge, volontairement : dans ce menu, rouge = « quelque chose
   t'attend ».

   ET IL EST LE SEUL : s'il y en avait deux, aucun ne se verrait.
   ========================================================================== */
.opa-rappel {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .1rem .5rem .12rem;
    border-radius: 999px;
    background: #fef2f2;
    border: 1.5px solid #fecaca;
    color: #b91c1c;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .02em;
    text-transform: uppercase;
    white-space: nowrap;
}
/* Le point qui respire. C'est LUI le « clinquant » : la pastille reste sobre,
   le mouvement fait le travail -- et il s'arrete net pour qui a demande moins
   d'animation. Trois secondes de cycle : present, jamais agitant. */
.opa-rappel-pt {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #ef4444;
    box-shadow: 0 0 0 0 rgba(239, 68, 68, .6);
    animation: opaRappelBat 3s ease-out infinite;
}
@keyframes opaRappelBat {
    0%        { box-shadow: 0 0 0 0 rgba(239, 68, 68, .55); }
    35%, 100% { box-shadow: 0 0 0 7px rgba(239, 68, 68, 0); }
}
/* L'entree de sous-menu qui dit QUOI faire. Fond tres pale au repos : elle se
   distingue des autres entrees sans hurler, et le survol assume le rouge. */
.opa-rappel-lien {
    color: #b91c1c;
    background: #fef2f2;
    transition: background .15s ease, color .15s ease;
}
.opa-rappel-lien:hover,
.opa-rappel-lien:focus-visible {
    background: #fee2e2;
    color: #991b1b;
}
.opa-rappel-lien:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(239, 68, 68, .3);
}
@media (prefers-reduced-motion: reduce) {
    .opa-rappel-pt { animation: none; box-shadow: none; }
    .opa-rappel-lien { transition: none; }
}

/* Sous-sous-menu Interface comptable */
.submenu-compta {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
    /* Menu du haut / compact : .submenu devient une COLONNE FLEX bornée à 60vh.
       Avec overflow: hidden, ce bloc peut y rétrécir jusqu'à 0 : le menu ne
       déborde alors jamais, n'affiche aucun ascenseur, et le bas du bloc
       (« Remise en banque ») est rogné sans moyen d'y accéder. Il garde donc sa
       hauteur, et c'est le menu qui défile (08/10/2026, Étrier de Bourgogne). */
    flex-shrink: 0;
}
/* Plafond LARGE, et c'est voulu : il ne sert qu'à l'animation d'ouverture.
   À 250px, en menu du haut (entrées de ~52px), « Prélèvements » était coupé et
   « Remise en banque » invisible, sans aucun défilement possible (overflow:
   hidden). C'est le conteneur .submenu.open (60vh, overflow-y: auto) qui fait
   défiler quand l'écran est trop petit, pas ce bloc. */
.submenu-compta.open { max-height: 40rem; }
.submenu-compta-toggle .compta-chevron { transition: transform 0.3s ease; }
.submenu-compta-toggle.open .compta-chevron { transform: rotate(90deg); }

/* ------------------------------------------
   FOCUS CLAVIER DU MENU LATERAL
   ------------------------------------------
   Les entrées du menu sont de vrais <a>/<button>, donc atteignables au clavier,
   mais elles n'avaient que des états :hover : le focus se déplaçait sans que rien
   ne se voie. On pose la couleur du thème (§1) et jamais une couleur en dur.

   Contour INTERNE (outline-offset négatif) et non un halo : #mainNavigation et
   .submenu.open sont en overflow auto, ils rogneraient un anneau posé à
   l'extérieur de l'élément. L'outline suit le border-radius tout seul. */
/* Le FOND est posé sur :focus — donc au clic comme au clavier : l'entrée sur
   laquelle on est se teinte de la couleur du thème, jamais d'un gris neutre. */
#sidebar a:focus,
#sidebar button:focus {
    background-color: rgba(var(--primary-rgb), 0.14);
    color: var(--primary-darker);
}

/* Le CONTOUR, lui, ne concerne que le clavier : au clic il serait du bruit. */
#sidebar a:focus-visible,
#sidebar button:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: -2px;
}
#sidebar a:focus:not(:focus-visible),
#sidebar button:focus:not(:focus-visible) {
    outline: none;
}

/* ------------------------------------------
   MENU UTILISATEUR (POPUP)
   ------------------------------------------ */
.user-menu {
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    background: white;
    border-radius: 16px;
    margin-bottom: 8px;
    box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0,0,0,0.05);
    z-index: 100;
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: all 0.3s ease;
}
.user-menu.open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* ------------------------------------------
   SIDEBAR - MOBILE & DESKTOP
   ------------------------------------------ */
/* ⚠️ LE TIROIR PASSE AU-DESSUS DE TOUTE BANDE DU BAS (09/10/2026).
   Signalement client : « sur une fiche d'événement, quand j'ouvre le menu après
   avoir vu Réserver / Annuler ma place, je ne vois plus le bas du menu ».
   La bande « Ma réservation en ligne » est déplacée dans le <body> par
   `efCliAncrerResa()` et monte à 90 ; le FAB va à 890, le chatbot à 1200. Tant
   que le menu vivait dans le conteneur `z-10` de `header.php`, AUCUN z-index
   écrit ici ne pouvait le faire passer devant : un contexte d'empilement plafonne
   tout ce qu'il contient. Le menu et son fond en sont donc sortis (`header.php`),
   et c'est seulement de là que ces deux valeurs ont un effet.
   9001 / 9000 : au-dessus de la page et de ses bandes, et SOUS les modaux (9999),
   la confirmation (10100) et les toasts (10003) -- qui doivent couvrir le menu. */
.sidebar {
    position: fixed;
    top: 0;
    right: 0;
    height: 100%;
    width: 320px;
    max-width: 85vw;
    background: white;
    border-left: 1px solid #e2e8f0;
    z-index: 9001;
    transform: translateX(100%);
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    flex-direction: column;
    box-shadow: -10px 0 40px rgba(0, 0, 0, 0.1);
}
.sidebar.open { transform: translateX(0); }

/* Sidebar Desktop - Positionnee a gauche */
@media (min-width: 1024px) {
    .sidebar {
        left: 0;
        right: auto;
        width: 300px;
        max-width: none;
        border-left: none;
        border-right: 1px solid #f1f5f9;
        transform: translateX(0);
        background: rgba(255, 255, 255, 0.8);
        backdrop-filter: blur(20px);
        -webkit-backdrop-filter: blur(20px);
        box-shadow: 10px 0 40px rgba(0, 0, 0, 0.05);
        /* Sur PC ce n'est plus un tiroir mais une COLONNE : rien ne la recouvre,
           et elle reprend donc la hauteur d'empilement que le conteneur `z-10` lui
           donnait jusqu'ici.

           ⚠️ 11, PAS 10, ET C'EST TOUTE LA DIFFERENCE (09/10/2026). Le conteneur
           de page de `header.php` est `<div class="relative z-10 ...">`, donc lui
           aussi à 10 -- et A EGALITE DE Z-INDEX, C'EST LE DERNIER DANS LE DOM QUI
           GAGNE. L'`<aside>` du menu est émis bien avant lui : le conteneur passait
           donc PAR-DESSUS le menu. Comme il n'a aucun fond, il reste invisible --
           le menu s'affichait parfaitement, et AUCUN de ses liens n'était cliquable.
           Sur PC uniquement, puisque la règle vit dans cette media query.

           Mesuré au navigateur sur une page réelle : 0 lien cliquable sur 5 à
           z-index 10, 5 sur 5 dès 11. Ne pas redescendre à 10. */
        z-index: 11;
    }
    /* REVERS DU 11 : LES MODAUX RENDUS DANS LA PAGE PASSAIENT SOUS LE MENU (12/10/2026).
       Le conteneur de page (`.eqm-page-conteneur`, z-10) est un contexte
       d'empilement : un modal rendu à l'intérieur -- « Nouvelle facture »
       (.fact-modal-overlay, 9002), l'envoi, la confirmation... -- ne vaut que 10
       face au reste du document. Le menu à 11 recouvrait donc toute la partie
       gauche du modal, et le sélecteur de client (porté au <body>) s'ouvrait à
       moitié caché derrière lui.
       On n'abaisse pas le menu (ses liens redeviendraient inertes) : c'est le
       conteneur qui monte, et seulement le temps qu'un modal de la page est
       ouvert. 9002 le laisse sous ce qui vit au <body> et doit couvrir un modal
       -- .eqm-modal (9999), menu d'actions d'une fiche en modal (10080), dropdown
       eqm-select (10000), confirmation (10100), toasts (10003).
       Même liste que `_eqmCloseAny()` (footer.php) : toutes ces familles
       s'ouvrent par la classe `.show`. Le `:has` porte sur le CONTENEUR, pas
       sur <body> : un overlay de ces familles déplacé au <body> avec un z-index
       bas (`.ef-modal-ov` est à 200) passerait sinon SOUS la page relevée. */
    .eqm-page-conteneur:has(:is(.fact-modal-overlay, .fact-email-overlay, .fact-confirm-overlay,
                 .comm-msg-modal, .ef-modal-ov, .modal-overlay, .msg-overlay,
                 .ca-modal-overlay, .confirm-overlay, .theme-modal).show) {
        z-index: 9002;
    }
    .sidebar .mobile-header { display: none; }
    .sidebar .desktop-header { display: block; }
}

/* ------------------------------------------
   OVERLAY SIDEBAR MOBILE
   ------------------------------------------ */
.sidebar-overlay {
    position: fixed;
    inset: 0;
    background: rgba(255, 255, 255, .35);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    z-index: 9000;   /* juste sous le tiroir : voir le commentaire de .sidebar */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}
.sidebar-overlay.open { opacity: 1; visibility: visible; pointer-events: auto; }

@media (min-width: 1024px) {
    .sidebar-overlay { display: none !important; }
}

/* ------------------------------------------
   GRAPHIQUES
   ------------------------------------------ */
.chart-container {
    position: relative;
    height: 260px;
}

/* ------------------------------------------
   UTILITAIRES
   ------------------------------------------ */
.card-hover {
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.focus-ring:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.3);
}

/* ------------------------------------------
   ANIMATIONS SUPPLEMENTAIRES (LOGIN)
   ------------------------------------------ */
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

.animate-fade-in { animation: fadeIn 0.8s ease-out forwards; }

/* ------------------------------------------
   PAGE DE CONNEXION - COTE IMAGE
   ------------------------------------------ */
.image-side {
    position: relative;
    overflow: hidden;
}
.image-side::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        135deg,
        rgba(6, 78, 59, 0.85) 0%,
        rgba(5, 150, 105, 0.7) 100%
    );
}
.image-bg {
    position: absolute;
    inset: 0;
    background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"><rect fill="%23065f46"/><g fill="%23047857" opacity="0.4"><circle cx="200" cy="300" r="150"/><circle cx="800" cy="200" r="200"/><circle cx="600" cy="700" r="180"/><circle cx="150" cy="800" r="120"/></g></svg>') center/cover;
}

@media (max-width: 1024px) {
    .image-side { display: none; }
}

/* ------------------------------------------
   CHAMPS DE SAISIE MINIMALISTES (LOGIN)
   ------------------------------------------ */
/* Champ « plug » du design system (docs/DESIGN_SYSTEM.html, input.f) :
   bordure complète, coins arrondis, halo du thème au focus. */
.input-minimal {
    min-height: 56px;
    border: 1.5px solid #cbd5e1;
    border-radius: 14px;
    background: #fff;
    padding: 14px 52px 14px 18px;
    font-size: 16px;
    font-weight: 500;
    transition: border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
}
.input-minimal:hover {
    border-color: var(--primary-200);
}
.input-minimal:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 4px rgba(var(--primary-rgb), .13);
}
.input-minimal::placeholder {
    color: #6b7785;
    font-weight: 400;
}
/* Remplissage automatique du navigateur : on neutralise le fond bleu
   (un box-shadow intérieur est la seule façon de le couvrir). */
.input-minimal:-webkit-autofill,
.input-minimal:-webkit-autofill:hover {
    -webkit-box-shadow: 0 0 0 100px #fff inset;
    -webkit-text-fill-color: #1f2a37;
    caret-color: #1f2a37;
}
.input-minimal:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 100px #fff inset, 0 0 0 4px rgba(var(--primary-rgb), .13);
}

/* Input avec icône */
.input-icon {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    color: #9ca3af;
    pointer-events: none;
    transition: color .2s ease, background-color .2s ease;
}
button.input-icon {
    pointer-events: auto;
    background: transparent;
    border: none;
}
button.input-icon:hover {
    background: rgba(var(--primary-rgb), .08);
}
button.input-icon:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 0;
}
.input-wrapper:focus-within .input-icon {
    color: var(--primary);
}
@media (prefers-reduced-motion: reduce) {
    .input-minimal, .input-icon { transition: none; }
}

/* ------------------------------------------
   TEXTE AVEC DEGRADE (LOGIN)
   ------------------------------------------ */
.gradient-text {
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

/* ------------------------------------------
   BOUTONS (LOGIN)
   ------------------------------------------ */
.btn-primary {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    box-shadow: 0 4px 15px rgba(var(--primary-rgb), 0.3);
    transition: all 0.3s ease;
}
.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(var(--primary-rgb), 0.4);
}
.btn-primary:active {
    transform: translateY(0);
}

.btn-ghost {
    border: 1px solid #e5e7eb;
    background: transparent;
    transition: all 0.3s ease;
}
.btn-ghost:hover {
    border-color: var(--primary);
    color: var(--primary);
}

/* ------------------------------------------
   CHECKBOX PERSONNALISEE (LOGIN)
   ------------------------------------------ */
.checkbox-custom {
    appearance: none;
    width: 20px;
    height: 20px;
    border: 2px solid #d1d5db;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;
}
.checkbox-custom:checked {
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    border-color: transparent;
}
.checkbox-custom:checked::after {
    content: '';
    position: absolute;
    left: 6px;
    top: 3px;
    width: 5px;
    height: 9px;
    border: solid white;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* ------------------------------------------
   SEPARATEUR (LOGIN)
   ------------------------------------------ */
.divider {
    display: flex;
    align-items: center;
    gap: 16px;
}
.divider::before,
.divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: #e5e7eb;
}

/* ------------------------------------------
   ELEMENTS DE LA PAGE DE CONNEXION
   ------------------------------------------ */
.feature-item {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.testimonial-card {
    background: rgba(255, 255, 255, 0.08);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
}

/* ================================================================
   PAGE LISTE CAVALIERS - VARIABLES CSS GLOBALES - THEME OPADDOCK
   ================================================================ */
:root {
    /* ANCRE HORIZONTALE des boutons flottants du coin bas-droite (chatbot + FAB).
       Pendant de --eqm-bottombar-h, qui regle la verticale (CLAUDE.md §10c).

       Pourquoi une variable : les deux boutons avaient chacun leur `right`, et ils
       ont derive -- 56px pour le FAB sur PC (pour « eviter » l'index alphabetique,
       qui est en realite a MI-HAUTEUR, top:50%), 24px sur mobile, 20px puis 16px
       pour le chatbot. Resultat : deux boutons visiblement desalignes sur toutes
       les pages, dont la fiche client.

       Une page qui a VRAIMENT quelque chose dans ce coin releve cette variable, et
       toute la pile se decale ensemble. Ne posez plus de `right` en dur. */
    --eqm-fab-right: 20px;

    --primary: #10b981;
    --primary-dark: #059669;
    --primary-darker: #047857;
    --primary-light: #34d399;
    --primary-300: #6ee7b7;
    --primary-200: #a7f3d0;
    --primary-100: #d1fae5;
    --primary-50: #ecfdf5;
    --primary-50b: #f0fdf4;
    --primary-rgb: 16, 185, 129;
    --primary-ultra-light: rgba(16, 185, 129, 0.08);
    --primary-glow: rgba(16, 185, 129, 0.3);
    --secondary: #0d9488;
    --accent: #f59e0b;
    --glass-bg: rgba(255, 255, 255, 0.65);
    --glass-border: rgba(255, 255, 255, 0.5);
    --glass-strong: rgba(255, 255, 255, 0.85);
    --text-dark: #064e3b;
    --text-medium: #065f46;
    --text-light: #6b7280;
    --text-muted: #9ca3af;
    --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.04);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.06);
    --shadow-lg: 0 20px 40px rgba(0, 0, 0, 0.08);
    --shadow-xl: 0 25px 60px rgba(0, 0, 0, 0.12);
    --radius-sm: 12px;
    --radius-md: 16px;
    --radius-lg: 24px;
    --radius-xl: 32px;
}

/* Ancre horizontale, valeur SMARTPHONE. Elle vit ici, avec la valeur par defaut, et
   non dans la feuille du chatbot : celle-ci n'est chargee que sur les pages qui
   affichent le widget, si bien que le FAB des autres pages serait reste a 20px.
   Une media query ne peut pas se declarer a l'interieur du bloc :root ci-dessus. */
@media (max-width: 480px) {
    :root { --eqm-fab-right: 16px; }
}


/* ================================================================
   BLOBS ANIMES - FOND DECORATIF FLOTTANT (LISTE CAVALIERS)
   ================================================================ */
.blob-1 {
    width: 500px; height: 500px;
    background: linear-gradient(135deg, var(--primary-light), var(--secondary));
    top: -100px; left: -100px;
    animation: blobFloat1 20s ease-in-out infinite;
}
.blob-2 {
    width: 400px; height: 400px;
    background: linear-gradient(135deg, var(--accent), var(--primary));
    bottom: -80px; right: -80px;
    animation: blobFloat2 18s ease-in-out infinite;
}
.blob-3 {
    width: 300px; height: 300px;
    background: linear-gradient(135deg, var(--primary), var(--primary-300));
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    animation: blobFloat3 22s ease-in-out infinite;
}

@keyframes blobFloat1 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33% { transform: translate(60px, 80px) scale(1.15); }
    66% { transform: translate(-40px, 40px) scale(0.9); }
}
@keyframes blobFloat2 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33% { transform: translate(-70px, -50px) scale(1.1); }
    66% { transform: translate(50px, -80px) scale(0.95); }
}
@keyframes blobFloat3 {
    0%, 100% { transform: translate(-50%, -50%) scale(1); }
    50% { transform: translate(-50%, -50%) scale(1.25); }
}

/* ================================================================
   PATTERN DE FOND - GRILLE DE POINTS (LISTE CAVALIERS)
   ================================================================ */
.pattern-overlay {
    position: fixed; inset: 0;
    background-image: radial-gradient(circle at 1px 1px, rgba(var(--primary-rgb), 0.04) 1px, transparent 0);
    background-size: 36px 36px;
    pointer-events: none; z-index: 0;
}

/* ================================================================
   CONTENEUR PRINCIPAL - PLEINE LARGEUR (LISTE CAVALIERS)
   ================================================================ */
.app-container {
    position: relative;
    z-index: 1;
    margin: 0;
    padding: 24px 32px;
    padding-right: 64px; /* ESPACE POUR L'INDEX ALPHABETIQUE */
}

@keyframes cardAppear {
    to { opacity: 1; transform: translateY(0); }
}

/* ================================================================
   BARRE D'OUTILS - RECHERCHE + BOUTONS DESKTOP (LISTE CAVALIERS)
   ================================================================ */
.toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 24px;
    animation: slideUp 0.6s ease-out both;
}

/* CHAMP DE RECHERCHE */
.search-box { flex: 1; position: relative; }

.search-box input {
    width: 100%;
    padding: 16px 20px 16px 52px;
    background: var(--glass-strong);
    backdrop-filter: blur(20px);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    font-family: 'Outfit', sans-serif;
    font-size: 15px; color: var(--text-dark);
    outline: none; transition: all 0.3s ease;
    box-shadow: var(--shadow-sm);
}
.search-box input::placeholder { color: var(--text-muted); }
.search-box input:focus {
    border-color: var(--primary-light);
    box-shadow: 0 0 0 4px var(--primary-ultra-light), var(--shadow-md);
}

.search-box .search-icon {
    position: absolute; left: 18px; top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    transition: color 0.3s;
    display: flex; align-items: center;
}
.search-box input:focus ~ .search-icon { color: var(--primary); }

/* BOUTONS DESKTOP */
.desktop-btn {
    display: flex; align-items: center; gap: 8px;
    padding: 14px 24px; border: none;
    border-radius: var(--radius-lg);
    font-family: 'Outfit', sans-serif;
    font-size: 15px; font-weight: 400;
    cursor: pointer; transition: all 0.3s ease;
    white-space: nowrap;
}
.desktop-btn.btn-filter {
    background: var(--glass-strong); backdrop-filter: blur(20px);
    color: var(--text-dark);
    border: 1px solid var(--glass-border);
    box-shadow: var(--shadow-sm);
}
.desktop-btn.btn-filter:hover {
    background: var(--primary-ultra-light);
    border-color: var(--primary-light);
    color: var(--primary-dark);
    transform: translateY(-2px);
}
.desktop-btn.btn-add {
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    color: white;
    box-shadow: 0 4px 16px var(--primary-glow);
}
.desktop-btn.btn-add:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px var(--primary-glow);
}

/* ================================================================
   GRILLE DES CAVALIERS - 3 COLONNES FIXES
   ================================================================ */

/* ================================================================
   EN-TETE DE PAGE CAVALIERS
   ================================================================ */
.page-header-clients {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
    padding-bottom: 16px;
    border-bottom: 2px solid rgba(var(--primary-rgb), 0.12);
    animation: slideUp 0.5s ease-out both;
}
.page-header-left {
    display: flex;
    align-items: baseline;
    gap: 14px;
}
.page-title-clients {
    font-family: 'Playfair Display', serif;
    font-size: 28px;
    font-weight: 500;
    color: var(--text-dark);
    letter-spacing: -0.5px;
}
.page-count-badge {
    font-size: 15px;
    font-weight: 500;
    color: var(--primary-dark);
    background: var(--primary-ultra-light);
    padding: 4px 14px;
    border-radius: 20px;
    border: 1px solid rgba(var(--primary-rgb), 0.15);
}
.page-header-right { display: flex; align-items: center; }
.page-subtitle {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-muted);
    letter-spacing: 0.5px;
    text-transform: uppercase;
}


/* ================================================================
   GRILLE DES CAVALIERS
   ================================================================ */
.riders-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    animation: slideUp 0.7s ease-out 0.15s both;
}


/* ================================================================
   CARTE CAVALIER
   ================================================================ */
a.rider-card {
    text-decoration: none;
    color: inherit;
    display: flex;
    align-items: stretch;
    background: white;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 16px;
    overflow: hidden;
    transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.03);
    position: relative;
    opacity: 0;
    transform: translateY(16px);
    animation: cardAppear 0.5s ease-out forwards;
}

a.rider-card:nth-child(3n+1) { animation-delay: 0.05s; }
a.rider-card:nth-child(3n+2) { animation-delay: 0.1s; }
a.rider-card:nth-child(3n+3) { animation-delay: 0.15s; }

a.rider-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08), 0 4px 10px rgba(var(--primary-rgb), 0.06);
    border-color: rgba(var(--primary-rgb), 0.2);
}

a.rider-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 3px;
    background: linear-gradient(90deg, var(--primary), var(--primary-light), var(--accent));
    opacity: 0;
    transition: opacity 0.35s ease;
}
a.rider-card:hover::before { opacity: 1; }

a.rider-card.hidden { display: none; }


/* ================================================================
   CARTE - PHOTO
   ================================================================ */
.rider-photo {
    position: relative;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 18px 16px;
    background: linear-gradient(175deg, var(--primary-50b) 0%, var(--primary-50) 50%, #f8fafc 100%);
}

.rider-avatar-wrap { position: relative; }

.rider-avatar {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    border: 3px solid white;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
    object-fit: cover;
    transition: all 0.35s ease;
    background: linear-gradient(135deg, var(--primary-100), var(--primary-200));
}

a.rider-card:hover .rider-avatar {
    transform: scale(1.05);
    box-shadow: 0 6px 20px rgba(var(--primary-rgb), 0.18);
}

.online-dot {
    position: absolute;
    bottom: 4px; right: 4px;
    width: 14px; height: 14px;
    background: var(--primary);
    border: 2.5px solid white;
    border-radius: 50%;
}
.online-dot.on {
    animation: pulseOnline 2s ease-in-out infinite;
}
@keyframes pulseOnline {
    0%, 100% { box-shadow: 0 0 0 0 rgba(var(--primary-rgb), 0.4); }
    50% { box-shadow: 0 0 0 5px rgba(var(--primary-rgb), 0); }
}
.online-dot.off { background: #d1d5db; }


/* ================================================================
   CARTE - INFORMATIONS
   ================================================================ */
.rider-info {
    flex: 1;
    padding: 16px 18px 16px 12px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
}

.rider-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
    gap: 10px;
}

.rider-name {
    font-family: 'Playfair Display', serif;
    font-size: 15px;
    font-weight: 500;
    color: #1e293b;
    flex: 1;
    min-width: 0;
    line-height: 1.3;
}

.level-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 500;
    color: white;
    white-space: nowrap;
    flex-shrink: 0;
    letter-spacing: 0.3px;
    text-transform: uppercase;
}
.level-badge.g7 { background: linear-gradient(135deg, #f59e0b, #d97706); }
.level-badge.g6 { background: linear-gradient(135deg, #8b5cf6, #7c3aed); }
.level-badge.g5 { background: linear-gradient(135deg, #3b82f6, #2563eb); }
.level-badge.g4 { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); }
.level-badge.g3 { background: linear-gradient(135deg, #14b8a6, #0d9488); }
.level-badge.g2 { background: linear-gradient(135deg, #f97316, #ea580c); }
.level-badge.g1 { background: linear-gradient(135deg, #ec4899, #db2777); }

.rider-reprise {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 15px;
    color: var(--primary-dark);
    font-weight: 400;
    margin-bottom: 10px;
    padding: 3px 10px;
    background: rgba(var(--primary-rgb), 0.06);
    border-radius: 6px;
    width: fit-content;
}

.rider-metrics {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.metric-pill {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 8px;
    flex: 1;
    min-width: 0;
}
.metric-pill.hours {
    background: #eff6ff;
    border: 1px solid rgba(59, 130, 246, 0.1);
}
.metric-pill.bal-ok {
    background: var(--primary-50b);
    border: 1px solid rgba(22, 163, 74, 0.1);
}
.metric-pill.bal-due {
    background: #fef2f2;
    border: 1px solid rgba(220, 38, 38, 0.1);
}

.mp-icon { font-size: 16px; flex-shrink: 0; }
.mp-val  { font-size: 15px; font-weight: 500; line-height: 1.2; }
.mp-val.blue  { color: #2563eb; }
.mp-val.green { color: var(--primary); }
.mp-val.red   { color: #dc2626; }


/* ================================================================
   INDEX ALPHABETIQUE
   ================================================================ */
.alpha-index {
    position: fixed;
    right: 6px; top: 50%;
    transform: translateY(-50%);
    z-index: 100;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    padding: 6px 3px;
    background: white;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.alpha-letter {
    width: 30px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 6px;
    transition: all 0.2s ease;
    user-select: none;
}
.alpha-letter:hover {
    background: var(--primary-ultra-light);
    color: var(--primary-dark);
}
.alpha-letter.active {
    background: var(--primary);
    color: white;
    box-shadow: 0 2px 6px rgba(var(--primary-rgb), 0.3);
}
.alpha-letter.disabled { color: #e5e7eb; cursor: default; }
.alpha-letter.disabled:hover { background: transparent; color: #e5e7eb; }


/* ================================================================
   MODAL FILTRE
   ================================================================ */
.filter-overlay {
    position: fixed;
    inset: 0;
    background: rgba(255, 255, 255, .35);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    z-index: 999;
    opacity: 0;
    visibility: hidden;
    cursor: pointer;
    transition: visibility 0s .4s;
}
.filter-overlay.active {
    opacity: 1;
    visibility: visible;
    transition: visibility 0s;
    animation: eqmFadeIn .4s cubic-bezier(.4, 0, .2, 1) forwards;
}

.filter-modal {
    position: fixed;
    z-index: 1001;
    background: white;
    border-radius: 20px;
    padding: 28px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
    top: 50%; left: 50%;
    transform: translate(-50%, -50%) scale(0.95);
    width: 440px;
    max-width: 92vw;
    max-height: 80vh;
    overflow-y: auto;
    opacity: 0;
    visibility: hidden;
    transition: visibility 0s .5s;
}
.filter-modal.active {
    opacity: 1;
    visibility: visible;
    transition: visibility 0s;
    animation: eqmWowInCenter .5s cubic-bezier(.175, .885, .32, 1.1) forwards;
}

.filter-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 24px;
}
.filter-title {
    font-family: 'Playfair Display', serif;
    font-size: 20px;
    font-weight: 500;
    color: var(--text-dark);
}
.filter-close {
    width: 36px; height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f3f4f6;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    font-size: 15px;
    color: var(--text-medium);
    transition: all 0.2s ease;
}
.filter-close:hover { background: #e5e7eb; }

.filter-label {
    font-size: 13px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-bottom: 8px;
}
.filter-options {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 20px;
}
.filter-opt {
    padding: 8px 16px;
    background: #f9fafb;
    border: 1.5px solid #e5e7eb;
    border-radius: 8px;
    font-family: 'Outfit', sans-serif;
    font-size: 15px;
    font-weight: 500;
    color: var(--text-medium);
    cursor: pointer;
    transition: all 0.2s ease;
}
.filter-opt:hover {
    background: var(--primary-ultra-light);
    border-color: rgba(var(--primary-rgb), 0.3);
}
.filter-opt.active {
    background: var(--primary-ultra-light);
    border-color: var(--primary);
    color: var(--primary-dark);
}

.filter-apply {
    width: 100%;
    padding: 14px;
    background: var(--primary);
    color: white;
    border: none;
    border-radius: 12px;
    font-family: 'Outfit', sans-serif;
    font-size: 15px;
    font-weight: 400;
    cursor: pointer;
    transition: all 0.2s ease;
    margin-top: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    line-height: 1;
}
.filter-apply:hover {
    background: var(--primary-dark);
}


/* ================================================================
   BARRE DU BAS MOBILE
   ================================================================ */
.bottom-bar {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    z-index: 1000;
    padding: 0 16px env(safe-area-inset-bottom, 0px);
    pointer-events: none;
    display: none;
}
.bottom-bar-inner {
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: white;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.06);
    pointer-events: all;
}
.bottom-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px;
    border: none;
    border-radius: 12px;
    font-family: 'Outfit', sans-serif;
    font-size: 15px;
    font-weight: 400;
    cursor: pointer;
    transition: all 0.2s ease;
}
.bottom-btn.btn-filter-mobile {
    background: #f3f4f6;
    color: var(--text-dark);
}
.bottom-btn.btn-add-mobile {
    background: var(--primary);
    color: white;
}


/* ================================================================
   MESSAGE VIDE + TOAST
   ================================================================ */
.empty-state { text-align: center; padding: 60px 24px; display: none; }
.empty-state.visible { display: block; }
.empty-state-icon { font-size: 48px; margin-bottom: 16px; }
.empty-state-text { font-size: 15px; color: var(--text-light); font-weight: 500; }

/* Toast legacy #toast (modclielist1 afficherToast) - aligné en haut à droite */
#toast.toast {
    position: fixed;
    top: 1rem; right: 1rem;
    transform: translateX(120%);
    padding: 12px 24px;
    background: #1e293b;
    color: white;
    border-radius: 10px;
    font-family: 'Outfit', sans-serif;
    font-size: 15px;
    font-weight: 500;
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s ease;
    z-index: 99999;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
#toast.toast.visible {
    transform: translateX(0);
    opacity: 1;
    visibility: visible;
}


/* ================================================================
   SCROLLBAR (voir aussi section SCROLLBAR PERSONNALISEE en haut)
   ================================================================ */


/* ================================================================
   RESPONSIVE - TABLETTE (1024px)
   ================================================================ */
@media (max-width: 1024px) {
    .riders-grid { grid-template-columns: repeat(2, 1fr); }
}


/* ================================================================
   RESPONSIVE - TABLETTE (768px)
   ================================================================ */
@media (max-width: 768px) {
    .app-container { padding: 16px 16px 110px; padding-right: 46px; }
    .page-header-clients { margin-bottom: 16px; padding-bottom: 12px; }
    .page-title-clients { font-size: 22px; }
    .page-subtitle { display: none; }
    .desktop-btn { display: none !important; }
    .bottom-bar { display: block; }
    .riders-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .rider-photo { padding: 14px 12px; }
    .rider-avatar { width: 76px; height: 76px; }
    .rider-info { padding: 14px 14px 14px 8px; }
    .rider-name { font-size: 16px; }
    .alpha-index { padding: 4px 2px; }
    .alpha-letter { width: 26px; height: 20px; font-size: 10px; }
    .filter-modal {
        top: auto; left: 0; right: 0; bottom: 0;
        transform: translateY(100%);
        width: 100%; max-width: 100%;
        border-radius: 20px 20px 0 0;
        max-height: 70vh;
        animation: none;
    }
    .filter-modal.active {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        animation: eqmSlideUp .5s cubic-bezier(.175, .885, .32, 1.1) forwards;
    }
}


/* ================================================================
   RESPONSIVE - SMARTPHONE (480px)
   ================================================================ */
@media (max-width: 480px) {
    .app-container { padding: 12px 10px 120px; padding-right: 40px; }
    .page-header-clients { flex-direction: column; align-items: flex-start; gap: 4px; }
    .page-title-clients { font-size: 20px; }
    .riders-grid { grid-template-columns: 1fr; gap: 10px; }

    a.rider-card {
        flex-direction: row;
        align-items: stretch;
    }

    .rider-photo {
        padding: 14px 10px;
        min-width: 100px;
        max-width: 100px;
    }
    .rider-avatar { width: 76px; height: 76px; border-width: 2.5px; }

    .rider-info { padding: 12px 12px 12px 6px; }

    .rider-header { margin-bottom: 3px; gap: 8px; }
    .rider-name { font-size: 15px; }
    .level-badge { font-size: 10px; padding: 2px 8px; }

    .rider-reprise { font-size: 12px; padding: 2px 8px; margin-bottom: 8px; }

    .rider-metrics { flex-direction: column; gap: 4px; }
    .metric-pill { padding: 5px 8px; }
    .mp-val { font-size: 12px; }
    .mp-icon { font-size: 13px; }

    .alpha-index { padding: 3px 2px; right: 3px; }
    .alpha-letter { width: 24px; height: 18px; font-size: 9px; border-radius: 5px; }
}

/* ================= TOAST NOTIFICATIONS ================= */
/* Conteneur : en haut droite, style notification moderne */
#toast-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    pointer-events: none;
}
#toast-container .toast {
    pointer-events: auto;
}
.toast {
    pointer-events: auto;
    min-width: 280px;
    max-width: 420px;
    padding: 14px 16px;
    border-radius: 10px;
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.2);
    display: flex;
    align-items: center;
    gap: 12px;
    transform: translateX(120%);
    opacity: 0;
    transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
    font-family: system-ui, -apple-system, sans-serif;
}

.toast.show {
    transform: translateX(0);
    opacity: 1;
    visibility: visible;
}

.toast.success {
    background: var(--primary-50);
    color: var(--primary);
}

.toast.error {
    background: #fef2f2;
    color: #dc2626;
}

.toast.warning {
    background: #fffbeb;
    color: #d97706;
}

.toast.info {
    background: #eff6ff;
    color: #2563eb;
}

.toast-icon {
    font-size: 1.4rem;
    flex-shrink: 0;
}

.toast-message {
    flex: 1;
    font-size: 0.875rem;
    line-height: 1.4;
}

.toast-close {
    background: none;
    border: none;
    font-size: 1.1rem;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s;
}

.toast-close:hover {
    opacity: 1;
}

/* Mobile : tableaux - supprimer scroll horizontal, afficher 2 colonnes uniquement */
@media (max-width: 768px) {
    .table-scroll {
        overflow-x: hidden !important;
    }
    .table-scroll .data-table,
    .table-scroll .breakdown-table {
        min-width: 0;
    }
    /* Masquer colonnes 3 à avant-dernière, garder 2 premières + colonne actions */
    .table-scroll .data-table thead th:nth-child(n+3):not(:last-child),
    .table-scroll .data-table tbody td:nth-child(n+3):not(:last-child),
    .table-scroll .data-table tfoot td:nth-child(n+3):not(:last-child),
    .table-scroll .breakdown-table thead th:nth-child(n+3):not(:last-child),
    .table-scroll .breakdown-table tbody td:nth-child(n+3):not(:last-child) {
        display: none;
    }
}

/* ================================================================
   ZONE TACTILE MINIMALE 44px (Apple/Google - accessibilite)
   Toute interaction : boutons, champs, liens cliquables, modales
   ================================================================ */
@media (max-width: 1024px) {
    button,
    input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]),
    select,
    [role="button"],
    .cfg-btn,
    .cfg-btn-sm,
    .cfg-btn-outline,
    .cfg-btn-amber,
    .cfg-pill,
    .cfg-ibtn,
    .cfg-modal-close,
    .eqm-modal button,
    .eqm-modal input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]),
    .eqm-modal select,
    .eqm-confirm-cancel,
    .eqm-confirm-ok,
    .eqm-modal-content button,
    .eqm-modal-content input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]),
    .eqm-modal-content select,
    .eqm-modal-content [role="button"],
    .filter-modal button,
    .filter-modal input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]),
    .filter-modal select,
    .alpha-letter,
    .se-stat-page .se-tab-btn,
    .sr-stat-page .sr-period-btn,
    .st-stat-page .st-tab-btn {
        min-height: 44px !important;
    }
    /* Croix de fermeture d'un modal : 32 px A L'OEIL, 44 px AU DOIGT.
       ------------------------------------------------------------------
       Le verrou bilateral (min ET max, en !important) figeait la cible
       tactile a 32 px : en dessous du minimum de 44 px que le §17 pose
       comme non negociable, et aucune page ne pouvait le relever. Sur la
       croix, c'est-a-dire le bouton qu'on vise en dernier, souvent d'une
       main, parfois au bord d'un manege.
       Agrandir le dessin a 44 px etait la mauvaise reponse : une croix de
       44 px ecrase l'en-tete du modal et devient l'element le plus lourd
       d'une fenetre qui doit rester legere. On garde donc le carre visible
       a 32 px et on etend la ZONE CLIQUABLE par un ::after transparent --
       le patron deja employe par eqm-select.css pour ses puces de retrait,
       et celui que le §17 attend : la cible se mesure au doigt, pas au
       pixel colore. */
    button.eqm-modal-close,
    .eqm-modal button.eqm-modal-close,
    .eqm-modal-content button.eqm-modal-close,
    .eqm-modal-header button.eqm-modal-close {
        position: relative;
        min-height: 32px !important;
        max-height: 32px !important;
        min-width: 32px !important;
        max-width: 32px !important;
        width: 32px !important;
        height: 32px !important;
    }
    /* La zone tactile. `content` vide + position absolue centree : elle
       deborde du bouton sans deplacer quoi que ce soit dans l'en-tete.
       Elle est SOUS le contenu (z-index 0) pour ne pas passer par-dessus
       l'icone, et ne capte rien d'autre : le bouton reste le seul element
       cliquable de la zone. */
    button.eqm-modal-close::after,
    .eqm-modal button.eqm-modal-close::after,
    .eqm-modal-content button.eqm-modal-close::after,
    .eqm-modal-header button.eqm-modal-close::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
        border-radius: inherit;
        z-index: 0;
    }
    /* PETITS CONTROLES RONDS : 44 px AU DOIGT, PAS A L'OEIL (06/09/2026)
       ------------------------------------------------------------------
       Ces deux-la sont des pastilles de 20 px posees DANS un champ. Les
       gonfler a 44 px de dessin les rendait plus grosses que le texte
       qu'elles accompagnent -- et prises par `.eqm-modal button` plus haut,
       qui ne pose QUE min-height, elles devenaient des ellipses de 20x44
       (border-radius: 50% sur un rectangle). Sur le composant le plus
       reutilise du depot.
       On rend donc la taille visible au CSS du composant et on etend la
       seule zone cliquable, patron deja employe par la croix des modals.
       Le `!important` est necessaire : il faut battre le filet generique
       ci-dessus, lui-meme en !important. */
    .eqm-chip-remove,
    .eqm-result-add {
        position: relative;
        min-height: 0 !important;
        min-width: 0 !important;
    }
    .eqm-chip-remove::after,
    .eqm-result-add::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
        border-radius: 50%;
        z-index: 0;
    }
    .cfg-fg input,
    .cfg-fg select {
        min-height: 44px !important;
    }
    /* Toggle : zone tactile elargie (hauteur min) */
    .cfg-toggle {
        min-height: 44px;
    }
}

/* --- Taille uniforme icones suppression (.72rem) --- */
.eqm-supprimer-groupe i,
.eqm-retirer-membre i {
    font-size: .72rem;
}


/* ============================================================================
   PLEINE LARGEUR SUR SMARTPHONE  --  .eqm-page-large
   ============================================================================
   Sur smartphone, l'espace horizontal est la ressource la plus rare. Le
   .main-wrapper applique par defaut un padding Tailwind (p-4 = 16px de chaque
   cote) : sur un ecran de 360px, c'est 9 % de la largeur perdue en marge, ce
   qui ecrase les cartes et tronque les libelles.

   Une page qui porte la classe `eqm-page-large` reduit ce padding a 1px a
   gauche et 1px a droite en dessous de 768px : les rubriques, cartes et listes
   occupent alors toute la largeur de l'ecran. Le confort de lecture reste
   assure par le padding INTERNE des cartes -- qu'il ne faut donc pas retirer.

   Tablette et PC ne sont pas concernes : au-dela de 768px, la marge aere la
   mise en page sans couter de place utile.

   Usage : <div id="page-xxx" class="eqm-page-large"> ... </div>
   Reference : CLAUDE.md section 10d.
   ============================================================================ */
@media (max-width: 768px) {
    body:has(.eqm-page-large) .main-wrapper {
        padding-left: 1px !important;
        padding-right: 1px !important;
        max-width: 100% !important;
    }
    .eqm-page-large { max-width: 100% !important; width: 100%; }
}

/* =============================================================================
   ANNIVERSAIRES DU TABLEAU DE BORD -- carte cliquable et modal.

   Un anniversaire appelle un geste (souhaiter, ouvrir la fiche). La carte est
   donc un <button> : le curseur, le clavier et les lecteurs d'ecran la
   reconnaissent comme une action, pas comme du texte.
   ========================================================================== */

.anni-card {
    cursor: pointer;
    border-width: 1px;
    font: inherit;
}
.anni-card:hover  { transform: translateY(-1px); }
.anni-card:active { transform: translateY(0); }
.anni-card:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .3);
}

.anni-mod-head {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}
.anni-mod-date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    flex-shrink: 0;
    border-radius: 20px;
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    color: #fff;
    box-shadow: 0 8px 20px -8px rgba(var(--primary-rgb), .6);
}
.anni-mod-j { font-size: 1.4rem; font-weight: 700; line-height: 1; }
.anni-mod-m { font-size: .65rem; text-transform: uppercase; opacity: .85; letter-spacing: .04em; }

.anni-mod-who  { min-width: 0; }
.anni-mod-type { margin: 0; font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: #64748b; font-weight: 600; }
.anni-mod-nom  { margin: .15rem 0 0; font-family: 'Fraunces', Georgia, serif; font-size: 1.25rem; font-weight: 600; color: #0f172a; }
.anni-mod-age  { margin: .1rem 0 0; font-size: .85rem; color: #64748b; }

.anni-mod-quand {
    margin: 0;
    padding: .7rem .9rem;
    border-radius: 12px;
    background: rgba(var(--primary-rgb), .06);
    border: 1px solid rgba(var(--primary-rgb), .14);
    font-size: .85rem;
    font-weight: 600;
    color: var(--primary-dark);
    text-align: center;
}

.anni-mod-footer > a { text-decoration: none; }
/* Pas d'adresse : le bouton reste visible mais inerte, et dit pourquoi au survol.
   Le masquer laisserait croire que souhaiter n'est pas possible. */
.anni-mod-footer .is-off { opacity: .45; cursor: not-allowed; }

@media (max-width: 480px) {
    .anni-mod-footer { flex-direction: column-reverse; align-items: stretch; }
    .anni-mod-footer > a { justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { .anni-card { transition: none; } }

/* =============================================================================
   DATE EN TROIS SELECTEURS -- liste manquante mise en evidence
   Posee par eqm-date-parts.js quand l'utilisateur valide un formulaire avec une
   date a moitie choisie (« janvier 1984 », sans le jour) ou impossible
   (31 fevrier). Le toast dit QUOI faire, cette bordure dit OU.
   Rouge volontairement hors theme : c'est une alerte, pas une couleur de marque
   -- meme registre que les autres etats d'erreur de l'application.
   ============================================================================= */
.eqm-date-part-erreur {
    border-color: #dc2626 !important;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .12) !important;
}
.eqm-date-part-erreur:focus {
    outline: none;
    border-color: #dc2626 !important;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .22) !important;
}

/* ===========================================================================
   .eqm-attente — bloc d'attente longue (cf. eqmAttente, javascript_divers.js).
   Utilise partout ou une generation IA fait patienter : affiche IA d'une seance
   ou d'un modele recurrent. Design system (§17) : coins arrondis, air, teintes
   du theme -- aucune couleur en dur (§1).
   =========================================================================== */
.eqm-attente {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 22px 20px; border-radius: 18px;
    background: linear-gradient(180deg, rgba(var(--primary-rgb), .08), transparent);
    border: 1px solid rgba(var(--primary-rgb), .18);
    text-align: left;
}
.eqm-attente-ic { font-size: 1.5rem; color: var(--primary); margin-top: 2px; flex: 0 0 auto; }
.eqm-attente-txt { flex: 1; min-width: 0; }
.eqm-attente-titre { display: block; font-size: .98rem; color: var(--primary-darker); }
.eqm-attente-sub { margin: 5px 0 0; font-size: .86rem; line-height: 1.5; opacity: .85; }
/* Le chrono : discret, tabulaire pour que les chiffres ne dansent pas. */
.eqm-attente-chrono {
    display: inline-block; margin-top: 10px; padding: 2px 10px;
    border-radius: 999px; font-size: .78rem; font-variant-numeric: tabular-nums;
    background: rgba(var(--primary-rgb), .12); color: var(--primary-darker);
}
/* ----------------------------------------------------------------------------
   L'ANNEAU DE PROGRESSION (28/09/2026)
   ----------------------------------------------------------------------------
   Il remplace le spinner et tient dans la meme place. Le chiffre se lit au
   centre -- pas de ligne supplementaire.

   ⚠️ LE POURCENTAGE EST UNE ESTIMATION (cf. l'en-tete de `eqmAttente` dans
   javascript_divers.js) : l'API ne renvoie aucune progression. La courbe ne
   redescend jamais et n'atteint 100 % qu'au resultat.
   -------------------------------------------------------------------------- */
.eqm-attente-ring {
    position: relative;
    flex: 0 0 auto;
    width: 60px;
    height: 60px;
}
.eqm-attente-ring svg {
    width: 60px;
    height: 60px;
    /* L'arc part du HAUT et tourne dans le sens des aiguilles : c'est le seul
       sens qu'on lit comme « ca avance ». Un SVG commence a 3 h. */
    transform: rotate(-90deg);
}
.eqm-attente-ring-bg,
.eqm-attente-ring-fg {
    fill: none;
    stroke-width: 5;
    stroke-linecap: round;
}
.eqm-attente-ring-bg { stroke: rgba(var(--primary-rgb), .16); }
.eqm-attente-ring-fg {
    stroke: var(--primary);
    /* 260ms : l'anneau GLISSE entre deux mesures (prises 10 fois par seconde)
       au lieu de sauter. `stroke-dashoffset` n'entraine aucun recalcul de mise
       en page -- c'est ce qui permet de l'animer en continu sans cout. */
    transition: stroke-dashoffset .26s cubic-bezier(.22, 1, .36, 1);
}

/* LE CHIFFRE. Tabulaire : sans lui, la largeur des chiffres change et le
   pourcentage tremble a chaque mise a jour -- dix fois par seconde. */
.eqm-attente-pct {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .82rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--primary-darker);
    letter-spacing: -.02em;
}

/* UN SOUFFLE, pour que l'anneau ne paraisse pas fige entre deux paliers.
   C'est une lueur, pas un mouvement : rien ne se deplace. */
.eqm-attente-ring::after {
    content: '';
    position: absolute;
    inset: 6px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(var(--primary-rgb), .16), transparent 70%);
    animation: eqmAttenteSouffle 2.4s ease-in-out infinite;
}
@keyframes eqmAttenteSouffle {
    0%, 100% { opacity: .35; transform: scale(.92); }
    50%      { opacity: .9;  transform: scale(1);   }
}

/* AU RESULTAT : l'anneau se referme en vert plein, une fois. */
.eqm-attente.est-termine .eqm-attente-ring-fg { stroke: var(--primary-dark); }
.eqm-attente.est-termine .eqm-attente-ring::after { animation: none; opacity: .5; }

@media (prefers-reduced-motion: reduce) {
    .eqm-attente-ic { animation: none; }
    /* Le mouvement s'arrete, PAS l'information : l'anneau et le pourcentage
       continuent de se mettre a jour, ils sautent simplement d'un palier a
       l'autre au lieu de glisser. */
    .eqm-attente-ring::after { animation: none; opacity: .5; }
    .eqm-attente-ring-fg     { transition: none; }
}

/* Heure civile du centre lue depuis un autre fuseau (eqm-temps.js, CLAUDE.md §33quater).
   Discrète : elle n'apparaît que pour un appareil hors du fuseau du centre. */
.eqm-civil-mention { font-size: .85em; font-weight: 500; color: var(--text-light, #64748b); white-space: nowrap; }
.eqm-civil-ic { font-size: .8em; margin-left: .25em; opacity: .75; cursor: help; }

/* IMPRESSION -- l'habillage de l'application ne sort pas sur le papier (30/09/2026).
   Aucune règle ne masquait le menu latéral ni l'en-tête : toute page imprimée par
   `window.print()` (la fiche d'un événement ouverte en pleine page, par exemple)
   sortait avec le menu à gauche et le contenu décalé de 300 px. Les pages qui ont
   leur propre mise en page d'impression gardent la leur : on ne retire ici que ce
   qui n'appartient à AUCUN document. */
@media print {
    #sidebar, #sidebarOverlay, main > header,
    .ast-launcher, .fab-wrap, .fab-backdrop { display: none !important; }
    main { margin-left: 0 !important; }
}
