JVCash

Amélioration de l'interface

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         JVCash
// @description  Amélioration de l'interface
// @namespace    http://tampermonkey.net/
// @version      3.128
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function isForumListPage() {
        return document.querySelector('.tablesForum, .tablesForum--listTopics');
    }

    function isTopicPage() {
        return document.querySelector('#js-list-message-tools-actions');
    }

    function isForumPage() {
        return /\/forums\/0-\d+-/.test(location.href);
    }

    function replaceForumHeaderLabels() {
        const participants = document.querySelector('.tablesForum__rowParticipants');
        const rep = document.querySelector('.tablesForum__rowNbMessages');

        if (participants && participants.dataset.replaced !== "1") {
            participants.textContent = "Pseudos";
            participants.dataset.replaced = "1";
        }

        if (rep && rep.dataset.replaced !== "1") {
            rep.textContent = "Posts";
            rep.dataset.replaced = "1";
        }
    }

    function replaceLastPageButton() {
        const lastBtn = document.querySelector('.pagination__button--last');

        if (lastBtn && lastBtn.dataset.replaced !== "1") {
            lastBtn.textContent = "Dernière page";
            lastBtn.dataset.replaced = "1";
        }
    }

    function cleanForumAvatars() {
        if (!isForumListPage()) return;

        document.querySelectorAll('.sideCardForum__listItemAvatar').forEach(el => {
            el.style.display = "none";
        });
    }

    function addAdminSection() {
        const list = document.querySelector('.sideCardForum__list');
        if (!list) return;

        if (document.querySelector('.sideCardForum__listItem--admin')) return;

        const modsItem = document.querySelector('.sideCardForum__listItem--moderators');
        if (!modsItem) return;

        const links = modsItem.querySelectorAll('span.sideCardForum__listItemLink');

        let keptMods = [];

        links.forEach(link => {
            const name = link.textContent.trim();
            if (name !== "Suumas") {
                keptMods.push(link.outerHTML);
            }
        });

        modsItem.innerHTML = `
            Modos bénévoles : ${keptMods.join(', ')}
        `;

        const admin = document.createElement('li');
        admin.className = 'sideCardForum__listItem sideCardForum__listItem--admin';

        admin.innerHTML = `
            Admin salarié :&nbsp;<span class="sideCardForum__listItemLink sideCardForum__listItemLink--text sideCardForum__listItemLink--bold">Suumas</span>
        `;

        modsItem.parentNode.insertBefore(admin, modsItem.nextSibling);
    }

    function replaceContactModeratorsText() {
        const link = document.querySelector('a[title="Contacter les modérateurs"]');

        if (!link) return;
        if (link.dataset.replaced === "1") return;

        link.textContent = "Contacter les responsables";
        link.dataset.replaced = "1";
    }

    function replaceUserCountText() {
        const container = document.querySelector('.userCount');
        if (!container) return;

        if (container.dataset.replaced === "1") return;

        const textNode = Array.from(container.childNodes)
            .find(n => n.nodeType === 3 && n.textContent.includes('connect'));

        if (textNode) {
            textNode.textContent = ' /51404 connectés';
            container.dataset.replaced = "1";
        }
    }

    function fixUserCountPosition() {
        const el = document.querySelector('.userCount');
        if (!el) return;

        el.style.transform = "translateX(-3px)";
    }

    function moveDeleteButtonBeforeQuote() {
        if (!isTopicPage()) return;

        document.querySelectorAll('.messageUser').forEach(msg => {
            const group = msg.querySelector('.messageUser__groupFills');
            if (!group) return;

            const deleteBtn = group.querySelector('button[title="Supprimer le message"]');
            const quoteBtn = group.querySelector('button[title="Citer le message"]');

            if (!deleteBtn || !quoteBtn) return;
            if (deleteBtn.dataset.moved === "1") return;

            deleteBtn.dataset.moved = "1";

            if (deleteBtn.parentNode !== group) {
                group.appendChild(deleteBtn);
            }

            group.insertBefore(deleteBtn, quoteBtn);
            deleteBtn.style.transform = "translateX(6px)";
        });
    }

    function moveNavTopSafe() {
        const navTop = document.querySelector('.container__navTop');
        const breadcrumb = document.querySelector('.breadcrumb');

        if (!navTop || !breadcrumb || !breadcrumb.parentNode) return;
        if (navTop.dataset.moved === "1") return;

        let wrapper = document.querySelector('#jvc-breadcrumb-row');

        if (!wrapper) {
            wrapper = document.createElement('div');
            wrapper.id = 'jvc-breadcrumb-row';
            wrapper.style.display = 'flex';
            wrapper.style.alignItems = 'center';
            wrapper.style.justifyContent = 'space-between';
            wrapper.style.width = '100%';
        }

        breadcrumb.parentNode.insertBefore(wrapper, breadcrumb.nextSibling);

        wrapper.appendChild(breadcrumb);
        wrapper.appendChild(navTop);

        navTop.dataset.moved = "1";
    }

    function fixButtonsNavbarPosition() {
        const title = document.querySelector('.titleMessagesUsers__title');
        const navbar = document.querySelector('.buttonsNavbar.buttonsNavbar--search');

        if (!title || !navbar) return;
        if (navbar.dataset.moved === "1") return;

        title.parentNode.insertBefore(navbar, title.nextSibling);

        navbar.dataset.moved = "1";
        navbar.style.position = 'relative';
        navbar.style.marginTop = '-16px';
        navbar.style.transform = 'none';
        navbar.style.boxShadow = 'none';
    }

    function fixButtonsNavbarOnTopics() {
        const navbar = document.querySelector('.buttonsNavbar');
        if (!navbar) return;
        if (!isTopicPage()) return;
        if (navbar.dataset.topicFixed === "1") return;

        navbar.dataset.topicFixed = "1";
        navbar.style.position = 'relative';
        navbar.style.transform = 'none';
        navbar.style.boxShadow = 'none';
        navbar.style.border = 'none';
    }

    function shiftMessageToolbarOnlyOnTopic() {
        if (!isTopicPage()) return;

        const container = document.querySelector('#js-list-message-tools-actions');
        if (!container) return;

        if (container.dataset.shifted === "1") return;
        container.dataset.shifted = "1";

        container.style.transform = "translateY(-170px)";
        container.style.position = "relative";
    }

    function shiftTopPaginationOnTopic() {
        if (!isTopicPage()) return;

        const nav = document.querySelector('.pagination__navigation--zone1');
        if (!nav) return;

        if (nav.dataset.shiftedTop === "1") return;
        nav.dataset.shiftedTop = "1";

        nav.style.transform = "translateY(-25px)";
        nav.style.position = "relative";
    }

    function shiftZone3Pagination() {
        const nav = document.querySelector('.pagination__navigation--zone2, .pagination__navigation--zone3, .pagination__navigation--zone4');
        if (!nav) return;

        const currentBtn = nav.querySelector('.pagination__button--current');
        if (!currentBtn) return;

        const page = parseInt(currentBtn.textContent.trim(), 10);
        if (isNaN(page) || page < 10) return;

        if (nav.dataset.shiftedZone3 === "1") return;
        nav.dataset.shiftedZone3 = "1";

        if (nav.classList.contains('pagination__navigation--zone2')) {
            nav.style.transform = "translateY(-26px)";
        } else {
            nav.style.transform = "translateY(-26px)";
        }

        nav.style.position = "relative";
    }

    function fixPaginationSpacingBelowOnTopic() {
        if (!isTopicPage()) return;

        const wrapper = document.querySelector('.js-pagination-top.container__pagination');
        if (!wrapper) return;

        if (wrapper.dataset.spacingFixed === "1") return;
        wrapper.dataset.spacingFixed = "1";

        wrapper.style.marginBottom = "-22px";
    }

    function moveMessageActionsToHeader() {
        if (!isTopicPage()) return;

        document.querySelectorAll('.messageUser').forEach(msg => {
            const header = msg.querySelector('.messageUser__header');
            const footer = msg.querySelector('.messageUser__footer');

            if (!header || !footer) return;
            if (footer.dataset.moved === "1") return;

            footer.dataset.moved = "1";

            footer.style.border = "none";
            footer.style.boxShadow = "none";
            footer.style.background = "transparent";

            let right = header.querySelector('.jvc-actions-right');

            if (!right) {
                right = document.createElement('div');
                right.className = 'jvc-actions-right';

                right.style.marginLeft = 'auto';
                right.style.display = 'flex';
                right.style.alignItems = 'center';

                header.style.display = 'flex';
                header.style.alignItems = 'center';

                header.appendChild(right);
            }

            right.appendChild(footer);
        });
    }

    function moveCheckboxPosition() {
        if (!isTopicPage()) return;

        document.querySelectorAll('.messageUser__checkboxContainer').forEach(el => {
            if (el.dataset.moved === "1") return;
            el.dataset.moved = "1";

            el.style.position = "relative";
            el.style.left = "+4px";
            el.style.top = "0px";
        });
    }

    function fixDropdownClickBug() {
        document.querySelectorAll('.dropdownCustom__list').forEach(menu => {
            const style = getComputedStyle(menu);
            const rect = menu.getBoundingClientRect();

            const isVisible =
                style.display !== "none" &&
                style.visibility !== "hidden" &&
                style.opacity !== "0" &&
                rect.width > 0 &&
                rect.height > 0;

            menu.style.pointerEvents = isVisible ? "auto" : "none";
        });
    }

    function shiftSurveyBoxesOnTopic() {
        if (!isTopicPage()) return;

        document.querySelectorAll('.surveyResults').forEach(box => {
            if (box.dataset.shifted === "1") return;
            box.dataset.shifted = "1";

            box.style.position = "relative";
            box.style.transform = "translateY(-65px)";
        });
    }

    function injectCSS() {
        const style = document.createElement('style');
        const forumPage = isForumPage();

        style.textContent = `
            .header,
            .header__top {
                box-shadow: none !important;
                position: relative !important;
            }

            .header__bottom,
            .layout__adHeader {
                display: none !important;
            }

            #content,
            .content,
            .layout,
            .layout__container,
            .main,
            main,
            #bloc-page {
                margin-top: 0 !important;
                padding-top: 0 !important;
            }

            body {
                margin-top: 0 !important;
            }

            .buttonsNavbar {
                box-shadow: none !important;
                border: none !important;
                background: ${forumPage ? 'transparent' : '#ffffff'} !important;
            }

            .buttonsNavbar.buttonsNavbar--search {
                display: none !important;
            }

            .buttonsNavbar__space {
                display: none !important;
            }

            #js-list-topics-tools-actions {
                display: none !important;
                height: 0 !important;
                margin: 0 !important;
                padding: 0 !important;
            }

            .titleMessagesUsers__title {
                margin-top: -30px !important;
                margin-bottom: 4px !important;
            }

            .container__navTop {
                margin-bottom: -10px !important;
            }

            .js-pagination-top.container__pagination {
                margin-top: -43px !important;
            }

            ul.tablesForum.tablesForum--listTopics {
                transform: translateY(-32px) !important;
            }

            ul.dropdownCustom__list {
                transform: translateX(-278px) !important;
            }

            .sideCardForum__listItemAvatar {
                display: none !important;
            }

            .messageUser__header {
                display: flex !important;
                align-items: center !important;
            }

            .messageUser__footer {
                border: none !important;
                box-shadow: none !important;
                background: transparent !important;
                margin: 0 !important;
                padding: 0 !important;
            }

            .messageUser__fills {
                display: flex !important;
                align-items: center !important;
                gap: 3px !important;
            }

            .messageUser__action {
                margin: 0 !important;
            }

            .userCount {
                transform: translateX(-3px) !important;
            }

            .surveyResults {
                position: relative !important;
            }

            button[title="Citer le message"] {
                transform: translateX(-3px);
            }

            .messageUser__header button[title="Citer le message"] {
                transform: translateX(-3px) !important;
                margin-left: 0px !important;
            }
        `;

        document.head.appendChild(style);
    }

    function clean() {
        const header = document.querySelector('.header');
        const headerTop = document.querySelector('.header__top');
        const headerBottom = document.querySelector('.header__bottom');

        if (header) {
            header.style.position = 'relative';
            header.style.boxShadow = 'none';
            header.classList.remove('sticky', 'is-sticky', 'fixed', 'header--sticky');
        }

        if (headerTop) {
            headerTop.style.position = 'relative';
            headerTop.style.boxShadow = 'none';
            headerTop.style.zIndex = '1';
        }

        if (headerBottom) headerBottom.style.display = 'none';

        document.querySelectorAll('.header__nav--platform, .layout__adHeader')
            .forEach(el => el.style.display = 'none');

        document.body.style.marginTop = '0px';

        document.querySelectorAll('#content,.content,.layout,.layout__container,.main,main,#bloc-page')
            .forEach(el => {
                el.style.marginTop = '0px';
                el.style.paddingTop = '0px';
            });

        document.querySelectorAll('.buttonsNavbar').forEach(el => {
            el.classList.remove('buttonsNavbar__sticky', 'is-sticky', 'buttonsNavbar--sticky');
            el.style.transform = 'none';
            el.style.zIndex = 'auto';
            el.style.boxShadow = 'none';
        });
    }

    function run() {
        injectCSS();
        clean();

        replaceForumHeaderLabels();
        replaceLastPageButton();

        cleanForumAvatars();
        addAdminSection();
        replaceContactModeratorsText();
        replaceUserCountText();

        moveNavTopSafe();
        fixButtonsNavbarPosition();
        fixButtonsNavbarOnTopics();

        shiftMessageToolbarOnlyOnTopic();
        shiftTopPaginationOnTopic();

        shiftZone3Pagination();

        fixPaginationSpacingBelowOnTopic();

        moveMessageActionsToHeader();
        moveDeleteButtonBeforeQuote?.();

        moveCheckboxPosition();
        fixDropdownClickBug();
        fixUserCountPosition();

        shiftSurveyBoxesOnTopic();
    }

    run();

    const observer = new MutationObserver(() => run());
    observer.observe(document.body, { childList: true, subtree: true });

    window.addEventListener('load', run);

})();

