(function () {
    'use strict';

    const SCRIPT_VERSION = '1.0.8';

    if (window.HerVoiceInputManager) {
        const existingVersion = window.HerVoiceInputManager._version;

        // 같은 버전이면 건너뛰기
        if (existingVersion === SCRIPT_VERSION) {
            return;
        } else {
            // 이전 인스턴스 정리
            if (window.voiceInputManager) {
                try {
                    window.voiceInputManager.buttonManager?.cleanup();
                } catch (e) {}
            }
        }
    }

    function debugLog(message, ...args) {
        // 로그 비활성화
    }

    // 입력 필드 유효성 검사 (최적화된 버전)
    class InputDetector {
        static isValidInput(element) {
            if (!element) {
                debugLog('[InputDetector] 요소가 없음');
                return false;
            }

            /* console.log('[InputDetector] 📋 요소 체크:', {
                tag: element.tagName,
                id: element.id,
                type: element.type,
                className: element.className,
                disabled: element.disabled,
                readOnly: element.readOnly,
                contentEditable: element.contentEditable
            }); */

            // 성능 최적화: 자주 사용되는 조건을 먼저 체크
            // readOnly만 체크, disabled는 허용 (음성 입력으로 활성화 가능)
            if (element.readOnly) {
                debugLog('[InputDetector] readOnly 필드 제외');
                return false;
            }

            const tag = element.tagName.toLowerCase();

            // 가장 일반적인 케이스들 먼저 처리
            if (tag === 'textarea') {
                debugLog('[InputDetector] textarea 유효함');
                return true;
            }

            if (tag === 'input') {
                const type = (element.type || 'text').toLowerCase();
                const isValid = ['text', 'search', 'email', 'url', 'tel', 'password'].includes(type);
                // console.log('[InputDetector] 🔍 input 타입 검사:', { type, isValid });
                return isValid;
            }
            
            // combobox role을 가진 요소 (네이버 검색 등)
            if (element.getAttribute('role') === 'combobox') {
                debugLog('[InputDetector] combobox role 유효함');
                return true;
            }

            // contentEditable 체크
            if (element.isContentEditable || element.contentEditable === 'true') {
                debugLog('[InputDetector] contentEditable 유효함');
                return true;
            }

            // 특정 사이트 특별 처리 (ChatGPT 등)
            if (element.id === 'prompt-textarea') {
                debugLog('[InputDetector] prompt-textarea 유효함');
                return true;
            }

            debugLog('[InputDetector] 유효하지 않은 입력 필드');
            return false;
        }
    }

    // Vibe Coding 마이크 버튼 컨테이너
    class VibeCodingButton {
        constructor(onClick) {
            this.container = null;
            // this.button = null; // 🚨 완전 제거 - 더 이상 사용하지 않음
            this.statusText = null;
            this.brandText = null;  // "Vibe Coding" 텍스트 참조 추가
            this.onClick = onClick;
            this.isVisible = false;
            this.currentStatus = 'ready'; // 'ready', 'recording', 'countdown'
            // 🔥 createButton() 호출 제거 - 필요할 때만 생성 (showButtonForInput에서)
            // this.createButton();
        }

        createButton() {
            if (this.container) {
                return;
            }

            // 컨테이너 생성 - 단일 버튼으로 통합
            this.container = document.createElement('div');
            this.container.className = 'vibe-coding-container';
            this.container.setAttribute('data-her-voice', 'true'); // 식별용
            
            // 기본 적응형 투명 스타일 설정
            this.setTransparentStyle();

            // 브랜딩 텍스트
            this.brandText = document.createElement('span');
            this.brandText.className = 'vibe-branding';
            this.brandText.textContent = 'Vibe Coding';
            this.brandText.style.pointerEvents = 'none'; // 클릭 이벤트가 부모로 전달되도록

            // 마이크 아이콘 버튼 생성 제거 - Vibe Coding 텍스트만 사용
            // this.button = document.createElement('button'); // 🚨 완전 제거
            
            // 🎤 아이콘을 statusText에 통합
            this.statusText = document.createElement('span');
            this.statusText.className = 'status-text';
            this.statusText.textContent = 'Ready';
            this.statusText.style.pointerEvents = 'none'; // 클릭 이벤트가 부모로 전달되도록

            // 한 줄 레이아웃으로 요소들 추가 (버튼 제외)
            this.container.appendChild(this.brandText);
            // this.container.appendChild(this.button); // 🚨 완전 제거
            this.container.appendChild(this.statusText);

            // this.updateIcon(false); // 🚨 제거: 기존 마이크 버튼 사용하지 않음

            // DOM 추가
            this.ensureButtonInDOM();

            this.container.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();

                // 🚨 클릭 후 즉시 원래 입력 필드로 포커스 복원
                const manager = window.voiceInputManager;
                if (manager && manager.currentInput) {
                    setTimeout(() => {
                        try {
                            manager.currentInput.focus();
                            debugLog('[MicButton] 입력 필드로 포커스 복원');
                        } catch (error) {
                            console.warn('[MicButton] 포커스 복원 실패:', error);
                        }
                    }, 10);
                }

                if (typeof this.onClick === 'function') {
                    this.onClick();
                }
            });

            // 호버 효과
            this.container.addEventListener('mouseenter', () => {
                this.container.style.transform = 'scale(1.05)';
            });

            this.container.addEventListener('mouseleave', () => {
                this.container.style.transform = 'scale(1)';
            });
        }

        // 페이지 배경색 감지
        detectPageBackground() {
            // 1. body 배경색/이미지 확인
            const bodyStyle = window.getComputedStyle(document.body);
            const bodyBg = bodyStyle.backgroundColor;
            const bodyBgImage = bodyStyle.backgroundImage;
            
            // 1-1. body gradient 확인
            if (bodyBgImage && bodyBgImage !== 'none') {
                const gradientBrightness = this.getGradientBrightness(bodyBgImage);
                if (gradientBrightness !== null) {
                    // console.log('[VibeCodingButton] 🎨 body gradient 감지:', { bodyBgImage, brightness: gradientBrightness, isDark: gradientBrightness < 128 });
                    return gradientBrightness < 128;
                }
            }
            
            // 1-2. body 배경색 확인
            if (bodyBg && bodyBg !== 'rgba(0, 0, 0, 0)' && bodyBg !== 'transparent') {
                const brightness = this.getColorBrightness(bodyBg);
                // console.log('[VibeCodingButton] 🎨 body 배경색 감지:', { bodyBg, brightness, isDark: brightness < 128 });
                return brightness < 128; // 128 미만이면 어두운 색
            }
            
            // 2. html 배경색/이미지 확인
            const htmlStyle = window.getComputedStyle(document.documentElement);
            const htmlBg = htmlStyle.backgroundColor;
            const htmlBgImage = htmlStyle.backgroundImage;
            
            // 2-1. html gradient 확인
            if (htmlBgImage && htmlBgImage !== 'none') {
                const gradientBrightness = this.getGradientBrightness(htmlBgImage);
                if (gradientBrightness !== null) {
                    // console.log('[VibeCodingButton] 🎨 html gradient 감지:', { htmlBgImage, brightness: gradientBrightness, isDark: gradientBrightness < 128 });
                    return gradientBrightness < 128;
                }
            }
            
            // 2-2. html 배경색 확인
            if (htmlBg && htmlBg !== 'rgba(0, 0, 0, 0)' && htmlBg !== 'transparent') {
                const brightness = this.getColorBrightness(htmlBg);
                // console.log('[VibeCodingButton] 🎨 html 배경색 감지:', { htmlBg, brightness, isDark: brightness < 128 });
                return brightness < 128;
            }
            
            // 3. 주요 컨테이너 요소들 확인
            const containers = ['main', 'article', '[role="main"]', '.container', '#root', '#app'];
            for (const selector of containers) {
                const element = document.querySelector(selector);
                if (element) {
                    const elementStyle = window.getComputedStyle(element);
                    const bg = elementStyle.backgroundColor;
                    const bgImage = elementStyle.backgroundImage;
                    
                    // 3-1. 컨테이너 gradient 확인
                    if (bgImage && bgImage !== 'none') {
                        const gradientBrightness = this.getGradientBrightness(bgImage);
                        if (gradientBrightness !== null) {
                            // console.log('[VibeCodingButton] 🎨 컨테이너 gradient 감지:', { selector, bgImage, brightness: gradientBrightness, isDark: gradientBrightness < 128 });
                            return gradientBrightness < 128;
                        }
                    }
                    
                    // 3-2. 컨테이너 배경색 확인
                    if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') {
                        const brightness = this.getColorBrightness(bg);
                        // console.log('[VibeCodingButton] 🎨 컨테이너 배경색 감지:', { selector, bg, brightness, isDark: brightness < 128 });
                        return brightness < 128;
                    }
                }
            }
            
            // 4. 배경색을 감지할 수 없으면 다크모드로 간주 (transparent 등의 경우)
            // console.log('[VibeCodingButton] 🎨 배경색 감지 실패 - 다크모드로 간주');
            return true; // 다크모드로 간주
        }
        
        // RGB 색상의 밝기 계산 (0-255)
        getColorBrightness(color) {
            // rgb(r, g, b) 또는 rgba(r, g, b, a) 형식 파싱
            const match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
            if (!match) return 128; // 기본값
            
            const [, r, g, b] = match.map(Number);
            // 인간의 눈이 인지하는 밝기 공식
            return Math.round(0.299 * r + 0.587 * g + 0.114 * b);
        }

        // Gradient에서 색상 추출 및 밝기 계산
        getGradientBrightness(backgroundImage) {
            try {
                // linear-gradient 패턴 매칭
                const gradientMatch = backgroundImage.match(/linear-gradient\([^)]+\)/);
                if (!gradientMatch) return null;
                
                const gradientStr = gradientMatch[0];
                
                // 색상값 추출 (hex, rgb, rgba, 색상명 등)
                const colorMatches = gradientStr.match(/(#[0-9a-fA-F]{3,6}|rgb\([^)]+\)|rgba\([^)]+\)|[a-zA-Z]+(?=\s|,|%))/g);
                if (!colorMatches || colorMatches.length === 0) return null;
                
                const brightnesses = [];
                
                for (const colorStr of colorMatches) {
                    let brightness = null;
                    
                    // 1. hex 색상 처리
                    if (colorStr.startsWith('#')) {
                        brightness = this.getHexBrightness(colorStr);
                    }
                    // 2. rgb/rgba 색상 처리
                    else if (colorStr.startsWith('rgb')) {
                        brightness = this.getColorBrightness(colorStr);
                    }
                    // 3. 색상명 처리 (기본적인 색상만)
                    else {
                        brightness = this.getNamedColorBrightness(colorStr);
                    }
                    
                    if (brightness !== null) {
                        brightnesses.push(brightness);
                    }
                }
                
                // 색상이 하나도 파싱되지 않으면 null 반환
                if (brightnesses.length === 0) return null;
                
                // 평균 밝기 계산
                const avgBrightness = brightnesses.reduce((sum, b) => sum + b, 0) / brightnesses.length;
                return Math.round(avgBrightness);
                
            } catch (error) {
                // console.log('[VibeCodingButton] gradient 파싱 에러:', error);
                return null;
            }
        }

        // Hex 색상의 밝기 계산
        getHexBrightness(hex) {
            // #RGB 또는 #RRGGBB 형식
            let cleanHex = hex.replace('#', '');
            
            // #RGB를 #RRGGBB로 확장
            if (cleanHex.length === 3) {
                cleanHex = cleanHex.split('').map(c => c + c).join('');
            }
            
            if (cleanHex.length !== 6) return null;
            
            const r = parseInt(cleanHex.substr(0, 2), 16);
            const g = parseInt(cleanHex.substr(2, 2), 16);
            const b = parseInt(cleanHex.substr(4, 2), 16);
            
            return Math.round(0.299 * r + 0.587 * g + 0.114 * b);
        }

        // 기본 색상명의 밝기 반환
        getNamedColorBrightness(colorName) {
            const namedColors = {
                'white': 255, 'black': 0, 'red': 76, 'green': 150, 'blue': 29,
                'yellow': 225, 'cyan': 179, 'magenta': 105, 'orange': 165,
                'purple': 73, 'pink': 171, 'brown': 101, 'gray': 128, 'grey': 128
            };
            
            return namedColors[colorName.toLowerCase()] || null;
        }

        // 시스템 다크모드 기반 간단한 투명 효과 설정
        setTransparentStyle() {
            if (!this.container) return;
            
            // 페이지 배경색 기반 감지 + 시스템 다크모드 폴백
            const isDarkMode = this.detectPageBackground();
            
            /* console.log('[VibeCodingButton] 🎨 테마 적용:', {
                isDarkMode,
                theme: isDarkMode ? 'light-on-dark' : 'dark-on-light'
            }); */
            
            // 기본 스타일
            const baseStyle = `
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 8px 12px;
                border-radius: 24px;
                cursor: pointer !important;
                font-size: 13px;
                font-weight: 500;
                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                backdrop-filter: blur(40px);
                -webkit-backdrop-filter: blur(40px);
                user-select: none;
                pointer-events: auto;
            `;
            
            let themeStyle;
            if (isDarkMode) {
                // 다크모드: 밝은 버튼
                themeStyle = `
                    background: rgba(255, 255, 255, 0.1);
                    border: 1px solid rgba(255, 255, 255, 0.2);
                    color: rgba(255, 255, 255, 0.9);
                    box-shadow: 0 -1px 0 0 rgba(255, 255, 255, 0.2), 0 4px 20px 0 rgba(255, 255, 255, 0.1) inset;
                `;
            } else {
                // 라이트모드: 진한 배경에 흰색 텍스트 (Ready 상태 기본)
                themeStyle = `
                    background: rgba(0, 0, 0, 0.25);
                    border: 1px solid rgba(255, 255, 255, 0.3);
                    color: rgba(255, 255, 255, 0.9);
                    box-shadow: 0 -1px 0 0 rgba(255, 255, 255, 0.2), 0 4px 20px 0 rgba(0, 0, 0, 0.1) inset;
                `;
            }
            
            this.container.style.cssText = baseStyle + themeStyle;
        }


        // 🚨 추가: 버튼이 DOM에 안전하게 추가되도록 보장
        ensureButtonInDOM() {
            if (!this.container) return;

            // 이미 DOM에 있고 연결되어 있다면 건너뛰기
            if (this.container.parentElement && document.contains(this.container)) {
                return;
            }

            // 🔍 iframe 체크
            const isInIframe = window.self !== window.top;
            
            // 🚨 DOM에서 기존 .vibe-coding-container 모두 제거 (중복 방지)
            const existingContainers = document.querySelectorAll('.vibe-coding-container');
            existingContainers.forEach(container => {
                if (container !== this.container) {
                    container.remove();
                    debugLog('[VibeCodingButton] 중복 컨테이너 제거됨');
                }
            });

            try {
                // DOM이 준비되었는지 확인
                if (document.body) {
                    document.body.appendChild(this.container);
                    debugLog(`[VibeCodingButton] 버튼이 DOM에 추가됨 ${isInIframe ? '(iframe 내부)' : '(메인 페이지)'}`);
                    
                    // 🔍 iframe인 경우 특별한 z-index 설정
                    if (isInIframe) {
                        this.container.style.setProperty('z-index', '999999999', 'important');
                        this.container.style.setProperty('position', 'fixed', 'important');
                        debugLog('[VibeCodingButton] iframe 내부 - 최고 z-index 적용');
                    }
                } else {
                    // DOM이 준비되지 않았다면 대기 후 재시도
                    setTimeout(() => this.ensureButtonInDOM(), 10);
                    debugLog('[VibeCodingButton] DOM 대기 중...');
                }
            } catch (error) {
                console.error('[VibeCodingButton] DOM 추가 실패:', error);
                // 실패해도 재시도
                setTimeout(() => this.ensureButtonInDOM(), 100);
            }
        }

        updateStatus(status, text) {
            // 상태 업데이트
            this.currentStatus = status;

            // 완전한 DOM 재동기화
            this.resyncWithDOM();

            // container가 없으면 조용히 무시 (showButtonForInput에서 생성됨)
            if (!this.container || !this.statusText) {
                return;
            }
            
            if (this.statusText && this.container) {
                // 🔥 모든 DOM 버튼에 대해 상태 클래스 완전 제거
                this.clearAllStatesFromAllButtons();
                
                // 기존 애니메이션과 스타일도 즉시 제거
                this.stopPulseAnimation();
                
                switch(status) {
                    case 'ready':
                        this.statusText.textContent = text || 'Ready';
                        // 🔥 강제로 모든 상태 스타일 초기화
                        if (this.container) {
                            this.container.style.removeProperty('background');
                            this.container.style.removeProperty('background-color');
                            this.container.style.removeProperty('border-color');
                            this.container.style.removeProperty('transform');
                            this.container.style.removeProperty('animation');
                            this.container.style.removeProperty('box-shadow');
                            this.stopPulseAnimation(); // 맥박 애니메이션 중지
                        }
                        
                        // Ready 상태 텍스트 색상 초기화
                        if (this.statusText) {
                            this.statusText.style.removeProperty('color');
                            this.statusText.style.removeProperty('font-weight');
                            this.statusText.style.removeProperty('animation');
                        }
                        
                        // "Vibe Coding" 텍스트 색상도 초기화 (중요!)
                        if (this.brandText) {
                            this.brandText.style.removeProperty('color');
                        }
                        
                        // Ready 상태 완료 후 테마 스타일 재적용
                        this.setTransparentStyle();
                        
                        // Ready 상태: "Vibe Coding"은 기본 테마 색상 유지 (이미 setTransparentStyle에서 적용됨)
                        
                        // 🚨 디버그 박스 제거
                        const debugBox = document.querySelector('#debug-countdown-box');
                        if (debugBox) {
                            debugBox.remove();
                            // 디버그 박스 제거
                        }
                        break;
                    case 'recording':
                        this.statusText.textContent = text || 'Recording...';
                        this.container.classList.add('recording-active');
                        
                        // 레코딩 상태는 항상 빨간색 (배경에 관계없이)
                        if (this.statusText) {
                            this.statusText.style.setProperty('color', 'rgba(255, 107, 107, 0.9)', 'important');
                        }
                        
                        // 페이지 배경에 따른 "Vibe Coding" 텍스트 색상
                        const isDarkBg = this.detectPageBackground();
                        if (this.brandText) {
                            if (!isDarkBg) {
                                // 라이트 모드: "Vibe Coding"을 어두운색으로
                                this.brandText.style.setProperty('color', 'rgba(0, 0, 0, 0.8)', 'important');
                            } else {
                                // 다크 모드: "Vibe Coding"을 흰색으로 유지
                                this.brandText.style.setProperty('color', 'rgba(255, 255, 255, 0.9)', 'important');
                            }
                        }
                        
                        // 레코딩 상태 적용
                        break;
                    case 'countdown':
                        this.statusText.textContent = text || 'Auto-sending...';
                        
                        // 페이지 배경에 따른 "Vibe Coding" 텍스트 색상
                        const isDarkBgCountdown = this.detectPageBackground();
                        if (this.brandText) {
                            if (!isDarkBgCountdown) {
                                // 라이트 모드: "Vibe Coding"을 어두운색으로
                                this.brandText.style.setProperty('color', 'rgba(0, 0, 0, 0.8)', 'important');
                            } else {
                                // 다크 모드: "Vibe Coding"을 흰색으로 유지
                                this.brandText.style.setProperty('color', 'rgba(255, 255, 255, 0.9)', 'important');
                            }
                        }
                        
                        // 🔥 모든 DOM 버튼에 카운트다운 상태 강제 적용
                        this.forceCountdownStateOnAllButtons();
                        
                        // 디버그 박스 제거 (프로덕션에서는 불필요)
                        // this.showDebugBox('COUNTDOWN ACTIVE - Force Applied', 'orange');
                        
                        // 카운트다운 상태 적용
                        break;
                }
            } else {
                console.error('[VibeCodingButton] ❌ 버튼 요소 생성 실패 - container:', !!this.container, 'statusText:', !!this.statusText);
            }
        }

        // 맥박 애니메이션 직접 구현
        startPulseAnimation() {
            if (!this.container) return;
            
            // 기존 애니메이션 중지
            if (this.pulseInterval) {
                clearInterval(this.pulseInterval);
            }
            
            let scale = 1.08;
            let growing = true;
            
            this.pulseInterval = setInterval(() => {
                if (growing) {
                    scale += 0.01;
                    if (scale >= 1.12) growing = false;
                } else {
                    scale -= 0.01;
                    if (scale <= 1.08) growing = true;
                }
                
                if (this.container && this.container.classList.contains('countdown-active')) {
                    this.container.style.setProperty('transform', `scale(${scale})`, 'important');
                } else {
                    // 카운트다운이 끝나면 애니메이션 중지
                    clearInterval(this.pulseInterval);
                    this.pulseInterval = null;
                }
            }, 50);
        }
        
        stopPulseAnimation() {
            if (this.pulseInterval) {
                clearInterval(this.pulseInterval);
                this.pulseInterval = null;
            }
        }
        
        // 🚨 디버그: 카운트다운 상태 박스 표시
        showDebugCountdownBox(message) {
            // 기존 디버그 박스 제거
            const existingBox = document.querySelector('#debug-countdown-box');
            if (existingBox) {
                existingBox.remove();
            }
            
            // 새 디버그 박스 생성
            const debugBox = document.createElement('div');
            debugBox.id = 'debug-countdown-box';
            debugBox.style.cssText = `
                position: fixed;
                top: 50px;
                left: 50%;
                transform: translateX(-50%);
                background: rgba(255, 0, 0, 0.9);
                color: white;
                padding: 20px 30px;
                border-radius: 15px;
                font-size: 18px;
                font-weight: bold;
                z-index: 2147483647;
                border: 3px solid #ff6b6b;
                box-shadow: 0 10px 30px rgba(255, 0, 0, 0.5);
                animation: debugPulse 1s ease-in-out infinite;
                font-family: monospace;
                text-align: center;
                min-width: 200px;
            `;
            
            // 애니메이션 스타일 추가
            if (!document.querySelector('#debug-countdown-style')) {
                const style = document.createElement('style');
                style.id = 'debug-countdown-style';
                style.textContent = `
                    @keyframes debugPulse {
                        0%, 100% { 
                            transform: translateX(-50%) scale(1); 
                            opacity: 1; 
                        }
                        50% { 
                            transform: translateX(-50%) scale(1.1); 
                            opacity: 0.8; 
                        }
                    }
                `;
                document.head.appendChild(style);
            }
            
            debugBox.innerHTML = `
                🚨 DEBUG: COUNTDOWN ACTIVE 🚨<br>
                <div style="font-size: 14px; margin-top: 8px;">${message}</div>
                <div style="font-size: 12px; margin-top: 5px; opacity: 0.8;">${new Date().toLocaleTimeString()}</div>
            `;
            
            document.body.appendChild(debugBox);
            
            // 10초 후 자동 제거 (또는 ready 상태가 될 때까지)
            setTimeout(() => {
                if (debugBox.parentNode) {
                    debugBox.remove();
                }
            }, 10000);
            
            // 디버그 박스
        }
        
        // 🔥 DOM의 모든 버튼에 강제 스타일 적용
        forceApplyCountdownToAllButtons() {
            // 카운트다운 스타일 적용
            
            // DOM의 모든 vibe-coding-container 찾기
            const allButtons = document.querySelectorAll('.vibe-coding-container');
            // 버튼 개수 확인
            
            allButtons.forEach((button, index) => {
                // 버튼 스타일 적용
                
                // 클래스 추가
                button.classList.remove('recording-active');
                button.classList.add('countdown-active');
                
                // 인라인 스타일 강제 적용
                button.style.cssText = `
                    background: rgba(255, 200, 100, 0.12) !important;
                    background-color: rgba(255, 200, 100, 0.12) !important;
                    border: 1px solid rgba(255, 200, 100, 0.5) !important;
                    border-color: rgba(255, 200, 100, 0.5) !important;
                    transform: scale(1.15) !important;
                    box-shadow: 0 8px 32px rgba(255, 200, 100, 0.8) !important;
                    animation: countdownPulse 1s ease-in-out infinite !important;
                    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
                `;
                
                // status-text 스타일도 변경
                const statusText = button.querySelector('.status-text');
                if (statusText) {
                    statusText.style.cssText = `
                        color: rgba(255, 200, 100, 1) !important;
                        font-weight: 700 !important;
                        animation: statusTextPulse 1s ease-in-out infinite !important;
                    `;
                }
                
                // 위치와 z-index 유지
                const existingStyle = window.getComputedStyle(button);
                button.style.setProperty('position', existingStyle.position || 'fixed', 'important');
                button.style.setProperty('z-index', '2147483647', 'important');
            });
            
            // 모든 버튼 스타일 적용 완료
        }
        
        // 🔍 버튼 상태 강제 검사 및 수정
        forceButtonStyleCheck() {
            // 버튼 상태 검사
            
            // DOM에서 실제 요소 찾기
            const actualButton = document.querySelector('.vibe-coding-container');
            const actualStatusText = actualButton ? actualButton.querySelector('.status-text') : null;
            
            // 🔥 실제 DOM 버튼 사용하도록 강제
            if (actualButton) {
                this.container = actualButton;
                this.statusText = actualStatusText || this.statusText;
                // DOM 버튼 교체
            } else {
                console.error('[VibeCodingButton] ❌ DOM에 버튼이 없음');
                return;
            }
            
            const isInDOM = document.body.contains(this.container);
            
            /* console.log('[VibeCodingButton] 🔍 DOM 상태 체크:', {
                containerExists: !!this.container,
                statusTextExists: !!this.statusText,
                isInDOM: isInDOM,
                actualButtonExists: !!actualButton,
                isSameElement: actualButton === this.container,
                containerClasses: Array.from(this.container.classList),
                actualButtonClasses: actualButton ? Array.from(actualButton.classList) : null
            }); */
            
            // 스타일 강제 적용 (무조건 적용)
            // 강제 스타일 적용
            this.container.style.setProperty('background', 'rgba(255, 200, 100, 0.12)', 'important');
            this.container.style.setProperty('background-color', 'rgba(255, 200, 100, 0.12)', 'important');
            this.container.style.setProperty('border', '1px solid rgba(255, 200, 100, 0.5)', 'important');
            this.container.style.setProperty('border-color', 'rgba(255, 200, 100, 0.5)', 'important');
            this.container.style.setProperty('transform', 'scale(1.15)', 'important');
            this.container.style.setProperty('box-shadow', '0 8px 32px rgba(255, 200, 100, 0.8)', 'important');
            this.container.style.setProperty('z-index', '2147483647', 'important');
            
            // statusText는 항상 주황색 (배경에 관계없이)
            if (this.statusText) {
                this.statusText.style.setProperty('color', 'rgba(255, 200, 100, 1)', 'important');
                this.statusText.style.setProperty('font-weight', '700', 'important');
            }
            
            // 잠시 후 실제 적용된 스타일 확인
            setTimeout(() => {
                const computedStyle = window.getComputedStyle(this.container);
                /* console.log('[VibeCodingButton] 🎨 강제 적용 후 실제 스타일:', {
                    backgroundColor: computedStyle.backgroundColor,
                    borderColor: computedStyle.borderColor,
                    transform: computedStyle.transform,
                    boxShadow: computedStyle.boxShadow,
                    zIndex: computedStyle.zIndex,
                    display: computedStyle.display,
                    visibility: computedStyle.visibility,
                    opacity: computedStyle.opacity
                }); */
            }, 100);
        }

        showAt(input) {
            if (!this.container || !input) {
                debugLog('[VibeCodingButton] showAt 실패 - container 또는 input 없음');
                return;
            }

            // 🚨 추가: DOM에 추가되었는지 확인하고 필요시 추가
            this.ensureButtonInDOM();

            // 실시간 위치 계산
            let rect = input.getBoundingClientRect();
            debugLog('[VibeCodingButton] 입력 필드 위치:', rect);

            // ChatGPT: 부모 컨테이너 중 가장 큰 것 사용
            if (window.location.hostname.includes('chatgpt.com') && rect.width < 500) {
                let parent = input.parentElement;
                while (parent && parent.getBoundingClientRect().width < 600) {
                    parent = parent.parentElement;
                }
                if (parent) rect = parent.getBoundingClientRect();
            }

            // position: fixed를 사용하므로 scroll 값 불필요 (viewport 기준 위치)
            
            // 🔍 Textarea는 위치 조정: 화면 위쪽으로 벗어나는 경우 아래쪽에 배치
            let buttonTop = rect.top - 40; // 기본: 위쪽 40px (viewport 기준)
            let buttonLeft = rect.left; // 좌측 정렬 (viewport 기준)
            
            // Textarea이고 버튼이 화면 위쪽으로 벗어나는 경우 -> 아래쪽에 배치
            if (input.tagName === 'TEXTAREA' && buttonTop < 0) {
                buttonTop = rect.bottom + 8; // 아래쪽 8px (viewport 기준)
                debugLog('[VibeCodingButton] 🔄 TEXTAREA 위치 조정: 위쪽 벗어남 -> 아래쪽 배치');
            }
            
            // 🔥 상단 경계 처리: top이 5px 미만이면 75px로 설정
            if (buttonTop < 5) {
                buttonTop = 75;
                debugLog('[VibeCodingButton] ⚠️ 상단 경계 처리: top < 5px -> 75px로 조정');
            }
            
            // 🔥 하단 경계 처리: 버튼이 화면 하단을 벗어나는 경우 위쪽으로 이동
            const buttonHeight = 40; // 버튼 대략적인 높이
            const buttonWidth = 140; // 버튼 대략적인 너비
            const windowHeight = window.innerHeight;
            const windowWidth = window.innerWidth;
            
            if (buttonTop + buttonHeight > windowHeight - 10) {
                buttonTop = windowHeight - buttonHeight - 10;
                debugLog('[VibeCodingButton] ⚠️ 하단 경계 처리: 화면 하단 벗어남 -> 위쪽으로 조정');
            }
            
            // 🔥 좌우 경계 처리: 버튼이 화면 좌우를 벗어나는 경우 조정
            if (buttonLeft < 10) {
                buttonLeft = 10;
                debugLog('[VibeCodingButton] ⚠️ 좌측 경계 처리: 좌측 벗어남 -> 우측으로 조정');
            } else if (buttonLeft + buttonWidth > windowWidth - 10) {
                buttonLeft = windowWidth - buttonWidth - 10;
                debugLog('[VibeCodingButton] ⚠️ 우측 경계 처리: 우측 벗어남 -> 좌측으로 조정');
            }
            
            const left = buttonLeft + 'px';
            const top = buttonTop + 'px';
            
            debugLog('[VibeCodingButton] 계산된 위치:', {
                inputTag: input.tagName,
                inputRect: rect,
                finalLeft: left, 
                finalTop: top
            });
            
            // 🔥 강제로 position과 z-index 설정
            const isInIframe = window.self !== window.top;
            
            this.container.style.setProperty('position', 'fixed', 'important');
            this.container.style.setProperty('z-index', isInIframe ? '999999999' : '2147483647', 'important');
            this.container.style.setProperty('left', left, 'important');
            this.container.style.setProperty('top', top, 'important');
            this.container.style.setProperty('display', 'flex', 'important');
            
            // 🔍 iframe인 경우 추가 스타일 강제 적용
            if (isInIframe) {
                this.container.style.setProperty('visibility', 'visible', 'important');
                this.container.style.setProperty('opacity', '1', 'important');
                this.container.style.setProperty('pointer-events', 'auto', 'important');
                debugLog('[VibeCodingButton] iframe 내부 - 강제 스타일 적용 완료');
            }
            
            this.isVisible = true;
            
            /* debugLog('[VibeCodingButton] 버튼 위치 설정 완료:', {
                left, 
                top, 
                display: this.container.style.display,
                zIndex: this.container.style.zIndex,
                isInDOM: document.contains(this.container)
            }); */
            
            // 🔍 Textarea 전용 디버그: 실제 화면에서 보이는지 체크
            if (input.tagName === 'TEXTAREA') {
                const buttonRect = this.container.getBoundingClientRect();
                const isOnScreen = (
                    buttonRect.top >= 0 && 
                    buttonRect.left >= 0 && 
                    buttonRect.top <= window.innerHeight && 
                    buttonRect.left <= window.innerWidth
                );
                
                // 🔍 iframe 체크 추가
                const isInIframe = window.self !== window.top;
                const inputRect = input.getBoundingClientRect();
                
                /* debugLog('[VibeCodingButton] 🔍 TEXTAREA 전용 화면 노출 체크:', {
                    buttonRect: {
                        x: buttonRect.x,
                        y: buttonRect.y,
                        width: buttonRect.width,
                        height: buttonRect.height,
                        top: buttonRect.top,
                        left: buttonRect.left,
                        bottom: buttonRect.bottom,
                        right: buttonRect.right
                    },
                    inputRect: {
                        x: inputRect.x,
                        y: inputRect.y,
                        width: inputRect.width,
                        height: inputRect.height,
                        top: inputRect.top,
                        left: inputRect.left
                    },
                    windowSize: { width: window.innerWidth, height: window.innerHeight },
                    isOnScreen,
                    isInIframe: isInIframe,
                    frameInfo: {
                        href: window.location.href,
                        origin: window.location.origin,
                        parentOrigin: isInIframe ? document.referrer : 'same window'
                    },
                    computedStyle: {
                        visibility: getComputedStyle(this.container).visibility,
                        opacity: getComputedStyle(this.container).opacity,
                        pointerEvents: getComputedStyle(this.container).pointerEvents,
                        zIndex: getComputedStyle(this.container).zIndex,
                        position: getComputedStyle(this.container).position,
                        display: getComputedStyle(this.container).display
                    },
                    containerStyle: {
                        left: this.container.style.left,
                        top: this.container.style.top,
                        display: this.container.style.display,
                        position: this.container.style.position,
                        zIndex: this.container.style.zIndex
                    }
                }); */
            }
        }

        hide() {
            if (this.container) {
                this.container.style.display = 'none';
                this.isVisible = false;
            }
        }

        setRecording(isRecording) {
            // this.updateIcon(isRecording); // 🚨 제거: 기존 마이크 버튼 사용하지 않음
            this.updateStatus(isRecording ? 'recording' : 'ready', isRecording ? 'Recording...' : 'Ready');
            debugLog('[VibeCodingButton] 녹음 상태 변경:', isRecording);
        }

        cleanup() {
            if (this.container) {
                this.container.remove();
                this.container = null;
                // this.button = null; // 🚨 완전 제거 - 더 이상 사용하지 않음
                this.statusText = null;
                this.brandText = null;
            }
        }

        // 🔥 DOM 참조 완전 재동기화 메서드
        resyncWithDOM() {
            // console.log('[VibeCodingButton] 🔄 DOM 재동기화 시작');
            
            // DOM에서 실제 버튼 찾기
            const actualButton = document.querySelector('.vibe-coding-container');
            
            if (actualButton) {
                // 기존 참조가 실제 DOM과 다른지 확인
                const isDifferent = this.container !== actualButton;
                
                // 참조 업데이트
                this.container = actualButton;
                this.statusText = actualButton.querySelector('.status-text');
                this.brandText = actualButton.querySelector('.vibe-branding');
                
                /* console.log('[VibeCodingButton] ✅ DOM 재동기화 성공:', {
                    isDifferent,
                    hasContainer: !!this.container,
                    hasStatusText: !!this.statusText,
                    isInDOM: document.contains(this.container),
                    classList: Array.from(this.container.classList || [])
                }); */
            } else {
                // console.error('[VibeCodingButton] ❌ DOM에서 버튼을 찾을 수 없음');
            }
        }

        // 🔥 모든 DOM 버튼에서 상태 클래스 완전 제거
        clearAllStatesFromAllButtons() {
            const allButtons = document.querySelectorAll('.vibe-coding-container');
            
            allButtons.forEach(button => {
                // 클래스 제거
                button.classList.remove('countdown-active', 'recording-active');
                
                // 인라인 스타일도 제거 - 더 완전한 제거
                button.style.removeProperty('background');
                button.style.removeProperty('background-color');
                button.style.removeProperty('border-color');
                button.style.removeProperty('animation');
                button.style.removeProperty('transform');
                button.style.removeProperty('box-shadow');
                
                // 상태 텍스트 색상도 초기화
                const statusText = button.querySelector('.status-text');
                if (statusText) {
                    statusText.style.removeProperty('color');
                    statusText.style.removeProperty('font-weight');
                    statusText.style.removeProperty('animation');
                }
            });
            
            // console.log('[VibeCodingButton] 🧹 모든 버튼 상태 클리어 완료:', allButtons.length, '개');
        }

        // 🔥 모든 DOM 버튼에 카운트다운 상태 강제 적용
        forceCountdownStateOnAllButtons() {
            const allButtons = document.querySelectorAll('.vibe-coding-container');
            
            // console.log('[VibeCodingButton] 🎯 카운트다운 강제 적용 시작:', allButtons.length, '개 버튼');
            
            allButtons.forEach((button, index) => {
                // 클래스 추가
                button.classList.add('countdown-active');
                
                // 강제 인라인 스타일 적용 (크기 고정)
                button.style.cssText += `
                    background: rgba(255, 200, 100, 0.12) !important;
                    border-color: rgba(255, 200, 100, 0.5) !important;
                    animation: countdownPulse 1s ease-in-out infinite !important;
                    box-shadow: 0 8px 32px rgba(255, 200, 100, 0.5) !important;
                    height: 36px !important;
                `;
                
                // 상태 텍스트 업데이트 (항상 주황색)
                const statusText = button.querySelector('.status-text');
                if (statusText) {
                    statusText.style.cssText += `
                        color: rgba(255, 200, 100, 1) !important;
                        font-weight: 700 !important;
                        animation: statusTextPulse 1s ease-in-out infinite !important;
                    `;
                }
                
                // console.log(`[VibeCodingButton] 📦 버튼 ${index + 1} 카운트다운 스타일 강제 적용 완료`);
            });
            
            // console.log('[VibeCodingButton] ✅ 모든 버튼 카운트다운 강제 적용 완료');
        }

        // 🔥 디버그 박스 표시 메서드
        showDebugBox(message, color = 'green') {
            // 기존 디버그 박스 제거
            const existingBox = document.querySelector('#debug-countdown-box');
            if (existingBox) {
                existingBox.remove();
            }

            // 새 디버그 박스 생성
            const debugBox = document.createElement('div');
            debugBox.id = 'debug-countdown-box';
            debugBox.style.cssText = `
                position: fixed;
                top: 100px;
                right: 20px;
                background: ${color};
                color: white;
                padding: 15px 20px;
                border-radius: 8px;
                z-index: 9999999;
                font-weight: bold;
                font-size: 14px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            `;
            debugBox.textContent = message;

            document.body.appendChild(debugBox);
            // console.log('[VibeCodingButton] 📋 디버그 박스 표시:', message);

            // 5초 후 자동 제거
            setTimeout(() => {
                if (debugBox.parentNode) {
                    debugBox.remove();
                }
            }, 5000);
        }
    }

    class HerVoiceInputManager {
        constructor() {
            debugLog('[VoiceInputManager] 생성자 실행');
            this.buttonManager = new VibeCodingButton(() => this.toggleRecording());
            this.currentInput = null;
            this.isRecording = false;
            this.isRecordingState = false; // ← 추가
            this.sttEngine = null;
            this.isEnabled = true;
            this.eventListenersSetup = false; // 중복 설정 방지 플래그
            this.domObserver = null; // DOM 관찰자

            // 🚨 추가: 의존성 상태 체크
            debugLog('[VoiceInputManager] 의존성 상태:', {
                herSVGIcons: !!window.herSVGIcons,
                HerSTTEngine: !!window.HerSTTEngine,
                HerContentSTTHandler: !!window.HerContentSTTHandler,
                HerContextManager: !!window.HerContextManager,
                HerDomainManager: !!window.HerDomainManager,
                chromeStorage: !!(typeof chrome !== 'undefined' && chrome.storage)
            });

            this.init();
        }

        async init() {
            debugLog('[VoiceInputManager] 초기화 시작');

            // 🚨 기존 버튼 모두 제거
            this.cleanupExistingButtons();
            
            // DOM 관찰자 설정 - 새로 생성되는 기존 버튼들을 실시간 제거
            this.setupDOMObserver();

            // ✅ 의존성과 무관하게 이벤트 리스너 먼저 설정
            this.setupEventListeners();

            // 의존성과 설정을 병렬로 로드
            Promise.all([
                this.waitForDependencies(),
                this.loadSettings()
            ]).then(() => {
                if (this.isEnabled) {
                    this.checkInitialFocus();
                } else {
                    // 🔥 Off 상태: 버튼이 있으면 제거 (생성자에서 createButton 안 하므로 보통 없음)
                    if (this.buttonManager && this.buttonManager.container) {
                        this.buttonManager.container.remove();
                        debugLog('[VoiceInputManager] 초기화 시 버튼 제거 (isEnabled=false)');
                    }
                }
                debugLog('[VoiceInputManager] 초기화 완료');
            }).catch((error) => {
                console.error('[VoiceInputManager] 초기화 중 오류:', error);
                // 오류가 있어도 기본 기능은 동작하도록
                this.isEnabled = true;
                this.checkInitialFocus();
            });
        }

        cleanupExistingButtons() {
            // console.log('[VoiceInputManager] 🧹 강력한 버튼 정리 시작');
            
            // 🚨 기존 VibeCodingButton 인스턴스 정리
            if (this.buttonManager && this.buttonManager.container) {
                this.buttonManager.container.remove();
                this.buttonManager.container = null;
                // this.buttonManager.button = null; // 🚨 완전 제거 - 더 이상 사용하지 않음
                this.buttonManager.statusText = null;
            }
            
            // 모든 관련 버튼과 컨테이너를 강력하게 제거 (더 많은 셀렉터 추가)
            const selectors = [
                '.vibe-coding-container',
                '.her-voice-btn', 
                '.her-mic-button',
                '.her-voice-input-btn',
                '.floating-mic-btn',
                '.voice-recording-btn',
                '[data-her-voice]', // 데이터 속성으로도 제거
                '[aria-label="Voice input"]', // aria-label로도 제거
                '.voice-button', // 추가 가능한 클래스
                '.mic-btn' // 추가 가능한 클래스
            ];
            
            let totalRemoved = 0;
            
            // 1차: 직접 셀렉터로 제거 (즉시 5번 반복)
            for (let i = 0; i < 5; i++) {
                selectors.forEach(selector => {
                    try {
                        const elements = document.querySelectorAll(selector);
                        elements.forEach(element => {
                            element.remove();
                            totalRemoved++;
                        });
                    } catch (e) {
                        // 잘못된 셀렉터 무시
                    }
                });
            }
            
            // 2차: Her Extension이 생성한 버튼들만 제거
            try {
                const allButtons = document.querySelectorAll('button');
                allButtons.forEach(button => {
                    // 🚨 오직 Her Extension이 명시적으로 생성한 요소만 제거
                    if (button.classList.contains('her-voice-btn') ||
                        button.getAttribute('aria-label') === 'Voice input' ||
                        button.getAttribute('data-her-voice') ||
                        button.hasAttribute('data-her-extension')) {
                        button.remove();
                        totalRemoved++;
                    }
                });
            } catch (e) {
                console.warn('[VoiceInputManager] 고급 버튼 정리 실패:', e);
            }
            
            // 3차: 즉시 고아 버튼 정리 (타이머 제거로 깜박임 방지)
            this.forceCleanupOrphanButtons();
            
            // console.log(`[VoiceInputManager] ✅ 총 ${totalRemoved}개의 기존 버튼/컨테이너 제거 완료`);
        }
        
        forceCleanupOrphanButtons() {
            // Her Extension이 생성한 고아 버튼들만 제거
            let orphansRemoved = 0;
            
            try {
                // 🚨 Her Extension이 생성한 요소만 검사
                const herButtons = document.querySelectorAll('.her-voice-btn, .her-mic-button, [data-her-voice], [data-her-extension]');
                herButtons.forEach(element => {
                    // 버튼이거나 버튼 내부 요소라면 버튼을 제거
                    const button = element.tagName === 'BUTTON' ? element : element.closest('button');
                    if (button && (
                        button.classList.contains('her-voice-btn') ||
                        button.getAttribute('aria-label') === 'Voice input' ||
                        button.getAttribute('data-her-voice') ||
                        button.hasAttribute('data-her-extension')
                    )) {
                        button.remove();
                        orphansRemoved++;
                    }
                });
                
                if (orphansRemoved > 0) {
                    debugLog(`[VoiceInputManager] 추가로 ${orphansRemoved}개의 고아 버튼 제거`);
                }
            } catch (e) {
                console.warn('[VoiceInputManager] 고아 버튼 정리 실패:', e);
            }
        }
        
        setupDOMObserver() {
            // 새로 추가되는 기존 버튼들을 실시간으로 제거하는 관찰자
            if (this.domObserver) {
                this.domObserver.disconnect();
            }
            
            this.domObserver = new MutationObserver((mutations) => {
                let shouldCleanup = false;
                
                mutations.forEach((mutation) => {
                    if (mutation.type === 'childList') {
                        mutation.addedNodes.forEach((node) => {
                            if (node.nodeType === Node.ELEMENT_NODE) {
                                // 새로 추가된 노드가 기존 버튼인지 확인
                                if (node.classList && (
                                    node.classList.contains('her-voice-btn') ||
                                    node.classList.contains('her-mic-button') ||
                                    (node.tagName === 'BUTTON' && node.getAttribute('aria-label') === 'Voice input')
                                )) {
                                    shouldCleanup = true;
                                }
                                
                                // 하위 노드들도 확인
                                const suspiciousButtons = node.querySelectorAll && node.querySelectorAll('.her-voice-btn, .her-mic-button, button[aria-label="Voice input"]');
                                if (suspiciousButtons && suspiciousButtons.length > 0) {
                                    shouldCleanup = true;
                                }
                            }
                        });
                    }
                });
                
                if (shouldCleanup) {
                    debugLog('[VoiceInputManager] DOM 변화 감지 - 기존 버튼 제거 실행');
                    setTimeout(() => {
                        this.forceCleanupOrphanButtons();
                    }, 10);
                }
            });
            
            // 전체 document를 관찰
            this.domObserver.observe(document.body, {
                childList: true,
                subtree: true
            });
            
            debugLog('[VoiceInputManager] DOM 관찰자 설정 완료');
        }

        checkInitialFocus() {
            const activeElement = document.activeElement;
            if (InputDetector.isValidInput(activeElement) && this.isEnabled) {
                this.showButtonForInput(activeElement);
            }
        }

        async waitForDependencies() {
            return new Promise((resolve) => {
                let attempts = 0;
                const check = () => {
                    attempts++;
                    const ready = window.herSVGIcons &&
                        window.HerSTTEngine &&
                        window.HerContentSTTHandler;

                    if (ready) {
                        this.sttEngine = window.HerSTTEngine.getInstance();
                        // ❌ 제거: this.setupEventListeners(); - 이미 init()에서 설정했음
                        resolve();
                    } else if (attempts > 100) {
                        console.error('[VoiceInputManager] 의존성 로딩 타임아웃');
                        resolve();
                    } else {
                        setTimeout(check, 50);
                    }
                };
                check();
            });
        }

        async loadSettings() {
            try {
                // HerContextManager 체크 제거 - chrome.storage만 확인
                if (typeof chrome !== 'undefined' && chrome.storage) {
                    const result = await chrome.storage.sync.get(['voiceIntelligenceEnabled']);
                    this.isEnabled = result.voiceIntelligenceEnabled !== false;
                } else {
                    // 브라우저 환경이나 확장 컨텍스트가 아닌 경우 기본값 사용
                    this.isEnabled = true;
                }
            } catch (error) {
                console.error('[VoiceInputManager] 설정 로드 실패:', error);
                this.isEnabled = true; // 기본값으로 대체
            }
        }

        setupEventListeners() {
            // 중복 설정 방지
            if (this.eventListenersSetup) return;
            this.eventListenersSetup = true;

            // 포커스 이벤트 (이벤트 위임 방식) - 캡처 단계에서도 시도
            document.addEventListener('focusin', (e) => {
                // isEnabled가 false면 버튼 숨기고 종료
                if (!this.isEnabled) {
                    this.hideButton();
                    if (this.buttonManager && this.buttonManager.container) {
                        this.buttonManager.container.remove();
                    }
                    return;
                }

                if (InputDetector.isValidInput(e.target)) {
                    this.showButtonForInput(e.target);
                }
            });
            
            // 캡처 단계에서도 시도
            document.addEventListener('focusin', (e) => {
                /* console.log('[VoiceInputManager] 🎯 focusin 이벤트 (capture):', {
                    tag: e.target.tagName,
                    id: e.target.id,
                    type: e.target.type
                }); */
            }, true); // 캡처 단계
            
            // focus 이벤트도 시도
            document.addEventListener('focus', (e) => {
                /* console.log('[VoiceInputManager] 🎯 focus 이벤트:', {
                    tag: e.target.tagName,
                    id: e.target.id,
                    type: e.target.type
                }); */
            }, true);
            
            // 모든 클릭 이벤트 감지
            document.addEventListener('click', (e) => {
                /* console.log('[VoiceInputManager] 🖱️ 클릭 이벤트:', {
                    tag: e.target.tagName,
                    id: e.target.id,
                    type: e.target.type,
                    className: e.target.className
                }); */
                
                if (e.target.tagName === 'INPUT') {
                    /* console.log('[VoiceInputManager] 🎯 INPUT 요소 클릭:', {
                        id: e.target.id,
                        type: e.target.type,
                        tabIndex: e.target.tabIndex,
                        disabled: e.target.disabled,
                        readOnly: e.target.readOnly
                    }); */
                }
            });
            
            // DOM에서 모든 input 필드 찾기
            setTimeout(() => {
                // 1. 특정 ID로 찾기
                const appleIdField = document.getElementById('account_name_text_field');
                /* console.log('[VoiceInputManager] 🔍 Apple ID 필드 검색 결과:', {
                    found: !!appleIdField,
                    element: appleIdField
                }); */
                
                // 2. 모든 input 필드 찾기
                const allInputs = document.querySelectorAll('input[type="text"], input[type="email"], input[type="password"]');
                /* console.log('[VoiceInputManager] 📋 페이지의 모든 input 필드:', {
                    count: allInputs.length,
                    inputs: Array.from(allInputs).map(input => ({
                        id: input.id,
                        type: input.type,
                        className: input.className,
                        placeholder: input.placeholder,
                        name: input.name
                    }))
                }); */
                
                // 3. iframe 내부 검색
                const iframes = document.querySelectorAll('iframe');
                // console.log('[VoiceInputManager] 🖼️ iframe 개수:', iframes.length);
                
                iframes.forEach((iframe, index) => {
                    try {
                        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                        const iframeInputs = iframeDoc.querySelectorAll('input[type="text"], input[type="email"], input[type="password"]');
                        /* console.log(`[VoiceInputManager] iframe ${index + 1} 내부 input:`, {
                            count: iframeInputs.length,
                            inputs: Array.from(iframeInputs).map(input => ({
                                id: input.id,
                                type: input.type,
                                className: input.className,
                                placeholder: input.placeholder,
                                name: input.name
                            }))
                        }); */
                        
                        // iframe 내부에 이벤트 리스너 추가
                        if (iframeInputs.length > 0) {
                            // console.log(`[VoiceInputManager] ✅ iframe ${index + 1}에 이벤트 리스너 추가`);
                            
                            const self = this; // this 바인딩
                            
                            // 다양한 이벤트 방식으로 시도
                            iframeDoc.addEventListener('focusin', (e) => {
                                /* console.log('[VoiceInputManager] 🎯 iframe focusin 이벤트:', {
                                    tag: e.target.tagName,
                                    id: e.target.id,
                                    type: e.target.type,
                                    className: e.target.className
                                }); */
                                
                                if (InputDetector.isValidInput(e.target) && self.isEnabled) {
                                    // console.log('[VoiceInputManager] ✅ iframe 내 유효한 입력 필드 - 버튼 표시');
                                    self.showButtonForInput(e.target);
                                }
                            });
                            
                            // focus 이벤트로도 시도 (캡처 단계)
                            iframeDoc.addEventListener('focus', (e) => {
                                /* console.log('[VoiceInputManager] 🎯 iframe focus 이벤트:', {
                                    tag: e.target.tagName,
                                    id: e.target.id,
                                    type: e.target.type
                                }); */
                                
                                if (InputDetector.isValidInput(e.target) && self.isEnabled) {
                                    // console.log('[VoiceInputManager] ✅ iframe focus - 버튼 표시');
                                    self.showButtonForInput(e.target);
                                }
                            }, true);
                            
                            // 클릭 이벤트로도 시도
                            iframeDoc.addEventListener('click', (e) => {
                                /* console.log('[VoiceInputManager] 🖱️ iframe click 이벤트:', {
                                    tag: e.target.tagName,
                                    id: e.target.id,
                                    type: e.target.type
                                }); */
                                
                                if (InputDetector.isValidInput(e.target) && self.isEnabled) {
                                    // console.log('[VoiceInputManager] ✅ iframe click - 버튼 표시');
                                    self.showButtonForInput(e.target);
                                }
                            });
                            
                            iframeDoc.addEventListener('focusout', (e) => {
                                // console.log('[VoiceInputManager] 🎯 iframe focusout 이벤트');
                                // iframe 내부에서도 focusout 처리
                                const lostFocusElement = e.target;
                                if (InputDetector.isValidInput(lostFocusElement)) {
                                    setTimeout(() => {
                                        const newFocusedElement = iframeDoc.activeElement;
                                        if (!InputDetector.isValidInput(newFocusedElement)) {
                                            self.hideButton();
                                        }
                                    }, 500);
                                }
                            });
                        }
                    } catch (error) {
                        // console.log(`[VoiceInputManager] iframe ${index + 1} 접근 불가:`, error.message);
                    }
                });
                
                if (appleIdField) {
                    // console.log('[VoiceInputManager] ✅ Apple ID 필드 발견 - 직접 이벤트 테스트');
                    appleIdField.addEventListener('focus', () => {
                        // console.log('[VoiceInputManager] 🎯 직접 focus 이벤트 발생');
                    });
                    appleIdField.addEventListener('click', () => {
                        // console.log('[VoiceInputManager] 🖱️ 직접 click 이벤트 발생');
                    });
                }
            }, 3000);


            // focusout 이벤트 핸들러 (오토포커스 문제 해결)
            document.addEventListener('focusout', (e) => {
                // 녹음 중이면 아예 처리하지 않음
                if (this.isRecordingState) {
                    return;
                }

                // 🚨 마이크 버튼으로 포커스가 이동한 경우 무시
                if (e.relatedTarget && e.relatedTarget.classList.contains('her-voice-btn')) {
                    return;
                }

                // 현재 포커스를 잃은 요소가 유효한 입력 필드인지 확인
                const lostFocusElement = e.target;
                if (!InputDetector.isValidInput(lostFocusElement)) {
                    return; // 유효하지 않은 필드에서 포커스를 잃은 경우 무시
                }

                // 더 긴 지연으로 오토포커스 완료를 기다림
                setTimeout(() => {
                    const activeElement = document.activeElement;
                    
                    // 마이크 버튼이 포커스된 경우 무시
                    if (activeElement && activeElement.classList.contains('her-voice-btn')) {
                        return;
                    }

                    // 새로 포커스된 요소도 유효한 입력 필드라면 버튼 유지 (오토포커스 대응)
                    if (InputDetector.isValidInput(activeElement)) {
                        debugLog('[VoiceInputManager] 오토포커스로 다른 유효한 필드로 이동 - 버튼 유지');
                        this.showButtonForInput(activeElement);
                        return;
                    }

                    // 유효하지 않은 요소로 포커스가 이동했거나 포커스가 없는 경우에만 버튼 숨김
                    this.hideButton();
                }, 500); // 200ms → 500ms로 증가 (오토포커스 완료 대기)
            });

            // 스크롤 이벤트 throttling으로 성능 최적화
            let scrollTimeout;
            document.addEventListener('scroll', () => {
                if (scrollTimeout) clearTimeout(scrollTimeout);
                scrollTimeout = setTimeout(() => {
                    if (this.currentInput && this.buttonManager.isVisible) {
                        this.buttonManager.showAt(this.currentInput);
                    }
                }, 16); // 60fps 기준
            }, true);

            // 창 크기 변경 이벤트
            window.addEventListener('resize', () => {
                if (this.currentInput && this.buttonManager.isVisible) {
                    this.buttonManager.showAt(this.currentInput);
                }
            });

            // Storage 리스너 설정 - 안전성 강화
            if (typeof chrome !== 'undefined' && chrome.storage) {
                try {
                    chrome.storage.onChanged.addListener((changes) => {
                        if (changes.voiceIntelligenceEnabled) {
                            const newValue = changes.voiceIntelligenceEnabled.newValue;
                            this.isEnabled = newValue !== false;
                            debugLog('[VoiceInputManager] 설정 변경됨:', { isEnabled: this.isEnabled });

                            if (!this.isEnabled) {
                                // 🔥 Off 상태: 버튼 완전 제거 및 녹음 중지
                                this.hideButton();
                                if (this.isRecording) {
                                    this.stopRecording();
                                }
                                // 버튼 컨테이너 완전 제거
                                if (this.buttonManager && this.buttonManager.container) {
                                    this.buttonManager.container.remove();
                                    debugLog('[VoiceInputManager] 버튼 컨테이너 완전 제거됨');
                                }
                            } else {
                                // 🔥 On 상태: 현재 포커스된 필드에 버튼 표시
                                this.checkInitialFocus();
                            }
                        }
                    });
                } catch (error) {
                    console.error('[VoiceInputManager] Storage 리스너 설정 실패:', error);
                }
            }
        }

        showButtonForInput(input) {
            // isEnabled가 false면 버튼 표시하지 않음
            if (!this.isEnabled) {
                debugLog('[VoiceInputManager] 비활성화 상태 - 버튼 표시 안 함');
                return;
            }

            // 🚨 변경: 의존성 로딩 중이어도 버튼 표시
            this.currentInput = input;

            // 버튼이 생성되지 않았다면 생성
            if (!this.buttonManager.container) {
                this.buttonManager.createButton();
            }

            this.buttonManager.showAt(input);
        }

        hideButton() {
            // 핵심 변경: 녹음 중일 때는 무조건 버튼 유지
            if (this.isRecordingState) {
                return; // 녹음 중에는 숨기지 않음
            }

            this.buttonManager.hide();
            this.currentInput = null;
            this.buttonManager.isVisible = false;
        }

        toggleRecording() {
            debugLog('[VoiceInputManager] 🎯 녹음 토글 요청:', {
                isRecording: this.isRecording,
                hasInput: !!this.currentInput,
                isEnabled: this.isEnabled,
                activeElement: document.activeElement?.tagName + (document.activeElement?.id ? '#' + document.activeElement.id : '')
            });

            // currentInput이 null인 경우 현재 활성 요소로 다시 설정 시도
            if (!this.currentInput) {
                const activeElement = document.activeElement;
                debugLog('[VoiceInputManager] 🔍 currentInput이 null - 활성 요소 확인:', {
                    activeElement: activeElement?.tagName + (activeElement?.id ? '#' + activeElement.id : ''),
                    isValid: InputDetector.isValidInput(activeElement)
                });
                
                if (InputDetector.isValidInput(activeElement)) {
                    debugLog('[VoiceInputManager] ✅ currentInput 복원 성공:', activeElement);
                    this.currentInput = activeElement;
                } else {
                    debugLog('[VoiceInputManager] ❌ 유효한 활성 요소 없음');
                }
            }

            if (!this.isEnabled) {
                debugLog('[VoiceInputManager] ❌ 비활성화 상태로 인한 차단');
                return;
            }
            
            if (!this.currentInput) {
                debugLog('[VoiceInputManager] ❌ currentInput 없음으로 인한 차단');
                return;
            }

            debugLog('[VoiceInputManager] ✅ 조건 통과 - 녹음 상태 확인:', {
                isRecording: this.isRecording
            });

            if (this.isRecording) {
                debugLog('[VoiceInputManager] 🛑 녹음 중지 시도');
                this.stopRecording();
            } else {
                debugLog('[VoiceInputManager] 🎤 녹음 시작 시도');
                this.startRecording();
            }
        }

        startRecording() {
            this.isRecordingState = true;
            if (!window.HerContentSTTHandler || !this.currentInput) {
                console.error('[VoiceInputManager] 녹음 시작 불가');
                this.isRecordingState = false; // 실패 시 상태 복원
                return;
            }

            // 녹음 중일 때 입력 필드에 포커스 유지
            if (this.currentInput && typeof this.currentInput.focus === 'function') {
                this.currentInput.focus();
            }

            debugLog('[VoiceInputManager] 녹음 시작');

            // 필수 모듈 로드 확인
            if (!window.HerContentSTTHandler) {
                console.error('[VoiceInputManager] ❌ HerContentSTTHandler not loaded');
                this.buttonManager?.updateStatus('ready', 'Module Loading...');
                setTimeout(() => this.buttonManager?.updateStatus('ready', 'Ready'), 2000);
                return false;
            }

            if (!window.HerGlobalState) {
                console.error('[VoiceInputManager] ❌ HerGlobalState not loaded');
                this.buttonManager?.updateStatus('ready', 'Module Loading...');
                setTimeout(() => this.buttonManager?.updateStatus('ready', 'Ready'), 2000);
                return false;
            }

            const success = window.HerContentSTTHandler.start(this.currentInput, (data) => {
                // 실시간 텍스트 업데이트는 HerContentSTTHandler에서 처리
                debugLog('[VoiceInputManager] 텍스트 업데이트:', data.text?.substring(0, 50));
            });

            if (success) {
                this.isRecording = true;
                this.buttonManager.setRecording(true);
                debugLog('[VoiceInputManager] 녹음 시작 성공');
            } else {
                this.isRecordingState = false; // 실패 시 상태 복원
                console.error('[VoiceInputManager] 녹음 시작 실패');
            }
        }

        stopRecording() {
            this.isRecordingState = false;
            debugLog('[VoiceInputManager] 녹음 중지');
            if (this.isRecording) {
                window.HerContentSTTHandler.stop();
                this.isRecording = false;
                this.buttonManager.setRecording(false);
            }
        }

        // 최적화된 getAllValidInputs 메서드
        getAllValidInputs() {
            const inputs = document.querySelectorAll('input, textarea, [contenteditable="true"]');
            return Array.from(inputs).filter(InputDetector.isValidInput);
        }
    }

    // 버전 정보 추가
    HerVoiceInputManager._version = SCRIPT_VERSION;

    window.HerVoiceInputManager = HerVoiceInputManager;

    // 즉시 인스턴스 생성 제거 - content.js에서 필요할 때 생성
    // window.voiceInputManager = new HerVoiceInputManager();

    debugLog('[VoiceInputManager] 클래스 등록 완료:', !!window.HerVoiceInputManager);
})(); 