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

De Wiki Gla
Ir para navegação Ir para pesquisar
m
m
 
(Uma revisão intermediária pelo mesmo usuário não está sendo mostrada)
Linha 1: Linha 1:
<!-- SKINS SYSTEM - Layout Isométrico -->
<!-- SKINS SYSTEM - Layout Isométrico -->
<script>
<script>
    (function initSkinsPodiumUI() {
  (function initSkinsPodiumUI() {
        const podium = document.querySelector('.skins-podium');
    const podium = document.querySelector(".skins-podium");
        if (!podium || podium.dataset.wired === '1') return;
    if (!podium || podium.dataset.wired === "1") return;
        podium.dataset.wired = '1';
    podium.dataset.wired = "1";


        // ---------- Função para aplicar offset_x individualmente em cada skin ----------
    // ---------- Função para aplicar offset_x individualmente em cada skin ----------
        // IMPORTANTE: Usa margin-left em vez de transform para afetar o layout do flexbox
    // IMPORTANTE: Usa margin-left em vez de transform para afetar o layout do flexbox
        function applyOffsetX() {
    function applyOffsetX() {
            const allSlots = podium.querySelectorAll('.podium-slot');
      const allSlots = podium.querySelectorAll(".podium-slot");
            allSlots.forEach((slot, index) => {
      allSlots.forEach((slot, index) => {
                // Lê o atributo data-offset-x diretamente do elemento
        // Lê o atributo data-offset-x diretamente do elemento
                const offsetXAttr = slot.getAttribute('data-offset-x');
        const offsetXAttr = slot.getAttribute("data-offset-x");


                if (offsetXAttr !== null && offsetXAttr !== '' && offsetXAttr !== 'undefined') {
        if (
                    const numOffset = parseFloat(offsetXAttr);
          offsetXAttr !== null &&
                    if (!isNaN(numOffset) && numOffset !== 0) {
          offsetXAttr !== "" &&
                        // Usa margin-left negativo para afetar o layout do flexbox
          offsetXAttr !== "undefined"
                        // Isso faz com que o elemento realmente se aproxime dos outros
        ) {
                        const currentStyle = slot.getAttribute('style') || '';
          const numOffset = parseFloat(offsetXAttr);
                        // Remove qualquer margin-left anterior e transform (legado)
          if (!isNaN(numOffset) && numOffset !== 0) {
                        const cleanedStyle = currentStyle
            // Usa margin-left negativo para afetar o layout do flexbox
                            .replace(/margin-left\s*:[^;]+;?/gi, '')
            // Isso faz com que o elemento realmente se aproxime dos outros
                            .replace(/transform\s*:[^;]+;?/gi, '')
            const currentStyle = slot.getAttribute("style") || "";
                            .trim();
            // Remove qualquer margin-left anterior e transform (legado)
                        // Aplica o margin-left preservando outros estilos (como z-index)
            const cleanedStyle = currentStyle
                        const newMargin = `margin-left: ${numOffset}px`;
              .replace(/margin-left\s*:[^;]+;?/gi, "")
                        if (cleanedStyle && cleanedStyle.length > 0) {
              .replace(/transform\s*:[^;]+;?/gi, "")
                            slot.setAttribute('style', cleanedStyle + (cleanedStyle.endsWith(';') ? ' ' : '; ') + newMargin + ';');
              .trim();
                        } else {
            // Aplica o margin-left preservando outros estilos (como z-index)
                            slot.setAttribute('style', newMargin + ';');
            const newMargin = `margin-left: ${numOffset}px`;
                        }
            if (cleanedStyle && cleanedStyle.length > 0) {
                        // Força a atualização do layout
              slot.setAttribute(
                        slot.offsetHeight;
                "style",
                    } else {
                cleanedStyle +
                        // Se o offset for 0 ou inválido, remove margin-left e transform
                (cleanedStyle.endsWith(";") ? " " : "; ") +
                        const currentStyle = slot.getAttribute('style') || '';
                newMargin +
                        const cleanedStyle = currentStyle
                ";"
                            .replace(/margin-left\s*:[^;]+;?/gi, '')
              );
                            .replace(/transform\s*:[^;]+;?/gi, '')
            } else {
                            .trim();
              slot.setAttribute("style", newMargin + ";");
                        if (cleanedStyle) {
            }
                            slot.setAttribute('style', cleanedStyle + (cleanedStyle.endsWith(';') ? '' : ';'));
            // Força a atualização do layout
                        } else {
            slot.offsetHeight;
                            slot.removeAttribute('style');
          } else {
                        }
            // Se o offset for 0 ou inválido, remove margin-left e transform
                    }
            const currentStyle = slot.getAttribute("style") || "";
                } else {
            const cleanedStyle = currentStyle
                    // Se não tem offset_x, remove margin-left e transform (preserva outros estilos)
              .replace(/margin-left\s*:[^;]+;?/gi, "")
                    const currentStyle = slot.getAttribute('style') || '';
              .replace(/transform\s*:[^;]+;?/gi, "")
                    const cleanedStyle = currentStyle
              .trim();
                        .replace(/margin-left\s*:[^;]+;?/gi, '')
            if (cleanedStyle) {
                        .replace(/transform\s*:[^;]+;?/gi, '')
              slot.setAttribute(
                        .trim();
                "style",
                    if (cleanedStyle) {
                cleanedStyle + (cleanedStyle.endsWith(";") ? "" : ";")
                        slot.setAttribute('style', cleanedStyle + (cleanedStyle.endsWith(';') ? '' : ';'));
              );
                    } else {
            } else {
                        slot.removeAttribute('style');
              slot.removeAttribute("style");
                    }
            }
                }
          }
            });
        } else {
          // Se não tem offset_x, remove margin-left e transform (preserva outros estilos)
          const currentStyle = slot.getAttribute("style") || "";
          const cleanedStyle = currentStyle
            .replace(/margin-left\s*:[^;]+;?/gi, "")
            .replace(/transform\s*:[^;]+;?/gi, "")
            .trim();
          if (cleanedStyle) {
            slot.setAttribute(
              "style",
              cleanedStyle + (cleanedStyle.endsWith(";") ? "" : ";")
            );
          } else {
            slot.removeAttribute("style");
          }
         }
         }
      });
    }


        // Flag para evitar múltiplas execuções simultâneas
    // Flag para evitar múltiplas execuções simultâneas
        let isApplying = false;
    let isApplying = false;


        function applyOffsetXOnce() {
    function applyOffsetXOnce() {
            if (isApplying) return;
      if (isApplying) return;
            isApplying = true;
      isApplying = true;
            applyOffsetX();
      applyOffsetX();
            requestAnimationFrame(() => {
      requestAnimationFrame(() => {
                isApplying = false;
        isApplying = false;
            });
      });
        }
    }


        // Aplica usando requestAnimationFrame para garantir que o DOM esteja renderizado
    // Aplica usando requestAnimationFrame para garantir que o DOM esteja renderizado
        requestAnimationFrame(() => {
    requestAnimationFrame(() => {
            applyOffsetXOnce();
      applyOffsetXOnce();
            // Reaplica após pequenos delays para garantir
      // Reaplica após pequenos delays para garantir
            setTimeout(applyOffsetXOnce, 50);
      setTimeout(applyOffsetXOnce, 50);
            setTimeout(applyOffsetXOnce, 200);
      setTimeout(applyOffsetXOnce, 200);
        });
    });


        // Também aplica quando o DOM estiver pronto
    // Também aplica quando o DOM estiver pronto
        if (document.readyState === 'loading') {
    if (document.readyState === "loading") {
            document.addEventListener('DOMContentLoaded', () => {
      document.addEventListener("DOMContentLoaded", () => {
                requestAnimationFrame(applyOffsetXOnce);
        requestAnimationFrame(applyOffsetXOnce);
             });
      });
    }
 
    // Observa mudanças no DOM para reaplicar se necessário (apenas para novos elementos)
    if (window.MutationObserver) {
      const observer = new MutationObserver((mutations) => {
        // Só reaplica se houver mudanças relevantes
        const hasRelevantChanges = mutations.some(
          (m) =>
             m.type === "childList" ||
            (m.type === "attributes" &&
              (m.attributeName === "data-offset-x" ||
                m.attributeName === "style"))
        );
        if (hasRelevantChanges) {
          clearTimeout(observer.timeout);
          observer.timeout = setTimeout(applyOffsetXOnce, 50);
         }
         }
      });
      observer.observe(podium, {
        childList: true,
        subtree: false, // Apenas observa filhos diretos
        attributes: true,
        attributeFilter: ["data-offset-x"],
      });
    }


        // Observa mudanças no DOM para reaplicar se necessário (apenas para novos elementos)
    // ---------- Tooltip único ----------
        if (window.MutationObserver) {
    function ensureTip() {
            const observer = new MutationObserver((mutations) => {
      let tip = document.querySelector(".skin-tooltip");
                // Só reaplica se houver mudanças relevantes
      if (!tip) {
                const hasRelevantChanges = mutations.some(m =>
        tip = document.createElement("div");
                    m.type === 'childList' ||
        tip.className = "skin-tooltip";
                    (m.type === 'attributes' && (m.attributeName === 'data-offset-x' || m.attributeName === 'style'))
        tip.setAttribute("role", "tooltip");
                );
        tip.setAttribute("aria-hidden", "true");
                if (hasRelevantChanges) {
        tip.style.position = "fixed";
                    clearTimeout(observer.timeout);
        tip.style.transform = "translate(-9999px,-9999px)";
                    observer.timeout = setTimeout(applyOffsetXOnce, 50);
        tip.style.opacity = "0";
                }
        tip.style.transition = "opacity .15s ease";
            });
        document.body.appendChild(tip);
            observer.observe(podium, {
      }
                childList: true,
      return tip;
                subtree: false, // Apenas observa filhos diretos
    }
                attributes: true,
                attributeFilter: ['data-offset-x']
            });
        }


        // ---------- Tooltip único ----------
    const tip = ensureTip();
        function ensureTip() {
    let hoveredSlot = null;
            let tip = document.querySelector('.skin-tooltip');
            if (!tip) {
                tip = document.createElement('div');
                tip.className = 'skin-tooltip';
                tip.setAttribute('role', 'tooltip');
                tip.setAttribute('aria-hidden', 'true');
                tip.style.position = 'fixed';
                tip.style.transform = 'translate(-9999px,-9999px)';
                tip.style.opacity = '0';
                tip.style.transition = 'opacity .15s ease';
                document.body.appendChild(tip);
            }
            return tip;
        }


        const tip = ensureTip();
    function place(card) {
        let hoveredSlot = null;
      if (!card || tip.getAttribute("aria-hidden") === "true") return;


        function place(card) {
      // Calcula nova posição - tooltip centralizada em relação à imagem do piso
            if (!card || tip.getAttribute('aria-hidden') === 'true') return;
      tip.style.transform = "translate(-9999px,-9999px)";
      const tr = tip.getBoundingClientRect();


            // Calcula nova posição - tooltip centralizada em relação à imagem do piso
      // Pega a posição da imagem do tile (piso) para centralizar
            tip.style.transform = 'translate(-9999px,-9999px)';
      const platformImg = card.querySelector(".podium-platform-top img");
            const tr = tip.getBoundingClientRect();
      let platformRect = card.getBoundingClientRect(); // Fallback para o card se não encontrar
      if (platformImg) {
        platformRect = platformImg.getBoundingClientRect();
      } else {
        // Se não encontrar a img, tenta o container do tile
        const platform = card.querySelector(".podium-platform");
        if (platform) {
          platformRect = platform.getBoundingClientRect();
        }
      }


            // Pega a posição da imagem do tile (piso) para centralizar
      // Centraliza horizontalmente baseado na imagem do tile
            const platformImg = card.querySelector('.podium-platform-top img');
      let leftPos = Math.round(
            let platformRect = card.getBoundingClientRect(); // Fallback para o card se não encontrar
        platformRect.left + (platformRect.width - tr.width) / 2
            if (platformImg) {
      );
                platformRect = platformImg.getBoundingClientRect();
      leftPos = Math.max(
            } else {
        8,
                // Se não encontrar a img, tenta o container do tile
        Math.min(leftPos, window.innerWidth - tr.width - 8)
                const platform = card.querySelector('.podium-platform');
      );
                if (platform) {
                    platformRect = platform.getBoundingClientRect();
                }
            }


            // Centraliza horizontalmente baseado na imagem do tile
      // Posiciona logo abaixo da imagem do tile, com pequeno espaçamento
            let leftPos = Math.round(platformRect.left + (platformRect.width - tr.width) / 2);
      let top = Math.round(platformRect.bottom + 15);
            leftPos = Math.max(8, Math.min(leftPos, window.innerWidth - tr.width - 8));


            // Posiciona logo abaixo da imagem do tile, com pequeno espaçamento
      // Se não couber embaixo, coloca em cima
            let top = Math.round(platformRect.bottom + 15);
      if (top + tr.height > window.innerHeight - 8) {
        top = Math.round(platformRect.top - tr.height - 15);
        if (top < 8) top = 8; // Fallback se não couber em cima também
      }


            // Se não couber embaixo, coloca em cima
      tip.style.transform = `translate(${leftPos}px, ${top}px)`;
            if (top + tr.height > window.innerHeight - 8) {
    }
                top = Math.round(platformRect.top - tr.height - 15);
                if (top < 8) top = 8; // Fallback se não couber em cima também
            }


            tip.style.transform = `translate(${leftPos}px, ${top}px)`;
    function show(card) {
        }
      const tooltipText = card.getAttribute("data-skin-tooltip") || "";
      tip.innerHTML = tooltipText;
      tip.setAttribute("aria-hidden", "false");
      place(card);
      tip.style.opacity = "1";
    }


        function show(card) {
    function hide() {
            const tooltipText = card.getAttribute('data-skin-tooltip') || '';
      tip.setAttribute("aria-hidden", "true");
            tip.innerHTML = tooltipText;
      tip.style.opacity = "0";
            tip.setAttribute('aria-hidden', 'false');
      tip.style.transform = "translate(-9999px,-9999px)";
            place(card);
    }
            tip.style.opacity = '1';
        }


        function hide() {
    // Função para restaurar z-index original baseado na posição do slot
            tip.setAttribute('aria-hidden', 'true');
    function restoreOriginalZIndex(slot) {
            tip.style.opacity = '0';
      if (!slot) return;
            tip.style.transform = 'translate(-9999px,-9999px)';
        }


        // Função para restaurar z-index original baseado na posição do slot
      // Determina a posição do slot (1, 2, 3, 4, etc)
        function restoreOriginalZIndex(slot) {
      const allSlots = Array.from(podium.querySelectorAll(".podium-slot"));
            if (!slot) return;
      const slotIndex = allSlots.indexOf(slot);


            // Determina a posição do slot (1, 2, 3, 4, etc)
      // Z-index: esquerda (0) = menor, direita (último) = maior (direita passa na frente)
            const allSlots = Array.from(podium.querySelectorAll('.podium-slot'));
      const originalZIndex = slotIndex + 1;
            const slotIndex = allSlots.indexOf(slot);
      const originalSpriteZIndex = (slotIndex + 1) * 10;


            // Z-index: esquerda (0) = menor, direita (último) = maior (direita passa na frente)
      slot.style.zIndex = originalZIndex.toString();
            const originalZIndex = slotIndex + 1;
      const spriteContainer = slot.querySelector(".podium-sprite-container");
            const originalSpriteZIndex = (slotIndex + 1) * 10;
      if (spriteContainer)
        spriteContainer.style.zIndex = originalSpriteZIndex.toString();


            slot.style.zIndex = originalZIndex.toString();
      // CRÍTICO: Garante que TODOS os tiles sempre fiquem atrás de TODAS as sprites
            const spriteContainer = slot.querySelector('.podium-sprite-container');
      // Força z-index negativo nos tiles de todos os slots
            if (spriteContainer) spriteContainer.style.zIndex = originalSpriteZIndex.toString();
      const platform = slot.querySelector(".podium-platform");
      const platformTop = slot.querySelector(".podium-platform-top");
      const platformImg = slot.querySelector(".podium-platform-top img");
      if (platform) platform.style.zIndex = "-1";
      if (platformTop) platformTop.style.zIndex = "-2";
      if (platformImg) platformImg.style.zIndex = "-2";
    }


            // CRÍTICO: Garante que TODOS os tiles sempre fiquem atrás de TODAS as sprites
    function setHovered(card) {
            // Força z-index negativo nos tiles de todos os slots
      if (hoveredSlot === card) {
            const platform = slot.querySelector('.podium-platform');
        // Se já está hovered, não reposiciona - mantém posição fixa
            const platformTop = slot.querySelector('.podium-platform-top');
        return;
            const platformImg = slot.querySelector('.podium-platform-top img');
      }
            if (platform) platform.style.zIndex = '-1';
            if (platformTop) platformTop.style.zIndex = '-2';
            if (platformImg) platformImg.style.zIndex = '-2';
        }


         function setHovered(card) {
      // Remove hover anterior e restaura z-index original
            if (hoveredSlot === card) {
      if (hoveredSlot) {
                // Se já está hovered, não reposiciona - mantém posição fixa
         hoveredSlot.classList.remove("hovered");
                return;
        restoreOriginalZIndex(hoveredSlot);
            }
        // Garante que tiles continuem atrás após restaurar z-index
        forceTilesBehind();
      }


            // Remove hover anterior e restaura z-index original
      podium.classList.remove("hovering");
            if (hoveredSlot) {
      podium
                hoveredSlot.classList.remove('hovered');
        .querySelectorAll(".podium-slot.dim")
                restoreOriginalZIndex(hoveredSlot);
        .forEach((n) => n.classList.remove("dim"));
                // Garante que tiles continuem atrás após restaurar z-index
                forceTilesBehind();
            }


            podium.classList.remove('hovering');
      if (!card) {
            podium.querySelectorAll('.podium-slot.dim').forEach(n => n.classList.remove('dim'));
        hoveredSlot = null;
        hide();
        return;
      }


            if (!card) {
      hoveredSlot = card;
                hoveredSlot = null;
      hoveredSlot.classList.add("hovered");
                hide();
      podium.classList.add("hovering");
                return;
      podium.querySelectorAll(".podium-slot").forEach((n) => {
            }
        if (n !== hoveredSlot) n.classList.add("dim");
      });


            hoveredSlot = card;
      // Qualquer skin com hover fica acima de tudo
            hoveredSlot.classList.add('hovered');
      card.style.zIndex = "9999";
            podium.classList.add('hovering');
      const spriteContainer = card.querySelector(".podium-sprite-container");
            podium.querySelectorAll('.podium-slot').forEach(n => { if (n !== hoveredSlot) n.classList.add('dim'); });
      if (spriteContainer) spriteContainer.style.zIndex = "9999";


            // Qualquer skin com hover fica acima de tudo
      // CRÍTICO: Garante que tiles continuem atrás mesmo durante hover
            card.style.zIndex = '9999';
      forceTilesBehind();
            const spriteContainer = card.querySelector('.podium-sprite-container');
            if (spriteContainer) spriteContainer.style.zIndex = '9999';


            // CRÍTICO: Garante que tiles continuem atrás mesmo durante hover
      show(card);
            forceTilesBehind();
    }


            show(card);
    // Função para verificar se o pixel na posição do mouse é transparente
        }
    function isPixelTransparent(img, x, y) {
      if (!img.complete || img.naturalWidth === 0) return true;


        // Função para verificar se o pixel na posição do mouse é transparente
      try {
         function isPixelTransparent(img, x, y) {
         const canvas = document.createElement("canvas");
            if (!img.complete || img.naturalWidth === 0) return true;
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;
        const ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);


            try {
        // Calcula a posição relativa na imagem
                const canvas = document.createElement('canvas');
        const rect = img.getBoundingClientRect();
                canvas.width = img.naturalWidth;
        const scaleX = img.naturalWidth / rect.width;
                canvas.height = img.naturalHeight;
        const scaleY = img.naturalHeight / rect.height;
                const ctx = canvas.getContext('2d');
        const imgX = Math.floor((x - rect.left) * scaleX);
                ctx.drawImage(img, 0, 0);
        const imgY = Math.floor((y - rect.top) * scaleY);


                // Calcula a posição relativa na imagem
        // Verifica se está dentro dos limites
                const rect = img.getBoundingClientRect();
        if (
                const scaleX = img.naturalWidth / rect.width;
          imgX < 0 ||
                const scaleY = img.naturalHeight / rect.height;
          imgX >= img.naturalWidth ||
                const imgX = Math.floor((x - rect.left) * scaleX);
          imgY < 0 ||
                const imgY = Math.floor((y - rect.top) * scaleY);
          imgY >= img.naturalHeight
        ) {
          return true;
        }


                // Verifica se está dentro dos limites
        // Obtém o pixel
                if (imgX < 0 || imgX >= img.naturalWidth || imgY < 0 || imgY >= img.naturalHeight) {
        const pixelData = ctx.getImageData(imgX, imgY, 1, 1).data;
                    return true;
        const alpha = pixelData[3]; // Canal alpha
                }


                // Obtém o pixel
        return alpha < 10; // Considera transparente se alpha < 10
                const pixelData = ctx.getImageData(imgX, imgY, 1, 1).data;
      } catch (e) {
                const alpha = pixelData[3]; // Canal alpha
        return false; // Em caso de erro, permite o hover
      }
    }


                return alpha < 10; // Considera transparente se alpha < 10
    // ---------- Clique YouTube (sem duplicar) ----------
            } catch (e) {
    podium.addEventListener(
                return false; // Em caso de erro, permite o hover
      "click",
            }
      (ev) => {
        const slot = ev.target?.closest(".podium-slot[data-youtube]");
        if (!slot) return;
        const url = (slot.dataset.youtube || "").trim();
        if (!url) return;
        if (slot.dataset._opening === "1") return;
        slot.dataset._opening = "1";
        ev.preventDefault();
        ev.stopPropagation();
        ev.stopImmediatePropagation();
        try {
          window.open(url, "_blank", "noopener,noreferrer");
        } catch (e) {
          location.href = url;
         }
         }
        setTimeout(() => {
          delete slot.dataset._opening;
        }, 500);
      },
      { capture: true }
    );


        // ---------- Clique YouTube (sem duplicar) ----------
    podium.addEventListener(
        podium.addEventListener('click', (ev) => {
      "keydown",
            const slot = ev.target?.closest('.podium-slot[data-youtube]');
      (ev) => {
            if (!slot) return;
         if (ev.key !== "Enter" && ev.key !== " ") return;
            const url = (slot.dataset.youtube || '').trim();
        const slot = ev.target?.closest(".podium-slot[data-youtube]");
            if (!url) return;
        if (!slot) return;
            if (slot.dataset._opening === '1') return;
        const url = (slot.dataset.youtube || "").trim();
            slot.dataset._opening = '1';
        if (!url) return;
            ev.preventDefault();
        if (slot.dataset._opening === "1") return;
            ev.stopPropagation();
        slot.dataset._opening = "1";
            ev.stopImmediatePropagation();
        ev.preventDefault();
            try { window.open(url, '_blank', 'noopener,noreferrer'); }
        ev.stopPropagation();
            catch (e) { location.href = url; }
        ev.stopImmediatePropagation();
            setTimeout(() => { delete slot.dataset._opening; }, 500);
        try {
        }, { capture: true });
          window.open(url, "_blank", "noopener,noreferrer");
 
        } catch (e) {
         podium.addEventListener('keydown', (ev) => {
          location.href = url;
            if (ev.key !== 'Enter' && ev.key !== ' ') return;
        }
            const slot = ev.target?.closest('.podium-slot[data-youtube]');
        setTimeout(() => {
            if (!slot) return;
          delete slot.dataset._opening;
            const url = (slot.dataset.youtube || '').trim();
        }, 500);
            if (!url) return;
      },
            if (slot.dataset._opening === '1') return;
      { capture: true }
            slot.dataset._opening = '1';
    );
            ev.preventDefault();
            ev.stopPropagation();
            ev.stopImmediatePropagation();
            try { window.open(url, '_blank', 'noopener,noreferrer'); }
            catch (e) { location.href = url; }
            setTimeout(() => { delete slot.dataset._opening; }, 500);
        }, { capture: true });


        // ---------- Hitbox pixel-perfect por sprite ----------
    // ---------- Hitbox pixel-perfect por sprite ----------
        // CRÍTICO: Move tiles para fora do sprite-container para separar contexto de empilhamento
    // CRÍTICO: Move tiles para fora do sprite-container para separar contexto de empilhamento
        function moveTilesOutOfSpriteContainer() {
    function moveTilesOutOfSpriteContainer() {
            const allSlots = Array.from(podium.querySelectorAll('.podium-slot'));
      const allSlots = Array.from(podium.querySelectorAll(".podium-slot"));
            allSlots.forEach(slot => {
      allSlots.forEach((slot) => {
                const spriteContainer = slot.querySelector('.podium-sprite-container');
        const spriteContainer = slot.querySelector(".podium-sprite-container");
                const platform = slot.querySelector('.podium-platform');
        const platform = slot.querySelector(".podium-platform");


                // Se o tile ainda está dentro do sprite-container, move para o slot
        // Se o tile ainda está dentro do sprite-container, move para o slot
                if (platform && spriteContainer && spriteContainer.contains(platform)) {
        if (platform && spriteContainer && spriteContainer.contains(platform)) {
                    // Salva os estilos inline atuais antes de mover
          // Salva os estilos inline atuais antes de mover
                    const currentRight = platform.style.right || '';
          const currentRight = platform.style.right || "";
                    const currentBottom = platform.style.bottom || '';
          const currentBottom = platform.style.bottom || "";
                    const computedRight = getComputedStyle(platform).right;
          const computedRight = getComputedStyle(platform).right;
                    const computedBottom = getComputedStyle(platform).bottom;
          const computedBottom = getComputedStyle(platform).bottom;


                    // Move o tile para fora do sprite-container, mas mantém dentro do slot
          // Move o tile para fora do sprite-container, mas mantém dentro do slot
                    slot.appendChild(platform);
          slot.appendChild(platform);


                    // Restaura a posição (os valores já estão corretos, apenas precisa manter)
          // Restaura a posição (os valores já estão corretos, apenas precisa manter)
                    platform.style.position = 'absolute';
          platform.style.position = "absolute";
                    if (currentRight) {
          if (currentRight) {
                        platform.style.right = currentRight;
            platform.style.right = currentRight;
                    } else if (computedRight && computedRight !== 'auto') {
          } else if (computedRight && computedRight !== "auto") {
                        platform.style.right = computedRight;
            platform.style.right = computedRight;
                    } else {
          } else {
                        // Usa o valor padrão do CSS
            // Usa o valor padrão do CSS
                        platform.style.right = '-25px';
            platform.style.right = "-25px";
                    }
          }


                    if (currentBottom) {
          if (currentBottom) {
                        platform.style.bottom = currentBottom;
            platform.style.bottom = currentBottom;
                    } else if (computedBottom && computedBottom !== 'auto') {
          } else if (computedBottom && computedBottom !== "auto") {
                        platform.style.bottom = computedBottom;
            platform.style.bottom = computedBottom;
                    } else {
          } else {
                        // Usa o valor padrão do CSS
            // Usa o valor padrão do CSS
                        platform.style.bottom = '-15px';
            platform.style.bottom = "-15px";
                    }
          }
                }
            });
         }
         }
      });
    }


        // CRÍTICO: Força todos os tiles a terem z-index negativo na inicialização
    // CRÍTICO: Força todos os tiles a terem z-index negativo na inicialização
        function forceTilesBehind() {
    function forceTilesBehind() {
            const allSlots = Array.from(podium.querySelectorAll('.podium-slot'));
      const allSlots = Array.from(podium.querySelectorAll(".podium-slot"));
            allSlots.forEach(slot => {
      allSlots.forEach((slot) => {
                const platform = slot.querySelector('.podium-platform');
        const platform = slot.querySelector(".podium-platform");
                const platformTop = slot.querySelector('.podium-platform-top');
        const platformTop = slot.querySelector(".podium-platform-top");
                const platformImg = slot.querySelector('.podium-platform-top img');
        const platformImg = slot.querySelector(".podium-platform-top img");


                if (platform) {
        if (platform) {
                    platform.style.zIndex = '0';
          platform.style.zIndex = "0";
                    platform.style.setProperty('z-index', '0', 'important');
          platform.style.setProperty("z-index", "0", "important");
                }
        }
                if (platformTop) {
        if (platformTop) {
                    platformTop.style.zIndex = '0';
          platformTop.style.zIndex = "0";
                    platformTop.style.setProperty('z-index', '0', 'important');
          platformTop.style.setProperty("z-index", "0", "important");
                }
        }
                if (platformImg) {
        if (platformImg) {
                    platformImg.style.zIndex = '0';
          platformImg.style.zIndex = "0";
                    platformImg.style.setProperty('z-index', '0', 'important');
          platformImg.style.setProperty("z-index", "0", "important");
                }
            });
         }
         }
      });
    }


        // Move tiles para fora do sprite-container primeiro
    // Move tiles para fora do sprite-container primeiro
        moveTilesOutOfSpriteContainer();
    moveTilesOutOfSpriteContainer();
        setTimeout(moveTilesOutOfSpriteContainer, 10);
    setTimeout(moveTilesOutOfSpriteContainer, 10);
        setTimeout(moveTilesOutOfSpriteContainer, 100);
    setTimeout(moveTilesOutOfSpriteContainer, 100);


        // Depois força z-index negativo
    // Depois força z-index negativo
        forceTilesBehind();
    forceTilesBehind();
        setTimeout(forceTilesBehind, 10);
    setTimeout(forceTilesBehind, 10);
        setTimeout(forceTilesBehind, 100);
    setTimeout(forceTilesBehind, 100);


        const slots = Array.from(podium.querySelectorAll('.podium-slot'));
    const slots = Array.from(podium.querySelectorAll(".podium-slot"));
        slots.forEach(slot => {
    slots.forEach((slot) => {
            const spriteImg = slot.querySelector('.podium-sprite img');
      const spriteImg = slot.querySelector(".podium-sprite img");


            // Hitbox apenas na imagem do sprite, verificando transparência
      // Hitbox apenas na imagem do sprite, verificando transparência
            if (spriteImg) {
      if (spriteImg) {
                spriteImg.addEventListener('pointermove', (ev) => {
        spriteImg.addEventListener(
                    if (!slot.hasAttribute('data-skin-tooltip')) return;
          "pointermove",
          (ev) => {
            if (!slot.hasAttribute("data-skin-tooltip")) return;


                    // Verifica se o pixel é transparente
            // Verifica se o pixel é transparente
                    if (isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
            if (isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
                        // Se for transparente e estiver hovered, remove o hover
              // Se for transparente e estiver hovered, remove o hover
                        if (hoveredSlot === slot) {
              if (hoveredSlot === slot) {
                            setHovered(null);
                setHovered(null);
                        }
              }
                        return;
              return;
                    }
            }


                    // Se não for transparente, ativa o hover
            // Se não for transparente, ativa o hover
                    if (hoveredSlot !== slot) {
            if (hoveredSlot !== slot) {
                        setHovered(slot);
              setHovered(slot);
                    }
            }
                }, { passive: true });
          },
          { passive: true }
        );


                spriteImg.addEventListener('pointerenter', (ev) => {
        spriteImg.addEventListener(
                    if (!slot.hasAttribute('data-skin-tooltip')) return;
          "pointerenter",
          (ev) => {
            if (!slot.hasAttribute("data-skin-tooltip")) return;


                    // Verifica transparência no enter também
            // Verifica transparência no enter também
                    if (!isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
            if (!isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
                        setHovered(slot);
              setHovered(slot);
                    }
            }
                }, { passive: true });
          },
          { passive: true }
        );


                spriteImg.addEventListener('pointerleave', (ev) => {
        spriteImg.addEventListener(
                    const toCard = ev.relatedTarget && ev.relatedTarget.closest && ev.relatedTarget.closest('.podium-slot');
          "pointerleave",
                    if (toCard && podium.contains(toCard)) {
          (ev) => {
                        // Se está indo para outro slot, verifica transparência
            const toCard =
                        const otherImg = toCard.querySelector('.podium-sprite img');
              ev.relatedTarget &&
                        if (otherImg && ev.relatedTarget && !isPixelTransparent(otherImg, ev.clientX, ev.clientY)) {
              ev.relatedTarget.closest &&
                            return; // Não remove hover se está indo para pixel não-transparente
              ev.relatedTarget.closest(".podium-slot");
                        }
            if (toCard && podium.contains(toCard)) {
                    }
              // Se está indo para outro slot, verifica transparência
                    setHovered(null);
              const otherImg = toCard.querySelector(".podium-sprite img");
                }, { passive: true });
              if (
                otherImg &&
                ev.relatedTarget &&
                !isPixelTransparent(otherImg, ev.clientX, ev.clientY)
              ) {
                return; // Não remove hover se está indo para pixel não-transparente
              }
             }
             }
         });
            setHovered(null);
          },
          { passive: true }
         );
      }
    });


        podium.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
    podium.addEventListener(
      "pointerleave",
      () => {
        setHovered(null);
      },
      { passive: true }
    );


        // Só atualiza em scroll/resize, não em mousemove
    // Só atualiza em scroll/resize, não em mousemove
        window.addEventListener('scroll', () => { if (hoveredSlot) place(hoveredSlot); }, true);
    window.addEventListener(
        window.addEventListener('resize', () => { if (hoveredSlot) place(hoveredSlot); });
      "scroll",
      () => {
        if (hoveredSlot) place(hoveredSlot);
      },
      true
    );
    window.addEventListener("resize", () => {
      if (hoveredSlot) place(hoveredSlot);
    });


        // Função para ajustar sombra ao tamanho exato da imagem do tile
    // Função para ajustar sombra ao tamanho exato da imagem do tile
        function updateShadows() {
    function updateShadows() {
            const platformTops = document.querySelectorAll('.podium-platform-top');
      const platformTops = document.querySelectorAll(".podium-platform-top");
            platformTops.forEach((top, index) => {
      platformTops.forEach((top, index) => {
                const img = top.querySelector('img');
        const img = top.querySelector("img");
                if (img) {
        if (img) {
                    const updateShadow = () => {
          const updateShadow = () => {
                        // Usa naturalWidth/naturalHeight primeiro (mais rápido)
            // Usa naturalWidth/naturalHeight primeiro (mais rápido)
                        let imgWidth = img.naturalWidth || img.offsetWidth || 0;
            let imgWidth = img.naturalWidth || img.offsetWidth || 0;
                        let imgHeight = img.naturalHeight || img.offsetHeight || 0;
            let imgHeight = img.naturalHeight || img.offsetHeight || 0;


                        // Se ainda não tem dimensões, tenta forçar o carregamento
            // Se ainda não tem dimensões, tenta forçar o carregamento
                        if (imgWidth === 0 || imgHeight === 0) {
            if (imgWidth === 0 || imgHeight === 0) {
                            // Força o recálculo das dimensões
              // Força o recálculo das dimensões
                            imgWidth = img.naturalWidth || img.width || img.offsetWidth || 0;
              imgWidth = img.naturalWidth || img.width || img.offsetWidth || 0;
                            imgHeight = img.naturalHeight || img.height || img.offsetHeight || 0;
              imgHeight =
                        }
                img.naturalHeight || img.height || img.offsetHeight || 0;
            }


                        if (imgWidth > 0 && imgHeight > 0) {
            if (imgWidth > 0 && imgHeight > 0) {
                            top.style.setProperty('--img-width', imgWidth + 'px');
              top.style.setProperty("--img-width", imgWidth + "px");
                            top.style.setProperty('--img-height', imgHeight + 'px');
              top.style.setProperty("--img-height", imgHeight + "px");
                        } else {
            } else {
                            // Se ainda não tem dimensões, agenda nova tentativa
              // Se ainda não tem dimensões, agenda nova tentativa
                            // Especialmente importante para a última skin que pode carregar por último
              // Especialmente importante para a última skin que pode carregar por último
                            setTimeout(() => {
              setTimeout(() => {
                                const retryWidth = img.naturalWidth || img.offsetWidth || img.width || 0;
                const retryWidth =
                                const retryHeight = img.naturalHeight || img.offsetHeight || img.height || 0;
                  img.naturalWidth || img.offsetWidth || img.width || 0;
                                if (retryWidth > 0 && retryHeight > 0) {
                const retryHeight =
                                    top.style.setProperty('--img-width', retryWidth + 'px');
                  img.naturalHeight || img.offsetHeight || img.height || 0;
                                    top.style.setProperty('--img-height', retryHeight + 'px');
                if (retryWidth > 0 && retryHeight > 0) {
                                }
                  top.style.setProperty("--img-width", retryWidth + "px");
                            }, 100 + (index * 20)); // Delay progressivo para cada tile
                  top.style.setProperty("--img-height", retryHeight + "px");
                        }
                }
                    };
              }, 100 + index * 20); // Delay progressivo para cada tile
            }
          };


                    // Tenta atualizar imediatamente
          // Tenta atualizar imediatamente
                    updateShadow();
          updateShadow();


                    // Se a imagem já carregou, atualiza novamente para garantir
          // Se a imagem já carregou, atualiza novamente para garantir
                    if (img.complete && img.naturalWidth > 0) {
          if (img.complete && img.naturalWidth > 0) {
                        requestAnimationFrame(updateShadow);
            requestAnimationFrame(updateShadow);
                    } else {
          } else {
                        // Usa 'load' e também verifica periodicamente
            // Usa 'load' e também verifica periodicamente
                        img.addEventListener('load', () => {
            img.addEventListener(
                            requestAnimationFrame(updateShadow);
              "load",
                        }, { once: true });
              () => {
                requestAnimationFrame(updateShadow);
              },
              { once: true }
            );


                        // Fallback: verifica após um tempo curto (com delay progressivo para última skin)
            // Fallback: verifica após um tempo curto (com delay progressivo para última skin)
                        setTimeout(() => {
            setTimeout(() => {
                            if (img.complete || img.naturalWidth > 0) {
              if (img.complete || img.naturalWidth > 0) {
                                requestAnimationFrame(updateShadow);
                requestAnimationFrame(updateShadow);
                            }
              }
                        }, 50 + (index * 10));
            }, 50 + index * 10);


                        // Fallback adicional para garantir que a última skin seja atualizada
            // Fallback adicional para garantir que a última skin seja atualizada
                        if (index === platformTops.length - 1) {
            if (index === platformTops.length - 1) {
                            setTimeout(() => {
              setTimeout(() => {
                                updateShadow();
                updateShadow();
                            }, 200);
              }, 200);
                            setTimeout(() => {
              setTimeout(() => {
                                updateShadow();
                updateShadow();
                            }, 500);
              }, 500);
                        }
            }
                    }
          }
                }
            });
         }
         }
      });
    }


        // Executa imediatamente e também após DOMContentLoaded
    // Executa imediatamente e também após DOMContentLoaded
        updateShadows();
    updateShadows();


        if (document.readyState === 'loading') {
    if (document.readyState === "loading") {
            document.addEventListener('DOMContentLoaded', updateShadows);
      document.addEventListener("DOMContentLoaded", updateShadows);
            window.addEventListener('load', updateShadows);
      window.addEventListener("load", updateShadows);
        } else {
    } else {
            // Se já carregou, executa imediatamente e depois de um frame
      // Se já carregou, executa imediatamente e depois de um frame
            requestAnimationFrame(updateShadows);
      requestAnimationFrame(updateShadows);
        }
    }


        // Garante que todas as imagens dos tiles sejam atualizadas após o carregamento completo
    // Garante que todas as imagens dos tiles sejam atualizadas após o carregamento completo
        window.addEventListener('load', () => {
    window.addEventListener("load", () => {
            setTimeout(updateShadows, 100);
      setTimeout(updateShadows, 100);
            setTimeout(updateShadows, 300);
      setTimeout(updateShadows, 300);
            setTimeout(updateShadows, 500);
      setTimeout(updateShadows, 500);
        });
    });


        // Observa mudanças nas imagens
    // Observa mudanças nas imagens
        if ('MutationObserver' in window) {
    if ("MutationObserver" in window) {
            const observer = new MutationObserver(() => {
      const observer = new MutationObserver(() => {
                updateShadows();
        updateShadows();
            });
      });
            observer.observe(podium, { childList: true, subtree: true });
      observer.observe(podium, { childList: true, subtree: true });
        }
    }


        // Observa quando imagens dos tiles são carregadas
    // Observa quando imagens dos tiles são carregadas
        const tileImages = document.querySelectorAll('.podium-platform-top img');
    const tileImages = document.querySelectorAll(".podium-platform-top img");
        tileImages.forEach((img, index) => {
    tileImages.forEach((img, index) => {
            if (img.complete) {
      if (img.complete) {
                // Se já carregou, força atualização
        // Se já carregou, força atualização
                setTimeout(() => updateShadows(), 50 + (index * 20));
        setTimeout(() => updateShadows(), 50 + index * 20);
            } else {
      } else {
                img.addEventListener('load', () => {
        img.addEventListener(
                    updateShadows();
          "load",
                }, { once: true });
          () => {
            }
            updateShadows();
        });
          },
    })();
          { once: true }
        );
      }
    });
  })();
