Mudanças entre as edições de "Widget:C.WeaponToggle"

De Wiki Gla
Ir para navegação Ir para pesquisar
m
m (modal checkbox)
 
(2 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
<!-- WEAPON TOGGLE SYSTEM - Estado global + popup i18n -->
<!-- WEAPON TOGGLE SYSTEM - Estado global + popup i18n -->
<script>
<script>
    (() => {
  (() => {
        let modalListenersBound = false;
    let modalListenersBound = false;


        // Variável global para o ícone do weapon toggle
    // Variável global para o ícone do weapon toggle
        let globalWeaponToggleIcon = null;
    let globalWeaponToggleIcon = null;


        // Função helper para construir URL de arquivo (mesmo sistema usado em Character.Skills.html)
    // Função helper para construir URL de arquivo (mesmo sistema usado em Character.Skills.html)
        function filePathURL(fileName) {
    function filePathURL(fileName) {
            // Evita requisições para Nada.png que não existe
      // Evita requisições para valores vazios
            if (!fileName || fileName.trim() === '' || fileName === 'Nada.png' || fileName.toLowerCase() === 'nada.png') {
      if (
                return '';
        !fileName ||
            }
        fileName.trim() === ""
            // Remove prefixos e decodifica se já estiver codificado (evita double encoding)
      ) {
            let cleanName = fileName.replace(/^Arquivo:|^File:/, '');
        return "";
      }
      // Remove prefixos e decodifica se já estiver codificado (evita double encoding)
      let cleanName = fileName.replace(/^Arquivo:|^File:/, "");
      try {
        // Tenta decodificar primeiro (caso já venha codificado como %27)
        cleanName = decodeURIComponent(cleanName);
      } catch (e) {
        // Se falhar, usa o nome original
      }
      // Agora codifica corretamente
      const f = encodeURIComponent(cleanName);
      const base =
        window.mw && mw.util && typeof mw.util.wikiScript === "function"
          ? mw.util.wikiScript()
          : window.mw && window.mw.config
            ? mw.config.get("wgScript") || "/index.php"
            : "/index.php";
      // Garante HTTPS para evitar Mixed Content
      let url = `${base}?title=Especial:FilePath/${f}`;
      if (window.location.protocol === "https:" && url.startsWith("http://")) {
        url = url.replace("http://", "https://");
      }
      return url;
    }
 
    // Função para resolver o ícone do weapon toggle do character-box
    function resolveCharacterWeaponIcon() {
      const root = document.querySelector(".character-box");
      if (!root) return;
      const raw = root.dataset.weaponicon;
      if (!raw || raw.trim() === "") {
        globalWeaponToggleIcon = null;
        return;
      }
      globalWeaponToggleIcon = filePathURL(raw.trim());
      // console.log('[WeaponToggle] Resolved weaponicon:', raw, '->', globalWeaponToggleIcon);
    }
 
    // Textos i18n para o popup
    const i18nTexts = {
      pt: {
        title: "Visualização com Arma Especial",
        body1:
          "Este modo ativa a visualização do personagem equipado com sua <strong>arma especial</strong>.",
        body2:
          "Algumas habilidades são diferentes enquanto estão com a arma equipada, essas habilidades ficam <strong>destacadas com borda vermelha</strong>.",
        dontShow: "Não mostrar novamente",
        ok: "Entendi",
        weaponLink: "Ver página da arma:",
      },
      en: {
        title: "Special Weapon View",
        body1:
          "This mode activates the view of the character equipped with their <strong>special weapon</strong>.",
        body2:
          "Some abilities are different while equipped with the weapon, these abilities are <strong>highlighted with a red border</strong>.",
        dontShow: "Don't show again",
        ok: "Got it",
        weaponLink: "View weapon page:",
      },
      es: {
        title: "Visualización con Arma Especial",
        body1:
          "Este modo activa la visualización del personaje equipado con su <strong>arma especial</strong>.",
        body2:
          "Algunas habilidades son diferentes mientras están con el arma equipada, estas habilidades quedan <strong>destacadas con borde rojo</strong>.",
        dontShow: "No mostrar de nuevo",
        ok: "Entendido",
        weaponLink: "Ver página del arma:",
      },
      pl: {
        title: "Widok z Bronią Specjalną",
        body1:
          "Ten tryb aktywuje widok postaci wyposażonej w <strong>broń specjalną</strong>.",
        body2:
          "Niektóre umiejętności różnią się podczas posiadania broni, te umiejętności są <strong>podświetlone czerwoną obwódką</strong>.",
        dontShow: "Nie pokazuj ponownie",
        ok: "Rozumiem",
        weaponLink: "Zobacz stronę broni:",
      },
    };
 
    const getCurrentLang = () => {
      const html = document.documentElement.lang || "pt-br";
      const norm = html.toLowerCase().split("-")[0];
      return i18nTexts[norm] ? norm : "pt";
    };
 
    const bindModalEvents = () => {
      if (modalListenersBound) return;
      modalListenersBound = true;
      document.addEventListener("click", (ev) => {
        if (
          ev.target.closest(".weapon-modal-close") ||
          ev.target.closest(".weapon-modal-btn")
        ) {
          const checkbox = document.getElementById("weapon-dont-show");
          if (checkbox && checkbox.checked) {
             try {
             try {
                // Tenta decodificar primeiro (caso já venha codificado como %27)
              localStorage.setItem("glaWeaponPopupDismissed", "1");
                cleanName = decodeURIComponent(cleanName);
             } catch (x) { }
             } catch (e) {
          }
                // Se falhar, usa o nome original
          hidePopup();
            }
          return;
            // Agora codifica corretamente
            const f = encodeURIComponent(cleanName);
            const base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function') ? mw.util.wikiScript() : (window.mw && window.mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
            // Garante HTTPS para evitar Mixed Content
            let url = `${base}?title=Especial:FilePath/${f}`;
            if (window.location.protocol === 'https:' && url.startsWith('http://')) {
                url = url.replace('http://', 'https://');
            }
            return url;
         }
         }
 
         if (ev.target.classList.contains("weapon-modal-overlay")) {
         // Função para resolver o ícone do weapon toggle do character-box
          hidePopup();
        function resolveCharacterWeaponIcon() {
            const root = document.querySelector('.character-box');
            if (!root) return;
            const raw = root.dataset.weaponicon;
            if (!raw || raw.trim() === '' || raw === 'Nada.png') {
                globalWeaponToggleIcon = null;
                return;
            }
            globalWeaponToggleIcon = filePathURL(raw.trim());
            // console.log('[WeaponToggle] Resolved weaponicon:', raw, '->', globalWeaponToggleIcon);
         }
         }
      });
    };


        // Textos i18n para o popup
    const applyWeaponState = (enabled) => {
        const i18nTexts = {
      if (typeof window.__setGlobalWeaponEnabled === "function") {
            pt: {
        window.__setGlobalWeaponEnabled(enabled);
                title: 'Visualização com Arma Especial',
      }
                body1: 'Este modo ativa a visualização do personagem equipado com sua <strong>arma especial</strong>.',
                body2: 'Algumas habilidades são diferentes enquanto estão com a arma equipada, essas habilidades ficam <strong>destacadas com borda vermelha</strong>.',
                dontShow: 'Não mostrar novamente',
                ok: 'Entendi',
                weaponLink: 'Ver página da arma:'
            },
            en: {
                title: 'Special Weapon View',
                body1: 'This mode activates the view of the character equipped with their <strong>special weapon</strong>.',
                body2: 'Some abilities are different while equipped with the weapon, these abilities are <strong>highlighted with a red border</strong>.',
                dontShow: "Don't show again",
                ok: 'Got it',
                weaponLink: 'View weapon page:'
            },
            es: {
                title: 'Visualización con Arma Especial',
                body1: 'Este modo activa la visualización del personaje equipado con su <strong>arma especial</strong>.',
                body2: 'Algunas habilidades son diferentes mientras están con el arma equipada, estas habilidades quedan <strong>destacadas con borde rojo</strong>.',
                dontShow: 'No mostrar de nuevo',
                ok: 'Entendido',
                weaponLink: 'Ver página del arma:'
            },
            pl: {
                title: 'Widok z Bronią Specjalną',
                body1: 'Ten tryb aktywuje widok postaci wyposażonej w <strong>broń specjalną</strong>.',
                body2: 'Niektóre umiejętności różnią się podczas posiadania broni, te umiejętności są <strong>podświetlone czerwoną obwódką</strong>.',
                dontShow: 'Nie pokazuj ponownie',
                ok: 'Rozumiem',
                weaponLink: 'Zobacz stronę broni:'
            }
        };


        const getCurrentLang = () => {
      try {
            const html = document.documentElement.lang || 'pt-br';
        localStorage.setItem("glaWeaponEnabled", enabled ? "1" : "0");
            const norm = html.toLowerCase().split('-')[0];
      } catch (x) { }
            return i18nTexts[norm] ? norm : 'pt';
        };


        const bindModalEvents = () => {
      // Dispara evento para atualizar subskills
            if (modalListenersBound) return;
      window.dispatchEvent(
            modalListenersBound = true;
        new CustomEvent("gla:weaponToggled", { detail: { enabled } })
            document.addEventListener('click', (ev) => {
      );
                if (ev.target.closest('.weapon-modal-close') || ev.target.closest('.weapon-modal-btn')) {
                    const checkbox = document.getElementById('weapon-dont-show');
                    if (checkbox && checkbox.checked) {
                        try { localStorage.setItem('glaWeaponPopupDismissed', '1'); } catch (x) { }
                    }
                    hidePopup();
                    return;
                }
                if (ev.target.classList.contains('weapon-modal-overlay')) {
                    hidePopup();
                }
            });
        };


         const applyWeaponState = (enabled) => {
      // SISTEMA UNIFICADO: Aplica toggle em skills E subskills
             if (typeof window.__setGlobalWeaponEnabled === 'function') {
      // Skills principais e subskills usam data-weapon (padronizado)
                 window.__setGlobalWeaponEnabled(enabled);
      document
         .querySelectorAll(".skill-icon[data-weapon], .subicon[data-weapon]")
        .forEach((el) => {
          const weaponData = el.getAttribute("data-weapon");
          // Verifica se o weapon não está vazio (não é '{}' ou vazio)
          let hasValidWeapon = false;
          if (weaponData && weaponData.trim() !== "" && weaponData !== "{}") {
             try {
              const weaponObj = JSON.parse(weaponData);
              if (
                weaponObj &&
                typeof weaponObj === "object" &&
                Object.keys(weaponObj).length > 0
              ) {
                 hasValidWeapon = true;
              }
            } catch (e) {
              // Se não for JSON válido, não considera como weapon válido
             }
             }
          }


             try {
          if (enabled && hasValidWeapon) {
                localStorage.setItem('glaWeaponEnabled', enabled ? '1' : '0');
             el.classList.add("has-weapon-available");
             } catch (x) { }
          } else {
            el.classList.remove("has-weapon-available");
            el.classList.remove("weapon-equipped");
            const ind = el.querySelector(".weapon-indicator");
             if (ind) ind.remove();
          }
        });


             // Dispara evento para atualizar subskills
      // Atualiza descrição da skill/subskill selecionada (se houver) para refletir estado da arma
             window.dispatchEvent(new CustomEvent('gla:weaponToggled', { detail: { enabled } }));
      // Aguarda um pouco mais para garantir que o estado global foi sincronizado
      setTimeout(() => {
        // Atualiza skill principal se houver - força reativação completa incluindo vídeo
        const sel = document.querySelector(
          ".skill-icon.active:not(.weapon-bar-toggle)"
        );
        if (sel) {
          // Força uma reativação completa da skill para garantir que vídeo seja atualizado
          if (
            typeof window.__subskills !== "undefined" &&
             window.__subskills.hideAll
          ) {
            const videoBox =
              document.querySelector(".video-container") ||
              document.querySelector(".skills-video-box");
            if (videoBox) window.__subskills.hideAll(videoBox);
          }
          // Reativa a skill para atualizar vídeo, descrição e atributos
          if (
            typeof window.__lastActiveSkillIcon !== "undefined" &&
             window.__lastActiveSkillIcon === sel
          ) {
            sel.dispatchEvent(new Event("click", { bubbles: true }));
          } else {
            sel.dispatchEvent(new Event("click", { bubbles: true }));
          }
        }
        // Atualiza subskill ativa se houver - força reativação completa incluindo vídeo
        const activeSub = document.querySelector(".subicon.active");
        if (activeSub) {
          activeSub.dispatchEvent(new Event("click", { bubbles: true }));
        }
      }, 100);
    };


            // SISTEMA UNIFICADO: Aplica toggle em skills E subskills
    const updateModalTexts = (modal) => {
            // Skills principais e subskills usam data-weapon (padronizado)
      const lang = getCurrentLang();
            document.querySelectorAll('.skill-icon[data-weapon], .subicon[data-weapon]').forEach(el => {
      const t = i18nTexts[lang];
                const weaponData = el.getAttribute('data-weapon');
                // Verifica se o weapon não está vazio (não é '{}' ou vazio)
                let hasValidWeapon = false;
                if (weaponData && weaponData.trim() !== '' && weaponData !== '{}') {
                    try {
                        const weaponObj = JSON.parse(weaponData);
                        if (weaponObj && typeof weaponObj === 'object' && Object.keys(weaponObj).length > 0) {
                            hasValidWeapon = true;
                        }
                    } catch (e) {
                        // Se não for JSON válido, não considera como weapon válido
                    }
                }


                if (enabled && hasValidWeapon) {
      const title = modal.querySelector(".weapon-modal-header h3");
                    el.classList.add('has-weapon-available');
      if (title) title.textContent = t.title;
                } else {
                    el.classList.remove('has-weapon-available');
                    el.classList.remove('weapon-equipped');
                    const ind = el.querySelector('.weapon-indicator');
                    if (ind) ind.remove();
                }
            });


            // Atualiza descrição da skill/subskill selecionada (se houver) para refletir estado da arma
      const body = modal.querySelector(".weapon-modal-body");
            // Aguarda um pouco mais para garantir que o estado global foi sincronizado
      if (body) {
            setTimeout(() => {
        const p1 = body.querySelector("p:first-child");
                // Atualiza skill principal se houver - força reativação completa incluindo vídeo
        const p2 = body.querySelector("p:nth-child(2)");
                const sel = document.querySelector('.skill-icon.active:not(.weapon-bar-toggle)');
        if (p1) p1.innerHTML = t.body1;
                if (sel) {
        if (p2) p2.innerHTML = t.body2;
                    // Força uma reativação completa da skill para garantir que vídeo seja atualizado
      }
                    if (typeof window.__subskills !== 'undefined' && window.__subskills.hideAll) {
                        const videoBox = document.querySelector('.video-container') || document.querySelector('.skills-video-box');
                        if (videoBox) window.__subskills.hideAll(videoBox);
                    }
                    // Reativa a skill para atualizar vídeo, descrição e atributos
                    if (typeof window.__lastActiveSkillIcon !== 'undefined' && window.__lastActiveSkillIcon === sel) {
                        sel.dispatchEvent(new Event('click', { bubbles: true }));
                    } else {
                        sel.dispatchEvent(new Event('click', { bubbles: true }));
                    }
                }
                // Atualiza subskill ativa se houver - força reativação completa incluindo vídeo
                const activeSub = document.querySelector('.subicon.active');
                if (activeSub) {
                    activeSub.dispatchEvent(new Event('click', { bubbles: true }));
                }
            }, 100);
        };


        const updateModalTexts = (modal) => {
      const checkbox = modal.querySelector(".weapon-modal-checkbox span");
            const lang = getCurrentLang();
      if (checkbox) checkbox.textContent = t.dontShow;
            const t = i18nTexts[lang];


            const title = modal.querySelector('.weapon-modal-header h3');
      const btn = modal.querySelector(".weapon-modal-btn");
            if (title) title.textContent = t.title;
      if (btn) btn.textContent = t.ok;


            const body = modal.querySelector('.weapon-modal-body');
      // Atualiza link da arma se existir
            if (body) {
      try {
                const p1 = body.querySelector('p:first-child');
        const firstWithWeapon = document.querySelector(
                const p2 = body.querySelector('p:nth-child(2)');
          ".skill-icon[data-weapon]"
                 if (p1) p1.innerHTML = t.body1;
        );
                if (p2) p2.innerHTML = t.body2;
        if (firstWithWeapon) {
          const raw = firstWithWeapon.getAttribute("data-weapon");
          const obj = JSON.parse(raw || "{}");
          const nm = obj && obj.name ? String(obj.name).trim() : "";
          if (nm) {
            const linkHost =
              window.mw && mw.util && typeof mw.util.getUrl === "function"
                 ? mw.util.getUrl(nm)
                : "/index.php?title=" + encodeURIComponent(nm);
            const holder = modal.querySelector(".weapon-info-link");
            if (holder) {
              holder.style.display = "block";
              holder.innerHTML = `<a href="${linkHost}">${t.weaponLink} ${nm}</a>`;
             }
             }
          }
        }
      } catch (_) { }
    };


            const checkbox = modal.querySelector('.weapon-modal-checkbox span');
    const ensureModal = () => {
            if (checkbox) checkbox.textContent = t.dontShow;
      let modal = document.getElementById("weapon-info-modal");
      if (modal) {
        updateModalTexts(modal);
        return modal;
      }


            const btn = modal.querySelector('.weapon-modal-btn');
      // Insere dentro da character-box para isolar completamente
            if (btn) btn.textContent = t.ok;
      const container =
        document.querySelector(".character-box") ||
        document.querySelector("#mw-content-text") ||
        document.body;


            // Atualiza link da arma se existir
      modal = document.createElement("div");
            try {
      modal.id = "weapon-info-modal";
                const firstWithWeapon = document.querySelector('.skill-icon[data-weapon]');
      modal.className = "weapon-modal";
                if (firstWithWeapon) {
      modal.innerHTML = `
                    const raw = firstWithWeapon.getAttribute('data-weapon');
                    const obj = JSON.parse(raw || '{}');
                    const nm = (obj && obj.name) ? String(obj.name).trim() : '';
                    if (nm) {
                        const linkHost = (window.mw && mw.util && typeof mw.util.getUrl === 'function') ? mw.util.getUrl(nm) : ('/index.php?title=' + encodeURIComponent(nm));
                        const holder = modal.querySelector('.weapon-info-link');
                        if (holder) {
                            holder.style.display = 'block';
                            holder.innerHTML = `<a href="${linkHost}">${t.weaponLink} ${nm}</a>`;
                        }
                    }
                }
            } catch (_) { }
        };
 
        const ensureModal = () => {
            let modal = document.getElementById('weapon-info-modal');
            if (modal) {
                updateModalTexts(modal);
                return modal;
            }
 
            // Insere dentro da character-box para isolar completamente
            const container = document.querySelector('.character-box') || document.querySelector('#mw-content-text') || document.body;
 
            modal = document.createElement('div');
            modal.id = 'weapon-info-modal';
            modal.className = 'weapon-modal';
            modal.innerHTML = `
             <div class="weapon-modal-overlay"></div>
             <div class="weapon-modal-overlay"></div>
             <div class="weapon-modal-content">
             <div class="weapon-modal-content">
Linha 244: Linha 291:
             </div>
             </div>
         `;
         `;
            container.appendChild(modal);
      container.appendChild(modal);
            updateModalTexts(modal);
      updateModalTexts(modal);
            bindModalEvents();
      bindModalEvents();
            return modal;
      return modal;
         };
    };
 
    const showPopup = () => {
      const modal = ensureModal();
      if (modal) {
         updateModalTexts(modal);
        // Força reflow antes de adicionar classe para garantir transição
        void modal.offsetHeight;
        modal.classList.add("show");
      }
    };
 
    const hidePopup = () => {
      const m = document.getElementById("weapon-info-modal");
      if (m) m.classList.remove("show");
    };


        const showPopup = () => {
    window.__applyWeaponState = applyWeaponState;
            const modal = ensureModal();
    window.__glaWeaponShowPopup = showPopup;
            if (modal) {
    window.__glaWeaponHidePopup = hidePopup;
                updateModalTexts(modal);
    try {
                // Força reflow antes de adicionar classe para garantir transição
      window.dispatchEvent(
                void modal.offsetHeight;
        new CustomEvent("weapon:ready", {
                modal.classList.add('show');
          detail: { applyWeaponState, showPopup, hidePopup },
            }
        })
        };
      );
    } catch (err) { }


        const hidePopup = () => {
    // Escuta mudanças de idioma
            const m = document.getElementById('weapon-info-modal');
    window.addEventListener("gla:langChanged", () => {
            if (m) m.classList.remove('show');
      const modal = document.getElementById("weapon-info-modal");
        };
      if (modal) updateModalTexts(modal);
    });


        window.__applyWeaponState = applyWeaponState;
    // Função para obter o nome da arma
         window.__glaWeaponShowPopup = showPopup;
    function getWeaponName() {
         window.__glaWeaponHidePopup = hidePopup;
      let weaponName = "Arma Especial";
         try {
      try {
            window.dispatchEvent(new CustomEvent('weapon:ready', { detail: { applyWeaponState, showPopup, hidePopup } }));
         const firstWithWeapon = document.querySelector(
        } catch (err) {
          ".skill-icon[data-weapon]"
         );
         if (firstWithWeapon) {
          const raw = firstWithWeapon.getAttribute("data-weapon");
          const obj = JSON.parse(raw || "{}");
          if (obj && obj.name) {
            weaponName = String(obj.name).trim();
          }
         }
         }
      } catch (e) { }
      return weaponName;
    }


        // Escuta mudanças de idioma
    // Função para criar o novo toggle abaixo do char-translator
        window.addEventListener('gla:langChanged', () => {
    function createWeaponToggle() {
            const modal = document.getElementById('weapon-info-modal');
      // Remove toggle antigo se existir
            if (modal) updateModalTexts(modal);
      const oldToggle = document.querySelector(".weapon-bar-toggle");
         });
      if (oldToggle) oldToggle.remove();
 
      const existingContainer = document.querySelector(
         ".weapon-toggle-container"
      );
      if (existingContainer) return existingContainer;


        // Função para obter o nome da arma
      const characterHeader = document.querySelector(".character-header");
        function getWeaponName() {
      if (!characterHeader) return null;
            let weaponName = 'Arma Especial';
            try {
                const firstWithWeapon = document.querySelector('.skill-icon[data-weapon]');
                if (firstWithWeapon) {
                    const raw = firstWithWeapon.getAttribute('data-weapon');
                    const obj = JSON.parse(raw || '{}');
                    if (obj && obj.name) {
                        weaponName = String(obj.name).trim();
                    }
                }
            } catch (e) { }
            return weaponName;
        }


        // Função para criar o novo toggle abaixo do char-translator
      // Resolve o ícone
        function createWeaponToggle() {
      resolveCharacterWeaponIcon();
            // Remove toggle antigo se existir
      const weaponName = getWeaponName();
            const oldToggle = document.querySelector('.weapon-bar-toggle');
            if (oldToggle) oldToggle.remove();


            const existingContainer = document.querySelector('.weapon-toggle-container');
      // Cria o container do toggle
            if (existingContainer) return existingContainer;
      const container = document.createElement("div");
      container.className = "weapon-toggle-container";
      container.setAttribute("role", "button");
      container.setAttribute("aria-pressed", "false");
      container.setAttribute("aria-label", weaponName);


            const characterHeader = document.querySelector('.character-header');
      // Cria o sprite (círculo com imagem)
            if (!characterHeader) return null;
      const sprite = document.createElement("div");
      sprite.className = "weapon-toggle-sprite";


            // Resolve o ícone
      if (globalWeaponToggleIcon) {
            resolveCharacterWeaponIcon();
        const img = document.createElement("img");
            const weaponName = getWeaponName();
        img.src = globalWeaponToggleIcon;
        img.alt = weaponName;
        img.className = "weapon-toggle-icon";
        img.decoding = "async";
        img.loading = "eager"; // Ícone do toggle é crítico - carrega imediatamente
        img.onerror = function () {
          // console.error('[WeaponToggle] Erro ao carregar imagem:', globalWeaponToggleIcon);
        };
        img.onload = function () {
          // console.log('[WeaponToggle] Imagem carregada com sucesso:', globalWeaponToggleIcon);
        };
        sprite.appendChild(img);
      }


            // Cria o container do toggle
      // Cria a barra com texto
            const container = document.createElement('div');
      const bar = document.createElement("div");
            container.className = 'weapon-toggle-container';
      bar.className = "weapon-toggle-bar";
            container.setAttribute('role', 'button');
      const nameSpan = document.createElement("span");
            container.setAttribute('aria-pressed', 'false');
      nameSpan.className = "weapon-toggle-name";
            container.setAttribute('aria-label', weaponName);
      nameSpan.setAttribute("data-lang", getCurrentLang());
      bar.appendChild(nameSpan);


            // Cria o sprite (círculo com imagem)
      container.appendChild(sprite);
            const sprite = document.createElement('div');
      container.appendChild(bar);
            sprite.className = 'weapon-toggle-sprite';


            if (globalWeaponToggleIcon) {
      // Adiciona evento de clique
                const img = document.createElement('img');
      container.addEventListener("click", () => {
                img.src = globalWeaponToggleIcon;
        let currentState = false;
                img.alt = weaponName;
        try {
                img.className = 'weapon-toggle-icon';
          currentState = localStorage.getItem("glaWeaponEnabled") === "1";
                img.decoding = 'async';
        } catch (e) { }
                img.loading = 'eager'; // Ícone do toggle é crítico - carrega imediatamente
        const nextState = !currentState;
                img.onerror = function () {
        if (nextState) {
                    // console.error('[WeaponToggle] Erro ao carregar imagem:', globalWeaponToggleIcon);
          // Verifica se o popup foi dispensado antes de mostrar
                };
          let shouldShowPopup = true;
                img.onload = function () {
          try {
                    // console.log('[WeaponToggle] Imagem carregada com sucesso:', globalWeaponToggleIcon);
            if (localStorage.getItem("glaWeaponPopupDismissed") === "1") {
                };
              shouldShowPopup = false;
                sprite.appendChild(img);
             }
             }
          } catch (e) { }
          if (
            shouldShowPopup &&
            typeof window.__glaWeaponShowPopup === "function"
          ) {
            window.__glaWeaponShowPopup();
          }
        }
        if (typeof window.__applyWeaponState === "function") {
          window.__applyWeaponState(nextState);
        }
      });


            // Cria a barra com texto
      // Insere no container de controles (character-header-controls)
            const bar = document.createElement('div');
      const controlsContainer = document.querySelector(
            bar.className = 'weapon-toggle-bar';
        ".character-header-controls"
            const nameSpan = document.createElement('span');
      );
            nameSpan.className = 'weapon-toggle-name';
      if (controlsContainer) {
            nameSpan.setAttribute('data-lang', getCurrentLang());
        controlsContainer.appendChild(container);
            bar.appendChild(nameSpan);
      } else {
        // Fallback: insere no character-header se o container não existir
        characterHeader.appendChild(container);
      }


            container.appendChild(sprite);
      // Atualiza estado visual inicial
            container.appendChild(bar);
      updateToggleVisualState();


            // Adiciona evento de clique
      return container;
            container.addEventListener('click', () => {
    }
                let currentState = false;
                try {
                    currentState = localStorage.getItem('glaWeaponEnabled') === '1';
                } catch (e) { }
                const nextState = !currentState;
                if (nextState) {
                    // Verifica se o popup foi dispensado antes de mostrar
                    let shouldShowPopup = true;
                    try {
                        if (localStorage.getItem('glaWeaponPopupDismissed') === '1') {
                            shouldShowPopup = false;
                        }
                    } catch (e) { }
                    if (shouldShowPopup && typeof window.__glaWeaponShowPopup === 'function') {
                        window.__glaWeaponShowPopup();
                    }
                }
                if (typeof window.__applyWeaponState === 'function') {
                    window.__applyWeaponState(nextState);
                }
            });


            // Insere no container de controles (character-header-controls)
    // Função para atualizar o estado visual do toggle
            const controlsContainer = document.querySelector('.character-header-controls');
    function updateToggleVisualState() {
            if (controlsContainer) {
      const container = document.querySelector(".weapon-toggle-container");
                controlsContainer.appendChild(container);
      if (!container) return;
            } else {
                // Fallback: insere no character-header se o container não existir
                characterHeader.appendChild(container);
            }


            // Atualiza estado visual inicial
      let isEnabled = false;
            updateToggleVisualState();
      try {
        isEnabled = localStorage.getItem("glaWeaponEnabled") === "1";
      } catch (e) { }


            return container;
      if (isEnabled) {
         }
        container.classList.add("weapon-active");
        container.setAttribute("aria-pressed", "true");
      } else {
        container.classList.remove("weapon-active");
         container.setAttribute("aria-pressed", "false");
      }


        // Função para atualizar o estado visual do toggle
      // Atualiza idioma do texto
        function updateToggleVisualState() {
      const nameSpan = container.querySelector(".weapon-toggle-name");
            const container = document.querySelector('.weapon-toggle-container');
      if (nameSpan) {
            if (!container) return;
        nameSpan.setAttribute("data-lang", getCurrentLang());
      }
    }


            let isEnabled = false;
    // Observa quando o container de controles é criado para posicionar o toggle
            try {
    function observeCharacterHeader() {
                isEnabled = localStorage.getItem('glaWeaponEnabled') === '1';
      const controlsContainer = document.querySelector(
            } catch (e) { }
        ".character-header-controls"
      );
      const characterHeader = document.querySelector(".character-header");
      if (controlsContainer) {
        // Container existe - cria o toggle imediatamente
        createWeaponToggle();
      } else if (characterHeader) {
        // Header existe mas container não - cria o container e depois o toggle
        const newContainer = document.createElement("div");
        newContainer.className = "character-header-controls";
        characterHeader.appendChild(newContainer);
        // Aguarda um frame para garantir que o container foi adicionado
        requestAnimationFrame(() => {
          createWeaponToggle();
        });
      } else {
        // Nada existe ainda - tenta novamente após um delay
        setTimeout(observeCharacterHeader, 100);
      }
    }


             if (isEnabled) {
    // Observa mudanças no DOM para detectar quando o container de controles é criado
                 container.classList.add('weapon-active');
    function observeDOMForHeader() {
                container.setAttribute('aria-pressed', 'true');
      const observer = new MutationObserver((mutations) => {
            } else {
        mutations.forEach((mutation) => {
                 container.classList.remove('weapon-active');
          mutation.addedNodes.forEach((node) => {
                container.setAttribute('aria-pressed', 'false');
             if (node.nodeType === 1) {
              if (
                node.classList &&
                 (node.classList.contains("character-header-controls") ||
                  node.classList.contains("character-header"))
              ) {
                setTimeout(() => createWeaponToggle(), 10);
              } else if (
                 node.querySelector &&
                (node.querySelector(".character-header-controls") ||
                  node.querySelector(".character-header"))
              ) {
                setTimeout(() => createWeaponToggle(), 10);
              }
             }
             }
          });
        });
      });


            // Atualiza idioma do texto
      observer.observe(document.body, { childList: true, subtree: true });
            const nameSpan = container.querySelector('.weapon-toggle-name');
    }
            if (nameSpan) {
 
                nameSpan.setAttribute('data-lang', getCurrentLang());
    const boot = () => {
            }
      // Resolve o ícone do character antes de tudo
      resolveCharacterWeaponIcon();
 
      // Verificar se existe alguma skill ou subskill com arma
      function checkHasAnyWeapon() {
        // PRIORIDADE 1: Verifica se há weaponicon global no character-box
        const characterBox = document.querySelector(".character-box");
        if (characterBox && characterBox.dataset.weaponicon) {
          const weaponIcon = characterBox.dataset.weaponicon.trim();
          if (weaponIcon && weaponIcon !== "") {
            return true;
          }
         }
         }


         // Observa quando o container de controles é criado para posicionar o toggle
         // PRIORIDADE 2: Verifica skills principais
         function observeCharacterHeader() {
         const mainSkills = document.querySelectorAll(
            const controlsContainer = document.querySelector('.character-header-controls');
          ".skill-icon[data-weapon]"
            const characterHeader = document.querySelector('.character-header');
        );
            if (controlsContainer) {
        for (const el of mainSkills) {
                // Container existe - cria o toggle imediatamente
          const weapon = el.dataset.weapon;
                createWeaponToggle();
          if (weapon && weapon.trim() !== "" && weapon !== "{}") {
            } else if (characterHeader) {
            try {
                 // Header existe mas container não - cria o container e depois o toggle
              const weaponObj = JSON.parse(weapon);
                 const newContainer = document.createElement('div');
              if (
                newContainer.className = 'character-header-controls';
                 weaponObj &&
                 characterHeader.appendChild(newContainer);
                 typeof weaponObj === "object" &&
                // Aguarda um frame para garantir que o container foi adicionado
                 Object.keys(weaponObj).length > 0
                requestAnimationFrame(() => {
              ) {
                    createWeaponToggle();
                return true;
                });
              }
             } else {
             } catch (e) {
                // Nada existe ainda - tenta novamente após um delay
              // Se não for JSON válido mas não está vazio, considera válido
                setTimeout(observeCharacterHeader, 100);
              return true;
             }
             }
          }
         }
         }


         // Observa mudanças no DOM para detectar quando o container de controles é criado
         // PRIORIDADE 3: Verifica weaponicon em skills principais
         function observeDOMForHeader() {
         const skillsWithWeaponIcon = document.querySelectorAll(
            const observer = new MutationObserver((mutations) => {
          ".skill-icon[data-weaponicon]"
                mutations.forEach((mutation) => {
        );
                    mutation.addedNodes.forEach((node) => {
        for (const el of skillsWithWeaponIcon) {
                        if (node.nodeType === 1) {
          const weaponIcon = el.dataset.weaponicon;
                            if (node.classList && (node.classList.contains('character-header-controls') || node.classList.contains('character-header'))) {
          if (weaponIcon && weaponIcon.trim() !== "") {
                                setTimeout(() => createWeaponToggle(), 10);
            return true;
                            } else if (node.querySelector && (node.querySelector('.character-header-controls') || node.querySelector('.character-header'))) {
          }
                                setTimeout(() => createWeaponToggle(), 10);
        }
                            }
                        }
                    });
                });
            });


             observer.observe(document.body, { childList: true, subtree: true });
        // PRIORIDADE 4: Verifica subskills
        const skillIcons = document.querySelectorAll(".skill-icon[data-subs]");
        for (const el of skillIcons) {
          try {
             const subs = JSON.parse(el.getAttribute("data-subs") || "[]");
            if (
              Array.isArray(subs) &&
              subs.some(
                (s) =>
                  s &&
                  s.weapon &&
                  typeof s.weapon === "object" &&
                  Object.keys(s.weapon).length > 0
              )
            ) {
              return true;
            }
          } catch (e) { }
         }
         }
        return false;
      }
      const hasAnyWeapon = checkHasAnyWeapon();


         const boot = () => {
      if (!hasAnyWeapon) {
             // Resolve o ícone do character antes de tudo
        // Limpar estado visual para chars sem arma (previne cache entre páginas)
            resolveCharacterWeaponIcon();
         const topRail = document.querySelector(".top-rail.skills");
        if (topRail) {
          topRail.classList.remove("weapon-mode-on");
        }
        document
          .querySelectorAll(".skill-icon.has-weapon-available")
          .forEach((el) => {
             el.classList.remove("has-weapon-available");
            el.classList.remove("weapon-equipped");
            const ind = el.querySelector(".weapon-indicator");
            if (ind) ind.remove();
          });
        // Remover toggle se existir
        const toggleContainer = document.querySelector(
          ".weapon-toggle-container"
        );
        if (toggleContainer) toggleContainer.remove();
        // Atualizar estado global para desligado
        if (typeof window.__setGlobalWeaponEnabled === "function") {
          window.__setGlobalWeaponEnabled(false);
        }
        return;
      }


            // Verificar se existe alguma skill ou subskill com arma
      ensureModal();
            function checkHasAnyWeapon() {
                // PRIORIDADE 1: Verifica se há weaponicon global no character-box
                const characterBox = document.querySelector('.character-box');
                if (characterBox && characterBox.dataset.weaponicon) {
                    const weaponIcon = characterBox.dataset.weaponicon.trim();
                    if (weaponIcon && weaponIcon !== '' && weaponIcon !== 'Nada.png') {
                        return true;
                    }
                }


                // PRIORIDADE 2: Verifica skills principais
      // Cria o novo toggle - tenta múltiplas vezes para garantir
                const mainSkills = document.querySelectorAll('.skill-icon[data-weapon]');
      observeCharacterHeader();
                for (const el of mainSkills) {
      observeDOMForHeader();
                    const weapon = el.dataset.weapon;
                    if (weapon && weapon.trim() !== '' && weapon !== '{}') {
                        try {
                            const weaponObj = JSON.parse(weapon);
                            if (weaponObj && typeof weaponObj === 'object' && Object.keys(weaponObj).length > 0) {
                                return true;
                            }
                        } catch (e) {
                            // Se não for JSON válido mas não está vazio, considera válido
                            return true;
                        }
                    }
                }


                // PRIORIDADE 3: Verifica weaponicon em skills principais
      // Tenta criar novamente após um delay maior para garantir que o translator já criou o container
                const skillsWithWeaponIcon = document.querySelectorAll('.skill-icon[data-weaponicon]');
      setTimeout(() => {
                for (const el of skillsWithWeaponIcon) {
        const existing = document.querySelector(".weapon-toggle-container");
                    const weaponIcon = el.dataset.weaponicon;
        if (!existing) {
                    if (weaponIcon && weaponIcon.trim() !== '' && weaponIcon !== 'Nada.png') {
          observeCharacterHeader();
                        return true;
        }
                    }
      }, 500);
                }


                // PRIORIDADE 4: Verifica subskills
      // Última tentativa após 1 segundo
                const skillIcons = document.querySelectorAll('.skill-icon[data-subs]');
      setTimeout(() => {
                for (const el of skillIcons) {
        const existing = document.querySelector(".weapon-toggle-container");
                    try {
        if (!existing) {
                        const subs = JSON.parse(el.getAttribute('data-subs') || '[]');
          observeCharacterHeader();
                        if (Array.isArray(subs) && subs.some(s => s && s.weapon && typeof s.weapon === 'object' && Object.keys(s.weapon).length > 0)) {
        }
                            return true;
      }, 1000);
                        }
                    } catch (e) { }
                }
                return false;
            }
            const hasAnyWeapon = checkHasAnyWeapon();


            if (!hasAnyWeapon) {
      // Remove qualquer toggle antigo que apareça nas barras de skills/subskills
                // Limpar estado visual para chars sem arma (previne cache entre páginas)
      function removeOldToggles() {
                const topRail = document.querySelector('.top-rail.skills');
        document.querySelectorAll(".weapon-bar-toggle").forEach((toggle) => {
                if (topRail) {
          toggle.remove();
                    topRail.classList.remove('weapon-mode-on');
        });
                }
      }
                document.querySelectorAll('.skill-icon.has-weapon-available').forEach(el => {
                    el.classList.remove('has-weapon-available');
                    el.classList.remove('weapon-equipped');
                    const ind = el.querySelector('.weapon-indicator');
                    if (ind) ind.remove();
                });
                // Remover toggle se existir
                const toggleContainer = document.querySelector('.weapon-toggle-container');
                if (toggleContainer) toggleContainer.remove();
                // Atualizar estado global para desligado
                if (typeof window.__setGlobalWeaponEnabled === 'function') {
                    window.__setGlobalWeaponEnabled(false);
                }
                return;
            }


            ensureModal();
      // Observa mudanças nas barras de ícones para remover toggles antigos
      const iconBarObserver = new MutationObserver(() => {
        removeOldToggles();
      });


            // Cria o novo toggle - tenta múltiplas vezes para garantir
      // Observa todas as barras de ícones existentes e futuras
            observeCharacterHeader();
      const observeAllIconBars = () => {
            observeDOMForHeader();
        document.querySelectorAll(".icon-bar").forEach((bar) => {
          iconBarObserver.observe(bar, { childList: true, subtree: true });
        });
      };


            // Tenta criar novamente após um delay maior para garantir que o translator já criou o container
      // Remove toggles antigos imediatamente
            setTimeout(() => {
      removeOldToggles();
                const existing = document.querySelector('.weapon-toggle-container');
                if (!existing) {
                    observeCharacterHeader();
                }
            }, 500);


            // Última tentativa após 1 segundo
      // Observa barras existentes
            setTimeout(() => {
      observeAllIconBars();
                const existing = document.querySelector('.weapon-toggle-container');
                if (!existing) {
                    observeCharacterHeader();
                }
            }, 1000);


            // Remove qualquer toggle antigo que apareça nas barras de skills/subskills
      // Observa criação de novas barras
            function removeOldToggles() {
      const bodyObserver = new MutationObserver((mutations) => {
                document.querySelectorAll('.weapon-bar-toggle').forEach(toggle => {
        mutations.forEach((mutation) => {
                    toggle.remove();
          mutation.addedNodes.forEach((node) => {
            if (node.nodeType === 1) {
              if (node.classList && node.classList.contains("icon-bar")) {
                iconBarObserver.observe(node, {
                  childList: true,
                  subtree: true,
                 });
                 });
                removeOldToggles();
              } else if (
                node.querySelector &&
                node.querySelector(".icon-bar")
              ) {
                observeAllIconBars();
                removeOldToggles();
              }
             }
             }
          });
        });
      });
      bodyObserver.observe(document.body, { childList: true, subtree: true });


            // Observa mudanças nas barras de ícones para remover toggles antigos
      // Escuta mudanças no estado do weapon para atualizar visual
            const iconBarObserver = new MutationObserver(() => {
      window.addEventListener("gla:weaponToggled", () => {
                removeOldToggles();
        setTimeout(updateToggleVisualState, 50);
            });
      });


            // Observa todas as barras de ícones existentes e futuras
      // Escuta mudanças de idioma
            const observeAllIconBars = () => {
      window.addEventListener("gla:langChanged", () => {
                document.querySelectorAll('.icon-bar').forEach(bar => {
        updateToggleVisualState();
                    iconBarObserver.observe(bar, { childList: true, subtree: true });
      });
                });
            };


            // Remove toggles antigos imediatamente
      // Estado inicial do toggle
            removeOldToggles();
      let init = false;
      try {
        if (localStorage.getItem("glaWeaponEnabled") === "1") init = true;
      } catch (x) { }
      setTimeout(() => {
        applyWeaponState(init);
        updateToggleVisualState();
      }, 150);
    };


            // Observa barras existentes
    if (document.readyState === "loading") {
            observeAllIconBars();
      document.addEventListener("DOMContentLoaded", boot);
    } else {
      boot();
    }
  })();
</script>
<style>
  /* Character-box precisa de position relative para conter o modal */
  .character-box {
    position: relative;
  }


            // Observa criação de novas barras
  /* Modal posicionado dentro da character-box */
            const bodyObserver = new MutationObserver((mutations) => {
  .weapon-modal {
                mutations.forEach((mutation) => {
    position: absolute;
                    mutation.addedNodes.forEach((node) => {
    inset: 0;
                        if (node.nodeType === 1) {
    z-index: 100;
                            if (node.classList && node.classList.contains('icon-bar')) {
    display: flex;
                                iconBarObserver.observe(node, { childList: true, subtree: true });
    align-items: center;
                                removeOldToggles();
    justify-content: center;
                            } else if (node.querySelector && node.querySelector('.icon-bar')) {
    pointer-events: none;
                                observeAllIconBars();
  }
                                removeOldToggles();
                            }
                        }
                    });
                });
            });


            bodyObserver.observe(document.body, { childList: true, subtree: true });
  .weapon-modal.show {
    pointer-events: all;
  }


            // Escuta mudanças no estado do weapon para atualizar visual
  /* Overlay escurece apenas a character-box - aparece PRIMEIRO */
            window.addEventListener('gla:weaponToggled', () => {
  .weapon-modal-overlay {
                setTimeout(updateToggleVisualState, 50);
    position: absolute;
            });
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    opacity: 0;
    transition: opacity 0.15s ease;
  }


            // Escuta mudanças de idioma
  .weapon-modal.show .weapon-modal-overlay {
            window.addEventListener('gla:langChanged', () => {
    opacity: 1;
                updateToggleVisualState();
  }
            });


            // Estado inicial do toggle
  /* Conteúdo aparece DEPOIS do overlay */
            let init = false;
  .weapon-modal-content {
            try {
    position: relative;
                if (localStorage.getItem('glaWeaponEnabled') === '1') init = true;
    z-index: 1;
            } catch (x) { }
    transform: scale(0.96);
            setTimeout(() => {
    background: linear-gradient(145deg, #2d1a1a, #1e1212);
                applyWeaponState(init);
    border: 1px solid rgba(255, 100, 100, 0.2);
                updateToggleVisualState();
    border-radius: 14px;
            }, 150);
    max-width: 420px;
        };
    width: 90%;
    opacity: 0;
    transition: transform 0.18s ease 0.08s, opacity 0.15s ease 0.08s;
    overflow: hidden;
  }


        if (document.readyState === 'loading') {
  .weapon-modal.show .weapon-modal-content {
            document.addEventListener('DOMContentLoaded', boot);
     transform: scale(1);
        } else {
     opacity: 1;
            boot();
  }
        }
     })();
</script>
<style>
    /* Character-box precisa de position relative para conter o modal */
     .character-box {
        position: relative;
    }


    /* Modal posicionado dentro da character-box */
  .weapon-modal-header {
    .weapon-modal {
    display: flex;
        position: absolute;
    align-items: center;
        inset: 0;
    justify-content: space-between;
        z-index: 100;
    padding: 16px 20px;
        display: flex;
    border-bottom: 1px solid rgba(255, 100, 100, 0.12);
        align-items: center;
     background: linear-gradient(90deg, rgba(255, 80, 80, 0.06), transparent);
        justify-content: center;
  }
        pointer-events: none;
     }


    .weapon-modal.show {
  .weapon-modal-header h3 {
        pointer-events: all;
    margin: 0;
     }
    font-size: 16px;
    font-weight: 600;
     color: #fff;
  }


    /* Overlay escurece apenas a character-box - aparece PRIMEIRO */
  .weapon-modal-close {
    .weapon-modal-overlay {
    background: transparent;
        position: absolute;
    border: 1px solid rgba(255, 255, 255, 0.1);
        inset: 0;
    color: rgba(255, 255, 255, 0.5);
        background: rgba(0, 0, 0, .65);
    font-size: 18px;
        -webkit-backdrop-filter: blur(4px);
    font-family: Arial, sans-serif;
        backdrop-filter: blur(4px);
    line-height: 1;
        opacity: 0;
    cursor: pointer;
        transition: opacity .15s ease;
    padding: 0;
    }
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    border-radius: 6px;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
  }


    .weapon-modal.show .weapon-modal-overlay {
  .weapon-modal-close:hover {
        opacity: 1;
    background: rgba(255, 80, 80, 0.15);
     }
    border-color: rgba(255, 80, 80, 0.3);
     color: #ff7043;
  }


    /* Conteúdo aparece DEPOIS do overlay */
  .weapon-modal-body {
    .weapon-modal-content {
    padding: 20px;
        position: relative;
    color: rgba(255, 255, 255, 0.85);
        z-index: 1;
    line-height: 1.65;
        transform: scale(0.96);
    font-size: 14px;
        background: linear-gradient(145deg, #2d1a1a, #1e1212);
  }
        border: 1px solid rgba(255, 100, 100, .2);
        border-radius: 14px;
        max-width: 420px;
        width: 90%;
        opacity: 0;
        transition: transform .18s ease .08s, opacity .15s ease .08s;
        overflow: hidden;
    }


    .weapon-modal.show .weapon-modal-content {
  .weapon-modal-body p {
        transform: scale(1);
    margin: 0 0 12px;
        opacity: 1;
    display: block !important;
    }
  }


    .weapon-modal-header {
  .weapon-modal-body p:last-child,
        display: flex;
  .weapon-modal-body p.weapon-info-link {
        align-items: center;
    margin: 0;
        justify-content: space-between;
  }
        padding: 16px 20px;
        border-bottom: 1px solid rgba(255, 100, 100, .12);
        background: linear-gradient(90deg, rgba(255, 80, 80, .06), transparent);
    }


    .weapon-modal-header h3 {
  .weapon-modal-body p.weapon-info-link:empty {
        margin: 0;
    display: none !important;
        font-size: 16px;
  }
        font-weight: 600;
        color: #fff;
    }


    .weapon-modal-close {
  .weapon-modal-body strong {
        background: transparent;
    color: #ff7043;
        border: 1px solid rgba(255, 255, 255, .1);
    font-weight: 600;
        color: rgba(255, 255, 255, .5);
  }
        font-size: 18px;
        font-family: Arial, sans-serif;
        line-height: 1;
        cursor: pointer;
        padding: 0;
        width: 28px;
        height: 28px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        border-radius: 6px;
        transition: background .15s, color .15s, border-color .15s;
    }


    .weapon-modal-close:hover {
  .weapon-modal-body .weapon-info-link a {
        background: rgba(255, 80, 80, .15);
    color: #ff7043;
        border-color: rgba(255, 80, 80, .3);
    text-decoration: none;
        color: #FF7043;
    font-weight: 600;
    }
  }


    .weapon-modal-body {
  .weapon-modal-body .weapon-info-link a:hover {
        padding: 20px;
    text-decoration: underline;
        color: rgba(255, 255, 255, .85);
  }
        line-height: 1.65;
        font-size: 14px;
    }


    .weapon-modal-body p {
  .weapon-modal-footer {
        margin: 0 0 12px;
    display: flex;
        display: block !important;
    align-items: center;
    }
    justify-content: space-between;
    padding: 14px 20px;
    border-top: 1px solid rgba(255, 100, 100, 0.1);
    background: rgba(0, 0, 0, 0.1);
    gap: 12px;
  }


    .weapon-modal-body p:last-child,
  .weapon-modal-checkbox {
     .weapon-modal-body p.weapon-info-link {
    display: inline-flex;
        margin: 0;
    align-items: center;
     }
    gap: 8px;
     font-size: 12px;
    line-height: 1.2;
    color: rgba(255, 255, 255, 0.5);
    cursor: pointer;
     transition: color 0.15s;
  }


    .weapon-modal-body p.weapon-info-link:empty {
  .weapon-modal-checkbox:hover {
        display: none !important;
    color: rgba(255, 255, 255, 0.75);
    }
  }


    .weapon-modal-body strong {
  .weapon-modal-checkbox input[type="checkbox"] {
        color: #FF7043;
    accent-color: #ff5722;
        font-weight: 600;
    margin: 0;
     }
    width: 14px;
    height: 14px;
    flex-shrink: 0;
     transform: translateY(1px);
  }


    .weapon-modal-body .weapon-info-link a {
  .weapon-modal-checkbox span {
        color: #FF7043;
    line-height: 1.2;
        text-decoration: none;
  }
        font-weight: 600;
    }


    .weapon-modal-body .weapon-info-link a:hover {
  .weapon-modal-btn {
        text-decoration: underline;
    background: #bf360c;
    }
    border: none;
    color: #fff;
    padding: 10px 24px;
    border-radius: 6px;
    font-weight: 600;
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }


    .weapon-modal-footer {
  .weapon-modal-btn:hover {
        display: flex;
    background: #d84315;
        align-items: center;
  }
        justify-content: space-between;
        padding: 14px 20px;
        border-top: 1px solid rgba(255, 100, 100, .1);
        background: rgba(0, 0, 0, .1);
        gap: 12px;
    }


    .weapon-modal-checkbox {
  .weapon-modal-btn:active {
        display: inline-flex;
    background: #a52714;
        align-items: center;
  }
        gap: 6px;
        font-size: 12px;
        color: rgba(255, 255, 255, .5);
        cursor: pointer;
        transition: color .15s;
    }


     .weapon-modal-checkbox:hover {
  @media (max-width: 600px) {
        color: rgba(255, 255, 255, .75);
     .weapon-modal-content {
      width: 92%;
      max-width: none;
     }
     }


     .weapon-modal-checkbox input[type="checkbox"] {
     .weapon-modal-header,
        accent-color: #FF5722;
    .weapon-modal-body,
        margin: 0;
    .weapon-modal-footer {
        flex-shrink: 0;
      padding: 14px 16px;
     }
     }


     .weapon-modal-checkbox span {
     .weapon-modal-footer {
        line-height: 1;
      flex-direction: column;
      gap: 12px;
     }
     }


     .weapon-modal-btn {
     .weapon-modal-btn {
        background: #BF360C;
      width: 100%;
        border: none;
        color: #fff;
        padding: 10px 24px;
        border-radius: 6px;
        font-weight: 600;
        font-size: 13px;
        line-height: 1;
        cursor: pointer;
        transition: background .15s;
        display: inline-flex;
        align-items: center;
        justify-content: center;
     }
     }
  }


    .weapon-modal-btn:hover {
  /* =========================== NOVO WEAPON TOGGLE =========================== */
        background: #D84315;
  .weapon-toggle-container {
     }
    display: flex;
    align-items: center;
    z-index: 10;
    background: transparent;
    padding: 0;
    border-radius: 0;
    border: none;
    box-shadow: none;
     cursor: pointer;
    transition: transform 0.08s ease;
    overflow: visible;
    height: 44px;
    box-sizing: border-box;
  }


    .weapon-modal-btn:active {
  .weapon-toggle-container:hover {
        background: #A52714;
    transform: translateY(-1px);
    }
  }


     @media (max-width: 600px) {
  .weapon-toggle-sprite {
        .weapon-modal-content {
     width: 44px;
            width: 92%;
    height: 44px;
            max-width: none;
    flex-shrink: 0;
        }
    border-radius: 50%;
    overflow: visible;
    position: relative;
    background: rgb(40, 40, 48);
    border: 2px solid rgba(255, 255, 255, 0.15);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
      border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
      box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: background-color;
  }


        .weapon-modal-header,
  .weapon-toggle-sprite img {
        .weapon-modal-body,
    width: 64px;
        .weapon-modal-footer {
    height: 64px;
            padding: 14px 16px;
    display: block;
        }
    /* Força redimensionamento pixelado (nearest neighbor) - ordem importante */
    -ms-interpolation-mode: nearest-neighbor;
    /* IE/Edge antigo - deve vir primeiro */
    image-rendering: -moz-crisp-edges;
    /* Firefox */
    image-rendering: -webkit-optimize-contrast;
    /* Safari/Chrome antigo */
    image-rendering: pixelated;
    /* Chrome/Edge moderno */
    image-rendering: crisp-edges !important;
    /* Fallback padrão - força sem suavização */
    /* Garante que não há suavização por transform ou filter */
    transform: translateZ(0);
    backface-visibility: hidden;
    /* Mantém proporção sem suavização */
    object-fit: contain;
    object-position: center;
    /* Força renderização sem suavização - importante para sprites pixelados */
    -webkit-font-smoothing: none;
    font-smoothing: none;
  }


        .weapon-modal-footer {
  .weapon-toggle-bar {
            flex-direction: column;
    background: rgb(40, 40, 48);
            gap: 12px;
    padding: 5px 14px 5px 28px;
        }
    border-radius: 0 7px 7px 0;
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-left: none;
    display: flex;
    align-items: center;
    width: 180px;
    position: relative;
    overflow: hidden;
    margin: 0;
    margin-left: -22px;
    height: 34px;
    box-sizing: border-box;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
      background-image 0.15s cubic-bezier(0.4, 0, 0.2, 1),
      border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: background-color, background-image;
  }


        .weapon-modal-btn {
  .weapon-toggle-name {
            width: 100%;
    color: #fff;
        }
    font-size: 14px;
     }
    font-weight: 600;
    white-space: nowrap;
     text-overflow: ellipsis;
    overflow: hidden;
    position: relative;
    z-index: 2;
    letter-spacing: 0.3px;
    display: inline-block;
  }


    /* =========================== NOVO WEAPON TOGGLE =========================== */
  /* Textos i18n - usando ::after para mostrar o texto baseado no data-lang e estado */
    .weapon-toggle-container {
  .weapon-toggle-name::after {
        display: flex;
    content: "Equipar Arma";
        align-items: center;
    /* Default PT */
        z-index: 10;
  }
        background: transparent;
        padding: 0;
        border-radius: 0;
        border: none;
        box-shadow: none;
        cursor: pointer;
        transition: transform .08s ease;
        overflow: visible;
        height: 44px;
        box-sizing: border-box;
    }


    .weapon-toggle-container:hover {
  .weapon-toggle-name[data-lang="pt"]::after {
        transform: translateY(-1px);
    content: "Equipar Arma";
    }
  }


    .weapon-toggle-sprite {
  .weapon-toggle-name[data-lang="en"]::after {
        width: 44px;
    content: "Equip Weapon";
        height: 44px;
  }
        flex-shrink: 0;
        border-radius: 50%;
        overflow: visible;
        position: relative;
        background: rgb(40, 40, 48);
        border: 2px solid rgba(255, 255, 255, 0.15);
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 2;
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
        transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
        will-change: background-color;
    }


    .weapon-toggle-sprite img {
  .weapon-toggle-name[data-lang="es"]::after {
        width: 64px;
    content: "Equipar Arma";
        height: 64px;
  }
        display: block;
        /* Força redimensionamento pixelado (nearest neighbor) - ordem importante */
        -ms-interpolation-mode: nearest-neighbor;
        /* IE/Edge antigo - deve vir primeiro */
        image-rendering: -moz-crisp-edges;
        /* Firefox */
        image-rendering: -webkit-optimize-contrast;
        /* Safari/Chrome antigo */
        image-rendering: pixelated;
        /* Chrome/Edge moderno */
        image-rendering: crisp-edges !important;
        /* Fallback padrão - força sem suavização */
        /* Garante que não há suavização por transform ou filter */
        transform: translateZ(0);
        backface-visibility: hidden;
        /* Mantém proporção sem suavização */
        object-fit: contain;
        object-position: center;
        /* Força renderização sem suavização - importante para sprites pixelados */
        -webkit-font-smoothing: none;
        font-smoothing: none;
    }


    .weapon-toggle-bar {
  .weapon-toggle-name[data-lang="pl"]::after {
        background: rgb(40, 40, 48);
    content: "Wyposaż Broń";
        padding: 5px 14px 5px 28px;
  }
        border-radius: 0 7px 7px 0;
        border: 2px solid rgba(255, 255, 255, 0.15);
        border-left: none;
        display: flex;
        align-items: center;
        width: 180px;
        position: relative;
        overflow: hidden;
        margin: 0;
        margin-left: -22px;
        height: 34px;
        box-sizing: border-box;
        box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
        transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), background-image 0.15s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1);
        will-change: background-color, background-image;
    }


    .weapon-toggle-name {
  /* Estado ATIVO (arma equipada) - muda o texto */
        color: #fff;
  .weapon-toggle-container.weapon-active .weapon-toggle-name::after {
        font-size: 14px;
    content: "Desequipar Arma";
        font-weight: 600;
    /* Default PT */
        white-space: nowrap;
  }
        text-overflow: ellipsis;
        overflow: hidden;
        position: relative;
        z-index: 2;
        letter-spacing: 0.3px;
        display: inline-block;
    }


    /* Textos i18n - usando ::after para mostrar o texto baseado no data-lang e estado */
  .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pt"]::after {
    .weapon-toggle-name::after {
    content: "Desequipar Arma";
        content: "Equipar Arma";
  }
        /* Default PT */
    }


    .weapon-toggle-name[data-lang="pt"]::after {
  .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="en"]::after {
        content: "Equipar Arma";
     content: "Unequip Weapon";
    }
  }
 
    .weapon-toggle-name[data-lang="en"]::after {
        content: "Equip Weapon";
    }
 
    .weapon-toggle-name[data-lang="es"]::after {
        content: "Equipar Arma";
    }
 
     .weapon-toggle-name[data-lang="pl"]::after {
        content: "Wyposaż Broń";
    }
 
    /* Estado ATIVO (arma equipada) - muda o texto */
    .weapon-toggle-container.weapon-active .weapon-toggle-name::after {
        content: "Desequipar Arma";
        /* Default PT */
    }


    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pt"]::after {
  .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="es"]::after {
        content: "Desequipar Arma";
    content: "Desequipar Arma";
    }
  }


    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="en"]::after {
  .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pl"]::after {
        content: "Unequip Weapon";
    content: "Zdjęć Broń";
    }
  }


    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="es"]::after {
  /* Estado ativo - destaque vermelho */
        content: "Desequipar Arma";
  .weapon-toggle-container.weapon-active .weapon-toggle-sprite {
    }
    background-color: rgb(200, 60, 40) !important;
    border: 2px solid rgba(255, 255, 255, 0.15);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  }


    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pl"]::after {
  .weapon-toggle-container.weapon-active .weapon-toggle-bar {
         content: "Zdjęć Broń";
    background-color: rgb(200, 60, 40);
     }
    background-image: linear-gradient(135deg,
        rgb(200, 60, 40),
         rgb(160, 45, 30));
    border-color: rgba(255, 87, 34, 0.3);
     border-left: none;
    border-radius: 0 7px 7px 0;
  }


    /* Estado ativo - destaque vermelho */
  .weapon-toggle-container.weapon-active .weapon-toggle-name {
    .weapon-toggle-container.weapon-active .weapon-toggle-sprite {
     color: #fff;
        background-color: rgb(200, 60, 40) !important;
    text-shadow: 0 0 4px rgba(255, 87, 34, 0.5);
        border: 2px solid rgba(255, 255, 255, 0.15);
  }
        box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
     }
 
    .weapon-toggle-container.weapon-active .weapon-toggle-bar {
        background-color: rgb(200, 60, 40);
        background-image: linear-gradient(135deg, rgb(200, 60, 40), rgb(160, 45, 30));
        border-color: rgba(255, 87, 34, 0.3);
        border-left: none;
        border-radius: 0 7px 7px 0;
    }
 
    .weapon-toggle-container.weapon-active .weapon-toggle-name {
        color: #fff;
        text-shadow: 0 0 4px rgba(255, 87, 34, 0.5);
    }
