GLIF Tools V2

A set of tools i use in glif.app

// ==UserScript==
// @name         GLIF Tools V2
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  A set of tools i use in glif.app
// @author       i12bp8
// @match        https://glif.app/*
// @run-at       document-start
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// ==/UserScript==

(function() {
    'use strict';

    // Modern SVG Icons
    const icons = {
        history: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M12 8v4l3 3"></path>
            <path d="M3.05 11a9 9 0 1 1 .5 4"></path>
        </svg>`,
        tools: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-code-slash" viewBox="0 0 16 16">
  <path d="M10.478 1.647a.5.5 0 1 0-.956-.294l-4 13a.5.5 0 0 0 .956.294zM4.854 4.146a.5.5 0 0 1 0 .708L1.707 8l3.147 3.146a.5.5 0 0 1-.708.708l-3.5-3.5a.5.5 0 0 1 0-.708l3.5-3.5a.5.5 0 0 1 .708 0m6.292 0a.5.5 0 0 0 0 .708L14.293 8l-3.147 3.146a.5.5 0 0 0 .708.708l3.5-3.5a.5.5 0 0 0 0-.708l-3.5-3.5a.5.5 0 0 1 .708 0"></path>
</svg>`,
        trash: `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M2.5 5h15M6.67 5V3.33a1.67 1.67 0 011.66-1.66h3.34a1.67 1.67 0 011.66 1.66V5m2.5 0v11.67a1.67 1.67 0 01-1.66 1.66H5.83a1.67 1.67 0 01-1.66-1.66V5h11.66z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
            <path d="M8.33 9.17v5M11.67 9.17v5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>`,
        private: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
        </svg>`,
        public: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"></path>
        </svg>`,
        time: `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="12" cy="12" r="10"></circle>
            <polyline points="12 6 12 12 16 14"></polyline>
        </svg>`,
        search: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="11" cy="11" r="8"></circle>
            <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
        </svg>`,
        prompt: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
        </svg>`,
        batch: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <rect x="3" y="3" width="18" height="18" rx="2" />
            <line x1="8" y1="12" x2="16" y2="12" />
            <line x1="8" y1="8" x2="16" y2="8" />
            <line x1="8" y1="16" x2="16" y2="16" />
        </svg>`,
        add: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <circle cx="12" cy="12" r="10"/>
            <line x1="12" y1="8" x2="12" y2="16"/>
            <line x1="8" y1="12" x2="16" y2="12"/>
        </svg>`,
        remove: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <circle cx="12" cy="12" r="10"/>
            <line x1="8" y1="12" x2="16" y2="12"/>
        </svg>`,
        play: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <circle cx="12" cy="12" r="10"/>
            <polygon points="10 8 16 12 10 16" fill="currentColor"/>
        </svg>`,
        lock: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
            <path d="M7 11V7a5 5 0 0 1 10 0v4"/>
        </svg>`,
        close: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <line x1="18" y1="6" x2="6" y2="18"/>
            <line x1="6" y1="6" x2="18" y2="18"/>
        </svg>`,
        error: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="12" cy="12" r="10"></circle>
            <line x1="15" y1="9" x2="9" y2="15"></line>
            <line x1="9" y1="9" x2="15" y2="15"></line>
        </svg>`,
        loading: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"></path>
            <path d="M12 12l-.01 0"></path>
        </svg>`,
        check: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <polyline points="20 6 9 17 4 12"></polyline>
        </svg>`,
        globe: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="12" cy="12" r="10"></circle>
            <line x1="2" y1="12" x2="22" y2="12"></line>
            <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
        </svg>`,
        lock: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <rect x="3" y="11" width="18" height="11" rx="2" fill="none"></rect>
            <path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
        </svg>`,
        image: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <rect x="3" y="3" width="18" height="18" rx="2" fill="none"></rect>
            <circle cx="8.5" cy="8.5" r="1.5"></circle>
            <path d="M21 21.35l-9-9"></path>
        </svg>`,
        copy: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
        </svg>`,
        generate: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
            <path d="M9 12l2 2 4-4"/>
        </svg>`,
        bug: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16" fill="currentColor" class="bi bi-bug" style="min-width: 20px;">
  <path d="M4.355.522a.5.5 0 0 1 .623.333l.291.956A5 5 0 0 1 8 1c1.007 0 1.946.298 2.731.811l.29-.956a.5.5 0 1 1 .957.29l-.41 1.352A5 5 0 0 1 13 6h.5a.5.5 0 0 0 .5-.5V5a.5.5 0 0 1 1 0v.5A1.5 1.5 0 0 1 13.5 7H13v1h1.5a.5.5 0 0 1 0 1H13v1h.5a1.5 1.5 0 0 1 1.5 1.5v.5a.5.5 0 0 1-1 0v-.5a.5.5 0 0 0-.5-.5H13a5 5 0 0 1-10 0h-.5a.5.5 0 0 0-.5.5v.5a.5.5 0 1 1-1 0v-.5A1.5 1.5 0 0 1 2.5 10H3V9H1.5a.5.5 0 0 0 0-1H3V7h-.5A1.5 1.5 0 0 1 1 5.5V5a.5.5 0 0 1 1 0v.5a.5.5 0 0 0 .5.5H3c0-1.364.547-2.601 1.432-3.503l-.41-1.352a.5.5 0 0 1 .333-.623M4 7v4a4 4 0 0 0 3.5 3.97V7zm4.5 0v7.97A4 4 0 0 0 12 11V7zM12 6a4 4 0 0 0-1.334-2.982A3.98 3.98 0 0 0 8 2a3.98 3.98 0 0 0-2.667 1.018A4 4 0 0 0 4 6z"/>
</svg>`,
        feature: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-star" viewBox="0 0 16 16">
  <path d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.56.56 0 0 0-.163-.505L1.71 6.745l4.052-.576a.53.53 0 0 0 .393-.288L8 2.223l1.847 3.658a.53.53 0 0 0 .393.288l4.052.575-2.906 2.77a.56.56 0 0 0-.163.506l.694 3.957-3.686-1.894a.5.5 0 0 0-.461 0z"/>
</svg>`,
        moon: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
  <path d="M6 .278a.77.77 0 0 1 .08.858 7.2 7.2 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277q.792-.001 1.533-.16a.79.79 0 0 1 .81.316.73.73 0 0 1-.031.893A8.35 8.35 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.75.75 0 0 1 6 .278"/>
</svg>`,
        sun: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
  <path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8M8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0m0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13m8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5M3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8m10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0m-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0m9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707M4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707"/>
</svg>`
    };

    // Initialize dark mode from localStorage
    let isDarkMode = localStorage.getItem('glifToolsDarkMode') === 'true';

    // Toggle dark mode
    const toggleDarkMode = () => {
        isDarkMode = !isDarkMode;
        localStorage.setItem('glifToolsDarkMode', isDarkMode);
        document.documentElement.setAttribute('data-glif-dark-mode', isDarkMode);

        // Force update all dropdowns to ensure correct state
        const dropdowns = document.querySelectorAll('.glif-tools-dropdown');
        dropdowns.forEach(dropdown => {
            const oldMenu = dropdown.querySelector('.glif-tools-menu');
            if (oldMenu) {
                const newDropdown = createToolsDropdown();
                dropdown.parentNode.replaceChild(newDropdown, dropdown);
            }
        });

        // Update all panels and their contents
        const updatePanelStyles = (panel) => {
            if (isDarkMode) {
                panel.style.backgroundColor = '#1E1E1E';
                panel.style.color = '#FFFFFF';
                panel.style.borderColor = '#2E2E2E';
                panel.style.boxShadow = '0 8px 24px rgba(0, 0, 0, 0.35)';

                // Update header
                const header = panel.querySelector('.panel-header, .history-header, .batch-header, .metadata-header, .bug-report-header');
                if (header) {
                    header.style.backgroundColor = '#1E1E1E';
                    header.style.borderBottomColor = '#2E2E2E';
                    const title = header.querySelector('h2');
                    if (title) title.style.color = '#FFFFFF';
                }

                // Update content
                const content = panel.querySelector('.panel-content, .history-content, .batch-content, .metadata-content, .bug-report-content');
                if (content) {
                    content.style.backgroundColor = '#1E1E1E';
                }

                // Update form elements
                panel.querySelectorAll('input, textarea, select').forEach(el => {
                    el.style.backgroundColor = '#2A2A2A';
                    el.style.color = '#FFFFFF';
                    el.style.borderColor = '#3E3E3E';
                });

                // Update buttons
                panel.querySelectorAll('button').forEach(btn => {
                    btn.style.backgroundColor = '#2A2A2A';
                    btn.style.color = '#FFFFFF';
                    btn.style.borderColor = '#3E3E3E';
                });

                // Update history/batch items
                panel.querySelectorAll('.history-item, .batch-result-item').forEach(item => {
                    item.style.backgroundColor = '#2A2A2A';
                    item.style.borderColor = '#3E3E3E';
                });

                // Update metadata
                panel.querySelectorAll('.history-metadata, .batch-metadata').forEach(meta => {
                    meta.style.color = '#FFFFFF';
                });

                // Update timestamps and status
                panel.querySelectorAll('.history-timestamp, .history-status').forEach(el => {
                    el.style.color = '#6B7280';
                });

                // Update progress bars
                panel.querySelectorAll('.batch-progress-container').forEach(container => {
                    container.style.backgroundColor = '#2A2A2A';
                    container.style.borderColor = '#3E3E3E';
                    const bar = container.querySelector('.progress-bar');
                    if (bar) bar.style.backgroundColor = '#33363C';
                    const fill = container.querySelector('.progress-fill');
                    if (fill) fill.style.backgroundColor = '#4F46E5';
                });

                // Update error containers
                panel.querySelectorAll('.error-container').forEach(container => {
                    container.style.backgroundColor = 'rgba(239, 68, 68, 0.1)';
                    container.style.borderColor = 'rgba(239, 68, 68, 0.2)';
                    const message = container.querySelector('.error-message');
                    if (message) message.style.color = '#EF4444';
                });
            } else {
                // Reset all styles to default
                panel.style = '';
                panel.querySelectorAll('*').forEach(el => {
                    el.style = '';
                });
            }
        };

        // Update all panels
        document.querySelectorAll('.glif-panel, .history-panel, .batch-panel, .bug-report-panel, .metadata-panel').forEach(updatePanelStyles);

        // Update overlays
        document.querySelectorAll('.history-overlay, .batch-overlay, .metadata-overlay').forEach(overlay => {
            overlay.style.backgroundColor = isDarkMode ? 'rgba(0, 0, 0, 0.75)' : '';
        });

        // Update toasts
        document.querySelectorAll('.glif-toast').forEach(toast => {
            if (isDarkMode) {
                toast.style.backgroundColor = '#1E1E1E';
                toast.style.color = '#FFFFFF';
                toast.style.borderColor = '#2E2E2E';
                if (toast.classList.contains('success')) {
                    toast.style.borderLeftColor = '#10B981';
                } else if (toast.classList.contains('error')) {
                    toast.style.borderLeftColor = '#EF4444';
                }
            } else {
                toast.style = '';
            }
        });
    };

    // Inject modern styles
    const injectStyles = () => {
        const styleSheet = document.createElement('style');
        styleSheet.id = 'glif-tools-v3-styles';
        styleSheet.textContent = `
            /* Dark mode transitions */
            .glif-panel, .glif-panel *, .glif-tools-menu, .glif-tools-menu *,
            .glif-toast, input, textarea, button, select {
                transition: all 0.3s ease;
            }

            /* Dark mode styles - Tools Dropdown */
            [data-glif-dark-mode="true"] .glif-tools-menu {
                background-color: #1E1E1E !important;
                border: 1px solid #2E2E2E !important;
                box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-menu-item {
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-menu-item:hover {
                background-color: #2A2A2A !important;
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-menu-item svg {
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-menu-item:hover svg {
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-credits {
                border-top: 1px solid #2E2E2E !important;
                color: #FFFFFF !important;
                margin-top: 8px !important;
                padding-top: 8px !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-credits a {
                color: #4F46E5 !important;
            }

            [data-glif-dark-mode="true"] .glif-tools-credits a:hover {
                color: #6366F1 !important;
            }

            /* Dark mode styles - Panels */
            [data-glif-dark-mode="true"] .glif-panel,
            [data-glif-dark-mode="true"] .history-panel,
            [data-glif-dark-mode="true"] .batch-panel,
            [data-glif-dark-mode="true"] .bug-report-panel,
            [data-glif-dark-mode="true"] .metadata-panel {
                background-color: #1E1E1E !important;
                color: #FFFFFF !important;
                border: 1px solid #2E2E2E !important;
                box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
            }

            /* Panel Headers */
            [data-glif-dark-mode="true"] .panel-header,
            [data-glif-dark-mode="true"] .history-header,
            [data-glif-dark-mode="true"] .batch-header,
            [data-glif-dark-mode="true"] .metadata-header,
            [data-glif-dark-mode="true"] .bug-report-header {
                background-color: #1E1E1E !important;
                border-bottom: 1px solid #2E2E2E !important;
            }

            [data-glif-dark-mode="true"] .panel-header h2,
            [data-glif-dark-mode="true"] .history-header h2,
            [data-glif-dark-mode="true"] .batch-header h2,
            [data-glif-dark-mode="true"] .metadata-header h2,
            [data-glif-dark-mode="true"] .bug-report-header h2 {
                color: #FFFFFF !important;
            }

            /* Panel Content */
            [data-glif-dark-mode="true"] .panel-content,
            [data-glif-dark-mode="true"] .history-content,
            [data-glif-dark-mode="true"] .batch-content,
            [data-glif-dark-mode="true"] .metadata-content,
            [data-glif-dark-mode="true"] .bug-report-content {
                background-color: #1E1E1E !important;
            }

            /* Form Elements */
            [data-glif-dark-mode="true"] .glif-panel input,
            [data-glif-dark-mode="true"] .glif-panel textarea,
            [data-glif-dark-mode="true"] .glif-panel select,
            [data-glif-dark-mode="true"] .search-input,
            [data-glif-dark-mode="true"] .batch-input {
                background-color: #2A2A2A !important;
                color: #FFFFFF !important;
                border: 1px solid #3E3E3E !important;
            }

            [data-glif-dark-mode="true"] .glif-panel input:focus,
            [data-glif-dark-mode="true"] .glif-panel textarea:focus,
            [data-glif-dark-mode="true"] .glif-panel select:focus,
            [data-glif-dark-mode="true"] .search-input:focus,
            [data-glif-dark-mode="true"] .batch-input:focus {
                border-color: #4F46E5 !important;
                box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2) !important;
            }

            [data-glif-dark-mode="true"] .glif-panel input:hover,
            [data-glif-dark-mode="true"] .glif-panel textarea:hover,
            [data-glif-dark-mode="true"] .glif-panel select:hover,
            [data-glif-dark-mode="true"] .search-input:hover,
            [data-glif-dark-mode="true"] .batch-input:hover {
                background-color: #33363C !important;
            }

            /* Buttons */
            [data-glif-dark-mode="true"] .glif-panel button,
            [data-glif-dark-mode="true"] .batch-generate-button,
            [data-glif-dark-mode="true"] .clear-history-button,
            [data-glif-dark-mode="true"] .filter-button,
            [data-glif-dark-mode="true"] .batch-row-action-button,
            [data-glif-dark-mode="true"] .glif-type-button {
                background-color: #2A2A2A !important;
                color: #FFFFFF !important;
                border: 1px solid #3E3E3E !important;
            }

            [data-glif-dark-mode="true"] .glif-panel button:hover,
            [data-glif-dark-mode="true"] .batch-generate-button:hover,
            [data-glif-dark-mode="true"] .clear-history-button:hover,
            [data-glif-dark-mode="true"] .filter-button:hover,
            [data-glif-dark-mode="true"] .batch-row-action-button:hover,
            [data-glif-dark-mode="true"] .glif-type-button:hover {
                background-color: #33363C !important;
                border-color: #4F46E5 !important;
            }

            /* History Items */
            [data-glif-dark-mode="true"] .history-item,
            [data-glif-dark-mode="true"] .batch-result-item {
                background-color: #2A2A2A !important;
                border: 1px solid #3E3E3E !important;
            }

            [data-glif-dark-mode="true"] .history-item:hover,
            [data-glif-dark-mode="true"] .batch-result-item:hover {
                background-color: #33363C !important;
                border-color: #4F46E5 !important;
            }

            [data-glif-dark-mode="true"] .history-metadata,
            [data-glif-dark-mode="true"] .batch-metadata {
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .history-timestamp,
            [data-glif-dark-mode="true"] .history-status {
                color: #6B7280 !important;
            }

            [data-glif-dark-mode="true"] .history-status.private {
                color: #EF4444 !important;
            }

            [data-glif-dark-mode="true"] .history-status.public {
                color: #38A169 !important;
            }

            /* Progress Bars */
            [data-glif-dark-mode="true"] .batch-progress-container {
                background-color: #2A2A2A !important;
                border: 1px solid #3E3E3E !important;
            }

            [data-glif-dark-mode="true"] .progress-bar {
                background-color: #33363C !important;
            }

            [data-glif-dark-mode="true"] .progress-fill {
                background-color: #4F46E5 !important;
            }

            /* Error States */
            [data-glif-dark-mode="true"] .error-container {
                background-color: rgba(239, 68, 68, 0.1) !important;
                border: 1px solid rgba(239, 68, 68, 0.2) !important;
            }

            [data-glif-dark-mode="true"] .error-message {
                color: #EF4444 !important;
            }

            /* Overlays */
            [data-glif-dark-mode="true"] .history-overlay,
            [data-glif-dark-mode="true"] .batch-overlay,
            [data-glif-dark-mode="true"] .metadata-overlay {
                background-color: rgba(0, 0, 0, 0.75) !important;
            }

            /* Toast Notifications */
            [data-glif-dark-mode="true"] .glif-toast {
                background-color: #1E1E1E !important;
                color: #FFFFFF !important;
                border: 1px solid #2E2E2E !important;
            }

            [data-glif-dark-mode="true"] .glif-toast.success {
                border-left: 4px solid #10B981 !important;
            }

            [data-glif-dark-mode="true"] .glif-toast.error {
                border-left: 4px solid #EF4444 !important;
            }

            /* Regular styles */
            .glif-tools-dropdown {
                position: relative;
                display: inline-block;
            }

            .glif-tools-menu {
                position: absolute;
                top: 100%;
                right: 0;
                background: white;
                border-radius: 8px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                padding: 8px;
                display: none;
                z-index: 1000;
                min-width: 200px;
                opacity: 0;
                visibility: hidden;
                transform: translateY(-10px);
                transition: all 0.2s ease;
            }

            .glif-tools-menu.active {
                display: block;
                opacity: 1;
                visibility: visible;
                transform: translateY(0);
            }

            .glif-tools-menu-item {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 8px 12px;
                color: #374151;
                text-decoration: none;
                border-radius: 6px;
                cursor: pointer;
                font-size: 14px;
                width: 100%;
                white-space: nowrap;
            }

            .glif-tools-menu-item svg {
                width: 18px;
                height: 18px;
                flex-shrink: 0;
            }

            .glif-tools-menu-item:hover {
                background: #f3f4f6;
            }

            .glif-tools-credits {
                margin-top: 8px;
                padding-top: 8px;
                border-top: 1px solid #e5e7eb;
                font-size: 12px;
                color: #6b7280;
                text-align: center;
            }

            .glif-tools-credits a {
                color: #3b82f6;
                text-decoration: none;
            }

            .glif-tools-credits a:hover {
                text-decoration: underline;
            }

            .history-overlay {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(17, 17, 17, 0.7);
                backdrop-filter: blur(4px);
                display: flex;
                align-items: center;
                justify-content: center;
                z-index: 10000;
            }

            .history-panel {
                background: #ffffff;
                border-radius: 24px;
                width: 90%;
                max-width: 1200px;
                max-height: 90vh;
                overflow: hidden;
                display: flex;
                flex-direction: column;
                box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
            }

            .history-header {
                padding: 24px 32px;
                background: #ffffff;
                display: flex;
                flex-direction: column;
                gap: 24px;
                border-bottom: 1px solid #edf2f7;
            }

            .history-panel-title-section {
                display: flex;
                align-items: center;
                justify-content: space-between;
            }

            .history-panel-title {
                display: flex;
                align-items: center;
                gap: 12px;
                margin: 0;
                font-size: 1.5rem;
                font-weight: 700;
                color: #2d3748;
            }

            .history-controls {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 20px;
            }

            .history-filters {
                display: flex;
                align-items: center;
                gap: 8px;
                background: #f7fafc;
                padding: 4px;
                border-radius: 12px;
            }

            .filter-button {
                padding: 8px 16px;
                border-radius: 8px;
                border: none;
                background: transparent;
                color: #718096;
                cursor: pointer;
                transition: all 0.2s ease;
                font-size: 0.9rem;
                font-weight: 500;
            }

            .filter-button:hover {
                color: #4a5568;
            }

            .filter-button.active {
                background: #ffffff;
                color: #2d3748;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
            }

            .search-container {
                position: relative;
                flex: 1;
                max-width: 300px;
            }

            .search-input {
                width: 100%;
                padding: 10px 16px 10px 40px;
                border: 2px solid #edf2f7;
                border-radius: 12px;
                font-size: 0.95rem;
                outline: none;
                transition: border-color 0.2s ease;
                background: #f8fafc;
                color: #2d3748;
            }

            .search-input:focus {
                border-color: #cbd5e0;
                background: #ffffff;
            }

            .search-input::placeholder {
                color: #a0aec0;
            }

            .search-icon {
                position: absolute;
                left: 14px;
                top: 50%;
                transform: translateY(-50%);
                color: #a0aec0;
            }

            .clear-history-button {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 10px 16px;
                background: #fff5f5;
                border: none;
                border-radius: 12px;
                color: #e53e3e;
                cursor: pointer;
                transition: background 0.2s;
                font-size: 0.9rem;
                font-weight: 500;
            }

            .clear-history-button:hover {
                background: #fed7d7;
            }

            .history-content {
                padding: 32px;
                overflow-y: auto;
                flex: 1;
                background: #f8fafc;
            }

            .history-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
                gap: 24px;
                margin: 0;
            }

            .history-item {
                background: #ffffff;
                border-radius: 16px;
                overflow: hidden;
                transition: transform 0.2s ease;
                cursor: pointer;
                border: 1px solid #edf2f7;
                display: flex;
                flex-direction: column;
            }

            .history-item:hover {
                transform: translateY(-2px);
                box-shadow: 0 8px 16px rgba(0, 0, 0, 0.05);
            }

            .history-item-image {
                width: 100%;
                height: 220px;
                flex-shrink: 0;
                position: relative;
                border-radius: 8px 8px 0 0;
                overflow: hidden;
                background: #f7fafc;
            }

            .history-item-image img {
                width: 100%;
                height: 100%;
                object-fit: cover;
            }

            .history-item-info {
                padding: 16px;
                display: flex;
                flex-direction: column;
                gap: 12px;
                background: #ffffff;
                flex: 1;
                min-height: 0;
            }

            .history-metadata {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: 8px;
            }

            .history-timestamp {
                display: flex;
                align-items: center;
                gap: 4px;
                color: #718096;
                font-size: 0.85rem;
            }

            .history-status {
                display: flex;
                align-items: center;
                gap: 4px;
                font-size: 0.85rem;
                font-weight: 500;
            }

            .history-status.private {
                color: #e53e3e;
            }

            .history-status.public {
                color: #38a169;
            }

            .history-item-prompt-container {
                background: #ebf8ff;
                padding: 12px;
                border-radius: 8px;
                margin-top: 4px;
                max-height: calc(1.5em * 2 + 24px);
                overflow: hidden;
            }

            .history-item-prompt {
                color: #2b6cb0;
                font-size: 0.95rem;
                line-height: 1.5;
                margin: 0;
                font-weight: 600;
                overflow: hidden;
                text-overflow: ellipsis;
                display: -webkit-box;
                -webkit-line-clamp: 2;
                -webkit-box-orient: vertical;
                max-height: calc(1.5em * 2);
            }

            .empty-state {
                text-align: center;
                padding: 48px;
                color: #718096;
            }

            .empty-state svg {
                width: 48px;
                height: 48px;
                margin-bottom: 16px;
                color: #a0aec0;
            }

            .empty-state p {
                margin: 8px 0;
                font-size: 0.95rem;
            }

            .empty-state p:first-of-type {
                font-weight: 600;
                color: #4a5568;
                font-size: 1.1rem;
            }

            .privacy-toggle {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                margin-top: 12px;
                padding: 0 4px;
                width: 100%;
            }

            .privacy-toggle button {
                display: inline-flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                width: 100%;
                padding: 12px;
                border: none;
                border-radius: 6px;
                font-size: 0.95rem;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                color: #4a5568;
            }

            .privacy-toggle:hover {
                background: rgba(0, 0, 0, 0.05);
            }

            .privacy-toggle.public button {
                background: #2563eb;
                color: white;
            }

            .privacy-toggle.public button:hover {
                background: #1d4ed8;
            }

            .privacy-toggle.private button {
                background: #dc2626;
                color: white;
            }

            .privacy-toggle.private button:hover {
                background: #b91c1c;
            }

            .metadata-overlay {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.75);
                backdrop-filter: blur(8px);
                -webkit-backdrop-filter: blur(8px);
                z-index: 10000;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 20px;
            }

            .metadata-content {
                background: #ffffff;
                border-radius: 16px;
                box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
                width: 90%;
                max-width: 1200px;
                max-height: 90vh;
                overflow-y: auto;
                position: relative;
                padding: 32px;
            }

            .metadata-close {
                position: absolute;
                top: 24px;
                right: 24px;
                background: none;
                border: none;
                color: var(--foreground);
                cursor: pointer;
                padding: 8px;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                transition: background-color 0.2s;
            }

            .metadata-close:hover {
                background: rgba(var(--background-rgb), 0.1);
            }

            .metadata-grid {
                display: grid;
                grid-template-columns: 400px 1fr;
                gap: 32px;
                margin-bottom: 32px;
            }

            .metadata-image {
                background: var(--background-secondary, #f3f4f6);
                border-radius: 12px;
                padding: 16px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            }

            .metadata-image img {
                width: 100%;
                height: auto;
                border-radius: 8px;
                cursor: pointer;
            }

            .metadata-image img:hover {
                transform: scale(1.02);
            }

            .metadata-details {
                display: flex;
                flex-direction: column;
                gap: 24px;
            }

            .metadata-details h2 {
                margin: 0;
                font-size: 28px;
                font-weight: 600;
                color: var(--foreground);
            }

            .metadata-info-grid {
                display: grid;
                grid-template-columns: repeat(2, 1fr);
                gap: 16px;
            }

            .metadata-info-item {
                background: var(--background-secondary, #f3f4f6);
                padding: 12px;
                border-radius: 8px;
                display: flex;
                flex-direction: column;
                gap: 4px;
            }

            .metadata-info-label {
                color: var(--foreground-secondary);
                font-size: 14px;
                display: flex;
                align-items: center;
                gap: 6px;
            }

            .metadata-info-value {
                color: var(--foreground);
                font-size: 16px;
                font-weight: 500;
            }

            .metadata-run-link {
                display: inline-flex;
                align-items: center;
                gap: 8px;
                padding: 12px 20px;
                background: var(--accent);
                color: white;
                border-radius: 8px;
                text-decoration: none;
                font-weight: 500;
                transition: background 0.2s;
                width: fit-content;
            }

            .metadata-run-link:hover {
                background: var(--accent-hover);
            }

            .metadata-section {
                margin-top: 32px;
                background: #ffffff;
                border-radius: 12px;
                padding: 24px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            }

            .metadata-section h3 {
                margin: 0 0 20px 0;
                font-size: 20px;
                font-weight: 600;
                color: var(--foreground);
            }

            .metadata-node-outputs {
                display: flex;
                flex-direction: column;
                gap: 16px;
            }

            .metadata-node {
                background: var(--background-secondary, #f3f4f6);
                border-radius: 8px;
                padding: 16px;
            }

            .metadata-node-title {
                font-weight: 500;
                color: var(--foreground);
                margin-bottom: 8px;
            }

            .metadata-node-content {
                font-family: monospace;
                white-space: pre-wrap;
                background: var(--background-tertiary, #e5e7eb);
                padding: 12px;
                border-radius: 6px;
                font-size: 14px;
                color: var(--foreground-secondary);
            }

            .metadata-images-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                gap: 16px;
            }

            .metadata-image-item {
                background: var(--background-secondary, #f3f4f6);
                padding: 12px;
                border-radius: 8px;
                transition: transform 0.2s;
                cursor: pointer;
            }

            .metadata-image-item:hover {
                transform: scale(1.02);
            }

            .metadata-image-item img {
                width: 100%;
                height: auto;
                border-radius: 4px;
            }

            .metadata-collapsible {
                margin-bottom: 16px;
            }

            .metadata-collapsible-header {
                width: 100%;
                padding: 12px;
                background: var(--background-secondary, #f3f4f6);
                border: none;
                border-radius: 8px;
                color: var(--foreground);
                font-weight: 500;
                cursor: pointer;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }

            .metadata-collapsible-icon {
                transition: transform 0.2s;
            }

            .metadata-collapsible-content {
                display: none;
                padding: 16px;
                background: var(--background-tertiary, #e5e7eb);
                border-radius: 8px;
                margin-top: 8px;
            }

            .metadata-collapsible-content pre {
                margin: 0;
                white-space: pre-wrap;
                font-family: monospace;
                font-size: 14px;
                color: var(--foreground-secondary);
            }

            .batch-results-overlay {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.75);
                backdrop-filter: blur(8px);
                -webkit-backdrop-filter: blur(8px);
                z-index: 10000;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 20px;
            }

            .batch-results-panel {
                background: var(--background);
                border-radius: 20px;
                box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
                width: 90%;
                max-width: 1200px;
                max-height: 90vh;
                overflow: hidden;
                display: flex;
                flex-direction: column;
            }

            .batch-results-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 24px 32px;
                border-bottom: 1px solid var(--border-color);
                background: var(--background);
                position: sticky;
                top: 0;
                z-index: 1;
            }

            .batch-results-content {
                padding: 32px;
                overflow-y: auto;
                flex: 1;
            }

            .batch-results-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
                gap: 24px;
                margin: 0;
            }

            .batch-result-item {
                background: var(--background);
                border-radius: 16px;
                overflow: hidden;
                transition: all 0.3s ease;
                cursor: pointer;
                border: 1px solid var(--border-color);
                display: flex;
                flex-direction: column;
            }

            .batch-result-item:hover {
                transform: translateY(-4px);
                box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
                border-color: var(--accent-color);
            }

            .batch-result-item.success {
                border-color: var(--success-color);
            }

            .batch-result-item.error {
                border-color: var(--error-color);
            }

            .batch-overlay {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.75);
                backdrop-filter: blur(8px);
                -webkit-backdrop-filter: blur(8px);
                z-index: 10000;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 32px;
            }

            .batch-panel {
                background: #ffffff;
                border-radius: 20px;
                box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
                width: 90%;
                max-width: 1000px;
                max-height: 90vh;
                overflow: hidden;
                display: flex;
                flex-direction: column;
                position: relative;
            }

            .batch-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 24px 32px;
                border-bottom: 1px solid #e5e7eb;
                background: #ffffff;
                position: sticky;
                top: 0;
                z-index: 1;
            }

            .batch-title-section {
                display: flex;
                align-items: center;
                gap: 12px;
            }

            .batch-title {
                font-size: 1.5rem;
                font-weight: 600;
                color: #1f2937;
                margin: 0;
                display: flex;
                align-items: center;
                gap: 12px;
            }

            .batch-title svg {
                width: 24px;
                height: 24px;
                color: #6366f1;
            }

            .batch-close-button {
                position: absolute;
                top: 20px;
                right: 20px;
                background: transparent;
                border: none;
                color: #6b7280;
                cursor: pointer;
                padding: 8px;
                border-radius: 8px;
                display: flex;
                align-items: center;
                justify-content: center;
                transition: all 0.2s ease;
            }

            .batch-close-button svg {
                width: 20px;
                height: 20px;
            }

            .batch-close-button:hover {
                background: #f3f4f6;
                color: #4b5563;
            }

            .batch-controls {
                display: flex;
                align-items: center;
                gap: 12px;
            }

            .batch-control-button {
                display: inline-flex;
                align-items: center;
                gap: 6px;
                padding: 8px 16px;
                border-radius: 6px;
                border: none;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
            }

            .batch-control-button svg {
                width: 16px;
                height: 16px;
                flex-shrink: 0;
            }

            .batch-control-button span {
                line-height: 1;
            }

            .batch-control-button:hover {
                background: #f5f5ff;
                border-color: #6366f1;
                color: #6366f1;
            }

            .batch-input-container {
                display: flex;
                flex-direction: column;
                gap: 16px;
                background: #ffffff;
                border-radius: 12px;
                padding: 24px;
                border: 1px solid #e5e7eb;
                box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
            }

            .batch-input-row {
                display: grid;
                grid-template-columns: 1fr auto;
                gap: 16px;
                padding: 16px;
                border-radius: 12px;
                background: #f9fafb;
                border: 1px solid #e5e7eb;
                transition: all 0.2s ease;
            }

            .batch-input-row:hover {
                border-color: #6366f1;
                background: #ffffff;
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }

            .batch-input-fields {
                display: flex;
                flex-direction: row;
                gap: 12px;
                flex: 1;
            }

            .batch-input {
                flex: 1;
                min-width: 0;
                padding: 10px 12px;
                border: 1px solid #e5e7eb;
                border-radius: 8px;
                background: #ffffff;
                color: #1f2937;
                font-size: 0.95rem;
                line-height: 1.4;
                transition: all 0.2s ease;
            }

            .batch-input:focus {
                outline: none;
                border-color: #6366f1;
                box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
            }

            .batch-input::placeholder {
                color: #9ca3af;
            }

            .batch-row-actions {
                display: flex;
                gap: 8px;
                align-items: center;
                margin-right: 4px;
            }

            .batch-row-action-button {
                display: flex;
                align-items: center;
                justify-content: center;
                width: 32px;
                height: 32px;
                padding: 0;
                border: 1px solid #e5e7eb;
                border-radius: 6px;
                background: #ffffff;
                color: #6b7280;
                cursor: pointer;
                transition: all 0.2s ease;
            }

            .batch-row-action-button svg {
                width: 16px;
                height: 16px;
            }

            .batch-row-action-button:hover {
                background: #f3f4f6;
                border-color: #6366f1;
                color: #6366f1;
            }

            .batch-row-action-button.delete:hover {
                background: #fee2e2;
                border-color: #ef4444;
                color: #dc2626;
            }

            .batch-generate-button {
                display: inline-flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                margin-top: 24px;
                padding: 14px 28px;
                background: linear-gradient(180deg, #ff5733 0%, #c70039 100%);
                color: white;
                border: none;
                border-radius: 10px;
                font-size: 1rem;
                font-weight: 600;
                cursor: pointer;
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                letter-spacing: 0.5px;
            }

            .batch-generate-button:hover {
                background: linear-gradient(180deg, #c70039 0%, #900c3f 100%);
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
                transform: translateY(-2px);
            }

            .batch-generate-button:active {
                transform: translateY(0px);
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
            }

            .batch-generate-button:disabled {
                background: #e5e7eb;
                cursor: not-allowed;
                transform: none;
                box-shadow: none;
            }

            .batch-generate-button:disabled {
                background: #e5e7eb;
                cursor: not-allowed;
                transform: none;
                box-shadow: none;
            }

            .batch-generate-button.processing {
                background: #818cf8;
            }

            .batch-generate-button.success {
                background: #10b981;
            }

            .batch-generate-button.error {
                background: #ef4444;
            }

            /* Action Buttons */
            .action-button {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 12px 20px;
                border-radius: 12px;
                font-size: 1rem;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                border: 1px solid var(--border-color);
                background: var(--background);
                color: var(--foreground);
            }

            .action-button svg {
                width: 20px;
                height: 20px;
            }

            .action-button:hover {
                background: var(--background-secondary);
                border-color: var(--accent-color);
            }

            .action-button.primary {
                background: var(--accent-color);
                color: white;
                border: none;
            }

            .action-button.primary:hover {
                background: var(--accent-color-hover);
                transform: translateY(-1px);
            }

            /* Header Actions */
            .header-actions {
                display: flex;
                align-items: center;
                gap: 16px;
            }

            .private-toggle {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                padding: 8px 16px;
                border-radius: 12px;
                font-size: 1rem;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                border: 1px solid var(--border-color);
                background: var(--background);
                color: var(--foreground);
            }

            .private-toggle svg {
                width: 20px;
                height: 20px;
            }

            .private-toggle:hover {
                background: var(--background-secondary);
                border-color: var(--accent-color);
            }

            .private-toggle.active {
                background: var(--accent-color);
                color: white;
                border: none;
            }

            /* Add Row Button */
            .add-row-button {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 16px;
                border-radius: 16px;
                font-size: 1.1rem;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                width: 100%;
                justify-content: center;
                margin-top: 16px;
            }

            .add-row-button svg {
                width: 24px;
                height: 24px;
            }

            .add-row-button:hover {
                border-color: var(--accent-color);
                color: var(--accent-color);
                background: var(--background-secondary);
            }

            .input-section {
                margin-bottom: 24px;
            }

            .input-label {
                display: block;
                font-size: 1rem;
                font-weight: 600;
                color: var(--foreground);
                margin-bottom: 12px;
            }

            .input-field {
                display: flex;
                align-items: center;
                gap: 16px;
                background: var(--background);
                border: 1px solid var(--border-color);
                border-radius: 16px;
                padding: 12px 16px;
                transition: all 0.2s ease;
            }

            .input-field:hover {
                border-color: var(--accent-color);
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            }

            .input-fields-grid {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 16px;
            }

            .history-input {
                width: 100%;
                background: transparent;
                border: none;
                color: var(--foreground);
                font-size: 1rem;
                padding: 8px;
                border-radius: 8px;
            }

            .history-input:focus {
                outline: none;
                background: var(--background-secondary);
            }

            .history-input::placeholder {
                color: var(--foreground-secondary);
                opacity: 0.7;
            }

            .batch-row-actions button {
                padding: 8px;
                border-radius: 8px;
                color: var(--foreground-secondary);
                transition: all 0.2s ease;
            }

            .batch-row-actions button:hover {
                background: var(--background-secondary);
                color: var(--foreground);
            }

            .add-row-button {
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                padding: 16px;
                background: transparent;
                border: 2px dashed var(--border-color);
                border-radius: 16px;
                color: var(--foreground-secondary);
                font-size: 1rem;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                margin-top: 24px;
            }

            .add-row-button:hover {
                border-color: var(--accent-color);
                color: var(--accent-color);
                background: var(--background-secondary);
            }

            .batch-controls {
                margin-top: 32px;
                padding: 24px;
                background: var(--background-secondary);
                border-radius: 20px;
                display: flex;
                align-items: center;
                gap: 24px;
            }

            .batch-generate-button {
                background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
                color: white;
                padding: 12px 24px;
                border-radius: 8px;
                border: none;
                font-weight: 600;
                margin-top: 16px;
                width: 100%;
                cursor: pointer;
                box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                letter-spacing: 0.5px;
            }

            .batch-generate-button:hover {
                background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);
                box-shadow: 0 6px 16px rgba(79, 70, 229, 0.4);
                transform: translateY(-2px);
            }

            .batch-generate-button:active {
                transform: translateY(0px);
                box-shadow: 0 2px 8px rgba(79, 70, 229, 0.4);
            }

            .batch-generate-button:disabled {
                background: #e5e7eb;
                cursor: not-allowed;
                transform: none;
                box-shadow: none;
            }

            .batch-results-container {
                padding: 2rem;
                background: white;
                border-radius: 12px;
                max-width: 1200px;
                margin: 0 auto;
            }
            .batch-results-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
                gap: 1.5rem;
                margin-bottom: 2rem;
            }
            .batch-result-item {
                background: white;
                border-radius: 16px;
                overflow: hidden;
                transition: all 0.3s ease;
                cursor: pointer;
                border: 1px solid #e5e7eb;
                display: flex;
                flex-direction: column;
            }
            .result-image-wrapper {
                position: relative;
                padding-top: 100%;
                background: #f3f4f6;
                overflow: hidden;
            }
            .result-image {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                object-fit: cover;
                transition: transform 0.3s ease;
            }
            .result-image:hover {
                transform: scale(1.05);
            }
            .result-details {
                padding: 1rem;
                display: flex;
                flex-direction: column;
                gap: 0.5rem;
            }
            .result-prompt {
                font-size: 0.875rem;
                color: #1f2937;
                font-weight: 500;
                line-height: 1.25rem;
                overflow: hidden;
                display: -webkit-box;
                -webkit-box-orient: vertical;
                -webkit-line-clamp: 2;
            }
            .result-prompt:hover {
                -webkit-line-clamp: unset;
            }
            .result-metadata {
                display: flex;
                align-items: center;
                gap: 0.75rem;
                font-size: 0.75rem;
                color: #6b7280;
            }
            .final-image-popup {
                position: fixed;
                bottom: 20px;
                right: 20px;
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
                z-index: 10000;
                padding: 10px;
                max-width: 300px;
                animation: slideIn 0.3s ease-out;
            }

            .final-image-popup .popup-content {
                display: flex;
                flex-direction: column;
                gap: 10px;
            }

            .final-image-popup img {
                width: 100%;
                height: auto;
                border-radius: 4px;
            }

            .final-image-popup .open-new-tab {
                background: #007bff;
                color: white;
                border: none;
                padding: 8px 12px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                transition: background 0.2s;
            }

            .final-image-popup .open-new-tab:hover {
                background: #0056b3;
            }

            @keyframes slideIn {
                from {
                    transform: translateX(100%);
                    opacity: 0;
                }
                to {
                    transform: translateX(0);
                    opacity: 1;
                }
            }

            /* Bug Report Form Styles */
            .glif-modal {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, 0.7);
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 10000;
                backdrop-filter: blur(4px);
            }

            .glif-modal-content {
                background: #ffffff;
                padding: 24px;
                border-radius: 12px;
                width: 90%;
                max-width: 500px;
                max-height: 90vh;
                overflow-y: auto;
                position: relative;
                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
            }

            .glif-close-button {
                position: absolute;
                top: 16px;
                right: 16px;
                background: none;
                border: none;
                cursor: pointer;
                color: #6b7280;
                padding: 8px;
                border-radius: 8px;
                transition: all 0.2s;
                line-height: 0;
            }

            .glif-close-button:hover {
                background: #f3f4f6;
                color: #1f2937;
            }

            .glif-modal-title {
                margin: 0 0 20px 0;
                font-size: 20px;
                font-weight: 600;
                color: #1f2937;
            }

            .glif-type-container {
                display: flex;
                gap: 8px;
                margin-bottom: 20px;
            }

            .glif-type-button {
                flex: 1;
                padding: 10px;
                border: 1px solid #e5e7eb;
                border-radius: 8px;
                background: #ffffff;
                cursor: pointer;
                font-size: 14px;
                font-weight: 500;
                color: #6b7280;
                transition: all 0.2s;
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 6px;
            }

            .glif-type-button:hover {
                border-color: #3b82f6;
                color: #3b82f6;
                background: #f3f4f6;
            }

            .glif-type-button.active {
                border-color: #3b82f6;
                color: #3b82f6;
                background: #eff6ff;
            }

            .glif-input-container {
                margin-bottom: 16px;
            }

            .glif-input-label {
                display: block;
                margin-bottom: 6px;
                font-weight: 500;
                color: #374151;
                font-size: 14px;
            }

            .glif-input {
                width: 100%;
                padding: 10px 12px;
                border: 1px solid #e5e7eb;
                border-radius: 8px;
                font-size: 14px;
                transition: all 0.2s;
                background: #f9fafb;
                color: #1f2937;
            }

            .glif-textarea {
                height: 120px;
                resize: vertical;
                line-height: 1.5;
            }

            .glif-input:focus {
                outline: none;
                border-color: #3b82f6;
                background: #ffffff;
                box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
            }

            .glif-submit-button {
                width: 100%;
                padding: 10px;
                background: #3b82f6;
                color: white;
                border: none;
                border-radius: 8px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s;
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 6px;
                margin-top: 8px;
            }

            .glif-submit-button:hover {
                background: #2563eb;
            }

            .glif-submit-button:disabled {
                background: #93c5fd;
                cursor: not-allowed;
            }

            /* Toast Notification Styles */
            .glif-toast {
                position: fixed;
                bottom: 24px;
                right: 24px;
                padding: 12px 16px;
                border-radius: 8px;
                font-size: 14px;
                font-weight: 500;
                color: white;
                z-index: 10001;
                display: flex;
                align-items: center;
                gap: 8px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                animation: slideInRight 0.3s ease-out;
            }

            .glif-toast.success {
                background: #059669;
            }

            .glif-toast.error {
                background: #dc2626;
            }

            @keyframes slideInRight {
                from {
                    transform: translateX(100%);
                    opacity: 0;
                }
                to {
                    transform: translateX(0);
                    opacity: 1;
                }
            }

            @keyframes fadeOut {
                from {
                    opacity: 1;
                }
                to {
                    opacity: 0;
                }
            }

            .glif-tools-menu-item svg,
            .bug-report-type-button svg {
                width: 20px;
                height: 20px;
                min-width: 20px;
                flex-shrink: 0;
            }

            /* Bug Report Panel Specific Styles */
            [data-glif-dark-mode="true"] .glif-modal-content {
                background-color: #1E1E1E !important;
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-modal-title {
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-type-button {
                background-color: #2A2A2A !important;
                color: #FFFFFF !important;
                border: 1px solid #3E3E3E !important;
                transition: all 0.2s ease !important;
            }

            [data-glif-dark-mode="true"] .glif-type-button:hover {
                background-color: #33363C !important;
                border-color: #4F46E5 !important;
            }

            [data-glif-dark-mode="true"] .glif-type-button.active {
                background-color: #4F46E5 !important;
                border-color: #4F46E5 !important;
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-input-label {
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] .glif-input,
            [data-glif-dark-mode="true"] .glif-textarea {
                background-color: #2A2A2A !important;
                color: #FFFFFF !important;
                border: 1px solid #3E3E3E !important;
            }

            [data-glif-dark-mode="true"] .glif-input:focus,
            [data-glif-dark-mode="true"] .glif-textarea:focus {
                border-color: #4F46E5 !important;
                box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2) !important;
            }

            [data-glif-dark-mode="true"] .glif-input::placeholder,
            [data-glif-dark-mode="true"] .glif-textarea::placeholder {
                color: #6B7280 !important;
            }

            [data-glif-dark-mode="true"] .glif-submit-button {
                background-color: #4F46E5 !important;
                color: #FFFFFF !important;
                border: none !important;
                transition: all 0.2s ease !important;
            }

            [data-glif-dark-mode="true"] .glif-submit-button:hover {
                background-color: #4338CA !important;
            }

            [data-glif-dark-mode="true"] .glif-close-button {
                color: #6B7280 !important;
            }

            [data-glif-dark-mode="true"] .glif-close-button:hover {
                color: #FFFFFF !important;
            }

            /* Batch Generator Specific Styles */
            [data-glif-dark-mode="true"] #batchInputContainer .batch-input-row {
                background-color: #2A2A2A !important;
                border: 1px solid #3E3E3E !important;
                color: #FFFFFF !important;
            }

            [data-glif-dark-mode="true"] #batchInputContainer .batch-input-row:hover {
                background-color: #33363C !important;
                border-color: #4F46E5 !important;
            }

            [data-glif-dark-mode="true"] #batchInputContainer .batch-input {
                background-color: #2A2A2A !important;
                color: #FFFFFF !important;
                border: 1px solid #3E3E3E !important;
            }

            [data-glif-dark-mode="true"] #batchInputContainer .batch-input:focus {
                border-color: #4F46E5 !important;
                box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2) !important;
            }

            [data-glif-dark-mode="true"] #batchInputContainer .batch-input::placeholder {
                color: #6B7280 !important;
            }

            [data-glif-dark-mode="true"] #batchInputContainer .batch-row-action-button {
                color: #6B7280 !important;
            }

            [data-glif-dark-mode="true"] #batchInputContainer .batch-row-action-button:hover {
                color: #FFFFFF !important;
            }

            /* History Panel Dark Mode Styles */
            [data-glif-dark-mode="true"] .history-filters {
                background-color: #1A1B1E !important;
                border-bottom: 1px solid #2D2E32 !important;
                padding: 16px !important;
            }

            [data-glif-dark-mode="true"] .history-filters input {
                background-color: #25262B !important;
                color: #E6E8EC !important;
                border: 1px solid #383A3F !important;
                transition: all 0.2s ease !important;
            }

            [data-glif-dark-mode="true"] .history-filters input:focus {
                border-color: #4F46E5 !important;
                background-color: #2C2D32 !important;
                box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.25) !important;
            }

            [data-glif-dark-mode="true"] .history-filters input::placeholder {
                color: #9095A0 !important;
            }

            [data-glif-dark-mode="true"] .history-item > div {
                background-color: #25262B !important;
                color: #E6E8EC !important;
                border: 1px solid #383A3F !important;
                transition: all 0.2s ease !important;
            }

            [data-glif-dark-mode="true"] .history-item > div:hover {
                background-color: #2C2D32 !important;
                border-color: #4F46E5 !important;
                transform: translateY(-1px) !important;
            }

            [data-glif-dark-mode="true"] .history-item-content {
                color: #E6E8EC !important;
            }

            [data-glif-dark-mode="true"] .history-item-metadata {
                color: #9095A0 !important;
            }

            [data-glif-dark-mode="true"] .history-item-prompt {
                color: #E6E8EC !important;
                font-weight: 500 !important;
            }

            [data-glif-dark-mode="true"] .history-item-timestamp {
                color: #9095A0 !important;
                font-size: 0.9em !important;
            }

            [data-glif-dark-mode="true"] .history-item-actions {
                background-color: #2C2D32 !important;
                border-top: 1px solid #383A3F !important;
                padding: 8px !important;
            }

            [data-glif-dark-mode="true"] .history-item-actions button {
                color: #9095A0 !important;
                transition: all 0.2s ease !important;
            }

            [data-glif-dark-mode="true"] .history-item-actions button:hover {
                color: #E6E8EC !important;
                background-color: #383A3F !important;
            }

            /* Metadata Panel Dark Mode */
            [data-glif-dark-mode="true"] .metadata-grid {
                background-color: #25262B !important;
                border: 1px solid #383A3F !important;
                border-radius: 8px !important;
            }

            [data-glif-dark-mode="true"] .metadata-details {
                background-color: #2C2D32 !important;
                border-left: 1px solid #383A3F !important;
            }

            [data-glif-dark-mode="true"] .metadata-details h2 {
                color: #E6E8EC !important;
                font-weight: 600 !important;
            }

            [data-glif-dark-mode="true"] .metadata-info-grid {
                gap: 16px !important;
            }

            [data-glif-dark-mode="true"] .metadata-info-item {
                background-color: #1A1B1E !important;
                border: 1px solid #2D2E32 !important;
                border-radius: 6px !important;
                padding: 12px !important;
            }

            [data-glif-dark-mode="true"] .metadata-info-label {
                color: #9095A0 !important;
                font-weight: 500 !important;
            }

            [data-glif-dark-mode="true"] .metadata-info-value {
                color: #E6E8EC !important;
                font-family: 'Roboto Mono', monospace !important;
            }

            [data-glif-dark-mode="true"] .metadata-section {
                border-top: 1px solid #383A3F !important;
                padding-top: 24px !important;
                margin-top: 24px !important;
            }

            [data-glif-dark-mode="true"] .metadata-section h3 {
                color: #E6E8EC !important;
                font-weight: 600 !important;
                margin-bottom: 16px !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible {
                background-color: #25262B !important;
                border: 1px solid #383A3F !important;
                border-radius: 6px !important;
                margin-bottom: 8px !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-header {
                background-color: #2C2D32 !important;
                color: #E6E8EC !important;
                padding: 12px 16px !important;
                font-weight: 500 !important;
                transition: all 0.2s ease !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-header:hover {
                background-color: #383A3F !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-content {
                background-color: #1A1B1E !important;
                border-top: 1px solid #2D2E32 !important;
                padding: 16px !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-content pre {
                color: #E6E8EC !important;
                font-family: 'Roboto Mono', monospace !important;
                font-size: 0.9em !important;
            }

            /* Batch Input Container Dark Mode */
            [data-glif-dark-mode="true"] .batch-input-container {
                background-color: #1A1B1E !important;
            }

            [data-glif-dark-mode="true"] .batch-content {
                background-color: #1A1B1E !important;
            }

            /* History Item Specific Dark Mode */
            [data-glif-dark-mode="true"] .history-item > div:nth-child(2) > div:nth-child(2) {
                background-color: #25262B !important;
                color: #E6E8EC !important;
            }

            /* Node Outputs Dark Mode */
            [data-glif-dark-mode="true"] .metadata-node-outputs {
                background-color: #1A1B1E !important;
                border-radius: 8px !important;
                padding: 16px !important;
            }

            [data-glif-dark-mode="true"] .metadata-node {
                background-color: #25262B !important;
                border: 1px solid #383A3F !important;
                border-radius: 6px !important;
                margin-bottom: 12px !important;
            }

            [data-glif-dark-mode="true"] .metadata-node:last-child {
                margin-bottom: 0 !important;
            }

            [data-glif-dark-mode="true"] .metadata-node-title {
                background-color: #2C2D32 !important;
                color: #E6E8EC !important;
                font-weight: 500 !important;
                padding: 8px 12px !important;
                border-bottom: 1px solid #383A3F !important;
                border-radius: 6px 6px 0 0 !important;
            }

            [data-glif-dark-mode="true"] .metadata-node-content {
                color: #E6E8EC !important;
                font-family: 'Roboto Mono', monospace !important;
                font-size: 0.9em !important;
                padding: 12px !important;
                background-color: #1A1B1E !important;
                border-radius: 0 0 6px 6px !important;
                white-space: pre-wrap !important;
            }

            /* Metadata Sections Dark Mode */
            [data-glif-dark-mode="true"] .metadata-section {
                border: 1px solid #2E2E2E !important;
                background-color: #1E1E1E !important;
                padding: 20px !important;
                border-radius: 8px !important;
                margin-top: 24px !important;
            }

            [data-glif-dark-mode="true"] .metadata-section h3 {
                color: #FFFFFF !important;
                margin-bottom: 16px !important;
            }

            [data-glif-dark-mode="true"] .metadata-node {
                background-color: #25262B !important;
                border: 1px solid #2E2E2E !important;
            }

            [data-glif-dark-mode="true"] .metadata-node-content {
                background-color: #2C2D32 !important;
                color: #E6E8EC !important;
                border: 1px solid #383A3F !important;
            }

            [data-glif-dark-mode="true"] .metadata-image-item {
                background-color: #25262B !important;
                border: 1px solid #2E2E2E !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-header {
                background-color: #25262B !important;
                color: #E6E8EC !important;
                border: 1px solid #2E2E2E !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-content {
                background-color: #2C2D32 !important;
                border: 1px solid #383A3F !important;
            }

            [data-glif-dark-mode="true"] .metadata-collapsible-content pre {
                color: #E6E8EC !important;
            }

            /* Batch Input Container Dark Mode */
            [data-glif-dark-mode="true"] .batch-input-container {
                background-color: #1A1B1E !important;
            }

            [data-glif-dark-mode="true"] .batch-content {
                background-color: #1A1B1E !important;
            }

            /* History Item Specific Dark Mode */
            [data-glif-dark-mode="true"] .history-item > div:nth-child(2) > div:nth-child(2) {
                background-color: #25262B !important;
                color: #E6E8EC !important;
            }

            /* Node Outputs Dark Mode */
            [data-glif-dark-mode="true"] .metadata-node-outputs {
                background-color: #1A1B1E !important;
                border-radius: 8px !important;
                padding: 16px !important;
            }

            [data-glif-dark-mode="true"] .metadata-node {
                background-color: #25262B !important;
                border: 1px solid #383A3F !important;
                border-radius: 6px !important;
                margin-bottom: 12px !important;
            }

            [data-glif-dark-mode="true"] .metadata-node:last-child {
                margin-bottom: 0 !important;
            }

            [data-glif-dark-mode="true"] .metadata-node-title {
                background-color: #2C2D32 !important;
                color: #E6E8EC !important;
                font-weight: 500 !important;
                padding: 8px 12px !important;
                border-bottom: 1px solid #383A3F !important;
                border-radius: 6px 6px 0 0 !important;
            }

            [data-glif-dark-mode="true"] .metadata-node-content {
                color: #E6E8EC !important;
                font-family: 'Roboto Mono', monospace !important;
                font-size: 0.9em !important;
                padding: 12px !important;
                background-color: #1A1B1E !important;
                border-radius: 0 0 6px 6px !important;
                white-space: pre-wrap !important;
            }
        `;
        document.head.appendChild(styleSheet);
    };

    // Create tools dropdown
    const createToolsDropdown = () => {
        const toolsDropdown = document.createElement('div');
        toolsDropdown.className = 'glif-tools-dropdown';

        const toolsButton = document.createElement('button');
        toolsButton.className = 'flex items-center gap-1 text-lg font-bold hover:text-brand-600 active:text-brand-600';
        toolsButton.innerHTML = `<span class="block h-2 w-2"></span>${icons.tools}<span>Tools</span>`;
        toolsDropdown.appendChild(toolsButton);

        const menu = document.createElement('div');
        menu.className = 'glif-tools-menu';

        const createMenuItem = (icon, text, onClick) => {
            const item = document.createElement('div');
            item.className = 'glif-tools-menu-item';
            item.innerHTML = `${icon}<span>${text}</span>`;
            item.addEventListener('click', (e) => {
                e.stopPropagation();
                onClick();
                menu.classList.remove('active');
            });
            return item;
        };

        // Add menu items
        menu.appendChild(createMenuItem(icons.history, 'View History', displayHistoryPanel));
        menu.appendChild(createMenuItem(icons.batch, 'Batch Generator', displayBatchPanel));
        menu.appendChild(createMenuItem(icons.bug, 'Report Bug', displayBugReportForm));

        // Create dark mode toggle item with an ID for easy updating
        const darkModeItem = createMenuItem(
            isDarkMode ? icons.sun : icons.moon,
            isDarkMode ? 'Light Mode' : 'Dark Mode',
            toggleDarkMode
        );
        darkModeItem.id = 'dark-mode-toggle';
        menu.appendChild(darkModeItem);

        // Add credits
        const credits = document.createElement('div');
        credits.className = 'glif-tools-credits';
        credits.innerHTML = 'Made by <a href="https://glif.app/@appelsiensam" target="_blank">I12bp8</a> <3';
        menu.appendChild(credits);

        toolsDropdown.appendChild(menu);

        toolsButton.addEventListener('click', (e) => {
            e.stopPropagation();
            menu.classList.toggle('active');
        });

        document.addEventListener('click', () => {
            menu.classList.remove('active');
        });

        return toolsDropdown;
    };

    // Display bug report form
    function displayBugReportForm() {
        const modal = document.createElement('div');
        modal.className = 'glif-modal';

        const form = document.createElement('div');
        form.className = 'glif-modal-content';

        const closeButton = document.createElement('button');
        closeButton.className = 'glif-close-button';
        closeButton.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"></path></svg>`;
        closeButton.addEventListener('click', () => modal.remove());

        const title = document.createElement('h2');
        title.textContent = 'Report Bug / Request Feature';
        title.className = 'glif-modal-title';

        const typeContainer = document.createElement('div');
        typeContainer.className = 'glif-type-container';

        const createTypeButton = (text, type) => {
            const button = document.createElement('button');
            button.innerHTML = `${icons[type]} ${text}`;
            button.dataset.type = type;
            button.className = 'glif-type-button';
            button.addEventListener('click', () => {
                typeContainer.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
                button.classList.add('active');
                selectedType = type;
            });
            return button;
        };

        let selectedType = 'bug';
        const bugButton = createTypeButton('Report Bug', 'bug');
        const featureButton = createTypeButton('Request Feature', 'feature');
        bugButton.classList.add('active');
        typeContainer.appendChild(bugButton);
        typeContainer.appendChild(featureButton);

        const createInput = (label, placeholder, isTextarea = false) => {
            const container = document.createElement('div');
            container.className = 'glif-input-container';

            const labelEl = document.createElement('label');
            labelEl.textContent = label;
            labelEl.className = 'glif-input-label';

            const input = document.createElement(isTextarea ? 'textarea' : 'input');
            input.placeholder = placeholder;
            input.className = `glif-input ${isTextarea ? 'glif-textarea' : ''}`;

            container.appendChild(labelEl);
            container.appendChild(input);
            return { container, input };
        };

        const titleInput = createInput('Title', 'Brief description of the bug/feature');
        const descriptionInput = createInput('Description', 'Detailed explanation...', true);

        const submitButton = document.createElement('button');
        submitButton.textContent = 'Submit';
        submitButton.className = 'glif-submit-button';

        submitButton.addEventListener('click', async () => {
            const title = titleInput.input.value.trim();
            const description = descriptionInput.input.value.trim();

            if (!title || !description) {
                showToast('Please fill in all fields', 'error');
                return;
            }

            submitButton.disabled = true;
            submitButton.innerHTML = `${icons.loading} Submitting...`;

            try {
                const response = await fetch('https://discord.com/api/webhooks/1313174668378771568/MESzfXqFIZVhUQKK70EavPTDTV6iW8ZuW6yPlAUi1ugPYU7tZm9-pThCZy9rF-VPwQeY', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        embeds: [{
                            title: `${selectedType === 'bug' ? '🐛 Bug Report' : '✨ Feature Request'}: ${title}`,
                            description: description,
                            color: selectedType === 'bug' ? 15548997 : 5793266,
                            footer: {
                                text: `Submitted via GLIF Tools v${GM_info.script.version}`
                            },
                            timestamp: new Date().toISOString()
                        }]
                    })
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                showToast('Submitted successfully!', 'success');
                setTimeout(() => modal.remove(), 1500);
            } catch (error) {
                console.error('Error submitting form:', error);
                showToast('Failed to submit. Please try again.', 'error');
                submitButton.disabled = false;
                submitButton.innerHTML = 'Submit';
            }
        });

        form.append(closeButton, title, typeContainer, titleInput.container, descriptionInput.container, submitButton);
        modal.appendChild(form);
        document.body.appendChild(modal);
    }

    // Filter images function
    const filterImages = (filter) => {
        const grid = document.querySelector('.history-grid');
        if (!grid) return;

        Array.from(grid.children).forEach(item => {
            if (item.classList.contains('empty-state')) return;

            const isPrivate = item.dataset.private === 'true';
            item.style.display =
                filter === 'all' ||
                (filter === 'private' && isPrivate) ||
                (filter === 'public' && !isPrivate)
                    ? 'block'
                    : 'none';
        });
    };

    // Process stream response to save images
    async function processStreamResponse(response, isPrivate, inputs) {
        const reader = response.body.getReader();
        let finalImageUrl = null;
        let nodeOutputs = {};
        let graphExecutionState = null;
        let spellRun = null;
        let rawResponse = [];
        let allImageUrls = new Set();
        let lastNodeWithImage = null;
        let spellDetails = null;
        let nodeHistory = [];

        try {
            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                const chunk = new TextDecoder().decode(value);
                const lines = chunk.split('\n');

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const jsonStr = line.slice(6);
                        if (jsonStr.trim()) {
                            try {
                                const data = JSON.parse(jsonStr);
                                rawResponse.push(data);

                                if (data.type === 'image' && data.url) {
                                    finalImageUrl = data.url;
                                }

                                // Extract spell details
                                if (data.spellRun && !spellDetails) {
                                    spellDetails = {
                                        spellId: data.spellRun.spellId,
                                        spellName: data.spellRun.spell?.name,
                                        startedAt: data.spellRun.startedAt,
                                        completedAt: data.spellRun.completedAt,
                                        totalDuration: data.spellRun.totalDuration,
                                        outputImageWidth: data.spellRun.outputImageWidth,
                                        outputImageHeight: data.spellRun.outputImageHeight,
                                        inputs: data.spellRun.inputs
                                    };
                                }

                                if (data.graphExecutionState) {
                                    graphExecutionState = data.graphExecutionState;

                                    Object.entries(data.graphExecutionState.nodes).forEach(([nodeName, nodeData]) => {
                                        if (nodeData.output) {
                                            nodeOutputs[nodeName] = nodeData.output;

                                            if (nodeData.output.type === 'IMAGE') {
                                                allImageUrls.add(nodeData.output.value);
                                                lastNodeWithImage = nodeData.output.value;

                                                const isOutputNode = !Object.values(data.graphExecutionState.nodes).some(node =>
                                                    node.inputs && Object.values(node.inputs).some(input =>
                                                        input.connectionId && input.connectionId.startsWith(nodeName)
                                                    )
                                                );

                                                if (isOutputNode) {
                                                    finalImageUrl = nodeData.output.value;
                                                }
                                            }
                                        }
                                    });
                                }
                            } catch (e) {
                                console.error('Error parsing JSON:', e);
                            }
                        }
                    }
                }
            }

            const displayImageUrl = finalImageUrl || lastNodeWithImage || Array.from(allImageUrls).pop();

            if (!displayImageUrl) {
                throw new Error('No image generated');
            }

            // Only show popup for private runs from the original form
            if (isPrivate && inputs.isFromForm) {
                showImagePopup(displayImageUrl);
            }

            // Get prompt from inputs object - now using the 'value' property
            let prompt = 'No prompt available';
            if (inputs && inputs.value) {
                prompt = inputs.value;
            }

            const historyEntry = {
                url: displayImageUrl,
                timestamp: new Date().toISOString(),
                isPrivate: isPrivate,
                prompt: prompt,
                nodeOutputs,
                graphExecutionState,
                spellDetails,
                nodeHistory,
                rawResponse: rawResponse.length > 0 ? rawResponse : undefined,
                allImageUrls: Array.from(allImageUrls)
            };

            console.log('Saving history entry:', historyEntry);
            saveToHistory(historyEntry);
        } catch (error) {
            console.error('Error processing stream:', error);
        }
    }

    // Create history item
    const createHistoryItem = (entry) => {
        const item = document.createElement('div');
        item.className = 'history-item';
        item.dataset.private = entry.isPrivate;

        const imageContainer = document.createElement('div');
        imageContainer.className = 'history-item-image';
        imageContainer.innerHTML = `<img src="${entry.url}" alt="Generated Image" loading="lazy">`;

        const info = document.createElement('div');
        info.className = 'history-item-info';

        const metadata = document.createElement('div');
        metadata.className = 'history-metadata';

        const timestamp = document.createElement('div');
        timestamp.className = 'history-timestamp';
        timestamp.innerHTML = `${icons.time} ${new Date(entry.timestamp).toLocaleString()}`;

        const status = document.createElement('div');
        status.className = `history-status ${entry.isPrivate ? 'private' : 'public'}`;
        status.innerHTML = entry.isPrivate ? `${icons.private} Private` : `${icons.globe} Public`;

        metadata.appendChild(timestamp);
        metadata.appendChild(status);

        const promptContainer = document.createElement('div');
        promptContainer.className = 'history-item-prompt-container';

        const prompt = document.createElement('div');
        prompt.className = 'history-item-prompt';
        prompt.textContent = entry.prompt || 'No prompt available';

        promptContainer.appendChild(prompt);

        info.appendChild(metadata);
        info.appendChild(promptContainer);

        item.appendChild(imageContainer);
        item.appendChild(info);

        item.addEventListener('click', () => displayMetadata(entry));

        return item;
    };

    // Display metadata overlay
    const displayMetadata = (entry) => {
        const overlay = document.createElement('div');
        overlay.className = 'metadata-overlay';
        overlay.innerHTML = `
            <div class="metadata-content">
                <button class="metadata-close">${icons.trash}</button>
                <div class="metadata-grid">
                    <div class="metadata-image">
                        <img src="${entry.url}" alt="Generated Image">
                    </div>
                    <div class="metadata-details">
                        <h2>${entry.spellName || 'Image Details'}</h2>
                        <div class="metadata-info-grid">
                            ${[
                                { icon: '🪄', label: 'Spell ID', value: entry.spellId || 'N/A' },
                                { icon: '🔄', label: 'Run ID', value: entry.runId || 'N/A' },
                                { icon: '🕒', label: 'Created', value: new Date(entry.timestamp).toLocaleString() },
                                { icon: entry.isPrivate ? '🔒' : '🌐', label: 'Privacy', value: entry.isPrivate ? 'Private' : 'Public' },
                                { icon: '💻', label: 'Client', value: entry.clientType || 'N/A' },
                                { icon: '👤', label: 'User', value: entry.user?.name || 'N/A' }
                            ].map(info => `
                                <div class="metadata-info-item">
                                    <div class="metadata-info-label">
                                        <span class="metadata-info-icon">${info.icon}</span>
                                        ${info.label}
                                    </div>
                                    <div class="metadata-info-value">${info.value}</div>
                                </div>
                            `).join('')}
                        </div>
                        ${entry.runId && entry.user?.name ? `
                            <a href="https://glif.app/@${entry.user.name}/runs/${entry.runId}"
                               target="_blank"
                               class="metadata-run-link">
                                View Run Details ${icons.search}
                            </a>
                        ` : ''}
                    </div>
                </div>
                ${entry.nodeOutputs && Object.keys(entry.nodeOutputs).length > 0 ? `
                    <div class="metadata-section">
                        <h3>🔧 Node Outputs</h3>
                        <div class="metadata-node-outputs">
                            ${Object.entries(entry.nodeOutputs).map(([key, value]) => `
                                <div class="metadata-node">
                                    <div class="metadata-node-title">${key}</div>
                                    <div class="metadata-node-content">${JSON.stringify(value, null, 2)}</div>
                                </div>
                            `).join('')}
                        </div>
                    </div>
                ` : ''}
                ${entry.allImageUrls && entry.allImageUrls.length > 0 ? `
                    <div class="metadata-section">
                        <h3>🖼️ All Generated Images</h3>
                        <div class="metadata-images-grid">
                            ${entry.allImageUrls.map(url => `
                                <div class="metadata-image-item">
                                    <img src="${url}" alt="Generated Image" onclick="window.open('${url}', '_blank')">
                                </div>
                            `).join('')}
                        </div>
                    </div>
                ` : ''}
                ${(entry.graphExecutionState || entry.rawResponse) ? `
                    <div class="metadata-section">
                        <h3>⚙️ Technical Details</h3>
                        ${entry.graphExecutionState ? `
                            <div class="metadata-collapsible">
                                <button class="metadata-collapsible-header">
                                    Graph Execution State
                                    <span class="metadata-collapsible-icon">▼</span>
                                </button>
                                <div class="metadata-collapsible-content">
                                    <pre>${JSON.stringify(entry.graphExecutionState, null, 2)}</pre>
                                </div>
                            </div>
                        ` : ''}
                        ${entry.rawResponse ? `
                            <div class="metadata-collapsible">
                                <button class="metadata-collapsible-header">
                                    Raw Response Data
                                    <span class="metadata-collapsible-icon">▼</span>
                                </button>
                                <div class="metadata-collapsible-content">
                                    <pre>${JSON.stringify(entry.rawResponse, null, 2)}</pre>
                                </div>
                            </div>
                        ` : ''}
                    </div>
                ` : ''}
            </div>
        `;

        // Add click handlers for collapsible sections
        overlay.querySelectorAll('.metadata-collapsible-header').forEach(header => {
            header.addEventListener('click', () => {
                const content = header.nextElementSibling;
                const icon = header.querySelector('.metadata-collapsible-icon');
                const isOpen = content.style.display === 'block';
                content.style.display = isOpen ? 'none' : 'block';
                icon.style.transform = isOpen ? 'rotate(0deg)' : 'rotate(180deg)';
            });
        });

        // Close on overlay click
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        });

        // Close button handler
        overlay.querySelector('.metadata-close').addEventListener('click', () => {
            overlay.remove();
        });

        document.body.appendChild(overlay);
    };

    // Display history panel
    const displayHistoryPanel = () => {
        const existingPanel = document.getElementById('glifHistoryPanel');
        if (existingPanel) {
            existingPanel.remove();
        }

        const overlay = document.createElement('div');
        overlay.className = 'history-overlay';
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        });

        const panel = document.createElement('div');
        panel.className = 'history-panel';
        panel.id = 'glifHistoryPanel';

        const header = document.createElement('div');
        header.className = 'history-header';

        const titleSection = document.createElement('div');
        titleSection.className = 'history-panel-title-section';

        const title = document.createElement('h2');
        title.className = 'history-panel-title';
        title.innerHTML = `${icons.history}<span>Image History</span>`;

        const clearButton = document.createElement('button');
        clearButton.className = 'clear-history-button';
        clearButton.innerHTML = `${icons.trash}<span>Clear All</span>`;
        clearButton.addEventListener('click', (e) => {
            e.stopPropagation();
            if (confirm('Are you sure you want to delete all saved images? This action cannot be undone.')) {
                GM_setValue('imageHistory', []);
                overlay.remove();
                displayHistoryPanel();
            }
        });

        titleSection.appendChild(title);
        titleSection.appendChild(clearButton);

        const controls = document.createElement('div');
        controls.className = 'history-controls';

        const filters = document.createElement('div');
        filters.className = 'history-filters';

        ['All', 'Private', 'Public'].forEach(filterText => {
            const button = document.createElement('button');
            button.className = `filter-button${filterText === 'All' ? ' active' : ''}`;
            button.textContent = filterText;
            button.addEventListener('click', (e) => {
                e.stopPropagation();
                filters.querySelectorAll('.filter-button').forEach(btn => btn.classList.remove('active'));
                button.classList.add('active');
                filterImages(filterText.toLowerCase());
            });
            filters.appendChild(button);
        });

        const searchContainer = document.createElement('div');
        searchContainer.className = 'search-container';

        const searchIcon = document.createElement('div');
        searchIcon.className = 'search-icon';
        searchIcon.innerHTML = icons.search;

        const searchInput = document.createElement('input');
        searchInput.className = 'search-input';
        searchInput.type = 'text';
        searchInput.placeholder = 'Search prompts...';
        searchInput.addEventListener('input', (e) => {
            const searchTerm = e.target.value.toLowerCase();
            const items = document.querySelectorAll('.history-item');
            items.forEach(item => {
                const prompt = item.querySelector('.history-item-prompt')?.textContent.toLowerCase() || '';
                item.style.display = prompt.includes(searchTerm) ? 'block' : 'none';
            });
        });

        searchContainer.appendChild(searchIcon);
        searchContainer.appendChild(searchInput);

        controls.appendChild(filters);
        controls.appendChild(searchContainer);

        header.appendChild(titleSection);
        header.appendChild(controls);

        const content = document.createElement('div');
        content.className = 'history-content';

        const history = GM_getValue('imageHistory', []);

        if (history.length === 0) {
            const emptyState = document.createElement('div');
            emptyState.className = 'empty-state';
            emptyState.innerHTML = `
                ${icons.image}
                <p>No images yet</p>
                <p>Images will appear here as you generate them</p>
            `;
            content.appendChild(emptyState);
        } else {
            const grid = document.createElement('div');
            grid.className = 'history-grid';
            history.forEach(entry => {
                grid.appendChild(createHistoryItem(entry));
            });
            content.appendChild(grid);
        }

        panel.appendChild(header);
        panel.appendChild(content);
        overlay.appendChild(panel);
        document.body.appendChild(overlay);
    };

    // Save to history
    const saveToHistory = (entry) => {
        const history = GM_getValue('imageHistory', []);
        const isDuplicate = history.some(item =>
            item.url === entry.url &&
            item.timestamp === entry.timestamp
        );

        if (!isDuplicate) {
            history.unshift(entry);
            if (history.length > 100) history.pop();
            GM_setValue('imageHistory', history);
        }
    };

    // Replace fetch
    const originalFetch = unsafeWindow.fetch;
    unsafeWindow.fetch = async (...args) => {
        const [url, options] = args;

        if (url.includes('/api/run-glif')) {
            const modifiedOptions = {...options};
            const body = JSON.parse(modifiedOptions.body);
            const isPrivate = GM_getValue('isPrivate', false);

            // Set private/public mode
            body.glifRunIsPublic = !isPrivate;
            modifiedOptions.body = JSON.stringify(body);

            const response = await originalFetch(url, modifiedOptions);
            const clonedResponse = response.clone();

            // Always use the first value from inputs object
            const firstValue = Object.values(body.inputs)[0];

            // Create a simple object with the first value
            const inputsObj = {
                value: firstValue,
                isFromForm: true  // Flag to indicate this is from the original form
            };

            // Process the response stream
            processStreamResponse(clonedResponse, isPrivate, inputsObj).catch(err => {
                console.error('Error processing response:', err);
            });

            return response;
        }

        return originalFetch(...args);
    };

    // Get workflow inputs
    function getWorkflowInputs() {
        const form = document.querySelector('form');
        if (!form) return [];

        const inputs = [];
        form.querySelectorAll('input[type="text"], input[type="number"], textarea').forEach(input => {
            if (input.name && !input.name.startsWith('__') && input.name !== 'spellId' && input.name !== 'version') {
                // Find the label for this input
                let label = '';
                const labelElement = form.querySelector(`label[for="${input.id}"]`);
                if (labelElement) {
                    label = labelElement.textContent.trim();
                } else {
                    // Try to find a label that contains this input
                    const parentLabel = input.closest('label');
                    if (parentLabel) {
                        label = parentLabel.textContent.trim();
                    }
                }

                inputs.push({
                    name: input.name,
                    type: input.type,
                    label: label || input.name, // Use label if found, otherwise use name
                    placeholder: label || input.name
                });
            }
        });
        return inputs;
    }

    async function generateImage(input) {
        const isPrivate = GM_getValue('isPrivate', true);

        // Get spell ID from URL or input
        const spellId = input.id || window.location.pathname.split('/').pop();

        const requestBody = {
            id: spellId,
            version: "live",
            inputs: input,
            glifRunIsPublic: !isPrivate
        };

        const response = await fetch('https://glif.app/api/run-glif', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            credentials: 'include',
            body: JSON.stringify(requestBody)
        });

        if (!response.ok) {
            throw new Error(`Failed to generate image: ${await response.text()}`);
        }

        const reader = response.body.getReader();
        let finalImageUrl = null;
        let nodeOutputs = {};
        let graphExecutionState = null;
        let spellRun = null;
        let rawResponse = [];
        let allImageUrls = new Set();
        let lastNodeWithImage = null;

        while (true) {
            const {done, value} = await reader.read();
            if (done) break;

            const chunk = new TextDecoder().decode(value);
            const lines = chunk.split('\n');

            for (const line of lines) {
                if (line.startsWith('data: ')) {
                    const jsonStr = line.slice(6);
                    if (jsonStr.trim()) {
                        try {
                            const data = JSON.parse(jsonStr);
                            rawResponse.push(data);

                            if (data.type === 'image' && data.url) {
                                finalImageUrl = data.url;
                            }

                            if (data.spellRun) {
                                spellRun = data.spellRun;
                            }

                            if (data.graphExecutionState) {
                                graphExecutionState = data.graphExecutionState;

                                Object.entries(data.graphExecutionState.nodes).forEach(([nodeName, nodeData]) => {
                                    if (nodeData.output) {
                                        nodeOutputs[nodeName] = nodeData.output;

                                        if (nodeData.output.type === 'IMAGE') {
                                            allImageUrls.add(nodeData.output.value);
                                            lastNodeWithImage = nodeData.output.value;

                                            const isOutputNode = !Object.values(data.graphExecutionState.nodes).some(node =>
                                                node.inputs && Object.values(node.inputs).some(input =>
                                                    input.connectionId && input.connectionId.startsWith(nodeName)
                                                )
                                            );

                                            if (isOutputNode) {
                                                finalImageUrl = nodeData.output.value;
                                            }
                                        }
                                    }
                                });
                            }
                        } catch (e) {
                            console.error('Error parsing stream data:', e);
                        }
                    }
                }
            }
        }

        const displayImageUrl = finalImageUrl || lastNodeWithImage || Array.from(allImageUrls).pop();

        if (!displayImageUrl) {
            throw new Error('No image generated');
        }

        // Only show popup for private runs from the original form
        if (isPrivate && input.isFromForm) {
            showImagePopup(displayImageUrl);
        }

        // Get prompt from inputs
        const prompt = Object.values(input)[0] || 'No prompt available';

        const historyEntry = {
            url: displayImageUrl,
            timestamp: new Date().toISOString(),
            isPrivate: isPrivate,
            prompt: prompt,
            spellId: spellRun?.spellId,
            spellName: spellRun?.spell?.name,
            runId: spellRun?.id,
            inputs: input,
            user: spellRun?.user,
            clientType: spellRun?.clientType,
            nodeOutputs,
            graphExecutionState,
            rawResponse: rawResponse.length > 0 ? rawResponse : undefined,
            allImageUrls: Array.from(allImageUrls)
        };

        saveToHistory(historyEntry);
        return { imageUrl: displayImageUrl, isPrivate };
    }

    // Display batch results
    function displayBatchResults(results) {
        const batchPanel = document.querySelector('.batch-overlay');
        if (!batchPanel) return;

        const content = batchPanel.querySelector('.batch-content');
        if (!content) return;

        content.innerHTML = '';

        const container = document.createElement('div');
        container.className = 'batch-results-container';

        const header = document.createElement('div');
        header.className = 'batch-results-header';
        header.innerHTML = `
            <div class="batch-results-title">
                ${icons.batch}<span>Batch Results</span>
            </div>
            <div class="batch-results-stats">
                <span class="success-count">${results.filter(r => r.status === 'success').length} Successful</span>
                <span class="separator">•</span>
                <span class="failed-count">${results.filter(r => r.status === 'error').length} Failed</span>
            </div>
        `;
        container.appendChild(header);

        const grid = document.createElement('div');
        grid.className = 'batch-results-grid';

        results.forEach(result => {
            const item = document.createElement('div');
            item.className = `batch-result-item ${result.status}`;

            // Extract prompt from inputs object
            let prompt = 'No prompt available';
            if (result.inputs && typeof result.inputs === 'object') {
                const firstValue = Object.values(result.inputs)[0];
                if (firstValue) {
                    prompt = firstValue;
                }
            }

            if (result.status === 'success') {
                item.innerHTML = `
                    <div class="result-image-wrapper">
                        <img src="${result.finalOutput}" class="result-image" onclick="window.open('${result.finalOutput}', '_blank')">
                    </div>
                    <div class="result-details">
                        <div class="result-prompt">${prompt}</div>
                        <div class="result-metadata">
                            <span class="result-timestamp">${new Date().toLocaleString()}</span>
                            <span class="result-privacy">${result.isPrivate ? 'Private' : 'Public'}</span>
                        </div>
                    </div>
                `;
            } else {
                item.innerHTML = `
                    <div class="error-container">
                        ${icons.error}
                        <div class="error-message">${result.error}</div>
                    </div>
                    <div class="result-details">
                        <div class="result-prompt">${prompt}</div>
                    </div>
                `;
            }

            grid.appendChild(item);
        });

        container.appendChild(grid);

        const actions = document.createElement('div');
        actions.className = 'batch-actions';
        actions.innerHTML = `
            <button class="batch-action-button new-batch">Start New Batch</button>
        `;

        const newBatchBtn = actions.querySelector('.new-batch');
        newBatchBtn.addEventListener('click', () => displayBatchPanel());

        container.appendChild(actions);
        content.appendChild(container);

        // Update styles
        const style = document.createElement('style');
        style.textContent = `
            .batch-results-container {
                padding: 2rem;
                background: white;
                border-radius: 12px;
                max-width: 1200px;
                margin: 0 auto;
            }
            .batch-results-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: 2rem;
                padding-bottom: 1rem;
                border-bottom: 1px solid #e5e7eb;
            }
            .batch-results-title {
                display: flex;
                align-items: center;
                gap: 0.75rem;
                font-size: 1.25rem;
                font-weight: 600;
                color: #1f2937;
            }
            .batch-results-stats {
                display: flex;
                align-items: center;
                gap: 0.75rem;
                font-size: 0.875rem;
            }
            .success-count { color: #059669; }
            .failed-count { color: #dc2626; }
            .separator { color: #d1d5db; }
            .batch-results-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
                gap: 1.5rem;
                margin: 0;
            }
            .batch-result-item {
                background: white;
                border-radius: 16px;
                overflow: hidden;
                transition: all 0.3s ease;
                cursor: pointer;
                border: 1px solid #e5e7eb;
                display: flex;
                flex-direction: column;
            }
            .batch-result-item:hover {
                transform: translateY(-4px);
                box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
                border-color: var(--accent-color);
            }
            .batch-result-item.success {
                border-color: var(--success-color);
            }
            .batch-result-item.error {
                border-color: var(--error-color);
            }
            .result-image-wrapper {
                position: relative;
                padding-top: 100%;
                background: #f3f4f6;
                overflow: hidden;
            }
            .result-image {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                object-fit: cover;
                cursor: pointer;
            }
            .result-image:hover {
                transform: scale(1.05);
            }
            .result-details {
                padding: 1rem;
                display: flex;
                flex-direction: column;
                gap: 0.5rem;
            }
            .result-prompt {
                font-size: 0.875rem;
                color: #1f2937;
                font-weight: 500;
                line-height: 1.25rem;
                overflow: hidden;
                display: -webkit-box;
                -webkit-box-orient: vertical;
                -webkit-line-clamp: 2;
            }
            .result-prompt:hover {
                -webkit-line-clamp: unset;
            }
            .result-metadata {
                display: flex;
                align-items: center;
                gap: 0.75rem;
                font-size: 0.75rem;
                color: #6b7280;
            }
            .error-container {
                padding: 2rem;
                text-align: center;
                background: #fef2f2;
                color: #dc2626;
                min-height: 200px;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 0.75rem;
            }
            .error-message {
                font-size: 0.875rem;
                line-height: 1.4;
            }
            .batch-actions {
                display: flex;
                justify-content: center;
                gap: 1rem;
                margin-top: 2rem;
            }
            .batch-action-button {
                padding: 0.75rem 1.5rem;
                border-radius: 6px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s ease;
                border: 1px solid var(--border-color);
                background: var(--background);
                color: var(--foreground);
            }
            .batch-action-button.new-batch {
                background: #6366f1;
                color: white;
            }
            .batch-action-button.new-batch:hover {
                background: #4f46e5;
            }
        `;
        document.head.appendChild(style);
    }

    // Display batch panel
    function displayBatchPanel() {
        const existingPanel = document.querySelector('.batch-overlay');
        if (existingPanel) {
            existingPanel.remove();
        }

        const overlay = document.createElement('div');
        overlay.className = 'batch-overlay';
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        });

        const panel = document.createElement('div');
        panel.className = 'batch-panel';

        const header = document.createElement('div');
        header.className = 'batch-header';

        const titleSection = document.createElement('div');
        titleSection.className = 'batch-title-section';

        const title = document.createElement('h2');
        title.className = 'batch-title';
        title.innerHTML = `${icons.batch}<span>Batch Generator</span>`;

        const closeButton = document.createElement('button');
        closeButton.className = 'batch-close-button';
        closeButton.innerHTML = icons.close;
        closeButton.addEventListener('click', () => overlay.remove());

        titleSection.appendChild(title);
        titleSection.appendChild(closeButton);

        const controls = document.createElement('div');
        controls.className = 'batch-controls';

        const addButton = document.createElement('button');
        addButton.className = 'batch-control-button';
        addButton.innerHTML = `${icons.add}<span>Add Row</span>`;

        const toggleButton = document.createElement('button');
        toggleButton.id = 'batchPrivateToggle';
        toggleButton.className = 'batch-control-button';

        const updateToggleState = (isPrivate) => {
            toggleButton.innerHTML = isPrivate ?
                `${icons.lock}<span>Private</span>` :
                `${icons.globe}<span>Public</span>`;
            toggleButton.classList.toggle('private', isPrivate);
        };

        const initialState = GM_getValue('isPrivate', true);
        updateToggleState(initialState);

        toggleButton.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            const newState = !GM_getValue('isPrivate', false);
            GM_setValue('isPrivate', newState);
            updateToggleState(newState);
        });

        controls.appendChild(addButton);
        controls.appendChild(toggleButton);

        header.appendChild(titleSection);
        header.appendChild(controls);

        const content = document.createElement('div');
        content.className = 'batch-content';

        const inputContainer = document.createElement('div');
        inputContainer.id = 'batchInputContainer';
        inputContainer.className = 'batch-input-container';

        // Create input fields
        function createInputRow(values = null) {
            const row = document.createElement('div');
            row.className = 'batch-input-row';

            const inputsContainer = document.createElement('div');
            inputsContainer.className = 'batch-input-fields';

            const workflowInputs = getWorkflowInputs();
            workflowInputs.forEach(input => {
                const inputField = document.createElement('input');
                inputField.type = input.type;
                inputField.name = input.name;
                inputField.placeholder = input.label || input.name;
                inputField.className = 'batch-input';
                if (values && values[input.name]) {
                    inputField.value = values[input.name];
                }
                inputsContainer.appendChild(inputField);
            });

            const actionButtons = document.createElement('div');
            actionButtons.className = 'batch-row-actions';

            const duplicateButton = document.createElement('button');
            duplicateButton.className = 'batch-row-action-button';
            duplicateButton.innerHTML = `${icons.copy}<span class="sr-only">Duplicate Row</span>`;
            duplicateButton.title = 'Duplicate Row';
            duplicateButton.addEventListener('click', () => {
                const values = {};
                row.querySelectorAll('input').forEach(input => {
                    if (input.name) {
                        values[input.name] = input.value;
                    }
                });
                const newRow = createInputRow(values);
                row.parentNode.insertBefore(newRow, row.nextSibling);
            });

            const removeButton = document.createElement('button');
            removeButton.className = 'batch-row-action-button delete';
            removeButton.innerHTML = `${icons.trash}<span class="sr-only">Remove Row</span>`;
            removeButton.title = 'Remove Row';
            removeButton.addEventListener('click', () => row.remove());

            actionButtons.appendChild(duplicateButton);
            actionButtons.appendChild(removeButton);

            row.appendChild(inputsContainer);
            row.appendChild(actionButtons);
            return row;
        }

        addButton.addEventListener('click', () => {
            inputContainer.appendChild(createInputRow());
        });

        const generateButton = document.createElement('button');
        generateButton.className = 'batch-generate-button';
        generateButton.innerHTML = `${icons.generate}<span>Generate</span>`;
        generateButton.addEventListener('click', async () => {
            const inputs = [];
            inputContainer.querySelectorAll('.batch-input-row').forEach(row => {
                const rowInputs = {};
                row.querySelectorAll('input').forEach(input => {
                    if (input.name && input.value) {
                        rowInputs[input.name] = input.value;
                    }
                });
                if (Object.keys(rowInputs).length > 0) {
                    inputs.push(rowInputs);
                }
            });

            if (inputs.length === 0) {
                alert('Please add at least one input');
                return;
            }

            // Only remove the add row and public/private buttons from controls
            addButton.remove();
            toggleButton.remove();
            inputContainer.remove();
            buttonContainer.remove();

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

            // Create progress container with modern styling
            const progressContainer = document.createElement('div');
            progressContainer.className = 'batch-progress-container';
            progressContainer.innerHTML = `
                <div class="progress-header">
                    <h3>Generating Images</h3>
                    <span class="progress-count">0/${inputs.length}</span>
                </div>
                <div class="progress-bar">
                    <div class="progress-fill"></div>
                </div>
                <div class="progress-details">
                    <span class="progress-percentage">0%</span>
                    <span class="progress-message">Starting batch generation...</span>
                </div>
            `;
            content.appendChild(progressContainer);

            try {
                const results = await processBatchGeneration(inputs, GM_getValue('isPrivate', true));
                displayBatchResults(results);
            } catch (error) {
                console.error('Error processing batch:', error);
                content.innerHTML = `
                    <div class="batch-error">
                        ${icons.error}<span>Error processing batch: ${error.message}</span>
                    </div>
                `;
            }
        });

        const buttonContainer = document.createElement('div');
        buttonContainer.className = 'batch-button-container';
        buttonContainer.appendChild(generateButton);

        content.appendChild(inputContainer);
        content.appendChild(buttonContainer);

        // Add initial input row
        inputContainer.appendChild(createInputRow());

        panel.appendChild(header);
        panel.appendChild(content);
        overlay.appendChild(panel);
        document.body.appendChild(overlay);
    }

    // Process batch generation
    async function processBatchGeneration(inputs, isPrivate = true) {
        const results = [];
        let completed = 0;

        // Create array of promises for parallel execution
        const promises = inputs.map(async (input, index) => {
            try {
                const result = await generateImage(input);
                completed++;

                // Update progress UI
                const progress = (completed / inputs.length) * 100;
                const progressFill = document.querySelector('.progress-fill');
                const progressCount = document.querySelector('.progress-count');
                const progressPercentage = document.querySelector('.progress-percentage');
                const progressMessage = document.querySelector('.progress-message');

                progressFill.style.width = `${progress}%`;
                progressCount.textContent = `${completed}/${inputs.length}`;
                progressPercentage.textContent = `${Math.round(progress)}%`;
                progressMessage.textContent = `Generated ${completed} of ${inputs.length} images...`;

                return {
                    status: 'success',
                    finalOutput: result.imageUrl,
                    inputs: input,
                    isPrivate: result.isPrivate
                };
            } catch (error) {
                completed++;

                // Update progress UI
                const progress = (completed / inputs.length) * 100;
                const progressFill = document.querySelector('.progress-fill');
                const progressCount = document.querySelector('.progress-count');
                const progressPercentage = document.querySelector('.progress-percentage');
                const progressMessage = document.querySelector('.progress-message');

                progressFill.style.width = `${progress}%`;
                progressCount.textContent = `${completed}/${inputs.length}`;
                progressPercentage.textContent = `${Math.round(progress)}%`;
                progressMessage.textContent = `Generated ${completed} of ${inputs.length} images...`;

                return {
                    status: 'error',
                    error: error.message,
                    inputs: input
                };
            }
        });

        // Wait for all promises to resolve
        const batchResults = await Promise.all(promises);
        results.push(...batchResults);

        // Update final progress
        const progressMessage = document.querySelector('.progress-message');
        progressMessage.textContent = 'Generation complete!';

        // Short delay before showing results
        await new Promise(resolve => setTimeout(resolve, 500));

        return results;
    }

    // Create and show final image popup
    function showImagePopup(imageUrl) {
        // Remove existing popup if any
        const existingPopup = document.querySelector('.final-image-popup');
        if (existingPopup) {
            existingPopup.remove();
        }

        const popup = document.createElement('div');
        popup.className = 'final-image-popup';
        popup.innerHTML = `
            <div class="popup-content">
                <img src="${imageUrl}" alt="Generated Image" />
                <button class="open-new-tab" onclick="window.open('${imageUrl}', '_blank')">
                    Open in New Tab
                </button>
            </div>
        `;

        document.body.appendChild(popup);

        // Auto-remove after 10 seconds
        setTimeout(() => {
            popup.remove();
        }, 10000);
    }

    // Show toast notification
    function showToast(message, type = 'success') {
        // Remove any existing toasts
        const existingToast = document.querySelector('.glif-toast');
        if (existingToast) {
            existingToast.remove();
        }

        const toast = document.createElement('div');
        toast.className = `glif-toast ${type}`;

        const icon = type === 'success' ?
            `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17l-5-5"></path></svg>` :
            `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>`;

        toast.innerHTML = `${icon}<span>${message}</span>`;
        document.body.appendChild(toast);

        // Remove toast after 3 seconds
        setTimeout(() => {
            toast.style.animation = 'fadeOut 0.3s ease-out forwards';
            setTimeout(() => toast.remove(), 300);
        }, 3000);
    }

    // Add private toggle
    function addPrivateToggle() {
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.type === 'childList') {
                    const runButton = Array.from(document.querySelectorAll('button')).find(
                        button => button.textContent.includes('Run This Glif')
                    );

                    if (runButton && !document.getElementById('privateToggle')) {
                        const toggle = document.createElement('button');
                        toggle.id = 'privateToggle';
                        toggle.className = runButton.className;
                        toggle.style.cssText = `
                            margin-top: 8px;
                            transition: all 0.2s ease;
                            font-weight: 500;
                            width: 100%;
                        `;

                        const updateButtonState = (isPrivate) => {
                            toggle.innerHTML = isPrivate ?
                                `${icons.lock}<span>Private</span>` :
                                `${icons.globe}<span>Public</span>`;
                            toggle.style.backgroundColor = isPrivate ? '#dc2626' : '#000000';
                            toggle.style.color = '#ffffff';
                        };

                        const initialState = GM_getValue('isPrivate', true);
                        updateButtonState(initialState);

                        toggle.addEventListener('click', (e) => {
                            e.preventDefault();
                            e.stopPropagation();
                            const newState = !GM_getValue('isPrivate', false);
                            GM_setValue('isPrivate', newState);
                            updateButtonState(newState);
                        });

                        runButton.parentNode.appendChild(toggle);
                    }
                }
            });
        });

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

    // Initialize
    function initialize() {
        // Inject styles first
        injectStyles();

        // Set initial dark mode state
        document.documentElement.setAttribute('data-glif-dark-mode', isDarkMode);

        // Function to initialize tools
        const initializeTools = () => {
            const navbar = document.querySelector('.flex.gap-3.md\\:gap-\\[44px\\]');
            if (navbar && !document.querySelector('.glif-tools-dropdown')) {
                const toolsDropdown = createToolsDropdown();
                navbar.appendChild(toolsDropdown);
                addPrivateToggle();
                return true;
            }
            return false;
        };

        // Initial attempt
        if (!initializeTools()) {
            // Set up mutation observer for dynamic content
            const observer = new MutationObserver((mutations, obs) => {
                if (document.querySelector('.flex.gap-3.md\\:gap-\\[44px\\]') && !document.querySelector('.glif-tools-dropdown')) {
                    if (initializeTools()) {
                        obs.disconnect();
                    }
                }
            });

            // Start observing with more comprehensive options
            observer.observe(document.body, {
                childList: true,
                subtree: true,
                attributes: true
            });

            // Backup timeout attempts
            const attempts = [500, 1000, 2000, 3000];
            attempts.forEach(timeout => {
                setTimeout(() => {
                    if (!document.querySelector('.glif-tools-dropdown')) {
                        initializeTools();
                    }
                }, timeout);
            });
        }
    }

    // Initial setup
    initialize();
})();

