Ranked War Cache Rewards Value

Calculate and display ranked war cache reward values with % of total reward split, custom pricing, API integration, PDA support, and other rewards (points/respect). Features automatic theme detection and multiple trader configurations.

// ==UserScript==
// @name         Ranked War Cache Rewards Value
// @namespace    http://tampermonkey.net/
// @version      3.1
// @description  Calculate and display ranked war cache reward values with % of total reward split, custom pricing, API integration, PDA support, and other rewards (points/respect). Features automatic theme detection and multiple trader configurations.
// @author       Mistborn [3037268]
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @match        https://www.torn.com/war.php?step=rankreport*
// @run-at       document-start
// @grant        GM.xmlHttpRequest
// @grant        none
// @connect      api.torn.com
// @supportURL   https://github.com/MistbornTC/ranked-war-cache-rewards/issues
// @license      MIT
// @credits      Inspired by bot_7420 [2937420]
// ==/UserScript==

// PDA API Key placeholder - MUST be at global scope for PDA replacement
const PDA_API_KEY = '###PDA-APIKEY###';

// PDA API URLs - complete strings for PDA to process
const PDA_USER_API_URL = 'https://api.torn.com/user/?selections=basic&key=###PDA-APIKEY###';
const PDA_ITEMS_API_URL = 'https://api.torn.com/torn/?selections=items&key=###PDA-APIKEY###';
const PDA_POINTS_API_URL = 'https://api.torn.com/torn/?selections=pointsmarket&key=###PDA-APIKEY###';