</style>
</style>

Edição atual tal como às 05h18min de 24 de janeiro de 2026

<script>

 (() => {
   let modalListenersBound = false;
   // Variável global para o ícone do weapon toggle
   let globalWeaponToggleIcon = null;
   // Função helper para construir URL de arquivo (mesmo sistema usado em Character.Skills.html)
   function filePathURL(fileName) {
     // Evita requisições para valores vazios
     if (
       !fileName ||
       fileName.trim() === ""
     ) {
       return "";
     }
     // Remove prefixos e decodifica se já estiver codificado (evita double encoding)
     let cleanName = fileName.replace(/^Arquivo:|^File:/, "");
     try {
       // Tenta decodificar primeiro (caso já venha codificado como %27)
       cleanName = decodeURIComponent(cleanName);
     } catch (e) {
       // Se falhar, usa o nome original
     }
     // Agora codifica corretamente
     const f = encodeURIComponent(cleanName);
     const base =
       window.mw && mw.util && typeof mw.util.wikiScript === "function"
         ? mw.util.wikiScript()
         : window.mw && window.mw.config
           ? mw.config.get("wgScript") || "/index.php"
           : "/index.php";
     // Garante HTTPS para evitar Mixed Content
     let url = `${base}?title=Especial:FilePath/${f}`;
     if (window.location.protocol === "https:" && url.startsWith("http://")) {
       url = url.replace("http://", "https://");
     }
     return url;
   }
   // Função para resolver o ícone do weapon toggle do character-box
   function resolveCharacterWeaponIcon() {
     const root = document.querySelector(".character-box");
     if (!root) return;
     const raw = root.dataset.weaponicon;
     if (!raw || raw.trim() === "") {
       globalWeaponToggleIcon = null;
       return;
     }
     globalWeaponToggleIcon = filePathURL(raw.trim());
     // console.log('[WeaponToggle] Resolved weaponicon:', raw, '->', globalWeaponToggleIcon);
   }
   // Textos i18n para o popup
   const i18nTexts = {
     pt: {
       title: "Visualização com Arma Especial",
       body1:
         "Este modo ativa a visualização do personagem equipado com sua arma especial.",
       body2:
         "Algumas habilidades são diferentes enquanto estão com a arma equipada, essas habilidades ficam destacadas com borda vermelha.",
       dontShow: "Não mostrar novamente",
       ok: "Entendi",
       weaponLink: "Ver página da arma:",
     },
     en: {
       title: "Special Weapon View",
       body1:
         "This mode activates the view of the character equipped with their special weapon.",
       body2:
         "Some abilities are different while equipped with the weapon, these abilities are highlighted with a red border.",
       dontShow: "Don't show again",
       ok: "Got it",
       weaponLink: "View weapon page:",
     },
     es: {
       title: "Visualización con Arma Especial",
       body1:
         "Este modo activa la visualización del personaje equipado con su arma especial.",
       body2:
         "Algunas habilidades son diferentes mientras están con el arma equipada, estas habilidades quedan destacadas con borde rojo.",
       dontShow: "No mostrar de nuevo",
       ok: "Entendido",
       weaponLink: "Ver página del arma:",
     },
     pl: {
       title: "Widok z Bronią Specjalną",
       body1:
         "Ten tryb aktywuje widok postaci wyposażonej w broń specjalną.",
       body2:
         "Niektóre umiejętności różnią się podczas posiadania broni, te umiejętności są podświetlone czerwoną obwódką.",
       dontShow: "Nie pokazuj ponownie",
       ok: "Rozumiem",
       weaponLink: "Zobacz stronę broni:",
     },
   };
   const getCurrentLang = () => {
     const html = document.documentElement.lang || "pt-br";
     const norm = html.toLowerCase().split("-")[0];
     return i18nTexts[norm] ? norm : "pt";
   };
   const bindModalEvents = () => {
     if (modalListenersBound) return;
     modalListenersBound = true;
     document.addEventListener("click", (ev) => {
       if (
         ev.target.closest(".weapon-modal-close") ||
         ev.target.closest(".weapon-modal-btn")
       ) {
         const checkbox = document.getElementById("weapon-dont-show");
         if (checkbox && checkbox.checked) {
           try {
             localStorage.setItem("glaWeaponPopupDismissed", "1");
           } catch (x) { }
         }
         hidePopup();
         return;
       }
       if (ev.target.classList.contains("weapon-modal-overlay")) {
         hidePopup();
       }
     });
   };
   const applyWeaponState = (enabled) => {
     if (typeof window.__setGlobalWeaponEnabled === "function") {
       window.__setGlobalWeaponEnabled(enabled);
     }
     try {
       localStorage.setItem("glaWeaponEnabled", enabled ? "1" : "0");
     } catch (x) { }
     // Dispara evento para atualizar subskills
     window.dispatchEvent(
       new CustomEvent("gla:weaponToggled", { detail: { enabled } })
     );
     // SISTEMA UNIFICADO: Aplica toggle em skills E subskills
     // Skills principais e subskills usam data-weapon (padronizado)
     document
       .querySelectorAll(".skill-icon[data-weapon], .subicon[data-weapon]")
       .forEach((el) => {
         const weaponData = el.getAttribute("data-weapon");
         // Verifica se o weapon não está vazio (não é '{}' ou vazio)
         let hasValidWeapon = false;
         if (weaponData && weaponData.trim() !== "" && weaponData !== "{}") {
           try {
             const weaponObj = JSON.parse(weaponData);
             if (
               weaponObj &&
               typeof weaponObj === "object" &&
               Object.keys(weaponObj).length > 0
             ) {
               hasValidWeapon = true;
             }
           } catch (e) {
             // Se não for JSON válido, não considera como weapon válido
           }
         }
         if (enabled && hasValidWeapon) {
           el.classList.add("has-weapon-available");
         } else {
           el.classList.remove("has-weapon-available");
           el.classList.remove("weapon-equipped");
           const ind = el.querySelector(".weapon-indicator");
           if (ind) ind.remove();
         }
       });
     // Atualiza descrição da skill/subskill selecionada (se houver) para refletir estado da arma
     // Aguarda um pouco mais para garantir que o estado global foi sincronizado
     setTimeout(() => {
       // Atualiza skill principal se houver - força reativação completa incluindo vídeo
       const sel = document.querySelector(
         ".skill-icon.active:not(.weapon-bar-toggle)"
       );
       if (sel) {
         // Força uma reativação completa da skill para garantir que vídeo seja atualizado
         if (
           typeof window.__subskills !== "undefined" &&
           window.__subskills.hideAll
         ) {
           const videoBox =
             document.querySelector(".video-container") ||
             document.querySelector(".skills-video-box");
           if (videoBox) window.__subskills.hideAll(videoBox);
         }
         // Reativa a skill para atualizar vídeo, descrição e atributos
         if (
           typeof window.__lastActiveSkillIcon !== "undefined" &&
           window.__lastActiveSkillIcon === sel
         ) {
           sel.dispatchEvent(new Event("click", { bubbles: true }));
         } else {
           sel.dispatchEvent(new Event("click", { bubbles: true }));
         }
       }
       // Atualiza subskill ativa se houver - força reativação completa incluindo vídeo
       const activeSub = document.querySelector(".subicon.active");
       if (activeSub) {
         activeSub.dispatchEvent(new Event("click", { bubbles: true }));
       }
     }, 100);
   };
   const updateModalTexts = (modal) => {
     const lang = getCurrentLang();
     const t = i18nTexts[lang];
     const title = modal.querySelector(".weapon-modal-header h3");
     if (title) title.textContent = t.title;
     const body = modal.querySelector(".weapon-modal-body");
     if (body) {
       const p1 = body.querySelector("p:first-child");
       const p2 = body.querySelector("p:nth-child(2)");
       if (p1) p1.innerHTML = t.body1;
       if (p2) p2.innerHTML = t.body2;
     }
     const checkbox = modal.querySelector(".weapon-modal-checkbox span");
     if (checkbox) checkbox.textContent = t.dontShow;
     const btn = modal.querySelector(".weapon-modal-btn");
     if (btn) btn.textContent = t.ok;
     // Atualiza link da arma se existir
     try {
       const firstWithWeapon = document.querySelector(
         ".skill-icon[data-weapon]"
       );
       if (firstWithWeapon) {
         const raw = firstWithWeapon.getAttribute("data-weapon");
         const obj = JSON.parse(raw || "{}");
         const nm = obj && obj.name ? String(obj.name).trim() : "";
         if (nm) {
           const linkHost =
             window.mw && mw.util && typeof mw.util.getUrl === "function"
               ? mw.util.getUrl(nm)
               : "/index.php?title=" + encodeURIComponent(nm);
           const holder = modal.querySelector(".weapon-info-link");
           if (holder) {
             holder.style.display = "block";
             holder.innerHTML = `<a href="${linkHost}">${t.weaponLink} ${nm}</a>`;
           }
         }
       }
     } catch (_) { }
   };
   const ensureModal = () => {
     let modal = document.getElementById("weapon-info-modal");
     if (modal) {
       updateModalTexts(modal);
       return modal;
     }
     // Insere dentro da character-box para isolar completamente
     const container =
       document.querySelector(".character-box") ||
       document.querySelector("#mw-content-text") ||
       document.body;
     modal = document.createElement("div");
     modal.id = "weapon-info-modal";
     modal.className = "weapon-modal";
     modal.innerHTML = `

                   <button class="weapon-modal-close" type="button" aria-label="Fechar">×</button>

       `;
     container.appendChild(modal);
     updateModalTexts(modal);
     bindModalEvents();
     return modal;
   };
   const showPopup = () => {
     const modal = ensureModal();
     if (modal) {
       updateModalTexts(modal);
       // Força reflow antes de adicionar classe para garantir transição
       void modal.offsetHeight;
       modal.classList.add("show");
     }
   };
   const hidePopup = () => {
     const m = document.getElementById("weapon-info-modal");
     if (m) m.classList.remove("show");
   };
   window.__applyWeaponState = applyWeaponState;
   window.__glaWeaponShowPopup = showPopup;
   window.__glaWeaponHidePopup = hidePopup;
   try {
     window.dispatchEvent(
       new CustomEvent("weapon:ready", {
         detail: { applyWeaponState, showPopup, hidePopup },
       })
     );
   } catch (err) { }
   // Escuta mudanças de idioma
   window.addEventListener("gla:langChanged", () => {
     const modal = document.getElementById("weapon-info-modal");
     if (modal) updateModalTexts(modal);
   });
   // Função para obter o nome da arma
   function getWeaponName() {
     let weaponName = "Arma Especial";
     try {
       const firstWithWeapon = document.querySelector(
         ".skill-icon[data-weapon]"
       );
       if (firstWithWeapon) {
         const raw = firstWithWeapon.getAttribute("data-weapon");
         const obj = JSON.parse(raw || "{}");
         if (obj && obj.name) {
           weaponName = String(obj.name).trim();
         }
       }
     } catch (e) { }
     return weaponName;
   }
   // Função para criar o novo toggle abaixo do char-translator
   function createWeaponToggle() {
     // Remove toggle antigo se existir
     const oldToggle = document.querySelector(".weapon-bar-toggle");
     if (oldToggle) oldToggle.remove();
     const existingContainer = document.querySelector(
       ".weapon-toggle-container"
     );
     if (existingContainer) return existingContainer;
     const characterHeader = document.querySelector(".character-header");
     if (!characterHeader) return null;
     // Resolve o ícone
     resolveCharacterWeaponIcon();
     const weaponName = getWeaponName();
     // Cria o container do toggle
     const container = document.createElement("div");
     container.className = "weapon-toggle-container";
     container.setAttribute("role", "button");
     container.setAttribute("aria-pressed", "false");
     container.setAttribute("aria-label", weaponName);
     // Cria o sprite (círculo com imagem)
     const sprite = document.createElement("div");
     sprite.className = "weapon-toggle-sprite";
     if (globalWeaponToggleIcon) {
       const img = document.createElement("img");
       img.src = globalWeaponToggleIcon;
       img.alt = weaponName;
       img.className = "weapon-toggle-icon";
       img.decoding = "async";
       img.loading = "eager"; // Ícone do toggle é crítico - carrega imediatamente
       img.onerror = function () {
         // console.error('[WeaponToggle] Erro ao carregar imagem:', globalWeaponToggleIcon);
       };
       img.onload = function () {
         // console.log('[WeaponToggle] Imagem carregada com sucesso:', globalWeaponToggleIcon);
       };
       sprite.appendChild(img);
     }
     // Cria a barra com texto
     const bar = document.createElement("div");
     bar.className = "weapon-toggle-bar";
     const nameSpan = document.createElement("span");
     nameSpan.className = "weapon-toggle-name";
     nameSpan.setAttribute("data-lang", getCurrentLang());
     bar.appendChild(nameSpan);
     container.appendChild(sprite);
     container.appendChild(bar);
     // Adiciona evento de clique
     container.addEventListener("click", () => {
       let currentState = false;
       try {
         currentState = localStorage.getItem("glaWeaponEnabled") === "1";
       } catch (e) { }
       const nextState = !currentState;
       if (nextState) {
         // Verifica se o popup foi dispensado antes de mostrar
         let shouldShowPopup = true;
         try {
           if (localStorage.getItem("glaWeaponPopupDismissed") === "1") {
             shouldShowPopup = false;
           }
         } catch (e) { }
         if (
           shouldShowPopup &&
           typeof window.__glaWeaponShowPopup === "function"
         ) {
           window.__glaWeaponShowPopup();
         }
       }
       if (typeof window.__applyWeaponState === "function") {
         window.__applyWeaponState(nextState);
       }
     });
     // Insere no container de controles (character-header-controls)
     const controlsContainer = document.querySelector(
       ".character-header-controls"
     );
     if (controlsContainer) {
       controlsContainer.appendChild(container);
     } else {
       // Fallback: insere no character-header se o container não existir
       characterHeader.appendChild(container);
     }
     // Atualiza estado visual inicial
     updateToggleVisualState();
     return container;
   }
   // Função para atualizar o estado visual do toggle
   function updateToggleVisualState() {
     const container = document.querySelector(".weapon-toggle-container");
     if (!container) return;
     let isEnabled = false;
     try {
       isEnabled = localStorage.getItem("glaWeaponEnabled") === "1";
     } catch (e) { }
     if (isEnabled) {
       container.classList.add("weapon-active");
       container.setAttribute("aria-pressed", "true");
     } else {
       container.classList.remove("weapon-active");
       container.setAttribute("aria-pressed", "false");
     }
     // Atualiza idioma do texto
     const nameSpan = container.querySelector(".weapon-toggle-name");
     if (nameSpan) {
       nameSpan.setAttribute("data-lang", getCurrentLang());
     }
   }
   // Observa quando o container de controles é criado para posicionar o toggle
   function observeCharacterHeader() {
     const controlsContainer = document.querySelector(
       ".character-header-controls"
     );
     const characterHeader = document.querySelector(".character-header");
     if (controlsContainer) {
       // Container existe - cria o toggle imediatamente
       createWeaponToggle();
     } else if (characterHeader) {
       // Header existe mas container não - cria o container e depois o toggle
       const newContainer = document.createElement("div");
       newContainer.className = "character-header-controls";
       characterHeader.appendChild(newContainer);
       // Aguarda um frame para garantir que o container foi adicionado
       requestAnimationFrame(() => {
         createWeaponToggle();
       });
     } else {
       // Nada existe ainda - tenta novamente após um delay
       setTimeout(observeCharacterHeader, 100);
     }
   }
   // Observa mudanças no DOM para detectar quando o container de controles é criado
   function observeDOMForHeader() {
     const observer = new MutationObserver((mutations) => {
       mutations.forEach((mutation) => {
         mutation.addedNodes.forEach((node) => {
           if (node.nodeType === 1) {
             if (
               node.classList &&
               (node.classList.contains("character-header-controls") ||
                 node.classList.contains("character-header"))
             ) {
               setTimeout(() => createWeaponToggle(), 10);
             } else if (
               node.querySelector &&
               (node.querySelector(".character-header-controls") ||
                 node.querySelector(".character-header"))
             ) {
               setTimeout(() => createWeaponToggle(), 10);
             }
           }
         });
       });
     });
     observer.observe(document.body, { childList: true, subtree: true });
   }
   const boot = () => {
     // Resolve o ícone do character antes de tudo
     resolveCharacterWeaponIcon();
     // Verificar se existe alguma skill ou subskill com arma
     function checkHasAnyWeapon() {
       // PRIORIDADE 1: Verifica se há weaponicon global no character-box
       const characterBox = document.querySelector(".character-box");
       if (characterBox && characterBox.dataset.weaponicon) {
         const weaponIcon = characterBox.dataset.weaponicon.trim();
         if (weaponIcon && weaponIcon !== "") {
           return true;
         }
       }
       // PRIORIDADE 2: Verifica skills principais
       const mainSkills = document.querySelectorAll(
         ".skill-icon[data-weapon]"
       );
       for (const el of mainSkills) {
         const weapon = el.dataset.weapon;
         if (weapon && weapon.trim() !== "" && weapon !== "{}") {
           try {
             const weaponObj = JSON.parse(weapon);
             if (
               weaponObj &&
               typeof weaponObj === "object" &&
               Object.keys(weaponObj).length > 0
             ) {
               return true;
             }
           } catch (e) {
             // Se não for JSON válido mas não está vazio, considera válido
             return true;
           }
         }
       }
       // PRIORIDADE 3: Verifica weaponicon em skills principais
       const skillsWithWeaponIcon = document.querySelectorAll(
         ".skill-icon[data-weaponicon]"
       );
       for (const el of skillsWithWeaponIcon) {
         const weaponIcon = el.dataset.weaponicon;
         if (weaponIcon && weaponIcon.trim() !== "") {
           return true;
         }
       }
       // PRIORIDADE 4: Verifica subskills
       const skillIcons = document.querySelectorAll(".skill-icon[data-subs]");
       for (const el of skillIcons) {
         try {
           const subs = JSON.parse(el.getAttribute("data-subs") || "[]");
           if (
             Array.isArray(subs) &&
             subs.some(
               (s) =>
                 s &&
                 s.weapon &&
                 typeof s.weapon === "object" &&
                 Object.keys(s.weapon).length > 0
             )
           ) {
             return true;
           }
         } catch (e) { }
       }
       return false;
     }
     const hasAnyWeapon = checkHasAnyWeapon();
     if (!hasAnyWeapon) {
       // Limpar estado visual para chars sem arma (previne cache entre páginas)
       const topRail = document.querySelector(".top-rail.skills");
       if (topRail) {
         topRail.classList.remove("weapon-mode-on");
       }
       document
         .querySelectorAll(".skill-icon.has-weapon-available")
         .forEach((el) => {
           el.classList.remove("has-weapon-available");
           el.classList.remove("weapon-equipped");
           const ind = el.querySelector(".weapon-indicator");
           if (ind) ind.remove();
         });
       // Remover toggle se existir
       const toggleContainer = document.querySelector(
         ".weapon-toggle-container"
       );
       if (toggleContainer) toggleContainer.remove();
       // Atualizar estado global para desligado
       if (typeof window.__setGlobalWeaponEnabled === "function") {
         window.__setGlobalWeaponEnabled(false);
       }
       return;
     }
     ensureModal();
     // Cria o novo toggle - tenta múltiplas vezes para garantir
     observeCharacterHeader();
     observeDOMForHeader();
     // Tenta criar novamente após um delay maior para garantir que o translator já criou o container
     setTimeout(() => {
       const existing = document.querySelector(".weapon-toggle-container");
       if (!existing) {
         observeCharacterHeader();
       }
     }, 500);
     // Última tentativa após 1 segundo
     setTimeout(() => {
       const existing = document.querySelector(".weapon-toggle-container");
       if (!existing) {
         observeCharacterHeader();
       }
     }, 1000);
     // Remove qualquer toggle antigo que apareça nas barras de skills/subskills
     function removeOldToggles() {
       document.querySelectorAll(".weapon-bar-toggle").forEach((toggle) => {
         toggle.remove();
       });
     }
     // Observa mudanças nas barras de ícones para remover toggles antigos
     const iconBarObserver = new MutationObserver(() => {
       removeOldToggles();
     });
     // Observa todas as barras de ícones existentes e futuras
     const observeAllIconBars = () => {
       document.querySelectorAll(".icon-bar").forEach((bar) => {
         iconBarObserver.observe(bar, { childList: true, subtree: true });
       });
     };
     // Remove toggles antigos imediatamente
     removeOldToggles();
     // Observa barras existentes
     observeAllIconBars();
     // Observa criação de novas barras
     const bodyObserver = new MutationObserver((mutations) => {
       mutations.forEach((mutation) => {
         mutation.addedNodes.forEach((node) => {
           if (node.nodeType === 1) {
             if (node.classList && node.classList.contains("icon-bar")) {
               iconBarObserver.observe(node, {
                 childList: true,
                 subtree: true,
               });
               removeOldToggles();
             } else if (
               node.querySelector &&
               node.querySelector(".icon-bar")
             ) {
               observeAllIconBars();
               removeOldToggles();
             }
           }
         });
       });
     });
     bodyObserver.observe(document.body, { childList: true, subtree: true });
     // Escuta mudanças no estado do weapon para atualizar visual
     window.addEventListener("gla:weaponToggled", () => {
       setTimeout(updateToggleVisualState, 50);
     });
     // Escuta mudanças de idioma
     window.addEventListener("gla:langChanged", () => {
       updateToggleVisualState();
     });
     // Estado inicial do toggle
     let init = false;
     try {
       if (localStorage.getItem("glaWeaponEnabled") === "1") init = true;
     } catch (x) { }
     setTimeout(() => {
       applyWeaponState(init);
       updateToggleVisualState();
     }, 150);
   };
   if (document.readyState === "loading") {
     document.addEventListener("DOMContentLoaded", boot);
   } else {
     boot();
   }
 })();

