Advanced site customization tool - Custom fonts, CSS/HTML editor, site downloader, YouTube thumbnail grabber, and more!
Size
69.1 KB
Version
1.1.1
Created
Feb 7, 2026
Updated
29 days ago
1// ==UserScript==
2// @name Menew
3// @description Advanced site customization tool - Custom fonts, CSS/HTML editor, site downloader, YouTube thumbnail grabber, and more!
4// @version 1.1.1
5// @match *://*/*
6// @icon https://chatgpt.com/cdn/assets/favicon-l4nq08hd.svg
7// @author TheRealFiveky!
8// @grant GM.getValue
9// @grant GM.setValue
10// @grant GM.xmlhttpRequest
11// @grant GM.setClipboard
12// @connect *
13// @run-at document-end
14// ==/UserScript==
15(function() {
16 'use strict';
17
18 // ============================================
19 // MENEW - Advanced Site Customization Tool
20 // Version: 1.0.1
21 // Created by: TheRealFiveky!
22 // ============================================
23
24 // UPDATE LOG
25 // v1.0.1 (Feature Update)
26 // - Added resizable panel with drag handles
27 // - Multiple UI themes (Purple, Blue, Green, Red, Dark, Light)
28 // - Site color changer with preset palettes
29 // - Advanced color customization tools
30 // - Theme persistence across sessions
31 // - Color picker integration
32 // - Quick color presets
33 // - Enhanced UI with more customization options
34 //
35 // v1.0.0 (Initial Release)
36 // - Custom font uploader with multiple font support
37 // - Full site downloader (HTML, CSS, JS, images)
38 // - YouTube thumbnail grabber and downloader
39 // - Live CSS/HTML editor with syntax highlighting
40 // - Persistent settings across page reloads
41 // - Stylish modern UI with animations
42 // - Draggable control panel
43 // - Font management system
44 // - Real-time preview for all changes
45
46 console.log('🎨 Menew v1.0.1 by TheRealFiveky! - Initializing...');
47
48 // ============================================
49 // THEME DEFINITIONS
50 // ============================================
51
52 const THEMES = {
53 purple: {
54 name: 'Purple Dream',
55 primary: '#667eea',
56 secondary: '#764ba2',
57 background: '#1e1e2e',
58 backgroundAlt: '#2a2a3e',
59 text: '#ffffff',
60 textAlt: 'rgba(255, 255, 255, 0.8)'
61 },
62 blue: {
63 name: 'Ocean Blue',
64 primary: '#4facfe',
65 secondary: '#00f2fe',
66 background: '#1a1a2e',
67 backgroundAlt: '#252541',
68 text: '#ffffff',
69 textAlt: 'rgba(255, 255, 255, 0.8)'
70 },
71 green: {
72 name: 'Forest Green',
73 primary: '#11998e',
74 secondary: '#38ef7d',
75 background: '#1a2a1e',
76 backgroundAlt: '#253a2e',
77 text: '#ffffff',
78 textAlt: 'rgba(255, 255, 255, 0.8)'
79 },
80 red: {
81 name: 'Crimson Fire',
82 primary: '#eb3349',
83 secondary: '#f45c43',
84 background: '#2a1a1e',
85 backgroundAlt: '#3a252e',
86 text: '#ffffff',
87 textAlt: 'rgba(255, 255, 255, 0.8)'
88 },
89 dark: {
90 name: 'Midnight Dark',
91 primary: '#434343',
92 secondary: '#000000',
93 background: '#0a0a0a',
94 backgroundAlt: '#1a1a1a',
95 text: '#ffffff',
96 textAlt: 'rgba(255, 255, 255, 0.8)'
97 },
98 light: {
99 name: 'Pure Light',
100 primary: '#667eea',
101 secondary: '#764ba2',
102 background: '#f5f5f5',
103 backgroundAlt: '#ffffff',
104 text: '#1a1a1a',
105 textAlt: 'rgba(0, 0, 0, 0.7)'
106 }
107 };
108
109 // ============================================
110 // UTILITY FUNCTIONS
111 // ============================================
112
113 function debounce(func, wait) {
114 let timeout;
115 return function executedFunction(...args) {
116 const later = () => {
117 clearTimeout(timeout);
118 func(...args);
119 };
120 clearTimeout(timeout);
121 timeout = setTimeout(later, wait);
122 };
123 }
124
125 // ============================================
126 // STORAGE MANAGEMENT
127 // ============================================
128
129 async function loadFonts() {
130 const fonts = await GM.getValue('menew_fonts', '[]');
131 return JSON.parse(fonts);
132 }
133
134 async function saveFonts(fonts) {
135 await GM.setValue('menew_fonts', JSON.stringify(fonts));
136 }
137
138 async function loadCustomCSS() {
139 return await GM.getValue('menew_custom_css_' + window.location.hostname, '');
140 }
141
142 async function saveCustomCSS(css) {
143 await GM.setValue('menew_custom_css_' + window.location.hostname, css);
144 }
145
146 async function loadCustomHTML() {
147 return await GM.getValue('menew_custom_html_' + window.location.hostname, '');
148 }
149
150 async function saveCustomHTML(html) {
151 await GM.setValue('menew_custom_html_' + window.location.hostname, html);
152 }
153
154 async function loadTheme() {
155 return await GM.getValue('menew_theme', 'purple');
156 }
157
158 async function saveTheme(theme) {
159 await GM.setValue('menew_theme', theme);
160 }
161
162 async function loadSiteColors() {
163 return await GM.getValue('menew_site_colors_' + window.location.hostname, '{}');
164 }
165
166 async function saveSiteColors(colors) {
167 await GM.setValue('menew_site_colors_' + window.location.hostname, colors);
168 }
169
170 async function loadPanelSize() {
171 return await GM.getValue('menew_panel_size', JSON.stringify({ width: 800, height: 600 }));
172 }
173
174 async function savePanelSize(size) {
175 await GM.setValue('menew_panel_size', JSON.stringify(size));
176 }
177
178 // ============================================
179 // FONT MANAGEMENT
180 // ============================================
181
182 async function applyFonts() {
183 const fonts = await loadFonts();
184 let fontFaceCSS = '';
185
186 fonts.forEach(font => {
187 fontFaceCSS += `
188 @font-face {
189 font-family: '${font.name}';
190 src: url('${font.data}');
191 }
192 `;
193
194 if (font.applyTo === 'all') {
195 fontFaceCSS += `
196 * {
197 font-family: '${font.name}', sans-serif !important;
198 }
199 `;
200 } else if (font.applyTo) {
201 fontFaceCSS += `
202 ${font.applyTo} {
203 font-family: '${font.name}', sans-serif !important;
204 }
205 `;
206 }
207 });
208
209 const existingStyle = document.getElementById('menew-font-style');
210 if (existingStyle) {
211 existingStyle.textContent = fontFaceCSS;
212 } else {
213 const style = document.createElement('style');
214 style.id = 'menew-font-style';
215 style.textContent = fontFaceCSS;
216 document.head.appendChild(style);
217 }
218
219 console.log('✅ Applied', fonts.length, 'custom fonts');
220 }
221
222 async function addFont(name, data, applyTo) {
223 const fonts = await loadFonts();
224 fonts.push({ name, data, applyTo, id: Date.now() });
225 await saveFonts(fonts);
226 await applyFonts();
227 console.log('✅ Font added:', name);
228 }
229
230 async function removeFont(fontId) {
231 let fonts = await loadFonts();
232 fonts = fonts.filter(f => f.id !== fontId);
233 await saveFonts(fonts);
234 await applyFonts();
235 console.log('✅ Font removed');
236 }
237
238 // ============================================
239 // CSS/HTML EDITOR
240 // ============================================
241
242 async function applyCustomCSS() {
243 const css = await loadCustomCSS();
244 if (!css) return;
245
246 const existingStyle = document.getElementById('menew-custom-css');
247 if (existingStyle) {
248 existingStyle.textContent = css;
249 } else {
250 const style = document.createElement('style');
251 style.id = 'menew-custom-css';
252 style.textContent = css;
253 document.head.appendChild(style);
254 }
255 console.log('✅ Applied custom CSS');
256 }
257
258 async function applyCustomHTML() {
259 const html = await loadCustomHTML();
260 if (!html) return;
261
262 const container = document.getElementById('menew-custom-html-container');
263 if (container) {
264 container.innerHTML = html;
265 } else {
266 const div = document.createElement('div');
267 div.id = 'menew-custom-html-container';
268 div.innerHTML = html;
269 document.body.appendChild(div);
270 }
271 console.log('✅ Applied custom HTML');
272 }
273
274 // ============================================
275 // COLOR MANAGEMENT
276 // ============================================
277
278 async function applySiteColors() {
279 const colorsJson = await loadSiteColors();
280 const colors = JSON.parse(colorsJson);
281
282 if (Object.keys(colors).length === 0) return;
283
284 let colorCSS = '';
285
286 if (colors.background) {
287 colorCSS += `body { background-color: ${colors.background} !important; }`;
288 }
289 if (colors.text) {
290 colorCSS += `body, p, span, div, a, li, td, th { color: ${colors.text} !important; }`;
291 }
292 if (colors.links) {
293 colorCSS += `a { color: ${colors.links} !important; }`;
294 }
295 if (colors.headings) {
296 colorCSS += `h1, h2, h3, h4, h5, h6 { color: ${colors.headings} !important; }`;
297 }
298 if (colors.buttons) {
299 colorCSS += `button, input[type="submit"], input[type="button"] { background-color: ${colors.buttons} !important; }`;
300 }
301
302 const existingStyle = document.getElementById('menew-site-colors');
303 if (existingStyle) {
304 existingStyle.textContent = colorCSS;
305 } else {
306 const style = document.createElement('style');
307 style.id = 'menew-site-colors';
308 style.textContent = colorCSS;
309 document.head.appendChild(style);
310 }
311
312 console.log('✅ Applied site colors');
313 }
314
315 async function clearSiteColors() {
316 await saveSiteColors('{}');
317 const style = document.getElementById('menew-site-colors');
318 if (style) style.remove();
319 console.log('✅ Cleared site colors');
320 }
321
322 // ============================================
323 // THEME MANAGEMENT
324 // ============================================
325
326 function applyThemeToPanel(themeName) {
327 const theme = THEMES[themeName];
328 const panel = document.querySelector('.menew-panel');
329 const button = document.querySelector('.menew-button');
330
331 if (!panel || !button) return;
332
333 // Update CSS variables
334 panel.style.setProperty('--menew-primary', theme.primary);
335 panel.style.setProperty('--menew-secondary', theme.secondary);
336 panel.style.setProperty('--menew-bg', theme.background);
337 panel.style.setProperty('--menew-bg-alt', theme.backgroundAlt);
338 panel.style.setProperty('--menew-text', theme.text);
339 panel.style.setProperty('--menew-text-alt', theme.textAlt);
340
341 // Update panel background
342 panel.style.background = `linear-gradient(135deg, ${theme.background} 0%, ${theme.backgroundAlt} 100%)`;
343
344 // Update header
345 const header = panel.querySelector('.menew-header');
346 if (header) {
347 header.style.background = `linear-gradient(135deg, ${theme.primary} 0%, ${theme.secondary} 100%)`;
348 }
349
350 // Update button
351 button.style.background = `linear-gradient(135deg, ${theme.primary} 0%, ${theme.secondary} 100%)`;
352 button.style.boxShadow = `0 8px 32px ${theme.primary}66`;
353
354 console.log('✅ Applied theme:', theme.name);
355 }
356
357 // ============================================
358 // SITE DOWNLOADER
359 // ============================================
360
361 async function downloadSite() {
362 console.log('📥 Starting site download...');
363
364 const siteName = window.location.hostname.replace(/\./g, '_');
365 const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
366
367 // Get all resources
368 const html = document.documentElement.outerHTML;
369 const cssLinks = Array.from(document.querySelectorAll('link[rel="stylesheet"]')).map(link => link.href);
370 const jsLinks = Array.from(document.querySelectorAll('script[src]')).map(script => script.src);
371 const images = Array.from(document.querySelectorAll('img[src]')).map(img => img.src);
372
373 // Create a comprehensive package
374 let packageContent = `
375===========================================
376MENEW SITE DOWNLOAD PACKAGE
377===========================================
378Site: ${window.location.href}
379Downloaded: ${new Date().toLocaleString()}
380By: Menew v1.0.1 (TheRealFiveky!)
381===========================================
382
383========== HTML CONTENT ==========
384${html}
385
386========== CSS LINKS ==========
387${cssLinks.join('\n')}
388
389========== JAVASCRIPT LINKS ==========
390${jsLinks.join('\n')}
391
392========== IMAGE LINKS ==========
393${images.join('\n')}
394
395========== INLINE STYLES ==========
396${Array.from(document.querySelectorAll('style')).map(s => s.textContent).join('\n\n')}
397
398========== INLINE SCRIPTS ==========
399${Array.from(document.querySelectorAll('script:not([src])')).map(s => s.textContent).join('\n\n')}
400
401===========================================
402END OF PACKAGE
403===========================================
404 `;
405
406 // Create download
407 const blob = new Blob([packageContent], { type: 'text/plain' });
408 const url = URL.createObjectURL(blob);
409 const a = document.createElement('a');
410 a.href = url;
411 a.download = `menew_${siteName}_${timestamp}.txt`;
412 document.body.appendChild(a);
413 a.click();
414 document.body.removeChild(a);
415 URL.revokeObjectURL(url);
416
417 console.log('✅ Site downloaded successfully!');
418 showNotification('Site downloaded successfully!', 'success');
419 }
420
421 // ============================================
422 // YOUTUBE THUMBNAIL GRABBER
423 // ============================================
424
425 function getYouTubeVideoId() {
426 const url = window.location.href;
427 let videoId = null;
428
429 // Regular YouTube video
430 const match1 = url.match(/[?&]v=([^&]+)/);
431 if (match1) videoId = match1[1];
432
433 // YouTube Shorts
434 const match2 = url.match(/\/shorts\/([^?&]+)/);
435 if (match2) videoId = match2[1];
436
437 // Embedded videos
438 const match3 = url.match(/\/embed\/([^?&]+)/);
439 if (match3) videoId = match3[1];
440
441 return videoId;
442 }
443
444 function getYouTubeThumbnails(videoId) {
445 return {
446 maxres: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`,
447 sd: `https://img.youtube.com/vi/${videoId}/sddefault.jpg`,
448 hq: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,
449 mq: `https://img.youtube.com/vi/${videoId}/mqdefault.jpg`,
450 default: `https://img.youtube.com/vi/${videoId}/default.jpg`
451 };
452 }
453
454 async function downloadThumbnail(url, quality) {
455 try {
456 const response = await fetch(url);
457 const blob = await response.blob();
458 const objectUrl = URL.createObjectURL(blob);
459
460 const a = document.createElement('a');
461 a.href = objectUrl;
462 a.download = `youtube_thumbnail_${quality}_${Date.now()}.jpg`;
463 document.body.appendChild(a);
464 a.click();
465 document.body.removeChild(a);
466 URL.revokeObjectURL(objectUrl);
467
468 showNotification(`Thumbnail (${quality}) downloaded!`, 'success');
469 } catch (error) {
470 console.error('Error downloading thumbnail:', error);
471 showNotification('Failed to download thumbnail', 'error');
472 }
473 }
474
475 async function copyThumbnailUrl(url) {
476 try {
477 await GM.setClipboard(url);
478 showNotification('Thumbnail URL copied to clipboard!', 'success');
479 } catch (error) {
480 console.error('Error copying URL:', error);
481 showNotification('Failed to copy URL', 'error');
482 }
483 }
484
485 // ============================================
486 // NOTIFICATION SYSTEM
487 // ============================================
488
489 function showNotification(message, type = 'info') {
490 const notification = document.createElement('div');
491 notification.className = `menew-notification menew-notification-${type}`;
492 notification.textContent = message;
493 notification.style.cssText = `
494 position: fixed;
495 top: 20px;
496 right: 20px;
497 background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'};
498 color: white;
499 padding: 16px 24px;
500 border-radius: 12px;
501 box-shadow: 0 10px 40px rgba(0,0,0,0.3);
502 z-index: 999999;
503 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
504 font-size: 14px;
505 font-weight: 500;
506 animation: menewSlideIn 0.3s ease-out;
507 `;
508
509 document.body.appendChild(notification);
510
511 setTimeout(() => {
512 notification.style.animation = 'menewSlideOut 0.3s ease-out';
513 setTimeout(() => notification.remove(), 300);
514 }, 3000);
515 }
516
517 // ============================================
518 // UI CREATION
519 // ============================================
520
521 function createUI() {
522 // Add global styles
523 const globalStyles = document.createElement('style');
524 globalStyles.textContent = `
525 @keyframes menewSlideIn {
526 from {
527 transform: translateX(400px);
528 opacity: 0;
529 }
530 to {
531 transform: translateX(0);
532 opacity: 1;
533 }
534 }
535
536 @keyframes menewSlideOut {
537 from {
538 transform: translateX(0);
539 opacity: 1;
540 }
541 to {
542 transform: translateX(400px);
543 opacity: 0;
544 }
545 }
546
547 @keyframes menewFadeIn {
548 from { opacity: 0; }
549 to { opacity: 1; }
550 }
551
552 @keyframes menewPulse {
553 0%, 100% { transform: scale(1); }
554 50% { transform: scale(1.05); }
555 }
556
557 .menew-button {
558 position: fixed;
559 bottom: 30px;
560 right: 30px;
561 width: 60px;
562 height: 60px;
563 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
564 border: none;
565 border-radius: 50%;
566 cursor: pointer;
567 z-index: 999998;
568 box-shadow: 0 8px 32px rgba(102, 126, 234, 0.4);
569 transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
570 display: flex;
571 align-items: center;
572 justify-content: center;
573 font-size: 28px;
574 color: white;
575 font-weight: bold;
576 animation: menewPulse 2s infinite;
577 }
578
579 .menew-button:hover {
580 transform: scale(1.1) rotate(90deg);
581 box-shadow: 0 12px 48px rgba(102, 126, 234, 0.6);
582 }
583
584 .menew-button:active {
585 transform: scale(0.95);
586 }
587
588 .menew-panel {
589 position: fixed;
590 top: 50%;
591 left: 50%;
592 transform: translate(-50%, -50%);
593 width: 800px;
594 height: 600px;
595 max-width: 90vw;
596 max-height: 90vh;
597 background: linear-gradient(135deg, #1e1e2e 0%, #2a2a3e 100%);
598 border-radius: 24px;
599 box-shadow: 0 20px 80px rgba(0, 0, 0, 0.5);
600 z-index: 999999;
601 display: none;
602 flex-direction: column;
603 overflow: hidden;
604 animation: menewFadeIn 0.3s ease-out;
605 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
606 resize: both;
607 min-width: 400px;
608 min-height: 300px;
609 }
610
611 .menew-panel.active {
612 display: flex;
613 }
614
615 .menew-resize-handle {
616 position: absolute;
617 width: 20px;
618 height: 20px;
619 background: rgba(255, 255, 255, 0.2);
620 border-radius: 4px;
621 transition: all 0.2s;
622 }
623
624 .menew-resize-handle:hover {
625 background: rgba(255, 255, 255, 0.4);
626 }
627
628 .menew-resize-handle.bottom-right {
629 bottom: 5px;
630 right: 5px;
631 cursor: nwse-resize;
632 }
633
634 .menew-resize-handle.bottom-left {
635 bottom: 5px;
636 left: 5px;
637 cursor: nesw-resize;
638 }
639
640 .menew-resize-handle.top-right {
641 top: 5px;
642 right: 5px;
643 cursor: nesw-resize;
644 }
645
646 .menew-resize-handle.top-left {
647 top: 5px;
648 left: 5px;
649 cursor: nwse-resize;
650 }
651
652 .menew-header {
653 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
654 padding: 20px 24px;
655 display: flex;
656 justify-content: space-between;
657 align-items: center;
658 cursor: move;
659 user-select: none;
660 }
661
662 .menew-title {
663 font-size: 24px;
664 font-weight: 700;
665 color: white;
666 margin: 0;
667 display: flex;
668 align-items: center;
669 gap: 12px;
670 }
671
672 .menew-version {
673 font-size: 12px;
674 opacity: 0.8;
675 font-weight: 400;
676 }
677
678 .menew-close {
679 background: rgba(255, 255, 255, 0.2);
680 border: none;
681 width: 32px;
682 height: 32px;
683 border-radius: 8px;
684 cursor: pointer;
685 color: white;
686 font-size: 20px;
687 display: flex;
688 align-items: center;
689 justify-content: center;
690 transition: all 0.2s;
691 }
692
693 .menew-close:hover {
694 background: rgba(255, 255, 255, 0.3);
695 transform: rotate(90deg);
696 }
697
698 .menew-tabs {
699 display: flex;
700 background: rgba(0, 0, 0, 0.2);
701 padding: 8px;
702 gap: 8px;
703 overflow-x: auto;
704 }
705
706 .menew-tab {
707 padding: 12px 20px;
708 background: transparent;
709 border: none;
710 color: rgba(255, 255, 255, 0.6);
711 cursor: pointer;
712 border-radius: 10px;
713 font-size: 14px;
714 font-weight: 600;
715 transition: all 0.2s;
716 white-space: nowrap;
717 }
718
719 .menew-tab:hover {
720 background: rgba(255, 255, 255, 0.1);
721 color: rgba(255, 255, 255, 0.9);
722 }
723
724 .menew-tab.active {
725 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
726 color: white;
727 }
728
729 .menew-content {
730 flex: 1;
731 overflow-y: auto;
732 padding: 24px;
733 }
734
735 .menew-tab-content {
736 display: none;
737 }
738
739 .menew-tab-content.active {
740 display: block;
741 animation: menewFadeIn 0.3s ease-out;
742 }
743
744 .menew-section {
745 background: rgba(255, 255, 255, 0.05);
746 border-radius: 16px;
747 padding: 20px;
748 margin-bottom: 20px;
749 }
750
751 .menew-section-title {
752 font-size: 18px;
753 font-weight: 600;
754 color: white;
755 margin: 0 0 16px 0;
756 display: flex;
757 align-items: center;
758 gap: 8px;
759 }
760
761 .menew-input {
762 width: 100%;
763 padding: 12px 16px;
764 background: rgba(0, 0, 0, 0.3);
765 border: 2px solid rgba(255, 255, 255, 0.1);
766 border-radius: 10px;
767 color: white;
768 font-size: 14px;
769 margin-bottom: 12px;
770 transition: all 0.2s;
771 box-sizing: border-box;
772 }
773
774 .menew-input:focus {
775 outline: none;
776 border-color: #667eea;
777 background: rgba(0, 0, 0, 0.4);
778 }
779
780 .menew-color-input {
781 width: 100%;
782 height: 50px;
783 padding: 4px;
784 background: rgba(0, 0, 0, 0.3);
785 border: 2px solid rgba(255, 255, 255, 0.1);
786 border-radius: 10px;
787 cursor: pointer;
788 margin-bottom: 12px;
789 transition: all 0.2s;
790 }
791
792 .menew-color-input:hover {
793 border-color: #667eea;
794 }
795
796 .menew-textarea {
797 width: 100%;
798 min-height: 200px;
799 padding: 16px;
800 background: rgba(0, 0, 0, 0.4);
801 border: 2px solid rgba(255, 255, 255, 0.1);
802 border-radius: 10px;
803 color: #a8dadc;
804 font-size: 13px;
805 font-family: 'Courier New', monospace;
806 margin-bottom: 12px;
807 resize: vertical;
808 transition: all 0.2s;
809 box-sizing: border-box;
810 }
811
812 .menew-textarea:focus {
813 outline: none;
814 border-color: #667eea;
815 }
816
817 .menew-button-primary {
818 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
819 color: white;
820 border: none;
821 padding: 12px 24px;
822 border-radius: 10px;
823 font-size: 14px;
824 font-weight: 600;
825 cursor: pointer;
826 transition: all 0.2s;
827 margin-right: 8px;
828 margin-bottom: 8px;
829 }
830
831 .menew-button-primary:hover {
832 transform: translateY(-2px);
833 box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
834 }
835
836 .menew-button-secondary {
837 background: rgba(255, 255, 255, 0.1);
838 color: white;
839 border: 2px solid rgba(255, 255, 255, 0.2);
840 padding: 12px 24px;
841 border-radius: 10px;
842 font-size: 14px;
843 font-weight: 600;
844 cursor: pointer;
845 transition: all 0.2s;
846 margin-right: 8px;
847 margin-bottom: 8px;
848 }
849
850 .menew-button-secondary:hover {
851 background: rgba(255, 255, 255, 0.2);
852 border-color: rgba(255, 255, 255, 0.3);
853 }
854
855 .menew-button-danger {
856 background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
857 color: white;
858 border: none;
859 padding: 8px 16px;
860 border-radius: 8px;
861 font-size: 12px;
862 font-weight: 600;
863 cursor: pointer;
864 transition: all 0.2s;
865 }
866
867 .menew-button-danger:hover {
868 transform: translateY(-2px);
869 box-shadow: 0 4px 16px rgba(239, 68, 68, 0.4);
870 }
871
872 .menew-theme-grid {
873 display: grid;
874 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
875 gap: 12px;
876 margin-top: 16px;
877 }
878
879 .menew-theme-card {
880 background: rgba(0, 0, 0, 0.3);
881 border: 2px solid rgba(255, 255, 255, 0.1);
882 border-radius: 12px;
883 padding: 16px;
884 cursor: pointer;
885 transition: all 0.2s;
886 text-align: center;
887 }
888
889 .menew-theme-card:hover {
890 transform: translateY(-4px);
891 border-color: rgba(255, 255, 255, 0.3);
892 }
893
894 .menew-theme-card.active {
895 border-color: #667eea;
896 background: rgba(102, 126, 234, 0.2);
897 }
898
899 .menew-theme-preview {
900 width: 100%;
901 height: 60px;
902 border-radius: 8px;
903 margin-bottom: 8px;
904 }
905
906 .menew-theme-name {
907 color: white;
908 font-size: 13px;
909 font-weight: 600;
910 }
911
912 .menew-color-preset-grid {
913 display: grid;
914 grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
915 gap: 12px;
916 margin-top: 16px;
917 }
918
919 .menew-color-preset {
920 height: 60px;
921 border-radius: 10px;
922 cursor: pointer;
923 transition: all 0.2s;
924 border: 2px solid rgba(255, 255, 255, 0.1);
925 display: flex;
926 align-items: center;
927 justify-content: center;
928 color: white;
929 font-size: 12px;
930 font-weight: 600;
931 text-shadow: 0 2px 4px rgba(0,0,0,0.5);
932 }
933
934 .menew-color-preset:hover {
935 transform: translateY(-4px);
936 box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
937 }
938
939 .menew-font-item {
940 background: rgba(0, 0, 0, 0.3);
941 padding: 16px;
942 border-radius: 12px;
943 margin-bottom: 12px;
944 display: flex;
945 justify-content: space-between;
946 align-items: center;
947 }
948
949 .menew-font-info {
950 color: white;
951 }
952
953 .menew-font-name {
954 font-size: 16px;
955 font-weight: 600;
956 margin-bottom: 4px;
957 }
958
959 .menew-font-target {
960 font-size: 12px;
961 opacity: 0.7;
962 }
963
964 .menew-label {
965 display: block;
966 color: rgba(255, 255, 255, 0.8);
967 font-size: 13px;
968 font-weight: 500;
969 margin-bottom: 8px;
970 }
971
972 .menew-file-input {
973 display: none;
974 }
975
976 .menew-file-label {
977 display: inline-block;
978 padding: 12px 24px;
979 background: rgba(255, 255, 255, 0.1);
980 border: 2px dashed rgba(255, 255, 255, 0.3);
981 border-radius: 10px;
982 color: white;
983 cursor: pointer;
984 transition: all 0.2s;
985 text-align: center;
986 margin-bottom: 12px;
987 }
988
989 .menew-file-label:hover {
990 background: rgba(255, 255, 255, 0.15);
991 border-color: #667eea;
992 }
993
994 .menew-thumbnail-grid {
995 display: grid;
996 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
997 gap: 16px;
998 margin-top: 16px;
999 }
1000
1001 .menew-thumbnail-item {
1002 background: rgba(0, 0, 0, 0.3);
1003 border-radius: 12px;
1004 overflow: hidden;
1005 transition: all 0.2s;
1006 }
1007
1008 .menew-thumbnail-item:hover {
1009 transform: translateY(-4px);
1010 box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
1011 }
1012
1013 .menew-thumbnail-img {
1014 width: 100%;
1015 height: 120px;
1016 object-fit: cover;
1017 }
1018
1019 .menew-thumbnail-actions {
1020 padding: 12px;
1021 display: flex;
1022 gap: 8px;
1023 }
1024
1025 .menew-thumbnail-btn {
1026 flex: 1;
1027 padding: 8px;
1028 background: rgba(255, 255, 255, 0.1);
1029 border: none;
1030 border-radius: 6px;
1031 color: white;
1032 font-size: 12px;
1033 cursor: pointer;
1034 transition: all 0.2s;
1035 }
1036
1037 .menew-thumbnail-btn:hover {
1038 background: rgba(255, 255, 255, 0.2);
1039 }
1040
1041 .menew-info-box {
1042 background: rgba(102, 126, 234, 0.1);
1043 border-left: 4px solid #667eea;
1044 padding: 16px;
1045 border-radius: 8px;
1046 color: rgba(255, 255, 255, 0.9);
1047 font-size: 13px;
1048 line-height: 1.6;
1049 margin-bottom: 20px;
1050 }
1051
1052 .menew-changelog {
1053 background: rgba(0, 0, 0, 0.3);
1054 padding: 20px;
1055 border-radius: 12px;
1056 color: white;
1057 font-size: 14px;
1058 line-height: 1.8;
1059 }
1060
1061 .menew-changelog h3 {
1062 color: #667eea;
1063 margin-top: 0;
1064 margin-bottom: 12px;
1065 }
1066
1067 .menew-changelog ul {
1068 margin: 8px 0;
1069 padding-left: 20px;
1070 }
1071
1072 .menew-changelog li {
1073 margin-bottom: 6px;
1074 }
1075
1076 .menew-scrollbar::-webkit-scrollbar {
1077 width: 8px;
1078 }
1079
1080 .menew-scrollbar::-webkit-scrollbar-track {
1081 background: rgba(0, 0, 0, 0.2);
1082 border-radius: 4px;
1083 }
1084
1085 .menew-scrollbar::-webkit-scrollbar-thumb {
1086 background: rgba(102, 126, 234, 0.5);
1087 border-radius: 4px;
1088 }
1089
1090 .menew-scrollbar::-webkit-scrollbar-thumb:hover {
1091 background: rgba(102, 126, 234, 0.7);
1092 }
1093
1094 .menew-content {
1095 scrollbar-width: thin;
1096 scrollbar-color: rgba(102, 126, 234, 0.5) rgba(0, 0, 0, 0.2);
1097 }
1098 `;
1099 document.head.appendChild(globalStyles);
1100
1101 // Create floating button
1102 const button = document.createElement('button');
1103 button.className = 'menew-button';
1104 button.innerHTML = '⚡';
1105 button.title = 'Open Menew Panel';
1106 document.body.appendChild(button);
1107
1108 // Create main panel
1109 const panel = document.createElement('div');
1110 panel.className = 'menew-panel';
1111 panel.innerHTML = `
1112 <div class="menew-resize-handle top-left"></div>
1113 <div class="menew-resize-handle top-right"></div>
1114 <div class="menew-resize-handle bottom-left"></div>
1115 <div class="menew-resize-handle bottom-right"></div>
1116
1117 <div class="menew-header">
1118 <div class="menew-title">
1119 ⚡ Menew
1120 <span class="menew-version">v1.0.1</span>
1121 </div>
1122 <button class="menew-close">×</button>
1123 </div>
1124
1125 <div class="menew-tabs">
1126 <button class="menew-tab active" data-tab="themes">🎨 Themes</button>
1127 <button class="menew-tab" data-tab="colors">🌈 Site Colors</button>
1128 <button class="menew-tab" data-tab="fonts">🔤 Fonts</button>
1129 <button class="menew-tab" data-tab="css">💅 CSS Editor</button>
1130 <button class="menew-tab" data-tab="html">📝 HTML Editor</button>
1131 <button class="menew-tab" data-tab="download">📥 Downloader</button>
1132 <button class="menew-tab" data-tab="youtube">🎬 YouTube</button>
1133 <button class="menew-tab" data-tab="about">ℹ️ About</button>
1134 </div>
1135
1136 <div class="menew-content menew-scrollbar">
1137 <!-- THEMES TAB -->
1138 <div class="menew-tab-content active" data-content="themes">
1139 <div class="menew-section">
1140 <h3 class="menew-section-title">🎨 Choose Your Theme</h3>
1141 <div class="menew-info-box">
1142 Select a theme to customize the Menew panel appearance. Your choice is saved automatically!
1143 </div>
1144
1145 <div class="menew-theme-grid" id="menew-theme-grid"></div>
1146 </div>
1147 </div>
1148
1149 <!-- SITE COLORS TAB -->
1150 <div class="menew-tab-content" data-content="colors">
1151 <div class="menew-section">
1152 <h3 class="menew-section-title">🌈 Customize Site Colors</h3>
1153 <div class="menew-info-box">
1154 Change the colors of the current website. Colors are saved per-domain and persist across page reloads.
1155 </div>
1156
1157 <label class="menew-label">Background Color</label>
1158 <input type="color" class="menew-color-input" id="menew-color-bg" value="#ffffff">
1159
1160 <label class="menew-label">Text Color</label>
1161 <input type="color" class="menew-color-input" id="menew-color-text" value="#000000">
1162
1163 <label class="menew-label">Link Color</label>
1164 <input type="color" class="menew-color-input" id="menew-color-links" value="#0066cc">
1165
1166 <label class="menew-label">Heading Color</label>
1167 <input type="color" class="menew-color-input" id="menew-color-headings" value="#1a1a1a">
1168
1169 <label class="menew-label">Button Color</label>
1170 <input type="color" class="menew-color-input" id="menew-color-buttons" value="#667eea">
1171
1172 <button class="menew-button-primary" id="menew-apply-colors">Apply Colors</button>
1173 <button class="menew-button-secondary" id="menew-clear-colors">Clear Colors</button>
1174 </div>
1175
1176 <div class="menew-section">
1177 <h3 class="menew-section-title">🎨 Quick Color Presets</h3>
1178 <div class="menew-color-preset-grid">
1179 <div class="menew-color-preset" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);" data-preset="purple">Purple</div>
1180 <div class="menew-color-preset" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);" data-preset="blue">Blue</div>
1181 <div class="menew-color-preset" style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);" data-preset="green">Green</div>
1182 <div class="menew-color-preset" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);" data-preset="pink">Pink</div>
1183 <div class="menew-color-preset" style="background: linear-gradient(135deg, #30cfd0 0%, #330867 100%);" data-preset="ocean">Ocean</div>
1184 <div class="menew-color-preset" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);" data-preset="sunset">Sunset</div>
1185 <div class="menew-color-preset" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);" data-preset="sky">Sky</div>
1186 <div class="menew-color-preset" style="background: linear-gradient(135deg, #0f0c29 0%, #302b63 100%);" data-preset="dark">Dark</div>
1187 </div>
1188 </div>
1189 </div>
1190
1191 <!-- FONTS TAB -->
1192 <div class="menew-tab-content" data-content="fonts">
1193 <div class="menew-section">
1194 <h3 class="menew-section-title">📤 Upload Custom Font</h3>
1195 <div class="menew-info-box">
1196 Upload your own font files (.ttf, .otf, .woff, .woff2) and apply them to any website!
1197 </div>
1198
1199 <label class="menew-label">Font Name</label>
1200 <input type="text" class="menew-input" id="menew-font-name" placeholder="e.g., My Custom Font">
1201
1202 <label class="menew-label">Font File</label>
1203 <input type="file" class="menew-file-input" id="menew-font-file" accept=".ttf,.otf,.woff,.woff2">
1204 <label for="menew-font-file" class="menew-file-label">
1205 📁 Choose Font File
1206 </label>
1207
1208 <label class="menew-label">Apply To (CSS Selector)</label>
1209 <input type="text" class="menew-input" id="menew-font-target" placeholder="e.g., body, h1, .class-name (leave empty for all elements)" value="all">
1210
1211 <button class="menew-button-primary" id="menew-add-font">Add Font</button>
1212 </div>
1213
1214 <div class="menew-section">
1215 <h3 class="menew-section-title">📚 Installed Fonts</h3>
1216 <div id="menew-fonts-list"></div>
1217 </div>
1218 </div>
1219
1220 <!-- CSS EDITOR TAB -->
1221 <div class="menew-tab-content" data-content="css">
1222 <div class="menew-section">
1223 <h3 class="menew-section-title">💅 Custom CSS Editor</h3>
1224 <div class="menew-info-box">
1225 Write custom CSS to modify the appearance of this site. Changes are saved automatically and persist across page reloads.
1226 </div>
1227
1228 <textarea class="menew-textarea" id="menew-css-editor" placeholder="/* Enter your custom CSS here */
1229body {
1230 background-color: #1a1a2e;
1231}
1232
1233h1 {
1234 color: #667eea;
1235}"></textarea>
1236
1237 <button class="menew-button-primary" id="menew-apply-css">Apply CSS</button>
1238 <button class="menew-button-secondary" id="menew-clear-css">Clear CSS</button>
1239 </div>
1240 </div>
1241
1242 <!-- HTML EDITOR TAB -->
1243 <div class="menew-tab-content" data-content="html">
1244 <div class="menew-section">
1245 <h3 class="menew-section-title">📝 Custom HTML Editor</h3>
1246 <div class="menew-info-box">
1247 Inject custom HTML elements into the page. Perfect for adding custom widgets, banners, or content blocks.
1248 </div>
1249
1250 <textarea class="menew-textarea" id="menew-html-editor" placeholder="<!-- Enter your custom HTML here -->
1251<div style='position: fixed; top: 10px; left: 10px; background: #667eea; color: white; padding: 20px; border-radius: 10px;'>
1252 <h2>Custom Widget</h2>
1253 <p>This is a custom HTML element!</p>
1254</div>"></textarea>
1255
1256 <button class="menew-button-primary" id="menew-apply-html">Apply HTML</button>
1257 <button class="menew-button-secondary" id="menew-clear-html">Clear HTML</button>
1258 </div>
1259 </div>
1260
1261 <!-- SITE DOWNLOADER TAB -->
1262 <div class="menew-tab-content" data-content="download">
1263 <div class="menew-section">
1264 <h3 class="menew-section-title">📥 Download Entire Site</h3>
1265 <div class="menew-info-box">
1266 Download all content from the current page including HTML, CSS, JavaScript, and image links. Perfect for archiving or offline viewing.
1267 </div>
1268
1269 <p style="color: rgba(255,255,255,0.8); margin-bottom: 16px;">
1270 Current Site: <strong style="color: #667eea;">${window.location.hostname}</strong>
1271 </p>
1272
1273 <button class="menew-button-primary" id="menew-download-site">
1274 📥 Download Site Package
1275 </button>
1276
1277 <div style="margin-top: 20px; padding: 16px; background: rgba(0,0,0,0.3); border-radius: 10px; color: rgba(255,255,255,0.7); font-size: 13px;">
1278 <strong>Package includes:</strong>
1279 <ul style="margin: 8px 0; padding-left: 20px;">
1280 <li>Complete HTML source code</li>
1281 <li>All CSS stylesheets (links)</li>
1282 <li>All JavaScript files (links)</li>
1283 <li>All image URLs</li>
1284 <li>Inline styles and scripts</li>
1285 </ul>
1286 </div>
1287 </div>
1288 </div>
1289
1290 <!-- YOUTUBE TOOLS TAB -->
1291 <div class="menew-tab-content" data-content="youtube">
1292 <div class="menew-section">
1293 <h3 class="menew-section-title">🎬 YouTube Thumbnail Grabber</h3>
1294 <div class="menew-info-box">
1295 Extract and download YouTube video thumbnails in multiple qualities. Works on regular videos and Shorts!
1296 </div>
1297
1298 <div id="menew-youtube-content"></div>
1299 </div>
1300 </div>
1301
1302 <!-- ABOUT TAB -->
1303 <div class="menew-tab-content" data-content="about">
1304 <div class="menew-section">
1305 <h3 class="menew-section-title">ℹ️ About Menew</h3>
1306 <div style="text-align: center; padding: 20px;">
1307 <div style="font-size: 48px; margin-bottom: 16px;">⚡</div>
1308 <h2 style="color: #667eea; margin: 0 0 8px 0;">Menew</h2>
1309 <p style="color: rgba(255,255,255,0.6); margin: 0 0 20px 0;">Advanced Site Customization Tool</p>
1310 <p style="color: white; margin: 0 0 8px 0;">Version 1.0.1</p>
1311 <p style="color: rgba(255,255,255,0.8); margin: 0;">Created by <strong style="color: #667eea;">TheRealFiveky!</strong></p>
1312 </div>
1313 </div>
1314
1315 <div class="menew-section">
1316 <h3 class="menew-section-title">📋 Features</h3>
1317 <div class="menew-changelog">
1318 <ul>
1319 <li>🎨 <strong>UI Themes</strong> - 6 beautiful themes to customize the panel</li>
1320 <li>🌈 <strong>Site Color Changer</strong> - Change any website's colors with presets</li>
1321 <li>📏 <strong>Resizable Panel</strong> - Drag corners to resize the control panel</li>
1322 <li>🔤 <strong>Custom Font Uploader</strong> - Upload and apply your own fonts</li>
1323 <li>💅 <strong>CSS Editor</strong> - Write custom CSS with live preview</li>
1324 <li>📝 <strong>HTML Editor</strong> - Inject custom HTML elements</li>
1325 <li>📥 <strong>Site Downloader</strong> - Download entire websites</li>
1326 <li>🎬 <strong>YouTube Thumbnail Grabber</strong> - Extract thumbnails in multiple qualities</li>
1327 <li>💾 <strong>Persistent Storage</strong> - All settings saved across sessions</li>
1328 <li>✨ <strong>Modern UI</strong> - Beautiful, responsive interface</li>
1329 </ul>
1330 </div>
1331 </div>
1332
1333 <div class="menew-section">
1334 <h3 class="menew-section-title">📝 Update Log</h3>
1335 <div class="menew-changelog">
1336 <h3>Version 1.0.1 (Feature Update)</h3>
1337 <ul>
1338 <li>🎨 Added 6 UI themes (Purple, Blue, Green, Red, Dark, Light)</li>
1339 <li>🌈 Site color changer with 8 quick presets</li>
1340 <li>📏 Resizable panel with drag handles</li>
1341 <li>🎯 Advanced color customization tools</li>
1342 <li>💾 Theme and size persistence</li>
1343 <li>🖌️ Color picker integration</li>
1344 <li>⚡ Enhanced UI with more options</li>
1345 </ul>
1346
1347 <h3>Version 1.0.0 (Initial Release)</h3>
1348 <ul>
1349 <li>✨ Initial release of Menew</li>
1350 <li>🔤 Custom font uploader</li>
1351 <li>📥 Full site downloader</li>
1352 <li>🎬 YouTube thumbnail grabber</li>
1353 <li>💅 Live CSS/HTML editor</li>
1354 <li>🎯 Draggable control panel</li>
1355 </ul>
1356 </div>
1357 </div>
1358
1359 <div class="menew-section">
1360 <h3 class="menew-section-title">💡 Tips</h3>
1361 <div class="menew-changelog">
1362 <ul>
1363 <li>Drag the panel header to move it around</li>
1364 <li>Drag the corner handles to resize the panel</li>
1365 <li>Choose a theme that matches your style</li>
1366 <li>Use color presets for quick site customization</li>
1367 <li>All settings are saved automatically per-domain</li>
1368 <li>CSS selectors like <code>body</code>, <code>h1</code> work for fonts</li>
1369 </ul>
1370 </div>
1371 </div>
1372 </div>
1373 </div>
1374 `;
1375 document.body.appendChild(panel);
1376
1377 // Setup resize functionality
1378 setupResize(panel);
1379
1380 // Make panel draggable
1381 setupDraggable(panel);
1382
1383 // Toggle panel
1384 button.addEventListener('click', () => {
1385 panel.classList.toggle('active');
1386 });
1387
1388 panel.querySelector('.menew-close').addEventListener('click', () => {
1389 panel.classList.remove('active');
1390 });
1391
1392 // Tab switching
1393 setupTabs(panel);
1394
1395 // Setup theme selector
1396 setupThemeSelector();
1397
1398 // Setup color controls
1399 setupColorControls();
1400
1401 // Font management
1402 setupFontManagement();
1403
1404 // CSS Editor
1405 setupCSSEditor();
1406
1407 // HTML Editor
1408 setupHTMLEditor();
1409
1410 // Site Downloader
1411 document.getElementById('menew-download-site').addEventListener('click', downloadSite);
1412
1413 // Load saved data
1414 loadSavedData();
1415 }
1416
1417 function setupResize(panel) {
1418 const handles = panel.querySelectorAll('.menew-resize-handle');
1419 let isResizing = false;
1420 let currentHandle = null;
1421 let startX, startY, startWidth, startHeight, startLeft, startTop;
1422
1423 handles.forEach(handle => {
1424 handle.addEventListener('mousedown', (e) => {
1425 isResizing = true;
1426 currentHandle = handle;
1427 startX = e.clientX;
1428 startY = e.clientY;
1429 startWidth = panel.offsetWidth;
1430 startHeight = panel.offsetHeight;
1431 startLeft = panel.offsetLeft;
1432 startTop = panel.offsetTop;
1433 e.stopPropagation();
1434 });
1435 });
1436
1437 document.addEventListener('mousemove', (e) => {
1438 if (!isResizing) return;
1439 e.preventDefault();
1440
1441 const deltaX = e.clientX - startX;
1442 const deltaY = e.clientY - startY;
1443
1444 if (currentHandle.classList.contains('bottom-right')) {
1445 panel.style.width = Math.max(400, startWidth + deltaX) + 'px';
1446 panel.style.height = Math.max(300, startHeight + deltaY) + 'px';
1447 } else if (currentHandle.classList.contains('bottom-left')) {
1448 const newWidth = Math.max(400, startWidth - deltaX);
1449 panel.style.width = newWidth + 'px';
1450 panel.style.height = Math.max(300, startHeight + deltaY) + 'px';
1451 panel.style.left = (startLeft + (startWidth - newWidth)) + 'px';
1452 } else if (currentHandle.classList.contains('top-right')) {
1453 const newHeight = Math.max(300, startHeight - deltaY);
1454 panel.style.width = Math.max(400, startWidth + deltaX) + 'px';
1455 panel.style.height = newHeight + 'px';
1456 panel.style.top = (startTop + (startHeight - newHeight)) + 'px';
1457 } else if (currentHandle.classList.contains('top-left')) {
1458 const newWidth = Math.max(400, startWidth - deltaX);
1459 const newHeight = Math.max(300, startHeight - deltaY);
1460 panel.style.width = newWidth + 'px';
1461 panel.style.height = newHeight + 'px';
1462 panel.style.left = (startLeft + (startWidth - newWidth)) + 'px';
1463 panel.style.top = (startTop + (startHeight - newHeight)) + 'px';
1464 }
1465 });
1466
1467 document.addEventListener('mouseup', async () => {
1468 if (isResizing) {
1469 isResizing = false;
1470 currentHandle = null;
1471 // Save panel size
1472 await savePanelSize({
1473 width: panel.offsetWidth,
1474 height: panel.offsetHeight
1475 });
1476 }
1477 });
1478 }
1479
1480 function setupDraggable(panel) {
1481 let isDragging = false;
1482 let currentX, currentY, initialX, initialY;
1483 const header = panel.querySelector('.menew-header');
1484
1485 header.addEventListener('mousedown', (e) => {
1486 if (e.target.closest('.menew-close')) return;
1487 isDragging = true;
1488 initialX = e.clientX - panel.offsetLeft;
1489 initialY = e.clientY - panel.offsetTop;
1490 });
1491
1492 document.addEventListener('mousemove', (e) => {
1493 if (!isDragging) return;
1494 e.preventDefault();
1495 currentX = e.clientX - initialX;
1496 currentY = e.clientY - initialY;
1497 panel.style.left = currentX + 'px';
1498 panel.style.top = currentY + 'px';
1499 panel.style.transform = 'none';
1500 });
1501
1502 document.addEventListener('mouseup', () => {
1503 isDragging = false;
1504 });
1505 }
1506
1507 function setupTabs(panel) {
1508 const tabs = panel.querySelectorAll('.menew-tab');
1509 const tabContents = panel.querySelectorAll('.menew-tab-content');
1510
1511 tabs.forEach(tab => {
1512 tab.addEventListener('click', () => {
1513 const targetTab = tab.dataset.tab;
1514
1515 tabs.forEach(t => t.classList.remove('active'));
1516 tab.classList.add('active');
1517
1518 tabContents.forEach(content => {
1519 content.classList.remove('active');
1520 if (content.dataset.content === targetTab) {
1521 content.classList.add('active');
1522 }
1523 });
1524
1525 if (targetTab === 'youtube') {
1526 updateYouTubeContent();
1527 }
1528 });
1529 });
1530 }
1531
1532 function setupThemeSelector() {
1533 const grid = document.getElementById('menew-theme-grid');
1534
1535 Object.entries(THEMES).forEach(([key, theme]) => {
1536 const card = document.createElement('div');
1537 card.className = 'menew-theme-card';
1538 card.dataset.theme = key;
1539
1540 const preview = document.createElement('div');
1541 preview.className = 'menew-theme-preview';
1542 preview.style.background = `linear-gradient(135deg, ${theme.primary} 0%, ${theme.secondary} 100%)`;
1543
1544 const name = document.createElement('div');
1545 name.className = 'menew-theme-name';
1546 name.textContent = theme.name;
1547
1548 card.appendChild(preview);
1549 card.appendChild(name);
1550 grid.appendChild(card);
1551
1552 card.addEventListener('click', async () => {
1553 document.querySelectorAll('.menew-theme-card').forEach(c => c.classList.remove('active'));
1554 card.classList.add('active');
1555 applyThemeToPanel(key);
1556 await saveTheme(key);
1557 showNotification(`Theme changed to ${theme.name}!`, 'success');
1558 });
1559 });
1560 }
1561
1562 function setupColorControls() {
1563 const colorPresets = {
1564 purple: { bg: '#1a1a2e', text: '#ffffff', links: '#667eea', headings: '#764ba2', buttons: '#667eea' },
1565 blue: { bg: '#0a1929', text: '#ffffff', links: '#4facfe', headings: '#00f2fe', buttons: '#4facfe' },
1566 green: { bg: '#0d1f12', text: '#ffffff', links: '#11998e', headings: '#38ef7d', buttons: '#11998e' },
1567 pink: { bg: '#2d1b2e', text: '#ffffff', links: '#fa709a', headings: '#fee140', buttons: '#fa709a' },
1568 ocean: { bg: '#0a1f2e', text: '#ffffff', links: '#30cfd0', headings: '#330867', buttons: '#30cfd0' },
1569 sunset: { bg: '#2e1a1f', text: '#ffffff', links: '#f093fb', headings: '#f5576c', buttons: '#f093fb' },
1570 sky: { bg: '#e3f2fd', text: '#1a1a1a', links: '#1976d2', headings: '#0d47a1', buttons: '#2196f3' },
1571 dark: { bg: '#000000', text: '#ffffff', links: '#666666', headings: '#999999', buttons: '#333333' }
1572 };
1573
1574 // Color preset buttons
1575 document.querySelectorAll('.menew-color-preset').forEach(preset => {
1576 preset.addEventListener('click', async () => {
1577 const presetName = preset.dataset.preset;
1578 const colors = colorPresets[presetName];
1579
1580 document.getElementById('menew-color-bg').value = colors.bg;
1581 document.getElementById('menew-color-text').value = colors.text;
1582 document.getElementById('menew-color-links').value = colors.links;
1583 document.getElementById('menew-color-headings').value = colors.headings;
1584 document.getElementById('menew-color-buttons').value = colors.buttons;
1585
1586 await saveSiteColors(JSON.stringify(colors));
1587 await applySiteColors();
1588 showNotification(`Applied ${presetName} color preset!`, 'success');
1589 });
1590 });
1591
1592 // Apply colors button
1593 document.getElementById('menew-apply-colors').addEventListener('click', async () => {
1594 const colors = {
1595 background: document.getElementById('menew-color-bg').value,
1596 text: document.getElementById('menew-color-text').value,
1597 links: document.getElementById('menew-color-links').value,
1598 headings: document.getElementById('menew-color-headings').value,
1599 buttons: document.getElementById('menew-color-buttons').value
1600 };
1601
1602 await saveSiteColors(JSON.stringify(colors));
1603 await applySiteColors();
1604 showNotification('Site colors applied!', 'success');
1605 });
1606
1607 // Clear colors button
1608 document.getElementById('menew-clear-colors').addEventListener('click', async () => {
1609 await clearSiteColors();
1610 showNotification('Site colors cleared!', 'success');
1611 });
1612 }
1613
1614 function setupFontManagement() {
1615 document.getElementById('menew-add-font').addEventListener('click', async () => {
1616 const nameInput = document.getElementById('menew-font-name');
1617 const fileInput = document.getElementById('menew-font-file');
1618 const targetInput = document.getElementById('menew-font-target');
1619
1620 const name = nameInput.value.trim();
1621 const file = fileInput.files[0];
1622 const target = targetInput.value.trim() || 'all';
1623
1624 if (!name || !file) {
1625 showNotification('Please provide font name and file', 'error');
1626 return;
1627 }
1628
1629 const reader = new FileReader();
1630 reader.onload = async (e) => {
1631 await addFont(name, e.target.result, target);
1632 nameInput.value = '';
1633 fileInput.value = '';
1634 targetInput.value = 'all';
1635 await updateFontsList();
1636 showNotification('Font added successfully!', 'success');
1637 };
1638 reader.readAsDataURL(file);
1639 });
1640 }
1641
1642 function setupCSSEditor() {
1643 document.getElementById('menew-apply-css').addEventListener('click', async () => {
1644 const css = document.getElementById('menew-css-editor').value;
1645 await saveCustomCSS(css);
1646 await applyCustomCSS();
1647 showNotification('CSS applied successfully!', 'success');
1648 });
1649
1650 document.getElementById('menew-clear-css').addEventListener('click', async () => {
1651 document.getElementById('menew-css-editor').value = '';
1652 await saveCustomCSS('');
1653 const style = document.getElementById('menew-custom-css');
1654 if (style) style.remove();
1655 showNotification('CSS cleared!', 'success');
1656 });
1657 }
1658
1659 function setupHTMLEditor() {
1660 document.getElementById('menew-apply-html').addEventListener('click', async () => {
1661 const html = document.getElementById('menew-html-editor').value;
1662 await saveCustomHTML(html);
1663 await applyCustomHTML();
1664 showNotification('HTML applied successfully!', 'success');
1665 });
1666
1667 document.getElementById('menew-clear-html').addEventListener('click', async () => {
1668 document.getElementById('menew-html-editor').value = '';
1669 await saveCustomHTML('');
1670 const container = document.getElementById('menew-custom-html-container');
1671 if (container) container.remove();
1672 showNotification('HTML cleared!', 'success');
1673 });
1674 }
1675
1676 async function updateFontsList() {
1677 const fonts = await loadFonts();
1678 const container = document.getElementById('menew-fonts-list');
1679
1680 if (fonts.length === 0) {
1681 container.innerHTML = '<p style="color: rgba(255,255,255,0.5); text-align: center; padding: 20px;">No fonts installed yet</p>';
1682 return;
1683 }
1684
1685 container.innerHTML = fonts.map(font => `
1686 <div class="menew-font-item">
1687 <div class="menew-font-info">
1688 <div class="menew-font-name">${font.name}</div>
1689 <div class="menew-font-target">Applied to: ${font.applyTo}</div>
1690 </div>
1691 <button class="menew-button-danger" onclick="window.menewRemoveFont(${font.id})">Remove</button>
1692 </div>
1693 `).join('');
1694 }
1695
1696 function updateYouTubeContent() {
1697 const container = document.getElementById('menew-youtube-content');
1698 const videoId = getYouTubeVideoId();
1699
1700 if (!videoId) {
1701 container.innerHTML = '<p style="color: rgba(255,255,255,0.7); text-align: center; padding: 20px;">Navigate to a YouTube video to use this feature</p>';
1702 return;
1703 }
1704
1705 const thumbnails = getYouTubeThumbnails(videoId);
1706
1707 container.innerHTML = `
1708 <p style="color: rgba(255,255,255,0.8); margin-bottom: 16px;">
1709 Video ID: <strong style="color: #667eea;">${videoId}</strong>
1710 </p>
1711
1712 <div class="menew-thumbnail-grid">
1713 ${Object.entries(thumbnails).map(([quality, url]) => `
1714 <div class="menew-thumbnail-item">
1715 <img src="${url}" class="menew-thumbnail-img" alt="${quality}">
1716 <div class="menew-thumbnail-actions">
1717 <button class="menew-thumbnail-btn" onclick="window.menewDownloadThumbnail('${url}', '${quality}')">
1718 📥 Download
1719 </button>
1720 <button class="menew-thumbnail-btn" onclick="window.menewCopyThumbnailUrl('${url}')">
1721 📋 Copy URL
1722 </button>
1723 </div>
1724 <div style="padding: 8px; text-align: center; color: rgba(255,255,255,0.7); font-size: 12px; text-transform: uppercase;">
1725 ${quality}
1726 </div>
1727 </div>
1728 `).join('')}
1729 </div>
1730 `;
1731 }
1732
1733 async function loadSavedData() {
1734 // Load and apply theme
1735 const savedTheme = await loadTheme();
1736 applyThemeToPanel(savedTheme);
1737 const themeCard = document.querySelector(`.menew-theme-card[data-theme="${savedTheme}"]`);
1738 if (themeCard) themeCard.classList.add('active');
1739
1740 // Load panel size
1741 const sizeJson = await loadPanelSize();
1742 const size = JSON.parse(sizeJson);
1743 const panel = document.querySelector('.menew-panel');
1744 if (panel) {
1745 panel.style.width = size.width + 'px';
1746 panel.style.height = size.height + 'px';
1747 }
1748
1749 // Load CSS
1750 const savedCSS = await loadCustomCSS();
1751 if (savedCSS) {
1752 document.getElementById('menew-css-editor').value = savedCSS;
1753 }
1754
1755 // Load HTML
1756 const savedHTML = await loadCustomHTML();
1757 if (savedHTML) {
1758 document.getElementById('menew-html-editor').value = savedHTML;
1759 }
1760
1761 // Load site colors
1762 const colorsJson = await loadSiteColors();
1763 const colors = JSON.parse(colorsJson);
1764 if (colors.background) document.getElementById('menew-color-bg').value = colors.background;
1765 if (colors.text) document.getElementById('menew-color-text').value = colors.text;
1766 if (colors.links) document.getElementById('menew-color-links').value = colors.links;
1767 if (colors.headings) document.getElementById('menew-color-headings').value = colors.headings;
1768 if (colors.buttons) document.getElementById('menew-color-buttons').value = colors.buttons;
1769
1770 // Update fonts list
1771 await updateFontsList();
1772 }
1773
1774 // Expose functions to window for onclick handlers
1775 window.menewRemoveFont = async (fontId) => {
1776 await removeFont(fontId);
1777 await updateFontsList();
1778 showNotification('Font removed!', 'success');
1779 };
1780
1781 window.menewDownloadThumbnail = downloadThumbnail;
1782 window.menewCopyThumbnailUrl = copyThumbnailUrl;
1783
1784 // ============================================
1785 // INITIALIZATION
1786 // ============================================
1787
1788 async function init() {
1789 console.log('🚀 Menew initializing...');
1790
1791 // Apply saved customizations
1792 await applyFonts();
1793 await applyCustomCSS();
1794 await applyCustomHTML();
1795 await applySiteColors();
1796
1797 // Create UI
1798 createUI();
1799
1800 console.log('✅ Menew initialized successfully!');
1801 console.log('💡 Click the ⚡ button in the bottom-right corner to open the panel');
1802 }
1803
1804 // Wait for DOM to be ready
1805 if (document.readyState === 'loading') {
1806 document.addEventListener('DOMContentLoaded', init);
1807 } else {
1808 init();
1809 }
1810
1811})();