// ==UserScript==
// @name         JVC Search Panel + Settings (UI improved)
// @namespace    http://tampermonkey.net/
// @version      3.6
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const BASE_URL =
        "https://www.jeuxvideo.com/recherche/forums/0-51-0-1-0-1-0-blabla-18-25-ans.htm";

    let internalClick = false;

    function injectCSS() {
        if (document.getElementById('jvc-style')) return;

        const style = document.createElement('style');
        style.id = 'jvc-style';

        style.textContent = `
            #jvc-container {
                position: fixed;
                left: 15px;
                bottom: 15px;
                display: flex;
                flex-direction: column;
                gap: 7px;
                z-index: 9999;
            }

            #jvc-container > div {
                width: 45px;
                height: 45px;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 50%;
                cursor: pointer;

                background: #2f6fed;
                color: #fff;
                border: 2px solid transparent;
                transition: all 0.15s ease;
            }

            #jvc-container > div:hover {
                background: #fff;
                color: #2f6fed;
                border: 2px solid #2f6fed;
            }

            #jvc-container > div.active {
                background: #fff;
                color: #ff8a00;
                border: 2px solid #ff8a00;
            }

            /* PANELS */
            #jvc-panel,
            #jvc-settings {
                position: fixed;
                left: 75px;
                bottom: 15px;
                width: 300px;
                border-radius: 10px;
                box-shadow: 0 5px 20px rgba(0,0,0,0.2);
                padding: 10px;
                display: none;
                flex-direction: column;
                gap: 10px;
                z-index: 9999;
                font-family: sans-serif;
            }

            /* SEARCH PANEL BLEU */
            #jvc-panel {
                background: #2f6fed;
            }

            /* SETTINGS PANEL BLANC */
            #jvc-settings {
                background: #fff;
            }

            #jvc-panel.open,
            #jvc-settings.open {
                display: flex;
            }

            #jvc-settings,
            #jvc-settings * {
                color: #000 !important;
            }

            .jvc-setting span {
                font-size: 15px;
            }

            #jvc-panel input,
            #jvc-panel select,
            #jvc-panel button {
                color: #000 !important;
                background-color: #fff !important;
            }

            #jvc-panel select,
            #jvc-panel input,
            #jvc-panel button {
                border: none;
                outline: none;
            }

            .jvc-setting {
                display: flex;
                justify-content: space-between;
                align-items: center;
                font-size: 13px;
                padding: 4px 0;
            }

            .jvc-switch {
                width: 40px;
                height: 20px;
                border-radius: 10px;
                background: #ccc;
                position: relative;
                cursor: pointer;
            }

            .jvc-switch.active {
                background: #2f6fed;
            }

            .jvc-switch::after {
                content: "";
                position: absolute;
                width: 16px;
                height: 16px;
                top: 2px;
                left: 2px;
                background: #fff;
                border-radius: 50%;
                transition: 0.2s;
            }

            .jvc-switch.active::after {
                left: 22px;
            }

            #forums-settings-app {
                position: fixed !important;
                width: 1px !important;
                height: 1px !important;
                overflow: hidden !important;
                opacity: 0 !important;
                pointer-events: none !important;
                top: 0 !important;
                left: 0 !important;
                z-index: -1 !important;
            }
        `;

        document.head.appendChild(style);
    }

    function readInitialState(label) {
        const dom = [...document.querySelectorAll('.userParameters__parameterText')]
            .find(e => e.textContent.trim() === label);

        if (!dom) return false;

        const btn = dom.closest('.userParameters__parameterItem')
            ?.querySelector('.buttonSwitch');

        if (!btn) return false;

        if (btn.classList.contains('buttonSwitch--isActive')) return true;

        const bg = getComputedStyle(btn).backgroundColor;
        if (bg === 'rgb(47, 111, 237)') return true;

        return false;
    }

    function createUI() {
        if (document.getElementById('jvc-container')) return;

        const container = document.createElement('div');
        container.id = 'jvc-container';

        const toggle = document.createElement('div');
        toggle.textContent = '🔍';

        const settingsBtn = document.createElement('div');
        settingsBtn.textContent = '⚙️';

        container.appendChild(toggle);
        container.appendChild(settingsBtn);

        const panel = document.createElement('div');
        panel.id = 'jvc-panel';

        panel.innerHTML = `
            <select id="jvc-type">
                <option value="titre_topic">Sujet</option>
                <option value="auteur_topic">Auteur</option>
                <option value="texte_message">Message</option>
            </select>
            <input id="jvc-input" placeholder="Rechercher">
            <button id="jvc-ok">Ok</button>
        `;

        const settings = document.createElement('div');
        settings.id = 'jvc-settings';

        const items = [
            "Afficher les avatars",
            "Afficher les signatures",
            "Afficher les spoilers",
            "Miniatures noelshack",
            "Afficher les vidéos",
            "Liste des sujets classique",
            "Densité compacte",
            "Alternance de couleurs"
        ];

        settings.innerHTML = items.map(t => `
            <div class="jvc-setting">
                <span>${t}</span>
                <div class="jvc-switch"></div>
            </div>
        `).join('');

        document.body.appendChild(container);
        document.body.appendChild(panel);
        document.body.appendChild(settings);

        function closeAll() {
            toggle.classList.remove('active');
            settingsBtn.classList.remove('active');
        }

        toggle.onclick = (e) => {
            e.stopPropagation();
            const open = panel.classList.toggle('open');
            settings.classList.remove('open');
            closeAll();
            if (open) toggle.classList.add('active');
        };

        settingsBtn.onclick = (e) => {
            e.stopPropagation();
            const open = settings.classList.toggle('open');
            panel.classList.remove('open');
            closeAll();
            if (open) settingsBtn.classList.add('active');
        };

        document.getElementById('jvc-ok').onclick = () => {
            const val = document.getElementById('jvc-input').value.trim();
            const type = document.getElementById('jvc-type').value;
            if (!val) return;

            location.href =
                `${BASE_URL}?search_in_forum=${encodeURIComponent(val)}&type_search_in_forum=${type}`;
        };

        const switches = document.querySelectorAll('.jvc-switch');

        switches.forEach((sw, i) => {
            const label = items[i];

            if (readInitialState(label)) sw.classList.add('active');

            sw.onclick = () => {
                internalClick = true;
                sw.classList.toggle('active');

                const dom = [...document.querySelectorAll('.userParameters__parameterText')]
                    .find(e => e.textContent.trim() === label);

                dom?.closest('.userParameters__parameterItem')
                    ?.querySelector('.buttonSwitch')
                    ?.click();

                setTimeout(() => internalClick = false, 0);
            };
        });

        document.addEventListener('click', (e) => {
            if (internalClick) return;

            if (
                settings.contains(e.target) ||
                panel.contains(e.target) ||
                container.contains(e.target)
            ) return;

            panel.classList.remove('open');
            settings.classList.remove('open');
            closeAll();
        });
    }

    function init() {
        injectCSS();
        createUI();
    }

    init();

})();

