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

De Wiki Gla
Ir para navegação Ir para pesquisar
(Criou página com '<!-- =========================== SKINS SYSTEM =========================== --> <script> (function initSkinCardsUI() { const wrapper = document.querySelect...')
 
m
 
Linha 1: Linha 1:
<!-- ===========================
<!-- SKINS SYSTEM -->
    SKINS SYSTEM
    =========================== -->
<script>
<script>
     (function initSkinCardsUI() {
     (function initSkinCardsUI() {
Linha 8: Linha 6:
         const left = wrapper?.querySelector('.skins-arrow.left');
         const left = wrapper?.querySelector('.skins-arrow.left');
         const right = wrapper?.querySelector('.skins-arrow.right');
         const right = wrapper?.querySelector('.skins-arrow.right');
         if (!wrapper || !carousel || wrapper.dataset.wired) return;
         if (!wrapper || !carousel || wrapper.dataset.wired) return;
         wrapper.dataset.wired = '1';
         wrapper.dataset.wired = '1';
Linha 27: Linha 26:
             return tip;
             return tip;
         }
         }
         const tip = ensureTip();
         const tip = ensureTip();
         let hovered = null;
         let hovered = null;
Linha 32: Linha 32:
         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)'; // reset antes de medir
             tip.style.transform = 'translate(-9999px,-9999px)';
             const r = card.getBoundingClientRect();
             const r = card.getBoundingClientRect();
             const tr = tip.getBoundingClientRect();
             const tr = tip.getBoundingClientRect();
             let left = Math.round(r.left + (r.width - tr.width) / 2);
             let leftPos = Math.round(r.left + (r.width - tr.width) / 2);
             left = Math.max(8, Math.min(left, 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);
             let top = Math.round(r.top - tr.height - 10);
             if (top < 8) top = Math.round(r.bottom + 10);
             if (top < 8) top = Math.round(r.bottom + 10);
             tip.style.transform = `translate(${left}px, ${top}px)`;
             tip.style.transform = `translate(${leftPos}px, ${top}px)`;
         }
         }
         function show(card) {
         function show(card) {
             tip.innerHTML = card.getAttribute('data-skin-tooltip') || '';
             tip.innerHTML = card.getAttribute('data-skin-tooltip') || '';
Linha 47: Linha 48:
             tip.style.opacity = '1';
             tip.style.opacity = '1';
         }
         }
         function hide() {
         function hide() {
             tip.setAttribute('aria-hidden', 'true');
             tip.setAttribute('aria-hidden', 'true');
Linha 54: Linha 56:


         // ---------- Navegação (setas) ----------
         // ---------- Navegação (setas) ----------
         function scrollAmt() { return Math.round(carousel.clientWidth * 0.6); }
         function scrollAmt() {
            return Math.round(carousel.clientWidth * 0.6);
        }
 
         function setState() {
         function setState() {
             const max = carousel.scrollWidth - carousel.clientWidth;
             const max = carousel.scrollWidth - carousel.clientWidth;
             const x = carousel.scrollLeft;
             const x = carousel.scrollLeft;
             const hasLeft = x > 5, hasRight = x < max - 5;
             const hasLeft = x > 5;
            const hasRight = x < max - 5;
             if (left) left.style.display = hasLeft ? 'inline-block' : 'none';
             if (left) left.style.display = hasLeft ? 'inline-block' : 'none';
             if (right) right.style.display = hasRight ? 'inline-block' : 'none';
             if (right) right.style.display = hasRight ? 'inline-block' : 'none';
Linha 65: Linha 71:
             carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
             carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
         }
         }
         function go(dir) {
         function go(dir) {
             const max = carousel.scrollWidth - carousel.clientWidth;
             const max = carousel.scrollWidth - carousel.clientWidth;
Linha 72: Linha 79:
             carousel.scrollTo({ left: next, behavior: 'smooth' });
             carousel.scrollTo({ left: next, behavior: 'smooth' });
         }
         }
         left?.addEventListener('click', () => go(-1));
         left?.addEventListener('click', () => go(-1));
         right?.addEventListener('click', () => go(1));
         right?.addEventListener('click', () => go(1));
Linha 84: Linha 92:
             const url = (card.dataset.youtube || '').trim();
             const url = (card.dataset.youtube || '').trim();
             if (!url) return;
             if (!url) return;
             if (card.dataset._opening === '1') return;       // de-dupe
             if (card.dataset._opening === '1') return;
             card.dataset._opening = '1';
             card.dataset._opening = '1';
             ev.preventDefault();
             ev.preventDefault();
             ev.stopPropagation();
             ev.stopPropagation();
             ev.stopImmediatePropagation();
             ev.stopImmediatePropagation();
             try { window.open(url, '_blank', 'noopener,noreferrer'); }
             try { window.open(url, '_blank', 'noopener,noreferrer'); }
             catch (e) { location.href = url; }
             catch (e) { location.href = url; }
             setTimeout(() => { delete card.dataset._opening; }, 500);
             setTimeout(() => { delete card.dataset._opening; }, 500);
         }, { capture: true });
         }, { capture: true });
