Actions

MediaWiki

Common.js: Difference between revisions

From Dune Awakening DB

mNo edit summary
Tags: Manual revert Reverted
mNo edit summary
Tag: Reverted
Line 1: Line 1:
/* ========================================
/* ========================================
   MediaWiki:Common.js - Fixed Header Spacing
   MediaWiki:Common.js - Fixed Header Spacing
Line 7: Line 6:
     // HEADER FIX - Wait for page to load then force header
     // HEADER FIX - Wait for page to load then force header
     setTimeout(function() {
     setTimeout(function() {
    // Remove ALL existing headers and nav attempts
        // Remove ALL existing headers and nav attempts
    $('.mw-header, #mw-header-container, nav.tab-bar, .tab-bar').remove();
        $('.mw-header, #mw-header-container, nav.tab-bar, .tab-bar').remove();
   
       
    // Hide the page title and extra elements completely
        // Hide the page title and extra elements completely
    $('.firstHeading, h1.title, .mw-page-title-main, #firstHeading, #tagline, h3#tagline, #contentSub, .mw-content-subtitle').remove();
        $('.firstHeading, h1.title, .mw-page-title-main, #firstHeading, #tagline, h3#tagline, #contentSub, .mw-content-subtitle').remove();
          
          
         // Create the navigation bar HTML with inline styles
         // Create the navigation bar HTML with inline styles
         var headerHTML = `
         var headerHTML = `
             <div id="dune-header" style="position: fixed; top: 0; left: 0; right: 0; height: 60px; background: linear-gradient(180deg, rgba(20, 18, 28, 0.95) 0%, rgba(10, 8, 16, 0.98) 100%); border-bottom: 3px solid rgba(252, 231, 200, 0.4); box-shadow: 0 2px 20px rgba(0,0,0,0.8); z-index: 99999; display: flex; align-items: center;">
             <div id="dune-header" style="position: fixed; top: 0; left: 0; right: 0; height: 60px; background: linear-gradient(180deg, rgba(20, 18, 28, 0.95) 0%, rgba(10, 8, 16, 0.98) 100%); border-bottom: 3px solid rgba(252, 231, 200, 0.4); box-shadow: 0 2px 20px rgba(0,0,0,0.8); z-index: 99999; display: flex; align-items: center;">
                 <div style="width: 100%; max-width: 1600px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; height: 100%;">
                 <div class="dune-header-inner" style="width: 100%; max-width: 1600px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; height: 100%;">
                     <a href="/wiki/Main_Page" style="font-family: 'Orbitron', sans-serif; font-size: 22px; color: #fce7c8; text-transform: uppercase; letter-spacing: 3px; font-weight: 700; text-shadow: 0 0 15px rgba(252, 231, 200, 0.4); text-decoration: none; white-space: nowrap;">DUNE DB</a>
                     <a href="/wiki/Main_Page" class="dune-logo" style="font-family: 'Orbitron', sans-serif; font-size: 22px; color: #fce7c8; text-transform: uppercase; letter-spacing: 3px; font-weight: 700; text-shadow: 0 0 15px rgba(252, 231, 200, 0.4); text-decoration: none; white-space: nowrap;">DUNE DB</a>
                      
                      
                     <nav style="display: flex; gap: 0; margin: 0 20px; height: 100%;">
                     <nav class="dune-nav" style="display: flex; gap: 0; margin: 0 20px; height: 100%;">
                         <a href="/wiki/Items" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-left: 1px solid rgba(252, 231, 200, 0.1); border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">◇ Items</a>
                         <a href="/wiki/Items" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-left: 1px solid rgba(252, 231, 200, 0.1); border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">◇ Items</a>
                         <a href="/wiki/Crafting" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">⚒ Crafting</a>
                         <a href="/wiki/Crafting" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">⚒ Crafting</a>
Line 29: Line 28:
                     </nav>
                     </nav>
                      
                      
                     <div style="display: flex; align-items: center;">
                     <div class="dune-search" style="display: flex; align-items: center;">
                         <form action="/index.php" method="get" style="display: flex; align-items: center; gap: 0;">
                         <form action="/index.php" method="get" style="display: flex; align-items: center; gap: 0;">
                             <input type="search" name="search" placeholder="Search wiki..." style="background: rgba(0, 0, 2, 0.8); border: 2px solid rgba(252, 231, 200, 0.3); border-radius: 0; color: #fce7c8; padding: 8px 12px; width: 200px; font-size: 13px; font-family: 'Rajdhani', sans-serif; transition: all 0.3s ease; outline: none;" onfocus="this.style.borderColor='#fce7c8'; this.style.boxShadow='0 0 10px rgba(252, 231, 200, 0.3)'; this.style.width='250px';" onblur="this.style.borderColor='rgba(252, 231, 200, 0.3)'; this.style.boxShadow='none'; this.style.width='200px';">
                             <input type="search" name="search" placeholder="Search wiki..." style="background: rgba(0, 0, 2, 0.8); border: 2px solid rgba(252, 231, 200, 0.3); border-radius: 0; color: #fce7c8; padding: 8px 12px; width: 200px; font-size: 13px; font-family: 'Rajdhani', sans-serif; transition: all 0.3s ease; outline: none;" onfocus="this.style.borderColor='#fce7c8'; this.style.boxShadow='0 0 10px rgba(252, 231, 200, 0.3)'; this.style.width='250px';" onblur="this.style.borderColor='rgba(252, 231, 200, 0.3)'; this.style.boxShadow='none'; this.style.width='200px';">
Line 40: Line 39:
          
          
         $('body').prepend(headerHTML);
         $('body').prepend(headerHTML);
   
       
    // CRITICAL: Force proper spacing
        // CRITICAL: Force proper spacing
    $('body').css({
        $('body').css({
        'padding-top': '60px',
            'padding-top': '60px',
        'margin-top': '0'
            'margin-top': '0'
    });
        });
   
       
    // Remove ALL top spacing from content elements
        // Remove ALL top spacing from content elements
    $('#content, .mw-body, #mw-content-text, .mw-body-content, .mw-parser-output, #main-section, .main-section, #page-content, #p-cactions').css({
        $('#content, .mw-body, #mw-content-text, .mw-body-content, .mw-parser-output, #main-section, .main-section, #page-content, #p-cactions').css({
        'padding-top': '0',
            'padding-top': '0',
        'margin-top': '0'
            'margin-top': '0'
    });
        });
   
       
    // Force breadcrumb to be tight
        // Force breadcrumb to be tight
    $('.dune-breadcrumb-nav').css({
        $('.dune-breadcrumb-nav').css({
        'margin-top': '0',
            'margin-top': '0',
        'margin-bottom': '15px',
            'margin-bottom': '15px',
        'padding': '8px 12px'
            'padding': '8px 12px'
    });
        });
   
       
    // Force first element to start at top
        // Force first element to start at top
    $('.mw-parser-output > *:first-child, .mw-body-content > *:first-child').css({
        $('.mw-parser-output > *:first-child, .mw-body-content > *:first-child').css({
        'margin-top': '0',
            'margin-top': '0',
        'padding-top': '0'
            'padding-top': '0'
    });
        });
   
       
    // Remove sidebar space
        // Remove sidebar space
    $('#sidebar, .columns.large-2.medium-3').css('display', 'none');
        $('#sidebar, .columns.large-2.medium-3').css('display', 'none');
    $('#page-content, .columns.large-10.medium-9').css({
        $('#page-content, .columns.large-10.medium-9').css({
        'width': '100%',
            'width': '100%',
        'max-width': '100%',
            'max-width': '100%',
        'margin': '0',
            'margin': '0',
        'padding': '0'
            'padding': '0'
    });
        });
   
       
    // Handle Actions button area
        // Handle Actions button area
    $('#p-cactions').css({
        $('#p-cactions').css({
        'margin-bottom': '0',
            'margin-bottom': '0',
        'padding-bottom': '0'
            'padding-bottom': '0'
    });
        });
   
       
    // Remove spacing from all column wrappers
        // Remove spacing from all column wrappers
    $('.row > .columns').css({
        $('.row > .columns').css({
        'padding-top': '0',
            'padding-top': '0',
        'margin-top': '0'
            'margin-top': '0'
    });
        });
      
       
}, 100);
     }, 100);
});
});


// MediaWiki Common.js - Actions Button Header Integration
// MediaWiki Common.js - SAFER Actions Button Header Integration
// This script moves the actions button into the header navigation bar
// This version moves the actions button without breaking functionality
 
$(document).ready(function() {
$(document).ready(function() {
     // Wait for DOM to be fully loaded
     // Wait for header to be created
     setTimeout(function() {
     setTimeout(function() {
         // Find the actions dropdown
         try {
        var $actions = $('#p-cactions');
            var $actions = $('#p-cactions');
        var $drop = $('#drop');
            var $drop = $('#drop');
       
             var $headerInner = $('.dune-header-inner');
        if ($actions.length && $drop.length) {
            // Create a wrapper for the actions in the header
             var $actionsWrapper = $('<div class="dune-header-actions"></div>');
           
            // Clone the dropdown button and menu
            var $actionsClone = $drop.clone(true);
           
            // Add the cloned actions to the wrapper
            $actionsWrapper.append($actionsClone);
           
            // Find the search element in the header
             var $search = $('.dune-search');
             var $search = $('.dune-search');
              
              
             if ($search.length) {
            // Only proceed if all elements exist
                 // Insert the actions after the search
             if ($actions.length && $drop.length && $headerInner.length) {
                 $search.after($actionsWrapper);
                 // Create wrapper for actions in header
            } else {
                var $actionsWrapper = $('<div class="dune-header-actions" style="display: flex; align-items: center; margin-left: 10px;"></div>');
                 // If no search, append to header inner
               
                 $('.dune-header-inner').append($actionsWrapper);
                // MOVE the actions (don't clone) to preserve functionality
                $actionsWrapper.append($actions);
               
                // Insert after search
                 if ($search.length) {
                    $search.after($actionsWrapper);
                } else {
                    $headerInner.append($actionsWrapper);
                }
               
                 // Reset positioning on the moved element
                $actions.css({
                    'position': 'static',
                    'top': 'auto',
                    'right': 'auto',
                    'margin': '0',
                    'padding': '0',
                    'display': 'block'
                });
               
                // Style the button
                 $('#drop .button').css({
                    'height': '38px',
                    'margin': '0'
                });
               
                // Make sure actions are visible
                $actions.show();
             }
             }
           
        } catch (e) {
            // Hide the original actions
             console.error('Error moving actions:', e);
             $actions.hide();
             // Fallback: ensure actions are at least visible
           
             $('#p-cactions').css({
             // Ensure the dropdown functionality works
                 'display': 'block',
             $actionsClone.find('[data-dropdown]').each(function() {
                 'position': 'relative',
                 var dropdownId = $(this).attr('data-dropdown');
                 'visibility': 'visible'
                 var $dropdown = $('#' + dropdownId);
                 if ($dropdown.length) {
                    // Move the dropdown to body to ensure proper positioning
                    $dropdown.appendTo('body');
                }
             });
             });
         }
         }
     }, 100);
     }, 200); // Run after header is created
});
});


/* ===== REST OF YOUR EXISTING CODE BELOW ===== */
/* ===== REST OF YOUR EXISTING CODE BELOW ===== */
// Your radial menu code continues here...