// ==UserScript==
// @name         JVC Navbar Middle Click FIX (SAFE NO STEAL)
// @namespace    http://tampermonkey.net/
// @version      2.5.4
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function getButtons() {
        return document.querySelectorAll('.buttonsNavbar__button');
    }

    function getStableForumUrl() {
        const link =
            document.querySelector('.breadcrumb a[href*="/forums/"]') ||
            document.querySelector('a[href*="/forums/0-"]');

        if (link && link.href && !link.href.includes("forums.htm")) {
            return link.href.split('#')[0];
        }

        return location.href.split('#')[0];
    }

    function resolveAction(btn) {
        const label = btn.querySelector('.buttonsNavbar__label')
            ?.textContent.trim().toLowerCase();

        const base = getStableForumUrl();

        if (label === "répondre") {
            return location.href.split('#')[0] + "#forums-post-message-editor";
        }

        if (label === "nouveau sujet") {
            return base + "#forums-post-topic-editor";
        }

        if (label === "liste des sujets") {
            return base;
        }

        if (label === "actualiser") {
            return location.href.split('#')[0] + "?_refresh=" + Date.now();
        }

        return location.href;
    }

    function openInNewTab(url) {
        window.open(url, '_blank', 'noopener,noreferrer');
    }

    function blockAll(e) {
        if (e.button !== 1) return;

        e.preventDefault();
        e.stopImmediatePropagation();
        e.stopPropagation();
    }

    function init() {
        getButtons().forEach(btn => {
            if (btn.dataset.midclick === "1") return;
            btn.dataset.midclick = "1";

            btn.addEventListener('mousedown', blockAll, true);
            btn.addEventListener('mouseup', blockAll, true);
            btn.addEventListener('click', blockAll, true);

            btn.addEventListener('auxclick', (e) => {
                if (e.button !== 1) return;

                e.preventDefault();
                e.stopImmediatePropagation();

                const url = resolveAction(btn);
                openInNewTab(url);
            }, true);
        });
    }

    init();

    const observer = new MutationObserver(init);
    observer.observe(document.body, { childList: true, subtree: true });

})();

