Grok Imagine Manager (Updated V4.6 - Targeted Capture)

Includes targeted auto-capture for new Grok image input styles. History tab now only shows Auto-Captured items. Fixed slider display bug. Video tab includes Sort by High/Low Percentage. Includes Silent Mode.

当前为 2025-11-20 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Grok Imagine Manager (Updated V4.6 - Targeted Capture)
// @namespace    http://tampermonkey.net/
// @version      4.6.0
// @description  Includes targeted auto-capture for new Grok image input styles. History tab now only shows Auto-Captured items. Fixed slider display bug. Video tab includes Sort by High/Low Percentage. Includes Silent Mode.
// @author       You
// @license MIT
// @match        https://grok.com/*
// @match        https://*.grok.com/*
// @match        https://grok.x.ai/*
// @match        https://*.grok.x.ai/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    if (window.grokPromptManagerLoaded) return;
    window.grokPromptManagerLoaded = true;

    function initScript() {
        // --- MODERN CSS ---
        GM_addStyle(`
            :root {
                --grok-bg: #000000;
                --grok-surface: #16181c;
                --grok-surface-hover: #1d1f23;
                --grok-border: #2f3336;
                --grok-primary: #1d9bf0;
                --grok-primary-hover: #1a8cd8;
                --grok-text-main: #e7e9ea;
                --grok-text-muted: #71767b;
                --grok-danger: #f4212e;
                --grok-warning: #ffd400;
                --grok-success: #00ba7c;
                --grok-radius: 16px;
                --grok-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
            }

            .grok-prompt-overlay { position: fixed; inset: 0; z-index: 10000; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(4px); display: none; opacity: 0; transition: opacity 0.2s ease; }
            .grok-prompt-overlay.open { display: flex; opacity: 1; pointer-events: auto; }
            .grok-prompt-modal { position: fixed; background: rgba(22, 24, 28, 0.95); border: 1px solid var(--grok-border); border-radius: var(--grok-radius); width: 950px; height: 800px; min-width: 500px; min-height: 500px; display: flex; flex-direction: column; box-shadow: var(--grok-shadow); top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1); color: var(--grok-text-main); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
            .grok-prompt-overlay.open .grok-prompt-modal { transform: translate(-50%, -50%) scale(1); }
            .grok-prompt-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; border-bottom: 1px solid var(--grok-border); cursor: move; background: rgba(255,255,255,0.02); }
            .grok-prompt-title { font-size: 18px; font-weight: 700; display: flex; align-items: center; gap: 10px; }
            .grok-prompt-close { background: transparent; border: none; color: var(--grok-text-muted); cursor: pointer; padding: 8px; border-radius: 50%; transition: all 0.2s; }
            .grok-prompt-close:hover { background: rgba(239, 68, 68, 0.1); color: var(--grok-danger); }
            .grok-prompt-tabs { display: flex; padding: 0 16px; border-bottom: 1px solid var(--grok-border); background: var(--grok-bg); }
            .grok-prompt-tab { padding: 16px; background: none; border: none; color: var(--grok-text-muted); font-weight: 600; font-size: 14px; cursor: pointer; border-bottom: 3px solid transparent; transition: all 0.2s; }
            .grok-prompt-tab:hover { color: var(--grok-text-main); background: rgba(255,255,255,0.03); }
            .grok-prompt-tab.active { color: var(--grok-primary); border-bottom-color: var(--grok-primary); }
            .grok-prompt-content { flex: 1; overflow-y: auto; padding: 24px; scroll-behavior: smooth; }
            .grok-prompt-content::-webkit-scrollbar { width: 8px; }
            .grok-prompt-content::-webkit-scrollbar-track { background: transparent; }
            .grok-prompt-content::-webkit-scrollbar-thumb { background: var(--grok-border); border-radius: 4px; }
            .grok-prompt-form { display: flex; flex-direction: column; gap: 20px; }
            .grok-prompt-label { display: block; font-size: 13px; font-weight: 600; color: var(--grok-text-muted); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
            .grok-prompt-select, .grok-prompt-textarea, .grok-prompt-category-input { width: 100%; background: black; border: 1px solid var(--grok-border); border-radius: 8px; padding: 12px; color: var(--grok-text-main); font-size: 15px; font-family: inherit; transition: border-color 0.2s, box-shadow 0.2s; box-sizing: border-box; }
            .grok-prompt-select:focus, .grok-prompt-textarea:focus, .grok-prompt-category-input:focus { outline: none; border-color: var(--grok-primary); box-shadow: 0 0 0 2px rgba(29, 155, 240, 0.2); }
            .grok-prompt-textarea { height: 140px; line-height: 1.5; resize: vertical; }
            .grok-prompt-button, .grok-prompt-add-btn { background: var(--grok-primary); color: white; border: none; padding: 12px 20px; border-radius: 24px; font-weight: 700; cursor: pointer; transition: transform 0.1s, background 0.2s; display: flex; align-items: center; justify-content: center; gap: 8px; }
            .grok-prompt-button:hover { background: var(--grok-primary-hover); transform: translateY(-1px); }
            .grok-prompt-list { display: flex; flex-direction: column; gap: 12px; }

            /* --- CHECKBOX SUPPORT --- */
            .grok-prompt-item { display: flex; gap: 12px; align-items: flex-start; background: transparent; border: 1px solid var(--grok-border); border-radius: 12px; padding: 16px; transition: background 0.2s, border-color 0.2s; }
            .grok-prompt-item:hover { background: rgba(255,255,255,0.02); border-color: #555; }

            .grok-item-check-wrapper { padding-top: 4px; display: flex; align-items: center; justify-content: center; }
            .grok-item-checkbox { width: 18px; height: 18px; accent-color: var(--grok-primary); cursor: pointer; }

            .grok-item-content-wrapper { flex: 1; width: 100%; min-width: 0; }

            .grok-prompt-item-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 15px; margin-bottom: 10px; }
            .grok-prompt-item-text { flex: 1; color: var(--grok-text-main); line-height: 1.5; font-size: 15px; white-space: pre-wrap; }
            .grok-prompt-item-delete { opacity: 0; color: var(--grok-text-muted); background: none; border: none; cursor: pointer; transition: opacity 0.2s, color 0.2s; padding: 4px; }
            .grok-prompt-item:hover .grok-prompt-item-delete { opacity: 1; }
            .grok-prompt-item-delete:hover { color: var(--grok-danger); }

            .grok-prompt-item-footer { display: flex; align-items: center; gap: 12px; margin-top: 12px; flex-wrap: wrap; }
            .grok-prompt-category-badge { background: rgba(29, 155, 240, 0.1); color: var(--grok-primary); padding: 4px 10px; border-radius: 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; flex-shrink: 0; }
            .grok-prompt-category-badge.auto { background: rgba(0, 186, 124, 0.1); color: var(--grok-success); }
            .grok-prompt-copy-btn { flex-shrink: 0; background: transparent; border: 1px solid var(--grok-border); color: var(--grok-text-muted); padding: 6px 12px; border-radius: 16px; font-size: 12px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: all 0.2s; }
            .grok-prompt-copy-btn:hover { border-color: var(--grok-text-main); color: var(--grok-text-main); background: rgba(255,255,255,0.05); }
            .grok-prompt-stars { display: flex; gap: 6px; }
            .grok-prompt-star { width: 32px; height: 32px; cursor: pointer; color: #333; transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1); }
            .grok-prompt-star.filled { color: #ffd700; filter: drop-shadow(0 0 2px rgba(255, 215, 0, 0.4)); }
            .grok-prompt-star:hover { transform: scale(1.15); }
            .grok-toast-container { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 11000; pointer-events: none; }
            .grok-toast { background: var(--grok-primary); color: white; padding: 10px 20px; border-radius: 24px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); font-weight: 600; font-size: 14px; animation: slideUpFade 0.3s ease forwards; display: flex; align-items: center; gap: 8px; }
            @keyframes slideUpFade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
            .grok-prompt-category-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
            .grok-prompt-category-tag { background: var(--grok-surface-hover); border: 1px solid var(--grok-border); color: var(--grok-text-main); padding: 8px 14px; border-radius: 20px; font-size: 13px; display: flex; align-items: center; gap: 8px; }
            .grok-prompt-export-section { margin-top: 32px; padding-top: 24px; border-top: 1px solid var(--grok-border); }
            .grok-prompt-export-btn { flex: 1; background: transparent; border: 1px solid var(--grok-border); color: var(--grok-text-main); padding: 12px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px; transition: all 0.2s; font-weight: 600; }
            .grok-prompt-export-btn:hover { background: var(--grok-surface-hover); border-color: #666; }
            .grok-prompt-export-btn.danger { color: var(--grok-danger); border-color: rgba(244, 33, 46, 0.3); }
            .grok-prompt-export-btn.danger:hover { background: rgba(244, 33, 46, 0.1); border-color: var(--grok-danger); }
            .grok-prompt-hint { position: fixed; bottom: 20px; right: 20px; background: var(--grok-surface); border: 1px solid var(--grok-border); padding: 10px 16px; border-radius: 12px; color: var(--grok-text-muted); font-size: 13px; font-weight: 500; box-shadow: 0 10px 20px rgba(0,0,0,0.3); display: flex; align-items: center; gap: 10px; z-index: 9999; }
            .grok-prompt-kbd { background: #333; color: white; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 12px; border-bottom: 2px solid #111; }
            .grok-prompt-resize-handle { position: absolute; width: 20px; height: 20px; right: 0; bottom: 0; cursor: se-resize; z-index: 10; }

            /* --- BULK ACTIONS & CONTROLS --- */
            .grok-control-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 10px; }
            .grok-filter-group { display: flex; gap: 6px; flex-wrap: wrap; }
            .grok-sort-group { display: flex; gap: 4px; align-items: center; padding-left: 10px; border-left: 1px solid var(--grok-border); }

            .grok-prompt-filter-btn { background: transparent; border: 1px solid var(--grok-border); color: var(--grok-text-muted); padding: 6px 14px; border-radius: 20px; cursor: pointer; font-size: 13px; font-weight: 500; transition: 0.2s; }
            .grok-prompt-filter-btn.active { background: var(--grok-primary); border-color: var(--grok-primary); color: white; }

            .grok-prompt-sort-btn { background: transparent; border: none; color: var(--grok-text-muted); padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 11px; font-weight: 600; text-transform: uppercase; transition: 0.2s; }
            .grok-prompt-sort-btn:hover { color: var(--grok-text-main); background: rgba(255,255,255,0.05); }
            .grok-prompt-sort-btn.active { color: var(--grok-primary); background: rgba(29, 155, 240, 0.1); }

            .grok-bulk-bar { display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; background: rgba(29, 155, 240, 0.05); border: 1px solid var(--grok-border); border-radius: 12px; margin-bottom: 16px; }
            .grok-bulk-delete-btn { background: rgba(244, 33, 46, 0.1); color: var(--grok-danger); border: 1px solid transparent; padding: 6px 12px; border-radius: 20px; font-size: 12px; font-weight: 700; cursor: pointer; transition: 0.2s; display: flex; align-items: center; gap: 6px;}
            .grok-bulk-delete-btn:hover { background: var(--grok-danger); color: white; }
            .grok-bulk-delete-btn:disabled { opacity: 0.5; cursor: not-allowed; background: transparent; color: var(--grok-text-muted); }

            .grok-checkbox-wrapper { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; padding: 16px; background: rgba(255,255,255,0.03); border-radius: 12px; }
            .grok-checkbox { width: 20px; height: 20px; accent-color: var(--grok-primary); cursor: pointer; }

            .grok-keybind-wrapper { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; background: black; border: 1px solid var(--grok-border); padding: 10px; border-radius: 8px; }
            .grok-keybind-display { font-family: monospace; background: #222; color: var(--grok-primary); padding: 4px 8px; border-radius: 4px; border: 1px solid #333; min-width: 80px; text-align: center; font-weight: 700; }
            .grok-keybind-btn { background: var(--grok-surface-hover); border: 1px solid var(--grok-border); color: white; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; }
            .grok-keybind-btn.recording { background: var(--grok-danger); border-color: var(--grok-danger); animation: pulse 1s infinite; }
            @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.7; } 100% { opacity: 1; } }

            .grok-video-section { margin-top: 12px; background: rgba(255, 255, 255, 0.03); padding: 10px; border-radius: 8px; border: 1px dashed var(--grok-border); }
            .grok-video-input { width: 100%; background: transparent; border: none; color: var(--grok-text-muted); font-size: 13px; font-family: inherit; resize: none; outline: none; height: 32px; transition: height 0.2s; }
            .grok-video-input:focus { color: var(--grok-text-main); height: 60px; }
            .grok-video-label { font-size: 11px; color: var(--grok-primary); font-weight: 700; text-transform: uppercase; margin-bottom: 4px; display: block; }
            .grok-video-save-hint { font-size: 10px; color: #555; text-align: right; display: none; }
            .grok-video-input:focus + .grok-video-save-hint { display: block; }

            .grok-image-item-grid { display: flex; gap: 16px; }
            .grok-image-content-col { flex: 1; }
            .grok-image-preview-col { width: 120px; display: flex; flex-direction: column; gap: 8px; align-items: center; justify-content: flex-start; }

            .grok-snapshot-thumb { width: 100%; height: 100px; object-fit: cover; border-radius: 8px; border: 1px solid var(--grok-border); cursor: zoom-in; transition: transform 0.2s; background: #000; }
            .grok-snapshot-thumb:hover { transform: scale(1.05); border-color: var(--grok-primary); }

            .grok-snapshot-upload-btn { position: relative; width: 100%; height: 100px; border: 1px dashed var(--grok-border); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-direction: column; color: var(--grok-text-muted); cursor: pointer; font-size: 12px; transition: 0.2s; background: rgba(255,255,255,0.02); }
            .grok-snapshot-upload-btn:hover { border-color: var(--grok-primary); color: var(--grok-primary); background: rgba(29, 155, 240, 0.05); }
            .grok-snapshot-input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }

            .grok-snapshot-del { background: rgba(0,0,0,0.7); color: white; border: none; border-radius: 50%; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; cursor: pointer; position: absolute; top: -5px; right: -5px; font-size: 12px; line-height: 1; }
            .grok-snapshot-wrapper { position: relative; width: 100%; }

            .grok-mod-wrapper { display: flex; align-items: center; gap: 10px; flex-grow: 1; min-width: 140px; max-width: 300px; background: rgba(0,0,0,0.2); padding: 4px 10px; border-radius: 20px; border: 1px solid var(--grok-border); margin-right: 8px; }
            .grok-mod-label { font-size: 10px; text-transform: uppercase; color: var(--grok-text-muted); font-weight: 700; white-space: nowrap; }
            .grok-mod-slider { -webkit-appearance: none; appearance: none; flex: 1; height: 4px; background: #333; border-radius: 2px; outline: none; cursor: ew-resize; }
            .grok-mod-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; background: var(--grok-text-main); border-radius: 50%; cursor: pointer; transition: 0.2s; }
            .grok-mod-slider::-webkit-slider-thumb:hover { transform: scale(1.2); }
            .grok-mod-val { font-size: 12px; font-weight: 700; min-width: 35px; text-align: right; font-variant-numeric: tabular-nums; }
            .grok-mod-val.low { color: var(--grok-danger); }
            .grok-mod-val.med { color: var(--grok-warning); }
            .grok-mod-val.high { color: var(--grok-success); }

            .grok-lightbox { position: fixed; inset: 0; z-index: 12000; background: rgba(0,0,0,0.9); display: none; align-items: center; justify-content: center; cursor: zoom-out; }
            .grok-lightbox.open { display: flex; animation: fadeIn 0.2s; }
            .grok-lightbox img { max-width: 90%; max-height: 90%; border-radius: 4px; box-shadow: 0 0 50px rgba(0,0,0,0.5); }
            @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
        `);

        // --- STATE ---
        let isOpen = false;
        let currentRating = 0;
        let currentCategory = '';
        let filterCategory = 'all';
        let videoSortMode = 'newest';
        let isDragging = false, isResizing = false;
        let dragOffset = { x: 0, y: 0 };
        let modalElement = null;
        let isRecordingKeybind = false;

        // New state for bulk selection
        let selectedPromptIds = new Set();

        // --- HELPERS ---
        function showToast(message, type = 'success') {
            let container = document.querySelector('.grok-toast-container');
            if (!container) {
                container = document.createElement('div');
                container.className = 'grok-toast-container';
                document.body.appendChild(container);
            }

            const toast = document.createElement('div');
            toast.className = 'grok-toast';
            if(type === 'error') toast.style.background = 'var(--grok-danger)';

            toast.innerHTML = `
                <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                <span>${message}</span>
            `;
            container.appendChild(toast);

            setTimeout(() => {
                toast.style.opacity = '0';
                toast.style.transform = 'translateY(10px)';
                setTimeout(() => toast.remove(), 300);
            }, 3000);
        }

        function getCategories() {
            let cats = JSON.parse(GM_getValue('grok_categories', '["General"]'));
            if (!cats.includes('Image')) { cats.push('Image'); saveCategories(cats); }
            if (!cats.includes('Auto-History')) { cats.push('Auto-History'); saveCategories(cats); }
            return cats;
        }
        function saveCategories(cats) { GM_setValue('grok_categories', JSON.stringify(cats)); }
        function getPrompts() { return JSON.parse(GM_getValue('grok_prompts', '[]')); }
        function savePrompts(prompts) { GM_setValue('grok_prompts', JSON.stringify(prompts)); }

        function getSettings() {
            const defaults = {
                autoTrack: true,
                silentMode: false,
                keybind: { key: 'k', altKey: true, ctrlKey: false, shiftKey: false, metaKey: false }
            };
            const saved = JSON.parse(GM_getValue('grok_settings', '{}'));
            return { ...defaults, ...saved };
        }

        function saveSettings(s) { GM_setValue('grok_settings', JSON.stringify(s)); }

        function getKeybindString(kb) {
            if (!kb) return 'Alt + K';
            const parts = [];
            if (kb.ctrlKey) parts.push('Ctrl');
            if (kb.altKey) parts.push('Alt');
            if (kb.shiftKey) parts.push('Shift');
            if (kb.metaKey) parts.push('Meta');
            parts.push((kb.key === ' ' ? 'Space' : kb.key).toUpperCase());
            return parts.join(' + ');
        }

        // --- IMAGE COMPRESSION ---
        function compressImage(file, callback) {
            const reader = new FileReader();
            reader.onload = (e) => {
                const img = new Image();
                img.onload = () => {
                    const canvas = document.createElement('canvas');
                    const ctx = canvas.getContext('2d');
                    const MAX_SIZE = 400;
                    let width = img.width;
                    let height = img.height;

                    if (width > height) {
                        if (width > MAX_SIZE) {
                            height *= MAX_SIZE / width;
                            width = MAX_SIZE;
                        }
                    } else {
                        if (height > MAX_SIZE) {
                            width *= MAX_SIZE / height;
                            height = MAX_SIZE;
                        }
                    }

                    canvas.width = width;
                    canvas.height = height;
                    ctx.drawImage(img, 0, 0, width, height);
                    callback(canvas.toDataURL('image/jpeg', 0.7));
                };
                img.src = e.target.result;
            };
            reader.readAsDataURL(file);
        }

        // --- AUTO TRACKING (TARGETED UPDATE) ---
        function setupAutoTracker() {
            const sendIconPath = "M5 11L12 4M12 4L19 11M12 4V21";

            const capture = (specificText = null, specificType = null) => {
                if (!getSettings().autoTrack) return;

                let text = specificText || '';
                let sourceType = specificType || 'Image';

                // Fallback logic for generic enter/click if specificText wasn't passed
                if (!text) {
                    const editor = document.querySelector('.tiptap.ProseMirror');
                    const videoInput = document.querySelector('textarea[aria-label="Make a video"]');
                    // Just find any Image prompt that has a value
                    const imageInput = document.querySelector('textarea[aria-label="Image prompt"]');

                    if (videoInput && (document.activeElement === videoInput || (videoInput.value.trim().length > 0))) {
                        text = videoInput.value.trim();
                        sourceType = 'Video';
                    }
                    else if (imageInput && imageInput.value.trim().length > 0) {
                        text = imageInput.value.trim();
                        sourceType = 'Image';
                    }
                    else if (editor && editor.textContent.trim().length > 0) {
                        text = editor.textContent.trim();
                        sourceType = 'Image';
                    }
                }

                if (!text || text.length < 2) return;

                const prompts = getPrompts();
                if (prompts.some(p => p.text === text)) return;

                prompts.push({
                    id: 'auto_' + Date.now().toString(),
                    text: text,
                    rating: 0,
                    category: 'Auto-History',
                    sourceType: sourceType,
                    timestamp: Date.now()
                });
                savePrompts(prompts);

                if (!getSettings().silentMode) {
                    showToast(`Auto-Captured (${sourceType})`);
                }

                if (isOpen && document.querySelector('.grok-prompt-tab.active[data-tab="recent"]')) {
                    renderPromptsList('grokRecentTab', p => p.category === 'Auto-History', (a,b) => b.timestamp - a.timestamp);
                }
            };

            document.addEventListener('keydown', (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    if (e.target.closest('.ProseMirror') || e.target.closest('textarea[aria-label="Image prompt"]') || e.target.closest('textarea[aria-label="Make a video"]')) {
                        // Check if it's the specific image textarea
                        if(e.target.matches('textarea[aria-label="Image prompt"]')) {
                            capture(e.target.value.trim(), 'Image');
                        } else {
                            capture();
                        }
                    }
                }
            }, true);

            document.addEventListener('mousedown', (e) => {
                // Check for the specific SUBMIT button
                const submitBtn = e.target.closest('button[aria-label="Submit"]');
                const videoBtn = e.target.closest('button[aria-label="Make video"]');
                const genericBtn = e.target.closest('button') || e.target.closest('[role="button"]');

                if (videoBtn) { capture(); return; }

                if (submitBtn) {
                    // Strategy: The button is often a sibling or in the same container as the input
                    // Look for the specific Image prompt text area near this button
                    const parent = submitBtn.parentElement;
                    let targetInput = null;

                    if (parent) {
                        targetInput = parent.querySelector('textarea[aria-label="Image prompt"]');
                    }

                    // If not found in direct parent, look closely for it
                    if (!targetInput) {
                         targetInput = document.querySelector('textarea[aria-label="Image prompt"]');
                    }

                    if (targetInput && targetInput.value.trim().length > 0) {
                        capture(targetInput.value.trim(), 'Image');
                        return;
                    }

                    // If the button has the SVG but we missed the input above
                    if (submitBtn.querySelector(`path[d="${sendIconPath}"]`)) { capture(); return; }
                }

                if (genericBtn && genericBtn.querySelector(`path[d="${sendIconPath}"]`)) capture();
            }, true);
        }

        // --- UI CREATION ---
        function createUI() {
            document.querySelector('.grok-prompt-overlay')?.remove();
            document.querySelector('.grok-lightbox')?.remove();
            document.querySelector('.grok-prompt-hint')?.remove();

            const lightbox = document.createElement('div');
            lightbox.className = 'grok-lightbox';
            lightbox.innerHTML = '<img src="" id="grokLightboxImg">';
            lightbox.onclick = () => { lightbox.classList.remove('open'); setTimeout(()=>lightbox.style.display='none', 200); };
            document.body.appendChild(lightbox);

            const overlay = document.createElement('div');
            overlay.className = 'grok-prompt-overlay';

            const modal = document.createElement('div');
            modal.className = 'grok-prompt-modal';
            modalElement = modal;

            const pos = GM_getValue('grok_modal_position', null);
            const size = GM_getValue('grok_modal_size', null);
            if (pos) { modal.style.top = pos.top; modal.style.left = pos.left; modal.style.transform = 'translate(0,0)'; }
            if (size) { modal.style.width = size.width; modal.style.height = size.height; }

            const settings = getSettings();
            const kbString = getKeybindString(settings.keybind);

            modal.innerHTML = `
                <div class="grok-prompt-header" id="grokDragHandle">
                    <div class="grok-prompt-title">
                        <svg width="24" height="24" fill="currentColor" viewBox="0 0 24 24" style="color: var(--grok-primary);">
                            <path d="M2 21L23 12L2 3V10L17 12L2 14V21Z"/>
                        </svg>
                        <span>Grok Imagine Manager</span>
                    </div>
                    <button class="grok-prompt-close" id="grokCloseBtn" title="Close (Esc)">
                        <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
                    </button>
                </div>
                <div class="grok-prompt-tabs">
                    <button class="grok-prompt-tab active" data-tab="generate">New Prompt</button>
                    <button class="grok-prompt-tab" data-tab="recent">History</button>
                    <button class="grok-prompt-tab" data-tab="saved">Video</button>
                    <button class="grok-prompt-tab" data-tab="quick">Images</button>
                    <button class="grok-prompt-tab" data-tab="categories">Tags</button>
                    <button class="grok-prompt-tab" data-tab="settings">Settings</button>
                </div>
                <div class="grok-prompt-content">
                    <div id="grokGenerateTab" class="grok-prompt-form">
                        <div>
                            <label class="grok-prompt-label">Category</label>
                            <select class="grok-prompt-select" id="grokCategorySelect"></select>
                        </div>
                        <div>
                            <label class="grok-prompt-label">Your Prompt</label>
                            <textarea class="grok-prompt-textarea" id="grokPromptInput" placeholder="What do you want to see?"></textarea>
                        </div>
                        <div>
                            <label class="grok-prompt-label">Rating</label>
                            <div class="grok-prompt-stars" id="grokStars">
                                ${[1,2,3,4,5].map(i => `<svg class="grok-prompt-star" data-rating="${i}" fill="currentColor" viewBox="0 0 24 24"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>`).join('')}
                            </div>
                        </div>
                        <button class="grok-prompt-button" id="grokSaveBtn">
                            <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"/></svg>
                            Save Prompt
                        </button>
                    </div>

                    <div id="grokRecentTab" class="grok-prompt-list" style="display: none;"></div>
                    <div id="grokSavedTab" class="grok-prompt-list" style="display: none;"></div>
                    <div id="grokQuickTab" class="grok-prompt-list" style="display: none;"></div>

                    <div id="grokCategoriesTab" class="grok-prompt-form" style="display: none;">
                        <div>
                            <label class="grok-prompt-label">Add Category</label>
                            <div style="display:flex; gap:10px;">
                                <input type="text" class="grok-prompt-category-input" id="grokNewCategory" placeholder="e.g. Sci-Fi, Portraits...">
                                <button class="grok-prompt-add-btn" id="grokAddCategoryBtn">Add</button>
                            </div>
                            <div class="grok-prompt-category-list" id="grokCategoryList"></div>
                        </div>
                    </div>

                    <div id="grokSettingsTab" style="display: none;">
                        <label class="grok-prompt-label">Shortcuts</label>
                        <div class="grok-keybind-wrapper">
                            <div class="grok-keybind-display" id="grokKeybindDisplay">${kbString}</div>
                            <button class="grok-keybind-btn" id="grokKeybindBtn">Change Keybind</button>
                        </div>

                        <label class="grok-prompt-label">Automation</label>
                        <div class="grok-checkbox-wrapper">
                            <input type="checkbox" id="grokAutoTrackToggle" class="grok-checkbox">
                            <div>
                                <div style="font-weight:600; color:var(--grok-text-main);">Auto-Capture Prompts</div>
                                <div style="font-size:12px; color:var(--grok-text-muted);">Automatically save prompts from Chat and Image Input.</div>
                            </div>
                        </div>
                        <div class="grok-checkbox-wrapper">
                            <input type="checkbox" id="grokSilentModeToggle" class="grok-checkbox">
                            <div>
                                <div style="font-weight:600; color:var(--grok-text-main);">Silent Mode</div>
                                <div style="font-size:12px; color:var(--grok-text-muted);">Turn off pop-up notifications when a prompt is auto-saved.</div>
                            </div>
                        </div>
                        <label class="grok-prompt-label">Data Management</label>
                        <div style="display:flex; gap:12px; margin-bottom:24px;">
                            <button class="grok-prompt-export-btn" id="grokExportBtn">Export JSON</button>
                            <button class="grok-prompt-export-btn" id="grokImportBtn">Import JSON</button>
                            <input type="file" id="grokImportFile" style="display:none" accept=".json">
                        </div>
                        <div class="grok-prompt-export-section">
                            <label class="grok-prompt-label" style="color: var(--grok-danger);">Danger Zone</label>
                            <button class="grok-prompt-export-btn danger" id="grokClearBtn">Wipe All Data</button>
                        </div>
                    </div>
                </div>
                <div class="grok-prompt-resize-handle" id="grokResizeHandle"></div>
            `;

            overlay.appendChild(modal);
            document.body.appendChild(overlay);

            if (!GM_getValue('grok_hint_hidden', false)) {
                const hint = document.createElement('div');
                hint.className = 'grok-prompt-hint';
                hint.innerHTML = `<span>Press <span class="grok-prompt-kbd">${kbString}</span> to manage prompts</span>`;
                const closeHint = document.createElement('div');
                closeHint.innerHTML = '&times;';
                closeHint.style.cssText = 'cursor:pointer; font-size:16px; padding:0 5px;';
                closeHint.onclick = () => { hint.remove(); GM_setValue('grok_hint_hidden', true); };
                hint.appendChild(closeHint);
                document.body.appendChild(hint);
            }

            return overlay;
        }

        // --- RENDERERS ---
        function renderPromptsList(targetId, filterFn, sortFn) {
            const container = document.getElementById(targetId);
            let prompts = getPrompts();
            if (filterFn) prompts = prompts.filter(filterFn);

            // Common Bulk Bar - Only for History (Recent) Tab
            const bulkBarHTML = targetId === 'grokRecentTab' ? `
                <div class="grok-bulk-bar">
                    <div style="display:flex; align-items:center; gap:8px;">
                         <input type="checkbox" id="grokSelectAll-${targetId}" class="grok-item-checkbox">
                         <label for="grokSelectAll-${targetId}" style="font-size:13px; font-weight:600; cursor:pointer; color:var(--grok-text-main);">Select All</label>
                    </div>
                    <button id="grokBulkDeleteBtn-${targetId}" class="grok-bulk-delete-btn" disabled>
                        <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
                        Delete Selected
                    </button>
                </div>
            ` : '';

            if (targetId === 'grokSavedTab') {
                const categories = getCategories().filter(cat => cat !== 'Image' && cat !== 'Auto-History');

                const controlsHTML = `
                    <div class="grok-control-bar">
                        <div class="grok-filter-group">
                            <button class="grok-prompt-filter-btn ${filterCategory === 'all' ? 'active' : ''}" data-f="all">All</button>
                            ${categories.map(c => `<button class="grok-prompt-filter-btn ${filterCategory === c ? 'active' : ''}" data-f="${c}">${c}</button>`).join('')}
                        </div>
                        <div class="grok-sort-group">
                             <span style="font-size:10px; color:#555; font-weight:700; text-transform:uppercase; margin-right:4px;">Sort:</span>
                             <button class="grok-prompt-sort-btn ${videoSortMode === 'newest' ? 'active' : ''}" data-sort="newest">Newest</button>
                             <button class="grok-prompt-sort-btn ${videoSortMode === 'high' ? 'active' : ''}" data-sort="high">High %</button>
                             <button class="grok-prompt-sort-btn ${videoSortMode === 'low' ? 'active' : ''}" data-sort="low">Low %</button>
                        </div>
                    </div>`;

                if (filterCategory !== 'all') prompts = prompts.filter(p => p.category === filterCategory);

                if (videoSortMode === 'high') {
                    prompts.sort((a, b) => (b.moderation || 0) - (a.moderation || 0));
                } else if (videoSortMode === 'low') {
                    prompts.sort((a, b) => (a.moderation || 0) - (b.moderation || 0));
                } else {
                    prompts.sort((a, b) => b.timestamp - a.timestamp);
                }

                if (prompts.length === 0) {
                    container.innerHTML = controlsHTML + `<div style="text-align:center; color:#666; padding:40px;">No saved prompts found.</div>`;
                    bindControls();
                    return;
                }
                container.innerHTML = controlsHTML + '<div class="grok-prompt-list">' + prompts.map(p => generatePromptHTML(p, 'video')).join('') + '</div>';
                bindControls();
                bindMediaEvents(container);
            }
            else if (targetId === 'grokQuickTab') {
                if (sortFn) prompts.sort(sortFn);
                 if (prompts.length === 0) {
                    container.innerHTML = `<div style="text-align:center; color:#666; padding:40px;">No image prompts saved yet.</div>`;
                    return;
                }
                container.innerHTML = '<div class="grok-prompt-list">' + prompts.map(p => generatePromptHTML(p, 'image')).join('') + '</div>';
                bindMediaEvents(container);
            }
            else {
                // Recent / History Tab
                if (sortFn) prompts.sort(sortFn);
                if (prompts.length === 0) {
                    container.innerHTML = `<div style="text-align:center; color:#666; padding:40px;">History is empty.</div>`;
                    return;
                }
                container.innerHTML = bulkBarHTML + '<div class="grok-prompt-list">' + prompts.map(p => generatePromptHTML(p, 'history')).join('') + '</div>';
                bindMediaEvents(container);
                bindBulkEvents(container, targetId, prompts);
            }

            bindPromptEvents(container);
        }

        function generatePromptHTML(p, renderMode) {
            const isAuto = p.category === 'Auto-History' || p.id.startsWith('auto_');
            const videoPromptValue = p.videoPrompt || '';
            let badgeLabel = isAuto ? (p.sourceType || 'Auto-History') : p.category;

            // Only show checkbox in history mode
            const isHistoryMode = renderMode === 'history';
            const isSelected = isHistoryMode && selectedPromptIds.has(p.id) ? 'checked' : '';

            let snapshotHtml = '';
            let videoInputHtml = '';

            if (renderMode === 'image') {
                snapshotHtml = p.snapshot
                    ? `<div class="grok-snapshot-wrapper"><img src="${p.snapshot}" class="grok-snapshot-thumb" data-src="${p.snapshot}" title="Click to Zoom"><button class="grok-snapshot-del" data-id="${p.id}" title="Remove Snapshot">&times;</button></div>`
                    : `<label class="grok-snapshot-upload-btn">+ Snapshot<input type="file" class="grok-snapshot-input" data-id="${p.id}" accept="image/jpeg, image/png, image/webp"></label>`;
            }

            if (renderMode === 'video') {
                 videoInputHtml = `
                 <div class="grok-video-section">
                    <label class="grok-video-label">Video Prompt</label>
                    <textarea class="grok-video-input" data-id="${p.id}" placeholder="Add video description...">${videoPromptValue}</textarea>
                    <div class="grok-video-save-hint">Press Tab to save</div>
                </div>`;
            }

            const previewCol = renderMode === 'image' ? `<div class="grok-image-preview-col">${snapshotHtml}</div>` : '';
            const modVal = p.moderation || 0;
            const modClass = modVal < 40 ? 'low' : (modVal < 80 ? 'med' : 'high');

            const checkboxHtml = isHistoryMode ? `
                <div class="grok-item-check-wrapper">
                    <input type="checkbox" class="grok-item-checkbox grok-select-item" data-id="${p.id}" ${isSelected}>
                </div>` : '';

            return `
            <div class="grok-prompt-item">
                ${checkboxHtml}
                <div class="grok-item-content-wrapper">
                    <div class="grok-image-item-grid">
                        <div class="grok-image-content-col">
                            <div class="grok-prompt-item-header">
                                <div class="grok-prompt-item-text">${p.text}</div>
                                <button class="grok-prompt-item-delete" data-id="${p.id}" title="Delete"><svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg></button>
                            </div>
                            ${videoInputHtml}
                        </div>
                        ${previewCol}
                    </div>
                    <div class="grok-prompt-item-footer">
                        <span class="grok-prompt-category-badge ${isAuto ? 'auto' : ''}">${badgeLabel}</span>
                        <div class="grok-mod-wrapper">
                            <label class="grok-mod-label">Moderation Pass:</label>
                            <input type="range" min="0" max="100" value="${modVal}" class="grok-mod-slider" data-id="${p.id}">
                            <span class="grok-mod-val ${modClass}" id="mod-val-${p.id}">${modVal}%</span>
                        </div>
                        <button class="grok-prompt-copy-btn" data-text="${p.text.replace(/"/g, '&quot;')}">Copy</button>
                        ${isAuto ? `<button class="grok-prompt-copy-btn save-btn" data-id="${p.id}" style="color:var(--grok-primary); border-color:var(--grok-primary);">Save to Favorites</button>` : ''}
                        <span style="margin-left:auto; font-size:11px; color:#555;">${new Date(p.timestamp).toLocaleDateString()}</span>
                    </div>
                </div>
            </div>`;
        }

        // --- BULK LOGIC ---
        function bindBulkEvents(container, targetId, currentVisiblePrompts) {
            const selectAllCb = container.querySelector(`#grokSelectAll-${targetId}`);
            const deleteBtn = container.querySelector(`#grokBulkDeleteBtn-${targetId}`);
            const itemCheckboxes = container.querySelectorAll('.grok-select-item');

            const updateBulkUI = () => {
                // Check if all currently visible items are selected
                const allVisibleSelected = currentVisiblePrompts.length > 0 && currentVisiblePrompts.every(p => selectedPromptIds.has(p.id));
                if(selectAllCb) selectAllCb.checked = allVisibleSelected;

                // Enable delete button if anything is selected
                const selectedCount = selectedPromptIds.size;
                if(deleteBtn) {
                    deleteBtn.disabled = selectedCount === 0;
                    deleteBtn.innerHTML = selectedCount > 0
                        ? `<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg> Delete Selected (${selectedCount})`
                        : `<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg> Delete Selected`;
                }
            };

            if(selectAllCb) {
                selectAllCb.onclick = (e) => {
                    const isChecked = e.target.checked;
                    currentVisiblePrompts.forEach(p => {
                        if (isChecked) selectedPromptIds.add(p.id);
                        else selectedPromptIds.delete(p.id);
                    });
                    // Update visually without full re-render
                    itemCheckboxes.forEach(cb => cb.checked = isChecked);
                    updateBulkUI();
                };
            }

            itemCheckboxes.forEach(cb => {
                cb.onclick = (e) => {
                    const id = e.target.dataset.id;
                    if (e.target.checked) selectedPromptIds.add(id);
                    else selectedPromptIds.delete(id);
                    updateBulkUI();
                };
            });

            if(deleteBtn) {
                deleteBtn.onclick = () => {
                    const count = selectedPromptIds.size;
                    if (confirm(`Are you sure you want to delete ${count} prompt${count > 1 ? 's' : ''}?`)) {
                        let allPrompts = getPrompts();
                        allPrompts = allPrompts.filter(p => !selectedPromptIds.has(p.id));
                        savePrompts(allPrompts);
                        selectedPromptIds.clear();
                        showToast(`Deleted ${count} prompt${count > 1 ? 's' : ''}`);
                        refreshActiveTab();
                    }
                };
            }

            // Initialize UI state
            updateBulkUI();
        }

        function bindControls() {
            document.querySelectorAll('.grok-prompt-filter-btn').forEach(b => {
                b.onclick = () => {
                    filterCategory = b.dataset.f;
                    selectedPromptIds.clear(); // Clear selection when changing filters
                    renderPromptsList('grokSavedTab', p => p.category !== 'Image' && p.category !== 'Auto-History');
                };
            });

            document.querySelectorAll('.grok-prompt-sort-btn').forEach(b => {
                b.onclick = () => {
                    videoSortMode = b.dataset.sort;
                    renderPromptsList('grokSavedTab', p => p.category !== 'Image' && p.category !== 'Auto-History');
                };
            });
        }

        function bindMediaEvents(container) {
             container.querySelectorAll('.grok-video-input').forEach(input => {
                 input.addEventListener('blur', (e) => {
                     const id = e.target.dataset.id;
                     const val = e.target.value;
                     let prompts = getPrompts();
                     let p = prompts.find(x => x.id === id);
                     if (p && p.videoPrompt !== val) {
                         p.videoPrompt = val;
                         savePrompts(prompts);
                         showToast('Video prompt saved');
                     }
                 });
             });

             // FIXED SLIDER LOGIC: Use relative traversal instead of getElementById
             container.querySelectorAll('.grok-mod-slider').forEach(slider => {
                 slider.addEventListener('input', (e) => {
                    const val = e.target.value;
                    // Find the span relative to the slider (sibling)
                    const display = e.target.parentElement.querySelector('.grok-mod-val');
                    if(display) {
                        display.innerText = val + '%';
                        display.className = `grok-mod-val ${val < 40 ? 'low' : (val < 80 ? 'med' : 'high')}`;
                    }
                 });
                 slider.addEventListener('change', (e) => {
                     const val = parseInt(e.target.value);
                     const id = e.target.dataset.id;
                     let prompts = getPrompts();
                     let p = prompts.find(x => x.id === id);
                     if (p) {
                         p.moderation = val;
                         savePrompts(prompts);
                         if (videoSortMode !== 'newest') {
                             refreshActiveTab();
                         }
                     }
                 });
             });

             container.querySelectorAll('.grok-snapshot-input').forEach(input => {
                 input.addEventListener('change', (e) => {
                     const file = e.target.files[0];
                     if (!file) return;
                     const id = e.target.dataset.id;
                     compressImage(file, (base64) => {
                         let prompts = getPrompts();
                         let p = prompts.find(x => x.id === id);
                         if (p) {
                             p.snapshot = base64;
                             savePrompts(prompts);
                             refreshActiveTab();
                             showToast('Snapshot attached!');
                         }
                     });
                 });
             });

             container.querySelectorAll('.grok-snapshot-del').forEach(btn => {
                 btn.addEventListener('click', (e) => {
                     if (!confirm('Remove snapshot?')) return;
                     const id = e.target.dataset.id;
                     let prompts = getPrompts();
                     let p = prompts.find(x => x.id === id);
                     if (p) {
                         delete p.snapshot;
                         savePrompts(prompts);
                         refreshActiveTab();
                     }
                 });
             });

             container.querySelectorAll('.grok-snapshot-thumb').forEach(img => {
                 img.addEventListener('click', (e) => {
                     const lightbox = document.querySelector('.grok-lightbox');
                     const lbImg = document.getElementById('grokLightboxImg');
                     lbImg.src = e.target.dataset.src;
                     lightbox.style.display = 'flex';
                     lightbox.offsetHeight;
                     lightbox.classList.add('open');
                 });
             });
        }

        function bindPromptEvents(container) {
            container.onclick = (e) => {
                const btn = e.target.closest('button');
                // Ignore bulk buttons here, handled in bindBulkEvents
                if (!btn || btn.classList.contains('grok-bulk-delete-btn')) return;

                if (btn.classList.contains('grok-prompt-copy-btn') && btn.dataset.text) {
                    navigator.clipboard.writeText(btn.dataset.text).then(() => showToast('Copied to clipboard!'));
                }
                else if (btn.classList.contains('grok-prompt-item-delete')) {
                    if (confirm('Delete this prompt?')) {
                        let prompts = getPrompts().filter(p => p.id !== btn.dataset.id);
                        savePrompts(prompts);
                        refreshActiveTab();
                    }
                }
                else if (btn.classList.contains('save-btn')) {
                    let prompts = getPrompts();
                    let p = prompts.find(x => x.id === btn.dataset.id);
                    if (p) {
                        document.querySelector('[data-tab="generate"]').click();
                        document.getElementById('grokPromptInput').value = p.text;
                        showToast('Edit and rate to save permanently', 'success');
                    }
                }
            };
        }

        function refreshActiveTab() {
            const active = document.querySelector('.grok-prompt-tab.active').dataset.tab;
            if (active === 'saved') renderPromptsList('grokSavedTab', p => p.category !== 'Image' && p.category !== 'Auto-History');
            // --- MODIFIED: Only show Auto-Captured prompts in History, hide labeled/tagged ones ---
            else if (active === 'recent') renderPromptsList('grokRecentTab', p => p.category === 'Auto-History', (a,b) => b.timestamp - a.timestamp);
            // ------------------------------------------------------------------------------------
            else if (active === 'quick') renderPromptsList('grokQuickTab', p => p.category === 'Image', (a,b) => b.timestamp - a.timestamp);
            else if (active === 'categories') renderCategories();
            updateCounts();
        }

        function renderCategories() {
            const div = document.getElementById('grokCategoryList');
            div.innerHTML = getCategories().filter(c => c !== 'Auto-History').map(c => `
                <div class="grok-prompt-category-tag">
                    ${c}
                    <span style="cursor:pointer; color:#666; padding:0 4px;" data-rem="${c}">&times;</span>
                </div>
            `).join('');
            div.querySelectorAll('[data-rem]').forEach(span => {
                span.onclick = () => {
                    let c = span.dataset.rem;
                    let cats = getCategories();
                    if (cats.length <= 1) return alert('Keep at least one category.');
                    saveCategories(cats.filter(x => x !== c));
                    renderCategories();
                    updateCategorySelect();
                };
            });
        }

        function updateCategorySelect() {
            const sel = document.getElementById('grokCategorySelect');
            const cats = getCategories().filter(c => c !== 'Auto-History');
            sel.innerHTML = cats.map(c => `<option value="${c}">${c}</option>`).join('');
            if (!currentCategory) currentCategory = cats[0];
        }

        function updateCounts() {
            const p = getPrompts();
            document.querySelector('[data-tab="saved"]').innerText = `Video (${p.filter(x=>x.category!=='Image' && x.category!=='Auto-History').length})`;
            document.querySelector('[data-tab="quick"]').innerText = `Images (${p.filter(x=>x.category==='Image').length})`;
        }

        // --- INITIALIZATION ---
        const overlay = createUI();
        const modal = modalElement;
        setupAutoTracker();

        const handle = document.getElementById('grokDragHandle');
        handle.onmousedown = (e) => {
            if(e.target.closest('button')) return;
            isDragging = true;
            const rect = modal.getBoundingClientRect();
            dragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top };
            modal.style.transition = 'none';
            modal.style.transform = 'none';
            modal.style.left = rect.left + 'px';
            modal.style.top = rect.top + 'px';
        };

        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                modal.style.left = (e.clientX - dragOffset.x) + 'px';
                modal.style.top = (e.clientY - dragOffset.y) + 'px';
            }
            if (isResizing) {
                const rect = modal.getBoundingClientRect();
                modal.style.width = Math.max(400, e.clientX - rect.left) + 'px';
                modal.style.height = Math.max(300, e.clientY - rect.top) + 'px';
            }
        });

        document.addEventListener('mouseup', () => {
            if (isDragging || isResizing) {
                modal.style.transition = '';
                GM_setValue('grok_modal_position', { top: modal.style.top, left: modal.style.left });
                GM_setValue('grok_modal_size', { width: modal.style.width, height: modal.style.height });
            }
            isDragging = false; isResizing = false;
        });

        document.getElementById('grokResizeHandle').onmousedown = (e) => { e.preventDefault(); isResizing = true; };

        document.getElementById('grokCloseBtn').onclick = () => {
            overlay.classList.remove('open');
            setTimeout(() => overlay.style.display = 'none', 200);
            isOpen = false;
        };

        document.querySelectorAll('.grok-prompt-tab').forEach(tab => {
            tab.onclick = () => {
                document.querySelectorAll('.grok-prompt-tab').forEach(t => t.classList.remove('active'));
                tab.classList.add('active');

                // Clear selections when changing tabs
                selectedPromptIds.clear();

                const t = tab.dataset.tab;
                ['generate','recent','saved','quick','categories','settings'].forEach(id => {
                    document.getElementById('grok'+id.charAt(0).toUpperCase()+id.slice(1)+'Tab').style.display = (id === t ? (id==='categories' || id==='generate' || id==='settings' ? 'flex' : 'block') : 'none');
                });
                refreshActiveTab();
            };
        });

        const currentSettings = getSettings();

        const kbBtn = document.getElementById('grokKeybindBtn');
        const kbDisplay = document.getElementById('grokKeybindDisplay');

        kbBtn.onclick = () => {
            isRecordingKeybind = true;
            kbBtn.classList.add('recording');
            kbBtn.innerText = 'Press keys...';
        };

        const autoTrackToggle = document.getElementById('grokAutoTrackToggle');
        autoTrackToggle.checked = currentSettings.autoTrack;
        autoTrackToggle.onchange = () => {
            const s = getSettings();
            s.autoTrack = autoTrackToggle.checked;
            saveSettings(s);
            showToast(autoTrackToggle.checked ? 'Auto-Capture Enabled' : 'Auto-Capture Disabled');
        };

        const silentModeToggle = document.getElementById('grokSilentModeToggle');
        silentModeToggle.checked = currentSettings.silentMode;
        silentModeToggle.onchange = () => {
            const s = getSettings();
            s.silentMode = silentModeToggle.checked;
            saveSettings(s);
            showToast(silentModeToggle.checked ? 'Silent Mode Enabled' : 'Silent Mode Disabled');
        };

        document.querySelectorAll('.grok-prompt-star').forEach(s => {
            s.onclick = () => {
                currentRating = parseInt(s.dataset.rating);
                document.querySelectorAll('.grok-prompt-star').forEach((st,i) => {
                    st.classList.toggle('filled', i < currentRating);
                });
            };
        });

        document.getElementById('grokSaveBtn').onclick = () => {
            const text = document.getElementById('grokPromptInput').value.trim();
            if (!text || !currentRating) return alert('Please add text and a rating.');
            const cat = document.getElementById('grokCategorySelect').value;
            const prompts = getPrompts();
            prompts.push({ id: Date.now().toString(), text, rating: currentRating, category: cat, timestamp: Date.now() });
            savePrompts(prompts);
            document.getElementById('grokPromptInput').value = '';
            currentRating = 0;
            document.querySelectorAll('.grok-prompt-star').forEach(s => s.classList.remove('filled'));
            showToast('Prompt Saved!');
            document.querySelector('[data-tab="saved"]').click();
        };

        document.getElementById('grokAddCategoryBtn').onclick = () => {
            const val = document.getElementById('grokNewCategory').value.trim();
            if (!val) return;
            const cats = getCategories();
            if (!cats.includes(val)) {
                cats.push(val);
                saveCategories(cats);
                document.getElementById('grokNewCategory').value = '';
                renderCategories();
                updateCategorySelect();
                showToast('Category added');
            }
        };

        document.getElementById('grokExportBtn').onclick = () => {
            const data = JSON.stringify({ prompts: getPrompts(), categories: getCategories() }, null, 2);
            const blob = new Blob([data], {type: 'application/json'});
            const a = document.createElement('a');
            a.href = URL.createObjectURL(blob);
            a.download = `grok-prompts-${new Date().toISOString().split('T')[0]}.json`;
            a.click();
        };

        document.getElementById('grokImportBtn').onclick = () => document.getElementById('grokImportFile').click();
        document.getElementById('grokImportFile').onchange = (e) => {
            const fr = new FileReader();
            fr.onload = (ev) => {
                try {
                    const d = JSON.parse(ev.target.result);

                    if (confirm('Merge with existing (OK) or Replace All (Cancel)?')) {
                        const currentPrompts = getPrompts();
                        const importedPrompts = d.prompts || [];

                        const promptMap = new Map(currentPrompts.map(p => [p.id, p]));

                        importedPrompts.forEach(newP => {
                            if (promptMap.has(newP.id)) {
                                const existing = promptMap.get(newP.id);
                                promptMap.set(newP.id, { ...existing, ...newP });
                            } else {
                                promptMap.set(newP.id, newP);
                            }
                        });

                        savePrompts(Array.from(promptMap.values()));

                        const newCats = new Set([...getCategories(), ...(d.categories || [])]);
                        saveCategories(Array.from(newCats));

                    } else {
                        savePrompts(d.prompts || []);
                        saveCategories(d.categories || ['General']);
                    }

                    showToast('Import Successful');
                    refreshActiveTab();
                    renderCategories();
                    updateCategorySelect();

                } catch(err) {
                    console.error(err);
                    alert('Invalid file format');
                }
            };
            fr.readAsText(e.target.files[0]);
        };

        document.getElementById('grokClearBtn').onclick = () => {
            if (confirm('PERMANENTLY DELETE ALL DATA?')) {
                savePrompts([]);
                saveCategories(['General']);
                location.reload();
            }
        };

        document.addEventListener('keydown', (e) => {
            if (isRecordingKeybind) {
                e.preventDefault();
                e.stopPropagation();

                if (['Control','Alt','Shift','Meta'].includes(e.key)) return;

                const newKb = {
                    key: e.key,
                    altKey: e.altKey,
                    ctrlKey: e.ctrlKey,
                    shiftKey: e.shiftKey,
                    metaKey: e.metaKey
                };

                const s = getSettings();
                s.keybind = newKb;
                saveSettings(s);

                kbDisplay.innerText = getKeybindString(newKb);
                kbBtn.classList.remove('recording');
                kbBtn.innerText = 'Change Keybind';
                isRecordingKeybind = false;
                showToast('Keybind Saved');
                return;
            }

            const s = getSettings();
            const kb = s.keybind || { key: 'k', altKey: true };

            const matchKey = e.key.toLowerCase() === kb.key.toLowerCase();
            const matchAlt = e.altKey === (kb.altKey || false);
            const matchCtrl = e.ctrlKey === (kb.ctrlKey || false);
            const matchShift = e.shiftKey === (kb.shiftKey || false);
            const matchMeta = e.metaKey === (kb.metaKey || false);

            if (matchKey && matchAlt && matchCtrl && matchShift && matchMeta) {
                e.preventDefault();
                isOpen = !isOpen;
                if (isOpen) {
                    overlay.style.display = 'flex';
                    overlay.offsetHeight;
                    overlay.classList.add('open');
                    updateCounts();
                    updateCategorySelect();
                    refreshActiveTab();
                } else {
                    overlay.classList.remove('open');
                    setTimeout(() => overlay.style.display = 'none', 200);
                }
            }

            if (e.key === 'Escape' && isOpen) document.getElementById('grokCloseBtn').click();
        });

        updateCounts();
        updateCategorySelect();
    }

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

})();