</script>
</script>
<style>
<style>
    /* Container escuro para área de skins - igual ao content-card */
  /* Container escuro para área de skins - igual ao content-card */
    .card-skins {
  .card-skins {
        width: min(1600px, 96vw);
    width: min(1600px, 96vw);
        max-width: 96vw;
    max-width: 96vw;
        margin: 10px auto;
    margin: 10px auto;
        background: rgba(28, 28, 34, .95);
    background: rgba(28, 28, 34, 0.95);
        border-radius: 12px;
    border-radius: 12px;
        box-shadow: 0 8px 24px rgba(0, 0, 0, .30);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
        padding: 18px;
    padding: 18px;
        z-index: 2;
    z-index: 2;
        box-sizing: border-box;
    box-sizing: border-box;
        overflow-x: hidden;
    overflow-x: hidden;
        overflow-y: visible;
    overflow-y: visible;
     }
  }
 
  /* Regras globais para filhos do card-skins - igual ao content-card */
  .card-skins,
  .skins-podium {
     box-sizing: border-box;
    max-width: 100%;
  }
 
  .card-skins * {
    max-width: 100%;
    box-sizing: border-box;
  }
 
  /* Exceção: imagens do tile e sprite mantêm tamanho natural (exceto no mobile) */
  .podium-platform-top img,
  .podium-sprite img {
    max-width: none;
  }
 
  /* Podium de skins - layout isométrico */
  .skins-podium {
    display: flex;
    align-items: flex-end;
    /* Alinha todos os slots pelo bottom */
    justify-content: center;
    gap: 30px;
    padding: 20px 0 50px 0;
    /* Padding extra na parte inferior para os tiles */
    position: relative;
    width: 100%;
    flex-wrap: wrap;
    box-sizing: border-box;
    overflow-x: hidden;
    overflow-y: visible;
  }
 
  .podium-slot {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    /* Alinha pelo bottom */
    cursor: pointer;
    transition: filter 0.14s ease, box-shadow 0.14s ease;
    flex-shrink: 0;
    max-width: 100%;
    box-sizing: border-box;
    overflow: visible;
    /* Permite que os tiles saiam do slot se necessário */
    /* Permite margin-left negativo para offset_x */
  }
 
  /* Z-index: sprites da direita passam na frente das da esquerda */
  /* Aplicado dinamicamente via JS, mas CSS base para primeiros slots */
  .podium-slot:nth-child(1) {
    z-index: 1;
    /* Esquerda: mais atrás */
  }
 
  .podium-slot:nth-child(2) {
    z-index: 2;
  }


    /* Regras globais para filhos do card-skins - igual ao content-card */
  .podium-slot:nth-child(3) {
    .card-skins,
    z-index: 3;
    .skins-podium {
  }
        box-sizing: border-box;
        max-width: 100%;
    }


    .card-skins * {
  .podium-slot:nth-child(4) {
        max-width: 100%;
    z-index: 4;
        box-sizing: border-box;
    /* Direita: mais na frente */
    }
  }


    /* Exceção: imagens do tile e sprite mantêm tamanho natural (exceto no mobile) */
  /* Z-index para sprite-containers: direita passa na frente da esquerda */
    .podium-platform-top img,
  /* IMPORTANTE: z-index alto para garantir que sprites sempre fiquem acima dos tiles (z-index negativo) */
    .podium-sprite img {
  .podium-slot:nth-child(1) .podium-sprite-container {
        max-width: none;
    z-index: 1000 !important;
     }
     /* Esquerda: mais atrás */
  }


    /* Podium de skins - layout isométrico */
  .podium-slot:nth-child(2) .podium-sprite-container {
    .skins-podium {
    z-index: 2000 !important;
        display: flex;
  }
        align-items: flex-end;
        /* Alinha todos os slots pelo bottom */
        justify-content: center;
        gap: 30px;
        padding: 20px 0 50px 0;
        /* Padding extra na parte inferior para os tiles */
        position: relative;
        width: 100%;
        flex-wrap: wrap;
        box-sizing: border-box;
        overflow-x: hidden;
        overflow-y: visible;
    }


    .podium-slot {
  .podium-slot:nth-child(3) .podium-sprite-container {
        position: relative;
    z-index: 3000 !important;
        display: flex;
  }
        flex-direction: column;
        align-items: center;
        justify-content: flex-end;
        /* Alinha pelo bottom */
        cursor: pointer;
        transition: filter 0.14s ease, box-shadow 0.14s ease;
        flex-shrink: 0;
        max-width: 100%;
        box-sizing: border-box;
        overflow: visible;
        /* Permite que os tiles saiam do slot se necessário */
        /* Permite margin-left negativo para offset_x */
    }


    /* Z-index: sprites da direita passam na frente das da esquerda */
  .podium-slot:nth-child(4) .podium-sprite-container {
    /* Aplicado dinamicamente via JS, mas CSS base para primeiros slots */
    z-index: 4000 !important;
    .podium-slot:nth-child(1) {
    /* Direita: mais na frente, acima de todos os tiles */
        z-index: 1;
  }
        /* Esquerda: mais atrás */
    }


    .podium-slot:nth-child(2) {
  /* Hitbox baseada na imagem, não no container */
        z-index: 2;
  .podium-slot>* {
    }
    pointer-events: none;
  }


    .podium-slot:nth-child(3) {
  /* Apenas a imagem do sprite tem hitbox - container não interfere */
        z-index: 3;
  .podium-sprite img {
    }
    pointer-events: auto;
  }


    .podium-slot:nth-child(4) {
  /* Container e sprite não têm hitbox para não interferir */
        z-index: 4;
  .podium-sprite-container,
        /* Direita: mais na frente */
  .podium-sprite {
    }
    pointer-events: none;
  }


    /* Z-index para sprite-containers: direita passa na frente da esquerda */
  /* Piso nunca tem hitbox */
    /* IMPORTANTE: z-index alto para garantir que sprites sempre fiquem acima dos tiles (z-index negativo) */
  .podium-platform,
    .podium-slot:nth-child(1) .podium-sprite-container {
  .podium-platform-top,
        z-index: 1000 !important;
  .podium-platform-top img {
        /* Esquerda: mais atrás */
    pointer-events: none !important;
    }
  }


    .podium-slot:nth-child(2) .podium-sprite-container {
  /* Container do sprite - tamanho natural, não afetado pelo tile */
        z-index: 2000 !important;
  .podium-sprite-container {
     }
    position: relative;
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    /* Alinha pelo bottom (pés) - horizontalmente */
    justify-content: center;
    /* Centraliza horizontalmente */
    filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.5));
    transform: none !important;
     flex-shrink: 0;
    max-width: 100%;
    box-sizing: border-box;
    /* REMOVIDO isolation: isolate - estava criando contexto que impedia tiles de ficarem atrás */
  }


    .podium-slot:nth-child(3) .podium-sprite-container {
  /* Garante que TODAS as sprites fiquem acima de TODOS os tiles */
        z-index: 3000 !important;
  /* IMPORTANTE: z-index mínimo de 1 para garantir que sprites sempre fiquem acima dos tiles (z-index negativo) */
    }
  .podium-slot .podium-sprite-container {
    position: relative;
    z-index: 1 !important;
  }


    .podium-slot:nth-child(4) .podium-sprite-container {
  .podium-sprite {
        z-index: 4000 !important;
    display: block;
        /* Direita: mais na frente, acima de todos os tiles */
    position: relative;
    }
    transform: none !important;
    flex-shrink: 0;
  }


     /* Hitbox baseada na imagem, não no container */
  .podium-sprite img {
     .podium-slot>* {
    width: auto;
        pointer-events: none;
    height: auto;
    }
    max-width: none;
    max-height: none;
    image-rendering: pixelated;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: crisp-edges;
    display: block;
    position: relative;
    z-index: 10 !important;
     /* Imagem sempre acima do piso (z-index maior que tiles) */
     transform: none !important;
    will-change: auto;
    flex-shrink: 0;
  }


    /* Apenas a imagem do sprite tem hitbox - container não interfere */
  /* Tile isométrico nos pés da sprite - atrás da sprite */
    .podium-sprite img {
  /* IMPORTANTE: z-index 0 para ficar acima do background do card-skins, mas abaixo das sprites (z-index 10-40) */
        pointer-events: auto;
  .podium-platform {
     }
    position: absolute;
    width: auto;
    height: auto;
    bottom: -15px;
    right: -25px;
    z-index: 0 !important;
     /* z-index 0 fica acima do background do card-skins, mas abaixo das sprites */
  }


    /* Container e sprite não têm hitbox para não interferir */
  /* Todos os pisos com z-index 0 - acima do background, mas abaixo das sprites */
    .podium-sprite-container,
  .podium-slot .podium-platform {
    .podium-sprite {
    z-index: 0 !important;
        pointer-events: none;
  }
    }


    /* Piso nunca tem hitbox */
  /* CRÍTICO: Garante que tiles fiquem acima do background do card, mas abaixo de TODAS as sprites */
    .podium-platform,
  .podium-slot .podium-platform,
    .podium-platform-top,
  .podium-slot .podium-platform-top,
    .podium-platform-top img {
  .podium-slot .podium-platform-top img {
        pointer-events: none !important;
    /* z-index 0 garante que fiquem acima do background do card-skins */
    }
    /* mas as sprites têm z-index 10-40, então ficam na frente */
    z-index: 0 !important;
  }


    /* Container do sprite - tamanho natural, não afetado pelo tile */
  /* Tile - usando imagem no tamanho natural */
    .podium-sprite-container {
  .podium-platform-top {
        position: relative;
    position: absolute;
        z-index: 10;
    width: auto;
        display: flex;
    height: auto;
        flex-direction: column;
    transform-origin: center bottom;
        align-items: flex-end;
    transform: rotateX(15deg);
        /* Alinha pelo bottom (pés) - horizontalmente */
    /* Inclinação fixa em 15 graus */
        justify-content: center;
    z-index: 0 !important;
        /* Centraliza horizontalmente */
    /* z-index 0 fica acima do background do card, mas abaixo das sprites */
        filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.5));
  }
        transform: none !important;
        flex-shrink: 0;
        max-width: 100%;
        box-sizing: border-box;
        /* REMOVIDO isolation: isolate - estava criando contexto que impedia tiles de ficarem atrás */
    }


     /* Garante que TODAS as sprites fiquem acima de TODOS os tiles */
  .podium-platform-top img {
     /* IMPORTANTE: z-index mínimo de 1 para garantir que sprites sempre fiquem acima dos tiles (z-index negativo) */
     display: block;
     .podium-slot .podium-sprite-container {
    width: auto;
        position: relative;
    height: auto;
        z-index: 1 !important;
    max-width: none;
     }
    max-height: none;
    image-rendering: pixelated;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: crisp-edges;
    position: relative;
    z-index: 0 !important;
     /* z-index 0 fica acima do background do card, mas abaixo das sprites (z-index 10-40) */
     border: none !important;
    outline: none;
    box-shadow: none;
    opacity: 1 !important;
     /* Garante que a imagem do tile sempre esteja visível */
  }


    .podium-sprite {
  /* Sombra quadrada sólida - perfeitamente alinhada com a imagem */
        display: block;
  .podium-platform-top::before {
        position: relative;
    content: "";
        transform: none !important;
    position: absolute;
        flex-shrink: 0;
    top: 0;
     }
    left: 0;
    width: var(--img-width, 100%);
    height: var(--img-height, 100%);
    background: rgba(0, 0, 0, 0.5);
    z-index: -1 !important;
    /* z-index -1 para ficar atrás da imagem do tile, mas ainda acima do background do card */
    transform: translate(3px, 3px);
    pointer-events: none;
    opacity: 0;
     transition: opacity 0.1s ease;
  }


    .podium-sprite img {
  /* Mostra a sombra quando as dimensões estão definidas */
        width: auto;
  .podium-platform-top[style*="--img-width"]::before {
        height: auto;
    opacity: 1;
        max-width: none;
  }
        max-height: none;
        image-rendering: pixelated;
        image-rendering: -moz-crisp-edges;
        image-rendering: -webkit-optimize-contrast;
        image-rendering: crisp-edges;
        display: block;
        position: relative;
        z-index: 10 !important;
        /* Imagem sempre acima do piso (z-index maior que tiles) */
        transform: none !important;
        will-change: auto;
        flex-shrink: 0;
    }


    /* Tile isométrico nos pés da sprite - atrás da sprite */
  /* Sistema de hover - dim outras skins, destaque na hovered */
    /* IMPORTANTE: z-index 0 para ficar acima do background do card-skins, mas abaixo das sprites (z-index 10-40) */
  .skins-podium.hovering .podium-slot.dim {
    .podium-platform {
    filter: brightness(0.55) saturate(0.85);
        position: absolute;
    transition: filter 0.14s ease;
        width: auto;
  }
        height: auto;
        bottom: -15px;
        right: -25px;
        z-index: 0 !important;
        /* z-index 0 fica acima do background do card-skins, mas abaixo das sprites */
    }


    /* Todos os pisos com z-index 0 - acima do background, mas abaixo das sprites */
  .skins-podium.hovering .podium-slot.hovered {
    .podium-slot .podium-platform {
    filter: none;
        z-index: 0 !important;
  }
    }


    /* CRÍTICO: Garante que tiles fiquem acima do background do card, mas abaixo de TODAS as sprites */
  /* CRÍTICO: Remove efeito de hover da imagem do piso (sem "borda fantasma") */
    .podium-slot .podium-platform,
  .skins-podium.hovering .podium-slot.dim .podium-platform-top,
    .podium-slot .podium-platform-top,
  .skins-podium.hovering .podium-slot.hovered .podium-platform-top,
    .podium-slot .podium-platform-top img {
  .skins-podium.hovering .podium-slot.dim .podium-platform-top img,
        /* z-index 0 garante que fiquem acima do background do card-skins */
  .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
        /* mas as sprites têm z-index 10-40, então ficam na frente */
    filter: none !important;
        z-index: 0 !important;
    box-shadow: none !important;
    }
  }


    /* Tile - usando imagem no tamanho natural */
  /* Borda no tile quando hovered - apenas no container, não na imagem */
    .podium-platform-top {
  .skins-podium.hovering .podium-slot.hovered .podium-platform-top {
        position: absolute;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.12),
        width: auto;
      0 10px 28px rgba(0, 0, 0, 0.45);
        height: auto;
  }
        transform-origin: center bottom;
        transform: rotateX(15deg);
        /* Inclinação fixa em 15 graus */
        z-index: 0 !important;
        /* z-index 0 fica acima do background do card, mas abaixo das sprites */
    }


    .podium-platform-top img {
  /* Remove sombra da imagem do tile no hover */
        display: block;
  .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
        width: auto;
    box-shadow: none !important;
        height: auto;
    filter: none !important;
        max-width: none;
  }
        max-height: none;
        image-rendering: pixelated;
        image-rendering: -moz-crisp-edges;
        image-rendering: -webkit-optimize-contrast;
        image-rendering: crisp-edges;
        position: relative;
        z-index: 0 !important;
        /* z-index 0 fica acima do background do card, mas abaixo das sprites (z-index 10-40) */
        border: none !important;
        outline: none;
        box-shadow: none;
        opacity: 1 !important;
        /* Garante que a imagem do tile sempre esteja visível */
    }


    /* Sombra quadrada sólida - perfeitamente alinhada com a imagem */
  /* Tooltip */
    .podium-platform-top::before {
  .skin-tooltip {
        content: '';
    position: fixed;
        position: absolute;
    z-index: 9999;
        top: 0;
    left: 0;
        left: 0;
    top: 0;
        width: var(--img-width, 100%);
    pointer-events: none;
        height: var(--img-height, 100%);
    padding: 10px 12px;
        background: rgba(0, 0, 0, 0.5);
    border-radius: 8px;
        z-index: -1 !important;
    background: rgba(40, 45, 60, 0.98);
        /* z-index -1 para ficar atrás da imagem do tile, mas ainda acima do background do card */
    /* Azul escuro para melhor contraste */
        transform: translate(3px, 3px);
    color: #f0f0f0;
        pointer-events: none;
    font-size: 13px;
        opacity: 0;
    line-height: 1.4;
        transition: opacity 0.1s ease;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6),
     }
      0 0 0 1px rgba(80, 90, 120, 0.4),
      /* Borda azulada para definição */
      inset 0 0 0 1px rgba(255, 255, 255, 0.08);
    transform: translate(-9999px, -9999px);
    opacity: 0;
    transition: opacity 0.15s ease;
     text-align: center;
    white-space: normal;
    max-width: 280px;
    min-width: 200px;
  }


    /* Mostra a sombra quando as dimensões estão definidas */
  .skin-tooltip b {
    .podium-platform-top[style*="--img-width"]::before {
    color: #ffffff;
        opacity: 1;
     font-weight: 600;
     }
  }


    /* Sistema de hover - dim outras skins, destaque na hovered */
  .podium-slot.is-clickable {
    .skins-podium.hovering .podium-slot.dim {
    cursor: pointer;
        filter: brightness(.55) saturate(.85);
  }
        transition: filter .14s ease;
    }


    .skins-podium.hovering .podium-slot.hovered {
  .podium-slot.is-clickable:focus {
        filter: none;
    outline: 2px solid #156bc7;
     }
     outline-offset: 2px;
  }


    /* CRÍTICO: Remove efeito de hover da imagem do piso (sem "borda fantasma") */
  /* Responsivo */
    .skins-podium.hovering .podium-slot.dim .podium-platform-top,
  @media (max-width: 1100px) {
     .skins-podium.hovering .podium-slot.hovered .podium-platform-top,
     .skins-podium {
    .skins-podium.hovering .podium-slot.dim .podium-platform-top img,
      gap: 24px;
    .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
        filter: none !important;
        box-shadow: none !important;
     }
     }
  }


    /* Borda no tile quando hovered - apenas no container, não na imagem */
  @media (max-width: 768px) {
     .skins-podium.hovering .podium-slot.hovered .podium-platform-top {
     .card-skins {
        box-shadow:
      padding: 14px;
            0 0 0 2px rgba(255, 255, 255, .12),
            0 10px 28px rgba(0, 0, 0, .45);
     }
     }


    /* Remove sombra da imagem do tile no hover */
     .skins-podium {
     .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
      gap: 20px;
        box-shadow: none !important;
      padding: 15px 0;
        filter: none !important;
     }
     }
  }


    /* Tooltip */
  @media (max-width: 600px) {
     .skin-tooltip {
     .card-skins {
        position: fixed;
      box-sizing: border-box;
        z-index: 9999;
      max-width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right) - 16px);
        left: 0;
      width: 100%;
        top: 0;
      margin: 10px auto;
        pointer-events: none;
      padding: 12px;
        padding: 10px 12px;
      border-radius: 10px;
        border-radius: 8px;
      overflow-x: hidden;
        background: rgba(28, 28, 34, .98);
      overflow-y: visible;
        color: #eaeaea;
        font-size: 13px;
        line-height: 1.4;
        box-shadow: 0 8px 24px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .06);
        transform: translate(-9999px, -9999px);
        opacity: 0;
        transition: opacity .15s ease;
        text-align: center;
        white-space: normal;
        max-width: 280px;
        min-width: 200px;
     }
     }


     .skin-tooltip b {
     .skins-podium {
        color: #fff;
      gap: 16px;
      padding: 10px 8px 50px 8px;
      /* Padding extra na parte inferior para os tiles */
      justify-content: center;
      overflow-y: visible;
     }
     }


     .podium-slot.is-clickable {
     .podium-slot {
        cursor: pointer;
      max-width: calc(50% - 8px);
      flex: 0 0 auto;
      min-width: 0;
     }
     }


     .podium-slot.is-clickable:focus {
     .podium-sprite-container {
        outline: 2px solid #156bc7;
      max-width: 100%;
        outline-offset: 2px;
      min-width: 0;
     }
     }


     /* Responsivo */
     .podium-sprite img {
    @media (max-width: 1100px) {
      max-width: 100%;
        .skins-podium {
      height: auto;
            gap: 24px;
        }
     }
     }


     @media (max-width: 768px) {
     .podium-platform-top img {
        .card-skins {
      max-width: 100%;
            padding: 14px;
      height: auto;
        }
 
        .skins-podium {
            gap: 20px;
            padding: 15px 0;
        }
     }
     }
  }


    @media (max-width: 600px) {
  @media (max-width: 400px) {
        .card-skins {
    .skins-podium {
            box-sizing: border-box;
      gap: 12px;
            max-width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right) - 16px);
      padding-left: 4px;
            width: 100%;
      padding-right: 4px;
            margin: 10px auto;
            padding: 12px;
            border-radius: 10px;
            overflow-x: hidden;
            overflow-y: visible;
        }
 
        .skins-podium {
            gap: 16px;
            padding: 10px 8px 50px 8px;
            /* Padding extra na parte inferior para os tiles */
            justify-content: center;
            overflow-y: visible;
        }
 
        .podium-slot {
            max-width: calc(50% - 8px);
            flex: 0 0 auto;
            min-width: 0;
        }
 
        .podium-sprite-container {
            max-width: 100%;
            min-width: 0;
        }
 
        .podium-sprite img {
            max-width: 100%;
            height: auto;
        }
 
        .podium-platform-top img {
            max-width: 100%;
            height: auto;
        }
     }
     }


     @media (max-width: 400px) {
     .podium-slot {
        .skins-podium {
      max-width: calc(50% - 6px);
            gap: 12px;
            padding-left: 4px;
            padding-right: 4px;
        }
 
        .podium-slot {
            max-width: calc(50% - 6px);
        }
     }
     }
  }