// ==UserScript==
// @name         JVC Fake Connectés (stable)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const MIN = 51390;
    const MAX = 51430;

    let fakeCount = Number(localStorage.getItem('jvc_fake_count'));

    if (!fakeCount || fakeCount < MIN || fakeCount > MAX) {
        fakeCount = 51404;
    }

    let lastUpdate = 0;

    function alertVisible() {
        return /(\[?\s*alerte\s*\]?)/i.test(document.body.textContent);
    }

    function maybeUpdate() {
        const now = Date.now();

        if (!alertVisible()) return;
        if (now - lastUpdate < 2000) return;

        lastUpdate = now;

        fakeCount += Math.random() < 0.5 ? 1 : -1;

        if (fakeCount < MIN) fakeCount = MIN;
        if (fakeCount > MAX) fakeCount = MAX;

        localStorage.setItem('jvc_fake_count', fakeCount);
    }

    function applyOnce() {
        const el = document.querySelector('.userCount');
        if (!el) return;

        maybeUpdate();

        const node = Array.from(el.childNodes)
            .find(n => n.nodeType === 3 && /connect/i.test(n.textContent));

        if (node) {
            node.textContent = ` /${fakeCount} connectés`;
        }
    }

    function runOnce() {
        applyOnce();
    }

    window.addEventListener('load', runOnce);

    const observer = new MutationObserver(() => {
        runOnce();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();

// ==UserScript==
// @name         JVC Taux de glissade (gradient 1-200)
// @namespace    http://tampermonkey.net/
// @version      1.3
// @match        https://www.jeuxvideo.com/forums/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // ================== MOTS MODIFIABLES ==================
    const TARGET_WORDS = ["lol", "ui", "mdrr", "nn", "pq", "pk", "mp", "slt", "dsl", "deso", "déso", "qq", "mdrrr", "wi", "put1", "pb", "tt", "ftg", "qqu", "mdr", "lols", "xptdr", "frr", "pa", "cv?", "osef", "cc", "mnt", "oklm", "ajd", "tlm", "jpp", "ez", "gpalu", "stv", "mps", "cimer", "rofl", "qqch", "bcp", "milf", "aw", "gg", "c", "vazy", "ptdr", "goat", "yrr", "ykk", "l'op", "not rdy", "cte", "ste", "cdd", "cdi", "rsa", "fdp", "nimp", "aah", "l'aah", "jtm", "tkt", "rdv", "ptn", "a+", "mci", "tjr", "tjrs", "omg", "ntm", "askip", "def", "pls", "bz", "pyj", "pnj", "vdd", "svp", "stp", "ddb", "xd", "fap", "m+z", "z+v", "c+t", "ptdrrr", "mma", "wtf", "jvc", "qi", "btg", "kj", "bmg", "jsp", "jyfu", "yorarien", "msn", "msg", "bg", "qd", "mm", "bgs", "pemt", "ist", "mst", "kel", "gouine", "gouines", "pédé", "pédés", "babtou", "babtoue", "babtous", "babtoues", "blanco", "blancos", "boucaque", "boucaques", "bounioul", "bouniouls", "bounioule", "bounioules", "chinetoc", "chinetocs", "chinetoque", "chinetoques", "fiotte", "fiottes", "frouze", "frouzes", "droitardé", "droitardés", "droitardée", "droitardées", "gauchiasse", "gauchiasses", "facho", "fachos", "fasciste", "fascistes", "gwer", "gwers", "kaffir", "kafir", "kaffirs", "kafirs", "makoumé", "makoumés", "bamboula", "bamboulas", "nègre", "nègres", "nègresse", "nègresses", "niaouké", "niaoukés", "youtre", "youtres", "youpin", "youpins", "youp", "youps", "youd", "youds", "youpine", "youpines", "tapette", "tapettes", "féminazie", "féminazies", "tantouze", "tantouzes", "nazillard", "nazillards", "nazillon", "nazillons", "nazillar", "nazillars", "chouffax", "muzz", "pd", "pds", "negre", "negres", "negro", "negros", "choffa", "choffas", "chofchof", "chofchofs", "chofa", "chofas", "tafiole", "tafioles", "taffiole", "taffioles", "pucix", "gaucho", "gauchos", "chof", "chofs", "chouffin", "chouffins", "bougnouke", "bougnoukes", "bougnoul", "bougnouls", "bougnoule", "bougnoules", "batards", "bâtard", "bâtards", "batar", "batars", "batarde", "tarés", "tg", "batardes", "hypocrite", "hypocrites", "con", "cons", "conne", "connes", "connard", "connards", "connasse", "connasses", "salaud", "salauds", "salaude", "salaudes", "idiot", "idiots", "idiote", "idiotes", "mange-merde", "mange-merdes", "abruti", "abrutis", "abrutie", "abruties", "salope", "salopes", "shlag", "shlags", "schlag", "schlags", "pute", "putes", "garce", "garces", "bouffon", "bouffons", "imbécile", "imbéciles", "incel", "incels", "crétin", "crétins", "crétine", "crétines", "autiste", "autistes", "enfoiré", "enfoirés", "salopard", "salopards", "lemgo", "lemgos", "l'idiot", "l'idiote", "batard", "tocards", "branleurs", "gogol", "gourdasse", "catin", "d'abruti", "d'abrutis", "d'idiot", "d'idiote", "enculé", "trisos", "gogols", "débile", "débiles", "taré", "tarée", "fou", "folle", "cinglées", "magalax", "teubé", "teubés", "teubée", "teubées", "golem", "golems", "cinglé", "cinglés", "cinglée", "cinglées", "poltron", "poltrons", "poltrone", "poltrones", "cafar", "cafard", "cafars", "cafards", "boutonneux", "boutonneuse", "boutonneuses", "parasite", "parasites", "tocard", "tocar", "dégénéré", "dégénérés", "dégénérée", "dégénérées", "minable", "minables", "nuisible", "incompétent", "dechet", "dechets", "golmon", "golmons", "d'incapable", "lourdaud", "empoté", "égorger", "égorgé", "égorgée", "égorgées", "cuck", "cucks", "shithole", "shitholes", "violer", "violé", "violés", "violée", "violées", "éjaculer", "éjaculé", "éjaculés", "éjacule", "j'éjacule", "éjaculent", "éjaculation", "éjaculations", "bite", "bites", "sex", "sexe", "sexes", "wokiste", "wokistes", "wokisme", "woke", "wokes", "juif", "juifs", "juive", "juives", "arabe", "arabes", "musulman", "musulmans", "musulmane", "musulmanes", "truie", "truies", "clown", "clowns", "putain", "putains", "bordele", "bordel", "ordure", "ordures", "déchet", "déchets", "mamadou", "mohamed", "mohammed", "prophète", "coran", "hadith", "hadiths", "daronne", "nique", "niquez", "gonzesse", "gonzesses", "homesexuel", "homesexuels", "lesbienne", "lesbiennes", "lgbt", "lgbtqia+", "gouine", "gouines", "halouf", "journalope", "journalopes", "nazisme", "nazi", "nazis", "hitler", "boob", "boobs", "nibard", "nibards", "nichon", "nichons", "lolo", "lolos", "tété", "tétés", "couille", "couilles", "emmerdeur", "emmerdeurs", "emmerdeuse", "emmerdeuses", "emmerdement", "emmerdements", "cul", "enflure", "enflures", "enfoirée", "enfoirées", "ass", "nain", "nains", "naine", "naines", "creuver", "sein", "seins", "crever", "puceau", "puceaux", "pucelle", "pucelles", "loser", "losers", "blanc", "blancs", "blanche", "blanches", "black", "blacks", "blacked", "renoi", "renois", "bzez", "noir", "noirs", "looser", "loosers", "shit", "boomer", "boomers", "boomeuse", "boomeuses", "merdique", "gangbang", "foutre", "chier", "merdas", "immigré", "immigrée", "immigrés", "immigrées", "racaille", "racailles", "islamiste", "islamistes", "islamisation", "l'islamisation", "sodomiser", "sodomisé", "sodomisés", "sodomisée", "sodomisées", "sodomie", "sodomies", "l'homosexualité", "homosexualité", "pedo", "muslim", "muslims", "hamas", "antisémite", "antisémites", "hétérosexuelle", "hétérosexuelles", "gueule", "gueules", "chibre", "chibres", "baise", "baiser", "inch'allah", "allawakbar", "inchallah", "allahwakbar", "palestine", "palestinien", "palestiniens", "palestinienne", "palestiniennes", "israel", "israël", "israélien", "israéliens", "israéliene", "israéliennes", "drogue", "drogues", "drogué", "drogués", "droguée", "droguées", "hétérosexuel", "hétérosexuels", "ahuri", "ahuris", "puant", "puants", "chiale", "chialez", "singe", "singes", "primate", "primates", "macaque", "macaques", "holocause", "l'origine", "d'origine", "migrant", "migrants", "migrante", "migrantes", "maghrébin", "chiotte", "chiottes", "suicide", "suicides", "rat", "rats", "fiak", "fiaks", "toast", "sexualité", "sexualités", "sexuel", "sexuels", "sexuelle", "sexuelles", "gaza", "l'immigration", "siounist", "sioniste", "guignol", "islam", "l'islam", "sexdoll", "sexualisé", "sexualisée", "sexualisées", "sexualiser", "sexualisation", "sexualisent", "cannabis", "aicha", "aïcha", "dmt", "lsd", "mdma", "codéine", "fentanyl", "coke", "héroïne", "crack", "oxy", "salvia", "ecstasy", "dph", "ghb", "kratom", "rima", "nadia", "homosexuel", "homosexuels", "porno", "israelien", "israeliens", "kétamine", "tramadol", "aphets", "meth", "datura", "pornographie", "porn", "gay", "gays", "gangbang", "gangbangs", "lesbienne", "lesbiennes", "meuf", "meufs", "allah", "daesh", "starfoullah", "cochonne"];
    // =======================================================

    function countWords(text) {
        let count = 0;
        const lower = text.toLowerCase();

        TARGET_WORDS.forEach(word => {
            const regex = new RegExp(`\\b${word}\\b`, "g");
            const matches = lower.match(regex);
            if (matches) count += matches.length;
        });

        return count;
    }

    function getColorFromScore(score) {
        const min = 1;
        const max = 200;

        score = Math.max(min, Math.min(max, score));

        const t = (score - min) / (max - min);

        const stops = [
            { t: 0.00, c: [47, 111, 237] },
            { t: 0.16, c: [46, 204, 113] },
            { t: 0.33, c: [241, 196, 15] },
            { t: 0.50, c: [230, 126, 34] },
            { t: 0.66, c: [231, 76, 60] },
            { t: 0.83, c: [155, 89, 182] },
            { t: 1.00, c: [0, 0, 0] }
        ];

        function lerp(a, b, t) {
            return a + (b - a) * t;
        }

        let i = 0;
        while (i < stops.length - 1 && t > stops[i + 1].t) i++;

        const start = stops[i];
        const end = stops[i + 1];

        const localT = (t - start.t) / (end.t - start.t);

        const r = Math.round(lerp(start.c[0], end.c[0], localT));
        const g = Math.round(lerp(start.c[1], end.c[1], localT));
        const b = Math.round(lerp(start.c[2], end.c[2], localT));

        return `rgb(${r}, ${g}, ${b})`;
    }

    function createToast(message, score) {
        const box = document.createElement("div");

        box.textContent = message;

        const color = getColorFromScore(score);

        box.style.cssText = `
            position: fixed !important;
            bottom: 20px !important;
            right: 20px !important;
            background: ${color};
            color: white;
            padding: 10px 14px;
            border-radius: 8px;
            font-size: 14px;
            font-family: sans-serif;
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            z-index: 2147483647 !important;
            opacity: 1;
            transition: opacity 1s ease;
            pointer-events: none;
        `;

        document.body.appendChild(box);

        setTimeout(() => {
            box.style.opacity = "0";
            setTimeout(() => box.remove(), 1000);
        }, 2000);
    }

    function scanTopic() {
        const content = document.body.innerText;
        const count = countWords(content);

        if (count > 0) {
            createToast(`Taux de glissade : ${count}`, count);
        }
    }

    function init() {
        setTimeout(scanTopic, 1000);
    }

    window.addEventListener("load", init);
})();

