﻿/* ===================================================================================================
   assets/css/assistant-bulle.css — LA BULLE de l'assistant IA, et rien d'autre

   Ancien `assistantia.css`, réduit à son seul sujet. Tout l'habillage du chat est parti dans
   `assets/css/assistant-ia.css` : dock, fil, états, fenêtre agrandie, badge.

   Ce qui a été SUPPRIMÉ au passage, et pourquoi il fallait le supprimer et non le laisser dormir :

     - `.bubble`, `.bubble-content`, `.bubble-time`, `.bubble-avatar` étaient déclarées SANS AUCUN
       SCOPE dans une feuille chargée sur toutes les pages du produit. Des noms aussi génériques posés
       globalement sont une bombe à retardement : le jour où un autre écran nomme un élément
       « bubble », il hérite du chat. Le nouveau composant est entièrement préfixé.

     - `#assistantPromptForm` était déclaré DEUX FOIS, avec des valeurs différentes (espacement,
       retrait, et une bordure en dur d'un côté, un jeton de l'autre). C'est la seconde qui gagnait,
       donc toute retouche de la première était invisible.

     - `.assistant-header` était déclarée deux fois elle aussi, et le bloc « mobile » portait DOUZE
       déclarations forcées, qu'aucune règle du nouveau composant n'aurait pu battre.

     - `.tg-ia-forme`, `.tg-ia-bulle` et `.assistant-header .assistant-actions button` ne
       correspondaient à AUCUN élément du markup : du style mort, qui laisse croire qu'il tient
       quelque chose.

     - Le mode plein écran (`.fullscreen`) et sa couche : la fenêtre agrandie est désormais une vraie
       modale, dont la couche appartient au socle.
   =================================================================================================== */


/* ---------------------------------------------------------------------------------------------------
   La pastille ronde

   🛑 L'habillage est porté par la CLASSE, jamais par l'identifiant : la pastille a deux porteurs
   possibles selon la surface, et ils n'ont pas le même identifiant. Écrire ces règles sur
   l'identifiant a déjà laissé une fois un porteur ENTIÈREMENT nu — bouton gris du navigateur, coins
   carrés — sans que rien ne le signale.

   Le fond est porté ici parce que l'icône est un TRAIT : sans lui, le picto se perdrait sur ce qu'il
   recouvre.
   --------------------------------------------------------------------------------------------------- */
.assistant-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 35px;
    height: 35px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--bs-info);
    color: #fff;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .2);
    user-select: none;
}

    .assistant-button:hover {
        opacity: .6;
    }

    /* 🛑 `> i` ET `> svg` : le rendu des icônes remplace le `<i>` par un `<svg>` et lui RETIRE son
       attribut d'origine (parade anti-boucle). Une règle accrochée à cet attribut serait donc morte
       dès que l'icône existe vraiment — le `> i` couvre le battement avant rendu, le `> svg` la suite. */
    .assistant-button > i,
    .assistant-button > svg,
    .assistant-button > img {
        display: block;
        width: 22px;
        height: 22px;
        margin-bottom: 2px;
    }


/* ---------------------------------------------------------------------------------------------------
   La bulle FLOTTANTE, et elle seule : position, couche, déplacement.

   ⚠️ Elle n'existe PAS sur le dashboard : le panneau y est déjà dans le flux, il n'y a rien à ouvrir.
   C'est pourquoi le badge de réponse non lue a un second porteur dans l'entête du panneau — sans quoi
   il serait structurellement invisible sur cette surface.
   --------------------------------------------------------------------------------------------------- */
#assistantToggleBtn {
    position: fixed;
    /* Position par défaut : en haut à droite, sous la sélection du dossier annuel, donc calée sur la
       barre du fil d'Ariane.
       ⚠️ Une position MÉMORISÉE par l'utilisateur prime : le script pose alors les coordonnées en
       ligne. Ceci n'est que le point de départ. */
    top: var(--tg-assistant-top, 54px);
    right: 20px;
    /* 🛑 Couche « flottante » du socle, et surtout pas une valeur arbitrairement haute : la bulle
       flotte au-dessus du CONTENU, mais doit passer DERRIÈRE tout panneau ouvert — le panneau
       lui-même, les tiroirs, le voile d'une modale et la modale. Placée au-dessus, elle restait au
       premier plan par-dessus le panneau affiché, et cliquable au travers de son voile. */
    z-index: 1040;
    cursor: grab;
    touch-action: none;
}

    #assistantToggleBtn.assistant-button-dragging {
        cursor: grabbing;
        opacity: 1;
        filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .35));
    }