</style>
</style>

Edição atual tal como às 14h18min de 22 de janeiro de 2026

<script>

 (function initSkinsPodiumUI() {
   const podium = document.querySelector(".skins-podium");
   if (!podium || podium.dataset.wired === "1") return;
   podium.dataset.wired = "1";
   // ---------- Função para aplicar offset_x individualmente em cada skin ----------
   // IMPORTANTE: Usa margin-left em vez de transform para afetar o layout do flexbox
   function applyOffsetX() {
     const allSlots = podium.querySelectorAll(".podium-slot");
     allSlots.forEach((slot, index) => {
       // Lê o atributo data-offset-x diretamente do elemento
       const offsetXAttr = slot.getAttribute("data-offset-x");
       if (
         offsetXAttr !== null &&
         offsetXAttr !== "" &&
         offsetXAttr !== "undefined"
       ) {
         const numOffset = parseFloat(offsetXAttr);
         if (!isNaN(numOffset) && numOffset !== 0) {
           // Usa margin-left negativo para afetar o layout do flexbox
           // Isso faz com que o elemento realmente se aproxime dos outros
           const currentStyle = slot.getAttribute("style") || "";
           // Remove qualquer margin-left anterior e transform (legado)
           const cleanedStyle = currentStyle
             .replace(/margin-left\s*:[^;]+;?/gi, "")
             .replace(/transform\s*:[^;]+;?/gi, "")
             .trim();
           // Aplica o margin-left preservando outros estilos (como z-index)
           const newMargin = `margin-left: ${numOffset}px`;
           if (cleanedStyle && cleanedStyle.length > 0) {
             slot.setAttribute(
               "style",
               cleanedStyle +
               (cleanedStyle.endsWith(";") ? " " : "; ") +
               newMargin +
               ";"
             );
           } else {
             slot.setAttribute("style", newMargin + ";");
           }
           // Força a atualização do layout
           slot.offsetHeight;
         } else {
           // Se o offset for 0 ou inválido, remove margin-left e transform
           const currentStyle = slot.getAttribute("style") || "";
           const cleanedStyle = currentStyle
             .replace(/margin-left\s*:[^;]+;?/gi, "")
             .replace(/transform\s*:[^;]+;?/gi, "")
             .trim();
           if (cleanedStyle) {
             slot.setAttribute(
               "style",
               cleanedStyle + (cleanedStyle.endsWith(";") ? "" : ";")
             );
           } else {
             slot.removeAttribute("style");
           }
         }
       } else {
         // Se não tem offset_x, remove margin-left e transform (preserva outros estilos)
         const currentStyle = slot.getAttribute("style") || "";
         const cleanedStyle = currentStyle
           .replace(/margin-left\s*:[^;]+;?/gi, "")
           .replace(/transform\s*:[^;]+;?/gi, "")
           .trim();
         if (cleanedStyle) {
           slot.setAttribute(
             "style",
             cleanedStyle + (cleanedStyle.endsWith(";") ? "" : ";")
           );
         } else {
           slot.removeAttribute("style");
         }
       }
     });
   }
   // Flag para evitar múltiplas execuções simultâneas
   let isApplying = false;
   function applyOffsetXOnce() {
     if (isApplying) return;
     isApplying = true;
     applyOffsetX();
     requestAnimationFrame(() => {
       isApplying = false;
     });
   }
   // Aplica usando requestAnimationFrame para garantir que o DOM esteja renderizado
   requestAnimationFrame(() => {
     applyOffsetXOnce();
     // Reaplica após pequenos delays para garantir
     setTimeout(applyOffsetXOnce, 50);
     setTimeout(applyOffsetXOnce, 200);
   });
   // Também aplica quando o DOM estiver pronto
   if (document.readyState === "loading") {
     document.addEventListener("DOMContentLoaded", () => {
       requestAnimationFrame(applyOffsetXOnce);
     });
   }
   // Observa mudanças no DOM para reaplicar se necessário (apenas para novos elementos)
   if (window.MutationObserver) {
     const observer = new MutationObserver((mutations) => {
       // Só reaplica se houver mudanças relevantes
       const hasRelevantChanges = mutations.some(
         (m) =>
           m.type === "childList" ||
           (m.type === "attributes" &&
             (m.attributeName === "data-offset-x" ||
               m.attributeName === "style"))
       );
       if (hasRelevantChanges) {
         clearTimeout(observer.timeout);
         observer.timeout = setTimeout(applyOffsetXOnce, 50);
       }
     });
     observer.observe(podium, {
       childList: true,
       subtree: false, // Apenas observa filhos diretos
       attributes: true,
       attributeFilter: ["data-offset-x"],
     });
   }
   // ---------- Tooltip único ----------
   function ensureTip() {
     let tip = document.querySelector(".skin-tooltip");
     if (!tip) {
       tip = document.createElement("div");
       tip.className = "skin-tooltip";
       tip.setAttribute("role", "tooltip");
       tip.setAttribute("aria-hidden", "true");
       tip.style.position = "fixed";
       tip.style.transform = "translate(-9999px,-9999px)";
       tip.style.opacity = "0";
       tip.style.transition = "opacity .15s ease";
       document.body.appendChild(tip);
     }
     return tip;
   }
   const tip = ensureTip();
   let hoveredSlot = null;
   function place(card) {
     if (!card || tip.getAttribute("aria-hidden") === "true") return;
     // Calcula nova posição - tooltip centralizada em relação à imagem do piso
     tip.style.transform = "translate(-9999px,-9999px)";
     const tr = tip.getBoundingClientRect();
     // Pega a posição da imagem do tile (piso) para centralizar
     const platformImg = card.querySelector(".podium-platform-top img");
     let platformRect = card.getBoundingClientRect(); // Fallback para o card se não encontrar
     if (platformImg) {
       platformRect = platformImg.getBoundingClientRect();
     } else {
       // Se não encontrar a img, tenta o container do tile
       const platform = card.querySelector(".podium-platform");
       if (platform) {
         platformRect = platform.getBoundingClientRect();
       }
     }
     // Centraliza horizontalmente baseado na imagem do tile
     let leftPos = Math.round(
       platformRect.left + (platformRect.width - tr.width) / 2
     );
     leftPos = Math.max(
       8,
       Math.min(leftPos, window.innerWidth - tr.width - 8)
     );
     // Posiciona logo abaixo da imagem do tile, com pequeno espaçamento
     let top = Math.round(platformRect.bottom + 15);
     // Se não couber embaixo, coloca em cima
     if (top + tr.height > window.innerHeight - 8) {
       top = Math.round(platformRect.top - tr.height - 15);
       if (top < 8) top = 8; // Fallback se não couber em cima também
     }
     tip.style.transform = `translate(${leftPos}px, ${top}px)`;
   }
   function show(card) {
     const tooltipText = card.getAttribute("data-skin-tooltip") || "";
     tip.innerHTML = tooltipText;
     tip.setAttribute("aria-hidden", "false");
     place(card);
     tip.style.opacity = "1";
   }
   function hide() {
     tip.setAttribute("aria-hidden", "true");
     tip.style.opacity = "0";
     tip.style.transform = "translate(-9999px,-9999px)";
   }
   // Função para restaurar z-index original baseado na posição do slot
   function restoreOriginalZIndex(slot) {
     if (!slot) return;
     // Determina a posição do slot (1, 2, 3, 4, etc)
     const allSlots = Array.from(podium.querySelectorAll(".podium-slot"));
     const slotIndex = allSlots.indexOf(slot);
     // Z-index: esquerda (0) = menor, direita (último) = maior (direita passa na frente)
     const originalZIndex = slotIndex + 1;
     const originalSpriteZIndex = (slotIndex + 1) * 10;
     slot.style.zIndex = originalZIndex.toString();
     const spriteContainer = slot.querySelector(".podium-sprite-container");
     if (spriteContainer)
       spriteContainer.style.zIndex = originalSpriteZIndex.toString();
     // CRÍTICO: Garante que TODOS os tiles sempre fiquem atrás de TODAS as sprites
     // Força z-index negativo nos tiles de todos os slots
     const platform = slot.querySelector(".podium-platform");
     const platformTop = slot.querySelector(".podium-platform-top");
     const platformImg = slot.querySelector(".podium-platform-top img");
     if (platform) platform.style.zIndex = "-1";
     if (platformTop) platformTop.style.zIndex = "-2";
     if (platformImg) platformImg.style.zIndex = "-2";
   }
   function setHovered(card) {
     if (hoveredSlot === card) {
       // Se já está hovered, não reposiciona - mantém posição fixa
       return;
     }
     // Remove hover anterior e restaura z-index original
     if (hoveredSlot) {
       hoveredSlot.classList.remove("hovered");
       restoreOriginalZIndex(hoveredSlot);
       // Garante que tiles continuem atrás após restaurar z-index
       forceTilesBehind();
     }
     podium.classList.remove("hovering");
     podium
       .querySelectorAll(".podium-slot.dim")
       .forEach((n) => n.classList.remove("dim"));
     if (!card) {
       hoveredSlot = null;
       hide();
       return;
     }
     hoveredSlot = card;
     hoveredSlot.classList.add("hovered");
     podium.classList.add("hovering");
     podium.querySelectorAll(".podium-slot").forEach((n) => {
       if (n !== hoveredSlot) n.classList.add("dim");
     });
     // Qualquer skin com hover fica acima de tudo
     card.style.zIndex = "9999";
     const spriteContainer = card.querySelector(".podium-sprite-container");
     if (spriteContainer) spriteContainer.style.zIndex = "9999";
     // CRÍTICO: Garante que tiles continuem atrás mesmo durante hover
     forceTilesBehind();
     show(card);
   }
   // Função para verificar se o pixel na posição do mouse é transparente
   function isPixelTransparent(img, x, y) {
     if (!img.complete || img.naturalWidth === 0) return true;
     try {
       const canvas = document.createElement("canvas");
       canvas.width = img.naturalWidth;
       canvas.height = img.naturalHeight;
       const ctx = canvas.getContext("2d");
       ctx.drawImage(img, 0, 0);
       // Calcula a posição relativa na imagem
       const rect = img.getBoundingClientRect();
       const scaleX = img.naturalWidth / rect.width;
       const scaleY = img.naturalHeight / rect.height;
       const imgX = Math.floor((x - rect.left) * scaleX);
       const imgY = Math.floor((y - rect.top) * scaleY);
       // Verifica se está dentro dos limites
       if (
         imgX < 0 ||
         imgX >= img.naturalWidth ||
         imgY < 0 ||
         imgY >= img.naturalHeight
       ) {
         return true;
       }
       // Obtém o pixel
       const pixelData = ctx.getImageData(imgX, imgY, 1, 1).data;
       const alpha = pixelData[3]; // Canal alpha
       return alpha < 10; // Considera transparente se alpha < 10
     } catch (e) {
       return false; // Em caso de erro, permite o hover
     }
   }
   // ---------- Clique YouTube (sem duplicar) ----------
   podium.addEventListener(
     "click",
     (ev) => {
       const slot = ev.target?.closest(".podium-slot[data-youtube]");
       if (!slot) return;
       const url = (slot.dataset.youtube || "").trim();
       if (!url) return;
       if (slot.dataset._opening === "1") return;
       slot.dataset._opening = "1";
       ev.preventDefault();
       ev.stopPropagation();
       ev.stopImmediatePropagation();
       try {
         window.open(url, "_blank", "noopener,noreferrer");
       } catch (e) {
         location.href = url;
       }
       setTimeout(() => {
         delete slot.dataset._opening;
       }, 500);
     },
     { capture: true }
   );
   podium.addEventListener(
     "keydown",
     (ev) => {
       if (ev.key !== "Enter" && ev.key !== " ") return;
       const slot = ev.target?.closest(".podium-slot[data-youtube]");
       if (!slot) return;
       const url = (slot.dataset.youtube || "").trim();
       if (!url) return;
       if (slot.dataset._opening === "1") return;
       slot.dataset._opening = "1";
       ev.preventDefault();
       ev.stopPropagation();
       ev.stopImmediatePropagation();
       try {
         window.open(url, "_blank", "noopener,noreferrer");
       } catch (e) {
         location.href = url;
       }
       setTimeout(() => {
         delete slot.dataset._opening;
       }, 500);
     },
     { capture: true }
   );
   // ---------- Hitbox pixel-perfect por sprite ----------
   // CRÍTICO: Move tiles para fora do sprite-container para separar contexto de empilhamento
   function moveTilesOutOfSpriteContainer() {
     const allSlots = Array.from(podium.querySelectorAll(".podium-slot"));
     allSlots.forEach((slot) => {
       const spriteContainer = slot.querySelector(".podium-sprite-container");
       const platform = slot.querySelector(".podium-platform");
       // Se o tile ainda está dentro do sprite-container, move para o slot
       if (platform && spriteContainer && spriteContainer.contains(platform)) {
         // Salva os estilos inline atuais antes de mover
         const currentRight = platform.style.right || "";
         const currentBottom = platform.style.bottom || "";
         const computedRight = getComputedStyle(platform).right;
         const computedBottom = getComputedStyle(platform).bottom;
         // Move o tile para fora do sprite-container, mas mantém dentro do slot
         slot.appendChild(platform);
         // Restaura a posição (os valores já estão corretos, apenas precisa manter)
         platform.style.position = "absolute";
         if (currentRight) {
           platform.style.right = currentRight;
         } else if (computedRight && computedRight !== "auto") {
           platform.style.right = computedRight;
         } else {
           // Usa o valor padrão do CSS
           platform.style.right = "-25px";
         }
         if (currentBottom) {
           platform.style.bottom = currentBottom;
         } else if (computedBottom && computedBottom !== "auto") {
           platform.style.bottom = computedBottom;
         } else {
           // Usa o valor padrão do CSS
           platform.style.bottom = "-15px";
         }
       }
     });
   }
   // CRÍTICO: Força todos os tiles a terem z-index negativo na inicialização
   function forceTilesBehind() {
     const allSlots = Array.from(podium.querySelectorAll(".podium-slot"));
     allSlots.forEach((slot) => {
       const platform = slot.querySelector(".podium-platform");
       const platformTop = slot.querySelector(".podium-platform-top");
       const platformImg = slot.querySelector(".podium-platform-top img");
       if (platform) {
         platform.style.zIndex = "0";
         platform.style.setProperty("z-index", "0", "important");
       }
       if (platformTop) {
         platformTop.style.zIndex = "0";
         platformTop.style.setProperty("z-index", "0", "important");
       }
       if (platformImg) {
         platformImg.style.zIndex = "0";
         platformImg.style.setProperty("z-index", "0", "important");
       }
     });
   }
   // Move tiles para fora do sprite-container primeiro
   moveTilesOutOfSpriteContainer();
   setTimeout(moveTilesOutOfSpriteContainer, 10);
   setTimeout(moveTilesOutOfSpriteContainer, 100);
   // Depois força z-index negativo
   forceTilesBehind();
   setTimeout(forceTilesBehind, 10);
   setTimeout(forceTilesBehind, 100);
   const slots = Array.from(podium.querySelectorAll(".podium-slot"));
   slots.forEach((slot) => {
     const spriteImg = slot.querySelector(".podium-sprite img");
     // Hitbox apenas na imagem do sprite, verificando transparência
     if (spriteImg) {
       spriteImg.addEventListener(
         "pointermove",
         (ev) => {
           if (!slot.hasAttribute("data-skin-tooltip")) return;
           // Verifica se o pixel é transparente
           if (isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
             // Se for transparente e estiver hovered, remove o hover
             if (hoveredSlot === slot) {
               setHovered(null);
             }
             return;
           }
           // Se não for transparente, ativa o hover
           if (hoveredSlot !== slot) {
             setHovered(slot);
           }
         },
         { passive: true }
       );
       spriteImg.addEventListener(
         "pointerenter",
         (ev) => {
           if (!slot.hasAttribute("data-skin-tooltip")) return;
           // Verifica transparência no enter também
           if (!isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
             setHovered(slot);
           }
         },
         { passive: true }
       );
       spriteImg.addEventListener(
         "pointerleave",
         (ev) => {
           const toCard =
             ev.relatedTarget &&
             ev.relatedTarget.closest &&
             ev.relatedTarget.closest(".podium-slot");
           if (toCard && podium.contains(toCard)) {
             // Se está indo para outro slot, verifica transparência
             const otherImg = toCard.querySelector(".podium-sprite img");
             if (
               otherImg &&
               ev.relatedTarget &&
               !isPixelTransparent(otherImg, ev.clientX, ev.clientY)
             ) {
               return; // Não remove hover se está indo para pixel não-transparente
             }
           }
           setHovered(null);
         },
         { passive: true }
       );
     }
   });
   podium.addEventListener(
     "pointerleave",
     () => {
       setHovered(null);
     },
     { passive: true }
   );
   // Só atualiza em scroll/resize, não em mousemove
   window.addEventListener(
     "scroll",
     () => {
       if (hoveredSlot) place(hoveredSlot);
     },
     true
   );
   window.addEventListener("resize", () => {
     if (hoveredSlot) place(hoveredSlot);
   });
   // Função para ajustar sombra ao tamanho exato da imagem do tile
   function updateShadows() {
     const platformTops = document.querySelectorAll(".podium-platform-top");
     platformTops.forEach((top, index) => {
       const img = top.querySelector("img");
       if (img) {
         const updateShadow = () => {
           // Usa naturalWidth/naturalHeight primeiro (mais rápido)
           let imgWidth = img.naturalWidth || img.offsetWidth || 0;
           let imgHeight = img.naturalHeight || img.offsetHeight || 0;
           // Se ainda não tem dimensões, tenta forçar o carregamento
           if (imgWidth === 0 || imgHeight === 0) {
             // Força o recálculo das dimensões
             imgWidth = img.naturalWidth || img.width || img.offsetWidth || 0;
             imgHeight =
               img.naturalHeight || img.height || img.offsetHeight || 0;
           }
           if (imgWidth > 0 && imgHeight > 0) {
             top.style.setProperty("--img-width", imgWidth + "px");
             top.style.setProperty("--img-height", imgHeight + "px");
           } else {
             // Se ainda não tem dimensões, agenda nova tentativa
             // Especialmente importante para a última skin que pode carregar por último
             setTimeout(() => {
               const retryWidth =
                 img.naturalWidth || img.offsetWidth || img.width || 0;
               const retryHeight =
                 img.naturalHeight || img.offsetHeight || img.height || 0;
               if (retryWidth > 0 && retryHeight > 0) {
                 top.style.setProperty("--img-width", retryWidth + "px");
                 top.style.setProperty("--img-height", retryHeight + "px");
               }
             }, 100 + index * 20); // Delay progressivo para cada tile
           }
         };
         // Tenta atualizar imediatamente
         updateShadow();
         // Se a imagem já carregou, atualiza novamente para garantir
         if (img.complete && img.naturalWidth > 0) {
           requestAnimationFrame(updateShadow);
         } else {
           // Usa 'load' e também verifica periodicamente
           img.addEventListener(
             "load",
             () => {
               requestAnimationFrame(updateShadow);
             },
             { once: true }
           );
           // Fallback: verifica após um tempo curto (com delay progressivo para última skin)
           setTimeout(() => {
             if (img.complete || img.naturalWidth > 0) {
               requestAnimationFrame(updateShadow);
             }
           }, 50 + index * 10);
           // Fallback adicional para garantir que a última skin seja atualizada
           if (index === platformTops.length - 1) {
             setTimeout(() => {
               updateShadow();
             }, 200);
             setTimeout(() => {
               updateShadow();
             }, 500);
           }
         }
       }
     });
   }
   // Executa imediatamente e também após DOMContentLoaded
   updateShadows();
   if (document.readyState === "loading") {
     document.addEventListener("DOMContentLoaded", updateShadows);
     window.addEventListener("load", updateShadows);
   } else {
     // Se já carregou, executa imediatamente e depois de um frame
     requestAnimationFrame(updateShadows);
   }
   // Garante que todas as imagens dos tiles sejam atualizadas após o carregamento completo
   window.addEventListener("load", () => {
     setTimeout(updateShadows, 100);
     setTimeout(updateShadows, 300);
     setTimeout(updateShadows, 500);
   });
   // Observa mudanças nas imagens
   if ("MutationObserver" in window) {
     const observer = new MutationObserver(() => {
       updateShadows();
     });
     observer.observe(podium, { childList: true, subtree: true });
   }
   // Observa quando imagens dos tiles são carregadas
   const tileImages = document.querySelectorAll(".podium-platform-top img");
   tileImages.forEach((img, index) => {
     if (img.complete) {
       // Se já carregou, força atualização
       setTimeout(() => updateShadows(), 50 + index * 20);
     } else {
       img.addEventListener(
         "load",
         () => {
           updateShadows();
         },
         { once: true }
       );
     }
   });
 })();