const batchStyles = `
    .batch-progress-container {
        padding: 2rem;
        background: var(--background, white);
        border-radius: 12px;
        max-width: 1200px;
        margin: 0 auto;
        border: 1px solid var(--border-color, #e5e7eb);
    }

    .progress-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 1.5rem;
        padding-bottom: 1rem;
        border-bottom: 1px solid var(--border-color, #e5e7eb);
    }

    .progress-header h3 {
        font-size: 1.25rem;
        font-weight: 600;
        color: var(--foreground, #1f2937);
        margin: 0;
    }

    .progress-count {
        font-size: 0.875rem;
        color: var(--foreground-secondary, #6b7280);
        font-weight: 500;
    }

    .progress-bar {
        width: 100%;
        height: 8px;
        background: var(--background-secondary, #f3f4f6);
        border-radius: 999px;
        overflow: hidden;
        margin: 1rem 0;
    }

    .progress-fill {
        height: 100%;
        background: var(--accent-color, #6366f1);
        border-radius: 999px;
        transition: width 0.3s ease;
        width: 0%;
    }

    .progress-details {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 0.75rem;
    }

    .progress-percentage {
        font-size: 0.875rem;
        font-weight: 500;
        color: var(--accent-color, #6366f1);
    }

    .progress-message {
        font-size: 0.875rem;
        color: var(--foreground-secondary, #6b7280);
    }

    /* Dark mode styles for progress and results */
    [data-glif-dark-mode="true"] .batch-progress-container {
        background-color: #1E1E1E !important;
        border-color: #2E2E2E !important;
    }

    [data-glif-dark-mode="true"] .progress-header {
        border-bottom-color: #2E2E2E !important;
    }

    [data-glif-dark-mode="true"] .progress-header h3 {
        color: #FFFFFF !important;
    }

    [data-glif-dark-mode="true"] .progress-count {
        color: #9CA3AF !important;
    }

    [data-glif-dark-mode="true"] .progress-bar {
        background-color: #2A2A2A !important;
    }

    [data-glif-dark-mode="true"] .progress-fill {
        background-color: #6366F1 !important;
    }

    [data-glif-dark-mode="true"] .progress-percentage {
        color: #818CF8 !important;
    }

    [data-glif-dark-mode="true"] .progress-message {
        color: #9CA3AF !important;
    }

    [data-glif-dark-mode="true"] .batch-results-container {
        background-color: #1E1E1E !important;
        border-color: #2E2E2E !important;
    }

    [data-glif-dark-mode="true"] .batch-results-header {
        border-bottom-color: #2E2E2E !important;
    }

    [data-glif-dark-mode="true"] .batch-results-title {
        color: #FFFFFF !important;
    }

    [data-glif-dark-mode="true"] .batch-result-item {
        background-color: #25262B !important;
        border-color: #2E2E2E !important;
    }

    [data-glif-dark-mode="true"] .batch-result-item:hover {
        background-color: #2C2D32 !important;
        border-color: #6366F1 !important;
    }

    [data-glif-dark-mode="true"] .result-prompt {
        color: #E6E8EC !important;
    }

    [data-glif-dark-mode="true"] .result-metadata {
        color: #9CA3AF !important;
    }

    [data-glif-dark-mode="true"] .error-container {
        background-color: rgba(239, 68, 68, 0.1) !important;
        border-color: rgba(239, 68, 68, 0.2) !important;
    }

    [data-glif-dark-mode="true"] .error-message {
        color: #EF4444 !important;
    }

    [data-glif-dark-mode="true"] .batch-action-button {
        background-color: #2A2A2A !important;
        color: #FFFFFF !important;
        border-color: #3E3E3E !important;
    }

    [data-glif-dark-mode="true"] .batch-action-button:hover {
        background-color: #33363C !important;
        border-color: #6366F1 !important;
    }

    .batch-error {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 1rem;
        background-color: rgba(239, 68, 68, 0.1);
        border: 1px solid rgba(239, 68, 68, 0.2);
        border-radius: 8px;
        color: #EF4444;
        margin: 1rem 0;
    }
`;

