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

De Wiki Gla
Ir para navegação Ir para pesquisar
m (OTIMIZAÇÃO)
m
Linha 1: Linha 1:
<!-- SKINS SYSTEM -->
<!-- SKINS SYSTEM - Layout Isométrico -->
<script>
<script>
     (function initSkinCardsUI() {
     (function initSkinPodiumUI() {
         const wrapper = document.querySelector('.skins-carousel-wrapper');
         const podium = document.querySelector('.skins-podium');
        const carousel = wrapper?.querySelector('.skins-carousel');
         if (!podium || podium.dataset.wired) return;
        const left = wrapper?.querySelector('.skins-arrow.left');
         podium.dataset.wired = '1';
        const right = wrapper?.querySelector('.skins-arrow.right');
 
         if (!wrapper || !carousel || wrapper.dataset.wired) return;
         wrapper.dataset.wired = '1';


         // ---------- Tooltip único ----------
         // ---------- Tooltip único ----------
Linha 28: Linha 24:


         const tip = ensureTip();
         const tip = ensureTip();
         let hovered = null;
         let hoveredSlot = null;


         function place(card) {
         function place(card) {
             if (!card || tip.getAttribute('aria-hidden') === 'true') return;
             if (!card || tip.getAttribute('aria-hidden') === 'true') return;
             tip.style.transform = 'translate(-9999px,-9999px)';
             tip.style.transform = 'translate(-9999px,-9999px)';
            const r = card.getBoundingClientRect();
             const tr = tip.getBoundingClientRect();
             const tr = tip.getBoundingClientRect();
             let leftPos = Math.round(r.left + (r.width - tr.width) / 2);
 
            // Pega a posição da imagem do tile (piso) para centralizar
            const platformImg = card.querySelector('.podium-platform-top img');
            let platformRect = card.getBoundingClientRect();
            if (platformImg) {
                platformRect = platformImg.getBoundingClientRect();
            } else {
                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));
             leftPos = Math.max(8, Math.min(leftPos, window.innerWidth - tr.width - 8));
             let top = Math.round(r.top - tr.height - 10);
 
            if (top < 8) top = Math.round(r.bottom + 10);
            // Posiciona logo abaixo da imagem do tile
             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;
            }
 
             tip.style.transform = `translate(${leftPos}px, ${top}px)`;
             tip.style.transform = `translate(${leftPos}px, ${top}px)`;
         }
         }


         function show(card) {
         function show(card) {
             tip.innerHTML = card.getAttribute('data-skin-tooltip') || '';
             const tooltipText = card.getAttribute('data-skin-tooltip') || '';
            tip.innerHTML = tooltipText;
             tip.setAttribute('aria-hidden', 'false');
             tip.setAttribute('aria-hidden', 'false');
             place(card);
             place(card);
Linha 55: Linha 72:
         }
         }


         // ---------- Navegação (setas) ----------
         // Função para restaurar z-index original baseado na posição do slot
        function scrollAmt() {
        function restoreOriginalZIndex(slot) {
             return Math.round(carousel.clientWidth * 0.6);
            if (!slot) return;
 
            const allSlots = Array.from(podium.querySelectorAll('.podium-slot'));
            const slotIndex = allSlots.indexOf(slot);
 
            // Z-index invertido: esquerda (0) = mais alto, direita = mais baixo
            const originalZIndex = allSlots.length - slotIndex;
            const originalSpriteZIndex = (allSlots.length - slotIndex) * 1000;
 
            slot.style.zIndex = originalZIndex.toString();
             const spriteContainer = slot.querySelector('.podium-sprite-container');
            if (spriteContainer) spriteContainer.style.zIndex = originalSpriteZIndex.toString();
         }
         }


         function setState() {
         function setHovered(card) {
             const max = carousel.scrollWidth - carousel.clientWidth;
             if (hoveredSlot === card) return;
             const x = carousel.scrollLeft;
 
            const hasLeft = x > 5;
             if (hoveredSlot) {
             const hasRight = x < max - 5;
                hoveredSlot.classList.remove('hovered');
             if (left) left.style.display = hasLeft ? 'inline-block' : 'none';
                restoreOriginalZIndex(hoveredSlot);
             if (right) right.style.display = hasRight ? 'inline-block' : 'none';
             }
             wrapper.classList.toggle('has-left', hasLeft);
 
             wrapper.classList.toggle('has-right', hasRight);
             podium.classList.remove('hovering');
             carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
            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';
 
            show(card);
         }
         }


         function go(dir) {
        // Função para verificar se o pixel na posição do mouse é transparente
             const max = carousel.scrollWidth - carousel.clientWidth;
         function isPixelTransparent(img, x, y) {
            const next = dir < 0
             if (!img.complete || img.naturalWidth === 0) return true;
                 ? Math.max(0, carousel.scrollLeft - scrollAmt())
 
                 : Math.min(max, carousel.scrollLeft + scrollAmt());
            try {
            carousel.scrollTo({ left: next, behavior: 'smooth' });
                const canvas = document.createElement('canvas');
                canvas.width = img.naturalWidth;
                canvas.height = img.naturalHeight;
                const ctx = canvas.getContext('2d');
                 ctx.drawImage(img, 0, 0);
 
                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);
 
                if (imgX < 0 || imgX >= img.naturalWidth || imgY < 0 || imgY >= img.naturalHeight) {
                    return true;
                }
 
                const pixelData = ctx.getImageData(imgX, imgY, 1, 1).data;
                return pixelData[3] < 10;
            } catch (e) {
                return false;
            }
         }
         }
        left?.addEventListener('click', () => go(-1));
        right?.addEventListener('click', () => go(1));
        carousel.addEventListener('scroll', setState);
        new ResizeObserver(setState).observe(carousel);
        setState();


         // ---------- Abrir YouTube (sem duplicar) ----------
         // ---------- Abrir YouTube (sem duplicar) ----------
         carousel.addEventListener('click', (ev) => {
         podium.addEventListener('click', (ev) => {
             const card = ev.target?.closest('.skin-card[data-youtube]');
             const card = ev.target?.closest('.podium-slot[data-youtube]');
             if (!card) return;
             if (!card) return;
             const url = (card.dataset.youtube || '').trim();
             const url = (card.dataset.youtube || '').trim();
Linha 102: Linha 164:
         }, { capture: true });
         }, { capture: true });


         carousel.addEventListener('keydown', (ev) => {
         podium.addEventListener('keydown', (ev) => {
             if (ev.key !== 'Enter' && ev.key !== ' ') return;
             if (ev.key !== 'Enter' && ev.key !== ' ') return;
             const card = ev.target?.closest('.skin-card[data-youtube]');
             const card = ev.target?.closest('.podium-slot[data-youtube]');
             if (!card) return;
             if (!card) return;
             const url = (card.dataset.youtube || '').trim();
             const url = (card.dataset.youtube || '').trim();
Linha 118: Linha 180:
         }, { capture: true });
         }, { capture: true });


         // ---------- Hitbox de hover por carta ----------
         // ---------- Hitbox pixel-perfect de hover ----------
         function setHovered(card) {
         const slots = podium.querySelectorAll('.podium-slot');
            if (hovered === card) { place(card); return; }
        slots.forEach(slot => {
             if (hovered) hovered.classList.remove('hovered');
             const spriteImg = slot.querySelector('.podium-sprite img');
             carousel.classList.remove('hovering');
 
            carousel.querySelectorAll('.skin-card.dim').forEach(n => n.classList.remove('dim'));
             if (spriteImg) {
            if (!card) { hovered = null; hide(); return; }
                spriteImg.addEventListener('pointerenter', (ev) => {
            hovered = card;
                    if (!slot.hasAttribute('data-skin-tooltip')) return;
            hovered.classList.add('hovered');
                    if (!isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
            carousel.classList.add('hovering');
                        setHovered(slot);
            carousel.querySelectorAll('.skin-card').forEach(n => { if (n !== hovered) n.classList.add('dim'); });
                    }
            show(card);
                }, { passive: true });
        }
 
                spriteImg.addEventListener('pointermove', (ev) => {
                    if (!slot.hasAttribute('data-skin-tooltip')) return;
 
                    if (isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
                        if (hoveredSlot === slot) setHovered(null);
                    } else {
                        if (hoveredSlot !== slot) setHovered(slot);
                    }
                }, { passive: true });


        carousel.addEventListener('mouseleave', () => { setHovered(null); });
                spriteImg.addEventListener('pointerleave', (ev) => {
        carousel.addEventListener('mousemove', (ev) => {
                    const toCard = ev.relatedTarget?.closest?.('.podium-slot');
            const card = ev.target?.closest('.skin-card');
                    if (toCard && podium.contains(toCard)) {
            if (card && card.hasAttribute('data-skin-tooltip')) {
                        const otherImg = toCard.querySelector('.podium-sprite img');
                setHovered(card);
                        if (otherImg && ev.relatedTarget && !isPixelTransparent(otherImg, ev.clientX, ev.clientY)) {
            } else {
                            return;
                setHovered(null);
                        }
                    }
                    setHovered(null);
                }, { passive: true });
             }
             }
         });
         });


         window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
        podium.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
         window.addEventListener('resize', () => { if (hovered) place(hovered); });
         window.addEventListener('scroll', () => { if (hoveredSlot) place(hoveredSlot); }, true);
         window.addEventListener('resize', () => { if (hoveredSlot) place(hoveredSlot); });
     })();
     })();
