{"id":59,"date":"2026-01-31T11:55:46","date_gmt":"2026-01-31T19:55:46","guid":{"rendered":"https:\/\/gogoit.com\/video\/?page_id=59"},"modified":"2026-01-31T11:55:49","modified_gmt":"2026-01-31T19:55:49","slug":"agent-dashboard","status":"publish","type":"page","link":"https:\/\/gogoit.com\/video\/agent-dashboard\/","title":{"rendered":"Agent\u00a0Dashboard"},"content":{"rendered":"\n\n<!-- DASHBOARD VERSION: 2026-02-05-v1-PREMIUM-UI -->\n<!-- Premium Font: Plus Jakarta Sans -->\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\n<!-- Cropper.js for image cropping -->\n<link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/cropperjs\/1.6.1\/cropper.min.css\">\n\n<style>\n:root {\n    --dash-primary: #6366F1;\n    --dash-primary-dark: #4F46E5;\n    --dash-primary-light: #818CF8;\n    --dash-primary-glow: rgba(99, 102, 241, 0.15);\n    --dash-success: #10B981;\n    --dash-success-light: #D1FAE5;\n    --dash-warning: #F59E0B;\n    --dash-warning-light: #FEF3C7;\n    --dash-danger: #EF4444;\n    --dash-danger-light: #FEE2E2;\n    --dash-gray-50: #F9FAFB;\n    --dash-gray-100: #F3F4F6;\n    --dash-gray-200: #E5E7EB;\n    --dash-gray-300: #D1D5DB;\n    --dash-gray-400: #9CA3AF;\n    --dash-gray-500: #6B7280;\n    --dash-gray-600: #4B5563;\n    --dash-gray-700: #374151;\n    --dash-gray-800: #1F2937;\n    --dash-gray-900: #111827;\n    --sidebar-width: 260px;\n    --wp-admin-bar: 32px;\n    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.03);\n    --card-shadow-hover: 0 4px 16px rgba(0, 0, 0, 0.08);\n    --transition-fast: 0.15s ease;\n    --transition-smooth: 0.25s ease;\n    --border-radius-sm: 8px;\n    --border-radius-md: 12px;\n    --border-radius-lg: 16px;\n}\n\n* {\n    box-sizing: border-box;\n}\n\n\/* Hide WordPress page title - we don't need it *\/\n.entry-title,\n.page-title,\narticle > header,\n.entry-header,\n.ast-archive-description,\nh1.entry-title {\n    display: none !important;\n}\n\n\/* Fix WordPress theme footer - center within content area, not full page *\/\n.site-footer,\nfooter.site-footer,\n.ast-footer-copyright,\n.site-info,\nfooter[role=\"contentinfo\"] {\n    margin-left: var(--sidebar-width) !important;\n    text-align: center !important;\n}\n\n@media (max-width: 768px) {\n    .site-footer,\n    footer.site-footer,\n    .ast-footer-copyright,\n    .site-info,\n    footer[role=\"contentinfo\"] {\n        margin-left: 0 !important;\n    }\n}\n\n\/* Dashboard wrapper - works within WordPress theme *\/\n.gvei-dashboard-wrapper {\n    margin: 0;\n    padding: 0;\n    width: 100%;\n    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n    min-height: 100vh;\n}\n\n\/* Override WordPress theme page constraints *\/\n.page .entry-content,\n.gvei-dashboard-wrapper .entry-content,\narticle.page,\n.site-content,\n.content-area,\n.ast-container,\n.site-main,\nmain#main,\n#primary,\n#content,\n.hentry,\n.ast-separate-container .ast-article-single,\n.ast-separate-container .ast-article-post {\n    max-width: none !important;\n    width: 100% !important;\n    padding: 0 !important;\n    margin: 0 !important;\n    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important;\n}\n\n\/* Ensure main content fills available space *\/\n.gvei-main {\n    width: 100%;\n}\n\n.gvei-main-content {\n    width: 100%;\n}\n\n\/* Account for WordPress admin bar when logged in *\/\nbody.admin-bar .gvei-sidebar {\n    top: var(--wp-admin-bar);\n    height: calc(100vh - var(--wp-admin-bar));\n    max-height: calc(100vh - var(--wp-admin-bar));\n}\n\nbody.admin-bar .gvei-dashboard {\n    min-height: calc(100vh - var(--wp-admin-bar));\n}\n\nbody.admin-bar .gvei-sidebar-overlay {\n    top: var(--wp-admin-bar);\n}\n\n.gvei-dashboard {\n    font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n    min-height: 100vh;\n    padding: 0;\n    margin: 0;\n    display: flex;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n\n.gvei-main {\n    flex: 1;\n    margin-left: var(--sidebar-width);\n    min-height: 100vh;\n    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n}\n\n\/* ===== SIDEBAR ===== *\/\n.gvei-sidebar {\n    width: var(--sidebar-width);\n    height: 100vh;\n    max-height: 100vh;\n    background: linear-gradient(180deg, #0F172A 0%, #1E293B 100%);\n    position: fixed;\n    left: 0;\n    top: 0;\n    z-index: 1000;\n    display: flex;\n    flex-direction: column;\n    transition: transform 0.3s ease;\n    box-shadow: 4px 0 24px rgba(0, 0, 0, 0.15);\n    overflow: hidden;\n}\n\n.gvei-sidebar-header {\n    flex-shrink: 0;\n    padding: 28px 24px;\n    border-bottom: 1px solid rgba(255,255,255,0.08);\n}\n\n.gvei-sidebar-logo {\n    font-size: 26px;\n    font-weight: 800;\n    letter-spacing: 1px;\n    display: flex;\n    align-items: center;\n    text-transform: uppercase;\n}\n\n.gvei-sidebar-logo .logo-gogo {\n    color: #fff;\n}\n\n.gvei-sidebar-logo .logo-it {\n    color: #cbc9c9;\n    font-weight: 800;\n}\n\n.gvei-sidebar-user {\n    margin-top: 16px;\n    display: flex;\n    align-items: center;\n    gap: 12px;\n}\n\n.gvei-sidebar-avatar {\n    width: 40px;\n    height: 40px;\n    border-radius: 50%;\n    background: var(--dash-primary);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    color: #fff;\n    font-weight: 600;\n    font-size: 16px;\n    overflow: hidden;\n}\n\n.gvei-sidebar-avatar img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n}\n\n.gvei-sidebar-user-info {\n    flex: 1;\n    min-width: 0;\n}\n\n.gvei-sidebar-user-name {\n    color: #fff;\n    font-weight: 600;\n    font-size: 14px;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n\n.gvei-sidebar-user-status {\n    font-size: 12px;\n    color: var(--dash-success);\n    display: flex;\n    align-items: center;\n    gap: 4px;\n}\n\n.gvei-sidebar-user-status::before {\n    content: '';\n    width: 6px;\n    height: 6px;\n    background: var(--dash-success);\n    border-radius: 50%;\n}\n\n\/* Navigation - scrollable when content overflows *\/\n.gvei-sidebar-nav {\n    flex: 1;\n    min-height: 0;\n    padding: 20px 12px;\n    overflow-y: auto;\n    overflow-x: hidden;\n    -webkit-overflow-scrolling: touch;\n}\n.gvei-sidebar-nav::-webkit-scrollbar {\n    width: 6px;\n}\n.gvei-sidebar-nav::-webkit-scrollbar-track {\n    background: transparent;\n}\n.gvei-sidebar-nav::-webkit-scrollbar-thumb {\n    background: rgba(255,255,255,0.2);\n    border-radius: 3px;\n}\n.gvei-sidebar-nav::-webkit-scrollbar-thumb:hover {\n    background: rgba(255,255,255,0.35);\n}\n\n.gvei-nav-item {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    padding: 12px 16px;\n    color: var(--dash-gray-400);\n    text-decoration: none;\n    border-radius: 10px;\n    margin-bottom: 4px;\n    transition: all 0.2s;\n    font-size: 15px;\n    font-weight: 500;\n}\n\n.gvei-nav-item:hover {\n    background: rgba(255,255,255,0.08);\n    color: #fff;\n}\n\n.gvei-nav-item.active {\n    background: var(--dash-primary);\n    color: #fff;\n}\n\n.gvei-nav-group-label {\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    color: var(--dash-gray-500);\n    padding: 16px 16px 8px 16px;\n    margin-top: 8px;\n    border-top: 1px solid rgba(255,255,255,0.08);\n}\n\n.gvei-nav-icon {\n    font-size: 18px;\n    width: 24px;\n    text-align: center;\n}\n\n\/* Background Music - Play button (agent dashboard) *\/\n.gvei-music-play-btn {\n    width: 36px;\n    height: 36px;\n    min-width: 36px;\n    min-height: 36px;\n    border-radius: 50%;\n    border: 1.5px solid var(--dash-gray-300);\n    background: #fff;\n    color: var(--dash-gray-600);\n    cursor: pointer;\n    flex-shrink: 0;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    transition: all 0.2s ease;\n    padding: 0;\n}\n.gvei-music-play-btn:hover {\n    border-color: var(--dash-primary);\n    color: var(--dash-primary);\n    background: rgba(99, 102, 241, 0.08);\n}\n.gvei-music-play-btn.playing {\n    border-color: var(--dash-primary);\n    background: var(--dash-primary);\n    color: #fff;\n}\n.gvei-music-play-btn svg {\n    width: 14px;\n    height: 14px;\n}\n\n\/* Sidebar Footer *\/\n.gvei-sidebar-footer {\n    flex-shrink: 0;\n    padding: 16px 20px;\n    border-top: 1px solid rgba(255,255,255,0.1);\n}\n\n.gvei-sidebar-help {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    background: rgba(255, 255, 255, 0.08);\n    border: 1px solid rgba(255, 255, 255, 0.1);\n    border-radius: 10px;\n    cursor: pointer;\n    width: 100%;\n    text-align: left;\n    font-family: inherit;\n    font-size: 14px;\n    font-weight: 500;\n    color: rgba(255, 255, 255, 0.8);\n    padding: 12px 14px;\n    transition: all 0.2s ease;\n}\n\n\/* Support Panel Styles *\/\n.gvei-support-overlay {\n    display: none;\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    z-index: 9998;\n    opacity: 0;\n    transition: opacity 0.3s ease;\n}\n\n.gvei-support-overlay.open {\n    display: block;\n    opacity: 1;\n}\n\n.gvei-support-panel {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: #fff;\n    border-radius: 20px 20px 0 0;\n    box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15);\n    z-index: 9999;\n    max-height: 90vh;\n    overflow-y: auto;\n    transform: translateY(100%);\n    transition: transform 0.3s ease;\n}\n\n.gvei-support-panel.open {\n    transform: translateY(0);\n}\n\n@media (min-width: 769px) {\n    .gvei-support-panel {\n        left: auto;\n        right: 24px;\n        bottom: 24px;\n        width: 420px;\n        max-height: 80vh;\n        border-radius: 16px;\n        transform: translateY(20px);\n        opacity: 0;\n        pointer-events: none;\n    }\n    \n    .gvei-support-panel.open {\n        transform: translateY(0);\n        opacity: 1;\n        pointer-events: auto;\n    }\n}\n\n.gvei-support-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 20px 24px;\n    border-bottom: 1px solid var(--dash-gray-200);\n    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n    border-radius: 20px 20px 0 0;\n}\n\n@media (min-width: 769px) {\n    .gvei-support-header {\n        border-radius: 16px 16px 0 0;\n    }\n}\n\n.gvei-support-header h3 {\n    margin: 0;\n    font-size: 18px;\n    font-weight: 700;\n    color: var(--dash-gray-900);\n}\n\n.gvei-support-close {\n    background: var(--dash-gray-100);\n    border: none;\n    width: 32px;\n    height: 32px;\n    border-radius: 8px;\n    color: var(--dash-gray-500);\n    cursor: pointer;\n    padding: 0;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    transition: all 0.2s ease;\n    font-size: 0;\n}\n\n.gvei-support-close::before {\n    content: '';\n    width: 14px;\n    height: 14px;\n    background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C\/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C\/line%3E%3C\/svg%3E\");\n    background-size: contain;\n    background-repeat: no-repeat;\n    background-position: center;\n}\n\n.gvei-support-close:hover {\n    background: var(--dash-primary);\n}\n\n.gvei-support-close:hover::before {\n    background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C\/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C\/line%3E%3C\/svg%3E\");\n}\n\n.gvei-support-body {\n    padding: 16px 20px 20px 20px;\n    overflow: visible;\n}\n\n.gvei-support-body select {\n    -webkit-appearance: none;\n    -moz-appearance: none;\n    appearance: none;\n    background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 8L1 3h10z'\/%3E%3C\/svg%3E\");\n    background-repeat: no-repeat;\n    background-position: right 12px center;\n    padding-right: 36px;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden;\n    min-height: 44px;\n}\n\n.gvei-support-greeting {\n    background: linear-gradient(135deg, #EEF2FF 0%, #E0E7FF 100%);\n    border: 1px solid #C7D2FE;\n    border-radius: 10px;\n    padding: 12px 14px;\n    margin-bottom: 16px;\n    font-size: 13px;\n    color: var(--dash-gray-700);\n    line-height: 1.4;\n}\n\n.gvei-support-greeting strong {\n    color: var(--dash-gray-900);\n}\n\n#gvei-support-form .gvei-form-group {\n    margin-bottom: 14px;\n}\n\n#gvei-support-form .gvei-label {\n    font-size: 13px;\n    margin-bottom: 6px;\n}\n\n#gvei-support-form .gvei-input {\n    padding: 10px 12px;\n    font-size: 14px;\n}\n\n#gvei-support-form textarea.gvei-input {\n    min-height: 80px;\n}\n\n#gvei-support-form .gvei-helper {\n    margin-top: 4px;\n    font-size: 11px;\n}\n\n.gvei-support-submit {\n    margin-top: 8px;\n}\n\n.gvei-support-submit:disabled {\n    opacity: 0.6;\n    cursor: not-allowed;\n}\n\n\/* Support Upload Area *\/\n.gvei-support-upload-area {\n    border: 2px dashed var(--dash-gray-300);\n    border-radius: 8px;\n    padding: 12px;\n    text-align: center;\n    cursor: pointer;\n    transition: all 0.2s;\n    background: var(--dash-gray-50);\n}\n\n.gvei-support-upload-area:hover {\n    border-color: var(--dash-primary);\n    background: rgba(34, 197, 94, 0.05);\n}\n\n.gvei-support-upload-prompt {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    color: var(--dash-gray-500);\n    font-size: 12px;\n}\n\n.gvei-support-upload-prompt span:first-child {\n    font-size: 20px !important;\n}\n\n.gvei-support-upload-preview {\n    position: relative;\n    display: inline-block;\n}\n\n.gvei-support-upload-preview img {\n    max-width: 100%;\n    max-height: 150px;\n    border-radius: 8px;\n    object-fit: contain;\n}\n\n.gvei-support-remove-upload {\n    position: absolute;\n    top: -10px;\n    right: -10px;\n    width: 28px;\n    height: 28px;\n    min-width: 28px;\n    min-height: 28px;\n    background: #ef4444;\n    color: white;\n    border: 2px solid white;\n    border-radius: 50%;\n    font-size: 20px;\n    font-weight: 300;\n    line-height: 1;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 0;\n    padding-bottom: 2px;\n    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n    font-family: Arial, sans-serif;\n}\n\n.gvei-support-remove-upload:hover {\n    background: #dc2626;\n    transform: scale(1.1);\n}\n    color: var(--dash-gray-400);\n    font-size: 13px;\n    text-decoration: none;\n}\n\n.gvei-sidebar-help:hover {\n    background: rgba(99, 102, 241, 0.9);\n    border-color: rgba(99, 102, 241, 0.9);\n    color: #fff;\n    transform: translateY(-1px);\n    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n\/* ===== MAIN CONTENT ===== *\/\n.gvei-main {\n    flex: 1;\n    margin-left: var(--sidebar-width);\n    min-height: 100vh;\n    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n}\n\n.gvei-main-header {\n    background: #fff;\n    padding: 16px 24px;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    border-bottom: 1px solid var(--dash-gray-200);\n    position: sticky;\n    top: 0;\n    z-index: 100;\n}\n\n.gvei-mobile-toggle {\n    display: none;\n    background: var(--dash-gray-100);\n    border: 1px solid var(--dash-gray-200);\n    cursor: pointer;\n    padding: 0;\n    border-radius: 10px;\n    width: 44px;\n    height: 44px;\n    align-items: center;\n    justify-content: center;\n    transition: all 0.2s;\n    box-shadow: 0 1px 3px rgba(0,0,0,0.06);\n}\n\n.gvei-mobile-toggle:hover {\n    background: var(--dash-gray-200);\n    box-shadow: 0 2px 6px rgba(0,0,0,0.1);\n}\n\n\/* CSS Hamburger lines - perfectly centered *\/\n.hamburger-lines {\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    gap: 5px;\n    width: 20px;\n    height: 20px;\n}\n\n.hamburger-lines span {\n    display: block;\n    width: 20px;\n    height: 2px;\n    background: var(--dash-gray-600);\n    border-radius: 1px;\n    transition: all 0.2s;\n}\n\n.gvei-mobile-toggle:hover .hamburger-lines span {\n    background: var(--dash-gray-800);\n}\n\n.gvei-main-header {\n    display: none; \/* Hide on desktop - sections have their own titles *\/\n}\n\n\/* Show header on mobile for menu toggle *\/\n@media (max-width: 768px) {\n    .gvei-main-header {\n        display: flex;\n        align-items: center;\n        padding: 12px 16px;\n        background: #fff;\n        border-bottom: 1px solid var(--dash-gray-200);\n        position: sticky;\n        top: 0;\n        z-index: 100;\n        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n        -webkit-backdrop-filter: blur(10px);\n        backdrop-filter: blur(10px);\n    }\n    \n    \/* Better stats grid on mobile *\/\n    .gvei-stats-grid {\n        gap: 12px;\n    }\n    \n    .gvei-stat-card {\n        padding: 20px 16px;\n    }\n    \n    .gvei-stat-value {\n        font-size: 32px;\n    }\n}\n\n.gvei-page-title {\n    font-size: 16px;\n    font-weight: 600;\n    flex: 1;\n    text-align: center;\n    margin: 0;\n    color: var(--dash-gray-800);\n    margin: 0;\n    letter-spacing: -0.01em;\n}\n\n.gvei-main-content {\n    padding: 20px;\n    max-width: none;\n    min-height: 100%;\n}\n\n\/* ===== MOBILE OVERLAY ===== *\/\n.gvei-sidebar-overlay {\n    display: none;\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0,0,0,0.5);\n    z-index: 999;\n}\n\n\/* ===== CARDS ===== *\/\n.gvei-card {\n    background: #fff;\n    border-radius: var(--border-radius-lg);\n    padding: 20px;\n    margin-bottom: 16px;\n    margin-top: 0;\n    border: 1px solid rgba(226, 232, 240, 0.7);\n    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.gvei-card:hover {\n    border-color: rgba(203, 213, 225, 0.9);\n}\n\n\/* Ensure first card has no extra top margin *\/\n.gvei-main-content > .gvei-card:first-child {\n    margin-top: 0;\n}\n\n.gvei-card-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 16px;\n    padding-bottom: 14px;\n    border-bottom: 1px solid rgba(226, 232, 240, 0.6);\n}\n\n.gvei-card-title {\n    font-size: 17px;\n    font-weight: 600;\n    color: var(--dash-gray-800);\n    margin: 0;\n    display: flex;\n    letter-spacing: -0.01em;\n    align-items: center;\n    gap: 8px;\n}\n\n\/* ===== TUTORIAL VIDEO LINK ===== *\/\n.gvei-card-header:has(.gvei-tutorial-link) {\n    flex-wrap: wrap;\n}\n.gvei-tutorial-link {\n    flex-basis: 100%;\n    display: block;\n    font-size: 13.5px;\n    font-weight: 500;\n    color: #7c6fbd;\n    text-decoration: none;\n    margin-top: 6px;\n    transition: color 0.15s ease, opacity 0.15s ease;\n    opacity: 0.85;\n}\n.gvei-tutorial-link:hover {\n    color: var(--dash-primary);\n    opacity: 1;\n}\n@media (max-width: 768px) {\n    .gvei-tutorial-link {\n        font-size: 14px;\n        padding: 2px 0;\n    }\n}\n\n\/* Tutorial Lightbox *\/\n.gvei-video-lightbox {\n    display: none;\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 99999;\n    align-items: center;\n    justify-content: center;\n    padding: 20px;\n}\n.gvei-video-lightbox.open {\n    display: flex;\n}\n.gvei-video-lightbox-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0,0,0,0.8);\n    cursor: pointer;\n}\n.gvei-video-lightbox-content {\n    position: relative;\n    width: 100%;\n    max-width: 820px;\n    z-index: 1;\n}\n.gvei-video-lightbox-close {\n    position: absolute;\n    top: -40px;\n    right: 0;\n    background: none;\n    border: none;\n    color: #fff;\n    font-size: 28px;\n    cursor: pointer;\n    line-height: 1;\n    padding: 4px 8px;\n    opacity: 0.8;\n    transition: opacity 0.15s ease;\n}\n.gvei-video-lightbox-close:hover {\n    opacity: 1;\n}\n.gvei-video-lightbox-iframe-wrap {\n    position: relative;\n    padding-bottom: 56.25%; \/* 16:9 *\/\n    height: 0;\n    overflow: hidden;\n    border-radius: 10px;\n    background: #000;\n    box-shadow: 0 8px 40px rgba(0,0,0,0.4);\n}\n.gvei-video-lightbox-iframe-wrap iframe {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    border: 0;\n}\n\n\/* ===== STATS ===== *\/\n.gvei-stats-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n    gap: 16px;\n    margin-bottom: 24px;\n}\n\n.gvei-stat-card {\n    background: #fff;\n    border-radius: var(--border-radius-md);\n    padding: 20px 16px;\n    text-align: center;\n    border: 1px solid rgba(226, 232, 240, 0.7);\n    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n    transition: all var(--transition-smooth);\n}\n\n.gvei-stat-card:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n}\n\n.gvei-stat-card-link {\n    text-decoration: none;\n    cursor: pointer;\n    display: block;\n}\n\n.gvei-stat-card-link:hover {\n    border-color: var(--dash-primary);\n}\n\n.gvei-stat-card-link:hover .gvei-stat-value {\n    color: var(--dash-primary-dark);\n}\n\n.gvei-stat-value {\n    font-size: 32px;\n    font-weight: 700;\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    -webkit-background-clip: text;\n    -webkit-text-fill-color: transparent;\n    background-clip: text;\n    letter-spacing: -0.02em;\n}\n\n.gvei-stat-label {\n    font-size: 12px;\n    color: var(--dash-gray-500);\n    margin-top: 6px;\n    font-weight: 500;\n    letter-spacing: 0.01em;\n}\n\n\/* ===== SCHEDULE LIST ===== *\/\n.gvei-schedule-list {\n    display: flex;\n    flex-direction: column;\n    gap: 0;\n}\n\n.gvei-schedule-day {\n    padding: 20px 0;\n    border-bottom: 1px solid #E5E7EB;\n}\n.gvei-schedule-day:first-child {\n    padding-top: 0;\n}\n.gvei-schedule-day:last-child {\n    border-bottom: none;\n    padding-bottom: 0;\n}\n\n.gvei-schedule-date {\n    font-size: 15px;\n    font-weight: 700;\n    color: var(--dash-gray-700);\n    margin-bottom: 12px;\n    letter-spacing: -0.01em;\n}\n\n.gvei-schedule-item {\n    display: flex;\n    flex-direction: column;\n    gap: 0;\n    padding: 18px 20px;\n    background: #FFFFFF;\n    border-radius: var(--border-radius-md);\n    border: 1px solid #E8EAF0;\n    box-shadow: 0 1px 3px rgba(0,0,0,0.04);\n    transition: all var(--transition-fast);\n}\n.gvei-schedule-item + .gvei-schedule-item {\n    margin-top: 10px;\n}\n\n.gvei-schedule-item:hover {\n    border-color: var(--dash-primary-light);\n    box-shadow: 0 2px 8px rgba(99,102,241,0.08);\n}\n\n.gvei-schedule-row-top {\n    display: flex;\n    align-items: flex-start;\n    gap: 14px;\n}\n\n.gvei-schedule-time {\n    font-size: 13px;\n    color: var(--dash-gray-400);\n    min-width: 62px;\n    font-weight: 500;\n    padding-top: 3px;\n}\n\n.gvei-schedule-info {\n    flex: 1;\n    min-width: 0;\n}\n\n.gvei-schedule-type-row {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    flex-wrap: wrap;\n}\n\n.gvei-schedule-type {\n    font-weight: 600;\n    color: var(--dash-gray-800);\n    font-size: 16px;\n    letter-spacing: -0.01em;\n}\n\n.gvei-schedule-address {\n    font-size: 14px;\n    color: var(--dash-gray-500);\n    margin-top: 6px;\n    line-height: 1.5;\n}\n\n.gvei-schedule-meta-row {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    flex-wrap: wrap;\n    margin-top: 6px;\n}\n\n.gvei-see-listing-link {\n    display: inline-flex;\n    align-items: center;\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--dash-primary);\n    text-decoration: none;\n}\n\n.gvei-see-listing-link:hover {\n    color: var(--dash-primary-dark);\n    text-decoration: underline;\n}\n\n.gvei-replaced-badge {\n    display: inline-flex;\n    align-items: center;\n    font-size: 11px;\n    padding: 3px 8px;\n    border-radius: 5px;\n    background: #FEF3C7;\n    color: #92400E;\n    font-weight: 500;\n    white-space: nowrap;\n}\n\n.gvei-schedule-status {\n    font-size: 11px;\n    padding: 4px 10px;\n    border-radius: 20px;\n    font-weight: 600;\n    letter-spacing: 0.01em;\n    white-space: nowrap;\n    flex-shrink: 0;\n}\n\n.gvei-schedule-status.planned { background: #EEF2FF; color: #4338CA; }\n.gvei-schedule-status.queued { background: #FEF3C7; color: #B45309; }\n.gvei-schedule-status.processing { background: #DBEAFE; color: #1D4ED8; }\n.gvei-schedule-status.rendering { background: #CCFBF1; color: #0D9488; }\n.gvei-schedule-status.ready { background: #D1FAE5; color: #059669; }\n.gvei-schedule-status.failed { background: #FFEDD5; color: #C2410C; }\n.gvei-schedule-status.pending_listing { background: #F1F5F9; color: #94A3B8; }\n\n.gvei-schedule-actions {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-top: 14px;\n    padding-top: 14px;\n    border-top: 1px solid #F1F3F5;\n}\n\n.gvei-btn-small {\n    font-size: 13px;\n    padding: 9px 18px;\n    border-radius: 8px;\n    font-weight: 500;\n    cursor: pointer;\n    white-space: nowrap;\n    transition: all 0.15s ease;\n    line-height: 1;\n}\n\n.gvei-replace-listing-btn {\n    background: #F8FAFC !important;\n    color: #374151 !important;\n    border: 1px solid #D1D5DB !important;\n    box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n}\n.gvei-replace-listing-btn:hover {\n    background: #E5E7EB !important;\n    color: #111827 !important;\n    border-color: #9CA3AF !important;\n    box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n}\n.gvei-replace-listing-btn:active {\n    background: #D1D5DB !important;\n    color: #111827 !important;\n    box-shadow: none;\n}\n\n.gvei-btn-outline {\n    background: transparent !important;\n    color: #64748B !important;\n    border: 1px dashed #CBD5E1 !important;\n    font-size: 13px;\n    padding: 9px 18px;\n    border-radius: 8px;\n    cursor: pointer;\n    white-space: nowrap;\n    transition: all 0.15s ease;\n    line-height: 1;\n}\n.gvei-btn-outline:hover {\n    background: #F1F5F9 !important;\n    color: #1E293B !important;\n    border-color: #94A3B8 !important;\n    border-style: dashed !important;\n}\n.gvei-btn-outline:active {\n    background: #E2E8F0 !important;\n    color: #1E293B !important;\n}\n\n\/* Replace Listing Modal *\/\n.gvei-replace-listing-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 10000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 20px;\n}\n\n.gvei-replace-listing-modal .gvei-modal-overlay {\n    position: absolute;\n    inset: 0;\n    background: rgba(0,0,0,0.4);\n}\n\n.gvei-replace-listing-modal-content {\n    position: relative;\n    background: #fff;\n    border-radius: 12px;\n    padding: 24px;\n    max-width: 500px;\n    width: 100%;\n    box-shadow: 0 20px 60px rgba(0,0,0,0.2);\n}\n\n.gvei-replace-listing-modal .gvei-modal-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    margin-bottom: 16px;\n}\n\n.gvei-replace-listing-modal .gvei-modal-header h3 {\n    margin: 0;\n    font-size: 18px;\n}\n\n.gvei-replace-listing-modal .gvei-modal-close {\n    background: none;\n    border: none;\n    font-size: 24px;\n    color: var(--dash-gray-500);\n    cursor: pointer;\n    padding: 0;\n    line-height: 1;\n}\n\n.gvei-replace-listing-desc {\n    color: var(--dash-gray-600);\n    font-size: 14px;\n    margin: 0 0 12px;\n}\n\n.gvei-replace-listing-current {\n    font-size: 12px;\n    color: var(--dash-gray-500);\n    margin: 0 0 16px;\n    font-style: italic;\n}\n\n.gvei-replace-listing-form .gvei-input {\n    width: 100%;\n    margin-bottom: 16px;\n}\n\n.gvei-replace-listing-buttons {\n    display: flex;\n    gap: 12px;\n}\n\n.gvei-replace-listing-status {\n    margin-top: 16px;\n    padding: 12px;\n    border-radius: 8px;\n    font-size: 14px;\n}\n\n.gvei-replace-listing-status.success {\n    background: #D1FAE5;\n    color: #059669;\n}\n\n.gvei-replace-listing-status.error {\n    background: #FEE2E2;\n    color: #991B1B;\n}\n\n\/* ===== VOICE SECTION ===== *\/\n.gvei-voice-current {\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    border-radius: 12px;\n    padding: 20px;\n    color: #fff;\n    margin-bottom: 20px;\n}\n\n.gvei-voice-label {\n    font-size: 12px;\n    text-transform: uppercase;\n    letter-spacing: 1px;\n    opacity: 0.8;\n    margin-bottom: 4px;\n}\n\n.gvei-voice-name {\n    font-size: 20px;\n    font-weight: 700;\n}\n\n.gvei-audio-player {\n    margin-top: 16px;\n}\n\n.gvei-audio-player audio {\n    width: 100%;\n    height: 40px;\n}\n\n.gvei-voice-options {\n    display: flex;\n    flex-direction: column;\n    gap: 10px;\n}\n\n.gvei-voice-option {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    padding: 14px 16px;\n    background: linear-gradient(135deg, #fafaff 0%, #f8fafc 100%);\n    border-radius: var(--border-radius-md);\n    border: 1.5px solid var(--dash-gray-200);\n    cursor: pointer;\n    transition: all var(--transition-fast);\n}\n\n.gvei-voice-option:hover {\n    border-color: var(--dash-gray-300);\n    background: linear-gradient(135deg, #f5f3ff 0%, #f1f5f9 100%);\n}\n\n.gvei-voice-option.selected {\n    border-color: var(--dash-primary);\n    background: linear-gradient(135deg, #EEF2FF 0%, #E0E7FF 100%);\n    box-shadow: 0 0 0 3px var(--dash-primary-glow);\n}\n\n.gvei-voice-option-radio {\n    width: 22px;\n    height: 22px;\n    border-radius: 50%;\n    border: 2px solid var(--dash-gray-300);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    transition: all var(--transition-fast);\n    flex-shrink: 0;\n}\n\n.gvei-voice-option.selected .gvei-voice-option-radio {\n    border-color: var(--dash-primary);\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n}\n\n.gvei-voice-option.selected .gvei-voice-option-radio::after {\n    content: '\u2713';\n    color: #fff;\n    font-size: 11px;\n    font-weight: 600;\n}\n\n.gvei-voice-option-info {\n    flex: 1;\n    min-width: 0;\n}\n\n.gvei-voice-option-name {\n    font-weight: 600;\n    color: var(--dash-gray-800);\n    font-size: 14px;\n}\n\n.gvei-voice-option-desc {\n    font-size: 12px;\n    color: var(--dash-gray-500);\n}\n\n\/* ===== VIDEO LIST ===== *\/\n.gvei-video-list {\n    display: flex;\n    flex-direction: column;\n    gap: 16px;\n}\n\n.gvei-video-item {\n    display: flex;\n    gap: 20px;\n    padding: 20px;\n    background: linear-gradient(135deg, #fafaff 0%, #f8fafc 100%);\n    border-radius: var(--border-radius-md);\n    border: 1px solid rgba(226, 232, 240, 0.8);\n    box-shadow: var(--card-shadow);\n    transition: all var(--transition-smooth);\n}\n\n.gvei-video-item:hover {\n    border-color: var(--dash-gray-300);\n    box-shadow: var(--card-shadow-hover);\n    transform: translateY(-1px);\n}\n\n.gvei-video-thumb {\n    width: 160px;\n    height: 100px;\n    background: linear-gradient(135deg, #1e293b 0%, #334155 100%);\n    border-radius: 10px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 32px;\n    flex-shrink: 0;\n    overflow: hidden;\n    position: relative;\n}\n\n.gvei-video-thumb img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n}\n\n\/* Dark overlay on top of thumbnail image (45% opacity) *\/\n.gvei-video-thumb::after {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.45);\n    pointer-events: none;\n    z-index: 1;\n    border-radius: 10px;\n}\n\n.gvei-video-thumb-play {\n    position: absolute;\n    width: 44px;\n    height: 44px;\n    background: rgba(255,255,255,0.95);\n    border-radius: 50%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    color: #1e293b;\n    font-size: 16px;\n    cursor: pointer;\n    transition: all 0.2s;\n    box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n    z-index: 2;\n}\n\n.gvei-video-thumb:hover .gvei-video-thumb-play {\n    background: var(--dash-primary);\n    color: #fff;\n    transform: scale(1.1);\n}\n\n\/* Video Player Modal *\/\n.gvei-video-modal {\n    display: none;\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0,0,0,0.9);\n    z-index: 10000;\n    align-items: center;\n    justify-content: center;\n    padding: 20px;\n}\n\n.gvei-video-modal.active {\n    display: flex;\n}\n\n.gvei-video-modal-content {\n    max-width: 900px;\n    width: 100%;\n    position: relative;\n}\n\n.gvei-video-modal-close {\n    position: absolute;\n    top: -40px;\n    right: 0;\n    background: none;\n    border: none;\n    color: #fff;\n    font-size: 32px;\n    cursor: pointer;\n    padding: 8px;\n}\n\n.gvei-video-modal video {\n    width: 100%;\n    max-height: 80vh;\n    border-radius: 12px;\n}\n\n\/* ===== VIDEO EXPIRATION BADGES ===== *\/\n.gvei-video-expiry {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 11px;\n    font-weight: 500;\n    padding: 3px 8px;\n    border-radius: 12px;\n    margin-left: 8px;\n    white-space: nowrap;\n}\n\n.gvei-video-expiry.normal {\n    background: var(--dash-gray-100);\n    color: var(--dash-gray-600);\n}\n\n.gvei-video-expiry.warning {\n    background: #FEF3C7;\n    color: #92400E;\n}\n\n.gvei-video-expiry.urgent {\n    background: #FEE2E2;\n    color: #991B1B;\n}\n\n.gvei-video-expiry.expired {\n    background: var(--dash-gray-200);\n    color: var(--dash-gray-500);\n}\n\n\/* Expired videos styling *\/\n.gvei-video-item.expired {\n    opacity: 0.6;\n    background: var(--dash-gray-100);\n}\n\n.gvei-video-item.expired .gvei-video-thumb {\n    filter: grayscale(100%);\n}\n\n.gvei-video-item.expired .gvei-video-actions {\n    display: none;\n}\n\n\/* Expired videos section *\/\n.gvei-expired-section {\n    margin-top: 32px;\n    padding-top: 24px;\n    border-top: 1px solid var(--dash-gray-200);\n}\n\n.gvei-expired-toggle {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    background: none;\n    border: 1px solid var(--dash-gray-300);\n    color: var(--dash-gray-600);\n    padding: 8px 16px;\n    border-radius: 8px;\n    font-size: 13px;\n    cursor: pointer;\n    transition: all 0.2s;\n}\n\n.gvei-expired-toggle:hover {\n    background: var(--dash-gray-100);\n    border-color: var(--dash-gray-400);\n}\n\n.gvei-expired-toggle.active {\n    background: var(--dash-gray-100);\n}\n\n.gvei-expired-notice {\n    background: #FEF3C7;\n    border: 1px solid #FCD34D;\n    border-radius: 8px;\n    padding: 12px 16px;\n    margin-bottom: 16px;\n    font-size: 13px;\n    color: #92400E;\n}\n\n.gvei-expired-list {\n    display: none;\n}\n\n.gvei-expired-list.active {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n    margin-top: 16px;\n}\n\n\/* ===== IMAGE CROP MODAL ===== *\/\n.gvei-crop-modal {\n    display: none;\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0,0,0,0.8);\n    z-index: 100000;\n    align-items: center;\n    justify-content: center;\n    padding: 20px;\n}\n\n.gvei-crop-modal.active {\n    display: flex;\n}\n\n.gvei-crop-container {\n    background: #fff;\n    border-radius: 20px;\n    max-width: 500px;\n    width: 100%;\n    max-height: 90vh;\n    overflow: hidden;\n    display: flex;\n    flex-direction: column;\n}\n\n.gvei-crop-header {\n    padding: 24px 24px 16px;\n    text-align: center;\n}\n\n.gvei-crop-header h3 {\n    margin: 0 0 8px;\n    font-size: 22px;\n    font-weight: 600;\n    color: var(--dash-gray-900);\n}\n\n.gvei-crop-header p {\n    margin: 0;\n    font-size: 14px;\n    color: var(--dash-gray-500);\n}\n\n.gvei-crop-area {\n    flex: 1;\n    background: var(--dash-gray-100);\n    min-height: 300px;\n    max-height: 400px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    overflow: hidden;\n}\n\n.gvei-crop-area img {\n    max-width: 100%;\n    display: block;\n}\n\n.gvei-crop-controls {\n    padding: 16px 24px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 16px;\n    background: var(--dash-gray-50);\n}\n\n.gvei-zoom-btn {\n    width: 44px;\n    height: 44px;\n    border-radius: 50%;\n    border: 1px solid var(--dash-gray-300);\n    background: #fff;\n    font-size: 20px;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    transition: all 0.2s;\n}\n\n.gvei-zoom-btn:hover {\n    background: var(--dash-gray-100);\n}\n\n.gvei-crop-actions {\n    padding: 16px 24px 24px;\n    display: flex;\n    gap: 12px;\n}\n\n.gvei-crop-actions button {\n    flex: 1;\n    padding: 14px 20px;\n    border-radius: 12px;\n    font-size: 16px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s;\n}\n\n.gvei-crop-cancel {\n    background: var(--dash-gray-100);\n    border: none;\n    color: var(--dash-gray-700);\n}\n\n.gvei-crop-cancel:hover {\n    background: var(--dash-gray-200);\n}\n\n.gvei-crop-save {\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    border: none;\n    color: #fff;\n}\n\n.gvei-crop-save:hover {\n    transform: translateY(-1px);\n    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);\n}\n\n\/* Cropper.js overrides for circular crop *\/\n.cropper-view-box,\n.cropper-face {\n    border-radius: 50%;\n}\n\n.cropper-view-box {\n    outline: 3px solid rgba(255,255,255,0.9);\n    outline-offset: -3px;\n    box-shadow: 0 0 0 9999px rgba(0,0,0,0.5);\n}\n\n.cropper-face {\n    background: transparent;\n}\n\n.cropper-dashed,\n.cropper-point,\n.cropper-line {\n    display: none;\n}\n\n\/* AI Panel (inline expansion) *\/\n.gvei-ai-panel {\n    display: none;\n    margin-top: 16px;\n    padding: 16px;\n    background: #fff;\n    border: 2px solid var(--dash-primary-light);\n    border-radius: 12px;\n}\n\n.gvei-ai-panel.active {\n    display: block;\n}\n\n.gvei-ai-panel-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 16px;\n}\n\n.gvei-ai-panel-title {\n    font-weight: 600;\n    color: var(--dash-gray-900);\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.gvei-ai-panel-close {\n    background: var(--dash-gray-200);\n    border: none;\n    font-size: 16px;\n    cursor: pointer;\n    color: var(--dash-gray-500);\n    width: 32px;\n    height: 32px;\n    border-radius: 6px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    transition: all 0.15s ease;\n}\n\n.gvei-ai-panel-close:hover {\n    background: #1e293b;\n    color: white;\n}\n\n.gvei-ai-generate-btn {\n    width: 100%;\n    padding: 16px;\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    color: #fff;\n    border: none;\n    border-radius: 8px;\n    font-size: 15px;\n    font-weight: 600;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    transition: all 0.2s;\n}\n\n.gvei-ai-generate-btn:hover {\n    transform: translateY(-1px);\n    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);\n}\n\n.gvei-ai-generate-btn:disabled {\n    opacity: 0.6;\n    cursor: not-allowed;\n    transform: none;\n}\n\n\/* Small buttons for thumbnail image change\/reset *\/\n.gvei-thumb-btn-small {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    padding: 6px 10px;\n    font-size: 11px;\n    font-weight: 500;\n    color: var(--dash-gray-600);\n    background: var(--dash-gray-100);\n    border: 1px solid var(--dash-gray-200);\n    border-radius: 6px;\n    cursor: pointer;\n    transition: all 0.2s;\n}\n\n.gvei-thumb-btn-small:hover {\n    background: var(--dash-gray-200);\n    color: var(--dash-gray-700);\n}\n\n.gvei-thumb-btn-reset {\n    background: transparent;\n    border-color: transparent;\n    color: var(--dash-gray-500);\n}\n\n.gvei-thumb-btn-reset:hover {\n    background: var(--dash-gray-100);\n    color: var(--dash-gray-600);\n}\n\n.gvei-ai-result {\n    margin-top: 16px;\n}\n\n.gvei-ai-result-item {\n    margin-bottom: 16px;\n}\n\n.gvei-ai-result-label {\n    font-size: 12px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--dash-gray-500);\n    margin-bottom: 6px;\n}\n\n.gvei-ai-result-value {\n    background: var(--dash-gray-50);\n    border: 1px solid var(--dash-gray-200);\n    border-radius: 8px;\n    padding: 12px;\n    font-size: 14px;\n    line-height: 1.5;\n    position: relative;\n}\n\n.gvei-ai-copy-btn {\n    position: absolute;\n    top: 8px;\n    right: 8px;\n    background: var(--dash-primary);\n    color: #fff;\n    border: none;\n    padding: 6px 12px;\n    border-radius: 6px;\n    font-size: 12px;\n    cursor: pointer;\n    opacity: 0;\n    transition: opacity 0.2s;\n}\n\n.gvei-ai-result-value:hover .gvei-ai-copy-btn {\n    opacity: 1;\n}\n\n.gvei-ai-copy-btn.copied {\n    background: var(--dash-success);\n}\n\n.gvei-video-info {\n    flex: 1;\n    min-width: 0;\n}\n\n.gvei-video-title-row {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-bottom: 6px;\n    flex-wrap: wrap;\n}\n\n.gvei-video-title {\n    font-weight: 600;\n    font-size: 15px;\n    color: var(--dash-gray-900);\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n\n.gvei-video-meta {\n    font-size: 13px;\n    color: var(--dash-gray-500);\n    margin-bottom: 16px;\n}\n\n.gvei-video-format {\n    display: inline-flex;\n    align-items: center;\n    padding: 3px 10px;\n    border-radius: 20px;\n    font-size: 10px;\n    font-weight: 600;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    flex-shrink: 0;\n}\n\n.gvei-format-vertical {\n    background: #dbeafe;\n    color: #1d4ed8;\n}\n\n.gvei-format-horizontal {\n    background: #dcfce7;\n    color: #15803d;\n}\n\n@media (max-width: 480px) {\n    .gvei-video-format {\n        padding: 2px 8px;\n        font-size: 9px;\n    }\n}\n\n.gvei-video-actions {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 10px;\n    align-items: center;\n}\n\n.gvei-video-btn {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 6px;\n    padding: 0 16px;\n    height: 42px;\n    border-radius: var(--border-radius-sm);\n    font-size: 13px;\n    font-weight: 600;\n    font-family: inherit;\n    text-decoration: none;\n    cursor: pointer;\n    border: none;\n    transition: all var(--transition-fast);\n    white-space: nowrap;\n    letter-spacing: -0.01em;\n}\n\n\/* Primary button - Watch (solid, stands out) *\/\n.gvei-video-btn-primary {\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    color: #fff;\n    box-shadow: 0 2px 6px rgba(99, 102, 241, 0.25);\n}\n\n.gvei-video-btn-primary:hover {\n    background: linear-gradient(135deg, var(--dash-primary-dark) 0%, #4338CA 100%);\n    box-shadow: 0 4px 10px rgba(99, 102, 241, 0.35);\n    transform: translateY(-1px);\n}\n\n\/* Secondary button - Caption\/Thumbnail Maker (subtle but clickable) *\/\n.gvei-video-btn-secondary {\n    background: #fff;\n    color: var(--dash-gray-600);\n    border: 1.5px solid var(--dash-gray-200);\n}\n\n.gvei-video-btn-secondary:hover {\n    background: var(--dash-gray-50);\n    border-color: var(--dash-gray-300);\n    color: var(--dash-gray-800);\n}\n\n\/* Download button - Primary green, strong action *\/\n.gvei-download-btn {\n    display: inline-flex;\n    align-items: center;\n    gap: 5px;\n    background: linear-gradient(135deg, var(--dash-success) 0%, #059669 100%);\n    color: white;\n    border: none;\n    box-shadow: 0 2px 6px rgba(16, 185, 129, 0.25);\n}\n\n.gvei-download-btn:hover {\n    background: linear-gradient(135deg, #059669 0%, #047857 100%);\n    box-shadow: 0 4px 10px rgba(16, 185, 129, 0.35);\n    transform: translateY(-1px);\n}\n\n.gvei-download-btn:hover {\n    background: #059669;\n    border-color: #059669;\n    color: white;\n}\n\n.gvei-download-btn:disabled {\n    opacity: 0.7;\n    cursor: wait;\n}\n\n\/* Already downloaded = Secondary green (still strong, lighter shade) *\/\n.gvei-download-btn.previously-downloaded {\n    background: #d1fae5;\n    color: #047857;\n    border-color: #a7f3d0;\n}\n\n.gvei-download-btn.previously-downloaded:hover {\n    background: #34d399;\n    color: white;\n    border-color: #34d399;\n}\n\n\/* ===== FORM ELEMENTS ===== *\/\n.gvei-form-group {\n    margin-bottom: 20px;\n}\n\n.gvei-label {\n    display: block;\n    font-weight: 600;\n    color: var(--dash-gray-700);\n    margin-bottom: 8px;\n    font-size: 13px;\n    letter-spacing: 0.01em;\n}\n\n.gvei-input {\n    width: 100%;\n    padding: 12px 16px;\n    border: 1.5px solid var(--dash-gray-200);\n    border-radius: var(--border-radius-sm);\n    font-size: 14px;\n    font-family: inherit;\n    transition: all var(--transition-fast);\n    background: #fff;\n    color: var(--dash-gray-800);\n}\n\n.gvei-input::placeholder {\n    color: var(--dash-gray-400);\n}\n\n.gvei-input:hover {\n    border-color: var(--dash-gray-300);\n}\n\n.gvei-input:focus {\n    outline: none;\n    border-color: var(--dash-primary);\n    box-shadow: 0 0 0 3px var(--dash-primary-glow);\n}\n\n.gvei-helper {\n    font-size: 12px;\n    color: var(--dash-gray-500);\n    margin-top: 6px;\n    line-height: 1.4;\n}\n\n.gvei-btn {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    padding: 12px 24px;\n    border-radius: var(--border-radius-sm);\n    font-size: 14px;\n    font-weight: 600;\n    cursor: pointer;\n    transition: all var(--transition-fast);\n    text-decoration: none;\n    border: none;\n    font-family: inherit;\n    letter-spacing: -0.01em;\n}\n\n.gvei-btn-primary {\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    color: #fff;\n    box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);\n}\n\n.gvei-btn-primary:hover {\n    background: linear-gradient(135deg, var(--dash-primary-dark) 0%, #4338CA 100%);\n    color: #fff;\n    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n    transform: translateY(-1px);\n}\n\n.gvei-btn-secondary {\n    background: #fff;\n    color: var(--dash-gray-700);\n    border: 1px solid var(--dash-gray-200);\n}\n\n.gvei-btn-secondary:hover {\n    background: var(--dash-gray-100);\n    border-color: var(--dash-gray-400);\n    color: var(--dash-gray-900);\n}\n\n\/* Toggle Switch - Billing *\/\n.gvei-toggle-switch {\n    position: relative;\n    display: inline-block;\n    width: 56px;\n    height: 30px;\n    flex-shrink: 0;\n}\n.gvei-toggle-switch input {\n    opacity: 0;\n    width: 0;\n    height: 0;\n}\n.gvei-toggle-slider {\n    position: absolute;\n    cursor: pointer;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background-color: var(--dash-gray-300);\n    transition: all 0.3s ease;\n    border-radius: 30px;\n}\n.gvei-toggle-slider:before {\n    position: absolute;\n    content: \"\";\n    height: 24px;\n    width: 24px;\n    left: 3px;\n    bottom: 3px;\n    background-color: white;\n    transition: all 0.3s ease;\n    border-radius: 50%;\n    box-shadow: 0 2px 4px rgba(0,0,0,0.2);\n}\n.gvei-toggle-switch input:checked + .gvei-toggle-slider {\n    background: linear-gradient(135deg, var(--dash-primary), #8b5cf6);\n}\n.gvei-toggle-switch input:checked + .gvei-toggle-slider:before {\n    transform: translateX(26px);\n}\n.gvei-toggle-switch input:focus + .gvei-toggle-slider {\n    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);\n}\n\n\/* Voice Filter Buttons *\/\n.gvei-filter-btn {\n    padding: 8px 18px;\n    border: 1.5px solid transparent;\n    border-radius: 24px;\n    background: var(--dash-gray-100);\n    color: var(--dash-gray-500);\n    font-size: 13px;\n    font-weight: 600;\n    font-family: inherit;\n    cursor: pointer;\n    transition: all var(--transition-fast);\n}\n\n.gvei-filter-btn:hover {\n    background: var(--dash-gray-200);\n    color: var(--dash-gray-700);\n}\n\n.gvei-filter-btn.active {\n    background: linear-gradient(135deg, var(--dash-primary) 0%, var(--dash-primary-dark) 100%);\n    color: white;\n    box-shadow: 0 2px 6px rgba(99, 102, 241, 0.25);\n}\n\n\/* Voice List Scrollbar *\/\n.gvei-voice-list::-webkit-scrollbar {\n    width: 6px;\n}\n\n.gvei-voice-list::-webkit-scrollbar-track {\n    background: var(--dash-gray-100);\n    border-radius: 3px;\n}\n\n.gvei-voice-list::-webkit-scrollbar-thumb {\n    background: var(--dash-gray-300);\n    border-radius: 3px;\n}\n\n\/* Voice Card Hover *\/\n.gvei-voice-card:hover {\n    background: var(--dash-gray-200) !important;\n    transform: translateY(-1px);\n}\n\n.gvei-voice-card.selected:hover {\n    background: linear-gradient(135deg, rgba(99,102,241,0.15) 0%, rgba(139,92,246,0.12) 100%) !important;\n}\n\n\/* Voice Play Button States *\/\n.gvei-voice-play:hover {\n    transform: scale(1.08);\n    box-shadow: 0 4px 12px rgba(99,102,241,0.4);\n}\n\n.gvei-voice-play.loading::before {\n    content: '';\n    position: absolute;\n    top: -4px;\n    left: -4px;\n    right: -4px;\n    bottom: -4px;\n    border-radius: 50%;\n    border: 3px solid rgba(99,102,241,0.2);\n    border-top-color: var(--dash-primary);\n    animation: gvei-spin 0.8s linear infinite;\n}\n\n@keyframes gvei-spin {\n    0% { transform: rotate(0deg); }\n    100% { transform: rotate(360deg); }\n}\n\n@keyframes gvei-pulse {\n    0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.4); }\n    50% { box-shadow: 0 0 0 8px rgba(245, 158, 11, 0); }\n}\n\n\/* ZIP Code Input Styles *\/\n.gvei-zip-item {\n    transition: all 0.2s ease;\n}\n\n.gvei-zip-item:hover .gvei-remove-zip {\n    color: var(--dash-danger) !important;\n}\n\n.gvei-secondary-zip:focus {\n    border-color: var(--dash-primary);\n    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n\/* ===== INTRO\/OUTRO SECTION ===== *\/\n.gvei-media-grid {\n    display: grid;\n    grid-template-columns: repeat(2, 1fr);\n    gap: 16px;\n}\n\n.gvei-media-box {\n    background: var(--dash-gray-50);\n    border-radius: 12px;\n    padding: 16px;\n}\n\n.gvei-media-box-title {\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--dash-gray-600);\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    margin-bottom: 12px;\n}\n\n.gvei-media-preview {\n    aspect-ratio: 16\/9;\n    background: var(--dash-gray-200);\n    border-radius: 8px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 24px;\n    margin-bottom: 12px;\n    overflow: hidden;\n}\n\n.gvei-media-preview video {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n}\n\n.gvei-upload-btn {\n    width: 100%;\n    padding: 10px;\n    border: 2px dashed var(--dash-gray-300);\n    background: transparent;\n    border-radius: 8px;\n    color: var(--dash-gray-500);\n    font-size: 13px;\n    cursor: pointer;\n    transition: all 0.2s;\n}\n\n.gvei-upload-btn:hover {\n    border-color: var(--dash-primary);\n    color: var(--dash-primary);\n}\n\n\/* ===== END CARD PREVIEW (matches actual video end card) ===== *\/\n.gvei-endcard-preview {\n    background: #000;\n    border-radius: 12px;\n    padding: 32px 24px;\n    color: #fff;\n    text-align: center;\n    margin-bottom: 24px;\n    aspect-ratio: 9\/16;\n    max-width: 280px;\n    margin-left: auto;\n    margin-right: auto;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: flex-start;\n}\n\n.gvei-endcard-agency-logo {\n    background: rgba(255,255,255,0.1);\n    border-radius: 8px;\n    padding: 12px 24px;\n    margin-bottom: 32px;\n    min-height: 50px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n\/* When no agency logo, spacer keeps photo\/name\/phone in same position as when logo is present *\/\n.gvei-endcard-no-logo-spacer {\n    height: 0;\n    margin-bottom: 92px; \/* tuned so content sits slightly higher; admin preview matches this *\/\n    flex-shrink: 0;\n}\n\n.gvei-endcard-agency-logo img {\n    max-height: 40px;\n    max-width: 180px;\n    object-fit: contain;\n}\n\n.gvei-endcard-agency-logo .placeholder {\n    color: inherit;\n    opacity: 0.4;\n    font-size: 12px;\n    text-transform: uppercase;\n    letter-spacing: 1px;\n}\n\n\n\n.gvei-endcard-photo {\n    width: 120px;\n    height: 120px;\n    border-radius: 50%;\n    background: var(--dash-gray-700);\n    margin: 0 auto 20px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 48px;\n    overflow: hidden;\n}\n\n.gvei-endcard-photo img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n}\n\n.gvei-endcard-name {\n    font-size: 24px;\n    font-weight: 300;\n    margin-bottom: 8px;\n    letter-spacing: 1px;\n}\n\n.gvei-endcard-phone {\n    font-size: 20px;\n    font-weight: 300;\n    letter-spacing: 1px;\n    opacity: 0.8;\n}\n\n\/* Prevent mobile from styling phone number as a link (keep end card preview color) *\/\n.gvei-endcard-preview .gvei-endcard-phone a,\n.gvei-endcard-preview .gvei-endcard-phone .gvei-endcard-phone-inner {\n    color: inherit !important;\n    text-decoration: none !important;\n    -webkit-tap-highlight-color: transparent;\n}\n.gvei-endcard-preview .gvei-endcard-phone a {\n    pointer-events: none;\n}\n\n.gvei-endcard-label {\n    display: none;\n}\n\n\/* ===== EMPTY STATE ===== *\/\n.gvei-empty {\n    text-align: center;\n    padding: 40px 20px;\n    color: var(--dash-gray-500);\n}\n\n.gvei-empty-icon {\n    font-size: 48px;\n    margin-bottom: 16px;\n    opacity: 0.5;\n}\n\n\/* ===== ERROR STATE ===== *\/\n.gvei-error {\n    background: #FEF2F2;\n    border: 1px solid #FECACA;\n    border-radius: 16px;\n    padding: 40px;\n    text-align: center;\n    margin: 40px auto;\n    max-width: 500px;\n}\n\n.gvei-error-icon {\n    font-size: 48px;\n    margin-bottom: 16px;\n}\n\n.gvei-error h2 {\n    color: #991B1B;\n    margin: 0 0 8px 0;\n}\n\n.gvei-error p {\n    color: #DC2626;\n    margin: 0;\n}\n\n\/* ===== WELCOME BANNER ===== *\/\n.gvei-welcome {\n    background: linear-gradient(135deg, #ECFDF5 0%, #D1FAE5 100%);\n    border: 1px solid #A7F3D0;\n    border-radius: 16px;\n    padding: 24px;\n    margin-bottom: 24px;\n    text-align: center;\n}\n\n.gvei-welcome-icon {\n    font-size: 48px;\n    margin-bottom: 12px;\n}\n\n.gvei-welcome h2 {\n    color: #065F46;\n    margin: 0 0 8px 0;\n    font-size: 22px;\n}\n\n.gvei-welcome p {\n    color: #047857;\n    margin: 0;\n}\n\n\/* ===== TRIAL BANNER ===== *\/\n.gvei-trial-banner {\n    background: linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);\n    border: 1px solid #F59E0B;\n    border-radius: 16px;\n    padding: 20px 24px;\n    margin-bottom: 24px;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 16px;\n    flex-wrap: wrap;\n}\n.gvei-trial-banner.trial-ended {\n    background: linear-gradient(135deg, #FEE2E2 0%, #FECACA 100%);\n    border-color: #EF4444;\n}\n.gvei-trial-banner-content {\n    flex: 1;\n    min-width: 200px;\n}\n.gvei-trial-banner-icon {\n    font-size: 28px;\n    margin-right: 12px;\n    display: inline-block;\n}\n.gvei-trial-banner h3 {\n    margin: 0 0 4px;\n    font-size: 16px;\n    font-weight: 600;\n    color: #92400E;\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n.gvei-trial-banner.trial-ended h3 {\n    color: #991B1B;\n}\n.gvei-trial-banner p {\n    margin: 0;\n    color: #B45309;\n    font-size: 14px;\n}\n.gvei-trial-banner.trial-ended p {\n    color: #DC2626;\n}\n.gvei-trial-days {\n    background: #F59E0B;\n    color: #fff;\n    padding: 4px 12px;\n    border-radius: 20px;\n    font-size: 13px;\n    font-weight: 600;\n}\n.gvei-trial-banner.trial-ended .gvei-trial-days {\n    background: #EF4444;\n}\n.gvei-trial-btn {\n    background: #F59E0B;\n    color: #fff;\n    border: none;\n    padding: 10px 20px;\n    border-radius: 8px;\n    font-weight: 600;\n    cursor: pointer;\n    text-decoration: none;\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    font-size: 14px;\n    transition: all 0.2s;\n}\n.gvei-trial-btn:hover {\n    background: #D97706;\n    color: #fff;\n    transform: translateY(-1px);\n}\n.gvei-trial-banner.trial-ended .gvei-trial-btn {\n    background: #EF4444;\n}\n.gvei-trial-banner.trial-ended .gvei-trial-btn:hover {\n    background: #DC2626;\n}\n\n\/* ===== RESPONSIVE ===== *\/\n@media (max-width: 768px) {\n    .gvei-sidebar {\n        transform: translateX(-100%);\n    }\n    \n    .gvei-sidebar.open {\n        transform: translateX(0);\n    }\n    \n    .gvei-sidebar-overlay.open {\n        display: block;\n    }\n    \n    .gvei-main {\n        margin-left: 0;\n    }\n    \n    .gvei-mobile-toggle {\n        display: flex;\n    }\n    \n    .gvei-main-content {\n        padding: 14px 14px 14px 14px;\n    }\n    \n    .gvei-card {\n        border-radius: var(--border-radius-md);\n        padding: 16px;\n        margin-bottom: 12px;\n    }\n    \n    .gvei-card-header {\n        padding: 0 0 12px 0;\n        margin-bottom: 14px;\n    }\n    \n    .gvei-video-list {\n        gap: 14px;\n    }\n    \n    .gvei-video-item {\n        flex-direction: column;\n        padding: 16px;\n        border-radius: var(--border-radius-md);\n        gap: 14px;\n    }\n    \n    .gvei-video-thumb {\n        width: 100%;\n        height: 200px;\n        border-radius: var(--border-radius-sm);\n    }\n    \n    .gvei-video-info {\n        width: 100%;\n    }\n    \n    .gvei-video-title-row {\n        flex-direction: row;\n        align-items: center;\n        gap: 10px;\n        flex-wrap: wrap;\n    }\n    \n    .gvei-video-title {\n        font-size: 16px;\n        white-space: normal;\n        line-height: 1.3;\n    }\n    \n    .gvei-video-meta {\n        margin-bottom: 14px;\n    }\n    \n    .gvei-video-actions {\n        display: grid;\n        grid-template-columns: 1fr 1fr;\n        gap: 10px;\n        width: 100%;\n    }\n    \n    .gvei-video-btn {\n        height: 44px;\n        font-size: 14px;\n        padding: 0 12px;\n    }\n    \n    \/* Make Watch button span full width *\/\n    .gvei-video-btn-primary {\n        grid-column: 1 \/ -1;\n    }\n    \n    .gvei-media-grid {\n        grid-template-columns: 1fr;\n    }\n    \n    .gvei-stats-grid {\n        grid-template-columns: repeat(2, 1fr);\n    }\n\n    \/* Schedule: mobile layout *\/\n    .gvei-schedule-day {\n        padding: 18px 0;\n    }\n\n    .gvei-schedule-date {\n        font-size: 15px;\n        margin-bottom: 10px;\n    }\n\n    .gvei-schedule-item {\n        padding: 16px;\n    }\n\n    .gvei-schedule-row-top {\n        flex-direction: column;\n        gap: 2px;\n    }\n\n    .gvei-schedule-time {\n        font-size: 13px;\n        min-width: unset;\n        padding-top: 0;\n        color: var(--dash-gray-400);\n    }\n\n    .gvei-schedule-type {\n        font-size: 17px;\n    }\n\n    .gvei-schedule-address {\n        font-size: 15px;\n        margin-top: 4px;\n        line-height: 1.45;\n    }\n\n    .gvei-schedule-meta-row {\n        margin-top: 8px;\n        gap: 12px;\n    }\n\n    .gvei-replaced-badge {\n        font-size: 12px;\n    }\n\n    .gvei-see-listing-link {\n        font-size: 14px;\n    }\n\n    .gvei-schedule-actions {\n        gap: 10px;\n        margin-top: 14px;\n        padding-top: 14px;\n    }\n\n    .gvei-schedule-actions .gvei-btn-small {\n        flex: 1;\n        text-align: center;\n        min-height: 46px;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        font-size: 14px;\n        font-weight: 600;\n        padding: 12px 14px;\n        border-radius: 10px;\n    }\n\n    .gvei-schedule-actions .gvei-replace-listing-btn {\n        background: #F8FAFC;\n        border: 1.5px solid #D1D5DB;\n    }\n\n    .gvei-schedule-actions .gvei-btn-outline {\n        border-width: 1.5px;\n        padding: 12px 14px;\n        font-weight: 600;\n        font-size: 14px;\n        min-height: 46px;\n        border-radius: 10px;\n    }\n}\n\n\/* Extra small screens *\/\n@media (max-width: 400px) {\n    .gvei-main-content {\n        padding: 8px;\n    }\n    \n    .gvei-card {\n        padding: 14px;\n    }\n    \n    .gvei-video-item {\n        padding: 14px;\n    }\n    \n    .gvei-video-actions {\n        grid-template-columns: 1fr;\n    }\n    \n    .gvei-video-btn {\n        height: 48px;\n    }\n}\n\n\/* Recording animations *\/\n@keyframes pulse {\n    0%, 100% { transform: scale(1); opacity: 1; }\n    50% { transform: scale(1.05); opacity: 0.9; }\n}\n\n@keyframes spin {\n    0% { transform: rotate(0deg); }\n    100% { transform: rotate(360deg); }\n}\n\n.gvei-spinner {\n    width: 40px;\n    height: 40px;\n    border: 3px solid #e5e7eb;\n    border-top-color: #8b5cf6;\n    border-radius: 50%;\n    animation: spin 1s linear infinite;\n}\n\n\/* Modal Styles *\/\n.gvei-modal {\n    display: none;\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 10000;\n    align-items: center;\n    justify-content: center;\n    padding: 20px;\n}\n\n.gvei-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.6);\n    backdrop-filter: blur(4px);\n}\n\n.gvei-modal-content {\n    position: relative;\n    background: white;\n    border-radius: 16px;\n    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n    width: 100%;\n    max-width: 500px;\n    max-height: 90vh;\n    overflow: auto;\n    animation: modalSlideIn 0.2s ease-out;\n}\n\n@keyframes modalSlideIn {\n    from {\n        opacity: 0;\n        transform: scale(0.95) translateY(-10px);\n    }\n    to {\n        opacity: 1;\n        transform: scale(1) translateY(0);\n    }\n}\n\n.gvei-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 20px 24px;\n    border-bottom: 1px solid var(--dash-gray-200);\n}\n\n.gvei-modal-header h3 {\n    margin: 0;\n    font-size: 18px;\n    font-weight: 700;\n    color: var(--dash-gray-900);\n}\n\n.gvei-modal-close {\n    background: none;\n    border: none;\n    font-size: 24px;\n    color: var(--dash-gray-400);\n    cursor: pointer;\n    padding: 0;\n    line-height: 1;\n    transition: color 0.15s;\n}\n\n.gvei-modal-close:hover {\n    color: var(--dash-gray-600);\n}\n\n.gvei-modal-body {\n    padding: 24px;\n}\n\n.gvei-modal-footer {\n    padding: 16px 24px;\n    border-top: 1px solid var(--dash-gray-200);\n    background: var(--dash-gray-50);\n    border-radius: 0 0 16px 16px;\n}\n\n\/* Toast animation *\/\n@keyframes toastSlideIn {\n    from {\n        opacity: 0;\n        transform: translateX(100%);\n    }\n    to {\n        opacity: 1;\n        transform: translateX(0);\n    }\n}\n\n<\/style>\n\n<div class=\"gvei-dashboard-wrapper\">\n<div class=\"gvei-dashboard\">\n    \n    <!-- Sidebar Overlay (mobile) -->\n    <div class=\"gvei-sidebar-overlay\" id=\"gvei-sidebar-overlay\"><\/div>\n    \n    <!-- Sidebar -->\n    <aside class=\"gvei-sidebar\" id=\"gvei-sidebar\">\n        <div class=\"gvei-sidebar-header\">\n            <div class=\"gvei-sidebar-logo\">\n                <span class=\"logo-gogo\">GOGO<\/span><span class=\"logo-it\">IT<\/span>\n            <\/div>\n            \n                    <\/div>\n        \n        <nav class=\"gvei-sidebar-nav\">\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=videos\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83d\udcf9<\/span>\n                    My Videos                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=overview\" \n                   class=\"gvei-nav-item active\">\n                    <span class=\"gvei-nav-icon\">\ud83d\udcca<\/span>\n                    Overview                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=schedule\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83d\udcc5<\/span>\n                    Schedule                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=locations\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83d\udccd<\/span>\n                    Video Locations                <\/a>\n                                                <div class=\"gvei-nav-group-label\">Settings<\/div>\n                                <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=profile\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83d\udc64<\/span>\n                    Profile                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=voice\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83c\udf99\ufe0f<\/span>\n                    Voice &amp; Audio                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=intros\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83c\udfac<\/span>\n                    Intro Clips                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=music\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83c\udfb5<\/span>\n                    Background Music                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=billing\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83d\udcb3<\/span>\n                    Billing                <\/a>\n                                            <a href=\"https:\/\/gogoit.com\/video\/agent-dashboard\/?tab=referrals\" \n                   class=\"gvei-nav-item \">\n                    <span class=\"gvei-nav-icon\">\ud83d\udcb0<\/span>\n                    Referrals                <\/a>\n                    <\/nav>\n        \n        <div class=\"gvei-sidebar-footer\">\n            <button type=\"button\" class=\"gvei-sidebar-help\" id=\"gvei-open-support-form\">\n                <span>\ud83d\udcac<\/span> Need help? Contact us            <\/button>\n        <\/div>\n    <\/aside>\n    \n    <!-- Support Form Panel -->\n    <div class=\"gvei-support-overlay\" id=\"gvei-support-overlay\"><\/div>\n    <div class=\"gvei-support-panel\" id=\"gvei-support-panel\">\n        <div class=\"gvei-support-header\">\n            <h3>\ud83d\udcac Contact Support<\/h3>\n            <button type=\"button\" class=\"gvei-support-close\" id=\"gvei-close-support\">&times;<\/button>\n        <\/div>\n        \n        <div class=\"gvei-support-body\">\n            <!-- Greeting with user info -->\n            <div class=\"gvei-support-greeting\">\n                Hi <strong>there<\/strong>! Need help? We&#039;ll reply to <strong><\/strong>            <\/div>\n            \n            <form id=\"gvei-support-form\" enctype=\"multipart\/form-data\">\n                <input type=\"hidden\" name=\"action\" value=\"gvei_submit_support_request\">\n                <input type=\"hidden\" name=\"client_id\" value=\"\">\n                <input type=\"hidden\" name=\"current_tab\" value=\"overview\">\n                <input type=\"hidden\" id=\"gvei_support_nonce\" name=\"gvei_support_nonce\" value=\"e367d401b3\" \/><input type=\"hidden\" name=\"_wp_http_referer\" value=\"\/video\/wp-json\/wp\/v2\/pages\/59\" \/>                \n                <div class=\"gvei-form-group\">\n                    <label class=\"gvei-label\">Subject <span style=\"color: #ef4444;\">*<\/span><\/label>\n                    <select name=\"subject\" id=\"gvei-support-subject\" class=\"gvei-input\" required>\n                        <option value=\"\">Select a topic...<\/option>\n                        <option value=\"Account Help\">Account Help<\/option>\n                        <option value=\"Billing Question\">Billing Question<\/option>\n                        <option value=\"Bug Report\">Bug Report<\/option>\n                        <option value=\"Video Issue\">Video Issue<\/option>\n                        <option value=\"General Question\">General Question<\/option>\n                    <\/select>\n                <\/div>\n                \n                <div class=\"gvei-form-group\">\n                    <label class=\"gvei-label\">Message <span style=\"color: #ef4444;\">*<\/span><\/label>\n                    <textarea name=\"message\" id=\"gvei-support-message\" class=\"gvei-input\" rows=\"4\" required\n                              placeholder=\"Please describe your question or issue in detail...\"><\/textarea>\n                <\/div>\n                \n                <div class=\"gvei-form-group\">\n                    <label class=\"gvei-label\">Screenshot (optional)<\/label>\n                    <div class=\"gvei-support-upload-area\" id=\"gvei-support-upload-area\">\n                        <input type=\"file\" name=\"screenshot\" id=\"gvei-support-screenshot\" accept=\"image\/jpeg,image\/png,image\/gif,image\/webp,.jpg,.jpeg,.png,.gif,.webp\" style=\"display: none;\">\n                        <div class=\"gvei-support-upload-prompt\" id=\"gvei-support-upload-prompt\">\n                            <span style=\"font-size: 24px;\">\ud83d\udcf7<\/span>\n                            <span>Click to add screenshot<\/span>\n                        <\/div>\n                        <div class=\"gvei-support-upload-preview\" id=\"gvei-support-upload-preview\" style=\"display: none;\">\n                            <img decoding=\"async\" id=\"gvei-support-preview-img\" src=\"\" alt=\"\">\n                            <button type=\"button\" class=\"gvei-support-remove-upload\" onclick=\"event.stopPropagation(); removeSupportScreenshot();\">&times;<\/button>\n                        <\/div>\n                    <\/div>\n                    <p class=\"gvei-helper\">Max 10MB. JPG, PNG, GIF, or WebP.<\/p>\n                <\/div>\n                \n                <button type=\"submit\" class=\"gvei-btn gvei-btn-primary gvei-support-submit\" style=\"width: 100%;\">\n                    \ud83d\udce8 Send Message                <\/button>\n            <\/form>\n            \n            <!-- Success State -->\n            <div class=\"gvei-support-success\" id=\"gvei-support-success\" style=\"display: none;\">\n                <div style=\"text-align: center; padding: 20px 20px 40px 20px;\">\n                    <div style=\"font-size: 48px; margin-bottom: 12px;\">\u2705<\/div>\n                    <h4 style=\"margin: 0 0 8px 0; color: var(--dash-gray-900); font-size: 20px;\">Message Sent!<\/h4>\n                    <p style=\"color: var(--dash-gray-600); margin: 0 0 24px 0; font-size: 14px;\">\n                        We&#039;ve received your request and will get back to you within 24 hours.                    <\/p>\n                    <button type=\"button\" class=\"gvei-btn gvei-btn-secondary\" onclick=\"closeSupportPanel()\">\n                        Close                    <\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n    \n    <!-- Main Content -->\n    <main class=\"gvei-main\">\n        \n        <!-- Header -->\n        <header class=\"gvei-main-header\">\n            <button class=\"gvei-mobile-toggle\" id=\"gvei-mobile-toggle\" aria-label=\"Toggle menu\">\n                <span class=\"hamburger-lines\">\n                    <span><\/span>\n                    <span><\/span>\n                    <span><\/span>\n                <\/span>\n            <\/button>\n            <h1 class=\"gvei-page-title\">\n                \ud83d\udcca Overview            <\/h1>\n            <div style=\"width: 44px;\"><\/div><!-- Spacer to balance hamburger -->\n        <\/header>\n        \n        <div class=\"gvei-main-content\">\n        \n                    <!-- Error State -->\n                <div class=\"gvei-error\">\n                    <div class=\"gvei-error-icon\">\ud83d\udd12<\/div>\n                <h2>Access Denied<\/h2>\n                <p>Access denied. Please use the link from your email.<\/p>\n            <\/div>\n            \n            \n    <\/div>\n    <\/main>\n    \n<\/div>\n\n<script>\n(function() {\n    'use strict';\n    \n    \/\/ Defensive try-catch for all initializations\n    try {\n    \n    \/\/ Mobile menu toggle\n    var sidebar = document.getElementById('gvei-sidebar');\n    var overlay = document.getElementById('gvei-sidebar-overlay');\n    var toggle = document.getElementById('gvei-mobile-toggle');\n    \n    if (toggle && sidebar && overlay) {\n        toggle.addEventListener('click', function() {\n            sidebar.classList.toggle('open');\n            overlay.classList.toggle('open');\n        });\n        \n        overlay.addEventListener('click', function() {\n            sidebar.classList.remove('open');\n            overlay.classList.remove('open');\n        });\n    }\n    \n    \/\/ Support Form Panel\n    var supportPanel = document.getElementById('gvei-support-panel');\n    var supportOverlay = document.getElementById('gvei-support-overlay');\n    var openSupportBtn = document.getElementById('gvei-open-support-form');\n    var closeSupportBtn = document.getElementById('gvei-close-support');\n    var supportForm = document.getElementById('gvei-support-form');\n    var supportSuccess = document.getElementById('gvei-support-success');\n    \n    function openSupportPanel() {\n        if (supportPanel && supportOverlay) {\n            supportPanel.classList.add('open');\n            supportOverlay.classList.add('open');\n            document.body.style.overflow = 'hidden';\n            \/\/ Close mobile sidebar if open\n            if (sidebar) sidebar.classList.remove('open');\n            if (overlay) overlay.classList.remove('open');\n        }\n    }\n    \n    window.closeSupportPanel = function() {\n        if (supportPanel && supportOverlay) {\n            supportPanel.classList.remove('open');\n            supportOverlay.classList.remove('open');\n            document.body.style.overflow = '';\n            \/\/ Reset form after closing\n            setTimeout(function() {\n                if (supportForm) {\n                    supportForm.reset();\n                    supportForm.style.display = 'block';\n                    \/\/ Reset submit button state\n                    var submitBtn = supportForm.querySelector('.gvei-support-submit');\n                    if (submitBtn) {\n                        submitBtn.innerHTML = '\ud83d\udce8 Send Message';\n                        submitBtn.disabled = false;\n                    }\n                }\n                if (supportSuccess) supportSuccess.style.display = 'none';\n                var greetingBox = document.querySelector('.gvei-support-greeting');\n                if (greetingBox) greetingBox.style.display = 'block';\n                \/\/ Reset screenshot upload\n                window.removeSupportScreenshot();\n            }, 300);\n        }\n    };\n    \n    if (openSupportBtn) {\n        openSupportBtn.addEventListener('click', openSupportPanel);\n    }\n    \n    if (closeSupportBtn) {\n        closeSupportBtn.addEventListener('click', closeSupportPanel);\n    }\n    \n    if (supportOverlay) {\n        supportOverlay.addEventListener('click', closeSupportPanel);\n    }\n    \n    \/\/ Support Screenshot Upload\n    var supportUploadArea = document.getElementById('gvei-support-upload-area');\n    var supportScreenshotInput = document.getElementById('gvei-support-screenshot');\n    var supportUploadPrompt = document.getElementById('gvei-support-upload-prompt');\n    var supportUploadPreview = document.getElementById('gvei-support-upload-preview');\n    var supportPreviewImg = document.getElementById('gvei-support-preview-img');\n    \n    if (supportUploadArea && supportScreenshotInput) {\n        supportUploadArea.addEventListener('click', function() {\n            supportScreenshotInput.click();\n        });\n        \n        supportScreenshotInput.addEventListener('change', function(e) {\n            var file = e.target.files[0];\n            if (!file) return;\n            \n            \/\/ Validate file size (10MB max)\n            if (file.size > 10 * 1024 * 1024) {\n                alert('File is too large. Maximum size is 10MB.');\n                supportScreenshotInput.value = '';\n                return;\n            }\n            \n            \/\/ Validate file type\n            var validTypes = ['image\/jpeg', 'image\/png', 'image\/gif', 'image\/webp'];\n            if (!validTypes.includes(file.type)) {\n                alert('Invalid file type. Please upload JPG, PNG, GIF, or WebP.');\n                supportScreenshotInput.value = '';\n                return;\n            }\n            \n            \/\/ Show preview\n            var reader = new FileReader();\n            reader.onload = function(e) {\n                supportPreviewImg.src = e.target.result;\n                supportUploadPrompt.style.display = 'none';\n                supportUploadPreview.style.display = 'block';\n            };\n            reader.readAsDataURL(file);\n        });\n    }\n    \n    window.removeSupportScreenshot = function() {\n        if (supportScreenshotInput) supportScreenshotInput.value = '';\n        if (supportUploadPrompt) supportUploadPrompt.style.display = 'flex';\n        if (supportUploadPreview) supportUploadPreview.style.display = 'none';\n        if (supportPreviewImg) supportPreviewImg.src = '';\n    };\n    \n    \/\/ Support Form Submission\n    if (supportForm) {\n        supportForm.addEventListener('submit', function(e) {\n            e.preventDefault();\n            \n            var submitBtn = supportForm.querySelector('.gvei-support-submit');\n            var originalText = submitBtn.innerHTML;\n            submitBtn.innerHTML = '\u23f3 Sending...';\n            submitBtn.disabled = true;\n            \n            var formData = new FormData(supportForm);\n            \n            fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n                method: 'POST',\n                body: formData\n            })\n            .then(function(response) { return response.json(); })\n            .then(function(data) {\n                if (data.success) {\n                    supportForm.style.display = 'none';\n                    var greetingBox = document.querySelector('.gvei-support-greeting');\n                    if (greetingBox) greetingBox.style.display = 'none';\n                    supportSuccess.style.display = 'block';\n                } else {\n                    alert(data.data.message || 'Something went wrong. Please try again.');\n                    submitBtn.innerHTML = originalText;\n                    submitBtn.disabled = false;\n                }\n            })\n            .catch(function(error) {\n                console.error('Support form error:', error);\n                alert('Network error. Please try again.');\n                submitBtn.innerHTML = originalText;\n                submitBtn.disabled = false;\n            });\n        });\n    }\n    \n    \/\/ Show voice recorder section\n    var rerecordVoiceBtn = document.getElementById('gvei-rerecord-btn');\n    if (rerecordVoiceBtn) {\n        rerecordVoiceBtn.addEventListener('click', function() {\n            var savedSection = document.getElementById('gvei-saved-voice-section');\n            var recorder = document.getElementById('gvei-voice-recorder');\n            if (savedSection) savedSection.style.display = 'none';\n            if (recorder) recorder.style.display = 'block';\n        });\n    }\n    \n    \/\/ Voice toggle buttons (Record vs Upload)\n    document.querySelectorAll('.gvei-voice-toggle-btn').forEach(function(btn) {\n        btn.addEventListener('click', function(e) {\n            e.preventDefault();\n            e.stopPropagation();\n            \n            var panel = btn.getAttribute('data-panel');\n            document.querySelectorAll('.gvei-voice-toggle-btn').forEach(function(b) {\n                b.classList.remove('active');\n                b.style.background = 'transparent';\n                b.style.color = 'var(--dash-gray-600)';\n            });\n            btn.classList.add('active');\n            btn.style.background = 'white';\n            btn.style.color = 'var(--dash-gray-900)';\n            \n            var recordPanel = document.getElementById('gvei-record-panel');\n            var uploadPanel = document.getElementById('gvei-upload-panel');\n            if (panel === 'record') {\n                if (recordPanel) recordPanel.style.display = 'block';\n                if (uploadPanel) uploadPanel.style.display = 'none';\n            } else {\n                if (recordPanel) recordPanel.style.display = 'none';\n                if (uploadPanel) uploadPanel.style.display = 'block';\n            }\n        });\n    });\n    \n    \/\/ Voice option selection\n    var voiceOptions = document.querySelectorAll('.gvei-voice-option');\n    voiceOptions.forEach(function(option) {\n        var radio = option.querySelector('input[type=\"radio\"]');\n        if (radio) {\n            option.addEventListener('click', function() {\n                voiceOptions.forEach(function(o) { o.classList.remove('selected'); });\n                option.classList.add('selected');\n                radio.checked = true;\n            });\n        }\n    });\n    \n    \/\/ End card color live preview\n    var ecBgInput = document.getElementById('end-card-bg-color');\n    var ecTextInput = document.getElementById('end-card-text-color');\n    var ecPreview = document.getElementById('gvei-endcard-preview');\n    if (ecBgInput && ecPreview) {\n        ecBgInput.addEventListener('input', function() {\n            ecPreview.style.background = this.value;\n        });\n    }\n    if (ecTextInput && ecPreview) {\n        ecTextInput.addEventListener('input', function() {\n            ecPreview.style.color = this.value;\n            var nameEl = ecPreview.querySelector('.gvei-endcard-name');\n            var phoneEl = ecPreview.querySelector('.gvei-endcard-phone');\n            if (nameEl) nameEl.style.color = this.value;\n            if (phoneEl) phoneEl.style.color = this.value;\n        });\n    }\n\n    \/\/ Profile form submission\n    var profileForm = document.getElementById('gvei-profile-form');\n    if (profileForm) {\n        profileForm.addEventListener('submit', function(e) {\n            e.preventDefault();\n            \n            var formData = new FormData(this);\n            var ajaxUrl = this.getAttribute('data-ajax-url');\n            var submitBtn = this.querySelector('button[type=\"submit\"]');\n            var originalText = submitBtn.innerHTML;\n            \n            submitBtn.innerHTML = '\u23f3 Saving...';\n            submitBtn.disabled = true;\n            \n            fetch(ajaxUrl, {\n                method: 'POST',\n                body: formData\n            })\n            .then(function(response) { return response.json(); })\n            .then(function(data) {\n                    submitBtn.disabled = false;\n                if (data.success) {\n                    submitBtn.innerHTML = '\u2713 Saved!';\n                                setTimeout(function() {\n                        submitBtn.innerHTML = originalText;\n                                }, 2000);\n                            } else {\n                    alert('Error: ' + (data.data ? data.data.message : 'Unknown error'));\n                    submitBtn.innerHTML = originalText;\n                }\n            })\n            .catch(function() {\n                alert('Server error. Please try again.');\n                submitBtn.innerHTML = originalText;\n                submitBtn.disabled = false;\n            });\n        });\n    }\n    \n    \/\/ Voice form submission\n    var voiceForm = document.getElementById('gvei-voice-form');\n    if (voiceForm) {\n        voiceForm.addEventListener('submit', function(e) {\n            e.preventDefault();\n            \n            var formData = new FormData(this);\n            var ajaxUrl = this.getAttribute('data-ajax-url');\n            var submitBtn = this.querySelector('button[type=\"submit\"]');\n            var originalText = submitBtn.innerHTML;\n            \n            submitBtn.innerHTML = '\u23f3 Saving...';\n            submitBtn.disabled = true;\n            \n            fetch(ajaxUrl, {\n                method: 'POST',\n                body: formData\n            })\n            .then(function(response) { return response.json(); })\n            .then(function(data) {\n                submitBtn.disabled = false;\n                if (data.success) {\n                    submitBtn.innerHTML = '\u2713 Saved!';\n                    setTimeout(function() {\n                        window.location.reload();\n                    }, 800);\n                } else {\n                    alert('Error: ' + (data.data ? data.data.message : 'Unknown error'));\n                    submitBtn.innerHTML = originalText;\n                }\n            })\n            .catch(function() {\n                alert('Server error. Please try again.');\n                submitBtn.innerHTML = originalText;\n                submitBtn.disabled = false;\n            });\n        });\n    }\n    \n    \/\/ ===== ACTIVATE OWN VOICE (switch back from preset) =====\n    window.gveiActivateOwnVoice = function() {\n        var btn = document.getElementById('gvei-activate-own-voice-btn');\n        if (btn) {\n            btn.innerHTML = '\u23f3 Saving...';\n            btn.disabled = true;\n        }\n        \n        var ajaxUrl = 'https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php';\n        var formData = new FormData();\n        formData.append('action', 'gvei_update_voice_settings');\n        formData.append('client_id', '');\n        formData.append('token', '');\n        formData.append('voice_mode', 'clone');\n        formData.append('gvei_voice_nonce', 'b110b0eeb5');\n        \n        fetch(ajaxUrl, { method: 'POST', body: formData })\n        .then(function(r) { return r.json(); })\n        .then(function(data) {\n            if (data.success) {\n                if (btn) btn.innerHTML = '\u2713 Saved!';\n                setTimeout(function() { window.location.reload(); }, 600);\n            } else {\n                alert('Error: ' + (data.data ? data.data.message : 'Unknown error'));\n                if (btn) { btn.innerHTML = '\u2713 Use My Voice'; btn.disabled = false; }\n            }\n        })\n        .catch(function() {\n            alert('Server error. Please try again.');\n            if (btn) { btn.innerHTML = '\u2713 Use My Voice'; btn.disabled = false; }\n        });\n    };\n    \n    \/\/ ===== VOICE RECORDING FUNCTIONALITY =====\n    var gveiDashMediaRecorder = null;\n    var gveiDashAudioChunks = [];\n    var gveiDashRecordingTimer = null;\n    var gveiDashRecordingSeconds = 0;\n    var gveiDashPendingAudioBlob = null;\n    var gveiDashMediaStream = null;\n    var gveiDashPendingUploadFile = null;\n    \n    window.gveiDashStartRecording = function() {\n        if (!navigator.mediaDevices) {\n            alert('Your browser does not support audio recording. Please use a modern browser or upload an audio file instead.');\n            return;\n        }\n        \n        navigator.mediaDevices.getUserMedia({ \n            audio: { echoCancellation: true, noiseSuppression: true, sampleRate: 44100 } \n        })\n        .then(function(stream) {\n            gveiDashMediaStream = stream;\n            \n            var options = {};\n            if (MediaRecorder.isTypeSupported('audio\/webm;codecs=opus')) {\n                options.mimeType = 'audio\/webm;codecs=opus';\n            } else if (MediaRecorder.isTypeSupported('audio\/webm')) {\n                options.mimeType = 'audio\/webm';\n            } else if (MediaRecorder.isTypeSupported('audio\/mp4')) {\n                options.mimeType = 'audio\/mp4';\n            }\n            \n            gveiDashMediaRecorder = new MediaRecorder(stream, options);\n            gveiDashAudioChunks = [];\n            \n            gveiDashMediaRecorder.ondataavailable = function(e) {\n                gveiDashAudioChunks.push(e.data);\n            };\n            \n            gveiDashMediaRecorder.onstop = function() {\n                var mimeType = gveiDashMediaRecorder.mimeType || 'audio\/webm';\n                gveiDashPendingAudioBlob = new Blob(gveiDashAudioChunks, { type: mimeType });\n                gveiDashShowReviewScreen();\n            };\n            \n            \/\/ Show countdown\n            var startArea = document.getElementById('gvei-record-start-area');\n            var countdownArea = document.getElementById('gvei-countdown-area');\n            if (startArea) startArea.style.display = 'none';\n            if (countdownArea) countdownArea.style.display = 'block';\n            \n            var countdownNum = 4;\n            var countdownEl = document.getElementById('gvei-countdown-number');\n            gveiDashRecordingSeconds = 0;\n            \n            var countdownInterval = setInterval(function() {\n                countdownNum--;\n                \n                if (countdownNum === 1) {\n                    gveiDashMediaRecorder.start();\n                }\n                \n                if (countdownNum > 0) {\n                    if (countdownEl) countdownEl.textContent = countdownNum;\n                } else {\n                    clearInterval(countdownInterval);\n                    if (countdownArea) countdownArea.style.display = 'none';\n                    var activeArea = document.getElementById('gvei-recording-active-area');\n                    if (activeArea) activeArea.style.display = 'block';\n                    \n                    var maxSeconds = 180;\n                    gveiDashRecordingTimer = setInterval(function() {\n                        gveiDashRecordingSeconds++;\n                        gveiDashUpdateRecordingTime();\n                        gveiDashUpdateProgress(gveiDashRecordingSeconds, maxSeconds);\n                        if (gveiDashRecordingSeconds >= maxSeconds) {\n                            gveiDashStopRecording();\n                        }\n                    }, 1000);\n                }\n            }, 1000);\n        })\n        .catch(function(err) {\n            console.error('Microphone access error:', err);\n            alert('Could not access microphone. Please check permissions or upload an audio file instead.');\n        });\n    };\n    \n    window.gveiDashStopRecording = function() {\n        if (gveiDashMediaRecorder && gveiDashMediaRecorder.state === 'recording') {\n            gveiDashMediaRecorder.stop();\n        }\n        if (gveiDashRecordingTimer) {\n            clearInterval(gveiDashRecordingTimer);\n            gveiDashRecordingTimer = null;\n        }\n        if (gveiDashMediaStream) {\n            gveiDashMediaStream.getTracks().forEach(function(track) { track.stop(); });\n            gveiDashMediaStream = null;\n        }\n    };\n    \n    function gveiDashUpdateRecordingTime() {\n        var timerEl = document.getElementById('gvei-record-timer');\n        if (timerEl) {\n            var mins = Math.floor(gveiDashRecordingSeconds \/ 60);\n            var secs = gveiDashRecordingSeconds % 60;\n            timerEl.textContent = mins + ':' + (secs < 10 ? '0' : '') + secs;\n        }\n    }\n    \n    function gveiDashUpdateProgress(seconds, maxSeconds) {\n        var progressBar = document.getElementById('gvei-recording-progress-bar');\n        var progressText = document.getElementById('gvei-recording-progress-text');\n        \n        var percentage = Math.min((seconds \/ 90) * 100, 100);\n        if (progressBar) progressBar.style.width = percentage + '%';\n        \n        if (progressText) {\n            if (seconds >= 90) {\n                progressText.textContent = '\u2713 Great! You have enough for an excellent voice clone.';\n                progressText.style.color = '#22c55e';\n                if (progressBar) progressBar.style.background = '#22c55e';\n            } else if (seconds >= 60) {\n                progressText.textContent = '\u2713 Good! 30 more seconds will be even better.';\n                progressText.style.color = '#f59e0b';\n                if (progressBar) progressBar.style.background = 'linear-gradient(90deg, #f59e0b, #22c55e)';\n            } else if (seconds >= 30) {\n                progressText.textContent = '\u2713 Minimum reached! Keep going for better quality.';\n                progressText.style.color = '#f59e0b';\n                if (progressBar) progressBar.style.background = 'linear-gradient(90deg, #f97316, #f59e0b)';\n            } else {\n                progressText.textContent = 'Keep going! Need at least 30 seconds.';\n                progressText.style.color = '#ef4444';\n            }\n        }\n    }\n    \n    function gveiDashShowReviewScreen() {\n        var activeArea = document.getElementById('gvei-recording-active-area');\n        var reviewArea = document.getElementById('gvei-record-review-area');\n        var audioPlayer = document.getElementById('gvei-recorded-audio-review');\n        var durationBadge = document.getElementById('gvei-recording-duration-badge');\n        \n        if (activeArea) activeArea.style.display = 'none';\n        if (reviewArea) reviewArea.style.display = 'block';\n        \n        if (audioPlayer && gveiDashPendingAudioBlob) {\n            audioPlayer.src = URL.createObjectURL(gveiDashPendingAudioBlob);\n        }\n        \n        if (durationBadge) {\n            var mins = Math.floor(gveiDashRecordingSeconds \/ 60);\n            var secs = gveiDashRecordingSeconds % 60;\n            var quality = '';\n            if (gveiDashRecordingSeconds >= 90) {\n                quality = '\u2713\u2713\u2713 Excellent';\n                durationBadge.style.background = '#dcfce7';\n                durationBadge.style.color = '#166534';\n            } else if (gveiDashRecordingSeconds >= 60) {\n                quality = '\u2713\u2713 Great';\n                durationBadge.style.background = '#dcfce7';\n                durationBadge.style.color = '#166534';\n            } else if (gveiDashRecordingSeconds >= 30) {\n                quality = '\u2713 Good';\n                durationBadge.style.background = '#fef3c7';\n                durationBadge.style.color = '#92400e';\n            } else {\n                quality = '\u26a0\ufe0f Short';\n                durationBadge.style.background = '#fee2e2';\n                durationBadge.style.color = '#991b1b';\n            }\n            durationBadge.textContent = quality + ' \u2022 ' + mins + ':' + (secs < 10 ? '0' : '') + secs;\n        }\n    }\n    \n    window.gveiDashReRecord = function() {\n        gveiDashPendingAudioBlob = null;\n        gveiDashRecordingSeconds = 0;\n        \n        var timerEl = document.getElementById('gvei-record-timer');\n        if (timerEl) timerEl.textContent = '0:00';\n        \n        var countdownEl = document.getElementById('gvei-countdown-number');\n        if (countdownEl) countdownEl.textContent = '4';\n        \n        var progressBar = document.getElementById('gvei-recording-progress-bar');\n        var progressText = document.getElementById('gvei-recording-progress-text');\n        if (progressBar) {\n            progressBar.style.width = '0%';\n            progressBar.style.background = 'linear-gradient(90deg, #ef4444, #f97316)';\n        }\n        if (progressText) {\n            progressText.textContent = 'Keep going! Need at least 30 seconds.';\n            progressText.style.color = '#ef4444';\n        }\n        \n        \/\/ Restore review area HTML if it was replaced by the upload spinner\n        var reviewArea = document.getElementById('gvei-record-review-area');\n        if (reviewArea && window._gveiDashReviewHTML) {\n            reviewArea.innerHTML = window._gveiDashReviewHTML;\n        }\n        \n        var startArea = document.getElementById('gvei-record-start-area');\n        var countdownArea = document.getElementById('gvei-countdown-area');\n        var activeArea = document.getElementById('gvei-recording-active-area');\n        if (startArea) startArea.style.display = 'block';\n        if (countdownArea) countdownArea.style.display = 'none';\n        if (activeArea) activeArea.style.display = 'none';\n        if (reviewArea) reviewArea.style.display = 'none';\n    };\n    \n    window.gveiDashSubmitVoice = function() {\n        if (!gveiDashPendingAudioBlob) {\n            alert('No recording found. Please try again.');\n            return;\n        }\n        \n        var reviewArea = document.getElementById('gvei-record-review-area');\n        if (reviewArea) {\n            if (!window._gveiDashReviewHTML) {\n                window._gveiDashReviewHTML = reviewArea.innerHTML;\n            }\n            reviewArea.innerHTML = '<div style=\"text-align: center; padding: 40px 20px;\">' +\n                '<div class=\"gvei-spinner\" style=\"width: 40px; height: 40px; border: 3px solid #e5e7eb; border-top-color: #8b5cf6; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 16px;\"><\/div>' +\n                '<p style=\"color: var(--dash-gray-600);\">Saving your voice...<\/p>' +\n            '<\/div>';\n        }\n        \n        var clientId = '';\n        var ajaxUrl = 'https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php';\n        \n        if (!clientId) {\n            alert('Session expired. Please refresh the page.');\n            gveiDashReRecord();\n            return;\n        }\n        \n        \/\/ Build the transcript text that matches what's displayed on screen\n        \/\/ This MUST match what the user recorded for voice cloning to work!\n        var agentName = 'your name';\n        var transcriptText = \"Hi, my name is \" + agentName + \". I'm reading this so you can hear how I normally speak. \" +\n            \"Here's what just got listed in this neighborhood. This home has four bedrooms, three bathrooms, and about two thousand four hundred square feet of space. It feels open, bright, and very welcoming the moment you walk in. \" +\n            \"The kitchen is clean and modern, with a large island, new appliances, and lots of light. It flows right into the living room, which makes the space feel big and comfortable. This looks amazing. \" +\n            \"The primary bedroom is quiet and spacious. The bathroom has a double sink, a walk-in shower, and a soaking tub. Everything feels simple, fresh, and easy to enjoy.\";\n        \n        var formData = new FormData();\n        formData.append('action', 'gvei_upload_voice_file');\n        formData.append('client_id', clientId);\n        formData.append('duration', gveiDashRecordingSeconds);\n        formData.append('voice_sample_text', transcriptText); \/\/ CRITICAL for voice cloning!\n        \n        var ext = 'webm';\n        if (gveiDashPendingAudioBlob.type.indexOf('mp4') !== -1) ext = 'm4a';\n        if (gveiDashPendingAudioBlob.type.indexOf('mpeg') !== -1) ext = 'mp3';\n        formData.append('voice_file', gveiDashPendingAudioBlob, 'voice-sample.' + ext);\n        \n        fetch(ajaxUrl, { method: 'POST', body: formData })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (data.success) {\n                var audioUrl = data.data ? data.data.url : '';\n                gveiDashShowVoiceSuccess(audioUrl);\n            } else {\n                var errMsg = data.data || 'Unknown error';\n                alert('Error saving voice: ' + errMsg);\n                gveiDashReRecord();\n            }\n        })\n        .catch(function(err) {\n            console.error('Voice upload error:', err);\n            alert('Error saving voice. Please try again.');\n            gveiDashReRecord();\n        });\n    };\n    \n    function gveiDashShowVoiceSuccess(audioUrl) {\n        gveiDashPendingAudioBlob = null;\n        gveiDashPendingUploadFile = null;\n        \n        \/\/ Hide recorder, show saved voice section\n        var recorder = document.getElementById('gvei-voice-recorder');\n        var savedSection = document.getElementById('gvei-saved-voice-section');\n        var savedAudio = document.getElementById('gvei-saved-voice-audio');\n        \n        if (recorder) recorder.style.display = 'none';\n        if (savedSection) savedSection.style.display = 'block';\n        if (savedAudio && audioUrl) savedAudio.src = audioUrl + '?v=' + Date.now();\n        \n        \/\/ Reset for next time\n        gveiDashReRecord();\n        \n        \/\/ Reload page so banner\/badges reflect voice_mode=clone\n        setTimeout(function() { window.location.reload(); }, 1200);\n    }\n    \n    \/\/ ===== VOICE FILE UPLOAD =====\n    var voiceFileInput = document.getElementById('gvei-voice-file-input');\n    if (voiceFileInput) {\n        voiceFileInput.addEventListener('change', function(e) {\n            var file = e.target.files[0];\n            if (!file) return;\n            \n            if (file.size > 40 * 1024 * 1024) {\n                alert('File is too large. Maximum size is 40MB.');\n                return;\n            }\n            \n            gveiDashPendingUploadFile = file;\n            \n            var uploadArea = document.getElementById('gvei-voice-upload-area');\n            var previewArea = document.getElementById('gvei-upload-preview');\n            var audioEl = document.getElementById('gvei-uploaded-audio');\n            var filenameEl = document.getElementById('gvei-uploaded-filename');\n            \n            if (uploadArea) uploadArea.style.display = 'none';\n            if (previewArea) previewArea.style.display = 'block';\n            if (filenameEl) filenameEl.textContent = file.name;\n            if (audioEl) audioEl.src = URL.createObjectURL(file);\n        });\n    }\n    \n    window.gveiDashDiscardUpload = function() {\n        gveiDashPendingUploadFile = null;\n        var uploadArea = document.getElementById('gvei-voice-upload-area');\n        var previewArea = document.getElementById('gvei-upload-preview');\n        var fileInput = document.getElementById('gvei-voice-file-input');\n        var audioEl = document.getElementById('gvei-uploaded-audio');\n        \n        if (uploadArea) uploadArea.style.display = 'block';\n        if (previewArea) previewArea.style.display = 'none';\n        if (fileInput) fileInput.value = '';\n        if (audioEl) audioEl.src = '';\n    };\n    \n    window.gveiDashSaveUploadedVoice = function() {\n        if (!gveiDashPendingUploadFile) {\n            alert('No file selected. Please try again.');\n            return;\n        }\n        \n        var previewArea = document.getElementById('gvei-upload-preview');\n        if (previewArea) {\n            previewArea.innerHTML = '<div style=\"text-align: center; padding: 20px;\">' +\n                '<div class=\"gvei-spinner\" style=\"width: 40px; height: 40px; border: 3px solid #e5e7eb; border-top-color: #8b5cf6; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 16px;\"><\/div>' +\n                '<p style=\"color: var(--dash-gray-600);\">Uploading your voice...<\/p>' +\n            '<\/div>';\n        }\n        \n        var clientId = '';\n        var ajaxUrl = 'https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php';\n        \n        var formData = new FormData();\n        formData.append('action', 'gvei_upload_voice_file');\n        formData.append('client_id', clientId);\n        formData.append('voice_file', gveiDashPendingUploadFile);\n        \n        fetch(ajaxUrl, { method: 'POST', body: formData })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (data.success) {\n                var audioUrl = data.data ? data.data.url : '';\n                gveiDashShowVoiceSuccess(audioUrl);\n            } else {\n                var errMsg = data.data || 'Unknown error';\n                alert('Error uploading voice: ' + errMsg);\n                gveiDashDiscardUpload();\n            }\n        })\n        .catch(function(err) {\n            console.error('Voice upload error:', err);\n            alert('Error uploading voice. Please try again.');\n            gveiDashDiscardUpload();\n        });\n    };\n    \n    \/\/ ===== DRAG & DROP FOR VOICE UPLOAD =====\n    (function() {\n        var uploadArea = document.getElementById('gvei-voice-upload-area');\n        var fileInput = document.getElementById('gvei-voice-file-input');\n        \n        if (!uploadArea || !fileInput) return;\n        \n        \/\/ Click to upload\n        uploadArea.addEventListener('click', function() {\n            fileInput.click();\n        });\n        \n        \/\/ Prevent default drag behaviors\n        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function(eventName) {\n            uploadArea.addEventListener(eventName, function(e) {\n                e.preventDefault();\n                e.stopPropagation();\n            }, false);\n        });\n        \n        \/\/ Highlight on drag\n        ['dragenter', 'dragover'].forEach(function(eventName) {\n            uploadArea.addEventListener(eventName, function() {\n                uploadArea.style.borderColor = 'var(--dash-primary)';\n                uploadArea.style.background = 'var(--dash-gray-50)';\n            }, false);\n        });\n        \n        \/\/ Remove highlight on drag leave\/drop\n        ['dragleave', 'drop'].forEach(function(eventName) {\n            uploadArea.addEventListener(eventName, function() {\n                uploadArea.style.borderColor = 'var(--dash-gray-300)';\n                uploadArea.style.background = 'transparent';\n            }, false);\n        });\n        \n        \/\/ Handle drop\n        uploadArea.addEventListener('drop', function(e) {\n            var dt = e.dataTransfer;\n            var files = dt.files;\n            \n            if (files.length > 0) {\n                var file = files[0];\n                \/\/ Check if audio file\n                if (file.type.indexOf('audio\/') === 0 || file.name.match(\/\\.(mp3|wav|m4a)$\/i)) {\n                    \/\/ Trigger the same handler as file input\n                    fileInput.files = files;\n                    var event = new Event('change', { bubbles: true });\n                    fileInput.dispatchEvent(event);\n                } else {\n                    alert('Please drop an audio file (MP3, WAV, or M4A).');\n                }\n            }\n        }, false);\n    })();\n    \n    \/\/ ===== GLOBAL AUDIO MANAGEMENT =====\n    var gveiCurrentAudio = null;\n    var gveiPreviewGenerating = false;\n    \n    \/\/ Stop all playing audio\n    window.gveiStopAllAudio = function() {\n        \/\/ Stop preview audio\n        var previewAudio = document.getElementById('gvei-voice-preview-audio');\n        if (previewAudio) {\n            previewAudio.pause();\n            previewAudio.currentTime = 0;\n        }\n        \n        \/\/ Stop saved voice audio\n        var savedAudio = document.getElementById('gvei-saved-voice-audio');\n        if (savedAudio) {\n            savedAudio.pause();\n            savedAudio.currentTime = 0;\n        }\n        \n        \/\/ Stop uploaded audio preview\n        var uploadedAudio = document.getElementById('gvei-uploaded-audio');\n        if (uploadedAudio) {\n            uploadedAudio.pause();\n            uploadedAudio.currentTime = 0;\n        }\n        \n        \/\/ Stop recorded audio review\n        var recordedAudio = document.getElementById('gvei-recorded-audio-review');\n        if (recordedAudio) {\n            recordedAudio.pause();\n            recordedAudio.currentTime = 0;\n        }\n        \n        \/\/ Reset all preview buttons (old style)\n        document.querySelectorAll('.gvei-voice-preview-btn').forEach(function(btn) {\n            btn.innerHTML = '\u25b6 Preview';\n            btn.disabled = false;\n        });\n        \n        \/\/ Reset all voice play buttons (new card style)\n        document.querySelectorAll('.gvei-voice-play').forEach(function(btn) {\n            var playIcon = btn.querySelector('.play-icon');\n            if (playIcon) playIcon.textContent = '\u25b6';\n            btn.style.background = 'var(--dash-primary)';\n            btn.classList.remove('loading');\n        });\n    };\n    \n    \/\/ Stop audio when switching tabs\n    document.querySelectorAll('.gvei-nav-item').forEach(function(link) {\n        link.addEventListener('click', gveiStopAllAudio);\n    });\n    \n    \/\/ Stop audio when switching voice toggle (record vs upload)\n    document.querySelectorAll('.gvei-voice-toggle-btn').forEach(function(btn) {\n        btn.addEventListener('click', gveiStopAllAudio);\n    });\n    \n    \/\/ ===== VIDEO LOCATIONS (ZIP CODES) =====\n    var gveiLocationsHasUnsavedChanges = false;\n    \n    \/\/ Mark locations form as having unsaved changes\n    window.markLocationsUnsaved = function() {\n        if (gveiLocationsHasUnsavedChanges) return; \/\/ Already marked\n        gveiLocationsHasUnsavedChanges = true;\n        \n        var warning = document.getElementById('gvei-locations-unsaved-warning');\n        var saveBtn = document.getElementById('gvei-locations-save-btn');\n        \n        if (warning) {\n            warning.style.display = 'block';\n        }\n        if (saveBtn) {\n            saveBtn.style.background = 'linear-gradient(135deg, #F59E0B 0%, #D97706 100%)';\n            saveBtn.style.animation = 'gvei-pulse 2s infinite';\n        }\n    };\n    \n    \/\/ Clear unsaved changes state\n    window.clearLocationsUnsaved = function() {\n        gveiLocationsHasUnsavedChanges = false;\n        \n        var warning = document.getElementById('gvei-locations-unsaved-warning');\n        var saveBtn = document.getElementById('gvei-locations-save-btn');\n        \n        if (warning) {\n            warning.style.display = 'none';\n        }\n        if (saveBtn) {\n            saveBtn.style.background = '';\n            saveBtn.style.animation = '';\n        }\n    };\n    \n    \/\/ Add secondary ZIP field\n    window.addSecondaryZip = function() {\n        var container = document.getElementById('secondary-zips-container');\n        if (!container) return;\n        \n        var newItem = document.createElement('div');\n        newItem.className = 'gvei-zip-item';\n        newItem.style.cssText = 'position: relative;';\n        newItem.innerHTML = '<input type=\"tel\" name=\"secondary_zips[]\" class=\"gvei-input gvei-secondary-zip gvei-zip-input\" placeholder=\"ZIP Code\" maxlength=\"5\" pattern=\"[0-9]{5}\" autocomplete=\"off\" data-lpignore=\"true\" data-form-type=\"other\" data-1p-ignore=\"true\" style=\"width: 100%; padding-right: 40px;\">' +\n                            '<button type=\"button\" class=\"gvei-remove-zip\" onclick=\"removeZipField(this); markLocationsUnsaved();\" style=\"position: absolute; right: 8px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--dash-gray-400); cursor: pointer; font-size: 18px; padding: 4px; line-height: 1;\" title=\"Remove\">\u00d7<\/button>';\n        container.appendChild(newItem);\n        \n        \/\/ Add change listener to new input\n        var newInput = newItem.querySelector('input');\n        newInput.addEventListener('input', markLocationsUnsaved);\n        \n        \/\/ Focus the new input\n        newInput.focus();\n        \n        \/\/ Mark as unsaved since we added a new field\n        markLocationsUnsaved();\n    };\n    \n    \/\/ Remove secondary ZIP field\n    window.removeZipField = function(btn) {\n        var item = btn.closest('.gvei-zip-item');\n        if (item) {\n            item.remove();\n        }\n    };\n    \n    \/\/ Track changes on all existing ZIP inputs\n    document.querySelectorAll('.gvei-zip-input').forEach(function(input) {\n        input.addEventListener('input', markLocationsUnsaved);\n    });\n    \n    \/\/ Warn before leaving page with unsaved changes\n    window.addEventListener('beforeunload', function(e) {\n        if (gveiLocationsHasUnsavedChanges) {\n            e.preventDefault();\n            e.returnValue = 'You have unsaved ZIP code changes. Are you sure you want to leave?';\n            return e.returnValue;\n        }\n    });\n    \n    \/\/ Handle locations form submission\n    var locationsForm = document.getElementById('gvei-locations-form');\n    if (locationsForm) {\n        locationsForm.addEventListener('submit', function(e) {\n            e.preventDefault();\n            \n            var formData = new FormData(locationsForm);\n            var submitBtn = document.getElementById('gvei-locations-save-btn');\n            var originalText = submitBtn.innerHTML;\n            var originalBg = submitBtn.style.background;\n            \n            submitBtn.disabled = true;\n            submitBtn.innerHTML = '\u23f3 Saving...';\n            submitBtn.style.background = '';\n            submitBtn.style.animation = '';\n            \n            fetch(locationsForm.getAttribute('data-ajax-url'), {\n                method: 'POST',\n                body: formData\n            })\n            .then(function(response) { return response.json(); })\n            .then(function(data) {\n                submitBtn.disabled = false;\n                if (data.success) {\n                    submitBtn.innerHTML = '\u2705 Saved!';\n                    clearLocationsUnsaved(); \/\/ Clear unsaved state\n                    setTimeout(function() {\n                        submitBtn.innerHTML = originalText;\n                    }, 2000);\n                } else {\n                    submitBtn.innerHTML = originalText;\n                    \/\/ Restore unsaved state if save failed\n                    if (gveiLocationsHasUnsavedChanges) {\n                        markLocationsUnsaved();\n                    }\n                    alert('Error: ' + (data.data ? data.data.message : 'Could not save locations'));\n                }\n            })\n            .catch(function(err) {\n                console.error('Save error:', err);\n                submitBtn.disabled = false;\n                submitBtn.innerHTML = originalText;\n                \/\/ Restore unsaved state if save failed\n                if (gveiLocationsHasUnsavedChanges) {\n                    markLocationsUnsaved();\n                }\n                alert('Error saving locations. Please try again.');\n            });\n        });\n    }\n    \n    \/\/ ===== VOICE FILTER BUTTONS =====\n    document.querySelectorAll('.gvei-filter-btn').forEach(function(btn) {\n        btn.addEventListener('click', function(e) {\n            e.preventDefault();\n            var filter = btn.getAttribute('data-filter');\n            \n            \/\/ Update active state\n            document.querySelectorAll('.gvei-filter-btn').forEach(function(b) {\n                b.classList.remove('active');\n            });\n            btn.classList.add('active');\n            \n            \/\/ Filter voice cards\n            document.querySelectorAll('.gvei-voice-card').forEach(function(card) {\n                var gender = card.getAttribute('data-gender');\n                if (filter === 'all' || gender === filter) {\n                    card.style.display = 'flex';\n                } else {\n                    card.style.display = 'none';\n                }\n            });\n        });\n    });\n    \n    \/\/ ===== VOICE CARD SELECTION =====\n    document.querySelectorAll('.gvei-voice-card').forEach(function(card) {\n        card.addEventListener('click', function(e) {\n            \/\/ Don't select if clicking on play button\n            if (e.target.closest('.gvei-voice-play')) return;\n            \n            var voiceId = card.getAttribute('data-voice-id');\n            \n            \/\/ Update hidden inputs (voice_library_id is the new standard)\n            var libraryIdInput = document.getElementById('voice-library-id-hidden');\n            if (libraryIdInput) {\n                libraryIdInput.value = voiceId;\n            }\n            \/\/ Also set voice_preset for backwards compatibility\n            var presetInput = document.getElementById('voice-preset-hidden');\n            if (presetInput) {\n                presetInput.value = voiceId;\n            }\n            \n            \/\/ Update visual selection\n            document.querySelectorAll('.gvei-voice-card').forEach(function(c) {\n                c.classList.remove('selected');\n                c.style.background = 'var(--dash-gray-100)';\n                c.style.boxShadow = 'none';\n            });\n            card.classList.add('selected');\n            card.style.background = 'linear-gradient(135deg, rgba(99,102,241,0.1) 0%, rgba(139,92,246,0.08) 100%)';\n            card.style.boxShadow = 'inset 0 0 0 2px var(--dash-primary)';\n        });\n    });\n    \n    \/\/ Auto-scroll to the currently selected voice card so it's visible\n    var selectedVoiceCard = document.querySelector('.gvei-voice-card.selected');\n    if (selectedVoiceCard) {\n        var voiceList = selectedVoiceCard.closest('.gvei-voice-list');\n        if (voiceList) {\n            setTimeout(function() {\n                selectedVoiceCard.scrollIntoView({ block: 'center', behavior: 'smooth' });\n            }, 300);\n        }\n    }\n\n    \/\/ ===== PRESET VOICE PREVIEW (Voice Library - direct sample playback) =====\n    document.querySelectorAll('.gvei-voice-play').forEach(function(btn) {\n        btn.addEventListener('click', function(e) {\n            e.preventDefault();\n            e.stopPropagation();\n            \n            var voiceId = btn.getAttribute('data-voice-id');\n            var previewAudio = document.getElementById('gvei-voice-preview-audio');\n            var playIcon = btn.querySelector('.play-icon');\n            \n            \/\/ Get sample URL from the parent card\n            var card = btn.closest('.gvei-voice-card');\n            var sampleUrl = card ? card.getAttribute('data-sample') : null;\n            \n            \/\/ If same voice is playing, pause it\n            if (gveiCurrentAudio === voiceId && previewAudio && !previewAudio.paused) {\n                previewAudio.pause();\n                if (playIcon) playIcon.textContent = '\u25b6';\n                btn.style.background = 'var(--dash-primary)';\n                gveiCurrentAudio = null;\n                return;\n            }\n            \n            \/\/ Stop any currently playing audio\n            gveiStopAllAudio();\n            \n            \/\/ Check if we have a sample URL\n            if (!sampleUrl) {\n                alert('No audio sample available for this voice.');\n                return;\n            }\n            \n            \/\/ Show loading state\n            btn.classList.add('loading');\n            btn.style.position = 'relative';\n            if (playIcon) playIcon.textContent = '...';\n            gveiCurrentAudio = voiceId;\n            \n            \/\/ Play directly from Voice Library sample URL\n            previewAudio.src = sampleUrl;\n            \n            previewAudio.oncanplaythrough = function() {\n                previewAudio.play();\n                btn.classList.remove('loading');\n                if (playIcon) playIcon.textContent = '\u23f8';\n                btn.style.background = '#10b981'; \/\/ Green when playing\n            };\n            \n            previewAudio.onerror = function() {\n                btn.classList.remove('loading');\n                alert('Could not play voice sample. Please try again.');\n                if (playIcon) playIcon.textContent = '\u25b6';\n                gveiCurrentAudio = null;\n            };\n            \n            \/\/ Reset button when audio ends\n            previewAudio.onended = function() {\n                if (playIcon) playIcon.textContent = '\u25b6';\n                btn.style.background = 'var(--dash-primary)';\n                gveiCurrentAudio = null;\n            };\n            \n            previewAudio.load();\n        });\n    });\n    \n    \/\/ ===== PHOTO UPLOAD WITH CROPPER =====\n    var photoCropper = null;\n    var photoUploadHandlerAttached = false;\n    \n    \/\/ Initialize photo upload - handles file selection\n    function initPhotoUpload() {\n        var photoInput = document.getElementById('agent-photo-input');\n        var photoPreview = document.getElementById('photo-preview');\n        var cropModal = document.getElementById('gvei-crop-modal');\n        var cropImage = document.getElementById('gvei-crop-image');\n        \n        \/\/ Only proceed if we're on a page with these elements (profile tab)\n        if (!photoInput) {\n            console.log('Photo upload: Not on profile tab or elements not found');\n            return;\n        }\n        \n        \/\/ Prevent double handler attachment but allow re-checking\n        if (photoUploadHandlerAttached) {\n            console.log('Photo upload: Handler already attached');\n            return;\n        }\n        \n        photoUploadHandlerAttached = true;\n        console.log('Photo upload: Initializing...');\n        \n        \/\/ Handle file selection - use onchange to prevent duplicates\n        photoInput.onchange = function(e) {\n            var file = e.target.files[0];\n            if (!file) return;\n            \n            console.log('Photo upload: File selected:', file.name, file.type);\n            \n            \/\/ Check if it's an image\n            var isImage = file.type && file.type.indexOf('image\/') === 0;\n            var isHeic = file.name.toLowerCase().match(\/\\.(heic|heif)$\/i) || file.type === 'image\/heic' || file.type === 'image\/heif';\n            \n            \/\/ Accept common image formats\n            var validExtensions = \/\\.(jpg|jpeg|png|gif|webp|bmp|tiff?)$\/i;\n            var hasValidExtension = file.name.match(validExtensions);\n            \n            if (!isImage && !isHeic && !hasValidExtension) {\n                alert('Please select an image file (JPG, PNG, GIF, WebP, or BMP).');\n                photoInput.value = '';\n                return;\n            }\n            \n            \/\/ Handle HEIC\/HEIF files (iPhone)\n            if (isHeic) {\n                \/\/ Try heic2any conversion if available\n                if (typeof heic2any !== 'undefined') {\n                    console.log('Photo upload: Attempting HEIC conversion...');\n                    heic2any({\n                        blob: file,\n                        toType: 'image\/jpeg',\n                        quality: 0.9\n                    }).then(function(convertedBlob) {\n                        console.log('Photo upload: HEIC converted successfully');\n                        openCropModal(convertedBlob);\n                    }).catch(function(err) {\n                        console.error('Photo upload: HEIC client conversion failed, will try server-side');\n                        \/\/ Fallback: upload raw HEIC to server for conversion\n                        uploadHeicToServer(file);\n                    });\n                } else {\n                    \/\/ No client-side converter, try server\n                    uploadHeicToServer(file);\n                }\n                return;\n            }\n            \n            \/\/ Helper to convert HEIC via server and then open cropper\n            function uploadHeicToServer(heicFile) {\n                var formData = new FormData();\n                formData.append('action', 'gvei_convert_heic');\n                formData.append('nonce', '6e44952dee');\n                formData.append('image', heicFile, heicFile.name);\n                \n                \/\/ Show loading state\n                if (photoPreview) {\n                    photoPreview.innerHTML = '<div style=\"display:flex;align-items:center;justify-content:center;width:100%;height:100%;\"><span style=\"animation:spin 1s linear infinite;\">\u23f3<\/span> Converting...<\/div>';\n                }\n                \n                fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n                    method: 'POST',\n                    body: formData\n                })\n                .then(function(response) { return response.json(); })\n                .then(function(data) {\n                    if (data.success && data.data.jpeg_data) {\n                        console.log('Photo upload: Server converted HEIC successfully, opening cropper');\n                        \/\/ Convert base64 to blob and open cropper\n                        var byteString = atob(data.data.jpeg_data);\n                        var ab = new ArrayBuffer(byteString.length);\n                        var ia = new Uint8Array(ab);\n                        for (var i = 0; i < byteString.length; i++) {\n                            ia[i] = byteString.charCodeAt(i);\n                        }\n                        var blob = new Blob([ab], { type: 'image\/jpeg' });\n                        \n                        \/\/ Restore preview while cropper opens\n                        if (photoPreview && originalPhotoSrc) {\n                            photoPreview.innerHTML = '<img decoding=\"async\" src=\"' + originalPhotoSrc + '\" style=\"width:100%;height:100%;object-fit:cover;\" alt=\"\">';\n                        }\n                        \n                        \/\/ Open the cropper with converted image\n                        openCropModal(blob);\n                    } else {\n                        console.error('Photo upload: Server conversion failed', data);\n                        var msg = data.data ? data.data.message : 'Could not process HEIC file.';\n                        msg += '\\n\\n\ud83d\udcf1 Quick fix: Take a screenshot of your photo on your phone, then upload the screenshot instead!';\n                        alert(msg);\n                        photoInput.value = '';\n                        \/\/ Restore preview\n                        if (photoPreview && originalPhotoSrc) {\n                            photoPreview.innerHTML = '<img decoding=\"async\" src=\"' + originalPhotoSrc + '\" style=\"width:100%;height:100%;object-fit:cover;\" alt=\"\">';\n                        }\n                    }\n                })\n                .catch(function(err) {\n                    console.error('Photo upload: Server error', err);\n                    alert('Upload failed. Please try again.');\n                    photoInput.value = '';\n                    \/\/ Restore preview\n                    if (photoPreview && originalPhotoSrc) {\n                        photoPreview.innerHTML = '<img decoding=\"async\" src=\"' + originalPhotoSrc + '\" style=\"width:100%;height:100%;object-fit:cover;\" alt=\"\">';\n                    }\n                });\n            }\n            \n            \/\/ Store original photo src for restoration\n            var originalPhotoSrc = photoPreview ? (photoPreview.querySelector('img') ? photoPreview.querySelector('img').src : null) : null;\n            \n            \/\/ Load regular image\n            openCropModal(file);\n        };\n        \n        \/\/ Open crop modal with image\n        function openCropModal(file) {\n            var reader = new FileReader();\n            reader.onload = function(ev) {\n                console.log('Photo upload: Image loaded, opening cropper');\n                console.log('Photo upload: Data length:', ev.target.result.length);\n                \n                if (!cropModal || !cropImage) {\n                    console.error('Photo upload: Crop modal elements not found');\n                    alert('Image cropper not available. Please refresh the page.');\n                    return;\n                }\n                \n                \/\/ Destroy existing cropper first if any\n                if (photoCropper) {\n                    photoCropper.destroy();\n                    photoCropper = null;\n                }\n                \n                \/\/ Set up onload handler before setting src\n                cropImage.onload = function() {\n                    console.log('Photo upload: Crop image loaded, initializing cropper');\n                    \n                    \/\/ Check if Cropper.js is loaded\n                    if (typeof Cropper === 'undefined') {\n                        console.error('Photo upload: Cropper.js not loaded!');\n                        alert('Image cropper not available. Please refresh the page and try again.');\n                        cropModal.classList.remove('active');\n                        return;\n                    }\n                    \n                    \/\/ Initialize cropper with circular crop\n                    photoCropper = new Cropper(cropImage, {\n                        aspectRatio: 1,\n                        viewMode: 1,\n                        dragMode: 'move',\n                        autoCropArea: 0.9,\n                        cropBoxResizable: false,\n                        cropBoxMovable: false,\n                        guides: false,\n                        center: false,\n                        highlight: false,\n                        background: false,\n                        responsive: true,\n                        restore: false,\n                        ready: function() {\n                            console.log('Photo upload: Cropper ready');\n                        }\n                    });\n                };\n                \n                \/\/ Now set the source and show modal\n                cropImage.src = ev.target.result;\n                cropModal.classList.add('active');\n            };\n            reader.onerror = function() {\n                console.error('Photo upload: Error reading file');\n                alert('Error reading image file. Please try again.');\n            };\n            reader.readAsDataURL(file);\n        }\n        \n        \/\/ Zoom controls - use onclick\n        var zoomIn = document.getElementById('gvei-zoom-in');\n        var zoomOut = document.getElementById('gvei-zoom-out');\n        \n        if (zoomIn) {\n            zoomIn.onclick = function() {\n                if (photoCropper) photoCropper.zoom(0.1);\n            };\n        }\n        if (zoomOut) {\n            zoomOut.onclick = function() {\n                if (photoCropper) photoCropper.zoom(-0.1);\n            };\n        }\n        \n        \/\/ Cancel crop - use onclick\n        var cropCancel = document.getElementById('gvei-crop-cancel');\n        if (cropCancel) {\n            cropCancel.onclick = function() {\n                console.log('Photo upload: Cancelled');\n                if (cropModal) cropModal.classList.remove('active');\n                if (photoCropper) {\n                    photoCropper.destroy();\n                    photoCropper = null;\n                }\n                photoInput.value = '';\n            };\n        }\n        \n        \/\/ Save cropped image - use onclick\n        var cropSave = document.getElementById('gvei-crop-save');\n        if (cropSave) {\n            cropSave.onclick = function() {\n                if (!photoCropper) {\n                    console.error('Photo upload: No cropper instance');\n                    return;\n                }\n                \n                console.log('Photo upload: Saving cropped image');\n                \n                var canvas = photoCropper.getCroppedCanvas({\n                    width: 400,\n                    height: 400,\n                    imageSmoothingEnabled: true,\n                    imageSmoothingQuality: 'high'\n                });\n                \n                \/\/ Update preview immediately\n                var croppedDataUrl = canvas.toDataURL('image\/jpeg', 0.9);\n                if (photoPreview) {\n                    var previewImg = photoPreview.querySelector('img');\n                    if (previewImg) {\n                        previewImg.src = croppedDataUrl;\n                    } else {\n                        photoPreview.innerHTML = '<img decoding=\"async\" src=\"' + croppedDataUrl + '\" style=\"width: 100%; height: 100%; object-fit: cover;\" alt=\"\">';\n                    }\n                }\n                \n                \/\/ Upload to server\n                canvas.toBlob(function(blob) {\n                    var formData = new FormData();\n                    formData.append('action', 'gvei_dashboard_upload_photo');\n                    formData.append('nonce', '6e44952dee');\n                    formData.append('client_id', '');\n                    formData.append('image', blob, 'agent-photo.jpg');\n                    formData.append('image_type', 'agent_photo');\n                    \n                    fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n                        method: 'POST',\n                        body: formData\n                    })\n                    .then(function(response) { return response.json(); })\n                    .then(function(data) {\n                        if (data.success) {\n                            console.log('Photo upload: Upload successful');\n                        } else {\n                            console.error('Photo upload: Upload failed', data);\n                            alert('Error uploading photo: ' + (data.data ? data.data.message : 'Unknown error'));\n                        }\n                    })\n                    .catch(function(err) {\n                        console.error('Photo upload: Upload error:', err);\n                        alert('Error uploading photo. Please try again.');\n                    });\n                }, 'image\/jpeg', 0.9);\n                \n                \/\/ Close modal\n                if (cropModal) cropModal.classList.remove('active');\n                if (photoCropper) {\n                    photoCropper.destroy();\n                    photoCropper = null;\n                }\n                photoInput.value = '';\n            };\n        }\n        \n        console.log('Photo upload: Initialization complete');\n    }\n    \n    \/\/ Make function available globally for re-initialization after Cropper.js loads\n    window.initPhotoUpload = initPhotoUpload;\n    \n    \/\/ Initialize photo upload after a small delay to ensure Cropper.js is loaded\n    setTimeout(initPhotoUpload, 100);\n    \n    \/\/ Toggle expired videos section\n    window.toggleExpiredVideos = function() {\n        var list = document.getElementById('expired-videos-list');\n        var btn = document.querySelector('.gvei-expired-toggle');\n        if (list && btn) {\n            list.classList.toggle('active');\n            btn.classList.toggle('active');\n        }\n    };\n    \n    \/\/ Free sample engagement tracking helper\n    var _fsTracked = {};\n    window.gveiFsTrack = function(event) {\n        if (_fsTracked[event]) return;\n        _fsTracked[event] = true;\n        var token = '';\n        if (!token) return;\n        var fd = new FormData();\n        fd.append('action', 'gvei_fs_track_event');\n        fd.append('t', token);\n        fd.append('event', event);\n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', { method: 'POST', body: fd }).catch(function(){});\n    };\n\n    \/\/ Video Player Modal\n    window.playVideo = function(url) {\n        if (!url) {\n            alert('Video not available. It may have been moved or deleted.');\n            return;\n        }\n        gveiFsTrack('video_watched');\n        var modal = document.getElementById('gvei-video-modal');\n        var video = document.getElementById('gvei-video-player');\n        if (modal && video) {\n            video.src = url;\n            modal.classList.add('active');\n            video.play();\n        }\n    };\n    \n    \/\/ Download tracking using localStorage\n    window.getDownloadedVideos = function() {\n        try {\n            return JSON.parse(localStorage.getItem('gvei_downloaded_videos') || '{}');\n        } catch (e) {\n            return {};\n        }\n    };\n    \n    window.markVideoDownloaded = function(videoId) {\n        var downloaded = window.getDownloadedVideos();\n        downloaded[videoId] = Date.now();\n        localStorage.setItem('gvei_downloaded_videos', JSON.stringify(downloaded));\n    };\n    \n    window.isVideoDownloaded = function(videoId) {\n        var downloaded = window.getDownloadedVideos();\n        return downloaded.hasOwnProperty(videoId);\n    };\n    \n    \/\/ Update download buttons on page load\n    window.updateDownloadButtons = function() {\n        document.querySelectorAll('.gvei-download-btn').forEach(function(btn) {\n            var videoId = btn.getAttribute('data-video-id');\n            if (window.isVideoDownloaded(videoId)) {\n                btn.querySelector('.download-text').textContent = 'Download Again';\n                btn.classList.add('previously-downloaded');\n            }\n        });\n    };\n    \n    \/\/ Mark video as downloaded when clicking download link\n    window.markAsDownloaded = function(link) {\n        gveiFsTrack('video_downloaded');\n        var videoId = link.getAttribute('data-video-id');\n        if (videoId) {\n            window.markVideoDownloaded(videoId);\n            \/\/ Update UI after a short delay (allow download to start)\n            setTimeout(function() {\n                link.querySelector('.download-text').textContent = 'Download Again';\n                link.classList.add('previously-downloaded');\n            }, 500);\n        }\n        \/\/ Allow the default link behavior (navigate to download URL)\n        return true;\n    };\n    \n    \/\/ Initialize download button states on page load\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', window.updateDownloadButtons);\n    } else {\n        window.updateDownloadButtons();\n    }\n    \n    window.closeVideoModal = function() {\n        var modal = document.getElementById('gvei-video-modal');\n        var video = document.getElementById('gvei-video-player');\n        if (modal && video) {\n            video.pause();\n            video.src = '';\n            modal.classList.remove('active');\n        }\n    };\n    \n    \/\/ Close video modal on background click\n    var videoModal = document.getElementById('gvei-video-modal');\n    if (videoModal) {\n        videoModal.addEventListener('click', function(e) {\n            if (e.target === videoModal) {\n                closeVideoModal();\n            }\n        });\n    }\n    \n    \/\/ AI Panel Toggle\n    window.toggleAiPanel = function(videoId, type) {\n        var panel = document.getElementById(type + '-panel-' + videoId);\n        if (panel) {\n            \/\/ Close other panels first\n            document.querySelectorAll('.gvei-ai-panel.active').forEach(function(p) {\n                if (p !== panel) p.classList.remove('active');\n            });\n            panel.classList.toggle('active');\n        }\n    };\n    \n    \/\/ Generate AI Titles with automatic retry\n    window.generateTitles = function(videoId, retryCount) {\n        retryCount = retryCount || 0;\n        var maxRetries = 2; \/\/ Will try up to 3 times total\n        \n        var contentDiv = document.getElementById('titles-content-' + videoId);\n        if (!contentDiv) return;\n        \n        var btn = contentDiv.querySelector('.gvei-ai-generate-btn');\n        if (btn) {\n            btn.disabled = true;\n            var retryText = retryCount > 0 ? ' (Retry ' + retryCount + ')' : '';\n            btn.innerHTML = '\u23f3 Generating...' + retryText;\n        }\n        \n        var formData = new FormData();\n        formData.append('action', 'gvei_generate_video_titles');\n        formData.append('video_id', videoId);\n        formData.append('nonce', '6e44952dee');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData\n        })\n        .then(function(response) { \n            if (!response.ok) {\n                throw new Error('Server returned ' + response.status);\n            }\n            return response.json(); \n        })\n        .then(function(data) {\n            if (data.success) {\n                contentDiv.innerHTML = '<div class=\"gvei-ai-result\">' +\n                    '<div class=\"gvei-ai-result-item\">' +\n                        '<div class=\"gvei-ai-result-label\">Suggested Title<\/div>' +\n                        '<div class=\"gvei-ai-result-value\" style=\"position: relative;\">' + \n                            escapeHtml(data.data.title) +\n                            '<button class=\"gvei-ai-copy-btn\" onclick=\"copyText(this, \\'' + escapeHtml(data.data.title).replace(\/'\/g, \"\\\\'\") + '\\')\">Copy<\/button>' +\n                        '<\/div>' +\n                    '<\/div>' +\n                    '<div class=\"gvei-ai-result-item\">' +\n                        '<div class=\"gvei-ai-result-label\">Suggested Description<\/div>' +\n                        '<div class=\"gvei-ai-result-value\" style=\"position: relative; white-space: pre-line;\">' + \n                            escapeHtml(data.data.description) +\n                            '<button class=\"gvei-ai-copy-btn\" data-copy-text=\"' + escapeHtml(data.data.description).replace(\/\"\/g, '&quot;') + '\" onclick=\"copyFromData(this)\">Copy<\/button>' +\n                        '<\/div>' +\n                    '<\/div>' +\n                    '<button class=\"gvei-ai-generate-btn\" style=\"background: var(--dash-gray-200); color: var(--dash-gray-700); margin-top: 8px;\" onclick=\"generateTitles(' + videoId + ')\">\ud83d\udd04 Generate New<\/button>' +\n                '<\/div>';\n            } else {\n                \/\/ API returned an error - retry if possible\n                if (retryCount < maxRetries) {\n                    console.log('AI Titles failed, retrying... (' + (retryCount + 1) + '\/' + maxRetries + ')');\n                    setTimeout(function() {\n                        generateTitles(videoId, retryCount + 1);\n                    }, 1000); \/\/ Wait 1 second before retry\n                } else {\n                    showToast('Error: ' + (data.data ? data.data.message : 'Could not generate titles. Please try again.'), 'error');\n                if (btn) {\n                    btn.disabled = false;\n                    btn.innerHTML = '\ud83e\udd16 Generate with AI';\n                    }\n                }\n            }\n        })\n        .catch(function(error) {\n            console.log('AI Titles network error:', error);\n            \/\/ Network or server error - retry if possible\n            if (retryCount < maxRetries) {\n                console.log('Retrying after error... (' + (retryCount + 1) + '\/' + maxRetries + ')');\n                if (btn) {\n                    btn.innerHTML = '\u23f3 Retrying (' + (retryCount + 1) + '\/' + maxRetries + ')...';\n                }\n                setTimeout(function() {\n                    generateTitles(videoId, retryCount + 1);\n                }, 1500); \/\/ Wait 1.5 seconds before retry\n            } else {\n                showToast('Server error after ' + maxRetries + ' retries. Please try again later.', 'error');\n            if (btn) {\n                btn.disabled = false;\n                btn.innerHTML = '\ud83e\udd16 Generate with AI';\n                }\n            }\n        });\n    };\n    \n    \/\/ Generate AI Thumbnail with full options (like admin)\n    window.generateThumbnailWithOptions = function(videoId) {\n        var contentDiv = document.getElementById('thumbnail-content-' + videoId);\n        if (!contentDiv) return;\n        \n        \/\/ Get user inputs\n        var headline = document.getElementById('thumb-headline-' + videoId)?.value || '';\n        var bgUrl = document.getElementById('thumb-bg-url-' + videoId)?.value || '';\n        var profileUrl = document.getElementById('thumb-profile-url-' + videoId)?.value || '';\n        var aspectRatio = document.getElementById('thumb-aspect-' + videoId)?.value || 'horizontal';\n        \n        \/\/ Check if custom images are still uploading\n        var bgInput = document.getElementById('thumb-bg-url-' + videoId);\n        var profileInput = document.getElementById('thumb-profile-url-' + videoId);\n        \n        if (bgInput && bgInput.dataset.isCustom === 'uploading') {\n            alert('Background image is still uploading. Please wait a moment and try again.');\n            return;\n        }\n        if (profileInput && profileInput.dataset.isCustom === 'uploading') {\n            alert('Profile image is still uploading. Please wait a moment and try again.');\n            return;\n        }\n        \n        \/\/ Validate\n        if (!headline.trim()) {\n            alert('Please enter a headline for your thumbnail.');\n            return;\n        }\n        if (!bgUrl) {\n            alert('No background image available for this video.');\n            return;\n        }\n        \n        \/\/ Make sure we have actual URLs, not data URLs\n        if (bgUrl.startsWith('data:')) {\n            alert('Background image is still processing. Please wait a moment and try again.');\n            return;\n        }\n        if (profileUrl && profileUrl.startsWith('data:')) {\n            alert('Profile image is still processing. Please wait a moment and try again.');\n            return;\n        }\n        \n        var btn = contentDiv.querySelector('.gvei-ai-generate-btn');\n        var startTime = Date.now();\n        var timerInterval = null;\n        \n        \/\/ Show progress with timer\n        if (btn) {\n            btn.disabled = true;\n            btn.innerHTML = '\u23f3 Generating (0s)...';\n            \n            \/\/ Update timer every second\n            timerInterval = setInterval(function() {\n                var elapsed = Math.floor((Date.now() - startTime) \/ 1000);\n                btn.innerHTML = '\u23f3 Generating (' + elapsed + 's)...';\n            }, 1000);\n        }\n        \n        var formData = new FormData();\n        formData.append('action', 'gvei_generate_video_thumbnail_custom');\n        formData.append('video_id', videoId);\n        formData.append('headline', headline);\n        formData.append('background_url', bgUrl);\n        formData.append('profile_url', profileUrl);\n        formData.append('aspect_ratio', aspectRatio);\n        formData.append('nonce', '6e44952dee');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (timerInterval) clearInterval(timerInterval);\n            \n            if (data.success) {\n                var thumbUrl = data.data.thumbnail_url;\n                var elapsed = Math.floor((Date.now() - startTime) \/ 1000);\n                \n                contentDiv.innerHTML = '<div class=\"gvei-ai-result\" style=\"background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%); border: 1px solid #86efac; border-radius: 12px; padding: 16px;\">' +\n                    '<div style=\"font-weight: 600; margin-bottom: 12px; color: #166534;\">\u2705 Thumbnail Ready! (' + elapsed + 's)<\/div>' +\n                    '<img decoding=\"async\" src=\"' + thumbUrl + '\" style=\"width: 100%; border-radius: 8px; margin-bottom: 12px; border: 2px solid #86efac;\">' +\n                    '<button class=\"gvei-ai-generate-btn\" id=\"thumb-download-btn-' + videoId + '\" style=\"text-align: center; width: 100%;\" onclick=\"downloadThumbnail(\\'' + thumbUrl + '\\', \\'video-thumbnail-' + videoId + '.png\\', ' + videoId + ')\">\u2b07\ufe0f Download Thumbnail<\/button>' +\n                '<\/div>' +\n                '<button class=\"gvei-ai-generate-btn\" style=\"background: var(--dash-gray-200); color: var(--dash-gray-700); margin-top: 12px; width: 100%;\" onclick=\"showThumbnailForm(' + videoId + ')\">\ud83d\udd04 Create Another<\/button>';\n            } else {\n                alert('Error: ' + (data.data ? data.data.message : 'Could not generate thumbnail'));\n                if (btn) {\n                    btn.disabled = false;\n                    btn.innerHTML = '\ud83c\udfa8 Generate AI Thumbnail';\n                }\n            }\n        })\n        .catch(function() {\n            if (timerInterval) clearInterval(timerInterval);\n            alert('Server error. Please try again.');\n            if (btn) {\n                btn.disabled = false;\n                btn.innerHTML = '\ud83c\udfa8 Generate AI Thumbnail';\n            }\n        });\n    };\n    \n    \/\/ Download thumbnail image (uses server-side proxy to bypass CORS)\n    window.downloadThumbnail = function(url, filename, videoId) {\n        var btn = document.getElementById('thumb-download-btn-' + videoId);\n        if (btn) {\n            btn.disabled = true;\n            btn.innerHTML = '\u23f3 Downloading...';\n        }\n        \n        \/\/ Use server-side proxy to download (bypasses CORS)\n        var formData = new FormData();\n        formData.append('action', 'gvei_download_image');\n        formData.append('image_url', url);\n        formData.append('nonce', '6e44952dee');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData\n        })\n        .then(function(response) {\n            if (!response.ok) throw new Error('Download failed');\n            return response.blob();\n        })\n        .then(function(blob) {\n            \/\/ Create download link\n            var blobUrl = URL.createObjectURL(blob);\n            var link = document.createElement('a');\n            link.href = blobUrl;\n            link.download = filename;\n            link.style.display = 'none';\n            document.body.appendChild(link);\n            link.click();\n            \n            \/\/ Cleanup\n            setTimeout(function() {\n                document.body.removeChild(link);\n                URL.revokeObjectURL(blobUrl);\n            }, 100);\n            \n            if (btn) {\n                btn.disabled = false;\n                btn.innerHTML = '\u2705 Downloaded! Click again to re-download';\n            }\n        })\n        .catch(function(error) {\n            console.error('Download failed:', error);\n            alert('Download failed. Please try right-clicking the image and selecting \"Save Image As...\"');\n            \n            if (btn) {\n                btn.disabled = false;\n                btn.innerHTML = '\u2b07\ufe0f Download Thumbnail';\n            }\n        });\n    };\n    \n    \/\/ Show thumbnail form again (Create Another)\n    window.showThumbnailForm = function(videoId) {\n        \/\/ Get current URL and preserve the token\n        var urlParams = new URLSearchParams(window.location.search);\n        var token = urlParams.get('token');\n        var baseUrl = window.location.href.split('?')[0];\n        \n        \/\/ Build URL preserving token and adding our params\n        var newUrl = baseUrl + '?token=' + encodeURIComponent(token) + '&tab=videos&openThumb=' + videoId + '&_t=' + Date.now();\n        \n        window.location.href = newUrl;\n    };\n    \n    \/\/ Check if we need to auto-open a thumbnail panel (from Create Another)\n    (function() {\n        var urlParams = new URLSearchParams(window.location.search);\n        var openThumbId = urlParams.get('openThumb');\n        if (openThumbId) {\n            \/\/ Wait for page to render, then open the panel\n            setTimeout(function() {\n                var panel = document.getElementById('thumbnail-panel-' + openThumbId);\n                if (panel) {\n                    panel.style.display = 'block';\n                    \/\/ Scroll to the video\n                    var videoCard = panel.closest('.gvei-video-item');\n                    if (videoCard) {\n                        videoCard.scrollIntoView({ behavior: 'smooth', block: 'center' });\n                    }\n                }\n            }, 300);\n        }\n    })();\n    \n    \/\/ Change thumbnail image (background or profile) - uploads to R2 first\n    window.changeThumbImage = function(videoId, type, input) {\n        if (!input.files || !input.files[0]) return;\n        \n        var file = input.files[0];\n        var previewId = type === 'bg' ? 'thumb-bg-preview-' : 'thumb-profile-preview-';\n        var urlId = type === 'bg' ? 'thumb-bg-url-' : 'thumb-profile-url-';\n        var containerId = type === 'bg' ? 'thumb-bg-container-' : 'thumb-profile-container-';\n        \n        var preview = document.getElementById(previewId + videoId);\n        var urlInput = document.getElementById(urlId + videoId);\n        var container = preview ? preview.closest('.thumb-bg-container') || preview.parentNode : null;\n        \n        \/\/ Show uploading indicator\n        if (container) {\n            var loader = document.createElement('div');\n            loader.id = 'upload-loader-' + type + '-' + videoId;\n            loader.style.cssText = 'position: absolute; bottom: 8px; left: 8px; right: 8px; background: rgba(0,0,0,0.8); color: #fff; padding: 6px 12px; border-radius: 6px; font-size: 12px; text-align: center;';\n            loader.innerHTML = '\u23f3 Uploading...';\n            container.style.position = 'relative';\n            container.appendChild(loader);\n        }\n        \n        \/\/ Show preview immediately using data URL\n        var reader = new FileReader();\n        reader.onload = function(e) {\n            if (preview) {\n                if (preview.tagName === 'DIV') {\n                    var img = document.createElement('img');\n                    img.id = preview.id;\n                    img.style.cssText = 'max-width: 100%; max-height: 100%; object-fit: contain;';\n                    preview.parentNode.replaceChild(img, preview);\n                    preview = document.getElementById(previewId + videoId);\n                }\n                preview.src = e.target.result;\n            }\n        };\n        reader.readAsDataURL(file);\n        \n        \/\/ Upload to R2 to get a real URL\n        var formData = new FormData();\n        formData.append('action', 'gvei_upload_thumb_image');\n        formData.append('file', file);\n        formData.append('type', type);\n        formData.append('video_id', videoId);\n        formData.append('nonce', '6e44952dee');\n        \n        \/\/ Show uploading state\n        if (urlInput) {\n            urlInput.dataset.isCustom = 'uploading';\n        }\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            \/\/ Remove loader\n            var loader = document.getElementById('upload-loader-' + type + '-' + videoId);\n            if (loader) loader.remove();\n            \n            if (data.success && data.data.url) {\n                if (urlInput) {\n                    urlInput.value = data.data.url;\n                    urlInput.dataset.isCustom = 'true';\n                }\n                \/\/ Show success briefly\n                if (container) {\n                    var success = document.createElement('div');\n                    success.style.cssText = 'position: absolute; bottom: 8px; left: 8px; right: 8px; background: rgba(22,101,52,0.9); color: #fff; padding: 6px 12px; border-radius: 6px; font-size: 12px; text-align: center;';\n                    success.innerHTML = '\u2713 Uploaded!';\n                    container.appendChild(success);\n                    setTimeout(function() { success.remove(); }, 2000);\n                }\n            } else {\n                alert('Upload failed: ' + (data.data ? data.data.message : 'Unknown error'));\n                \/\/ Reset to default\n                resetThumbImage(videoId, type);\n            }\n        })\n        .catch(function(err) {\n            \/\/ Remove loader\n            var loader = document.getElementById('upload-loader-' + type + '-' + videoId);\n            if (loader) loader.remove();\n            \n            console.error('Upload error:', err);\n            alert('Failed to upload image. Please try again or use the default image.');\n            resetThumbImage(videoId, type);\n            \n            if (urlInput) {\n                urlInput.dataset.isCustom = 'false';\n            }\n        });\n    };\n    \n    \/\/ Reset thumbnail image to default\n    window.resetThumbImage = function(videoId, type) {\n        var contentDiv = document.getElementById('thumbnail-content-' + videoId);\n        if (!contentDiv) return;\n        \n        var defaultUrl = type === 'bg' ? contentDiv.dataset.defaultBg : contentDiv.dataset.defaultProfile;\n        var previewId = type === 'bg' ? 'thumb-bg-preview-' : 'thumb-profile-preview-';\n        var urlId = type === 'bg' ? 'thumb-bg-url-' : 'thumb-profile-url-';\n        \n        var preview = document.getElementById(previewId + videoId);\n        var urlInput = document.getElementById(urlId + videoId);\n        \n        if (preview && defaultUrl) {\n            preview.src = defaultUrl;\n        } else if (preview && !defaultUrl) {\n            \/\/ No default, show placeholder\n            preview.outerHTML = '<div id=\"' + previewId + videoId + '\" style=\"width: 100%; height: 120px; background: var(--dash-gray-100); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--dash-gray-400); font-size: 12px;\">No image<\/div>';\n        }\n        if (urlInput) {\n            urlInput.value = defaultUrl || '';\n            urlInput.dataset.isCustom = 'false';\n        }\n    };\n    \n    \/\/ Legacy download function for other uses (video downloads, etc.)\n    window.downloadImage = function(url, filename) {\n        fetch(url, { mode: 'cors' })\n            .then(function(response) { return response.blob(); })\n            .then(function(blob) {\n                var link = document.createElement('a');\n                link.href = URL.createObjectURL(blob);\n                link.download = filename;\n                document.body.appendChild(link);\n                link.click();\n                document.body.removeChild(link);\n                URL.revokeObjectURL(link.href);\n            })\n            .catch(function() {\n                \/\/ Fallback: open in new tab\n                window.open(url, '_blank');\n            });\n    };\n    \n    \/\/ Copy text helper\n    window.copyText = function(btn, text) {\n        navigator.clipboard.writeText(text).then(function() {\n            btn.classList.add('copied');\n            btn.textContent = 'Copied!';\n            setTimeout(function() {\n                btn.classList.remove('copied');\n                btn.textContent = 'Copy';\n            }, 2000);\n        });\n    };\n    \n    \/\/ Copy from data attribute (preserves newlines properly)\n    window.copyFromData = function(btn) {\n        var text = btn.getAttribute('data-copy-text') || '';\n        navigator.clipboard.writeText(text).then(function() {\n            btn.classList.add('copied');\n            btn.textContent = 'Copied!';\n            setTimeout(function() {\n                btn.classList.remove('copied');\n                btn.textContent = 'Copy';\n            }, 2000);\n        });\n    };\n    \n    \/\/ Escape HTML helper\n    function escapeHtml(text) {\n        var div = document.createElement('div');\n        div.textContent = text;\n        return div.innerHTML;\n    }\n    \n    \/\/ ===== BILLING FUNCTIONS =====\n    \n    \/\/ Horizontal Add-on Toggle with Confirmation\n    window.toggleHorizontalAddon = function(enabled) {\n        var horizontalPrice = 200;\n        var toggle = document.getElementById('horizontal-addon-toggle');\n        \n        if (enabled) {\n            \/\/ Confirm before enabling\n            var confirmed = confirm(\n                'Add Horizontal Videos?\\n\\n' +\n                'This will add $' + horizontalPrice + '\/month to your subscription.\\n\\n' +\n                'You\\'ll be charged a prorated amount on your next invoice.\\n\\n' +\n                'Click OK to confirm.'\n            );\n            \n            if (!confirmed) {\n                \/\/ User cancelled - revert toggle\n                if (toggle) toggle.checked = false;\n                return;\n            }\n        } else {\n            \/\/ Confirm before disabling\n            var confirmed = confirm(\n                'Remove Horizontal Videos?\\n\\n' +\n                'You will no longer receive horizontal format videos.\\n\\n' +\n                'Your next invoice will be reduced accordingly.\\n\\n' +\n                'Click OK to confirm.'\n            );\n            \n            if (!confirmed) {\n                \/\/ User cancelled - revert toggle\n                if (toggle) toggle.checked = true;\n                return;\n            }\n        }\n        \n        \/\/ Disable toggle while processing\n        if (toggle) toggle.disabled = true;\n        \n        \/\/ Make AJAX request to toggle add-on\n        var formData = new FormData();\n        formData.append('action', 'gvei_toggle_horizontal_addon');\n        formData.append('enabled', enabled ? '1' : '0');\n        formData.append('token', '');\n        formData.append('_wpnonce', 'f4e2bb55fb');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData,\n            credentials: 'same-origin'\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (data.success) {\n                \/\/ Reload page to show updated status\n                window.location.reload();\n            } else {\n                alert(data.data.message || 'Something went wrong. Please try again.');\n                \/\/ Revert toggle on error\n                if (toggle) {\n                    toggle.checked = !enabled;\n                    toggle.disabled = false;\n                }\n            }\n        })\n        .catch(function(error) {\n            console.error('Billing error:', error);\n            alert('Network error. Please try again.');\n            \/\/ Revert toggle on error\n            if (toggle) {\n                toggle.checked = !enabled;\n                toggle.disabled = false;\n            }\n        });\n    };\n    \n    \/\/ Subscribe to or upgrade to a plan\n    window.subscribeToPlan = function(planSlug) {\n        \/\/ Check if user has an active subscription and show proration preview\n                \n        var hasActiveSubscription = false;\n        var hasStripeSubscription = false;\n        \n        \/\/ If they have an active subscription, show proration preview first\n        if (hasActiveSubscription && hasStripeSubscription) {\n            showProrationPreview(planSlug);\n            return;\n        }\n        \n        \/\/ Otherwise, go directly to checkout (no setup fee for dashboard signups)\n        proceedToCheckout(planSlug);\n    };\n    \n    \/\/ Show proration preview modal\n    window.showProrationPreview = function(planSlug) {\n        \/\/ Show loading state\n        var modal = document.getElementById('proration-preview-modal');\n        if (!modal) {\n            \/\/ Create modal if it doesn't exist\n            modal = document.createElement('div');\n            modal.id = 'proration-preview-modal';\n            modal.innerHTML = '<div class=\"gvei-modal-overlay\" onclick=\"closeProrationModal()\"><\/div><div class=\"gvei-modal-content\" style=\"max-width: 500px;\"><div id=\"proration-loading\" style=\"text-align: center; padding: 40px;\"><div class=\"gvei-spinner\"><\/div><p style=\"margin-top: 16px; color: var(--dash-gray-600);\">Calculating price changes...<\/p><\/div><div id=\"proration-content\" style=\"display: none;\"><\/div><\/div>';\n            modal.className = 'gvei-modal';\n            document.body.appendChild(modal);\n        }\n        \n        modal.style.display = 'flex';\n        document.getElementById('proration-loading').style.display = 'block';\n        document.getElementById('proration-content').style.display = 'none';\n        \n        \/\/ Fetch proration preview\n        var formData = new FormData();\n        formData.append('action', 'gvei_get_proration_preview');\n        formData.append('_wpnonce', 'f4e2bb55fb');\n        formData.append('new_plan_slug', planSlug);\n        formData.append('token', '');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData,\n            credentials: 'same-origin'\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            document.getElementById('proration-loading').style.display = 'none';\n            var content = document.getElementById('proration-content');\n            content.style.display = 'block';\n            \n            if (!data.success) {\n                content.innerHTML = '<div style=\"padding: 20px;\"><p style=\"color: #ef4444; margin-bottom: 16px;\">' + (data.data?.message || 'Error fetching proration details') + '<\/p><button onclick=\"closeProrationModal()\" class=\"gvei-btn gvei-btn-secondary\">Close<\/button><\/div>';\n                return;\n            }\n            \n            var info = data.data;\n            var isUpgrade = info.is_upgrade;\n            var isNewSignup = info.is_new_signup;\n            \n            var html = '<div style=\"padding: 0;\">';\n            html += '<div style=\"padding: 24px; border-bottom: 1px solid var(--dash-gray-200);\">';\n            html += '<h3 style=\"font-size: 20px; font-weight: 600; margin: 0 0 8px 0; color: var(--dash-gray-900);\">';\n            html += isUpgrade ? '\u2b06\ufe0f Upgrade to ' + info.new_plan_name : '\u2b07\ufe0f Switch to ' + info.new_plan_name;\n            html += '<\/h3>';\n            html += '<p style=\"font-size: 14px; color: var(--dash-gray-600); margin: 0;\">';\n            html += isNewSignup ? 'New subscription' : 'From ' + info.current_plan_name;\n            html += '<\/p>';\n            html += '<\/div>';\n            \n            html += '<div style=\"padding: 24px;\">';\n            \n            if (!info.has_proration) {\n                \/\/ New signup - simple display\n                html += '<div style=\"background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 12px; padding: 16px; margin-bottom: 20px;\">';\n                html += '<div style=\"font-size: 28px; font-weight: 700; color: #059669; margin-bottom: 4px;\">' + info.formatted_price + '<span style=\"font-size: 14px; font-weight: 500;\">\/month<\/span><\/div>';\n                html += '<div style=\"font-size: 14px; color: var(--dash-gray-600);\">Your new monthly rate<\/div>';\n                html += '<\/div>';\n            } else {\n                \/\/ Has proration - show breakdown\n                html += '<div style=\"background: ' + (isUpgrade ? '#f0fdf4' : '#eff6ff') + '; border: 1px solid ' + (isUpgrade ? '#bbf7d0' : '#bfdbfe') + '; border-radius: 12px; padding: 20px; margin-bottom: 20px;\">';\n                \n                if (isUpgrade) {\n                    html += '<div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;\">';\n                    html += '<span style=\"font-size: 14px; color: var(--dash-gray-700);\">Prorated charge today<\/span>';\n                    html += '<span style=\"font-size: 24px; font-weight: 700; color: #059669;\">' + info.formatted.prorated_amount + '<\/span>';\n                    html += '<\/div>';\n                } else {\n                    html += '<div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;\">';\n                    html += '<span style=\"font-size: 14px; color: var(--dash-gray-700);\">Credit to your account<\/span>';\n                    html += '<span style=\"font-size: 24px; font-weight: 700; color: #2563eb;\">' + info.formatted.prorated_amount + '<\/span>';\n                    html += '<\/div>';\n                }\n                \n                html += '<div style=\"font-size: 13px; color: var(--dash-gray-600); background: rgba(0,0,0,0.05); padding: 12px; border-radius: 8px;\">';\n                html += '<div style=\"margin-bottom: 4px;\"><strong>How we calculated this:<\/strong><\/div>';\n                html += info.breakdown;\n                html += '<\/div>';\n                html += '<\/div>';\n                \n                html += '<div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px;\">';\n                html += '<div style=\"padding: 12px; background: var(--dash-gray-50); border-radius: 8px;\">';\n                html += '<div style=\"font-size: 12px; color: var(--dash-gray-500); text-transform: uppercase;\">New Monthly Rate<\/div>';\n                html += '<div style=\"font-size: 20px; font-weight: 600; color: var(--dash-gray-900);\">' + info.formatted.new_price + '<\/div>';\n                html += '<\/div>';\n                html += '<div style=\"padding: 12px; background: var(--dash-gray-50); border-radius: 8px;\">';\n                html += '<div style=\"font-size: 12px; color: var(--dash-gray-500); text-transform: uppercase;\">Next Billing Date<\/div>';\n                html += '<div style=\"font-size: 14px; font-weight: 600; color: var(--dash-gray-900); margin-top: 4px;\">' + info.next_billing_date + '<\/div>';\n                html += '<\/div>';\n                html += '<\/div>';\n            }\n            \n            html += '<div style=\"font-size: 14px; color: var(--dash-gray-600); margin-bottom: 24px; padding: 12px; border-left: 3px solid var(--dash-gray-300);\">';\n            html += info.message;\n            html += '<\/div>';\n            \n            html += '<div style=\"display: flex; gap: 12px;\">';\n            html += '<button onclick=\"closeProrationModal()\" class=\"gvei-btn gvei-btn-secondary\" style=\"flex: 1;\">Cancel<\/button>';\n            html += '<button onclick=\"proceedToCheckout(\\'' + planSlug + '\\')\" class=\"gvei-btn gvei-btn-primary\" style=\"flex: 2;\">';\n            html += isUpgrade ? '\u2728 Upgrade Now' : '\u2192 Switch Plan';\n            html += '<\/button>';\n            html += '<\/div>';\n            \n            html += '<\/div><\/div>';\n            \n            content.innerHTML = html;\n        })\n        .catch(function(error) {\n            console.error('Proration preview error:', error);\n            document.getElementById('proration-loading').style.display = 'none';\n            document.getElementById('proration-content').innerHTML = '<div style=\"padding: 20px;\"><p style=\"color: #ef4444; margin-bottom: 16px;\">Network error. Please try again.<\/p><button onclick=\"closeProrationModal()\" class=\"gvei-btn gvei-btn-secondary\">Close<\/button><\/div>';\n            document.getElementById('proration-content').style.display = 'block';\n        });\n    };\n    \n    \/\/ Close proration modal\n    window.closeProrationModal = function() {\n        var modal = document.getElementById('proration-preview-modal');\n        if (modal) {\n            modal.style.display = 'none';\n        }\n    };\n    \n    \/\/ Proceed to checkout (no setup fee for dashboard signups)\n    window.proceedToCheckout = function(planSlug) {\n        var hasStripeSubscription = false;\n\n        if (hasStripeSubscription) {\n            \/\/ Switch existing subscription via AJAX\n            closeProrationModal();\n            showToast('Switching plan...', 'info');\n\n            var formData = new FormData();\n            formData.append('action', 'gvei_switch_plan');\n            formData.append('token', '');\n            formData.append('new_plan_slug', planSlug);\n            formData.append('_wpnonce', 'f4e2bb55fb');\n\n            fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n                method: 'POST',\n                body: formData,\n                credentials: 'same-origin'\n            })\n            .then(function(r) { return r.json(); })\n            .then(function(data) {\n                if (data.success) {\n                    showToast(data.data.message, 'success');\n                    setTimeout(function() { window.location.reload(); }, 1500);\n                } else {\n                    showToast(data.data.message || 'Something went wrong.', 'error');\n                }\n            })\n            .catch(function() {\n                showToast('Network error. Please try again.', 'error');\n            });\n        } else {\n            \/\/ No existing subscription - redirect to new checkout\n            closeProrationModal();\n            var checkoutUrl = 'https:\/\/gogoit.com\/video\/start-checkout?' + new URLSearchParams({\n                plan_id: planSlug,\n                addon_horizontal: 0,\n                trial: 0,\n                no_setup_fee: 1,\n                source: 'agent_dashboard'\n            }).toString();\n\n            window.location.href = checkoutUrl;\n        }\n    };\n    \n    \/\/ Simple toast notification\n    window.showToast = function(message, type) {\n        type = type || 'info';\n        var toast = document.createElement('div');\n        toast.className = 'gvei-toast gvei-toast-' + type;\n        toast.innerHTML = message;\n        toast.style.cssText = 'position: fixed; bottom: 24px; right: 24px; padding: 16px 24px; border-radius: 12px; font-size: 14px; font-weight: 500; z-index: 10001; animation: toastSlideIn 0.3s ease-out; box-shadow: 0 10px 40px rgba(0,0,0,0.2);';\n        \n        if (type === 'error') {\n            toast.style.background = 'linear-gradient(135deg, #ef4444, #dc2626)';\n            toast.style.color = 'white';\n        } else if (type === 'success') {\n            toast.style.background = 'linear-gradient(135deg, #10b981, #059669)';\n            toast.style.color = 'white';\n        } else {\n            toast.style.background = 'linear-gradient(135deg, #6366f1, #4f46e5)';\n            toast.style.color = 'white';\n        }\n        \n        document.body.appendChild(toast);\n        \n        setTimeout(function() {\n            toast.style.opacity = '0';\n            toast.style.transform = 'translateX(100%)';\n            toast.style.transition = 'all 0.3s ease-out';\n            setTimeout(function() { toast.remove(); }, 300);\n        }, 4000);\n    };\n    \n    \/\/ Open Stripe Billing Portal\n    window.openBillingPortal = function() {\n        var btn = document.getElementById('billing-portal-btn');\n        if (btn) {\n            btn.disabled = true;\n            btn.innerHTML = '\u23f3 Opening...';\n        }\n        \n        var formData = new FormData();\n        formData.append('action', 'gvei_create_billing_portal');\n        formData.append('token', '');\n        formData.append('_wpnonce', 'f4e2bb55fb');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData,\n            credentials: 'same-origin'\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (data.success && data.data.url) {\n                window.location.href = data.data.url;\n            } else {\n                alert(data.data.message || 'Could not open billing portal. Please try again.');\n                if (btn) {\n                    btn.disabled = false;\n                    btn.innerHTML = '\ud83d\udd17 Open Billing Portal';\n                }\n            }\n        })\n        .catch(function(error) {\n            console.error('Billing portal error:', error);\n            alert('Network error. Please try again.');\n            if (btn) {\n                btn.disabled = false;\n                btn.innerHTML = '\ud83d\udd17 Open Billing Portal';\n            }\n        });\n    };\n    \n    \/\/ ===== CANCEL SUBSCRIPTION MODAL =====\n    window.gveiOpenCancelModal = function() {\n        var modal = document.getElementById('gvei-cancel-modal');\n        if (!modal) return;\n        modal.style.display = 'flex';\n        document.getElementById('gvei-cancel-step1').style.display = '';\n        document.getElementById('gvei-cancel-step2').style.display = 'none';\n        document.getElementById('gvei-cancel-step3').style.display = 'none';\n        var input = document.getElementById('gvei-cancel-confirm-input');\n        if (input) input.value = '';\n        gveiValidateCancelInput(input);\n    };\n    window.gveiCloseCancelModal = function() {\n        var modal = document.getElementById('gvei-cancel-modal');\n        if (modal) modal.style.display = 'none';\n    };\n    window.gveiCancelStep2 = function() {\n        document.getElementById('gvei-cancel-step1').style.display = 'none';\n        document.getElementById('gvei-cancel-step2').style.display = '';\n        var input = document.getElementById('gvei-cancel-confirm-input');\n        if (input) { input.value = ''; input.focus(); }\n        gveiValidateCancelInput(input);\n    };\n    window.gveiCancelStep1 = function() {\n        document.getElementById('gvei-cancel-step2').style.display = 'none';\n        document.getElementById('gvei-cancel-step1').style.display = '';\n    };\n    window.gveiValidateCancelInput = function(el) {\n        var btn = document.getElementById('gvei-cancel-confirm-btn');\n        if (!btn || !el) return;\n        var match = el.value.trim().toUpperCase() === 'CANCEL';\n        btn.disabled = !match;\n        if (match) {\n            btn.style.background = '#dc2626';\n            btn.style.color = '#fff';\n            btn.style.borderColor = '#dc2626';\n            btn.style.cursor = 'pointer';\n            el.style.borderColor = '#dc2626';\n        } else {\n            btn.style.background = '#d1d5db';\n            btn.style.color = '#9ca3af';\n            btn.style.borderColor = '#d1d5db';\n            btn.style.cursor = 'not-allowed';\n            el.style.borderColor = '#e5e7eb';\n        }\n    };\n    window.gveiConfirmCancel = function() {\n        var input = document.getElementById('gvei-cancel-confirm-input');\n        if (!input || input.value.trim().toUpperCase() !== 'CANCEL') return;\n\n        document.getElementById('gvei-cancel-step2').style.display = 'none';\n        document.getElementById('gvei-cancel-step3').style.display = '';\n        document.getElementById('gvei-cancel-processing').style.display = '';\n        document.getElementById('gvei-cancel-done').style.display = 'none';\n\n        var fd = new FormData();\n        fd.append('action', 'gvei_cancel_own_subscription');\n        fd.append('token', '');\n        fd.append('_wpnonce', 'f4e2bb55fb');\n        fd.append('confirmation_text', 'CANCEL');\n\n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST', body: fd, credentials: 'same-origin'\n        })\n        .then(function(r) { return r.json(); })\n        .then(function(data) {\n            document.getElementById('gvei-cancel-processing').style.display = 'none';\n            if (data.success) {\n                document.getElementById('gvei-cancel-done').style.display = '';\n                var msg = document.getElementById('gvei-cancel-access-msg');\n                if (msg && data.data.access_end) {\n                    msg.textContent = 'You still have access until ' + data.data.access_end + '.';\n                }\n                \/\/ Reload page after a short delay so PHP re-renders with canceling status\n                setTimeout(function() {\n                    window.location.reload();\n                }, 3000);\n            } else {\n                alert(data.data.message || 'Something went wrong. Please contact support.');\n                gveiCloseCancelModal();\n            }\n        })\n        .catch(function() {\n            document.getElementById('gvei-cancel-processing').style.display = 'none';\n            alert('Network error. Please try again.');\n            gveiCloseCancelModal();\n        });\n    };\n    \/\/ Close modal on backdrop click\n    (function() {\n        var modal = document.getElementById('gvei-cancel-modal');\n        if (modal) {\n            modal.addEventListener('click', function(e) {\n                if (e.target === modal) gveiCloseCancelModal();\n            });\n        }\n    })();\n\n    \/\/ ===== REACTIVATE SUBSCRIPTION =====\n    window.gveiReactivateSubscription = function(btn) {\n        if (!confirm('Are you sure you want to reactivate your subscription?')) return;\n\n        btn.disabled = true;\n        btn.textContent = 'Reactivating...';\n\n        var fd = new FormData();\n        fd.append('action', 'gvei_reactivate_own_subscription');\n        fd.append('token', '');\n        fd.append('_wpnonce', 'f4e2bb55fb');\n\n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST', body: fd, credentials: 'same-origin'\n        })\n        .then(function(r) { return r.json(); })\n        .then(function(data) {\n            if (data.success) {\n                window.location.reload();\n            } else {\n                alert(data.data.message || 'Something went wrong. Please contact support.');\n                btn.disabled = false;\n                btn.textContent = 'Reactivate Plan';\n            }\n        })\n        .catch(function() {\n            alert('Network error. Please try again.');\n            btn.disabled = false;\n            btn.textContent = 'Reactivate Plan';\n        });\n    };\n\n    \/\/ ===== BILLING DATA LOADING =====\n    var billingInvoicesData = [];\n    var billingHasMore = false;\n    var billingLastInvoiceId = null;\n    \n    \/\/ Load billing info on page load\n    window.loadBillingInfo = function() {\n        var formData = new FormData();\n        formData.append('action', 'gvei_get_billing_info');\n        formData.append('token', '');\n        formData.append('_wpnonce', 'f4e2bb55fb');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData,\n            credentials: 'same-origin'\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (data.success) {\n                renderBillingInfo(data.data);\n            }\n        })\n        .catch(function(error) {\n            console.error('Load billing info error:', error);\n        });\n    };\n    \n    \/\/ Render billing info\n    function renderBillingInfo(info) {\n        \/\/ Update plan name\n        var planNameEl = document.getElementById('billing-plan-name');\n        if (planNameEl && info.plan_name) {\n            planNameEl.textContent = info.plan_name;\n        }\n        \n        \/\/ Update renewal date\n        var renewalEl = document.getElementById('billing-renewal-date');\n        if (renewalEl && info.subscription) {\n            var sub = info.subscription;\n            if (sub.cancel_at_period_end) {\n                renewalEl.innerHTML = '<span style=\"color: #f59e0b;\">\u26a0\ufe0f Cancels on ' + sub.renewal_date + '<\/span>';\n            } else if (sub.is_trialing) {\n                renewalEl.innerHTML = 'Trial ends ' + sub.renewal_date;\n            } else {\n                renewalEl.innerHTML = 'Your subscription will auto renew on ' + sub.renewal_date + '.';\n            }\n        }\n        \n        \/\/ Update payment method\n        var paymentTextEl = document.getElementById('billing-payment-text');\n        if (paymentTextEl && info.payment_method) {\n            var pm = info.payment_method;\n            if (pm.type === 'card') {\n                paymentTextEl.textContent = pm.brand + ' ending in ' + pm.last4;\n                if (pm.is_expiring) {\n                    paymentTextEl.innerHTML += ' <span style=\"color: #f59e0b; font-size: 12px;\">(expires soon)<\/span>';\n                }\n            } else if (pm.type === 'link') {\n                paymentTextEl.textContent = 'Link by Stripe';\n            } else if (pm.type === 'none') {\n                paymentTextEl.textContent = 'No payment method';\n            } else {\n                paymentTextEl.textContent = pm.brand || pm.type;\n            }\n        }\n    }\n    \n    \/\/ Load invoices\n    window.loadInvoices = function(startingAfter) {\n        var container = document.getElementById('billing-invoices-container') || document.getElementById('billing-invoices-container-inactive');\n        if (!container) return;\n        \n        var formData = new FormData();\n        formData.append('action', 'gvei_get_invoices');\n        formData.append('token', '');\n        formData.append('limit', 12);\n        if (startingAfter) {\n            formData.append('starting_after', startingAfter);\n        }\n        formData.append('_wpnonce', 'f4e2bb55fb');\n        \n        fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData,\n            credentials: 'same-origin'\n        })\n        .then(function(response) { return response.json(); })\n        .then(function(data) {\n            if (data.success) {\n                if (startingAfter) {\n                    \/\/ Append to existing\n                    billingInvoicesData = billingInvoicesData.concat(data.data.invoices);\n                } else {\n                    billingInvoicesData = data.data.invoices;\n                }\n                billingHasMore = data.data.has_more;\n                if (data.data.invoices.length > 0) {\n                    billingLastInvoiceId = data.data.invoices[data.data.invoices.length - 1].id;\n                }\n                renderInvoices(container);\n                \n                \/\/ Show past invoices section for inactive users\n                var pastSection = document.getElementById('past-invoices-section');\n                if (pastSection && billingInvoicesData.length > 0) {\n                    pastSection.style.display = 'block';\n                }\n            } else {\n                container.innerHTML = '<p style=\"color: var(--dash-gray-500); text-align: center;\">Could not load invoices.<\/p>';\n            }\n        })\n        .catch(function(error) {\n            console.error('Load invoices error:', error);\n            container.innerHTML = '<p style=\"color: var(--dash-gray-500); text-align: center;\">Error loading invoices.<\/p>';\n        });\n    };\n    \n    \/\/ Render invoices table\n    function renderInvoices(container) {\n        if (billingInvoicesData.length === 0) {\n            container.innerHTML = '<p style=\"color: var(--dash-gray-500); text-align: center; padding: 20px;\">No invoices yet.<\/p>';\n            return;\n        }\n        \n        var html = '<table style=\"width: 100%; border-collapse: collapse;\">';\n        html += '<thead><tr style=\"border-bottom: 1px solid var(--dash-gray-200);\">';\n        html += '<th style=\"text-align: left; padding: 12px 8px; font-size: 13px; font-weight: 600; color: var(--dash-gray-500);\">Date<\/th>';\n        html += '<th style=\"text-align: left; padding: 12px 8px; font-size: 13px; font-weight: 600; color: var(--dash-gray-500);\">Total<\/th>';\n        html += '<th style=\"text-align: left; padding: 12px 8px; font-size: 13px; font-weight: 600; color: var(--dash-gray-500);\">Status<\/th>';\n        html += '<th style=\"text-align: left; padding: 12px 8px; font-size: 13px; font-weight: 600; color: var(--dash-gray-500);\">Actions<\/th>';\n        html += '<\/tr><\/thead><tbody>';\n        \n        billingInvoicesData.forEach(function(invoice) {\n            var statusBadge = invoice.status === 'paid' \n                ? '<span style=\"color: #10b981; font-weight: 500;\">Paid<\/span>'\n                : '<span style=\"color: #f59e0b;\">' + invoice.status + '<\/span>';\n            \n            html += '<tr style=\"border-bottom: 1px solid var(--dash-gray-100);\">';\n            html += '<td style=\"padding: 16px 8px; font-size: 14px; color: var(--dash-gray-700);\">' + invoice.created_date + '<\/td>';\n            html += '<td style=\"padding: 16px 8px; font-size: 14px; color: var(--dash-gray-900); font-weight: 500;\">$' + invoice.amount_paid.toFixed(2) + '<\/td>';\n            html += '<td style=\"padding: 16px 8px;\">' + statusBadge + '<\/td>';\n            html += '<td style=\"padding: 16px 8px;\">';\n            if (invoice.hosted_invoice_url) {\n                html += '<a href=\"' + invoice.hosted_invoice_url + '\" target=\"_blank\" style=\"color: var(--dash-primary); text-decoration: none; font-size: 14px; font-weight: 500;\">View<\/a>';\n            }\n            html += '<\/td>';\n            html += '<\/tr>';\n        });\n        \n        html += '<\/tbody><\/table>';\n        container.innerHTML = html;\n        \n        \/\/ Show\/hide load more button\n        var loadMoreContainer = document.getElementById('billing-load-more-container');\n        if (loadMoreContainer) {\n            loadMoreContainer.style.display = billingHasMore ? 'block' : 'none';\n        }\n    }\n    \n    \/\/ Load more invoices\n    window.loadMoreInvoices = function() {\n        if (billingLastInvoiceId) {\n            loadInvoices(billingLastInvoiceId);\n        }\n    };\n    \n    \/\/ Show\/hide plan picker\n    window.showPlanPicker = function() {\n        var picker = document.getElementById('billing-plan-picker');\n        if (picker) {\n            picker.style.display = '';\n            picker.scrollIntoView({ behavior: 'smooth', block: 'start' });\n        } else {\n            openBillingPortal();\n        }\n    };\n    window.hidePlanPicker = function() {\n        var picker = document.getElementById('billing-plan-picker');\n        if (picker) {\n            picker.style.display = 'none';\n        }\n    };\n    \n    \/\/ Replace Listing modal (schedule tab)\n    window.gveiReplaceListingVideoId = null;\n    window.gveiOpenReplaceListingModal = function(videoId, previewText) {\n        window.gveiReplaceListingVideoId = videoId;\n        var modal = document.getElementById('gvei-replace-listing-modal');\n        var urlInput = document.getElementById('gvei-replace-listing-url');\n        var previewEl = document.getElementById('gvei-replace-current-preview');\n        var statusEl = document.getElementById('gvei-replace-listing-status');\n        if (modal && urlInput) {\n            urlInput.value = '';\n            if (previewEl) previewEl.textContent = previewText ? ('Current: ' + previewText) : '';\n            if (statusEl) { statusEl.style.display = 'none'; statusEl.className = 'gvei-replace-listing-status'; }\n            modal.style.display = 'flex';\n        }\n    };\n    window.gveiCloseReplaceListingModal = function() {\n        var modal = document.getElementById('gvei-replace-listing-modal');\n        if (modal) modal.style.display = 'none';\n        window.gveiReplaceListingVideoId = null;\n    };\n    (function() {\n        var replaceBtns = document.querySelectorAll('.gvei-replace-listing-btn');\n        var submitBtn = document.getElementById('gvei-replace-listing-submit');\n        replaceBtns.forEach(function(btn) {\n            btn.addEventListener('click', function() {\n                var videoId = btn.getAttribute('data-video-id');\n                var preview = btn.getAttribute('data-preview') || '';\n                gveiOpenReplaceListingModal(videoId, preview);\n            });\n        });\n        if (submitBtn) {\n            submitBtn.addEventListener('click', function() {\n                var videoId = window.gveiReplaceListingVideoId;\n                var urlInput = document.getElementById('gvei-replace-listing-url');\n                var statusEl = document.getElementById('gvei-replace-listing-status');\n                var newUrl = urlInput ? urlInput.value.trim() : '';\n                if (!videoId || !newUrl) {\n                    if (statusEl) { statusEl.textContent = 'Please enter a Zillow URL.'; statusEl.className = 'gvei-replace-listing-status error'; statusEl.style.display = 'block'; }\n                    return;\n                }\n                if (newUrl.indexOf('zillow.com') === -1) {\n                    if (statusEl) { statusEl.textContent = 'Please enter a valid Zillow listing URL.'; statusEl.className = 'gvei-replace-listing-status error'; statusEl.style.display = 'block'; }\n                    return;\n                }\n                submitBtn.disabled = true;\n                if (statusEl) { statusEl.textContent = 'Fetching listing data...'; statusEl.className = 'gvei-replace-listing-status'; statusEl.style.display = 'block'; }\n                var formData = new FormData();\n                formData.append('action', 'gvei_agent_replace_listing');\n                formData.append('video_id', videoId);\n                formData.append('new_url', newUrl);\n                formData.append('client_id', '');\n                formData.append('token', '');\n                fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', { method: 'POST', body: formData })\n                    .then(function(r) { return r.json(); })\n                    .then(function(data) {\n                        submitBtn.disabled = false;\n                        if (data.success) {\n                            if (statusEl) { statusEl.textContent = (data.data && data.data.message) || 'Listing replaced successfully! Refreshing...'; statusEl.className = 'gvei-replace-listing-status success'; }\n                            setTimeout(function() { window.location.reload(); }, 1500);\n                        } else {\n                            if (statusEl) { statusEl.textContent = (data.data && data.data.message) || 'Something went wrong.'; statusEl.className = 'gvei-replace-listing-status error'; }\n                        }\n                    })\n                    .catch(function(err) {\n                        submitBtn.disabled = false;\n                        if (statusEl) { statusEl.textContent = 'Network error. Please try again.'; statusEl.className = 'gvei-replace-listing-status error'; }\n                    });\n            });\n        }\n    })();\n\n    \/\/ Reset listing handler (Let us pick)\n    (function() {\n        var resetBtns = document.querySelectorAll('.gvei-reset-listing-btn');\n        resetBtns.forEach(function(btn) {\n            btn.addEventListener('click', function() {\n                var videoId = this.getAttribute('data-video-id');\n                if (!confirm('Reset this video so we pick the freshest listing for you automatically?')) return;\n                btn.disabled = true;\n                btn.textContent = 'Resetting...';\n                var formData = new FormData();\n                formData.append('action', 'gvei_agent_reset_listing');\n                formData.append('video_id', videoId);\n                formData.append('client_id', '');\n                formData.append('token', '');\n                fetch('https:\/\/gogoit.com\/video\/wp-admin\/admin-ajax.php', { method: 'POST', body: formData })\n                    .then(function(r) { return r.json(); })\n                    .then(function(data) {\n                        if (data.success) {\n                            btn.textContent = 'Done! Refreshing...';\n                            setTimeout(function() { window.location.reload(); }, 1000);\n                        } else {\n                            btn.disabled = false;\n                            btn.textContent = 'Let us pick';\n                            alert((data.data && data.data.message) || 'Something went wrong.');\n                        }\n                    })\n                    .catch(function() {\n                        btn.disabled = false;\n                        btn.textContent = 'Let us pick';\n                        alert('Network error. Please try again.');\n                    });\n            });\n        });\n    })();\n\n    \/\/ Initialize billing on billing tab\n        \n    } catch (e) {\n        console.error('Dashboard initialization error:', e);\n    }\n})();\n<\/script>\n\n<!-- Video Player Modal -->\n<div class=\"gvei-video-modal\" id=\"gvei-video-modal\">\n    <div class=\"gvei-video-modal-content\">\n        <button type=\"button\" class=\"gvei-video-modal-close\" onclick=\"closeVideoModal()\">\u00d7<\/button>\n        <video id=\"gvei-video-player\" controls playsinline><\/video>\n    <\/div>\n<\/div>\n\n<!-- Image Crop Modal -->\n<div class=\"gvei-crop-modal\" id=\"gvei-crop-modal\">\n    <div class=\"gvei-crop-container\">\n        <div class=\"gvei-crop-header\">\n            <h3>Crop Your Photo<\/h3>\n            <p>Drag to position, pinch or use buttons to zoom<\/p>\n        <\/div>\n        <div class=\"gvei-crop-area\">\n            <img decoding=\"async\" id=\"gvei-crop-image\" src=\"\" alt=\"Crop preview\">\n        <\/div>\n        <div class=\"gvei-crop-controls\">\n            <button type=\"button\" class=\"gvei-zoom-btn\" id=\"gvei-zoom-out\" style=\"font-size: 24px; font-weight: bold; color: #333;\">\u2212<\/button>\n            <span style=\"color: var(--dash-gray-500); font-size: 14px;\">Zoom<\/span>\n            <button type=\"button\" class=\"gvei-zoom-btn\" id=\"gvei-zoom-in\" style=\"font-size: 24px; font-weight: bold; color: #333;\">+<\/button>\n        <\/div>\n        <div class=\"gvei-crop-actions\">\n            <button type=\"button\" class=\"gvei-crop-cancel\" id=\"gvei-crop-cancel\">Cancel<\/button>\n            <button type=\"button\" class=\"gvei-crop-save\" id=\"gvei-crop-save\">Use This Photo<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<\/div><!-- .gvei-dashboard-wrapper -->\n\n<!-- Cropper.js and HEIC converter - Load at end for profile photo editing -->\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/cropperjs\/1.6.1\/cropper.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/heic2any\/0.0.4\/heic2any.min.js\"><\/script>\n\n<script>\n\/\/ Re-initialize photo upload after external scripts are loaded\nif (typeof initPhotoUpload === 'function') {\n    initPhotoUpload();\n}\n<\/script>\n\n<!-- Tutorial Video Lightbox -->\n<div class=\"gvei-video-lightbox\" id=\"gvei-video-lightbox\">\n    <div class=\"gvei-video-lightbox-overlay\" id=\"gvei-lightbox-overlay\"><\/div>\n    <div class=\"gvei-video-lightbox-content\">\n        <button class=\"gvei-video-lightbox-close\" id=\"gvei-lightbox-close\">&times;<\/button>\n        <div class=\"gvei-video-lightbox-iframe-wrap\">\n            <iframe id=\"gvei-lightbox-iframe\" src=\"\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen><\/iframe>\n        <\/div>\n    <\/div>\n<\/div>\n<script>\n(function(){\n    var lightbox  = document.getElementById('gvei-video-lightbox');\n    var iframe    = document.getElementById('gvei-lightbox-iframe');\n    var overlay   = document.getElementById('gvei-lightbox-overlay');\n    var closeBtn  = document.getElementById('gvei-lightbox-close');\n\n    function vimeoEmbedUrl(raw) {\n        var m = raw.match(\/vimeo\\.com\\\/(?:video\\\/)?(\\d+)\/);\n        return m ? 'https:\/\/player.vimeo.com\/video\/' + m[1] + '?title=0&byline=0&portrait=0' : '';\n    }\n\n    function openLightbox(url) {\n        var embed = vimeoEmbedUrl(url);\n        if (!embed) return;\n        iframe.src = embed;\n        lightbox.classList.add('open');\n        document.body.style.overflow = 'hidden';\n    }\n\n    function closeLightbox() {\n        lightbox.classList.remove('open');\n        iframe.src = '';\n        document.body.style.overflow = '';\n    }\n\n    document.querySelectorAll('.gvei-tutorial-link').forEach(function(link) {\n        link.addEventListener('click', function(e) {\n            e.preventDefault();\n            openLightbox(this.getAttribute('data-vimeo-url'));\n        });\n    });\n\n    if (overlay) overlay.addEventListener('click', closeLightbox);\n    if (closeBtn) closeBtn.addEventListener('click', closeLightbox);\n    document.addEventListener('keydown', function(e) {\n        if (e.key === 'Escape' && lightbox.classList.contains('open')) closeLightbox();\n    });\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-59","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/pages\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":2,"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/pages\/59\/revisions"}],"predecessor-version":[{"id":61,"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/pages\/59\/revisions\/61"}],"wp:attachment":[{"href":"https:\/\/gogoit.com\/video\/wp-json\/wp\/v2\/media?parent=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}