Linha 105: Linha 110:
             if (card.dataset._opening === '1') return;
             if (card.dataset._opening === '1') return;
             card.dataset._opening = '1';
             card.dataset._opening = '1';
             ev.preventDefault();
             ev.preventDefault();
             ev.stopPropagation();
             ev.stopPropagation();
             ev.stopImmediatePropagation();
             ev.stopImmediatePropagation();
             try { window.open(url, '_blank', 'noopener,noreferrer'); }
             try { window.open(url, '_blank', 'noopener,noreferrer'); }
             catch (e) { location.href = url; }
             catch (e) { location.href = url; }
             setTimeout(() => { delete card.dataset._opening; }, 500);
             setTimeout(() => { delete card.dataset._opening; }, 500);
         }, { capture: true });
         }, { capture: true });


         // ---------- Hitbox de hover por carta (sem escurecer fora) ----------
         // ---------- Hitbox de hover por carta ----------
         function setHovered(card) {
         function setHovered(card) {
             if (hovered === card) { place(card); return; }
             if (hovered === card) { place(card); return; }
            // limpa estado anterior
             if (hovered) hovered.classList.remove('hovered');
             if (hovered) hovered.classList.remove('hovered');
             carousel.classList.remove('hovering');
             carousel.classList.remove('hovering');
             carousel.querySelectorAll('.skin-card.dim').forEach(n => n.classList.remove('dim'));
             carousel.querySelectorAll('.skin-card.dim').forEach(n => n.classList.remove('dim'));
             if (!card) { hovered = null; hide(); return; }
             if (!card) { hovered = null; hide(); return; }
             hovered = card;
             hovered = card;
             hovered.classList.add('hovered');
             hovered.classList.add('hovered');
Linha 140: Linha 138:
                 setHovered(card);
                 setHovered(card);
             } else {
             } else {
                 setHovered(null); // fora da carta => nada de dim, nada de tooltip
                 setHovered(null);
             }
             }
         });
         });
         window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
         window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
         window.addEventListener('resize', () => { if (hovered) place(hovered); });
         window.addEventListener('resize', () => { if (hovered) place(hovered); });
     })();
     })();
</script>
</script>
<!-- ===========================
    SKINS STYLES
    =========================== -->