</script>
</script>
<style>
<style>
     .skin-tooltip {
     .skins-podium {
         position: fixed;
         display: flex;
         z-index: 9999;
         align-items: flex-end;
        left: 0;
         justify-content: center;
        top: 0;
         gap: 30px;
        pointer-events: none;
         padding: 40px 20px;
        padding: 8px 10px;
         border-radius: 8px;
         background: rgba(28, 28, 34, .95);
         color: #eaeaea;
        font-size: 13px;
        line-height: 1.25;
        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 .12s ease;
        white-space: nowrap;
     }
     }


     .skin-tooltip b {
     .podium-slot {
         color: #fff;
         position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: flex-end;
        cursor: pointer;
        transition: filter 0.14s ease, box-shadow 0.14s ease;
     }
     }


     .skin-card .skin-sprite img {
    /* Z-index INVERTIDO: sprites da direita passam por trás das da esquerda */
         box-shadow: none !important;
     .podium-slot:nth-child(1) {
         z-index: 4;
     }
     }


     .card-skins,
     .podium-slot:nth-child(2) {
    .skins-carousel {
         z-index: 3;
         overflow: visible !important;
     }
     }


     .skin-card.is-clickable {
     .podium-slot:nth-child(3) {
         cursor: pointer;
         z-index: 2;
     }
     }


     .skin-card.is-clickable:focus {
     .podium-slot:nth-child(4) {
         outline: 2px solid #156bc7;
         z-index: 1;
        outline-offset: 2px;
     }
     }


     .skin-card {
     .podium-slot:nth-child(5) {
         position: relative;
         z-index: 1;
     }
     }


     .skins-carousel {
    /* Z-index INVERTIDO: sprites da direita passam por trás das da esquerda */
         position: relative;
     .podium-slot:nth-child(1) .podium-sprite-container {
         z-index: 4000;
     }
     }


     .skins-carousel.hovering .skin-card.dim {
     .podium-slot:nth-child(2) .podium-sprite-container {
        filter: brightness(.55) saturate(.85);
         z-index: 3000;
         transition: filter .14s ease, transform .14s ease;
     }
     }


     .skins-carousel.hovering .skin-card.hovered {
     .podium-slot:nth-child(3) .podium-sprite-container {
         filter: none;
         z-index: 2000;
        transform: none;
        box-shadow: 0 0 0 2px rgba(255, 255, 255, .12), 0 10px 28px rgba(0, 0, 0, .45);
     }
     }


     .skin-tooltip {
     .podium-slot:nth-child(4) .podium-sprite-container {
         pointer-events: none;
         z-index: 1000;
     }
     }


     .skins-carousel .skin-card {
     .podium-slot:nth-child(5) .podium-sprite-container {
         transition: filter .14s ease, box-shadow .14s ease;
         z-index: 1000;
     }
     }


     .skin-card .skin-banner {
    /* Hitbox baseada na imagem, não no container */
         z-index: 0;
     .podium-slot>* {
         pointer-events: none;
     }
     }


     .skin-card .skin-sprite {
     .podium-sprite img {
         z-index: 2;
         pointer-events: auto;
     }
     }


     .skin-badge {
     .podium-sprite-container,
         display: none !important;
    .podium-sprite {
         pointer-events: none;
     }
     }


     .skin-tooltip,
     .podium-platform,
     .skill-tooltip {
     .podium-platform-top,
        text-align: center !important;
    .podium-platform-top img {
        white-space: normal !important;
         pointer-events: none !important;
         max-width: 380px !important;
     }
     }


     .skins-carousel.hover-mode .skin-card.hovered {
     .podium-sprite-container {
         filter: none !important;
        position: relative;
        z-index: 10;
        display: flex;
        align-items: flex-end;
        justify-content: center;
         filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.5));
         transform: none !important;
         transform: none !important;
         box-shadow: 0 0 0 2px rgba(255, 255, 255, .12), 0 10px 28px rgba(0, 0, 0, .45) !important;
         flex-shrink: 0;
        width: 100%;
     }
     }


     .skins-carousel .skin-card {
     .podium-sprite {
         transition: filter .14s ease, box-shadow .14s ease !important;
         display: block;
        position: relative;
        transform: none !important;
        flex-shrink: 0;
     }
     }