/* ---------------------------------------------------------------------------------------------------
   La bulle passe AU-DESSUS d'un menu de chrome déplié

   🛑 Un menu déplié ne sort pas du contexte d'empilement de son conteneur : le socle relève donc
   l'entête tant qu'un de ses menus est ouvert. La bulle, calée plus bas, se retrouvait DERRIÈRE le
   sous-menu dès qu'il tombait à sa hauteur — elle disparaissait au simple survol du menu du haut.

   Le relèvement est donc CONDITIONNÉ au même état, et non permanent : hors de ce cas, la bulle doit
   rester sous le panneau, les tiroirs et les modales. La garde sur l'état « modale ouverte » reprend
   celle du socle — modale ouverte, tout l'arrière-plan reste sous le voile.

   ⚠️ L'entête est ciblé par son ATTRIBUT et non par son identifiant : le minifieur bute sur un
   identifiant écrit à l'intérieur de cette forme de sélecteur. La spécificité reste très au-dessus de
   la règle de base, celui de la bulle étant, lui, hors de la parenthèse.
   --------------------------------------------------------------------------------------------------- */
body:not(.modal-open):has([id="header"] .dropdown-menu.show) #assistantToggleBtn,
body:not(.modal-open):has([id="header"] .navbar-collapse.show) #assistantToggleBtn,
body:not(.modal-open):has(.rail-modules .dropdown-menu.show) #assistantToggleBtn,
body:not(.modal-open):has(.rail-flyout.est-ouvert) #assistantToggleBtn {
    z-index: calc(var(--tg-couche-menu-ouvert, 1095) + 1);
}


/* ---------------------------------------------------------------------------------------------------
   Pastille de COMPTAGE DES WIDGETS (à ne pas confondre avec le badge de l'assistant)

   Elle annonce ce que le panneau a à montrer, et elle a déjà DEUX écrivains : le chargement paresseux
   du panneau et le script des bulles d'onglets. Le badge de réponse non lue de l'assistant est un
   composant distinct, orange, en bas à droite — cf. `assets/css/assistant-ia.css`.

   🛑 La règle sur l'attribut de masquage est écrite EXPLICITEMENT : le `display` posé ci-dessous
   écraserait sinon celui que l'agent utilisateur applique à cet attribut, et une pastille sans compte
   resterait affichée à vide.
   --------------------------------------------------------------------------------------------------- */
.assistant-button-bulle {
    position: absolute;
    top: -2px;
    right: -2px;
    display: inline-block;
    min-width: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background-color: var(--bs-danger, #dc3545);
    color: #fff;
    font-size: 10px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 16px;
    text-align: center;
    pointer-events: none;
}

.assistant-button-bulle[hidden] {
    display: none;
}


/* --- Apparition de la pastille ---------------------------------------------------------------------

   Le compte arrive APRÈS le chargement de la page — la requête qui le calcule est volontairement
   passée en arrière-plan pour ne pas concurrencer le rendu de l'écran — donc la pastille surgit un
   instant plus tard. Cette petite animation fait lire ce surgissement comme voulu.

   🛑 Une animation et non une transition : la pastille passe de « non rendue » à visible, et une
   transition n'aurait alors aucun état de départ à animer. Une animation, elle, se joue d'elle-même
   dès que l'élément devient rendu, et se rejoue à chaque réapparition.
   --------------------------------------------------------------------------------------------------- */
@keyframes tg-pastille-apparait {
    from {
        opacity: 0;
        transform: scale(.5);
    }

    to {
        opacity: 1;
        transform: scale(1);
    }
}

.assistant-button-bulle,
.dashboard-assistant-toggle-bulle {
    animation: tg-pastille-apparait .2s ease-out;
}

@media (prefers-reduced-motion: reduce) {

    .assistant-button-bulle,
    .dashboard-assistant-toggle-bulle {
        animation: none;
    }
}