<style>
<style>
    /* ===========================
  SKINS: Tooltip novo
  =========================== */
     .skin-tooltip {
     .skin-tooltip {
         position: fixed;
         position: fixed;
Linha 178: Linha 170:
     }
     }


    /* Remover borda branca interna do quadro da sprite */
     .skin-card .skin-sprite img {
     .skin-card .skin-sprite img {
         box-shadow: none !important;
         box-shadow: none !important;
     }
     }


    /* Garantir que a sombra das cards não seja cortada */
     .card-skins,
     .card-skins,
     .skins-carousel {
     .skins-carousel {
Linha 189: Linha 179:
     }
     }


    /* Acessibilidade/feedback de click quando há youtube */
     .skin-card.is-clickable {
     .skin-card.is-clickable {
         cursor: pointer;
         cursor: pointer;
Linha 199: Linha 188:
     }
     }


    /* badge "onde obter" */
     .skin-card {
     .skin-card {
         position: relative;
         position: relative;
Linha 257: Linha 245:
</style>
</style>


<!-- DROP-IN V2: Skins com hitbox por carta e clique único -->
<script>
<script>
    /* === DROP-IN estável: Skins com hitbox por carta e clique único === */
     (function initSkinCardsUI_v2() {
     (function initSkinCardsUI_v2() {
         const wrapper = document.querySelector('.skins-carousel-wrapper');
         const wrapper = document.querySelector('.skins-carousel-wrapper');
Linha 264: Linha 252:
         const left = wrapper?.querySelector('.skins-arrow.left');
         const left = wrapper?.querySelector('.skins-arrow.left');
         const right = wrapper?.querySelector('.skins-arrow.right');
         const right = wrapper?.querySelector('.skins-arrow.right');
         if (!wrapper || !carousel) return;
         if (!wrapper || !carousel) return;
         if (wrapper.dataset.skinsV2Wired === '1') return;   // evita duplicar
         if (wrapper.dataset.skinsV2Wired === '1') return;
         wrapper.dataset.skinsV2Wired = '1';
         wrapper.dataset.skinsV2Wired = '1';


         /* ---------- Tooltip único (não captura ponteiro) ---------- */
         // ---------- Tooltip único ----------
         function ensureTip() {
         function ensureTip() {
             let tip = document.querySelector('.skin-tooltip');
             let tip = document.querySelector('.skin-tooltip');
Linha 277: Linha 266:
                 tip.setAttribute('aria-hidden', 'true');
                 tip.setAttribute('aria-hidden', 'true');
                 Object.assign(tip.style, {
                 Object.assign(tip.style, {
                     position: 'fixed', transform: 'translate(-9999px,-9999px)',
                     position: 'fixed',
                     opacity: '0', transition: 'opacity .12s ease', pointerEvents: 'none'
                    transform: 'translate(-9999px,-9999px)',
                     opacity: '0',
                    transition: 'opacity .12s ease',
                    pointerEvents: 'none'
                 });
                 });
                 document.body.appendChild(tip);
                 document.body.appendChild(tip);
Linha 284: Linha 276:
             return tip;
             return tip;
         }
         }
         const tip = ensureTip();
         const tip = ensureTip();
         let hovered = null;
         let hovered = null;
Linha 289: Linha 282:
         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)'; // reset
             tip.style.transform = 'translate(-9999px,-9999px)';
             const r = card.getBoundingClientRect();
             const r = card.getBoundingClientRect();
             const tr = tip.getBoundingClientRect();
             const tr = tip.getBoundingClientRect();
             let left = Math.round(r.left + (r.width - tr.width) / 2);
             let leftPos = Math.round(r.left + (r.width - tr.width) / 2);
             left = Math.max(8, Math.min(left, 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);
             let top = Math.round(r.top - tr.height - 10);
             if (top < 8) top = Math.round(r.bottom + 10);
             if (top < 8) top = Math.round(r.bottom + 10);
             tip.style.transform = `translate(${left}px, ${top}px)`;
             tip.style.transform = `translate(${leftPos}px, ${top}px)`;
         }
         }
         function show(card) {
         function show(card) {
             tip.innerHTML = card.getAttribute('data-skin-tooltip') || '';
             tip.innerHTML = card.getAttribute('data-skin-tooltip') || '';
Linha 304: Linha 298:
             tip.style.opacity = '1';
             tip.style.opacity = '1';
         }
         }
         function hide() {
         function hide() {
             tip.setAttribute('aria-hidden', 'true');
             tip.setAttribute('aria-hidden', 'true');
Linha 310: Linha 305:
         }
         }


         /* ---------- Navegação (setas) ---------- */
         // ---------- Navegação (setas) ----------
         function scrollAmt() { return Math.round(carousel.clientWidth * 0.6); }
         function scrollAmt() {
            return Math.round(carousel.clientWidth * 0.6);
        }
 
         function setState() {
         function setState() {
             const max = carousel.scrollWidth - carousel.clientWidth;
             const max = carousel.scrollWidth - carousel.clientWidth;
             const x = carousel.scrollLeft;
             const x = carousel.scrollLeft;
             const hasLeft = x > 5, hasRight = x < max - 5;
             const hasLeft = x > 5;
            const hasRight = x < max - 5;
             if (left) left.style.display = hasLeft ? 'inline-block' : 'none';
             if (left) left.style.display = hasLeft ? 'inline-block' : 'none';
             if (right) right.style.display = hasRight ? 'inline-block' : 'none';
             if (right) right.style.display = hasRight ? 'inline-block' : 'none';
Linha 322: Linha 321:
             carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
             carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
         }
         }
         function go(dir) {
         function go(dir) {
             const max = carousel.scrollWidth - carousel.clientWidth;
             const max = carousel.scrollWidth - carousel.clientWidth;
Linha 329: Linha 329:
             carousel.scrollTo({ left: next, behavior: 'smooth' });
             carousel.scrollTo({ left: next, behavior: 'smooth' });
         }
         }
         left?.addEventListener('click', () => go(-1));
         left?.addEventListener('click', () => go(-1));
         right?.addEventListener('click', () => go(1));
         right?.addEventListener('click', () => go(1));
Linha 335: Linha 336:
         setState();
         setState();


         /* ---------- Click por carta (YouTube 1x) ---------- */
         // ---------- Click por carta (YouTube 1x) ----------
         const cards = Array.from(carousel.querySelectorAll('.skin-card'));
         const cards = Array.from(carousel.querySelectorAll('.skin-card'));
         cards.forEach(card => {
         cards.forEach(card => {
            // acessibilidade
             card.setAttribute('tabindex', '0');
             card.setAttribute('tabindex', '0');
             if (card.dataset.youtube) card.setAttribute('role', 'button');
             if (card.dataset.youtube) card.setAttribute('role', 'button');
Linha 344: Linha 344:
             card.addEventListener('click', (ev) => {
             card.addEventListener('click', (ev) => {
                 const url = (card.dataset.youtube || '').trim();
                 const url = (card.dataset.youtube || '').trim();
                 if (!url) return;                   // carta sem vídeo: ignora
                 if (!url) return;
                 if (card.dataset._opening === '1') return; // de-dupe
                 if (card.dataset._opening === '1') return;
                 card.dataset._opening = '1';
                 card.dataset._opening = '1';
                 ev.preventDefault();
                 ev.preventDefault();
                 ev.stopPropagation();
                 ev.stopPropagation();
                 try { window.open(url, '_blank', 'noopener,noreferrer'); }
                 try { window.open(url, '_blank', 'noopener,noreferrer'); }
                 catch (e) { location.href = url; }
                 catch (e) { location.href = url; }
                 setTimeout(() => { delete card.dataset._opening; }, 400);
                 setTimeout(() => { delete card.dataset._opening; }, 400);
             });
             });
Linha 363: Linha 360:
                 if (card.dataset._opening === '1') return;
                 if (card.dataset._opening === '1') return;
                 card.dataset._opening = '1';
                 card.dataset._opening = '1';
                 ev.preventDefault();
                 ev.preventDefault();
                 ev.stopPropagation();
                 ev.stopPropagation();
                 try { window.open(url, '_blank', 'noopener,noreferrer'); }
                 try { window.open(url, '_blank', 'noopener,noreferrer'); }
                 catch (e) { location.href = url; }
                 catch (e) { location.href = url; }
                 setTimeout(() => { delete card.dataset._opening; }, 400);
                 setTimeout(() => { delete card.dataset._opening; }, 400);
             });
             });
         });
         });


         /* ---------- Hitbox real de hover (só escurece com card sob cursor) ---------- */
         // ---------- Hitbox real de hover ----------
         function setHovered(card) {
         function setHovered(card) {
             if (hovered === card) { place(card); return; }
             if (hovered === card) { place(card); return; }
             if (hovered) hovered.classList.remove('hovered');
             if (hovered) hovered.classList.remove('hovered');
             carousel.classList.remove('hovering');
             carousel.classList.remove('hovering');
             carousel.querySelectorAll('.skin-card.dim').forEach(n => n.classList.remove('dim'));
             carousel.querySelectorAll('.skin-card.dim').forEach(n => n.classList.remove('dim'));
             if (!card) { hovered = null; hide(); return; }
             if (!card) { hovered = null; hide(); return; }
             hovered = card;
             hovered = card;
             hovered.classList.add('hovered');
             hovered.classList.add('hovered');
Linha 391: Linha 382:
         }
         }


        // pointer events diretamente nas cartas
         cards.forEach(card => {
         cards.forEach(card => {
             card.addEventListener('pointerenter', () => {
             card.addEventListener('pointerenter', () => {
Linha 400: Linha 390:
             card.addEventListener('pointerleave', (ev) => {
             card.addEventListener('pointerleave', (ev) => {
                 const toCard = ev.relatedTarget && ev.relatedTarget.closest && ev.relatedTarget.closest('.skin-card');
                 const toCard = ev.relatedTarget && ev.relatedTarget.closest && ev.relatedTarget.closest('.skin-card');
                 if (toCard && carousel.contains(toCard)) {
                 if (toCard && carousel.contains(toCard)) return;
                    // vai entrar em outra carta; o pointerenter dela assume
                    return;
                }
                 setHovered(null);
                 setHovered(null);
             }, { passive: true });
             }, { passive: true });
         });
         });


        // saiu do carrossel inteiro => limpa tudo
         carousel.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
         carousel.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
        // mantém o tooltip posicionado
         window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
         window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
         window.addEventListener('resize', () => { if (hovered) place(hovered); });
         window.addEventListener('resize', () => { if (hovered) place(hovered); });
Linha 418: Linha 402:


<style>
<style>
    /* ===========================
      SKINS SYSTEM
      =========================== */
     .card-skins,
     .card-skins,
     .skins-carousel {
     .skins-carousel {
Linha 487: Linha 468:
     }
     }


    /* ===========================
      ADDITIONAL RESPONSIVE FIXES
      =========================== */
     @media (max-width: 820px) {
     @media (max-width: 820px) {



Edição atual tal como às 17h09min de 30 de novembro de 2025

<script>

   (function initSkinCardsUI() {
       const wrapper = document.querySelector('.skins-carousel-wrapper');
       const carousel = wrapper?.querySelector('.skins-carousel');
       const left = wrapper?.querySelector('.skins-arrow.left');
       const right = wrapper?.querySelector('.skins-arrow.right');
       if (!wrapper || !carousel || wrapper.dataset.wired) return;
       wrapper.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 hovered = null;
       function place(card) {
           if (!card || tip.getAttribute('aria-hidden') === 'true') return;
           tip.style.transform = 'translate(-9999px,-9999px)';
           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();
       // ---------- Abrir YouTube (sem duplicar) ----------
       carousel.addEventListener('click', (ev) => {
           const card = ev.target?.closest('.skin-card[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 });
       carousel.addEventListener('keydown', (ev) => {
           if (ev.key !== 'Enter' && ev.key !== ' ') return;
           const card = ev.target?.closest('.skin-card[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 de hover por carta ----------
       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);
       }
       carousel.addEventListener('mouseleave', () => { setHovered(null); });
       carousel.addEventListener('mousemove', (ev) => {
           const card = ev.target?.closest('.skin-card');
           if (card && card.hasAttribute('data-skin-tooltip')) {
               setHovered(card);
           } else {
               setHovered(null);
           }
       });
       window.addEventListener('scroll', () => { if (hovered) place(hovered); }, true);
       window.addEventListener('resize', () => { if (hovered) place(hovered); });
   })();

</script> <style>

   .skin-tooltip {
       position: fixed;
       z-index: 9999;
       left: 0;
       top: 0;
       pointer-events: none;
       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 {
       color: #fff;
   }
   .skin-card .skin-sprite img {
       box-shadow: none !important;
   }
   .card-skins,
   .skins-carousel {
       overflow: visible !important;
   }
   .skin-card.is-clickable {
       cursor: pointer;
   }
   .skin-card.is-clickable:focus {
       outline: 2px solid #156bc7;
       outline-offset: 2px;
   }
   .skin-card {
       position: relative;
   }
   .skins-carousel {
       position: relative;
   }
   .skins-carousel.hovering .skin-card.dim {
       filter: brightness(.55) saturate(.85);
       transition: filter .14s ease, transform .14s ease;
   }
   .skins-carousel.hovering .skin-card.hovered {
       filter: none;
       transform: none;
       box-shadow: 0 0 0 2px rgba(255, 255, 255, .12), 0 10px 28px rgba(0, 0, 0, .45);
   }
   .skin-tooltip {
       pointer-events: none;
   }
   .skins-carousel .skin-card {
       transition: filter .14s ease, box-shadow .14s ease;
   }
   .skin-card .skin-banner {
       z-index: 0;
   }
   .skin-card .skin-sprite {
       z-index: 2;
   }
   .skin-badge {
       display: none !important;
   }
   .skin-tooltip,
   .skill-tooltip {
       text-align: center !important;
       white-space: normal !important;
       max-width: 380px !important;
   }
   .skins-carousel.hover-mode .skin-card.hovered {
       filter: 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;
   }
   .skins-carousel .skin-card {
       transition: filter .14s ease, box-shadow .14s ease !important;
   }

</style>

<script>

   (function initSkinCardsUI_v2() {
       const wrapper = document.querySelector('.skins-carousel-wrapper');
       const carousel = wrapper?.querySelector('.skins-carousel');
       const left = wrapper?.querySelector('.skins-arrow.left');
       const right = wrapper?.querySelector('.skins-arrow.right');
       if (!wrapper || !carousel) return;
       if (wrapper.dataset.skinsV2Wired === '1') return;
       wrapper.dataset.skinsV2Wired = '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');
               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();
       let hovered = null;
       function place(card) {
           if (!card || tip.getAttribute('aria-hidden') === 'true') return;
           tip.style.transform = 'translate(-9999px,-9999px)';
           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 {
       position: relative;
       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 {
       position: absolute;
       inset: 0;
       z-index: 0;
       overflow: hidden;
   }
   .skin-card .skin-banner img {
       width: 100%;
       height: 100%;
       object-fit: cover;
       object-position: center;
       display: block;
   }
   .skin-card .skin-sprite {
       position: relative;
       z-index: 2;
       display: flex;
       align-items: center;
       justify-content: center;
       width: 90%;
       height: 90%;
       pointer-events: none;
   }
   .skin-card .skin-sprite img {
       width: 100%;
       height: 100%;
       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) {
       .card-skins,
       .skins-carousel {
           grid-template-columns: repeat(auto-fill, minmax(120px, 160px));
           justify-content: center;
       }
       .skin-card {
           max-width: 200px;
       }
   }
   @media (max-width: 1100px) {
       .video-container {
           margin: 0 auto;
           justify-self: center;
           align-self: center;
           display: flex;
           justify-content: center;
       }
       .video-container>video {
           margin: 0 auto;
           display: block;
       }
   }
   @media (max-width: 600px) {
       .desc-box {
           overflow: visible !important;
           height: auto !important;
           min-height: 0 !important;
           align-items: stretch !important;
       }
       .card-skins,
       .skins-carousel {
           overflow: visible !important;
       }
   }

</style>