</style>


<!-- DROP-IN V2: Skins com hitbox por carta e clique único -->
    .podium-sprite img {
<script>
        width: auto;
    (function initSkinCardsUI_v2() {
        height: auto;
         const wrapper = document.querySelector('.skins-carousel-wrapper');
        max-width: none;
         const carousel = wrapper?.querySelector('.skins-carousel');
        max-height: none;
         const left = wrapper?.querySelector('.skins-arrow.left');
        image-rendering: pixelated;
         const right = wrapper?.querySelector('.skins-arrow.right');
        image-rendering: -moz-crisp-edges;
        image-rendering: -webkit-optimize-contrast;
         image-rendering: crisp-edges;
         display: block;
        position: relative;
        z-index: 100 !important;
         transform: none !important;
         flex-shrink: 0;
    }


         if (!wrapper || !carousel) return;
    .podium-platform {
         if (wrapper.dataset.skinsV2Wired === '1') return;
        position: absolute;
         wrapper.dataset.skinsV2Wired = '1';
         width: auto;
        height: auto;
        bottom: -15px;
         right: -25px;
         z-index: 0 !important;
    }


        // ---------- Tooltip único ----------
    .podium-platform-top {
         function ensureTip() {
         position: absolute;
            let tip = document.querySelector('.skin-tooltip');
        width: auto;
            if (!tip) {
        height: auto;
                tip = document.createElement('div');
        transform-origin: center bottom;
                tip.className = 'skin-tooltip';
        transform: rotateX(15deg);
                tip.setAttribute('role', 'tooltip');
        z-index: -1 !important;
                tip.setAttribute('aria-hidden', 'true');
    }
                Object.assign(tip.style, {
                    position: 'fixed',
                    transform: 'translate(-9999px,-9999px)',
                    opacity: '0',
                    transition: 'opacity .12s ease',
                    pointerEvents: 'none'
                });
                document.body.appendChild(tip);
            }
            return tip;
        }


         const tip = ensureTip();
    .podium-platform-top img {
        let hovered = null;
        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: 1;
        border: none !important;
        outline: none;
        box-shadow: none;
        filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.5));
    }


        function place(card) {
    .skins-podium.hovering .podium-slot.dim {
            if (!card || tip.getAttribute('aria-hidden') === 'true') return;
         filter: brightness(.55) saturate(.85);
            tip.style.transform = 'translate(-9999px,-9999px)';
         transition: filter .14s ease;
            const r = card.getBoundingClientRect();
            const tr = tip.getBoundingClientRect();
            let leftPos = Math.round(r.left + (r.width - tr.width) / 2);
            leftPos = Math.max(8, Math.min(leftPos, window.innerWidth - tr.width - 8));
            let top = Math.round(r.top - tr.height - 10);
            if (top < 8) top = Math.round(r.bottom + 10);
            tip.style.transform = `translate(${leftPos}px, ${top}px)`;
        }
 
        function show(card) {
            tip.innerHTML = card.getAttribute('data-skin-tooltip') || '';
            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)';
        }
 
        // ---------- Navegação (setas) ----------
        function scrollAmt() {
            return Math.round(carousel.clientWidth * 0.6);
        }
 
        function setState() {
            const max = carousel.scrollWidth - carousel.clientWidth;
            const x = carousel.scrollLeft;
            const hasLeft = x > 5;
            const hasRight = x < max - 5;
            if (left) left.style.display = hasLeft ? 'inline-block' : 'none';
            if (right) right.style.display = hasRight ? 'inline-block' : 'none';
            wrapper.classList.toggle('has-left', hasLeft);
            wrapper.classList.toggle('has-right', hasRight);
            carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
        }
 
        function go(dir) {
            const max = carousel.scrollWidth - carousel.clientWidth;
            const next = dir < 0
                ? Math.max(0, carousel.scrollLeft - scrollAmt())
                : Math.min(max, carousel.scrollLeft + scrollAmt());
            carousel.scrollTo({ left: next, behavior: 'smooth' });
        }
 
        left?.addEventListener('click', () => go(-1));
        right?.addEventListener('click', () => go(1));
        carousel.addEventListener('scroll', setState);
        new ResizeObserver(setState).observe(carousel);
        setState();
 
        // ---------- Click por carta (YouTube 1x) ----------
        const cards = Array.from(carousel.querySelectorAll('.skin-card'));
        cards.forEach(card => {
            card.setAttribute('tabindex', '0');
            if (card.dataset.youtube) card.setAttribute('role', 'button');
 
            card.addEventListener('click', (ev) => {
                const url = (card.dataset.youtube || '').trim();
                if (!url) return;
                if (card.dataset._opening === '1') return;
                card.dataset._opening = '1';
                ev.preventDefault();
                ev.stopPropagation();
                try { window.open(url, '_blank', 'noopener,noreferrer'); }
                catch (e) { location.href = url; }
                setTimeout(() => { delete card.dataset._opening; }, 400);
            });
 
            card.addEventListener('keydown', (ev) => {
                if (ev.key !== 'Enter' && ev.key !== ' ') return;
                const url = (card.dataset.youtube || '').trim();
                if (!url) return;
                if (card.dataset._opening === '1') return;
                card.dataset._opening = '1';
                ev.preventDefault();
                ev.stopPropagation();
                try { window.open(url, '_blank', 'noopener,noreferrer'); }
                catch (e) { location.href = url; }
                setTimeout(() => { delete card.dataset._opening; }, 400);
            });
        });
 
        // ---------- Hitbox real de hover ----------
        function setHovered(card) {
            if (hovered === card) { place(card); return; }
            if (hovered) hovered.classList.remove('hovered');
            carousel.classList.remove('hovering');
            carousel.querySelectorAll('.skin-card.dim').forEach(n => n.classList.remove('dim'));
            if (!card) { hovered = null; hide(); return; }
            hovered = card;
            hovered.classList.add('hovered');
            carousel.classList.add('hovering');
            carousel.querySelectorAll('.skin-card').forEach(n => { if (n !== hovered) n.classList.add('dim'); });
            show(card);
        }
 
         cards.forEach(card => {
            card.addEventListener('pointerenter', () => {
                if (card.hasAttribute('data-skin-tooltip')) setHovered(card);
                else setHovered(null);
            }, { passive: true });
 
            card.addEventListener('pointerleave', (ev) => {
                const toCard = ev.relatedTarget && ev.relatedTarget.closest && ev.relatedTarget.closest('.skin-card');
                if (toCard && carousel.contains(toCard)) return;
                setHovered(null);
            }, { passive: true });
        });
 
         carousel.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
        window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
        window.addEventListener('resize', () => { if (hovered) place(hovered); });
    })();
