/**
 * ULTIME - habillage du bouton charge, de la jauge et de la mise en scene.
 * File: modules/combat/ulti_charge.css
 * Documentation: Documentations/Combat/barre_ulti_globale.md
 *
 * Une classe CSS nommee, et pas des utilitaires Tailwind : Tailwind est purge
 * STATIQUEMENT dans ce projet, donc une classe fabriquee dans un module JS
 * n'existerait pas dans la feuille finale. Les boutons de competence sont d'ailleurs
 * deja habilles en styles inline pour la meme raison.
 *
 * Le degrade est double : la couche de fond defile en continu, et la couche de
 * lueur respire. Un bouton qui vient de se charger doit se remarquer sans lire
 * le texte.
 */

.combat-skill-ulti-pret {
    /* « background-image » et SURTOUT PAS le raccourci « background ». Le raccourci
       remet toutes les sous-proprietes a leur valeur initiale, dont
       « background-position: 0% 0% », et le !important part avec elles. Or dans la
       cascade CSS une declaration author !important passe DEVANT les animations : le
       keyframe ci-dessous tournait bien (animation-play-state valait « running ») mais
       ne pouvait plus deplacer quoi que ce soit. Le bouton restait fige sur un degrade
       immobile. Mesure a l'appui : background-position valait « 0% 0% » a t=0 comme a
       t=600 ms. */
    background-image: linear-gradient(
        100deg,
        #7e22ce 0%,
        #22c55e 25%,
        #a855f7 50%,
        #16a34a 75%,
        #7e22ce 100%
    ) !important;
    /* 300 % de largeur : c'est ce qui laisse la place au degrade pour defiler. */
    background-size: 300% 100% !important;
    background-repeat: repeat !important;
    animation: combat-ulti-defile 2.4s linear infinite,
               combat-ulti-pulse 1.2s ease-in-out infinite alternate !important;
    color: #ffffff !important;
    border: 2px solid #d8b4fe !important;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    font-weight: 800;
}

/* L'icone GameIcons est un SVG : sans ca elle garde sa couleur d'origine sur un
   fond devenu sombre. */
.combat-skill-ulti-pret svg {
    fill: currentColor;
    stroke: currentColor;
}

/* 0 -> 150 % fait avancer le fond de EXACTEMENT une periode du degrade : le motif
   retombe sur lui-meme, la boucle n'a pas de raccord visible. (Le calcul : un fond de
   300 % de large se decale de 2 largeurs de bouton entre 0 % et 100 %, donc de 3 entre
   0 % et 150 %, soit la largeur du degrade.) La valeur precedente, 300 %, parcourait
   deux periodes dans le meme temps : correct aussi, mais deux fois trop rapide, le
   bouton papillotait. */
@keyframes combat-ulti-defile {
    from { background-position: 0% 50%; }
    to   { background-position: 150% 50%; }
}

@keyframes combat-ulti-pulse {
    from { box-shadow: 0 0 6px rgba(168, 85, 247, 0.55), 0 0 2px rgba(34, 197, 94, 0.4); }
    to   { box-shadow: 0 0 18px rgba(34, 197, 94, 0.85), 0 0 8px rgba(168, 85, 247, 0.7); }
}

/* Respect du reglage systeme : une animation infinie sur un bouton est
   exactement le genre de mouvement que ce reglage vise. Le degrade reste,
   seul le mouvement s'arrete. */
@media (prefers-reduced-motion: reduce) {
    .combat-skill-ulti-pret {
        animation: none !important;
        background-position: 50% 50% !important;
        box-shadow: 0 0 12px rgba(168, 85, 247, 0.7) !important;
    }
}

/* == OVERLAY PLEIN ECRAN DE L'ULTIME ========================================
   Monte dans #turn-based-combat-container, qui est deja `fixed inset-0` :
   l'overlay couvre donc l'ecran entier et disparait avec le combat. */
