<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
	<id>https://wiki.gla.com.br/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Lucky+Jao</id>
	<title>Wiki Gla - Contribuições do usuário [pt-br]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.gla.com.br/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Lucky+Jao"/>
	<link rel="alternate" type="text/html" href="https://wiki.gla.com.br/index.php/Especial:Contribui%C3%A7%C3%B5es/Lucky_Jao"/>
	<updated>2026-04-05T17:17:24Z</updated>
	<subtitle>Contribuições do usuário</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.gla.com.br/index.php?title=Widget:Teste&amp;diff=38267</id>
		<title>Widget:Teste</title>
		<link rel="alternate" type="text/html" href="https://wiki.gla.com.br/index.php?title=Widget:Teste&amp;diff=38267"/>
		<updated>2025-08-28T01:31:50Z</updated>

		<summary type="html">&lt;p&gt;Lucky Jao: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
    (function () {&lt;br /&gt;
        const $ = (s, root = document) =&amp;gt; root.querySelector(s);&lt;br /&gt;
        const $$ = (s, root = document) =&amp;gt; Array.from(root.querySelectorAll(s));&lt;br /&gt;
&lt;br /&gt;
        // Idempotent helpers&lt;br /&gt;
        const ensureRemoved = sel =&amp;gt; { Array.from(document.querySelectorAll(sel)).forEach(n =&amp;gt; n.remove()); };&lt;br /&gt;
        const onceFlag = (el, key) =&amp;gt; { if (!el) return false; if (el.dataset[key]) return false; el.dataset[key] = '1'; return true; };&lt;br /&gt;
&lt;br /&gt;
        // Basic DOM nodes&lt;br /&gt;
        const skillsTab = $('#skills');&lt;br /&gt;
        const skinsTab = $('#skins');&lt;br /&gt;
&lt;br /&gt;
        // Clean up legacy nodes/titles/placeholders before building&lt;br /&gt;
        ensureRemoved('.top-rail');&lt;br /&gt;
        ensureRemoved('.content-card');&lt;br /&gt;
        ensureRemoved('.video-placeholder');&lt;br /&gt;
        // remove old duplicated skins titles (text match)&lt;br /&gt;
        Array.from(document.querySelectorAll('.card-skins-title, .card-skins .card-skins-title, .cardskins-title, .rail-title')).forEach(t =&amp;gt; {&lt;br /&gt;
            if ((t.textContent || '').trim().toLowerCase().includes('skins')) {&lt;br /&gt;
                // keep only if it's inside a future top-rail.skins we will create; remove for now&lt;br /&gt;
                t.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Build top-rail for skills (only icon-bar, centered)&lt;br /&gt;
        if (skillsTab) {&lt;br /&gt;
            const iconBar = skillsTab.querySelector('.icon-bar');&lt;br /&gt;
            if (iconBar) {&lt;br /&gt;
                const rail = document.createElement('div');&lt;br /&gt;
                rail.className = 'top-rail skills';&lt;br /&gt;
                // center icon bar inside rail&lt;br /&gt;
                rail.appendChild(iconBar);&lt;br /&gt;
                skillsTab.prepend(rail);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Build top-rail for skins (single title + keep carousel wrapper)&lt;br /&gt;
        if (skinsTab) {&lt;br /&gt;
            const wrapper = skinsTab.querySelector('.skins-carousel-wrapper');&lt;br /&gt;
            const rail = document.createElement('div');&lt;br /&gt;
            rail.className = 'top-rail skins';&lt;br /&gt;
            const title = document.createElement('div');&lt;br /&gt;
            title.className = 'rail-title';&lt;br /&gt;
            title.textContent = 'Skins &amp;amp; Spotlights';&lt;br /&gt;
            rail.appendChild(title);&lt;br /&gt;
            if (wrapper) {&lt;br /&gt;
                const card = document.createElement('div');&lt;br /&gt;
                card.className = 'content-card';&lt;br /&gt;
                card.appendChild(wrapper);&lt;br /&gt;
                skinsTab.prepend(rail);&lt;br /&gt;
                skinsTab.appendChild(card);&lt;br /&gt;
            } else {&lt;br /&gt;
                skinsTab.prepend(rail);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Create content-card for skills (description + video) and move nodes in&lt;br /&gt;
        if (skillsTab) {&lt;br /&gt;
            const details = skillsTab.querySelector('.skills-details');&lt;br /&gt;
            const videoContainer = skillsTab.querySelector('.video-container');&lt;br /&gt;
            const card = document.createElement('div');&lt;br /&gt;
            card.className = 'content-card skills-grid';&lt;br /&gt;
            if (details) card.appendChild(details);&lt;br /&gt;
            if (videoContainer) card.appendChild(videoContainer);&lt;br /&gt;
            skillsTab.appendChild(card);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ----- Elements after build&lt;br /&gt;
        const iconsBar = $('#skills') ? $('.icon-bar', $('#skills')) : null;&lt;br /&gt;
        const iconItems = iconsBar ? Array.from(iconsBar.querySelectorAll('.skill-icon')) : [];&lt;br /&gt;
        const descBox = $('#skills') ? $('.desc-box', $('#skills')) : null;&lt;br /&gt;
        const videoBox = $('#skills') ? $('.video-container', $('#skills')) : null;&lt;br /&gt;
&lt;br /&gt;
        // Video cache and state&lt;br /&gt;
        const videosCache = new Map();&lt;br /&gt;
        let totalVideos = 0, loadedVideos = 0, autoplay = false;&lt;br /&gt;
&lt;br /&gt;
        // Single placeholder node: create once at page load and never re-create later.&lt;br /&gt;
        let placeholder = videoBox ? videoBox.querySelector('.video-placeholder') : null;&lt;br /&gt;
        let placeholderCreatedOnLoad = false;&lt;br /&gt;
        // true once the single placeholder was used/consumed (only show for the first active video)&lt;br /&gt;
        let placeholderConsumed = false;&lt;br /&gt;
        if (!placeholder &amp;amp;&amp;amp; videoBox) {&lt;br /&gt;
            placeholder = document.createElement('div');&lt;br /&gt;
            placeholder.className = 'video-placeholder';&lt;br /&gt;
            placeholder.innerHTML = '&amp;lt;img src=&amp;quot;/images/d/d5/Icon_gla.png&amp;quot; alt=&amp;quot;Carregando...&amp;quot;&amp;gt;';&lt;br /&gt;
            videoBox.appendChild(placeholder);&lt;br /&gt;
            placeholderCreatedOnLoad = true;&lt;br /&gt;
        } else if (placeholder) {&lt;br /&gt;
            // If a placeholder already exists in DOM (legacy), mark it as created on load.&lt;br /&gt;
            placeholderCreatedOnLoad = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (!placeholder) placeholderConsumed = true; // nothing to show&lt;br /&gt;
&lt;br /&gt;
        // Robust hide/show: fade-out hides the single placeholder but keeps it in DOM&lt;br /&gt;
        // so it can be reused without duplication. Removal (DOM delete) is avoided.&lt;br /&gt;
        const removePlaceholderSmooth = () =&amp;gt; {&lt;br /&gt;
            if (!placeholder) return;&lt;br /&gt;
            if (placeholder.classList.contains('fade-out')) return;&lt;br /&gt;
            placeholder.classList.add('fade-out');&lt;br /&gt;
            // when transition completes, keep node but hide it so showPlaceholder can reuse.&lt;br /&gt;
            const onEnd = () =&amp;gt; {&lt;br /&gt;
                try { placeholder.style.display = 'none'; } catch (e) { /* ignore */ }&lt;br /&gt;
                placeholder.removeEventListener('transitionend', onEnd);&lt;br /&gt;
            };&lt;br /&gt;
            placeholder.addEventListener('transitionend', onEnd, { once: true });&lt;br /&gt;
            // fallback ensure it's hidden&lt;br /&gt;
            setTimeout(() =&amp;gt; { try { placeholder.style.display = 'none'; } catch (e) {} }, 600);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        // showPlaceholder: shows the single placeholder created at load (no new nodes).&lt;br /&gt;
        const showPlaceholder = () =&amp;gt; {&lt;br /&gt;
            if (!videoBox) return;&lt;br /&gt;
            if (!placeholder || !placeholderCreatedOnLoad) return;&lt;br /&gt;
            if (placeholderConsumed) return; // never show again after first use&lt;br /&gt;
            placeholder.classList.remove('fade-out');&lt;br /&gt;
            placeholder.style.display = 'flex';&lt;br /&gt;
            // force reflow to ensure transition apply on hide later&lt;br /&gt;
            void placeholder.offsetWidth;&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        // Utility: attach listener only once per element&lt;br /&gt;
        const addOnce = (el, ev, fn) =&amp;gt; {&lt;br /&gt;
            if (!el) return;&lt;br /&gt;
            const attr = `data-wired-${ev}`;&lt;br /&gt;
            if (el.hasAttribute(attr)) return;&lt;br /&gt;
            el.addEventListener(ev, fn);&lt;br /&gt;
            el.setAttribute(attr, '1');&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        // Preload videos (idempotent: skip if present in map)&lt;br /&gt;
        if (iconItems.length &amp;amp;&amp;amp; videoBox) {&lt;br /&gt;
            iconItems.forEach(el =&amp;gt; {&lt;br /&gt;
                const src = (el.dataset.video || '').trim();&lt;br /&gt;
                const idx = el.dataset.index || '';&lt;br /&gt;
                if (!src || videosCache.has(idx)) return;&lt;br /&gt;
&lt;br /&gt;
                totalVideos++;&lt;br /&gt;
                const v = document.createElement('video');&lt;br /&gt;
                v.className = 'skill-video';&lt;br /&gt;
                v.setAttribute('controls', '');&lt;br /&gt;
                v.setAttribute('preload', 'auto');&lt;br /&gt;
                v.setAttribute('playsinline', '');&lt;br /&gt;
                v.style.display = 'none';&lt;br /&gt;
                v.dataset.index = idx;&lt;br /&gt;
                // prefer consistent sizing: width 100% inside video container, and use 16:9 to avoid layout jumps&lt;br /&gt;
                v.style.width = '100%';&lt;br /&gt;
                v.style.maxWidth = '100%';&lt;br /&gt;
                v.style.height = 'auto';&lt;br /&gt;
                v.style.aspectRatio = '16/9';&lt;br /&gt;
                v.style.objectFit = 'cover';&lt;br /&gt;
                const source = document.createElement('source');&lt;br /&gt;
                source.src = src;&lt;br /&gt;
                source.type = 'video/webm';&lt;br /&gt;
                v.appendChild(source);&lt;br /&gt;
&lt;br /&gt;
                v.addEventListener('canplay', () =&amp;gt; {&lt;br /&gt;
                    loadedVideos++;&lt;br /&gt;
                    if (loadedVideos === 1) { try { v.pause(); v.currentTime = 0; } catch (e) { } }&lt;br /&gt;
                    const active = $('.skill-icon.active', iconsBar);&lt;br /&gt;
                    if (active &amp;amp;&amp;amp; active.dataset.index === idx) {&lt;br /&gt;
                        // remove placeholder for the active video (only once)&lt;br /&gt;
                        if (!placeholderConsumed) {&lt;br /&gt;
                            setTimeout(() =&amp;gt; { removePlaceholderSmooth(); placeholderConsumed = true; }, 180);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    if (loadedVideos === totalVideos) autoplay = true;&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                v.addEventListener('error', () =&amp;gt; {&lt;br /&gt;
                    loadedVideos++;&lt;br /&gt;
                    removePlaceholderSmooth();&lt;br /&gt;
                    if (loadedVideos === totalVideos) autoplay = true;&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                videoBox.appendChild(v);&lt;br /&gt;
                videosCache.set(idx, v);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (totalVideos === 0 &amp;amp;&amp;amp; placeholder) {&lt;br /&gt;
            // no videos: hide placeholder but keep the node for idempotence&lt;br /&gt;
            placeholder.style.display = 'none';&lt;br /&gt;
            placeholder.classList.add('fade-out');&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Attach skill icon click handlers once&lt;br /&gt;
        iconItems.forEach(el =&amp;gt; {&lt;br /&gt;
            if (el.dataset.wired) return;&lt;br /&gt;
            el.dataset.wired = '1';&lt;br /&gt;
            const name = el.dataset.nome || el.dataset.name || '';&lt;br /&gt;
            const desc = (el.dataset.desc || '').replace(/'''(.*?)'''/g, '&amp;lt;b&amp;gt;$1&amp;lt;/b&amp;gt;');&lt;br /&gt;
            const attrs = el.dataset.atr || el.dataset.attrs || '';&lt;br /&gt;
            const idx = el.dataset.index || '';&lt;br /&gt;
            const hasVideo = !!(el.dataset.video &amp;amp;&amp;amp; el.dataset.video.trim() !== '');&lt;br /&gt;
&lt;br /&gt;
            el.title = name;&lt;br /&gt;
            el.addEventListener('click', () =&amp;gt; {&lt;br /&gt;
                // update description area&lt;br /&gt;
                if (descBox) {&lt;br /&gt;
                    descBox.innerHTML = `&lt;br /&gt;
  &amp;lt;div class=&amp;quot;skill-title&amp;quot;&amp;gt;&amp;lt;h3&amp;gt;${name}&amp;lt;/h3&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
  ${renderAttributes(attrs)}&lt;br /&gt;
  &amp;lt;div class=&amp;quot;desc&amp;quot;&amp;gt;${desc}&amp;lt;/div&amp;gt;&lt;br /&gt;
`;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // switch videos: hide all, show selected (if any)&lt;br /&gt;
                videosCache.forEach(v =&amp;gt; { try { v.pause(); } catch (e) { } v.style.display = 'none'; });&lt;br /&gt;
                if (videoBox) {&lt;br /&gt;
                    if (hasVideo &amp;amp;&amp;amp; videosCache.has(idx)) {&lt;br /&gt;
                        const v = videosCache.get(idx);&lt;br /&gt;
                        // ensure video container visible and video fills container consistently&lt;br /&gt;
                        videoBox.style.display = 'block';&lt;br /&gt;
                        v.style.display = 'block';&lt;br /&gt;
                        try { v.currentTime = 0; } catch (e) {}&lt;br /&gt;
                        // show the (single) placeholder until this video can play&lt;br /&gt;
                        if (v.readyState &amp;gt;= 3) {&lt;br /&gt;
                            if (!placeholderConsumed) { removePlaceholderSmooth(); placeholderConsumed = true; }&lt;br /&gt;
                        } else {&lt;br /&gt;
                            // show placeholder only if it hasn't been used yet&lt;br /&gt;
                            if (!placeholderConsumed) {&lt;br /&gt;
                                showPlaceholder();&lt;br /&gt;
                                const canplayHandler = () =&amp;gt; { removePlaceholderSmooth(); placeholderConsumed = true; v.removeEventListener('canplay', canplayHandler); };&lt;br /&gt;
                                v.addEventListener('canplay', canplayHandler);&lt;br /&gt;
                            }&lt;br /&gt;
                        }&lt;br /&gt;
                        if (autoplay) v.play().catch(() =&amp;gt; { });&lt;br /&gt;
                    } else {&lt;br /&gt;
                        // no video for this skill: hide video area and hide placeholder&lt;br /&gt;
                        videoBox.style.display = 'none';&lt;br /&gt;
                        if (placeholder) {&lt;br /&gt;
                            placeholder.style.display = 'none';&lt;br /&gt;
                            placeholder.classList.add('fade-out');&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // active state&lt;br /&gt;
                iconItems.forEach(i =&amp;gt; i.classList.remove('active'));&lt;br /&gt;
                el.classList.add('active');&lt;br /&gt;
                if (!autoplay &amp;amp;&amp;amp; loadedVideos &amp;gt; 0) autoplay = true;&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Tooltip: single global tooltip for skill icons (idempotent)&lt;br /&gt;
        (function initSkillTooltip() {&lt;br /&gt;
            if (document.querySelector('.skill-tooltip')) return;&lt;br /&gt;
            const tip = document.createElement('div');&lt;br /&gt;
            tip.className = 'skill-tooltip';&lt;br /&gt;
            tip.setAttribute('role', 'tooltip');&lt;br /&gt;
            tip.setAttribute('aria-hidden', 'true');&lt;br /&gt;
            document.body.appendChild(tip);&lt;br /&gt;
&lt;br /&gt;
            function measureAndPos(el) {&lt;br /&gt;
                if (!el || tip.getAttribute('aria-hidden') === 'true') return;&lt;br /&gt;
                // reset to measure&lt;br /&gt;
                tip.style.left = '0px';&lt;br /&gt;
                tip.style.top = '0px';&lt;br /&gt;
                const rect = el.getBoundingClientRect();&lt;br /&gt;
                const tr = tip.getBoundingClientRect();&lt;br /&gt;
                let left = Math.round(rect.left + (rect.width - tr.width) / 2);&lt;br /&gt;
                left = Math.max(8, Math.min(left, window.innerWidth - tr.width - 8));&lt;br /&gt;
                let top = Math.round(rect.top - tr.height - 8);&lt;br /&gt;
                if (top &amp;lt; 8) top = Math.round(rect.bottom + 8);&lt;br /&gt;
                tip.style.left = left + 'px';&lt;br /&gt;
                tip.style.top = top + 'px';&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function show(el, text) {&lt;br /&gt;
                tip.textContent = text || '';&lt;br /&gt;
                tip.setAttribute('aria-hidden', 'false');&lt;br /&gt;
                tip.style.opacity = '1';&lt;br /&gt;
                measureAndPos(el);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function hide() {&lt;br /&gt;
                tip.setAttribute('aria-hidden', 'true');&lt;br /&gt;
                tip.style.opacity = '0';&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // attach once to each icon&lt;br /&gt;
            Array.from(document.querySelectorAll('.icon-bar .skill-icon')).forEach(icon =&amp;gt; {&lt;br /&gt;
                if (icon.dataset.tipwired) return;&lt;br /&gt;
                icon.dataset.tipwired = '1';&lt;br /&gt;
                const label = icon.dataset.nome || icon.dataset.name || icon.title || '';&lt;br /&gt;
                icon.addEventListener('mouseenter', () =&amp;gt; show(icon, label));&lt;br /&gt;
                icon.addEventListener('mousemove', () =&amp;gt; measureAndPos(icon));&lt;br /&gt;
                icon.addEventListener('mouseleave', hide);&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // keep positioned while scrolling/resizing&lt;br /&gt;
            window.addEventListener('scroll', () =&amp;gt; {&lt;br /&gt;
                const visible = document.querySelector('.skill-tooltip[aria-hidden=&amp;quot;false&amp;quot;]');&lt;br /&gt;
                if (!visible) return;&lt;br /&gt;
                const hover = document.querySelector('.icon-bar .skill-icon:hover') || document.querySelector('.icon-bar .skill-icon.active');&lt;br /&gt;
                measureAndPos(hover);&lt;br /&gt;
            }, true);&lt;br /&gt;
            window.addEventListener('resize', () =&amp;gt; {&lt;br /&gt;
                const hover = document.querySelector('.icon-bar .skill-icon:hover') || document.querySelector('.icon-bar .skill-icon.active');&lt;br /&gt;
                measureAndPos(hover);&lt;br /&gt;
            });&lt;br /&gt;
        })();&lt;br /&gt;
&lt;br /&gt;
        // Select first skill by default (dispatch click once)&lt;br /&gt;
        if (iconItems.length) {&lt;br /&gt;
            const first = iconItems[0];&lt;br /&gt;
            if (first) {&lt;br /&gt;
                // ensure default active visual &amp;amp; trigger behavior&lt;br /&gt;
                if (!first.classList.contains('active')) first.classList.add('active');&lt;br /&gt;
                // trigger click after microtask so videos are ready to be shown&lt;br /&gt;
                setTimeout(() =&amp;gt; first.click(), 0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Keep .desc max-height synced to the visible video height so long descriptions&lt;br /&gt;
        // scroll instead of pushing the layout and stretching the background.&lt;br /&gt;
        function syncDescHeight() {&lt;br /&gt;
            if (!descBox || !videoBox) return;&lt;br /&gt;
            const descEl = descBox.querySelector('.desc');&lt;br /&gt;
            if (!descEl) return;&lt;br /&gt;
            // if video area hidden, restore CSS fallback (clamp)&lt;br /&gt;
            const computedDisplay = getComputedStyle(videoBox).display;&lt;br /&gt;
            if (computedDisplay === 'none') {&lt;br /&gt;
                descEl.style.maxHeight = '';&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            // prefer measuring video element if present, fallback to videoBox&lt;br /&gt;
            const v = videoBox.querySelector('video');&lt;br /&gt;
            const targetHeight = (v &amp;amp;&amp;amp; v.offsetHeight &amp;gt; 0) ? v.offsetHeight : videoBox.clientHeight;&lt;br /&gt;
            if (!targetHeight || targetHeight &amp;lt;= 0) {&lt;br /&gt;
                descEl.style.maxHeight = '';&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            // subtract vertical padding on desc element to keep inner scroll consistent&lt;br /&gt;
            const cs = getComputedStyle(descEl);&lt;br /&gt;
            const padTop = parseFloat(cs.paddingTop) || 0;&lt;br /&gt;
            const padBottom = parseFloat(cs.paddingBottom) || 0;&lt;br /&gt;
            const maxH = Math.max(64, targetHeight - padTop - padBottom); // ensure a minimum&lt;br /&gt;
            descEl.style.maxHeight = `${maxH}px`;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // keep in sync on resize and when videos change layout&lt;br /&gt;
        window.addEventListener('resize', syncDescHeight);&lt;br /&gt;
        if (videoBox) new ResizeObserver(syncDescHeight).observe(videoBox);&lt;br /&gt;
&lt;br /&gt;
        // call sync after each icon click (desc is rebuilt there)&lt;br /&gt;
        // patch: wrap existing click wiring to call syncDescHeight after updating DOM&lt;br /&gt;
        iconItems.forEach(el =&amp;gt; {&lt;br /&gt;
            const wired = !!el.dataset._sync_wired;&lt;br /&gt;
            if (wired) return;&lt;br /&gt;
            el.dataset._sync_wired = '1';&lt;br /&gt;
            // find existing click handler we attached earlier and chain sync&lt;br /&gt;
            el.addEventListener('click', () =&amp;gt; {&lt;br /&gt;
                // run in next microtask so DOM update from earlier handler is settled&lt;br /&gt;
                Promise.resolve().then(syncDescHeight);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // horizontal scroll on wheel (attach once)&lt;br /&gt;
        if (iconsBar) addOnce(iconsBar, 'wheel', (e) =&amp;gt; {&lt;br /&gt;
            if (e.deltaY) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                iconsBar.scrollLeft += e.deltaY;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // skins carousel arrows init (idempotent)&lt;br /&gt;
        (function initSkinsArrows() {&lt;br /&gt;
            const carousel = $('.skins-carousel');&lt;br /&gt;
            const wrapper = $('.skins-carousel-wrapper');&lt;br /&gt;
            const left = $('.skins-arrow.left');&lt;br /&gt;
            const right = $('.skins-arrow.right');&lt;br /&gt;
            if (!carousel || !left || !right || !wrapper) return;&lt;br /&gt;
            if (wrapper.dataset.wired) return;&lt;br /&gt;
            wrapper.dataset.wired = '1';&lt;br /&gt;
            const scrollAmt = () =&amp;gt; Math.round(carousel.clientWidth * 0.6);&lt;br /&gt;
            function setState() {&lt;br /&gt;
                const max = carousel.scrollWidth - carousel.clientWidth;&lt;br /&gt;
                const x = carousel.scrollLeft;&lt;br /&gt;
                const hasLeft = x &amp;gt; 5, hasRight = x &amp;lt; max - 5;&lt;br /&gt;
                left.style.display = hasLeft ? 'inline-block' : 'none';&lt;br /&gt;
                right.style.display = hasRight ? 'inline-block' : 'none';&lt;br /&gt;
                wrapper.classList.toggle('has-left', hasLeft);&lt;br /&gt;
                wrapper.classList.toggle('has-right', hasRight);&lt;br /&gt;
                carousel.style.justifyContent = (!hasLeft &amp;amp;&amp;amp; !hasRight) ? 'center' : '';&lt;br /&gt;
            }&lt;br /&gt;
            function go(dir) {&lt;br /&gt;
                const max = carousel.scrollWidth - carousel.clientWidth;&lt;br /&gt;
                const next = dir &amp;lt; 0&lt;br /&gt;
                    ? Math.max(0, carousel.scrollLeft - scrollAmt())&lt;br /&gt;
                    : Math.min(max, carousel.scrollLeft + scrollAmt());&lt;br /&gt;
                carousel.scrollTo({ left: next, behavior: 'smooth' });&lt;br /&gt;
            }&lt;br /&gt;
            left.addEventListener('click', () =&amp;gt; go(-1));&lt;br /&gt;
            right.addEventListener('click', () =&amp;gt; go(1));&lt;br /&gt;
            carousel.addEventListener('scroll', setState);&lt;br /&gt;
            new ResizeObserver(setState).observe(carousel);&lt;br /&gt;
            setState();&lt;br /&gt;
        })();&lt;br /&gt;
&lt;br /&gt;
        // Render attributes function (keeps empty rows above visible ones)&lt;br /&gt;
        function renderAttributes(str) {&lt;br /&gt;
            const vals = (str || '').split(',').map(v =&amp;gt; v.trim());&lt;br /&gt;
            const pve = parseInt(vals[0], 10);&lt;br /&gt;
            const pvp = parseInt(vals[1], 10);&lt;br /&gt;
            const ene = parseInt(vals[2], 10);&lt;br /&gt;
            const cd = parseInt(vals[3], 10);&lt;br /&gt;
&lt;br /&gt;
            const recargaVal = isNaN(cd) ? '-' : cd;&lt;br /&gt;
            const energiaLabel = isNaN(ene) ? 'Energia' : (ene &amp;gt;= 0 ? 'Ganho de energia' : 'Custo de energia');&lt;br /&gt;
            const energiaVal = isNaN(ene) ? '-' : Math.abs(ene);&lt;br /&gt;
            const poderVal = isNaN(pve) ? '-' : pve;&lt;br /&gt;
            const poderPvpVal = isNaN(pvp) ? '-' : pvp;&lt;br /&gt;
&lt;br /&gt;
            const rows = [&lt;br /&gt;
                ['Recarga', recargaVal],&lt;br /&gt;
                [energiaLabel, energiaVal],&lt;br /&gt;
                ['Poder', poderVal],&lt;br /&gt;
                ['Poder PvP', poderPvpVal],&lt;br /&gt;
            ];&lt;br /&gt;
&lt;br /&gt;
            const visible = rows.filter(([, v]) =&amp;gt; v !== '-');&lt;br /&gt;
            const empties = rows.length - visible.length;&lt;br /&gt;
            const emptyHtml = Array.from({ length: empties }).map(() =&amp;gt; `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;attr-row is-empty&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;attr-label&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;attr-value&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `).join('');&lt;br /&gt;
            const visibleHtml = visible.map(([label, value]) =&amp;gt; `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;attr-row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;attr-label&amp;quot;&amp;gt;${label}:&amp;lt;/span&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;attr-value&amp;quot;&amp;gt;${value}&amp;lt;/span&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `).join('');&lt;br /&gt;
            if (visible.length === 0) {&lt;br /&gt;
                // still keep one empty row to preserve spacing but on top&lt;br /&gt;
                return `&amp;lt;div class=&amp;quot;attr-list&amp;quot;&amp;gt;${emptyHtml || `\n      &amp;lt;div class=&amp;quot;attr-row is-empty&amp;quot;&amp;gt;\n        &amp;lt;span class=&amp;quot;attr-label&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/span&amp;gt;\n        &amp;lt;span class=&amp;quot;attr-value&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/span&amp;gt;\n      &amp;lt;/div&amp;gt;\n    `}&amp;lt;/div&amp;gt;`;&lt;br /&gt;
            }&lt;br /&gt;
            return `&amp;lt;div class=&amp;quot;attr-list&amp;quot;&amp;gt;${emptyHtml}${visibleHtml}&amp;lt;/div&amp;gt;`;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // language-aware tab label for Skills&lt;br /&gt;
        (function localizeSkillsTab() {&lt;br /&gt;
            const lang = (document.documentElement.lang || navigator.language || '').toLowerCase();&lt;br /&gt;
            const code = lang.split('-')[0];&lt;br /&gt;
            const map = {&lt;br /&gt;
                en: 'Skills',&lt;br /&gt;
                'pt': 'Habilidades',&lt;br /&gt;
                'pt-br': 'Habilidades',&lt;br /&gt;
                'es': 'Habilidades',&lt;br /&gt;
                pl: 'Umiejętności'&lt;br /&gt;
            };&lt;br /&gt;
            // prefer full match (pt-br) then base code&lt;br /&gt;
            const key = map[lang] ? lang : (map[code] ? code : 'en');&lt;br /&gt;
            const label = map[key] || map.en;&lt;br /&gt;
            // try well-known selector first, fallback to searching for english-like text&lt;br /&gt;
            let btn = document.querySelector('.character-tabs .tab-btn[data-tab=&amp;quot;skills&amp;quot;]') ||&lt;br /&gt;
                      Array.from(document.querySelectorAll('.character-tabs .tab-btn')).find(b =&amp;gt; /skill|habil|umiej/i.test(b.textContent || ''));&lt;br /&gt;
            if (btn) btn.textContent = label;&lt;br /&gt;
        })();&lt;br /&gt;
&lt;br /&gt;
        // DEBUG: log video sources and errors&lt;br /&gt;
        setTimeout(() =&amp;gt; {&lt;br /&gt;
            console.log('DEBUG: totalVideos=', totalVideos);&lt;br /&gt;
            Array.from(document.querySelectorAll('.skill-icon')).forEach(el =&amp;gt; {&lt;br /&gt;
                console.log('icon', el.dataset.index, 'data-video=', el.dataset.video);&lt;br /&gt;
            });&lt;br /&gt;
            videosCache.forEach((v, idx) =&amp;gt; {&lt;br /&gt;
                const src = v.querySelector('source') ? v.querySelector('source').src : v.src;&lt;br /&gt;
                console.log('video element', idx, 'src=', src, 'readyState=', v.readyState);&lt;br /&gt;
                v.addEventListener('error', (ev) =&amp;gt; {&lt;br /&gt;
                    console.error('VIDEO ERROR idx=', idx, 'src=', src, 'error=', v.error);&lt;br /&gt;
                });&lt;br /&gt;
                v.addEventListener('loadedmetadata', () =&amp;gt; {&lt;br /&gt;
                    console.log('loadedmetadata idx=', idx, 'dimensions=', v.videoWidth, 'x', v.videoHeight);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }, 600);&lt;br /&gt;
    })();&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
    /* ===========================&lt;br /&gt;
   Base&lt;br /&gt;
   =========================== */&lt;br /&gt;
    img {&lt;br /&gt;
        pointer-events: none;&lt;br /&gt;
        user-select: none;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    /* video baseline; specific skill video sizing overridden below */&lt;br /&gt;
    video { max-height: none; }&lt;br /&gt;
 &lt;br /&gt;
    .mw-body {&lt;br /&gt;
        padding: unset !important;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    /* precisa de !important p/ MediaWiki */&lt;br /&gt;
    .mw-body-content {&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    .mw-body-content p {&lt;br /&gt;
        display: none;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    /* ===========================&lt;br /&gt;
   Banner&lt;br /&gt;
   =========================== */&lt;br /&gt;
    /* Hide the original banner element (we'll use the image as the template background)&lt;br /&gt;
       and keep the selector so existing markup doesn't break. */&lt;br /&gt;
    .banner { display: none !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Use the banner image as the background for the template container and add&lt;br /&gt;
       a subtle dark overlay via ::before to improve text contrast. */&lt;br /&gt;
    .character-box {&lt;br /&gt;
        /* ...existing properties... */&lt;br /&gt;
        background-image: url(https://i.imgur.com/RktmgO8.png);&lt;br /&gt;
        background-position: center top;&lt;br /&gt;
        background-repeat: no-repeat;&lt;br /&gt;
        background-size: cover;&lt;br /&gt;
        position: relative; /* ensure positioning context for ::before */&lt;br /&gt;
        z-index: 1; /* base layer for the box content */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* overlay sits above the background image but below the content; darker bottom-to-top gradient */&lt;br /&gt;
    .character-box::before {&lt;br /&gt;
        content: &amp;quot;&amp;quot;;&lt;br /&gt;
        position: absolute;&lt;br /&gt;
        inset: 0;&lt;br /&gt;
        pointer-events: none;&lt;br /&gt;
        background: linear-gradient(to bottom, rgba(0,0,0,.45), rgba(0,0,0,.60));&lt;br /&gt;
        z-index: 0; /* overlay: below content (content kept at z-index:1) */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ===========================&lt;br /&gt;
   Character topbar&lt;br /&gt;
   =========================== */&lt;br /&gt;
    .character-box {&lt;br /&gt;
        color: #000;&lt;br /&gt;
        font-family: 'Noto Sans', sans-serif;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        margin: auto;&lt;br /&gt;
        position: relative;&lt;br /&gt;
        user-select: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .character-box p {&lt;br /&gt;
        display: unset;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .character-topbar {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-direction: column;&lt;br /&gt;
        align-items: flex-start;&lt;br /&gt;
        padding: 8px 20px 0;&lt;br /&gt;
    z-index: 1; /* topbar above overlay */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .character-name-box {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        align-items: center;&lt;br /&gt;
        gap: 14px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .topbar-icon {&lt;br /&gt;
        margin-top: 8px;&lt;br /&gt;
        width: 100px;&lt;br /&gt;
        height: 100px;&lt;br /&gt;
        object-fit: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .character-name {&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        font-size: 56px;&lt;br /&gt;
        font-family: 'Orbitron', sans-serif;&lt;br /&gt;
        font-weight: 900;&lt;br /&gt;
        text-shadow: 0 0 6px #000, 0 0 9px #000;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .topbar-description {&lt;br /&gt;
        display: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ===========================&lt;br /&gt;
   Header / Artwork&lt;br /&gt;
   =========================== */&lt;br /&gt;
    .character-header {&lt;br /&gt;
        position: relative;&lt;br /&gt;
        overflow: hidden; /* artwork must not 'vazar' */&lt;br /&gt;
        display: flex;&lt;br /&gt;
        gap: 10px;&lt;br /&gt;
        flex-direction: column;&lt;br /&gt;
        z-index: 1; /* header/topbar layer */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* artwork removed from layout (server still accepts param but we ignore rendering).&lt;br /&gt;
       ensure it doesn't reserve space if present in legacy markup */&lt;br /&gt;
    .character-art { display: none !important; width: 0 !important; height: 0 !important; overflow: hidden !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Class / tier chips */&lt;br /&gt;
    .class-tags {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        gap: 9px;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        margin-left: .28rem;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .class-tag {&lt;br /&gt;
        background: #353420;&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        outline: 2px solid #000;&lt;br /&gt;
        padding: 1px 6px;&lt;br /&gt;
        border-radius: 4px;&lt;br /&gt;
        font-size: .9em;&lt;br /&gt;
        font-weight: 700;&lt;br /&gt;
        box-shadow: 0 0 2px rgb(0 0 0 / 70%);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .character-info .tier,&lt;br /&gt;
    .character-info .class-tag {&lt;br /&gt;
        font-size: 18px;&lt;br /&gt;
        color: #bbb;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ===========================&lt;br /&gt;
   Tabs&lt;br /&gt;
   =========================== */&lt;br /&gt;
    .character-tabs {&lt;br /&gt;
        margin: 4px 0 4px 8px;&lt;br /&gt;
        display: flex;&lt;br /&gt;
        gap: 12px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tab-btn {&lt;br /&gt;
        padding: 5px 20px;&lt;br /&gt;
        background: #333;&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        border: 2px solid transparent;&lt;br /&gt;
        border-radius: 8px;&lt;br /&gt;
        font-size: 20px;&lt;br /&gt;
        cursor: pointer;&lt;br /&gt;
        font-weight: 600;&lt;br /&gt;
        line-height: 1;&lt;br /&gt;
        transition: background .15s, border-color .15s;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tab-btn.active {&lt;br /&gt;
        background: #156bc7;&lt;br /&gt;
        border-color: #156bc7;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tab-content {&lt;br /&gt;
        display: none;&lt;br /&gt;
        padding: 0 8px 8px;&lt;br /&gt;
        position: relative;&lt;br /&gt;
    z-index: 2; /* content layer */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tab-content.active {&lt;br /&gt;
        display: block;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ===========================&lt;br /&gt;
   Skills &lt;br /&gt;
   =========================== */&lt;br /&gt;
    .skills-container {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        gap: 20px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .skills-details {&lt;br /&gt;
        flex: 1;&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-direction: column;&lt;br /&gt;
        gap: 10px;&lt;br /&gt;
        width: auto; /* let grid control widths */&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: nowrap;&lt;br /&gt;
        gap: 10px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        overflow-x: auto;&lt;br /&gt;
        overflow-y: hidden;&lt;br /&gt;
        padding: 6px 6px; /* centraliza melhor verticalmente */&lt;br /&gt;
        margin-bottom: 6px;&lt;br /&gt;
        scrollbar-width: thin;&lt;br /&gt;
        scrollbar-color: #ababab transparent;&lt;br /&gt;
        scroll-behavior: smooth;&lt;br /&gt;
        justify-content: flex-start;&lt;br /&gt;
        align-items: center; /* centraliza os ícones verticalmente dentro da barra */&lt;br /&gt;
        position: relative;&lt;br /&gt;
        z-index: 4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar::-webkit-scrollbar {&lt;br /&gt;
        height: 6px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar::-webkit-scrollbar-track {&lt;br /&gt;
        background: transparent;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar::-webkit-scrollbar-thumb {&lt;br /&gt;
        background: #151515;&lt;br /&gt;
        border-radius: 3px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    :root {&lt;br /&gt;
        --icon-size: 39px;&lt;br /&gt;
        --icon-radius: 8px;&lt;br /&gt;
        /* ring width and colors (icons-only overrides) */&lt;br /&gt;
        --icon-ring-w: 2px;&lt;br /&gt;
        --icon-idle: #bbb;&lt;br /&gt;
        --icon-active: #FFD257;               /* amarelo agradável */&lt;br /&gt;
        --icon-active-ring: rgba(255,210,87,.45);&lt;br /&gt;
        --icon-active-glow: rgba(255,210,87,.35);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ensure each icon is vertically centered inside the bar */&lt;br /&gt;
    .icon-bar .skill-icon {&lt;br /&gt;
        /* keep original sizing and alignment but ensure perfect clipping */&lt;br /&gt;
        width: var(--icon-size);&lt;br /&gt;
        height: var(--icon-size);&lt;br /&gt;
        position: relative;&lt;br /&gt;
        flex: 0 0 auto;&lt;br /&gt;
        border-radius: var(--icon-radius);&lt;br /&gt;
        overflow: hidden;        /* hard clip the image */&lt;br /&gt;
        contain: paint;          /* reduce subpixel leakage */&lt;br /&gt;
        margin-top: 0;&lt;br /&gt;
        display: flex;&lt;br /&gt;
        align-items: center;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        -webkit-tap-highlight-color: transparent;&lt;br /&gt;
        background-clip: padding-box;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar .skill-icon img {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        height: 100%;&lt;br /&gt;
        object-fit: cover;&lt;br /&gt;
        border-radius: inherit;&lt;br /&gt;
        clip-path: inset(0 round var(--icon-radius));&lt;br /&gt;
        -webkit-clip-path: inset(0 round var(--icon-radius));&lt;br /&gt;
        will-change: transform;&lt;br /&gt;
        backface-visibility: hidden;&lt;br /&gt;
        transform: translateZ(0);&lt;br /&gt;
        transition: transform .12s ease;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* internal ring implemented via inset box-shadow to avoid border layout changes */&lt;br /&gt;
    .icon-bar .skill-icon::after {&lt;br /&gt;
        content: &amp;quot;&amp;quot;;&lt;br /&gt;
        position: absolute;&lt;br /&gt;
        inset: 0;&lt;br /&gt;
        border-radius: inherit;&lt;br /&gt;
        /* internal ring keeps constant thickness between states */&lt;br /&gt;
        box-shadow: inset 0 0 0 var(--icon-ring-w) var(--icon-idle);&lt;br /&gt;
        pointer-events: none;&lt;br /&gt;
        z-index: 2;&lt;br /&gt;
        transition: box-shadow .14s ease;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* subtle hover color change without changing ring width */&lt;br /&gt;
    .icon-bar .skill-icon:hover::after {&lt;br /&gt;
        box-shadow: inset 0 0 0 var(--icon-ring-w) #e0e0e0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* separate pseudo for glow so ring thickness does not change */&lt;br /&gt;
    .icon-bar .skill-icon::before {&lt;br /&gt;
        content: &amp;quot;&amp;quot;;&lt;br /&gt;
        position: absolute;&lt;br /&gt;
        inset: 0;&lt;br /&gt;
        border-radius: inherit;&lt;br /&gt;
        pointer-events: none;&lt;br /&gt;
        z-index: 1;&lt;br /&gt;
        box-shadow: none;&lt;br /&gt;
        opacity: 0;&lt;br /&gt;
        transition: opacity .14s ease, box-shadow .14s ease;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar .skill-icon.active::after {&lt;br /&gt;
        box-shadow: inset 0 0 0 var(--icon-ring-w) var(--icon-active);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .icon-bar .skill-icon.active::before {&lt;br /&gt;
        /* glow only (does not change inner ring thickness) */&lt;br /&gt;
        box-shadow: 0 0 10px 2px var(--icon-active-glow), 0 0 0 4px var(--icon-active-ring);&lt;br /&gt;
        opacity: 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* smooth zoom on the image only (keeps ring aligned) */&lt;br /&gt;
    .icon-bar .skill-icon.active img {&lt;br /&gt;
        transform: scale(1.10);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @media (prefers-reduced-motion: reduce) {&lt;br /&gt;
        .icon-bar .skill-icon {&lt;br /&gt;
            transition: none;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Title description */&lt;br /&gt;
    .skill-title {&lt;br /&gt;
        margin: 0 0 12px;&lt;br /&gt;
        display: flex;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        align-items: center;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .skill-title h3 {&lt;br /&gt;
        margin: 0;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        text-align: center;&lt;br /&gt;
        font-size: 1.6em;&lt;br /&gt;
        color: #fff;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Description */&lt;br /&gt;
    /* Description box: remove own card background/shadow so it doesn't stack&lt;br /&gt;
       on top of the outer .content-card. The .content-card remains the main&lt;br /&gt;
       visual container. Keep padding and readable colors. */&lt;br /&gt;
    .desc-box {&lt;br /&gt;
        padding: 12px 18px; /* breathing room */&lt;br /&gt;
        background: transparent;&lt;br /&gt;
        border-radius: 6px;&lt;br /&gt;
        position: relative;&lt;br /&gt;
        box-shadow: none;&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        transition: all .3s ease;&lt;br /&gt;
        z-index: 2;&lt;br /&gt;
        overflow: visible;&lt;br /&gt;
        text-shadow: none;&lt;br /&gt;
        /* allow description area to grow but not force whole card height */&lt;br /&gt;
        height: auto;&lt;br /&gt;
        min-height: 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc-box h3 {&lt;br /&gt;
        font-size: 2.7em;&lt;br /&gt;
        margin: 0;&lt;br /&gt;
        text-align: center;&lt;br /&gt;
        padding-top: 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc {&lt;br /&gt;
        font-size: 1.32em !important;&lt;br /&gt;
        line-height: 1.7 !important;&lt;br /&gt;
        letter-spacing: .01em;&lt;br /&gt;
        /* preferred CSS fallback — JS will override to the video height when possible */&lt;br /&gt;
        max-height : clamp(10rem, 37vh, 21rem);&lt;br /&gt;
        /* keep scrollbar gutter stable to avoid layout shift of background/content */&lt;br /&gt;
        overflow-y: auto;&lt;br /&gt;
        scrollbar-gutter: stable;&lt;br /&gt;
        margin-top: 10px;&lt;br /&gt;
        padding-right: 8px;&lt;br /&gt;
        color: #f1efe9;&lt;br /&gt;
        /* allow long words/URLs to wrap instead of pushing layout */&lt;br /&gt;
        overflow-wrap: anywhere;&lt;br /&gt;
        word-break: break-word;&lt;br /&gt;
        white-space: normal;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc b,&lt;br /&gt;
    .desc strong {&lt;br /&gt;
        font-weight: 700;&lt;br /&gt;
        color: #fff;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc::-webkit-scrollbar {&lt;br /&gt;
        width: 7px;&lt;br /&gt;
        height: 7px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc::-webkit-scrollbar-thumb {&lt;br /&gt;
        background: #156bc7;&lt;br /&gt;
        border-radius: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc::-webkit-scrollbar-track {&lt;br /&gt;
        background: #151515a8;&lt;br /&gt;
        border-radius: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Attributes list */&lt;br /&gt;
    .attrs,&lt;br /&gt;
    .attr-list {&lt;br /&gt;
        display: block;&lt;br /&gt;
        margin: 6px 0 12px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .desc-box .attrs,&lt;br /&gt;
    .desc-box .attr-list,&lt;br /&gt;
    .desc-box .attrs *,&lt;br /&gt;
    .desc-box .attr-list * {&lt;br /&gt;
        text-shadow: none;&lt;br /&gt;
        font-family: 'Noto Sans', sans-serif;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .attrs__row,&lt;br /&gt;
    .attr-row {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        align-items: baseline;&lt;br /&gt;
        gap: 8px;&lt;br /&gt;
        min-height: 22px;&lt;br /&gt;
        line-height: 1.2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .attrs__row--empty,&lt;br /&gt;
    .attr-row.is-empty {&lt;br /&gt;
        visibility: hidden;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .attrs__label,&lt;br /&gt;
    .attr-label {&lt;br /&gt;
        font-weight: 700;&lt;br /&gt;
        color: #f0c87b;&lt;br /&gt;
        font-size: .98rem;&lt;br /&gt;
        white-space: nowrap;&lt;br /&gt;
        margin: 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .attrs__value,&lt;br /&gt;
    .attr-value {&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        font-weight: 800;&lt;br /&gt;
        /* equal size with label for consistent centering */&lt;br /&gt;
        font-size: .98rem;&lt;br /&gt;
        letter-spacing: .01em;&lt;br /&gt;
        margin: 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ensure rows center both label &amp;amp; value (value vertically centered on label) */&lt;br /&gt;
    .attr-row {&lt;br /&gt;
        align-items: center;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* remove fixed skill pane height and let content decide height */&lt;br /&gt;
    :root { --skill-pane-height: unset; }&lt;br /&gt;
    .skills-container { align-items: flex-start; }&lt;br /&gt;
&lt;br /&gt;
    /* Video container: allow the video to display at its original size&lt;br /&gt;
       while keeping it responsive (max-width:100%). Remove extra inner&lt;br /&gt;
       shadows so the .content-card is the primary card. Center content. */&lt;br /&gt;
    .video-container {&lt;br /&gt;
         position: relative;&lt;br /&gt;
         width: 100%;&lt;br /&gt;
         max-width: 100%;&lt;br /&gt;
         background: transparent;&lt;br /&gt;
         display: flex;&lt;br /&gt;
         align-items: center;&lt;br /&gt;
         justify-content: center;&lt;br /&gt;
         border-radius: 10px;&lt;br /&gt;
         box-shadow: none;&lt;br /&gt;
         overflow: hidden; /* rounded corners */&lt;br /&gt;
         padding: 0;&lt;br /&gt;
         z-index: 2;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     /* ensure every skill video has consistent visible size to avoid tiny thumbnails;&lt;br /&gt;
        videos fill the video column (responsive) using 16:9 to avoid layout jumps */&lt;br /&gt;
    .video-container&amp;gt;video {&lt;br /&gt;
        /* Preencher a coluna do vídeo; mostrar conteúdo inteiro sem recorte */&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
        aspect-ratio: 16 / 9;&lt;br /&gt;
        object-fit: contain;&lt;br /&gt;
        object-position: center;&lt;br /&gt;
        z-index: 2;&lt;br /&gt;
        display: block;&lt;br /&gt;
        border-radius: 6px;&lt;br /&gt;
        background: #000;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Center the placeholder/logo while videos load. Keep it as an overlay&lt;br /&gt;
       so it doesn't shift layout. */&lt;br /&gt;
    .video-placeholder {&lt;br /&gt;
        position: absolute;&lt;br /&gt;
        inset: 0;&lt;br /&gt;
        z-index: 6;&lt;br /&gt;
        display: flex;&lt;br /&gt;
        align-items: center;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        pointer-events: none;&lt;br /&gt;
        opacity: 1;&lt;br /&gt;
        transition: opacity .28s ease;&lt;br /&gt;
        background: linear-gradient(rgba(0,0,0,0.0), rgba(0,0,0,0.0)); /* transparent overlay but keeps stacking context */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .video-placeholder img {&lt;br /&gt;
        max-width: 160px;&lt;br /&gt;
        width: auto;&lt;br /&gt;
        height: auto;&lt;br /&gt;
        opacity: 0.98;&lt;br /&gt;
        display: block;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* fade-out helper used by JS removePlaceholder() */&lt;br /&gt;
    .video-placeholder.fade-out {&lt;br /&gt;
        opacity: 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @media (max-width:1100px) {&lt;br /&gt;
        .top-rail {&lt;br /&gt;
            flex-direction: column;&lt;br /&gt;
            align-items: stretch;&lt;br /&gt;
        }&lt;br /&gt;
        .top-rail .icon-bar {&lt;br /&gt;
            order: 2;&lt;br /&gt;
            width: 100%;&lt;br /&gt;
            flex-wrap: wrap;&lt;br /&gt;
        }&lt;br /&gt;
        .content-card.skills-grid { grid-template-columns: 1fr; }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @media (max-aspect-ratio: 3/4) {&lt;br /&gt;
         .character-header .character-art {&lt;br /&gt;
             display: none;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
        .video-container {&lt;br /&gt;
            width: 80%;&lt;br /&gt;
            border-radius: 3%;&lt;br /&gt;
            margin-top: 2%;&lt;br /&gt;
            align-self: center;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Tiers */&lt;br /&gt;
    .tier-bronze .topbar-icon,&lt;br /&gt;
    .tier-bronze .tier {&lt;br /&gt;
        outline: 2px solid #7b4e2f;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tier-silver .topbar-icon,&lt;br /&gt;
    .tier-silver .tier {&lt;br /&gt;
        outline: 2px solid #d6d2d2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tier-gold .topbar-icon,&lt;br /&gt;
    .tier-gold .tier {&lt;br /&gt;
        outline: 2px solid #fcd300;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .tier-diamond .topbar-icon,&lt;br /&gt;
    .tier-diamond .tier {&lt;br /&gt;
        outline: 2px solid #60dae2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Top rail: created dynamically by JS; styles for tabs header */&lt;br /&gt;
    .top-rail {&lt;br /&gt;
        display:flex;&lt;br /&gt;
        align-items:center;&lt;br /&gt;
        justify-content:center;&lt;br /&gt;
        width:max-content;&lt;br /&gt;
        max-width:96vw;&lt;br /&gt;
        margin:8px auto;&lt;br /&gt;
        padding:8px 12px;&lt;br /&gt;
        background:rgba(0,0,0,.55);&lt;br /&gt;
        border: 2px solid rgba(255,255,255,.08);&lt;br /&gt;
        border-radius: 12px;&lt;br /&gt;
        box-shadow: 0 4px 12px rgba(0,0,0,.25);&lt;br /&gt;
        -webkit-backdrop-filter:blur(2px);&lt;br /&gt;
        backdrop-filter:blur(2px);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* hide title by default (skills rail won't show it) */&lt;br /&gt;
    .top-rail .rail-title { display:none; }&lt;br /&gt;
&lt;br /&gt;
    /* skins variant shows the title at left */&lt;br /&gt;
    .top-rail.skins .rail-title {&lt;br /&gt;
        display:block;&lt;br /&gt;
        font-weight:800;&lt;br /&gt;
        font-size:clamp(20px,2.2vw,28px);&lt;br /&gt;
        color:#fff;&lt;br /&gt;
        margin-right:auto;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* center icons and keep scroll behavior if overflow */&lt;br /&gt;
    .top-rail .icon-bar {&lt;br /&gt;
        width:auto;&lt;br /&gt;
        justify-content:center;&lt;br /&gt;
        margin:0;&lt;br /&gt;
        overflow-x:auto; /* preserve horizontal scroll */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Card sizing: larger but constrained to viewport; padding included via box-sizing */&lt;br /&gt;
    .content-card {&lt;br /&gt;
        width: min(1600px, 96vw);&lt;br /&gt;
        max-width: 96vw;&lt;br /&gt;
        margin: 10px auto;&lt;br /&gt;
        background: #26211C;&lt;br /&gt;
        border-radius: 12px;&lt;br /&gt;
        box-shadow: 0 8px 24px rgba(0,0,0,.30);&lt;br /&gt;
        padding: 18px;&lt;br /&gt;
        z-index: 2; /* above overlay */&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
     /* layout specific for skills card: larger grid */&lt;br /&gt;
     /* Make the video column wider so the video has more space.&lt;br /&gt;
        minmax garante largura mínima para o vídeo e permite expansão até 70% do card. */&lt;br /&gt;
     .content-card.skills-grid {&lt;br /&gt;
         display: grid;&lt;br /&gt;
        /* user requested layout for testing: description column wider, video a bit smaller */&lt;br /&gt;
        grid-template-columns: minmax(320px, 60%) minmax(320px, 45%);&lt;br /&gt;
         gap: 16px; /* menor gap para evitar overflow */&lt;br /&gt;
         align-items: start; /* don't stretch items vertically */&lt;br /&gt;
         grid-auto-rows: auto;&lt;br /&gt;
         margin: 10px auto 0;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
    @media (max-width:1100px) {&lt;br /&gt;
        .top-rail {&lt;br /&gt;
            flex-direction: column;&lt;br /&gt;
            align-items: stretch;&lt;br /&gt;
        }&lt;br /&gt;
        .top-rail .icon-bar {&lt;br /&gt;
            order: 2;&lt;br /&gt;
            width: 100%;&lt;br /&gt;
            flex-wrap: wrap;&lt;br /&gt;
        }&lt;br /&gt;
        .content-card.skills-grid { grid-template-columns: 1fr; gap: 12px; }&lt;br /&gt;
        .video-container { width: 80%; max-width: 820px; align-self: center; }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @media (max-width:600px) {&lt;br /&gt;
    /* Make the card fit symmetrically on small screens (same left/right limit) */&lt;br /&gt;
    .content-card {&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
        /* limitar ao viewport menos safe-area + margem interna */&lt;br /&gt;
        max-width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right) - 16px);&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        margin: 10px auto;&lt;br /&gt;
        padding: 12px;&lt;br /&gt;
        border-radius: 10px;&lt;br /&gt;
        overflow: hidden; /* evita scroll horizontal causado por filhos */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* ensure the skills grid collapses to single column and doesn't overflow */&lt;br /&gt;
    .content-card.skills-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
        gap: 12px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* top-rail full width, icon bar flush edge-to-edge */&lt;br /&gt;
    .top-rail {&lt;br /&gt;
        width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right));&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        margin: 0 auto 8px;&lt;br /&gt;
        padding: 6px 8px;&lt;br /&gt;
        border-radius: 0;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
        overflow: hidden;&lt;br /&gt;
    }&lt;br /&gt;
    .top-rail .icon-bar {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        padding: 0 6px;&lt;br /&gt;
        gap: 12px;&lt;br /&gt;
        justify-content: flex-start;&lt;br /&gt;
        overflow-x: auto;&lt;br /&gt;
        -webkit-overflow-scrolling: touch;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* larger, more visible icons on mobile */&lt;br /&gt;
    :root { --icon-size: 92px; } /* overrides default on mobile */&lt;br /&gt;
    .icon-bar .skill-icon {&lt;br /&gt;
        width: var(--icon-size);&lt;br /&gt;
        height: var(--icon-size);&lt;br /&gt;
        flex: 0 0 auto;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* limitar explicitamente elementos do vídeo/skins para não extrapolarem */&lt;br /&gt;
    .video-container,&lt;br /&gt;
    .skins-carousel-wrapper,&lt;br /&gt;
    .skins-carousel {&lt;br /&gt;
        max-width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right) - 16px);&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    .video-container &amp;gt; video,&lt;br /&gt;
    .video-container img,&lt;br /&gt;
    .skins-carousel img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* extra safety: prevent horizontal scroll coming from other elements using 100vw */&lt;br /&gt;
    html, body, .mw-body, .mw-body-content {&lt;br /&gt;
        overflow-x: hidden;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===========================&lt;br /&gt;
   Base — mobile/overflow guards&lt;br /&gt;
   =========================== */&lt;br /&gt;
/* evitar qualquer elemento extrapolar o viewport e respeitar safe-area (iPhone notch) */&lt;br /&gt;
html, body, .mw-body, .mw-body-content {&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    max-width: 100vw;&lt;br /&gt;
    overflow-x: hidden;&lt;br /&gt;
    -webkit-overflow-scrolling: touch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* garantir imagens / vídeos internos não forçarem overflow */&lt;br /&gt;
.content-card, .top-rail, .video-container, .skins-carousel-wrapper, .skins-carousel {&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
/* impedir filhos de extrapolarem a coluna do card */&lt;br /&gt;
.content-card *,&lt;br /&gt;
.top-rail *,&lt;br /&gt;
.video-container * {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ---------------------------&lt;br /&gt;
   Visual tweaks: icons, attrs, desc&lt;br /&gt;
   --------------------------- */&lt;br /&gt;
/* override base icon size (desktop) */&lt;br /&gt;
:root {&lt;br /&gt;
    --icon-size: 56px;   /* desktop icons larger */&lt;br /&gt;
    --icon-radius: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* make skill icons use the variable (safety if other rules exist) */&lt;br /&gt;
.icon-bar .skill-icon {&lt;br /&gt;
    width: var(--icon-size) !important;&lt;br /&gt;
    height: var(--icon-size) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon active color variables (only for icon visuals: border + glow) */&lt;br /&gt;
:root {&lt;br /&gt;
    --icon-active: #F7D34B;&lt;br /&gt;
    --icon-active-ring: rgba(247,211,75,.35);&lt;br /&gt;
    --icon-active-glow: rgba(247,211,75,.32);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ensure perfect clipping and aligned border for skill icons */&lt;br /&gt;
.icon-bar .skill-icon {&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: var(--icon-radius);&lt;br /&gt;
    contain: paint;&lt;br /&gt;
    width: var(--icon-size) !important;&lt;br /&gt;
    height: var(--icon-size) !important;&lt;br /&gt;
    position: relative; /* keep stacking for pseudo element */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon img {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    border-radius: inherit;&lt;br /&gt;
    clip-path: inset(0 round var(--icon-radius));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon::after {&lt;br /&gt;
    border-radius: inherit;&lt;br /&gt;
    /* keep neutral/inactive ring defined elsewhere; this ensures radius matches image */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon.active::after {&lt;br /&gt;
    border-color: var(--icon-active);&lt;br /&gt;
    box-shadow: 0 0 0 2px var(--icon-active), 0 0 0 4px var(--icon-active-ring), 0 0 10px 2px var(--icon-active-glow);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Tooltip style (single global tooltip attached to body to avoid clipping) */&lt;br /&gt;
.skill-tooltip {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    padding: 6px 8px;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    background: rgba(17,17,17,.9);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0,0,0,.5);&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity .12s ease, transform .08s ease;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon clipping, ring and active halo (overrides; scoped to icons only) */&lt;br /&gt;
:root {&lt;br /&gt;
    --icon-ring-w: 2px;&lt;br /&gt;
    --icon-idle: #bbb;&lt;br /&gt;
    --icon-active: #FFD95A;                 /* amarelo mais visível */&lt;br /&gt;
    --icon-active-ring: rgba(255,217,90,.50);&lt;br /&gt;
    --icon-active-glow: rgba(255,217,90,.38);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    outline: none !important;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: var(--icon-radius);&lt;br /&gt;
    contain: paint;&lt;br /&gt;
    isolation: isolate;&lt;br /&gt;
    will-change: transform;&lt;br /&gt;
    transform: translateZ(0);&lt;br /&gt;
    /* keep original sizing/flow from existing rules (do not change --icon-size) */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon img {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    border-radius: inherit;&lt;br /&gt;
    -webkit-clip-path: inset(0 round var(--icon-radius));&lt;br /&gt;
    clip-path: inset(0 round var(--icon-radius));&lt;br /&gt;
    transition: transform .12s ease;&lt;br /&gt;
    backface-visibility: hidden;&lt;br /&gt;
    transform: translateZ(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border-radius: inherit;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    z-index: 2;&lt;br /&gt;
    /* internal ring that NEVER changes thickness between states */&lt;br /&gt;
    box-shadow: inset 0 0 0 var(--icon-ring-w) var(--icon-idle);&lt;br /&gt;
    transition: box-shadow .12s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.icon-bar .skill-icon::before {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: -2px;&lt;br /&gt;
    border-radius: calc(var(--icon-radius) + 2px);&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
    box-shadow: none;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity .12s ease, box-shadow .12s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Active state: gentle scale + yellow ring + halo. No change in ring thickness. */&lt;br /&gt;
.icon-bar .skill-icon.active {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
}&lt;br /&gt;
.icon-bar .skill-icon.active::after {&lt;br /&gt;
    box-shadow: inset 0 0 0 var(--icon-ring-w) var(--icon-active);&lt;br /&gt;
}&lt;br /&gt;
.icon-bar .skill-icon.active::before {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
    box-shadow:&lt;br /&gt;
        0 0 12px 3px var(--icon-active-glow),&lt;br /&gt;
        0 0 0 4px var(--icon-active-ring);&lt;br /&gt;
}&lt;br /&gt;
.icon-bar .skill-icon.active img {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover should never change ring thickness — only color hint */&lt;br /&gt;
.icon-bar .skill-icon:hover:not(.active)::after {&lt;br /&gt;
    box-shadow: inset 0 0 0 var(--icon-ring-w) #e0e0e0;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
     /* ===========================&lt;br /&gt;
   Fixed background (scoped to article content only)&lt;br /&gt;
   =========================== */&lt;br /&gt;
/* aplicar o background apenas quando .character-box estiver dentro do conteúdo do artigo */&lt;br /&gt;
.mw-body-content .character-box {&lt;br /&gt;
    background-image: url(&amp;quot;https://i.imgur.com/RktmgO8.png&amp;quot;);&lt;br /&gt;
    background-position: center top;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    /* keep the visual background stable when content height changes.&lt;br /&gt;
       using fixed attachment prevents the artwork from scaling as the box grows. */&lt;br /&gt;
    background-size: cover;&lt;br /&gt;
    background-attachment: fixed;&lt;br /&gt;
    position: relative; /* stacking context para pseudo-elementos */&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* overlay interno (escuro) acima do background mas abaixo do conteúdo da caixa */&lt;br /&gt;
.mw-body-content .character-box::before {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    background: linear-gradient(to bottom, rgba(0,0,0,.45), rgba(0,0,0,.60));&lt;br /&gt;
    z-index: 0; /* abaixo do conteúdo (.character-box deve ter z-index &amp;gt; 0) */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* remove any previous global fixed rules that targeted body.character-bg .character-box&lt;br /&gt;
   NOTE: original reset removed the background we want; removed to keep .character-box background. */&lt;br /&gt;
/* (reset removed) */&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lucky Jao</name></author>
	</entry>
</feed>