</script>
 
<style>
    .card-skins,
    .skins-carousel {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
        gap: 12px;
        align-items: start;
        justify-items: center;
        width: 100%;
        padding: 8px 4px;
        box-sizing: border-box;
        overflow-x: hidden;
     }
     }


     .skin-card {
     .skins-podium.hovering .podium-slot.hovered {
         position: relative;
         filter: none;
        width: 100%;
        max-width: 240px;
        min-width: 120px;
        aspect-ratio: 1 / 1;
        border-radius: 12px;
        overflow: hidden;
        box-shadow: 7px 5px 10px rgb(0 0 0 / 45%);
        background: #0f0f12;
        display: grid;
        place-items: center;
        box-sizing: border-box;
     }
     }


     .skin-card .skin-banner {
     .skins-podium.hovering .podium-slot.hovered .podium-platform-top {
         position: absolute;
         box-shadow:
        inset: 0;
            0 0 0 2px rgba(255, 255, 255, .12),
        z-index: 0;
            0 10px 28px rgba(0, 0, 0, .45);
        overflow: hidden;
     }
     }


     .skin-card .skin-banner img {
     .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
         width: 100%;
         box-shadow: none !important;
         height: 100%;
         filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.5)) !important;
        object-fit: cover;
        object-position: center;
        display: block;
     }
     }


     .skin-card .skin-sprite {
     .skin-tooltip {
         position: relative;
         position: fixed;
         z-index: 2;
         z-index: 9999;
        display: flex;
         left: 0;
        align-items: center;
         top: 0;
        justify-content: center;
         width: 90%;
         height: 90%;
         pointer-events: none;
         pointer-events: none;
        padding: 10px 12px;
        border-radius: 8px;
        background: rgba(28, 28, 34, .98);
        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-card .skin-sprite img {
     .skin-tooltip b {
         width: 100%;
         color: #fff;
        height: 100%;
        aspect-ratio: 1 / 1;
        object-fit: contain;
        transform-origin: center;
        transform: scale(1.02);
        display: block;
        filter: drop-shadow(0 8px 18px rgba(0, 0, 0, .6));
        box-shadow: 0 0 0 2px rgba(200, 200, 200, 0.85);
        border-radius: 8px;
     }
     }


     @media (max-width: 820px) {
     .podium-slot.is-clickable {
        cursor: pointer;
    }


        .card-skins,
    .podium-slot.is-clickable:focus {
        .skins-carousel {
        outline: 2px solid #156bc7;
            grid-template-columns: repeat(auto-fill, minmax(120px, 160px));
         outline-offset: 2px;
            justify-content: center;
         }
 
        .skin-card {
            max-width: 200px;
        }
     }
     }


     @media (max-width: 1100px) {
     @media (max-width: 1024px) {
         .video-container {
         .skins-podium {
             margin: 0 auto;
             gap: 24px;
            justify-self: center;
            align-self: center;
            display: flex;
            justify-content: center;
        }
 
        .video-container>video {
            margin: 0 auto;
            display: block;
         }
         }
     }
     }


     @media (max-width: 600px) {
     @media (max-width: 768px) {
         .desc-box {
         .skins-podium {
             overflow: visible !important;
             flex-wrap: wrap;
            height: auto !important;
             gap: 20px;
            min-height: 0 !important;
            align-items: stretch !important;
        }
 
        .card-skins,
        .skins-carousel {
             overflow: visible !important;
         }
         }
     }
     }
</style>
</style>

Edição das 18h34min de 24 de dezembro de 2025

<script>

   (function initSkinPodiumUI() {
       const podium = document.querySelector('.skins-podium');
       if (!podium || podium.dataset.wired) return;
       podium.dataset.wired = '1';
       // ---------- 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 .12s ease';
               document.body.appendChild(tip);
           }
           return tip;
       }
       const tip = ensureTip();
       let hoveredSlot = null;
       function place(card) {
           if (!card || tip.getAttribute('aria-hidden') === 'true') return;
           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();
           if (platformImg) {
               platformRect = platformImg.getBoundingClientRect();
           } else {
               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
           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;
           }
           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;
           const allSlots = Array.from(podium.querySelectorAll('.podium-slot'));
           const slotIndex = allSlots.indexOf(slot);
           // Z-index invertido: esquerda (0) = mais alto, direita = mais baixo
           const originalZIndex = allSlots.length - slotIndex;
           const originalSpriteZIndex = (allSlots.length - slotIndex) * 1000;
           slot.style.zIndex = originalZIndex.toString();
           const spriteContainer = slot.querySelector('.podium-sprite-container');
           if (spriteContainer) spriteContainer.style.zIndex = originalSpriteZIndex.toString();
       }
       function setHovered(card) {
           if (hoveredSlot === card) return;
           if (hoveredSlot) {
               hoveredSlot.classList.remove('hovered');
               restoreOriginalZIndex(hoveredSlot);
           }
           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';
           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);
               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);
               if (imgX < 0 || imgX >= img.naturalWidth || imgY < 0 || imgY >= img.naturalHeight) {
                   return true;
               }
               const pixelData = ctx.getImageData(imgX, imgY, 1, 1).data;
               return pixelData[3] < 10;
           } catch (e) {
               return false;
           }
       }
       // ---------- Abrir YouTube (sem duplicar) ----------
       podium.addEventListener('click', (ev) => {
           const card = ev.target?.closest('.podium-slot[data-youtube]');
           if (!card) return;
           const url = (card.dataset.youtube || ).trim();
           if (!url) return;
           if (card.dataset._opening === '1') return;
           card.dataset._opening = '1';
           ev.preventDefault();
           ev.stopPropagation();
           ev.stopImmediatePropagation();
           try { window.open(url, '_blank', 'noopener,noreferrer'); }
           catch (e) { location.href = url; }
           setTimeout(() => { delete card.dataset._opening; }, 500);
       }, { capture: true });
       podium.addEventListener('keydown', (ev) => {
           if (ev.key !== 'Enter' && ev.key !== ' ') return;
           const card = ev.target?.closest('.podium-slot[data-youtube]');
           if (!card) return;
           const url = (card.dataset.youtube || ).trim();
           if (!url) return;
           if (card.dataset._opening === '1') return;
           card.dataset._opening = '1';
           ev.preventDefault();
           ev.stopPropagation();
           ev.stopImmediatePropagation();
           try { window.open(url, '_blank', 'noopener,noreferrer'); }
           catch (e) { location.href = url; }
           setTimeout(() => { delete card.dataset._opening; }, 500);
       }, { capture: true });
       // ---------- Hitbox pixel-perfect de hover ----------
       const slots = podium.querySelectorAll('.podium-slot');
       slots.forEach(slot => {
           const spriteImg = slot.querySelector('.podium-sprite img');
           if (spriteImg) {
               spriteImg.addEventListener('pointerenter', (ev) => {
                   if (!slot.hasAttribute('data-skin-tooltip')) return;
                   if (!isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
                       setHovered(slot);
                   }
               }, { passive: true });
               spriteImg.addEventListener('pointermove', (ev) => {
                   if (!slot.hasAttribute('data-skin-tooltip')) return;
                   if (isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
                       if (hoveredSlot === slot) setHovered(null);
                   } else {
                       if (hoveredSlot !== slot) setHovered(slot);
                   }
               }, { passive: true });
               spriteImg.addEventListener('pointerleave', (ev) => {
                   const toCard = ev.relatedTarget?.closest?.('.podium-slot');
                   if (toCard && podium.contains(toCard)) {
                       const otherImg = toCard.querySelector('.podium-sprite img');
                       if (otherImg && ev.relatedTarget && !isPixelTransparent(otherImg, ev.clientX, ev.clientY)) {
                           return;
                       }
                   }
                   setHovered(null);
               }, { passive: true });
           }
       });
       podium.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
       window.addEventListener('scroll', () => { if (hoveredSlot) place(hoveredSlot); }, true);
       window.addEventListener('resize', () => { if (hoveredSlot) place(hoveredSlot); });
   })();