// ==UserScript==
// @name         JVC - Masquer "Topic résolu"
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Masque le bloc "Topic résolu" sur les forums jeuxvideo.com
// @author       -
// @match        https://www.jeuxvideo.com/forums/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function hideResolvedBlock() {
        const elements = document.querySelectorAll('.topicResolve.resolvedTopicContainer');
        elements.forEach(el => {
            el.style.display = 'none';
        });
    }

    hideResolvedBlock();

    const observer = new MutationObserver(() => {
        hideResolvedBlock();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();

// ==UserScript==
// @name         JVC Survey Offset Fix (stable)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const CLASS_NAME = 'jvc-survey-active';

    function updateState() {
        const survey = document.querySelector('.surveyResults');
        const body = document.body;

        if (!body) return;

        if (survey && survey.offsetParent !== null) {
            body.classList.add(CLASS_NAME);
        } else {
            body.classList.remove(CLASS_NAME);
        }
    }

    function injectCSS() {
        if (document.getElementById('jvc-survey-css')) return;

        const style = document.createElement('style');
        style.id = 'jvc-survey-css';

        style.textContent = `
            body.${CLASS_NAME} .js-pagination-top {
                margin-top: -87px !important;
                transition: margin-top 0.2s ease;
            }
        `;

        document.head.appendChild(style);
    }

    function observe() {
        const observer = new MutationObserver(() => {
            updateState();
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

        updateState();
    }

    function init() {
        injectCSS();
        observe();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();

// ==UserScript==
// @name         JVC - Bouton Actualiser pagination bas (stable)
// @namespace    http://tampermonkey.net/
// @version      1.9.1
// @description  Bouton actualiser + liste des sujets uniquement dans les topics
// @match        https://www.jeuxvideo.com/forums/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function isTopicPage() {
        return !/forums\/0-\d+-0-1-0-1-0-/.test(window.location.pathname);
    }

    function createRefreshButton() {
        const wrapper = document.createElement('span');
        wrapper.className = 'pagination__item pagination__button--light';
        wrapper.id = 'tm-refresh-btn';

        const btn = document.createElement('button');
        btn.type = 'button';
        btn.className = 'buttonsNavbar__button';
        btn.style.display = 'flex';
        btn.style.alignItems = 'center';
        btn.style.gap = '6px';

        btn.innerHTML = `
            <i class="buttonsNavbar__icon icon-refresh" style="transform: scale(1.3);"></i>
            <div class="buttonsNavbar__label">Actualiser</div>
        `;

        btn.addEventListener('click', () => location.reload());

        wrapper.appendChild(btn);
        return wrapper;
    }

    function createTopicsButton() {
        const wrapper = document.createElement('span');
        wrapper.className = 'pagination__item pagination__button--light';
        wrapper.id = 'tm-topics-btn';

        const btn = document.createElement('button');
        btn.type = 'button';
        btn.className = 'buttonsNavbar__button';
        btn.style.display = 'flex';
        btn.style.alignItems = 'center';
        btn.style.gap = '6px';

        btn.innerHTML = `
            <div class="buttonsNavbar__label">Liste des sujets</div>
        `;

        btn.addEventListener('click', () => {
            const label = Array.from(document.querySelectorAll('.buttonsNavbar__label'))
                .find(el => el.textContent.trim() === 'Liste des sujets');

            const clickable = label?.closest('a') || label?.closest('button');
            if (clickable) clickable.click();
        });

        wrapper.appendChild(btn);
        return wrapper;
    }

    function getBottomPagination() {
        const bottom = document.querySelector('nav.pagination__navigation--bottom');
        if (bottom) return bottom;

        const all = document.querySelectorAll('nav.pagination__navigation');
        return all.length ? all[all.length - 1] : null;
    }

    function insertButtons() {
        const nav = getBottomPagination();
        if (!nav) return;

        if (isTopicPage() && !nav.querySelector('#tm-topics-btn')) {
            nav.appendChild(createTopicsButton());
        }

        if (!nav.querySelector('#tm-refresh-btn')) {
            nav.appendChild(createRefreshButton());
        }
    }

    const observer = new MutationObserver(insertButtons);
    observer.observe(document.body, { childList: true, subtree: true });

    insertButtons();
})();

// ==UserScript==
// @name         JVC Search Result Move Up
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Remonte le bloc de résultat de recherche de 30px sur jeuxvideo.com
// @match        https://www.jeuxvideo.com/recherche/forums/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function adjustPosition() {
        const el = document.querySelector('.tablesForum__searchResult');
        if (el && !el.dataset.moved) {
            el.style.transform = 'translateY(-27px)';
            el.dataset.moved = "true";
        }
    }

    adjustPosition();

    const observer = new MutationObserver(() => {
        adjustPosition();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();

// ==UserScript==
// @name         JVC - Back to active forum (topics + search)
// @namespace    http://tampermonkey.net/
// @version      1.8
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function extractForumUrl() {
        const path = window.location.pathname;

        let match = path.match(/^\/forums\/\d+-(\d+)-/);
        if (match) {
            const forumId = match[1];
            return `https://www.jeuxvideo.com/forums/0-${forumId}-0-1-0-1-0-blabla.htm`;
        }

        match = path.match(/^\/recherche\/forums\/(0-\d+-\d+-\d+-\d+-\d+-\d+-[^\/]+\.htm)/);
        if (match) {
            return `https://www.jeuxvideo.com/forums/${match[1]}`;
        }

        match = path.match(/^\/forums\/(0-\d+-\d+-\d+-\d+-\d+-\d+-[^\/]+\.htm)/);
        if (match) {
            return `https://www.jeuxvideo.com/forums/${match[1]}`;
        }

        return null;
    }

    function bindTitle() {
        const title = document.querySelector('.titleMessagesUsers__title');
        if (!title) return;

        if (title.dataset.backBound === "1") return;
        title.dataset.backBound = "1";

        title.style.cursor = "pointer";

        title.addEventListener('click', function (e) {
            e.preventDefault();

            const url = extractForumUrl();

            if (url) {
                window.location.href = url;
            }
        });
    }

    function init() {
        bindTitle();
    }

    const observer = new MutationObserver(init);
    observer.observe(document.body, { childList: true, subtree: true });

    init();
})();

// ==UserScript==
// @name         JVC Pagination Fix (Zone Safe)
// @namespace    http://tampermonkey.net/
// @version      2.6
// @match        https://www.jeuxvideo.com/forums/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function applyFix(dropdown) {
        if (!dropdown) return;

        const wrapper = dropdown.querySelector('.pagination__dropdownListWrapper');
        const list = dropdown.querySelector('.pagination__dropdownList');
        const nav = dropdown.closest('nav');

        if (!wrapper || !list || !nav) return;

        nav.style.zIndex = '999999';
        dropdown.style.zIndex = '999999';
        wrapper.style.zIndex = '2147483647';

        list.style.background = '#fff';
        list.style.border = '1px solid #ddd';
        list.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';
        list.style.padding = '6px';
    }

    document.addEventListener('click', (e) => {

        const btn = e.target.closest('.pagination__button--current');
        if (!btn) return;

        const dropdown = btn.closest('.pagination__dropdown');

        if (!dropdown) return;

        setTimeout(() => {
            applyFix(dropdown);
        }, 50);

    }, true);

})();