/* ===== YOUR EXISTING RADIAL MENU CODE ===== */
/* ===== YOUR EXISTING RADIAL MENU CODE ===== */

Revision as of 04:53, 24 May 2025

/* ========================================
   MediaWiki:Common.js - Fixed Header Spacing
   ======================================== */

$(document).ready(function() {
    // HEADER FIX - Wait for page to load then force header
    setTimeout(function() {
        // Remove ALL existing headers and nav attempts
        $('.mw-header, #mw-header-container, nav.tab-bar, .tab-bar').remove();
        
        // Hide the page title and extra elements completely
        $('.firstHeading, h1.title, .mw-page-title-main, #firstHeading, #tagline, h3#tagline, #contentSub, .mw-content-subtitle').remove();
        
        // Create the navigation bar HTML with inline styles
        var headerHTML = `
            <div id="dune-header" style="position: fixed; top: 0; left: 0; right: 0; height: 60px; background: linear-gradient(180deg, rgba(20, 18, 28, 0.95) 0%, rgba(10, 8, 16, 0.98) 100%); border-bottom: 3px solid rgba(252, 231, 200, 0.4); box-shadow: 0 2px 20px rgba(0,0,0,0.8); z-index: 99999; display: flex; align-items: center;">
                <div class="dune-header-inner" style="width: 100%; max-width: 1600px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; height: 100%;">
                    <a href="/wiki/Main_Page" class="dune-logo" style="font-family: 'Orbitron', sans-serif; font-size: 22px; color: #fce7c8; text-transform: uppercase; letter-spacing: 3px; font-weight: 700; text-shadow: 0 0 15px rgba(252, 231, 200, 0.4); text-decoration: none; white-space: nowrap;">DUNE DB</a>
                    
                    <nav class="dune-nav" style="display: flex; gap: 0; margin: 0 20px; height: 100%;">
                        <a href="/wiki/Items" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-left: 1px solid rgba(252, 231, 200, 0.1); border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">◇ Items</a>
                        <a href="/wiki/Crafting" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">⚒ Crafting</a>
                        <a href="/wiki/Building" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">⌂ Building</a>
                        <a href="/wiki/Tech_Tree" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">⬢ Tech Tree</a>
                        <a href="/wiki/Journeys" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">➤ Journeys</a>
                        <a href="/wiki/Skills" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">★ Skills</a>
                        <a href="/wiki/Map" style="display: flex; align-items: center; padding: 0 18px; height: 100%; color: rgba(252, 231, 200, 0.8); font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.2px; text-decoration: none; border-right: 1px solid rgba(252, 231, 200, 0.1); transition: all 0.3s ease; background: transparent;" onmouseover="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.color='#fce7c8';" onmouseout="this.style.background='transparent'; this.style.color='rgba(252, 231, 200, 0.8)';">🗺 Map</a>
                    </nav>
                    
                    <div class="dune-search" style="display: flex; align-items: center;">
                        <form action="/index.php" method="get" style="display: flex; align-items: center; gap: 0;">
                            <input type="search" name="search" placeholder="Search wiki..." style="background: rgba(0, 0, 2, 0.8); border: 2px solid rgba(252, 231, 200, 0.3); border-radius: 0; color: #fce7c8; padding: 8px 12px; width: 200px; font-size: 13px; font-family: 'Rajdhani', sans-serif; transition: all 0.3s ease; outline: none;" onfocus="this.style.borderColor='#fce7c8'; this.style.boxShadow='0 0 10px rgba(252, 231, 200, 0.3)'; this.style.width='250px';" onblur="this.style.borderColor='rgba(252, 231, 200, 0.3)'; this.style.boxShadow='none'; this.style.width='200px';">
                            <button type="submit" style="background: rgba(252, 231, 200, 0.1); border: 2px solid rgba(252, 231, 200, 0.3); border-left: none; color: #fce7c8; padding: 8px 12px; cursor: pointer; font-size: 14px; transition: all 0.3s ease; height: 38px;" onmouseover="this.style.background='rgba(252, 231, 200, 0.2)'; this.style.borderColor='#fce7c8';" onmouseout="this.style.background='rgba(252, 231, 200, 0.1)'; this.style.borderColor='rgba(252, 231, 200, 0.3)';"><span>🔍</span></button>
                        </form>
                    </div>
                </div>
            </div>
        `;
        
        $('body').prepend(headerHTML);
        
        // CRITICAL: Force proper spacing
        $('body').css({
            'padding-top': '60px',
            'margin-top': '0'
        });
        
        // Remove ALL top spacing from content elements
        $('#content, .mw-body, #mw-content-text, .mw-body-content, .mw-parser-output, #main-section, .main-section, #page-content, #p-cactions').css({
            'padding-top': '0',
            'margin-top': '0'
        });
        
        // Force breadcrumb to be tight
        $('.dune-breadcrumb-nav').css({
            'margin-top': '0',
            'margin-bottom': '15px',
            'padding': '8px 12px'
        });
        
        // Force first element to start at top
        $('.mw-parser-output > *:first-child, .mw-body-content > *:first-child').css({
            'margin-top': '0',
            'padding-top': '0'
        });
        
        // Remove sidebar space
        $('#sidebar, .columns.large-2.medium-3').css('display', 'none');
        $('#page-content, .columns.large-10.medium-9').css({
            'width': '100%',
            'max-width': '100%',
            'margin': '0',
            'padding': '0'
        });
        
        // Handle Actions button area
        $('#p-cactions').css({
            'margin-bottom': '0',
            'padding-bottom': '0'
        });
        
        // Remove spacing from all column wrappers
        $('.row > .columns').css({
            'padding-top': '0',
            'margin-top': '0'
        });
        
    }, 100);
});