</script> <style>

   .skins-podium {
       display: flex;
       align-items: flex-end;
       justify-content: center;
       gap: 30px;
       padding: 40px 20px;
   }
   .podium-slot {
       position: relative;
       display: flex;
       flex-direction: column;
       align-items: center;
       justify-content: flex-end;
       cursor: pointer;
       transition: filter 0.14s ease, box-shadow 0.14s ease;
   }
   /* Z-index INVERTIDO: sprites da direita passam por trás das da esquerda */
   .podium-slot:nth-child(1) {
       z-index: 4;
   }
   .podium-slot:nth-child(2) {
       z-index: 3;
   }
   .podium-slot:nth-child(3) {
       z-index: 2;
   }
   .podium-slot:nth-child(4) {
       z-index: 1;
   }
   .podium-slot:nth-child(5) {
       z-index: 1;
   }
   /* Z-index INVERTIDO: sprites da direita passam por trás das da esquerda */
   .podium-slot:nth-child(1) .podium-sprite-container {
       z-index: 4000;
   }
   .podium-slot:nth-child(2) .podium-sprite-container {
       z-index: 3000;
   }
   .podium-slot:nth-child(3) .podium-sprite-container {
       z-index: 2000;
   }
   .podium-slot:nth-child(4) .podium-sprite-container {
       z-index: 1000;
   }
   .podium-slot:nth-child(5) .podium-sprite-container {
       z-index: 1000;
   }
   /* Hitbox baseada na imagem, não no container */
   .podium-slot>* {
       pointer-events: none;
   }
   .podium-sprite img {
       pointer-events: auto;
   }
   .podium-sprite-container,
   .podium-sprite {
       pointer-events: none;
   }
   .podium-platform,
   .podium-platform-top,
   .podium-platform-top img {
       pointer-events: none !important;
   }
   .podium-sprite-container {
       position: relative;
       z-index: 10;
       display: flex;
       align-items: flex-end;
       justify-content: center;
       filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.5));
       transform: none !important;
       flex-shrink: 0;
       width: 100%;
   }
   .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: 100 !important;
       transform: none !important;
       flex-shrink: 0;
   }
   .podium-platform {
       position: absolute;
       width: auto;
       height: auto;
       bottom: -15px;
       right: -25px;
       z-index: 0 !important;
   }
   .podium-platform-top {
       position: absolute;
       width: auto;
       height: auto;
       transform-origin: center bottom;
       transform: rotateX(15deg);
       z-index: -1 !important;
   }
   .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: 1;
       border: none !important;
       outline: none;
       box-shadow: none;
       filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.5));
   }
   .skins-podium.hovering .podium-slot.dim {
       filter: brightness(.55) saturate(.85);
       transition: filter .14s ease;
   }
   .skins-podium.hovering .podium-slot.hovered {
       filter: none;
   }
   .skins-podium.hovering .podium-slot.hovered .podium-platform-top {
       box-shadow:
           0 0 0 2px rgba(255, 255, 255, .12),
           0 10px 28px rgba(0, 0, 0, .45);
   }
   .skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
       box-shadow: none !important;
       filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.5)) !important;
   }
   .skin-tooltip {
       position: fixed;
       z-index: 9999;
       left: 0;
       top: 0;
       pointer-events: none;
       padding: 10px 12px;
       border-radius: 8px;
       background: rgba(28, 28, 34, .98);
       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 {
       color: #fff;
   }
   .podium-slot.is-clickable {
       cursor: pointer;
   }
   .podium-slot.is-clickable:focus {
       outline: 2px solid #156bc7;
       outline-offset: 2px;
   }
   @media (max-width: 1024px) {
       .skins-podium {
           gap: 24px;
       }
   }
   @media (max-width: 768px) {
       .skins-podium {
           flex-wrap: wrap;
           gap: 20px;
       }
   }

</style>