// ==UserScript==
// @name         JVC Pagination Shift (201+ FIX ROBUST)
// @namespace    http://tampermonkey.net/
// @version      1.2
// @match        https://www.jeuxvideo.com/forums/0-51-0-1-0-*blabla-18-25-ans.htm*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function getPageFromURL() {
        const match = location.href.match(/-1-0-(\d+)-0-/);
        if (!match) return null;
        return parseInt(match[1], 10);
    }

    function applyShift() {
        const page = getPageFromURL();
        if (page === null) return;

        if (page < 201) return;

        const zones = document.querySelectorAll(
            '.pagination__navigation--zone2, .pagination__navigation--zone3, .pagination__navigation--zone4'
        );

        if (!zones.length) return;

        zones.forEach(nav => {
            nav.style.setProperty('transform', 'translateY(1px)', 'important');
            nav.style.setProperty('position', 'relative', 'important');
        });
    }

    function run() {
        applyShift();
    }

    run();

    const observer = new MutationObserver(run);

    observer.observe(document.documentElement, {
        childList: true,
        subtree: true
    });

    window.addEventListener('load', run);
})();

// ==UserScript==
// @name         JVCash - Bouton refresh en haut (forum uniquement)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Ajoute un bouton "Actualiser" à droite du titre (page forum uniquement)
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function isTopicPage() {
        return document.querySelector('#js-list-message-tools-actions');
    }

    function isForumPage() {
        return /\/forums\/0-\d+-/.test(location.href);
    }

    function addRefreshButtonToTitle() {
        if (isTopicPage()) return;
        if (!isForumPage()) return;

        const title = document.querySelector('.titleMessagesUsers__title');
        if (!title) return;

        if (title.dataset.refreshAdded === "1") return;
        title.dataset.refreshAdded = "1";

        let wrapper = document.querySelector('#jvc-title-row');

        if (!wrapper) {
            wrapper = document.createElement('div');
            wrapper.id = 'jvc-title-row';
            wrapper.style.display = 'flex';
            wrapper.style.alignItems = 'center';
            wrapper.style.justifyContent = 'space-between';
            wrapper.style.width = '100%';

            title.parentNode.insertBefore(wrapper, title);
            wrapper.appendChild(title);
        }

        const btn = document.createElement('button');
        btn.type = "button";
        btn.className = "buttonsNavbar__button";
        btn.style.display = "flex";
        btn.style.alignItems = "center";
        btn.style.gap = "6px";
        btn.style.marginLeft = "auto";

        btn.innerHTML = `
            <i class="buttonsNavbar__icon icon-refresh" style="transform: scale(1.3);"></i>
            <div class="buttonsNavbar__label">Actualiser</div>
        `;

        btn.addEventListener('click', () => location.reload());

        wrapper.appendChild(btn);
    }

    function run() {
        addRefreshButtonToTitle();
    }

    run();

    const observer = new MutationObserver(run);
    observer.observe(document.body, { childList: true, subtree: true });

    window.addEventListener('load', run);

})();