</script> <style>

 /* Character-box precisa de position relative para conter o modal */
 .character-box {
   position: relative;
 }
 /* Modal posicionado dentro da character-box */
 .weapon-modal {
   position: absolute;
   inset: 0;
   z-index: 100;
   display: flex;
   align-items: center;
   justify-content: center;
   pointer-events: none;
 }
 .weapon-modal.show {
   pointer-events: all;
 }
 /* Overlay escurece apenas a character-box - aparece PRIMEIRO */
 .weapon-modal-overlay {
   position: absolute;
   inset: 0;
   background: rgba(0, 0, 0, 0.65);
   -webkit-backdrop-filter: blur(4px);
   backdrop-filter: blur(4px);
   opacity: 0;
   transition: opacity 0.15s ease;
 }
 .weapon-modal.show .weapon-modal-overlay {
   opacity: 1;
 }
 /* Conteúdo aparece DEPOIS do overlay */
 .weapon-modal-content {
   position: relative;
   z-index: 1;
   transform: scale(0.96);
   background: linear-gradient(145deg, #2d1a1a, #1e1212);
   border: 1px solid rgba(255, 100, 100, 0.2);
   border-radius: 14px;
   max-width: 420px;
   width: 90%;
   opacity: 0;
   transition: transform 0.18s ease 0.08s, opacity 0.15s ease 0.08s;
   overflow: hidden;
 }
 .weapon-modal.show .weapon-modal-content {
   transform: scale(1);
   opacity: 1;
 }
 .weapon-modal-header {
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 16px 20px;
   border-bottom: 1px solid rgba(255, 100, 100, 0.12);
   background: linear-gradient(90deg, rgba(255, 80, 80, 0.06), transparent);
 }
 .weapon-modal-header h3 {
   margin: 0;
   font-size: 16px;
   font-weight: 600;
   color: #fff;
 }
 .weapon-modal-close {
   background: transparent;
   border: 1px solid rgba(255, 255, 255, 0.1);
   color: rgba(255, 255, 255, 0.5);
   font-size: 18px;
   font-family: Arial, sans-serif;
   line-height: 1;
   cursor: pointer;
   padding: 0;
   width: 28px;
   height: 28px;
   display: inline-flex;
   align-items: center;
   justify-content: center;
   text-align: center;
   border-radius: 6px;
   transition: background 0.15s, color 0.15s, border-color 0.15s;
 }
 .weapon-modal-close:hover {
   background: rgba(255, 80, 80, 0.15);
   border-color: rgba(255, 80, 80, 0.3);
   color: #ff7043;
 }
 .weapon-modal-body {
   padding: 20px;
   color: rgba(255, 255, 255, 0.85);
   line-height: 1.65;
   font-size: 14px;
 }
 .weapon-modal-body p {
   margin: 0 0 12px;
   display: block !important;
 }
 .weapon-modal-body p:last-child,
 .weapon-modal-body p.weapon-info-link {
   margin: 0;
 }
 .weapon-modal-body p.weapon-info-link:empty {
   display: none !important;
 }
 .weapon-modal-body strong {
   color: #ff7043;
   font-weight: 600;
 }
 .weapon-modal-body .weapon-info-link a {
   color: #ff7043;
   text-decoration: none;
   font-weight: 600;
 }
 .weapon-modal-body .weapon-info-link a:hover {
   text-decoration: underline;
 }
 .weapon-modal-footer {
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 14px 20px;
   border-top: 1px solid rgba(255, 100, 100, 0.1);
   background: rgba(0, 0, 0, 0.1);
   gap: 12px;
 }
 .weapon-modal-checkbox {
   display: inline-flex;
   align-items: center;
   gap: 8px;
   font-size: 12px;
   line-height: 1.2;
   color: rgba(255, 255, 255, 0.5);
   cursor: pointer;
   transition: color 0.15s;
 }
 .weapon-modal-checkbox:hover {
   color: rgba(255, 255, 255, 0.75);
 }
 .weapon-modal-checkbox input[type="checkbox"] {
   accent-color: #ff5722;
   margin: 0;
   width: 14px;
   height: 14px;
   flex-shrink: 0;
   transform: translateY(1px);
 }
 .weapon-modal-checkbox span {
   line-height: 1.2;
 }
 .weapon-modal-btn {
   background: #bf360c;
   border: none;
   color: #fff;
   padding: 10px 24px;
   border-radius: 6px;
   font-weight: 600;
   font-size: 13px;
   line-height: 1;
   cursor: pointer;
   transition: background 0.15s;
   display: inline-flex;
   align-items: center;
   justify-content: center;
 }
 .weapon-modal-btn:hover {
   background: #d84315;
 }
 .weapon-modal-btn:active {
   background: #a52714;
 }
 @media (max-width: 600px) {
   .weapon-modal-content {
     width: 92%;
     max-width: none;
   }
   .weapon-modal-header,
   .weapon-modal-body,
   .weapon-modal-footer {
     padding: 14px 16px;
   }
   .weapon-modal-footer {
     flex-direction: column;
     gap: 12px;
   }
   .weapon-modal-btn {
     width: 100%;
   }
 }
 /* =========================== NOVO WEAPON TOGGLE =========================== */
 .weapon-toggle-container {
   display: flex;
   align-items: center;
   z-index: 10;
   background: transparent;
   padding: 0;
   border-radius: 0;
   border: none;
   box-shadow: none;
   cursor: pointer;
   transition: transform 0.08s ease;
   overflow: visible;
   height: 44px;
   box-sizing: border-box;
 }
 .weapon-toggle-container:hover {
   transform: translateY(-1px);
 }
 .weapon-toggle-sprite {
   width: 44px;
   height: 44px;
   flex-shrink: 0;
   border-radius: 50%;
   overflow: visible;
   position: relative;
   background: rgb(40, 40, 48);
   border: 2px solid rgba(255, 255, 255, 0.15);
   display: flex;
   align-items: center;
   justify-content: center;
   z-index: 2;
   margin: 0;
   padding: 0;
   box-sizing: border-box;
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
   transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
     border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
     box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
   will-change: background-color;
 }
 .weapon-toggle-sprite img {
   width: 64px;
   height: 64px;
   display: block;
   /* Força redimensionamento pixelado (nearest neighbor) - ordem importante */
   -ms-interpolation-mode: nearest-neighbor;
   /* IE/Edge antigo - deve vir primeiro */
   image-rendering: -moz-crisp-edges;
   /* Firefox */
   image-rendering: -webkit-optimize-contrast;
   /* Safari/Chrome antigo */
   image-rendering: pixelated;
   /* Chrome/Edge moderno */
   image-rendering: crisp-edges !important;
   /* Fallback padrão - força sem suavização */
   /* Garante que não há suavização por transform ou filter */
   transform: translateZ(0);
   backface-visibility: hidden;
   /* Mantém proporção sem suavização */
   object-fit: contain;
   object-position: center;
   /* Força renderização sem suavização - importante para sprites pixelados */
   -webkit-font-smoothing: none;
   font-smoothing: none;
 }
 .weapon-toggle-bar {
   background: rgb(40, 40, 48);
   padding: 5px 14px 5px 28px;
   border-radius: 0 7px 7px 0;
   border: 2px solid rgba(255, 255, 255, 0.15);
   border-left: none;
   display: flex;
   align-items: center;
   width: 180px;
   position: relative;
   overflow: hidden;
   margin: 0;
   margin-left: -22px;
   height: 34px;
   box-sizing: border-box;
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
   transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
     background-image 0.15s cubic-bezier(0.4, 0, 0.2, 1),
     border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1);
   will-change: background-color, background-image;
 }
 .weapon-toggle-name {
   color: #fff;
   font-size: 14px;
   font-weight: 600;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
   position: relative;
   z-index: 2;
   letter-spacing: 0.3px;
   display: inline-block;
 }
 /* Textos i18n - usando ::after para mostrar o texto baseado no data-lang e estado */
 .weapon-toggle-name::after {
   content: "Equipar Arma";
   /* Default PT */
 }
 .weapon-toggle-name[data-lang="pt"]::after {
   content: "Equipar Arma";
 }
 .weapon-toggle-name[data-lang="en"]::after {
   content: "Equip Weapon";
 }
 .weapon-toggle-name[data-lang="es"]::after {
   content: "Equipar Arma";
 }
 .weapon-toggle-name[data-lang="pl"]::after {
   content: "Wyposaż Broń";
 }
 /* Estado ATIVO (arma equipada) - muda o texto */
 .weapon-toggle-container.weapon-active .weapon-toggle-name::after {
   content: "Desequipar Arma";
   /* Default PT */
 }
 .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pt"]::after {
   content: "Desequipar Arma";
 }
 .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="en"]::after {
   content: "Unequip Weapon";
 }
 .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="es"]::after {
   content: "Desequipar Arma";
 }
 .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pl"]::after {
   content: "Zdjęć Broń";
 }
 /* Estado ativo - destaque vermelho */
 .weapon-toggle-container.weapon-active .weapon-toggle-sprite {
   background-color: rgb(200, 60, 40) !important;
   border: 2px solid rgba(255, 255, 255, 0.15);
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
 }
 .weapon-toggle-container.weapon-active .weapon-toggle-bar {
   background-color: rgb(200, 60, 40);
   background-image: linear-gradient(135deg,
       rgb(200, 60, 40),
       rgb(160, 45, 30));
   border-color: rgba(255, 87, 34, 0.3);
   border-left: none;
   border-radius: 0 7px 7px 0;
 }
 .weapon-toggle-container.weapon-active .weapon-toggle-name {
   color: #fff;
   text-shadow: 0 0 4px rgba(255, 87, 34, 0.5);
 }

</style>