.combat-ulti-overlay {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* `fill` et non `cover` : l'overlay doit faire EXACTEMENT les dimensions de
       l'ecran, quitte a deformer. `cover` remplit aussi, mais en rognant, donc une
       partie de l'animation sort du cadre sur un ecran plus etroit que le 16:9 du
       fichier. `fill` etire a la place : rien ne sort, rien n'est coupe. */
    object-fit: fill;
    /* Meme neutralisation du preflight Tailwind que sur .combat-ulti-launch. A 100 %
       le clamp ne mord pas, mais il mordrait au premier reglage au-dessus. */
    max-width: none;
    max-height: none;
    /* Purement decoratif : le tour continue dessous et les boutons restent
       cliquables meme pendant que l'overlay couvre l'ecran. */
    pointer-events: none;
    opacity: 0;
    transition: opacity 220ms ease-out;
    will-change: opacity;
}

/* == BARRE D'ULTIME ==========================================================
   La jauge commune du camp, posee SOUS la barre de points de combat
   (modules/combat/ulti_bar.js).

   Elle a remplace `.combat-cp-ulti-pret`, qui repeignait la BARRE DE POINTS DE COMBAT
   en vert et violet quand un ultime etait pret. Cette barre-la porte desormais une
   seule information, les points disponibles, et garde donc son orange en toutes
   circonstances. Le remplissage de l'ultime, lui, n'etait auparavant visible nulle
   part : le joueur ne voyait que l'arrivee, jamais le trajet.

   Le violet de la montee est celui de la barre d'Horizon (bg-purple-600, #9333ea) :
   les deux jauges fines du panneau se ressemblent, et l'ultime ne se confond pas avec
   l'orange des points de combat. */