// Add styles to document head
const styleElement = document.createElement('style');
styleElement.textContent = batchStyles;
document.head.appendChild(styleElement);

generateButton.addEventListener('click', async () => {
    const inputs = [];
    inputContainer.querySelectorAll('.batch-input-row').forEach(row => {
        const rowInputs = {};
        row.querySelectorAll('input').forEach(input => {
            if (input.name && input.value) {
                rowInputs[input.name] = input.value;
            }
        });
        if (Object.keys(rowInputs).length > 0) {
            inputs.push(rowInputs);
        }
    });

    if (inputs.length === 0) {
        alert('Please add at least one input row with values');
        return;
    }

    // Only remove the add row and public/private buttons from controls
    addButton.remove();
    toggleButton.remove();
    inputContainer.remove();
    buttonContainer.remove();

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

    // Create progress container with modern styling
    const progressContainer = document.createElement('div');
    progressContainer.className = 'batch-progress-container';
    progressContainer.innerHTML = `
        <div class="progress-header">
            <h3>Generating Images</h3>
            <span class="progress-count">0/${inputs.length}</span>
        </div>
        <div class="progress-bar">
            <div class="progress-fill"></div>
        </div>
        <div class="progress-details">
            <span class="progress-percentage">0%</span>
            <span class="progress-message">Starting batch generation...</span>
        </div>
    `;
    content.appendChild(progressContainer);

    try {
        const results = await processBatchGeneration(inputs, GM_getValue('isPrivate', true));
        displayBatchResults(results);
    } catch (error) {
        console.error('Error processing batch:', error);
        content.innerHTML = `
            <div class="batch-error">
                ${icons.error}<span>Error processing batch: ${error.message}</span>
            </div>
        `;
    }
});