DeepCo NekStyle

Style switchers

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

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.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name         DeepCo NekStyle
// @namespace    http://tampermonkey.net/
// @version      2.13.0
// @description  Style switchers
// @match        https://deepco.app/*
// @license      MIT
// @grant        none
// @icon         https://www.google.com/s2/favicons?sz=64&domain=deepco.app
// ==/UserScript==

/*

  Thanks
    - Nippeli for the feedbacks
    - M3P for idea for "Sort Online by department" and "Hide idle autos"

*/

(function () {
    'use strict';

    const STORAGE_KEY = 'NekCssToggles';
    const INJECT_TARGET_SELECTOR = 'footer.footer>nav';
    const buttonLabel = 'NekStyle';
    const version = '2.13.0';
    const profilingEnabledAtStart = false; // start profiling at start and print a report when page unload

    const presenceTooltipOption = {
        id: 'presence-tooltip',
        label: 'Always show presence tooltips',
        alt: "Show name of people in your departement",
        css: `
            div[data-section="grid-presence"] .tooltip[data-tip]::before{
                display: inline-block !important;
                visibility: visible !important;
                position: static !important;
                content: var(--tw-content);
                transform:none;
                transition:none;
                opacity:1;
                margin-right:-10px;
            }
            div[data-section="grid-presence"] .tooltip[data-tip]::after{ display: none !important; }
            div[data-section="grid-presence"] .tooltip[data-tip]>a>span{ margin-bottom: 2px }
        `,
    };

    const softIDPlusOption = {
        id: 'soft-IDPlus',
        label: 'Less Shiny ID+',
        alt: "Make ID+ less shiny in chat",
        css: `
            .worker-name-link .valuable { color: #ffd70066; text-shadow: none; }
        `
    };

    const colorSpecificRainbowOption = {
        id: 'rainbow-name-specific',
        label: 'Color Specific Rainbow Names',
        alt: "Rainbow animation is slower and use the player color customization",
        css: `
            .gradient-rainbow {
                background: linear-gradient(45deg,
                    var(--base-color,#3498db) 0%, var(--base-color,#3498db) 12.50%,
                    rgba(255, 242, 0, 1) 25.00%, var(--base-color,#3498db) 37.50%,
                    var(--base-color,#3498db) 50.00%, var(--base-color,#3498db) 62.50%,
                    rgba(0, 242, 255, 1) 75%, var(--base-color,#3498db) 87.50%,
                    var(--base-color,#3498db) 100%);
                -webkit-text-fill-color: transparent;
                background-size: 400% 400%;
                -webkit-background-clip: text;
                background-clip: text;
                animation: 12s ease-in-out infinite rainbow-shift;
            }
        `,
    };

    const bubbleNamesOption = (() => {
        const NEK_BUBBLE_ATTR = "data-nek-bubble-original-color";

        function enableBubble(selector, root = document) {
            const els = [...root.querySelectorAll(selector.map(e => e.trim() + ':not(.nek-bubble)').join(', '))];
            if (els.length === 0) return;

            const colors = els.map(el => window.getComputedStyle(el).color);
            els.forEach((el, i) => {
                const color = colors[i];
                el.setAttribute(NEK_BUBBLE_ATTR, color);
                el.removeAttribute("style");
                el.classList.add("nek-bubble", "text-success/80");

                const bubble = document.createElement("span");
                bubble.className = "nek-color-bubble inline-block rounded-full align-middle border border-white";
                bubble.style.cssText = `width: 12px; height: 12px; margin: 0 3px 3px; background-color: ${color};`;
                el.parentNode.insertBefore(bubble, el);
            });
        }

        function disableBubble(selector) {
            document.querySelectorAll(selector).forEach((el) => {
                const color = el.getAttribute(NEK_BUBBLE_ATTR);
                el.classList.remove("nek-bubble", "text-success/80");
                if (color) el.style.color = color;
                el.removeAttribute(NEK_BUBBLE_ATTR);
                const prev = el.previousElementSibling;
                if (prev && prev.classList.contains("nek-color-bubble")) prev.remove();
            });
        }

        //const chatNameSelector = '#chat-messages .worker-name-link >.truncate:not(.gradient-rainbow)';
        const nameSelector = '.worker-name-link >.truncate:not(.gradient-rainbow)';
        const nameLinkSelector = 'a[href^="/workers/"] >.truncate:not(.gradient-rainbow)';

        const selectors = [
            // chat
            '#chat-messages '+nameSelector,
            // doom
            '#grid-panel>div>aside fieldset>legend.fieldset-legend>'+nameLinkSelector,
            // chunk complete reward list
            '#layer-complete-text '+nameLinkSelector,
            // departement leaderboard
            '#main-panel>div>table>tbody>tr>td>'+nameLinkSelector,
            // online
            '#main-panel>div.grid a.card[href^="/workers/"]>div>header>h2>.truncate:not(.gradient-rainbow)',
            // performance
            '#legends-list>div.grid>a.card[href^="/workers/"]>div>header>h3>.truncate:not(.gradient-rainbow)',
            // roaster
            '#main-panel>div.grid>div.card>div>div>div>span>span.truncate:not(.gradient-rainbow)',
            // side menu -- lets keep it
            // 'body>.drawer>.drawer-side>aside span.truncate:not(.gradient-rainbow)',
            // profile -- bugged
            // '#main-panel > main > .settings-panel .tab-content span.truncate:not(.gradient-rainbow)',
        ]
        return {
            id: 'readable-chat',
            label: 'More readable names',
            alt: "Replace color customization by a colored bubble, so they are easier to read",
            onChecked() {
                enableBubble(selectors)
            },
            onUnchecked() {
                disableBubble(selectors)
            },
            onDomUpdated(mutations) {
                mutations.forEach(target => enableBubble(selectors, target))
            },
        };
    })();

    const IDPlusSpaceInChatOption = (() => {
        const emptyVIPclass = "nek-emptyVIP";
        const fakeVIPclass = "nek-fakeVIP";
        function enableEmptyVIP(selector) {
            document.querySelectorAll(selector).forEach((el) => {
                if (el.classList.contains(emptyVIPclass)) return;
                el.classList.add(emptyVIPclass);
                const badge = el.querySelector('.official-badge.valuable');
                if (badge) return;
                const span = document.createElement('span');
                span.className = 'official-badge valuable ' + fakeVIPclass;
                span.textContent = '[ID+]';
                span.style.cssText = 'opacity: 0';
                el.insertBefore(span, el.firstChild)
            });
        }

        function disableEmptyVIP(selector) {
            document.querySelectorAll(selector).forEach((el) => {
                if (!el.classList.contains(emptyVIPclass)) return;
                el.classList.remove(emptyVIPclass);
                const badge = el.querySelector('.official-badge.valuable.' + fakeVIPclass);
                if (badge) badge.remove();
            });
        }
        const nameSelector = '#chat-messages .worker-name-link';

        return {
            id: 'empty-VIP-chat',
            label: 'add ID+ space',
            alt: "Add a blank space for people with no ID+ in chat",
            onChecked() {
                enableEmptyVIP(nameSelector);
            },
            onUnchecked() {
                disableEmptyVIP(nameSelector);
            },
            onDomUpdated() {
                enableEmptyVIP(nameSelector);
            },
        };
    })()

    const fatGridOption = {
        id: 'fat-grid',
        label: 'Fat grid',
        alt: "big icons and large blocks",
        css: `
            .you-are-queued-here { position:relative; box-shadow: none; }
            .you-are-queued-here:after {
                content: ""; position: absolute; top: 0; bottom: 0; left: 0; right: 0;
                box-shadow: inset 0 0 2px 1px #c0fbfb90;
            }
            .tile .tile-icon { font-size:1.5em; }
            .tile.undug .tile-icon { opacity:0.25; font-size:2.75em; }
            .layer_bonus .tile-icon{ color:white !important; }
        `,
    };

    const fatGridSpinnerOption = {
        id: 'fat-grid-spinner',
        label: 'Fat spinner',
        alt: "Bigger spinners",
        css: `
            .mining-spinner {
                border:calc(5px*var(--ui-scale))solid transparent;
                top:calc(50% + 2* var(--spinner-offset,0px));
                left:calc(50% + 2* var(--spinner-offset,0px));
            }
        `,
    };

    const fatGridCrossOption = {
        id: 'fat-grid-no-dig-cross',
        label: 'Remove dig cross',
        alt: "remove the red cross that appear when you mine a block",
        css: `
            .dig-flash{ display:none !important; }
        `,
    };

    const BigHPBarOption = {
        id: 'fat-grid-hp-bar',
        label: 'Full height HP bar',
        alt: "Make HP bar bigger on blocks",
        css: `
            .progress-bar{ height:100%; opacity:0.55; }
        `,
    };

    const prettyDoomOption = {
        id: 'pretty-doom',
        label: 'Prettier DOOM name',
        alt: "Remove small clip bug on DOOM name and remove underline",
        css: `
            legend[title="Department Operator Of the Month"]{
                overflow-x: hidden;
                margin-top: -5px;
                margin-bottom: calc(-.25rem + -5px);
                padding-top: 5px;
                padding-bottom: 5px;
            }

            legend[title="Department Operator Of the Month"] .link{
                overflow: visible;
                text-decoration: none;
            }`,
    };

    const fullHeightShadowMenuOption = (() => {
        const shadowMenuSelector = '#grid-shadow-departments select';
        return {
            id: 'full-height-shadow-menu',
            label: 'Big shadow menu',
            beforeAnimationFrame: true,
            alt: "Keep shadow menu open so you can see every shadow departements",
            css: `
                ${shadowMenuSelector}{
                    height: 100%;
                    background: none;
                    overflow-y: auto;
                    padding: 0;
                }
                ${shadowMenuSelector} > option:checked {
                    background: #6666;
                    color: var(--color-base-content);
                }
                ${shadowMenuSelector} > option {
                    font-size: 1.2em;
                    padding: 2px 1em;
                }
                `,
            onChecked() {
                const menu = document.querySelector(shadowMenuSelector);
                if (menu && menu.size != menu.options.length) menu.size = menu.options.length;
            },
            onUnchecked() {
                const menu = document.querySelector(shadowMenuSelector);
                if (menu) menu.size = 1;
            },
            onDomUpdated() {
                const menu = document.querySelector(shadowMenuSelector);
                if (menu && menu.size != menu.options.length) menu.size = menu.options.length;
            },
        };
    })()

    const shortenInternMessageOption = (() => {
        const feedbackVariants = [
            "The precision of DeepCo",
            "DeepCo's performance metrics",
            "The transparency of DeepCo",
            "I am constantly amazed by the wisdom",
            "The relentless pursuit of productivity",
            "DeepCo's commitment to continuous improvement motivates me daily",
            "The consistency of DeepCo's operations is reassuring",
            "DeepCo's safety protocols are extensive"
        ];

        function shortenSystemMessages() {
            document.querySelectorAll('#chat-messages > [data-is-system="true"]:not(.nek-system-checked)').forEach((message) => {
                const target = message.querySelector("div.font-mono.text-success\\/80");
                if (!target) return;

                const originalText = target.textContent;

                const internMatch = originalText.match(/^Internship completion logged\.\s*(.+?)\s+has been promoted from intern status\..*$/i);
                if (internMatch) {
                    message.dataset.nekOriginal = originalText;
                    target.textContent = `${internMatch[1].trim()} has been promoted from intern status.`;
                    message.classList.add("nek-system-checked", "nek-intern");
                    return;
                }

                const milestoneMatch = originalText.match(/^Milestone achievement logged\.\s*(.+?)\s+has been promoted to\s+(.+?)\..*$/i);
                if (milestoneMatch) {
                    message.dataset.nekOriginal = originalText;
                    target.textContent = `${milestoneMatch[1].trim()} has been promoted to ${milestoneMatch[2].trim()}.`;
                    message.classList.add("nek-system-checked", "nek-milestone");
                    return;
                }

                const feedbackPattern = new RegExp(`^Feedback received from\\s*(.+?)\\.\\s*(${feedbackVariants.join('|').replace(/\./g, '\\.')})`, 'i');
                const feedbackMatch = originalText.match(feedbackPattern);

                if (feedbackMatch) {
                    message.dataset.nekOriginal = originalText;
                    target.textContent = `Feedback received from ${feedbackMatch[1].trim()}.`;
                    message.classList.add("nek-system-checked", "nek-feedback");
                    return;
                }

                message.classList.add("nek-system-checked");
            });
        }

        function restoreSystemMessages() {
            document.querySelectorAll('#chat-messages > [data-is-system="true"].nek-system-checked').forEach((message) => {
                const target = message.querySelector("div.font-mono.text-success\\/80");
                if (target && message.dataset.nekOriginal) {
                    target.textContent = message.dataset.nekOriginal;
                }

                message.classList.remove("nek-system-checked", "nek-intern", "nek-milestone", "nek-feedback");
                delete message.dataset.nekOriginal;
            });
        }

        return {
            id: 'shorten-intern-message',
            label: 'Small system message',
            alt: "Shorten system messages (interns, milestones, and feedback)",
            onChecked() { shortenSystemMessages(); },
            onUnchecked() { restoreSystemMessages(); },
            onDomUpdated() { shortenSystemMessages(); },
        };
    })();
    const zebraChatOption = (() => {
        function applyStableChatZebra(root = document) {
            const newMessages = root.querySelectorAll("#chat-messages > :not(.nek-even):not(.nek-odd)");

            newMessages.forEach((msg) => {
                const currentId = msg.getAttribute('data-worker-id');
                const prev = msg.previousElementSibling;
                const next = msg.nextElementSibling;

                const ref = (prev && (prev.classList.contains("nek-odd") || prev.classList.contains("nek-even"))) ? prev :
                (next && (next.classList.contains("nek-odd") || next.classList.contains("nek-even"))) ? next : null;

                if (ref) {
                    const refIsOdd = ref.classList.contains("nek-odd");
                    const sameAuthor = currentId && currentId === ref.getAttribute('data-worker-id');
                    const targetIsOdd = sameAuthor ? refIsOdd : !refIsOdd;
                    msg.classList.add(targetIsOdd ? "nek-odd" : "nek-even");
                } else {
                    msg.classList.add("nek-odd");
                }
            });
        }

        return {
            id: 'zebra-chat',
            label: 'Zebra chat',
            alt: "Add a subtle grey background to one chat message out of two.",
            css: `
                #chat-messages > .nek-even {
                    background: #6662;
                }
                #chat-messages{
                    gap: 0;
                }
                #chat-messages > .nek-even, #chat-messages > .nek-odd {
                    padding: calc(var(--spacing)*0.5) 0;
                }
            `,
            onChecked() { applyStableChatZebra(); },
            onUnchecked() {
                document.querySelectorAll("#chat-messages > *").forEach(m => m.classList.remove("nek-even", "nek-odd"));
            },
            onDomUpdated(mutations) {
                mutations.forEach(target => applyStableChatZebra(target))
            },
        };
    })();

    const hideFlashMessagesOption = {
        id: 'hide-flash-messages',
        label: 'Hide flash messages',
        alt: "Hide notifications on the bottom right without breaking the userscripts",
        css: `
            #flash-messages{
              display: none
            }
        `
    }

    const containedBoltsOption = (() => {
        const targetSelector = 'div.card[data-tutorial-target="gridCard"]';

        let canvas = null;

        function getCanvas() {
            const c = document.body.querySelector('canvas:not(.contained-thunderbolt):last-of-type');
            if (!c) return null;

            if (!c.classList.contains('rain-mask-handled')) {
                c.classList.add('rain-mask-handled');
            }

            return c;
        }

        function updateClip() {
            if (!canvas) return;

            const target = document.querySelector(targetSelector);
            if (!target) return;

            const rect = target.getBoundingClientRect();

            canvas.style.position = 'fixed';
            canvas.style.top = '0';
            canvas.style.left = '0';
            canvas.classList.add('contained-thunderbolt');

            canvas.style.clipPath = `inset(
            ${rect.top}px
            ${window.innerWidth - rect.right}px
            ${window.innerHeight - rect.bottom}px
            ${rect.left}px
        )`;
        }

        let rafScheduled = false;
        function scheduleUpdate() {
            if (rafScheduled) return;
            rafScheduled = true;
            requestAnimationFrame(() => {
                rafScheduled = false;
                updateClip();
            });
        }

        return {
            id: 'contain-thunderbolts-messages',
            label: 'Contained thunderbolts',
            alt: "the overclock thunderbolts stay within the game space",
            beforeAnimationFrame: true,
            css: '',

            onChecked() {
                canvas = getCanvas();
                if (!canvas) return;

                updateClip();

                window.addEventListener('resize', scheduleUpdate);
                window.addEventListener('scroll', scheduleUpdate, true);
            },

            onUnchecked() {
                if (canvas) {
                    canvas.style.clipPath = '';
                    canvas.style.position = '';
                    canvas.style.top = '';
                    canvas.style.left = '';
                }

                window.removeEventListener('resize', scheduleUpdate);
                window.removeEventListener('scroll', scheduleUpdate, true);
            },

            onDomUpdated() {
                const newCanvas = getCanvas();
                if (newCanvas && newCanvas !== canvas) {
                    canvas = newCanvas;
                    scheduleUpdate();
                } else if (canvas) {
                    scheduleUpdate();
                }
            },
        };
    })();

    const chillProgressBadgeOption = {
        id: 'chill-progress',
        label: 'Chill progress badge',
        alt: "remove the animation from the Progress Badge when you break a block",
        css: `
                #tiles-defeated-badge > .nudge-animation {
                    animation: none;
                }
            `
        };

    const getVintageTvCss = (targetSelector) => {

        return `
        ${targetSelector} {
            position: relative;
        }

        ${targetSelector}::before,
        ${targetSelector}::after {
            content: " ";
            display: block;
            position: fixed;
            top: 0; left: 0; bottom: 0; right: 0;
            z-index: 2147483647;
            pointer-events: none;
            mix-blend-mode: overlay;
        }

        ${targetSelector}::before {
            background:
                linear-gradient(rgba(18, 16, 16, 0.15) 50%, rgba(66, 66, 66, 0.1) 50%),
                linear-gradient(90deg,
                    rgba(255, 0, 0, 0.18) 33.33%,
                    rgba(0, 255, 0, 0.15) 33.33%,
                    rgba(0, 255, 0, 0.15) 66.66%,
                    rgba(0, 0, 255, 0.18) 66.66%
                );
            background-size: 100% 3px, 3px 100%;
        }

        ${targetSelector}::after {
            content: " ";
            display: block;
            position: fixed;
            top: 0; left: 0; bottom: 0; right: 0;
            z-index: 2147483647;
            pointer-events: none;
            mix-blend-mode: overlay;

            background:
                linear-gradient(
                    to bottom,
                    transparent 0%,
                    rgba(255, 255, 255, 0.15) 50%,
                    transparent 100%
                ),
                linear-gradient(
                    to bottom,
                    rgba(255, 255, 255, 0.05) 0%,
                    transparent 20%,
                    rgba(255, 255, 255, 0.05) 40%,
                    transparent 100%
                );

            background-size: 100% 400px, 100% 17px;

            animation:
                scanlineScroll 1s linear infinite,
                jitter 0.1s steps(2) infinite;
        }

        @keyframes scanlineScroll {
            from { background-position: 0 0px, 0 0px; }
            to { background-position: 0 400px, 0 0px; }
        }

        @keyframes jitter {
            from { background-position: 0 0px, 0 0px; }
            to { background-position: 0 0px, 0 17px; }
        }

    `;
    }

    const vintageTvOption = {
        id: 'vintage-tv',
        label: 'CRT Monitor',
        alt: "Old monitor effect",
        css: getVintageTvCss('body')
    };

    const removeAsyncNotificationOption = (() => {
        function removeAsyncNotif(root = document) {
            const autoAsync = root.querySelector('#auto-async-header');
            if(!autoAsync) return
            if(autoAsync.querySelectorAll('button[disabled]').length === 0) {
                return
            };
            [
                ...autoAsync.querySelectorAll('.indicator-item')
                ,...root.querySelectorAll('#async-division-header .indicator-item')
            ].forEach((e) => {
                e.classList.add('hidden')
            });
        }

        function putBackAsyncNotif(root = document) {
            const autoAsync = root.querySelector('#auto-async-header');
            if(!autoAsync) return
            if(autoAsync.querySelectorAll('button[disabled]').length === 0) {
                return
            };
            [
                ...autoAsync.querySelectorAll('.indicator-item')
                ,...root.querySelectorAll('#async-division-header .indicator-item')
            ].forEach((e) => {
                e.classList.remove('hidden')
            });
        }

        return {
            id: 'remove-async-notif',
            label: 'Remove Async Badge',
            alt: "Remove the Notification Badge on Async and Auto-Async",
            onChecked() { removeAsyncNotif() },
            onUnchecked() {
                putBackAsyncNotif()
            },
            onDomUpdated(mutations) {
                mutations.forEach(target => removeAsyncNotif(target))
            },

        }
    })();

    const autoAsyncHeaderOption = (() => {
        function autoAsyncWarning(root = document) {
            const autoAsync = root.querySelector('#auto-async-header');
            if(!autoAsync) return
            if(autoAsync.querySelectorAll('button[disabled]').length === 0) {
                const mainIcon = root.querySelector('header.navbar a[href="/"]')
                if(mainIcon){
                    mainIcon.classList.remove("text-primary")
                    mainIcon.classList.add("text-warning")
                }
                return
            }
        }
        function removeAutoAsyncWarning(root = document) {
            const autoAsync = root.querySelector('#auto-async-header');
            if(!autoAsync) return
            if(autoAsync.querySelectorAll('button[disabled]').length === 0) {
                const mainIcon = root.querySelector('header.navbar a[href="/"]')
                if(mainIcon){
                    mainIcon.classList.add("text-primary")
                    mainIcon.classList.remove("text-warning")
                }
                return
            }
        }
        return {
            id: 'auto-async-header',
            label: 'Auto Async Warning',
            alt: "Change color of the header when auto-async isn't armed",
            onChecked() { autoAsyncWarning() },
            onUnchecked() {
                removeAutoAsyncWarning()
            },
            onDomUpdated(mutations) {
                autoAsyncWarning();
            },

        }
    })();

    const colorRecurseCoinsOption = (() => {
        function colorRecurseCoins() {
            const settingsPanel = document.getElementById("main-panel")?.getElementsByTagName('main')[0]?.getElementsByClassName('settings-panel')[0];
            if(!settingsPanel || settingsPanel.classList.contains('nek-color-recurse-points')) return;
            const fieldsetLabel = "Lifetime Output";
            const innerLabel = "Recursive Credits Acquired";

            settingsPanel.querySelectorAll("fieldset").forEach(fieldset => {
                const legend = fieldset.querySelector("legend");

                if (legend && legend.textContent.trim() === fieldsetLabel) {

                    fieldset.querySelectorAll("div.text-xs").forEach(labelDiv => {

                        if (labelDiv.textContent.trim() === innerLabel) {

                            const container = labelDiv.closest(".rounded-box");
                            const valueDiv = container?.querySelector(".text-2xl");

                            if (valueDiv) {
                                valueDiv.classList.remove("text-base-content");
                                valueDiv.classList.add("text-secondary");
                            }

                        }

                    });

                }
            });
            settingsPanel.classList.add('nek-color-recurse-points')
        }

        function removecolorRecurseCoins() {
            const settingsPanel = document.getElementById("main-panel")?.getElementsByTagName('main')[0]?.getElementsByClassName('settings-panel')[0];
            if(!settingsPanel || !settingsPanel.classList.contains('nek-color-recurse-points')) return;
            const fieldsetLabel = "Lifetime Output";
            const innerLabel = "Recursive Credits Acquired";

            settingsPanel.querySelectorAll("fieldset").forEach(fieldset => {
                const legend = fieldset.querySelector("legend");

                if (legend && legend.textContent.trim() === fieldsetLabel) {

                    fieldset.querySelectorAll("div.text-xs").forEach(labelDiv => {

                        if (labelDiv.textContent.trim() === innerLabel) {

                            const container = labelDiv.closest(".rounded-box");
                            const valueDiv = container?.querySelector(".text-2xl");

                            if (valueDiv) {
                                valueDiv.classList.add("text-base-content");
                                valueDiv.classList.remove("text-secondary");
                            }

                        }

                    });

                }
            });
            settingsPanel.classList.remove('nek-color-recurse-points')

        }
        return {
            id: 'color-recurse-points',
            label: 'Color Recurse Points',
            alt: "Color the recurse points on the players profile",
            onChecked() { colorRecurseCoins() },
            onUnchecked() {
                removecolorRecurseCoins()
            },
            onDomUpdated(mutations) {
                colorRecurseCoins()
            },

        }
    })();

    const SortedOnlinePlayersOption = (() => {
        const FETCHED_CLASS = 'nek-fetched-card';
        const DONE_ATTR = 'data-nek-all-fetched';
        const FIELDSET_CLASS = 'nek-dept-fieldset';

        let abortController = null;

        function getOnlineGrid() {
            const h1 = document.querySelector('#main-panel h1');
            if (!h1?.textContent.includes('ACTIVE OPERATORS')) return null;
            return document.querySelector('#main-panel div.grid');
        }

        function getPagination() {
            return document.querySelector('#main-panel .join');
        }

        function getNextUrl(doc) {
            return doc.querySelector('a[rel="next"].join-item:not(.btn-disabled)')?.href ?? null;
        }

        function getDepartmentInfo(card) {
            for (const label of card.querySelectorAll('span.font-semibold')) {
                if (label.textContent.trim() !== 'Department:') continue;
                const valueSpan = label.nextElementSibling;
                if (!valueSpan) continue;
                const key = valueSpan.querySelector('span.font-mono')?.textContent.trim() ?? '?';
                const humanLabel = [...valueSpan.childNodes]
                .filter(n => n.nodeType === Node.TEXT_NODE)
                .map(n => n.textContent.trim())
                .filter(Boolean)
                .join('') || key;
                return { key, humanLabel };
            }
            return { key: '?', humanLabel: '?' };
        }

        function deptSortKey(key) {
            const m = key.match(/^dc\+(\d+)$/i);
            return m ? parseInt(m[1]) : Infinity;
        }

        function sortIntoFieldsets(grid, cards) {
            const groups = new Map();
            for (const card of cards) {
                const { key, humanLabel } = getDepartmentInfo(card);
                if (!groups.has(key)) groups.set(key, { humanLabel, cards: [] });
                groups.get(key).cards.push(card);
            }

            const sorted = [...groups.entries()].sort(([a], [b]) => {
                const da = deptSortKey(a), db = deptSortKey(b);
                if (da !== db) return db - da;
                return a.localeCompare(b);
            });

            grid.replaceChildren();

            for (const [key, { humanLabel, cards }] of sorted) {
                const fieldset = document.createElement('fieldset');
                fieldset.className = `fieldset ${FIELDSET_CLASS} col-span-full`;

                const legend = document.createElement('legend');
                legend.className = 'fieldset-legend';
                const legendSpan = document.createElement('span');
                legendSpan.className = 'flex-1';
                legendSpan.textContent = humanLabel !== key ? `${key} — ${humanLabel}` : key;
                legend.appendChild(legendSpan);
                fieldset.appendChild(legend);

                const inner = document.createElement('div');
                inner.className = 'grid grid-cols-1 gap-6 sm:grid-cols-2 xl:grid-cols-3';
                for (const card of cards) inner.appendChild(card);
                fieldset.appendChild(inner);

                grid.appendChild(fieldset);
            }
        }

        async function fetchAndSort(grid, signal) {
            const allCards = [...grid.querySelectorAll('a.card[href^="/workers/"]')];

            let nextUrl = getNextUrl(document);

            while (nextUrl) {
                if (signal.aborted) return;

                try {
                    const res = await fetch(nextUrl, { signal });
                    const text = await res.text();
                    const doc = new DOMParser().parseFromString(text, 'text/html');

                    const newCards = [...doc.querySelectorAll('#main-panel div.grid > a.card[href^="/workers/"]')];
                    nextUrl = getNextUrl(doc);

                    for (const card of newCards) {
                        const node = document.importNode(card, true);
                        node.classList.add(FETCHED_CLASS);
                        allCards.push(node);
                    }
                } catch {
                    break;
                }
            }

            if (signal.aborted) return;

            sortIntoFieldsets(grid, allCards);
            grid.setAttribute(DONE_ATTR, '');
            grid.classList.remove('grid-cols-1', 'sm:grid-cols-2', 'xl:grid-cols-3')
            getPagination()?.style.setProperty('display', 'none');
        }

        function apply() {
            const grid = getOnlineGrid();
            if (!grid || grid.hasAttribute(DONE_ATTR)) return;

            abortController?.abort();
            abortController = new AbortController();
            fetchAndSort(grid, abortController.signal);
        }

        function remove() {
            abortController?.abort();
            abortController = null;

            const grid = document.querySelector('#main-panel div.grid');
            if (grid) {
                const original = [...grid.querySelectorAll(`a.card[href^="/workers/"]:not(.${FETCHED_CLASS}`)];
                const fetched = [...grid.querySelectorAll(`a.card.${FETCHED_CLASS}`)];
                grid.replaceChildren(...original);
                grid.removeAttribute(DONE_ATTR);
            }

            const pagination = getPagination();
            if (pagination) pagination.style.removeProperty('display');
        }

        return {
            id: 'sorted-online-players',
            label: 'Sort online by department',
            alt: 'Fetch all pages and group operators into fieldsets by department',
            onChecked() { apply(); },
            onUnchecked() { remove(); },
            onDomUpdated() { apply(); },
        };
    })();

    const hideIdleHeadersOption = (() => {
        function setDisplay(el, value) {
            if (el.style.display !== value) el.style.display = value;
        }

        function applyHeaders() {
            const claim = document.getElementById('auto-claim-header');
            const asyncEl = document.getElementById('auto-async-header');

            const claimHidden = claim && claim.querySelector('.indicator-item')?.classList.contains('hidden');
            const asyncArmed = asyncEl && !!asyncEl.querySelector('button[disabled]');

            if (claim) setDisplay(claim, claimHidden ? 'none' : '');
            if (asyncEl) setDisplay(asyncEl, asyncArmed ? 'none' : '');
        }

        function removeHeaders() {
            ['auto-claim-header', 'auto-async-header'].forEach(id => {
                const el = document.getElementById(id);
                if (el) setDisplay(el, '');
            });
        }

        return {
            id: 'hide-idle-headers',
            label: 'Hide idle autos',
            alt: "Hide auto-claim when inactive, and auto-async when pending (by M3P)",
            beforeAnimationFrame: true,
            onChecked() { applyHeaders(); },
            onUnchecked() { removeHeaders(); },
            onDomUpdated() { applyHeaders(); },
        };
    })();

    const CATEGORIES = [
        {
            id: 'cat-fat-grid',
            label: 'Game Juice',
            alt: "Fat spinner, big icons and large blocks",
            options: [fatGridOption, BigHPBarOption, fatGridSpinnerOption]
        },
        {
            id: 'cat-contained-entropy',
            label: 'Contained Entropy',
            alt: "hide eye catchers",
            options: [hideFlashMessagesOption, containedBoltsOption, chillProgressBadgeOption, fatGridCrossOption, removeAsyncNotificationOption, hideIdleHeadersOption]
        },
        {
            id: 'cat-qol',
            label: 'Quality of Life',
            alt: "Show name of people in your departement, make shadow menu bigger, etc",
            options: [presenceTooltipOption, fullHeightShadowMenuOption, autoAsyncHeaderOption, colorRecurseCoinsOption, SortedOnlinePlayersOption]
        },
        {
            id: 'cat-readable-chat',
            label: 'Names styling',
            alt: "Make rainbow names less eye catcher, and change color customization",
            options: [colorSpecificRainbowOption, bubbleNamesOption, prettyDoomOption]
        },
        {
            id: 'cat-chat',
            label: 'Easy to read chat',
            alt: "Make chat easier to read",
            options: [zebraChatOption, shortenInternMessageOption, softIDPlusOption, IDPlusSpaceInChatOption]
        },
        {
            id: 'cat-vintage',
            label: 'Vintage monitor',
            alt: "Vintage CTR monitor",
            options: [ vintageTvOption]
        },
    ];

    const CSS_OPTIONS = CATEGORIES.reduce((acc, cat) => acc.concat(cat.options), []);

    /** Profiler **/

    const NekProfiler = (() => {
        const data = {};
        let monitoringEnabled = false;

        return {
            start: (id) => {
                if (!monitoringEnabled) return;
                if (!data[id]) {
                    data[id] = { totalTime: 0, callCount: 0, maxTime: 0, startTime: null };
                }
                data[id].startTime = performance.now();
            },

            stop: (id) => {
                if (!monitoringEnabled) return;
                const entry = data[id];
                if (entry && entry.startTime !== null) {
                    const duration = performance.now() - entry.startTime;
                    entry.totalTime += duration;
                    if (duration > entry.maxTime) {
                        entry.maxTime = duration;
                    }
                    entry.callCount++;
                    entry.startTime = null;
                }
            },

            report: (title) => {
                const reportData = Object.keys(data).map(id => {
                    const entry = data[id];
                    const avg = entry.callCount > 0 ? entry.totalTime / entry.callCount : 0;
                    return {
                        ID: id,
                        name: typeof CSS_OPTIONS !== 'undefined' ? CSS_OPTIONS.find(i => i.id === id)?.label : id,
                        "Calls": entry.callCount,
                        "Average (ms)": parseFloat(avg.toFixed(5)),
                        "Max (ms)": parseFloat(entry.maxTime.toFixed(5)),
                        "Total (ms)": parseFloat(entry.totalTime.toFixed(3))
                    };
                });
                reportData.sort((a, b) => b["Average (ms)"] - a["Average (ms)"]);
                if(title){
                    console.log(title);
                }
                console.table(reportData);
            },

            reset: () => {
                for (let id in data) delete data[id];
            },

            enable: (onOff = true) => {
                monitoringEnabled = onOff;
                return onOff;
            }
        };
    })();
    if(profilingEnabledAtStart){
        NekProfiler.enable(true);
        window.addEventListener('beforeunload', () => {
            NekProfiler.report(`${buttonLabel} ${version} profiling:`);
        });
    }

    /** ENGINE **/

    const domHandlers = new Map();
    const domHandlersBeforeAnimation = new Map();
    let sharedObserver = null;

    function runHandlersBeforeAnimation(mutations) {
        const nodes = cleanMutations(mutations);
        domHandlersBeforeAnimation.forEach((fn,i) => {
            NekProfiler.start(i)
            fn(nodes)
            NekProfiler.stop(i)
        });
    }
    function runHandlers(mutations) {
        const nodes = cleanMutations(mutations);
        domHandlers.forEach((fn,i) => {
            NekProfiler.start(i)
            fn(nodes)
            NekProfiler.stop(i)
        });
    }

    let rafPending = false;
    let promisePending = false;
    let mutationPromise = [];
    let mutationRaf = [];
    function ensureSharedObserver() {
        if (sharedObserver) return;
        sharedObserver = new MutationObserver((mutations) => {
            mutationRaf.push(...mutations);
            mutationPromise.push(...mutations);
            if (!promisePending) {
                promisePending = true;
                Promise.resolve().then(() => {
                    promisePending = false;
                    const batch = mutationPromise;
                    mutationPromise = [];
                    runHandlersBeforeAnimation(batch);
                });
            }
            if(!rafPending){
                rafPending = true;
                requestAnimationFrame(() => {
                    rafPending = false;
                    const batch = mutationRaf;
                    mutationRaf = [];
                    runHandlers(batch)
                });
            }
        });
        sharedObserver.observe(document.documentElement, { childList: true, subtree: true });
    }

    function cleanMutations(mutations) {
        const nodes = new Set();

        for (const m of mutations) {
            if (m.target) nodes.add(m.target);
            if (m.addedNodes) {
                for (const node of m.addedNodes) {
                    if (node.nodeType === 1) { // ELEMENT_NODE only
                        nodes.add(node);
                    }
                }
            }
        }

        // only nodes still in DOM
        const inDom = [...nodes].filter(node => node.isConnected);

        // Remove nodes whose ancestor is already included
        const result = [];
        for (const node of inDom) {
            let parent = node.parentNode;
            let skip = false;

            while (parent) {
                if (nodes.has(parent)) {
                    skip = true;
                    break;
                }
                parent = parent.parentNode;
            }

            if (!skip) result.push(node);
        }

        return result;
    }

    function registerHandler(id, fn, beforeAnimation) {
        if(beforeAnimation){
            domHandlersBeforeAnimation.set(id, fn);
        } else {
            domHandlers.set(id, fn);
        }
        ensureSharedObserver();
    }

    function unregisterHandler(id) {
        domHandlers.delete(id);
        domHandlersBeforeAnimation.delete(id);
        if ((domHandlers.size + domHandlersBeforeAnimation.size) === 0 && sharedObserver) {
            sharedObserver.disconnect();
            sharedObserver = null;
            rafPending = false;
        }
    }

    const styleElements = new Map();

    function enableOption(option) {
        if (option.css && !styleElements.has(option.id)) {
            const style = document.createElement('style');
            style.textContent = option.css;
            document.head.appendChild(style);
            styleElements.set(option.id, style);
        }
        if (typeof option.onDomUpdated === 'function' && !domHandlers.has(option.id)) {
            registerHandler(option.id, (mutations) => option.onDomUpdated(mutations), option.beforeAnimationFrame);
        }
        if (typeof option.onChecked === 'function') option.onChecked();
    }

    function disableOption(option) {
        const style = styleElements.get(option.id);
        if (style) { style.remove(); styleElements.delete(option.id); }
        unregisterHandler(option.id);
        if (typeof option.onUnchecked === 'function') option.onUnchecked();
    }

    function loadSettings() { try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || {}; } catch { return {}; } }
    function saveSettings(s) { localStorage.setItem(STORAGE_KEY, JSON.stringify(s)); }

    function createMenu(settings) {
        const container = document.createElement('div');
        container.style.cssText = `position: relative; display: inline-block;`;

        const button = document.createElement('button');
        button.textContent = buttonLabel;
        button.style.color = '#bada55';
        button.classList.add('btn', 'btn-ghost', 'btn-sm', 'text-primary');

        const menu = document.createElement('div');
        menu.style.cssText = `display: none; position: absolute; bottom: calc(100% + 8px); left: 0; min-width: 260px; z-index: 1000; text-align: left`;
        menu.classList.add('card', 'bg-base-100', 'border', 'border-base-300', 'p-2', 'text-xs', 'shadow-xl');

        const accordionRegistry = [];

        CATEGORIES.forEach((category) => {
            const hasMultiple = category.options.length > 1;

            const catContainer = document.createElement('div');
            catContainer.style.cssText = `margin-bottom: 4px;`;

            const catHeader = document.createElement('div');
            catHeader.style.cssText = `display: flex; align-items: center;`;

            if (category.alt) {
                catHeader.setAttribute("data-tip", category.alt);
                catHeader.classList.add("tooltip", "tooltip-right");
            }

            const clickableLabel = document.createElement('label');
            clickableLabel.style.cssText = `display: flex; gap: 8px; padding: 6px 10px; align-items: center; flex-grow: 1; cursor: pointer; user-select: none;`;

            const catCheckbox = document.createElement('input');
            catCheckbox.type = 'checkbox';
            catCheckbox.classList.add('checkbox', 'checkbox-sm', 'checkbox-primary');

            const catLabel = document.createElement('span');
            catLabel.textContent = category.label;
            catLabel.style.cssText = `font-weight: 700; font-size: 12px;`;

            clickableLabel.append(catCheckbox, catLabel);

            let expandBtn = null;
            let subContainer = null;

            if (hasMultiple) {
                expandBtn = document.createElement('div');
                expandBtn.textContent = '+';
                expandBtn.style.cssText = `padding: 6px 12px; cursor: pointer; font-weight: bold; border-left: 1px solid var(--fallback-bc, oklch(var(--bc)/0.1)); transition: background 0.2s;`;
                expandBtn.onmouseover = () => expandBtn.style.background = 'var(--fallback-b3, oklch(var(--b3)/0.3))';
                expandBtn.onmouseout = () => expandBtn.style.background = 'transparent';

                subContainer = document.createElement('div');
                subContainer.style.cssText = `display: none; padding: 2px 0; background: var(--fallback-b1, oklch(var(--b1)/1)); border-top: 1px solid var(--fallback-bc, oklch(var(--bc)/0.05));`;

                accordionRegistry.push({ subContainer, expandBtn });

                expandBtn.addEventListener('click', (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    const isOpen = subContainer.style.display === 'block';

                    accordionRegistry.forEach(item => {
                        item.subContainer.style.display = 'none';
                        item.expandBtn.textContent = '+';
                    });

                    if (!isOpen) {
                        subContainer.style.display = 'block';
                        expandBtn.textContent = '−';
                    }
                });
            }

            const optionCheckboxes = [];
            category.options.forEach((opt) => {
                const isChecked = !!settings[opt.id];

                if (hasMultiple) {
                    const row = document.createElement('label');
                    row.style.cssText = `display: flex; gap: 8px; padding: 4px 10px 4px 28px; cursor: pointer; align-items: center;`;
                    if (opt.alt) {
                        row.setAttribute("data-tip", opt.alt);
                        row.classList.add("tooltip", "tooltip-right");
                    }

                    const cb = document.createElement('input');
                    cb.type = 'checkbox';
                    cb.checked = isChecked;
                    cb.classList.add('checkbox', 'checkbox-xs');

                    cb.addEventListener('change', () => {
                        settings[opt.id] = cb.checked;
                        saveSettings(settings);
                        if (cb.checked) enableOption(opt); else disableOption(opt);
                        updateMaster();
                    });

                    optionCheckboxes.push({ cb, opt });
                    row.append(cb, document.createTextNode(opt.label));
                    subContainer.appendChild(row);
                } else {
                    optionCheckboxes.push({ cb: catCheckbox, opt });
                }
            });

            const updateMaster = () => {
                const checkedCount = category.options.filter(o => settings[o.id]).length;
                catCheckbox.checked = checkedCount === category.options.length;
                catCheckbox.indeterminate = checkedCount > 0 && checkedCount < category.options.length;
            };

            catCheckbox.addEventListener('change', () => {
                const state = catCheckbox.checked;
                optionCheckboxes.forEach(({ cb, opt }) => {
                    cb.checked = state;
                    settings[opt.id] = state;
                    if (state) enableOption(opt); else disableOption(opt);
                });
                saveSettings(settings);
                updateMaster();
            });

            updateMaster();
            catHeader.append(clickableLabel);
            if (expandBtn) catHeader.append(expandBtn);

            catContainer.append(catHeader);
            if (subContainer) catContainer.append(subContainer);
            menu.appendChild(catContainer);
        });

        const versionLine = document.createElement('div');
        versionLine.textContent = `v${version}`;
        versionLine.style.cssText = 'font-size: 10px; color: #777; text-align: right; margin-top: 4px; pointer-events:none;';
        menu.appendChild(versionLine);

        button.addEventListener('click', (e) => {
            e.stopPropagation();
            menu.style.display = menu.style.display === 'none' ? 'block' : 'none';
        });

        document.addEventListener('click', (e) => { if (!container.contains(e.target)) menu.style.display = 'none'; });

        container.append(button, menu);
        return container;
    }

    function waitForTarget(selector, callback) {
        const func = () => {
            const target = document.querySelector(selector);
            if (target) callback(target);
        }
        func();
        registerHandler('nek-main-menu', () => {
            func();
        })
    }

    function init() {
        const settings = loadSettings();
        CSS_OPTIONS.forEach(opt => { if (settings[opt.id]) enableOption(opt); });
        const menuEl = createMenu(settings);
        waitForTarget(INJECT_TARGET_SELECTOR, (target) => {
            if (menuEl.parentElement !== target) target.insertBefore(menuEl, target.firstChild);
        });
    }

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

    window.NekStyle = {
        enableProfiling: (onOff) => NekProfiler.enable(onOff),
        printProfilingReport: () => NekProfiler.report()
    }
})();