// MediaWiki Common.js - SAFER Actions Button Header Integration
// This version moves the actions button without breaking functionality
$(document).ready(function() {
    // Wait for header to be created
    setTimeout(function() {
        try {
            var $actions = $('#p-cactions');
            var $drop = $('#drop');
            var $headerInner = $('.dune-header-inner');
            var $search = $('.dune-search');
            
            // Only proceed if all elements exist
            if ($actions.length && $drop.length && $headerInner.length) {
                // Create wrapper for actions in header
                var $actionsWrapper = $('<div class="dune-header-actions" style="display: flex; align-items: center; margin-left: 10px;"></div>');
                
                // MOVE the actions (don't clone) to preserve functionality
                $actionsWrapper.append($actions);
                
                // Insert after search
                if ($search.length) {
                    $search.after($actionsWrapper);
                } else {
                    $headerInner.append($actionsWrapper);
                }
                
                // Reset positioning on the moved element
                $actions.css({
                    'position': 'static',
                    'top': 'auto',
                    'right': 'auto',
                    'margin': '0',
                    'padding': '0',
                    'display': 'block'
                });
                
                // Style the button
                $('#drop .button').css({
                    'height': '38px',
                    'margin': '0'
                });
                
                // Make sure actions are visible
                $actions.show();
            }
        } catch (e) {
            console.error('Error moving actions:', e);
            // Fallback: ensure actions are at least visible
            $('#p-cactions').css({
                'display': 'block',
                'position': 'relative',
                'visibility': 'visible'
            });
        }
    }, 200); // Run after header is created
});