(function () {
    "use strict";
    console.log("RWAwardValue: Script starting v3.1");

    // Enhanced PDA detection
    function isTornPDA() {
        const userAgentCheck = navigator.userAgent.includes('com.manuito.tornpda');
        const flutterCheck = !!window.flutter_inappwebview;
        const platformCheck = !!window.__PDA_platformReadyPromise;
        const httpCheck = !!window.PDA_httpGet;
        const result = !!(userAgentCheck || flutterCheck || platformCheck || httpCheck);
        console.log('RW: PDA Detection:', result, {
            userAgent: userAgentCheck,
            flutter: flutterCheck,
            platform: platformCheck,
            httpGet: httpCheck
        });
        return result;
    }

    // Configure PDA session
    const PDA_MODE = isTornPDA();
    console.log('RW: PDA Mode:', PDA_MODE);

    // ========================================
    // GLOBAL VARIABLES & SETTINGS
    // ========================================

    // User's API key and validation status
    let API_KEY = 'YOUR_API_KEY_HERE';
    let API_USERNAME = ''; // Username from successful API validation
    let PDA_VALIDATED = false; // Whether PDA mobile app API is working
    let SETTINGS = {
        showApiValues: false,
        showIndirectRewards: false,
        showCustomPrices: false,
        respectValue: 20000
    };

    // Cache API prices with timestamp to avoid repeated calls
    let apiPriceCache = {
        lastFetched: null,
        data: {}
    };

    // Debug mode - window.rwDebugMode = true/false
    let DEBUG_MODE = localStorage.getItem('rw_debug_mode') === 'true';

    Object.defineProperty(window, 'rwDebugMode', {
        get() { return DEBUG_MODE; },
        set(value) {
            DEBUG_MODE = !!value;
            localStorage.setItem('rw_debug_mode', DEBUG_MODE.toString());
            console.log('RW: Debug mode', DEBUG_MODE ? 'ENABLED' : 'DISABLED');
        }
    });

    // Custom seller prices (up to 10 different sellers) - declared before loadSettings
    let sellerData = {
        activeSeller: 0,
        sellers: [
            { name: "Trader 1", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 2", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 3", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 4", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 5", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 6", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 7", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 8", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 9", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
            { name: "Trader 10", pricingMode: "fixed", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } }
        ]
    };

    // Working data for calculations
    let marketValueMap = new Map();        // Live market prices from API
    let pointMarketValue = 0;              // Current points market rate
    let currentTheme = getTheme();         // Track dark/light mode
    let rewardData = [];                   // Processed reward data
    let rawRewardData = [];               // Original data for recalculation

    // ========================================
    // THEME DETECTION & MONITORING
    // ========================================

    // Watch for theme changes and update UI automatically
    function monitorThemeChanges() {
        // Set up listener to detect when user switches between dark/light mode
        const observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                if (mutation.type === 'attributes' &&
                    (mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
                    const newTheme = getTheme();
                    if (newTheme !== currentTheme) {
                        console.log('RW: Theme changed from', currentTheme, 'to', newTheme);
                        currentTheme = newTheme;
                        updateAllUIForTheme();
                    }
                }
            });
        });

        // Start observing body for class and style changes
        if (document.body) {
            observer.observe(document.body, {
                attributes: true,
                attributeFilter: ['class', 'style']
            });
        }
    }

    // Refresh all UI elements when theme changes
    function updateAllUIForTheme() {
        console.log('RW: Updating all UI elements for theme:', currentTheme);

        // Refresh the main reward display
        if (typeof refreshRewardDisplay === 'function') {
            refreshRewardDisplay();
        }

        // Update any open configuration panels by refreshing their styles
        const pricePanel = document.getElementById('rw-price-panel');
        const settingsPanel = document.getElementById('rw-settings-panel');

        if (pricePanel && pricePanel.style.maxHeight !== '0px') {
            console.log('RW: Refreshing price panel colors for new theme');
            // Close and reopen the price panel to apply new theme
            const priceButton = document.getElementById('rw-price-btn-header');
            if (priceButton) {
                priceButton.click(); // Close
                setTimeout(() => priceButton.click(), 50); // Reopen with new theme
            }
        }

        if (settingsPanel && settingsPanel.style.maxHeight !== '0px') {
            console.log('RW: Refreshing settings panel colors for new theme');
            // Close and reopen the settings panel to apply new theme
            const settingsButton = document.getElementById('rw-settings-btn-header');
            if (settingsButton) {
                settingsButton.click(); // Close
                setTimeout(() => settingsButton.click(), 50); // Reopen with new theme
            }
        }
    }

    // ========================================
    // UTILITY/HELPER FUNCTIONS
    // ========================================
    function isMobile() {
        const width = window.innerWidth;
        const isMobileWidth = width <= 768;
        console.log('RW: Mobile detection - width:', width, 'isMobile:', isMobileWidth);
        return isMobileWidth;
    }

    // Mobile-safe arrow function using HTML entities
    function getMobileArrow(isPositive) {
        // Use HTML entities that work reliably across all platforms
        return isPositive ? '&#9650;' : '&#9660;'; // ▲ ▼ as HTML entities
    }

    // Mobile-safe expand arrow using HTML entities
    function getExpandArrow(isExpanded) {
        // Use HTML entities for consistent rendering
        return isExpanded ? '&#9650;' : '&#9660;'; // ▲ ▼ as HTML entities
    }

    function getTheme() {
        // Wait for body to exist
        if (!document.body) {
            return 'dark'; // Default fallback
        }
        const body = document.body;
        const isDarkMode = body.classList.contains('dark-mode') ||
                          body.classList.contains('dark') ||
                          body.style.background.includes('#191919') ||
                          getComputedStyle(body).backgroundColor === 'rgb(25, 25, 25)';
        return isDarkMode ? 'dark' : 'light';
    }

    function getThemeColors() {
        const theme = getTheme();
        if (theme === 'dark') {
            return {
                panelBg: '#2a2a2a',
                panelBorder: '#444',
                statBoxBg: '#3a3a3a',
                statBoxBorder: '#444',
                statBoxShadow: '0 1px 3px rgba(0,0,0,0.1)',
                textPrimary: '#fff',
                textSecondary: '#ccc',
                textMuted: '#999',
                success: '#5cb85c',
                danger: '#d9534f',
                primary: 'rgb(116, 192, 252)',
                configBg: '#333',
                configBorder: '#555',
                inputBg: '#444',
                inputBorder: '#555'
            };
        } else {
            return {
                panelBg: '#eeeeee',
                panelBorder: 'rgba(102, 102, 102, 0.3)',
                statBoxBg: '#ffffff',
                statBoxBorder: 'rgba(102, 102, 102, 0.3)',
                statBoxShadow: 'rgba(50, 50, 50, 0.2) 0px 0px 2px 0px',
                textPrimary: '#212529',
                textSecondary: '#212529',
                textMuted: '#666',
                success: 'rgb(105, 168, 41)',
                danger: '#dc3545',
                primary: '#0092d8',
                configBg: '#ffffff',
                configBorder: '#ced4da',
                inputBg: '#ffffff',
                inputBorder: '#ced4da'
            };
        }
    }

    // Format number with commas
    function formatNumberWithCommas(num) {
        if (num === 0) return '0';
        return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

    // Parse number from comma-formatted string
    function parseCommaNumber(str) {
        return parseInt(str.replace(/,/g, '')) || 0;
    }

    // Detect ranking outcome from faction name for winner/loser determination
    function detectRankingOutcome(factionName) {
        if (!factionName || typeof factionName !== 'string') {
            return null; // Cannot determine
        }

        const lowerName = factionName.toLowerCase();
        if (lowerName.includes('ranked down')) {
            return 'loser';
        } else if (lowerName.includes('ranked up') || lowerName.includes('remained at')) {
            return 'winner';
        }

        return null; // Cannot determine
    }

    // Create dismissible info box for when no pricing is available
    function createNoPricingInfoBox() {
        const colors = getThemeColors();
        const mobile = isMobile();

        const infoBox = document.createElement('div');
        infoBox.id = 'rw-no-pricing-info';
        infoBox.style.cssText = `
            background: ${colors.statBoxBg};
            border: 1px solid ${colors.primary};
            border-radius: 6px;
            padding: ${mobile ? '12px' : '16px'};
            margin: 15px 0;
            position: relative;
            box-shadow: ${colors.statBoxShadow};
        `;

        // Close button (X)
        const closeButton = document.createElement('span');
        closeButton.style.cssText = `
            position: absolute;
            top: 8px;
            right: 12px;
            font-size: 18px;
            font-weight: bold;
            color: ${colors.textMuted};
            cursor: pointer;
            user-select: none;
            line-height: 1;
        `;
        closeButton.innerHTML = mobile ? '&#215;' : '×';
        closeButton.title = 'Dismiss this message';

        // Close functionality
        closeButton.addEventListener('click', function() {
            infoBox.remove();
            // Remember dismissal
            if (typeof(Storage) !== "undefined") {
                localStorage.setItem('rw_no_pricing_info_dismissed', 'true');
            }
        });

        // Info content
        const content = document.createElement('div');
        content.style.cssText = `
            color: ${colors.textPrimary};
            font-size: ${mobile ? '11px' : '12px'};
            line-height: 1.4;
        `;

        // Title
        const title = document.createElement('div');
        title.style.cssText = `
            font-weight: bold;
            margin-bottom: 8px;
            color: ${colors.primary};
            font-size: ${mobile ? '13px' : '14px'};
        `;
        title.textContent = 'No Pricing Configured';

        // Message content container
        const message = document.createElement('div');

        // Description text
        const description = document.createElement('div');
        description.style.marginBottom = '8px';
        description.textContent = 'Cache reward values are not being calculated as no pricing sources are configured.';

        // "To see reward values:" text
        const instructionHeader = document.createElement('div');
        instructionHeader.style.cssText = `font-weight: bold; margin-bottom: 4px;`;
        instructionHeader.textContent = 'To see reward values:';

        // Bullet points container
        const bulletPoints = document.createElement('div');

        // First bullet point - Price List
        const bullet1 = document.createElement('div');
        bullet1.style.marginBottom = '2px';
        bullet1.innerHTML = (mobile ? '&#8226; ' : '• ') + 'Configure custom prices using ';

        const priceListLink = document.createElement('span');
        priceListLink.textContent = 'Price List';
        priceListLink.style.cssText = `
            color: ${colors.primary};
        `;

        bullet1.appendChild(priceListLink);
        bullet1.innerHTML += ', and/or';

        // Second bullet point - Settings
        const bullet2 = document.createElement('div');
        bullet2.innerHTML = (mobile ? '&#8226; ' : '• ') + 'Enable market values in ';

        const settingsLink = document.createElement('span');
        settingsLink.textContent = 'Settings';
        settingsLink.style.cssText = `
            color: ${colors.primary};
        `;

        bullet2.appendChild(settingsLink);
        bullet2.innerHTML += ' (Public API key)';

        bulletPoints.appendChild(bullet1);
        bulletPoints.appendChild(bullet2);

        message.appendChild(description);
        message.appendChild(instructionHeader);
        message.appendChild(bulletPoints);

        content.appendChild(title);
        content.appendChild(message);
        infoBox.appendChild(closeButton);
        infoBox.appendChild(content);

        return infoBox;
    }

    // Check if no pricing info box should be shown
    function shouldShowNoPricingInfo() {
        // Don't show if user has dismissed it
        if (typeof(Storage) !== "undefined") {
            const dismissed = localStorage.getItem('rw_no_pricing_info_dismissed');
            if (dismissed === 'true') {
                return false;
            }
        }

        // Show if no valid API key AND no custom prices configured
        const hasValidApiKey = (API_KEY && API_KEY !== 'YOUR_API_KEY_HERE') || PDA_VALIDATED;
        const hasCustomPrices = SETTINGS.showCustomPrices && sellerData.sellers.some(seller =>
            Object.values(seller.prices).some(price => price > 0)
        );

        // Hide info box if user has either a valid API key OR configured custom prices
        return !hasValidApiKey && !hasCustomPrices;
    }

    // ========================================
    // SETTINGS & DATA PERSISTENCE
    // ========================================

    // Load settings from browser storage
    function loadSettings() {
        if (typeof(Storage) !== "undefined") {
            const saved = localStorage.getItem('rw_cache_settings');
            if (saved) {
                try {
                    SETTINGS = Object.assign(SETTINGS, JSON.parse(saved));
                } catch (e) {
                    console.log('RW: Could not load settings');
                }
            }

            const savedKey = localStorage.getItem('rw_api_key');
            if (savedKey) {
                API_KEY = savedKey;
            }

            const savedUsername = localStorage.getItem('rw_api_username');
            if (savedUsername) {
                API_USERNAME = savedUsername;
                console.log('RW: Loaded username from localStorage:', API_USERNAME);
            }

            const savedPdaValidated = localStorage.getItem('rw_pda_validated');
            if (savedPdaValidated === 'true') {
                PDA_VALIDATED = true;
                console.log('RW: PDA State Transition - Loaded validated state from localStorage');
                console.log('RW: PDA State - Mode:', PDA_MODE, 'Validated:', PDA_VALIDATED, 'Username:', API_USERNAME);
            } else {
                console.log('RW: PDA State - No validation flag in localStorage, PDA_MODE:', PDA_MODE);
            }

            // Load API price cache from localStorage
            const savedApiCache = localStorage.getItem('rw_api_price_cache');
            if (savedApiCache) {
                try {
                    apiPriceCache = JSON.parse(savedApiCache);
                    console.log('RW: Loaded API price cache from localStorage:', apiPriceCache);
                } catch (e) {
                    console.log('RW: Could not load API price cache from localStorage');
                }
            }

            // Load seller data with migration support
            const savedSellers = localStorage.getItem('rw_seller_data');
            if (savedSellers) {
                try {
                    const parsed = JSON.parse(savedSellers);
                    if (parsed && parsed.sellers && Array.isArray(parsed.sellers)) {
                        sellerData = parsed;


                        console.log('RW: Loaded seller data:', sellerData);
                    }
                } catch (e) {
                    console.log('RW: Could not load seller data, using defaults');
                }
            }
        }
    }

    // Save settings to localStorage
    function saveSettings() {
        if (typeof(Storage) !== "undefined") {
            localStorage.setItem('rw_cache_settings', JSON.stringify(SETTINGS));
            if (API_KEY !== 'YOUR_API_KEY_HERE') {
                localStorage.setItem('rw_api_key', API_KEY);
            }
            if (API_USERNAME) {
                localStorage.setItem('rw_api_username', API_USERNAME);
                console.log('RW: Saved username to localStorage:', API_USERNAME);
            }
            if (PDA_VALIDATED) {
                localStorage.setItem('rw_pda_validated', 'true');
                console.log('RW: PDA State Transition - Saved validated state to localStorage');
                console.log('RW: PDA State - Mode:', PDA_MODE, 'Validated:', PDA_VALIDATED, 'Username:', API_USERNAME);
            } else if (PDA_MODE) {
                // Clear the flag if PDA mode but not validated
                localStorage.removeItem('rw_pda_validated');
                console.log('RW: PDA State Transition - Cleared validation flag from localStorage');
            }
            // Save seller data
            localStorage.setItem('rw_seller_data', JSON.stringify(sellerData));
            console.log('RW: Saved seller data to localStorage');

            // Clear no-pricing info dismissal if pricing is now configured
            const hasApiValues = SETTINGS.showApiValues && apiPriceCache.data && Object.keys(apiPriceCache.data).length > 0;
            const hasCustomPrices = SETTINGS.showCustomPrices && sellerData.sellers.some(seller =>
                Object.values(seller.prices).some(price => price > 0)
            );
            if (hasApiValues || hasCustomPrices) {
                localStorage.removeItem('rw_no_pricing_info_dismissed');
            }
        }
    }

    // PDA reconnection logic - attempt to restore lost validation state
    async function attemptPdaReconnection() {
        if (!PDA_MODE) return;

        // If we have a username but no validation flag, try to reconnect
        if (API_USERNAME && !PDA_VALIDATED) {
            console.log('RW: PDA Reconnection - Attempting to restore validation for user:', API_USERNAME);
            try {
                const testResult = await testApiKey('');
                if (testResult.success && testResult.isPDA && testResult.name === API_USERNAME) {
                    console.log('RW: PDA Reconnection - Successfully restored validation');
                    PDA_VALIDATED = true;
                    saveSettings();
                } else {
                    console.log('RW: PDA Reconnection - Failed to restore validation');
                }
            } catch (error) {
                console.log('RW: PDA Reconnection - Error during reconnection attempt:', error);
            }
        }
    }

    // Initialize settings - LOAD FIRST BEFORE ANYTHING ELSE
    loadSettings();
    console.log('RW: Loaded settings - Active seller:', sellerData.activeSeller, 'Seller name:', sellerData.sellers[sellerData.activeSeller].name);

    // Attempt PDA reconnection if needed
    if (PDA_MODE && API_USERNAME && !PDA_VALIDATED) {
        console.log('RW: Detected potential PDA reconnection scenario');
        attemptPdaReconnection();
    }

    // Get current seller's custom price for an item
    function getCustomPrice(cacheType) {
        const seller = sellerData.sellers[sellerData.activeSeller];
        const priceValue = seller.prices[cacheType] || 0;

        if (priceValue === 0) return 0;

        // Handle relative pricing mode
        if (seller.pricingMode === 'relative') {
            // Calculate actual price from percentage of API price
            if (apiPriceCache.data && apiPriceCache.data[cacheType]) {
                const apiPrice = apiPriceCache.data[cacheType];
                const calculatedPrice = Math.round(apiPrice * (priceValue / 100));
                console.log(`RW: Relative pricing - ${cacheType}: ${priceValue}% of ${apiPrice} = ${calculatedPrice}`);
                return calculatedPrice;
            } else {
                // No API price available for calculation
                console.log(`RW: Relative pricing - ${cacheType}: No API price available for ${priceValue}%`);
                return 0;
            }
        } else {
            // Fixed pricing mode - return as-is
            return priceValue;
        }
    }

    // Check if API cache needs refreshing based on GMT timing
    function shouldRefreshApiCache() {
        if (!apiPriceCache.lastFetched) return true; // No cache

        const lastFetch = new Date(apiPriceCache.lastFetched);
        const now = new Date();

        // Convert both to UTC for GMT comparison
        const lastFetchUTC = new Date(lastFetch.getUTCFullYear(), lastFetch.getUTCMonth(), lastFetch.getUTCDate(), lastFetch.getUTCHours());
        const nowUTC = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours());

        // Different dates = definitely refresh
        if (lastFetchUTC.getUTCDate() !== nowUTC.getUTCDate() ||
            lastFetchUTC.getUTCMonth() !== nowUTC.getUTCMonth() ||
            lastFetchUTC.getUTCFullYear() !== nowUTC.getUTCFullYear()) {
            return true;
        }

        // Same date: check 3am GMT rule
        const lastHour = lastFetchUTC.getUTCHours();
        const nowHour = nowUTC.getUTCHours();

        return (lastHour < 3 && nowHour >= 3); // Was before 3am GMT, now after
    }

    // Function to update API price cache
    async function updateApiPriceCache(forceRefresh = false) {
        const currentApiKey = getApiKey();

        if (!currentApiKey || currentApiKey === 'YOUR_API_KEY_HERE') return false;

        // Check if we need to refresh the cache (skip check if forced)
        if (!forceRefresh && !shouldRefreshApiCache()) {
            console.log('RW: Using cached API prices (still fresh)');
            return true; // We have fresh data
        }

        console.log('RW: Cache expired or missing, fetching fresh API prices...');

        try {
            const result = await fetchApiPrices();
            if (result.success) {
                // Store with timestamp
                apiPriceCache = {
                    lastFetched: new Date().toISOString(),
                    data: result.prices
                };

                // Save to localStorage for persistence across page refreshes
                if (typeof(Storage) !== "undefined") {
                    localStorage.setItem('rw_api_price_cache', JSON.stringify(apiPriceCache));
                    console.log('RW: Saved API price cache to localStorage');
                }

                console.log('RW: Updated API price cache:', apiPriceCache);
                return true;
            } else {
                console.warn('RW: Failed to fetch API prices:', result.error);
                return false;
            }
        } catch (error) {
            console.error('RW: Error updating API cache:', error);
            return false;
        }
    }

    // ========================================
    // API INTEGRATION & REQUESTS
    // ========================================

    // Handle API requests - works with both browser and PDA mobile app
    function makeApiRequest(url, options = {}) {
        return new Promise(async function(resolve) {
            const timeout = options.timeout || 10000;

            if (PDA_MODE && typeof window.PDA_httpGet === 'function') {
                if (DEBUG_MODE) console.log('RW: Using PDA API request for:', url);
                console.log('RW: Using PDA API request');
                try {
                    // Set up timeout for PDA requests
                    const timeoutId = setTimeout(function() {
                        console.error('RW: PDA API request timeout');
                        resolve({ success: false, error: 'PDA API request timed out. Please check your connection and try again.' });
                    }, timeout);

                    // PDA_httpGet returns a Promise, not a callback
                    const response = await window.PDA_httpGet(url);
                    clearTimeout(timeoutId);

                    console.log('RW: PDA API response received:', response);

                    try {
                        let data;
                        if (typeof response.responseText === 'string') {
                            data = JSON.parse(response.responseText);
                        } else if (typeof response.responseText === 'object' && response.responseText !== null) {
                            data = response.responseText;
                        } else {
                            console.error('RW: Unexpected PDA response format:', response);
                            resolve({ success: false, error: 'PDA API response format error. Please ensure your API key is connected to PDA.' });
                            return;
                        }

                        console.log('RW: PDA API parsed data:', data);
                        resolve({ success: true, data: data });
                    } catch (error) {
                        console.error('RW: PDA API response parse error:', error);
                        resolve({ success: false, error: 'PDA API response could not be parsed. Please check your PDA API connection.' });
                    }
                } catch (error) {
                    console.error('RW: PDA API request error:', error);
                    resolve({ success: false, error: 'PDA API request failed. Please ensure your API key is properly connected to PDA and try again.' });
                }
            } else {
                // Check if GM.xmlHttpRequest is available, otherwise use fetch
                if (typeof GM !== 'undefined' && typeof GM.xmlHttpRequest === 'function') {
                    if (DEBUG_MODE) console.log('RW: Using GM API request for:', url);
                    console.log('RW: Using GM API request');
                    GM.xmlHttpRequest({
                        method: 'GET',
                        url: url,
                        timeout: timeout,
                        onload: function(response) {
                            try {
                                const data = JSON.parse(response.responseText);
                                resolve({ success: true, data: data });
                            } catch (error) {
                                resolve({ success: false, error: 'Invalid response from API' });
                            }
                        },
                        onerror: function() {
                            resolve({ success: false, error: 'Network error' });
                        },
                        ontimeout: function() {
                            resolve({ success: false, error: 'Request timed out' });
                        }
                    });
                } else {
                    // Fallback to fetch API
                    console.log('RW: GM not available, using fetch API');

                    const controller = new AbortController();
                    const timeoutId = setTimeout(() => controller.abort(), timeout);

                    fetch(url, {
                        signal: controller.signal,
                        method: 'GET'
                    })
                    .then(response => {
                        clearTimeout(timeoutId);
                        if (!response.ok) {
                            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                        }
                        return response.json();
                    })
                    .then(data => {
                        resolve({ success: true, data: data });
                    })
                    .catch(error => {
                        clearTimeout(timeoutId);
                        if (error.name === 'AbortError') {
                            resolve({ success: false, error: 'Request timed out' });
                        } else {
                            resolve({ success: false, error: error.message || 'Network error' });
                        }
                    });
                }
            }
        });
    }

    // Get the appropriate API key for requests
    function getApiKey() {
        if (PDA_MODE && (!API_KEY || API_KEY === 'YOUR_API_KEY_HERE')) {
            return '###PDA-APIKEY###'; // Direct placeholder for PDA replacement
        }
        return API_KEY;
    }

    async function testApiKey(apiKey) {
        return new Promise(async function(resolve) {
            // Handle PDA mode with empty API key
            if (PDA_MODE && (!apiKey || apiKey === 'YOUR_API_KEY_HERE')) {
                console.log('RW: Testing PDA API key');
                // Use the complete URL constant that PDA should have processed
                const url = PDA_USER_API_URL;
                if (DEBUG_MODE) console.log('RW: PDA API URL (key should be replaced):', url);

                try {
                    const result = await makeApiRequest(url, { timeout: 15000 });
                    console.log('RW: PDA API test result:', result);

                    if (result.success) {
                        if (result.data.error) {
                            console.log('RW: PDA API returned error:', result.data.error);
                            let errorMsg = result.data.error.error;
                            if (errorMsg.includes('Incorrect API key')) {
                                errorMsg = 'API key not connected to PDA. Please connect your API key in PDA settings first.';
                            }
                            resolve({ success: false, error: errorMsg });
                        } else {
                            console.log('RW: PDA API test successful:', result.data.name);
                            resolve({ success: true, name: result.data.name, isPDA: true });
                        }
                    } else {
                        console.log('RW: PDA API request failed:', result.error);
                        resolve({ success: false, error: 'PDA connection failed: ' + result.error });
                    }
                } catch (error) {
                    console.error('RW: PDA API test exception:', error);
                    resolve({ success: false, error: 'PDA API validation failed. Please ensure PDA is properly configured with your API key.' });
                }
                return;
            }

            // Standard API key validation
            if (!apiKey || apiKey === 'YOUR_API_KEY_HERE') {
                resolve({ success: false, error: 'No API key provided' });
                return;
            }

            const url = 'https://api.torn.com/user/?selections=basic&key=' + apiKey;
            const result = await makeApiRequest(url, { timeout: 10000 });

            if (result.success) {
                if (result.data.error) {
                    resolve({ success: false, error: result.data.error.error });
                } else {
                    resolve({ success: true, name: result.data.name, isPDA: false });
                }
            } else {
                resolve({ success: false, error: result.error });
            }
        });
    }

    async function fetchApiPrices() {
        return new Promise(async function(resolve) {
            let currentApiKey;
            if (PDA_MODE && (!API_KEY || API_KEY === 'YOUR_API_KEY_HERE')) {
                currentApiKey = '###PDA-APIKEY###'; // Direct placeholder for PDA
            } else {
                currentApiKey = API_KEY;
            }

            if (!currentApiKey || currentApiKey === 'YOUR_API_KEY_HERE') {
                resolve({ success: false, error: 'No API key configured' });
                return;
            }

            // Correct cache item IDs
            const cacheItems = {
                armorCache: '1118',       // Armor Cache
                meleeCache: '1119',       // Melee Cache
                smallArmsCache: '1120',   // Small Arms Cache
                mediumArmsCache: '1121',  // Medium Arms Cache
                heavyArmsCache: '1122'    // Heavy Arms Cache
            };

            const url = 'https://api.torn.com/torn/?selections=items&key=' + currentApiKey;
            const result = await makeApiRequest(url, { timeout: 15000 });

            if (result.success) {
                if (result.data.error) {
                    resolve({ success: false, error: result.data.error.error });
                } else {
                    const prices = {};
                    Object.keys(cacheItems).forEach(function(key) {
                        const itemId = cacheItems[key];
                        const item = result.data.items[itemId];
                        if (item && item.market_value) {
                            prices[key] = item.market_value;
                        }
                    });

                    console.log('RW: Cache prices from API:', prices);
                    resolve({ success: true, prices: prices });
                }
            } else {
                resolve({ success: false, error: result.error });
            }
        });
    }

    async function fetchPointValue() {
        return new Promise(async function(resolve) {
            let currentApiKey;
            if (PDA_MODE && (!API_KEY || API_KEY === 'YOUR_API_KEY_HERE')) {
                currentApiKey = '###PDA-APIKEY###'; // Direct placeholder for PDA
            } else {
                currentApiKey = API_KEY;
            }

            if (!currentApiKey || currentApiKey === 'YOUR_API_KEY_HERE') {
                resolve(31300); // Default mock value
                return;
            }

            const url = 'https://api.torn.com/torn/?selections=pointsmarket&key=' + currentApiKey;
            const result = await makeApiRequest(url, { timeout: 10000 });

            if (result.success) {
                if (result.data.error) {
                    console.warn('RW: Could not fetch point value:', result.data.error.error);
                    resolve(31300); // Fallback
                } else {
                    const pointValue = result.data.pointsmarket ? result.data.pointsmarket.cost : 31300;
                    resolve(pointValue);
                }
            } else {
                console.warn('RW: Point value API error:', result.error);
                resolve(31300); // Fallback
            }
        });
    }

    function numberFormatter(num, digits) {
        digits = digits || 1;
        const lookup = [
            { value: 1, symbol: "" },
            { value: 1e3, symbol: "k" },
            { value: 1e6, symbol: "M" },
            { value: 1e9, symbol: "B" },
        ];
        const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
        var item = lookup
            .slice()
            .reverse()
            .find(function (item) {
                return num >= item.value;
            });
        return item ? (num / item.value).toFixed(digits).replace(rx, "$1") + item.symbol : "0";
    }

    // Helper function to extract user ID from seller name
    function extractUserInfo(sellerName) {
        const match = sellerName.match(/^(.+?)\s*\[(\d+)\]$/);
        if (match) {
            return {
                name: match[1].trim(),
                id: match[2],
                hasId: true
            };
        }
        return {
            name: sellerName.trim(),
            id: null,
            hasId: false
        };
    }

    // Helper function to create profile link
    function createProfileLink(userId, colors) {
        const link = document.createElement('a');
        link.href = 'https://www.torn.com/profiles.php?XID=' + userId;
        link.target = '_blank';
        link.style.cssText = 'margin-left: 4px; color: ' + colors.primary + '; text-decoration: none; font-size: 12px;';

        // Use HTML entity for mobile compatibility
        if (isMobile()) {
            link.innerHTML = '&#128279;';
        } else {
            link.innerHTML = '🔗';
        }

        link.title = 'View profile [' + userId + ']';
        return link;
    }

    // ========================================
    // MAIN UI CREATION & DISPLAY
    // ========================================

    // Add control buttons to the page header (run only once)
    function addIconsToTopHeader() {
        const colors = getThemeColors();

        // Find the "Ranked War # header
        const titleHeader = document.querySelector('.title-black.m-top10.top-round') ||
                           document.querySelector('.title-black') ||
                           document.querySelector('[class*="title"]');

        if (!titleHeader) {
            console.log("RWAwardValue: Could not find title header for icons");
            return;
        }

        // Check if we already added buttons to avoid duplicates
        if (titleHeader.querySelector('#rw-price-btn-header')) {
            console.log("RWAwardValue: Header buttons already exist, skipping");
            return;
        }

        console.log("RWAwardValue: Adding icons to top header");

        // Make the header a flex container with proper alignment
        titleHeader.style.display = 'flex';
        titleHeader.style.justifyContent = 'space-between';
        titleHeader.style.alignItems = 'center';
        titleHeader.style.paddingLeft = titleHeader.style.paddingLeft || '15px';
        titleHeader.style.paddingRight = '15px';
        titleHeader.style.boxSizing = 'border-box';

        // Create button container with proper vertical alignment
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'display: flex; align-items: center; height: 100%; margin-left: auto;';

        // Price list button with text instead of icon
        const priceButton = document.createElement('button');
        priceButton.id = 'rw-price-btn-header';
        priceButton.textContent = 'Price List';
        priceButton.title = 'Manage Cache Prices';
        priceButton.style.cssText = 'background: transparent; color: rgba(255, 255, 255, 0.8); border: none; padding: 8px 12px; border-radius: 3px; cursor: pointer; font-size: 1em; font-weight: normal; transition: color 0.2s ease; line-height: 1; min-height: 32px;';

        // Separator
        const separator = document.createElement('span');
        separator.textContent = ' | ';
        separator.style.cssText = 'color: rgba(255, 255, 255, 0.5); font-size: 1em; margin: 0 4px;';

        // Settings button with text instead of icon
        const settingsButton = document.createElement('button');
        settingsButton.id = 'rw-settings-btn-header';
        settingsButton.textContent = 'Settings';
        settingsButton.title = 'RW Script Settings';
        settingsButton.style.cssText = 'background: transparent; color: rgba(255, 255, 255, 0.8); border: none; padding: 8px 12px; border-radius: 3px; cursor: pointer; font-size: 1em; font-weight: normal; transition: color 0.2s ease; line-height: 1; min-height: 32px;';

        // Add hover effects
        priceButton.addEventListener('mouseenter', function() {
            priceButton.style.color = 'rgba(255, 255, 255, 1)';
        });
        priceButton.addEventListener('mouseleave', function() {
            priceButton.style.color = 'rgba(255, 255, 255, 0.8)';
        });

        settingsButton.addEventListener('mouseenter', function() {
            settingsButton.style.color = 'rgba(255, 255, 255, 1)';
        });
        settingsButton.addEventListener('mouseleave', function() {
            settingsButton.style.color = 'rgba(255, 255, 255, 0.8)';
        });

        // Add event listeners for the actual panel functionality
        priceButton.addEventListener('click', function() {
            console.log('Header price management clicked');
            showPricePanel();
        });

        settingsButton.addEventListener('click', function() {
            console.log('Header settings clicked');
            showSettingsPanel();
        });

        buttonContainer.appendChild(priceButton);
        buttonContainer.appendChild(separator);
        buttonContainer.appendChild(settingsButton);
        titleHeader.appendChild(buttonContainer);
    }

    function refreshRewardDisplay() {
        // If we have stored raw data, recalculate with current seller prices AND API values
        if (rawRewardData && rawRewardData.length === 2) {
            if (DEBUG_MODE) console.log("RWAwardValue: Recalculating with stored data, current seller prices, and API values");
            console.log("RWAwardValue: Using seller:", sellerData.sellers[sellerData.activeSeller].name);
            console.log("RWAwardValue: API cache available:", Object.keys(apiPriceCache).length > 0);

            // Recalculate totals with current seller prices AND API comparisons
            rawRewardData.forEach(function(rawReward, index) {
                let newTotalValue = 0;
                let apiTotalValue = 0; // Track API total for comparison

                rawReward.items.forEach(function(item) {
                    let itemValue = 0;
                    let apiValue = 0;

                    if (item.type === 'cache') {
                        const customPrice = getCustomPrice(item.cacheType);
                        const hasCustomPrice = customPrice > 0;
                        const hasApiPrice = apiPriceCache.data && apiPriceCache.data[item.cacheType];
                        const hasValidApiKey = (API_KEY && API_KEY !== 'YOUR_API_KEY_HERE') || PDA_VALIDATED;

                        let baseValue = 0;
                        // Use same logic as initial calculation
                        if (SETTINGS.showCustomPrices && hasCustomPrice) {
                            baseValue = customPrice;
                        } else if (hasApiPrice && hasValidApiKey) {
                            baseValue = apiPriceCache.data[item.cacheType];
                        } else {
                            baseValue = 0; // Show "?" instead of old defaults
                        }

                        itemValue = baseValue * item.quantity;

                        console.log('RWAwardValue: ' + item.cacheType + ' - custom: ' + customPrice + ', using: ' + baseValue + ', quantity: ' + item.quantity + ', total: ' + itemValue);

                        // Get API value if available
                        if (SETTINGS.showApiValues && apiPriceCache.data[item.cacheType]) {
                            apiValue = apiPriceCache.data[item.cacheType] * item.quantity;
                            apiTotalValue += apiValue;
                            if (DEBUG_MODE) console.log('RWAwardValue: ' + item.cacheType + ' API: ' + apiPriceCache.data[item.cacheType] + ' * ' + item.quantity + ' = ' + apiValue);
                        }

                        // Store individual item calculations for dropdown details
                        item.calculatedValue = itemValue;
                        item.calculatedApiValue = apiValue;
                    } else if (item.type === 'points') {
                        itemValue = item.pointValue * item.quantity;
                        apiValue = itemValue; // Points are the same for both
                        apiTotalValue += apiValue;

                        item.calculatedValue = itemValue;
                        item.calculatedApiValue = apiValue;
                    }

                    newTotalValue += itemValue;
                });

                // Update the stored reward data WITH API totals
                rewardData[index].totalValue = newTotalValue;
                rewardData[index].apiTotalValue = apiTotalValue; // Store API total for display

                if (DEBUG_MODE) console.log('RWAwardValue: ' + rawReward.factionName + ' new total: ' + newTotalValue + ', API total: ' + apiTotalValue);
            });
        }

        // Clear existing containers and recreate with updated data
        const existingContainer = document.getElementById('rw-panels-container');
        if (existingContainer) {
            existingContainer.remove();
        }

        // Recreate with updated data (includes API values in headers)
        setTimeout(function() { createAndDisplayContainers(); }, 100);
    }

    function createAndDisplayContainers() {
        console.log("RWAwardValue: Creating containers...");
        if (rewardData.length !== 2) {
            console.error("RWAwardValue: Expected 2 rewards, got", rewardData.length);
            return;
        }

        // Check if containers already exist to prevent duplicates
        const existingContainer = document.getElementById('rw-panels-container');
        if (existingContainer) {
            console.log("RWAwardValue: Panels already exist, removing old ones first");
            existingContainer.remove();
        }

        const grandTotalValue = rewardData[0].totalValue + rewardData[1].totalValue;
        console.log("RWAwardValue: Grand total value:", grandTotalValue);

        // First, add icons to the top header
        addIconsToTopHeader();

        // Find the insertion point - target right after the war declaration section
        const reportTitle = document.querySelector('.report-title');
        const firstFactionText = document.querySelector('ul');
        let insertionPoint = null;
        let insertMethod = 'fallback';

        if (reportTitle && firstFactionText) {
            // Find the element that contains both the title and the faction descriptions
            const titleParent = reportTitle.parentElement;
            const factionParent = firstFactionText.parentElement;

            if (titleParent === factionParent) {
                // Same container - insert between them
                insertionPoint = titleParent;
                insertMethod = 'insertBefore';
                console.log("RWAwardValue: Will insert between title and faction descriptions");
            } else {
                // Different containers - insert after title
                insertionPoint = reportTitle;
                insertMethod = 'afterTitle';
                console.log("RWAwardValue: Will insert right after report title");
            }
        } else {
            // Fallback
            insertionPoint = reportTitle || document.body;
            insertMethod = 'fallback';
            console.log("RWAwardValue: Using fallback insertion");
        }

        // Create container for all our panels with proper spacing
        const panelContainer = document.createElement('div');
        panelContainer.id = 'rw-panels-container';
        panelContainer.style.cssText = 'margin: 15px 10px 20px 10px; padding: 0; display: block; visibility: visible; opacity: 1; position: relative; z-index: 1;';

        console.log("RWAwardValue: Created panel container with proper spacing");

        // Add trader selector first (above all containers) - only if custom prices are enabled
        if (SETTINGS.showCustomPrices) {
            const traderSelector = createTraderSelector();
            if (traderSelector) {
                panelContainer.appendChild(traderSelector);
            }
        }

        // Add info box if no pricing sources are configured
        if (shouldShowNoPricingInfo()) {
            const infoBox = createNoPricingInfoBox();
            panelContainer.appendChild(infoBox);
        }

        // Create individual reward containers
        for (let i = 0; i < 2; i++) {
            console.log("RWAwardValue: Creating container for reward", i);
            const container = createCompactContainer(
                rewardData[i].totalValue,
                i,
                grandTotalValue,
                rewardData[i].factionName,
                rewardData // Pass all faction data for ranking analysis
            );

            // Add click listener for expansion
            const header = container.querySelector('#rw-reward-' + i);
            header.addEventListener('click', function() { toggleExpansion(i); });

            // Populate details with updated item elements
            const details = container.querySelector('#rw-details-' + i);

            // Use the updated item elements that include API values
            if (rawRewardData && rawRewardData[i] && rawRewardData[i].items) {
                console.log('RWAwardValue: Building updated item elements for', rewardData[i].factionName);
                // Clear existing items
                details.innerHTML = '';

                // Pre-calculate colors and mobile flag to avoid unsafe references
                const detailColors = getThemeColors();
                const isMobileView = isMobile();

                // Create fresh item elements with current calculations
                rawRewardData[i].items.forEach(function(item) {
                        const itemDiv = document.createElement('div');
                        itemDiv.style.background = detailColors.statBoxBg;
                        itemDiv.style.padding = isMobileView ? '8px' : '10px';
                        itemDiv.style.borderRadius = '3px';
                        itemDiv.style.marginBottom = '6px';
                        itemDiv.style.borderLeft = '3px solid ' + detailColors.primary;
                        itemDiv.style.border = '1px solid ' + detailColors.statBoxBorder;
                        itemDiv.style.boxShadow = detailColors.statBoxShadow;
                        itemDiv.style.display = 'flex';
                        itemDiv.style.justifyContent = 'space-between';
                        itemDiv.style.alignItems = 'center';
                        itemDiv.style.fontSize = isMobileView ? '12px' : '13px';

                        const nameSpan = document.createElement('span');
                        nameSpan.style.color = detailColors.textSecondary;

                        // Create enhanced item name format
                        let itemName = '';
                        if (item.type === 'cache') {
                            // Use proper cache type names 
                            let cacheTypeName = '';
                            switch(item.cacheType) {
                                case 'armorCache':
                                    cacheTypeName = 'Armor';
                                    break;
                                case 'heavyArmsCache':
                                    cacheTypeName = 'Heavy Arms';
                                    break;
                                case 'mediumArmsCache':
                                    cacheTypeName = 'Medium Arms';
                                    break;
                                case 'meleeCache':
                                    cacheTypeName = 'Melee';
                                    break;
                                case 'smallArmsCache':
                                    cacheTypeName = 'Small Arms';
                                    break;
                            }

                            if (isMobileView) {
                                // Mobile: Simplified layout without quantity breakdown
                                if (item.quantity === 1) {
                                    itemName = '1x ' + cacheTypeName + ' Cache';
                                } else {
                                    itemName = item.quantity + 'x ' + cacheTypeName + ' Cache';
                                }

                                // Add API comparison on second line if available
                                if (SETTINGS.showApiValues && item.calculatedApiValue > 0) {
                                    const apiValue = item.calculatedApiValue;
                                    const customValue = item.calculatedValue;
                                    const percentDiff = customValue > 0 ? ((customValue - apiValue) / apiValue * 100) : 0;

                                    if (Math.abs(percentDiff) > 0.1) {
                                        let arrow = '';
                                        let arrowColor = detailColors.textMuted;
                                        if (percentDiff > 0) {
                                            arrow = ' ' + getMobileArrow(true) + ' ';
                                            arrowColor = detailColors.success;
                                        } else {
                                            arrow = ' ' + getMobileArrow(false) + ' ';
                                            arrowColor = detailColors.danger;
                                        }
                                        itemName += '<br><span style="font-size: 11px; color: ' + detailColors.textMuted + ';"><span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(apiValue, 2) + '</span>';
                                    }
                                }
                            } else {
                                // Desktop: Single line layout (unchanged)
                                const individualPrice = item.calculatedValue / item.quantity;
                                if (item.quantity === 1) {
                                    if (individualPrice > 0 && !isNaN(individualPrice)) {
                                        itemName = '1x ' + cacheTypeName + ' Cache (' + formatNumberWithCommas(individualPrice) + ')';
                                    } else {
                                        itemName = '1x ' + cacheTypeName + ' Cache';
                                    }
                                } else {
                                    if (individualPrice > 0 && !isNaN(individualPrice)) {
                                        itemName = item.quantity + 'x ' + cacheTypeName + ' Cache (' + item.quantity + 'x ' + formatNumberWithCommas(individualPrice) + ')';
                                    } else {
                                        itemName = item.quantity + 'x ' + cacheTypeName + ' Cache';
                                    }
                                }
                            }
                        } else if (item.type === 'points') {
                            if (isMobileView) {
                                // Mobile: Keep points simple
                                itemName = item.quantity.toLocaleString() + ' points<br><span style="font-size: 11px; color: ' + detailColors.textMuted + ';">(' + (item.calculatedValue > 0 ? numberFormatter(item.calculatedValue) : '?') + ' total)</span>';
                            } else {
                                // Desktop: Single line 
                                itemName = item.quantity.toLocaleString() + ' points (' + (item.calculatedValue > 0 ? numberFormatter(item.calculatedValue) : '?') + ' total)';
                            }
                        }
                        nameSpan.innerHTML = itemName; // Use innerHTML for mobile line breaks

                        const valueContainer = document.createElement('div');
                        valueContainer.style.display = 'flex';
                        valueContainer.style.alignItems = 'center';
                        valueContainer.style.gap = '8px';

                        // Add API comparison if enabled and available - DESKTOP ONLY (mobile has it inline)
                        if (!isMobileView && SETTINGS.showApiValues && item.calculatedApiValue > 0 && item.type === 'cache') {
                            const apiValue = item.calculatedApiValue;
                            const customValue = item.calculatedValue;
                            const percentDiff = customValue > 0 ? ((customValue - apiValue) / apiValue * 100) : 0;

                            console.log('RWAwardValue: Item', item.cacheType, '- Custom:', customValue, 'API:', apiValue, 'Diff:', percentDiff.toFixed(1) + '%');

                            if (Math.abs(percentDiff) > 0.1) {
                                // Create wrapper for name with API line below
                                const nameWrapper = document.createElement('div');
                                nameWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: flex-start;';

                                // Create main item name span
                                const mainNameSpan = document.createElement('span');
                                mainNameSpan.style.color = detailColors.textSecondary;
                                mainNameSpan.innerHTML = itemName;

                                // Create API comparison line with increased gap
                                const apiLine = document.createElement('div');
                                apiLine.style.cssText = 'margin-top: 4px; font-size: 11px; color: ' + detailColors.textMuted + '; font-weight: normal;';

                                let arrow = '';
                                let arrowColor = detailColors.textMuted;
                                if (percentDiff > 0) {
                                    arrow = ' ' + getMobileArrow(true) + ' ';
                                    arrowColor = detailColors.success;
                                } else {
                                    arrow = ' ' + getMobileArrow(false) + ' ';
                                    arrowColor = detailColors.danger;
                                }

                                apiLine.innerHTML = '<span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(apiValue, 2);

                                nameWrapper.appendChild(mainNameSpan);
                                nameWrapper.appendChild(apiLine);

                                // Adjust itemDiv to allow for multi-line content
                                itemDiv.style.alignItems = 'flex-start';
                                itemDiv.appendChild(nameWrapper);
                            } else {
                                // No significant API difference, use normal layout
                                nameSpan.innerHTML = itemName;
                                itemDiv.appendChild(nameSpan);
                            }
                        } else {
                            // No API comparison or mobile view, use normal layout
                            nameSpan.innerHTML = itemName;
                            itemDiv.appendChild(nameSpan);
                        }

                        const valueSpan = document.createElement('span');
                        valueSpan.style.color = detailColors.primary;
                        valueSpan.style.fontWeight = 'bold';
                        valueSpan.textContent = item.calculatedValue > 0 ? numberFormatter(item.calculatedValue, 2) : '?';

                        valueContainer.appendChild(valueSpan);

                        // Only add valueContainer if we haven't already added nameWrapper
                        if (!itemDiv.children.length) {
                            itemDiv.appendChild(nameSpan);
                        }
                        itemDiv.appendChild(valueContainer);
                        details.appendChild(itemDiv);
                });
            } else {
                // Fallback to original method
                rewardData[i].itemElements.forEach(function(element) {
                    details.appendChild(element);
                });
            }

            panelContainer.appendChild(container);
            rewardData[i].container = container;
            console.log("RWAwardValue: Container", i, "added to panel container");
        }

        // Add grand total to panel container
        const grandTotalContainer = createGrandTotalContainer(grandTotalValue);
        panelContainer.appendChild(grandTotalContainer);

        // Insert the panel container using the appropriate method
        if (insertMethod === 'insertBefore' && firstFactionText) {
            // Insert before faction descriptions
            insertionPoint.insertBefore(panelContainer, firstFactionText);
            console.log("RWAwardValue: Panels inserted before faction descriptions");
        } else if (insertMethod === 'afterTitle' && reportTitle) {
            // Insert immediately after report title
            insertionPoint.insertAdjacentElement('afterend', panelContainer);
            console.log("RWAwardValue: Panels inserted immediately after report title");
        } else {
            // Fallback - insert after title or at top
            insertionPoint.insertAdjacentElement('afterend', panelContainer);
            console.log("RWAwardValue: Panels inserted at fallback position");
        }

        console.log("RWAwardValue: All panels inserted at top position");

        // Debug: Check if panels are actually in the DOM
        setTimeout(function() {
            const insertedContainer = document.getElementById('rw-panels-container');
            if (insertedContainer) {
                console.log("RWAwardValue: Panel container found in DOM");
                console.log("RWAwardValue: Container has", insertedContainer.children.length, "children");
                console.log("RWAwardValue: Container computed style:", getComputedStyle(insertedContainer).display);

                // Force visibility if needed
                insertedContainer.style.display = 'block';
                insertedContainer.style.visibility = 'visible';

                // Check individual panels
                for (let i = 0; i < insertedContainer.children.length; i++) {
                    const child = insertedContainer.children[i];
                    console.log("RWAwardValue: Child", i, "display:", getComputedStyle(child).display);
                    child.style.display = 'block';
                    child.style.visibility = 'visible';
                }
            } else {
                console.error("RWAwardValue: Panel container NOT found in DOM!");
                // Try fallback placement
                console.log("RWAwardValue: Attempting fallback placement...");
                const fallbackTarget = document.querySelector('.report-title');
                if (fallbackTarget) {
                    fallbackTarget.parentElement.appendChild(panelContainer);
                    console.log("RWAwardValue: Fallback placement completed");
                }
            }
        }, 100);

        console.log("RWAwardValue: Script completed successfully!");

        // Initialize API cache if showing API values - ONLY ONCE, NOT IN REFRESH
        if (SETTINGS.showApiValues && ((API_KEY && API_KEY !== 'YOUR_API_KEY_HERE') || (PDA_MODE && PDA_VALIDATED)) && !window.rwApiInitialized) {
            console.log('RW: Initializing API price cache on startup...');
            window.rwApiInitialized = true; // Prevent multiple initializations
            updateApiPriceCache().then(function(success) {
                if (success) {
                    console.log('RW: Startup API fetch successful - refreshing display to integrate API values');
                    // We need a full refresh to integrate API values properly into the calculations
                    refreshRewardDisplay();
                } else {
                    console.log('RW: Startup API fetch failed');
                }
            });
        }

        console.log("RWAwardValue: Script completed successfully!");
    }

    // Panel Management Functions - Convert to slide-down panels (same as my gym script)
    function showPricePanel() {
        const colors = getThemeColors();
        const mobile = isMobile();

        // Close any existing panel
        const existingPanel = document.getElementById('rw-price-panel');
        if (existingPanel) {
            existingPanel.remove();
            return; // Toggle off
        }

        // Close settings panel if open
        const settingsPanel = document.getElementById('rw-settings-panel');
        if (settingsPanel) settingsPanel.remove();

        // Find the title header to attach panel after
        const titleHeader = document.querySelector('.title-black.m-top10.top-round') ||
                           document.querySelector('.title-black') ||
                           document.querySelector('[class*="title"]');
        if (!titleHeader) return;

        // Create slide-down panel
        const panel = document.createElement('div');
        panel.id = 'rw-price-panel';
        panel.style.cssText = 'background: ' + colors.configBg + '; border: none; border-radius: 0; padding: 15px; margin: 0; color: ' + colors.textPrimary + '; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; box-shadow: 0 4px 8px rgba(0,0,0,0.15); position: relative; overflow: hidden; max-height: 0; transition: max-height 0.3s ease, padding 0.3s ease;';

        // Animate in
        setTimeout(function() {
            panel.style.maxHeight = '600px'; // Increased from 500px to accommodate confirmations
        }, 10);

        // Create header
        const header = document.createElement('div');
        header.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid ' + colors.configBorder + ';';

        const title = document.createElement('h4');
        title.textContent = 'Price Configuration';
        title.style.cssText = 'margin: 0; color: ' + colors.textPrimary + '; font-size: 18px;';

        const closeBtn = document.createElement('button');
        // Use HTML entity for mobile compatibility
        if (isMobile()) {
            closeBtn.innerHTML = '&#10006;';
        } else {
            closeBtn.textContent = '✕';
        }
        closeBtn.style.cssText = 'background: none; border: none; font-size: 20px; color: ' + colors.textSecondary + '; cursor: pointer; padding: 5px; border-radius: 3px;';
        closeBtn.onclick = function() {
            panel.style.maxHeight = '0';
            panel.style.padding = '0 15px';
            setTimeout(function() {
                panel.remove();
                // Refresh values when panel closes
                refreshRewardDisplay();
            }, 300);
        };

        header.appendChild(title);
        header.appendChild(closeBtn);

        // Create seller section
        const sellerSection = document.createElement('div');
        sellerSection.style.marginBottom = '20px';

        const sellerLabel = document.createElement('label');
        sellerLabel.textContent = 'Active Trader:';
        sellerLabel.style.cssText = 'display: block; margin-bottom: 8px; font-weight: bold; color: ' + colors.textPrimary + ';';

        const sellerContainer = document.createElement('div');
        sellerContainer.style.cssText = 'display: flex; gap: 10px; align-items: center; margin-bottom: 10px;';

        // Create last modified date display
        const lastModifiedDiv = document.createElement('div');
        lastModifiedDiv.style.cssText = 'font-size: 12px; color: ' + colors.textMuted + '; margin-bottom: 15px;';

        function formatLastModified(dateString) {
            if (!dateString) return 'Last modified: Unknown';

            const date = new Date(dateString);
            const now = new Date();
            const diffTime = Math.abs(now - date);
            const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));

            const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
            const formattedDate = date.getDate() + ' ' + months[date.getMonth()];

            if (diffDays === 1) {
                return 'Last modified: ' + formattedDate + ' (today)';
            } else if (diffDays === 2) {
                return 'Last modified: ' + formattedDate + ' (yesterday)';
            } else {
                return 'Last modified: ' + formattedDate + ' (' + (diffDays - 1) + ' days ago)';
            }
        }

        const currentSeller = sellerData.sellers[sellerData.activeSeller];
        lastModifiedDiv.textContent = formatLastModified(currentSeller.lastModified);

        const sellerSelect = document.createElement('select');
        sellerSelect.style.cssText = 'background: ' + colors.inputBg + '; border: 1px solid ' + colors.inputBorder + '; color: ' + colors.textPrimary + '; padding: 8px; border-radius: 4px; flex: 1;';

        sellerData.sellers.forEach(function(seller, index) {
            const option = document.createElement('option');
            option.value = index;
            const userInfo = extractUserInfo(seller.name);
            option.textContent = userInfo.name + (userInfo.hasId ? ' [' + userInfo.id + ']' : '');
            option.selected = index === sellerData.activeSeller;
            sellerSelect.appendChild(option);
        });

        const editSellerBtn = document.createElement('button');
        editSellerBtn.textContent = 'Edit Name';
        editSellerBtn.style.cssText = 'background: ' + colors.primary + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 12px;';

        // Add seller name input field (initially hidden)
        const nameInputContainer = document.createElement('div');
        nameInputContainer.style.cssText = 'display: none; margin-top: 10px;';

        const nameLabel = document.createElement('label');
        nameLabel.textContent = 'Trader Name (e.g. "John Doe [123456]"):';
        nameLabel.style.cssText = 'display: block; margin-bottom: 5px; color: ' + colors.textSecondary + '; font-size: 12px;';

        const nameInputRow = document.createElement('div');
        nameInputRow.style.cssText = 'display: flex; gap: 8px; align-items: center; flex-wrap: ' + (mobile ? 'wrap' : 'nowrap') + ';';

        const nameInput = document.createElement('input');
        nameInput.type = 'text';
        nameInput.placeholder = 'Enter seller name with optional [ID]';
        nameInput.style.cssText = 'background: ' + colors.inputBg + '; border: 1px solid ' + colors.inputBorder + '; color: ' + colors.textPrimary + '; padding: 8px; border-radius: 4px; flex: 1; ' + (mobile ? 'width: 100%; margin-bottom: 8px;' : '');

        const saveNameBtn = document.createElement('button');
        saveNameBtn.textContent = 'Save';
        saveNameBtn.style.cssText = 'background: ' + colors.success + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; ' + (mobile ? 'flex: 1;' : '');

        const cancelNameBtn = document.createElement('button');
        cancelNameBtn.textContent = 'Cancel';
        cancelNameBtn.style.cssText = 'background: ' + colors.danger + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; ' + (mobile ? 'flex: 1;' : '');

        nameInputContainer.appendChild(nameLabel);
        if (mobile) {
            nameInputRow.appendChild(nameInput);
            nameInputRow.appendChild(document.createElement('div')); // Line break
            const buttonRow = document.createElement('div');
            buttonRow.style.cssText = 'display: flex; gap: 8px; width: 100%;';
            buttonRow.appendChild(saveNameBtn);
            buttonRow.appendChild(cancelNameBtn);
            nameInputContainer.appendChild(nameInputRow);
            nameInputContainer.appendChild(buttonRow);
        } else {
            nameInputRow.appendChild(nameInput);
            nameInputRow.appendChild(saveNameBtn);
            nameInputRow.appendChild(cancelNameBtn);
            nameInputContainer.appendChild(nameInputRow);
        }

        sellerContainer.appendChild(sellerSelect);
        sellerContainer.appendChild(editSellerBtn);
        sellerSection.appendChild(sellerLabel);
        sellerSection.appendChild(sellerContainer);
        sellerSection.appendChild(lastModifiedDiv);
        sellerSection.appendChild(nameInputContainer);

        // Add CSS for placeholder styling
        const styleId = 'rw-placeholder-styles';
        if (!document.getElementById(styleId)) {
            const style = document.createElement('style');
            style.id = styleId;
            style.textContent = `
                .rw-relative-input::placeholder {
                    color: #999 !important;
                    opacity: 1 !important;
                    font-style: italic !important;
                }
                .rw-relative-input::-webkit-input-placeholder {
                    color: #999 !important;
                    opacity: 1 !important;
                    font-style: italic !important;
                }
                .rw-relative-input::-moz-placeholder {
                    color: #999 !important;
                    opacity: 1 !important;
                    font-style: italic !important;
                }
            `;
            document.head.appendChild(style);
        }

        // Create pricing mode toggle
        const pricingModeSection = document.createElement('div');
        pricingModeSection.style.cssText = 'margin-bottom: 20px;';

        const pricingModeLabel = document.createElement('label');
        pricingModeLabel.textContent = 'Pricing Mode:';
        pricingModeLabel.style.cssText = 'display: block; margin-bottom: 8px; font-weight: bold; color: ' + colors.textPrimary + ';';

        // Create horizontal toggle
        const toggleContainer = document.createElement('div');
        const toggleBg = currentTheme === 'light' ? '#e8e8e8' : colors.inputBg;
        toggleContainer.style.cssText = `
            display: flex;
            background: ${toggleBg};
            border: 1px solid ${colors.inputBorder};
            border-radius: 6px;
            overflow: hidden;
            width: 100%;
        `;

        const isRelativeMode = currentSeller.pricingMode === 'relative';

        // Fixed prices option
        const fixedOption = document.createElement('div');
        fixedOption.style.cssText = `
            flex: 1;
            padding: 9px;
            text-align: center;
            cursor: pointer;
            transition: all 0.2s ease;
            background: ${!isRelativeMode ? colors.primary : 'transparent'};
            color: ${!isRelativeMode ? 'white' : colors.textPrimary};
            font-weight: ${!isRelativeMode ? 'bold' : 'normal'};
        `;
        fixedOption.textContent = 'Fixed Prices';

        // Relative prices option
        const relativeOption = document.createElement('div');
        relativeOption.style.cssText = `
            flex: 1;
            padding: 9px;
            text-align: center;
            cursor: pointer;
            transition: all 0.2s ease;
            background: ${isRelativeMode ? colors.primary : 'transparent'};
            color: ${isRelativeMode ? 'white' : colors.textPrimary};
            font-weight: ${isRelativeMode ? 'bold' : 'normal'};
        `;
        relativeOption.textContent = 'Relative Prices';

        toggleContainer.appendChild(fixedOption);
        toggleContainer.appendChild(relativeOption);
        pricingModeSection.appendChild(pricingModeLabel);
        pricingModeSection.appendChild(toggleContainer);

        // Function to update toggle styles
        function updateToggleStyles() {
            const activeSeller = sellerData.sellers[sellerData.activeSeller];
            const isRelative = activeSeller.pricingMode === 'relative';

            if (DEBUG_MODE) console.log('RW: Updating toggle for seller', sellerData.activeSeller, 'mode:', activeSeller.pricingMode);

            fixedOption.style.background = !isRelative ? colors.primary : 'transparent';
            fixedOption.style.color = !isRelative ? 'white' : colors.textPrimary;
            fixedOption.style.fontWeight = !isRelative ? 'bold' : 'normal';

            relativeOption.style.background = isRelative ? colors.primary : 'transparent';
            relativeOption.style.color = isRelative ? 'white' : colors.textPrimary;
            relativeOption.style.fontWeight = isRelative ? 'bold' : 'normal';
        }

        // Click handlers for toggle
        fixedOption.addEventListener('click', function() {
            const currentSeller = sellerData.sellers[sellerData.activeSeller];
            if (currentSeller.pricingMode !== 'fixed') {
                // Clear prices when switching modes to prevent confusion
                cacheTypes.forEach(function(cache) {
                    currentSeller.prices[cache.key] = 0;
                });
                currentSeller.pricingMode = 'fixed';
                updateToggleStyles();
                updateInputDisplayMode();
                saveSettings();
            }
        });

        relativeOption.addEventListener('click', function() {
            const currentSeller = sellerData.sellers[sellerData.activeSeller];
            if (currentSeller.pricingMode !== 'relative') {
                // Clear prices when switching modes to prevent confusion
                cacheTypes.forEach(function(cache) {
                    currentSeller.prices[cache.key] = 0;
                });
                currentSeller.pricingMode = 'relative';
                updateToggleStyles();
                updateInputDisplayMode();
                saveSettings();
            }
        });

        // Create price inputs
        const pricesSection = document.createElement('div');
        pricesSection.style.marginBottom = '20px';

        const cacheTypes = [
            { key: 'armorCache', label: 'Armor Cache' },
            { key: 'heavyArmsCache', label: 'Heavy Arms' },
            { key: 'mediumArmsCache', label: 'Medium Arms' },
            { key: 'meleeCache', label: 'Melee Cache' },
            { key: 'smallArmsCache', label: 'Small Arms' }
        ];

        const priceInputs = {};

        // Function to update input display mode
        function updateInputDisplayMode() {
            const activeSeller = sellerData.sellers[sellerData.activeSeller];
            const isRelative = activeSeller.pricingMode === 'relative';

            if (DEBUG_MODE) console.log('RW: Updating input mode for seller', sellerData.activeSeller, 'mode:', activeSeller.pricingMode);

            cacheTypes.forEach(function(cache, index) {
                const input = priceInputs[cache.key];
                if (input) {
                    if (isRelative) {
                        // Convert to percentage display (add % suffix, show as percentage)
                        const value = activeSeller.prices[cache.key];
                        input.value = value > 0 ? value + '%' : '%';
                        input.style.textAlign = 'center';
                        // Add placeholder only to first field (Armor Cache) and CSS class
                        if (index === 0) {
                            input.placeholder = 'e.g. 95';
                            input.classList.add('rw-relative-input');
                        } else {
                            input.placeholder = '';
                            input.classList.add('rw-relative-input');
                        }
                    } else {
                        // Convert to fixed price display (remove % suffix, format as currency)
                        const value = activeSeller.prices[cache.key];
                        input.value = value > 0 ? formatNumberWithCommas(value) : '';
                        input.style.textAlign = 'center';
                        input.placeholder = '';
                        input.classList.remove('rw-relative-input');
                    }
                }
            });
        }

        cacheTypes.forEach(function(cache) {
            const row = document.createElement('div');
            row.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;';

            const label = document.createElement('label');
            label.textContent = cache.label + ':';
            label.style.cssText = 'color: ' + colors.textPrimary + '; width: 35%;';

            const input = document.createElement('input');
            input.type = 'text';
            input.style.cssText = 'background: ' + colors.inputBg + '; border: 1px solid ' + colors.inputBorder + '; color: ' + colors.textPrimary + '; padding: 8px; border-radius: 4px; width: 60%; text-align: center;';

            // Set initial value based on pricing mode
            const currentSeller = sellerData.sellers[sellerData.activeSeller];
            const isRelative = currentSeller.pricingMode === 'relative';
            if (isRelative) {
                const value = currentSeller.prices[cache.key];
                input.value = value > 0 ? value + '%' : '%';
                input.style.textAlign = 'center';
                // Add placeholder only to first field (Armor Cache) and CSS class
                input.placeholder = cache.key === 'armorCache' ? 'e.g. 95' : '';
                input.classList.add('rw-relative-input');
            } else {
                input.value = formatNumberWithCommas(currentSeller.prices[cache.key]);
                input.style.textAlign = 'center';
                input.placeholder = '';
            }

            // Dynamic input formatting based on pricing mode
            input.addEventListener('input', function() {
                const currentSeller = sellerData.sellers[sellerData.activeSeller];
                const isRelative = currentSeller.pricingMode === 'relative';

                if (isRelative) {
                    // Handle percentage input with permanent % symbol
                    let value = input.value.replace(/[^0-9.]/g, ''); // Extract only numbers and decimals
                    if (value) {
                        const numValue = parseFloat(value);
                        if (!isNaN(numValue)) {
                            // Cap at 999% to prevent 4-digit percentages
                            const cappedValue = Math.min(numValue, 999);
                            input.value = cappedValue + '%';
                        }
                    } else {
                        // Always maintain % symbol even when empty
                        input.value = '%';
                    }
                } else {
                    // Handle fixed price input with comma formatting
                    const cursorPosition = input.selectionStart;
                    const oldValue = input.value;
                    const numericValue = input.value.replace(/[^0-9]/g, '');
                    const formattedValue = numericValue ? formatNumberWithCommas(parseInt(numericValue)) : '';

                    if (formattedValue !== oldValue) {
                        input.value = formattedValue;
                        // Adjust cursor position after formatting
                        const newCursorPosition = cursorPosition + (formattedValue.length - oldValue.length);
                        input.setSelectionRange(newCursorPosition, newCursorPosition);
                    }
                }
            });

            priceInputs[cache.key] = input;

            row.appendChild(label);
            row.appendChild(input);
            pricesSection.appendChild(row);
        });

        // Create button section
        const buttonSection = document.createElement('div');
        buttonSection.style.cssText = 'display: flex; gap: 10px; margin-top: 20px; padding-top: 15px; border-top: 1px solid ' + colors.configBorder + ';';

        // Create confirmation section for Clear All Sellers (initially hidden)
        const clearConfirmationSection = document.createElement('div');
        clearConfirmationSection.id = 'clear-confirmation';
        clearConfirmationSection.style.cssText = 'display: none; margin-top: 15px; padding: 15px; background: ' + colors.panelBg + '; border: 1px solid ' + colors.danger + '; border-radius: 4px;';

        const clearConfirmText = document.createElement('div');
        clearConfirmText.textContent = 'Reset all traders to default? This will clear all custom trader names and prices.';
        clearConfirmText.style.cssText = 'color: ' + colors.textPrimary + '; margin-bottom: 10px; font-size: 14px;';

        const clearConfirmButtons = document.createElement('div');
        clearConfirmButtons.style.cssText = 'display: flex; gap: 10px;';

        const clearConfirmYes = document.createElement('button');
        clearConfirmYes.textContent = 'Yes, Reset All';
        clearConfirmYes.style.cssText = 'background: ' + colors.danger + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; flex: 1;';

        const clearConfirmNo = document.createElement('button');
        clearConfirmNo.textContent = 'Cancel';
        clearConfirmNo.style.cssText = 'background: ' + colors.textSecondary + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; flex: 1;';

        clearConfirmButtons.appendChild(clearConfirmYes);
        clearConfirmButtons.appendChild(clearConfirmNo);
        clearConfirmationSection.appendChild(clearConfirmText);
        clearConfirmationSection.appendChild(clearConfirmButtons);

        // Create confirmation section for Delete Seller (initially hidden)
        const deleteConfirmationSection = document.createElement('div');
        deleteConfirmationSection.id = 'delete-confirmation';
        deleteConfirmationSection.style.cssText = 'display: none; margin-top: 15px; padding: 15px; background: ' + colors.panelBg + '; border: 1px solid ' + colors.danger + '; border-radius: 4px;';

        const deleteConfirmText = document.createElement('div');
        deleteConfirmText.textContent = 'Delete this trader configuration? This will reset name and set prices to zero.';
        deleteConfirmText.style.cssText = 'color: ' + colors.textPrimary + '; margin-bottom: 10px; font-size: 14px;';

        const deleteConfirmButtons = document.createElement('div');
        deleteConfirmButtons.style.cssText = 'display: flex; gap: 10px;';

        const deleteConfirmYes = document.createElement('button');
        deleteConfirmYes.textContent = mobile ? 'Delete Trader' : 'Yes, Delete Trader';
        deleteConfirmYes.style.cssText = 'background: ' + colors.danger + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; flex: 1; font-size: ' + (mobile ? '11px' : '12px') + ';';

        const deleteConfirmNo = document.createElement('button');
        deleteConfirmNo.textContent = 'Cancel';
        deleteConfirmNo.style.cssText = 'background: ' + colors.textSecondary + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; flex: 1;';

        deleteConfirmButtons.appendChild(deleteConfirmYes);
        deleteConfirmButtons.appendChild(deleteConfirmNo);
        deleteConfirmationSection.appendChild(deleteConfirmText);
        deleteConfirmationSection.appendChild(deleteConfirmButtons);

        const copyFromApiBtn = document.createElement('button');
        copyFromApiBtn.textContent = mobile ? 'Copy API' : 'Copy from API';
        copyFromApiBtn.style.cssText = 'background: #454545; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; flex: 1; font-size: ' + (mobile ? '11px' : '12px') + ';';

        const deleteBtn = document.createElement('button');
        deleteBtn.textContent = mobile ? 'Delete' : 'Delete Trader';
        deleteBtn.style.cssText = 'background: ' + colors.danger + '; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; flex: 1; font-size: ' + (mobile ? '11px' : '12px') + ';';

        const saveBtn = document.createElement('button');
        saveBtn.textContent = 'Save';
        saveBtn.style.cssText = 'background: ' + colors.success + '; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; flex: 1; font-size: ' + (mobile ? '11px' : '12px') + ';';

        const clearSellersBtn = document.createElement('button');
        clearSellersBtn.textContent = mobile ? 'Clear All' : 'Clear All Traders';
        clearSellersBtn.style.cssText = 'background: ' + colors.danger + '; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; flex: 1; font-size: ' + (mobile ? '11px' : '12px') + ';';

        buttonSection.appendChild(copyFromApiBtn);
        buttonSection.appendChild(clearSellersBtn);
        buttonSection.appendChild(deleteBtn);
        buttonSection.appendChild(saveBtn);

        // Event handlers
        let editMode = false; // Track if we're editing or adding new

        // Function to show name input
        function showNameInput(isEdit, currentName) {
            editMode = isEdit;
            nameInput.value = currentName || '';
            nameInputContainer.style.display = 'block';
            nameLabel.textContent = isEdit ?
                'Edit Trader Name e.g. \'John Doe [123456]\'' :
                'New Trader Name e.g. \'John Doe [123456]\'';
            nameInput.focus();
        }

        // Function to hide name input
        function hideNameInput() {
            nameInputContainer.style.display = 'none';
            nameInput.value = '';
        }

        // Edit seller button
        editSellerBtn.addEventListener('click', function() {
            const currentSeller = sellerData.sellers[sellerData.activeSeller];
            showNameInput(true, currentSeller.name);
        });

        // Save name button
        saveNameBtn.addEventListener('click', function() {
            const name = nameInput.value.trim();
            if (!name) {
                alert('Please enter a trader name');
                return;
            }

            const userInfo = extractUserInfo(name);

            if (editMode) {
                // Edit existing seller
                sellerData.sellers[sellerData.activeSeller].name = name;

                // Update dropdown option
                const option = sellerSelect.options[sellerData.activeSeller];
                option.textContent = userInfo.name + (userInfo.hasId ? ' [' + userInfo.id + ']' : '');
            } else {
                // Add new seller
                sellerData.sellers.push({
                    name: name,
                    pricingMode: "fixed",
                    prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 }
                });

                // Add to dropdown
                const option = document.createElement('option');
                option.value = sellerData.sellers.length - 1;
                option.textContent = userInfo.name + (userInfo.hasId ? ' [' + userInfo.id + ']' : '');
                sellerSelect.appendChild(option);

                // Select new seller
                sellerSelect.value = sellerData.sellers.length - 1;
                sellerData.activeSeller = sellerData.sellers.length - 1;

                // Update price inputs
                cacheTypes.forEach(function(cache) {
                    priceInputs[cache.key].value = '0';
                });
            }

            // Save seller changes
            saveSettings();
            hideNameInput();
        });

        // Cancel name button
        cancelNameBtn.addEventListener('click', function() {
            hideNameInput();
        });

        // Allow Enter key to save
        nameInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                saveNameBtn.click();
            }
        });

        sellerSelect.onchange = function() {
            sellerData.activeSeller = parseInt(sellerSelect.value);

            // Update toggle styles and input display mode
            updateToggleStyles();
            updateInputDisplayMode();

            // Update last modified date display
            const newSeller = sellerData.sellers[sellerData.activeSeller];
            lastModifiedDiv.textContent = formatLastModified(newSeller.lastModified);
            // Hide name input if open
            hideNameInput();
            // Save the active seller change
            saveSettings();
            // Just update the seller display - values will refresh when panel closes
            updateSellerDisplay();
        };

        // Function to update just the seller name in the combined total
        function updateSellerDisplay() {
            const combinedTotalContainers = document.querySelectorAll('#rw-panels-container');
            combinedTotalContainers.forEach(function(container) {
                // Find seller spans and update them
                const sellerSpans = container.querySelectorAll('span[style*="margin-left: 16px"]');
                sellerSpans.forEach(function(span) {
                    if (span.textContent.includes('Trader:')) {
                        const currentSeller = sellerData.sellers[sellerData.activeSeller];
                        const userInfo = extractUserInfo(currentSeller.name);

                        // Clear existing content
                        span.innerHTML = '';
                        span.textContent = 'Trader: ' + userInfo.name;

                        // Re-add profile link if exists
                        if (userInfo.hasId) {
                            const colors = getThemeColors();
                            const profileLink = createProfileLink(userInfo.id, colors);
                            span.appendChild(profileLink);
                        }
                    }
                });
            });
        }

        saveBtn.onclick = function() {
            console.log('RW: Save button clicked');

            // Save current prices and track if any changed
            let pricesChanged = false;
            const currentSeller = sellerData.sellers[sellerData.activeSeller];
            const isRelative = currentSeller.pricingMode === 'relative';

            cacheTypes.forEach(function(cache) {
                const oldPrice = currentSeller.prices[cache.key];
                let newPrice = 0;

                if (isRelative) {
                    // Parse percentage value (remove % and parse as decimal)
                    const percentValue = priceInputs[cache.key].value.replace('%', '').trim();
                    newPrice = percentValue ? parseFloat(percentValue) : 0;
                } else {
                    // Parse fixed price value (remove commas)
                    newPrice = parseCommaNumber(priceInputs[cache.key].value);
                }

                currentSeller.prices[cache.key] = newPrice;

                if (oldPrice !== newPrice) {
                    if (DEBUG_MODE) console.log('RW: Price changed for', cache.key, 'from', oldPrice, 'to', newPrice, 'mode:', currentSeller.pricingMode);
                    pricesChanged = true;
                }
            });

            // Update last modified date if any prices changed
            if (pricesChanged) {
                sellerData.sellers[sellerData.activeSeller].lastModified = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format
            }

            // Save seller data to localStorage
            saveSettings();

            if (DEBUG_MODE) {
                console.log('RW: Saved new prices for', sellerData.sellers[sellerData.activeSeller].name);
                console.log('RW: New prices:', sellerData.sellers[sellerData.activeSeller].prices);
            }

            // Close panel and use full refresh (reliable)
            panel.style.maxHeight = '0';
            panel.style.padding = '0 15px';
            setTimeout(function() {
                panel.remove();
                console.log('RW: Price panel closed, using full refresh for reliability');
                refreshRewardDisplay();
            }, 300);
        };

        copyFromApiBtn.onclick = async function() {
            copyFromApiBtn.textContent = 'Loading...';
            copyFromApiBtn.disabled = true;

            const result = await fetchApiPrices();

            if (result.success) {
                // Update the price inputs with API values
                Object.keys(result.prices).forEach(function(cacheType) {
                    const price = result.prices[cacheType];
                    if (priceInputs[cacheType]) {
                        priceInputs[cacheType].value = formatNumberWithCommas(price);
                    }
                });

                copyFromApiBtn.textContent = 'Copied!';
                copyFromApiBtn.style.background = colors.success;

                setTimeout(function() {
                    copyFromApiBtn.textContent = mobile ? 'Copy API' : 'Copy from API';
                    copyFromApiBtn.style.background = '#454545';
                    copyFromApiBtn.disabled = false;
                }, 2000);
            } else {
                alert('Failed to fetch API prices: ' + result.error);
                copyFromApiBtn.textContent = mobile ? 'Copy API' : 'Copy from API';
                copyFromApiBtn.disabled = false;
            }
        };

        clearSellersBtn.onclick = function() {
            // Hide delete confirmation if shown
            deleteConfirmationSection.style.display = 'none';
            deleteBtn.disabled = false;
            deleteBtn.style.opacity = '1';

            // Show clear confirmation section
            clearConfirmationSection.style.display = 'block';
            clearSellersBtn.disabled = true;
            clearSellersBtn.style.opacity = '0.5';
        };

        deleteBtn.onclick = function() {
            // Hide clear confirmation if shown
            clearConfirmationSection.style.display = 'none';
            clearSellersBtn.disabled = false;
            clearSellersBtn.style.opacity = '1';

            // Show delete confirmation section
            deleteConfirmationSection.style.display = 'block';
            deleteBtn.disabled = true;
            deleteBtn.style.opacity = '0.5';
        };

        // Clear All Sellers confirmation handlers
        clearConfirmYes.onclick = function() {
            // Reset to default sellers
            sellerData = {
                activeSeller: 0,
                sellers: [
                    { name: "Trader 1", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
                    { name: "Trader 2", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } },
                    { name: "Trader 3", prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 } }
                ]
            };

            // Save to localStorage
            saveSettings();

            // Refresh the panel by closing and reopening it
            panel.style.maxHeight = '0';
            panel.style.padding = '0 15px';
            setTimeout(function() {
                panel.remove();
                // Reopen the panel to show reset sellers
                setTimeout(function() {
                    showPricePanel();
                }, 100);
            }, 300);
        };

        clearConfirmNo.onclick = function() {
            // Hide confirmation section
            clearConfirmationSection.style.display = 'none';
            clearSellersBtn.disabled = false;
            clearSellersBtn.style.opacity = '1';
        };

        // Delete Seller confirmation handlers
        deleteConfirmYes.onclick = function() {
            const currentIndex = sellerData.activeSeller;

            // Determine the default name for this slot
            const defaultNames = ["Trader 1", "Trader 2", "Trader 3", "Trader 4", "Trader 5", "Trader 6", "Trader 7", "Trader 8", "Trader 9", "Trader 10"];
            const defaultName = defaultNames[currentIndex] || "Seller " + (currentIndex + 1);

            // Reset seller to default state
            sellerData.sellers[currentIndex] = {
                name: defaultName,
                prices: { armorCache: 0, heavyArmsCache: 0, mediumArmsCache: 0, meleeCache: 0, smallArmsCache: 0 }
            };

            // Update the dropdown option
            const option = sellerSelect.options[currentIndex];
            option.textContent = defaultName;

            // Update price inputs to show zeros
            cacheTypes.forEach(function(cache) {
                priceInputs[cache.key].value = '0';
            });

            // Save the changes
            saveSettings();

            // Hide confirmation
            deleteConfirmationSection.style.display = 'none';
            deleteBtn.disabled = false;
            deleteBtn.style.opacity = '1';
        };

        deleteConfirmNo.onclick = function() {
            // Hide confirmation section
            deleteConfirmationSection.style.display = 'none';
            deleteBtn.disabled = false;
            deleteBtn.style.opacity = '1';
        };

        // Assemble panel
        panel.appendChild(header);
        panel.appendChild(sellerSection);
        panel.appendChild(pricingModeSection);
        panel.appendChild(pricesSection);
        panel.appendChild(buttonSection);
        panel.appendChild(clearConfirmationSection);
        panel.appendChild(deleteConfirmationSection);

        // Insert after the title header
        titleHeader.insertAdjacentElement('afterend', panel);
    }

    // ========================================
    // CONFIGURATION PANELS
    // ========================================

    function showSettingsPanel() {
        const colors = getThemeColors();
        const mobile = isMobile();

        // Close any existing panel
        const existingPanel = document.getElementById('rw-settings-panel');
        if (existingPanel) {
            existingPanel.remove();
            return; // Toggle off
        }

        // Close price panel if open
        const pricePanel = document.getElementById('rw-price-panel');
        if (pricePanel) pricePanel.remove();

        // Find the title header to attach panel after
        const titleHeader = document.querySelector('.title-black.m-top10.top-round') ||
                           document.querySelector('.title-black') ||
                           document.querySelector('[class*="title"]');
        if (!titleHeader) return;

        // Create slide-down panel
        const panel = document.createElement('div');
        panel.id = 'rw-settings-panel';
        panel.style.cssText = 'background: ' + colors.configBg + '; border: none; border-radius: 0; padding: 15px; margin: 0; color: ' + colors.textPrimary + '; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; box-shadow: 0 4px 8px rgba(0,0,0,0.15); position: relative; overflow: hidden; max-height: 0; transition: max-height 0.3s ease, padding 0.3s ease;';

        // Animate in - increase height for PDA mode to accommodate extra info box
        setTimeout(function() {
            panel.style.maxHeight = PDA_MODE ? '550px' : '500px';
        }, 10);

        // Create header
        const header = document.createElement('div');
        header.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid ' + colors.configBorder + ';';

        const title = document.createElement('h3');
        title.textContent = 'Settings';
        title.style.cssText = 'margin: 0; color: ' + colors.textPrimary + '; font-size: 18px;';

        const closeBtn = document.createElement('button');
        // Use HTML entity for mobile compatibility
        if (isMobile()) {
            closeBtn.innerHTML = '&#10006;';
        } else {
            closeBtn.textContent = '✕';
        }
        closeBtn.style.cssText = 'background: none; border: none; font-size: 20px; color: ' + colors.textSecondary + '; cursor: pointer; padding: 5px; border-radius: 3px;';
        closeBtn.onclick = function() {
            panel.style.maxHeight = '0';
            panel.style.padding = '0 15px';
            setTimeout(function() {
                panel.remove();
                // Refresh the display to update info box visibility based on new settings
                refreshRewardDisplay();
            }, 300);
        };

        header.appendChild(title);
        header.appendChild(closeBtn);

        // API Configuration Section
        const apiSection = document.createElement('div');
        apiSection.style.marginBottom = '25px';

        const apiTitle = document.createElement('h4');
        apiTitle.textContent = 'API Configuration';
        apiTitle.style.cssText = 'margin: 0 0 15px 0; color: ' + colors.textPrimary + '; font-size: 16px;';

        apiSection.appendChild(apiTitle);

        const keyContainer = document.createElement('div');
        keyContainer.style.cssText = mobile ?
            'display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px;' :
            'display: flex; gap: 8px; align-items: center; margin-bottom: 10px;';

        const keyLabel = document.createElement('label');
        keyLabel.textContent = 'Public API Key:';
        keyLabel.style.cssText = 'color: ' + colors.textPrimary + '; ' + (mobile ? 'margin-bottom: 5px;' : 'width: 100px;');

        const inputRow = document.createElement('div');
        inputRow.style.cssText = 'display: flex; gap: 8px; align-items: center;' + (mobile ? ' flex-wrap: wrap; margin-bottom: 0;' : '');

        const keyInput = document.createElement('input');
        keyInput.type = 'password';
        keyInput.value = API_KEY !== 'YOUR_API_KEY_HERE' ? API_KEY : '';
        keyInput.placeholder = 'Enter your Torn API key';
        // Disable browser autocomplete/autofill to prevent login suggestions
        // Note: These attributes only prevent browser behaviour such as autofill
        keyInput.autocomplete = 'new-password'; // More effective than 'off' on mobile browsers
        keyInput.spellcheck = false;
        keyInput.setAttribute('data-form-type', 'other'); // Additional hint this isn't a login form
        keyInput.style.cssText = 'background: ' + colors.inputBg + '; border: 1px solid ' + colors.inputBorder + '; color: ' + colors.textPrimary + '; padding: 8px; border-radius: 4px; ' + (mobile ? 'width: 100%; margin-bottom: 0;' : 'flex: 1;');

        const buttonRow = document.createElement('div');
        buttonRow.style.cssText = mobile ?
            'display: flex; gap: 6px; width: 100%; flex-wrap: wrap;' :
            'display: flex; gap: 8px;';

        const editBtn = document.createElement('button');
        editBtn.textContent = 'Edit';
        const editBtnColor = currentTheme === 'light' ? '#999999' : colors.textSecondary;
        editBtn.style.cssText = 'background: ' + editBtnColor + ' !important; color: white !important; border: none !important; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; ' + (mobile ? 'flex: 1; min-width: 0;' : '');

        const testBtn = document.createElement('button');
        testBtn.textContent = 'Validate';
        testBtn.style.cssText = 'background: ' + colors.primary + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; ' + (mobile ? 'flex: 1; min-width: 0;' : '');

        const resetApiBtn = document.createElement('button');
        resetApiBtn.textContent = 'Reset';
        resetApiBtn.style.cssText = 'background: ' + colors.danger + '; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; ' + (mobile ? 'flex: 1; min-width: 0;' : '');
        resetApiBtn.title = 'Clear API key and cache';

        // Create status div first
        const statusDiv = document.createElement('div');
        statusDiv.style.cssText = 'margin-left: ' + (mobile ? '0px' : '110px') + '; font-size: 12px; color: ' + colors.textMuted + '; ' + (mobile ? 'text-align: left; margin-top: 4px; margin-bottom: 12px;' : '');
        const statusPrefix = mobile ? 'Status: ' : 'Status: ';

        // Use HTML entities for mobile compatibility
        const checkmark = mobile ? '&#9989;' : '✅';
        const cross = mobile ? '&#10060;' : '❌';

        // Improved status logic for better PDA handling
        let isConfigured = false;
        let statusMessage = '';

        if (API_KEY !== 'YOUR_API_KEY_HERE') {
            // Manual API key configured
            isConfigured = true;
            statusMessage = 'Valid - Welcome ' + (API_USERNAME || 'User');
        } else if (PDA_MODE && PDA_VALIDATED) {
            // PDA mode with validation - don't require API_USERNAME to show as valid
            isConfigured = true;
            statusMessage = 'Valid - Welcome ' + (API_USERNAME || 'PDA User') + ' (PDA)';
        } else if (PDA_MODE && API_USERNAME) {
            // PDA mode with username but no validation flag - could be a recovery case
            isConfigured = true;
            statusMessage = 'Valid - Welcome ' + API_USERNAME + ' (PDA - reconnected)';
            console.log('RW: PDA reconnection detected - username exists but validation flag missing');
            // Restore validation flag
            PDA_VALIDATED = true;
            saveSettings();
        }

        const validationSuccessColor = currentTheme === 'light' ? '#69a829' : colors.success;
        statusDiv.innerHTML = isConfigured ?
            statusPrefix + '<span style="color: ' + validationSuccessColor + ';">' + checkmark + ' ' + statusMessage + '</span>' :
            statusPrefix + '<span style="color: ' + colors.danger + ';">' + cross + ' Not configured</span>';

        if (mobile) {
            keyContainer.appendChild(keyLabel);
            inputRow.appendChild(keyInput);
            keyContainer.appendChild(inputRow);
            keyContainer.appendChild(statusDiv); // Status div positioned between input and buttons on mobile
            buttonRow.appendChild(editBtn);
            buttonRow.appendChild(testBtn);
            buttonRow.appendChild(resetApiBtn);
            keyContainer.appendChild(buttonRow);
        } else {
            inputRow.appendChild(keyLabel);
            inputRow.appendChild(keyInput);
            inputRow.appendChild(editBtn);
            inputRow.appendChild(testBtn);
            inputRow.appendChild(resetApiBtn);
            keyContainer.appendChild(inputRow);
        }

        // Create last retrieved info (moved up from API values section)
        const lastRetrievedDiv = document.createElement('div');
        lastRetrievedDiv.style.cssText = mobile ?
            'margin-left: 0px; margin-top: 8px; font-size: 11px; color: ' + colors.textMuted + ';' :
            'margin-left: 110px; margin-top: 4px; font-size: 11px; color: ' + colors.textMuted + ';';

        function getLastRetrievedText() {
            if (!apiPriceCache.lastFetched) return 'Last retrieved: Never';

            const lastFetched = new Date(apiPriceCache.lastFetched);
            const now = new Date();
            const diffMs = now - lastFetched;
            const diffMins = Math.floor(diffMs / (1000 * 60));
            const diffHours = Math.floor(diffMins / 60);
            const diffDays = Math.floor(diffHours / 24);

            const timeString = lastFetched.toLocaleTimeString('en-US', {
                hour: 'numeric',
                minute: '2-digit',
                hour12: true
            });

            if (diffDays === 0) {
                return 'Last retrieved: Today at ' + timeString;
            } else if (diffDays === 1) {
                return 'Last retrieved: Yesterday at ' + timeString;
            } else {
                const day = lastFetched.getDate();
                const month = lastFetched.toLocaleString('en-US', { month: 'short' });
                return 'Last retrieved: ' + day + ' ' + month + ' at ' + timeString;
            }
        }

        function updateLastRetrievedDisplay() {
            const uniqueId = 'refresh-api-link-' + Date.now(); // Unique ID to avoid conflicts
            lastRetrievedDiv.innerHTML = getLastRetrievedText() +
                (apiPriceCache.lastFetched ?
                    ' <span id="' + uniqueId + '" style="color: ' + colors.primary + '; cursor: pointer; text-decoration: underline;">Refresh</span>' :
                    '');

            // Add event listener for refresh link if it exists
            const refreshLink = document.getElementById(uniqueId);
            if (refreshLink) {
                refreshLink.addEventListener('click', function() {
                    console.log('RW: Manual API refresh requested');
                    refreshLink.textContent = 'Loading...';
                    refreshLink.style.cursor = 'wait';

                    updateApiPriceCache(true).then(function(success) { // Force refresh for manual clicks
                        if (success) {
                            console.log('RW: Manual API refresh successful');
                            updateLastRetrievedDisplay();
                            refreshRewardDisplay();
                        } else {
                            console.log('RW: Manual API refresh failed');
                            refreshLink.textContent = 'Failed';
                            setTimeout(function() {
                                updateLastRetrievedDisplay();
                            }, 2000);
                        }
                    });
                });
            } else {
                console.log('RW: Refresh link not found with ID:', uniqueId);
            }
        }

        apiSection.appendChild(apiTitle);
        apiSection.appendChild(keyContainer);
        if (!mobile) {
            apiSection.appendChild(statusDiv); // Status div positioned after keyContainer on desktop
            apiSection.appendChild(lastRetrievedDiv); // Last retrieved positioned after status on desktop
        } else {
            // On mobile, add last retrieved inside keyContainer after all other elements
            keyContainer.appendChild(lastRetrievedDiv);
        }

        // Update the display after the element is in the DOM with a small delay
        setTimeout(function() {
            updateLastRetrievedDisplay();
        }, 10);

        // Add PDA-specific instruction if detected - MOVED TO AFTER OTHER ELEMENTS
        if (PDA_MODE) {
            const pdaInfo = document.createElement('div');
            pdaInfo.style.cssText = 'margin-top: 15px; margin-bottom: 12px; padding: 8px 12px; background: ' + colors.statBoxBg + '; border: 1px solid ' + colors.primary + '; border-radius: 4px; font-size: 11px; color: ' + colors.textPrimary + ';';
            pdaInfo.innerHTML = '<strong>Torn PDA detected:</strong> If you\'ve already connected your API key to PDA, just click validate.';
            apiSection.appendChild(pdaInfo);
        }

        // Other Settings Section
        const otherSection = document.createElement('div');
        otherSection.style.marginBottom = '20px';

        const otherTitle = document.createElement('h4');
        otherTitle.textContent = 'Other Settings';
        otherTitle.style.cssText = 'margin: 0 0 15px 0; color: ' + colors.textPrimary + '; font-size: 16px;';

        // Custom Prices section
        const customPricesSection = document.createElement('div');
        customPricesSection.style.cssText = 'margin-bottom: 15px;';

        const showCustomPricesCheck = document.createElement('div');
        showCustomPricesCheck.style.cssText = 'display: flex; align-items: center; margin-bottom: 2px;';

        const customPricesCheckbox = document.createElement('input');
        customPricesCheckbox.type = 'checkbox';
        customPricesCheckbox.checked = SETTINGS.showCustomPrices;
        const customPricesCheckboxStyle = 'margin-right: 8px;' + (currentTheme === 'dark' ? ' accent-color: #74c0fc;' : '');
        customPricesCheckbox.style.cssText = customPricesCheckboxStyle;

        const customPricesLabel = document.createElement('label');
        customPricesLabel.textContent = 'Show custom prices';
        customPricesLabel.style.color = colors.textPrimary;
        customPricesLabel.style.cursor = 'pointer';

        // Make label clickable to toggle checkbox
        customPricesLabel.addEventListener('click', function() {
            customPricesCheckbox.checked = !customPricesCheckbox.checked;
            // Trigger the change event to ensure all logic runs
            customPricesCheckbox.dispatchEvent(new Event('change'));
        });

        // Handle checkbox change
        customPricesCheckbox.addEventListener('change', function() {
            SETTINGS.showCustomPrices = this.checked;
            saveSettings();
            // Update the "Show API alongside" checkbox state immediately
            const customPricesEnabled = this.checked;
            showCheckbox.disabled = !customPricesEnabled;
            showLabel.style.color = customPricesEnabled ? colors.textPrimary : colors.textMuted;
            showLabel.style.cursor = customPricesEnabled ? 'pointer' : 'not-allowed';

            // If disabling custom prices, also disable the API alongside option
            if (!customPricesEnabled) {
                SETTINGS.showApiValues = false;
                showCheckbox.checked = false;
                saveSettings();
            }

            // Refresh display to apply custom price changes immediately
            refreshRewardDisplay();
        });

        showCustomPricesCheck.appendChild(customPricesCheckbox);
        showCustomPricesCheck.appendChild(customPricesLabel);
        customPricesSection.appendChild(showCustomPricesCheck);

        // API Values section with combined checkbox and last retrieved
        const apiValuesSection = document.createElement('div');
        apiValuesSection.style.cssText = 'margin-bottom: 15px;';

        const showApiCheck = document.createElement('div');
        showApiCheck.style.cssText = 'display: flex; align-items: center; margin-bottom: 2px;';

        const showCheckbox = document.createElement('input');
        showCheckbox.type = 'checkbox';
        showCheckbox.checked = SETTINGS.showApiValues;
        // Only disable if custom prices are not enabled
        const customPricesDisabled = !SETTINGS.showCustomPrices;
        showCheckbox.disabled = customPricesDisabled;

        const checkboxStyle = 'margin-right: 8px;' + (currentTheme === 'dark' ? ' accent-color: #74c0fc;' : '');
        showCheckbox.style.cssText = checkboxStyle;

        const showLabel = document.createElement('label');
        showLabel.textContent = 'Show API market values alongside custom prices';

        // Grey out if disabled for any reason
        showLabel.style.color = showCheckbox.disabled ? colors.textMuted : colors.textPrimary;
        showLabel.style.cursor = showCheckbox.disabled ? 'not-allowed' : 'pointer';

        // Make label clickable to toggle checkbox
        showLabel.addEventListener('click', function() {
            if (!showCheckbox.disabled) {
                showCheckbox.checked = !showCheckbox.checked;
            }
        });

        // Note: API key input no longer affects the "Show API alongside" checkbox
        // That checkbox is now only controlled by the "Show custom prices" setting

        // Update display when checkbox changes
        showCheckbox.addEventListener('change', function() {
            SETTINGS.showApiValues = this.checked;
            saveSettings();
        });

        showApiCheck.appendChild(showCheckbox);
        showApiCheck.appendChild(showLabel);

        // Assemble API values section
        apiValuesSection.appendChild(showApiCheck);

        otherSection.appendChild(otherTitle);
        otherSection.appendChild(customPricesSection);
        otherSection.appendChild(apiValuesSection);

        // Indirect rewards section
        const showIndirectCheck = document.createElement('div');
        showIndirectCheck.style.cssText = 'display: flex; align-items: center; margin-bottom: 15px;';

        const indirectCheckbox = document.createElement('input');
        indirectCheckbox.type = 'checkbox';
        indirectCheckbox.checked = SETTINGS.showIndirectRewards;
        const indirectCheckboxStyle = 'margin-right: 8px;' + (currentTheme === 'dark' ? ' accent-color: #74c0fc;' : '');
        indirectCheckbox.style.cssText = indirectCheckboxStyle;

        const indirectLabel = document.createElement('label');
        indirectLabel.textContent = mobile ? 'Show other rewards incl points and respect' : 'Show other rewards including points and respect';
        indirectLabel.style.color = colors.textPrimary;
        indirectLabel.style.cursor = 'pointer';

        // Make label clickable to toggle checkbox
        indirectLabel.addEventListener('click', function() {
            indirectCheckbox.checked = !indirectCheckbox.checked;
        });

        showIndirectCheck.appendChild(indirectCheckbox);
        showIndirectCheck.appendChild(indirectLabel);

        // Respect value input section
        const respectValueSection = document.createElement('div');
        respectValueSection.style.cssText = mobile ?
            'display: flex; gap: 8px; align-items: center; margin-bottom: 15px; padding-left: 26px;' :
            'display: flex; gap: 8px; align-items: center; margin-bottom: 15px;';

        const respectLabel = document.createElement('label');
        respectLabel.textContent = 'Value per respect:';
        respectLabel.style.cssText = 'color: ' + colors.textPrimary + '; ' + (mobile ? 'width: 100px; white-space: nowrap;' : 'width: 100px;');

        const respectInputRow = document.createElement('div');
        respectInputRow.style.cssText = 'display: flex; gap: 8px; align-items: center;' + (mobile ? ' flex-wrap: wrap; margin-bottom: 0;' : '');

        const respectInput = document.createElement('input');
        respectInput.type = 'text';
        respectInput.value = formatNumberWithCommas(SETTINGS.respectValue);
        respectInput.placeholder = '20,000';
        respectInput.style.cssText = 'background: ' + colors.inputBg + '; border: 1px solid ' + colors.inputBorder + '; color: ' + colors.textPrimary + '; padding: 8px; border-radius: 4px; text-align: right; ' + (mobile ? 'width: 100px;' : 'width: 120px;');

        // Add real-time comma formatting for respect input
        respectInput.addEventListener('input', function() {
            const cursorPosition = respectInput.selectionStart;
            const oldValue = respectInput.value;
            const numericValue = respectInput.value.replace(/[^0-9]/g, '');
            const formattedValue = numericValue ? formatNumberWithCommas(parseInt(numericValue)) : '';

            if (formattedValue !== oldValue) {
                respectInput.value = formattedValue;
                // Adjust cursor position after formatting
                const newCursorPosition = cursorPosition + (formattedValue.length - oldValue.length);
                respectInput.setSelectionRange(newCursorPosition, newCursorPosition);
            }
        });

        respectInputRow.appendChild(respectInput);

        if (mobile) {
            respectValueSection.appendChild(respectLabel);
            respectValueSection.appendChild(respectInputRow);
        } else {
            respectValueSection.appendChild(respectLabel);
            respectValueSection.appendChild(respectInputRow);
        }

        otherSection.appendChild(showIndirectCheck);
        otherSection.appendChild(respectValueSection);

        // Save button
        const saveBtn = document.createElement('button');
        saveBtn.textContent = 'Save';
        const saveBtnColor = currentTheme === 'light' ? '#69a829' : colors.success;
        saveBtn.style.cssText = 'background: ' + saveBtnColor + ' !important; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; width: 100%; margin-top: ' + (mobile ? '8px' : '15px') + '; border-top: 1px solid ' + colors.configBorder + '; padding-top: ' + (mobile ? '8px' : '15px') + ';';

        // Event handlers
        editBtn.onclick = function() {
            keyInput.type = keyInput.type === 'password' ? 'text' : 'password';
            editBtn.textContent = keyInput.type === 'password' ? 'Edit' : 'Hide';
        };

        testBtn.onclick = async function() {
            // Allow validation with empty field if in PDA mode
            if (!keyInput.value.trim() && !PDA_MODE) {
                alert('Please enter an API key first.');
                return;
            }

            testBtn.textContent = 'Testing...';
            testBtn.disabled = true;

            try {
                const result = await testApiKey(keyInput.value.trim());

                if (result.success) {
                    const checkmark = mobile ? '&#9989;' : '✅';
                    const pdaIndicator = result.isPDA ? ' (PDA)' : '';
                    const dynamicValidationColor = currentTheme === 'light' ? '#69a829' : colors.success;
                    statusDiv.innerHTML = 'Status: <span style="color: ' + dynamicValidationColor + ';">' + checkmark + ' Valid - Welcome ' + result.name + pdaIndicator + '</span>';
                    testBtn.textContent = 'Valid!';
                    testBtn.style.background = colors.success;

                // Store the validated username
                API_USERNAME = result.name;

                // If this was a PDA validation, set PDA validated flag
                if (result.isPDA) {
                    console.log('RW: PDA State Transition - API validation successful for:', result.name);
                    PDA_VALIDATED = true;
                    console.log('RW: PDA State - Mode:', PDA_MODE, 'Validated:', PDA_VALIDATED, 'Username:', API_USERNAME);
                } else {
                    // Store manual API key for non-PDA validation
                    console.log('RW: Manual API validation successful for:', result.name);
                    API_KEY = keyInput.value.trim();
                    PDA_VALIDATED = false;
                    console.log('RW: Manual API State - Key saved, PDA_VALIDATED set to false');
                }

                // FIXED: Save to localStorage immediately - EXPLICIT save
                if (typeof(Storage) !== "undefined") {
                    localStorage.setItem('rw_api_username', API_USERNAME);
                    if (PDA_VALIDATED) {
                        localStorage.setItem('rw_pda_validated', 'true');
                    }
                    console.log('RW: EXPLICIT save of username to localStorage:', API_USERNAME);
                }

                // Immediately fetch API prices after successful validation
                console.log('RW: API validation successful - fetching prices immediately...');
                updateApiPriceCache().then(function(success) {
                    if (success) {
                        console.log('RW: API prices fetched successfully during validation');
                        updateLastRetrievedDisplay();
                    } else {
                        console.log('RW: Failed to fetch API prices during validation');
                    }
                });

                saveSettings();
            } else {
                const cross = mobile ? '&#10060;' : '❌';
                statusDiv.innerHTML = 'Status: <span style="color: ' + colors.danger + ';">' + cross + ' Error: ' + result.error + '</span>';
                testBtn.textContent = 'Error';
                testBtn.style.background = colors.danger;
            }
            } catch (error) {
                console.error('RW: API validation exception:', error);
                const cross = mobile ? '&#10060;' : '❌';
                statusDiv.innerHTML = 'Status: <span style="color: ' + colors.danger + ';">' + cross + ' Validation failed - please try again</span>';
                testBtn.textContent = 'Failed';
                testBtn.style.background = colors.danger;
            } finally {
                // Always reset button after 3 seconds
                setTimeout(function() {
                    testBtn.textContent = 'Validate';
                    testBtn.style.background = colors.primary;
                    testBtn.disabled = false;
                }, 3000);
            }
        };

        resetApiBtn.onclick = function() {
            // Clear API key
            API_KEY = 'YOUR_API_KEY_HERE';
            keyInput.value = '';

            // Clear API cache
            apiPriceCache = {
                lastFetched: null,
                data: {}
            };

            // Clear stored username and PDA validation
            API_USERNAME = '';
            PDA_VALIDATED = false;

            // Disable show API values
            SETTINGS.showApiValues = false;
            showCheckbox.checked = false;
            showCheckbox.disabled = true;
            showLabel.style.color = colors.textMuted;
            showLabel.style.cursor = 'not-allowed';

            // Update status
            const cross = mobile ? '&#10060;' : '❌';
            statusDiv.innerHTML = 'Status: <span style="color: ' + colors.danger + ';">' + cross + ' Not configured</span>';

            // Save settings
            saveSettings();

            // Clear from localStorage
            if (typeof(Storage) !== "undefined") {
                localStorage.removeItem('rw_api_key');
                localStorage.removeItem('rw_api_username');
                localStorage.removeItem('rw_pda_validated');
            }

            resetApiBtn.textContent = 'Cleared!';
            resetApiBtn.style.background = colors.success;

            setTimeout(function() {
                resetApiBtn.textContent = 'Reset';
                resetApiBtn.style.background = colors.danger;
            }, 2000);

            // Refresh display to remove API values
            setTimeout(function() {
                refreshRewardDisplay();
            }, 500);
        };

        saveBtn.onclick = function() {
            try {
                // Store previous settings to detect changes
                const previousApiKey = API_KEY;
                const previousShowApiValues = SETTINGS.showApiValues;
                const previousShowIndirectRewards = SETTINGS.showIndirectRewards;
                const previousRespectValue = SETTINGS.respectValue;

                // Save API key and username
                if (keyInput.value.trim() && !PDA_MODE) {
                    // Manual API key for non-PDA users
                    API_KEY = keyInput.value.trim();
                    console.log('RW: Saved manual API key');
                } else if (PDA_MODE && PDA_VALIDATED) {
                    // For PDA users, ensure we maintain the validated state
                    console.log('RW: Maintaining PDA validated state');
                }

                // Store username and validation state if we have it
                if (API_USERNAME) {
                    console.log('RW: Saving username and validation state:', API_USERNAME, 'PDA_VALIDATED:', PDA_VALIDATED);
                    saveSettings(); // This will save the username and PDA validation state
                }

                // Save settings
                SETTINGS.showApiValues = showCheckbox.checked;
                SETTINGS.showIndirectRewards = indirectCheckbox.checked;
                SETTINGS.respectValue = parseCommaNumber(respectInput.value);

                saveSettings();

                // Enhanced debugging logs for API updates
                console.log('RW: Settings saved - API key changed:', (previousApiKey !== API_KEY));
                console.log('RW: API update check - showApiValues:', SETTINGS.showApiValues, 'hasValidKey:', (API_KEY && API_KEY !== 'YOUR_API_KEY_HERE'), 'PDA_VALIDATED:', PDA_VALIDATED);

                // Handle API-related updates - include PDA validation
                const apiKeyChanged = previousApiKey !== API_KEY;
                const hasValidApiKey = ((API_KEY && API_KEY !== 'YOUR_API_KEY_HERE') || (PDA_MODE && PDA_VALIDATED));
                const needsApiUpdate = hasValidApiKey;

                console.log('RW: needsApiUpdate:', needsApiUpdate, 'apiKeyChanged:', apiKeyChanged, 'hasValidApiKey:', hasValidApiKey);

                if (needsApiUpdate && apiKeyChanged) {
                    console.log('RW: API key available and show API enabled - fetching prices...');
                    updateApiPriceCache().then(function(success) {
                        if (success) {
                            console.log('RW: API prices fetched successfully, refreshing display');
                            refreshRewardDisplay();
                        } else {
                            console.log('RW: API fetch failed, display unchanged');
                        }
                    });
                } else if (!SETTINGS.showApiValues && previousShowApiValues) {
                    console.log('RW: Show API disabled, refreshing display to remove API values');
                    refreshRewardDisplay();
                }

                // Handle indirect rewards setting changes
                const indirectRewardsChanged = (SETTINGS.showIndirectRewards !== previousShowIndirectRewards);
                const respectValueChanged = (SETTINGS.respectValue !== previousRespectValue);

                if (indirectRewardsChanged || respectValueChanged) {
                    console.log('RW: Indirect rewards settings changed, refreshing display');
                    refreshRewardDisplay();
                }

                console.log('RW: Settings saved successfully');

                // Close panel
                panel.style.maxHeight = '0';
                panel.style.padding = '0 15px';
                setTimeout(function() { panel.remove(); }, 300);

                // Refresh the reward display to update info box visibility and prices
                console.log('RW: Refreshing display after settings panel close');
                refreshRewardDisplay();

            } catch (error) {
                console.error('RW: Error saving settings:', error);
                alert('Error saving settings: ' + error.message);
            }
        };

        // Assemble panel
        panel.appendChild(header);
        panel.appendChild(apiSection);
        panel.appendChild(otherSection);
        panel.appendChild(saveBtn);

        // Insert after the title header
        titleHeader.insertAdjacentElement('afterend', panel);
    }

    // Create trader selector dropdown
    function createTraderSelector() {
        const colors = getThemeColors();
        const mobile = isMobile();

        // Filter to only show custom trader names (not default "Trader X")
        const customTraders = sellerData.sellers
            .map((seller, index) => ({ ...seller, index }))
            .filter(seller => !seller.name.match(/^Trader \d+$/));

        const container = document.createElement('div');
        container.style.display = 'flex';
        container.style.justifyContent = 'flex-end';
        container.style.alignItems = 'center';
        container.style.marginBottom = '10px';
        container.style.fontSize = '11px';
        container.style.gap = '6px';
        container.style.width = '100%';
        container.style.textAlign = 'right';

        if (customTraders.length > 0) {
            // Create dropdown with custom traders
            const label = document.createElement('span');
            label.textContent = 'Selected Trader:';
            label.style.cssText = `color: ${colors.textMuted}; font-weight: normal; margin-right: 4px;`;

            const dropdown = document.createElement('select');
            dropdown.style.cssText = `
                background: ${colors.inputBg};
                color: ${colors.textPrimary};
                border: 1px solid ${colors.inputBorder};
                border-radius: 3px;
                padding: 2px 6px;
                font-size: 11px;
                cursor: pointer;
            `;

            // Add options for each custom trader
            customTraders.forEach(trader => {
                const option = document.createElement('option');
                option.value = trader.index;
                option.textContent = trader.name;
                option.selected = trader.index === sellerData.activeSeller;
                dropdown.appendChild(option);
            });

            // Handle dropdown changes
            dropdown.addEventListener('change', function() {
                const newActiveIndex = parseInt(this.value);
                sellerData.activeSeller = newActiveIndex;
                saveSettings();
                refreshRewardDisplay();
            });

            container.appendChild(label);
            container.appendChild(dropdown);

            // Add profile link if current trader has one
            const currentTrader = sellerData.sellers[sellerData.activeSeller];
            if (currentTrader) {
                const userInfo = extractUserInfo(currentTrader.name);
                if (userInfo.hasId) {
                    const profileLink = createProfileLink(userInfo.id, colors);
                    profileLink.style.fontSize = '10px';
                    profileLink.style.marginLeft = '4px';
                    container.appendChild(profileLink);
                }
            }

        } else {
            // Show fallback message with clickable link
            const fallbackText = document.createElement('span');
            fallbackText.style.cssText = `color: ${colors.textMuted};`;
            fallbackText.textContent = 'No custom prices - ';

            const configLink = document.createElement('a');
            configLink.textContent = 'Configure Price List';
            configLink.style.cssText = `
                color: ${colors.primary};
                text-decoration: none;
                cursor: pointer;
            `;
            configLink.addEventListener('click', function(e) {
                e.preventDefault();
                showPricePanel();
            });

            fallbackText.appendChild(configLink);
            container.appendChild(fallbackText);
        }

        return container;
    }

    // Separate function to create grand total container
    function createGrandTotalContainer(grandTotalValue) {
        const colors = getThemeColors();
        const mobile = isMobile();

        // Pre-calculate API values to avoid scope issues
        let combinedApiTotal = 0;
        let showMobileApiComparison = false;
        let mobileApiHtml = '';

        if (SETTINGS.showApiValues && rewardData && rewardData.length === 2) {
            combinedApiTotal = (rewardData[0].apiTotalValue || 0) + (rewardData[1].apiTotalValue || 0);

            if (combinedApiTotal > 0) {
                const percentDiff = grandTotalValue > 0 ? ((grandTotalValue - combinedApiTotal) / combinedApiTotal * 100) : 0;

                if (Math.abs(percentDiff) > 0.1) {
                    showMobileApiComparison = true;
                    let arrow = '';
                    let arrowColor = colors.textMuted;
                    if (percentDiff > 0) {
                        arrow = ' ' + getMobileArrow(true) + ' ';
                        arrowColor = colors.success;
                    } else {
                        arrow = ' ' + getMobileArrow(false) + ' ';
                        arrowColor = colors.danger;
                    }
                    mobileApiHtml = '<br><span style="font-size: 11px; color: ' + colors.textMuted + '; font-weight: normal;"><span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(combinedApiTotal, 2) + '</span>';
                }
            }
        }

        // Create grand total container
        const grandContainer = document.createElement('div');
        grandContainer.style.background = colors.panelBg;
        grandContainer.style.border = '1px solid ' + colors.panelBorder;
        grandContainer.style.borderRadius = '5px';
        grandContainer.style.margin = mobile ? '5px 0' : '10px 0';
        grandContainer.style.fontFamily = '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif';
        grandContainer.style.color = colors.textPrimary;
        grandContainer.style.boxShadow = colors.statBoxShadow;
        grandContainer.style.overflow = 'hidden';
        grandContainer.style.position = 'relative';

        // Create single header
        const header = document.createElement('div');
        header.style.padding = mobile ? '10px 12px' : '12px 15px';
        header.style.cursor = 'pointer';
        header.style.userSelect = 'none';
        header.style.background = colors.statBoxBg;
        header.style.borderLeft = '3px solid ' + colors.primary; // Blue left border
        header.style.transition = 'background-color 0.2s ease';

        // Create header content container
        const headerContent = document.createElement('div');
        const currentSeller = sellerData.sellers[sellerData.activeSeller];
        const userInfo = extractUserInfo(currentSeller.name);

        if (mobile) {
            // Mobile: Clean layout with buyer info on third line
            headerContent.style.cssText = 'display: flex; justify-content: space-between; align-items: center; width: 100%;';

            const titleSpan = document.createElement('span');
            titleSpan.style.fontWeight = 'bold';
            titleSpan.style.fontSize = '14px';
            titleSpan.style.color = colors.textPrimary;
            titleSpan.textContent = 'Total Rewards';

            // Create right-aligned content area with just blue value (clean first line)
            const rightContent = document.createElement('div');
            rightContent.style.cssText = 'display: flex; align-items: center; gap: 6px;';

            const blueValue = document.createElement('span');
            blueValue.style.color = colors.primary;
            blueValue.style.fontWeight = 'bold';
            blueValue.style.fontSize = '14px';
            blueValue.textContent = grandTotalValue > 0 ? numberFormatter(grandTotalValue, 2) : '?';

            // Conditional arrow for alignment consistency with faction panels
            const expandArrow = document.createElement('span');
            expandArrow.id = 'grand-total-expand-icon';
            if (SETTINGS.showIndirectRewards) {
                // Visible, functional arrow
                expandArrow.style.cssText = 'transition: transform 0.2s ease; font-size: 12px; color: ' + colors.primary + '; font-weight: bold; width: 12px; text-align: center; display: inline-block; cursor: pointer;';
            } else {
                // Hidden arrow for layout consistency
                expandArrow.style.cssText = 'transition: transform 0.2s ease; font-size: 12px; color: ' + colors.primary + '; visibility: hidden; font-weight: bold; width: 12px; text-align: center; display: inline-block;';
            }
            expandArrow.innerHTML = getExpandArrow(false);

            rightContent.appendChild(blueValue);
            rightContent.appendChild(expandArrow);
            headerContent.appendChild(titleSpan);
            headerContent.appendChild(rightContent);

            // Apply desktop wrapper pattern for mobile
            header.style.display = 'flex';
            header.style.justifyContent = 'space-between';
            header.style.alignItems = 'flex-start'; // Allow for multi-line content

            // Always use wrapper pattern for mobile to add buyer info on third line
            const headerWrapper = document.createElement('div');
            headerWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: flex-start;';

            // Move title to wrapper
            headerWrapper.appendChild(headerContent);

            // Add API comparison line if needed (second line)
            if (SETTINGS.showApiValues && combinedApiTotal > 0) {
                const percentDiff = grandTotalValue > 0 ? ((grandTotalValue - combinedApiTotal) / combinedApiTotal * 100) : 0;

                if (Math.abs(percentDiff) > 0.1) {
                    const apiLine = document.createElement('div');
                    apiLine.style.cssText = 'margin-top: 4px; font-size: 11px; color: ' + colors.textMuted + '; font-weight: normal;';

                    let arrow = '';
                    let arrowColor = colors.textMuted;
                    if (percentDiff > 0) {
                        arrow = ' ' + getMobileArrow(true) + ' ';
                        arrowColor = colors.success;
                    } else {
                        arrow = ' ' + getMobileArrow(false) + ' ';
                        arrowColor = colors.danger;
                    }

                    const apiSpan = document.createElement('span');
                    apiSpan.style.cssText = 'font-size: 11px; color: ' + colors.textMuted + '; font-weight: normal;';
                    apiSpan.innerHTML = '<span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(combinedApiTotal, 2);

                    apiLine.appendChild(apiSpan);
                    headerWrapper.appendChild(apiLine);
                }
            }

            // Add buyer info line (third line) - consistent spacing and handle missing buyer
            const buyerLine = document.createElement('div');
            buyerLine.style.cssText = 'margin-top: 4px; font-size: 11px; color: ' + colors.textMuted + '; font-weight: normal;';

            // Buyer info removed - now handled by trader selector above

            header.appendChild(headerWrapper);
            header.appendChild(rightContent);
        } else {
            // Desktop: Apply new layout matching faction headers
            const titleSpan = document.createElement('span');
            titleSpan.style.fontWeight = 'bold';
            titleSpan.style.fontSize = '16px';
            titleSpan.style.color = colors.textPrimary;
            titleSpan.style.marginRight = '8px';
            titleSpan.textContent = 'Total Rewards';
            headerContent.appendChild(titleSpan);

            // Create right-aligned content area for buyer info and value
            const rightContent = document.createElement('div');
            rightContent.style.cssText = 'display: flex; align-items: center; gap: 8px; flex: 1; justify-content: flex-end;';

            // Buyer info removed - now handled by trader selector above

            // Add blue total value
            const valueSpan = document.createElement('span');
            valueSpan.style.color = colors.primary;
            valueSpan.style.fontWeight = 'bold';
            valueSpan.style.fontSize = '16px';
            valueSpan.style.marginRight = '8px'; // FIXED: Add gap before invisible arrow to match faction headers
            valueSpan.textContent = grandTotalValue > 0 ? numberFormatter(grandTotalValue, 2) : '?';

            // Conditional arrow for desktop layout
            const desktopExpandArrow = document.createElement('span');
            desktopExpandArrow.id = 'grand-total-expand-icon-desktop';
            desktopExpandArrow.style.transition = 'transform 0.2s ease';
            desktopExpandArrow.style.fontSize = '14px';
            desktopExpandArrow.style.color = colors.primary;
            desktopExpandArrow.style.fontWeight = 'bold';
            desktopExpandArrow.style.width = '14px';
            desktopExpandArrow.style.textAlign = 'center';
            desktopExpandArrow.style.display = 'inline-block';

            if (SETTINGS.showIndirectRewards) {
                // Visible, functional arrow
                desktopExpandArrow.style.cursor = 'pointer';
            } else {
                // Hidden but maintains layout space
                desktopExpandArrow.style.visibility = 'hidden';
            }
            desktopExpandArrow.innerHTML = getExpandArrow(false);

            rightContent.appendChild(valueSpan);
            rightContent.appendChild(desktopExpandArrow);

            // Set up flex layout
            header.style.display = 'flex';
            header.style.justifyContent = 'space-between';
            header.style.alignItems = 'flex-start'; // Allow for multi-line content

            // Handle API comparison on second line if enabled
            if (SETTINGS.showApiValues && combinedApiTotal > 0) {
                const percentDiff = grandTotalValue > 0 ? ((grandTotalValue - combinedApiTotal) / combinedApiTotal * 100) : 0;

                if (Math.abs(percentDiff) > 0.1) {
                    // Create container for header content with API line
                    const headerWrapper = document.createElement('div');
                    headerWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: flex-start;';

                    // Move title to wrapper
                    headerWrapper.appendChild(headerContent);

                    // Add API comparison on second line
                    const apiLine = document.createElement('div');
                    apiLine.style.cssText = 'margin-top: 4px; font-size: 12px; color: ' + colors.textMuted + '; font-weight: normal;';

                    let arrow = '';
                    let arrowColor = colors.textMuted;
                    if (percentDiff > 0) {
                        arrow = ' ' + getMobileArrow(true) + ' ';
                        arrowColor = colors.success;
                    } else {
                        arrow = ' ' + getMobileArrow(false) + ' ';
                        arrowColor = colors.danger;
                    }

                    apiLine.innerHTML = '<span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(combinedApiTotal, 2);
                    headerWrapper.appendChild(apiLine);

                    header.appendChild(headerWrapper);
                    header.appendChild(rightContent);
                } else {
                    // No API comparison, simpler layout
                    header.appendChild(headerContent);
                    header.appendChild(rightContent);
                }
            } else {
                // No API values, simpler layout
                header.appendChild(headerContent);
                header.appendChild(rightContent);
            }
        }

        // Create details section for indirect rewards (only if enabled)
        if (SETTINGS.showIndirectRewards) {
            const details = document.createElement('div');
            details.id = 'grand-total-details';
            details.style.display = 'none';
            details.style.padding = mobile ? '12px 12px 8px 12px' : '12px 15px 8px 15px';
            details.style.background = colors.panelBg;
            details.style.borderLeft = '3px solid ' + colors.primary;

            // Add click handler to header for expansion
            header.addEventListener('click', function() {
                toggleGrandTotalExpansion();
            });

            grandContainer.appendChild(header);
            grandContainer.appendChild(details);
        } else {
            grandContainer.appendChild(header);
        }
        return grandContainer;
    }

    function populateIndirectRewards() {
        const details = document.getElementById('grand-total-details');
        if (!details || !SETTINGS.showIndirectRewards || !rewardData || rewardData.length !== 2) {
            return;
        }

        // Clear existing content
        details.innerHTML = '';

        const colors = getThemeColors();
        const mobile = isMobile();

        // Create title for the section
        const sectionTitle = document.createElement('div');
        sectionTitle.style.cssText = 'margin-bottom: 12px; color: ' + colors.textPrimary + '; font-size: 12px;';
        sectionTitle.textContent = 'Other Rewards';
        details.appendChild(sectionTitle);

        // Calculate and display indirect rewards for each faction
        for (let i = 0; i < 2; i++) {
            const faction = rewardData[i];
            if (!faction) continue;

            // Create faction container
            const factionDiv = document.createElement('div');
            factionDiv.style.cssText = 'background: ' + colors.statBoxBg + '; padding: ' + (mobile ? '8px' : '10px') + '; border-radius: 3px; margin-bottom: 8px; border-left: 3px solid ' + colors.primary + '; border: 1px solid ' + colors.statBoxBorder + '; box-shadow: ' + colors.statBoxShadow + ';';

            // Faction name
            const factionName = document.createElement('div');
            factionName.style.cssText = 'font-weight: bold; margin-bottom: 6px; color: ' + colors.textPrimary + '; font-size: ' + (mobile ? '12px' : '13px') + ';';
            factionName.textContent = faction.factionName;
            factionDiv.appendChild(factionName);

            let indirectTotal = 0;

            // Respect rewards
            if (faction.respectAmount > 0) {
                const respectValue = faction.respectAmount * SETTINGS.respectValue;
                indirectTotal += respectValue;

                const respectRow = document.createElement('div');
                respectRow.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; font-size: ' + (mobile ? '11px' : '12px') + ';';

                const respectLabel = document.createElement('span');
                respectLabel.style.color = colors.textSecondary;
                respectLabel.textContent = formatNumberWithCommas(faction.respectAmount) + ' respect x' + formatNumberWithCommas(SETTINGS.respectValue);

                const respectValueSpan = document.createElement('span');
                respectValueSpan.style.cssText = 'color: ' + colors.primary + '; font-weight: bold;';
                respectValueSpan.textContent = numberFormatter(respectValue, 2);

                respectRow.appendChild(respectLabel);
                respectRow.appendChild(respectValueSpan);
                factionDiv.appendChild(respectRow);
            }

            // Points rewards (extract from items)
            if (rawRewardData[i] && rawRewardData[i].items) {
                const pointsItems = rawRewardData[i].items.filter(item => item.type === 'points');
                for (const pointsItem of pointsItems) {
                    if (pointsItem.quantity > 0) {
                        const pointsValue = pointsItem.quantity * pointsItem.pointValue;
                        indirectTotal += pointsValue;

                        const pointsRow = document.createElement('div');
                        pointsRow.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; font-size: ' + (mobile ? '11px' : '12px') + ';';

                        const pointsLabel = document.createElement('span');
                        pointsLabel.style.color = colors.textSecondary;
                        pointsLabel.textContent = formatNumberWithCommas(pointsItem.quantity) + ' points x' + formatNumberWithCommas(pointsItem.pointValue);

                        const pointsValueSpan = document.createElement('span');
                        pointsValueSpan.style.cssText = 'color: ' + colors.primary + '; font-weight: bold;';
                        pointsValueSpan.textContent = numberFormatter(pointsValue, 2);

                        pointsRow.appendChild(pointsLabel);
                        pointsRow.appendChild(pointsValueSpan);
                        factionDiv.appendChild(pointsRow);
                    }
                }
            }

            // Faction total
            if (indirectTotal > 0) {
                const totalRow = document.createElement('div');
                totalRow.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-top: 8px; padding-top: 6px; border-top: 1px solid ' + colors.statBoxBorder + '; font-weight: bold; font-size: ' + (mobile ? '12px' : '13px') + ';';

                const totalLabel = document.createElement('span');
                totalLabel.style.color = colors.textPrimary;
                totalLabel.textContent = 'Faction Total';

                const totalValueSpan = document.createElement('span');
                totalValueSpan.style.cssText = 'color: ' + colors.success + '; font-weight: bold;';
                totalValueSpan.textContent = numberFormatter(indirectTotal, 2);

                totalRow.appendChild(totalLabel);
                totalRow.appendChild(totalValueSpan);
                factionDiv.appendChild(totalRow);
            } else {
                // No indirect rewards
                const noRewardsDiv = document.createElement('div');
                noRewardsDiv.style.cssText = 'font-style: italic; color: ' + colors.textMuted + '; font-size: ' + (mobile ? '11px' : '12px') + ';';
                noRewardsDiv.textContent = 'No other rewards';
                factionDiv.appendChild(noRewardsDiv);
            }

            details.appendChild(factionDiv);
        }
    }

    function toggleGrandTotalExpansion() {
        const details = document.getElementById('grand-total-details');
        const mobileIcon = document.getElementById('grand-total-expand-icon');
        const desktopIcon = document.getElementById('grand-total-expand-icon-desktop');

        if (details && details.style.display === 'none') {
            details.style.display = 'block';
            // Populate content when expanding
            populateIndirectRewards();

            if (mobileIcon) {
                mobileIcon.style.transform = 'rotate(180deg)';
                mobileIcon.innerHTML = getExpandArrow(true);
            }
            if (desktopIcon) {
                desktopIcon.style.transform = 'rotate(180deg)';
                desktopIcon.innerHTML = getExpandArrow(true);
            }
        } else if (details) {
            details.style.display = 'none';
            if (mobileIcon) {
                mobileIcon.style.transform = 'rotate(0deg)';
                mobileIcon.innerHTML = getExpandArrow(false);
            }
            if (desktopIcon) {
                desktopIcon.style.transform = 'rotate(0deg)';
                desktopIcon.innerHTML = getExpandArrow(false);
            }
        }
    }

    function createCompactContainer(totalValue, index, grandTotalValue, factionName, allRewardData) {
        const colors = getThemeColors();
        const mobile = isMobile();
        const container = document.createElement('div');

        // Calculate distribution percentage for this reward
        const percentage = grandTotalValue > 0 ? (totalValue / grandTotalValue * 100).toFixed(1) : '?';

        // Determine winner/loser and set border color with progressive fallback
        let borderColor;
        let isWinner = false;

        if (percentage !== '?' && parseFloat(percentage) > 50) {
            // Primary method: Use percentage-based determination when prices available
            isWinner = true;
            borderColor = colors.success;
        } else if (percentage !== '?' && parseFloat(percentage) <= 50) {
            // Primary method: Loser based on percentage
            isWinner = false;
            borderColor = colors.danger;
        } else if (allRewardData && allRewardData.length === 2) {
            // Secondary method: Use ranking-based determination when no prices
            const faction0Outcome = allRewardData[0].rankingOutcome;
            const faction1Outcome = allRewardData[1].rankingOutcome;

            console.log("RWAwardValue: Ranking outcomes - Faction 0:", faction0Outcome, "Faction 1:", faction1Outcome);

            // If one faction ranked down, they're the loser
            if (faction0Outcome === 'loser' && faction1Outcome !== 'loser') {
                // Faction 0 is loser, faction 1 is winner
                isWinner = index === 1;
                borderColor = index === 1 ? colors.success : colors.danger;
                console.log("RWAwardValue: Faction 0 lost, faction 1 won. Current index:", index, "isWinner:", isWinner);
            } else if (faction1Outcome === 'loser' && faction0Outcome !== 'loser') {
                // Faction 1 is loser, faction 0 is winner
                isWinner = index === 0;
                borderColor = index === 0 ? colors.success : colors.danger;
                console.log("RWAwardValue: Faction 1 lost, faction 0 won. Current index:", index, "isWinner:", isWinner);
            } else {
                // Tertiary fallback: Cannot determine winner/loser
                borderColor = colors.primary; // Use blue as neutral
                console.log("RWAwardValue: Cannot determine winner/loser from ranking, using blue");
            }
        } else {
            // Tertiary fallback: Cannot determine winner/loser
            borderColor = colors.primary; // Use blue as neutral
        }

        // Set container styles
        container.style.background = colors.panelBg;
        container.style.border = '1px solid ' + colors.panelBorder;
        container.style.borderRadius = '5px';
        container.style.margin = mobile ? '5px 0' : '10px 0';
        container.style.fontFamily = '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif';
        container.style.color = colors.textPrimary;
        container.style.boxShadow = colors.statBoxShadow;
        container.style.overflow = 'hidden';
        container.style.position = 'relative';

        // Create header
        const header = document.createElement('div');
        header.id = 'rw-reward-' + index;
        header.style.padding = mobile ? '10px 12px' : '12px 15px';
        header.style.cursor = 'pointer';
        header.style.userSelect = 'none';
        header.style.display = 'flex';
        header.style.justifyContent = 'space-between';
        header.style.alignItems = 'center';
        header.style.background = colors.statBoxBg;
        header.style.borderLeft = '3px solid ' + borderColor;
        header.style.borderBottom = '1px solid ' + colors.statBoxBorder;
        header.style.transition = 'background-color 0.2s ease';

        // Create header content
        const headerContent = document.createElement('div');
        const titleSpan = document.createElement('span');
        titleSpan.style.fontWeight = 'bold';
        titleSpan.style.fontSize = mobile ? '14px' : '16px';
        titleSpan.style.color = colors.textPrimary;
        titleSpan.style.marginRight = '8px';

        if (mobile) {
            // Mobile: working structure
            headerContent.style.cssText = 'display: flex; justify-content: space-between; align-items: center; width: 100%;';

            const titleSpan = document.createElement('span');
            titleSpan.style.fontWeight = 'bold';
            titleSpan.style.fontSize = '14px';
            titleSpan.style.color = colors.textPrimary;

            // Truncate faction name on mobile if longer than 18 characters
            const displayName = factionName.length > 18 ? factionName.substring(0, 18) + '...' : factionName;
            titleSpan.innerHTML = displayName + ' <span style="color: ' + borderColor + ';">(' + percentage + '%)</span>';

            // Create right-aligned content area
            const rightContent = document.createElement('div');
            rightContent.style.cssText = 'display: flex; align-items: center; gap: 6px;';

            const blueValue = document.createElement('span');
            blueValue.style.color = colors.primary;
            blueValue.style.fontWeight = 'bold';
            blueValue.style.fontSize = '14px';
            blueValue.textContent = totalValue > 0 ? numberFormatter(totalValue, 2) : '?';

            const expandIcon = document.createElement('span');
            expandIcon.id = 'expand-icon-' + index;
            expandIcon.style.cssText = 'transition: transform 0.2s ease; font-size: 12px; color: ' + colors.primary + '; font-weight: bold; width: 12px; text-align: center; display: inline-block;';
            expandIcon.innerHTML = getExpandArrow(false);

            rightContent.appendChild(blueValue);
            rightContent.appendChild(expandIcon);
            headerContent.appendChild(titleSpan);
            headerContent.appendChild(rightContent);

            // Apply desktop wrapper pattern for mobile API comparison
            header.style.display = 'flex';
            header.style.justifyContent = 'space-between';
            header.style.alignItems = 'flex-start'; // Allow for multi-line content

            // Add API comparison using desktop wrapper pattern
            if (SETTINGS.showApiValues && rewardData[index] && rewardData[index].apiTotalValue > 0) {
                const apiValue = rewardData[index].apiTotalValue;
                const customValue = rewardData[index].totalValue;
                const percentDiff = customValue > 0 ? ((customValue - apiValue) / apiValue * 100) : 0;

                if (Math.abs(percentDiff) > 0.1) {
                    // Create container for header content with API line
                    const headerWrapper = document.createElement('div');
                    headerWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: flex-start;';

                    // Move title to wrapper
                    headerWrapper.appendChild(headerContent);

                    // Add API comparison on second line
                    const apiLine = document.createElement('div');
                    apiLine.style.cssText = 'margin-top: 4px; font-size: 11px; color: ' + colors.textMuted + '; font-weight: normal;';

                    let arrow = '';
                    let arrowColor = colors.textMuted;
                    if (percentDiff > 0) {
                        arrow = ' ' + getMobileArrow(true) + ' ';
                        arrowColor = colors.success;
                    } else {
                        arrow = ' ' + getMobileArrow(false) + ' ';
                        arrowColor = colors.danger;
                    }

                    apiLine.innerHTML = '<span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(apiValue, 2);
                    headerWrapper.appendChild(apiLine);

                    header.appendChild(headerWrapper);
                    header.appendChild(rightContent);
                } else {
                    // No API comparison, simpler layout
                    header.appendChild(headerContent);
                    header.appendChild(rightContent);
                }
            } else {
                // No API values, simpler layout
                header.appendChild(headerContent);
                header.appendChild(rightContent);
            }
        } else {
            // Desktop: Single line layout with percentage moved to left
            titleSpan.innerHTML = factionName + ' Rewards <span style="color: ' + borderColor + ';">(' + percentage + '%)</span>';
            headerContent.appendChild(titleSpan);

            // Desktop: Create right-aligned content area for blue value only
            const rightContent = document.createElement('div');
            rightContent.style.cssText = 'display: flex; align-items: center; gap: 8px; flex: 1; justify-content: flex-end;';

            // Add blue total value (percentage now on left with title)
            const valueSpan = document.createElement('span');
            valueSpan.style.color = colors.primary;
            valueSpan.style.fontWeight = 'bold';
            valueSpan.style.fontSize = '16px';
            valueSpan.style.marginRight = '8px'; // Gap before expand arrow
            valueSpan.textContent = totalValue > 0 ? numberFormatter(totalValue, 2) : '?';

            rightContent.appendChild(valueSpan);

            // Create expand icon
            const expandIcon = document.createElement('span');
            expandIcon.id = 'expand-icon-' + index;
            expandIcon.style.transition = 'transform 0.2s ease';
            expandIcon.style.fontSize = '14px';
            expandIcon.style.color = colors.primary;
            expandIcon.style.fontWeight = 'bold';
            expandIcon.style.width = '14px';
            expandIcon.style.textAlign = 'center';
            expandIcon.style.display = 'inline-block';
            expandIcon.innerHTML = getExpandArrow(false); // Start collapsed - USE innerHTML for HTML entities

            rightContent.appendChild(expandIcon);

            // Modify header to be flex container
            header.style.display = 'flex';
            header.style.justifyContent = 'space-between';
            header.style.alignItems = 'flex-start'; // Allow for multi-line content

            // Add API comparison on second line if enabled
            if (SETTINGS.showApiValues && rewardData[index] && rewardData[index].apiTotalValue > 0) {
                const apiValue = rewardData[index].apiTotalValue;
                const customValue = rewardData[index].totalValue;
                const percentDiff = customValue > 0 ? ((customValue - apiValue) / apiValue * 100) : 0;

                if (Math.abs(percentDiff) > 0.1) {
                    // Create container for header content with API line
                    const headerWrapper = document.createElement('div');
                    headerWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: flex-start;';

                    // Move title to wrapper
                    headerWrapper.appendChild(headerContent);

                    // Add API comparison on second line
                    const apiLine = document.createElement('div');
                    apiLine.style.cssText = 'margin-top: 4px; font-size: 12px; color: ' + colors.textMuted + '; font-weight: normal;';

                    let arrow = '';
                    let arrowColor = colors.textMuted;
                    if (percentDiff > 0) {
                        arrow = ' ' + getMobileArrow(true) + ' ';
                        arrowColor = colors.success;
                    } else {
                        arrow = ' ' + getMobileArrow(false) + ' ';
                        arrowColor = colors.danger;
                    }

                    apiLine.innerHTML = '<span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(apiValue, 2);
                    headerWrapper.appendChild(apiLine);

                    header.appendChild(headerWrapper);
                    header.appendChild(rightContent);
                } else {
                    // No API comparison, simpler layout
                    header.appendChild(headerContent);
                    header.appendChild(rightContent);
                }
            } else {
                // No API values, simpler layout
                header.appendChild(headerContent);
                header.appendChild(rightContent);
            }
        }

        // Create details section
        const details = document.createElement('div');
        details.id = 'rw-details-' + index;
        details.style.display = 'none';
        details.style.padding = mobile ? '12px 12px 8px 12px' : '12px 15px 8px 15px';
        details.style.background = colors.panelBg;
        details.style.borderLeft = '3px solid ' + borderColor;

        container.appendChild(header);
        container.appendChild(details);

        return container;
    }

    function toggleExpansion(index) {
        const details = document.getElementById('rw-details-' + index);
        const icon = document.getElementById('expand-icon-' + index);

        if (details.style.display === 'none') {
            details.style.display = 'block';
            icon.style.transform = 'rotate(180deg)';
            icon.innerHTML = getExpandArrow(true); // USE innerHTML for HTML entities
        } else {
            details.style.display = 'none';
            icon.style.transform = 'rotate(0deg)';
            icon.innerHTML = getExpandArrow(false); // USE innerHTML for HTML entities
        }
    }

    async function valueRow(row, index) {
        console.log("RWAwardValue: Processing row", index);

        // Extract faction name and ranking outcome from the row text
        let factionName = "Unknown Faction";
        let rankingOutcome = null;
        const rowText = row.innerText;
        const factionMatch = rowText.match(/^([A-Za-z0-9\.\s_'-]+)\s+(ranked\s+(up|down)\s+from|remained\s+at)/);
        if (factionMatch) {
            factionName = factionMatch[1].trim();
            const rankingText = factionMatch[2].toLowerCase();

            if (rankingText.includes('ranked down')) {
                rankingOutcome = 'loser';
            } else if (rankingText.includes('ranked up') || rankingText.includes('remained at')) {
                rankingOutcome = 'winner';
            }
        }
        console.log("RWAwardValue: Extracted faction name:", factionName, "ranking outcome:", rankingOutcome);

        // Extract respect amount before "bonus respect, "
        let respectAmount = 0;
        const respectMatch = row.innerText.match(/(\d{1,3}(?:,\d{3})*)\s+bonus respect,/);
        if (respectMatch) {
            respectAmount = parseInt(respectMatch[1].replace(/,/g, ''));
            console.log("RWAwardValue: Extracted respect amount:", respectAmount);
        }

        let startingIndex = row.innerText.indexOf("bonus respect, ") + 15;
        if (startingIndex === 14) {
            console.error("RWAwardValue: Could not find 'bonus respect, ' in row text");
            rewardData[index] = {
                totalValue: 0,
                totalBB: 0,
                itemElements: [],
                factionName: factionName,
                respectAmount: respectAmount,
                row: row
            };
            return;
        }

        let awardsString = row.innerText.substring(startingIndex, row.innerText.length);
        console.log("RWAwardValue: Awards string:", awardsString);

        let rowTotalValue = 0;
        let rawItems = []; // Store raw item data for recalculation
        const colors = getThemeColors();
        const mobile = isMobile();

        const items = awardsString.split(", ");
        let itemElements = [];

        for (const item of items) {
            console.log("RWAwardValue: Processing item:", item);
            let itemValue = 0;
            let itemBB = 0;
            let itemName = item;
            let rawItem = null;

            if (item.includes("points")) {
                const pointsAmount = parseInt(item.substring(0, item.indexOf(" ")).replace(",", ""));
                if (pointsAmount > 0) {
                    let pointValueForCalc;
                    if (API_KEY === 'YOUR_API_KEY_HERE' || !API_KEY) {
                        pointValueForCalc = 31300;
                        itemValue = 31300 * pointsAmount;
                        console.log("RWAwardValue: Using mock point value");
                    } else {
                        pointValueForCalc = await fetchPointValue();
                        itemValue = pointValueForCalc * pointsAmount;
                        console.log("RWAwardValue: Using API point value:", pointValueForCalc);
                    }

                    rawItem = {
                        type: 'points',
                        quantity: pointsAmount,
                        pointValue: pointValueForCalc
                    };

                    rowTotalValue += itemValue;
                    itemName = item + ' (' + numberFormatter(itemValue) + ' total)';
                } else {
                    console.log("RWAwardValue: Skipping 0 points");
                    continue;
                }
            } else if (item.includes("Cache")) {
                console.log("RWAwardValue: Found cache item:", item);
                let cacheValue = 0;
                let bbValue = 0;
                let cacheType = '';
                let defaultValue = 0;

                if (item.includes("Armor Cache")) {
                    cacheType = 'armorCache';
                    defaultValue = 312400000;
                } else if (item.includes("Heavy Arms Cache")) {
                    cacheType = 'heavyArmsCache';
                    defaultValue = 250000000;
                } else if (item.includes("Medium Arms Cache")) {
                    cacheType = 'mediumArmsCache';
                    defaultValue = 191000000;
                } else if (item.includes("Melee Cache")) {
                    cacheType = 'meleeCache';
                    defaultValue = 139500000;
                } else if (item.includes("Small Arms Cache")) {
                    cacheType = 'smallArmsCache';
                    defaultValue = 111400000;
                }

                const quantity = parseInt(item.substring(0, item.indexOf("x")));

                // Determine price source based on settings and availability
                const customPrice = getCustomPrice(cacheType);
                const hasCustomPrice = customPrice > 0;
                const hasApiPrice = apiPriceCache.data && apiPriceCache.data[cacheType];
                const hasValidApiKey = (API_KEY && API_KEY !== 'YOUR_API_KEY_HERE') || PDA_VALIDATED;

                // DEBUG: Log pricing decision
                console.log(`RW DEBUG: ${cacheType} - customPrice: ${customPrice}, hasCustomPrice: ${hasCustomPrice}, hasApiPrice: ${hasApiPrice}, showCustomPrices: ${SETTINGS.showCustomPrices}, hasValidApiKey: ${hasValidApiKey}`);
                if (hasApiPrice) {
                    console.log(`RW DEBUG: ${cacheType} - API price available: ${apiPriceCache.data[cacheType]}`);
                }

                // Priority: Custom prices (if enabled) > API prices (if available) > No pricing (show "?")
                if (SETTINGS.showCustomPrices && hasCustomPrice) {
                    cacheValue = customPrice;
                    itemValue = cacheValue * quantity;
                    console.log(`RW DEBUG: ${cacheType} - Using custom price: ${cacheValue}`);
                } else if (hasApiPrice && hasValidApiKey) {
                    cacheValue = apiPriceCache.data[cacheType];
                    itemValue = cacheValue * quantity;
                    console.log(`RW DEBUG: ${cacheType} - Using API price: ${cacheValue}`);
                } else {
                    // No prices available - show "?"
                    cacheValue = 0;
                    itemValue = 0;
                    console.log(`RW DEBUG: ${cacheType} - No pricing available, showing ?`);
                }

                rawItem = {
                    type: 'cache',
                    cacheType: cacheType,
                    quantity: quantity,
                    defaultValue: defaultValue
                };

                rowTotalValue += itemValue;
                // Only format value if we have a price, otherwise show just the item name
                if (itemValue > 0) {
                    itemName = item + ' (' + numberFormatter(itemValue) + ' total)';
                } else {
                    itemName = item; // Just show the item name without pricing
                }
            }

            if (rawItem) {
                rawItems.push(rawItem);
            }

            // Create item display element with ENHANCED FORMAT
                const itemDiv = document.createElement('div');
                itemDiv.style.background = colors.statBoxBg;
                itemDiv.style.padding = mobile ? '8px' : '10px';
                itemDiv.style.borderRadius = '3px';
                itemDiv.style.marginBottom = '6px';
                itemDiv.style.borderLeft = '3px solid ' + colors.primary;
                itemDiv.style.border = '1px solid ' + colors.statBoxBorder;
                itemDiv.style.boxShadow = colors.statBoxShadow;
                itemDiv.style.display = 'flex';
                itemDiv.style.justifyContent = 'space-between';
                itemDiv.style.alignItems = 'center';
                itemDiv.style.fontSize = mobile ? '12px' : '13px';

                const nameSpan = document.createElement('span');
                nameSpan.style.color = colors.textSecondary;

                // NEW ENHANCED FORMAT for item names - USE CUSTOM PRICES
                let enhancedItemName = '';
                let cacheTypeForApi = '';
                if (item.includes("Cache")) {
                    // Extract cache details for enhanced format
                    const quantity = parseInt(item.substring(0, item.indexOf("x")));
                    let cacheTypeName = '';
                    let individualPrice = 0;

                    if (item.includes("Armor Cache")) {
                        cacheTypeName = 'Armor';
                        cacheTypeForApi = 'armorCache';
                        const customPrice = getCustomPrice('armorCache');
                        const hasCustomPrice = customPrice > 0;
                        const hasApiPrice = SETTINGS.showApiValues && apiPriceCache.data && apiPriceCache.data['armorCache'];

                        if (SETTINGS.showCustomPrices && hasCustomPrice) {
                            individualPrice = customPrice;
                        } else if (hasApiPrice) {
                            individualPrice = apiPriceCache.data['armorCache'];
                        } else {
                            individualPrice = 0;
                        }
                    } else if (item.includes("Heavy Arms Cache")) {
                        cacheTypeName = 'Heavy Arms';
                        cacheTypeForApi = 'heavyArmsCache';
                        const customPrice = getCustomPrice('heavyArmsCache');
                        const hasCustomPrice = customPrice > 0;
                        const hasApiPrice = SETTINGS.showApiValues && apiPriceCache.data && apiPriceCache.data['heavyArmsCache'];

                        if (SETTINGS.showCustomPrices && hasCustomPrice) {
                            individualPrice = customPrice;
                        } else if (hasApiPrice) {
                            individualPrice = apiPriceCache.data['heavyArmsCache'];
                        } else {
                            individualPrice = 0;
                        }
                    } else if (item.includes("Medium Arms Cache")) {
                        cacheTypeName = 'Medium Arms';
                        cacheTypeForApi = 'mediumArmsCache';
                        const customPrice = getCustomPrice('mediumArmsCache');
                        const hasCustomPrice = customPrice > 0;
                        const hasApiPrice = SETTINGS.showApiValues && apiPriceCache.data && apiPriceCache.data['mediumArmsCache'];

                        if (SETTINGS.showCustomPrices && hasCustomPrice) {
                            individualPrice = customPrice;
                        } else if (hasApiPrice) {
                            individualPrice = apiPriceCache.data['mediumArmsCache'];
                        } else {
                            individualPrice = 0;
                        }
                    } else if (item.includes("Melee Cache")) {
                        cacheTypeName = 'Melee';
                        cacheTypeForApi = 'meleeCache';
                        const customPrice = getCustomPrice('meleeCache');
                        const hasCustomPrice = customPrice > 0;
                        const hasApiPrice = SETTINGS.showApiValues && apiPriceCache.data && apiPriceCache.data['meleeCache'];

                        if (SETTINGS.showCustomPrices && hasCustomPrice) {
                            individualPrice = customPrice;
                        } else if (hasApiPrice) {
                            individualPrice = apiPriceCache.data['meleeCache'];
                        } else {
                            individualPrice = 0;
                        }
                    } else if (item.includes("Small Arms Cache")) {
                        cacheTypeName = 'Small Arms';
                        cacheTypeForApi = 'smallArmsCache';
                        const customPrice = getCustomPrice('smallArmsCache');
                        const hasCustomPrice = customPrice > 0;
                        const hasApiPrice = SETTINGS.showApiValues && apiPriceCache.data && apiPriceCache.data['smallArmsCache'];

                        if (SETTINGS.showCustomPrices && hasCustomPrice) {
                            individualPrice = customPrice;
                        } else if (hasApiPrice) {
                            individualPrice = apiPriceCache.data['smallArmsCache'];
                        } else {
                            individualPrice = 0;
                        }
                    }

                    if (mobile) {
                        // Mobile: Simplified layout without quantity breakdown
                        if (quantity === 1) {
                            enhancedItemName = '1x ' + cacheTypeName + ' Cache';
                        } else {
                            enhancedItemName = quantity + 'x ' + cacheTypeName + ' Cache';
                        }

                        // Add API comparison if available and custom prices are enabled
                        if (SETTINGS.showCustomPrices && SETTINGS.showApiValues && item.includes("Cache") && Object.keys(apiPriceCache.data).length > 0 && cacheTypeForApi && apiPriceCache.data[cacheTypeForApi] && individualPrice > 0) {
                            const apiValue = apiPriceCache.data[cacheTypeForApi] * quantity;
                            const customValue = itemValue;
                            const percentDiff = customValue > 0 ? ((customValue - apiValue) / apiValue * 100) : 0;

                            if (Math.abs(percentDiff) > 0.1) {
                                let arrow = '';
                                let arrowColor = colors.textMuted;
                                if (percentDiff > 0) {
                                    arrow = ' ' + getMobileArrow(true) + ' ';
                                    arrowColor = colors.success;
                                } else {
                                    arrow = ' ' + getMobileArrow(false) + ' ';
                                    arrowColor = colors.danger;
                                }
                                enhancedItemName += '<br><span style="font-size: 11px; color: ' + colors.textMuted + ';"><span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(apiValue, 2) + '</span>';
                            }
                        }
                    } else {
                        // Desktop: Single line layout
                        if (individualPrice > 0) {
                            if (quantity === 1) {
                                enhancedItemName = '1x ' + cacheTypeName + ' Cache (' + formatNumberWithCommas(individualPrice) + ')';
                            } else {
                                enhancedItemName = quantity + 'x ' + cacheTypeName + ' Cache (' + quantity + 'x ' + formatNumberWithCommas(individualPrice) + ')';
                            }
                        } else {
                            // No price available - show just quantity and cache name
                            if (quantity === 1) {
                                enhancedItemName = '1x ' + cacheTypeName + ' Cache';
                            } else {
                                enhancedItemName = quantity + 'x ' + cacheTypeName + ' Cache';
                            }
                        }
                    }
                } else {
                    // For points, use the existing format
                    if (mobile) {
                        enhancedItemName = itemName.replace(' (', '<br><span style="font-size: 11px; color: ' + colors.textMuted + ';">(') + '</span>';
                    } else {
                        enhancedItemName = itemName;
                    }
                    cacheTypeForApi = 'points';
                }

                nameSpan.innerHTML = enhancedItemName; // Use innerHTML for mobile line breaks

                const valueContainer = document.createElement('div');
                valueContainer.style.display = 'flex';
                valueContainer.style.alignItems = 'center';
                valueContainer.style.gap = '8px';

                // Add API comparison for cache items if enabled and API data available (DESKTOP ONLY)
                if (!mobile && SETTINGS.showCustomPrices && SETTINGS.showApiValues && item.includes("Cache") && Object.keys(apiPriceCache.data).length > 0 && cacheTypeForApi && apiPriceCache.data[cacheTypeForApi] && itemValue > 0) {
                    const quantity = parseInt(item.substring(0, item.indexOf("x")));
                    const apiValue = apiPriceCache.data[cacheTypeForApi] * quantity;
                    const customValue = itemValue;
                    const percentDiff = customValue > 0 ? ((customValue - apiValue) / apiValue * 100) : 0;

                    if (Math.abs(percentDiff) > 0.1) { // Only show if meaningful difference
                        // Create wrapper for name with API line below
                        const nameWrapper = document.createElement('div');
                        nameWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: flex-start;';

                        // Create main item name span
                        const mainNameSpan = document.createElement('span');
                        mainNameSpan.style.color = colors.textSecondary;
                        mainNameSpan.innerHTML = enhancedItemName;

                        // Create API comparison line with increased gap
                        const apiLine = document.createElement('div');
                        apiLine.style.cssText = 'margin-top: 4px; font-size: 11px; color: ' + colors.textMuted + '; font-weight: normal;';

                        let arrow = '';
                        let arrowColor = colors.textMuted;
                        if (percentDiff > 0) {
                            arrow = getMobileArrow(true) + ' ';
                            arrowColor = colors.success;
                        } else {
                            arrow = getMobileArrow(false) + ' ';
                            arrowColor = colors.danger;
                        }

                        apiLine.innerHTML = '<span style="color: ' + arrowColor + ';">' + arrow + Math.abs(percentDiff).toFixed(1) + '%</span> Market value ' + numberFormatter(apiValue, 2);

                        nameWrapper.appendChild(mainNameSpan);
                        nameWrapper.appendChild(apiLine);

                        // Adjust itemDiv to allow for multi-line content
                        itemDiv.style.alignItems = 'flex-start';
                        itemDiv.appendChild(nameWrapper);
                    } else {
                        // No significant API difference, use normal layout
                        nameSpan.innerHTML = enhancedItemName;
                        itemDiv.appendChild(nameSpan);
                    }
                } else {
                    // No API comparison or mobile view, use normal layout
                    nameSpan.innerHTML = enhancedItemName;
                    itemDiv.appendChild(nameSpan);
                }

                const valueSpan = document.createElement('span');
                valueSpan.style.color = colors.primary;
                valueSpan.style.fontWeight = 'bold';
                valueSpan.textContent = numberFormatter(itemValue, 2);

                valueContainer.appendChild(valueSpan);

                // Only add valueContainer if we haven't already added nameWrapper
                if (!itemDiv.children.length) {
                    itemDiv.appendChild(nameSpan);
                }
                itemDiv.appendChild(valueContainer);
                itemElements.push(itemDiv);

                // Store reference for updating during refresh
                if (rawItem) {
                    itemDiv.setAttribute('data-cache-type', rawItem.cacheType || 'points');
                    itemDiv.setAttribute('data-item-type', rawItem.type);
                }
        }

        console.log("RWAwardValue: Row", index, "total value:", rowTotalValue);
        rewardData[index] = {
            totalValue: rowTotalValue,
            itemElements: itemElements,
            factionName: factionName,
            respectAmount: respectAmount,
            rankingOutcome: rankingOutcome, // Store ranking outcome for winner/loser determination
            row: row
        };

        // Store raw data for recalculation
        rawRewardData[index] = {
            factionName: factionName,
            respectAmount: respectAmount,
            items: rawItems
        };
    }

    // FIXED CSS SELECTOR - robust partial matching
    const checkRows = async function() {
        console.log("RWAwardValue: Checking for rows...");

        // Try multiple selector strategies to find the reward rows
        let selectedElements = [];

        // Strategy 1: Use partial class name matching (most reliable)
        selectedElements = document.querySelectorAll("div[class*='memberBonusRow']");

        // Strategy 2: If that fails, try other patterns
        if (selectedElements.length === 0) {
            selectedElements = document.querySelectorAll("div[class*='bonusRow']");
        }

        // Strategy 3: Look for text patterns that indicate bonus rows
        if (selectedElements.length === 0) {
            const allDivs = document.querySelectorAll('div');
            selectedElements = Array.from(allDivs).filter(div => {
                const text = div.innerText || '';
                return text.includes('ranked up from') || text.includes('ranked down from');
            });
        }

        console.log("RWAwardValue: Found", selectedElements.length, "rows");

        if (selectedElements.length > 0) {
            console.log("RWAwardValue: First element text:", selectedElements[0].innerText);
        }

        if (selectedElements.length == 2) {
            console.log("RWAwardValue: Found both rows, processing...");
            clearInterval(timer);
            try {
                await valueRow(selectedElements[0], 0);
                await valueRow(selectedElements[1], 1);
                console.log("RWAwardValue: Data collected, creating containers...");
                setTimeout(function() { createAndDisplayContainers(); }, 100);
            } catch (error) {
                console.error("RWAwardValue: Error processing rows:", error);
            }
        }
    };

    // ========================================
    // SCRIPT INITIALIZATION
    // ========================================

    // Start checking for reward tables
    let timer = setInterval(checkRows, 200);

    // Start theme monitoring
    monitorThemeChanges();

    console.log("RWAwardValue: Script setup complete v3.1");
})();