Загрузка данных


```html
<!DOCTYPE html>
<html lang="ru" class="h-full bg-black">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>ArtStudio — Профессиональный Графический Редактор</title>
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- FontAwesome Icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <!-- Google Fonts -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Montserrat:wght@400;700;900&family=Playfair+Display:ital,wght@0,600;1,400&family=Roboto+Mono:wght@400;700&family=Pacifico&display=swap" rel="stylesheet">

    <style>
        * {
            -webkit-tap-highlight-color: transparent;
            user-select: none;
            -webkit-user-select: none;
        }
        body {
            font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Inter", sans-serif;
            background-color: #000000;
            color: #f5f5f7;
            overflow: hidden;
        }
        
        ::-webkit-scrollbar {
            width: 4px;
            height: 4px;
        }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 999px; }

        .glass-card {
            background: rgba(24, 24, 27, 0.75);
            backdrop-filter: blur(30px);
            -webkit-backdrop-filter: blur(30px);
            border: 1px solid rgba(255, 255, 255, 0.08);
        }
        .glass-nav {
            background: rgba(18, 18, 20, 0.85);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        }

        .bg-checkered {
            background-color: #0c0c0e;
            background-image: 
                linear-gradient(45deg, #18181b 25%, transparent 25%), 
                linear-gradient(-45deg, #18181b 25%, transparent 25%),
                linear-gradient(45deg, transparent 75%, #18181b 75%),
                linear-gradient(-45deg, transparent 75%, #18181b 75%);
            background-size: 20px 20px;
            background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
        }

        input[type=range] {
            -webkit-appearance: none;
            background: rgba(255, 255, 255, 0.15);
            border-radius: 999px;
            height: 4px;
        }
        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
            height: 16px;
            width: 16px;
            border-radius: 50%;
            background: #ffffff;
            box-shadow: 0 2px 8px rgba(0,0,0,0.5);
            cursor: pointer;
            border: 1px solid rgba(0,0,0,0.1);
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: scale(0.98); }
            to { opacity: 1; transform: scale(1); }
        }
        .animate-fade-in {
            animation: fadeIn 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards;
        }

        /* SVG Aperture Logo Pulsate Glow */
        .logo-aperture {
            filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.2));
            transition: transform 0.3s ease;
        }
        .logo-aperture:hover {
            transform: rotate(30deg) scale(1.05);
        }
    </style>
</head>
<body class="h-full flex flex-col justify-between select-none">

    <!-- APP TOP HEADER / NAV BAR -->
    <header class="h-14 px-4 sm:px-6 flex items-center justify-between glass-nav z-40 shrink-0">
        <!-- Logo & Title -->
        <div class="flex items-center space-x-3 cursor-pointer" id="btn-home-logo">
            <svg class="w-8 h-8 logo-aperture" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="50" cy="50" r="46" stroke="rgba(255,255,255,0.2)" stroke-width="2"/>
                <path d="M50 10 C65 25, 65 40, 50 50 C35 60, 20 50, 10 50 C20 30, 35 10, 50 10 Z" fill="rgba(255,255,255,0.15)" stroke="rgba(255,255,255,0.7)" stroke-width="1.5"/>
                <path d="M90 50 C70 65, 55 65, 50 50 C45 35, 55 20, 50 10 C70 20, 90 35, 90 50 Z" fill="rgba(255,255,255,0.15)" stroke="rgba(255,255,255,0.7)" stroke-width="1.5"/>
                <path d="M50 90 C35 75, 35 60, 50 50 C65 40, 80 50, 90 50 C80 70, 65 90, 50 90 Z" fill="rgba(255,255,255,0.15)" stroke="rgba(255,255,255,0.7)" stroke-width="1.5"/>
                <path d="M10 50 C30 35, 45 35, 50 50 C55 65, 45 80, 50 90 C30 80, 10 65, 10 50 Z" fill="rgba(255,255,255,0.15)" stroke="rgba(255,255,255,0.7)" stroke-width="1.5"/>
                <circle cx="50" cy="50" r="14" fill="#000000" stroke="rgba(255,255,255,0.9)" stroke-width="1.5"/>
            </svg>
            <div>
                <h1 class="text-sm font-bold tracking-wider uppercase text-white/90">ArtStudio</h1>
                <p id="top-status-text" class="text-[10px] text-white/40">Главное меню</p>
            </div>
        </div>

        <!-- Desktop Navigation Tabs -->
        <div id="main-nav-tabs" class="hidden md:flex items-center bg-white/5 p-1 rounded-full border border-white/10 space-x-1">
            <button data-view="home" class="view-tab-btn active px-4 py-1.5 rounded-full text-xs font-medium text-white bg-white/10 transition">Главная</button>
            <button data-view="projects" class="view-tab-btn px-4 py-1.5 rounded-full text-xs font-medium text-white/60 hover:text-white transition">Мои работы</button>
            <button data-view="settings" class="view-tab-btn px-4 py-1.5 rounded-full text-xs font-medium text-white/60 hover:text-white transition">Настройки</button>
        </div>

        <!-- Top Right Controls -->
        <div class="flex items-center space-x-2">
            <!-- Audio Lo-Fi Toggle Button -->
            <button id="btn-lofi-toggle" title="Lo-Fi Музыка" class="px-3 py-1.5 rounded-full bg-white/5 hover:bg-white/10 text-xs text-white/80 border border-white/10 flex items-center space-x-2 transition">
                <i class="fa-solid fa-music text-purple-400"></i>
                <span class="hidden sm:inline text-[11px]">Lo-Fi Chill</span>
            </button>

            <!-- Editor-Only Quick Controls -->
            <div id="editor-top-controls" class="hidden flex items-center space-x-2">
                <button id="btn-undo" title="Отменить (Ctrl+Z)" class="w-8 h-8 flex items-center justify-center rounded-full bg-white/5 hover:bg-white/10 text-white/80 transition">
                    <i class="fa-solid fa-rotate-left text-xs"></i>
                </button>
                <button id="btn-redo" title="Повторить" class="w-8 h-8 flex items-center justify-center rounded-full bg-white/5 hover:bg-white/10 text-white/80 transition">
                    <i class="fa-solid fa-rotate-right text-xs"></i>
                </button>
                <button id="btn-search-trigger" title="Поиск инструментов" class="w-8 h-8 flex items-center justify-center rounded-full bg-white/5 hover:bg-white/10 text-white/80 transition">
                    <i class="fa-solid fa-magnifying-glass text-xs"></i>
                </button>
                <button id="btn-save-project" title="Сохранить проект" class="px-3 py-1.5 rounded-full bg-white/10 hover:bg-white/20 text-white text-xs font-medium border border-white/15 transition">
                    <i class="fa-solid fa-bookmark mr-1"></i> Сохранить
                </button>
                <button id="btn-export-modal" class="px-3.5 py-1.5 rounded-full bg-blue-600 hover:bg-blue-500 text-white text-xs font-semibold shadow-lg shadow-blue-600/30 transition">
                    Экспорт
                </button>
            </div>
        </div>
    </header>

    <!-- VIEW 1: HOME DASHBOARD / MAIN MENU -->
    <div id="view-home" class="app-view flex-1 overflow-y-auto p-4 sm:p-8 max-w-6xl mx-auto w-full animate-fade-in">
        <!-- Hero Section -->
        <div class="glass-card rounded-3xl p-6 sm:p-10 mb-8 border border-white/10 relative overflow-hidden">
            <div class="absolute -right-10 -bottom-10 w-72 h-72 bg-blue-600/10 rounded-full blur-3xl pointer-events-none"></div>
            <div class="max-w-xl">
                <span class="px-3 py-1 rounded-full bg-white/10 text-white/70 text-[11px] font-semibold tracking-wider uppercase border border-white/10">ArtStudio Pro v2.0</span>
                <h2 class="text-3xl sm:text-5xl font-extrabold text-white mt-4 tracking-tight leading-tight">Создавайте шедевры без границ.</h2>
                <p class="text-sm sm:text-base text-white/60 mt-3 leading-relaxed">
                    Минималистичный графический редактор в стиле Apple. Поддержка слоев, удаление фона, CapCut эффекты, 3D наклоны и рендер анимаций.
                </p>
                <div class="mt-6 flex flex-wrap gap-3">
                    <button id="btn-create-new-project" class="px-6 py-3 rounded-2xl bg-white text-black font-semibold text-sm hover:bg-white/90 active:scale-95 shadow-xl transition flex items-center space-x-2">
                        <i class="fa-solid fa-plus text-xs"></i>
                        <span>Создать новый проект</span>
                    </button>
                    <button id="btn-open-my-works" class="px-6 py-3 rounded-2xl bg-white/10 hover:bg-white/15 text-white font-medium text-sm border border-white/10 active:scale-95 transition">
                        Мои работы
                    </button>
                </div>
            </div>
        </div>

        <!-- Presets Grid -->
        <div class="mb-8">
            <h3 class="text-xs font-semibold text-white/50 uppercase tracking-wider mb-4">Быстрый старт с пресетов</h3>
            <div class="grid grid-cols-2 sm:grid-cols-4 gap-4">
                <div onclick="App.createNewProjectWithDimensions(1080, 1920, 'Story / Mobile')" class="glass-card p-5 rounded-2xl cursor-pointer hover:border-blue-500/50 hover:bg-white/10 transition group">
                    <i class="fa-solid fa-mobile-screen text-2xl text-blue-400 mb-3 group-hover:scale-110 transition-transform"></i>
                    <h4 class="text-sm font-semibold text-white">Mobile / Stories</h4>
                    <p class="text-xs text-white/40 mt-1">9:16 (1080 × 1920)</p>
                </div>
                <div onclick="App.createNewProjectWithDimensions(1080, 1080, 'Квадрат')" class="glass-card p-5 rounded-2xl cursor-pointer hover:border-purple-500/50 hover:bg-white/10 transition group">
                    <i class="fa-solid fa-square text-2xl text-purple-400 mb-3 group-hover:scale-110 transition-transform"></i>
                    <h4 class="text-sm font-semibold text-white">Квадрат</h4>
                    <p class="text-xs text-white/40 mt-1">1:1 (1080 × 1080)</p>
                </div>
                <div onclick="App.createNewProjectWithDimensions(1920, 1080, 'Desktop 16:9')" class="glass-card p-5 rounded-2xl cursor-pointer hover:border-emerald-500/50 hover:bg-white/10 transition group">
                    <i class="fa-solid fa-desktop text-2xl text-emerald-400 mb-3 group-hover:scale-110 transition-transform"></i>
                    <h4 class="text-sm font-semibold text-white">ПК / Landscape</h4>
                    <p class="text-xs text-white/40 mt-1">16:9 (1920 × 1080)</p>
                </div>
                <div onclick="App.openCustomProjectModal()" class="glass-card p-5 rounded-2xl cursor-pointer hover:border-amber-500/50 hover:bg-white/10 transition group flex flex-col justify-between">
                    <i class="fa-solid fa-sliders text-2xl text-amber-400 mb-3 group-hover:scale-110 transition-transform"></i>
                    <div>
                        <h4 class="text-sm font-semibold text-white">Свой размер</h4>
                        <p class="text-xs text-white/40 mt-1">Настроить px</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- VIEW 2: MY WORKS / SAVED PROJECTS GALLERY -->
    <div id="view-projects" class="app-view hidden flex-1 overflow-y-auto p-4 sm:p-8 max-w-6xl mx-auto w-full animate-fade-in">
        <div class="flex items-center justify-between mb-6">
            <div>
                <h2 class="text-2xl font-bold text-white">Мои работы</h2>
                <p class="text-xs text-white/50 mt-1">Сохранённые локальные черновики</p>
            </div>
            <button onclick="App.openTab('home')" class="text-xs text-white/60 hover:text-white">Назад на Главную</button>
        </div>

        <div id="projects-gallery-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
            <!-- Saved projects rendered dynamically -->
        </div>
    </div>

    <!-- VIEW 3: SETTINGS VIEW -->
    <div id="view-settings" class="app-view hidden flex-1 overflow-y-auto p-4 sm:p-8 max-w-3xl mx-auto w-full animate-fade-in">
        <h2 class="text-2xl font-bold text-white mb-6">Настройки приложения</h2>

        <div class="space-y-4">
            <div class="glass-card p-5 rounded-2xl flex items-center justify-between">
                <div>
                    <h4 class="text-sm font-semibold text-white">Звуки интерфейса (UI Sounds)</h4>
                    <p class="text-xs text-white/40 mt-0.5">Тихие приятные клики в стиле Apple</p>
                </div>
                <input type="checkbox" id="setting-sound-toggle" checked class="w-5 h-5 accent-blue-500 cursor-pointer">
            </div>

            <div class="glass-card p-5 rounded-2xl flex items-center justify-between">
                <div>
                    <h4 class="text-sm font-semibold text-white">Lo-Fi Фоновая Музыка</h4>
                    <p class="text-xs text-white/40 mt-0.5">Расслабляющие генеративные синтезаторы</p>
                </div>
                <input type="checkbox" id="setting-lofi-toggle" class="w-5 h-5 accent-purple-500 cursor-pointer">
            </div>

            <div class="glass-card p-5 rounded-2xl space-y-3">
                <h4 class="text-sm font-semibold text-white">Громкость звука</h4>
                <input type="range" id="setting-volume-slider" min="0" max="1" step="0.05" value="0.4" class="w-full">
            </div>

            <div class="glass-card p-5 rounded-2xl flex items-center justify-between">
                <div>
                    <h4 class="text-sm font-semibold text-white">Автосохранение проекта</h4>
                    <p class="text-xs text-white/40 mt-0.5">Автоматически сохранять изменения каждые 30 сек</p>
                </div>
                <input type="checkbox" id="setting-autosave-toggle" checked class="w-5 h-5 accent-blue-500 cursor-pointer">
            </div>

            <div class="glass-card p-5 rounded-2xl flex items-center justify-between border border-red-500/20">
                <div>
                    <h4 class="text-sm font-semibold text-red-400">Очистить кэш проектов</h4>
                    <p class="text-xs text-white/40 mt-0.5">Удалит все сохранённые проекты из браузера</p>
                </div>
                <button onclick="App.clearAllProjects()" class="px-4 py-2 bg-red-600/20 border border-red-500/40 text-red-300 rounded-xl text-xs hover:bg-red-600/40 transition">
                    Очистить
                </button>
            </div>
        </div>
    </div>

    <!-- VIEW 4: STUDIO EDITOR WORKSPACE (PC & Mobile Adaptive Studio) -->
    <div id="view-editor" class="app-view hidden flex-1 flex flex-col md:flex-row overflow-hidden relative">
        
        <!-- PC LEFT TOOLBAR / MOBILE FLOATING PANEL -->
        <aside class="hidden md:flex flex-col w-64 glass-nav border-r border-white/10 p-4 space-y-4 shrink-0 overflow-y-auto">
            <h3 class="text-xs font-semibold text-white/50 uppercase tracking-wider">Инструменты</h3>
            
            <div class="space-y-1">
                <button onclick="App.openEditorSubTab('canvas')" class="editor-side-btn w-full px-3 py-2.5 rounded-xl text-xs text-left text-white/80 hover:bg-white/10 flex items-center space-x-3 transition">
                    <i class="fa-solid fa-ruler-combined text-blue-400 w-5"></i>
                    <span>Холст и Размер</span>
                </button>
                <button onclick="App.openEditorSubTab('layers')" class="editor-side-btn w-full px-3 py-2.5 rounded-xl text-xs text-left text-white/80 hover:bg-white/10 flex items-center space-x-3 transition">
                    <i class="fa-solid fa-layer-group text-purple-400 w-5"></i>
                    <span>Управление Слоями</span>
                </button>
                <button onclick="App.openEditorSubTab('add')" class="editor-side-btn w-full px-3 py-2.5 rounded-xl text-xs text-left text-white/80 hover:bg-white/10 flex items-center space-x-3 transition">
                    <i class="fa-solid fa-circle-plus text-emerald-400 w-5"></i>
                    <span>Добавить Изображения / Текст</span>
                </button>
                <button onclick="App.openEditorSubTab('adjust')" class="editor-side-btn w-full px-3 py-2.5 rounded-xl text-xs text-left text-white/80 hover:bg-white/10 flex items-center space-x-3 transition">
                    <i class="fa-solid fa-sliders text-amber-400 w-5"></i>
                    <span>Цветокоррекция</span>
                </button>
                <button onclick="App.openEditorSubTab('fx')" class="editor-side-btn w-full px-3 py-2.5 rounded-xl text-xs text-left text-white/80 hover:bg-white/10 flex items-center space-x-3 transition">
                    <i class="fa-solid fa-wand-magic-sparkles text-pink-400 w-5"></i>
                    <span>CapCut Эффекты & 3D</span>
                </button>
            </div>

            <!-- Left Panel Dynamic Inspector Content -->
            <div class="border-t border-white/10 pt-4 flex-1 overflow-y-auto">
                <div id="desktop-inspector-content" class="space-y-4">
                    <!-- Dynamic controls injected here for PC -->
                </div>
            </div>
        </aside>

        <!-- MAIN CANVAS WORKSPACE -->
        <main id="workspace-container" class="relative flex-1 bg-checkered overflow-hidden flex items-center justify-center p-4">
            <div id="canvas-wrapper" class="relative shadow-2xl transition-transform duration-75 origin-center">
                <canvas id="main-canvas" class="block w-full h-full rounded-sm"></canvas>
            </div>

            <!-- Viewport Reset Overlay -->
            <div class="absolute bottom-4 left-4 z-20 flex space-x-2">
                <button id="btn-zoom-fit" class="px-3 py-1.5 glass-card rounded-full text-[11px] text-white/70 hover:text-white backdrop-blur-md active:scale-95 transition">
                    <i class="fa-solid fa-expand mr-1"></i> Сбросить зум
                </button>
                <button id="btn-toggle-grid" class="w-8 h-8 glass-card rounded-full flex items-center justify-center text-white/70 hover:text-white backdrop-blur-md active:scale-95 transition">
                    <i class="fa-solid fa-border-top-left"></i>
                </button>
            </div>
        </main>

        <!-- MOBILE FLOATING TOOL PARAMETERS SUB-PANEL -->
        <div id="sub-panel" class="md:hidden glass-card border-b-0 rounded-t-3xl p-4 transition-all duration-300 transform translate-y-full fixed bottom-16 inset-x-0 z-30 max-h-[55vh] overflow-y-auto">
            <div class="flex justify-between items-center mb-3 pb-2 border-b border-white/10">
                <h3 id="sub-panel-title" class="text-xs font-semibold tracking-wider text-white/80 uppercase">Настройки</h3>
                <button id="btn-close-subpanel" class="w-6 h-6 flex items-center justify-center rounded-full bg-white/10 text-white/60 text-xs">
                    <i class="fa-solid fa-xmark"></i>
                </button>
            </div>
            <div id="sub-panel-content" class="space-y-4">
                <!-- Dynamic Controls Injected Here for Mobile -->
            </div>
        </div>

        <!-- MOBILE BOTTOM TABS NAVIGATION -->
        <nav class="md:hidden h-16 glass-nav flex items-center justify-around px-2 z-30 shrink-0 border-t border-white/10">
            <button data-editor-tab="canvas" class="editor-mobile-tab flex flex-col items-center text-white/60 hover:text-white transition py-1 px-2">
                <i class="fa-solid fa-ruler-combined text-base mb-1"></i>
                <span class="text-[10px]">Холст</span>
            </button>
            <button data-editor-tab="layers" class="editor-mobile-tab active flex flex-col items-center text-white/60 hover:text-white transition py-1 px-2">
                <i class="fa-solid fa-layer-group text-base mb-1"></i>
                <span class="text-[10px]">Слои</span>
            </button>
            <button data-editor-tab="add" class="editor-mobile-tab flex flex-col items-center text-white/60 hover:text-white transition py-1 px-2">
                <i class="fa-solid fa-circle-plus text-lg text-blue-500 mb-1"></i>
                <span class="text-[10px]">Добавить</span>
            </button>
            <button data-editor-tab="adjust" class="editor-mobile-tab flex flex-col items-center text-white/60 hover:text-white transition py-1 px-2">
                <i class="fa-solid fa-sliders text-base mb-1"></i>
                <span class="text-[10px]">Коррекция</span>
            </button>
            <button data-editor-tab="fx" class="editor-mobile-tab flex flex-col items-center text-white/60 hover:text-white transition py-1 px-2">
                <i class="fa-solid fa-wand-magic-sparkles text-base mb-1"></i>
                <span class="text-[10px]">Эффекты</span>
            </button>
        </nav>
    </div>

    <!-- MOBILE BOTTOM NAVIGATION FOR MAIN MENU -->
    <nav id="mobile-main-nav" class="md:hidden h-14 glass-nav flex items-center justify-around px-2 z-40 shrink-0 border-t border-white/10">
        <button data-view="home" class="view-tab-btn flex flex-col items-center text-white/60 hover:text-white transition">
            <i class="fa-solid fa-house text-sm mb-0.5"></i>
            <span class="text-[10px]">Главное</span>
        </button>
        <button data-view="projects" class="view-tab-btn flex flex-col items-center text-white/60 hover:text-white transition">
            <i class="fa-solid fa-folder text-sm mb-0.5"></i>
            <span class="text-[10px]">Работы</span>
        </button>
        <button data-view="settings" class="view-tab-btn flex flex-col items-center text-white/60 hover:text-white transition">
            <i class="fa-solid fa-gear text-sm mb-0.5"></i>
            <span class="text-[10px]">Настройки</span>
        </button>
    </nav>

    <!-- SEARCH & COMMAND PALETTE MODAL -->
    <div id="search-modal" class="hidden fixed inset-0 z-50 bg-black/70 backdrop-blur-md p-4 flex flex-col items-center pt-16">
        <div class="w-full max-w-md glass-card rounded-2xl p-3 shadow-2xl animate-fade-in">
            <div class="flex items-center px-3 py-2 bg-white/5 rounded-xl border border-white/10 mb-3">
                <i class="fa-solid fa-magnifying-glass text-white/40 mr-2 text-sm"></i>
                <input type="text" id="search-input" placeholder="Поиск инструментов (текст, блеск, 3D, удаление фона)..." class="bg-transparent text-sm text-white focus:outline-none w-full placeholder-white/40">
                <button id="btn-close-search" class="text-xs text-white/40 hover:text-white ml-2">Отмена</button>
            </div>
            <div id="search-results" class="max-h-64 overflow-y-auto space-y-1"></div>
        </div>
    </div>

    <!-- NEW CUSTOM PROJECT DIMENSIONS MODAL -->
    <div id="custom-project-modal" class="hidden fixed inset-0 z-50 bg-black/80 backdrop-blur-xl p-4 flex flex-col items-center justify-center">
        <div class="w-full max-w-sm glass-card rounded-3xl p-6 text-center space-y-4 animate-fade-in">
            <h3 class="text-base font-semibold text-white">Новый проект</h3>
            <p class="text-xs text-white/50">Укажите произвольный размер холста</p>
            
            <div class="grid grid-cols-2 gap-3 text-left">
                <div>
                    <label class="text-[11px] text-white/60">Ширина (px)</label>
                    <input type="number" id="custom-width" value="1080" class="w-full mt-1 bg-white/5 border border-white/10 rounded-xl px-3 py-2 text-xs text-white">
                </div>
                <div>
                    <label class="text-[11px] text-white/60">Высота (px)</label>
                    <input type="number" id="custom-height" value="1080" class="w-full mt-1 bg-white/5 border border-white/10 rounded-xl px-3 py-2 text-xs text-white">
                </div>
            </div>

            <div class="flex space-x-3 pt-2">
                <button onclick="document.getElementById('custom-project-modal').classList.add('hidden')" class="flex-1 py-2.5 rounded-xl bg-white/10 text-white text-xs font-medium hover:bg-white/15 transition">Отмена</button>
                <button id="btn-create-custom-project" class="flex-1 py-2.5 rounded-xl bg-blue-600 text-white text-xs font-semibold hover:bg-blue-500 shadow-lg shadow-blue-600/30 transition">Создать</button>
            </div>
        </div>
    </div>

    <!-- EXPORT MODAL -->
    <div id="export-modal" class="hidden fixed inset-0 z-50 bg-black/80 backdrop-blur-xl p-4 flex flex-col items-center justify-center">
        <div class="w-full max-w-sm glass-card rounded-3xl p-6 text-center space-y-5 animate-fade-in">
            <div class="w-12 h-12 rounded-full bg-blue-600/20 text-blue-400 flex items-center justify-center mx-auto text-xl">
                <i class="fa-solid fa-download"></i>
            </div>
            <div>
                <h3 class="text-base font-semibold text-white">Экспорт ArtStudio</h3>
                <p class="text-xs text-white/50 mt-1">Выберите формат для сохранения</p>
            </div>

            <div class="space-y-3 text-left">
                <div>
                    <label class="text-[11px] text-white/60 font-medium">Формат файла</label>
                    <select id="export-format" class="w-full mt-1 bg-white/5 border border-white/10 rounded-xl px-3 py-2 text-xs text-white focus:outline-none">
                        <option value="png" class="bg-zinc-900">PNG (Прозрачность)</option>
                        <option value="jpeg" class="bg-zinc-900">JPEG (Стандарт)</option>
                        <option value="webm" class="bg-zinc-900">WebM Анимация (Видео)</option>
                    </select>
                </div>

                <div id="export-fps-container" class="hidden">
                    <label class="text-[11px] text-white/60 font-medium">Длительность видео (сек)</label>
                    <input type="number" id="export-duration" min="1" max="10" value="3" class="w-full mt-1 bg-white/5 border border-white/10 rounded-xl px-3 py-2 text-xs text-white">
                </div>
            </div>

            <div class="flex space-x-3 pt-2">
                <button id="btn-cancel-export" class="flex-1 py-2.5 rounded-xl bg-white/10 text-white text-xs font-medium hover:bg-white/15 transition">Отмена</button>
                <button id="btn-do-export" class="flex-1 py-2.5 rounded-xl bg-blue-600 text-white text-xs font-semibold hover:bg-blue-500 shadow-lg shadow-blue-600/30 transition">Сохранить</button>
            </div>
        </div>
    </div>

    <!-- CORE JAVASCRIPT ENGINE -->
    <script>
        /**
         * Web Audio Synthesizer & Lo-Fi Chill Ambience Engine
         */
        const AudioEngine = {
            ctx: null,
            volume: 0.4,
            soundEnabled: true,
            lofiPlaying: false,
            lofiInterval: null,

            init() {
                try {
                    const AudioCtx = window.AudioContext || window.webkitAudioContext;
                    this.ctx = new AudioCtx();
                } catch (e) {
                    console.log('Audio not supported');
                }
            },

            playClick() {
                if (!this.soundEnabled || !this.ctx) return;
                if (this.ctx.state === 'suspended') this.ctx.resume();
                const osc = this.ctx.createOscillator();
                const gain = this.ctx.createGain();
                osc.type = 'sine';
                osc.frequency.setValueAtTime(600, this.ctx.currentTime);
                osc.frequency.exponentialRampToValueAtTime(200, this.ctx.currentTime + 0.04);
                gain.gain.setValueAtTime(this.volume * 0.15, this.ctx.currentTime);
                gain.gain.linearRampToValueAtTime(0, this.ctx.currentTime + 0.04);
                osc.connect(gain);
                gain.connect(this.ctx.destination);
                osc.start();
                osc.stop(this.ctx.currentTime + 0.04);
            },

            toggleLofi() {
                if (!this.ctx) this.init();
                if (this.ctx.state === 'suspended') this.ctx.resume();

                this.lofiPlaying = !this.lofiPlaying;
                const btn = document.getElementById('btn-lofi-toggle');

                if (this.lofiPlaying) {
                    btn.classList.add('bg-purple-600/30', 'border-purple-500/50');
                    this.startLofiGenerator();
                } else {
                    btn.classList.remove('bg-purple-600/30', 'border-purple-500/50');
                    this.stopLofiGenerator();
                }
            },

            startLofiGenerator() {
                const chords = [
                    [261.63, 329.63, 392.00, 493.88], // Cmaj7
                    [220.00, 261.63, 329.63, 392.00], // Am7
                    [174.61, 220.00, 261.63, 329.63], // Fmaj7
                    [196.00, 246.94, 293.66, 349.23]  // G7
                ];
                let chordIdx = 0;

                const playChord = () => {
                    if (!this.lofiPlaying) return;
                    const notes = chords[chordIdx];
                    chordIdx = (chordIdx + 1) % chords.length;

                    notes.forEach(freq => {
                        const osc = this.ctx.createOscillator();
                        const gain = this.ctx.createGain();
                        osc.type = 'triangle';
                        osc.frequency.setValueAtTime(freq, this.ctx.currentTime);
                        
                        gain.gain.setValueAtTime(0, this.ctx.currentTime);
                        gain.gain.linearRampToValueAtTime(this.volume * 0.05, this.ctx.currentTime + 1);
                        gain.gain.linearRampToValueAtTime(0, this.ctx.currentTime + 3.8);

                        osc.connect(gain);
                        gain.connect(this.ctx.destination);
                        osc.start();
                        osc.stop(this.ctx.currentTime + 4);
                    });
                };

                playChord();
                this.lofiInterval = setInterval(playChord, 4000);
            },

            stopLofiGenerator() {
                if (this.lofiInterval) clearInterval(this.lofiInterval);
            }
        };

        /**
         * ArtStudio - Main Application Engine
         */
        const App = {
            currentView: 'home', // 'home', 'projects', 'settings', 'editor'
            activeEditorTab: 'layers',

            // Canvas & Project
            currentProjectName: 'Новый проект',
            canvas: null,
            ctx: null,
            width: 1080,
            height: 1920,
            zoom: 1,
            pan: { x: 0, y: 0 },
            showGrid: false,

            // Layers
            layers: [],
            selectedLayerId: null,
            nextLayerId: 1,

            // History
            history: [],
            historyIndex: -1,
            maxHistory: 20,

            // Render loop
            time: 0,

            // Fonts & Assets
            customFonts: ["Inter", "Montserrat", "Playfair Display", "Roboto Mono", "Pacifico"],
            stockOverlays: [
                { name: "Световой блик", type: "glow", color: "#0A84FF" },
                { name: "Неоновая стрелка", type: "arrow", color: "#FF3B30" },
                { name: "Пыль и Частицы", type: "dust", color: "#FFFFFF" },
                { name: "Золотое свечение", type: "glow", color: "#FFD60A" },
                { name: "Виньетка", type: "vignette", color: "#000000" }
            ],

            init() {
                this.canvas = document.getElementById('main-canvas');
                this.ctx = this.canvas.getContext('2d');
                
                this.setupNavigation();
                this.setupEventListeners();
                this.setupTouchPinchZoom();
                this.renderLoop();

                AudioEngine.init();
                this.renderSavedProjectsGallery();
            },

            // --- VIEW SWITCHING ---
            openTab(viewName) {
                AudioEngine.playClick();
                this.currentView = viewName;

                document.querySelectorAll('.app-view').forEach(el => el.classList.add('hidden'));
                document.querySelectorAll('.view-tab-btn').forEach(btn => {
                    btn.classList.toggle('active', btn.dataset.view === viewName);
                    btn.classList.toggle('text-white', btn.dataset.view === viewName);
                    btn.classList.toggle('text-white/60', btn.dataset.view !== viewName);
                });

                const topControls = document.getElementById('editor-top-controls');
                const mainNav = id => document.getElementById(id);

                if (viewName === 'editor') {
                    mainNav('view-editor').classList.remove('hidden');
                    topControls.classList.remove('hidden');
                    mainNav('mobile-main-nav').classList.add('hidden');
                    mainNav('top-status-text').innerText = `${this.currentProjectName} (${this.width}×${this.height}px)`;
                    this.fitZoomToScreen();
                } else {
                    topControls.classList.add('hidden');
                    mainNav('mobile-main-nav').classList.remove('hidden');

                    if (viewName === 'home') {
                        mainNav('view-home').classList.remove('hidden');
                        mainNav('top-status-text').innerText = 'Главное меню';
                    } else if (viewName === 'projects') {
                        mainNav('view-projects').classList.remove('hidden');
                        mainNav('top-status-text').innerText = 'Мои работы';
                        this.renderSavedProjectsGallery();
                    } else if (viewName === 'settings') {
                        mainNav('view-settings').classList.remove('hidden');
                        mainNav('top-status-text').innerText = 'Настройки';
                    }
                }
            },

            // --- PROJECT CREATION ---
            createNewProjectWithDimensions(w, h, name = 'Черновик') {
                this.width = w;
                this.height = h;
                this.currentProjectName = name;
                this.canvas.width = w;
                this.canvas.height = h;

                const wrapper = document.getElementById('canvas-wrapper');
                wrapper.style.width = `${w}px`;
                wrapper.style.height = `${h}px`;

                this.layers = [];
                this.history = [];
                this.historyIndex = -1;

                this.addSolidColorLayer('#121214', 'Фон');
                this.addTextLayer('ArtStudio', 'Inter', 110, '#FFFFFF');

                this.openTab('editor');
                this.openEditorSubTab('layers');
                this.saveHistory();
            },

            openCustomProjectModal() {
                document.getElementById('custom-project-modal').classList.remove('hidden');
            },

            // --- CANVAS & TRANSFORM ---
            fitZoomToScreen() {
                const container = document.getElementById('workspace-container');
                const padding = 40;
                const availableW = container.clientWidth - padding;
                const availableH = container.clientHeight - padding;

                const scaleW = availableW / this.width;
                const scaleH = availableH / this.height;
                
                this.zoom = Math.min(scaleW, scaleH, 1);
                this.pan = { x: 0, y: 0 };
                this.updateCanvasTransform();
            },

            updateCanvasTransform() {
                const wrapper = document.getElementById('canvas-wrapper');
                wrapper.style.transform = `translate(${this.pan.x}px, ${this.pan.y}px) scale(${this.zoom})`;
            },

            // --- LAYER SYSTEM ---
            createBaseLayer(type, name) {
                return {
                    id: this.nextLayerId++,
                    type: type,
                    name: name || `Слой ${this.nextLayerId}`,
                    visible: true,
                    locked: false,
                    opacity: 1.0,
                    blendMode: 'source-over',
                    x: this.width / 2,
                    y: this.height / 2,
                    scaleX: 1,
                    scaleY: 1,
                    rotation: 0,
                    tiltX: 0,
                    tiltY: 0,

                    brightness: 100,
                    contrast: 100,
                    saturation: 100,
                    blur: 0,
                    hue: 0,
                    invert: 0,

                    edgeGlow: false,
                    edgeGlowColor: '#0A84FF',
                    edgeGlowSize: 20,
                    outerGlow: false,
                    outerGlowColor: '#FF375F',
                    outerGlowBlur: 30,

                    animation: 'none',
                    animSpeed: 1,

                    chromaKey: false,
                    chromaColor: '#00FF00',
                    chromaTolerance: 40
                };
            },

            addSolidColorLayer(color = '#1c1c1e', name = 'Фон цветной') {
                const layer = this.createBaseLayer('solid', name);
                layer.color = color;
                this.layers.push(layer);
                this.selectedLayerId = layer.id;
                this.saveHistory();
                this.requestRender();
                this.refreshEditorInspector();
            },

            addTextLayer(text = 'ArtStudio', font = 'Inter', size = 90, color = '#FFFFFF') {
                const layer = this.createBaseLayer('text', 'Текст');
                layer.text = text;
                layer.fontFamily = font;
                layer.fontSize = size;
                layer.color = color;
                layer.useGradient = false;
                layer.gradientColor2 = '#0A84FF';

                this.layers.push(layer);
                this.selectedLayerId = layer.id;
                this.saveHistory();
                this.requestRender();
                this.refreshEditorInspector();
            },

            addImageLayer(imgElement, name = 'Изображение') {
                const layer = this.createBaseLayer('image', name);
                layer.image = imgElement;
                layer.width = imgElement.width;
                layer.height = imgElement.height;
                
                const maxDim = Math.min(this.width * 0.8, this.height * 0.8);
                const scale = Math.min(maxDim / layer.width, maxDim / layer.height);
                layer.scaleX = scale;
                layer.scaleY = scale;

                this.layers.push(layer);
                this.selectedLayerId = layer.id;
                this.saveHistory();
                this.requestRender();
                this.refreshEditorInspector();
            },

            addStockOverlay(overlayItem) {
                const tempCanvas = document.createElement('canvas');
                tempCanvas.width = 600;
                tempCanvas.height = 600;
                const tCtx = tempCanvas.getContext('2d');

                if (overlayItem.type === 'glow') {
                    const radG = tCtx.createRadialGradient(300, 300, 10, 300, 300, 280);
                    radG.addColorStop(0, overlayItem.color);
                    radG.addColorStop(1, 'transparent');
                    tCtx.fillStyle = radG;
                    tCtx.fillRect(0, 0, 600, 600);
                } else if (overlayItem.type === 'dust') {
                    tCtx.fillStyle = '#FFFFFF';
                    for (let i = 0; i < 150; i++) {
                        tCtx.globalAlpha = Math.random() * 0.7;
                        tCtx.beginPath();
                        tCtx.arc(Math.random() * 600, Math.random() * 600, Math.random() * 3, 0, Math.PI * 2);
                        tCtx.fill();
                    }
                } else if (overlayItem.type === 'arrow') {
                    tCtx.strokeStyle = overlayItem.color;
                    tCtx.lineWidth = 12;
                    tCtx.lineCap = 'round';
                    tCtx.beginPath();
                    tCtx.moveTo(100, 300);
                    tCtx.lineTo(450, 300);
                    tCtx.lineTo(350, 200);
                    tCtx.moveTo(450, 300);
                    tCtx.lineTo(350, 400);
                    tCtx.stroke();
                } else if (overlayItem.type === 'vignette') {
                    const g = tCtx.createRadialGradient(300, 300, 150, 300, 300, 300);
                    g.addColorStop(0, 'transparent');
                    g.addColorStop(1, 'rgba(0,0,0,0.85)');
                    tCtx.fillStyle = g;
                    tCtx.fillRect(0, 0, 600, 600);
                }

                const img = new Image();
                img.src = tempCanvas.toDataURL();
                img.onload = () => this.addImageLayer(img, overlayItem.name);
            },

            getSelectedLayer() {
                return this.layers.find(l => l.id === this.selectedLayerId);
            },

            deleteLayer(id) {
                AudioEngine.playClick();
                this.layers = this.layers.filter(l => l.id !== id);
                if (this.selectedLayerId === id) {
                    this.selectedLayerId = this.layers.length ? this.layers[this.layers.length - 1].id : null;
                }
                this.saveHistory();
                this.requestRender();
                this.refreshEditorInspector();
            },

            moveLayer(id, direction) {
                AudioEngine.playClick();
                const idx = this.layers.findIndex(l => l.id === id);
                if (idx < 0) return;
                if (direction === 'up' && idx < this.layers.length - 1) {
                    const temp = this.layers[idx];
                    this.layers[idx] = this.layers[idx + 1];
                    this.layers[idx + 1] = temp;
                } else if (direction === 'down' && idx > 0) {
                    const temp = this.layers[idx];
                    this.layers[idx] = this.layers[idx - 1];
                    this.layers[idx - 1] = temp;
                }
                this.saveHistory();
                this.requestRender();
                this.refreshEditorInspector();
            },

            duplicateLayer(id) {
                AudioEngine.playClick();
                const layer = this.layers.find(l => l.id === id);
                if (!layer) return;
                const clone = JSON.parse(JSON.stringify(layer));
                clone.id = this.nextLayerId++;
                clone.name = `${layer.name} (Копия)`;
                clone.x += 30;
                clone.y += 30;

                if (layer.type === 'image' && layer.image) {
                    clone.image = layer.image;
                }

                this.layers.push(clone);
                this.selectedLayerId = clone.id;
                this.saveHistory();
                this.requestRender();
                this.refreshEditorInspector();
            },

            // --- CHROMA KEY / BACKGROUND REMOVAL ENGINE ---
            applyChromaKey(layer) {
                if (layer.type !== 'image' || !layer.image) return;

                const tempC = document.createElement('canvas');
                tempC.width = layer.image.width;
                tempC.height = layer.image.height;
                const tCtx = tempC.getContext('2d');
                tCtx.drawImage(layer.image, 0, 0);

                const imgData = tCtx.getImageData(0, 0, tempC.width, tempC.height);
                const data = imgData.data;

                const hex = layer.chromaColor.replace('#', '');
                const targetR = parseInt(hex.substring(0, 2), 16);
                const targetG = parseInt(hex.substring(2, 4), 16);
                const targetB = parseInt(hex.substring(4, 6), 16);
                const tolerance = layer.chromaTolerance;

                for (let i = 0; i < data.length; i += 4) {
                    const r = data[i];
                    const g = data[i + 1];
                    const b = data[i + 2];

                    const dist = Math.sqrt((r - targetR) ** 2 + (g - targetG) ** 2 + (b - targetB) ** 2);
                    if (dist < tolerance) {
                        data[i + 3] = 0;
                    }
                }

                tCtx.putImageData(imgData, 0, 0);
                const processedImg = new Image();
                processedImg.src = tempC.toDataURL();
                processedImg.onload = () => {
                    layer.image = processedImg;
                    this.requestRender();
                };
            },

            // --- HISTORY (UNDO/REDO) ---
            saveHistory() {
                if (this.historyIndex < this.history.length - 1) {
                    this.history = this.history.slice(0, this.historyIndex + 1);
                }
                const serialized = this.layers.map(l => {
                    const c = { ...l };
                    if (l.type === 'image' && l.image) c._imgSrc = l.image.src;
                    return c;
                });
                this.history.push(JSON.stringify(serialized));
                if (this.history.length > this.maxHistory) this.history.shift();
                else this.historyIndex++;
            },

            undo() {
                AudioEngine.playClick();
                if (this.historyIndex > 0) {
                    this.historyIndex--;
                    this.restoreHistoryState(this.history[this.historyIndex]);
                }
            },

            redo() {
                AudioEngine.playClick();
                if (this.historyIndex < this.history.length - 1) {
                    this.historyIndex++;
                    this.restoreHistoryState(this.history[this.historyIndex]);
                }
            },

            restoreHistoryState(jsonState) {
                const parsed = JSON.parse(jsonState);
                this.layers = parsed.map(l => {
                    if (l.type === 'image' && l._imgSrc) {
                        const img = new Image();
                        img.src = l._imgSrc;
                        l.image = img;
                    }
                    return l;
                });
                this.requestRender();
                this.refreshEditorInspector();
            },

            // --- LOCAL STORAGE PROJECTS GALLERY ---
            saveCurrentProjectToGallery() {
                const thumbData = this.canvas.toDataURL('image/jpeg', 0.5);
                const projectObj = {
                    id: Date.now(),
                    name: this.currentProjectName,
                    width: this.width,
                    height: this.height,
                    thumbnail: thumbData,
                    date: new Date().toLocaleDateString('ru-RU'),
                    layers: this.layers.map(l => {
                        const c = { ...l };
                        if (l.type === 'image' && l.image) c._imgSrc = l.image.src;
                        return c;
                    })
                };

                let saved = JSON.parse(localStorage.getItem('artstudio_projects') || '[]');
                saved.unshift(projectObj);
                localStorage.setItem('artstudio_projects', JSON.stringify(saved));
                alert('Проект успешно сохранен в "Мои работы"!');
            },

            renderSavedProjectsGallery() {
                const container = document.getElementById('projects-gallery-grid');
                const saved = JSON.parse(localStorage.getItem('artstudio_projects') || '[]');

                if (saved.length === 0) {
                    container.innerHTML = `
                        <div class="col-span-full py-12 text-center text-white/40 glass-card rounded-2xl">
                            <i class="fa-solid fa-folder-open text-3xl mb-2"></i>
                            <p class="text-xs">У вас пока нет сохранённых работ</p>
                        </div>
                    `;
                    return;
                }

                container.innerHTML = saved.map(p => `
                    <div class="glass-card rounded-2xl overflow-hidden border border-white/10 group hover:border-blue-500/50 transition">
                        <div class="h-36 bg-black/50 overflow-hidden relative">
                            <img src="${p.thumbnail}" class="w-full h-full object-cover group-hover:scale-105 transition duration-300">
                        </div>
                        <div class="p-3">
                            <h4 class="text-xs font-semibold text-white truncate">${p.name}</h4>
                            <p class="text-[10px] text-white/40 mt-0.5">${p.width}×${p.height} px • ${p.date}</p>
                            <div class="mt-3 flex space-x-2">
                                <button onclick="App.loadProjectFromGallery(${p.id})" class="flex-1 py-1.5 bg-blue-600 rounded-xl text-[10px] text-white font-medium hover:bg-blue-500 transition">Открыть</button>
                                <button onclick="App.deleteProjectFromGallery(${p.id})" class="px-2.5 py-1.5 bg-white/10 rounded-xl text-[10px] text-red-400 hover:bg-red-600/20 transition"><i class="fa-solid fa-trash"></i></button>
                            </div>
                        </div>
                    </div>
                `).join('');
            },

            loadProjectFromGallery(id) {
                const saved = JSON.parse(localStorage.getItem('artstudio_projects') || '[]');
                const p = saved.find(item => item.id === id);
                if (!p) return;

                this.width = p.width;
                this.height = p.height;
                this.currentProjectName = p.name;
                this.canvas.width = p.width;
                this.canvas.height = p.height;

                const wrapper = document.getElementById('canvas-wrapper');
                wrapper.style.width = `${p.width}px`;
                wrapper.style.height = `${p.height}px`;

                this.restoreHistoryState(JSON.stringify(p.layers));
                this.openTab('editor');
            },

            deleteProjectFromGallery(id) {
                let saved = JSON.parse(localStorage.getItem('artstudio_projects') || '[]');
                saved = saved.filter(p => p.id !== id);
                localStorage.setItem('artstudio_projects', JSON.stringify(saved));
                this.renderSavedProjectsGallery();
            },

            clearAllProjects() {
                if (confirm('Удалить все сохранённые работы?')) {
                    localStorage.removeItem('artstudio_projects');
                    this.renderSavedProjectsGallery();
                }
            },

            // --- RENDERING LOOP ---
            requestRender() {
                requestAnimationFrame(() => this.render());
            },

            renderLoop() {
                this.time += 0.03;
                this.render();
                requestAnimationFrame(() => this.renderLoop());
            },

            render() {
                const ctx = this.ctx;
                ctx.clearRect(0, 0, this.width, this.height);

                this.layers.forEach(layer => {
                    if (!layer.visible) return;

                    ctx.save();
                    ctx.globalAlpha = layer.opacity;
                    ctx.globalCompositeOperation = layer.blendMode;

                    let animScale = 1;
                    let animRot = 0;
                    let animGlowOffset = 0;

                    if (layer.animation === 'pulse') {
                        animScale = 1 + Math.sin(this.time * 3 * layer.animSpeed) * 0.08;
                    } else if (layer.animation === 'spin') {
                        animRot = (this.time * 50 * layer.animSpeed) % 360;
                    } else if (layer.animation === 'float') {
                        var animY = Math.sin(this.time * 2 * layer.animSpeed) * 20;
                    } else if (layer.animation === 'glow') {
                        animGlowOffset = Math.abs(Math.sin(this.time * 4)) * 25;
                    }

                    ctx.translate(layer.x, layer.y + (animY || 0));
                    ctx.rotate(((layer.rotation + animRot) * Math.PI) / 180);

                    ctx.transform(
                        layer.scaleX * animScale, 
                        Math.tan((layer.tiltY * Math.PI) / 180), 
                        Math.tan((layer.tiltX * Math.PI) / 180), 
                        layer.scaleY * animScale, 
                        0, 0
                    );

                    ctx.filter = `
                        brightness(${layer.brightness}%) 
                        contrast(${layer.contrast}%) 
                        saturate(${layer.saturation}%) 
                        blur(${layer.blur}px) 
                        hue-rotate(${layer.hue}deg)
                        invert(${layer.invert}%)
                    `.trim();

                    if (layer.edgeGlow || layer.outerGlow) {
                        ctx.shadowColor = layer.edgeGlow ? layer.edgeGlowColor : layer.outerGlowColor;
                        ctx.shadowBlur = (layer.edgeGlow ? layer.edgeGlowSize : layer.outerGlowBlur) + animGlowOffset;
                    } else {
                        ctx.shadowColor = 'transparent';
                        ctx.shadowBlur = 0;
                    }

                    if (layer.type === 'solid') {
                        ctx.fillStyle = layer.color;
                        ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height);
                    } else if (layer.type === 'text') {
                        ctx.font = `${layer.fontSize}px "${layer.fontFamily}", sans-serif`;
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';

                        if (layer.useGradient) {
                            const grad = ctx.createLinearGradient(-100, 0, 100, 0);
                            grad.addColorStop(0, layer.color);
                            grad.addColorStop(1, layer.gradientColor2);
                            ctx.fillStyle = grad;
                        } else {
                            ctx.fillStyle = layer.color;
                        }

                        ctx.fillText(layer.text, 0, 0);
                    } else if (layer.type === 'image' && layer.image && layer.image.complete) {
                        ctx.drawImage(layer.image, -layer.width / 2, -layer.height / 2, layer.width, layer.height);
                    }

                    ctx.restore();
                });

                if (this.showGrid) {
                    ctx.save();
                    ctx.strokeStyle = 'rgba(255,255,255,0.15)';
                    ctx.lineWidth = 1;
                    const step = 100;
                    for (let x = 0; x < this.width; x += step) {
                        ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, this.height); ctx.stroke();
                    }
                    for (let y = 0; y < this.height; y += step) {
                        ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(this.width, y); ctx.stroke();
                    }
                    ctx.restore();
                }
            },

            // --- TOUCH / MOUSE INTERACTION ENGINE ---
            setupTouchPinchZoom() {
                const container = document.getElementById('workspace-container');
                let isDragging = false;
                let startX, startY;
                let activeLayer = null;

                const getCanvasCoords = (e) => {
                    const rect = this.canvas.getBoundingClientRect();
                    const clientX = e.touches ? e.touches[0].clientX : e.clientX;
                    const clientY = e.touches ? e.touches[0].clientY : e.clientY;
                    return {
                        x: (clientX - rect.left) * (this.width / rect.width),
                        y: (clientY - rect.top) * (this.height / rect.height)
                    };
                };

                const onPointerDown = (e) => {
                    if (e.target.closest('#sub-panel') || e.target.closest('header') || e.target.closest('aside')) return;

                    const coords = getCanvasCoords(e);
                    activeLayer = this.getSelectedLayer();

                    if (activeLayer && !activeLayer.locked) {
                        isDragging = true;
                        startX = coords.x - activeLayer.x;
                        startY = coords.y - activeLayer.y;
                    }
                };

                const onPointerMove = (e) => {
                    if (!isDragging || !activeLayer || activeLayer.locked) return;
                    const coords = getCanvasCoords(e);
                    activeLayer.x = coords.x - startX;
                    activeLayer.y = coords.y - startY;
                    this.requestRender();
                };

                const onPointerUp = () => {
                    if (isDragging) {
                        isDragging = false;
                        this.saveHistory();
                    }
                };

                container.addEventListener('mousedown', onPointerDown);
                window.addEventListener('mousemove', onPointerMove);
                window.addEventListener('mouseup', onPointerUp);

                container.addEventListener('touchstart', onPointerDown, { passive: true });
                window.addEventListener('touchmove', onPointerMove, { passive: true });
                window.addEventListener('touchend', onPointerUp);
            },

            // --- UI INSPECTOR PANELS (PC & MOBILE) ---
            openEditorSubTab(tabName) {
                AudioEngine.playClick();
                this.activeEditorTab = tabName;

                // Sync mobile active tab
                document.querySelectorAll('.editor-mobile-tab').forEach(b => b.classList.toggle('active', b.dataset.editorTab === tabName));
                
                const subPanel = document.getElementById('sub-panel');
                subPanel.classList.remove('translate-y-full');

                this.refreshEditorInspector();
            },

            refreshEditorInspector() {
                const currentLayer = this.getSelectedLayer();
                const tabName = this.activeEditorTab;

                // Target desktop and mobile containers
                const desktopContent = document.getElementById('desktop-inspector-content');
                const mobileContent = document.getElementById('sub-panel-content');
                const mobileTitle = document.getElementById('sub-panel-title');

                let htmlContent = '';

                if (tabName === 'canvas') {
                    if (mobileTitle) mobileTitle.innerText = 'Размер Холста';
                    htmlContent = `
                        <div class="space-y-3">
                            <button onclick="App.createNewProjectWithDimensions(1080,1920,'9:16 Mobile')" class="w-full p-3 bg-white/5 border border-white/10 rounded-2xl text-left text-xs text-white hover:bg-white/10 flex justify-between items-center">
                                <div><div class="font-bold">9:16 Mobile</div><div class="text-[10px] text-white/50">1080 × 1920</div></div>
                                <i class="fa-solid fa-chevron-right text-white/30"></i>
                            </button>
                            <button onclick="App.createNewProjectWithDimensions(1080,1080,'1:1 Квадрат')" class="w-full p-3 bg-white/5 border border-white/10 rounded-2xl text-left text-xs text-white hover:bg-white/10 flex justify-between items-center">
                                <div><div class="font-bold">1:1 Квадрат</div><div class="text-[10px] text-white/50">1080 × 1080</div></div>
                                <i class="fa-solid fa-chevron-right text-white/30"></i>
                            </button>
                            <button onclick="App.createNewProjectWithDimensions(1920,1080,'16:9 Landscape')" class="w-full p-3 bg-white/5 border border-white/10 rounded-2xl text-left text-xs text-white hover:bg-white/10 flex justify-between items-center">
                                <div><div class="font-bold">16:9 ПК / Landscape</div><div class="text-[10px] text-white/50">1920 × 1080</div></div>
                                <i class="fa-solid fa-chevron-right text-white/30"></i>
                            </button>
                        </div>
                    `;
                } else if (tabName === 'layers') {
                    if (mobileTitle) mobileTitle.innerText = 'Слои';
                    htmlContent = `
                        <div class="space-y-2">
                            ${this.layers.slice().reverse().map(layer => `
                                <div class="p-3 rounded-2xl ${layer.id === this.selectedLayerId ? 'bg-blue-600/20 border-blue-500/50' : 'bg-white/5 border-white/5'} border flex items-center justify-between">
                                    <div class="flex items-center space-x-3 cursor-pointer flex-1" onclick="App.selectLayer(${layer.id})">
                                        <i class="fa-solid ${layer.type === 'text' ? 'fa-font' : layer.type === 'image' ? 'fa-image' : 'fa-square'} text-white/60 text-sm"></i>
                                        <span class="text-xs text-white font-medium truncate max-w-[100px]">${layer.name}</span>
                                    </div>
                                    <div class="flex items-center space-x-2">
                                        <button onclick="App.toggleLayerVisibility(${layer.id})" class="text-white/40 hover:text-white text-xs"><i class="fa-solid ${layer.visible ? 'fa-eye' : 'fa-eye-slash'}"></i></button>
                                        <button onclick="App.moveLayer(${layer.id}, 'up')" class="text-white/40 hover:text-white text-xs"><i class="fa-solid fa-chevron-up"></i></button>
                                        <button onclick="App.moveLayer(${layer.id}, 'down')" class="text-white/40 hover:text-white text-xs"><i class="fa-solid fa-chevron-down"></i></button>
                                        <button onclick="App.duplicateLayer(${layer.id})" class="text-white/40 hover:text-white text-xs"><i class="fa-solid fa-clone"></i></button>
                                        <button onclick="App.deleteLayer(${layer.id})" class="text-red-400 hover:text-red-300 text-xs"><i class="fa-solid fa-trash"></i></button>
                                    </div>
                                </div>
                            `).join('')}
                        </div>
                    `;
                } else if (tabName === 'add') {
                    if (mobileTitle) mobileTitle.innerText = 'Добавить';
                    htmlContent = `
                        <div class="grid grid-cols-2 gap-3">
                            <button onclick="document.getElementById('file-upload-input').click()" class="p-3.5 bg-white/5 border border-white/10 rounded-2xl text-left hover:bg-white/10 flex items-center space-x-3">
                                <i class="fa-solid fa-image text-blue-400 text-lg"></i>
                                <div>
                                    <div class="text-xs font-semibold text-white">Из галереи</div>
                                    <div class="text-[10px] text-white/40">Файл фото</div>
                                </div>
                            </button>
                            <button onclick="App.addTextLayer()" class="p-3.5 bg-white/5 border border-white/10 rounded-2xl text-left hover:bg-white/10 flex items-center space-x-3">
                                <i class="fa-solid fa-font text-purple-400 text-lg"></i>
                                <div>
                                    <div class="text-xs font-semibold text-white">Текст</div>
                                    <div class="text-[10px] text-white/40">Надпись</div>
                                </div>
                            </button>
                        </div>

                        <div class="mt-3">
                            <h4 class="text-[11px] font-semibold text-white/60 mb-2">Оверлеи и Эффекты</h4>
                            <div class="grid grid-cols-2 gap-2">
                                ${this.stockOverlays.map((o, idx) => `
                                    <button onclick="App.addStockOverlay(App.stockOverlays[${idx}])" class="p-2 bg-white/5 border border-white/10 rounded-xl text-xs text-white/80 hover:bg-white/10 text-center truncate">
                                        ${o.name}
                                    </button>
                                `).join('')}
                            </div>
                        </div>
                    `;
                } else if (tabName === 'adjust') {
                    if (mobileTitle) mobileTitle.innerText = 'Коррекция';
                    if (!currentLayer) {
                        htmlContent = `<p class="text-xs text-white/40 text-center py-4">Выберите слой для настройки</p>`;
                    } else {
                        htmlContent = `
                            <div class="space-y-3">
                                <div>
                                    <div class="flex justify-between text-xs text-white/70 mb-1">
                                        <span>Прозрачность</span>
                                        <span>${Math.round(currentLayer.opacity * 100)}%</span>
                                    </div>
                                    <input type="range" min="0" max="1" step="0.01" value="${currentLayer.opacity}" oninput="App.updateLayerProp('opacity', parseFloat(this.value))" class="w-full">
                                </div>

                                ${currentLayer.type === 'text' ? `
                                <div>
                                    <label class="text-xs text-white/70 block mb-1">Текст надписи</label>
                                    <input type="text" value="${currentLayer.text}" onchange="App.updateLayerProp('text', this.value)" class="w-full bg-white/5 border border-white/10 rounded-xl px-3 py-1.5 text-xs text-white">
                                </div>
                                <div class="grid grid-cols-2 gap-2">
                                    <div>
                                        <label class="text-xs text-white/70 block mb-1">Шрифт</label>
                                        <select onchange="App.updateLayerProp('fontFamily', this.value)" class="w-full bg-white/5 border border-white/10 rounded-xl px-2 py-1.5 text-xs text-white">
                                            ${this.customFonts.map(f => `<option value="${f}" ${currentLayer.fontFamily === f ? 'selected' : ''} class="bg-zinc-900">${f}</option>`).join('')}
                                        </select>
                                    </div>
                                    <div>
                                        <label class="text-xs text-white/70 block mb-1">Цвет</label>
                                        <input type="color" value="${currentLayer.color}" onchange="App.updateLayerProp('color', this.value)" class="w-full h-8 bg-transparent cursor-pointer rounded-lg">
                                    </div>
                                </div>
                                ` : ''}

                                <div>
                                    <div class="flex justify-between text-xs text-white/70 mb-1"><span>Яркость</span><span>${currentLayer.brightness}%</span></div>
                                    <input type="range" min="0" max="200" value="${currentLayer.brightness}" oninput="App.updateLayerProp('brightness', parseInt(this.value))" class="w-full">
                                </div>
                                <div>
                                    <div class="flex justify-between text-xs text-white/70 mb-1"><span>Контраст</span><span>${currentLayer.contrast}%</span></div>
                                    <input type="range" min="0" max="200" value="${currentLayer.contrast}" oninput="App.updateLayerProp('contrast', parseInt(this.value))" class="w-full">
                                </div>
                                <div>
                                    <div class="flex justify-between text-xs text-white/70 mb-1"><span>Насыщенность</span><span>${currentLayer.saturation}%</span></div>
                                    <input type="range" min="0" max="200" value="${currentLayer.saturation}" oninput="App.updateLayerProp('saturation', parseInt(this.value))" class="w-full">
                                </div>
                            </div>
                        `;
                    }
                } else if (tabName === 'fx') {
                    if (mobileTitle) mobileTitle.innerText = 'CapCut FX & 3D';
                    if (!currentLayer) {
                        htmlContent = `<p class="text-xs text-white/40 text-center py-4">Выберите слой для эффектов</p>`;
                    } else {
                        htmlContent = `
                            <div class="space-y-3">
                                <div class="p-3 bg-white/5 border border-white/10 rounded-2xl space-y-2">
                                    <h4 class="text-xs font-semibold text-blue-400 uppercase tracking-wider">3D Угол и Поворот</h4>
                                    <div>
                                        <div class="flex justify-between text-xs text-white/70 mb-1"><span>Угол X</span><span>${currentLayer.tiltX}°</span></div>
                                        <input type="range" min="-45" max="45" value="${currentLayer.tiltX}" oninput="App.updateLayerProp('tiltX', parseInt(this.value))" class="w-full">
                                    </div>
                                    <div>
                                        <div class="flex justify-between text-xs text-white/70 mb-1"><span>Угол Y</span><span>${currentLayer.tiltY}°</span></div>
                                        <input type="range" min="-45" max="45" value="${currentLayer.tiltY}" oninput="App.updateLayerProp('tiltY', parseInt(this.value))" class="w-full">
                                    </div>
                                    <div>
                                        <div class="flex justify-between text-xs text-white/70 mb-1"><span>Поворот</span><span>${currentLayer.rotation}°</span></div>
                                        <input type="range" min="0" max="360" value="${currentLayer.rotation}" oninput="App.updateLayerProp('rotation', parseInt(this.value))" class="w-full">
                                    </div>
                                </div>

                                <div class="p-3 bg-white/5 border border-white/10 rounded-2xl space-y-2">
                                    <div class="flex items-center justify-between">
                                        <h4 class="text-xs font-semibold text-pink-400 uppercase tracking-wider">Свечение по краям (CapCut)</h4>
                                        <input type="checkbox" ${currentLayer.edgeGlow ? 'checked' : ''} onchange="App.updateLayerProp('edgeGlow', this.checked)">
                                    </div>
                                    <div class="grid grid-cols-2 gap-2">
                                        <div>
                                            <label class="text-[10px] text-white/60">Цвет ауры</label>
                                            <input type="color" value="${currentLayer.edgeGlowColor}" onchange="App.updateLayerProp('edgeGlowColor', this.value)" class="w-full h-8 bg-transparent">
                                        </div>
                                        <div>
                                            <label class="text-[10px] text-white/60">Размер</label>
                                            <input type="range" min="5" max="60" value="${currentLayer.edgeGlowSize}" oninput="App.updateLayerProp('edgeGlowSize', parseInt(this.value))" class="w-full">
                                        </div>
                                    </div>
                                </div>

                                ${currentLayer.type === 'image' ? `
                                <div class="p-3 bg-white/5 border border-white/10 rounded-2xl space-y-2">
                                    <h4 class="text-xs font-semibold text-green-400 uppercase tracking-wider">Удаление фона (Хромакей)</h4>
                                    <div class="grid grid-cols-2 gap-2">
                                        <div>
                                            <label class="text-[10px] text-white/60">Удаляемый цвет</label>
                                            <input type="color" value="${currentLayer.chromaColor}" onchange="App.updateLayerProp('chromaColor', this.value)" class="w-full h-8 bg-transparent">
                                        </div>
                                        <div>
                                            <label class="text-[10px] text-white/60">Допуск</label>
                                            <input type="range" min="10" max="150" value="${currentLayer.chromaTolerance}" oninput="App.updateLayerProp('chromaTolerance', parseInt(this.value))" class="w-full">
                                        </div>
                                    </div>
                                    <button onclick="App.applyChromaKey(App.getSelectedLayer())" class="w-full py-1.5 bg-green-600/30 border border-green-500/50 rounded-xl text-xs text-green-300 font-medium hover:bg-green-600/50 transition">
                                        Удалить цвет
                                    </button>
                                </div>
                                ` : ''}

                                <div class="p-3 bg-white/5 border border-white/10 rounded-2xl space-y-2">
                                    <h4 class="text-xs font-semibold text-amber-400 uppercase tracking-wider">Анимация элемента</h4>
                                    <select onchange="App.updateLayerProp('animation', this.value)" class="w-full bg-white/5 border border-white/10 rounded-xl px-3 py-1.5 text-xs text-white">
                                        <option value="none" ${currentLayer.animation === 'none' ? 'selected' : ''} class="bg-zinc-900">Без анимации</option>
                                        <option value="pulse" ${currentLayer.animation === 'pulse' ? 'selected' : ''} class="bg-zinc-900">Пульсация</option>
                                        <option value="spin" ${currentLayer.animation === 'spin' ? 'selected' : ''} class="bg-zinc-900">Вращение 360</option>
                                        <option value="float" ${currentLayer.animation === 'float' ? 'selected' : ''} class="bg-zinc-900">Парение</option>
                                        <option value="glow" ${currentLayer.animation === 'glow' ? 'selected' : ''} class="bg-zinc-900">Мерцание</option>
                                    </select>
                                </div>
                            </div>
                        `;
                    }
                }

                if (desktopContent) desktopContent.innerHTML = htmlContent;
                if (mobileContent) mobileContent.innerHTML = htmlContent;
            },

            selectLayer(id) {
                AudioEngine.playClick();
                this.selectedLayerId = id;
                this.requestRender();
                this.refreshEditorInspector();
            },

            toggleLayerVisibility(id) {
                AudioEngine.playClick();
                const layer = this.layers.find(l => l.id === id);
                if (layer) {
                    layer.visible = !layer.visible;
                    this.requestRender();
                    this.refreshEditorInspector();
                }
            },

            updateLayerProp(prop, value) {
                const layer = this.getSelectedLayer();
                if (!layer) return;
                layer[prop] = value;
                this.requestRender();
            },

            // --- EXPORT PIPELINE ---
            exportCanvas(format, duration = 3) {
                AudioEngine.playClick();
                if (format === 'png' || format === 'jpeg') {
                    const dataUrl = this.canvas.toDataURL(`image/${format}`, 0.95);
                    const link = document.createElement('a');
                    link.download = `artstudio-export.${format}`;
                    link.href = dataUrl;
                    link.click();
                } else if (format === 'webm') {
                    const stream = this.canvas.captureStream(30);
                    const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
                    const chunks = [];

                    recorder.ondataavailable = e => chunks.push(e.data);
                    recorder.onstop = () => {
                        const blob = new Blob(chunks, { type: 'video/webm' });
                        const url = URL.createObjectURL(blob);
                        const link = document.createElement('a');
                        link.download = 'artstudio-animation.webm';
                        link.href = url;
                        link.click();
                    };

                    recorder.start();
                    setTimeout(() => recorder.stop(), duration * 1000);
                }
            },

            // --- EVENT LISTENERS & SETUP ---
            setupNavigation() {
                document.querySelectorAll('.view-tab-btn').forEach(btn => {
                    btn.addEventListener('click', () => this.openTab(btn.dataset.view));
                });
                document.getElementById('btn-home-logo').addEventListener('click', () => this.openTab('home'));
                document.getElementById('btn-open-my-works').addEventListener('click', () => this.openTab('projects'));
            },

            setupEventListeners() {
                document.getElementById('btn-lofi-toggle').addEventListener('click', () => AudioEngine.toggleLofi());

                // Home Action
                document.getElementById('btn-create-new-project').addEventListener('click', () => {
                    this.createNewProjectWithDimensions(1080, 1920, 'Проект ArtStudio');
                });

                document.getElementById('btn-create-custom-project').addEventListener('click', () => {
                    const w = parseInt(document.getElementById('custom-width').value) || 1080;
                    const h = parseInt(document.getElementById('custom-height').value) || 1080;
                    this.createNewProjectWithDimensions(w, h, 'Свой проект');
                    document.getElementById('custom-project-modal').classList.add('hidden');
                });

                // Editor Controls
                document.getElementById('btn-close-subpanel').addEventListener('click', () => {
                    document.getElementById('sub-panel').classList.add('translate-y-full');
                });

                document.querySelectorAll('.editor-mobile-tab').forEach(btn => {
                    btn.addEventListener('click', () => this.openEditorSubTab(btn.dataset.editorTab));
                });

                document.getElementById('btn-undo').addEventListener('click', () => this.undo());
                document.getElementById('btn-redo').addEventListener('click', () => this.redo());
                document.getElementById('btn-save-project').addEventListener('click', () => this.saveCurrentProjectToGallery());

                document.getElementById('btn-zoom-fit').addEventListener('click', () => this.fitZoomToScreen());
                document.getElementById('btn-toggle-grid').addEventListener('click', () => {
                    this.showGrid = !this.showGrid;
                    this.requestRender();
                });

                // Export Modal
                document.getElementById('btn-export-modal').addEventListener('click', () => {
                    document.getElementById('export-modal').classList.remove('hidden');
                });
                document.getElementById('btn-cancel-export').addEventListener('click', () => {
                    document.getElementById('export-modal').classList.add('hidden');
                });
                document.getElementById('export-format').addEventListener('change', (e) => {
                    document.getElementById('export-fps-container').classList.toggle('hidden', e.target.value !== 'webm');
                });
                document.getElementById('btn-do-export').addEventListener('click', () => {
                    const fmt = document.getElementById('export-format').value;
                    const dur = parseInt(document.getElementById('export-duration').value) || 3;
                    this.exportCanvas(fmt, dur);
                    document.getElementById('export-modal').classList.add('hidden');
                });

                // Settings Controls
                document.getElementById('setting-sound-toggle').addEventListener('change', (e) => {
                    AudioEngine.soundEnabled = e.target.checked;
                });
                document.getElementById('setting-lofi-toggle').addEventListener('change', () => {
                    AudioEngine.toggleLofi();
                });
                document.getElementById('setting-volume-slider').addEventListener('input', (e) => {
                    AudioEngine.volume = parseFloat(e.target.value);
                });

                // Search Palette
                document.getElementById('btn-search-trigger').addEventListener('click', () => {
                    document.getElementById('search-modal').classList.remove('hidden');
                    document.getElementById('search-input').focus();
                });
                document.getElementById('btn-close-search').addEventListener('click', () => {
                    document.getElementById('search-modal').classList.add('hidden');
                });
                document.getElementById('search-input').addEventListener('input', (e) => {
                    this.handleSearch(e.target.value);
                });

                // File Upload
                const hiddenInput = document.createElement('input');
                hiddenInput.type = 'file';
                hiddenInput.id = 'file-upload-input';
                hiddenInput.accept = 'image/*';
                hiddenInput.className = 'hidden';
                document.body.appendChild(hiddenInput);

                hiddenInput.addEventListener('change', (e) => {
                    const file = e.target.files[0];
                    if (!file) return;
                    const reader = new FileReader();
                    reader.onload = (evt) => {
                        const img = new Image();
                        img.onload = () => this.addImageLayer(img, file.name);
                        img.src = evt.target.result;
                    };
                    reader.readAsDataURL(file);
                });

                // Keyboard Shortcuts
                window.addEventListener('keydown', (e) => {
                    if (e.ctrlKey && e.key === 'z') {
                        e.preventDefault();
                        this.undo();
                    } else if (e.ctrlKey && e.key === 's') {
                        e.preventDefault();
                        if (this.currentView === 'editor') this.saveCurrentProjectToGallery();
                    }
                });
            },

            handleSearch(query) {
                const container = document.getElementById('search-results');
                if (!query.trim()) {
                    container.innerHTML = '';
                    return;
                }

                const tools = [
                    { name: "Добавить текст", action: () => { this.addTextLayer(); this.openEditorSubTab('adjust'); } },
                    { name: "Загрузить картинку", action: () => document.getElementById('file-upload-input').click() },
                    { name: "Свечение по краям (CapCut Edge Glow)", action: () => this.openEditorSubTab('fx') },
                    { name: "Удаление фона / Хромакей", action: () => this.openEditorSubTab('fx') },
                    { name: "3D Угол и Наклон (Tilt)", action: () => this.openEditorSubTab('fx') },
                    { name: "Изменить размер холста", action: () => this.openEditorSubTab('canvas') },
                    { name: "Добавить оверлей / Блик / Пыль", action: () => this.openEditorSubTab('add') },
                    { name: "Сохранить проект в галактику", action: () => this.saveCurrentProjectToGallery() }
                ];

                const filtered = tools.filter(t => t.name.toLowerCase().includes(query.toLowerCase()));
                container.innerHTML = filtered.map((t, idx) => `
                    <div onclick="App.executeSearchResult(${idx})" class="p-3 bg-white/5 hover:bg-white/10 rounded-xl cursor-pointer text-xs text-white flex items-center justify-between">
                        <span>${t.name}</span>
                        <i class="fa-solid fa-chevron-right text-white/30 text-[10px]"></i>
                    </div>
                `).join('') || `<p class="text-xs text-white/30 p-2">Ничего не найдено</p>`;

                this.currentSearchResults = filtered;
            },

            executeSearchResult(idx) {
                if (this.currentSearchResults && this.currentSearchResults[idx]) {
                    this.currentSearchResults[idx].action();
                    document.getElementById('search-modal').classList.add('hidden');
                }
            }
        };

        window.onload = () => {
            App.init();
        };
    </script>
</body>
</html>
```