/* ===== REST OF YOUR EXISTING CODE BELOW ===== */

/* ===== YOUR EXISTING RADIAL MENU CODE ===== */
function waitForRadialData(callback, attempts = 0) {
  const dataTag = document.getElementById('radialMenuData');
  if (dataTag) {
    try {
      const menuItems = JSON.parse(dataTag.innerText || dataTag.textContent);
      console.log("✅ Loaded radialMenuData:", menuItems);
      callback(menuItems);
    } catch (e) {
      console.error("❌ Failed to parse radialMenuData", e);
    }
  } else if (attempts < 20) {
    setTimeout(() => waitForRadialData(callback, attempts + 1), 100);
  } else {
    console.warn("⚠️ radialMenuData tag not found after timeout.");
  }
}

$(document).ready(function () {
  waitForRadialData(function (menuItems) {
    const isMobile = () => window.innerWidth <= 768;

    let radialItemsHTML = '';
    menuItems.forEach((item, index) => {
      const id = item.category.toLowerCase().replace(/\s+/g, '-');
      item.id = id;

      radialItemsHTML += `
        <div class="dune-radial-item-container ${item.position}">
          <a data-id="${id}" class="dune-radial-item">
            <img src="${item.icon}" alt="${item.name}" class="dune-radial-icon">
            <span class="dune-radial-tooltip">${item.name}</span>
          </a>
        </div>
      `;
    });

    const centerButtonHTML = `
      <a href="https://dunedb.com/Main_Page" class="dune-radial-center">
        <img src="https://dunedb.com/images/9/99/HomeNavIcon.png" alt="Home" class="dune-radial-icon">
        <span class="dune-radial-tooltip">Main Page</span>
      </a>
    `;

    const radialMenuHTML = `
      <div id="duneRadialMenu" class="dune-radial-menu">
        <div class="dune-radial-background">
          <div class="dune-radial-circle outer"></div>
          <div class="dune-radial-circle middle"></div>
          <div class="dune-radial-circle inner"></div>
        </div>
        ${centerButtonHTML}
        ${radialItemsHTML}
      </div>
      <div id="duneRadialOverlay" class="dune-radial-overlay"></div>
    `;

    const subcategoryContainerHTML = `<div id="duneSubcategoryContainer" class="dune-subcategory-container"></div>`;
    $('body').append(radialMenuHTML);
    $('body').append(subcategoryContainerHTML);

    if (isMobile()) {
      $('#duneRadialMenu').addClass('mobile-grid');
    }

    const showSubcategories = (itemId, event) => {
      const item = menuItems.find(i => i.id === itemId);
      if (!item || !item.subcategories) return;

      $('.dune-radial-item').removeClass('selected');
      $(`.dune-radial-item[data-id="${itemId}"]`).addClass('selected');

      let subcategoryHTML = `
        <div class="dune-subcategory-header">
          <img src="${item.icon}" alt="${item.name}" class="dune-subcategory-icon">
          <span>${item.name}</span>
        </div>
        <div class="dune-subcategory-items">
      `;

      item.subcategories.forEach((sub, index) => {
        subcategoryHTML += `
          <a href="${sub.url}" class="dune-subcategory-item" style="--item-index: ${index}">
            <span class="dune-subcategory-name">${sub.name}</span>
          </a>
        `;
      });

      subcategoryHTML += `
        </div>
        <div class="dune-subcategory-footer">
          <a href="${item.url}" class="dune-subcategory-all">View All ${item.name}</a>
        </div>
      `;

      const $subcategoryContainer = $('#duneSubcategoryContainer');
      $subcategoryContainer.html(subcategoryHTML);

      $subcategoryContainer.removeClass((index, className) => {
        return (className.match(/from-\S+/g) || []).join(' ');
      });
      $subcategoryContainer.addClass(`from-${item.position}`);
      $subcategoryContainer.addClass('active');

      event.stopPropagation();
    };

    const hideSubcategories = () => {
      $('#duneSubcategoryContainer').removeClass('active');
      $('.dune-radial-item').removeClass('selected');
    };

    const toggleRadialMenu = () => {
      if ($('#duneRadialMenu').hasClass('active')) {
        hideSubcategories();
        $('#duneRadialMenu').removeClass('active');
        $('#duneRadialOverlay').removeClass('active');
      } else {
        $('#duneRadialMenu').addClass('active');
        $('#duneRadialOverlay').addClass('active');
        $('.dune-radial-item-container').each(function (index) {
          const $item = $(this);
          setTimeout(() => {
            $item.addClass('animated');
          }, index * 50);
        });
        setTimeout(() => {
          $('.dune-radial-center').addClass('animated');
        }, menuItems.length * 50);
      }
    };

    $(document).on('click', '#duneLogoBtn, #menuRadialTrigger img', function (e) {
      console.log("✅ Radial trigger clicked");
      e.preventDefault();
      e.stopPropagation();
      toggleRadialMenu();
    });

    $(document).on('click', '.dune-radial-item', function (e) {
      e.preventDefault();
      e.stopPropagation();
      const itemId = $(this).data('id');
      if ($(this).hasClass('selected')) {
        hideSubcategories();
      } else {
        showSubcategories(itemId, e);
      }
    });

    $(document).on('click', '#duneRadialOverlay', function () {
      hideSubcategories();
      $('#duneRadialMenu').removeClass('active');
      $('#duneRadialOverlay').removeClass('active');
    });

    $(document).on('click', 'li.name.logo a[href="/Main_Page"]', function (e) {
      e.preventDefault();
      toggleRadialMenu();
    });

    $(document).on('keydown', function (e) {
      if (e.key === 'Escape') {
        if ($('#duneSubcategoryContainer').hasClass('active')) {
          hideSubcategories();
        } else if ($('#duneRadialMenu').hasClass('active')) {
          $('#duneRadialMenu').removeClass('active');
          $('#duneRadialOverlay').removeClass('active');
        }
      }
    });

    $(window).on('resize', function () {
      if (isMobile()) {
        $('#duneRadialMenu').addClass('mobile-grid');
      } else {
        $('#duneRadialMenu').removeClass('mobile-grid');
      }
    });
  });
});