// ==UserScript==
// @name         JVC - Offset Toggle + Adblock UI (FINAL CLEAN NAV FIX)
// @namespace    http://tampermonkey.net/
// @version      5.6
// @description  Popup + offset toggle + breadcrumb fix + bouton stable + no text style override
// @match        https://www.jeuxvideo.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const STORAGE_KEY = 'jvc_offset_active';
    const ADBLOCK_KEY = 'jvc_adblock_choice';
    const OFFSET = 50;

    let active = localStorage.getItem(STORAGE_KEY) === '1';
    let adblockChoice = localStorage.getItem(ADBLOCK_KEY);

    let btnRef = null;

    let titleOriginalParent = null;
    let titleOriginalNextSibling = null;
    let breadcrumbOriginalParent = null;
    let breadcrumbOriginalNextSibling = null;
    let navbarOriginalParent = null;
    let navbarOriginalNextSibling = null;
    let surveyOriginalParent = null;
    let surveyOriginalNextSibling = null;

    /* =========================
       POPUP
    ========================= */

    function askAdblockChoice() {
        if (adblockChoice) return;

        const overlay = document.createElement('div');
        overlay.style.cssText = `
            position:fixed;
            inset:0;
            background:rgba(0,0,0,0.6);
            z-index:10000;
            display:flex;
            align-items:center;
            justify-content:center;
        `;

        const box = document.createElement('div');
        box.style.cssText = `
            background:#fff;
            padding:26px;
            border-radius:18px;
            width:340px;
            text-align:center;
            font-family:sans-serif;
        `;

        const title = document.createElement('div');
        title.textContent = "JVCash installé ✅";
        title.style.fontWeight = '800';

        const text = document.createElement('div');
        text.textContent = "Tu utilises un bloqueur de pub ?";
        text.style.margin = '12px 0';

        const wrap = document.createElement('div');
        wrap.style.display = 'flex';
        wrap.style.justifyContent = 'center';
        wrap.style.gap = '6px';

        function btn(label, color) {
            const b = document.createElement('button');
            b.textContent = label;
            b.style.cssText = `
                padding:8px 14px;
                border-radius:999px;
                border:2px solid ${color};
                background:#fff;
                font-weight:700;
                cursor:pointer;
            `;
            return b;
        }

        const yes = btn("OUI", "#1aa34a");
        const no = btn("NON", "#e53935");

        yes.onclick = () => {
            localStorage.setItem(ADBLOCK_KEY, 'yes');
            localStorage.setItem(STORAGE_KEY, '1');
            location.reload();
        };

        no.onclick = () => {
            localStorage.setItem(ADBLOCK_KEY, 'no');
            localStorage.setItem(STORAGE_KEY, '0');
            location.reload();
        };

        const hint = document.createElement('div');
        hint.textContent = 'Tu peux modifier ton choix via le bouton "🛡️" en bas à gauche.';
        hint.style.cssText = `
            margin-top:14px;
            font-size:16px;
            color:#000;
        `;

        wrap.append(yes, no);
        box.append(title, text, wrap, hint);
        overlay.appendChild(box);
        document.body.appendChild(overlay);
    }

    /* =========================
       OFFSET
    ========================= */

    function applyOffsetSpacer() {
        const header = document.querySelector('.js-header');
        if (!header) return;

        document.getElementById('jvc-offset-spacer')?.remove();

        if (!active) return;

        const spacer = document.createElement('div');
        spacer.id = 'jvc-offset-spacer';
        spacer.style.height = OFFSET + 'px';
        spacer.style.width = '100%';

        header.insertAdjacentElement('afterend', spacer);
    }

    function isTopicPage() {
        return !!document.querySelector('#js-list-message-tools-actions');
    }

    function getTitleEl() {
        return document.querySelector('.titleMessagesUsers__title, #jvc-title-row');
    }

    function getPaginationEl() {
        return document.querySelector('.pagination__navigation, .js-pagination-top');
    }

    /* =========================
       FORUM LIST DETECTION
    ========================= */

    function isForumListPage() {
        const match = location.pathname.match(/\/forums\/\d+-\d+-(\d+)-/);
        return match && match[1] === '0';
    }

    /* =========================
       MOVE
    ========================= */

    function moveTitle() {
        const title = getTitleEl();
        const pagination = getPaginationEl();
        if (!title || !pagination || title.dataset.moved) return;

        titleOriginalParent = title.parentNode;
        titleOriginalNextSibling = title.nextSibling;

        pagination.parentNode.insertBefore(title, pagination);

        title.dataset.moved = '1';
        title.style.transform = isTopicPage() ? 'translateY(-24px)' : 'translateY(-32px)';
    }

    function moveBreadcrumb() {
        const breadcrumb = document.querySelector('#jvc-breadcrumb-row');
        const title = getTitleEl();

        if (!breadcrumb || !title) return;
        if (breadcrumb.dataset.moved || title.dataset.moved !== '1') return;

        breadcrumbOriginalParent = breadcrumb.parentNode;
        breadcrumbOriginalNextSibling = breadcrumb.nextSibling;

        title.parentNode.insertBefore(breadcrumb, title);

        breadcrumb.dataset.moved = '1';
        breadcrumb.style.transform = 'translate(4px, -46px)';

        const navTop = breadcrumb.querySelector('.container__navTop');
        if (navTop) navTop.style.transform = 'translate(8px, -6px)';
    }

    function moveNavbar() {
        if (!isTopicPage()) return;

        const navbar = document.querySelector('#js-list-message-tools-actions');
        const title = getTitleEl();

        if (!navbar || !title) return;
        if (navbar.dataset.moved || title.dataset.moved !== '1') return;

        navbarOriginalParent = navbar.parentNode;
        navbarOriginalNextSibling = navbar.nextSibling;

        title.parentNode.insertBefore(navbar, title.nextSibling);

        navbar.dataset.moved = '1';
        const hasSurvey = !!document.querySelector('.surveyResults');
        navbar.style.transform = hasSurvey ? 'translateY(-211px)' : 'translateY(-168px)';
    }

    function moveSurvey() {
        if (!isTopicPage()) return;

        const survey = document.querySelector('.surveyResults');
        const title = getTitleEl();

        if (!survey || !title) return;
        if (survey.dataset.moved || title.dataset.moved !== '1') return;

        surveyOriginalParent = survey.parentNode;
        surveyOriginalNextSibling = survey.nextSibling;

        title.parentNode.insertBefore(survey, title.nextSibling);

        survey.dataset.moved = '1';
        survey.style.transform = 'translateY(-28px)';
    }

    /* =========================
       RESTORE
    ========================= */

    function restoreAll() {
        const title = getTitleEl();
        const breadcrumb = document.querySelector('#jvc-breadcrumb-row');
        const navbar = document.querySelector('#js-list-message-tools-actions');
        const survey = document.querySelector('.surveyResults');

        if (title && title.dataset.moved) {
            titleOriginalParent?.insertBefore(title, titleOriginalNextSibling);
            delete title.dataset.moved;
            title.style.transform = '';
        }

        if (breadcrumb && breadcrumb.dataset.moved) {
            breadcrumbOriginalParent?.insertBefore(breadcrumb, breadcrumbOriginalNextSibling);
            delete breadcrumb.dataset.moved;
            breadcrumb.style.transform = '';

            const navTop = breadcrumb.querySelector('.container__navTop');
            if (navTop) navTop.style.transform = '';
        }

        if (navbar && navbar.dataset.moved) {
            navbarOriginalParent?.insertBefore(navbar, navbarOriginalNextSibling);
            delete navbar.dataset.moved;
            navbar.style.transform = '';
        }

        if (survey && survey.dataset.moved) {
            surveyOriginalParent?.insertBefore(survey, surveyOriginalNextSibling);
            delete survey.dataset.moved;
            survey.style.transform = '';
        }
    }

    /* =========================
       NAV FIX
    ========================= */

    function fixNavTopText() {
        const navTop = document.querySelector('.container__navTop');
        if (!navTop) return;

        const text = navTop.querySelector('.backTo__text');
        if (!text) return;

        text.style.whiteSpace = 'nowrap';
        text.style.display = 'inline-flex';
        text.style.alignItems = 'center';

        text.style.fontSize = '';
        text.style.fontWeight = '';
        text.style.lineHeight = '';
        text.style.letterSpacing = '';
    }

    /* =========================
       BREADCRUMB WIDTH FIX
    ========================= */

    function fixBreadcrumbWidth() {
        const breadcrumb = document.querySelector('#jvc-breadcrumb-row');
        if (!breadcrumb) return;

        const nav = breadcrumb.querySelector('.breadcrumb');
        if (!nav) return;

        nav.style.flex = '1';
        nav.style.minWidth = '0';
        nav.style.overflow = 'hidden';

        nav.querySelectorAll('.breadcrumb__item').forEach(el => {
            el.style.whiteSpace = 'nowrap';
            el.style.overflow = 'hidden';
            el.style.textOverflow = 'ellipsis';
            el.style.maxWidth = '220px';
        });
    }

    /* =========================
       ACTUALISER BUTTON + PAGINATION FIX
    ========================= */

    function fixActualiserButton() {
        if (!isForumListPage()) return;

        const buttons = document.querySelectorAll('.buttonsNavbar__button');
        buttons.forEach(btn => {
            const label = btn.querySelector('.buttonsNavbar__label');
            if (label && label.textContent.trim() === 'Actualiser') {
                btn.style.marginRight = '2px';
            }
        });

        const pagination = document.querySelector('.pagination__navigation--zone1');
        if (pagination) {
            pagination.style.transform = 'translateY(-3px)';
        }
    }

    /* =========================
       BUTTON
    ========================= */

    function updateButton() {
        if (!btnRef) return;

        if (!active) {
            btnRef.style.background = '#2f6fed';
            btnRef.style.color = '#fff';
            btnRef.style.border = '2px solid transparent';
        } else {
            btnRef.style.background = '#fff';
            btnRef.style.color = '#2f6fed';
            btnRef.style.border = '2px solid #2f6fed';
        }
    }

    function createButton() {
        if (document.getElementById('jvc-offset-toggle')) return;

        const btn = document.createElement('div');
        btnRef = btn;

        btn.id = 'jvc-offset-toggle';

        Object.assign(btn.style, {
            position: 'fixed',
            bottom: '120px',
            left: '15px',
            width: '45px',
            height: '45px',
            borderRadius: '50%',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            cursor: 'pointer',
            zIndex: 2147483647,
            fontSize: '18px',
            fontWeight: 'bold',
            userSelect: 'none'
        });

        btn.textContent = '🛡️';

        btn.onclick = () => {
            active = !active;
            localStorage.setItem(STORAGE_KEY, active ? '1' : '0');

            updateButton();
            applyOffset();
        };

        document.body.appendChild(btn);
        updateButton();
    }

    /* =========================
       APPLY
    ========================= */

    function applyOffset() {
        applyOffsetSpacer();

        const header = document.querySelector('.js-header');
        if (header) header.style.position = 'relative';

        if (active) {
            moveTitle();
            moveBreadcrumb();
            moveNavbar();
            moveSurvey();
        } else {
            document.getElementById('jvc-offset-spacer')?.remove();
            restoreAll();
        }

        fixBreadcrumbWidth();
        fixNavTopText();
    }

    /* =========================
       INIT
    ========================= */

    function init() {
        askAdblockChoice();
        createButton();
        applyOffset();
        fixActualiserButton();

        const observer = new MutationObserver(() => {
            fixBreadcrumbWidth();
            fixNavTopText();
            fixActualiserButton();
        });

        observer.observe(document.body, { childList: true, subtree: true });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();