.combat-ulti-bar-fill {
    background-image: linear-gradient(90deg, #6b21a8 0%, #9333ea 60%, #c084fc 100%);
}

/* JAUGE PLEINE : le meme degrade anime que les boutons de competence. Un ultime pret se
   signale partout de la meme facon, et il n'y a qu'une animation a regler.

   LE DEFILEMENT EST ICI, LA LUEUR EST SUR LE CADRE (voir plus bas) : le cadre porte
   `overflow: hidden` pour que le remplissage garde ses coins arrondis, et une ombre
   portee vers l'exterieur y serait rognee. Sur le bouton de competence, qui n'a pas de
   cadre, les deux animations tiennent sur le meme element.

   Meme piege de cascade que sur le bouton : `background-image` et SURTOUT PAS le
   raccourci `background`, qui reposerait `background-position` en !important et
   figerait le defilement. Le detail est explique en tete de ce fichier.

   Le !important passe devant le degrade de montee ci-dessus, declare avec la meme
   specificite : sans lui, l'ordre du fichier deciderait. */
.combat-ulti-bar-fill.combat-ulti-bar-pleine {
    background-image: linear-gradient(
        100deg,
        #7e22ce 0%,
        #22c55e 25%,
        #a855f7 50%,
        #16a34a 75%,
        #7e22ce 100%
    ) !important;
    background-size: 300% 100% !important;
    background-repeat: repeat !important;
    animation: combat-ulti-defile 2.4s linear infinite !important;
}

/* La lueur qui respire, sur le CADRE. Meme keyframe que le bouton : un ultime pret se
   signale partout de la meme facon. */
.combat-ulti-bar-cadre.combat-ulti-bar-pleine {
    animation: combat-ulti-pulse 1.2s ease-in-out infinite alternate;
    border-color: #d8b4fe !important;
}

/* LA BARRE NE PORTE AUCUN TEXTE (2026-09-15). La regle qui habillait son libelle est
   partie avec lui : sur 12 px de haut, sous une barre de points de combat qui affiche
   deja son propre compte, la largeur du remplissage dit la meme chose sans rien a lire. */

@media (prefers-reduced-motion: reduce) {
    .combat-ulti-bar-fill.combat-ulti-bar-pleine,
    .combat-ulti-bar-cadre.combat-ulti-bar-pleine {
        animation: none !important;
        background-position: 50% 50% !important;
    }
}

/* ulti_launch fait 150 % de l'ecran : il lui faut un CADRE qui rogne ce qui depasse.

   Le conteneur de combat, lui, n'a pas de « overflow: hidden » (sa classe est
   « fixed inset-0 flex flex-col pointer-events-none opacity-0 z-40 »), et lui en poser
   un toucherait a un element partage par tout le combat. Le cadre porte donc son propre
   rognage, et l'opacite du fondu avec lui.

   Il est visible d'emblee, la demande disant que le lancement « demarre tout de suite ».
   La transition d'opacite est bien presente : c'est elle qui porte le fondu de sortie de
   700 ms. Un « transition: none » ici l'aurait coupee, et poser transitionDuration en JS
   n'aurait rien rallume, « none » valant « transition-property: none ». Aucune transition
   ne se declenche pour autant a l'apparition : l'opacite vaut 1 des le depart, il n'y a
   pas de changement de valeur a animer. */
.combat-ulti-launch-cadre {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: 1;
    transition: opacity 220ms ease-out;
    will-change: opacity;
}

/* L'image, centree sur le SPRITE DU LANCEUR. « left » et « top » sont poses en JS depuis
   le rectangle du sprite ; la translation de -50 % les transforme en centrage. Les 50 %
   ecrits ici ne servent que de repli, quand le sprite est introuvable.

   Sa taille aussi vient du JS, depuis ECHELLE_LANCEMENT, pour que la valeur ne vive
   qu'a un seul endroit.

   « contain » : la boite est desormais posee AU RATIO NATUREL de l'image (le calcul est
   dans dimensionnerSelonRatio), les deux valeurs reviennent donc au meme. « contain » dit
   l'intention : ne jamais deformer. C'est le correctif du rendu etire a l'horizontale. */
.combat-ulti-launch {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    object-fit: contain;
    pointer-events: none;
    /* INDISPENSABLE. Le preflight de Tailwind pose « img,video{max-width:100%;
       height:auto} » sur TOUTES les images du document. Sans ces deux lignes, une
       largeur de 150 % est ramenee a 100 % pendant que la hauteur, elle, passe :
       l'animation sortait ecrasee a l'horizontale. Le module des cinematiques porte
       la meme neutralisation sur .cine-acteur et .cine-effet, pour la meme raison. */
    max-width: none;
    max-height: none;
}

/* Le contour violet, du meme type que ceux des statuts (brulure, poison...) :
   meme recette d'ombre interne que updateCombatVignette, meme respiration.

   Un element SEPARE de #combat-vignette-overlay, et c'est delibere : la vignette
   de statut est pilotee par une machine a etats a priorite unique
   (updateCombatVignette n'en affiche qu'une seule a la fois, et retient laquelle
   dans activeVignetteType). S'y inserer aurait demande de sauvegarder puis de
   restaurer cet etat, avec le risque de laisser le joueur sans son contour de
   poison apres un ultime. Deux elements ne se marchent pas dessus. */
.combat-ulti-vignette {
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: inherit;
    box-shadow: inset 0 0 80px 30px rgba(168, 85, 247, 0.65);
    opacity: 0;
    transition: opacity 220ms ease-out;
    animation: combat-ulti-vignette-pulse 1.1s ease-in-out infinite;
    will-change: opacity;
}

/* Meme respiration que combatVignettePulse (turn_based_combat.js), redeclaree ici
   plutot que reutilisee : ce keyframe-la n'est injecte dans le document que si une
   vignette de STATUT a deja ete affichee au moins une fois. Un ultime lance avant
   le premier poison se serait retrouve sans animation. */
@keyframes combat-ulti-vignette-pulse {
    0%, 100% { box-shadow: inset 0 0 70px 22px rgba(168, 85, 247, 0.45); }
    50%      { box-shadow: inset 0 0 110px 40px rgba(168, 85, 247, 0.85); }
}

@media (prefers-reduced-motion: reduce) {
    .combat-ulti-vignette { animation: none !important; }
}

/* EOF: modules/combat/ulti_charge.css - INTEGRITY_CHECK_OK */
