GLIF Tools V2

A set of tools i use in glif.app

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

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

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

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

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

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

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

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

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

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

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

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

// ==UserScript==
// @name         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>
        `;
    }
});