/* Used-In dynamic filters & search */
mw.hook( 'wikipage.content' ).add( function ( $content ) {

  const $holder = $content.find( '#usedInFilterHolder' );
  const $table  = $content.find( '#usedInTable' );

  if ( !$holder.length || !$table.length ) return;

  const rowsData = [];
  const stations = new Set();
  const types    = new Set();

  $table.find( 'tbody tr' ).each( function () {
    const $tds     = $( this ).children( 'td' );
    const output   = $tds.eq( 0 ).text().trim();
    const type     = $tds.eq( 1 ).text().trim();
    const station  = $tds.last().text().trim();

    rowsData.push( { tr: this, output, type, station } );
    stations.add( station );
    types.add( type );
  } );

  const makeSel = ( id, label, opts ) => {
    const $sel = $( '<select>', { id, class: 'game-button', css:{margin:'6px 4px 6px 0'} } )
                  .append( $( '<option>', { value:'', text:label } ) );
    opts.forEach( o => $sel.append( $( '<option>', { value:o, text:o } ) ) );
    return $sel;
  };

  const $stationSel = makeSel( 'filterStation', 'All Stations', [ ...stations ].sort() );
  const $typeSel    = makeSel( 'filterType',    'All Types',    [ ...types ].sort() );
  const $search     = $( '<input>', {
                          type:'text',
                          placeholder:'Search…',
                          css:{ margin:'6px 0', padding:'4px', width:'140px',
                               'background':'#111', color:'#fff', border:'1px solid #555' }
                        } );

  $holder.append( $stationSel, $typeSel, $search );

  function applyFilters() {
    const sVal = $stationSel.val();
    const tVal = $typeSel.val();
    const q    = $search.val().toLowerCase();

    rowsData.forEach( ({ tr, output, type, station }) => {
      const show =
        (!sVal || station === sVal) &&
        (!tVal || type    === tVal) &&
        (!q    || output.toLowerCase().includes( q ));
      tr.style.display = show ? '' : 'none';
    } );
  }

  $stationSel.on( 'change', applyFilters );
  $typeSel   .on( 'change', applyFilters );
  $search    .on( 'input',  applyFilters );
} );

/* Lazy-load background image Blur */
document.addEventListener('DOMContentLoaded', () => {
  const hero = document.querySelector('.dune-hero');
  if (hero && !hero.style.backgroundImage) {
    hero.style.backgroundImage =
      'url(/images/7/70/Arrakis_dunes.jpg?2025)';
  }

  const radial = document.querySelector('.radial-menu-wrapper');
  if (!radial) return;
  const y = radial.offsetTop;
  window.addEventListener('scroll', () => {
    radial.classList.toggle('is-fixed', window.scrollY > y);
  });
});