Universal Link Manager Pro

A floating bubble to manage and quickly access all your important links, with extensive customization, backup, favicons, tags, folders, health checks, toast notifications, auto-categorize, and duplicate detection. Refined UI with sidebar folders and collapsible sections.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name          Universal Link Manager Pro
// @namespace     http://tampermonkey.net/
// @version       5.0
// @description   A floating bubble to manage and quickly access all your important links, with extensive customization, backup, favicons, tags, folders, health checks, toast notifications, auto-categorize, and duplicate detection. Refined UI with sidebar folders and collapsible sections.
// @author        echoZ (Enhanced & Refined)
// @license       MIT
// @match         *://*/*
// @exclude       *://routerlogin.net/
// @exclude       *://192.168.1.1/
// @exclude       *://192.168.0.1/
// @exclude       *://my.bankofamerica.com/
// @exclude       *://wellsfargo.com/
// @exclude       *://chase.com/
// @exclude       *://citibank.com/
// @exclude       *://online.citi.com/
// @exclude       *://capitalone.com/
// @exclude       *://usbank.com/
// @exclude       *://paypal.com/
// @grant         GM_setValue
// @grant         GM_getValue
// @grant         GM_xmlhttpRequest
// @run-at        document-end
// ==/UserScript==

(async function() {
    'use strict';
    if (window.self !== window.top) return;

    // --- SCRIPT EXCLUSION LOGIC ---
    const excludedDomainsStorageKey = 'excludedUniversalDomains';
    const currentUrl = window.location.href;
    const excludedDomains = await GM_getValue(excludedDomainsStorageKey, []);
    const isExcluded = excludedDomains.some(domain => currentUrl.includes(domain));
    if (isExcluded) return;

    // --- Storage Keys ---
    const STORAGE_KEYS = {
        links: 'universalLinkManagerLinks',
        bubbleHidden: 'isBubbleHidden',
        position: 'bubblePosition',
        theme: 'universalLinkManagerTheme',
        customColors: 'universalLinkManagerCustomColors',
        categories: 'universalLinkManagerCategories',
        settings: 'universalLinkManagerSettings',
        excludedDomains: 'excludedUniversalDomains',
        clickStats: 'universalLinkManagerClickStats',
        folders: 'universalLinkManagerFolders'
    };

    // --- Default Data ---
    const defaultLinks = [
        { label: 'Google', url: 'https://www.google.com/', category: 'default', shortcut: '', addedAt: Date.now() - 86400000 * 3, tags: [], folder: '', health: { status: 'unknown', checkedAt: 0 } },
        { label: 'Gemini AI', url: 'https://gemini.google.com/', category: 'default', shortcut: '', addedAt: Date.now() - 86400000 * 2, tags: [], folder: '', health: { status: 'unknown', checkedAt: 0 } },
        { label: 'OpenAI', url: 'https://www.openai.com/', category: 'default', shortcut: '', addedAt: Date.now() - 86400000, tags: [], folder: '', health: { status: 'unknown', checkedAt: 0 } }
    ];

    const defaultCategories = [
        { name: 'default', color: '#888888' },
        { name: 'social', color: '#4287f5' },
        { name: 'work', color: '#2ecc71' },
        { name: 'entertainment', color: '#f542d4' },
        { name: 'tools', color: '#ff6b6b' }
    ];

    const defaultSettings = {
        bubbleIcon: 'λ',
        bubbleSize: 60,
        animationsEnabled: true,
        openInNewTab: true,
        showClickCount: false,
        confirmDelete: true,
        sortMode: 'manual',
        recentCount: 10,
        showFavicons: true,
        defaultOpenSections: [],
        sidebarCollapsed: false,
        autoCategorizeDomains: {
            'youtube.com': 'entertainment', 'netflix.com': 'entertainment', 'twitch.tv': 'entertainment', 'spotify.com': 'entertainment',
            'twitter.com': 'social', 'x.com': 'social', 'facebook.com': 'social', 'instagram.com': 'social', 'reddit.com': 'social', 'linkedin.com': 'social', 'tiktok.com': 'social',
            'github.com': 'tools', 'stackoverflow.com': 'tools', 'codepen.io': 'tools',
            'docs.google.com': 'work', 'drive.google.com': 'work', 'notion.so': 'work', 'slack.com': 'work', 'trello.com': 'work'
        }
    };

    const defaultCustomColors = {
        bubbleBackground: '#0ff',
        bubbleText: '#001f3f',
        bubbleGlow: '#0ff',
        menuBackground: '#222',
        menuBorder: '#0ff',
        linkBackground: '#333',
        linkText: '#fff',
        linkHover: '#0ff',
        buttonBackground: '#444',
        buttonText: '#0ff',
        buttonHover: '#0ff'
    };

    // --- State Variables ---
    let isDeleteMode = false;
    let isExcludeDeleteMode = false;
    let currentCategory = 'all';
    let searchQuery = '';
    let draggedItem = null;
    let activeLetter = null;
    let currentSortMode = 'manual';
    let showRecentlyAdded = false;
    let currentFolder = '';
    let openAccordion = '';

    // --- Data Management Functions ---
    async function getData(key, defaultValue) {
        return await GM_getValue(key, defaultValue);
    }
    async function setData(key, value) {
        await GM_setValue(key, value);
    }
    async function getLinks() {
        const links = await getData(STORAGE_KEYS.links, defaultLinks);
        return links.map(link => ({
            ...link,
            category: link.category || 'default',
            shortcut: link.shortcut || '',
            addedAt: link.addedAt || 0,
            tags: link.tags || [],
            folder: link.folder || '',
            health: link.health || { status: 'unknown', checkedAt: 0 }
        }));
    }
    async function saveLinks(links) {
        await setData(STORAGE_KEYS.links, links);
    }
    async function getCategories() {
        const saved = await getData(STORAGE_KEYS.categories, null);
        if (!saved) {
            await saveCategories(defaultCategories);
            return defaultCategories;
        }
        if (saved.length > 0 && typeof saved[0] === 'string') {
            const migrated = saved.map((name, index) => ({
                name: name,
                color: defaultCategories[index]?.color || generateRandomColor()
            }));
            await saveCategories(migrated);
            return migrated;
        }
        return saved;
    }
    async function saveCategories(categories) {
        await setData(STORAGE_KEYS.categories, categories);
    }
    function generateRandomColor() {
        const colors = ['#4287f5', '#2ecc71', '#f542d4', '#ff6b6b', '#ffa500', '#9b59b6', '#1abc9c', '#e74c3c'];
        return colors[Math.floor(Math.random() * colors.length)];
    }
    async function getSettings() {
        const saved = await getData(STORAGE_KEYS.settings, {});
        const settings = { ...defaultSettings, ...saved };
        settings.autoCategorizeDomains = { ...defaultSettings.autoCategorizeDomains, ...(saved.autoCategorizeDomains || {}) };
        if (!Array.isArray(settings.defaultOpenSections)) settings.defaultOpenSections = [];
        if (typeof settings.sidebarCollapsed !== 'boolean') settings.sidebarCollapsed = false;
        return settings;
    }
    async function saveSettings(settings) {
        await setData(STORAGE_KEYS.settings, settings);
    }
    async function getCustomColors() {
        const saved = await getData(STORAGE_KEYS.customColors, {});
        return { ...defaultCustomColors, ...saved };
    }
    async function saveCustomColors(colors) {
        await setData(STORAGE_KEYS.customColors, colors);
    }
    async function getExcludedDomains() {
        return await getData(STORAGE_KEYS.excludedDomains, []);
    }
    async function saveExcludedDomains(domains) {
        await setData(STORAGE_KEYS.excludedDomains, domains);
    }
    async function getBubbleHiddenState() {
        return await getData(STORAGE_KEYS.bubbleHidden, false);
    }
    async function saveBubbleHiddenState(isHidden) {
        await setData(STORAGE_KEYS.bubbleHidden, isHidden);
    }
    async function getButtonPosition() {
        return await getData(STORAGE_KEYS.position, { vertical: 'bottom', horizontal: 'right' });
    }
    async function saveButtonPosition(position) {
        await setData(STORAGE_KEYS.position, position);
    }
    async function getTheme() {
        return await getData(STORAGE_KEYS.theme, 'default');
    }
    async function saveTheme(theme) {
        await setData(STORAGE_KEYS.theme, theme);
    }
    async function getClickStats() {
        return await getData(STORAGE_KEYS.clickStats, {});
    }
    async function incrementClickStat(url) {
        const stats = await getClickStats();
        stats[url] = (stats[url] || 0) + 1;
        await setData(STORAGE_KEYS.clickStats, stats);
    }
    async function getFolders() {
        return await getData(STORAGE_KEYS.folders, []);
    }
    async function saveFolders(folders) {
        await setData(STORAGE_KEYS.folders, folders);
    }

    // --- Toast Notification ---
    function showToast(message, type = 'success') {
        const existing = shadowRoot.querySelector('.ulm-toast');
        if (existing) existing.remove();
        const toast = document.createElement('div');
        toast.className = 'ulm-toast';
        toast.dataset.type = type;
        toast.textContent = message;
        shadowRoot.appendChild(toast);
        setTimeout(() => toast.classList.add('visible'), 10);
        setTimeout(() => {
            toast.classList.remove('visible');
            setTimeout(() => toast.remove(), 300);
        }, 2500);
    }

    // --- Favicon Helper ---
    function getFaviconUrl(url) {
        try {
            const u = new URL(url);
            return `https://www.google.com/s2/favicons?domain=${u.hostname}&sz=32`;
        } catch { return ''; }
    }

    // --- Auto-Categorize ---
    async function suggestCategory(url) {
        const settings = await getSettings();
        const domains = settings.autoCategorizeDomains || {};
        try {
            const hostname = new URL(url).hostname.replace('www.', '');
            for (const [domain, category] of Object.entries(domains)) {
                if (hostname.includes(domain)) return category;
            }
        } catch {}
        return 'default';
    }

    // --- URL Normalization Helper ---
    function normalizeUrl(url) {
        try {
            const urlObj = new URL(url);
            let path = urlObj.pathname;
            if (path.length > 1 && path.endsWith('/')) {
                path = path.slice(0, -1);
            }
            return urlObj.hostname.replace(/^www\./, '') + path;
        } catch {
            return url.replace(/^https?:\/\/(www\.)?/, '').replace(/\/$/, '');
        }
    }

    // --- Duplicate Detection ---
    async function checkDuplicate(url) {
        const links = await getLinks();
        const normalizedUrl = normalizeUrl(url);
        return links.find(l => normalizeUrl(l.url) === normalizedUrl);
    }

    // --- Link Health Check ---
    function checkLinkHealth(url) {
        return new Promise((resolve) => {
            if (typeof GM_xmlhttpRequest !== 'undefined') {
                GM_xmlhttpRequest({
                    method: 'HEAD',
                    url: url,
                    timeout: 8000,
                    onload: (res) => resolve({ status: res.status, ok: res.status >= 200 && res.status < 400 }),
                    onerror: () => resolve({ status: 0, ok: false }),
                    ontimeout: () => resolve({ status: 0, ok: false })
                });
            } else {
                resolve({ status: -1, ok: true });
            }
        });
    }

    // --- Helper: Time ago ---
    function timeAgo(timestamp) {
        if (!timestamp) return '';
        const seconds = Math.floor((Date.now() - timestamp) / 1000);
        if (seconds < 60) return 'just now';
        const minutes = Math.floor(seconds / 60);
        if (minutes < 60) return `${minutes}m ago`;
        const hours = Math.floor(minutes / 60);
        if (hours < 24) return `${hours}h ago`;
        const days = Math.floor(hours / 24);
        if (days < 7) return `${days}d ago`;
        if (days < 30) return `${Math.floor(days / 7)}w ago`;
        return `${Math.floor(days / 30)}mo ago`;
    }

    // --- Sort links ---
    function sortLinks(links, mode) {
        const sorted = [...links];
        switch (mode) {
            case 'az':
                sorted.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }));
                break;
            case 'za':
                sorted.sort((a, b) => b.label.localeCompare(a.label, undefined, { sensitivity: 'base' }));
                break;
            case 'recent':
                sorted.sort((a, b) => (b.addedAt || 0) - (a.addedAt || 0));
                break;
            case 'manual':
            default:
                break;
        }
        return sorted;
    }

    // --- Get available letters ---
    function getAvailableLetters(links) {
        const letters = new Set();
        links.forEach(link => {
            const firstChar = link.label.charAt(0).toUpperCase();
            if (/[A-Z]/.test(firstChar)) {
                letters.add(firstChar);
            } else {
                letters.add('#');
            }
        });
        return letters;
    }

    // --- Highlight search text helper ---
    function highlightText(text, query) {
        if (!query) return text;
        const words = query.toLowerCase().split(' ').filter(w => w);
        let result = text;
        words.forEach(word => {
            const regex = new RegExp(`(${word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
            result = result.replace(regex, '<mark style="background:#0ff3;color:inherit;padding:0 1px;border-radius:2px;">$1</mark>');
        });
        return result;
    }

    // --- Theme Definitions ---
    const themes = {
        default: { name: 'Cyan Neon', colors: defaultCustomColors },
        highContrast: { name: 'High Contrast', colors: { bubbleBackground: '#ffff00', bubbleText: '#000', bubbleGlow: '#ffff00', menuBackground: '#000', menuBorder: '#ffff00', linkBackground: '#000', linkText: '#ffff00', linkHover: '#ffff00', buttonBackground: '#333', buttonText: '#ffff00', buttonHover: '#ffff00' } },
        ocean: { name: 'Ocean Blue', colors: { bubbleBackground: '#00bcd4', bubbleText: '#fff', bubbleGlow: '#00bcd4', menuBackground: '#0d2137', menuBorder: '#00bcd4', linkBackground: '#1a3a5c', linkText: '#e0f7fa', linkHover: '#00bcd4', buttonBackground: '#1a3a5c', buttonText: '#00bcd4', buttonHover: '#00bcd4' } },
        sunset: { name: 'Sunset', colors: { bubbleBackground: '#ff6b6b', bubbleText: '#fff', bubbleGlow: '#ff6b6b', menuBackground: '#2d1b2e', menuBorder: '#ff6b6b', linkBackground: '#4a2c4a', linkText: '#ffeaa7', linkHover: '#ff6b6b', buttonBackground: '#4a2c4a', buttonText: '#ff6b6b', buttonHover: '#ff6b6b' } },
        forest: { name: 'Forest', colors: { bubbleBackground: '#2ecc71', bubbleText: '#fff', bubbleGlow: '#2ecc71', menuBackground: '#1a2f23', menuBorder: '#2ecc71', linkBackground: '#2d4a3e', linkText: '#a8e6cf', linkHover: '#2ecc71', buttonBackground: '#2d4a3e', buttonText: '#2ecc71', buttonHover: '#2ecc71' } },
        purple: { name: 'Purple Haze', colors: { bubbleBackground: '#a855f7', bubbleText: '#fff', bubbleGlow: '#a855f7', menuBackground: '#1e1033', menuBorder: '#a855f7', linkBackground: '#2d1f4a', linkText: '#e9d5ff', linkHover: '#a855f7', buttonBackground: '#2d1f4a', buttonText: '#a855f7', buttonHover: '#a855f7' } },
        light: { name: 'Light Mode', colors: { bubbleBackground: '#3b82f6', bubbleText: '#fff', bubbleGlow: '#3b82f6', menuBackground: '#ffffff', menuBorder: '#3b82f6', linkBackground: '#f0f4f8', linkText: '#1e293b', linkHover: '#3b82f6', buttonBackground: '#e2e8f0', buttonText: '#3b82f6', buttonHover: '#3b82f6' } },
        custom: { name: 'Custom', colors: null }
    };

    // --- Generate Dynamic Styles ---
    function generateStyles(colors, settings) {
        const bubbleSize = settings.bubbleSize || 60;
        const animationEnabled = settings.animationsEnabled !== false;
        return `
        *, *::before, *::after {
            all: revert;
            box-sizing: border-box !important;
        }

        @keyframes ulm-pulse {
            0% { transform: scale(1); box-shadow: 0 0 15px 3px ${colors.bubbleGlow}, 0 0 30px 10px ${colors.bubbleGlow}; }
            50% { transform: scale(1.05); box-shadow: 0 0 20px 5px ${colors.bubbleGlow}, 0 0 40px 15px ${colors.bubbleGlow}; }
            100% { transform: scale(1); box-shadow: 0 0 15px 3px ${colors.bubbleGlow}, 0 0 30px 10px ${colors.bubbleGlow}; }
        }
        @keyframes ulm-neonGlow {
            0% { box-shadow: 0 0 10px ${colors.menuBorder}aa; }
            50% { box-shadow: 0 0 15px ${colors.menuBorder}ee, 0 0 25px ${colors.menuBorder}99; }
            100% { box-shadow: 0 0 10px ${colors.menuBorder}aa; }
        }
        @keyframes ulm-fadeIn {
            from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
            to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
        }
        @keyframes ulm-slideDown {
            from { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; }
            to { opacity: 1; max-height: 800px; }
        }

        :host {
            all: initial !important;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif !important;
            font-size: 14px !important;
            line-height: 1.4 !important;
            color: ${colors.linkText} !important;
        }

        .ulm-bubble {
            position: fixed !important; width: ${bubbleSize}px !important; height: ${bubbleSize}px !important; min-width: ${bubbleSize}px !important; min-height: ${bubbleSize}px !important; max-width: ${bubbleSize}px !important; max-height: ${bubbleSize}px !important;
            background-color: ${colors.bubbleBackground} !important;
            border-radius: 50% !important;
            box-shadow: 0 0 15px 3px ${colors.bubbleGlow}, 0 0 30px 10px ${colors.bubbleGlow} !important;
            cursor: pointer !important; z-index: 2147483647 !important; display: flex !important; justify-content: center !important; align-items: center !important;
            font-size: ${Math.floor(bubbleSize * 0.6)}px !important; font-weight: 900 !important; color: ${colors.bubbleText} !important; user-select: none !important;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;
            transition: transform 0.2s ease, box-shadow 0.2s ease !important;
            ${animationEnabled ? 'animation: ulm-pulse 3s infinite ease-in-out !important;' : ''}
            border: none !important; outline: none !important; margin: 0 !important; padding: 0 !important; opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; transform: none !important; float: none !important; clear: none !important;
        }
        .ulm-bubble:hover { transform: scale(1.15) !important; box-shadow: 0 0 20px 5px ${colors.bubbleGlow}, 0 0 40px 15px ${colors.bubbleGlow} !important; }
        .ulm-bubble.hidden { display: none !important; }

        .ulm-show-button {
            position: fixed !important; width: ${bubbleSize}px !important; height: ${bubbleSize}px !important; min-width: ${bubbleSize}px !important; min-height: ${bubbleSize}px !important;
            cursor: pointer !important; z-index: 2147483646 !important; background-color: transparent !important;
            border: 3px dashed ${colors.bubbleBackground}66 !important; border-radius: 50% !important; display: none !important;
            margin: 0 !important; padding: 0 !important; opacity: 1 !important; visibility: visible !important;
        }
        .ulm-show-button:hover { border-color: ${colors.bubbleBackground} !important; }
        .ulm-show-button.visible { display: block !important; }

        .ulm-mini-menu {
            position: fixed !important; z-index: 2147483647 !important; padding: 10px !important; border-radius: 8px !important;
            display: none !important; flex-direction: column !important; gap: 8px !important;
            background-color: ${colors.menuBackground} !important; border: 2px solid ${colors.menuBorder} !important;
            ${animationEnabled ? 'animation: ulm-neonGlow 4s infinite ease-in-out !important;' : ''}
            box-shadow: 0 0 10px ${colors.menuBorder}aa !important;
            width: auto !important; height: auto !important; min-width: 150px !important; opacity: 0 !important; visibility: hidden !important;
            transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease !important;
            transform: scale(0.95) !important;
        }
        .ulm-mini-menu.visible { display: flex !important; opacity: 1 !important; visibility: visible !important; transform: scale(1) !important; }
        .ulm-mini-menu button {
            display: block !important; width: 100% !important; padding: 10px 15px !important; margin: 0 !important; color: ${colors.buttonText} !important;
            border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.buttonBackground} !important; border-radius: 5px !important;
            cursor: pointer !important; font-size: 14px !important; font-family: inherit !important; text-align: center !important;
            transition: background-color 0.2s, color 0.2s !important; line-height: 1.4 !important; opacity: 1 !important; visibility: visible !important;
        }
        .ulm-mini-menu button:hover { background-color: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }

        .ulm-main-ui {
            position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important;
            width: 680px !important; max-width: 95vw !important; max-height: 90vh !important;
            background-color: ${colors.menuBackground} !important; border: 2px solid ${colors.menuBorder} !important; border-radius: 12px !important;
            padding: 0 !important; z-index: 2147483647 !important; display: none !important; flex-direction: column !important;
            overflow: hidden !important;
            ${animationEnabled ? 'animation: ulm-fadeIn 0.3s ease, ulm-neonGlow 4s infinite ease-in-out !important;' : ''}
            box-shadow: 0 0 20px ${colors.menuBorder}aa, 0 0 50px rgba(0,0,0,0.5) !important;
            opacity: 1 !important; visibility: visible !important; margin: 0 !important; float: none !important;
            transition: border-color 0.3s ease;
        }
        .ulm-main-ui.visible { display: flex !important; }
        .ulm-main-ui.edit-mode { border-color: #f44336 !important; }

        /* --- Layout: Header + Body(Sidebar + Content) --- */
        .ulm-layout-header {
            display: flex !important; justify-content: space-between !important; align-items: center !important;
            border-bottom: 1px solid #555 !important; padding: 12px 15px !important; margin: 0 !important; flex-shrink: 0 !important;
        }
        .ulm-header-left { display: flex !important; flex-direction: column !important; gap: 2px !important; }
        .ulm-layout-header h2 { margin: 0 !important; padding: 0 !important; color: ${colors.menuBorder} !important; text-shadow: 0 0 5px ${colors.menuBorder} !important; font-size: 18px !important; font-weight: bold !important; line-height: 1.2 !important; }
        .ulm-header-info { font-size: 11px !important; color: ${colors.linkText}aa !important; margin: 0 !important; padding: 0 !important; }
        .ulm-header-shortcuts { font-size: 10px !important; color: ${colors.linkText}66 !important; margin: 0 !important; }
        .ulm-header-shortcuts kbd { background: ${colors.linkBackground} !important; border: 1px solid ${colors.menuBorder}44 !important; border-radius: 3px !important; padding: 1px 5px !important; font-size: 9px !important; font-family: monospace !important; }
        .ulm-close-btn { background: none !important; border: none !important; color: ${colors.linkText} !important; font-size: 28px !important; cursor: pointer !important; padding: 0 !important; margin: 0 !important; width: 35px !important; height: 35px !important; min-width: 35px !important; min-height: 35px !important; border-radius: 50% !important; transition: all 0.2s ease !important; display: flex !important; align-items: center !important; justify-content: center !important; line-height: 1 !important; }
        .ulm-close-btn:hover { background-color: #f00 !important; color: #fff !important; transform: scale(1.1) !important; }

        .ulm-layout-body {
            display: flex !important; flex: 1 !important; min-height: 0 !important; overflow: hidden !important;
        }

        /* --- Sidebar --- */
        .ulm-sidebar {
            width: 170px !important; min-width: 170px !important; flex-shrink: 0 !important;
            background-color: ${colors.linkBackground}88 !important;
            border-right: 1px solid ${colors.menuBorder}33 !important;
            display: flex !important; flex-direction: column !important;
            overflow-y: auto !important; overflow-x: hidden !important;
            transition: width 0.25s ease, min-width 0.25s ease, padding 0.25s ease, opacity 0.25s ease !important;
            padding: 8px 0 !important;
        }
        .ulm-sidebar.collapsed {
            width: 0px !important; min-width: 0px !important; padding: 0 !important; opacity: 0 !important; overflow: hidden !important;
            border-right: none !important;
        }
        .ulm-sidebar-header {
            display: flex !important; align-items: center !important; justify-content: space-between !important;
            padding: 6px 12px 10px 12px !important;
            border-bottom: 1px solid ${colors.menuBorder}22 !important;
            margin-bottom: 4px !important; flex-shrink: 0 !important;
        }
        .ulm-sidebar-header span {
            font-size: 11px !important; font-weight: 700 !important; text-transform: uppercase !important;
            letter-spacing: 1px !important; color: ${colors.menuBorder} !important; white-space: nowrap !important;
        }
        .ulm-sidebar-toggle {
            background: none !important; border: none !important; color: ${colors.linkText}88 !important;
            cursor: pointer !important; font-size: 14px !important; padding: 2px 4px !important;
            border-radius: 4px !important; transition: all 0.15s !important; line-height: 1 !important;
            display: flex !important; align-items: center !important; justify-content: center !important;
            width: 24px !important; height: 24px !important; min-width: 24px !important; min-height: 24px !important;
        }
        .ulm-sidebar-toggle:hover { background-color: ${colors.menuBorder}33 !important; color: ${colors.linkText} !important; }

        .ulm-sidebar-expand-btn {
            position: absolute !important; left: 0 !important; top: 50% !important; transform: translateY(-50%) !important;
            width: 20px !important; height: 44px !important;
            background-color: ${colors.linkBackground} !important;
            border: 1px solid ${colors.menuBorder}44 !important;
            border-left: none !important; border-radius: 0 6px 6px 0 !important;
            cursor: pointer !important; color: ${colors.linkText}88 !important;
            font-size: 10px !important; display: none !important;
            align-items: center !important; justify-content: center !important;
            z-index: 5 !important; transition: all 0.15s !important;
        }
        .ulm-sidebar-expand-btn:hover { background-color: ${colors.menuBorder}33 !important; color: ${colors.linkText} !important; }
        .ulm-sidebar-expand-btn.visible { display: flex !important; }

        .ulm-folder-nav { display: flex !important; flex-direction: column !important; gap: 1px !important; flex: 1 !important; }

        .ulm-folder-nav-item {
            display: flex !important; align-items: center !important; gap: 8px !important;
            padding: 8px 12px !important; cursor: pointer !important;
            color: ${colors.linkText}cc !important; font-size: 12px !important;
            transition: all 0.15s ease !important; border: none !important;
            background: transparent !important; width: 100% !important;
            text-align: left !important; font-family: inherit !important;
            white-space: nowrap !important; overflow: hidden !important;
            position: relative !important; border-radius: 0 !important;
            margin: 0 !important; min-height: 34px !important;
        }
        .ulm-folder-nav-item:hover { background-color: ${colors.menuBorder}18 !important; color: ${colors.linkText} !important; }
        .ulm-folder-nav-item.active {
            background-color: ${colors.menuBorder}22 !important; color: ${colors.menuBorder} !important;
            border-left: 3px solid ${colors.menuBorder} !important;
            font-weight: 600 !important;
        }
        .ulm-folder-nav-item .folder-icon { font-size: 14px !important; flex-shrink: 0 !important; width: 18px !important; text-align: center !important; }
        .ulm-folder-nav-item .folder-name { flex: 1 !important; overflow: hidden !important; text-overflow: ellipsis !important; }
        .ulm-folder-nav-item .folder-count {
            font-size: 10px !important; background: ${colors.menuBorder}22 !important;
            color: ${colors.linkText}88 !important; padding: 1px 6px !important;
            border-radius: 10px !important; flex-shrink: 0 !important;
            min-width: 20px !important; text-align: center !important;
        }
        .ulm-folder-nav-item .folder-delete-btn {
            position: absolute !important; right: 6px !important; top: 50% !important; transform: translateY(-50%) !important;
            width: 20px !important; height: 20px !important; min-width: 20px !important; min-height: 20px !important;
            border-radius: 50% !important; border: none !important;
            background: #a00 !important; color: #fff !important;
            font-size: 12px !important; cursor: pointer !important;
            display: none !important; align-items: center !important; justify-content: center !important;
            transition: background 0.15s !important; line-height: 1 !important; padding: 0 !important;
        }
        .ulm-folder-nav-item .folder-delete-btn:hover { background: #f00 !important; }
        .ulm-folder-nav-item.edit-mode .folder-delete-btn { display: flex !important; }
        .ulm-folder-nav-item.edit-mode .folder-count { display: none !important; }

        .ulm-sidebar-divider {
            height: 1px !important; background: ${colors.menuBorder}22 !important;
            margin: 6px 12px !important; flex-shrink: 0 !important;
        }

        /* --- Main Content Area --- */
        .ulm-content {
            flex: 1 !important; display: flex !important; flex-direction: column !important;
            gap: 12px !important; padding: 15px !important; overflow-y: auto !important;
            overflow-x: hidden !important; min-width: 0 !important;
            position: relative !important;
        }

        .ulm-search-container { display: flex !important; gap: 8px !important; flex-shrink: 0 !important; }
        .ulm-search-input { flex: 1 !important; padding: 10px 14px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.linkBackground} !important; color: ${colors.linkText} !important; border-radius: 6px !important; font-size: 14px !important; font-family: inherit !important; outline: none !important; margin: 0 !important; height: auto !important; min-height: 40px !important; transition: border-color 0.2s ease, box-shadow 0.2s ease !important; }
        .ulm-search-input::placeholder { color: ${colors.linkText}88 !important; }
        .ulm-search-input:focus { border-color: ${colors.buttonHover} !important; box-shadow: 0 0 5px ${colors.buttonHover}44 !important; }
        .ulm-clear-search { padding: 10px 14px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.buttonBackground} !important; color: ${colors.buttonText} !important; border-radius: 6px !important; cursor: pointer !important; font-size: 14px !important; margin: 0 !important; min-width: 40px !important; min-height: 40px !important; transition: all 0.2s ease !important; }
        .ulm-clear-search:hover { background-color: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }

        /* Sort and Filter Bar */
        .ulm-sort-filter-bar { display: flex !important; align-items: center !important; gap: 8px !important; flex-shrink: 0 !important; flex-wrap: wrap !important; }
        .ulm-category-filter { display: flex !important; align-items: center !important; gap: 6px !important; flex: 1 !important; min-width: 0 !important; }
        .ulm-category-filter label { font-size: 12px !important; color: ${colors.linkText}cc !important; white-space: nowrap !important; }
        .ulm-category-dropdown, .ulm-sort-dropdown { flex: 1 !important; padding: 7px 10px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.linkBackground} !important; color: ${colors.linkText} !important; border-radius: 6px !important; font-size: 13px !important; font-family: inherit !important; cursor: pointer !important; outline: none !important; min-width: 0 !important; transition: border-color 0.2s ease !important; }
        .ulm-category-dropdown:focus, .ulm-sort-dropdown:focus { border-color: ${colors.buttonHover} !important; }
        .ulm-category-dropdown option, .ulm-sort-dropdown option { background-color: ${colors.menuBackground} !important; color: ${colors.linkText} !important; }
        .ulm-sort-dropdown { flex: none !important; }
        .ulm-recent-btn { padding: 7px 12px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.buttonBackground} !important; color: ${colors.buttonText} !important; border-radius: 6px !important; cursor: pointer !important; font-size: 12px !important; font-family: inherit !important; white-space: nowrap !important; transition: all 0.2s !important; }
        .ulm-recent-btn:hover { background-color: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }
        .ulm-recent-btn.active { background-color: ${colors.menuBorder} !important; color: ${colors.menuBackground} !important; }

        /* Alphabetical Index Bar */
        .ulm-alpha-bar { display: flex !important; flex-wrap: wrap !important; gap: 2px !important; padding: 6px 4px !important; background-color: ${colors.linkBackground}88 !important; border-radius: 6px !important; flex-shrink: 0 !important; justify-content: center !important; }
        .ulm-alpha-bar.hidden { display: none !important; }
        .ulm-alpha-letter {
            width: 24px !important; height: 24px !important; min-width: 24px !important; min-height: 24px !important;
            display: flex !important; align-items: center !important; justify-content: center !important;
            font-size: 11px !important; font-weight: 600 !important; font-family: monospace !important;
            border-radius: 4px !important; cursor: pointer !important; transition: all 0.15s !important;
            border: none !important; padding: 0 !important; margin: 0 !important;
            background-color: transparent !important; color: ${colors.linkText}99 !important;
        }
        .ulm-alpha-letter:hover { background-color: ${colors.menuBorder}44 !important; color: ${colors.linkText} !important; }
        .ulm-alpha-letter.active { background-color: ${colors.menuBorder} !important; color: ${colors.menuBackground} !important; }
        .ulm-alpha-letter.has-links { color: ${colors.linkText} !important; font-weight: 700 !important; }
        .ulm-alpha-letter.disabled { color: ${colors.linkText}33 !important; cursor: default !important; pointer-events: none !important; }
        .ulm-alpha-clear {
            padding: 2px 8px !important; margin-left: 4px !important;
            font-size: 10px !important; font-family: inherit !important;
            border-radius: 4px !important; cursor: pointer !important;
            border: 1px solid ${colors.menuBorder}66 !important;
            background: ${colors.buttonBackground} !important; color: ${colors.buttonText} !important;
            transition: all 0.15s !important; display: none !important; align-items: center !important;
        }
        .ulm-alpha-clear.visible { display: flex !important; }
        .ulm-alpha-clear:hover { background: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }

        /* Recently Added Section */
        .ulm-recent-section { display: none !important; flex-direction: column !important; gap: 6px !important; flex-shrink: 0 !important; overflow: hidden !important; transition: all 0.3s ease !important; }
        .ulm-recent-section.visible { display: flex !important; }
        .ulm-recent-header { display: flex !important; align-items: center !important; justify-content: space-between !important; padding: 6px 0 !important; }
        .ulm-recent-header h3 { margin: 0 !important; font-size: 14px !important; color: ${colors.menuBorder} !important; font-weight: 600 !important; }
        .ulm-recent-header span { font-size: 11px !important; color: ${colors.linkText}88 !important; }
        .ulm-recent-list { display: flex !important; flex-direction: column !important; gap: 4px !important; max-height: 180px !important; overflow-y: auto !important; padding: 4px !important; }
        .ulm-recent-item { display: flex !important; align-items: center !important; gap: 8px !important; padding: 8px 12px !important; background-color: ${colors.linkBackground} !important; border: 1px solid ${colors.menuBorder}44 !important; border-radius: 6px !important; cursor: pointer !important; text-decoration: none !important; transition: all 0.2s !important; }
        .ulm-recent-item:hover { background-color: ${colors.linkHover} !important; color: ${colors.menuBackground} !important; border-color: ${colors.menuBorder} !important; }
        .ulm-recent-item .ulm-recent-icon { font-size: 16px !important; flex-shrink: 0 !important; opacity: 0.6 !important; }
        .ulm-recent-item .ulm-recent-label { flex: 1 !important; font-size: 13px !important; color: ${colors.linkText} !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
        .ulm-recent-item:hover .ulm-recent-label { color: ${colors.menuBackground} !important; }
        .ulm-recent-item .ulm-recent-time { font-size: 10px !important; color: ${colors.linkText}66 !important; white-space: nowrap !important; flex-shrink: 0 !important; }
        .ulm-recent-item:hover .ulm-recent-time { color: ${colors.menuBackground}aa !important; }
        .ulm-recent-item .ulm-recent-cat-dot { width: 8px !important; height: 8px !important; border-radius: 50% !important; flex-shrink: 0 !important; }

        /* Letter Group Headers */
        .ulm-letter-group-header { display: flex !important; align-items: center !important; gap: 8px !important; padding: 4px 8px !important; margin-top: 4px !important; }
        .ulm-letter-group-header:first-child { margin-top: 0 !important; }
        .ulm-letter-group-char { font-size: 14px !important; font-weight: 800 !important; color: ${colors.menuBorder} !important; font-family: monospace !important; min-width: 20px !important; text-align: center !important; }
        .ulm-letter-group-line { flex: 1 !important; height: 1px !important; background: ${colors.menuBorder}44 !important; }
        .ulm-letter-group-count { font-size: 10px !important; color: ${colors.linkText}66 !important; }

        .ulm-link-list { display: flex !important; flex-direction: column !important; gap: 6px !important; max-height: 250px !important; min-height: 60px !important; overflow-y: auto !important; overflow-x: hidden !important; padding: 5px !important; margin: 0 !important; flex-shrink: 0 !important; }
        .ulm-link-wrapper { display: flex !important; align-items: center !important; gap: 8px !important; width: 100% !important; margin: 0 !important; padding: 0 !important; opacity: 1 !important; visibility: visible !important; min-height: 42px !important; border-radius: 6px; transition: opacity 0.2s ease !important; }
        .ulm-link-wrapper.dragging { opacity: 0.5 !important; }
        .ulm-link-wrapper.drag-over { border-top: 2px solid ${colors.menuBorder} !important; }
        .ulm-link-wrapper.selected { background-color: ${colors.menuBorder}22; }
        .ulm-drag-handle { cursor: grab !important; padding: 5px !important; color: ${colors.linkText}88 !important; font-size: 16px !important; user-select: none !important; flex-shrink: 0 !important; }
        .ulm-drag-handle:active { cursor: grabbing !important; }
        .ulm-link { flex: 1 !important; padding: 10px 14px !important; text-decoration: none !important; border-radius: 6px !important; font-size: 14px !important; font-family: inherit !important; color: ${colors.linkText} !important; background-color: ${colors.linkBackground} !important; border: 1px solid ${colors.menuBorder} !important; display: flex !important; justify-content: space-between !important; align-items: center !important; transition: background-color 0.2s ease, color 0.2s ease !important; cursor: pointer !important; margin: 0 !important; min-height: 42px !important; opacity: 1 !important; visibility: visible !important; }
        .ulm-link:hover { background-color: ${colors.linkHover} !important; color: ${colors.menuBackground} !important; }
        .ulm-link-content { display: flex; align-items: center; flex: 1; min-width: 0; }
        .ulm-link-label { font-weight: 500 !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; max-width: 180px !important; }
        .ulm-link-meta { display: flex !important; align-items: center !important; gap: 6px !important; flex-shrink: 0 !important; }
        .ulm-shortcut-badge { font-size: 10px !important; padding: 3px 7px !important; background-color: ${colors.menuBorder}44 !important; border-radius: 4px !important; font-family: monospace !important; }
        .ulm-click-count { font-size: 10px !important; color: ${colors.linkText}88 !important; }
        .ulm-time-badge { font-size: 9px !important; color: ${colors.linkText}66 !important; font-style: italic !important; }
        .ulm-category-badge { font-size: 10px !important; padding: 3px 7px !important; border-radius: 10px !important; border: 1px solid currentColor !important; }
        .ulm-action-btn { width: 32px !important; height: 32px !important; min-width: 32px !important; min-height: 32px !important; border-radius: 50% !important; cursor: pointer !important; font-weight: bold !important; transition: background-color 0.2s ease !important; display: flex !important; justify-content: center !important; align-items: center !important; padding: 0 !important; margin: 0 !important; font-size: 16px !important; flex-shrink: 0 !important; border: none !important; }
        .ulm-delete-btn { background-color: #a00 !important; border: 1px solid #f00 !important; color: #fff !important; }
        .ulm-delete-btn:hover { background-color: #f00 !important; }
        .ulm-edit-btn { background-color: ${colors.buttonBackground} !important; border: 1px solid ${colors.menuBorder} !important; color: ${colors.buttonText} !important; }
        .ulm-edit-btn:hover { background-color: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }

        /* Accordion Sections */
        .ulm-accordion { display: flex !important; flex-direction: column !important; gap: 0 !important; flex-shrink: 0 !important; border: 1px solid ${colors.menuBorder}44 !important; border-radius: 8px !important; overflow: hidden !important; }
        .ulm-accordion-header {
            display: flex !important; align-items: center !important; justify-content: space-between !important;
            padding: 12px 14px !important; cursor: pointer !important;
            background-color: ${colors.linkBackground} !important; color: ${colors.linkText} !important;
            border-bottom: 1px solid ${colors.menuBorder}22 !important;
            font-size: 13px !important; font-weight: 600 !important; font-family: inherit !important;
            transition: all 0.2s ease !important; user-select: none !important;
            margin: 0 !important; border: none !important; width: 100% !important; text-align: left !important;
        }
        .ulm-accordion-header:hover { background-color: ${colors.menuBorder}22 !important; }
        .ulm-accordion-header.active { background-color: ${colors.menuBorder}18 !important; color: ${colors.menuBorder} !important; }
        .ulm-accordion-arrow { transition: transform 0.3s ease !important; font-size: 12px !important; opacity: 0.6 !important; }
        .ulm-accordion-header.active .ulm-accordion-arrow { transform: rotate(180deg) !important; }
        .ulm-accordion-body {
            max-height: 0 !important; overflow: hidden !important;
            transition: max-height 0.35s ease, padding 0.35s ease, opacity 0.25s ease !important;
            opacity: 0 !important; padding: 0 14px !important;
            background-color: ${colors.menuBackground} !important;
        }
        .ulm-accordion-body.open {
            max-height: 800px !important; opacity: 1 !important;
            padding: 14px !important;
        }

        .ulm-form-group { display: flex !important; flex-direction: column !important; gap: 6px !important; margin: 0 !important; }
        .ulm-form-group label { font-size: 12px !important; color: ${colors.linkText}cc !important; margin: 0 !important; padding: 0 !important; }
        .ulm-form-group input, .ulm-form-group select, .ulm-form-group textarea { padding: 10px 12px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.linkBackground} !important; color: ${colors.linkText} !important; border-radius: 6px !important; font-size: 14px !important; font-family: inherit !important; margin: 0 !important; outline: none !important; min-height: 40px !important; transition: border-color 0.2s ease !important; }
        .ulm-form-group input:focus, .ulm-form-group select:focus, .ulm-form-group textarea:focus { border-color: ${colors.buttonHover} !important; }
        .ulm-form-row { display: flex !important; gap: 10px !important; margin: 0 !important; }
        .ulm-form-row .ulm-form-group { flex: 1 !important; }
        .ulm-btn { padding: 10px 18px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.buttonBackground} !important; color: ${colors.buttonText} !important; border-radius: 6px !important; cursor: pointer !important; font-size: 13px !important; font-family: inherit !important; transition: all 0.2s !important; margin: 0 !important; text-align: center !important; min-height: 40px !important; }
        .ulm-btn:hover { background-color: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }
        .ulm-btn.active { background-color: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }
        .ulm-btn-primary { background-color: ${colors.menuBorder} !important; color: ${colors.menuBackground} !important; }
        .ulm-btn-primary:hover { background-color: ${colors.buttonHover} !important; filter: brightness(1.1) !important; }
        .ulm-btn-danger { background-color: #a00 !important; border-color: #f00 !important; color: #fff !important; }
        .ulm-btn-danger:hover { background-color: #f00 !important; }
        .ulm-btn-group { display: flex !important; gap: 8px !important; flex-wrap: wrap !important; margin: 0 !important; }
        .ulm-btn-group .ulm-btn { flex: 1 !important; min-width: 100px !important; }
        .ulm-color-grid { display: grid !important; grid-template-columns: repeat(2, 1fr) !important; gap: 10px !important; margin: 0 !important; }
        .ulm-color-item { display: flex !important; flex-direction: column !important; gap: 4px !important; }
        .ulm-color-item label { font-size: 11px !important; color: ${colors.linkText}aa !important; }
        .ulm-color-item input[type="color"] { width: 100% !important; height: 40px !important; padding: 3px !important; border: 1px solid ${colors.menuBorder} !important; border-radius: 6px !important; cursor: pointer !important; background-color: ${colors.linkBackground} !important; }

        /* Settings - Collapsible Groups */
        .ulm-settings-section { margin-bottom: 12px !important; }
        .ulm-settings-section:last-child { margin-bottom: 0 !important; }
        .ulm-settings-section-header {
            display: flex !important; align-items: center !important; justify-content: space-between !important;
            padding: 8px 10px !important; cursor: pointer !important;
            background-color: ${colors.linkBackground}88 !important; border-radius: 6px !important;
            font-size: 12px !important; font-weight: 600 !important; color: ${colors.menuBorder} !important;
            transition: all 0.2s ease !important; user-select: none !important;
        }
        .ulm-settings-section-header:hover { background-color: ${colors.linkBackground} !important; }
        .ulm-settings-section-header .ulm-ss-arrow { transition: transform 0.3s ease !important; font-size: 10px !important; }
        .ulm-settings-section-header.open .ulm-ss-arrow { transform: rotate(180deg) !important; }
        .ulm-settings-section-body {
            max-height: 0 !important; overflow: hidden !important;
            transition: max-height 0.3s ease, padding 0.3s ease, opacity 0.2s ease !important;
            opacity: 0 !important; padding: 0 4px !important;
        }
        .ulm-settings-section-body.open {
            max-height: 600px !important; opacity: 1 !important; padding: 10px 4px !important;
        }
        .ulm-settings-grid { display: grid !important; grid-template-columns: repeat(2, 1fr) !important; gap: 10px !important; margin: 0 !important; }
        .ulm-setting-item { display: flex !important; align-items: center !important; justify-content: space-between !important; padding: 10px !important; background-color: ${colors.linkBackground} !important; border-radius: 6px !important; min-height: 45px !important; }
        .ulm-setting-item label { font-size: 12px !important; color: ${colors.linkText} !important; }
        .ulm-toggle-switch { position: relative !important; width: 44px !important; height: 24px !important; flex-shrink: 0 !important; }
        .ulm-toggle-switch input { opacity: 0 !important; width: 0 !important; height: 0 !important; position: absolute !important; }
        .ulm-toggle-slider { position: absolute !important; cursor: pointer !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; background-color: #555 !important; transition: 0.3s !important; border-radius: 24px !important; }
        .ulm-toggle-slider:before { position: absolute !important; content: "" !important; height: 18px !important; width: 18px !important; left: 3px !important; bottom: 3px !important; background-color: white !important; transition: 0.3s !important; border-radius: 50% !important; }
        .ulm-toggle-switch input:checked + .ulm-toggle-slider { background-color: ${colors.menuBorder} !important; }
        .ulm-toggle-switch input:checked + .ulm-toggle-slider:before { transform: translateX(20px) !important; }
        .ulm-range-container { display: flex !important; align-items: center !important; gap: 12px !important; }
        .ulm-range-container input[type="range"] { flex: 1 !important; height: 8px !important; -webkit-appearance: none !important; appearance: none !important; background: ${colors.linkBackground} !important; border-radius: 4px !important; outline: none !important; border: none !important; padding: 0 !important; margin: 0 !important; }
        .ulm-range-container input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none !important; appearance: none !important; width: 20px !important; height: 20px !important; background: ${colors.menuBorder} !important; border-radius: 50% !important; cursor: pointer !important; border: none !important; }
        .ulm-range-value { min-width: 45px !important; text-align: center !important; color: ${colors.linkText} !important; font-size: 13px !important; }
        .ulm-theme-grid { display: grid !important; grid-template-columns: repeat(4, 1fr) !important; gap: 8px !important; margin: 0 !important; }
        .ulm-theme-option { padding: 10px 8px !important; border: 2px solid transparent !important; border-radius: 8px !important; cursor: pointer !important; text-align: center !important; font-size: 11px !important; transition: all 0.2s !important; background-color: ${colors.linkBackground} !important; color: ${colors.linkText} !important; }
        .ulm-theme-option:hover { border-color: ${colors.menuBorder}88 !important; }
        .ulm-theme-option.active { border-color: ${colors.menuBorder} !important; }
        .ulm-theme-preview { width: 100% !important; height: 35px !important; border-radius: 5px !important; margin-bottom: 6px !important; }
        .ulm-position-grid { display: grid !important; grid-template-columns: repeat(2, 1fr) !important; gap: 8px !important; margin: 0 !important; }
        .ulm-backup-area { width: 100% !important; height: 120px !important; resize: vertical !important; font-family: monospace !important; font-size: 12px !important; }

        /* Toast Notifications */
        .ulm-toast {
            position: fixed !important; bottom: 30px !important; left: 50% !important; transform: translateX(-50%) translateY(20px) !important;
            padding: 12px 24px !important; border-radius: 8px !important; font-size: 14px !important; font-family: inherit !important;
            z-index: 2147483647 !important; opacity: 0 !important; transition: all 0.3s ease !important; pointer-events: none !important;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3) !important; white-space: nowrap !important;
            background-color: ${colors.menuBorder} !important; color: ${colors.menuBackground} !important;
        }
        .ulm-toast[data-type="error"] { background-color: #f44336 !important; color: #fff !important; }
        .ulm-toast[data-type="warning"] { background-color: #ff9800 !important; color: #000 !important; }
        .ulm-toast[data-type="info"] { background-color: #2196f3 !important; color: #fff !important; }
        .ulm-toast.visible { opacity: 1 !important; transform: translateX(-50%) translateY(0) !important; }

        /* Favicon */
        .ulm-favicon { width: 16px !important; height: 16px !important; min-width: 16px !important; min-height: 16px !important; border-radius: 2px !important; flex-shrink: 0 !important; margin-right: 6px !important; vertical-align: middle !important; }

        /* Tags */
        .ulm-tag { display: inline-block !important; font-size: 9px !important; padding: 2px 6px !important; border-radius: 8px !important; background-color: ${colors.menuBorder}33 !important; color: ${colors.menuBorder} !important; margin-left: 3px !important; white-space: nowrap !important; }
        .ulm-tags-container { display: flex !important; flex-wrap: wrap !important; gap: 3px !important; align-items: center !important; }
        .ulm-tag-input-wrapper { display: flex !important; flex-wrap: wrap !important; gap: 4px !important; padding: 6px !important; border: 1px solid ${colors.menuBorder} !important; background-color: ${colors.linkBackground} !important; border-radius: 6px !important; min-height: 40px !important; align-items: center !important; }
        .ulm-tag-input-wrapper .ulm-tag { cursor: pointer !important; }
        .ulm-tag-input-wrapper .ulm-tag:hover { background-color: #f44336 !important; color: #fff !important; }
        .ulm-tag-input-wrapper input { border: none !important; background: transparent !important; color: ${colors.linkText} !important; font-size: 13px !important; outline: none !important; flex: 1 !important; min-width: 80px !important; padding: 4px !important; }

        /* Health Check */
        .ulm-health-dot { width: 8px !important; height: 8px !important; min-width: 8px !important; border-radius: 50% !important; flex-shrink: 0 !important; margin-right: 6px !important; }
        .ulm-health-dot.ok { background-color: #4caf50 !important; }
        .ulm-health-dot.error { background-color: #f44336 !important; }
        .ulm-health-dot.checking { background-color: #ff9800 !important; animation: ulm-pulse 1.5s infinite !important; }
        .ulm-health-dot.unknown { background-color: #888 !important; }

        /* Empty State */
        .ulm-empty-state {
            display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important;
            padding: 30px 20px !important; text-align: center !important; gap: 10px !important;
        }
        .ulm-empty-state-icon { font-size: 40px !important; opacity: 0.3 !important; }
        .ulm-empty-state-title { font-size: 15px !important; font-weight: 600 !important; color: ${colors.linkText}aa !important; margin: 0 !important; }
        .ulm-empty-state-subtitle { font-size: 12px !important; color: ${colors.linkText}66 !important; margin: 0 !important; }
        .ulm-no-results { text-align: center !important; color: ${colors.linkText}88 !important; padding: 25px !important; font-size: 14px !important; }

        .ulm-exclude-list { display: flex !important; flex-direction: column !important; gap: 6px !important; max-height: 120px !important; overflow-y: auto !important; margin: 0 !important; padding: 5px !important; }
        .ulm-exclude-wrapper { display: flex !important; align-items: center !important; gap: 8px !important; }
        .ulm-exclude-wrapper span { flex: 1 !important; padding: 8px 12px !important; background-color: ${colors.linkBackground} !important; border: 1px solid ${colors.menuBorder} !important; border-radius: 6px !important; font-size: 13px !important; color: ${colors.linkText} !important; }

        .ulm-modal-overlay { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; width: 100vw !important; height: 100vh !important; background: rgba(0,0,0,0.75) !important; z-index: 2147483647 !important; display: flex !important; justify-content: center !important; align-items: center !important; }
        .ulm-modal-content { background: ${colors.menuBackground} !important; border: 2px solid ${colors.menuBorder} !important; border-radius: 12px !important; padding: 20px !important; max-width: 400px !important; width: 90% !important; }
        .ulm-modal-content h3 { color: ${colors.menuBorder} !important; margin: 0 0 15px 0 !important; font-size: 16px !important; }

        /* Context Menu */
        .ulm-context-menu { position:fixed; background: ${colors.menuBackground}; border:1px solid ${colors.menuBorder}; border-radius:8px; padding:5px 0; z-index:999999; display:none; min-width:160px; box-shadow:0 4px 15px rgba(0,0,0,0.4); }
        .ulm-ctx-item { padding:8px 16px; cursor:pointer; color:${colors.linkText}; font-size:13px; transition: background 0.15s ease !important; }
        .ulm-ctx-item:hover { background: ${colors.linkHover}; color: ${colors.menuBackground}; }

        /* Generic Manager Item */
        .ulm-manager-list { display: flex !important; flex-direction: column !important; gap: 8px !important; max-height: 200px !important; overflow-y: auto !important; padding: 5px !important; margin: 0 !important; }
        .ulm-manager-item { display: flex !important; align-items: center !important; gap: 8px !important; padding: 8px 10px !important; background-color: ${colors.linkBackground} !important; border: 1px solid ${colors.menuBorder}66 !important; border-radius: 6px !important; }
        .ulm-manager-item .item-color { width: 32px !important; height: 32px !important; border: none !important; border-radius: 4px !important; cursor: pointer !important; padding: 0 !important; flex-shrink: 0 !important; }
        .ulm-manager-item .item-name { flex: 1 !important; font-size: 13px !important; color: ${colors.linkText} !important; padding: 5px 8px !important; background: transparent !important; border: 1px solid transparent !important; border-radius: 4px !important; }
        .ulm-manager-item .item-name:focus, .ulm-manager-item .item-name.editing { border-color: ${colors.menuBorder} !important; background: ${colors.menuBackground} !important; outline: none !important; }
        .ulm-manager-item .item-count { font-size: 11px !important; color: ${colors.linkText}88 !important; padding: 2px 6px !important; background: ${colors.menuBorder}22 !important; border-radius: 10px !important; }
        .ulm-manager-item .item-actions { display: flex !important; gap: 4px !important; }
        .ulm-manager-item .item-btn { width: 28px !important; height: 28px !important; min-width: 28px !important; min-height: 28px !important; border-radius: 4px !important; cursor: pointer !important; font-size: 14px !important; display: flex !important; align-items: center !important; justify-content: center !important; padding: 0 !important; margin: 0 !important; border: 1px solid ${colors.menuBorder}66 !important; background: ${colors.buttonBackground} !important; color: ${colors.buttonText} !important; transition: all 0.2s !important; }
        .ulm-manager-item .item-btn:hover { background: ${colors.buttonHover} !important; color: ${colors.menuBackground} !important; }
        .ulm-manager-item .item-btn.delete:hover { background: #f00 !important; border-color: #f00 !important; color: #fff !important; }

        /* Default Sections Checkboxes */
        .ulm-defaults-grid { display: flex !important; flex-direction: column !important; gap: 6px !important; }
        .ulm-default-section-item {
            display: flex !important; align-items: center !important; gap: 8px !important;
            padding: 6px 8px !important; background: ${colors.linkBackground} !important;
            border-radius: 4px !important; cursor: pointer !important;
        }
        .ulm-default-section-item:hover { background: ${colors.menuBorder}18 !important; }
        .ulm-default-section-item input[type="checkbox"] {
            width: 16px !important; height: 16px !important; cursor: pointer !important;
            accent-color: ${colors.menuBorder} !important; flex-shrink: 0 !important;
            margin: 0 !important; padding: 0 !important;
        }
        .ulm-default-section-item span { font-size: 12px !important; color: ${colors.linkText} !important; }

        /* Scrollbar Styles */
        .ulm-link-list::-webkit-scrollbar, .ulm-exclude-list::-webkit-scrollbar, .ulm-content::-webkit-scrollbar, .ulm-manager-list::-webkit-scrollbar, .ulm-recent-list::-webkit-scrollbar, .ulm-sidebar::-webkit-scrollbar { width: 8px !important; }
        .ulm-link-list::-webkit-scrollbar-track, .ulm-exclude-list::-webkit-scrollbar-track, .ulm-content::-webkit-scrollbar-track, .ulm-manager-list::-webkit-scrollbar-track, .ulm-recent-list::-webkit-scrollbar-track, .ulm-sidebar::-webkit-scrollbar-track { background: ${colors.linkBackground} !important; border-radius: 4px !important; }
        .ulm-link-list::-webkit-scrollbar-thumb, .ulm-exclude-list::-webkit-scrollbar-thumb, .ulm-content::-webkit-scrollbar-thumb, .ulm-manager-list::-webkit-scrollbar-thumb, .ulm-recent-list::-webkit-scrollbar-thumb, .ulm-sidebar::-webkit-scrollbar-thumb { background: ${colors.menuBorder}88 !important; border-radius: 4px !important; }
        .ulm-link-list::-webkit-scrollbar-thumb:hover, .ulm-exclude-list::-webkit-scrollbar-thumb:hover, .ulm-content::-webkit-scrollbar-thumb:hover, .ulm-manager-list::-webkit-scrollbar-thumb:hover, .ulm-recent-list::-webkit-scrollbar-thumb:hover, .ulm-sidebar::-webkit-scrollbar-thumb:hover { background: ${colors.menuBorder} !important; }
        `;
    }

    // --- Create Shadow DOM Container ---
    function createShadowContainer() {
        const container = document.createElement('div');
        container.id = 'universal-link-manager-container';
        container.style.cssText = 'all: initial !important; position: fixed !important; top: 0 !important; left: 0 !important; width: 0 !important; height: 0 !important; z-index: 2147483647 !important; pointer-events: none !important;';
        document.body.appendChild(container);
        const shadow = container.attachShadow({ mode: 'closed' });
        return shadow;
    }

    // --- UI Elements ---
    let shadowRoot = null;
    let styleElement = null;
    let bubble = null;
    let mainUI = null;
    let showBubbleButton = null;
    let bubbleMenu = null;

    // --- Apply Theme ---
    async function applyTheme(themeName) {
        const settings = await getSettings();
        let colors;
        if (themeName === 'custom') {
            colors = await getCustomColors();
        } else if (themes[themeName]) {
            colors = themes[themeName].colors;
        } else {
            colors = defaultCustomColors;
        }
        if (styleElement) {
            styleElement.textContent = generateStyles(colors, settings);
        }
        if (bubble) {
            bubble.textContent = settings.bubbleIcon;
            bubble.style.width = settings.bubbleSize + 'px';
            bubble.style.height = settings.bubbleSize + 'px';
            bubble.style.fontSize = Math.floor(settings.bubbleSize * 0.6) + 'px';
        }
    }

    // --- Populate Category Dropdown ---
    async function populateCategoryDropdown(links, categories) {
        const dropdown = shadowRoot.querySelector('.ulm-category-dropdown');
        if (!dropdown) return;
        dropdown.innerHTML = '';
        const allOption = document.createElement('option');
        allOption.value = 'all';
        allOption.textContent = `All Categories (${links.length})`;
        dropdown.appendChild(allOption);
        categories.forEach(cat => {
            const count = links.filter(l => l.category === cat.name).length;
            const option = document.createElement('option');
            option.value = cat.name;
            option.textContent = `${cat.name.charAt(0).toUpperCase() + cat.name.slice(1)} (${count})`;
            if (cat.name === currentCategory) option.selected = true;
            dropdown.appendChild(option);
        });
        if (currentCategory !== 'all') {
            dropdown.value = currentCategory;
        }
    }

    // --- Build Alphabetical Index Bar ---
    async function buildAlphaBar(links) {
        const alphaBar = shadowRoot.querySelector('.ulm-alpha-bar');
        if (!alphaBar) return;
        let filteredLinks = links;
        if (currentCategory !== 'all') {
            filteredLinks = filteredLinks.filter(link => link.category === currentCategory);
        }
        const availableLetters = getAvailableLetters(filteredLinks);
        const allLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ#'.split('');
        alphaBar.innerHTML = '';
        const shouldShow = currentSortMode === 'az' || currentSortMode === 'za';
        alphaBar.classList.toggle('hidden', !shouldShow);
        if (!shouldShow) return;
        allLetters.forEach(letter => {
            const btn = document.createElement('button');
            btn.className = 'ulm-alpha-letter';
            btn.textContent = letter;
            const hasLinks = availableLetters.has(letter);
            btn.classList.toggle('has-links', hasLinks);
            btn.classList.toggle('disabled', !hasLinks);
            btn.classList.toggle('active', activeLetter === letter);
            btn.addEventListener('click', async () => {
                if (!hasLinks) return;
                activeLetter = (activeLetter === letter) ? null : letter;
                await refreshUI();
            });
            alphaBar.appendChild(btn);
        });
        const clearBtn = document.createElement('button');
        clearBtn.className = 'ulm-alpha-clear';
        clearBtn.textContent = '✕ Clear';
        clearBtn.classList.toggle('visible', !!activeLetter);
        clearBtn.addEventListener('click', async () => {
            activeLetter = null;
            await refreshUI();
        });
        alphaBar.appendChild(clearBtn);
    }

    // --- Populate Recently Added Section ---
    async function populateRecentSection(links, settings, categories) {
        const recentSection = shadowRoot.querySelector('.ulm-recent-section');
        if (!recentSection) return;
        recentSection.classList.toggle('visible', showRecentlyAdded);
        if (!showRecentlyAdded) return;
        const recentList = recentSection.querySelector('.ulm-recent-list');
        const recentCountEl = recentSection.querySelector('.ulm-recent-count');
        const recentLinks = [...links]
            .filter(l => l.addedAt)
            .sort((a, b) => b.addedAt - a.addedAt)
            .slice(0, settings.recentCount || 10);
        if (recentCountEl) {
            recentCountEl.textContent = `Showing ${recentLinks.length} most recent`;
        }
        recentList.innerHTML = '';
        if (recentLinks.length === 0) {
            recentList.innerHTML = '<div class="ulm-empty-state"><div class="ulm-empty-state-icon">🕐</div><div class="ulm-empty-state-title">No recent links</div><div class="ulm-empty-state-subtitle">Links you add will show up here</div></div>';
            return;
        }
        recentLinks.forEach(linkData => {
            const item = document.createElement('a');
            item.className = 'ulm-recent-item';
            item.href = linkData.url;
            item.target = settings.openInNewTab ? '_blank' : '_self';
            const cat = categories.find(c => c.name === linkData.category);
            item.innerHTML = `
                <span class="ulm-recent-cat-dot" style="background-color: ${cat?.color || '#888'}"></span>
                <span class="ulm-recent-icon">🕐</span>
                <span class="ulm-recent-label">${linkData.label}</span>
                <span class="ulm-recent-time">${timeAgo(linkData.addedAt)}</span>
            `;
            item.addEventListener('click', () => incrementClickStat(linkData.url));
            recentList.appendChild(item);
        });
    }

    // --- Populate Link List ---
    async function populateLinkList(allLinks, settings, categories, clickStats) {
        const linkListElement = shadowRoot.querySelector('.ulm-link-list');
        linkListElement.innerHTML = '';
        let filteredLinks = allLinks;
        if (currentCategory !== 'all') {
            filteredLinks = filteredLinks.filter(link => link.category === currentCategory);
        }
        if (currentFolder) {
            filteredLinks = filteredLinks.filter(link => link.folder === currentFolder);
        }
        if (searchQuery) {
            const searchWords = searchQuery.toLowerCase().split(' ').filter(w => w);
            filteredLinks = filteredLinks.filter(link => {
                const searchableText = [link.label, link.url, ...(link.tags || []), link.folder || ''].join(' ').toLowerCase();
                return searchWords.every(word => searchableText.includes(word));
            });
        }
        if (activeLetter) {
            filteredLinks = filteredLinks.filter(link => {
                const firstChar = link.label.charAt(0).toUpperCase();
                return activeLetter === '#' ? !/[A-Z]/.test(firstChar) : firstChar === activeLetter;
            });
        }
        filteredLinks = sortLinks(filteredLinks, currentSortMode);
        if (filteredLinks.length === 0) {
            if (searchQuery) {
                linkListElement.innerHTML = '<div class="ulm-empty-state"><div class="ulm-empty-state-icon">🔍</div><div class="ulm-empty-state-title">No matches found</div><div class="ulm-empty-state-subtitle">Try a different search term</div></div>';
            } else if (allLinks.length === 0) {
                linkListElement.innerHTML = '<div class="ulm-empty-state"><div class="ulm-empty-state-icon">🔗</div><div class="ulm-empty-state-title">No links yet</div><div class="ulm-empty-state-subtitle">Add your first link below or press <kbd style="background:#444;padding:2px 6px;border-radius:3px;font-size:11px;">Ctrl+Alt+A</kbd> to save this page</div></div>';
            } else {
                linkListElement.innerHTML = '<div class="ulm-empty-state"><div class="ulm-empty-state-icon">📂</div><div class="ulm-empty-state-title">No links in this view</div><div class="ulm-empty-state-subtitle">Try changing filters or category</div></div>';
            }
            return;
        }
        const showGroups = (currentSortMode === 'az' || currentSortMode === 'za') && !activeLetter && !searchQuery;
        let lastLetter = null;
        filteredLinks.forEach((linkData) => {
            const originalIndex = allLinks.indexOf(linkData);
            if (showGroups) {
                const firstChar = linkData.label.charAt(0).toUpperCase();
                const groupLetter = /[A-Z]/.test(firstChar) ? firstChar : '#';
                if (groupLetter !== lastLetter) {
                    lastLetter = groupLetter;
                    const groupCount = filteredLinks.filter(l => (l.label.charAt(0).toUpperCase() === groupLetter) || (groupLetter === '#' && !/[A-Z]/.test(l.label.charAt(0).toUpperCase()))).length;
                    const header = document.createElement('div');
                    header.className = 'ulm-letter-group-header';
                    header.innerHTML = `<span class="ulm-letter-group-char">${groupLetter}</span><div class="ulm-letter-group-line"></div><span class="ulm-letter-group-count">${groupCount}</span>`;
                    linkListElement.appendChild(header);
                }
            }
            const linkWrapper = document.createElement('div');
            linkWrapper.className = 'ulm-link-wrapper';
            linkWrapper.draggable = currentSortMode === 'manual';
            linkWrapper.dataset.index = originalIndex;
            if (currentSortMode === 'manual') {
                linkWrapper.innerHTML = '<span class="ulm-drag-handle">⋮⋮</span>';
            }
            const link = document.createElement('a');
            link.href = linkData.url;
            link.target = settings.openInNewTab ? '_blank' : '_self';
            link.className = 'ulm-link';
            const linkContent = document.createElement('div');
            linkContent.className = 'ulm-link-content';
            const healthDot = document.createElement('div');
            healthDot.className = `ulm-health-dot ${linkData.health.status || 'unknown'}`;
            linkContent.appendChild(healthDot);
            if (settings.showFavicons) {
                const favicon = document.createElement('img');
                favicon.className = 'ulm-favicon';
                favicon.src = getFaviconUrl(linkData.url);
                favicon.onerror = () => { favicon.style.display = 'none'; };
                linkContent.appendChild(favicon);
            }
            const labelSpan = document.createElement('span');
            labelSpan.className = 'ulm-link-label';
            if (searchQuery) {
                labelSpan.innerHTML = highlightText(linkData.label, searchQuery);
            } else {
                labelSpan.textContent = linkData.label;
            }
            linkContent.appendChild(labelSpan);
            if (linkData.tags && linkData.tags.length > 0) {
                const tagsToDisplay = linkData.tags.slice(0, 2);
                tagsToDisplay.forEach(tag => {
                    const tagEl = document.createElement('span');
                    tagEl.className = 'ulm-tag';
                    tagEl.textContent = tag;
                    linkContent.appendChild(tagEl);
                });
                if (linkData.tags.length > 2) {
                    const moreTag = document.createElement('span');
                    moreTag.className = 'ulm-tag';
                    moreTag.textContent = `+${linkData.tags.length - 2}`;
                    linkContent.appendChild(moreTag);
                }
            }
            link.appendChild(linkContent);
            const metaSpan = document.createElement('span');
            metaSpan.className = 'ulm-link-meta';
            if (linkData.shortcut) {
                metaSpan.innerHTML += `<span class="ulm-shortcut-badge">${linkData.shortcut}</span>`;
            }
            if (settings.showClickCount && clickStats[linkData.url]) {
                metaSpan.innerHTML += `<span class="ulm-click-count">(${clickStats[linkData.url]})</span>`;
            }
            if (currentSortMode === 'recent' && linkData.addedAt) {
                metaSpan.innerHTML += `<span class="ulm-time-badge">${timeAgo(linkData.addedAt)}</span>`;
            }
            if (currentCategory === 'all' && linkData.category && linkData.category !== 'default') {
                const cat = categories.find(c => c.name === linkData.category);
                const catBadge = document.createElement('span');
                catBadge.className = 'ulm-category-badge';
                catBadge.textContent = linkData.category;
                if(cat) catBadge.style.color = cat.color;
                metaSpan.appendChild(catBadge);
            }
            link.appendChild(metaSpan);
            link.addEventListener('click', (e) => {
                if (!isDeleteMode) incrementClickStat(linkData.url);
            });
            linkWrapper.appendChild(link);
            if (isDeleteMode) {
                const editButton = document.createElement('button');
                editButton.className = 'ulm-action-btn ulm-edit-btn';
                editButton.innerHTML = '✎';
                editButton.onclick = (e) => { e.preventDefault(); e.stopPropagation(); showEditLinkModal(originalIndex); };
                linkWrapper.appendChild(editButton);
                const deleteButton = document.createElement('button');
                deleteButton.className = 'ulm-action-btn ulm-delete-btn';
                deleteButton.innerHTML = '×';
                deleteButton.onclick = async (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    const currentSettings = await getSettings();
                    if (!currentSettings.confirmDelete || confirm(`Delete "${linkData.label}"?`)) {
                        const allLinksMutable = await getLinks();
                        allLinksMutable.splice(originalIndex, 1);
                        await saveLinks(allLinksMutable);
                        await refreshUI();
                    }
                };
                linkWrapper.appendChild(deleteButton);
            }
            if (currentSortMode === 'manual') {
                linkWrapper.addEventListener('dragstart', () => { draggedItem = linkWrapper; linkWrapper.classList.add('dragging'); });
                linkWrapper.addEventListener('dragend', () => {
                    linkWrapper.classList.remove('dragging');
                    shadowRoot.querySelectorAll('.ulm-link-wrapper.drag-over').forEach(item => item.classList.remove('drag-over'));
                });
                linkWrapper.addEventListener('dragover', (e) => { e.preventDefault(); if (draggedItem !== linkWrapper) linkWrapper.classList.add('drag-over'); });
                linkWrapper.addEventListener('dragleave', () => linkWrapper.classList.remove('drag-over'));
                linkWrapper.addEventListener('drop', async (e) => {
                    e.preventDefault();
                    linkWrapper.classList.remove('drag-over');
                    if (draggedItem && draggedItem !== linkWrapper) {
                        const fromIndex = parseInt(draggedItem.dataset.index);
                        const toIndex = parseInt(linkWrapper.dataset.index);
                        const allLinksMutable = await getLinks();
                        const [movedItem] = allLinksMutable.splice(fromIndex, 1);
                        allLinksMutable.splice(toIndex, 0, movedItem);
                        await saveLinks(allLinksMutable);
                        await refreshUI();
                    }
                });
            }
            linkListElement.appendChild(linkWrapper);
        });
    }

    // --- Edit Link Modal ---
    async function showEditLinkModal(index) {
        const links = await getLinks();
        const categories = await getCategories();
        const linkData = links[index];
        const modal = document.createElement('div');
        modal.className = 'ulm-modal-overlay';
        modal.innerHTML = `
            <div class="ulm-modal-content">
                <h3>Edit Link</h3>
                <div class="ulm-form-group"><label>Label</label><input type="text" class="ulm-edit-label" value="${linkData.label}"></div>
                <div class="ulm-form-group"><label>URL</label><input type="text" class="ulm-edit-url" value="${linkData.url}"></div>
                <div class="ulm-form-group"><label>Category</label><select class="ulm-edit-category"></select></div>
                <div class="ulm-form-group"><label>Tags (comma separated)</label><input type="text" class="ulm-edit-tags" value="${(linkData.tags || []).join(', ')}"></div>
                <div class="ulm-form-group"><label>Folder</label><input type="text" class="ulm-edit-folder" value="${linkData.folder || ''}"></div>
                <div class="ulm-btn-group" style="margin-top: 15px;"><button class="ulm-btn ulm-btn-primary ulm-save-edit">Save</button><button class="ulm-btn ulm-cancel-edit">Cancel</button></div>
            </div>
        `;
        shadowRoot.appendChild(modal);
        const select = modal.querySelector('.ulm-edit-category');
        categories.forEach(cat => {
            const option = document.createElement('option');
            option.value = cat.name;
            option.textContent = cat.name.charAt(0).toUpperCase() + cat.name.slice(1);
            option.selected = (cat.name === linkData.category);
            select.appendChild(option);
        });
        modal.querySelector('.ulm-save-edit').onclick = async () => {
            const newLabel = modal.querySelector('.ulm-edit-label').value.trim();
            const newUrl = modal.querySelector('.ulm-edit-url').value.trim();
            if (newLabel && newUrl) {
                links[index].label = newLabel;
                links[index].url = newUrl;
                links[index].category = modal.querySelector('.ulm-edit-category').value;
                links[index].tags = modal.querySelector('.ulm-edit-tags').value.split(',').map(t => t.trim()).filter(Boolean);
                links[index].folder = modal.querySelector('.ulm-edit-folder').value.trim();
                await saveLinks(links);
                modal.remove();
                await refreshUI();
            }
        };
        modal.querySelector('.ulm-cancel-edit').onclick = () => modal.remove();
        modal.onclick = (e) => { if (e.target === modal) modal.remove(); };
    }

    // --- Populate Exclude List ---
    function populateExcludeList(domains, excludeListElement) {
        excludeListElement.innerHTML = '';
        if (domains.length === 0) {
            excludeListElement.innerHTML = '<div class="ulm-empty-state" style="padding:15px;"><div class="ulm-empty-state-icon" style="font-size:24px;">🌐</div><div class="ulm-empty-state-subtitle">No excluded domains</div></div>';
            return;
        }
        domains.forEach((domain, index) => {
            const domainWrapper = document.createElement('div');
            domainWrapper.className = 'ulm-exclude-wrapper';
            domainWrapper.innerHTML = `<span>${domain}</span>`;
            if (isExcludeDeleteMode) {
                const deleteButton = document.createElement('button');
                deleteButton.className = 'ulm-action-btn ulm-delete-btn';
                deleteButton.textContent = '×';
                deleteButton.onclick = async () => {
                    domains.splice(index, 1);
                    await saveExcludedDomains(domains);
                    populateExcludeList(domains, excludeListElement);
                };
                domainWrapper.appendChild(deleteButton);
            }
            excludeListElement.appendChild(domainWrapper);
        });
    }

    // --- Render a Generic Manager ---
    function renderManager(type, items, container) {
        container.innerHTML = '';
        items.forEach((item, index) => {
            const isCategory = type === 'category';
            const name = isCategory ? item.name : item;
            const itemEl = document.createElement('div');
            itemEl.className = 'ulm-manager-item';
            let colorInput = '';
            if (isCategory) {
                colorInput = `<input type="color" class="item-color" value="${item.color}" title="Change color">`;
            }
            itemEl.innerHTML = `
                ${colorInput}
                <input type="text" class="item-name" value="${name}" readonly>
                <div class="item-actions">
                    <button class="item-btn rename" title="Rename">✎</button>
                    <button class="item-btn delete" title="Delete">×</button>
                </div>
            `;
            container.appendChild(itemEl);
            if (isCategory) {
                itemEl.querySelector('.item-color').onchange = (e) => handleCategoryColorChange(index, e.target.value);
            }
            const nameInput = itemEl.querySelector('.item-name');
            const renameAction = () => {
                nameInput.readOnly = false;
                nameInput.classList.add('editing');
                nameInput.focus();
                nameInput.select();
            };
            itemEl.querySelector('.rename').onclick = renameAction;
            const saveRename = async () => {
                if (!nameInput.readOnly) {
                    const newName = nameInput.value.trim();
                    nameInput.readOnly = true;
                    nameInput.classList.remove('editing');
                    if (isCategory) {
                        await handleRenameCategory(index, newName);
                    } else {
                        await handleRenameFolder(name, newName);
                    }
                }
            };
            nameInput.onblur = saveRename;
            nameInput.onkeydown = (e) => {
                if (e.key === 'Enter') saveRename();
                else if (e.key === 'Escape') {
                    nameInput.value = name;
                    nameInput.readOnly = true;
                    nameInput.classList.remove('editing');
                }
            };
            itemEl.querySelector('.delete').onclick = () => {
                if (isCategory) handleDeleteCategory(index);
                else handleDeleteFolder(name);
            };
        });
    }

    // --- Category Management Handlers ---
    async function handleCategoryColorChange(index, newColor) {
        const categories = await getCategories();
        if(categories[index]) {
            categories[index].color = newColor;
            await saveCategories(categories);
            await refreshUI();
        }
    }
    async function handleRenameCategory(index, newName) {
        if (!newName) { showToast('Category name cannot be empty!', 'error'); await refreshUI(); return; }
        const categories = await getCategories();
        const oldName = categories[index].name;
        if (newName.toLowerCase() === oldName.toLowerCase()) { await refreshUI(); return; }
        if (categories.some((c, i) => i !== index && c.name.toLowerCase() === newName.toLowerCase())) {
            showToast('A category with this name already exists!', 'error');
            await refreshUI();
            return;
        }
        categories[index].name = newName.toLowerCase();
        await saveCategories(categories);
        const links = await getLinks();
        links.forEach(link => { if (link.category === oldName) link.category = newName.toLowerCase(); });
        await saveLinks(links);
        if (currentCategory === oldName) currentCategory = newName.toLowerCase();
        await refreshUI();
    }
    async function handleDeleteCategory(index) {
        const categories = await getCategories();
        const catToDelete = categories[index];
        if (catToDelete.name === 'default') { showToast('Cannot delete the default category!', 'warning'); return; }
        if (confirm(`Delete category "${catToDelete.name}"? Links using it will be moved to "default".`)) {
            categories.splice(index, 1);
            await saveCategories(categories);
            const links = await getLinks();
            links.forEach(link => { if (link.category === catToDelete.name) link.category = 'default'; });
            await saveLinks(links);
            if (currentCategory === catToDelete.name) currentCategory = 'all';
            await refreshUI();
        }
    }

    // --- Folder Management Handlers ---
    async function handleRenameFolder(oldName, newName) {
        if (!newName) { showToast('Folder name cannot be empty!', 'error'); await refreshUI(); return; }
        const folders = await getFolders();
        if (newName.toLowerCase() === oldName.toLowerCase()) { await refreshUI(); return; }
        if (folders.some(f => f.toLowerCase() === newName.toLowerCase())) {
            showToast('A folder with this name already exists!', 'error');
            await refreshUI();
            return;
        }
        const folderIndex = folders.findIndex(f => f === oldName);
        if (folderIndex > -1) {
            folders[folderIndex] = newName;
            await saveFolders(folders);
            const links = await getLinks();
            links.forEach(link => { if (link.folder === oldName) link.folder = newName; });
            await saveLinks(links);
            if (currentFolder === oldName) currentFolder = newName;
            await refreshUI();
        }
    }
    async function handleDeleteFolder(folderName) {
        if (confirm(`Delete folder "${folderName}"? Links will be removed from this folder but not deleted.`)) {
            let folders = await getFolders();
            folders = folders.filter(f => f !== folderName);
            await saveFolders(folders);
            const links = await getLinks();
            links.forEach(link => { if (link.folder === folderName) link.folder = ''; });
            await saveLinks(links);
            if (currentFolder === folderName) currentFolder = '';
            await refreshUI();
        }
    }

    // --- Initialize Category Select ---
    async function initializeCategorySelect(categories) {
        const categorySelect = shadowRoot.querySelector('.ulm-link-category-select');
        if (categorySelect) {
            categorySelect.innerHTML = categories.map(cat => `<option value="${cat.name}">${cat.name.charAt(0).toUpperCase() + cat.name.slice(1)}</option>`).join('');
        }
    }

    // --- Apply Button Position ---
    function applyButtonPosition(position) {
        [bubble, showBubbleButton, bubbleMenu].forEach(el => {
            if (el) {
                el.style.top = el.style.left = el.style.bottom = el.style.right = 'auto';
                el.style[position.vertical] = '30px';
                el.style[position.horizontal] = '30px';
                if (el === bubbleMenu) {
                    el.style[position.vertical] = '100px';
                }
            }
        });
        shadowRoot.querySelectorAll('.ulm-position-grid .ulm-btn').forEach(btn => btn.classList.remove('active'));
        const activeBtn = shadowRoot.querySelector(`#position-${position.vertical}-${position.horizontal}`);
        if (activeBtn) activeBtn.classList.add('active');
    }

    // --- Create Main UI HTML ---
    function createMainUIHTML() {
        return `
            <div class="ulm-layout-header">
                <div class="ulm-header-left">
                    <h2>Universal Links Pro</h2>
                    <span class="ulm-header-info ulm-link-count"></span>
                    <span class="ulm-header-shortcuts"><kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>U</kbd> toggle · <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>A</kbd> quick add</span>
                </div>
                <button class="ulm-close-btn">×</button>
            </div>
            <div class="ulm-layout-body">
                <div class="ulm-sidebar">
                    <div class="ulm-sidebar-header">
                        <span>📁 Folders</span>
                        <button class="ulm-sidebar-toggle" title="Collapse sidebar">◀</button>
                    </div>
                    <div class="ulm-folder-nav"></div>
                </div>
                <button class="ulm-sidebar-expand-btn" title="Show folders">▶</button>
                <div class="ulm-content">
                    <div class="ulm-search-container">
                        <input type="text" class="ulm-search-input" placeholder="Search links, tags, folders..."><button class="ulm-clear-search">✕</button>
                    </div>
                    <div class="ulm-sort-filter-bar">
                        <div class="ulm-category-filter"><label>Filter:</label><select class="ulm-category-dropdown"></select></div>
                        <select class="ulm-sort-dropdown"><option value="manual">Manual Order</option><option value="az">A → Z</option><option value="za">Z → A</option><option value="recent">Newest First</option></select>
                        <button class="ulm-recent-btn">🕐 Recent</button>
                    </div>
                    <div class="ulm-alpha-bar"></div>
                    <div class="ulm-recent-section"><div class="ulm-recent-header"><h3>🕐 Recently Added</h3><span class="ulm-recent-count"></span></div><div class="ulm-recent-list"></div></div>
                    <div class="ulm-link-list" tabindex="0"></div>

                    <div class="ulm-accordion">
                        <button class="ulm-accordion-header" data-section="addLink">
                            <span>➕ Add Link</span>
                            <span class="ulm-accordion-arrow">▼</span>
                        </button>
                        <div class="ulm-accordion-body" data-content="addLink">
                            <div class="ulm-form-row"><div class="ulm-form-group"><label>Label</label><input type="text" class="ulm-link-label-input" placeholder="My Site"></div><div class="ulm-form-group"><label>Category</label><select class="ulm-link-category-select"></select></div></div>
                            <div class="ulm-form-group"><label>URL</label><input type="text" class="ulm-link-url-input" placeholder="https://example.com"></div>
                            <div class="ulm-form-group"><label>Tags (press Enter to add)</label><div class="ulm-tag-input-wrapper ulm-add-tags-wrapper"><input type="text" class="ulm-tag-input" placeholder="Add tag..."></div></div>
                            <div class="ulm-form-group"><label>Folder (optional)</label><input type="text" class="ulm-link-folder-input" placeholder="e.g. Projects/AI" list="ulm-folder-suggestions"><datalist id="ulm-folder-suggestions"></datalist></div>
                            <div class="ulm-btn-group" style="margin-top:8px;"><button class="ulm-btn ulm-btn-primary ulm-save-link-btn">Save Link</button><button class="ulm-btn ulm-delete-links-btn">Edit Mode</button></div>
                            <div class="ulm-form-group" style="margin-top: 10px;"><label>Add New Category</label><div class="ulm-form-row"><input type="text" class="ulm-new-category-input" placeholder="New category name" style="flex: 2;"><button class="ulm-btn ulm-add-category-btn" style="flex: 1;">Add</button></div></div>
                        </div>

                        <button class="ulm-accordion-header" data-section="appearance">
                            <span>🎨 Appearance</span>
                            <span class="ulm-accordion-arrow">▼</span>
                        </button>
                        <div class="ulm-accordion-body" data-content="appearance">
                            <div class="ulm-form-group"><label>Theme</label><div class="ulm-theme-grid"></div></div>
                            <div class="ulm-custom-color-section" style="display: none;"><div class="ulm-form-group"><label>Custom Colors</label><div class="ulm-color-grid"></div></div></div>
                            <div class="ulm-form-group" style="margin-top:10px;"><label>Bubble Icon</label><input type="text" class="ulm-bubble-icon-input" maxlength="2" style="width: 70px; text-align: center; font-size: 24px;"></div>
                            <div class="ulm-form-group"><label>Bubble Size: <span class="ulm-bubble-size-value">60</span>px</label><div class="ulm-range-container"><input type="range" class="ulm-bubble-size-slider" min="40" max="100" value="60"></div></div>
                            <div class="ulm-form-group"><label>Button Position</label><div class="ulm-position-grid"><button id="position-top-left" class="ulm-btn">↖</button><button id="position-top-right" class="ulm-btn">↗</button><button id="position-bottom-left" class="ulm-btn">↙</button><button id="position-bottom-right" class="ulm-btn">↘</button></div></div>
                        </div>

                        <button class="ulm-accordion-header" data-section="settings">
                            <span>⚙️ Settings</span>
                            <span class="ulm-accordion-arrow">▼</span>
                        </button>
                        <div class="ulm-accordion-body" data-content="settings">
                            <div class="ulm-settings-section">
                                <div class="ulm-settings-section-header open" data-group="display"><span>🖥️ Display</span><span class="ulm-ss-arrow">▼</span></div>
                                <div class="ulm-settings-section-body open" data-group-body="display">
                                    <div class="ulm-settings-grid">
                                        <div class="ulm-setting-item"><label>Animations</label><label class="ulm-toggle-switch"><input type="checkbox" class="ulm-toggle-animations"><span class="ulm-toggle-slider"></span></label></div>
                                        <div class="ulm-setting-item"><label>Show Favicons</label><label class="ulm-toggle-switch"><input type="checkbox" class="ulm-toggle-favicons"><span class="ulm-toggle-slider"></span></label></div>
                                        <div class="ulm-setting-item"><label>Show Click Count</label><label class="ulm-toggle-switch"><input type="checkbox" class="ulm-toggle-click-count"><span class="ulm-toggle-slider"></span></label></div>
                                    </div>
                                </div>
                            </div>
                            <div class="ulm-settings-section">
                                <div class="ulm-settings-section-header" data-group="behavior"><span>⚡ Behavior</span><span class="ulm-ss-arrow">▼</span></div>
                                <div class="ulm-settings-section-body" data-group-body="behavior">
                                    <div class="ulm-settings-grid">
                                        <div class="ulm-setting-item"><label>Open in New Tab</label><label class="ulm-toggle-switch"><input type="checkbox" class="ulm-toggle-new-tab"><span class="ulm-toggle-slider"></span></label></div>
                                        <div class="ulm-setting-item"><label>Confirm Delete</label><label class="ulm-toggle-switch"><input type="checkbox" class="ulm-toggle-confirm-delete"><span class="ulm-toggle-slider"></span></label></div>
                                    </div>
                                    <div class="ulm-form-group" style="margin-top: 10px;"><label>Recent Links Count: <span class="ulm-recent-count-value">10</span></label><div class="ulm-range-container"><input type="range" class="ulm-recent-count-slider" min="3" max="25" value="10"></div></div>
                                </div>
                            </div>
                            <div class="ulm-settings-section">
                                <div class="ulm-settings-section-header" data-group="panelDefaults"><span>📋 Panel Defaults</span><span class="ulm-ss-arrow">▼</span></div>
                                <div class="ulm-settings-section-body" data-group-body="panelDefaults">
                                    <p style="font-size:11px; color:inherit; opacity:0.6; margin:0 0 8px 0;">Choose which sections open by default when you launch the panel.</p>
                                    <div class="ulm-defaults-grid">
                                        <label class="ulm-default-section-item"><input type="checkbox" value="addLink" class="ulm-default-section-check"><span>➕ Add Link</span></label>
                                        <label class="ulm-default-section-item"><input type="checkbox" value="appearance" class="ulm-default-section-check"><span>🎨 Appearance</span></label>
                                        <label class="ulm-default-section-item"><input type="checkbox" value="settings" class="ulm-default-section-check"><span>⚙️ Settings</span></label>
                                        <label class="ulm-default-section-item"><input type="checkbox" value="backup" class="ulm-default-section-check"><span>💾 Backup & Tools</span></label>
                                    </div>
                                </div>
                            </div>
                            <div class="ulm-settings-section">
                                <div class="ulm-settings-section-header" data-group="categories"><span>🏷️ Categories</span><span class="ulm-ss-arrow">▼</span></div>
                                <div class="ulm-settings-section-body" data-group-body="categories">
                                    <div class="ulm-category-manager ulm-manager-list"></div>
                                </div>
                            </div>
                            <div class="ulm-settings-section">
                                <div class="ulm-settings-section-header" data-group="excludes"><span>🚫 Excluded Domains</span><span class="ulm-ss-arrow">▼</span></div>
                                <div class="ulm-settings-section-body" data-group-body="excludes">
                                    <div class="ulm-exclude-list"></div>
                                    <div class="ulm-form-row" style="margin-top: 5px;"><input type="text" class="ulm-exclude-url-input" placeholder="example.com" style="flex: 2;"><button class="ulm-btn ulm-save-exclude-btn" style="flex: 1;">Add</button></div>
                                    <button class="ulm-btn ulm-delete-exclude-btn" style="margin-top: 5px; width: 100%;">Manage Excludes</button>
                                </div>
                            </div>
                            <div class="ulm-settings-section">
                                <div class="ulm-settings-section-header" data-group="danger"><span>⚠️ Danger Zone</span><span class="ulm-ss-arrow">▼</span></div>
                                <div class="ulm-settings-section-body" data-group-body="danger">
                                    <div class="ulm-btn-group"><button class="ulm-btn ulm-hide-btn">Hide Bubble</button><button class="ulm-btn ulm-btn-danger ulm-reset-btn">Reset All</button></div>
                                </div>
                            </div>
                        </div>

                        <button class="ulm-accordion-header" data-section="backup">
                            <span>💾 Backup & Tools</span>
                            <span class="ulm-accordion-arrow">▼</span>
                        </button>
                        <div class="ulm-accordion-body" data-content="backup">
                            <div class="ulm-form-group"><label>Export/Import</label><p style="font-size: 12px; color: #888; margin: 5px 0;">Includes links, settings, themes, and categories.</p><div class="ulm-btn-group"><button class="ulm-btn ulm-export-all-btn">Export All</button><button class="ulm-btn ulm-copy-export-btn" style="display: none;">Copy</button></div><textarea class="ulm-export-area ulm-backup-area" style="display: none; margin-top: 10px;" readonly></textarea></div>
                            <div class="ulm-form-group" style="margin-top: 15px;"><textarea class="ulm-import-area ulm-backup-area" placeholder="Paste your backup data here..."></textarea><div class="ulm-btn-group" style="margin-top: 5px;"><button class="ulm-btn ulm-import-links-btn">Import Links Only</button><button class="ulm-btn ulm-btn-primary ulm-import-all-btn">Import All</button></div></div>
                            <div class="ulm-form-group" style="margin-top: 15px;"><label>Quick Actions</label><div class="ulm-btn-group"><button class="ulm-btn ulm-export-links-only-btn">Export Links Only</button><button class="ulm-btn ulm-clear-stats-btn">Clear Click Stats</button></div><button class="ulm-btn ulm-health-check-btn" style="margin-top: 8px; width: 100%;">🏥 Check All Links Health</button></div>
                            <div class="ulm-form-group" style="margin-top: 15px;"><label>Folder Management</label><div class="ulm-folder-manager ulm-manager-list"></div><div class="ulm-form-row" style="margin-top: 5px;"><input type="text" class="ulm-new-folder-input" placeholder="New folder name" style="flex: 2;"><button class="ulm-btn ulm-add-folder-btn" style="flex: 1;">Add Folder</button></div></div>
                        </div>
                    </div>
                </div>
            </div>`;
    }

    // --- Build Sidebar Folder Navigation ---
    async function buildFolderSidebar(links) {
        const folderNav = shadowRoot.querySelector('.ulm-folder-nav');
        if (!folderNav) return;
        folderNav.innerHTML = '';

        // "All Links" item
        const allItem = document.createElement('button');
        allItem.className = 'ulm-folder-nav-item' + (!currentFolder ? ' active' : '');
        allItem.innerHTML = `<span class="folder-icon">📁</span><span class="folder-name">All Links</span><span class="folder-count">${links.length}</span>`;
        allItem.onclick = async () => { currentFolder = ''; await refreshUI(); };
        folderNav.appendChild(allItem);

        // Uncategorized count
        const uncategorizedCount = links.filter(l => !l.folder).length;
        if (uncategorizedCount > 0 && uncategorizedCount < links.length) {
            const uncatItem = document.createElement('button');
            uncatItem.className = 'ulm-folder-nav-item' + (currentFolder === '__uncategorized__' ? ' active' : '');
            uncatItem.innerHTML = `<span class="folder-icon">📄</span><span class="folder-name">Unfiled</span><span class="folder-count">${uncategorizedCount}</span>`;
            uncatItem.onclick = async () => { currentFolder = (currentFolder === '__uncategorized__') ? '' : '__uncategorized__'; await refreshUI(); };
            folderNav.appendChild(uncatItem);
        }

        // Divider
        const folderCounts = links.reduce((acc, link) => {
            if (link.folder) acc[link.folder] = (acc[link.folder] || 0) + 1;
            return acc;
        }, {});

        const savedFolders = await getFolders();
        const allFolderNames = new Set([...savedFolders, ...Object.keys(folderCounts)]);

        if (allFolderNames.size > 0) {
            const divider = document.createElement('div');
            divider.className = 'ulm-sidebar-divider';
            folderNav.appendChild(divider);
        }

        // Folder items
        [...allFolderNames].sort((a, b) => a.localeCompare(b)).forEach(folderName => {
            const count = folderCounts[folderName] || 0;
            const item = document.createElement('button');
            item.className = 'ulm-folder-nav-item' + (currentFolder === folderName ? ' active' : '') + (isDeleteMode ? ' edit-mode' : '');
            item.innerHTML = `
                <span class="folder-icon">📂</span>
                <span class="folder-name">${folderName}</span>
                <span class="folder-count">${count}</span>
                <button class="folder-delete-btn" title="Delete folder">×</button>
            `;
            item.onclick = async (e) => {
                if (e.target.classList.contains('folder-delete-btn')) return;
                currentFolder = (currentFolder === folderName) ? '' : folderName;
                await refreshUI();
            };
            const deleteBtn = item.querySelector('.folder-delete-btn');
            deleteBtn.onclick = async (e) => {
                e.stopPropagation();
                if (confirm(`Delete folder "${folderName}"? Links will be removed from this folder but not deleted.`)) {
                    let folders = await getFolders();
                    folders = folders.filter(f => f !== folderName);
                    await saveFolders(folders);
                    const allLinks = await getLinks();
                    allLinks.forEach(link => { if (link.folder === folderName) link.folder = ''; });
                    await saveLinks(allLinks);
                    if (currentFolder === folderName) currentFolder = '';
                    await refreshUI();
                }
            };
            folderNav.appendChild(item);
        });
    }

    // --- Open UI ---
    async function openUI() {
        // Apply default open sections on fresh open
        const settings = await getSettings();
        const defaults = settings.defaultOpenSections || [];

        // Reset all accordion states
        shadowRoot.querySelectorAll('.ulm-accordion-header').forEach(h => h.classList.remove('active'));
        shadowRoot.querySelectorAll('.ulm-accordion-body').forEach(b => b.classList.remove('open'));

        // Open the defaults
        defaults.forEach(section => {
            const header = shadowRoot.querySelector(`.ulm-accordion-header[data-section="${section}"]`);
            const body = shadowRoot.querySelector(`.ulm-accordion-body[data-content="${section}"]`);
            if (header && body) {
                header.classList.add('active');
                body.classList.add('open');
            }
        });
        openAccordion = defaults.length > 0 ? defaults[0] : '';

        await refreshUI();
        mainUI.classList.add('visible');
    }

    // --- Refresh UI ---
    async function refreshUI() {
        const links = await getLinks();
        const categories = await getCategories();
        const settings = await getSettings();
        const currentTheme = await getTheme();
        const customColors = await getCustomColors();
        const excluded = await getExcludedDomains();
        const clickStats = await getClickStats();
        const folders = await getFolders();

        // Update link count
        const linkCountEl = shadowRoot.querySelector('.ulm-link-count');
        if (linkCountEl) linkCountEl.textContent = `${links.length} links saved`;

        // Handle __uncategorized__ filter
        let effectiveLinks = links;
        let realCurrentFolder = currentFolder;
        if (currentFolder === '__uncategorized__') {
            realCurrentFolder = '';
            // We'll handle this in populateLinkList by filtering unfiled
        }

        // Populate UI components
        await initializeCategorySelect(categories);
        await populateCategoryDropdown(links, categories);
        await buildAlphaBar(links);
        await buildFolderSidebar(links);
        await populateRecentSection(links, settings, categories);

        // Special handling for uncategorized folder filter
        if (currentFolder === '__uncategorized__') {
            const origCurrentFolder = currentFolder;
            currentFolder = '';
            const unfiledLinks = links.filter(l => !l.folder);
            await populateLinkListCustom(unfiledLinks, links, settings, categories, clickStats);
            currentFolder = origCurrentFolder;
        } else {
            await populateLinkList(links, settings, categories, clickStats);
        }

        renderManager('category', categories, shadowRoot.querySelector('.ulm-category-manager'));
        renderManager('folder', folders, shadowRoot.querySelector('.ulm-folder-manager'));
        populateExcludeList(excluded, shadowRoot.querySelector('.ulm-exclude-list'));

        // Update settings values
        const sortDropdown = shadowRoot.querySelector('.ulm-sort-dropdown');
        if (sortDropdown) sortDropdown.value = currentSortMode;
        shadowRoot.querySelector('.ulm-bubble-icon-input').value = settings.bubbleIcon;
        shadowRoot.querySelector('.ulm-bubble-size-slider').value = settings.bubbleSize;
        shadowRoot.querySelector('.ulm-bubble-size-value').textContent = settings.bubbleSize;
        shadowRoot.querySelector('.ulm-recent-count-slider').value = settings.recentCount;
        shadowRoot.querySelector('.ulm-recent-count-value').textContent = settings.recentCount;

        // Toggles
        shadowRoot.querySelector('.ulm-toggle-animations').checked = settings.animationsEnabled;
        shadowRoot.querySelector('.ulm-toggle-new-tab').checked = settings.openInNewTab;
        shadowRoot.querySelector('.ulm-toggle-click-count').checked = settings.showClickCount;
        shadowRoot.querySelector('.ulm-toggle-confirm-delete').checked = settings.confirmDelete;
        shadowRoot.querySelector('.ulm-toggle-favicons').checked = settings.showFavicons;

        // Default open sections checkboxes
        const defaultChecks = shadowRoot.querySelectorAll('.ulm-default-section-check');
        defaultChecks.forEach(check => {
            check.checked = (settings.defaultOpenSections || []).includes(check.value);
        });

        // Sidebar collapsed state
        const sidebar = shadowRoot.querySelector('.ulm-sidebar');
        const expandBtn = shadowRoot.querySelector('.ulm-sidebar-expand-btn');
        if (sidebar) sidebar.classList.toggle('collapsed', settings.sidebarCollapsed);
        if (expandBtn) expandBtn.classList.toggle('visible', settings.sidebarCollapsed);

        // Populate folder datalist
        const folderDatalist = shadowRoot.querySelector('#ulm-folder-suggestions');
        if(folderDatalist) folderDatalist.innerHTML = folders.map(f => `<option value="${f}"></option>`).join('');

        // Populate theme grid
        const themeGrid = shadowRoot.querySelector('.ulm-theme-grid');
        if (themeGrid) {
            themeGrid.innerHTML = Object.entries(themes).map(([key, theme]) => {
                const colors = key === 'custom' ? customColors : theme.colors;
                return `<div class="ulm-theme-option ${currentTheme === key ? 'active' : ''}" data-theme="${key}">
                    <div class="ulm-theme-preview" style="background: linear-gradient(135deg, ${colors.bubbleBackground} 0%, ${colors.menuBackground} 100%); border: 1px solid ${colors.menuBorder};"></div>
                    <span>${theme.name}</span>
                </div>`;
            }).join('');
        }

        // Custom colors
        const colorGrid = shadowRoot.querySelector('.ulm-color-grid');
        if (colorGrid) {
            colorGrid.innerHTML = Object.entries(customColors).map(([key, value]) => `
                <div class="ulm-color-item">
                    <label>${key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}</label>
                    <input type="color" data-color-key="${key}" value="${value}">
                </div>`).join('');
        }
        shadowRoot.querySelector('.ulm-custom-color-section').style.display = currentTheme === 'custom' ? 'block' : 'none';
    }

    // Special version for unfiled links display
    async function populateLinkListCustom(filteredSourceLinks, allLinks, settings, categories, clickStats) {
        const linkListElement = shadowRoot.querySelector('.ulm-link-list');
        linkListElement.innerHTML = '';
        let filteredLinks = filteredSourceLinks;

        if (currentCategory !== 'all') {
            filteredLinks = filteredLinks.filter(link => link.category === currentCategory);
        }
        if (searchQuery) {
            const searchWords = searchQuery.toLowerCase().split(' ').filter(w => w);
            filteredLinks = filteredLinks.filter(link => {
                const searchableText = [link.label, link.url, ...(link.tags || []), link.folder || ''].join(' ').toLowerCase();
                return searchWords.every(word => searchableText.includes(word));
            });
        }
        if (activeLetter) {
            filteredLinks = filteredLinks.filter(link => {
                const firstChar = link.label.charAt(0).toUpperCase();
                return activeLetter === '#' ? !/[A-Z]/.test(firstChar) : firstChar === activeLetter;
            });
        }
        filteredLinks = sortLinks(filteredLinks, currentSortMode);

        if (filteredLinks.length === 0) {
            linkListElement.innerHTML = '<div class="ulm-empty-state"><div class="ulm-empty-state-icon">📂</div><div class="ulm-empty-state-title">No unfiled links</div><div class="ulm-empty-state-subtitle">All your links are in folders</div></div>';
            return;
        }

        // Reuse the same rendering logic but with the filtered source
        const showGroups = (currentSortMode === 'az' || currentSortMode === 'za') && !activeLetter && !searchQuery;
        let lastLetter = null;
        filteredLinks.forEach((linkData) => {
            const originalIndex = allLinks.indexOf(linkData);
            if (showGroups) {
                const firstChar = linkData.label.charAt(0).toUpperCase();
                const groupLetter = /[A-Z]/.test(firstChar) ? firstChar : '#';
                if (groupLetter !== lastLetter) {
                    lastLetter = groupLetter;
                    const groupCount = filteredLinks.filter(l => (l.label.charAt(0).toUpperCase() === groupLetter) || (groupLetter === '#' && !/[A-Z]/.test(l.label.charAt(0).toUpperCase()))).length;
                    const header = document.createElement('div');
                    header.className = 'ulm-letter-group-header';
                    header.innerHTML = `<span class="ulm-letter-group-char">${groupLetter}</span><div class="ulm-letter-group-line"></div><span class="ulm-letter-group-count">${groupCount}</span>`;
                    linkListElement.appendChild(header);
                }
            }
            const linkWrapper = document.createElement('div');
            linkWrapper.className = 'ulm-link-wrapper';
            linkWrapper.dataset.index = originalIndex;
            const link = document.createElement('a');
            link.href = linkData.url;
            link.target = settings.openInNewTab ? '_blank' : '_self';
            link.className = 'ulm-link';
            const linkContent = document.createElement('div');
            linkContent.className = 'ulm-link-content';
            const healthDot = document.createElement('div');
            healthDot.className = `ulm-health-dot ${linkData.health.status || 'unknown'}`;
            linkContent.appendChild(healthDot);
            if (settings.showFavicons) {
                const favicon = document.createElement('img');
                favicon.className = 'ulm-favicon';
                favicon.src = getFaviconUrl(linkData.url);
                favicon.onerror = () => { favicon.style.display = 'none'; };
                linkContent.appendChild(favicon);
            }
            const labelSpan = document.createElement('span');
            labelSpan.className = 'ulm-link-label';
            labelSpan.textContent = linkData.label;
            linkContent.appendChild(labelSpan);
            link.appendChild(linkContent);
            const metaSpan = document.createElement('span');
            metaSpan.className = 'ulm-link-meta';
            link.appendChild(metaSpan);
            link.addEventListener('click', () => { if (!isDeleteMode) incrementClickStat(linkData.url); });
            linkWrapper.appendChild(link);
            linkListElement.appendChild(linkWrapper);
        });
    }

    // --- Setup Event Listeners ---
    function setupEventListeners() {
        // Keyboard shortcut to toggle UI
        document.addEventListener('keydown', (event) => {
            if (event.ctrlKey && event.altKey && (event.key === 'u' || event.key === 'U')) {
                event.preventDefault();
                const isVisible = mainUI.classList.contains('visible');
                if (isVisible) mainUI.classList.remove('visible');
                else openUI();
            }
            if (event.ctrlKey && event.altKey && (event.key === 'a' || event.key === 'A')) {
                event.preventDefault();
                instantAddCurrentPage();
            }
        });

        // Bubble interactions
        bubble.addEventListener('click', (e) => {
            e.stopPropagation();
            bubbleMenu.classList.toggle('visible');
        });
        let bubbleClickCount = 0, bubbleClickTimer = null;
        bubble.addEventListener('click', () => {
            bubbleClickCount++;
            if (bubbleClickTimer) clearTimeout(bubbleClickTimer);
            bubbleClickTimer = setTimeout(() => bubbleClickCount = 0, 300);
            if (bubbleClickCount === 3) {
                clearTimeout(bubbleClickTimer);
                bubble.classList.add('hidden');
                showBubbleButton.classList.add('visible');
                mainUI.classList.remove('visible');
                bubbleMenu.classList.remove('visible');
                saveBubbleHiddenState(true);
                bubbleClickCount = 0;
            }
        });
        showBubbleButton.addEventListener('click', () => {
            bubble.classList.remove('hidden');
            showBubbleButton.classList.remove('visible');
            saveBubbleHiddenState(false);
        });

        shadowRoot.querySelector('.ulm-instant-add-btn').onclick = async () => {
            await instantAddCurrentPage();
        };
        shadowRoot.querySelector('.ulm-show-menu-btn').onclick = () => {
            bubbleMenu.classList.remove('visible');
            openUI();
        };
        shadowRoot.querySelector('.ulm-close-btn').onclick = () => mainUI.classList.remove('visible');

        // Sidebar toggle
        shadowRoot.querySelector('.ulm-sidebar-toggle').onclick = async () => {
            const settings = await getSettings();
            settings.sidebarCollapsed = true;
            await saveSettings(settings);
            await refreshUI();
        };
        shadowRoot.querySelector('.ulm-sidebar-expand-btn').onclick = async () => {
            const settings = await getSettings();
            settings.sidebarCollapsed = false;
            await saveSettings(settings);
            await refreshUI();
        };

        // Link List Keyboard Navigation
        const linkList = shadowRoot.querySelector('.ulm-link-list');
        linkList.addEventListener('keydown', (e) => {
            if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Enter') return;
            e.preventDefault();
            const items = Array.from(linkList.querySelectorAll('.ulm-link-wrapper'));
            if (items.length === 0) return;
            let currentIndex = items.findIndex(item => item.classList.contains('selected'));
            if (e.key === 'Enter' && currentIndex > -1) {
                items[currentIndex].querySelector('.ulm-link')?.click();
                return;
            }
            if(currentIndex > -1) items[currentIndex].classList.remove('selected');
            if (e.key === 'ArrowDown') currentIndex = (currentIndex + 1) % items.length;
            else if (e.key === 'ArrowUp') currentIndex = (currentIndex - 1 + items.length) % items.length;
            items[currentIndex].classList.add('selected');
            items[currentIndex].scrollIntoView({ block: 'nearest' });
        });

        // Filtering and sorting
        const searchInput = shadowRoot.querySelector('.ulm-search-input');
        searchInput.oninput = async () => { searchQuery = searchInput.value; await refreshUI(); };
        shadowRoot.querySelector('.ulm-clear-search').onclick = async () => { searchInput.value = ''; searchQuery = ''; await refreshUI(); };
        shadowRoot.querySelector('.ulm-category-dropdown').onchange = async (e) => { currentCategory = e.target.value; activeLetter = null; await refreshUI(); };
        shadowRoot.querySelector('.ulm-sort-dropdown').onchange = async (e) => {
            currentSortMode = e.target.value;
            activeLetter = null;
            const settings = await getSettings();
            settings.sortMode = currentSortMode;
            await saveSettings(settings);
            await refreshUI();
        };
        shadowRoot.querySelector('.ulm-recent-btn').onclick = async () => {
            showRecentlyAdded = !showRecentlyAdded;
            shadowRoot.querySelector('.ulm-recent-btn').classList.toggle('active', showRecentlyAdded);
            await refreshUI();
        };

        // Accordion Sections
        shadowRoot.querySelectorAll('.ulm-accordion-header').forEach(header => {
            header.addEventListener('click', () => {
                const section = header.dataset.section;
                const body = shadowRoot.querySelector(`.ulm-accordion-body[data-content="${section}"]`);
                const isOpen = header.classList.contains('active');
                // Close all
                shadowRoot.querySelectorAll('.ulm-accordion-header').forEach(h => h.classList.remove('active'));
                shadowRoot.querySelectorAll('.ulm-accordion-body').forEach(b => b.classList.remove('open'));
                // Toggle
                if (!isOpen) {
                    header.classList.add('active');
                    body.classList.add('open');
                    openAccordion = section;
                } else {
                    openAccordion = '';
                }
            });
        });

        // Settings collapsible sections
        shadowRoot.querySelectorAll('.ulm-settings-section-header').forEach(header => {
            header.addEventListener('click', () => {
                const group = header.dataset.group;
                const body = shadowRoot.querySelector(`.ulm-settings-section-body[data-group-body="${group}"]`);
                const isOpen = header.classList.contains('open');
                header.classList.toggle('open', !isOpen);
                body.classList.toggle('open', !isOpen);
            });
        });

        // Default open sections checkboxes
        shadowRoot.querySelector('.ulm-defaults-grid').addEventListener('change', async (e) => {
            if (!e.target.classList.contains('ulm-default-section-check')) return;
            const settings = await getSettings();
            const checks = shadowRoot.querySelectorAll('.ulm-default-section-check');
            settings.defaultOpenSections = Array.from(checks).filter(c => c.checked).map(c => c.value);
            await saveSettings(settings);
        });

        // Add Link Form
        const addTagsWrapper = shadowRoot.querySelector('.ulm-add-tags-wrapper');
        const tagInput = addTagsWrapper.querySelector('.ulm-tag-input');
        let addLinkTags = [];
        tagInput.onkeydown = (e) => {
            if (e.key === 'Enter' || e.key === ',') {
                e.preventDefault();
                const tag = tagInput.value.trim().replace(',', '');
                if (tag && !addLinkTags.includes(tag)) {
                    addLinkTags.push(tag);
                    const tagEl = document.createElement('span');
                    tagEl.className = 'ulm-tag';
                    tagEl.textContent = tag;
                    tagEl.onclick = () => { addLinkTags = addLinkTags.filter(t => t !== tag); tagEl.remove(); };
                    addTagsWrapper.insertBefore(tagEl, tagInput);
                }
                tagInput.value = '';
            }
        };

        const urlInput = shadowRoot.querySelector('.ulm-link-url-input');
        urlInput.onblur = async () => {
            const catSelect = shadowRoot.querySelector('.ulm-link-category-select');
            if (urlInput.value.trim() && catSelect.value === 'default') {
                const suggested = await suggestCategory(urlInput.value.trim());
                if (suggested !== 'default') catSelect.value = suggested;
            }
        };

        shadowRoot.querySelector('.ulm-save-link-btn').onclick = async () => {
            const label = shadowRoot.querySelector('.ulm-link-label-input').value.trim();
            const url = shadowRoot.querySelector('.ulm-link-url-input').value.trim();
            if (!label || !url) { showToast('Label and URL are required.', 'error'); return; }
            if (await checkDuplicate(url)) {
                if (!confirm('This URL already exists. Add anyway?')) return;
            }
            const links = await getLinks();
            const folderValue = shadowRoot.querySelector('.ulm-link-folder-input').value.trim();
            links.push({
                label, url,
                category: shadowRoot.querySelector('.ulm-link-category-select').value,
                folder: folderValue,
                tags: addLinkTags,
                addedAt: Date.now(),
                health: { status: 'unknown', checkedAt: 0 }
            });
            await saveLinks(links);
            // Auto-add folder if new
            if (folderValue) {
                const folders = await getFolders();
                if (!folders.some(f => f.toLowerCase() === folderValue.toLowerCase())) {
                    folders.push(folderValue);
                    await saveFolders(folders);
                }
            }
            shadowRoot.querySelector('.ulm-link-label-input').value = '';
            shadowRoot.querySelector('.ulm-link-url-input').value = '';
            shadowRoot.querySelector('.ulm-link-folder-input').value = '';
            tagInput.value = '';
            addTagsWrapper.querySelectorAll('.ulm-tag').forEach(t => t.remove());
            addLinkTags = [];
            showToast(`"${label}" saved!`);
            await refreshUI();
        };

        shadowRoot.querySelector('.ulm-delete-links-btn').onclick = async () => {
            isDeleteMode = !isDeleteMode;
            mainUI.classList.toggle('edit-mode', isDeleteMode);
            shadowRoot.querySelector('.ulm-delete-links-btn').textContent = isDeleteMode ? 'Exit Edit Mode' : 'Edit Mode';
            await refreshUI();
        };

        shadowRoot.querySelector('.ulm-add-category-btn').onclick = async () => {
            const input = shadowRoot.querySelector('.ulm-new-category-input');
            const newCatName = input.value.trim().toLowerCase();
            if (!newCatName) return;
            const categories = await getCategories();
            if (categories.some(c => c.name === newCatName)) { showToast('Category already exists!', 'warning'); return; }
            categories.push({ name: newCatName, color: generateRandomColor() });
            await saveCategories(categories);
            input.value = '';
            await refreshUI();
        };

        // Appearance Tab
        shadowRoot.querySelector('.ulm-theme-grid').onclick = async (e) => {
            const themeOption = e.target.closest('.ulm-theme-option');
            if (!themeOption) return;
            const themeName = themeOption.dataset.theme;
            await saveTheme(themeName);
            await applyTheme(themeName);
            await refreshUI();
        };
        shadowRoot.querySelector('.ulm-color-grid').oninput = async (e) => {
            if (e.target.type !== 'color') return;
            const colors = await getCustomColors();
            colors[e.target.dataset.colorKey] = e.target.value;
            await saveCustomColors(colors);
            if (await getTheme() === 'custom') await applyTheme('custom');
        };
        shadowRoot.querySelector('.ulm-bubble-icon-input').oninput = async (e) => {
            const settings = await getSettings();
            settings.bubbleIcon = e.target.value || 'λ';
            await saveSettings(settings);
            bubble.textContent = settings.bubbleIcon;
        };
        shadowRoot.querySelector('.ulm-bubble-size-slider').oninput = async (e) => {
            const size = parseInt(e.target.value);
            shadowRoot.querySelector('.ulm-bubble-size-value').textContent = size;
            const settings = await getSettings();
            settings.bubbleSize = size;
            await saveSettings(settings);
            await applyTheme(await getTheme());
        };
        shadowRoot.querySelector('.ulm-position-grid').onclick = async (e) => {
            if(e.target.id.startsWith('position-')) {
                const [, vertical, horizontal] = e.target.id.split('-');
                const newPosition = { vertical, horizontal };
                await saveButtonPosition(newPosition);
                applyButtonPosition(newPosition);
            }
        };

        // Settings Tab
        const settingsToggles = {
            '.ulm-toggle-animations': 'animationsEnabled',
            '.ulm-toggle-new-tab': 'openInNewTab',
            '.ulm-toggle-click-count': 'showClickCount',
            '.ulm-toggle-confirm-delete': 'confirmDelete',
            '.ulm-toggle-favicons': 'showFavicons'
        };
        for (const [selector, key] of Object.entries(settingsToggles)) {
            shadowRoot.querySelector(selector).onchange = async (e) => {
                const settings = await getSettings();
                settings[key] = e.target.checked;
                await saveSettings(settings);
                await refreshUI();
                await applyTheme(await getTheme());
            };
        }
        shadowRoot.querySelector('.ulm-recent-count-slider').oninput = async (e) => {
            const count = parseInt(e.target.value);
            shadowRoot.querySelector('.ulm-recent-count-value').textContent = count;
            const settings = await getSettings();
            settings.recentCount = count;
            await saveSettings(settings);
            if (showRecentlyAdded) await refreshUI();
        };
        shadowRoot.querySelector('.ulm-save-exclude-btn').onclick = async () => {
            const input = shadowRoot.querySelector('.ulm-exclude-url-input');
            const domain = input.value.trim();
            if (!domain) return;
            const excluded = await getExcludedDomains();
            if (excluded.includes(domain)) { showToast('Domain already excluded!', 'warning'); return; }
            excluded.push(domain);
            await saveExcludedDomains(excluded);
            input.value = '';
            populateExcludeList(excluded, shadowRoot.querySelector('.ulm-exclude-list'));
        };
        shadowRoot.querySelector('.ulm-delete-exclude-btn').onclick = async () => {
            isExcludeDeleteMode = !isExcludeDeleteMode;
            shadowRoot.querySelector('.ulm-delete-exclude-btn').textContent = isExcludeDeleteMode ? 'Done' : 'Manage Excludes';
            populateExcludeList(await getExcludedDomains(), shadowRoot.querySelector('.ulm-exclude-list'));
        };
        shadowRoot.querySelector('.ulm-hide-btn').onclick = () => {
            bubble.classList.add('hidden');
            showBubbleButton.classList.add('visible');
            mainUI.classList.remove('visible');
            bubbleMenu.classList.remove('visible');
            saveBubbleHiddenState(true);
        };
        shadowRoot.querySelector('.ulm-reset-btn').onclick = async () => {
            if (confirm('This will reset ALL data. Are you sure?') && confirm('This cannot be undone! Continue?')) {
                for (const key of Object.values(STORAGE_KEYS)) { await setData(key, undefined); }
                location.reload();
            }
        };

        // Backup Tab
        const exportArea = shadowRoot.querySelector('.ulm-export-area');
        const copyBtn = shadowRoot.querySelector('.ulm-copy-export-btn');
        const showExportData = (data) => {
            exportArea.value = JSON.stringify(data, null, 2);
            exportArea.style.display = 'block';
            copyBtn.style.display = 'block';
        };
        shadowRoot.querySelector('.ulm-export-all-btn').onclick = async () => {
            showExportData({
                links: await getLinks(), categories: await getCategories(),
                settings: await getSettings(), customColors: await getCustomColors(),
                theme: await getTheme(), excludedDomains: await getExcludedDomains(),
                clickStats: await getClickStats(), folders: await getFolders()
            });
        };
        shadowRoot.querySelector('.ulm-export-links-only-btn').onclick = async () => showExportData(await getLinks());
        copyBtn.onclick = () => { navigator.clipboard.writeText(exportArea.value).then(() => showToast('Copied to clipboard!'), () => showToast('Copy failed!', 'error')); };
        shadowRoot.querySelector('.ulm-import-all-btn').onclick = async () => {
            const data = shadowRoot.querySelector('.ulm-import-area').value.trim();
            if (!data) return;
            try {
                const parsed = JSON.parse(data);
                if (parsed.links) await saveLinks(parsed.links);
                if (parsed.categories) await saveCategories(parsed.categories);
                if (parsed.settings) await saveSettings(parsed.settings);
                if (parsed.customColors) await saveCustomColors(parsed.customColors);
                if (parsed.theme) await saveTheme(parsed.theme);
                if (parsed.excludedDomains) await saveExcludedDomains(parsed.excludedDomains);
                if (parsed.clickStats) await setData(STORAGE_KEYS.clickStats, parsed.clickStats);
                if (parsed.folders) await saveFolders(parsed.folders);
                showToast('All data imported successfully! Reloading...', 'success');
                setTimeout(() => location.reload(), 1000);
            } catch (e) { showToast('Invalid data format!', 'error'); }
        };
        shadowRoot.querySelector('.ulm-import-links-btn').onclick = async () => {
            const data = shadowRoot.querySelector('.ulm-import-area').value.trim();
            if (!data) return;
            try {
                const parsed = JSON.parse(data);
                const linksToImport = Array.isArray(parsed) ? parsed : parsed.links;
                if (!linksToImport) throw new Error('No links found in data.');
                await saveLinks(linksToImport);
                showToast('Links imported successfully!');
                await refreshUI();
            } catch (e) { showToast('Invalid data format!', 'error'); }
        };
        shadowRoot.querySelector('.ulm-clear-stats-btn').onclick = async () => {
            if (confirm('Clear all click statistics?')) {
                await setData(STORAGE_KEYS.clickStats, {});
                showToast('Click stats cleared!');
                await refreshUI();
            }
        };
        shadowRoot.querySelector('.ulm-health-check-btn').onclick = async () => {
            const links = await getLinks();
            if (links.length === 0) { showToast('No links to check.', 'info'); return; }
            showToast(`Checking ${links.length} links...`, 'info');
            links.forEach(link => link.health.status = 'checking');
            await saveLinks(links);
            await refreshUI();
            const checkPromises = links.map(async (link, index) => {
                const result = await checkLinkHealth(link.url);
                const allLinks = await getLinks();
                allLinks[index].health = {
                    status: result.ok ? 'ok' : 'error',
                    checkedAt: Date.now()
                };
                await saveLinks(allLinks);
            });
            const interval = setInterval(async () => await refreshUI(), 2000);
            await Promise.all(checkPromises);
            clearInterval(interval);
            showToast('Health check complete!');
            await refreshUI();
        };
        shadowRoot.querySelector('.ulm-add-folder-btn').onclick = async () => {
            const input = shadowRoot.querySelector('.ulm-new-folder-input');
            const newFolderName = input.value.trim();
            if (!newFolderName) return;
            const folders = await getFolders();
            if (folders.some(f => f.toLowerCase() === newFolderName.toLowerCase())) { showToast('Folder already exists!', 'warning'); return; }
            folders.push(newFolderName);
            await saveFolders(folders);
            input.value = '';
            await refreshUI();
        };

        // Hide menu on outside click
        document.addEventListener('click', (e) => {
            if (bubbleMenu && !bubble.contains(e.target) && !bubbleMenu.contains(e.target)) {
                bubbleMenu.classList.remove('visible');
            }
        });
    }

    // --- Instant Add Current Page ---
    async function instantAddCurrentPage() {
        const url = window.location.href;
        if (await checkDuplicate(url)) {
            showToast('This page is already in your links!', 'warning');
            return;
        }
        const autoCategory = await suggestCategory(url);
        const links = await getLinks();
        const title = document.title || 'Untitled';
        links.push({ label: title, url, category: autoCategory, addedAt: Date.now(), tags: [], folder: '', health: { status: 'unknown', checkedAt: 0 } });
        await saveLinks(links);
        bubbleMenu.classList.remove('visible');
        showToast(`Added "${title}"!`);
        if (mainUI.classList.contains('visible')) {
            await refreshUI();
        }
    }

    // --- Context Menu for Links ---
    function setupContextMenu() {
        const linkList = shadowRoot.querySelector('.ulm-link-list');
        const contextMenu = document.createElement('div');
        contextMenu.className = 'ulm-context-menu';
        shadowRoot.appendChild(contextMenu);

        linkList.addEventListener('contextmenu', async (e) => {
            const linkWrapper = e.target.closest('.ulm-link-wrapper');
            if (!linkWrapper) return;
            e.preventDefault();
            e.stopPropagation();
            const linkIndex = parseInt(linkWrapper.dataset.index);
            const links = await getLinks();
            const linkData = links[linkIndex];
            contextMenu.innerHTML = `
                <div class="ulm-ctx-item" data-action="newtab">🆕 Open in New Tab</div>
                <div class="ulm-ctx-item" data-action="copy">📋 Copy URL</div>
                <div class="ulm-ctx-item" data-action="edit">✏️ Edit</div>
                <div class="ulm-ctx-item" data-action="health">🩺 Check Health</div>
                <div class="ulm-ctx-item" data-action="delete" style="color:#f44336">🗑️ Delete</div>
            `;
            contextMenu.style.display = 'block';
            contextMenu.style.left = e.clientX + 'px';
            contextMenu.style.top = e.clientY + 'px';
            contextMenu.onclick = async (ev) => {
                const action = ev.target.dataset.action;
                if (!action) return;
                contextMenu.style.display = 'none';
                if (action === 'newtab') window.open(linkData.url, '_blank');
                else if (action === 'copy') navigator.clipboard.writeText(linkData.url).then(() => showToast('URL copied!'));
                else if (action === 'edit') showEditLinkModal(linkIndex);
                else if (action === 'delete') linkWrapper.querySelector('.ulm-delete-btn')?.click();
                else if (action === 'health') {
                    showToast(`Checking "${linkData.label}"...`, 'info');
                    links[linkIndex].health.status = 'checking';
                    await saveLinks(links);
                    await refreshUI();
                    const result = await checkLinkHealth(linkData.url);
                    links[linkIndex].health = { status: result.ok ? 'ok' : 'error', checkedAt: Date.now() };
                    await saveLinks(links);
                    showToast(result.ok ? 'Link is healthy!' : 'Link seems broken.', result.ok ? 'success' : 'error');
                    await refreshUI();
                }
            };
        });
        shadowRoot.addEventListener('click', () => { contextMenu.style.display = 'none'; });
    }

    // --- Initialize Script ---
    async function initializeScript() {
        if (document.getElementById('universal-link-manager-container')) return;
        await new Promise(resolve => { if (document.body) resolve(); else window.addEventListener('DOMContentLoaded', resolve); });

        shadowRoot = createShadowContainer();
        styleElement = document.createElement('style');
        shadowRoot.appendChild(styleElement);

        bubble = document.createElement('div');
        bubble.className = 'ulm-bubble';
        shadowRoot.appendChild(bubble);

        showBubbleButton = document.createElement('div');
        showBubbleButton.className = 'ulm-show-button';
        shadowRoot.appendChild(showBubbleButton);

        bubbleMenu = document.createElement('div');
        bubbleMenu.className = 'ulm-mini-menu';
        bubbleMenu.innerHTML = `<button class="ulm-instant-add-btn">⚡ Add This Site</button><button class="ulm-show-menu-btn">⚙️ Open Menu</button>`;
        shadowRoot.appendChild(bubbleMenu);

        mainUI = document.createElement('div');
        mainUI.className = 'ulm-main-ui';
        mainUI.innerHTML = createMainUIHTML();
        shadowRoot.appendChild(mainUI);

        await applyTheme(await getTheme());
        applyButtonPosition(await getButtonPosition());
        if (await getBubbleHiddenState()) {
            bubble.classList.add('hidden');
            showBubbleButton.classList.add('visible');
        }

        setupEventListeners();
        setupContextMenu();
        await refreshUI();
        console.log('Universal Link Manager Pro v5.0 initialized');
    }

    initializeScript();
})();