</script> <style>

 /* Container escuro para área de skins - igual ao content-card */
 .card-skins {
   width: min(1600px, 96vw);
   max-width: 96vw;
   margin: 10px auto;
   background: rgba(28, 28, 34, 0.95);
   border-radius: 12px;
   box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
   padding: 18px;
   z-index: 2;
   box-sizing: border-box;
   overflow-x: hidden;
   overflow-y: visible;
 }
 /* Regras globais para filhos do card-skins - igual ao content-card */
 .card-skins,
 .skins-podium {
   box-sizing: border-box;
   max-width: 100%;
 }
 .card-skins * {
   max-width: 100%;
   box-sizing: border-box;
 }
 /* Exceção: imagens do tile e sprite mantêm tamanho natural (exceto no mobile) */
 .podium-platform-top img,
 .podium-sprite img {
   max-width: none;
 }
 /* Podium de skins - layout isométrico */
 .skins-podium {
   display: flex;
   align-items: flex-end;
   /* Alinha todos os slots pelo bottom */
   justify-content: center;
   gap: 30px;
   padding: 20px 0 50px 0;
   /* Padding extra na parte inferior para os tiles */
   position: relative;
   width: 100%;
   flex-wrap: wrap;
   box-sizing: border-box;
   overflow-x: hidden;
   overflow-y: visible;
 }
 .podium-slot {
   position: relative;
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: flex-end;
   /* Alinha pelo bottom */
   cursor: pointer;
   transition: filter 0.14s ease, box-shadow 0.14s ease;
   flex-shrink: 0;
   max-width: 100%;
   box-sizing: border-box;
   overflow: visible;
   /* Permite que os tiles saiam do slot se necessário */
   /* Permite margin-left negativo para offset_x */
 }
 /* Z-index: sprites da direita passam na frente das da esquerda */
 /* Aplicado dinamicamente via JS, mas CSS base para primeiros slots */
 .podium-slot:nth-child(1) {
   z-index: 1;
   /* Esquerda: mais atrás */
 }
 .podium-slot:nth-child(2) {
   z-index: 2;
 }
 .podium-slot:nth-child(3) {
   z-index: 3;
 }
 .podium-slot:nth-child(4) {
   z-index: 4;
   /* Direita: mais na frente */
 }
 /* Z-index para sprite-containers: direita passa na frente da esquerda */
 /* IMPORTANTE: z-index alto para garantir que sprites sempre fiquem acima dos tiles (z-index negativo) */
 .podium-slot:nth-child(1) .podium-sprite-container {
   z-index: 1000 !important;
   /* Esquerda: mais atrás */
 }
 .podium-slot:nth-child(2) .podium-sprite-container {
   z-index: 2000 !important;
 }
 .podium-slot:nth-child(3) .podium-sprite-container {
   z-index: 3000 !important;
 }
 .podium-slot:nth-child(4) .podium-sprite-container {
   z-index: 4000 !important;
   /* Direita: mais na frente, acima de todos os tiles */
 }
 /* Hitbox baseada na imagem, não no container */
 .podium-slot>* {
   pointer-events: none;
 }
 /* Apenas a imagem do sprite tem hitbox - container não interfere */
 .podium-sprite img {
   pointer-events: auto;
 }
 /* Container e sprite não têm hitbox para não interferir */
 .podium-sprite-container,
 .podium-sprite {
   pointer-events: none;
 }
 /* Piso nunca tem hitbox */
 .podium-platform,
 .podium-platform-top,
 .podium-platform-top img {
   pointer-events: none !important;
 }
 /* Container do sprite - tamanho natural, não afetado pelo tile */
 .podium-sprite-container {
   position: relative;
   z-index: 10;
   display: flex;
   flex-direction: column;
   align-items: flex-end;
   /* Alinha pelo bottom (pés) - horizontalmente */
   justify-content: center;
   /* Centraliza horizontalmente */
   filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.5));
   transform: none !important;
   flex-shrink: 0;
   max-width: 100%;
   box-sizing: border-box;
   /* REMOVIDO isolation: isolate - estava criando contexto que impedia tiles de ficarem atrás */
 }
 /* Garante que TODAS as sprites fiquem acima de TODOS os tiles */
 /* IMPORTANTE: z-index mínimo de 1 para garantir que sprites sempre fiquem acima dos tiles (z-index negativo) */
 .podium-slot .podium-sprite-container {
   position: relative;
   z-index: 1 !important;
 }
 .podium-sprite {
   display: block;
   position: relative;
   transform: none !important;
   flex-shrink: 0;
 }
 .podium-sprite img {
   width: auto;
   height: auto;
   max-width: none;
   max-height: none;
   image-rendering: pixelated;
   image-rendering: -moz-crisp-edges;
   image-rendering: -webkit-optimize-contrast;
   image-rendering: crisp-edges;
   display: block;
   position: relative;
   z-index: 10 !important;
   /* Imagem sempre acima do piso (z-index maior que tiles) */
   transform: none !important;
   will-change: auto;
   flex-shrink: 0;
 }
 /* Tile isométrico nos pés da sprite - atrás da sprite */
 /* IMPORTANTE: z-index 0 para ficar acima do background do card-skins, mas abaixo das sprites (z-index 10-40) */
 .podium-platform {
   position: absolute;
   width: auto;
   height: auto;
   bottom: -15px;
   right: -25px;
   z-index: 0 !important;
   /* z-index 0 fica acima do background do card-skins, mas abaixo das sprites */
 }
 /* Todos os pisos com z-index 0 - acima do background, mas abaixo das sprites */
 .podium-slot .podium-platform {
   z-index: 0 !important;
 }
 /* CRÍTICO: Garante que tiles fiquem acima do background do card, mas abaixo de TODAS as sprites */
 .podium-slot .podium-platform,
 .podium-slot .podium-platform-top,
 .podium-slot .podium-platform-top img {
   /* z-index 0 garante que fiquem acima do background do card-skins */
   /* mas as sprites têm z-index 10-40, então ficam na frente */
   z-index: 0 !important;
 }
 /* Tile - usando imagem no tamanho natural */
 .podium-platform-top {
   position: absolute;
   width: auto;
   height: auto;
   transform-origin: center bottom;
   transform: rotateX(15deg);
   /* Inclinação fixa em 15 graus */
   z-index: 0 !important;
   /* z-index 0 fica acima do background do card, mas abaixo das sprites */
 }
 .podium-platform-top img {
   display: block;
   width: auto;
   height: auto;
   max-width: none;
   max-height: none;
   image-rendering: pixelated;
   image-rendering: -moz-crisp-edges;
   image-rendering: -webkit-optimize-contrast;
   image-rendering: crisp-edges;
   position: relative;
   z-index: 0 !important;
   /* z-index 0 fica acima do background do card, mas abaixo das sprites (z-index 10-40) */
   border: none !important;
   outline: none;
   box-shadow: none;
   opacity: 1 !important;
   /* Garante que a imagem do tile sempre esteja visível */
 }
 /* Sombra quadrada sólida - perfeitamente alinhada com a imagem */
 .podium-platform-top::before {
   content: "";
   position: absolute;
   top: 0;
   left: 0;
   width: var(--img-width, 100%);
   height: var(--img-height, 100%);
   background: rgba(0, 0, 0, 0.5);
   z-index: -1 !important;
   /* z-index -1 para ficar atrás da imagem do tile, mas ainda acima do background do card */
   transform: translate(3px, 3px);
   pointer-events: none;
   opacity: 0;
   transition: opacity 0.1s ease;
 }
 /* Mostra a sombra quando as dimensões estão definidas */
 .podium-platform-top[style*="--img-width"]::before {
   opacity: 1;
 }
 /* Sistema de hover - dim outras skins, destaque na hovered */
 .skins-podium.hovering .podium-slot.dim {
   filter: brightness(0.55) saturate(0.85);
   transition: filter 0.14s ease;
 }
 .skins-podium.hovering .podium-slot.hovered {
   filter: none;
 }
 /* CRÍTICO: Remove efeito de hover da imagem do piso (sem "borda fantasma") */
 .skins-podium.hovering .podium-slot.dim .podium-platform-top,
 .skins-podium.hovering .podium-slot.hovered .podium-platform-top,
 .skins-podium.hovering .podium-slot.dim .podium-platform-top img,
 .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
   filter: none !important;
   box-shadow: none !important;
 }
 /* Borda no tile quando hovered - apenas no container, não na imagem */
 .skins-podium.hovering .podium-slot.hovered .podium-platform-top {
   box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.12),
     0 10px 28px rgba(0, 0, 0, 0.45);
 }
 /* Remove sombra da imagem do tile no hover */
 .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
   box-shadow: none !important;
   filter: none !important;
 }
 /* Tooltip */
 .skin-tooltip {
   position: fixed;
   z-index: 9999;
   left: 0;
   top: 0;
   pointer-events: none;
   padding: 10px 12px;
   border-radius: 8px;
   background: rgba(40, 45, 60, 0.98);
   /* Azul escuro para melhor contraste */
   color: #f0f0f0;
   font-size: 13px;
   line-height: 1.4;
   box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6),
     0 0 0 1px rgba(80, 90, 120, 0.4),
     /* Borda azulada para definição */
     inset 0 0 0 1px rgba(255, 255, 255, 0.08);
   transform: translate(-9999px, -9999px);
   opacity: 0;
   transition: opacity 0.15s ease;
   text-align: center;
   white-space: normal;
   max-width: 280px;
   min-width: 200px;
 }
 .skin-tooltip b {
   color: #ffffff;
   font-weight: 600;
 }
 .podium-slot.is-clickable {
   cursor: pointer;
 }
 .podium-slot.is-clickable:focus {
   outline: 2px solid #156bc7;
   outline-offset: 2px;
 }
 /* Responsivo */
 @media (max-width: 1100px) {
   .skins-podium {
     gap: 24px;
   }
 }
 @media (max-width: 768px) {
   .card-skins {
     padding: 14px;
   }
   .skins-podium {
     gap: 20px;
     padding: 15px 0;
   }
 }
 @media (max-width: 600px) {
   .card-skins {
     box-sizing: border-box;
     max-width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right) - 16px);
     width: 100%;
     margin: 10px auto;
     padding: 12px;
     border-radius: 10px;
     overflow-x: hidden;
     overflow-y: visible;
   }
   .skins-podium {
     gap: 16px;
     padding: 10px 8px 50px 8px;
     /* Padding extra na parte inferior para os tiles */
     justify-content: center;
     overflow-y: visible;
   }
   .podium-slot {
     max-width: calc(50% - 8px);
     flex: 0 0 auto;
     min-width: 0;
   }
   .podium-sprite-container {
     max-width: 100%;
     min-width: 0;
   }
   .podium-sprite img {
     max-width: 100%;
     height: auto;
   }
   .podium-platform-top img {
     max-width: 100%;
     height: auto;
   }
 }
 @media (max-width: 400px) {
   .skins-podium {
     gap: 12px;
     padding-left: 4px;
     padding-right: 4px;
   }
   .podium-slot {
     max-width: calc(50% - 6px);
   }
 }

</style>