Backloggd+ (Buttons & Tweaks)

Adds customizable buttons to backloggd.

// ==UserScript==
// @name         Backloggd+ (Buttons & Tweaks)
// @namespace    http://vers.works/
// @version      2.7
// @icon         https://pbs.twimg.com/profile_images/1541908760607821824/3Am5dmsx_400x400.jpg
// @description  Adds customizable buttons to backloggd.
// @author       VERS
// @match        https://www.backloggd.com/*
// @match        *://backloggd.com/*
// @match        *://*.backloggd.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const whitelist = ['Steam', 'SteamDB', 'SteamGridDB', 'Epic Games Store', 'GOG', 'Twitch', 'Youtube', 'XBOX', 'Playstation', 'Nintendo',  "Retroachievements",];

    let buttons = GM_getValue('buttons', [
        {
            name: 'Steam',
            iconUrl: 'https://i.imgur.com/9NFBdz4.png',
            searchUrl: 'https://store.steampowered.com/search/?term=',
            color: '#1a9fff',
            status: true
        },
        {
            name: 'SteamDB',
            iconUrl: 'https://i.imgur.com/t6rV9xA.png',
            searchUrl: 'https://steamdb.info/search/?a=all&q=',
            color: '#3e76cb',
            status: true
        },
        {
            name: 'SteamGridDB',
            iconUrl: 'https://i.imgur.com/oluhFHS.png',
            searchUrl: 'https://www.steamgriddb.com/search/grids?term=',
            color: '#3a6e92',
            status: true
        },
        {
            name: 'Epic Games Store',
            iconUrl: 'https://cdn2.unrealengine.com/Unreal+Engine%2Feg-logo-filled-1255x1272-0eb9d144a0f981d1cbaaa1eb957de7a3207b31bb.png',
            searchUrl: 'https://store.epicgames.com/en-US/expanded-search-results?q=',
            color: '#000000',
            status: true
        },
        {
            name: 'GOG',
            iconUrl: 'https://i.imgur.com/3tL2SKY.png',
            searchUrl: 'https://www.gog.com/en/games?query=',
            color: '#9548a6',
            status: true
        },
        {
            name: 'Twitch',
            iconUrl: 'https://i.imgur.com/UVuf0iF.png',
            searchUrl: 'https://www.twitch.tv/search?term=',
            color: '#9046fd',
            status: true
        },
        {
            name: 'Youtube',
            iconUrl: 'https://i.imgur.com/C0Ux2Y3.png',
            searchUrl: 'https://www.youtube.com/results?search_query=',
            color: '#ff0000',
            status: true
        },
        {
            name: 'XBOX',
            iconUrl: 'https://i.imgur.com/jrItCUM.png',
            searchUrl: 'https://www.xbox.com/Search/Results?q=',
            color: '#107b10',
            status: true
        },
        {
            name: 'Playstation',
            iconUrl: 'https://i.imgur.com/wvB5DF8.png',
            searchUrl: 'https://www.playstation.com/search/?q=',
            color: '#0070d1',
            status: true
        },
        {
            name: 'Nintendo',
            iconUrl: 'https://i.imgur.com/7cGs7D6.png',
            searchUrl: 'https://www.nintendo.com/us/search/#q=',
            color: '#e70819',
            status: true
        },
        {
            name: 'Retroachievements',
            iconUrl: 'https://i.imgur.com/wp8wsD2.png',
            searchUrl: 'https://retroachievements.org/games?filter%5Btitle%5D=',
            color: '#ce9833',
            status: true
        },
        {
            name: 'Settings',
            iconUrl: 'https://i.imgur.com/WvM8EHQ.png',
            color: '#16181c',
            status: true,
            isSettings: true
        }
    ]);

    function createButtonElement(buttonData) {
        const { iconUrl, searchUrl, color, name } = buttonData;

        const col = document.createElement('div');
        col.className = 'custom-btn-container col px-0 mt-auto';
        col.setAttribute('data-name', name);

        const button = document.createElement('button');
        button.className = 'button-link btn-play mx-auto custom-button';
        button.style.backgroundColor = color;
        button.style.width = '40px';
        button.style.height = '40px';
        button.style.borderRadius = '7px';
        button.style.display = 'flex';
        button.style.justifyContent = 'center';
        button.style.alignItems = 'center';
        button.style.boxShadow = 'var(--lt-shadowDefault)';
        button.style.transition = 'transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out';

        button.addEventListener('mouseenter', () => {
            button.style.boxShadow = 'var(--lt-shadowActive)';
            button.style.transform = 'translateY(-1px)';
        });
        button.addEventListener('mouseleave', () => {
            button.style.boxShadow = 'var(--lt-shadowDefault)';
            button.style.transform = 'none';
        });

        const icon = document.createElement('img');
        icon.src = iconUrl;
        icon.alt = name;
        icon.style.width = '24px';
        icon.style.height = '24px';
        icon.style.pointerEvents = 'none';
        button.appendChild(icon);

        button.addEventListener('click', function() {
            if (name === 'Settings') {
                openSettingsModal();
            } else {
                let gameTitleElement = document.querySelector('#title h1');

                if (!gameTitleElement) {
                    gameTitleElement = document.querySelector('h1[itemprop="name"]');
                }
                if (!gameTitleElement) {
                    gameTitleElement = document.querySelector('.game-title h1');
                }
                if (!gameTitleElement) {
                    gameTitleElement = document.querySelector('h1');
                }

                if (gameTitleElement) {
                    const gameTitle = encodeURIComponent(gameTitleElement.textContent.trim());
                    console.log('Game title found:', gameTitle);
                    const searchLink = searchUrl.includes('%s')
                        ? searchUrl.replace('%s', gameTitle)
                        : searchUrl + gameTitle;
                    console.log('Opening URL:', searchLink);
                    window.open(searchLink, '_blank');
                } else {
                    console.error('Game title element not found on this page');
                    alert('Could not find game title on this page. Make sure you are on a game page.');
                }
            }
        });

        button.setAttribute('data-search', searchUrl);
        button.setAttribute('data-name', name);
        col.appendChild(button);
        return col;
    }

    function updateButtons() {
        const targetHr = document.querySelector('hr.mb-3.mt-2.d-none.d-md-flex');
        if (!targetHr) return;

        document.querySelectorAll('.custom-btn-row').forEach(row => row.remove());

        const activeButtons = buttons.filter(btn => btn.status);

        const whitelistButtons = activeButtons
            .filter(btn => whitelist.includes(btn.name))
            .sort((a, b) => whitelist.indexOf(a.name) - whitelist.indexOf(b.name));

        const customButtons = activeButtons.filter(btn => !whitelist.includes(btn.name) && !btn.isSettings);
        const settingsButtons = activeButtons.filter(btn => btn.isSettings);

        const allButtons = [...whitelistButtons, ...customButtons, ...settingsButtons];

        let insertAfter = targetHr;
        for (let i = 0; i < allButtons.length; i += 4) {
            const rowButtons = allButtons.slice(i, i + 4);
            const buttonRow = document.createElement('div');
            buttonRow.className = 'row mx-0 d-none d-md-flex logging-btns small-log-btns custom-btn-row flex-wrap';
            rowButtons.forEach(btn => buttonRow.appendChild(createButtonElement(btn)));

            insertAfter.parentNode.insertBefore(buttonRow, insertAfter.nextSibling);
            insertAfter = buttonRow;
        }
    }


    function addSpacer() {
        const targetHr = document.querySelector('hr.mb-3.mt-2.d-none.d-md-flex');
        if (!targetHr) return;

        const spacerParent = targetHr.parentNode.querySelector('.row.mt-2.d-none.d-md-flex');
        if (spacerParent && !spacerParent.querySelector('.spacer')) {
            const spacer = document.createElement('div');
            spacer.className = 'spacer';
            spacer.style.height = '10px';
            spacerParent.appendChild(spacer);
        }
    }

    function openSettingsModal() {
        const settingsModal = document.createElement('div');
        settingsModal.className = 'settings-modal';
        settingsModal.style.position = 'fixed';
        settingsModal.style.top = '50%';
        settingsModal.style.left = '50%';
        settingsModal.style.transform = 'translate(-50%, -50%)';
        settingsModal.style.backgroundColor = 'rgba(22, 24, 28)';
        settingsModal.style.borderRadius = '10px';
        settingsModal.style.padding = '20px';
        settingsModal.style.zIndex = '9999';
        settingsModal.style.maxHeight = 'auto';
        settingsModal.style.overflowY = 'visible';

        settingsModal.innerHTML = `
            <h1>BACKLOGGD BUTTONS</h1>
            <p style="display: flex; align-items: center;">Script made by VERS.
                <a href="https://www.backloggd.com/u/VERS/" target="_blank">
                    <img src="https://i.imgur.com/4FLnRC9.png" alt="Icon 1" style="margin-left: 10px; width: 19px; height: 19px;">
                </a>
                <a href="https://bento.me/thevers" target="_blank">
                    <img src="https://i.imgur.com/oePEdTt.png" alt="Icon 3" style="margin-left: 5px; width: 19px; height: 19px;">
                </a>
            </p>
            <h2>Button Settings</h2>
            <div style="max-height: 300px; overflow-y: auto;"> <!-- Only this container scrolls -->
                <ul>
                    ${buttons
                        .filter(button => !button.isSettings && button.name !== 'Remove Button')
                        .map(
                            button =>
                                `<li>
                                    <label>
                                        <input type="checkbox" id="${button.name}-checkbox" ${
                            button.status ? 'checked' : ''
                        }>
                                        ${button.name}
                                    </label>
                                </li>`
                        )
                        .join('')}
                </ul>
            </div>
            <button id="add-button" style="background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                <img src="https://i.imgur.com/i5OSWDm.png" alt="Add" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Add Custom Button
            </button>

            <button id="remove-button" style="background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                <img src="https://i.imgur.com/mffJ4qZ.png" alt="Remove" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Remove Custom Button
            </button>

            <div style="display: flex; gap: 6px; margin-bottom: 6px;">
                <button id="import-json-btn" style="flex:1; background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem;">
                    <img src="https://i.imgur.com/uLKJYct.png" alt="Import" style="width:20px; height:20px; margin-right:6px; vertical-align:middle;">Import JSON
                </button>
                <button id="export-json-btn" style="flex:1; background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem;">
                    <img src="https://i.imgur.com/riaa4f2.png" alt="Export" style="width:20px; height:20px; margin-right:6px; vertical-align:middle;">Export JSON
                </button>
            </div>

            <button id="flush-memory-btn" style="background-color: #ff4444; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                <img src="https://i.imgur.com/zVry85k.png" alt="Flush" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Flush Memory
            </button>

            <a href="https://discord.gg/eyDknctyUA" target="_blank" style="text-decoration: none;">
                <button id="discord-btn" style="background-color: #7289DA; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                    <img src="https://uxwing.com/wp-content/themes/uxwing/download/brands-and-social-media/discord-white-icon.png" alt="Discord" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">
                    Find more buttons
                </button>
            </a>
            <button id="save-settings-btn" style="background-color: #fc6399; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 0px;">
                <img src="https://i.imgur.com/IpDGyvR.png" alt="Save" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Save Settings
            </button>


        `;

        document.body.appendChild(settingsModal);
document.getElementById('import-json-btn').addEventListener('click', () => {
    const importModal = document.createElement('div');
    importModal.style.position = 'fixed';
    importModal.style.top = '50%';
    importModal.style.left = '50%';
    importModal.style.transform = 'translate(-50%, -50%)';
    importModal.style.backgroundColor = '#242832';
    importModal.style.borderRadius = '10px';
    importModal.style.padding = '20px';
    importModal.style.zIndex = '10000';
    importModal.style.width = '400px';
    importModal.innerHTML = `
        <h2>Import Buttons from JSON</h2>
        <p style="font-size: 12px;">Paste your JSON below and click <strong>Import</strong>:</p>
        <textarea id="json-import-input"
            style="width: 100%; height: 150px; background-color: #1a1d25; color: #fff; border: 1px solid #555; border-radius: 5px; padding: 8px;"></textarea>
        <div style="margin-top: 10px; display: flex; justify-content: space-between;">
            <button id="import-json-confirm" style="background-color: #fc6399; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Import</button>
            <button id="close-json-import" style="background-color: #4a5e8d; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Cancel</button>
        </div>
    `;
    document.body.appendChild(importModal);

    document.getElementById('close-json-import').addEventListener('click', () => importModal.remove());
    document.getElementById('import-json-confirm').addEventListener('click', () => {
        try {
            const text = document.getElementById('json-import-input').value.trim();
            if (!text) return alert('Please paste JSON first.');
            const arr = JSON.parse(text);
            if (!Array.isArray(arr)) throw new Error('Expected array.');
            let added = 0;
            arr.forEach(entry => {
                if (entry.name && entry.iconUrl && entry.searchUrl && entry.color) {
                    if (!buttons.some(b => b.name.toLowerCase() === entry.name.toLowerCase())) {
                        buttons.push({ ...entry, status: true });
                        added++;
                    }
                }
            });
            if (added > 0) {
                GM_setValue('buttons', buttons);
                alert(`✅ Imported ${added} new button(s)!`);
                window.location.reload();
            } else alert('No new buttons found.');
        } catch (err) {
            alert('❌ Invalid JSON: ' + err.message);
        }
    });
});


    document.getElementById('export-json-btn').addEventListener('click', () => {
        const exportModal = document.createElement('div');
        exportModal.style.position = 'fixed';
        exportModal.style.top = '50%';
        exportModal.style.left = '50%';
        exportModal.style.transform = 'translate(-50%, -50%)';
        exportModal.style.backgroundColor = '#242832';
        exportModal.style.borderRadius = '10px';
        exportModal.style.padding = '20px';
        exportModal.style.zIndex = '10000';
        exportModal.style.width = '400px';

        const customBtns = buttons.filter(b => !whitelist.includes(b.name) && !b.isSettings);
        exportModal.innerHTML = `
            <h2>Export Custom Buttons</h2>
            <p style="font-size: 12px;">Select which buttons to export:</p>
            <div id="export-checkboxes" style="max-height: 150px; overflow-y: auto; text-align: left; margin-bottom: 10px;">
                ${customBtns.length > 0
                    ? customBtns.map(b => `
                        <label style="display: block; margin-bottom: 4px;">
                            <input type="checkbox" value="${b.name}" checked> ${b.name}
                        </label>`).join('')
                    : '<p style="font-size: 12px; color: #ccc;">No custom buttons found.</p>'}
            </div>
            <textarea id="json-export-output" style="width:100%; height:120px; background:#1a1d25; color:#fff; border:1px solid #555; border-radius:5px; padding:6px;" readonly></textarea>
            <div style="margin-top: 10px; display: flex; justify-content: space-between;">
                <button id="export-json-generate" style="background-color: #fc6399; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Generate</button>
                <button id="export-json-close" style="background-color: #4a5e8d; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Close</button>
            </div>
        `;
        document.body.appendChild(exportModal);

        document.getElementById('export-json-close').addEventListener('click', () => exportModal.remove());
        document.getElementById('export-json-generate').addEventListener('click', () => {
            const selected = Array.from(exportModal.querySelectorAll('input[type="checkbox"]:checked')).map(cb => cb.value);
            const exportData = buttons
                .filter(b => selected.includes(b.name))
                .map(({ name, iconUrl, searchUrl, color }) => ({ name, iconUrl, searchUrl, color }));
            document.getElementById('json-export-output').value = JSON.stringify(exportData, null, 2);
        });
    });




        const addButtonBtn = document.getElementById('add-button');
        addButtonBtn.addEventListener('click', () => {
            openAddButtonModal();
        });

        const removeButtonBtn = document.getElementById('remove-button');
        removeButtonBtn.addEventListener('click', () => {
            openRemoveButtonModal();
        });

        const saveSettingsBtn = document.getElementById('save-settings-btn');
        saveSettingsBtn.addEventListener('click', () => {
            buttons.forEach(button => {
                if (!button.isSettings) {
                    const checkbox = document.getElementById(`${button.name}-checkbox`);
                    button.status = checkbox.checked;
                }
            });

            GM_setValue('buttons', buttons);
            window.location.reload();
        });
    }


    function openRemoveButtonModal() {
        const removeButtonModal = document.createElement('div');
        removeButtonModal.className = 'remove-button-modal';
        removeButtonModal.style.position = 'fixed';
        removeButtonModal.style.top = '50%';
        removeButtonModal.style.borderRadius = '10px';
        removeButtonModal.style.left = '50%';
        removeButtonModal.style.transform = 'translate(-50%, -50%)';
        removeButtonModal.style.backgroundColor = '#242832';
        removeButtonModal.style.padding = '20px';
        removeButtonModal.style.zIndex = '9999';
        removeButtonModal.innerHTML = `
            <h2>Remove Button</h2>
            <ul>
                ${buttons
                    .filter(button => !button.isSettings && !whitelist.includes(button.name))
                    .map(
                        button =>
                            `<li>
                                <button id="remove-${button.name}" style="background-color: #fc6399; border: none; color: #ffffff; padding: 5px 5; cursor: pointer;">✖</button>
                                <span style="margin-left: 10px;">${button.name}</span>
                            </li>`
                    )
                    .join('')}
            </ul>
            <button id="close-remove-modal" style="background-color: #4a5e8d; border: none; color: #ffffff; padding: 8px 16px; cursor: pointer; margin-top: 10px;">Close</button>
        `;

        document.body.appendChild(removeButtonModal);

        buttons
            .filter(button => !button.isSettings && !whitelist.includes(button.name))
            .forEach(button => {
                const removeButton = document.getElementById(`remove-${button.name}`);
                removeButton.addEventListener('click', () => {
                    removeButtonFromList(button.name);
                    removeButton.parentElement.remove();
                });
            });

        const closeModalBtn = document.getElementById('close-remove-modal');
        closeModalBtn.addEventListener('click', () => {
            removeButtonModal.remove();
        });
    }

    function removeButtonFromList(buttonName) {
        buttons = buttons.filter(button => button.name !== buttonName);
        GM_setValue('buttons', buttons);

        const existingRows = document.querySelectorAll('.custom-btn-row');
        existingRows.forEach(row => row.remove());

        addSpacer();
        updateButtons();
    }

    function openAddButtonModal() {
        const addButtonModal = document.createElement('div');
        addButtonModal.className = 'add-button-modal';
        Object.assign(addButtonModal.style, {
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            backgroundColor: '#242832',
            borderRadius: '10px',
            padding: '20px',
            zIndex: '9999',
            color: '#fff',
            textAlign: 'left',
            width: '420px',
            maxWidth: '90%',
            boxShadow: '0 0 12px rgba(0,0,0,0.5)',
            fontFamily: 'Inter, sans-serif'
        });

        addButtonModal.innerHTML = `
            <h2 style="text-align:center; margin-bottom: 12px;">Add Custom Button</h2>

            <div style="margin-bottom: 8px;">
                <label for="website-name" style="display:inline-block;width:120px;">Website Name:</label>
                <input type="text" id="website-name" style="width:220px; border:none; border-radius:4px; padding:4px;" required>
                <button id="info-website-name" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="margin-bottom: 8px;">
                <label for="icon-url" style="display:inline-block;width:120px;">Icon URL:</label>
                <input type="text" id="icon-url" style="width:220px; border:none; border-radius:4px; padding:4px;" required>
                <button id="info-icon-url" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="margin-bottom: 8px;">
                <label for="search-url" style="display:inline-block;width:120px;">Search URL:</label>
                <input type="text" id="search-url" style="width:220px; border:none; border-radius:4px; padding:4px;" required>
                <button id="info-search-url" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="margin-bottom: 8px;">
                <label for="color" style="display:inline-block;width:120px;">Button Color:</label>
                <input type="color" id="color" value="#fc6399" style="border:none; border-radius:4px; padding:2px;">
                <button id="info-color" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="display:flex; justify-content:space-between; margin-top:14px;">
                <button id="save-new-button" style="background-color:#fc6399; border:none; color:#fff; padding:8px 16px; border-radius:4px; cursor:pointer;">Add Button</button>
                <button id="close-button" style="background-color:#555; border:none; color:#fff; padding:8px 16px; border-radius:4px; cursor:pointer;">Close</button>
            </div>
        `;

        document.body.appendChild(addButtonModal);

        const infoTexts = {
            'website-name': `This is the button name shown in settings. It doesn't have to match the site exactly.`,
            'icon-url': `Direct link to an image (PNG/JPEG) used as the button icon. Example: https://i.imgur.com/abcd123.png`,
            'search-url': `The base URL for a search on the site, WITHOUT the search term.
    Example:
    • Google: https://www.google.com/search?q=
    • Or use %s placeholder if not at the end (e.g., https://example.com/search?query=%s&type=games)`,
            'color': `The background color for the button.`
        };

        Object.keys(infoTexts).forEach(id => {
            const btn = document.getElementById(`info-${id}`);
            btn.addEventListener('click', () => alert(infoTexts[id]));
        });

        document.getElementById('save-new-button').addEventListener('click', () => {
            const name = document.getElementById('website-name').value.trim();
            const iconUrl = document.getElementById('icon-url').value.trim();
            const searchUrl = document.getElementById('search-url').value.trim();
            const color = document.getElementById('color').value.trim();

            if (!name || !iconUrl || !searchUrl || !color) {
                alert('Please fill in all fields.');
                return;
            }

            if (buttons.some(b => b.name.toLowerCase() === name.toLowerCase())) {
                alert('A button with this name already exists.');
                return;
            }

            buttons.push({ name, iconUrl, searchUrl, color, status: true });
            GM_setValue('buttons', buttons);
            alert(`✅ "${name}" button added successfully!`);
            window.location.reload();
        });

        document.getElementById('close-button').addEventListener('click', () => addButtonModal.remove());
        document.getElementById('import-json').addEventListener('click', () => {
            const importModal = document.createElement('div');
            Object.assign(importModal.style, {
                position: 'fixed',
                top: '50%',
                left: '50%',
                transform: 'translate(-50%, -50%)',
                backgroundColor: '#242832',
                borderRadius: '10px',
                padding: '20px',
                zIndex: '10000',
                width: '420px',
                color: '#fff',
                textAlign: 'left',
                boxShadow: '0 0 12px rgba(0,0,0,0.5)'
            });
            importModal.innerHTML = `
                <h3>Import Buttons from JSON</h3>
                <p style="font-size:12px;">Paste your JSON below and click Import:</p>
                <textarea id="json-input" placeholder='[{"Website Name":"Example","Icon URL":"https://i.imgur.com/abcd.png","Search URL":"https://example.com/search?q=","Button Color":"#123456"}]'
                    style="width:100%;height:150px;background:#1a1d25;color:#fff;border:1px solid #555;border-radius:5px;padding:8px;resize:none;"></textarea>
                <div style="display:flex;justify-content:space-between;margin-top:10px;">
                    <button id="import-confirm" style="background-color:#fc6399;border:none;color:#fff;padding:6px 12px;border-radius:4px;cursor:pointer;">Import</button>
                    <button id="import-cancel" style="background-color:#4a5e8d;border:none;color:#fff;padding:6px 12px;border-radius:4px;cursor:pointer;">Cancel</button>
                </div>
            `;
            document.body.appendChild(importModal);

            document.getElementById('import-cancel').addEventListener('click', () => importModal.remove());
            document.getElementById('import-confirm').addEventListener('click', () => {
                const raw = document.getElementById('json-input').value.trim();
                if (!raw) return alert('Please paste JSON first.');

                try {
                    const arr = JSON.parse(raw);
                    if (!Array.isArray(arr)) throw new Error('Expected an array of objects.');
                    let added = 0;
                    arr.forEach(entry => {
                        const name = entry['Website Name'];
                        const iconUrl = entry['Icon URL'];
                        const searchUrl = entry['Search URL'];
                        const color = entry['Button Color'];
                        if (name && iconUrl && searchUrl && color && !buttons.some(b => b.name.toLowerCase() === name.toLowerCase())) {
                            buttons.push({ name, iconUrl, searchUrl, color, status: true });
                            added++;
                        }
                    });
                    if (added) {
                        GM_setValue('buttons', buttons);
                        alert(`✅ Imported ${added} new button(s)!`);
                        window.location.reload();
                    } else {
                        alert('No valid or new buttons found.');
                    }
                } catch (e) {
                    alert('❌ Invalid JSON: ' + e.message);
                }
            });
        });
    }


    function waitForElement(selector, callback, maxAttempts = 50) {
        let attempts = 0;
        const interval = setInterval(() => {
            const element = document.querySelector(selector);
            if (element) {
                clearInterval(interval);
                callback(element);
            } else if (++attempts >= maxAttempts) {
                clearInterval(interval);
                console.log(`Element ${selector} not found after ${maxAttempts} attempts`);
            }
        }, 100);
    }

    function addAtButton() {
        const commentRows = document.querySelectorAll('.row.mb-2');
        commentRows.forEach(row => {
            if (!row.querySelector('.at-button')) {
                const atButton = document.createElement('div');
                atButton.className = 'col-auto mt-auto pl-0 pr-1 at-button';
                atButton.innerHTML = '<button class="button-link secondary-link" style="cursor: pointer;">@</button>';

                const usernameDiv = row.querySelector('.col-auto.mt-auto.px-2');
                if (usernameDiv) {
                    const usernameLink = usernameDiv.querySelector('a.secondary-link');
                    if (usernameLink) {
                        const username = usernameLink.textContent.trim();
                        atButton.querySelector('button').addEventListener('click', () => {
                            const commentBox = document.getElementById('comment_body');
                            if (commentBox) {
                                const currentText = commentBox.value;
                                const cursorPosition = commentBox.selectionStart;
                                const textBefore = currentText.substring(0, cursorPosition);
                                const textAfter = currentText.substring(cursorPosition);
                                const newText = `${textBefore}@${username} ${textAfter}`;
                                commentBox.value = newText;
                                commentBox.focus();
                                const newCursorPosition = cursorPosition + username.length + 2;
                                commentBox.setSelectionRange(newCursorPosition, newCursorPosition);
                            }
                        });

                        row.appendChild(atButton);
                    }
                }
            }
        });
    }

    function processElements() {
        addAtButton();
    }

    const style = document.createElement('style');
    style.textContent = `
        .settings-modal button:hover {
            filter: brightness(85%);
        }

        /* Custom main buttons hover effect */
        .custom-button {
            transition: transform 0.15s ease, box-shadow 0.15s ease, border 0.15s ease;
            border: 2px solid transparent; /* default border */
        }

        .custom-button:hover {
            transform: translateY(-3px) scale(1.05);
            border: 2px solid rgba(255, 255, 255, 0.35); /* slightly lighter than button */
            box-shadow: 0 4px 8px rgba(0,0,0,0.3);
        }
        .custom-btn-row {
            display: flex;
            flex-wrap: wrap;
            align-items: flex-end;
            justify-content: flex-start; /* changed from space-between */
            margin-top: 6px;
        }

        .custom-btn-container {
            flex: 0 0 25%;   /* keeps each button container 1/4 of the row */
            max-width: 25%;
            display: flex;
            justify-content: center;
        }


        .custom-button {
            color: #fff;
            cursor: pointer;
        }

        .custom-button img {
            filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3));
        }
    `;
    document.head.appendChild(style);

    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.type === 'childList') {
                const addedNodes = Array.from(mutation.addedNodes);
                addedNodes.forEach(node => {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        if (node.classList && (node.classList.contains('comments-section') || node.closest('.comments-section'))) {
                            processElements();
                        }
                    }
                });
            }
        });
    });

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

    function initializeButtons() {
        waitForElement('hr.mb-3.mt-2.d-none.d-md-flex', () => {
            addSpacer();
            updateButtons();
            processElements();
        });
    }

    initializeButtons();

    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            console.log('URL changed, reinitializing buttons...');
            setTimeout(() => {
                initializeButtons();
            }, 300);
        }
    }).observe(document, { subtree: true, childList: true });

    window.addEventListener('hashchange', () => {
        console.log('Hash changed, reinitializing buttons...');
        setTimeout(() => {
            initializeButtons();
        }, 300);
    });
    const CURRENT_NOTICE_VERSION = 'debug';
    const hasSeenNotice = GM_getValue(CURRENT_NOTICE_VERSION, false);

    if (!hasSeenNotice) {
        const noticeModal = document.createElement('div');
        noticeModal.style.position = 'fixed';
        noticeModal.style.top = '50%';
        noticeModal.style.left = '50%';
        noticeModal.style.transform = 'translate(-50%, -50%)';
        noticeModal.style.backgroundColor = '#242831';
        noticeModal.style.border = '1px solid #444';
        noticeModal.style.borderRadius = '10px';
        noticeModal.style.padding = '20px';
        noticeModal.style.zIndex = '99999';
        noticeModal.style.color = '#fff';
        noticeModal.style.textAlign = 'center';
        noticeModal.style.boxShadow = '0 0 15px rgba(0,0,0,0.6)';
        noticeModal.innerHTML = `
            <h1 style="margin-bottom: 20px;">BACKLOGGD BUTTONS - 2.6</h1>
            <p style="font-size: 19px; margin-bottom: 20px;">
                If you are updating please flush the memory.
                (This will reset all of your settings!)
                You can also export your buttons in the settings.
            </p>
            <div style="display:flex; gap:8px; justify-content:center;">
                <button id="notice-flush-btn" style="
                    background-color: #ff4444;
                    border: none;
                    color: white;
                    padding: 8px 16px;
                    border-radius: 6px;
                    cursor: pointer;
                ">Flush Memory</button>
                <button id="notice-ok-btn" style="
                    background-color: #fc6399;
                    border: none;
                    color: white;
                    padding: 8px 16px;
                    border-radius: 6px;
                    cursor: pointer;
                ">Got it</button>
            </div>
        `;

        document.body.appendChild(noticeModal);

        const originalFlushMemory = () => {
            if (confirm('Are you sure you want to flush all saved buttons and reset the script?')) {
                const preserveNotice = GM_getValue(CURRENT_NOTICE_VERSION, true);
                GM_setValue('buttons', undefined);
                GM_setValue(CURRENT_NOTICE_VERSION, preserveNotice);
                window.location.reload();
            }
        };

        document.getElementById('notice-ok-btn').addEventListener('click', () => {
            GM_setValue(CURRENT_NOTICE_VERSION, true);
            noticeModal.remove();
        });
        document.getElementById('notice-flush-btn').addEventListener('click', () => {
            originalFlushMemory();
        });
    }


    const originalFlushMemory = () => {
        if (confirm('Are you sure you want to flush all saved buttons and reset the script?')) {
            const preserveNotice = GM_getValue(CURRENT_NOTICE_VERSION, true);
            GM_setValue('buttons', undefined);
            GM_setValue(CURRENT_NOTICE_VERSION, preserveNotice);
            window.location.reload();
        }
    };

    document.addEventListener('click', (e) => {
        if (e.target && e.target.id === 'flush-memory-btn') {
            e.preventDefault();
            originalFlushMemory();
        }
    });

})();