<?php
// CACHE BUSTER - Sept 26, 2025 - DOCUMENTS REMOVED
if (!defined('ABSPATH')) exit;

// Ensure WordPress Media Library JS (wp.media) is available so the Signature
// Maker's "Choose from Media Library" button can open the picker.
if (function_exists('wp_enqueue_media')) {
    wp_enqueue_media();
}

// Suppress WordPress admin footer
add_filter('admin_footer_text', '__return_empty_string', 11);
add_filter('update_footer', '__return_empty_string', 11);

$current_user = wp_get_current_user();
$plan = get_user_meta(get_current_user_id(), 'vmo_subscription_status', true) ?: 'free';
$balance = (int) get_user_meta(get_current_user_id(), 'vmo_token_balance', true) ?: 0;

// Feature Gate map for client-side plan gating
$vmo_feature_gate_map = [];
if (file_exists(plugin_dir_path(__DIR__) . 'includes/class-vmo-feature-gate.php')) {
    require_once plugin_dir_path(__DIR__) . 'includes/class-vmo-feature-gate.php';
    $vmo_feature_gate_map = VMO_Feature_Gate::get_client_map();
}

// Get usage data with percentage and days remaining
require_once plugin_dir_path(__DIR__) . 'includes/class-vmo-usage-calculator.php';
$usage_data = VMO_Usage_Calculator::get_usage_data(get_current_user_id());

// Compute plugin assets URL for logo usage
$plugin_main_file = dirname(__DIR__) . '/vmo-ai-website-builder.php';
$vmo_logo_url = function_exists('plugins_url') ? plugins_url('assets/vmo-icon.svg', $plugin_main_file) : '';
// Provide a best-effort default ringtone asset path (if file isn't present, JS will gracefully fall back)
$vmo_default_ring_url = function_exists('plugins_url') ? plugins_url('assets/vmo-default-ring.mp3', $plugin_main_file) : '';
// Base URL for generated/stored documents
$vmo_docs_base_url = function_exists('content_url') ? content_url('uploads/vmo-documents') : '/wp-content/uploads/vmo-documents';
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VMO Strategic Dashboard - Complete View</title>
    <style>
        :root{
            --bg:#0a0f16; --bg-2:#0c111c; --ink:#e6f3ff; --muted:#9fb2c8;
            --cyan:#0fe1ff; --cyan-soft:#65f1ff; --violet:#7c5cff;
            --chrome:#223242; --chrome-hi:#334b5f; --chrome-lo:#0b1117;
            --rim:rgba(15,225,255,.5); --rim-2:rgba(15,225,255,.25);
            --radius:22px; --panel-radius:16px; --border:rgba(15,225,255,.28); --edge:rgba(15,225,255,.65);
            --shadow:0 24px 60px rgba(0,0,0,.55);
        }
        * { box-sizing: border-box; }
        body {
            margin:0; font:500 14px/1.45 Inter,ui-sans-serif,system-ui; letter-spacing:.1px;
            background:radial-gradient(1200px 700px at 20% -10%, rgba(15,225,255,.06), transparent 60%),
                radial-gradient(1100px 650px at 100% 0%, rgba(124,92,255,.06), transparent 60%),
                linear-gradient(#07121a, #09131b 35%, #070d14);
            color:var(--ink); min-height:100vh;
        }
        
        /* HUD Interface */
        .vmo-hud { position:relative; min-height:100vh; padding:14px; border-radius:var(--radius);
            background:linear-gradient(180deg,var(--chrome-hi),var(--chrome-lo));
            box-shadow:inset 0 0 0 1px rgba(255,255,255,.03), inset 0 -6px 24px rgba(0,0,0,.5), var(--shadow); }
        .vmo-hud::before { content:""; position:absolute; inset:0; border-radius:var(--radius);
            box-shadow:inset 0 0 0 2px var(--rim), inset 0 0 40px var(--rim-2); }
        .vmo-app { display:grid; grid-template-rows:auto 1fr auto; min-height:calc(100vh - 28px); gap:10px; position:relative; z-index:1;
            max-width:1320px; width:100%; margin:0 auto; }

        /* Header */
        .vmo-header { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:10px 14px;
            border-radius:14px; background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.35));
            border:1px solid var(--border); box-shadow:inset 0 1px 0 rgba(255,255,255,.08), inset 0 -1px 0 rgba(0,0,0,.5),
            0 10px 28px rgba(0,0,0,.35); backdrop-filter:blur(12px); }
        .vmo-brand { display:flex; align-items:center; gap:10px; padding:6px 10px; border-radius:12px;
            background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(0,0,0,.35)); border:1px solid var(--border); flex-shrink: 0; white-space: nowrap; }
        .vmo-brand .logo { width:28px; height:28px; display:block; 
            flex-shrink: 0; min-width: 28px;
            filter:drop-shadow(0 0 6px rgba(15,225,255,.45)); }
        .vmo-brand h1 { margin:0; font-size:15px; color:var(--cyan-soft); }
        .vmo-pills { display:flex; gap:10px; align-items:center; }
        .vmo-pill { display:inline-flex; align-items:center; gap:8px; padding:9px 14px; border-radius:12px;
            color:var(--ink); cursor:pointer; background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(0,0,0,.45));
            border:1px solid var(--border); box-shadow:inset 0 1px 0 rgba(255,255,255,.08), inset 0 -1px 0 rgba(0,0,0,.6),
            0 8px 22px rgba(0,0,0,.35); transition:all 0.2s; }
        .vmo-pill:hover, .vmo-pill.active { box-shadow:0 0 0 1px var(--edge) inset, 0 12px 30px rgba(15,225,255,.18); }

        

        /* HUD Metrics */
        .vmo-metrics { display:flex; gap:12px; }
        .vmo-metric { text-align:center; padding:8px 12px; }
        .vmo-metric-value { font-size:18px; font-weight:700; color:var(--cyan-soft); }
        .vmo-metric-label { font-size:11px; color:var(--muted); margin-top:2px; }
        .progress-ring { width:32px; height:32px; margin:0 auto 4px; }
        .progress-ring circle { fill:none; stroke:var(--border); stroke-width:2; }
        .progress-ring .progress { stroke:var(--cyan); stroke-linecap:round; transition:stroke-dashoffset 0.5s; }

        /* Token & Billing Section */
        .vmo-tokens { background:linear-gradient(135deg, rgba(15,225,255,.08), rgba(0,0,0,.3)); 
            border:1px solid var(--edge); border-radius:12px; padding:12px; }
        .token-usage-meter { height:8px; background:rgba(255,255,255,0.1); border-radius:10px; 
            overflow:hidden; margin-bottom:10px; }
        .token-usage-meter .meter-fill { height:100%; background:linear-gradient(90deg, #10b981 0%, #10b981 74%, #f59e0b 75%, #f59e0b 89%, #ef4444 90%, #ef4444 100%); 
            transition:width 0.5s ease; border-radius:10px; }
        .token-balance { font-size:16px; font-weight:700; color:var(--cyan-soft); }
        .token-details { font-size:11px; color:var(--muted); margin-top:4px; }
        .auto-topup { display:flex; align-items:center; gap:6px; margin-top:8px; font-size:12px; }
        .toggle-switch { width:32px; height:18px; background:var(--chrome-lo); border-radius:12px; position:relative;
            cursor:pointer; border:1px solid var(--border); }
        .toggle-switch.active { background:var(--cyan); }
        .toggle-slider { width:14px; height:14px; background:white; border-radius:50%; position:absolute;
            top:1px; left:1px; transition:transform 0.2s; }
        .toggle-switch.active .toggle-slider { transform:translateX(14px); }

        /* Main Content */
        .vmo-main { display:grid; grid-template-columns:460px 1fr; gap:12px; min-height:0; }
        .vmo-panel { position:relative; background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(0,0,0,.55));
            border-radius:var(--panel-radius); border:1px solid var(--border);
            box-shadow:inset 0 2px 0 rgba(255,255,255,.06), inset 0 -2px 0 rgba(0,0,0,.7), var(--shadow); }

        /* Left Panel - Strategic Dashboard */
        .vmo-strategic { display:grid; grid-template-rows:auto 1fr auto; padding:16px; min-height:600px; }
        .vmo-title { font-weight:800; color:#d9ecff; margin:4px 0 10px 4px; text-shadow:0 0 12px rgba(15,225,255,.2); }
        .vmo-roadmap { overflow:auto; padding:10px; border-radius:12px;
            background:linear-gradient(180deg, rgba(255,255,255,.02), rgba(0,0,0,.45)); 
            border:1px dashed rgba(15,225,255,.28); }

        /* Progress Tracking */
        .progress-summary { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:16px; }
        .progress-card { background:rgba(255,255,255,.05); border:1px solid var(--border); border-radius:8px; padding:12px; }
        .progress-card h4 { margin:0 0 8px; color:var(--cyan-soft); font-size:13px; }
        .progress-bar { height:6px; background:var(--chrome-lo); border-radius:3px; overflow:hidden; }
        .progress-fill { height:100%; background:linear-gradient(90deg, var(--cyan), var(--violet)); transition:width 0.5s; }

        /* Task List */
        .task-list { margin-top:16px; }
        .task-item { display:flex; align-items:center; gap:10px; padding:8px; border-radius:6px;
            background:rgba(255,255,255,.02); border:1px solid rgba(255,255,255,.05); margin-bottom:6px; }
        .task-checkbox { width:16px; height:16px; border:1px solid var(--border); border-radius:3px;
            background:transparent; cursor:pointer; position:relative; }
        .task-checkbox.checked { background:var(--cyan); }
        .task-checkbox.checked::after { content:'✓'; color:white; position:absolute; inset:0;
            display:flex; align-items:center; justify-content:center; font-size:10px; }
        .task-text { flex:1; font-size:12px; }
        .task-tokens { color:var(--cyan-soft); font-size:11px; padding:2px 6px;
            background:rgba(15,225,255,.15); border-radius:4px; }

        /* Quick Actions */
        .quick-actions { display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-top:12px; }
        .action-btn { padding:8px 12px; border:1px solid var(--border); border-radius:8px;
            background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(0,0,0,.55)); color:var(--ink);
            cursor:pointer; text-align:center; font-size:11px; transition:all 0.2s; }
        .action-btn:hover { border-color:var(--edge); box-shadow:0 4px 12px rgba(15,225,255,.2); }
        .action-btn.primary { background:linear-gradient(180deg, rgba(15,225,255,.28), rgba(0,0,0,.6)); 
            border-color:var(--edge); }
        .action-btn.danger { background:linear-gradient(180deg, rgba(124,92,255,.24), rgba(0,0,0,.65));
            border-color:rgba(124,92,255,.45); color:var(--ink); }
        .action-btn.compact { padding:4px 8px; font-size:10px; }

        /* Reports tab styles */
        .vmo-report-tab.active { background:linear-gradient(180deg, rgba(15,225,255,.18), rgba(0,0,0,.6)); border-color:var(--edge); color:var(--cyan-soft); box-shadow:0 0 0 1px var(--edge) inset, 0 4px 14px rgba(15,225,255,.2); }
        .vmo-report-tab-content { animation: vmoFadeIn .2s ease; }
        @keyframes vmoFadeIn { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:translateY(0); } }

        /* Phone dialer polish (scoped) */
        #panel-interface-details .vmo-phone-interface-grid{ grid-template-columns:repeat(2, minmax(0, 1fr)); align-items:stretch; }
        #panel-interface-details .vmo-phone-tool-card{ min-height:222px; display:flex; flex-direction:column; }
        #panel-interface-details .vmo-phone-notes-card{ order:-1; }
        #panel-interface-details .vmo-phone-number-card{ order:0; }
        #vmo-assigned-notes{ flex:1; min-height:138px; width:100%; padding:10px; border-radius:8px; border:1px solid var(--border); background:#fff; color:#111; resize:vertical; box-shadow:inset 0 1px 2px rgba(0,0,0,.06); }
        #vmo-sci-fi-dialer{ position:relative; overflow:hidden; grid-column:1 / -1; order:-2; }
        #vmo-sci-fi-dialer::before{ content:""; position:absolute; inset:-40%; pointer-events:none; transform:rotate(8deg);
            background:
                radial-gradient(650px 420px at 22% 15%, rgba(15,225,255,.12), transparent 55%),
                radial-gradient(700px 460px at 78% 25%, rgba(124,92,255,.10), transparent 60%);
            opacity:.9;
        }
        #vmo-sci-fi-dialer > *{ position:relative; z-index:1; }
        #vmo-sci-fi-dialer .action-btn{ border-radius:12px; letter-spacing:0; }
        #vmo-sci-fi-dialer .action-btn:hover{
            transform:translateY(-1px);
            border-color:rgba(5,10,16,.8);
            box-shadow:inset 0 0 0 1px rgba(15,225,255,.62), inset 0 0 18px rgba(15,225,255,.24), 0 8px 18px rgba(0,0,0,.28);
        }
        #vmo-sci-fi-dialer .action-btn:active{
            transform:translateY(0);
            border-color:rgba(5,10,16,.88);
            box-shadow:inset 0 0 0 1px rgba(15,225,255,.76), inset 0 0 26px rgba(15,225,255,.34), inset 0 -2px 10px rgba(0,0,0,.72), 0 4px 12px rgba(0,0,0,.32);
        }
        #vmo-sci-fi-dialer .vmo-dialer-shell{ width:min(100%, 430px); margin:0 auto; display:grid; gap:10px; }
        #vmo-sci-fi-dialer .vmo-dialer-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:2px; }
        #vmo-sci-fi-dialer .vmo-dialer-state-tools{ display:flex; align-items:center; gap:8px; }
        #vmo-dialer-mode{ min-height:38px; min-width:64px; display:inline-flex; align-items:center; justify-content:center; padding:0 12px; border-radius:12px; border:1px solid rgba(56,189,248,.28); background:rgba(56,189,248,.08); color:#38bdf8; font-size:11px; font-weight:800; letter-spacing:0; text-transform:uppercase; }
        #vmo-ring-settings-btn{ width:42px; height:38px; min-height:38px; padding:0 !important; display:inline-flex; align-items:center; justify-content:center; font-size:22px !important; line-height:1 !important; font-weight:800; }
        #vmo-sci-fi-dialer .vmo-dialer-input-wrap{ position:relative; width:100%; }
        #vmo-dialer-input{ width:100%; min-height:56px; padding:12px 52px 12px 14px; border-radius:14px; border:1px solid var(--border); background:rgba(255,255,255,.055); color:var(--ink); font-size:20px; font-weight:700; letter-spacing:0; box-shadow:inset 0 1px 0 rgba(255,255,255,.08), inset 0 -1px 0 rgba(0,0,0,.45); }
        #vmo-dialer-backspace{ position:absolute; top:7px; right:7px; width:40px; height:42px; min-height:42px; padding:0; display:inline-flex; align-items:center; justify-content:center; border-radius:10px; font-size:16px; }
        #vmo-sci-fi-dialer .vmo-dialer-primary-actions{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; }
        #vmo-sci-fi-dialer .vmo-dialer-primary-actions .action-btn{ min-height:104px; padding:12px 8px; display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:800; white-space:normal; }
        #vmo-sci-fi-dialer .vmo-dialer-keypad{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; }
        #vmo-sci-fi-dialer .vmo-dialer-key{ min-height:52px; padding:12px 10px; font-size:18px; font-weight:800; letter-spacing:0;
            background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(0,0,0,.65));
            border-color:rgba(255,255,255,.10);
            box-shadow:inset 0 1px 0 rgba(255,255,255,.10), 0 10px 26px rgba(0,0,0,.25);
        }
        #vmo-sci-fi-dialer .vmo-dialer-plus-silent{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:8px; }
        #vmo-sci-fi-dialer .vmo-dialer-utilities{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; }
        #vmo-sci-fi-dialer .vmo-dialer-utilities .action-btn{ min-height:38px; padding:7px 8px; font-size:11px; }
        #vmo-ring-toggle{ min-height:52px; font-weight:800; }
        #vmo-ring-toggle.active{ background:linear-gradient(180deg, rgba(245,158,11,.22), rgba(0,0,0,.62));
            border-color:rgba(245,158,11,.62);
            box-shadow:0 0 0 1px rgba(245,158,11,.62) inset, 0 10px 26px rgba(245,158,11,.13);
        }
        #vmo-dialer-action.vmo-dialer-glow{ box-shadow:0 0 0 1px var(--edge) inset, 0 10px 26px rgba(15,225,255,.18); }
        #vmo-dialer-status:empty{ display:none; }
        #vmo-dialer-status:not(:empty){ display:block; margin-top:2px; color:var(--muted); font-size:11px; text-align:center; }

        @media (max-width: 520px) {
            #panel-interface-details .vmo-phone-interface-grid{ grid-template-columns:1fr; }
            #vmo-sci-fi-dialer .vmo-dialer-shell{ width:100%; }
            #vmo-sci-fi-dialer .vmo-dialer-primary-actions .action-btn{ min-height:82px; font-size:12px; }
            #vmo-dialer-input{ min-height:52px; font-size:17px; }
        }

        /* Hide scrollbars in phone system while keeping functionality */
        #vmo-sms-conversations::-webkit-scrollbar,
        #vmo-sms-thread::-webkit-scrollbar,
        #vmo-action-items-list::-webkit-scrollbar,
        #vmo-call-reports-list::-webkit-scrollbar,
        #vmo-missed-ops-list::-webkit-scrollbar,
        #vmo-history-list::-webkit-scrollbar {
            display: none;
        }
        #vmo-sms-conversations,
        #vmo-sms-thread,
        #vmo-action-items-list,
        #vmo-call-reports-list,
        #vmo-missed-ops-list,
        #vmo-history-list {
            scrollbar-width: none;
        }

        /* Right Panel - Navigation & Canvas */
        .vmo-workspace { display:grid; grid-template-rows:auto 1fr; padding:16px; }
        .vmo-tabs { display:flex; gap:8px; margin-bottom:12px; flex-wrap:wrap; }
        .vmo-tab { padding:12px 16px; border-radius:10px; border:1px solid var(--border);
            background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.5)); cursor:pointer;
            font-size:13px; transition:all 0.2s; color:#fff; }
        .vmo-tab:hover { border-color:var(--edge);
            box-shadow:0 0 0 1px var(--edge) inset, 0 8px 20px rgba(15,225,255,.18); }
        .vmo-tab.active { border-color:var(--edge) !important; color:var(--cyan-soft);
            background:linear-gradient(180deg, rgba(15,225,255,.18), rgba(0,0,0,.58)) !important;
            box-shadow:0 0 0 1px var(--edge) inset, 0 8px 24px rgba(15,225,255,.24), 0 0 18px rgba(15,225,255,.12) !important; }

        /* Canvas Sections */
        .vmo-canvas { position:relative; min-height:600px; border-radius:16px; background:var(--bg-2);
            border:1px solid var(--border); box-shadow:inset 0 0 0 1px rgba(255,255,255,.03), 
            inset 0 18px 60px rgba(0,0,0,.6); overflow:hidden; }
        .vmo-scan { position:absolute; inset:0; pointer-events:none;
            background:linear-gradient(rgba(255,255,255,.02), rgba(255,255,255,0) 2px) top/100% 4px; opacity:.18; }
    .vmo-section { position:absolute; inset:0; padding:18px 20px; overflow:auto; overflow-x:hidden; display:none; z-index:1; }
        .vmo-section.active { display:block; }

        /* Global phone-system scrollbars hide (still scrolls) */
        .vmo-section, .vmo-panel, .vmo-canvas, .nav-panel, #vmo-sci-fi-dialer, #vmo-ring-settings, #vmo-sms-conversations, #vmo-sms-thread, #vmo-action-items-list, #vmo-call-reports-list, #vmo-missed-ops-list {
            scrollbar-width: none;
            -ms-overflow-style: none;
        }
        .vmo-section::-webkit-scrollbar, .vmo-panel::-webkit-scrollbar, .vmo-canvas::-webkit-scrollbar, .nav-panel::-webkit-scrollbar, #vmo-sci-fi-dialer::-webkit-scrollbar, #vmo-ring-settings::-webkit-scrollbar, #vmo-sms-conversations::-webkit-scrollbar, #vmo-sms-thread::-webkit-scrollbar, #vmo-action-items-list::-webkit-scrollbar, #vmo-call-reports-list::-webkit-scrollbar, #vmo-missed-ops-list::-webkit-scrollbar, #vmo-history-list::-webkit-scrollbar {
            width: 0;
            height: 0;
            background: transparent;
        }

        /* Internal feature panels (newly added) */
        #section-overview { display: block; }
        #section-plan, #section-crm, #section-seo, #section-email, #section-payments { display: none; }

        /* Cards within sections */
        .vmo-cards { display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:14px; min-width:0; }

        /* Today sub-tab styles */
        .vmo-today-subtab { padding:6px 12px; border:none; background:transparent; color:var(--muted); font-size:12px; font-weight:600; cursor:pointer; border-radius:6px; transition:all 0.2s; }
        .vmo-today-subtab.active { background:rgba(15,225,255,0.15); color:var(--cyan-soft); }
        .vmo-today-subtab:hover { background:rgba(255,255,255,0.05); }
        .vmo-today-panel { }
        .vmo-today-panel:not(.active) { display:none; }
        .vmo-card { background:linear-gradient(180deg, rgba(255,255,255,.03), rgba(0,0,0,.55));
            border:1px solid var(--border); border-radius:12px; padding:16px; }
        .vmo-card, .vmo-card * { min-width:0; max-width:100%; box-sizing:border-box; }
        .vmo-card h4 { margin:0 0 10px; color:var(--cyan-soft); font-size:15px; }
        .vmo-card p { margin:0; font-size:13px; color:var(--muted); line-height:1.5; }
        /* Documents Hub */
        .documents-header { display:flex; flex-direction:column; gap:8px; margin-bottom:16px; }
        .documents-header h4 { margin:0; font-size:16px; color:var(--cyan-soft); }
        .documents-header p { margin:0; font-size:12px; color:var(--muted); line-height:1.55; }
        .doc-tagline { display:flex; flex-wrap:wrap; gap:8px; }
        .doc-chip { display:inline-flex; align-items:center; gap:4px; padding:3px 8px; border-radius:14px; font-size:10px;
            letter-spacing:.3px; text-transform:uppercase; border:1px solid rgba(255,255,255,.14); background:rgba(255,255,255,.05); color:var(--muted); }
        .doc-chip.critical { border-color:rgba(255,99,71,.45); background:rgba(255,99,71,.15); color:#ffb4a3; }
        .doc-chip.recommended { border-color:rgba(15,225,255,.35); background:rgba(15,225,255,.12); color:var(--cyan-soft); }
        .doc-chip.optional { border-color:rgba(108,117,125,.2); background:rgba(108,117,125,.08); color:#a8b5c3; }
        .documents-controls { display:flex; flex-wrap:wrap; gap:10px; margin:0 0 16px; }
        .documents-controls .action-btn { font-size:11px; padding:8px 14px; }
        .documents-layout { display:grid; grid-template-columns:240px 1fr; gap:16px; align-items:flex-start; }
        .documents-nav { display:flex; flex-direction:column; gap:10px; }
        .doc-nav-link { display:flex; flex-direction:column; gap:4px; text-align:left; border-radius:12px; padding:10px 14px;
            border:1px solid rgba(255,255,255,.1); background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(0,0,0,.45));
            color:var(--ink); font-size:12px; cursor:pointer; transition:border-color .2s ease, box-shadow .2s ease, transform .2s ease;
            appearance:none; -webkit-appearance:none; outline:none; }
        .doc-nav-link span { font-size:11px; color:var(--muted); }
        .doc-nav-link:hover, .doc-nav-link.active { border-color:var(--edge); box-shadow:0 8px 22px rgba(15,225,255,.18); transform:translateY(-1px); }
        .documents-panels { position:relative; min-height:320px; }
        .doc-panel { display:none; flex-direction:column; gap:10px; padding:14px; border-radius:14px; border:1px solid rgba(255,255,255,.1);
            background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(0,0,0,.45)); box-shadow:inset 0 0 0 1px rgba(255,255,255,.05); min-height:0; }
        .doc-panel.active { display:flex; animation:docPanelIn .22s ease; }
        @keyframes docPanelIn { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:translateY(0); } }
        .doc-panel h5 { margin:0; font-size:13px; color:var(--cyan-soft); }
        .doc-panel p { margin:0; font-size:11px; color:var(--muted); line-height:1.55; }
        .doc-list { display:flex; flex-direction:column; gap:8px; }
        .doc-item { display:flex; gap:10px; align-items:flex-start; padding:10px 12px; border-radius:12px; border:1px solid rgba(15,225,255,.16);
            background:rgba(7,18,26,.45); box-shadow:inset 0 0 0 1px rgba(255,255,255,.04); transition:border-color .2s ease, box-shadow .2s ease; }
        .doc-item:hover { border-color:var(--edge); box-shadow:0 6px 18px rgba(15,225,255,.18); }
        .doc-item input[type="checkbox"] { margin-top:4px; accent-color:var(--cyan); width:16px; height:16px; }
        .doc-body { flex:1; display:flex; flex-direction:column; gap:4px; }
        .doc-item strong { font-size:12px; color:var(--ink); display:flex; align-items:center; gap:6px; }
        .doc-item span { font-size:11px; color:var(--muted); line-height:1.45; }
        .doc-status { font-size:10px; text-transform:uppercase; letter-spacing:.4px; padding:2px 6px; border-radius:999px;
            background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.16); color:var(--muted); }
        .doc-status.generating { background:rgba(255,193,7,.18); border-color:rgba(255,193,7,.42); color:#ffdd8c; }
        .doc-status.ready { background:rgba(46,204,113,.16); border-color:rgba(46,204,113,.38); color:#8ff0b2; }
        .doc-status.uploaded { background:rgba(124,92,255,.18); border-color:rgba(124,92,255,.36); color:#cebaff; }
        .doc-library { display:flex; flex-direction:column; gap:10px; }
        .doc-category { border-radius:12px; border:1px solid rgba(255,255,255,.08); background:rgba(7,18,26,.35); overflow:hidden; }
        .doc-category summary { cursor:pointer; padding:10px 14px; font-size:12px; color:var(--ink); background:rgba(255,255,255,.04); display:flex; align-items:center; justify-content:space-between; }
        .doc-category summary::-webkit-details-marker { display:none; }
        .doc-category summary span { font-size:11px; color:var(--muted); }
        .doc-category-content { padding:10px 14px; display:flex; flex-direction:column; gap:8px; }
        .doc-empty { padding:14px; border:1px dashed rgba(255,255,255,.18); border-radius:12px; text-align:center; font-size:11px; color:var(--muted);
            background:rgba(7,18,26,.35); }
        .doc-generated-item { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border-radius:12px;
            border:1px solid rgba(15,225,255,.22); background:rgba(7,18,26,.5); }
        .doc-generated-item strong { font-size:12px; color:var(--ink); }
        .doc-generated-item small { font-size:10px; color:var(--muted); }
        .doc-generated-item .action-btn { padding:4px 10px; font-size:10px; }
        .doc-auto { display:flex; flex-direction:column; gap:6px; padding:10px; border-radius:12px; border:1px dashed rgba(255,255,255,.18);
            background:rgba(7,18,26,.4); }
        .doc-auto li { font-size:11px; color:var(--muted); }
        @media (max-width: 1024px) {
            .documents-layout { grid-template-columns:1fr; }
            .documents-nav { flex-direction:row; flex-wrap:wrap; }
            .doc-nav-link { flex:1 1 220px; }
        }
        @media (max-width: 768px) {
            .documents-controls { flex-direction:column; align-items:stretch; }
            .documents-panels { min-height:0; }
        }
        .vmo-kv { display:grid; grid-template-columns:1fr auto; gap:8px; margin:6px 0; color:var(--muted);
            font-size:13px; padding:6px 0; border-bottom:1px solid rgba(255,255,255,.05); }
        .vmo-kv:last-child { border-bottom:none; }

        /* Navigation Links */
        .nav-section { margin-bottom:24px; }
        .nav-section h4 { color:var(--cyan-soft); margin:0 0 14px; font-size:15px; }
        .nav-links { display:grid; gap:10px; }
        .nav-link { display:flex; align-items:center; gap:12px; padding:14px 14px; border-radius:10px;
            background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(0,0,0,.4));
            border:1px solid var(--border); cursor:pointer; transition:all 0.2s; }
        .nav-link:hover { border-color:var(--edge); box-shadow:0 4px 12px rgba(15,225,255,.2); }
        .nav-link.vmo-active { border-color:var(--edge) !important; background:linear-gradient(180deg, rgba(15,225,255,.18), rgba(0,0,0,.6)) !important; box-shadow:0 0 0 1px var(--edge) inset, 0 6px 18px rgba(15,225,255,.25) !important; color:var(--cyan-soft) !important; }
        .nav-link.vmo-active .nav-text { color:var(--cyan-soft); }
        .nav-link.vmo-active .nav-icon { background:var(--cyan); opacity:1; }
        .nav-link.expanded { border-color:var(--edge); background:linear-gradient(180deg, rgba(15,225,255,.1), rgba(0,0,0,.6)); }
        .nav-icon { width:24px; height:24px; background:var(--cyan); border-radius:6px; opacity:0.7; }
        .nav-text { flex:1; font-size:13px; }
        .nav-badge { background:rgba(15,225,255,.2); color:var(--cyan-soft); padding:3px 8px;
            border-radius:5px; font-size:11px; }
        .vmo-promo-subtabs { display:flex; gap:10px; flex-wrap:wrap; margin:0 0 18px; }
        .vmo-promo-subtab {
            padding:10px 14px; border-radius:10px; border:1px solid var(--border);
            background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.5));
            color:var(--ink); font-size:13px; font-weight:600; cursor:pointer; transition:all .2s ease;
        }
        .vmo-promo-subtab.active,
        .vmo-promo-subtab:hover:not([disabled]) {
            border-color:var(--edge);
            box-shadow:0 0 0 1px var(--edge) inset, 0 8px 20px rgba(15,225,255,.18);
            background:linear-gradient(180deg, rgba(15,225,255,.16), rgba(0,0,0,.58));
        }
        .vmo-promo-subtab[disabled] {
            opacity:.5; cursor:not-allowed; box-shadow:none; filter:saturate(.6);
        }
        .vmo-promo-note {
            margin:0 0 18px; padding:14px 16px; border-radius:12px; border:1px solid rgba(124,92,255,.28);
            background:linear-gradient(180deg, rgba(124,92,255,.14), rgba(0,0,0,.45));
            color:#d9e4ff;
        }
        .vmo-promo-note strong { color:#f0f5ff; }
        .vmo-promo-note p { margin:4px 0 0; color:#b7c6dd; font-size:12px; line-height:1.55; }
        .vmo-promo-metrics { display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:12px; margin-bottom:18px; }
        .vmo-promo-metric { background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(0,0,0,.52)); border:1px solid var(--border); border-radius:12px; padding:14px; }
        .vmo-promo-metric small { display:block; color:var(--muted); text-transform:uppercase; letter-spacing:.12em; font-size:10px; margin-bottom:8px; }
        .vmo-promo-metric strong { color:var(--cyan-soft); font-size:20px; }
        .vmo-promo-metric span { display:block; margin-top:6px; color:var(--muted); font-size:12px; }
        .vmo-promo-chiplist { display:flex; flex-wrap:wrap; gap:8px; }
        .vmo-promo-chip {
            display:inline-flex; align-items:center; gap:8px; padding:8px 12px; border-radius:999px;
            border:1px solid rgba(255,255,255,.12); background:rgba(255,255,255,.05); color:var(--ink); cursor:pointer;
            transition:border-color .2s ease, box-shadow .2s ease, background .2s ease;
        }
        .vmo-promo-chip.active,
        .vmo-promo-chip:hover {
            border-color:var(--edge); background:rgba(15,225,255,.12); box-shadow:0 0 16px rgba(15,225,255,.14);
        }
        .vmo-promo-chip input { display:none; }
        .vmo-promo-result-list,
        .vmo-promo-queue-list,
        .vmo-promo-asset-list { display:flex; flex-direction:column; gap:10px; }
        .vmo-promo-result-item,
        .vmo-promo-queue-item,
        .vmo-promo-asset-item {
            padding:12px 14px; border-radius:12px; border:1px solid rgba(255,255,255,.1);
            background:rgba(255,255,255,.04);
        }
        .vmo-promo-result-item strong,
        .vmo-promo-queue-item strong,
        .vmo-promo-asset-item strong { color:var(--ink); }
        .vmo-promo-result-item p,
        .vmo-promo-queue-item p,
        .vmo-promo-asset-item p { margin-top:6px; font-size:12px; line-height:1.6; color:var(--muted); }
        .vmo-promo-toggle-row {
            display:flex; justify-content:space-between; align-items:flex-start; gap:16px;
            padding:14px; border-radius:12px; border:1px solid rgba(255,255,255,.1); background:rgba(255,255,255,.04);
        }
        .vmo-promo-toggle-row small { display:block; margin-top:4px; color:var(--muted); line-height:1.5; }
        .vmo-promo-manual-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:10px; }
        .vmo-promo-upload {
            display:flex; flex-direction:column; gap:8px; padding:14px; border-radius:12px;
            border:1px dashed rgba(15,225,255,.32); background:rgba(7,18,26,.45);
        }
        .vmo-promo-upload label { color:var(--ink); font-size:13px; font-weight:600; }
        .vmo-promo-upload small { color:var(--muted); line-height:1.5; }
        .vmo-promo-mini-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:10px; }
        .vmo-promo-mini-card {
            padding:12px; border-radius:12px; border:1px solid rgba(255,255,255,.1); background:rgba(255,255,255,.04);
            color:var(--ink); font-size:12px; line-height:1.55;
        }
        .vmo-promo-empty {
            padding:16px; border-radius:12px; border:1px dashed rgba(255,255,255,.18);
            background:rgba(7,18,26,.32); color:var(--muted); font-size:12px; text-align:center;
        }
        #promotion.vmo-promo-preview-mode [id^="vmo-promo-"][id$="-panel"] { display:block !important; }
        #promotion.vmo-promo-preview-mode .nav-link,
        #promotion.vmo-promo-preview-mode .vmo-promo-subtab,
        #promotion.vmo-promo-preview-mode .action-btn,
        #promotion.vmo-promo-preview-mode .vmo-promo-chip,
        #promotion.vmo-promo-preview-mode input,
        #promotion.vmo-promo-preview-mode textarea,
        #promotion.vmo-promo-preview-mode select,
        #promotion.vmo-promo-preview-mode label,
        #promotion.vmo-promo-preview-mode a {
            pointer-events:none !important;
        }
        #promotion.vmo-promo-preview-mode .nav-link,
        #promotion.vmo-promo-preview-mode .vmo-promo-subtab,
        #promotion.vmo-promo-preview-mode .vmo-card,
        #promotion.vmo-promo-preview-mode .vmo-promo-metric,
        #promotion.vmo-promo-preview-mode .vmo-promo-result-item,
        #promotion.vmo-promo-preview-mode .vmo-promo-queue-item,
        #promotion.vmo-promo-preview-mode .vmo-promo-asset-item,
        #promotion.vmo-promo-preview-mode .vmo-promo-mini-card,
        #promotion.vmo-promo-preview-mode .vmo-promo-upload {
            filter:grayscale(.85);
            opacity:.7;
        }
        #promotion.vmo-promo-preview-mode .vmo-promo-note {
            border-color:rgba(245,158,11,.35);
            background:linear-gradient(180deg, rgba(245,158,11,.12), rgba(0,0,0,.48));
        }
        .vmo-promo-preview-banner {
            margin-bottom:18px;
            padding:14px 16px;
            border-radius:12px;
            border:1px solid rgba(245,158,11,.35);
            background:linear-gradient(180deg, rgba(245,158,11,.12), rgba(0,0,0,.45));
            color:#fde68a;
        }
        .vmo-promo-preview-banner strong { color:#fff7d6; }
        .vmo-promo-preview-banner p { margin:4px 0 0; color:#fce7a8; font-size:12px; line-height:1.6; }

        /* ✅ ISSUE 2: Phone System Accordion Layout */
        .nav-link.accordion-toggle { flex-direction: row; justify-content: flex-start; align-items: center; gap: 12px; text-align: left; position: relative; }
        .nav-link.accordion-toggle .nav-icon { width: 24px; height: 24px; margin: 0; flex-shrink: 0; }
        .nav-link.accordion-toggle .nav-text { flex: 1; }
        .nav-link.accordion-toggle .nav-badge { align-self: center; }
        .nav-panel { position: relative; z-index: 10; display: none; padding: 16px; border-radius: 0 0 10px 10px; margin-top: -10px;
            background: linear-gradient(180deg, rgba(15,225,255,.08), rgba(0,0,0,.5)); 
            border: 1px solid var(--border); border-top: none; }
        .nav-panel.open { display: block; animation: accordionSlideDown 0.3s ease; }

        /* Hide accordion viewport scrollbars while keeping scroll functional */
        .nav-panel {
            scrollbar-width: none;
            -ms-overflow-style: none;
        }
        .nav-panel::-webkit-scrollbar {
            width: 0;
            height: 0;
            background: transparent;
        }
        @keyframes accordionSlideDown { from { opacity: 0; max-height: 0; } to { opacity: 1; max-height: 500px; } }
        
        /* Expandable Analytics Panels */
        .analytics-panel { display:none; margin-top:10px; padding:16px; border-radius:10px; 
            background:linear-gradient(180deg, rgba(255,255,255,.02), rgba(0,0,0,.6)); 
            border:1px solid var(--border); }
        .analytics-panel.show { display:block; }
        .date-filter { display:flex; gap:10px; margin-bottom:14px; align-items:center; }
        .date-filter input, .date-filter select { padding:8px 10px; border-radius:8px; border:1px solid var(--border); 
            background:rgba(255,255,255,.05); color:var(--ink); font-size:12px; }
        .analytics-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr)); gap:10px; margin:10px 0; }
        .analytics-item { text-align:center; padding:12px; border-radius:8px; background:rgba(255,255,255,.03); }
        .analytics-value { font-size:16px; font-weight:700; color:var(--cyan-soft); }
        .analytics-label { font-size:10px; color:var(--muted); margin-top:2px; }

        /* Modal */
        .vmo-modal { position:fixed; inset:0; background:rgba(0,0,0,.8); display:none; align-items:center;
            justify-content:center; z-index:1000; backdrop-filter:none; -webkit-backdrop-filter:none; }
        /* Safety: ensure any modal element that is made visible is actually centered in viewport */
        .vmo-modal, .vmo-fs-modal { top:0 !important; left:0 !important; right:0 !important; bottom:0 !important; margin:0 !important; }
        .vmo-modal .modal-content, .vmo-fs-modal .vmo-modal-panel { margin:0 auto; }
        .vmo-modal, .vmo-fs-modal { display:none; align-items:center; justify-content:center; }
        .vmo-modal.show { display:flex; }
        /* Safety: ensure our JS class also forces display */
        .vmo-modal-visible { display:flex !important; }
        .modal-content { background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.72));
            border:1px solid var(--border); border-radius:18px; padding:20px; max-width:920px; width:min(920px, 96vw);
            max-height:90vh; overflow-y:auto;
            box-shadow:inset 0 1px 0 rgba(255,255,255,.08), inset 0 -2px 0 rgba(0,0,0,.6), var(--shadow); }
        .modal-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:16px; }
        .modal-title { color:var(--cyan-soft); margin:0; }
        .modal-close { background:none; border:none; color:var(--muted); cursor:pointer; font-size:20px; }
        .modal-body { color:var(--ink); line-height:1.6; }
        .vmo-toast-host { position:fixed; top:86px; right:24px; display:flex; flex-direction:column; gap:10px;
            z-index:10000; pointer-events:none; }
        .vmo-toast { padding:10px 14px; border-radius:12px; background:rgba(7,18,26,.92); color:var(--ink);
            border:1px solid rgba(15,225,255,.32); box-shadow:0 18px 36px rgba(0,0,0,.35); opacity:0;
            transform:translateY(-6px); transition:opacity .28s ease, transform .28s ease; }
        .vmo-toast.show { opacity:1; transform:translateY(0); }
        .vmo-toast-success { border-color:rgba(15,225,255,.48); }
        .vmo-toast-error { border-color:rgba(124,92,255,.48); color:var(--ink); }
        .vmo-toast-info { border-color:rgba(15,225,255,.32); }
    /* Recording modal containment: never break out of its dialog */
    #vmo-recording-modal { position:fixed !important; display:none; align-items:center; justify-content:center; z-index:999999 !important; -webkit-transform:translateZ(0); }
    #vmo-recording-modal #vmo-rec-body { max-height:70vh; overflow:auto; }

        .vmo-dashboard-footer { 
            position: static !important;
            left: auto !important;
            right: auto !important;
            bottom: auto !important;
            width: 100%;
            max-width: 1320px;
            margin: 0 auto;
            min-height: 64px;
            padding: 12px 16px; 
            box-sizing: border-box;
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center; 
            color: var(--muted); 
            border-radius: 12px;
            background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.45)); 
            border: 1px solid var(--border); 
            font-size: 11px;
            box-shadow: inset 0 1px 0 rgba(255,255,255,.06), inset 0 -1px 0 rgba(0,0,0,.5), var(--shadow);
            z-index: 1;
        }
        .vmo-dashboard-footer p {
            margin: 0;
            line-height: 1.35;
            max-width: 100%;
        }
        
        /* Hide WordPress admin footer */
        #wpfooter { display: none !important; }
        .wp-admin #wpfooter { display: none !important; }

        /* Full-screen modal standardization */
        .vmo-fs-modal { position:fixed; inset:0; width:100vw; height:100vh; display:none; align-items:center; justify-content:center; z-index:100000; backdrop-filter:none; -webkit-backdrop-filter:none; }
        .vmo-fs-modal .vmo-modal-overlay { position:absolute; inset:0; background:rgba(0,0,0,0.72); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); z-index:1; }
        .vmo-fs-modal .vmo-modal-panel { position:relative; z-index:2; width:min(1100px,92vw); max-height:88vh; overflow:auto; background:linear-gradient(135deg,#0e1d29,#122e3f); border:1px solid rgba(0,255,255,0.15); box-shadow:0 10px 50px -5px #000,0 0 0 1px rgba(0,255,255,0.08); border-radius:18px; padding:30px 34px 26px; animation:vmoModalIn .28s ease; backdrop-filter:none !important; -webkit-backdrop-filter:none !important; filter:none !important; }
        .vmo-fs-modal .modal-header { display:flex; align-items:center; justify-content:space-between; margin:-6px -6px 14px; padding:4px 6px 10px; border-bottom:1px solid rgba(0,255,255,0.08); }
        .vmo-fs-modal .modal-title { margin:0; font-size:1.15rem; letter-spacing:.5px; color:#d1faff; font-weight:600; }
        .vmo-fs-modal .modal-close { background:none; border:none; font-size:1.4rem; color:#7ad8e2; cursor:pointer; line-height:1; padding:2px 6px; }
        .vmo-fs-modal .modal-close:hover { color:#fff; }
        .vmo-modal-visible { animation:vmoFadeIn .3s ease forwards; }
        @keyframes vmoModalIn { from { opacity:0; transform:translateY(18px) scale(.97);} to { opacity:1; transform:translateY(0) scale(1);} }

        /* Make KPI panels occupy more vertical space to reduce blank area */
        #vmo-visitors-panel, #vmo-demo-panel, #vmo-conv-panel, #vmo-comp-panel {
            min-height: clamp(320px, 48vh, 640px);
        }

        /* Demographics cards must be visible (defensive override) */
        #vmo-demo-panel .vmo-cards { display: grid !important; }

        /* Shipping & Fulfillment Styles */
        .carrier-item, .fulfillment-item {
            display: flex; align-items: center; gap: 12px; padding: 8px 12px;
            border-radius: 6px; background: rgba(255,255,255,0.02); border: 1px solid var(--border);
            margin-bottom: 6px;
        }
        .carrier-item input[type="checkbox"], .fulfillment-item input[type="checkbox"] {
            width: 16px; height: 16px; accent-color: var(--cyan);
        }
        .carrier-item label, .fulfillment-item label {
            flex: 1; cursor: pointer; display: flex; flex-direction: column;
        }
        .carrier-item label strong, .fulfillment-item label strong {
            color: var(--cyan-soft); font-size: 12px; margin-bottom: 2px;
        }
        .carrier-item label small, .fulfillment-item label small {
            color: var(--muted); font-size: 10px;
        }
        .vmo-provider-contacts{
            margin-top:4px; font-size:10px; color:var(--muted);
            display:flex; flex-wrap:wrap; gap:10px;
        }
        .vmo-provider-contacts a{ color:var(--cyan-soft); text-decoration:none; }
        .vmo-provider-contacts a:hover{ text-decoration:underline; }
        .shipping-order-item {
            display: flex; align-items: center; justify-content: space-between; padding: 10px;
            border-radius: 6px; background: rgba(255,255,255,0.02); border: 1px solid var(--border);
            margin-bottom: 8px;
        }
        .shipping-order-info {
            display: flex; flex-direction: column; gap: 2px;
        }
        .shipping-order-id {
            font-weight: 600; color: var(--cyan-soft); font-size: 11px;
        }
        .shipping-order-customer {
            color: var(--ink); font-size: 10px;
        }
        .shipping-order-value {
            color: var(--muted); font-size: 9px;
        }
        .shipping-order-actions {
            display: flex; gap: 4px;
        }
        .approve-shipment-btn {
            background: linear-gradient(135deg, rgba(15,225,255,0.18), rgba(124,92,255,0.45));
            color: var(--ink); border: 1px solid rgba(124,92,255,0.35); padding: 4px 10px;
            border-radius: 6px; font-size: 10px; cursor: pointer; transition: all 0.2s;
        }
        .approve-shipment-btn:hover {
            border-color: var(--edge);
            box-shadow: 0 4px 12px rgba(124,92,255,0.22);
        }
        
        /* Global Shipping Configuration Styles */
        .shipping-region-config {
            display: flex; flex-direction: column; gap: 8px; margin-top: 8px;
        }

        /* Custom Shipping Carrier Styles */
        .custom-carrier-section {
            margin-top: 8px;
        }
        .custom-carrier-item {
            display: flex; align-items: center; justify-content: space-between; padding: 10px 12px;
            border-radius: 8px; background: linear-gradient(135deg, rgba(15,225,255,0.05), rgba(0,0,0,0.15));
            border: 1px solid var(--rim-2); margin-bottom: 8px;
            position: relative; overflow: hidden;
        }
        .custom-carrier-item::before {
            content: "🏪"; position: absolute; right: 8px; top: 50%;
            transform: translateY(-50%); font-size: 16px; opacity: 0.3;
        }
        .custom-carrier-info {
            flex: 1; display: flex; flex-direction: column; gap: 2px;
        }
        .custom-carrier-name {
            color: var(--cyan-soft); font-weight: 600; font-size: 13px;
        }
        .custom-carrier-details {
            color: var(--muted); font-size: 10px;
        }
        .custom-carrier-type {
            color: var(--violet); font-size: 9px; text-transform: uppercase;
            background: rgba(124,92,255,0.1); padding: 1px 4px; border-radius: 3px;
            margin-top: 2px; width: fit-content;
        }
        .custom-carrier-controls {
            display: flex; gap: 6px; align-items: center;
        }
        .custom-carrier-status {
            width: 8px; height: 8px; border-radius: 50%;
            background: rgba(255,255,255,0.22); /* Default idle */
        }
        .custom-carrier-status.online {
            background: #28a745;
        }
        .custom-carrier-status.testing {
            background: #ffc107;
            animation: pulse 1s infinite;
        }
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        .custom-carrier-placeholder {
            text-align: center; padding: 20px; color: var(--muted);
            border: 2px dashed var(--border); border-radius: 8px;
        }
        
        /* Custom Carrier Modal Styles */
        .custom-carrier-modal {
            position: fixed; top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(0,0,0,0.7); z-index: 10000;
            display: flex; align-items: center; justify-content: center;
        }
        .custom-carrier-modal-content {
            background: var(--chrome); border-radius: var(--panel-radius);
            border: 2px solid var(--rim); padding: 20px; width: 500px;
            max-height: 80vh; overflow-y: auto;
        }
        .modal-section {
            margin-bottom: 16px;
        }
        .modal-section label {
            display: block; margin-bottom: 4px; font-size: 12px; 
            color: var(--cyan-soft); font-weight: 500;
        }
        .modal-section input, .modal-section select, .modal-section textarea {
            width: 100%; padding: 8px; border-radius: 4px;
            border: 1px solid var(--border); background: var(--chrome-lo);
            color: var(--ink); font-size: 12px;
        }
        .modal-section input:focus, .modal-section select:focus, .modal-section textarea:focus {
            outline: none; border-color: var(--cyan);
        }
        .modal-buttons {
            display: flex; gap: 8px; justify-content: flex-end; margin-top: 20px;
        }
        .api-test-result {
            padding: 8px; margin-top: 8px; border-radius: 4px; font-size: 11px;
        }
        .api-test-result.success {
            background: rgba(15,225,255,0.12); color: var(--cyan-soft); border: 1px solid rgba(15,225,255,0.35);
        }
        .api-test-result.error {
            background: rgba(124,92,255,0.12); color: var(--violet); border: 1px solid rgba(124,92,255,0.3);
        }
        .region-carrier-item {
            display: flex; align-items: center; justify-content: space-between; padding: 6px 10px;
            border-radius: 4px; background: rgba(255,255,255,0.02); border: 1px solid var(--border);
        }
        .region-carrier-item input[type="checkbox"] {
            width: 14px; height: 14px; accent-color: var(--cyan); margin-right: 8px;
        }
        .region-carrier-item label {
            flex: 1; cursor: pointer; font-size: 11px; color: var(--ink);
        }
        .region-carrier-item label strong {
            color: var(--cyan-soft);
        }
        .carrier-coverage {
            font-size: 9px; color: var(--cyan-soft); background: rgba(15,225,255,0.08);
            padding: 2px 6px; border-radius: 3px; border: 1px solid rgba(15,225,255,0.18);
        }
        .trade-settings {
            display: flex; flex-direction: column; gap: 10px; margin-top: 8px;
        }
        .setting-item {
            display: flex; flex-direction: column; gap: 3px;
        }
        .setting-item label {
            display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 11px;
        }
        .setting-item input[type="checkbox"] {
            width: 14px; height: 14px; accent-color: var(--cyan);
        }
        .setting-item small {
            color: var(--muted); font-size: 9px; margin-left: 22px;
        }

        /* Responsive */
        @media (max-width: 768px) {
            .vmo-main { grid-template-columns:1fr; }
            .vmo-header { flex-direction:column; gap:8px; }
            .vmo-pills, .vmo-metrics { flex-wrap:wrap; }
        }
    </style>
    <?php // Ensure WP admin styles don't override our HUD too much ?>
    <script src="<?php echo esc_url(VMO_AI_BUILDER_URL . 'assets/vendor/twilio-voice-sdk.min.js'); ?>"></script>
</head>
<body>
    <div class="vmo-hud">
        <div class="vmo-app">
            <!-- Header -->
            <header class="vmo-header">
                <div class="vmo-brand">
                    <img class="logo" src="<?php echo esc_url($vmo_logo_url); ?>" alt="VMO Logo" />
                    <h1>VMO Strategic Dashboard</h1>
                </div>
                <div class="vmo-metrics">
                    <div class="vmo-metric">
                        <svg class="progress-ring" viewBox="0 0 32 32">
                            <circle cx="16" cy="16" r="14" stroke-dasharray="88" stroke-dashoffset="22"></circle>
                            <circle cx="16" cy="16" r="14" stroke-dasharray="88" stroke-dashoffset="22" class="progress"></circle>
                        </svg>
                        <div class="vmo-metric-value" id="vmo-metric-goals">—%</div>
                        <div class="vmo-metric-label">Goals Complete</div>
                    </div>
                    <div class="vmo-metric">
                        <svg class="progress-ring" viewBox="0 0 32 32">
                            <circle cx="16" cy="16" r="14" stroke-dasharray="88" stroke-dashoffset="44"></circle>
                            <circle cx="16" cy="16" r="14" stroke-dasharray="88" stroke-dashoffset="44" class="progress"></circle>
                        </svg>
                        <div class="vmo-metric-value" id="vmo-metric-alerts">0</div>
                        <div class="vmo-metric-label">Growth Alerts</div>
                    </div>
                </div>
                <div class="vmo-pills">
                    <div class="vmo-pill active" data-view="dashboard">📊 Dashboard</div>
                    <div class="vmo-pill" data-view="tools">🔧 Tools</div>
                    <div class="vmo-tokens">
                        <div class="token-usage-meter">
                            <div class="meter-fill" style="width: <?php echo min(100, round($usage_data['usage_percent'])); ?>%;"></div>
                        </div>
                        <div class="token-balance"><?php echo round($usage_data['usage_percent']); ?>% used • <?php echo esc_attr( $usage_data['days_remaining'] ); ?> days remaining</div>
                        <div class="token-details"><?php echo esc_html($usage_data['plan_name']); ?></div>
                        <div class="auto-topup">
                            <div class="toggle-switch active">
                                <div class="toggle-slider"></div>
                            </div>
                            <span>Auto add-on at $2.50</span>
                        </div>
                    </div>
                    
                </div>
            </header>

            <!-- Main Content -->
            <main class="vmo-main">

                <!-- ═══ JARVIS DAILY BRIEFING ═══ -->
                <div id="vmo-daily-briefing" style="grid-column:1/-1; display:none; padding:14px 18px; margin-bottom:12px; background:linear-gradient(135deg, rgba(15,225,255,.06), rgba(59,130,246,.04)); border:1px solid rgba(15,225,255,.15); border-radius:10px;">
                    <div style="display:flex; justify-content:space-between; align-items:flex-start;">
                        <div>
                            <h3 style="margin:0 0 6px; font-size:15px; color:var(--cyan-soft);" id="vmo-briefing-greeting">Good morning!</h3>
                            <div id="vmo-briefing-body" style="font-size:13px; line-height:1.6; color:var(--ink);"></div>
                        </div>
                        <button onclick="document.getElementById('vmo-daily-briefing').style.display='none'" style="background:none; border:none; color:var(--muted); cursor:pointer; font-size:16px; padding:0 4px;" title="Dismiss">✕</button>
                    </div>
                </div>
                <!-- Left: Strategic Dashboard -->
                <aside class="vmo-panel vmo-strategic">
                    <h2 class="vmo-title">🎯 Business Progress</h2>
                    
                    <!-- Progress Summary (wired) -->
                    <div class="progress-summary">
                        <div class="progress-card">
                            <h4>Short-term Goals (0-3mo)</h4>
                            <div class="progress-bar">
                                <div class="progress-fill" id="vmo-st-fill" style="width: 0%"></div>
                            </div>
                            <small style="color: var(--muted);"><span id="vmo-st-count">0/0</span> milestones complete • Today (<span id="vmo-today-date">—</span>): <span id="vmo-local-progress">0%</span></small>
                        </div>
                        <div class="progress-card">
                            <h4>Long-term Vision (12mo+)</h4>
                            <div class="progress-bar">
                                <div class="progress-fill" id="vmo-lt-fill" style="width: 0%"></div>
                            </div>
                            <small style="color: var(--muted);" id="vmo-lt-note">—</small>
                        </div>
                    </div>

                    <!-- Today Tab — Tasks / Actions / Done -->
                    <div class="vmo-roadmap">
                        <div style="display:flex; gap:4px; margin-bottom:8px; border-bottom:1px solid var(--border); padding-bottom:8px; flex-wrap:wrap; align-items:center;">
                            <button class="vmo-today-subtab active" type="button" onclick="vmoSwitchTodaySubtab('tasks', this)">📋 Tasks <span id="vmo-tasks-badge" style="background:rgba(15,225,255,.2);border-radius:8px;padding:0 5px;font-size:10px;margin-left:2px;"></span></button>
                            <button class="vmo-today-subtab" type="button" onclick="vmoSwitchTodaySubtab('actions', this)">⚡ Actions <span id="vmo-actions-badge" style="background:rgba(251,191,36,.2);border-radius:8px;padding:0 5px;font-size:10px;margin-left:2px;"></span></button>
                            <button class="vmo-today-subtab" type="button" onclick="vmoSwitchTodaySubtab('done', this)">✅ Done <span id="vmo-done-badge" style="background:rgba(34,197,94,.2);border-radius:8px;padding:0 5px;font-size:10px;margin-left:2px;"></span></button>
                            <div style="flex:1;"></div>
                            <select id="vmo-today-filter" onchange="vmoFilterTodayTasks()" style="background:rgba(0,0,0,.3);border:1px solid var(--border);color:var(--ink);border-radius:4px;font-size:10px;padding:2px 6px;">
                                <option value="all">All</option>
                                <option value="urgent">🔴 Urgent</option>
                                <option value="high">🟠 High</option>
                                <option value="overdue">⏰ Overdue</option>
                                <option value="sales">Sales</option>
                                <option value="support">Support</option>
                                <option value="content">Content</option>
                                <option value="marketing">Marketing</option>
                            </select>
                        </div>

                        <!-- Carryover alert banner -->
                        <div id="vmo-carryover-banner" style="display:none; background:rgba(251,191,36,.08); border:1px solid rgba(251,191,36,.3); border-radius:6px; padding:8px 12px; margin-bottom:10px; font-size:11px; color:#fbbf24;">
                            ⏰ <strong id="vmo-carryover-count">0</strong> items carried over from previous days
                        </div>

                        <!-- Tasks Sub-tab -->
                        <div id="vmo-today-tasks" class="vmo-today-panel active">
                            <div class="task-list" id="vmo-today-list"></div>
                        </div>

                        <!-- Actions Sub-tab -->
                        <div id="vmo-today-actions" class="vmo-today-panel" style="display:none;">
                            <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:8px;">
                                <small style="color:var(--muted);">Ad hoc actions from calls, emails, SMS, forms</small>
                                <button class="action-btn compact" type="button" onclick="vmoAddManualAction()" title="Add manual action">＋</button>
                            </div>
                            <div id="vmo-today-actions-list" class="task-list">
                                <div style="padding:10px; color:var(--muted); font-size:12px;">No pending actions.</div>
                            </div>
                        </div>

                        <!-- Done Sub-tab -->
                        <div id="vmo-today-done" class="vmo-today-panel" style="display:none;">
                            <div id="vmo-today-done-list" class="task-list">
                                <div style="padding:10px; color:var(--muted); font-size:12px;">No completed items today.</div>
                            </div>
                        </div>

                        <!-- End-of-Day Closure -->
                        <div id="vmo-eod-closure" style="margin-top:14px; padding:12px; background:rgba(15,225,255,.04); border:1px solid rgba(15,225,255,.15); border-radius:8px;">
                            <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:6px;">
                                <strong style="font-size:12px; color:var(--cyan-soft);">📊 End of Day</strong>
                                <button class="action-btn compact" onclick="vmoSubmitDailyReport()" style="font-size:10px;" title="Submit your end-of-day report">Submit Report</button>
                            </div>
                            <div id="vmo-eod-status" style="font-size:11px; color:var(--muted);">
                                Complete your tasks and submit your daily report to track progress.
                            </div>
                            <div style="margin-top:8px;display:none;" id="vmo-eod-form">
                                <textarea id="vmo-eod-notes" placeholder="Notes (wins, blockers, observations)..." rows="2" style="width:100%;background:rgba(0,0,0,.3);border:1px solid var(--border);color:var(--ink);border-radius:4px;padding:6px;font-size:11px;resize:vertical;"></textarea>
                            </div>
                        </div>

                        <h4 style="margin: 16px 0 12px; color: var(--cyan-soft);">🚨 Weekly Strategy Updates</h4>

                        <!-- ═══ Jerreme Recommendation Accordion ═══ -->
                        <div id="vmo-jerreme-recs" style="margin-top:16px;">
                            <div style="display:flex;align-items:center;gap:8px;cursor:pointer;padding:10px 12px;background:rgba(124,92,255,.08);border:1px solid rgba(124,92,255,.25);border-radius:10px;" onclick="vmoToggleJerremeRecs()">
                                <span style="font-size:18px;">💡</span>
                                <strong style="color:#c4b5fd;font-size:13px;flex:1;">Jerreme's Recommendations</strong>
                                <span id="vmo-jerreme-badge" style="background:rgba(124,92,255,.3);color:#c4b5fd;font-size:10px;padding:1px 8px;border-radius:8px;">—</span>
                                <span id="vmo-jerreme-chevron" style="color:var(--muted);transition:transform .2s;">▼</span>
                            </div>
                            <div id="vmo-jerreme-list" style="display:none;padding:12px;border:1px solid rgba(124,92,255,.15);border-top:none;border-radius:0 0 10px 10px;background:rgba(0,0,0,.2);">
                                <div style="color:var(--muted);font-size:12px;padding:8px;">Loading recommendations...</div>
                            </div>
                        </div>
                        <div id="vmo-weekly-alert" style="background: rgba(15,225,255,.1); border: 1px solid var(--cyan); border-radius: 6px; padding: 10px; margin-bottom: 12px;">
                            <strong style="color: var(--cyan-soft);">Market Alert:</strong> <span id="vmo-weekly-headline">—</span>
                            <button id="btn-weekly-briefing" class="action-btn primary" type="button" style="margin-top: 6px; width: 100%;" onclick="openWeeklyActions()">
                                View Actions & Analysis
                            </button>
                        </div>
                    </div>

                    <!-- Quick Actions -->
                    <div class="quick-actions">
                        <button id="btn-weekly-briefing-qa" class="action-btn primary" type="button" onclick="showWeeklyBriefing()">📊 Weekly Briefing</button>
                        <button class="action-btn" type="button" onclick="openAddObjective()">🔄 Update Roadmap</button>
                        <button class="action-btn" type="button" onclick="vmoOpenDateRangeForReport()">⬇️ Download Progress</button>
                        <button class="action-btn" type="button" onclick="openScheduleTask()">⏰ Schedule Task</button>
                        <button class="action-btn" type="button" onclick="vmoExportStaticSite(event)" title="Export your website as a portable plain HTML/CSS/JS package">📦 Export Static Site</button>
                        <button class="action-btn" type="button" onclick="vmoExportNextJS(event)" title="Export your website as a deployable Next.js project">⚡ Export Next.js</button>
                    </div>
                </aside>

                <!-- Right: Navigation & Canvas -->
                <section class="vmo-panel vmo-workspace">
                    <nav class="vmo-tabs">
                        <button class="vmo-tab active" type="button" onclick="switchTab('overview', event)">🏠 Overview</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('strategic', event)">🧠 Strategic</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('reports', event)">📈 Reports</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('phone', event)">📞 Phone System</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('crm', event)">👥 CRM</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('seo', event)">🔍 SEO</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('email', event)">✉️ Emails</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('promotion', event)">📣 Promotion</button>
                        <!-- SHIPPING TAB - UPDATED Sept 25, 2025 -->
                        <button class="vmo-tab" type="button" onclick="switchTab('shipping', event)" style="background: linear-gradient(135deg, rgba(15,225,255,0.1), rgba(0,0,0,0.5)); border: 1px solid rgba(15,225,255,0.3);">🚚 Shipping</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('documents', event)">📄 Documents</button>
                        <button class="vmo-tab" type="button" onclick="switchTab('payments', event)">📊 CFO Dashboard</button>
                    </nav>

                    <div class="vmo-canvas">
                        <div class="vmo-scan"></div>
                        
                        <!-- Overview Section -->
                        <div id="overview" class="vmo-section active">
                            <?php
                            // Tester plan: Show missed background operations banner
                            $tester_plan_active = in_array(strtolower($plan), ['tester', 'tester_pack'], true);
                            $missed_ops = get_user_meta(get_current_user_id(), 'vmo_upgrade_prompts', true) ?: [];
                            if ($tester_plan_active && !empty($missed_ops)) : ?>
                            <!-- Tester Plan — Missed Background Operations -->
                            <div id="vmo-missed-ops-banner" class="vmo-card" style="grid-column:1/-1; margin-bottom:18px; background:linear-gradient(135deg, rgba(245,158,11,0.06), rgba(139,92,246,0.06)); border:1px solid rgba(245,158,11,0.25); border-left:4px solid #f59e0b; border-radius:12px; padding:18px 20px;">
                                <div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:12px;">
                                    <div style="display:flex; align-items:center; gap:10px;">
                                        <span style="font-size:22px;">⏸️</span>
                                        <div>
                                            <h4 style="margin:0; font-size:15px; color:#f59e0b; font-weight:700;">Background Operations Paused</h4>
                                            <p style="margin:3px 0 0 0; font-size:12px; color:var(--muted);">Your Tester Plan gives you full setup quality — upgrade to unlock automated operations</p>
                                        </div>
                                    </div>
                                    <button onclick="vmoDismissAllMissedOps()" style="background:none; border:none; color:rgba(255,255,255,0.3); cursor:pointer; font-size:16px; padding:4px;" title="Dismiss all">&times;</button>
                                </div>
                                <div id="vmo-missed-ops-list" style="display:flex; flex-direction:column; gap:8px; max-height:240px; overflow-y:auto;">
                                    <?php foreach ($missed_ops as $idx => $prompt) : ?>
                                    <div class="vmo-missed-op-item" data-index="<?php echo (int)$idx; ?>" style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.06); border-radius:8px; transition:opacity 0.3s;">
                                        <div style="flex:1; min-width:0;">
                                            <div style="display:flex; align-items:center; gap:8px; margin-bottom:3px;">
                                                <span style="font-size:11px; padding:2px 8px; background:rgba(245,158,11,0.12); color:#f59e0b; border-radius:4px; font-weight:600; white-space:nowrap;">Paused</span>
                                                <strong style="font-size:13px; color:#fff; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;"><?php echo esc_html($prompt['operation_name'] ?? ucwords(str_replace('_', ' ', $prompt['operation'] ?? 'Unknown'))); ?></strong>
                                            </div>
                                            <p style="margin:0; font-size:11.5px; color:var(--muted); line-height:1.4;"><?php echo esc_html($prompt['message'] ?? ''); ?></p>
                                            <?php if (!empty($prompt['timestamp'])) : ?>
                                            <span style="font-size:10px; color:rgba(255,255,255,0.2); margin-top:2px; display:inline-block;">Since <?php echo esc_html(date('M j, g:ia', strtotime($prompt['timestamp']))); ?></span>
                                            <?php endif; ?>
                                        </div>
                                        <button onclick="vmoDismissMissedOp(<?php echo (int)$idx; ?>, this)" style="background:none; border:none; color:rgba(255,255,255,0.2); cursor:pointer; font-size:14px; padding:6px; flex-shrink:0;" title="Dismiss">&times;</button>
                                    </div>
                                    <?php endforeach; ?>
                                </div>
                                <div style="margin-top:14px; display:flex; gap:10px; justify-content:flex-end;">
                                    <a href="<?php echo esc_url('https://jerremejosephson.com/vmo-upgrade/' . (!empty(get_option('vmo_installation_id', '')) ? '?installation=' . urlencode(get_option('vmo_installation_id', '')) : '')); ?>" style="display:inline-flex; align-items:center; gap:6px; padding:8px 18px; background:linear-gradient(135deg, rgba(139,92,246,0.2), rgba(59,130,246,0.2)); border:1px solid rgba(139,92,246,0.4); color:#a78bfa; border-radius:8px; text-decoration:none; font-size:13px; font-weight:600; transition:all 0.2s;" onmouseover="this.style.background='linear-gradient(135deg,#8b5cf6,#3b82f6)';this.style.color='#fff';" onmouseout="this.style.background='linear-gradient(135deg, rgba(139,92,246,0.2), rgba(59,130,246,0.2))';this.style.color='#a78bfa';">🚀 Upgrade Plan</a>
                                </div>
                            </div>
                            <?php endif; ?>

                            <div class="nav-section">
                                <h4>� Website Analytics</h4>
                                <div class="nav-links">
                                    <div class="nav-link" onclick="togglePanel('vmo-visitors-panel', loadVisitorsPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">Website Visitors</div>
                                        <div class="nav-badge" id="vmo-visitors-total">—</div>
                                    </div>
                                    <div id="vmo-visitors-panel" class="vmo-card" style="display:none;">
                                        <div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:8px;">
                                            <label>From <input class="vmo-date" id="vmo-visitors-from" type="date" /></label>
                                            <label>To <input class="vmo-date" id="vmo-visitors-to" type="date" /></label>
                                            <button class="action-btn" onclick="loadVisitorsPanel()">Apply</button>
                                        </div>
                                        <div class="vmo-kv"><span>Today's visitors</span><strong id="vmo-visitors-today">—</strong></div>
                                        <div class="vmo-kv"><span>Total visitors</span><strong id="vmo-visitors-count">—</strong></div>
                                        <div style="margin-top:8px;">
                                            <svg id="vmo-visitors-spark" viewBox="0 0 100 24" preserveAspectRatio="none" style="width:100%; height:28px; background:rgba(255,255,255,.04); border-radius:6px;"></svg>
                                        </div>
                                    </div>

                                    <div class="nav-link" onclick="togglePanel('vmo-demo-panel', loadDemographicsPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">Visitor Demographics</div>
                                    </div>
                                    <div id="vmo-demo-panel" class="vmo-card" style="display:none;">
                                        <div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:8px;">
                                            <label>From <input class="vmo-date" id="vmo-demo-from" type="date" /></label>
                                            <label>To <input class="vmo-date" id="vmo-demo-to" type="date" /></label>
                                            <button class="action-btn" onclick="loadDemographicsPanel()">Apply</button>
                                        </div>
                                        <div class="vmo-cards" style="display:grid; grid-template-columns:repeat(auto-fit, minmax(220px,1fr));">
                                            <div class="vmo-card">
                                                <h4>Visits Summary</h4>
                                                <div class="vmo-kv"><span>Total visits</span><strong id="vmo-demo-total-visits">0</strong></div>
                                                <div class="vmo-kv"><span>Unique visitors</span><strong id="vmo-demo-unique-visitors">0</strong></div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Gender</h4>
                                                <div class="vmo-kv"><span>Male</span><strong id="vmo-gender-male">0</strong></div>
                                                <div class="vmo-kv"><span>Female</span><strong id="vmo-gender-female">0</strong></div>
                                                <div class="vmo-kv"><span>Other</span><strong id="vmo-gender-other">0</strong></div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Age Ranges</h4>
                                                <div class="vmo-kv"><span>18–24</span><strong id="vmo-age-18_24">0</strong></div>
                                                <div class="vmo-kv"><span>25–34</span><strong id="vmo-age-25_34">0</strong></div>
                                                <div class="vmo-kv"><span>35–44</span><strong id="vmo-age-35_44">0</strong></div>
                                                <div class="vmo-kv"><span>45–54</span><strong id="vmo-age-45_54">0</strong></div>
                                                <div class="vmo-kv"><span>55+</span><strong id="vmo-age-55_plus">0</strong></div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Devices</h4>
                                                <div class="vmo-kv"><span>Mobile</span><strong id="vmo-dev-mobile">0</strong></div>
                                                <div class="vmo-kv"><span>Desktop</span><strong id="vmo-dev-desktop">0</strong></div>
                                                <div class="vmo-kv"><span>Tablet</span><strong id="vmo-dev-tablet">0</strong></div>
                                                <div class="vmo-kv"><span>Other</span><strong id="vmo-dev-other">0</strong></div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Operating Systems</h4>
                                                <div class="vmo-kv"><span>iOS</span><strong id="vmo-os-ios">0</strong></div>
                                                <div class="vmo-kv"><span>Android</span><strong id="vmo-os-android">0</strong></div>
                                                <div class="vmo-kv"><span>Windows</span><strong id="vmo-os-windows">0</strong></div>
                                                <div class="vmo-kv"><span>macOS</span><strong id="vmo-os-macos">0</strong></div>
                                                <div class="vmo-kv"><span>Linux</span><strong id="vmo-os-linux">0</strong></div>
                                                <div class="vmo-kv"><span>Other</span><strong id="vmo-os-other">0</strong></div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Referrers</h4>
                                                <div id="vmo-referrers-list" style="font-size:12px; color:var(--muted)">—</div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Recent Activities</h4>
                                                <div id="vmo-activities-list" style="font-size:12px; color:var(--muted)">—</div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Top Countries</h4>
                                                <div id="vmo-top-countries" style="font-size:12px; color:var(--muted)">—</div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Top States</h4>
                                                <div id="vmo-top-states" style="font-size:12px; color:var(--muted)">—</div>
                                            </div>
                                            <div class="vmo-card">
                                                <h4>Top Pages Visited</h4>
                                                <div id="vmo-top-pages" style="font-size:12px; color:var(--muted)">—</div>
                                            </div>
                                        </div>
                                        <div class="vmo-card" style="margin-top:10px;">
                                            <h4>Visitors (Top 20)</h4>
                                            <div style="overflow:auto; max-height:220px;">
                                                <table style="width:100%; border-collapse:collapse; min-width:520px;">
                                                    <thead>
                                                        <tr style="text-align:left; border-bottom:1px solid rgba(255,255,255,.1)">
                                                            <th style="padding:6px 8px;">Contact</th>
                                                            <th style="padding:6px 8px;">Email</th>
                                                            <th style="padding:6px 8px;">Visits</th>
                                                            <th style="padding:6px 8px;">Last Visit</th>
                                                            <th style="padding:6px 8px;">Source</th>
                                                        </tr>
                                                    </thead>
                                                    <tbody id="vmo-visitors-rows">
                                                        <tr><td colspan="5" style="padding:8px; color:var(--muted)">No visitors</td></tr>
                                                    </tbody>
                                                </table>
                                            </div>
                                        </div>
                                    </div>

                                    <div class="nav-link" onclick="togglePanel('vmo-conv-panel', loadConversionPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">Conversion</div>
                                    </div>
                                    <div id="vmo-conv-panel" class="vmo-card" style="display:none;">
                                        <div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:8px;">
                                            <label>From <input class="vmo-date" id="vmo-conv-from" type="date" /></label>
                                            <label>To <input class="vmo-date" id="vmo-conv-to" type="date" /></label>
                                            <button class="action-btn" onclick="loadConversionPanel()">Apply</button>
                                        </div>
                                        <div class="vmo-kv"><span>Visitors</span><strong id="vmo-conv-visitors">—</strong></div>
                                        <div class="vmo-kv"><span>Orders</span><strong id="vmo-conv-orders">—</strong></div>
                                        <div class="vmo-kv"><span>Conversion Rate</span><strong id="vmo-conv-rate">—</strong></div>
                                        <div style="margin-top:8px;">
                                            <svg id="vmo-conv-spark" viewBox="0 0 100 24" preserveAspectRatio="none" style="width:100%; height:28px; background:rgba(255,255,255,.04); border-radius:6px;"></svg>
                                        </div>
                                    </div>

                                    <div class="nav-link" onclick="if(!vmoGateCheck('competitive_intel'))return;togglePanel('vmo-comp-panel', loadCompetitorPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">Competitor Analysis</div>
                                    </div>
                                    <div id="vmo-comp-panel" class="vmo-card" style="display:none;">
                                        <div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:8px;">
                                            <label>From <input class="vmo-date" id="vmo-comp-from" type="date" /></label>
                                            <label>To <input class="vmo-date" id="vmo-comp-to" type="date" /></label>
                                            <button class="action-btn" onclick="loadCompetitorPanel()">Apply</button>
                                        </div>
                                        <div class="vmo-kv"><span>Your Market Share</span><strong id="vmo-share-user">—</strong></div>
                                        <div class="vmo-kv"><span>Leader's Share</span><strong id="vmo-share-leader">—</strong></div>
                                        <div class="vmo-kv"><span>Your Rank</span><strong id="vmo-share-rank">—</strong></div>
                                        <div class="vmo-kv"><span>Monitored Competitors</span><strong id="vmo-share-monitored">—</strong></div>
                                        <div style="margin-top:8px;">
                                            <svg id="vmo-share-spark" viewBox="0 0 100 24" preserveAspectRatio="none" style="width:100%; height:28px; background:rgba(255,255,255,.04); border-radius:6px;"></svg>
                                        </div>
                                        <div id="vmo-share-list" style="font-size:12px; color:var(--muted); margin-top:8px;">—</div>
                                    </div>
                                </div>
                            </div>

                            <div class="nav-section">
                                <h4>📈 Business Intelligence</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card">
                                        <h4>Market Position</h4>
                                        <div class="vmo-kv">
                                            <span>Ranking</span>
                                            <strong id="vmo-bi-ranking" style="color: var(--cyan-soft);">—</strong>
                                        </div>
                                        <div class="vmo-kv">
                                            <span>Growth</span>
                                            <strong id="vmo-bi-growth" style="color: #4CAF50;">—</strong>
                                        </div>
                                        <div class="vmo-kv">
                                            <span>Next milestone</span>
                                            <strong id="vmo-bi-next">—</strong>
                                        </div>
                                    </div>
                                    <div class="vmo-card">
                                        <h4>Competitive Analysis</h4>
                                        <div class="vmo-kv">
                                            <span>Monitored competitors</span>
                                            <strong id="vmo-bi-monitored" style="color: var(--cyan-soft);">—</strong>
                                        </div>
                                        <div class="vmo-kv">
                                            <span>New threats</span>
                                            <strong id="vmo-bi-threats" style="color: orange;">—</strong>
                                        </div>
                                        <div class="vmo-kv">
                                            <span>Opportunities</span>
                                            <strong id="vmo-bi-opps" style="color: #4CAF50;">—</strong>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- ═════════════════════════════════════════════════
                             STRATEGIC DASHBOARD TAB
                             ═════════════════════════════════════════════════ -->
                        <div id="strategic" class="vmo-section">
                            <!-- Business Vision Progress -->
                            <div class="nav-section">
                                <h4>🎯 Business Vision Progress</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card" style="grid-column:1/-1;">
                                        <div style="display:flex; align-items:center; gap:20px; margin-bottom:12px;">
                                            <div style="position:relative; width:80px; height:80px;">
                                                <svg viewBox="0 0 100 100" style="width:80px; height:80px;">
                                                    <circle cx="50" cy="50" r="42" fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="8"/>
                                                    <circle id="vmo-strat-progress-ring" cx="50" cy="50" r="42" fill="none" stroke="var(--cyan)" stroke-width="8" stroke-linecap="round" stroke-dasharray="264" stroke-dashoffset="264" transform="rotate(-90 50 50)" style="transition:stroke-dashoffset 0.6s ease"/>
                                                    <text x="50" y="55" text-anchor="middle" fill="#fff" font-size="18" font-weight="bold" id="vmo-strat-progress-pct">0%</text>
                                                </svg>
                                            </div>
                                            <div style="flex:1;">
                                                <div id="vmo-strat-progress-interpretation" style="color:var(--ink); font-size:13px; line-height:1.5;">Loading strategic position...</div>
                                                <div style="display:flex; gap:16px; margin-top:8px;">
                                                    <div class="vmo-kv" style="flex:1;"><span>Milestones</span><strong id="vmo-strat-milestones">0/0</strong></div>
                                                    <div class="vmo-kv" style="flex:1;"><span>Est. Remaining</span><strong id="vmo-strat-remaining">—</strong></div>
                                                    <div class="vmo-kv" style="flex:1;"><span>Pace</span><strong id="vmo-strat-pace" style="color:#4CAF50;">—</strong></div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- Current Strategic Position -->
                            <div class="nav-section">
                                <h4>📊 Current Strategic Position</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card"><h4>Market Fit</h4><div class="vmo-kv"><span>Signal Strength</span><strong id="vmo-strat-market-fit">—</strong></div></div>
                                    <div class="vmo-card"><h4>Traction</h4><div class="vmo-kv"><span>Lead Velocity</span><strong id="vmo-strat-traction">—</strong></div></div>
                                    <div class="vmo-card"><h4>Visibility</h4><div class="vmo-kv"><span>SEO + Traffic</span><strong id="vmo-strat-visibility">—</strong></div></div>
                                    <div class="vmo-card"><h4>Conversion</h4><div class="vmo-kv"><span>Strength</span><strong id="vmo-strat-conversion">—</strong></div></div>
                                    <div class="vmo-card"><h4>Competitiveness</h4><div class="vmo-kv"><span>Rank vs Field</span><strong id="vmo-strat-competitive">—</strong></div></div>
                                </div>
                            </div>

                            <!-- Opportunities -->
                            <div class="nav-section">
                                <h4>🟢 Opportunities</h4>
                                <div id="vmo-strat-opportunities" class="vmo-cards">
                                    <div class="vmo-card"><p style="color:var(--muted);">Scanning for opportunities...</p></div>
                                </div>
                            </div>

                            <!-- Risks & Blockers -->
                            <div class="nav-section">
                                <h4>🔴 Risks & Blockers</h4>
                                <div id="vmo-strat-risks" class="vmo-cards">
                                    <div class="vmo-card"><p style="color:var(--muted);">Analyzing risks...</p></div>
                                </div>
                            </div>

                            <!-- Competitor & Market Movement -->
                            <div class="nav-section">
                                <h4>🔍 Competitor & Market Movement</h4>
                                <div id="vmo-strat-competitor-movement" class="vmo-cards">
                                    <div class="vmo-card"><p style="color:var(--muted);">Monitoring competitors...</p></div>
                                </div>
                            </div>

                            <!-- Executive KPIs -->
                            <div class="nav-section">
                                <h4>📈 Key Performance Indicators</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card"><h4>Leads</h4><div class="vmo-kv"><span>Created</span><strong id="vmo-strat-kpi-leads">0</strong></div><div class="vmo-kv"><span>Converted</span><strong id="vmo-strat-kpi-converted">0</strong></div></div>
                                    <div class="vmo-card"><h4>Revenue</h4><div class="vmo-kv"><span>Total</span><strong id="vmo-strat-kpi-revenue">$0</strong></div><div class="vmo-kv"><span>Avg Order</span><strong id="vmo-strat-kpi-aov">—</strong></div></div>
                                    <div class="vmo-card"><h4>Tasks</h4><div class="vmo-kv"><span>Completion Rate</span><strong id="vmo-strat-kpi-tasks">—</strong></div><div class="vmo-kv"><span>Overdue</span><strong id="vmo-strat-kpi-overdue">0</strong></div></div>
                                    <div class="vmo-card"><h4>SEO</h4><div class="vmo-kv"><span>Score</span><strong id="vmo-strat-kpi-seo">—</strong></div><div class="vmo-kv"><span>Keywords</span><strong id="vmo-strat-kpi-keywords">0</strong></div></div>
                                    <div class="vmo-card"><h4>Content</h4><div class="vmo-kv"><span>Pages</span><strong id="vmo-strat-kpi-pages">0</strong></div><div class="vmo-kv"><span>Blog Posts</span><strong id="vmo-strat-kpi-blogs">0</strong></div></div>
                                    <div class="vmo-card"><h4>Retention</h4><div class="vmo-kv"><span>Repeat Customers</span><strong id="vmo-strat-kpi-retention">—</strong></div><div class="vmo-kv"><span>Response Backlog</span><strong id="vmo-strat-kpi-backlog">0</strong></div></div>
                                </div>
                            </div>

                            <!-- Recommended Strategic Actions -->
                            <div class="nav-section">
                                <h4>💡 Recommended Strategic Actions</h4>
                                <div id="vmo-strat-actions" class="vmo-cards">
                                    <div class="vmo-card"><p style="color:var(--muted);">Generating recommendations...</p></div>
                                </div>
                            </div>

                            <!-- Approval Queue -->
                            <div class="nav-section">
                                <h4>⏳ Approval Queue</h4>
                                <div id="vmo-strat-approvals">
                                    <div class="vmo-card"><p style="color:var(--muted);">No items requiring approval.</p></div>
                                </div>
                            </div>

                            <!-- Recent Important Changes -->
                            <div class="nav-section">
                                <h4>🔔 Recent Important Changes</h4>
                                <div id="vmo-strat-recent-changes">
                                    <div class="vmo-card"><p style="color:var(--muted);">No recent changes to report.</p></div>
                                </div>
                            </div>

                            <!-- Forecast -->
                            <div class="nav-section">
                                <h4>🔮 Forecast & Estimated Path Forward</h4>
                                <div class="vmo-card" style="margin-top:8px;">
                                    <div id="vmo-strat-forecast" style="color:var(--ink); font-size:13px; line-height:1.6;">Loading forecast...</div>
                                    <div id="vmo-strat-interpretation"></div>
                                </div>
                            </div>
                        </div>

                        <!-- ═════════════════════════════════════════════════
                             REPORTS TAB
                             ═════════════════════════════════════════════════ -->
                        <div id="reports" class="vmo-section">
                            <div class="nav-section">
                                <h4>📈 Business Reports</h4>

                                <!-- Report Type Tabs -->
                                <div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom:12px;">
                                    <button class="action-btn vmo-report-tab active" data-tab="report-actions" onclick="vmoSwitchGlobalReportTab('report-actions')">📋 Action Items</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-calls" onclick="vmoSwitchGlobalReportTab('report-calls')">📞 Calls</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-email" onclick="vmoSwitchGlobalReportTab('report-email')">✉️ Email</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-sms" onclick="vmoSwitchGlobalReportTab('report-sms')">💬 SMS</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-payments" onclick="vmoSwitchGlobalReportTab('report-payments')">💳 Payments</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-shipping" onclick="vmoSwitchGlobalReportTab('report-shipping')">📦 Shipping</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-crm" onclick="vmoSwitchGlobalReportTab('report-crm')">👥 CRM</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-forms" onclick="vmoSwitchGlobalReportTab('report-forms')">📬 Forms</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-daily" onclick="vmoSwitchGlobalReportTab('report-daily')">📊 Daily</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-strategic" onclick="vmoSwitchGlobalReportTab('report-strategic')">🧠 Strategic</button>
                                    <button class="action-btn vmo-report-tab" data-tab="report-milestones" onclick="vmoSwitchGlobalReportTab('report-milestones')">🏆 Milestones</button>
                                </div>

                                <!-- Action Items -->
                                <div id="vmo-global-report-actions" class="vmo-report-tab-content" style="display:block;">
                                    <div id="vmo-report-action-items-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading action items...</p></div>
                                    </div>
                                </div>

                                <!-- Call Reports -->
                                <div id="vmo-global-report-calls" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-calls-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading call reports...</p></div>
                                    </div>
                                </div>

                                <!-- Email Reports -->
                                <div id="vmo-global-report-email" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-email-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading email reports...</p></div>
                                    </div>
                                </div>

                                <!-- SMS Reports -->
                                <div id="vmo-global-report-sms" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-sms-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading SMS reports...</p></div>
                                    </div>
                                </div>

                                <!-- Daily Reports -->
                                <div id="vmo-global-report-daily" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-daily-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading daily reports...</p></div>
                                    </div>
                                </div>

                                <!-- Strategic Reports -->
                                <div id="vmo-global-report-strategic" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-strategic-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading strategic reports...</p></div>
                                    </div>
                                </div>

                                <!-- Milestone Reports -->
                                <div id="vmo-global-report-milestones" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-milestones-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading milestone reports...</p></div>
                                    </div>
                                </div>

                                <!-- Payment Reports -->
                                <div id="vmo-global-report-payments" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-payments-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading payment reports...</p></div>
                                    </div>
                                </div>

                                <!-- Shipping Reports -->
                                <div id="vmo-global-report-shipping" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-shipping-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading shipping reports...</p></div>
                                    </div>
                                </div>

                                <!-- CRM Reports -->
                                <div id="vmo-global-report-crm" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-crm-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading CRM reports...</p></div>
                                    </div>
                                </div>

                                <!-- Forms Reports -->
                                <div id="vmo-global-report-forms" class="vmo-report-tab-content" style="display:none;">
                                    <div id="vmo-report-forms-list" class="vmo-cards">
                                        <div class="vmo-card"><p style="color:var(--muted);">Loading form submission reports...</p></div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- Phone System Section -->
                        <div id="phone" class="vmo-section">
                            <div class="nav-section">
                                <h4>📞 Phone Management</h4>
                                <div class="nav-links" id="vmo-phone-nav-accordion">
                                    <!-- Full Phone Interface Accordion -->
                                    <div class="nav-link accordion-toggle" onclick="togglePhonePanel(this, 'interface'); return false;">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">📞 Full Phone Interface</div>
                                        <div class="nav-badge">Live</div>
                                    </div>
                                    <div class="nav-panel" id="panel-interface-details" style="display:none; padding:15px; border:1px solid var(--border); border-top:none; border-radius:0 0 10px 10px; background:rgba(0,0,0,0.2);">
                                        <div class="vmo-cards vmo-phone-interface-grid">
                                            <div class="vmo-card vmo-phone-tool-card vmo-phone-number-card">
                                            <h4>Your Business Number</h4>
                                            <div class="vmo-kv">
                                            <span>Assigned number</span>
                                            <strong id="vmo-assigned-number"><?php
                                            global $vmo_twilio_manager;
                                            if (!isset($vmo_twilio_manager) && class_exists('VMO_Twilio_Manager')) {
                                            $vmo_twilio_manager = VMO_Twilio_Manager::get_instance();
                                            }
                                            if (isset($vmo_twilio_manager)) {
                                            $phone_data = $vmo_twilio_manager->get_user_phone(get_current_user_id());
                                            // Handle both Object (legacy) and String (new) returns
                                            if (empty($phone_data)) {
                                            // Final fallback: meta (covers schema drift during upgrades)
                                            $meta_phone = get_user_meta(get_current_user_id(), 'vmo_phone_number', true);
                                            echo $meta_phone ? esc_html($meta_phone) : '—';
                                            if (current_user_can('manage_options')) {
                                            echo ' <!-- ADMIN DEBUG: get_user_phone returned FALSE/EMPTY -->';
                                            }
                                            } elseif (is_object($phone_data)) {
                                            echo esc_html($phone_data->phone_number);
                                            } elseif (is_string($phone_data)) {
                                            echo esc_html($phone_data);
                                            } else {
                                            echo '—';
                                            }
                                            } else {
                                            $meta_phone = get_user_meta(get_current_user_id(), 'vmo_phone_number', true);
                                            echo $meta_phone ? esc_html($meta_phone) : '—';
                                            }
                                            ?></strong>
                                            </div>
                                            <div style="margin-top:10px;">
                                            <button onclick="VMOBusinessDashboard.setupVirtualNumber()" class="action-btn primary" style="width:100%; justify-content:center;">
                                            📞 Set Up / Change Number
                                            </button>
                                            <?php if(isset($phone_data) && $phone_data) : ?>
                                            <?php
                                            // Check SMS activation status
                                            $sms_status = get_user_meta(get_current_user_id(), 'vmo_sms_activated', true);
                                            $sms_is_active = ($sms_status === '1' || $sms_status === 'active');
                                            ?>
                                            <div style="margin-top:8px;">
                                            <button id="vmo-activate-sms-btn" onclick="openSMSActivation()" class="action-btn" style="width:100%; justify-content:center; border:1px solid <?php echo esc_attr( $sms_is_active ? '#10b981' : '#f59e0b' ); ?>; color:<?php echo esc_attr( $sms_is_active ? '#10b981' : '#f59e0b' ); ?>; background:<?php echo esc_attr( $sms_is_active ? 'rgba(16,185,129,0.08)' : 'rgba(245,158,11,0.08)' ); ?>;">
                                            <?php echo esc_html($sms_is_active ? '✅ SMS Active' : '💬 Activate SMS'); ?>
                                            </button>
                                            </div>
                                            <div style="margin-top:8px;">
                                            <button onclick="VMOBusinessDashboard.dropNumber()" class="action-btn danger" style="width:100%; justify-content:center; opacity:0.8;">
                                            🗑 Drop Number
                                            </button>
                                            </div>
                                            <?php endif; ?>
                                            </div>
                                            </div>
                                            <div class="vmo-card vmo-phone-tool-card vmo-phone-notes-card">
                                            <h4>Call Notes</h4>
                                            <label for="vmo-assigned-notes" style="display:block; font-size:12px; color:var(--muted); margin-bottom:6px;">Notes</label>
                                            <textarea id="vmo-assigned-notes" placeholder="Call notes or discussion points..." rows="6"></textarea>
                                            </div>
                                            <div class="vmo-card" id="vmo-sci-fi-dialer" title="Use this control surface for regular phone calls and live Power Dialer calls. You can place outbound calls, listen while AI handles the conversation, take over instantly, hand the call back to AI when available, and manage the live browser audio connection without leaving the phone system.">
                                            <div class="vmo-dialer-shell">
                                            <div class="vmo-dialer-head">
                                            <h4 style="margin:0;" title="Use this control surface for regular phone calls and live Power Dialer calls. You can place outbound calls, listen while AI handles the conversation, take over instantly, hand the call back to AI when available, and manage the live browser audio connection without leaving the phone system.">Live Dialer</h4>
                                            <div class="vmo-dialer-state-tools">
                                            <div id="vmo-dialer-mode">Idle</div>
                                            <button id="vmo-ring-settings-btn" class="action-btn" title="Ring settings">⚙︎</button>
                                            </div>
                                            </div>
                                            <div class="vmo-dialer-input-wrap">
                                            <input id="vmo-dialer-input" type="tel" placeholder="Enter number" />
                                            <button id="vmo-dialer-backspace" class="action-btn" title="Backspace one digit">⌫</button>
                                            </div>
                                            <div class="vmo-dialer-primary-actions">
                                            <button id="vmo-dialer-drop" class="action-btn danger" title="Drop current call">■ Drop</button>
                                            <button id="vmo-dialer-listen" class="action-btn" title="Listen to active call">👂 Listen</button>
                                            <button id="vmo-dialer-action" class="action-btn primary" title="Call / Pick up / Join">📞 Call</button>
                                            </div>
                                            <div class="vmo-dialer-keypad">
                                            <button class="action-btn vmo-dialer-key" data-key="1">1</button>
                                            <button class="action-btn vmo-dialer-key" data-key="2">2</button>
                                            <button class="action-btn vmo-dialer-key" data-key="3">3</button>
                                            <button class="action-btn vmo-dialer-key" data-key="4">4</button>
                                            <button class="action-btn vmo-dialer-key" data-key="5">5</button>
                                            <button class="action-btn vmo-dialer-key" data-key="6">6</button>
                                            <button class="action-btn vmo-dialer-key" data-key="7">7</button>
                                            <button class="action-btn vmo-dialer-key" data-key="8">8</button>
                                            <button class="action-btn vmo-dialer-key" data-key="9">9</button>
                                            <button class="action-btn vmo-dialer-key" data-key="*">*</button>
                                            <button class="action-btn vmo-dialer-key" data-key="0">0</button>
                                            <button class="action-btn vmo-dialer-key" data-key="#">#</button>
                                            </div>
                                            <div class="vmo-dialer-plus-silent">
                                            <button class="action-btn vmo-dialer-key" data-key="+">+</button>
                                            <button id="vmo-ring-toggle" class="action-btn" title="Silence ringing alerts">🔕 Silent</button>
                                            </div>
                                            <div class="vmo-dialer-utilities">
                                            <button id="vmo-dialer-hold" class="action-btn" title="Hand the call back to AI or release your live connection">⏸ Hold</button>
                                            <button id="vmo-dialer-mute" class="action-btn" title="Mute or unmute your microphone while connected">🔇 Mute</button>
                                            <button id="vmo-dialer-contacts" class="action-btn" title="Pick from contacts">👥 Contacts</button>
                                            </div>
                                            <div id="vmo-dialer-status"></div>
                                            </div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- SMS Workspace Accordion -->
                                    <div class="nav-link accordion-toggle" onclick="togglePhonePanel(this, 'sms'); return false;">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">💬 SMS Workspace</div>
                                    </div>
                                    <div class="nav-panel" id="panel-sms-details" style="display:none; padding:15px; border:1px solid var(--border); border-top:none; border-radius:0 0 10px 10px; background:rgba(0,0,0,0.2);">
                                        <div class="vmo-cards">
                                            <div class="vmo-card" id="vmo-sms-workspace" style="grid-column: 1 / -1; display:block;">
                                            <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:12px; flex-wrap:wrap; margin-bottom:14px;">
                                            <div>
                                            <h4 style="margin:0;">SMS Workspace</h4>
                                            <div style="font-size:12px; color:var(--muted); margin-top:4px; max-width:760px; line-height:1.6;">View customer texts, reply from the dashboard, and generate AI-assisted drafts. If you set an external phone number, inbound texts are relayed there and replies back to your business line can be sent to the latest customer automatically.</div>
                                            </div>
                                            <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                            <button class="action-btn" onclick="loadSmsWorkspace(window.__vmoSmsState && window.__vmoSmsState.activeContact ? window.__vmoSmsState.activeContact : '')">🔄 Refresh</button>
                                            <button class="action-btn primary" onclick="vmoStartNewSms()">✉️ New SMS</button>
                                            </div>
                                            </div>
                                            <div id="vmo-sms-summary" style="display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:10px; margin-bottom:12px;"></div>
                                            <div id="vmo-sms-advice" style="margin-bottom:12px;"></div>
                                            <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(320px, 1fr)); gap:12px; align-items:start;">
                                            <div style="border:1px solid var(--border); border-radius:12px; background:rgba(255,255,255,.03); min-height:420px; display:flex; flex-direction:column;">
                                            <div style="padding:12px; border-bottom:1px solid var(--border); display:flex; justify-content:space-between; align-items:center; gap:8px;">
                                            <strong style="font-size:13px;">Conversations</strong>
                                            <span id="vmo-sms-conversation-count" style="font-size:11px; color:var(--muted);">0</span>
                                            </div>
                                            <div id="vmo-sms-conversations" style="overflow:auto; padding:8px; flex:1;"></div>
                                            </div>
                                            <div style="border:1px solid var(--border); border-radius:12px; background:rgba(255,255,255,.03); min-height:420px; display:flex; flex-direction:column;">
                                            <div style="padding:12px; border-bottom:1px solid var(--border); display:grid; gap:8px;">
                                            <div style="display:flex; justify-content:space-between; gap:8px; align-items:center; flex-wrap:wrap;">
                                            <strong id="vmo-sms-thread-title" style="font-size:13px;">Select a conversation</strong>
                                            <span id="vmo-sms-thread-meta" style="font-size:11px; color:var(--muted);"></span>
                                            </div>
                                            <input id="vmo-sms-to" type="tel" placeholder="Customer number" style="width:100%; padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                            </div>
                                            <div id="vmo-sms-thread" style="flex:1; overflow:auto; padding:12px; display:grid; gap:10px;"></div>
                                            <div style="padding:12px; border-top:1px solid var(--border); display:grid; gap:10px;">
                                            <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:8px;">
                                            <label style="display:grid; gap:6px; font-size:12px; color:var(--muted);">
                                            <span>Intent</span>
                                            <select id="vmo-sms-intent" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                            <option value="General customer reply">General customer reply</option>
                                            <option value="Appointment reminder">Appointment reminder</option>
                                            <option value="Customer care follow-up">Customer care follow-up</option>
                                            <option value="Order or delivery update">Order or delivery update</option>
                                            <option value="Lead follow-up">Lead follow-up</option>
                                            <option value="Promotion or offer">Promotion or offer</option>
                                            </select>
                                            </label>
                                            <label style="display:grid; gap:6px; font-size:12px; color:var(--muted);">
                                            <span>AI Notes</span>
                                            <input id="vmo-sms-notes" type="text" placeholder="Optional guidance for the draft" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                            </label>
                                            </div>
                                            <textarea id="vmo-sms-compose" rows="4" placeholder="Write your message here or generate a draft with AI…" style="width:100%; padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); resize:vertical;"></textarea>
                                            <div style="display:flex; gap:8px; justify-content:flex-end; flex-wrap:wrap;">
                                            <button class="action-btn" id="vmo-sms-ai-btn" onclick="vmoGenerateSmsDraft()">✨ AI Draft</button>
                                            <button class="action-btn primary" id="vmo-sms-send-btn" onclick="vmoSendSmsMessage()">Send SMS</button>
                                            </div>
                                            </div>
                                            </div>
                                            </div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- Call History Accordion -->
                                    <div class="nav-link accordion-toggle" onclick="togglePhonePanel(this, 'history'); return false;">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">📞 Call History & Analytics</div>
                                    </div>
                                    <div class="nav-panel" id="panel-history-details" style="display:none; padding:15px; border:1px solid var(--border); border-top:none; border-radius:0 0 10px 10px; background:rgba(0,0,0,0.2);">
                                        <div class="vmo-cards">
                                            <div class="vmo-card" id="vmo-call-history" style="grid-column: 1 / -1; display:block;">
                                            <h4>Call History & Playback</h4>
                                            
                                            <!-- History & Summaries List (Top Priority) -->
                                            <div id="vmo-history-list" class="task-list" style="max-height: 400px; overflow-y: auto; margin-bottom: 20px; border-bottom: 1px solid var(--border); padding-bottom: 10px;"></div>
                                            <div id="vmo-ai-summaries-list" style="margin-top:10px; margin-bottom: 25px;"></div>

                                            <h4>Phone Analytics & Today's Overview</h4>
                                            <div class="vmo-cards" style="margin-bottom:10px;">
                                            <div class="vmo-card" id="vmo-today-summary-card">
                                            <h4>Today's Call Summary</h4>
                                            <div class="vmo-kv">
                                            <span>Total calls</span>
                                            <strong style="color: var(--cyan-soft);">—</strong>
                                            </div>
                                            <div class="vmo-kv">
                                            <span>Avg duration</span>
                                            <strong>—</strong>
                                            </div>
                                            <div class="vmo-kv">
                                            <span>Cost</span>
                                            <strong style="color: orange;">—</strong>
                                            </div>
                                            </div>
                                            <div class="vmo-card" id="vmo-phone-analytics">
                                            <h4>Phone Analytics (30 days)</h4>
                                            <div class="vmo-kv"><span>Total calls</span><strong id="vmo-anl-total">—</strong></div>
                                            <div class="vmo-kv"><span>Answered</span><strong id="vmo-anl-answered">—</strong></div>
                                            <div class="vmo-kv"><span>Missed</span><strong id="vmo-anl-missed">—</strong></div>
                                            <div class="vmo-kv"><span>Avg duration</span><strong id="vmo-anl-avg">—</strong></div>
                                            <div class="vmo-kv"><span>Top intent</span><strong id="vmo-anl-intent">—</strong></div>
                                            <div class="vmo-kv"><span>New vs Return</span><strong><span id="vmo-anl-new">—</span> / <span id="vmo-anl-return">—</span></strong></div>
                                            <div style="margin-top:8px;">
                                            <svg id="vmo-anl-spark" viewBox="0 0 100 24" preserveAspectRatio="none" style="width:100%; height:28px; background:rgba(255,255,255,.04); border-radius:6px;"></svg>
                                            </div>
                                            <div style="display:flex; gap:8px; margin-top:8px;">
                                            <button class="action-btn" id="vmo-anl-refresh">🔄 Refresh</button>
                                            </div>
                                            </div>
                                            </div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- Reports Accordion -->
                                    <div class="nav-link accordion-toggle" onclick="togglePhonePanel(this, 'reports'); return false;">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">📈 Reports & Actions</div>
                                        <div class="nav-badge" style="background:rgba(139,92,246,.15);color:#a78bfa;">New</div>
                                    </div>
                                    <div class="nav-panel" id="panel-reports-details" style="display:none; padding:15px; border:1px solid var(--border); border-top:none; border-radius:0 0 10px 10px; background:rgba(0,0,0,0.2);">
                                        <div class="vmo-cards">
                                            <div class="vmo-card" id="vmo-reports-panel" style="grid-column: 1 / -1; display:block;">
                                            <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:14px;">
                                            <h4 style="margin:0;">📊 Reports & Action Items</h4>

                                            </div>
                                            
                                            <!-- Reports Tab Bar -->
                                            <div style="display:flex; gap:6px; margin-bottom:14px; border-bottom:1px solid rgba(255,255,255,.08); padding-bottom:10px; flex-wrap:wrap;">
                                            <button class="action-btn vmo-report-tab active" data-tab="action-items" onclick="vmoSwitchReportTab('action-items')">📋 Action Items</button>
                                            <button class="action-btn vmo-report-tab" data-tab="call-reports" onclick="vmoSwitchReportTab('call-reports')">📞 Call Reports</button>
                                            <button class="action-btn vmo-report-tab" data-tab="daily-reports" onclick="vmoSwitchReportTab('daily-reports')">📅 Daily Reports</button>
                                            <button class="action-btn vmo-report-tab" data-tab="periodic-reports" onclick="vmoSwitchReportTab('periodic-reports')">📈 Weekly/Monthly</button>
                                            <button class="action-btn vmo-report-tab" data-tab="custom-report" onclick="vmoSwitchReportTab('custom-report')">🔍 Custom Range</button>
                                            <button class="action-btn vmo-report-tab" data-tab="fulfillment-log" onclick="vmoSwitchReportTab('fulfillment-log')">📤 Fulfillment Log</button>
                                            </div>
                                            
                                            <!-- Action Items Tab -->
                                            <div id="vmo-tab-action-items" class="vmo-report-tab-content">
                                            <div style="display:flex; gap:8px; margin-bottom:10px; flex-wrap:wrap;">
                                            <select id="vmo-action-filter" onchange="vmoLoadActionItems()" style="padding:6px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:12px;">
                                            <option value="">All Status</option>
                                            <option value="overdue">Overdue</option>
                                            <option value="pending">Pending</option>
                                            <option value="in_progress">In Progress</option>
                                            <option value="completed">Completed</option>
                                            </select>
                                            <button class="action-btn" onclick="vmoLoadActionItems()">🔄 Refresh</button>
                                            </div>
                                            <div id="vmo-action-items-list" class="task-list" style="max-height:500px; overflow-y:auto;">
                                            <div style="text-align:center;color:var(--muted);padding:20px;">Loading action items...</div>
                                            </div>
                                            </div>
                                            
                                            <!-- Call Reports Tab -->
                                            <div id="vmo-tab-call-reports" class="vmo-report-tab-content" style="display:block;">
                                            <div style="display:flex; gap:8px; margin-bottom:10px; flex-wrap:wrap;">
                                            <select id="vmo-report-category-filter" onchange="vmoLoadCallReports()" style="padding:6px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:12px;">
                                            <option value="">All Categories</option>
                                            <option value="lead">Leads</option>
                                            <option value="customer">Customers</option>
                                            <option value="support">Support</option>
                                            <option value="inquiry">Inquiry</option>
                                            </select>
                                            <input type="date" id="vmo-report-date-from" style="padding:6px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:12px;" />
                                            <input type="date" id="vmo-report-date-to" style="padding:6px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:12px;" />
                                            <button class="action-btn" onclick="vmoLoadCallReports()">🔍 Filter</button>
                                            </div>
                                            <div id="vmo-call-reports-list" style="max-height:500px; overflow-y:auto;">
                                            <div style="text-align:center;color:var(--muted);padding:20px;">Loading call reports...</div>
                                            </div>
                                            </div>
                                            
                                            <!-- Daily Reports Tab -->
                                            <div id="vmo-tab-daily-reports" class="vmo-report-tab-content" style="display:block;">
                                            <div id="vmo-daily-reports-list" style="max-height:500px; overflow-y:auto;">
                                            <div style="text-align:center;color:var(--muted);padding:20px;">Loading daily reports...</div>
                                            </div>
                                            </div>
                                            
                                            <!-- Periodic Reports Tab -->
                                            <div id="vmo-tab-periodic-reports" class="vmo-report-tab-content" style="display:block;">
                                            <div style="display:flex; gap:8px; margin-bottom:10px;">
                                            <select id="vmo-periodic-filter" onchange="vmoLoadPeriodicReports()" style="padding:6px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:12px;">
                                            <option value="">All Periods</option>
                                            <option value="weekly">Weekly</option>
                                            <option value="monthly">Monthly</option>
                                            <option value="quarterly">Quarterly</option>
                                            <option value="yearly">Yearly</option>
                                            </select>
                                            <button class="action-btn" onclick="vmoLoadPeriodicReports()">🔄 Refresh</button>
                                            </div>
                                            <div id="vmo-periodic-reports-list" style="max-height:500px; overflow-y:auto;">
                                            <div style="text-align:center;color:var(--muted);padding:20px;">Loading periodic reports...</div>
                                            </div>
                                            </div>
                                            
                                            <!-- Custom Range Report Tab -->
                                            <div id="vmo-tab-custom-report" class="vmo-report-tab-content" style="display:block;">
                                            <div style="display:flex; gap:8px; margin-bottom:14px; align-items:end; flex-wrap:wrap;">
                                            <div>
                                            <label style="font-size:11px; color:var(--muted);">From</label>
                                            <input type="date" id="vmo-custom-date-from" style="display:block; padding:8px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:13px;" />
                                            </div>
                                            <div>
                                            <label style="font-size:11px; color:var(--muted);">To</label>
                                            <input type="date" id="vmo-custom-date-to" style="display:block; padding:8px 10px; border-radius:6px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:13px;" />
                                            </div>
                                            <button class="action-btn primary" onclick="vmoGenerateCustomReport()" id="vmo-custom-report-btn">📊 Generate Report</button>
                                            </div>
                                            <div id="vmo-custom-report-result" style="max-height:500px; overflow-y:auto;">
                                            <div style="text-align:center;color:var(--muted);padding:30px;">Select a date range and click Generate Report to create a custom activity report with executive summary.</div>
                                            </div>
                                            </div>
                                            
                                            <!-- Fulfillment Log Tab -->
                                            <div id="vmo-tab-fulfillment-log" class="vmo-report-tab-content" style="display:block;">
                                            <div id="vmo-fulfillment-log-list" style="max-height:500px; overflow-y:auto;">
                                            <div style="text-align:center;color:var(--muted);padding:20px;">Loading fulfillment log...</div>
                                            </div>
                                            </div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- Buy Minutes Accordion -->
                                    <div class="nav-link accordion-toggle" onclick="togglePhonePanel(this, 'upgrade'); return false;">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">💳 Buy Phone Minutes</div>
                                    </div>
                                    <div class="nav-panel" id="panel-upgrade-details" style="display:none; padding:15px; border:1px solid var(--border); border-top:none; border-radius:0 0 10px 10px; background:rgba(0,0,0,0.2);">
                                        <div class="vmo-cards" style="margin-bottom:0;">
                                            <div class="vmo-card" id="vmo-upgrade-panel" style="grid-column: 1 / -1; display:block; background:linear-gradient(135deg, rgba(16,185,129,0.05), rgba(0,0,0,0.2)); border:1px solid rgba(16,185,129,0.2);">
                                            <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px;">
                                            <div>
                                            <h4 style="margin:0; color:#10b981;">📞 Buy Phone Minutes</h4>
                                            <p style="margin:4px 0 0 0; font-size:12px; color:var(--muted);">Bulk minute packs for heavy calling — valid for 1 year</p>
                                            </div>

                                            </div>
                                            <div style="display:grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap:10px;">
                                            <button class="action-btn" data-plan="phone_m" onclick="VMOBusinessDashboard.buyPack('phone_m')" style="border:1px solid var(--border); background:rgba(255,255,255,0.05);">Pack M ($99)</button>
                                            <button class="action-btn" data-plan="phone_l" onclick="VMOBusinessDashboard.buyPack('phone_l')" style="border:1px solid var(--border); background:rgba(255,255,255,0.05);">Pack L ($249)</button>
                                            <button class="action-btn" data-plan="power_dialer" onclick="VMOBusinessDashboard.buyPack('power_dialer')" style="border:1px solid #f59e0b; color:#f59e0b; background:rgba(245,158,11,0.1);">Power Dialer ($499)</button>
                                            <button class="action-btn" data-plan="phone_xl" onclick="VMOBusinessDashboard.buyPack('phone_xl')" style="border:1px solid #ef4444; color:#ef4444; background:rgba(239,68,68,0.1);">Call Center ($699)</button>
                                            </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <!-- Contacts Picker Modal -->
                            <div id="vmo-contacts-modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.6); z-index:9999; align-items:center; justify-content:center;">
                                <div style="background:var(--panel-bg, #0b0f1a); border:1px solid var(--border); border-radius:12px; width:min(640px, 92vw); max-height:80vh; display:flex; flex-direction:column;">
                                    <div style="display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--border);">
                                        <strong>Contacts</strong>
                                        <button id="vmo-contacts-close" class="action-btn">✖</button>
                                    </div>
                                    <div style="padding:10px; border-bottom:1px solid var(--border); display:flex; gap:8px;">
                                        <input id="vmo-contacts-search" type="search" placeholder="Search name, phone, email, company" style="flex:1; padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                        <button id="vmo-contacts-refresh" class="action-btn">🔍 Search</button>
                                    </div>
                                    <div id="vmo-contacts-list" style="overflow:auto; padding:8px;">
                                        <div style="color:var(--muted); padding:12px;">Loading…</div>
                                    </div>
                                </div>
                            </div>
                            <!-- Incoming Call Banner -->
                            <style>
                                @keyframes vmo-ring-pulse {
                                    0% { box-shadow: 0 4px 18px rgba(0,0,0,.4), 0 0 0 0 rgba(0,200,255,.6); }
                                    50% { box-shadow: 0 4px 18px rgba(0,0,0,.4), 0 0 0 12px rgba(0,200,255,0); }
                                    100% { box-shadow: 0 4px 18px rgba(0,0,0,.4), 0 0 0 0 rgba(0,200,255,0); }
                                }
                                /* Hide ring settings modal scrollbar while preserving scroll capability */
                                #vmo-ring-settings > div > div {
                                    scrollbar-width: none; /* Firefox */
                                    -ms-overflow-style: none; /* IE 10+ */
                                }
                                #vmo-ring-settings > div > div::-webkit-scrollbar {
                                    width: 0; height: 0; background: transparent; /* Chrome, Safari, Edge */
                                }
                                #vmo-incoming-banner[style*="display: block"], #vmo-incoming-banner[style*="display:block"] {
                                    animation: vmo-ring-pulse 1.5s ease-in-out infinite;
                                    border-color: rgba(0,200,255,.7) !important;
                                }
                            </style>
                            <div id="vmo-incoming-banner" style="display:none; position:fixed; right:16px; bottom:16px; z-index:10001; background:var(--panel-bg, #0b0f1a); border:2px solid var(--border); border-radius:12px; padding:10px 12px; box-shadow:0 4px 18px rgba(0,0,0,.4); min-width:260px;">
                                <div style="display:flex; align-items:center; justify-content:space-between; gap:10px;">
                                    <div>
                                        <div style="font-weight:600;">Incoming call</div>
                                        <div id="vmo-incoming-from" style="color:var(--muted); font-size:12px;">—</div>
                                        <div id="vmo-incoming-mode" style="color:#38bdf8; font-size:11px; margin-top:3px;">Live control available</div>
                                    </div>
                                    <div style="display:flex; gap:6px; flex-wrap:wrap; justify-content:flex-end;">
                                        <button id="vmo-incoming-pick" class="action-btn primary" title="Take over" style="font-weight:600;">📞 Take Over</button>
                                        <button id="vmo-incoming-listen" class="action-btn" title="Listen">👂 Listen</button>
                                        <button id="vmo-incoming-open-dialer" class="action-btn" title="Open live dialer">🎛 Dialer</button>
                                        <button id="vmo-incoming-dismiss" class="action-btn" title="Dismiss">✖</button>
                                    </div>
                                </div>
                            </div>
                            <!-- Ring Settings Modal -->
                            <div id="vmo-ring-settings" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.6); z-index:10002; align-items:center; justify-content:center;">
                                <div style="background:var(--panel-bg, #0b0f1a); border:1px solid var(--border); border-radius:12px; width:min(460px, 92vw); max-height:80vh; display:flex; flex-direction:column;">
                                    <div style="display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--border);">
                                        <strong>Ring Settings</strong>
                                        <button id="vmo-ring-settings-close" class="action-btn">✖</button>
                                    </div>
                                    <div style="padding:12px 14px; display:grid; gap:10px; overflow-y:auto; flex:1; min-height:0;">
                                        <label style="display:grid; gap:6px;">
                                            <span>Ringtone</span>
                                            <select id="vmo-ring-preset" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                                <option value="classic">Classic Bell</option>
                                                <option value="pulse">Digital Pulse</option>
                                                <option value="chime">Office Chime</option>
                                                <option value="soft">Soft Ping</option>
                                            </select>
                                            <small style="color:var(--muted); font-size:11px;">Built-in ringtones work without uploading audio.</small>
                                        </label>
                                        <label style="display:grid; gap:6px;">
                                            <span>Volume</span>
                                            <input id="vmo-ring-volume" type="range" min="0" max="100" step="1" />
                                        </label>
                                        <label style="display:grid; gap:6px;">
                                            <span>Custom Ringtone URL (optional)</span>
                                            <input id="vmo-ring-url" type="url" placeholder="https://example.com/ringtone.mp3" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                        </label>
                                        <div style="display:flex; align-items:center; gap:8px;">
                                            <input type="file" id="vmo-ring-file" accept="audio/*" style="display:none;" />
                                            <button id="vmo-ring-upload" class="action-btn">⬆ Upload Audio</button>
                                            <small id="vmo-ring-file-note" style="color:var(--muted);"></small>
                                        </div>
                                        <label style="display:grid; gap:6px;">
                                            <span>AI Receptionist Greeting</span>
                                            <input id="vmo-ai-greeting" type="text" maxlength="160" placeholder="e.g., Thank you for calling Acme Co., how can I help you today?" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                        </label>
                                        <label style="display:grid; gap:6px;">
                                            <span>AI Receptionist Voice</span>
                                            <select id="vmo-ai-receptionist-voice" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                                <option value="ash">Ash (Male — warm, conversational)</option>
                                                <option value="alloy">Alloy (Neutral — balanced, clear)</option>
                                                <option value="ballad">Ballad (Male — expressive)</option>
                                                <option value="cedar">Cedar (Male — calm, steady)</option>
                                                <option value="coral">Coral (Female — bright, friendly)</option>
                                                <option value="echo">Echo (Male — smooth, professional)</option>
                                                <option value="fable">Fable (Male — narrative, articulate)</option>
                                                <option value="marin">Marin (Female — natural, warm)</option>
                                                <option value="nova">Nova (Female — energetic, upbeat)</option>
                                                <option value="onyx">Onyx (Male — deep, authoritative)</option>
                                                <option value="sage">Sage (Female — composed, thoughtful)</option>
                                                <option value="shimmer">Shimmer (Female — soft, pleasant)</option>
                                                <option value="verse">Verse (Male — refined, eloquent)</option>
                                            </select>
                                            <small style="color:var(--muted); font-size:11px;">Choose the voice your AI receptionist uses when answering calls.</small>
                                        </label>
                                        <!-- Voice Quality Tier -->
                                        <div style="display:grid; gap:6px;">
                                            <span style="font-weight:600;">AI Voice Quality</span>
                                            <div style="display:flex; gap:12px;">
                                                <label style="display:flex; align-items:center; gap:6px; cursor:pointer;">
                                                    <input type="radio" name="vmo-voice-quality" id="vmo-vq-standard" value="standard" checked style="accent-color:var(--cyan-soft);" />
                                                    <div>
                                                        <span style="font-size:13px;">Standard</span>
                                                        <div style="color:var(--muted); font-size:10px;">Lower cost · Standard AI Voice</div>
                                                    </div>
                                                </label>
                                                <label style="display:flex; align-items:center; gap:6px; cursor:pointer;">
                                                    <input type="radio" name="vmo-voice-quality" id="vmo-vq-premium" value="premium" style="accent-color:var(--cyan-soft);" />
                                                    <div>
                                                        <span style="font-size:13px;">Premium</span>
                                                        <div style="color:var(--muted); font-size:10px;">Higher quality · Premium AI Voice</div>
                                                    </div>
                                                </label>
                                            </div>
                                            <small style="color:var(--muted); font-size:11px;">Controls the AI model used for real-time phone conversations.</small>
                                        </div>

                                        <label style="display:grid; gap:6px;">
                                            <span>External Phone Number (Optional)</span>
                                            <input id="vmo-external-phone" type="tel" placeholder="e.g., +1 (555) 123-4567" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                            <small style="color:var(--muted); font-size:11px;">
                                                Incoming calls will ring this number. You can answer on your phone and join the call.
                                            </small>
                                        </label>
                                        
                                        <!-- Call Recording Toggle (Moved to Modal) -->
                                        <div style="display:flex; align-items:center; justify-content:space-between; padding:12px; border-radius:10px; background:rgba(255,255,255,.03); border:1px solid var(--border);">
                                            <div style="display:flex; flex-direction:column; gap:2px;">
                                                <span style="font-weight:600; color:var(--ink); font-size:13px;">Call Recording</span>
                                                <small style="color:var(--muted); font-size:10px;">Record all conversations for QA & Training purposes.</small>
                                            </div>
                                            <?php
                                                $rec_meta = get_user_meta(get_current_user_id(), 'call_recording_enabled', true);
                                                $rec_on   = ($rec_meta === '' || $rec_meta === false) ? true : (bool) intval($rec_meta);
                                            ?>
                                            <div id="vmo-recording-toggle-ui" class="toggle-switch <?php echo esc_attr( $rec_on ? 'active' : '' ); ?>" onclick="this.classList.toggle('active'); document.getElementById('vmo-recording-input').click();">
                                                <div class="toggle-slider"></div>
                                            </div>
                                            <input type="checkbox" id="vmo-recording-input" style="display:none;" <?php if ($rec_on) echo 'checked'; ?>>
                                        </div>

                                        <!-- Email: Incoming Call Alerts Toggle -->
                                        <div style="display:flex; align-items:center; justify-content:space-between; padding:12px; border-radius:10px; background:rgba(255,255,255,.03); border:1px solid var(--border);">
                                            <div style="display:flex; flex-direction:column; gap:2px;">
                                                <span style="font-weight:600; color:var(--ink); font-size:13px;">Email: Incoming Call Alerts</span>
                                                <small style="color:var(--muted); font-size:10px;">Receive an email each time an incoming call arrives.</small>
                                            </div>
                                            <div id="vmo-email-alerts-toggle-ui" class="toggle-switch" onclick="this.classList.toggle('active'); document.getElementById('vmo-email-alerts-input').click();">
                                                <div class="toggle-slider"></div>
                                            </div>
                                            <input type="checkbox" id="vmo-email-alerts-input" style="display:none;">
                                        </div>

                                        <!-- Email: Post-Call Summary Toggle -->
                                        <div style="display:flex; align-items:center; justify-content:space-between; padding:12px; border-radius:10px; background:rgba(255,255,255,.03); border:1px solid var(--border);">
                                            <div style="display:flex; flex-direction:column; gap:2px;">
                                                <span style="font-weight:600; color:var(--ink); font-size:13px;">Email: Post-Call Summaries</span>
                                                <small style="color:var(--muted); font-size:10px;">Receive a summary email with transcript & recording after every call.</small>
                                            </div>
                                            <div id="vmo-email-summaries-toggle-ui" class="toggle-switch active" onclick="this.classList.toggle('active'); document.getElementById('vmo-email-summaries-input').click();">
                                                <div class="toggle-slider"></div>
                                            </div>
                                            <input type="checkbox" id="vmo-email-summaries-input" style="display:none;" checked>
                                        </div>

                                        <div style="display:grid; gap:6px;">
                                            <span>Extensions (1–7) → IVR Menu</span>
                                            <small style="color:var(--muted); font-size:11px; margin-bottom:4px;">Assign a department and phone number to each extension. Callers will hear "For [department], press [number]". When a caller selects an extension, the AI will attend to them while that extension's phone rings — giving the person at the extension the option to listen or take over.</small>
                                            <div style="display:grid; gap:8px;">
                                                <?php for ($ei = 1; $ei <= 7; $ei++) : ?>
                                                <div style="display:grid; grid-template-columns:32px 1fr 1fr; gap:6px; align-items:start;">
                                                    <span style="color:var(--muted); font-size:12px; font-weight:600; text-align:center; padding-top:10px;"><?php echo esc_attr( $ei ); ?></span>
                                                    <div style="display:grid; gap:4px;">
                                                        <select id="vmo-ext-dept-<?php echo esc_attr( $ei ); ?>" onchange="(function(s){var c=document.getElementById('vmo-ext-custom-<?php echo esc_attr( $ei ); ?>');var l=document.getElementById('vmo-ext-label-<?php echo esc_attr( $ei ); ?>');if(s.value==='custom'){c.style.display='block';l.value=c.value;}else{c.style.display='none';l.value=s.value;}})(this)" style="padding:8px 10px; border-radius:8px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px; cursor:pointer;">
                                                            <option value="">— Select Department —</option>
                                                            <option value="Sales">Sales</option>
                                                            <option value="Support">Support</option>
                                                            <option value="Billing">Billing</option>
                                                            <option value="Customer Care">Customer Care</option>
                                                            <option value="Technical Support">Technical Support</option>
                                                            <option value="Reservations">Reservations</option>
                                                            <option value="Scheduling">Scheduling</option>
                                                            <option value="Returns">Returns</option>
                                                            <option value="Complaints">Complaints</option>
                                                            <option value="Human Resources">Human Resources</option>
                                                            <option value="Accounts">Accounts</option>
                                                            <option value="Marketing">Marketing</option>
                                                            <option value="General Inquiries">General Inquiries</option>
                                                            <option value="Management">Management</option>
                                                            <option value="custom">Custom…</option>
                                                        </select>
                                                        <input id="vmo-ext-custom-<?php echo esc_attr( $ei ); ?>" type="text" placeholder="Enter custom department name" maxlength="40" style="display:none; padding:8px 10px; border-radius:8px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px;" oninput="document.getElementById('vmo-ext-label-<?php echo esc_attr( $ei ); ?>').value=this.value" />
                                                        <input id="vmo-ext-label-<?php echo esc_attr( $ei ); ?>" type="hidden" value="" />
                                                    </div>
                                                    <input id="vmo-ext-<?php echo esc_attr( $ei ); ?>" type="tel" placeholder="Phone number" style="padding:8px 10px; border-radius:8px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px;" />
                                                </div>
                                                <?php endfor; ?>
                                            </div>
                                            <small style="color:var(--muted); font-size:11px;">When extensions are configured, callers hear an IVR menu before reaching the AI. "Remain on the line" always goes to the AI assistant.</small>
                                        </div>
                                        <div style="display:flex; gap:8px; justify-content:flex-end;">
                                            <button id="vmo-ring-test" class="action-btn">▶ Test</button>
                                            <button id="vmo-ring-save" class="action-btn primary">Save</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <!-- SMS Activation Modal -->
                            <div id="vmo-sms-activation-modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.7); z-index:100001; align-items:center; justify-content:center; font-family:inherit;">
                                <div style="background:linear-gradient(135deg,#0e1d29,#122e3f); border:1px solid rgba(245,158,11,0.3); border-radius:16px; width:min(680px, 94vw); max-height:88vh; display:flex; flex-direction:column; box-shadow:0 12px 48px rgba(0,0,0,.6);">
                                    <div style="display:flex; align-items:center; justify-content:space-between; padding:18px 22px; border-bottom:1px solid rgba(255,255,255,.08);">
                                        <div>
                                            <strong style="font-size:17px; color:#fff;">💬 SMS Activation Center</strong>
                                            <div style="font-size:12px; color:var(--muted,#888); margin-top:2px;">Enable text messaging on your business number</div>
                                        </div>
                                        <button onclick="document.getElementById('vmo-sms-activation-modal').style.display='none'" class="action-btn" style="font-size:16px;">✕</button>
                                    </div>
                                    <div id="vmo-sms-wizard-body" style="padding:22px; overflow-y:auto; flex:1;">
                                        <!-- Step indicator -->
                                        <div id="vmo-sms-steps" style="display:flex; gap:4px; margin-bottom:20px;">
                                            <div class="vmo-sms-step active" data-step="1" style="flex:1; height:4px; border-radius:4px; background:#f59e0b; cursor:pointer;" onclick="showSMSStep(1)"></div>
                                            <div class="vmo-sms-step" data-step="2" style="flex:1; height:4px; border-radius:4px; background:rgba(255,255,255,.12); cursor:pointer;" onclick="showSMSStep(2)"></div>
                                            <div class="vmo-sms-step" data-step="3" style="flex:1; height:4px; border-radius:4px; background:rgba(255,255,255,.12); cursor:pointer;" onclick="showSMSStep(3)"></div>
                                            <div class="vmo-sms-step" data-step="4" style="flex:1; height:4px; border-radius:4px; background:rgba(255,255,255,.12); cursor:pointer;" onclick="showSMSStep(4)"></div>
                                        </div>

                                        <!-- Step 1: Overview -->
                                        <div id="vmo-sms-step-1" class="vmo-sms-pane">
                                            <h4 style="color:#f59e0b; margin:0 0 12px;">⚠️ Why SMS Requires Activation</h4>
                                            <div style="background:rgba(245,158,11,0.06); border:1px solid rgba(245,158,11,0.2); border-radius:10px; padding:16px; margin-bottom:16px;">
                                                <p style="color:#cbd5e1; font-size:13px; line-height:1.7; margin:0;">US mobile carriers now require all businesses to complete <strong style="color:#f59e0b;">A2P 10DLC Registration</strong> (Application-to-Person, 10-Digit Long Code) before sending SMS/MMS messages from local phone numbers.</p>
                                                <p style="color:#94a3b8; font-size:12px; line-height:1.6; margin:10px 0 0;">Without this registration, your text messages <strong>will be blocked</strong> by carriers like AT&T, T-Mobile, and Verizon. VMO will email and alert you at each milestone so you always know whether you are waiting on review or still have another step to finish.</p>
                                            </div>
                                            <div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:10px; margin-bottom:16px;">
                                                <div style="background:rgba(255,255,255,.04); border-radius:8px; padding:12px; text-align:center;">
                                                    <div id="vmo-sms-check-brand" style="font-size:22px; margin-bottom:4px;">⬜</div>
                                                    <div style="font-size:11px; color:var(--muted,#888);">Register your business brand</div>
                                                </div>
                                                <div style="background:rgba(255,255,255,.04); border-radius:8px; padding:12px; text-align:center;">
                                                    <div id="vmo-sms-check-campaign" style="font-size:22px; margin-bottom:4px;">⬜</div>
                                                    <div style="font-size:11px; color:var(--muted,#888);">Choose and register the SMS use case</div>
                                                </div>
                                                <div style="background:rgba(255,255,255,.04); border-radius:8px; padding:12px; text-align:center;">
                                                    <div id="vmo-sms-check-number" style="font-size:22px; margin-bottom:4px;">⬜</div>
                                                    <div style="font-size:11px; color:var(--muted,#888);">Activate the number for live texting</div>
                                                </div>
                                            </div>
                                            <div style="background:rgba(15,23,42,.55); border:1px solid rgba(148,163,184,.18); border-radius:12px; padding:16px; margin-bottom:16px;">
                                                <div style="font-size:13px; font-weight:600; color:#e2e8f0; margin-bottom:10px;">Choose the SMS path you need</div>
                                                <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:10px;">
                                                    <label style="display:grid; gap:8px; padding:14px; border-radius:12px; border:1px solid rgba(56,189,248,.22); background:rgba(56,189,248,.06); cursor:pointer;">
                                                        <div style="display:flex; align-items:flex-start; gap:10px;">
                                                            <input type="radio" name="a2p-registration-intent" id="a2p-intent-regular" value="regular" checked style="margin-top:2px;">
                                                            <div>
                                                                <strong style="display:block; color:#f8fafc; font-size:13px;">Regular business SMS</strong>
                                                                <span style="display:block; color:#94a3b8; font-size:11px; line-height:1.6; margin-top:4px;">Best for customer replies, appointment reminders, support messages, delivery updates, and one-to-one operational texting.</span>
                                                            </div>
                                                        </div>
                                                    </label>
                                                    <label style="display:grid; gap:8px; padding:14px; border-radius:12px; border:1px solid rgba(245,158,11,.24); background:rgba(245,158,11,.07); cursor:pointer;">
                                                        <div style="display:flex; align-items:flex-start; gap:10px;">
                                                            <input type="radio" name="a2p-registration-intent" id="a2p-intent-marketing" value="marketing" style="margin-top:2px;">
                                                            <div>
                                                                <strong style="display:block; color:#f8fafc; font-size:13px;">Bulk marketing capable SMS</strong>
                                                                <span style="display:block; color:#94a3b8; font-size:11px; line-height:1.6; margin-top:4px;">Choose this only if you expect to run promotional or mass SMS campaigns later from the Tools area. This path can carry higher recurring carrier/compliance fees.</span>
                                                            </div>
                                                        </div>
                                                    </label>
                                                </div>
                                                <div id="vmo-a2p-intent-summary" style="margin-top:12px; padding:12px 14px; border-radius:10px; border:1px solid rgba(56,189,248,.22); background:rgba(56,189,248,.08); color:#cbd5e1; font-size:12px; line-height:1.65;">
                                                    Regular business SMS keeps the registration focused on customer communication and operational texting. You can still finish setup later if you are not ready right now.
                                                </div>
                                                <label style="display:flex; align-items:flex-start; gap:8px; margin-top:12px; color:#cbd5e1; font-size:12px; line-height:1.55;">
                                                    <input type="checkbox" id="a2p-fee-confirm" style="margin-top:3px;">
                                                    <span>I understand that SMS is an optional add-on and carrier/compliance charges may include a one-time brand fee and ongoing monthly campaign fees depending on the path I choose.</span>
                                                </label>
                                            </div>
                                            <div style="display:flex; justify-content:flex-end;">
                                                <button onclick="showSMSStep(2)" class="action-btn primary" style="padding:10px 24px; font-weight:600;">Continue to Brand Registration →</button>
                                            </div>
                                        </div>

                                        <!-- Step 2: Brand Registration (In-Plugin A2P Form) -->
                                        <div id="vmo-sms-step-2" class="vmo-sms-pane" style="display:none;">
                                            <h4 style="color:#3b82f6; margin:0 0 12px;">Step 1 — Register Your Business Brand</h4>
                                            <div style="background:rgba(59,130,246,0.06); border:1px solid rgba(59,130,246,0.2); border-radius:10px; padding:16px; margin-bottom:16px;">
                                                <p style="color:#cbd5e1; font-size:13px; line-height:1.7; margin:0;">Fill in your business details below. We'll register your brand automatically with the carrier network.</p>
                                                <p style="color:#94a3b8; font-size:11px; line-height:1.6; margin:8px 0 0;">These fields are required by carriers and compliance partners for business texting. They are not VMO-created requirements.</p>
                                                <p style="color:#f59e0b; font-size:11px; margin:8px 0 0;">Optional SMS add-on charge: 13,500 VMO Credits ($9.00) one time for carrier brand registration.</p>
                                            </div>
                                            <div id="vmo-a2p-brand-form" style="display:grid; gap:10px;">
                                                <div style="display:grid; grid-template-columns:1fr 1fr; gap:10px;">
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Legal Business Name *</label>
                                                        <input type="text" id="a2p-business-name" placeholder="e.g., Acme Inc." style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">EIN / Tax ID *</label>
                                                        <input type="text" id="a2p-ein" placeholder="e.g., 12-3456789" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                </div>
                                                <div style="display:grid; grid-template-columns:1fr 1fr; gap:10px;">
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Business Type *</label>
                                                        <select id="a2p-business-type" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                            <option value="">Select...</option>
                                                            <option value="Partnership">Partnership</option>
                                                            <option value="Corporation">Corporation</option>
                                                            <option value="Co-operative">Co-operative</option>
                                                            <option value="LLC">LLC</option>
                                                            <option value="Non-profit">Non-profit</option>
                                                            <option value="Sole Proprietorship">Sole Proprietorship</option>
                                                        </select>
                                                    </div>
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Industry *</label>
                                                        <select id="a2p-industry" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                            <option value="">Select...</option>
                                                            <option value="AUTOMOTIVE">Automotive</option>
                                                            <option value="EDUCATION">Education</option>
                                                            <option value="ENERGY">Energy</option>
                                                            <option value="ENTERTAINMENT">Entertainment</option>
                                                            <option value="FINANCIAL">Financial</option>
                                                            <option value="HEALTHCARE">Healthcare</option>
                                                            <option value="HOSPITALITY">Hospitality</option>
                                                            <option value="INSURANCE">Insurance</option>
                                                            <option value="LEGAL">Legal</option>
                                                            <option value="MANUFACTURING">Manufacturing</option>
                                                            <option value="NOT_FOR_PROFIT">Not for Profit</option>
                                                            <option value="REAL_ESTATE">Real Estate</option>
                                                            <option value="RETAIL">Retail</option>
                                                            <option value="TECHNOLOGY">Technology</option>
                                                        </select>
                                                    </div>
                                                </div>
                                                <div>
                                                    <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Street Address *</label>
                                                    <input type="text" id="a2p-street" placeholder="123 Main St" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                </div>
                                                <div style="display:grid; grid-template-columns:2fr 1fr 1fr; gap:10px;">
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">City *</label>
                                                        <input type="text" id="a2p-city" placeholder="City" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">State *</label>
                                                        <input type="text" id="a2p-state" placeholder="CA" maxlength="2" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">ZIP *</label>
                                                        <input type="text" id="a2p-zip" placeholder="90210" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                </div>
                                                <div>
                                                    <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Business Website *</label>
                                                    <input type="url" id="a2p-website" placeholder="https://yourbusiness.com" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                </div>
                                                <div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:10px;">
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Contact Name *</label>
                                                        <input type="text" id="a2p-contact-name" placeholder="John Doe" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Contact Email *</label>
                                                        <input type="email" id="a2p-contact-email" placeholder="john@business.com" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                    <div>
                                                        <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Contact Phone *</label>
                                                        <input type="tel" id="a2p-contact-phone" placeholder="+1234567890" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                    </div>
                                                </div>
                                            </div>
                                            <div id="vmo-a2p-brand-status" style="display:none; margin-top:10px; padding:10px; border-radius:8px; font-size:13px;"></div>
                                            <div style="display:flex; justify-content:space-between; margin-top:14px;">
                                                <button onclick="showSMSStep(1)" class="action-btn" style="padding:10px 20px;">← Back</button>
                                                <button id="vmo-a2p-brand-submit" onclick="vmoSubmitA2PBrand()" class="action-btn primary" style="padding:10px 24px; font-weight:600;">Register Brand (13,500 credits) →</button>
                                            </div>
                                        </div>

                                        <!-- Step 3: Campaign Registration (In-Plugin) -->
                                        <div id="vmo-sms-step-3" class="vmo-sms-pane" style="display:none;">
                                            <h4 style="color:#8b5cf6; margin:0 0 12px;">Step 2 — Create a Messaging Campaign</h4>
                                            <div style="background:rgba(139,92,246,0.06); border:1px solid rgba(139,92,246,0.2); border-radius:10px; padding:16px; margin-bottom:16px;">
                                                <p style="color:#cbd5e1; font-size:13px; line-height:1.7; margin:0;">Describe how you'll use SMS messaging. This is required after brand approval.</p>
                                                <p style="color:#94a3b8; font-size:11px; line-height:1.6; margin:8px 0 0;">VMO will email and alert you when this step is submitted, while review is in progress, and when SMS becomes active.</p>
                                                <p style="color:#f59e0b; font-size:11px; margin:8px 0 0;">Optional SMS add-on charge: 30,000 VMO Credits ($20.00) monthly for the carrier campaign registration.</p>
                                            </div>
                                            <div id="vmo-a2p-campaign-guidance" style="background:rgba(15,23,42,.55); border:1px solid rgba(148,163,184,.18); border-radius:10px; padding:12px 14px; margin-bottom:16px; color:#cbd5e1; font-size:12px; line-height:1.65;">
                                                Choose the registration profile that matches how you will actually text customers. Regular business SMS and bulk-marketing-capable SMS are treated differently by carriers, so confirm the intended path before you submit this paid step.
                                            </div>
                                            <div id="vmo-a2p-cost-advice-live" style="background:rgba(245,158,11,0.08); border:1px solid rgba(245,158,11,0.18); border-radius:10px; padding:12px 14px; margin-bottom:16px; color:#f8fafc;">
                                                <div style="font-size:12px; line-height:1.6; color:#cbd5e1;"><strong style="color:#f59e0b;">SMS add-on advisory:</strong> This optional monthly campaign requirement is 30,000 VMO Credits. Your current balance is <?php echo esc_html(number_format_i18n($balance)); ?> credits. VMO recommends keeping at least 35,000 credits available before you submit so activation and live texting do not drain your balance unexpectedly.</div>
                                            </div>
                                            <div id="vmo-a2p-campaign-form" style="display:grid; gap:10px;">
                                                <div>
                                                    <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Use Case *</label>
                                                    <select id="a2p-use-case" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                        <option value="">Select how you'll use SMS...</option>
                                                        <option value="CUSTOMER_CARE">Customer Care — Responding to inquiries</option>
                                                        <option value="MIXED">Mixed — Multiple purposes</option>
                                                        <option value="MARKETING">Marketing — Promotions & offers</option>
                                                        <option value="LOW_VOLUME">Low Volume — Under 1,000 msgs/month</option>
                                                        <option value="DELIVERY_NOTIFICATION">Delivery Notifications</option>
                                                        <option value="ACCOUNT_NOTIFICATION">Account Notifications</option>
                                                        <option value="2FA">Two-Factor Authentication</option>
                                                    </select>
                                                </div>
                                                <div>
                                                    <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Description of SMS Usage *</label>
                                                    <textarea id="a2p-description" placeholder="e.g., We send appointment reminders, follow-up messages after phone calls, and promotional offers to customers who opt in via our website." rows="3" style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; resize:vertical; box-sizing:border-box;"></textarea>
                                                </div>
                                                <div>
                                                    <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Sample Message 1 *</label>
                                                    <input type="text" id="a2p-sample1" placeholder="e.g., Hi {name}, your appointment is confirmed for tomorrow at 2pm. Reply STOP to opt out." style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                </div>
                                                <div>
                                                    <label style="color:#94a3b8; font-size:11px; display:block; margin-bottom:4px;">Sample Message 2 *</label>
                                                    <input type="text" id="a2p-sample2" placeholder="e.g., Thank you for calling {business}! As discussed, here are our hours: Mon-Fri 9am-6pm." style="width:100%; padding:8px 12px; background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); border-radius:6px; color:#fff; font-size:13px; box-sizing:border-box;">
                                                </div>
                                                <div style="background:rgba(16,185,129,0.06); border:1px solid rgba(16,185,129,0.15); border-radius:8px; padding:10px 14px;">
                                                    <p style="color:#94a3b8; font-size:11px; margin:0; line-height:1.5;">
                                                        <strong style="color:#10b981;">✓ Auto-configured:</strong> VMO automatically handles STOP/HELP keyword compliance, opt-out management, and message delivery optimization.
                                                    </p>
                                                </div>
                                            </div>
                                            <div id="vmo-a2p-campaign-status" style="display:none; margin-top:10px; padding:10px; border-radius:8px; font-size:13px;"></div>
                                                <div style="display:flex; justify-content:space-between; margin-top:14px;">
                                                <button onclick="showSMSStep(2)" class="action-btn" style="padding:10px 20px;">← Back</button>
                                                <button id="vmo-a2p-campaign-submit" onclick="vmoSubmitA2PCampaign()" class="action-btn primary" style="padding:10px 24px; font-weight:600;">Register Campaign (30,000 credits) →</button>
                                            </div>
                                        </div>

                                        <!-- Step 4: Auto Status Check & Activate -->
                                        <div id="vmo-sms-step-4" class="vmo-sms-pane" style="display:none;">
                                            <h4 style="color:#10b981; margin:0 0 12px;">Step 3 — Registration Status & Activation</h4>
                                            <div style="background:rgba(16,185,129,0.06); border:1px solid rgba(16,185,129,0.2); border-radius:10px; padding:16px; margin-bottom:16px;">
                                                <p style="color:#cbd5e1; font-size:13px; line-height:1.7; margin:0;">Your registrations are being reviewed by the carrier network. This typically takes 1–7 business days. VMO checks status from inside the plugin, emails you when review moves forward, and alerts you when another step is still required or when approval is complete.</p>
                                            </div>
                                            <div style="margin-bottom:16px; padding:12px; background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.08); border-radius:8px;">
                                                <div style="display:flex; align-items:center; gap:8px; margin-bottom:8px;">
                                                    <span id="vmo-a2p-status-brand-icon" style="font-size:16px;">⏳</span>
                                                    <span style="color:#e2e8f0; font-size:13px;">Brand Registration: </span>
                                                    <span id="vmo-a2p-status-brand-text" style="color:#f59e0b; font-size:13px; font-weight:600;">Checking...</span>
                                                </div>
                                                <div style="display:flex; align-items:center; gap:8px; margin-bottom:8px;">
                                                    <span id="vmo-a2p-status-campaign-icon" style="font-size:16px;">⏳</span>
                                                    <span style="color:#e2e8f0; font-size:13px;">Campaign Registration: </span>
                                                    <span id="vmo-a2p-status-campaign-text" style="color:#f59e0b; font-size:13px; font-weight:600;">Checking...</span>
                                                </div>
                                                <div style="display:flex; align-items:center; gap:8px;">
                                                    <span id="vmo-a2p-status-sms-icon" style="font-size:16px;">⏳</span>
                                                    <span style="color:#e2e8f0; font-size:13px;">SMS Capability: </span>
                                                    <span id="vmo-a2p-status-sms-text" style="color:#f59e0b; font-size:13px; font-weight:600;">Pending</span>
                                                </div>
                                            </div>
                                            <button id="vmo-a2p-check-btn" onclick="vmoCheckA2PStatus()" class="action-btn" style="width:100%; justify-content:center; padding:12px; font-weight:600; font-size:14px; border:1px solid rgba(59,130,246,0.4); color:#3b82f6; border-radius:8px; margin-bottom:12px;">
                                                🔄 Check Registration Status
                                            </button>
                                            <div id="vmo-a2p-status-meta" style="margin-bottom:12px; padding:12px 14px; border-radius:10px; border:1px solid rgba(148,163,184,.2); background:rgba(148,163,184,.08); color:#cbd5e1; font-size:12px; line-height:1.65;">
                                                VMO will show your latest carrier status here, send email and alert updates when the status changes, and can validate an already approved existing number when needed.
                                            </div>
                                            <div id="vmo-a2p-cancel-panel" style="margin-bottom:12px; padding:12px 14px; border-radius:10px; border:1px solid rgba(239,68,68,.22); background:rgba(239,68,68,.06); color:#fecaca; font-size:12px; line-height:1.65;">
                                                <strong style="color:#fca5a5;">Campaign cancellation protection:</strong> If you no longer want the higher-cost marketing-capable registration path, you can cancel the current SMS campaign registration here. This may remove marketing-ready status and may require re-registration later if you want to re-enable bulk marketing.
                                                <div style="display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;">
                                                    <button id="vmo-a2p-cancel-btn" onclick="vmoCancelA2PCampaign()" class="action-btn danger">Cancel SMS Campaign Registration</button>
                                                    <span id="vmo-a2p-cancel-meta" style="color:#cbd5e1; font-size:11px; display:flex; align-items:center;">No cancellation has been recorded in VMO.</span>
                                                </div>
                                            </div>
                                            <div id="vmo-a2p-activated-msg" style="display:none; background:rgba(16,185,129,0.1); border:1px solid rgba(16,185,129,0.3); border-radius:8px; padding:14px; text-align:center;">
                                                <div style="font-size:24px; margin-bottom:6px;">🎉</div>
                                                <p style="color:#10b981; font-size:14px; font-weight:600; margin:0;">SMS is fully activated!</p>
                                                <p style="color:#94a3b8; font-size:12px; margin:4px 0 0;">Your phone number is now registered for A2P messaging. You can send and receive SMS.</p>
                                            </div>
                                            <div style="display:flex; justify-content:flex-start; margin-top:14px;">
                                                <button onclick="showSMSStep(3)" class="action-btn" style="padding:10px 20px;">← Back</button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- Recording Playback Modal -->
                            <div id="vmo-recording-modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.6); z-index:999999; align-items:center; justify-content:center;">
                                <div style="background:var(--panel-bg, #0b0f1a); border:1px solid var(--border); border-radius:12px; width:min(640px, 92vw); max-height:80vh; display:flex; flex-direction:column;">
                                    <div style="display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--border);">
                                        <strong>Recording Playback</strong>
                                        <button id="vmo-rec-close" class="action-btn">✖</button>
                                    </div>
                                    <div id="vmo-rec-body" style="padding:14px; display:grid; gap:10px;">
                                        <div id="vmo-rec-meta" style="color:var(--muted); font-size:12px;">Loading…</div>
                                        <audio id="vmo-rec-audio" controls style="width:100%; outline:none;"></audio>
                                        <div id="vmo-rec-alt" style="display:none; color:salmon; font-size:12px;">No recording found for this call.</div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- Payments Section -->
                        <div id="payments" class="vmo-section">
                            <div class="nav-section">
                                <h4>CFO Dashboard — Financial Command Center</h4>
                                <h5 style="font-size:13px; color:var(--muted); margin:0 0 8px 0;">Business Revenue</h5>
                                <div class="vmo-cards" id="vmo-payments-kpis">
                                    <div class="vmo-card"><h4>Today</h4><div class="vmo-kv"><span>Gross Sales</span><strong id="vmo-pay-kpi-day">—</strong></div></div>
                                    <div class="vmo-card"><h4>7 Days</h4><div class="vmo-kv"><span>Gross Sales</span><strong id="vmo-pay-kpi-week">—</strong></div></div>
                                    <div class="vmo-card"><h4>30 Days</h4><div class="vmo-kv"><span>Gross Sales</span><strong id="vmo-pay-kpi-month">—</strong></div><div class="vmo-kv"><span>MoM Change</span><strong id="vmo-pay-kpi-mom">—</strong></div></div>
                                    <div class="vmo-card"><h4>365 Days</h4><div class="vmo-kv"><span>Gross Sales</span><strong id="vmo-pay-kpi-year">—</strong></div></div>
                                    <div class="vmo-card"><h4>Pending Flow</h4><div class="vmo-kv"><span>Revenue</span><strong id="vmo-pay-kpi-pending-flow">—</strong></div><div class="vmo-kv"><span>Orders</span><strong id="vmo-pay-kpi-pending-count">—</strong></div></div>
                                    <div class="vmo-card"><h4>Completed Flow</h4><div class="vmo-kv"><span>Revenue</span><strong id="vmo-pay-kpi-completed-flow">—</strong></div><div class="vmo-kv"><span>Orders</span><strong id="vmo-pay-kpi-completed-count">—</strong></div></div>
                                    <div class="vmo-card"><h4>Net Revenue</h4><div class="vmo-kv"><span>Net</span><strong id="vmo-pay-kpi-net-revenue">—</strong></div><div class="vmo-kv"><span>Fees / Taxes</span><strong id="vmo-pay-kpi-fees-taxes">—</strong></div></div>
                                </div>
                            </div>
                            <div class="vmo-cards">
                                <div class="vmo-card" style="grid-column:1/-1">
                                    <h4>Sales Trend</h4>
                                    <div style="height:180px;position:relative">
                                        <canvas id="vmo-pay-line" height="180"></canvas>
                                    </div>
                                    <div style="height:180px;position:relative;margin-top:12px">
                                        <canvas id="vmo-pay-monthly" height="180"></canvas>
                                    </div>
                                </div>
                                <div class="vmo-card" style="grid-column:1/-1">
                                    <h4>Recent Transactions</h4>
                                    <div id="vmo-pay-table" style="overflow:auto">
                                        <table style="width:100%;border-collapse:collapse;min-width:600px">
                                            <thead>
                                                <tr style="text-align:left;border-bottom:1px solid rgba(255,255,255,.1)">
                                                    <th style="padding:6px 8px">Date</th>
                                                    <th style="padding:6px 8px">Product</th>
                                                    <th style="padding:6px 8px">Amount</th>
                                                    <th style="padding:6px 8px">Currency</th>
                                                    <th style="padding:6px 8px">Status</th>
                                                    <th style="padding:6px 8px">Flow</th>
                                                    <th style="padding:6px 8px">Action</th>
                                                    <th style="padding:6px 8px">Receipt</th>
                                                </tr>
                                            </thead>
                                            <tbody id="vmo-pay-rows">
                                                <tr><td colspan="8" style="padding:8px;color:var(--muted)">Loading…</td></tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </div>

                                <!-- AI Financial Inbox -->
                                <div class="vmo-card" style="grid-column:1/-1">
                                    <h4>AI Financial Inbox</h4>
                                    <div class="vmo-kv"><span>Detected events waiting</span><strong id="vmo-cfo-inbox-count">0</strong></div>
                                    <div style="display:grid; grid-template-columns:1fr auto; gap:8px; align-items:start; margin-top:10px;">
                                        <textarea id="vmo-cfo-instruction" placeholder="Tell VMO what happened financially" style="min-height:44px; padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px; resize:vertical;"></textarea>
                                        <button class="action-btn" style="height:44px; padding:0 12px;" onclick="vmoCFOCaptureInstruction()">Add Event</button>
                                    </div>
                                    <div id="vmo-cfo-instruction-followups" style="display:none; margin-top:8px; padding:8px; border:1px solid var(--border); border-radius:8px; color:var(--muted); font-size:12px;"></div>
                                    <div id="vmo-cfo-financial-inbox" style="display:grid; gap:8px; margin-top:10px;">
                                        <div style="padding:10px; color:var(--muted); font-size:12px; border:1px solid var(--border); border-radius:8px;">No detected financial events need review.</div>
                                    </div>
                                </div>

                                <!-- Balance Sheet Generator -->
                                <div class="vmo-card" style="grid-column:1/-1">
                                    <h4>📊 Balance Sheet Generator</h4>
                                    <div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px; margin-top:8px;">
                                        <div>
                                            <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">From Date</label>
                                            <input id="vmo-bs-date-from" type="date" style="width:100%; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:13px;" />
                                        </div>
                                        <div>
                                            <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">To Date</label>
                                            <input id="vmo-bs-date-to" type="date" style="width:100%; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:13px;" />
                                        </div>
                                        <div>
                                            <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">Quick Select</label>
                                            <select id="vmo-bs-preset" style="width:100%; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:13px;">
                                                <option value="">Custom Range</option>
                                                <option value="week">This Week</option>
                                                <option value="month">This Month</option>
                                                <option value="quarter">This Quarter</option>
                                                <option value="ytd">Year to Date</option>
                                                <option value="last_month">Last Month</option>
                                                <option value="last_quarter">Last Quarter</option>
                                                <option value="last_year">Last Year</option>
                                            </select>
                                        </div>
                                        <div style="display:flex; align-items:flex-end;">
                                            <button id="vmo-bs-generate" class="action-btn" style="flex:1; padding:8px; font-size:13px; font-weight:600; background:linear-gradient(135deg,#10b981,#059669); border:0; border-radius:8px; color:#fff; cursor:pointer;">📊 Generate Balance Sheet</button>
                                        </div>
                                    </div>
                                    <div id="vmo-bs-result" style="display:none; margin-top:14px;"></div>
                                </div>

                                <!-- Business Net Worth -->
                                <div class="vmo-card" style="grid-column:1/-1">
                                    <h4>🏛️ Business Net Worth</h4>
                                    <div id="vmo-nw-loading" style="padding:12px; text-align:center; color:var(--muted);">Loading net worth…</div>
                                    <div id="vmo-nw-display" style="display:none;">
                                        <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr)); gap:10px; margin-top:8px;">
                                            <div class="vmo-card" style="background:rgba(16,185,129,.08); border-color:rgba(16,185,129,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Total Assets</div>
                                                <strong id="vmo-nw-assets" style="font-size:22px; color:#10b981;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(239,68,68,.08); border-color:rgba(239,68,68,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Total Liabilities</div>
                                                <strong id="vmo-nw-liabilities" style="font-size:22px; color:#ef4444;">—</strong>
                                            </div>
                                            <div class="vmo-card" id="vmo-nw-card" style="border-color:rgba(168,85,247,.3);">
                                                <div style="font-size:11px; color:var(--muted);">Estimated Net Worth</div>
                                                <strong id="vmo-nw-total" style="font-size:26px;">—</strong>
                                            </div>
                                        </div>
                                        <div id="vmo-nw-breakdown" style="margin-top:12px; display:grid; grid-template-columns:1fr 1fr; gap:12px;"></div>

                                        <!-- Add External Assets & Liabilities -->
                                        <details style="margin-top:14px; border:1px solid var(--border); border-radius:8px; overflow:hidden;">
                                            <summary style="padding:10px 12px; cursor:pointer; font-size:13px; font-weight:600; background:rgba(255,255,255,.02);">➕ Add External Assets & Liabilities <span style="font-weight:400; color:var(--muted); font-size:11px;">(loans, property, investments)</span></summary>
                                            <div style="padding:10px 12px;">
                                                <div style="display:grid; grid-template-columns:1fr 1fr; gap:12px;">
                                                    <div>
                                                        <h5 style="font-size:12px; color:#10b981; margin:0 0 6px 0;">Assets</h5>
                                                        <div id="vmo-nw-asset-rows" style="display:grid; gap:4px;"></div>
                                                        <button id="vmo-nw-add-asset" class="action-btn" style="font-size:11px; margin-top:6px;">+ Add Asset</button>
                                                    </div>
                                                    <div>
                                                        <h5 style="font-size:12px; color:#ef4444; margin:0 0 6px 0;">Liabilities</h5>
                                                        <div id="vmo-nw-liability-rows" style="display:grid; gap:4px;"></div>
                                                        <button id="vmo-nw-add-liability" class="action-btn" style="font-size:11px; margin-top:6px;">+ Add Liability</button>
                                                    </div>
                                                </div>
                                                <button id="vmo-nw-save-al" class="action-btn" style="width:100%; margin-top:10px; font-size:12px;">💾 Save & Recalculate Net Worth</button>
                                            </div>
                                        </details>
                                    </div>
                                </div>

                                <div class="vmo-card" style="grid-column:1/-1">
                                    <h4>🧮 Tax Calculator <span style="font-size:11px; font-weight:400; color:var(--muted); margin-left:8px;">Powered by VMO Tax Engine — Your AI CFO prepares everything automatically</span></h4>
                                    <div id="vmo-cfo-loading" style="padding:20px; text-align:center; color:var(--muted);">⏳ Your AI CFO is preparing your financial briefing…</div>

                                    <!-- Auto-Detected Business Context Banner -->
                                    <div id="vmo-cfo-context" style="display:none; margin-top:8px; padding:12px 14px; background:rgba(16,185,129,.06); border:1px solid rgba(16,185,129,.15); border-radius:10px;">
                                        <div style="display:flex; align-items:center; gap:10px; flex-wrap:wrap;">
                                            <span style="font-size:13px; font-weight:600;">📍 <span id="vmo-cfo-location">—</span></span>
                                            <span style="font-size:12px; color:var(--muted);">|</span>
                                            <span style="font-size:12px;">🏢 <span id="vmo-cfo-biz-name">—</span></span>
                                            <span style="font-size:12px; color:var(--muted);">|</span>
                                            <span style="font-size:12px;">📋 <span id="vmo-cfo-biz-type">—</span></span>
                                            <span style="font-size:12px; color:var(--muted);">|</span>
                                            <span style="font-size:12px;">💰 <span id="vmo-cfo-currency">USD</span></span>
                                            <span id="vmo-cfo-source-badge" style="font-size:10px; padding:2px 8px; border-radius:10px; background:#10b981; color:#fff;">Auto-detected</span>
                                        </div>
                                        <div style="font-size:11px; color:var(--muted); margin-top:4px;">Location and business type deduced from your consultation. <a href="#" id="vmo-cfo-edit-location" style="color:#3b82f6;">Edit manually →</a></div>
                                    </div>

                                    <!-- Manual Location Override (hidden by default) -->
                                    <div id="vmo-cfo-manual-location" style="display:none; margin-top:8px; padding:10px 12px; background:rgba(59,130,246,.06); border:1px solid rgba(59,130,246,.15); border-radius:8px;">
                                        <div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:8px;">
                                            <div>
                                                <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">Country</label>
                                                <select id="vmo-tax-country" style="width:100%; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px;"><option value="">Select…</option></select>
                                            </div>
                                            <div>
                                                <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">State / Province</label>
                                                <select id="vmo-tax-state" style="width:100%; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px;"><option value="">Select…</option></select>
                                            </div>
                                            <div>
                                                <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">Filing Status</label>
                                                <select id="vmo-tax-filing-status" style="width:100%; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:12px;">
                                                    <option value="single">Single / Sole Proprietor</option>
                                                    <option value="married_joint">Married Filing Jointly</option>
                                                    <option value="married_separate">Married Filing Separately</option>
                                                    <option value="head_household">Head of Household</option>
                                                </select>
                                            </div>
                                            <div style="display:flex; align-items:flex-end; gap:6px;">
                                                <button id="vmo-tax-save-settings" class="action-btn" style="flex:1; font-size:12px;">💾 Save & Recalculate</button>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- CFO Financial Summary Cards (auto-populated) -->
                                    <div id="vmo-cfo-summary" style="display:none; margin-top:12px;">
                                        <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(160px, 1fr)); gap:10px;">
                                            <div class="vmo-card" style="background:rgba(16,185,129,.08); border-color:rgba(16,185,129,.2);">
                                                <div style="font-size:11px; color:var(--muted);">💰 VMO Pay Revenue</div>
                                                <strong id="vmo-cfo-vmo-gross" style="font-size:18px; color:#10b981;">—</strong>
                                                <div style="font-size:10px; color:var(--muted);"><span id="vmo-cfo-order-count">0</span> orders this year</div>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(59,130,246,.08); border-color:rgba(59,130,246,.2);">
                                                <div style="font-size:11px; color:var(--muted);">📊 Other Income</div>
                                                <strong id="vmo-cfo-other-income" style="font-size:18px; color:#3b82f6;">$0.00</strong>
                                                <div style="font-size:10px; color:var(--muted);">From external sources</div>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(168,85,247,.08); border-color:rgba(168,85,247,.2);">
                                                <div style="font-size:11px; color:var(--muted);">📈 Combined Gross</div>
                                                <strong id="vmo-cfo-combined-gross" style="font-size:18px; color:#a855f7;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(245,158,11,.08); border-color:rgba(245,158,11,.2);">
                                                <div style="font-size:11px; color:var(--muted);">📉 Total Expenses</div>
                                                <strong id="vmo-cfo-total-expenses" style="font-size:18px; color:#f59e0b;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(16,185,129,.08); border-color:rgba(16,185,129,.2);">
                                                <div style="font-size:11px; color:var(--muted);">✅ Net Profit</div>
                                                <strong id="vmo-cfo-net-profit" style="font-size:18px; color:#10b981;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(245,158,11,.08); border-color:rgba(245,158,11,.2);">
                                                <div style="font-size:11px; color:var(--muted);">🏷️ Sales Tax Collected</div>
                                                <strong id="vmo-cfo-sales-tax" style="font-size:18px; color:#f59e0b;">—</strong>
                                                <div style="font-size:10px; color:var(--muted);">Owed to tax authority</div>
                                            </div>
                                        </div>

                                        <!-- User Input Section: Only what the CFO needs from the CEO -->
                                        <div style="margin-top:14px; padding:12px 14px; background:rgba(255,255,255,.02); border:1px solid var(--border); border-radius:10px;">
                                            <h4 style="font-size:13px; margin:0 0 8px 0;">📝 CEO Declarations <span style="font-weight:400; font-size:11px; color:var(--muted);">— Only you know these figures</span></h4>
                                            <div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:10px;">
                                                <div>
                                                    <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">Total Overhead & Operating Costs</label>
                                                    <input id="vmo-cfo-overhead" type="number" min="0" step="0.01" placeholder="Rent, utilities, salaries, etc." style="width:100%; padding:7px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:14px;" />
                                                    <div style="font-size:10px; color:var(--muted); margin-top:2px;">Annual overhead your business incurs</div>
                                                </div>
                                                <div>
                                                    <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:3px;">Other Taxable Income (External)</label>
                                                    <input id="vmo-cfo-other-income-input" type="number" min="0" step="0.01" placeholder="Investments, freelance, etc." style="width:100%; padding:7px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:14px;" />
                                                    <div style="font-size:10px; color:var(--muted); margin-top:2px;">Income from sources outside VMO</div>
                                                </div>
                                            </div>
                                            <div style="display:flex; gap:8px; margin-top:10px;">
                                                <button id="vmo-cfo-save-declarations" class="action-btn" style="font-size:12px;">💾 Save Declarations</button>
                                                <button id="vmo-cfo-calculate-tax" class="action-btn" style="flex:1; padding:10px; font-size:14px; font-weight:600; background:linear-gradient(135deg,#3b82f6,#6366f1); border:0; border-radius:8px; color:#fff; cursor:pointer;">🧮 Calculate My Taxes</button>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- Tax Regime Info (auto-shown when location is known) -->
                                    <div id="vmo-tax-regime-info" style="display:none; margin-top:12px; padding:10px 12px; background:rgba(59,130,246,.08); border:1px solid rgba(59,130,246,.2); border-radius:8px;">
                                        <div style="display:flex; align-items:center; gap:8px; margin-bottom:6px;">
                                            <strong id="vmo-tax-regime-title" style="font-size:13px;">—</strong>
                                            <span id="vmo-tax-regime-badges" style="display:flex; gap:4px;"></span>
                                        </div>
                                        <div id="vmo-tax-brackets-display" style="font-size:12px; line-height:1.6;"></div>
                                    </div>

                                    <!-- Tax Results Panel -->
                                    <div id="vmo-tax-results" style="display:none; margin-top:14px;">
                                        <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(160px, 1fr)); gap:10px;">
                                            <div class="vmo-card" style="background:rgba(16,185,129,.08); border-color:rgba(16,185,129,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Gross Income</div>
                                                <strong id="vmo-tax-res-gross" style="font-size:18px; color:#10b981;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(245,158,11,.08); border-color:rgba(245,158,11,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Expenses</div>
                                                <strong id="vmo-tax-res-expenses" style="font-size:18px; color:#f59e0b;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(59,130,246,.08); border-color:rgba(59,130,246,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Net Profit</div>
                                                <strong id="vmo-tax-res-profit" style="font-size:18px; color:#3b82f6;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(239,68,68,.08); border-color:rgba(239,68,68,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Estimated Tax</div>
                                                <strong id="vmo-tax-res-total" style="font-size:18px; color:#ef4444;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(168,85,247,.08); border-color:rgba(168,85,247,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Effective Rate</div>
                                                <strong id="vmo-tax-res-rate" style="font-size:18px; color:#a855f7;">—</strong>
                                            </div>
                                            <div class="vmo-card" style="background:rgba(16,185,129,.08); border-color:rgba(16,185,129,.2);">
                                                <div style="font-size:11px; color:var(--muted);">Net After Tax</div>
                                                <strong id="vmo-tax-res-net" style="font-size:18px; color:#10b981;">—</strong>
                                            </div>
                                        </div>
                                        <div style="margin-top:12px;">
                                            <h4 style="font-size:13px; margin-bottom:6px;">📋 Tax Breakdown</h4>
                                            <div id="vmo-tax-breakdown" style="overflow:auto;">
                                                <table style="width:100%; border-collapse:collapse; min-width:400px; font-size:12px;">
                                                    <thead><tr style="text-align:left; border-bottom:1px solid rgba(255,255,255,.1);"><th style="padding:6px 8px;">Component</th><th style="padding:6px 8px;">Amount</th><th style="padding:6px 8px;">Rate / Note</th></tr></thead>
                                                    <tbody id="vmo-tax-breakdown-rows"><tr><td colspan="3" style="padding:8px; color:var(--muted);">Click "Calculate My Taxes" to see breakdown</td></tr></tbody>
                                                </table>
                                            </div>
                                        </div>
                                        <div id="vmo-tax-indirect-info" style="display:none; margin-top:10px; padding:8px 12px; background:rgba(245,158,11,.06); border:1px solid rgba(245,158,11,.15); border-radius:8px; font-size:12px;"></div>
                                    </div>

                                    <!-- Expense Tracker -->
                                    <details style="margin-top:14px; border:1px solid var(--border); border-radius:8px; overflow:hidden;">
                                        <summary style="padding:10px 12px; cursor:pointer; font-size:13px; font-weight:600; background:rgba(255,255,255,.02);">📝 Expense Tracker <span style="font-weight:400; color:var(--muted); font-size:11px;">(deductible business expenses — your CFO tracks processing fees automatically)</span></summary>
                                        <div style="padding:10px 12px;">
                                            <div id="vmo-expense-rows" style="display:grid; gap:6px;"></div>
                                            <div style="display:flex; gap:6px; margin-top:8px;">
                                                <button id="vmo-expense-add" class="action-btn" style="font-size:12px;">+ Add Expense</button>
                                                <button id="vmo-expense-save" class="action-btn" style="font-size:12px;">💾 Save Expenses</button>
                                            </div>
                                        </div>
                                    </details>

                                    <!-- AI Tax Advisor -->
                                    <details style="margin-top:10px; border:1px solid var(--border); border-radius:8px; overflow:hidden;">
                                        <summary style="padding:10px 12px; cursor:pointer; font-size:13px; font-weight:600; background:rgba(255,255,255,.02);">🤖 AI Tax Advisor <span style="font-weight:400; color:var(--muted); font-size:11px;">(costs tokens)</span></summary>
                                        <div style="padding:10px 12px;">
                                            <textarea id="vmo-tax-ai-question" placeholder="Ask your AI CFO a tax question, e.g. 'What deductions can I claim for my online business?'" style="width:100%; min-height:60px; padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); font-size:13px; resize:vertical;"></textarea>
                                            <button id="vmo-tax-ai-run" class="action-btn" style="margin-top:6px; width:100%;">🤖 Get AI Tax Analysis</button>
                                            <div id="vmo-tax-ai-result" style="display:none; margin-top:10px; padding:12px; background:rgba(59,130,246,.05); border:1px solid rgba(59,130,246,.15); border-radius:8px; font-size:12px; line-height:1.6; white-space:pre-wrap;"></div>
                                        </div>
                                    </details>

                                    <!-- LEGAL DISCLAIMER -->
                                    <div style="margin-top:12px; padding:10px 14px; background:rgba(239,68,68,.04); border:1px solid rgba(239,68,68,.12); border-radius:8px; font-size:11px; color:var(--muted); line-height:1.6;">
                                        <strong style="color:#ef4444;">⚠️ Disclaimer:</strong> This tax calculator is provided as a <strong>helpful estimation tool only</strong>. VMO, Jerreme Josephson LLC, and all affiliated partners <strong>are not tax professionals and cannot be held liable</strong> for any errors, omissions, or decisions made based on the information provided herein. Tax laws vary by jurisdiction and change frequently. This tool <strong>does not replace professional tax advice</strong>. We strongly recommend consulting a certified tax professional, CPA, or licensed tax management organization before making any tax-related decisions. By using this tool, you acknowledge that it serves only as an informational guide and that Jerreme Josephson LLC, VMO, and any associated partners bear <strong>no liability whatsoever</strong> for any financial outcomes arising from its use.
                                    </div>
                                </div>
                            </div>

                            <!-- ═══ TOKEN SYSTEM VISIBILITY ═══ -->
                            <div class="nav-section" style="margin-top:16px;">
                                <h4>VMO Operating Usage</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card">
                                        <h4>Current Balance</h4>
                                        <div class="vmo-kv"><span>Tokens Available</span><strong id="vmo-cfo-token-balance" style="color:var(--cyan-soft);">—</strong></div>
                                        <div class="vmo-kv"><span>Estimated Capacity</span><strong id="vmo-cfo-token-capacity">—</strong></div>
                                        <button class="action-btn" style="width:100%; margin-top:8px;" onclick="vmoTopUpTokens()">🪙 Top Up Tokens</button>
                                    </div>
                                    <div class="vmo-card">
                                        <h4>Recent Usage (30 days)</h4>
                                        <div class="vmo-kv"><span>Total Consumed</span><strong id="vmo-cfo-token-used-30d">—</strong></div>
                                        <div class="vmo-kv"><span>Daily Average</span><strong id="vmo-cfo-token-daily-avg">—</strong></div>
                                        <div class="vmo-kv"><span>Estimated Value</span><strong id="vmo-cfo-token-value-30d">—</strong></div>
                                    </div>
                                </div>
                            </div>

                            <!-- ═══ COST-BY-SYSTEM BREAKDOWN ═══ -->
                            <div class="nav-section">
                                <h4>Cost by System</h4>
                                <div class="vmo-cards" id="vmo-cfo-cost-breakdown">
                                    <div class="vmo-card"><h4>📞 Phone</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-phone">0</strong></div></div>
                                    <div class="vmo-card"><h4>💬 SMS</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-sms">0</strong></div></div>
                                    <div class="vmo-card"><h4>✉️ Email</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-email">0</strong></div></div>
                                    <div class="vmo-card"><h4>🌐 Website Gen</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-website">0</strong></div></div>
                                    <div class="vmo-card"><h4>🤖 AI Chat</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-ai-chat">0</strong></div></div>
                                    <div class="vmo-card"><h4>🎨 Media Gen</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-media">0</strong></div></div>
                                    <div class="vmo-card"><h4>🔍 SEO/Scans</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-seo">0</strong></div></div>
                                    <div class="vmo-card"><h4>📄 Documents</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-docs">0</strong></div></div>
                                    <div class="vmo-card"><h4>Research</h4><div class="vmo-kv"><span>Tokens</span><strong id="vmo-cost-research">0</strong></div></div>
                                </div>
                            </div>

                            <!-- ═══ PLAN & BILLING STATUS ═══ -->
                            <div class="nav-section">
                                <h4>Billing / Plan Status & Monetization Readiness</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card">
                                        <h4>Current Plan</h4>
                                        <div class="vmo-kv"><span>Plan</span><strong id="vmo-cfo-plan-name" style="color:var(--cyan-soft);">—</strong></div>
                                        <div class="vmo-kv"><span>Status</span><strong id="vmo-cfo-billing-status">—</strong></div>
                                        <div class="vmo-kv"><span>Billing Cycle</span><strong id="vmo-cfo-billing-cycle">—</strong></div>
                                        <div class="vmo-kv"><span>Next Renewal</span><strong id="vmo-cfo-renewal-date">—</strong></div>
                                        <div class="vmo-kv"><span>Included Tokens</span><strong id="vmo-cfo-tokens-included">—</strong></div>
                                        <div class="vmo-kv"><span>Plan Usage</span><strong id="vmo-cfo-plan-usage">—</strong></div>
                                        <div style="font-size:11px; color:var(--muted); margin-top:8px;" id="vmo-cfo-plan-recommendation">—</div>
                                    </div>
                                    <div class="vmo-card">
                                        <h4>VMO Pay Status</h4>
                                        <div class="vmo-kv"><span>VMO Pay</span><strong id="vmo-cfo-stripe-status">—</strong></div>
                                        <div class="vmo-kv"><span>Payment Account</span><strong id="vmo-cfo-stripe-account">—</strong></div>
                                        <div class="vmo-kv"><span>Details Submitted</span><strong id="vmo-cfo-details-submitted">—</strong></div>
                                        <div class="vmo-kv"><span>Charges Enabled</span><strong id="vmo-cfo-charges-enabled">—</strong></div>
                                        <div class="vmo-kv"><span>Payouts Enabled</span><strong id="vmo-cfo-payouts-enabled">—</strong></div>
                                        <div id="vmo-cfo-stripe-blockers" style="display:none; margin-top:8px; padding:8px; background:rgba(239,68,68,.06); border:1px solid rgba(239,68,68,.15); border-radius:6px; font-size:11px; color:#f87171;"></div>
                                    </div>
                                </div>
                            </div>

                            <!-- ═══ FORECASTS & RECOMMENDATIONS ═══ -->
                            <div class="nav-section">
                                <h4>Forecasts & Recommendations</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card"><h4>Token Runway</h4><div class="vmo-kv"><span>Days Remaining</span><strong id="vmo-cfo-runway-days">—</strong></div><div class="vmo-kv"><span>Projected 30d Tokens</span><strong id="vmo-cfo-projected-tokens">—</strong></div></div>
                                    <div class="vmo-card"><h4>Operating Spend</h4><div class="vmo-kv"><span>Projected Token Value</span><strong id="vmo-cfo-projected-spend">—</strong></div><div class="vmo-kv"><span>Usage / Revenue</span><strong id="vmo-cfo-ops-ratio">—</strong></div></div>
                                    <div class="vmo-card"><h4>Financial Target</h4><div class="vmo-kv"><span>Monthly Goal Progress</span><strong id="vmo-cfo-goal-progress">—</strong></div><div class="vmo-kv"><span>Sustainability</span><strong id="vmo-cfo-sustainability">—</strong></div></div>
                                </div>
                            </div>

                            <!-- ═══ HIGH-COST APPROVALS ═══ -->
                            <div class="nav-section">
                                <h4>High-Cost Approvals</h4>
                                <div id="vmo-cfo-high-cost-approvals" class="vmo-cards">
                                    <div class="vmo-card"><p style="color:var(--muted);">No high-cost actions are waiting for approval.</p></div>
                                </div>
                            </div>

                            <!-- ═══ FINANCIAL ALERTS ═══ -->
                            <div class="nav-section">
                                <h4>🚨 Financial Alerts</h4>
                                <div id="vmo-cfo-alerts" class="vmo-cards">
                                    <div class="vmo-card"><p style="color:var(--muted);">No active financial alerts.</p></div>
                                </div>
                            </div>

                            <!-- ═══ PROFIT & EFFICIENCY INTERPRETATION ═══ -->
                            <div class="nav-section">
                                <h4>📊 Financial Insights</h4>
                                <div class="vmo-card">
                                    <div id="vmo-cfo-insights" style="color:var(--ink); font-size:13px; line-height:1.6;">Loading financial insights...</div>
                                </div>
                            </div>

                            <!-- ═══════════════════════════════════════
                                 VMO PAY — Product Experience
                            ═══════════════════════════════════════ -->

                            <!-- Invoice Creator -->
                            <div class="nav-section">
                                <h4>💳 VMO Pay</h4>
                                <div class="nav-links">
                                    <div class="nav-link" onclick="if(!vmoGateCheck('invoices'))return;togglePanel('vmo-invoice-panel')" title="Create and send professional invoices to clients.">
                                        <div class="nav-icon">🧾</div>
                                        <div class="nav-text">Invoices</div>
                                        <div class="nav-badge" id="vmo-invoice-count">—</div>
                                    </div>
                                    <div id="vmo-invoice-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">🧾 Create & Send Invoices</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:14px">Generate professional invoices with VMO Pay payment links.</p>

                                        <!-- New Invoice Form -->
                                        <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px">
                                            <div>
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Client Name</label>
                                                <input type="text" id="vmo-inv-client-name" placeholder="John Doe" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                            </div>
                                            <div>
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Client Email</label>
                                                <input type="email" id="vmo-inv-client-email" placeholder="client@example.com" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                            </div>
                                        </div>

                                        <!-- Line Items -->
                                        <div style="margin-bottom:10px">
                                            <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:4px">Line Items</label>
                                            <div id="vmo-inv-items">
                                                <div class="vmo-inv-item-row" style="display:grid;grid-template-columns:2fr 80px 80px 32px;gap:6px;margin-bottom:6px;align-items:center">
                                                    <input type="text" placeholder="Description" class="vmo-inv-desc" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px">
                                                    <input type="number" placeholder="Qty" class="vmo-inv-qty" value="1" min="1" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px;text-align:center">
                                                    <input type="number" placeholder="Price" class="vmo-inv-price" step="0.01" min="0" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px;text-align:right">
                                                    <span></span>
                                                </div>
                                            </div>
                                            <button class="action-btn" onclick="window.vmoAddInvoiceLine()" style="font-size:11px;margin-top:4px">+ Add Line</button>
                                        </div>

                                        <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px">
                                            <div>
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Currency</label>
                                                <select id="vmo-inv-currency" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                                    <option value="usd">USD ($)</option>
                                                    <option value="eur">EUR (€)</option>
                                                    <option value="gbp">GBP (£)</option>
                                                    <option value="cad">CAD (C$)</option>
                                                    <option value="aud">AUD (A$)</option>
                                                    <option value="ngn">NGN (₦)</option>
                                                    <option value="kes">KES (KSh)</option>
                                                    <option value="zar">ZAR (R)</option>
                                                    <option value="inr">INR (₹)</option>
                                                    <option value="jpy">JPY (¥)</option>
                                                </select>
                                            </div>
                                            <div>
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Due Date</label>
                                                <input type="date" id="vmo-inv-due-date" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                            </div>
                                        </div>

                                        <div style="margin-bottom:12px">
                                            <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Notes (optional)</label>
                                            <textarea id="vmo-inv-notes" rows="2" placeholder="Thank you for your business!" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:12px;resize:vertical;font-family:inherit"></textarea>
                                        </div>

                                        <!-- Total Preview -->
                                        <div style="display:flex;justify-content:space-between;align-items:center;padding:10px 14px;background:rgba(15,225,255,.05);border:1px solid var(--border);border-radius:10px;margin-bottom:14px">
                                            <span style="font-size:13px;color:var(--muted)">Total</span>
                                            <strong id="vmo-inv-total-display" style="font-size:20px;color:var(--cyan)">$0.00</strong>
                                        </div>

                                        <div style="display:flex;gap:8px">
                                            <button class="action-btn primary" onclick="window.vmoCreateInvoice(true)" title="Create invoice and email it to the client">📧 Create & Send</button>
                                            <button class="action-btn" onclick="window.vmoCreateInvoice(false)" title="Create invoice without sending">💾 Save Draft</button>
                                        </div>

                                        <!-- Existing Invoices -->
                                        <div style="margin-top:16px;border-top:1px solid var(--border);padding-top:12px">
                                            <h5 style="color:var(--cyan-soft);font-size:13px;margin-bottom:8px">Recent Invoices</h5>
                                            <div id="vmo-invoice-list">
                                                <div style="padding:10px;text-align:center;color:var(--muted);font-size:12px">No invoices yet.</div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- Payment Links -->
                                    <div class="nav-link" onclick="if(!vmoGateCheck('payment_links'))return;togglePanel('vmo-paylinks-panel')" title="Generate shareable payment links for products or custom amounts.">
                                        <div class="nav-icon">🔗</div>
                                        <div class="nav-text">Payment Links</div>
                                        <div class="nav-badge" id="vmo-paylink-count">—</div>
                                    </div>
                                    <div id="vmo-paylinks-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">🔗 Payment Links</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:14px">Create shareable VMO Pay links for social media, chat, or your website.</p>

                                        <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px">
                                            <div>
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Link Purpose</label>
                                                <input type="text" id="vmo-pl-name" placeholder="e.g. Website Design Package" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                            </div>
                                            <div>
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Amount</label>
                                                <div style="display:flex;gap:6px">
                                                    <select id="vmo-pl-currency" style="width:80px;padding:7px 6px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                                        <option value="usd">USD</option>
                                                        <option value="eur">EUR</option>
                                                        <option value="gbp">GBP</option>
                                                        <option value="cad">CAD</option>
                                                        <option value="aud">AUD</option>
                                                        <option value="ngn">NGN</option>
                                                        <option value="kes">KES</option>
                                                        <option value="zar">ZAR</option>
                                                        <option value="inr">INR</option>
                                                        <option value="jpy">JPY</option>
                                                    </select>
                                                    <input type="number" id="vmo-pl-amount" placeholder="99.00" step="0.01" min="0.50" style="flex:1;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px;text-align:right">
                                                </div>
                                            </div>
                                        </div>

                                        <div style="margin-bottom:12px">
                                            <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:3px">Description (shown to customer)</label>
                                            <input type="text" id="vmo-pl-description" placeholder="One-time payment for services" style="width:100%;padding:7px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                        </div>

                                        <div style="display:flex;gap:8px;margin-bottom:14px">
                                            <label style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--ink);cursor:pointer">
                                                <input type="checkbox" id="vmo-pl-allow-custom" title="Let customer choose amount">
                                                Customer chooses amount
                                            </label>
                                        </div>

                                        <button class="action-btn primary" onclick="window.vmoCreatePaymentLink()" style="margin-bottom:14px">🔗 Generate Payment Link</button>

                                        <!-- Generated Link Display -->
                                        <div id="vmo-pl-result" style="display:none;padding:12px;background:rgba(16,185,129,.06);border:1px solid rgba(16,185,129,.2);border-radius:10px;margin-bottom:14px">
                                            <div style="font-size:11px;color:var(--muted);margin-bottom:4px">Your Payment Link</div>
                                            <div style="display:flex;gap:8px;align-items:center">
                                                <input type="text" id="vmo-pl-url" readonly style="flex:1;padding:8px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--cyan);font-size:12px;font-family:monospace">
                                                <button class="action-btn" onclick="navigator.clipboard.writeText(document.getElementById('vmo-pl-url').value);notify('Link copied!','success')" title="Copy to clipboard">📋</button>
                                            </div>
                                        </div>

                                        <!-- Existing Payment Links -->
                                        <div style="border-top:1px solid var(--border);padding-top:12px">
                                            <h5 style="color:var(--cyan-soft);font-size:13px;margin-bottom:8px">Active Payment Links</h5>
                                            <div id="vmo-paylink-list">
                                                <div style="padding:10px;text-align:center;color:var(--muted);font-size:12px">No payment links yet.</div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- Customer Lifetime Value -->
                                    <div class="nav-link" onclick="if(!vmoGateCheck('customer_ltv'))return;togglePanel('vmo-ltv-panel', window.vmoLoadLTV)" title="Lifetime value insights for your top customers.">
                                        <div class="nav-icon">💎</div>
                                        <div class="nav-text">Customer Value</div>
                                        <div class="nav-badge" id="vmo-ltv-top-badge">—</div>
                                    </div>
                                    <div id="vmo-ltv-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">💎 Customer Lifetime Value</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:14px">Top customers ranked by total spend. Data enriches CRM contacts automatically.</p>
                                        <div id="vmo-ltv-stats" style="display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:14px">
                                            <div style="text-align:center;padding:10px;background:rgba(255,255,255,.03);border-radius:8px;border:1px solid var(--border)">
                                                <div style="font-size:20px;font-weight:700;color:var(--cyan)" id="vmo-ltv-avg">—</div>
                                                <div style="font-size:10px;color:var(--muted)">Avg LTV</div>
                                            </div>
                                            <div style="text-align:center;padding:10px;background:rgba(255,255,255,.03);border-radius:8px;border:1px solid var(--border)">
                                                <div style="font-size:20px;font-weight:700;color:#10b981" id="vmo-ltv-top">—</div>
                                                <div style="font-size:10px;color:var(--muted)">Top Customer</div>
                                            </div>
                                            <div style="text-align:center;padding:10px;background:rgba(255,255,255,.03);border-radius:8px;border:1px solid var(--border)">
                                                <div style="font-size:20px;font-weight:700;color:#7c5cff" id="vmo-ltv-total-customers">—</div>
                                                <div style="font-size:10px;color:var(--muted)">Paying Customers</div>
                                            </div>
                                        </div>
                                        <div id="vmo-ltv-list">
                                            <div style="padding:12px;text-align:center;color:var(--muted)">Loading…</div>
                                        </div>
                                        <div style="margin-top:12px">
                                            <button class="action-btn" onclick="window.vmoLoadLTV()" title="Refresh customer value data.">🔄 Refresh</button>
                                        </div>
                                    </div>

                                    <!-- Product Management -->
                                    <div class="nav-link" onclick="togglePanel('vmo-product-mgmt-panel', window.vmoLoadProducts)" title="Manage your store catalog — products, services, and subscriptions.">
                                        <div class="nav-icon">🛍️</div>
                                        <div class="nav-text">Products</div>
                                        <div class="nav-badge" id="vmo-product-count">—</div>
                                    </div>
                                    <div id="vmo-product-mgmt-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">🛍️ Product Catalog</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:14px">Manage your products, services, and subscriptions.</p>
                                        <div id="vmo-product-list">
                                            <div style="padding:12px;text-align:center;color:var(--muted)">Loading products…</div>
                                        </div>
                                        <div style="margin-top:12px">
                                            <button class="action-btn" onclick="window.vmoLoadProducts()" title="Refresh product list">🔄 Refresh</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- CRM Section -->
                        <div id="crm" class="vmo-section">
                            <div class="nav-section">
                                <h4>👥 Customer Management</h4>
                                <div class="nav-links">
                                    <div class="nav-link" onclick="if(!vmoGateCheck('crm_basic'))return;togglePanel('vmo-crm-panel', loadCRMPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">All Contacts</div>
                                        <div class="nav-badge" id="vmo-badge-contacts">—</div>
                                    </div>
                                    
                                </div>
                            </div>
                            <div id="vmo-crm-panel" class="vmo-cards" style="display:none;">
                                <div class="vmo-card"><h4>Loading CRM...</h4><p>Fetching contacts & pipeline.</p></div>
                            </div>
                        </div>

                        <!-- SEO Section -->
                        <div id="seo" class="vmo-section">
                            <div class="nav-section">
                                <h4>🔍 SEO Management</h4>
                                <div class="nav-links">
                                    <div class="nav-link" onclick="if(!vmoGateCheck('seo_tools'))return;togglePanel('vmo-seo-panel', loadSEOPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">SEO Dashboard</div>
                                    </div>
                                    <div class="nav-link" onclick="if(!vmoGateCheck('seo_tools'))return;togglePanel('vmo-seo-reports-panel', loadSEOReportsPanel)">
                                        <div class="nav-icon"></div>
                                        <div class="nav-text">SEO Reports</div>
                                    </div>
                                </div>
                            </div>
                            <div id="vmo-seo-panel" class="vmo-cards" style="display:none;">
                                <div class="vmo-card"><h4>Loading SEO...</h4><p>Gathering keyword & traffic data.</p></div>
                            </div>
                            <div id="vmo-seo-reports-panel" class="vmo-cards" style="display:none;">
                                <div class="vmo-card"><h4>Loading SEO Reports…</h4><p>Preparing charts & recent audits.</p></div>
                            </div>
                        </div>

                        <!-- Webmail Section -->
                        <div id="email" class="vmo-section">
                            <style>
                                #email .vmo-account-topline { display:flex; flex-direction:column; gap:6px; margin-bottom:12px; color:var(--muted); font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; }
                                #email .vmo-mail-switch-row { display:grid; grid-template-columns:1fr auto; align-items:center; gap:10px; cursor:pointer; color:var(--ink); font-size:12px; font-weight:700; }
                                #email .vmo-mail-switch-row input { position:absolute; opacity:0; pointer-events:none; }
                                #email .vmo-mail-switch { width:42px; height:22px; border-radius:999px; background:rgba(255,255,255,.14); border:1px solid rgba(255,255,255,.18); position:relative; transition:all .2s ease; }
                                #email .vmo-mail-switch::after { content:''; position:absolute; width:16px; height:16px; top:2px; left:3px; border-radius:50%; background:#9fb2c8; transition:all .2s ease; }
                                #email .vmo-mail-switch-row input:checked + .vmo-mail-switch { background:rgba(15,225,255,.26); border-color:rgba(15,225,255,.7); }
                                #email .vmo-mail-switch-row input:checked + .vmo-mail-switch::after { transform:translateX(18px); background:#0fe1ff; }
                            </style>
                            <div class="vmo-webmail-container" style="display:grid; grid-template-columns:240px 1fr; gap:16px; height:100%; min-height:600px;">
                                <!-- Sidebar -->
                                <div class="vmo-webmail-sidebar" style="background:rgba(0,0,0,0.2); border-radius:12px; padding:16px; border:1px solid var(--border);">
                                    <label class="vmo-account-topline">
                                        <span>Account</span>
                                        <select class="vmo-account-selector" style="width:100%; padding:8px; border-radius:6px; background:rgba(0,0,0,0.3); border:1px solid var(--border); color:var(--ink); font-size:12px;">
                                            <option value="<?php echo esc_attr($current_user && !empty($current_user->user_email) ? $current_user->user_email : ('info@' . parse_url(get_site_url(), PHP_URL_HOST))); ?>"><?php echo esc_html($current_user && !empty($current_user->user_email) ? $current_user->user_email : ('info@' . parse_url(get_site_url(), PHP_URL_HOST))); ?></option>
                                            <option value="support@<?php echo esc_attr(parse_url(get_site_url(), PHP_URL_HOST)); ?>">support@<?php echo esc_html(parse_url(get_site_url(), PHP_URL_HOST)); ?></option>
                                        </select>
                                    </label>
                                    <button class="action-btn primary" style="width:100%; margin-bottom:16px; padding:12px;" onclick="vmoOpenComposeModal()">
                                        ✏️ Compose
                                    </button>
                                    
                                    <div class="vmo-folder-list" style="display:flex; flex-direction:column; gap:4px;">
                                        <div class="vmo-folder active" data-folder="inbox" onclick="vmoSwitchMailFolder('inbox')" style="padding:10px; border-radius:8px; cursor:pointer; display:flex; justify-content:space-between; align-items:center; background:rgba(255,255,255,0.05);">
                                            <span>📥 Inbox</span>
                                            <span class="vmo-badge" id="vmo-inbox-count" style="background:var(--cyan); color:#000; padding:2px 6px; border-radius:10px; font-size:10px; font-weight:bold;">0</span>
                                        </div>
                                        <div class="vmo-folder" data-folder="sent" onclick="vmoSwitchMailFolder('sent')" style="padding:10px; border-radius:8px; cursor:pointer; color:var(--muted);">
                                            <span>📤 Sent</span>
                                        </div>
                                        <div class="vmo-folder" data-folder="drafts" onclick="vmoSwitchMailFolder('drafts')" style="padding:10px; border-radius:8px; cursor:pointer; color:var(--muted);">
                                            <span>📝 Drafts</span>
                                            <span class="vmo-badge vmo-drafts-count" data-vmo-drafts-count style="background:rgba(255,255,255,0.1); padding:2px 6px; border-radius:10px; font-size:10px;">0</span>
                                        </div>
                                        <div class="vmo-folder" data-folder="trash" onclick="vmoSwitchMailFolder('trash')" style="padding:10px; border-radius:8px; cursor:pointer; color:var(--muted);">
                                            <span>🗑️ Trash</span>
                                        </div>
                                    </div>

                                    <!-- Email Templates Library -->
                                    <div style="margin-top:16px; padding-top:16px; border-top:1px solid var(--border);">
                                        <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:8px;">TEMPLATES</label>
                                        <div style="display:flex; flex-direction:column; gap:4px;">
                                            <div class="vmo-folder" onclick="vmoInsertEmailTemplate('welcome')" style="padding:8px 10px; border-radius:8px; cursor:pointer; color:var(--muted); font-size:12px;" title="Welcome email for new contacts">
                                                👋 Welcome
                                            </div>
                                            <div class="vmo-folder" onclick="vmoInsertEmailTemplate('follow-up')" style="padding:8px 10px; border-radius:8px; cursor:pointer; color:var(--muted); font-size:12px;" title="Follow-up after meeting or call">
                                                🔄 Follow-Up
                                            </div>
                                            <div class="vmo-folder" onclick="vmoInsertEmailTemplate('newsletter')" style="padding:8px 10px; border-radius:8px; cursor:pointer; color:var(--muted); font-size:12px;" title="Monthly newsletter template">
                                                📰 Newsletter
                                            </div>
                                            <div class="vmo-folder" onclick="vmoInsertEmailTemplate('promotion')" style="padding:8px 10px; border-radius:8px; cursor:pointer; color:var(--muted); font-size:12px;" title="Special offer or promotion">
                                                🎁 Promotion
                                            </div>
                                            <div class="vmo-folder" onclick="vmoInsertEmailTemplate('thank-you')" style="padding:8px 10px; border-radius:8px; cursor:pointer; color:var(--muted); font-size:12px;" title="Thank you after purchase">
                                                🙏 Thank You
                                            </div>
                                            <div class="vmo-folder" onclick="vmoInsertEmailTemplate('appointment')" style="padding:8px 10px; border-radius:8px; cursor:pointer; color:var(--muted); font-size:12px;" title="Appointment confirmation/reminder">
                                                📅 Appointment
                                            </div>
                                        </div>
                                    </div>
                                    <div style="margin-top:16px; padding-top:16px; border-top:1px solid var(--border);">
                                        <label style="font-size:11px; color:var(--muted); display:block; margin-bottom:8px;">AI AUTO-REPLY</label>
                                        <label class="vmo-mail-switch-row" style="padding:8px 0;">
                                            <span>Auto Reply</span>
                                            <input type="checkbox" id="vmo-regular-ai-autoreply-toggle" onchange="vmoToggleAutoReply(this)">
                                            <span class="vmo-mail-switch" aria-hidden="true"></span>
                                        </label>
                                        <select id="vmo-ai-autoreply-mode" onchange="vmoUpdateAutoReplyMode()" style="width:100%; margin-top:8px; padding:8px; border-radius:6px; background:rgba(0,0,0,0.3); border:1px solid var(--border); color:var(--ink); font-size:12px;">
                                            <option value="draft_only">Draft only</option>
                                            <option value="auto_send_safe">Auto-send safe replies</option>
                                            <option value="ask_every_reply">Ask before every reply</option>
                                        </select>
                                    </div>
                                </div>

                                <!-- Mail List / View -->
                                <div class="vmo-webmail-content" style="background:rgba(0,0,0,0.2); border-radius:12px; border:1px solid var(--border); display:flex; flex-direction:column;">
                                    <!-- Toolbar -->
                                    <div class="vmo-mail-toolbar" style="padding:12px; border-bottom:1px solid var(--border); display:flex; justify-content:space-between; align-items:center;">
                                        <h4 id="vmo-current-folder-title" style="margin:0; color:var(--cyan-soft);">Inbox</h4>
                                        <div style="display:flex; gap:8px;">
                                            <button class="action-btn compact" onclick="vmoRefreshMail()">🔄</button>
                                            <input id="vmo-mail-search" type="text" placeholder="Search mail..." style="background:rgba(0,0,0,0.3); border:1px solid var(--border); border-radius:6px; padding:4px 8px; color:var(--ink); font-size:12px;">
                                        </div>
                                    </div>

                                    <!-- Mail List -->
                                    <div id="vmo-mail-list" style="flex:1; overflow-y:auto; padding:0;">
                                        <!-- Empty State -->
                                        <div style="display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; color:var(--muted); padding:40px;">
                                            <div style="font-size:48px; margin-bottom:16px; opacity:0.3;">📭</div>
                                            <p>No messages in this folder</p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- Promotion Command Center -->
                        <?php
                        $vmo_promotion_preview_only = function_exists('vmo_promotion_is_preview_only') ? vmo_promotion_is_preview_only() : true;
                        $vmo_promotion_preview_message = function_exists('vmo_promotion_preview_message') ? vmo_promotion_preview_message() : 'The Promotion Command Center is coming soon in this release.';
                        ?>
                        <div id="promotion" class="vmo-section<?php echo $vmo_promotion_preview_only ? ' vmo-promo-preview-mode' : ''; ?>">
                            <div class="vmo-card" style="margin-bottom:16px;">
                                <h4>VMO Promotion Command Center</h4>
                                <p><?php echo esc_html($vmo_promotion_preview_only
                                    ? 'This entire command center is now presented as a locked preview for the next release. Users can see the full Social Media Posting workspace and the broader Advertising & Marketing Command Center, but both remain non-interactive until provider credentials, ads entitlements, and production connectors are completed.'
                                    : 'This command center centralizes VMO social posting and advertising workflows in one place.'); ?></p>
                            </div>

                            <div class="vmo-promo-metrics">
                                <div class="vmo-promo-metric">
                                    <small>Release Status</small>
                                    <strong id="vmo-promo-stat-capability"><?php echo esc_html($vmo_promotion_preview_only ? 'Coming Soon' : 'Available'); ?></strong>
                                    <span><?php echo esc_html($vmo_promotion_preview_only ? 'Preview-only until platform credentials and connectors are in place.' : 'This workspace is live and can be activated per provider as credentials are configured.'); ?></span>
                                </div>
                                <div class="vmo-promo-metric">
                                    <small>Selected Platforms</small>
                                    <strong id="vmo-promo-stat-platforms">0</strong>
                                    <span>Platforms tracked for both organic posting and future ads management.</span>
                                </div>
                                <div class="vmo-promo-metric">
                                    <small>Promo Budget</small>
                                    <strong id="vmo-promo-stat-budget">$0</strong>
                                    <span>Reserved budget target for future organic and paid promotion planning.</span>
                                </div>
                                <div class="vmo-promo-metric">
                                    <small>VMO Tokens</small>
                                    <strong id="vmo-promo-stat-tokens"><?php echo esc_html(number_format_i18n((int) $balance)); ?></strong>
                                    <span>Current balance available once the command center is unlocked in a later update.</span>
                                </div>
                            </div>

                            <div class="vmo-promo-subtabs">
                                <button id="vmo-promo-subtab-social" class="vmo-promo-subtab active" type="button" <?php echo $vmo_promotion_preview_only ? 'disabled aria-disabled="true" title="Coming soon"' : ''; ?>>Social Media Posting<?php echo esc_html($vmo_promotion_preview_only ? ' (Coming Soon)' : ''); ?></button>
                                <button id="vmo-promo-subtab-marketing" class="vmo-promo-subtab" type="button" <?php echo $vmo_promotion_preview_only ? 'disabled aria-disabled="true" title="Coming soon"' : ''; ?>>Advertising & Marketing Command Center<?php echo esc_html($vmo_promotion_preview_only ? ' (Coming Soon)' : ''); ?></button>
                            </div>

                            <div class="vmo-promo-note">
                                <strong>Clean-first structure</strong>
                                <p><?php echo esc_html($vmo_promotion_preview_only
                                    ? 'Both promotion lanes are intentionally visible now so users can understand the full planned system. For this release, the entire area is greyed out and locked while social, advertising, metrics, and account-connection credentials are gathered together.'
                                    : 'Both promotion lanes are available from the same command center so social publishing and advertising workflows can be managed together.'); ?></p>
                            </div>

                            <?php if ($vmo_promotion_preview_only) : ?>
                                <div class="vmo-promo-preview-banner">
                                    <strong>Preview only</strong>
                                    <p><?php echo esc_html($vmo_promotion_preview_message); ?></p>
                                </div>
                            <?php endif; ?>

                            <div id="vmo-promo-social-area">
                                <div class="nav-section">
                                    <h4>📣 Social Media Posting</h4>
                                    <div class="nav-links">
                                        <div class="nav-link" onclick="togglePanel('vmo-promo-strategy-panel', window.loadPromotionPanel)">
                                            <div class="nav-icon"></div>
                                            <div class="nav-text">AI Strategy</div>
                                            <div class="nav-badge">Preview</div>
                                        </div>
                                        <div id="vmo-promo-strategy-panel" class="vmo-card" style="display:none;">
                                            <div style="display:flex; align-items:flex-start; justify-content:space-between; gap:12px; flex-wrap:wrap;">
                                                <div>
                                                    <h4>Let VMO build the social strategy</h4>
                                                    <p>Use AI to create campaign ideas, engagement prompts, product-promotion angles, follower-growth suggestions, and recommended posting cadence.</p>
                                                </div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button id="vmo-promo-save-btn" class="action-btn" type="button">💾 Save Settings</button>
                                                    <button id="vmo-promo-build-plan-btn" class="action-btn primary" type="button">✨ Ask AI to Build Social Plan</button>
                                                </div>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <label for="vmo-promo-goal" style="display:block; margin-bottom:8px; color:var(--ink); font-size:12px;">Primary goal</label>
                                                <textarea id="vmo-promo-goal" rows="4" style="width:100%; padding:12px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);"></textarea>
                                            </div>
                                            <div style="margin-top:12px;" class="vmo-promo-mini-grid">
                                                <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('daily_ideas')">Generate daily posting ideas</button>
                                                <button class="action-btn" type="button" onclick="vmoPromotionGenerateEngagement('follower_growth')">Suggest follower-growth strategy</button>
                                                <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('product_plan')">Create product-post plan</button>
                                                <button class="action-btn" type="button" onclick="vmoPromotionGenerateEngagement('engagement_prompts')">Create engagement prompts</button>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <h4 style="margin-bottom:8px;">AI Strategy Output</h4>
                                                <div id="vmo-promo-strategy-output" class="vmo-promo-result-list">
                                                    <div class="vmo-promo-empty">No strategy generated yet.</div>
                                                </div>
                                            </div>
                                        </div>

                                        <div class="nav-link" onclick="togglePanel('vmo-promo-posts-panel', window.loadPromotionPanel)">
                                            <div class="nav-icon"></div>
                                            <div class="nav-text">Create or Generate Posts</div>
                                            <div class="nav-badge" id="vmo-promo-mode-badge"><?php echo esc_html($vmo_promotion_preview_only ? 'Preview' : 'AI'); ?></div>
                                        </div>
                                        <div id="vmo-promo-posts-panel" class="vmo-card" style="display:none;">
                                            <div style="display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px;">
                                                <button id="vmo-promo-mode-ai" class="action-btn primary" type="button" onclick="vmoPromotionSwitchMode('ai')">🤖 AI-Assisted</button>
                                                <button id="vmo-promo-mode-manual" class="action-btn" type="button" onclick="vmoPromotionSwitchMode('manual')">📤 Manual / Custom</button>
                                            </div>
                                            <input id="vmo-promo-social-mode" type="hidden" value="ai" />
                                            <div id="vmo-promo-ai-mode">
                                                <div class="vmo-promo-mini-grid">
                                                    <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('weekly_plan')">Generate 7 days of posts</button>
                                                    <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('product_post')">Create a product post</button>
                                                    <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('checkout_post')">Create a direct-checkout post</button>
                                                    <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('engagement_post')">Create engagement post ideas</button>
                                                    <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('carousel_reel')">Create carousel / reel concept</button>
                                                    <button class="action-btn" type="button" onclick="vmoPromotionGeneratePosts('audience_growth')">Create audience-growth content</button>
                                                </div>
                                                <div style="margin-top:12px;">
                                                    <h4 style="margin-bottom:8px;">Refine AI output</h4>
                                                    <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                        <button class="action-btn" type="button" onclick="vmoPromotionRefinePosts('Make the current drafts more elegant.')">Make more elegant</button>
                                                        <button class="action-btn" type="button" onclick="vmoPromotionRefinePosts('Make the current drafts more sales-driven.')">Make more sales-driven</button>
                                                        <button class="action-btn" type="button" onclick="vmoPromotionRefinePosts('Shorten the captions while keeping the CTA.')">Shorten caption</button>
                                                        <button class="action-btn" type="button" onclick="vmoPromotionRefinePosts('Strengthen the CTA in each draft.')">Stronger CTA</button>
                                                        <button class="action-btn" type="button" onclick="vmoPromotionRefinePosts('Adapt each draft for the selected platforms.')">Adapt for each platform</button>
                                                        <button class="action-btn" type="button" onclick="vmoPromotionRefinePosts('Generate variants for the current drafts.')">Generate variants</button>
                                                    </div>
                                                </div>
                                            </div>
                                            <div id="vmo-promo-manual-mode" style="display:none;">
                                                <div class="vmo-promo-manual-grid">
                                                    <div class="vmo-promo-upload">
                                                        <label for="vmo-promo-upload-images">Upload Images</label>
                                                        <small>Use your own product or brand visuals for social posting.</small>
                                                        <input id="vmo-promo-upload-images" type="file" accept="image/*" />
                                                    </div>
                                                    <div class="vmo-promo-upload">
                                                        <label for="vmo-promo-upload-videos">Upload Videos / Animations</label>
                                                        <small>Attach reels, clips, motion assets, or short promotional videos.</small>
                                                        <input id="vmo-promo-upload-videos" type="file" accept="video/*" />
                                                    </div>
                                                    <div class="vmo-promo-upload">
                                                        <label for="vmo-promo-upload-copy">Upload Copy / Notes</label>
                                                        <small>Attach product copy, campaign notes, or offer details.</small>
                                                        <input id="vmo-promo-upload-copy" type="file" accept=".txt,.doc,.docx,.pdf,.rtf" />
                                                    </div>
                                                    <div class="vmo-promo-upload">
                                                        <label for="vmo-promo-upload-voice">Upload Voice Direction</label>
                                                        <small>Attach audio direction if you want VMO to follow a spoken brief.</small>
                                                        <input id="vmo-promo-upload-voice" type="file" accept="audio/*" />
                                                    </div>
                                                </div>
                                                <div style="margin-top:14px;">
                                                    <label for="vmo-promo-manual-notes" style="display:block; margin-bottom:8px; color:var(--ink); font-size:12px;">Manual direction</label>
                                                    <textarea id="vmo-promo-manual-notes" rows="4" style="width:100%; padding:12px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);" placeholder="Describe how these uploaded assets should be used in the social post."></textarea>
                                                </div>
                                                <div style="margin-top:14px;">
                                                    <h4 style="margin-bottom:8px;">Uploaded manual assets</h4>
                                                    <div id="vmo-promo-assets" class="vmo-promo-asset-list">
                                                        <div class="vmo-promo-empty">No promotion assets uploaded yet.</div>
                                                    </div>
                                                </div>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <h4 style="margin-bottom:8px;">Current post output</h4>
                                                <div id="vmo-promo-post-output" class="vmo-promo-result-list">
                                                    <div class="vmo-promo-empty">No post drafts generated yet.</div>
                                                </div>
                                            </div>
                                        </div>

                                        <div class="nav-link" onclick="togglePanel('vmo-promo-cta-panel', window.loadPromotionPanel)">
                                            <div class="nav-icon"></div>
                                            <div class="nav-text">Media, Product & CTA Options</div>
                                        </div>
                                        <div id="vmo-promo-cta-panel" class="vmo-card" style="display:none;">
                                            <div class="vmo-promo-mini-grid">
                                                <div class="vmo-promo-mini-card">
                                                    <strong>Media handling</strong>
                                                    <p style="margin-top:8px;">VMO can work with generated media, uploaded images, uploaded videos, animations, and product notes when preparing social content.</p>
                                                </div>
                                                <div class="vmo-promo-mini-card">
                                                    <strong>Product-post destination</strong>
                                                    <p style="margin-top:8px;">Choose whether product-driven posts should send visitors to a product page, store page, or direct VMO Pay checkout.</p>
                                                </div>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <label style="display:block; margin-bottom:8px; color:var(--ink); font-size:12px;">CTA destination preference</label>
                                                <div class="vmo-promo-mini-grid">
                                                    <label class="vmo-promo-mini-card"><input type="radio" name="vmo-promo-cta-destination" value="product_page" /> Send users to product page on website</label>
                                                    <label class="vmo-promo-mini-card"><input type="radio" name="vmo-promo-cta-destination" value="store_page" /> Send users to online store page</label>
                                                    <label class="vmo-promo-mini-card"><input type="radio" name="vmo-promo-cta-destination" value="direct_checkout" /> Send users directly to VMO Pay checkout</label>
                                                    <label class="vmo-promo-mini-card"><input type="radio" name="vmo-promo-cta-destination" value="ai_recommend" /> Let AI recommend the best conversion path</label>
                                                </div>
                                            </div>
                                        </div>

                                        <div class="nav-link" onclick="togglePanel('vmo-promo-platforms-panel', window.loadPromotionPanel)">
                                            <div class="nav-icon"></div>
                                            <div class="nav-text">Platforms & Adaptation</div>
                                            <div class="nav-badge" id="vmo-promo-selected-count">0</div>
                                        </div>
                                        <div id="vmo-promo-platforms-panel" class="vmo-card" style="display:none;">
                                            <h4>Choose target platforms</h4>
                                            <p>Select the platforms VMO should target when shaping drafts. This controls strategy recommendations and platform-aware wording. Provider credentials, callback URLs, and rollout-wave setup live in <a href="<?php echo esc_url(admin_url('admin.php?page=vmo-ai-settings')); ?>">VMO Settings</a>.</p>
                                            <div id="vmo-promo-platform-list" class="vmo-promo-chiplist" style="margin-top:14px;"></div>
                                            <div style="margin-top:14px;">
                                                <h4 style="margin-bottom:8px;">Connected accounts</h4>
                                                <div id="vmo-promo-connected-accounts" class="vmo-promo-result-list">
                                                    <div class="vmo-promo-empty">No provider account connections have been recorded yet.</div>
                                                </div>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <h4 style="margin-bottom:8px;">Provider readiness matrix</h4>
                                                <div id="vmo-promo-provider-matrix" class="vmo-promo-result-list">
                                                    <div class="vmo-promo-empty">Provider readiness data will appear here once the promotion services load.</div>
                                                </div>
                                            </div>
                                        </div>

                                        <div class="nav-link" onclick="togglePanel('vmo-promo-schedule-panel', window.loadPromotionPanel)">
                                            <div class="nav-icon"></div>
                                            <div class="nav-text">Cadence & Queue Planning</div>
                                        </div>
                                        <div id="vmo-promo-schedule-panel" class="vmo-card" style="display:none;">
                                            <div class="vmo-promo-mini-card" style="margin-bottom:14px;">
                                                <strong>Release status</strong>
                                                <p style="margin-top:8px;"><?php echo esc_html($vmo_promotion_preview_only
                                                    ? 'The orchestration model, provider inventory, and readiness matrix are in place, but this entire command center remains locked until the next release. Direct publishing, replies, metrics sync, and ad-management workflows will activate only after the matching credentials, scopes, approvals, and adapters are completed.'
                                                    : 'Provider credentials, scopes, approvals, and adapters can now activate supported publishing, replies, metrics sync, and ad-management workflows per platform.'); ?></p>
                                            </div>
                                            <div class="vmo-promo-mini-grid" style="margin-top:14px;">
                                                <div class="vmo-promo-mini-card">
                                                    <label for="vmo-promo-budget" style="display:block; margin-bottom:8px;">Promotion budget target</label>
                                                    <input id="vmo-promo-budget" type="number" min="0" step="100" style="width:100%; padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);" />
                                                </div>
                                                <div class="vmo-promo-mini-card">
                                                    <label for="vmo-promo-cadence" style="display:block; margin-bottom:8px;">Default posting cadence</label>
                                                    <input id="vmo-promo-cadence" type="text" style="width:100%; padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);" placeholder="e.g. 5 posts per week" />
                                                </div>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <h4 style="margin-bottom:8px;">Content queue</h4>
                                                <div class="vmo-promo-mini-grid" style="margin-bottom:10px;">
                                                    <input id="vmo-promo-queue-title" type="text" placeholder="Queue item title" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);" />
                                                    <select id="vmo-promo-queue-status" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);">
                                                        <option value="Awaiting Approval">Awaiting Approval</option>
                                                        <option value="Scheduled">Scheduled</option>
                                                        <option value="Draft">Draft</option>
                                                    </select>
                                                    <input id="vmo-promo-queue-time" type="text" placeholder="Today · 2:00 PM" style="padding:10px; border-radius:10px; border:1px solid var(--border); background:rgba(0,0,0,.25); color:var(--ink);" />
                                                    <button id="vmo-promo-add-queue" class="action-btn primary" type="button">➕ Add to Queue</button>
                                                </div>
                                                <div id="vmo-promo-queue" class="vmo-promo-queue-list">
                                                    <div class="vmo-promo-empty">No posts in the queue yet.</div>
                                                </div>
                                            </div>
                                        </div>

                                        <div class="nav-link" onclick="togglePanel('vmo-promo-engagement-panel', window.loadPromotionPanel)">
                                            <div class="nav-icon"></div>
                                            <div class="nav-text">Engagement Guidance</div>
                                        </div>
                                        <div id="vmo-promo-engagement-panel" class="vmo-card" style="display:none;">
                                            <div class="vmo-promo-mini-grid">
                                                <button class="action-btn" type="button" onclick="vmoPromotionGenerateEngagement('questions')">Suggest engagement questions</button>
                                                <button class="action-btn" type="button" onclick="vmoPromotionGenerateEngagement('topics')">Suggest audience-attracting topics</button>
                                                <button class="action-btn" type="button" onclick="vmoPromotionGenerateEngagement('growth_tactics')">Suggest follower-growth tactics</button>
                                                <button class="action-btn" type="button" onclick="vmoPromotionGenerateEngagement('reply_guidance')">Create reply guidance drafts</button>
                                            </div>
                                            <div style="margin-top:14px;">
                                                <h4 style="margin-bottom:8px;">AI engagement output</h4>
                                                <div id="vmo-promo-engagement-output" class="vmo-promo-result-list">
                                                    <div class="vmo-promo-empty">No engagement guidance generated yet.</div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                                <div class="vmo-card">
                                    <h4>Advertising & Marketing Command Center (Coming Soon)</h4>
                                    <p>This future lane now previews the broader advertising stack as well. It stays locked for this release, but the credential model has been extended so social and paid-media requirements can be collected together ahead of the next update.</p>
                                    <div class="vmo-promo-mini-grid" style="margin-top:12px;">
                                        <div class="vmo-promo-mini-card"><strong>Search Advertising</strong><p>Keyword campaigns, landing-page mapping, conversion routing, and budget pacing.</p></div>
                                        <div class="vmo-promo-mini-card"><strong>Social Ads & Boosted Posts</strong><p>Ad-account readiness, campaign structure, promoted-content routing, and audience targeting.</p></div>
                                        <div class="vmo-promo-mini-card"><strong>Streaming / TV / Video</strong><p>Video inventory planning, media requirements, placement approvals, and budget allocation.</p><span style="display:inline-block;margin-top:6px;padding:3px 10px;border-radius:8px;background:rgba(16,185,129,.18);color:#10b981;font-size:11px;font-weight:600;">Vibe.co — Available</span></div>
                                        <div class="vmo-promo-mini-card"><strong>Premium Media</strong><p>Higher-tier placements, branded media buys, publication targeting, and sponsor approvals.</p></div>
                                        <div class="vmo-promo-mini-card"><strong>PR & Sponsored</strong><p>Sponsored content workflows, publication outreach, and campaign-specific approval routing.</p></div>
                                        <div class="vmo-promo-mini-card"><strong>Budget & Allocation</strong><p>Cross-channel budget planning, approval checkpoints, and future spend controls.</p></div>
                                    </div>
                                    <div style="margin-top:14px;">
                                        <h4 style="margin-bottom:8px;">Future media scope</h4>
                                        <div class="vmo-promo-chiplist">
                                            <span class="vmo-promo-chip" style="background:rgba(16,185,129,.22);color:#10b981;border-color:rgba(16,185,129,.4);">Vibe.co (CTV / Streaming TV)</span>
                                            <span class="vmo-promo-chip">Google</span>
                                            <span class="vmo-promo-chip">YouTube</span>
                                            <span class="vmo-promo-chip">Prime Video</span>
                                            <span class="vmo-promo-chip">Roku</span>
                                            <span class="vmo-promo-chip">Forbes</span>
                                            <span class="vmo-promo-chip">Bloomberg</span>
                                            <span class="vmo-promo-chip">CNN</span>
                                            <span class="vmo-promo-chip">Fox</span>
                                            <span class="vmo-promo-chip">Sponsored Articles</span>
                                            <span class="vmo-promo-chip">Magazines</span>
                                            <span class="vmo-promo-chip">Newspapers</span>
                                            <span class="vmo-promo-chip">TV Networks</span>
                                        </div>
                                    </div>
                                    <div style="margin-top:14px;">
                                        <h4 style="margin-bottom:8px;">Advertising credential readiness</h4>
                                        <div id="vmo-promo-marketing-provider-matrix" class="vmo-promo-result-list">
                                            <div class="vmo-promo-empty">Advertising readiness data will appear here once the promotion services load.</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- Shipping & Fulfillment Section -->
                        <div id="shipping" class="vmo-section">
                            <div class="nav-section">
                                <h4>🚚 Shipping & Fulfillment</h4>
                                <div class="nav-links">
                                    
                                    <!-- Active Orders Panel -->
                                    <div class="nav-link" onclick="if(!vmoGateCheck('shipping_management'))return;togglePanel('vmo-active-orders-panel', window.loadActiveOrdersPanel)" title="Orders that are paid and ready to ship. Open to view, approve shipping, or inspect details.">
                                        <div class="nav-icon">📦</div>
                                        <div class="nav-text">Active Orders</div>
                                        <div class="nav-badge" id="vmo-active-orders-count">—</div>
                                    </div>
                                    <div id="vmo-active-orders-panel" class="vmo-card" style="display:none;">
                                        <h4>Orders Pending Shipment</h4>
                                        <div id="vmo-active-orders-list">
                                            <div class="vmo-card"><p>Loading active orders...</p></div>
                                        </div>
                                        <div style="margin-top: 12px; display: flex; gap: 8px;">
                                            <button class="action-btn" onclick="window.refreshActiveOrders()" title="Reload the latest orders awaiting shipment.">🔄 Refresh</button>
                                            <button class="action-btn primary compact" onclick="window.openBulkShippingModal()" title="Process multiple pending orders in one flow (bulk approve).">📋 Bulk Process</button>
                                        </div>
                                    </div>

                                    <!-- Shipping Settings Panel -->
                                    <div class="nav-link" onclick="if(!vmoGateCheck('shipping_management'))return;togglePanel('vmo-shipping-settings-panel', window.loadShippingSettingsPanel)" title="Enable the carriers and fulfillment partners you want available, then save.">
                                        <div class="nav-icon">⚙️</div>
                                        <div class="nav-text">Shipping Settings</div>
                                        <div class="nav-badge" id="vmo-carriers-count">—</div>
                                    </div>
                                    <div id="vmo-shipping-settings-panel" class="vmo-card" style="display:none;">
                                        <h4>Carrier & Fulfillment Configuration</h4>
                                        <div id="vmo-shipping-config">
                                            <div class="vmo-cards">
                                                <div class="vmo-card">
                                                    <h5>Global Carriers</h5>
                                                    <div class="shipping-carrier-list" id="vmo-global-carrier-list">
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="fedex-enabled" title="Enable FedEx as an available carrier.">
                                                            <label for="fedex-enabled">
                                                                <strong>FedEx Global</strong>
                                                                <small>220+ countries & territories</small>
                                                                <div class="vmo-provider-contacts" data-provider="fedex"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('fedex')" title="Configure FedEx settings (credentials/default service).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="ups-enabled" title="Enable UPS as an available carrier.">
                                                            <label for="ups-enabled">
                                                                <strong>UPS Worldwide</strong>
                                                                <small>220+ countries & territories</small>
                                                                <div class="vmo-provider-contacts" data-provider="ups"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('ups')" title="Configure UPS settings (credentials/default service).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="dhl-enabled" title="Enable DHL as an available carrier.">
                                                            <label for="dhl-enabled">
                                                                <strong>DHL Express</strong>
                                                                <small>Global leader - 220+ countries</small>
                                                                <div class="vmo-provider-contacts" data-provider="dhl"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('dhl')" title="Configure DHL settings (credentials/default service).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="usps-enabled" title="Enable USPS as an available carrier.">
                                                            <label for="usps-enabled">
                                                                <strong>USPS International</strong>
                                                                <small>190+ countries via postal systems</small>
                                                                <div class="vmo-provider-contacts" data-provider="usps"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('usps')" title="Configure USPS settings (if required).">⚙️</button>
                                                        </div>
                                                    </div>
                                                </div>
                                                <div class="vmo-card">
                                                    <h5>Regional Specialists</h5>
                                                    <div class="shipping-carrier-list" id="vmo-regional-carrier-list">
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="aramex-enabled" title="Enable Aramex for Middle East & Africa coverage.">
                                                            <label for="aramex-enabled">
                                                                <strong>Aramex</strong>
                                                                <small>Middle East & Africa specialist</small>
                                                                <div class="vmo-provider-contacts" data-provider="aramex"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('aramex')" title="Configure Aramex settings (credentials/default service).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="tnt-enabled" title="Enable TNT (FedEx) for Europe/Asia-Pacific routes.">
                                                            <label for="tnt-enabled">
                                                                <strong>TNT (FedEx)</strong>
                                                                <small>Europe & Asia-Pacific focus</small>
                                                                <div class="vmo-provider-contacts" data-provider="tnt"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('tnt')" title="Configure TNT settings (credentials/default service).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="sf-express-enabled" title="Enable SF Express for Asia-Pacific and China coverage.">
                                                            <label for="sf-express-enabled">
                                                                <strong>SF Express</strong>
                                                                <small>Asia-Pacific & China specialist</small>
                                                                <div class="vmo-provider-contacts" data-provider="sf-express"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('sf-express')" title="Configure SF Express settings (credentials/default service).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="correios-enabled" title="Enable Correios for Brazil/South America coverage.">
                                                            <label for="correios-enabled">
                                                                <strong>Correios</strong>
                                                                <small>Brazil & South America</small>
                                                                <div class="vmo-provider-contacts" data-provider="correios"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('correios')" title="Configure Correios settings (if required).">⚙️</button>
                                                        </div>
                                                        <div class="carrier-item">
                                                            <input type="checkbox" id="ems-enabled" title="Enable EMS for postal express shipping across partner countries.">
                                                            <label for="ems-enabled">
                                                                <strong>EMS Global</strong>
                                                                <small>Postal network - 180+ countries</small>
                                                                <div class="vmo-provider-contacts" data-provider="ems"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureCarrier('ems')" title="Configure EMS settings (if required).">⚙️</button>
                                                        </div>
                                                    </div>
                                                </div>
                                                <div class="vmo-card">
                                                    <h5>Global Fulfillment Networks</h5>
                                                    <div class="fulfillment-center-list" id="vmo-fulfillment-list">
                                                        <div class="fulfillment-item">
                                                            <input type="checkbox" id="shipbob-enabled" title="Enable ShipBob so orders can be routed to their network for fulfillment.">
                                                            <label for="shipbob-enabled">
                                                                <strong>ShipBob Global</strong>
                                                                <small>US, EU, UK, Canada, Australia</small>
                                                                <div class="vmo-provider-contacts" data-provider="shipbob"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureFulfillment('shipbob')" title="Configure ShipBob settings (sync frequency, auto-fulfill, etc.).">⚙️</button>
                                                        </div>
                                                        <div class="fulfillment-item">
                                                            <input type="checkbox" id="amazon-fba-enabled" title="Enable Amazon FBA as a fulfillment option for eligible inventory.">
                                                            <label for="amazon-fba-enabled">
                                                                <strong>Amazon FBA Global</strong>
                                                                <small>20+ countries with FBA</small>
                                                                <div class="vmo-provider-contacts" data-provider="amazon-fba"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureFulfillment('amazon-fba')" title="Configure Amazon FBA settings (sync, automation).">⚙️</button>
                                                        </div>
                                                        <div class="fulfillment-item">
                                                            <input type="checkbox" id="easyship-enabled" title="Enable Easyship as an aggregation/fulfillment partner (if used).">
                                                            <label for="easyship-enabled">
                                                                <strong>Easyship</strong>
                                                                <small>Global shipping solutions</small>
                                                                <div class="vmo-provider-contacts" data-provider="easyship"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureFulfillment('easyship')" title="Configure Easyship settings (sync, automation).">⚙️</button>
                                                        </div>
                                                        <div class="fulfillment-item">
                                                            <input type="checkbox" id="flexport-enabled" title="Enable Flexport as a freight/fulfillment option (if used).">
                                                            <label for="flexport-enabled">
                                                                <strong>Flexport</strong>
                                                                <small>Global freight & fulfillment</small>
                                                                <div class="vmo-provider-contacts" data-provider="flexport"></div>
                                                            </label>
                                                            <button class="action-btn" onclick="window.configureFulfillment('flexport')" title="Configure Flexport settings (sync, automation).">⚙️</button>
                                                        </div>
                                                    </div>
                                                </div>
                                                    </div>
                                                </div>
                                                <div class="vmo-card">
                                                    <h5>🏪 Custom Shipping Companies</h5>
                                                    <div class="custom-carrier-section">
                                                        <div style="margin-bottom: 12px; padding: 8px; background: rgba(15,225,255,0.05); border-radius: 6px; border: 1px dashed var(--rim);">
                                                            <p style="font-size: 12px; color: var(--muted); margin: 0;">
                                                                💡 Add local shipping companies that might offer better rates or coverage in your region
                                                            </p>
                                                        </div>
                                                        
                                                        <div id="vmo-custom-carriers-list">
                                                            <!-- Custom carriers will be loaded here -->
                                                            <div class="custom-carrier-placeholder" style="padding: 16px; text-align: center; color: var(--muted); border: 2px dashed var(--border); border-radius: 8px;">
                                                                No custom carriers configured
                                                            </div>
                                                        </div>
                                                        
                                                        <div style="margin-top: 12px; display:flex; gap:8px;">
                                                            <button class="action-btn primary" onclick="window.openAddCustomCarrierModal()" title="Add a local/regional carrier not listed above.">
                                                                ➕ Add Custom Carrier
                                                            </button>
                                                            <button class="action-btn" onclick="window.importCarrierFromAPI()" title="Connect a carrier API or aggregator (advanced). If you don’t have credentials, you can skip this.">
                                                                🔗 Connect API
                                                            </button>
                                                        </div>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                        <div style="margin-top: 12px; display: flex; gap: 8px;">
                                            <button class="action-btn primary" onclick="window.saveShippingSettings(event)" title="Save your carrier + fulfillment selections.">💾 Save Settings</button>
                                            <button class="action-btn" onclick="window.testShippingIntegration()" title="Run a quick connectivity check for enabled shipping integrations.">🔗 Check Connections</button>
                                        </div>
                                    </div>

                                    <!-- Global Shipping Configuration Panel -->
                                    <div class="nav-link" onclick="togglePanel('vmo-global-shipping-panel', window.loadGlobalShippingPanel)" title="Configure worldwide carrier coverage and trade settings used by the AI.">
                                        <div class="nav-icon">🌍</div>
                                        <div class="nav-text">Global Configuration</div>
                                        <div class="nav-badge" id="vmo-global-regions-count">—</div>
                                    </div>
                                    <div id="vmo-global-shipping-panel" class="vmo-card" style="display:none;">
                                        <h4>Global Shipping Configuration</h4>
                                        <div class="vmo-cards">
                                            <div class="vmo-card">
                                                <h5>🌏 Asia-Pacific Region</h5>
                                                <div class="shipping-region-config">
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="asia-sf-express" title="Enable this carrier for destinations in this region.">
                                                        <label for="asia-sf-express">
                                                            <strong>SF Express</strong> - China, Hong Kong, Singapore, Malaysia
                                                        </label>
                                                        <span class="carrier-coverage">95% coverage</span>
                                                    </div>
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="asia-japan-post" title="Enable this carrier for destinations in this region.">
                                                        <label for="asia-japan-post">
                                                            <strong>Japan Post</strong> - Japan domestic & international
                                                        </label>
                                                        <span class="carrier-coverage">100% Japan</span>
                                                    </div>
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="asia-australia-post" title="Enable this carrier for destinations in this region.">
                                                        <label for="asia-australia-post">
                                                            <strong>Australia Post</strong> - Australia & Oceania
                                                        </label>
                                                        <span class="carrier-coverage">100% AUS</span>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="vmo-card">
                                                <h5>🌍 Africa & Middle East</h5>
                                                <div class="shipping-region-config">
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="africa-aramex" title="Enable this carrier for destinations in this region.">
                                                        <label for="africa-aramex">
                                                            <strong>Aramex</strong> - UAE, Saudi Arabia, Egypt, Kenya
                                                        </label>
                                                        <span class="carrier-coverage">80% coverage</span>
                                                    </div>
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="africa-fastway" title="Enable this carrier for destinations in this region.">
                                                        <label for="africa-fastway">
                                                            <strong>Fastway</strong> - South Africa, Nigeria, Ghana
                                                        </label>
                                                        <span class="carrier-coverage">65% coverage</span>
                                                    </div>
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="africa-posta" title="Enable this carrier for destinations in this region.">
                                                        <label for="africa-posta">
                                                            <strong>Posta Plus</strong> - East Africa corridor
                                                        </label>
                                                        <span class="carrier-coverage">70% coverage</span>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="vmo-card">
                                                <h5>🌎 South America</h5>
                                                <div class="shipping-region-config">
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="sa-correios" title="Enable this carrier for destinations in this region.">
                                                        <label for="sa-correios">
                                                            <strong>Correios</strong> - Brazil nationwide
                                                        </label>
                                                        <span class="carrier-coverage">100% Brazil</span>
                                                    </div>
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="sa-mercado" title="Enable this carrier for destinations in this region.">
                                                        <label for="sa-mercado">
                                                            <strong>MercadoEnvíos</strong> - Argentina, Chile, Colombia
                                                        </label>
                                                        <span class="carrier-coverage">85% coverage</span>
                                                    </div>
                                                    <div class="region-carrier-item">
                                                        <input type="checkbox" id="sa-chilexpress" title="Enable this carrier for destinations in this region.">
                                                        <label for="sa-chilexpress">
                                                            <strong>Chilexpress</strong> - Chile domestic
                                                        </label>
                                                        <span class="carrier-coverage">100% Chile</span>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="vmo-card">
                                                <h5>🚢 International Trade Settings</h5>
                                                <div class="trade-settings">
                                                    <div class="setting-item">
                                                        <label>
                                                            <input type="checkbox" id="auto-customs" title="When enabled, the AI will generate customs forms for international shipments.">
                                                            <strong>Automatic Customs Documentation</strong>
                                                        </label>
                                                        <small>AI generates customs forms and commercial invoices</small>
                                                    </div>
                                                    <div class="setting-item">
                                                        <label>
                                                            <input type="checkbox" id="duty-calc" title="When enabled, the AI will estimate duties/taxes (where possible) to reduce delivery surprises.">
                                                            <strong>Duty & Tax Calculator</strong>
                                                        </label>
                                                        <small>Show customers estimated duties at checkout</small>
                                                    </div>
                                                    <div class="setting-item">
                                                        <label>
                                                            <input type="checkbox" id="restricted-items" title="When enabled, the AI will flag restricted items by destination (best-effort).">
                                                            <strong>Restricted Items Detection</strong>
                                                        </label>
                                                        <small>AI blocks shipments with restricted items by destination</small>
                                                    </div>
                                                    <div class="setting-item">
                                                        <label>
                                                            <input type="checkbox" id="currency-hedge" title="When enabled, the AI applies basic currency protection logic for cross-border shipping costs.">
                                                            <strong>Currency Hedging</strong>
                                                        </label>
                                                        <small>Protect against exchange rate fluctuations</small>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                        <div style="margin-top: 12px; display: flex; gap: 8px;">
                                            <button class="action-btn" onclick="window.saveGlobalShippingSettings()" title="Save region and trade settings used for worldwide shipping.">🌍 Save Global Settings</button>
                                            <button class="action-btn" onclick="window.testGlobalConnectivity()" title="Test carrier connectivity and display results (best-effort)." style="background: #6f42c1;">🧪 Verify Regional Coverage</button>
                                        </div>
                                    </div>

                                    <!-- Shipping Analytics Panel -->
                                    <div class="nav-link" onclick="togglePanel('vmo-shipping-analytics-panel', window.loadShippingAnalyticsPanel)" title="Shipping performance metrics and cost breakdown.">
                                        <div class="nav-icon">📊</div>
                                        <div class="nav-text">Shipping Analytics</div>
                                        <div class="nav-badge" id="vmo-shipped-this-week">—</div>
                                    </div>
                                    <div id="vmo-shipping-analytics-panel" class="vmo-card" style="display:none;">
                                        <h4>Shipping Performance</h4>
                                        <div class="vmo-kv"><span>Orders shipped this week</span><strong id="vmo-shipping-week-count">—</strong></div>
                                        <div class="vmo-kv"><span>Average fulfillment time</span><strong id="vmo-avg-fulfillment-time">—</strong></div>
                                        <div class="vmo-kv"><span>Shipping cost savings (AI)</span><strong id="vmo-shipping-savings">—</strong></div>
                                        <div class="vmo-kv"><span>On-time delivery rate</span><strong id="vmo-delivery-rate">—</strong></div>
                                        
                                        <div style="margin-top: 12px;">
                                            <h5>Shipping Cost Breakdown</h5>
                                            <div id="vmo-shipping-costs-chart" style="height: 120px; background: rgba(255,255,255,0.04); border-radius: 6px; display: flex; align-items: center; justify-content: center; color: var(--muted);">
                                                Chart loading...
                                            </div>
                                        </div>
                                    </div>

                                    <!-- AI Shipping Recommendations Panel -->
                                    <div class="nav-link" onclick="togglePanel('vmo-shipping-ai-panel', window.loadShippingAIPanel)" title="AI suggestions to reduce shipping costs, improve delivery times, and expand coverage.">
                                        <div class="nav-icon">🤖</div>
                                        <div class="nav-text">AI Recommendations</div>
                                        <div class="nav-badge" id="vmo-ai-shipping-recommendations">—</div>
                                    </div>
                                    <div id="vmo-shipping-ai-panel" class="vmo-card" style="display:none;">
                                        <h4>AI-Powered Shipping Optimization</h4>
                                        <div id="vmo-shipping-ai-recommendations">
                                            <div class="vmo-card">
                                                <p style="color: var(--muted);">Loading AI shipping recommendations...</p>
                                            </div>
                                        </div>
                                        <div style="margin-top: 12px; display: flex; gap: 8px;">
                                            <button class="action-btn" onclick="window.generateShippingRecommendations(event)" title="Ask the AI to generate new shipping optimizations based on recent orders.">🧠 Generate New</button>
                                            <button class="action-btn primary compact" onclick="window.applyAllShippingOptimizations(event)" title="Apply all AI-recommended shipping optimizations at once.">✅ Apply All</button>
                                        </div>
                                    </div>

                                    <!-- ═══ Carrier Discovery Panel ═══ -->
                                    <div class="nav-link" onclick="if(!vmoGateCheck('carrier_discovery'))return;togglePanel('vmo-carrier-discovery-panel')" title="Find the best carriers for your shipping location and see onboarding steps.">
                                        <div class="nav-icon">🔍</div>
                                        <div class="nav-text">Discover Carriers</div>
                                        <div class="nav-badge" style="background:rgba(124,92,255,.18);color:#7c5cff">NEW</div>
                                    </div>
                                    <div id="vmo-carrier-discovery-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">🔍 Carrier Discovery</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:12px">Enter your shipping origin country to see recommended carriers and setup instructions.</p>
                                        <div style="display:flex;gap:8px;align-items:flex-end;margin-bottom:16px">
                                            <div style="flex:1">
                                                <label style="font-size:11px;color:var(--muted);display:block;margin-bottom:4px">Country Code</label>
                                                <select id="vmo-discover-country" style="width:100%;padding:8px 10px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:8px;color:var(--ink);font-size:13px">
                                                    <option value="">Select country…</option>
                                                    <option value="US">🇺🇸 United States</option>
                                                    <option value="CA">🇨🇦 Canada</option>
                                                    <option value="GB">🇬🇧 United Kingdom</option>
                                                    <option value="DE">🇩🇪 Germany</option>
                                                    <option value="FR">🇫🇷 France</option>
                                                    <option value="AU">🇦🇺 Australia</option>
                                                    <option value="JP">🇯🇵 Japan</option>
                                                    <option value="CN">🇨🇳 China</option>
                                                    <option value="IN">🇮🇳 India</option>
                                                    <option value="BR">🇧🇷 Brazil</option>
                                                    <option value="MX">🇲🇽 Mexico</option>
                                                    <option value="AE">🇦🇪 UAE</option>
                                                    <option value="SA">🇸🇦 Saudi Arabia</option>
                                                    <option value="NG">🇳🇬 Nigeria</option>
                                                    <option value="ZA">🇿🇦 South Africa</option>
                                                    <option value="KE">🇰🇪 Kenya</option>
                                                    <option value="GH">🇬🇭 Ghana</option>
                                                    <option value="EG">🇪🇬 Egypt</option>
                                                    <option value="SG">🇸🇬 Singapore</option>
                                                    <option value="KR">🇰🇷 South Korea</option>
                                                    <option value="NL">🇳🇱 Netherlands</option>
                                                    <option value="SE">🇸🇪 Sweden</option>
                                                    <option value="IT">🇮🇹 Italy</option>
                                                    <option value="ES">🇪🇸 Spain</option>
                                                    <option value="AR">🇦🇷 Argentina</option>
                                                    <option value="CL">🇨🇱 Chile</option>
                                                    <option value="CO">🇨🇴 Colombia</option>
                                                    <option value="NZ">🇳🇿 New Zealand</option>
                                                </select>
                                            </div>
                                            <button class="action-btn primary" onclick="window.vmoDiscoverCarriers()" style="height:38px">🔍 Discover</button>
                                        </div>
                                        <div id="vmo-carrier-discovery-results" style="display:none">
                                            <div style="margin-bottom:10px">
                                                <h5 style="color:var(--cyan-soft);font-size:13px;margin-bottom:8px">⭐ Recommended for Your Region</h5>
                                                <div id="vmo-recommended-carriers" class="vmo-cards" style="gap:8px"></div>
                                            </div>
                                            <div>
                                                <h5 style="color:var(--muted);font-size:13px;margin-bottom:8px">Other Available Carriers</h5>
                                                <div id="vmo-other-carriers" class="vmo-cards" style="gap:8px"></div>
                                            </div>
                                        </div>
                                    </div>

                                    <!-- ═══ Manual Delivery Panel ═══ -->
                                    <div class="nav-link" onclick="togglePanel('vmo-manual-delivery-panel', window.vmoLoadManualDeliveries)" title="Manage orders you deliver yourself — track status, add notes, mark delivered.">
                                        <div class="nav-icon">🚗</div>
                                        <div class="nav-text">Manual Delivery</div>
                                        <div class="nav-badge" id="vmo-manual-delivery-count">—</div>
                                    </div>
                                    <div id="vmo-manual-delivery-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">🚗 Manual / Self-Delivery</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:12px">For orders you deliver personally. Update status as you go — customers see live tracking.</p>
                                        <div id="vmo-manual-delivery-list">
                                            <div style="padding:16px;text-align:center;color:var(--muted);border:2px dashed var(--border);border-radius:8px">
                                                Loading manual deliveries…
                                            </div>
                                        </div>
                                        <div style="margin-top:12px;display:flex;gap:8px">
                                            <button class="action-btn" onclick="window.vmoLoadManualDeliveries()" title="Refresh your manual delivery list.">🔄 Refresh</button>
                                        </div>
                                    </div>

                                    <!-- ═══ Delivery Pipeline Panel ═══ -->
                                    <div class="nav-link" onclick="togglePanel('vmo-delivery-pipeline-panel', window.vmoLoadDeliveryPipeline)" title="Visual pipeline of all orders by fulfillment stage.">
                                        <div class="nav-icon">📋</div>
                                        <div class="nav-text">Delivery Pipeline</div>
                                        <div class="nav-badge" id="vmo-pipeline-total">—</div>
                                    </div>
                                    <div id="vmo-delivery-pipeline-panel" class="vmo-card" style="display:none;">
                                        <h4 style="color:var(--cyan-soft)">📋 Delivery Pipeline</h4>
                                        <p style="font-size:12px;color:var(--muted);margin-bottom:12px">All orders grouped by fulfillment stage.</p>
                                        <div id="vmo-delivery-pipeline-stages" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:10px">
                                            <!-- Stages populated by JS -->
                                        </div>
                                        <div style="margin-top:14px">
                                            <h5 style="color:var(--cyan-soft);font-size:13px;margin-bottom:8px">Orders</h5>
                                            <div id="vmo-pipeline-order-list">
                                                <div style="padding:12px;text-align:center;color:var(--muted)">Select a stage above or loading…</div>
                                            </div>
                                        </div>
                                        <div style="margin-top:12px;display:flex;gap:8px">
                                            <button class="action-btn" onclick="window.vmoLoadDeliveryPipeline()" title="Refresh pipeline view.">🔄 Refresh</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- Documents Section (card layout with rich toggle panels) -->
                        <div id="documents" class="vmo-section">
                            <div class="nav-section">
                                <h4>📄 Business Documents</h4>
                                <div class="vmo-cards">
                                    <div class="vmo-card">
                                        <h4>Legal Documents</h4>
                                        <div class="nav-links" style="gap: 6px;">
                                            <!-- Privacy Policy toggle -->
                                            <div class="nav-link doc-toggle" data-doc="privacy" style="padding: 8px 10px;">
                                                <div class="nav-text" style="font-size: 12px;">Privacy Policy</div>
                                            </div>
                                            <div id="doc-panel-privacy" class="doc-panel" style="display:none;">
                                                <h5>Privacy Policy</h5>
                                                <p>Standard website privacy policy with disclosures on data usage, cookies, and contact information.</p>
                                                <div class="vmo-kv"><span>Format</span><strong>PDF or DOCX</strong></div>
                                                <div class="vmo-kv"><span>Last generated</span><strong id="doc-privacy-last">—</strong></div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button class="action-btn" type="button" onclick="downloadDoc('privacy','pdf')">⬇️ PDF</button>
                                                    <button class="action-btn" type="button" onclick="downloadDoc('privacy','docx')">⬇️ DOCX</button>
                                                </div>
                                            </div>

                                            <!-- Terms of Service toggle -->
                                            <div class="nav-link doc-toggle" data-doc="terms" style="padding: 8px 10px;">
                                                <div class="nav-text" style="font-size: 12px;">Terms of Service</div>
                                            </div>
                                            <div id="doc-panel-terms" class="doc-panel" style="display:none;">
                                                <h5>Terms of Service</h5>
                                                <p>Usage rules, disclaimers, liability limits, and governing law for your website or service.</p>
                                                <div class="vmo-kv"><span>Format</span><strong>PDF or DOCX</strong></div>
                                                <div class="vmo-kv"><span>Last generated</span><strong id="doc-terms-last">—</strong></div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button class="action-btn" type="button" onclick="downloadDoc('terms','pdf')">⬇️ PDF</button>
                                                    <button class="action-btn" type="button" onclick="downloadDoc('terms','docx')">⬇️ DOCX</button>
                                                </div>
                                            </div>

                                            <!-- Service Agreement toggle -->
                                            <div class="nav-link doc-toggle" data-doc="service" style="padding: 8px 10px;">
                                                <div class="nav-text" style="font-size: 12px;">Service Agreement</div>
                                            </div>
                                            <div id="doc-panel-service" class="doc-panel" style="display:none;">
                                                <h5>Service Agreement</h5>
                                                <p>Defines scope, deliverables, timelines, and acceptance for service engagements.</p>
                                                <div class="vmo-kv"><span>Format</span><strong>PDF or DOCX</strong></div>
                                                <div class="vmo-kv"><span>Last generated</span><strong id="doc-service-last">—</strong></div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button class="action-btn" type="button" onclick="downloadDoc('service','pdf')">⬇️ PDF</button>
                                                    <button class="action-btn" type="button" onclick="downloadDoc('service','docx')">⬇️ DOCX</button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    <div class="vmo-card">
                                        <h4>Strategic Documents</h4>
                                        <div class="nav-links" style="gap: 6px;">
                                            <!-- Business Plan toggle -->
                                            <div class="nav-link doc-toggle" data-doc="business_plan" style="padding: 8px 10px;">
                                                <div class="nav-text" style="font-size: 12px;">Business Plan</div>
                                            </div>
                                            <div id="doc-panel-business_plan" class="doc-panel" style="display:none;">
                                                <h5>Business Plan</h5>
                                                <p>Executive summary, market sizing, go‑to‑market, and financial model highlights.</p>
                                                <div class="vmo-kv"><span>Format</span><strong>PDF or DOCX</strong></div>
                                                <div class="vmo-kv"><span>Last generated</span><strong id="doc-business_plan-last">—</strong></div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button class="action-btn" type="button" onclick="downloadDoc('business_plan','pdf')">⬇️ PDF</button>
                                                    <button class="action-btn" type="button" onclick="downloadDoc('business_plan','docx')">⬇️ DOCX</button>
                                                </div>
                                            </div>

                                            <!-- Marketing Strategy toggle -->
                                            <div class="nav-link doc-toggle" data-doc="marketing" style="padding: 8px 10px;">
                                                <div class="nav-text" style="font-size: 12px;">Marketing Strategy</div>
                                            </div>
                                            <div id="doc-panel-marketing" class="doc-panel" style="display:none;">
                                                <h5>Marketing Strategy</h5>
                                                <p>Channel mix, budget, messaging pillars, and KPI framework.</p>
                                                <div class="vmo-kv"><span>Format</span><strong>PDF or DOCX</strong></div>
                                                <div class="vmo-kv"><span>Last generated</span><strong id="doc-marketing-last">—</strong></div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button class="action-btn" type="button" onclick="downloadDoc('marketing','pdf')">⬇️ PDF</button>
                                                    <button class="action-btn" type="button" onclick="downloadDoc('marketing','docx')">⬇️ DOCX</button>
                                                </div>
                                            </div>

                                            <!-- Competitive Analysis toggle -->
                                            <div class="nav-link doc-toggle" data-doc="competitive" style="padding: 8px 10px;">
                                                <div class="nav-text" style="font-size: 12px;">Competitive Analysis</div>
                                            </div>
                                            <div id="doc-panel-competitive" class="doc-panel" style="display:none;">
                                                <h5>Competitive Analysis</h5>
                                                <p>Competitor landscape, positioning matrix, and differentiation strategy.</p>
                                                <div class="vmo-kv"><span>Format</span><strong>PDF or DOCX</strong></div>
                                                <div class="vmo-kv"><span>Last generated</span><strong id="doc-competitive-last">—</strong></div>
                                                <div style="display:flex; gap:8px; flex-wrap:wrap;">
                                                    <button class="action-btn" type="button" onclick="downloadDoc('competitive','pdf')">⬇️ PDF</button>
                                                    <button class="action-btn" type="button" onclick="downloadDoc('competitive','docx')">⬇️ DOCX</button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        </div>
                    </div>
                </section>
            </main>
        </div>

        <!-- Footer positioned at bottom of dashboard interface -->
        <footer class="vmo-dashboard-footer">
            <p>
                VMO Strategic Dashboard •
                Next market scan: <span id="vmo-next-scan">Not scheduled</span>
                • Last update: <span id="vmo-last-update">Never</span>
            </p>
        </footer>
    </div>

    <!-- Weekly Briefing Narrative Modal -->
    <div id="weeklyBriefingModal" class="vmo-fs-modal" style="display:none;">
        <div class="vmo-modal-overlay" data-close="weeklyBriefingModal"></div>
        <div class="modal-content vmo-modal-panel">
            <div class="modal-header">
                <h3 class="modal-title">📘 Weekly Briefing Narrative</h3>
                <button class="modal-close" data-close="weeklyBriefingModal" type="button">&times;</button>
            </div>
            <div class="modal-body">
                <p style="color:var(--muted);">AI-generated weekly briefings will appear here when available.</p>
                <div id="weeklyBriefingContent" style="white-space:pre-wrap; line-height:1.55;"></div>
            </div>
        </div>
    </div>

    <!-- Weekly Strategy Actions Modal (kept for actions) -->
    <div id="weeklyActionsModal" class="vmo-fs-modal" style="display:none;">
        <div class="vmo-modal-overlay" data-close="weeklyActionsModal"></div>
        <div class="modal-content vmo-modal-panel">
            <div class="modal-header">
                <h3 class="modal-title">📈 Weekly Strategy Actions</h3>
                <button class="modal-close" data-close="weeklyActionsModal" type="button">&times;</button>
            </div>
            <div class="modal-body">
                <h4 style="color: var(--cyan-soft); margin-top: 0;">Market Intelligence Update</h4>
                <ul id="vmo-weekly-insights" style="margin: 0 0 10px 18px; padding: 0; list-style: disc; color: var(--ink);"></ul>
                <h4 style="color: var(--cyan-soft);">Recommended Actions</h4>
                <div class="task-list" id="vmo-weekly-actions"></div>
                <div style="display: flex; gap: 10px; margin-top: 16px;">
                    <button class="action-btn primary" style="flex: 1;" onclick="approveAllActions()">Approve All Actions</button>
                    <button class="action-btn" style="flex: 1;" onclick="customizeStrategy()">Customize Strategy</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Weekly Briefing Narrative Modal -->
    <div id="weeklyModal" class="vmo-fs-modal" aria-hidden="true" role="dialog" aria-modal="true" style="display:none;">
        <div class="vmo-modal-overlay" data-close="weeklyModal"></div>
        <div class="modal-content vmo-modal-panel">
            <div class="modal-header">
                <h3 class="modal-title" id="vmo-brief-title">📊 Weekly Strategic Briefing</h3>
                <button class="modal-close" data-close="weeklyModal" type="button">&times;</button>
            </div>
            <div class="modal-body">
                <div id="vmo-brief-summary" style="color: var(--muted); margin-bottom: 10px;">Loading…</div>
                <div id="vmo-brief-analysis" style="white-space:pre-wrap; line-height:1.55;"></div>
                <div id="vmo-brief-sections" style="margin-top:14px;"></div>
                <div style="display:flex; gap:10px; margin-top:16px;">
                    <button class="action-btn primary" onclick="viewMarketAnalysis()">View Analysis</button>
                    <button class="action-btn" onclick="showPreviousScansPicker()">Previous Scans</button>
                </div>
                <div id="vmo-brief-history" style="display:none; margin-top:12px; background: var(--panel); border: 1px solid var(--panel-hr); border-radius: 10px; padding: 10px;">
                    <div style="display:flex; gap:8px; align-items:center;">
                        <label for="vmo-scan-select" style="color: var(--muted);">Choose a past scan:</label>
                        <select id="vmo-scan-select" style="flex:1; max-width: 260px;"></select>
                        <button class="action-btn" onclick="loadSelectedScanWeek()">Load</button>
                        <button class="action-btn" onclick="hidePreviousScansPicker()">Cancel</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="vmo-toast-host" id="vmo-toast-host" aria-live="polite" aria-atomic="true"></div>

    <script>
    // Shared constants (define early so all modules can use them safely)
    const VMO_AJAX = (typeof ajaxurl !== 'undefined' && ajaxurl) ? ajaxurl : '<?php echo esc_js(admin_url('admin-ajax.php')); ?>';
    // Provide both admin and builder nonces; some endpoints validate explicitly against one or the other
    const VMO_NONCE_ADMIN   = '<?php echo esc_js(wp_create_nonce('vmo_admin_nonce')); ?>';
    const VMO_NONCE_BUILDER = '<?php echo esc_js(wp_create_nonce('vmo_builder_nonce')); ?>';
    // Back-compat alias used in older code paths (treat as builder by default for stricter endpoints)
    const VMO_NONCE = VMO_NONCE_BUILDER;
    const VMO_DEFAULT_RING_URL = '<?php echo esc_js($vmo_default_ring_url); ?>';
    const VMO_UPLOAD_MANAGER_URL = '<?php echo esc_js(admin_url('upload.php')); ?>';
    const VMO_DOCS_BASE_URL = '<?php echo esc_js($vmo_docs_base_url); ?>';
    const VMO_DOCUMENT_NONCE = VMO_NONCE_ADMIN;

    // Ensure WP REST settings exist for pages that don't enqueue wp-api.
    // Tools mailbox uses wpApiSettings.root/wpApiSettings.nonce.
    try {
        window.wpApiSettings = window.wpApiSettings || {};
        if (!window.wpApiSettings.root) window.wpApiSettings.root = '<?php echo esc_js(esc_url_raw(rest_url())); ?>';
        if (!window.wpApiSettings.nonce) window.wpApiSettings.nonce = '<?php echo esc_js(wp_create_nonce('wp_rest')); ?>';
    } catch (e) { /* no-op */ }
    // Marker: if you see this in the console, the inline script parsed and executed
    try { console.info('[VMO] Strategic Dashboard script loaded'); } catch(e){}

    // ✅ ISSUE 2: Accordion Toggle for Phone System Navigation
    window.togglePhonePanel = function(element, panelName) {
        const accordion = document.getElementById('vmo-phone-nav-accordion');
        if (!accordion) return;

        // Get all nav-link buttons and panels
        const allLinks = accordion.querySelectorAll('.nav-link.accordion-toggle');
        const allPanels = accordion.querySelectorAll('.nav-panel');
        const panelId = 'panel-' + panelName + '-details';
        const panel = document.getElementById(panelId);

        if (!panel) {
            console.warn('[VMO] Panel not found:', panelId);
            return;
        }

        // Check if this panel is already open
        const isOpen = panel.classList.contains('open');

        // Close all panels and remove active class from all links
        allLinks.forEach(link => link.classList.remove('vmo-active'));
        allPanels.forEach(p => {
            p.classList.remove('open');
            p.style.display = 'none';
        });

        // If panel was not open, open it and activate the link
        if (!isOpen) {
            element.classList.add('vmo-active');
            panel.classList.add('open');
            panel.style.display = 'block';

            // Delegate to switchPhonePanel for consistent state/actions
            if (typeof switchPhonePanel === 'function') {
                try {
                    switchPhonePanel(panelName);
                } catch (e) {
                    console.warn('[VMO] switchPhonePanel error:', e);
                }
            } else {
                // Trigger panel-specific data refreshes (fallback)
                try {
                    if (panelName === 'interface') {
                        if (typeof loadPhoneOverview === 'function') loadPhoneOverview();
                        if (typeof loadPhoneAnalytics === 'function') loadPhoneAnalytics();
                    } else if (panelName === 'sms') {
                        if (typeof loadSmsWorkspace === 'function') {
                            loadSmsWorkspace(window.__vmoSmsState && window.__vmoSmsState.activeContact ? window.__vmoSmsState.activeContact : '');
                        }
                    } else if (panelName === 'history') {
                        if (typeof refreshHistory === 'function') refreshHistory(); else if (typeof window.refreshHistory === 'function') window.refreshHistory();
                        if (typeof loadPhoneOverview === 'function') loadPhoneOverview();
                        if (typeof loadPhoneAnalytics === 'function') loadPhoneAnalytics();
                    } else if (panelName === 'reports') {
                        if (typeof vmoLoadActionItems === 'function') vmoLoadActionItems();
                    }
                } catch (e) {
                    console.warn('[VMO] Panel refresh error:', e);
                }
            }

            // Smooth scroll to the panel
            setTimeout(() => {
                panel.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            }, 100);
        }
    };

        // Placement guard: ensure the Documents section lives inside the right-panel canvas
        document.addEventListener('DOMContentLoaded', () => {
            // ── VMO Pay onboarding return detection ──
            try {
                const sp = new URLSearchParams(window.location.search);
                const stripeAction = sp.get('stripe_onboard');
                if (stripeAction === 'return') {
                    // Show success toast
                    const toast = document.createElement('div');
                    toast.style.cssText = 'position:fixed;top:20px;right:20px;z-index:999999;background:linear-gradient(135deg,#0a2a1a,#0d3d22);border:1px solid #0ef;border-radius:12px;padding:16px 24px;color:#fff;font-size:14px;box-shadow:0 8px 32px rgba(0,0,0,.5);max-width:400px;animation:vmoSlideIn .3s ease;';
                    toast.innerHTML = '<div style="display:flex;align-items:center;gap:10px;"><span style="font-size:24px;">✅</span><div><strong style="color:#0ef;">VMO Pay Setup Complete</strong><br><span style="color:#ccc;font-size:12px;">Your payment account has been verified. Payments and payouts are being activated.</span></div></div>';
                    document.body.appendChild(toast);
                    setTimeout(() => { toast.style.opacity = '0'; toast.style.transition = 'opacity .5s'; setTimeout(() => toast.remove(), 500); }, 6000);
                    // Clean URL
                    const cleanUrl = new URL(window.location);
                    cleanUrl.searchParams.delete('stripe_onboard');
                    window.history.replaceState({}, '', cleanUrl.toString());
                } else if (stripeAction === 'refresh_error') {
                    const toast = document.createElement('div');
                    toast.style.cssText = 'position:fixed;top:20px;right:20px;z-index:999999;background:linear-gradient(135deg,#2a1a0a,#3d2200);border:1px solid #f80;border-radius:12px;padding:16px 24px;color:#fff;font-size:14px;box-shadow:0 8px 32px rgba(0,0,0,.5);max-width:400px;';
                    toast.innerHTML = '<div style="display:flex;align-items:center;gap:10px;"><span style="font-size:24px;">⚠️</span><div><strong style="color:#f80;">VMO Pay Setup Incomplete</strong><br><span style="color:#ccc;font-size:12px;">Your onboarding link expired. Please try again from Settings → Payments.</span></div></div>';
                    document.body.appendChild(toast);
                    setTimeout(() => { toast.style.opacity = '0'; toast.style.transition = 'opacity .5s'; setTimeout(() => toast.remove(), 500); }, 8000);
                    const cleanUrl = new URL(window.location);
                    cleanUrl.searchParams.delete('stripe_onboard');
                    window.history.replaceState({}, '', cleanUrl.toString());
                }
            } catch (e) { /* non-critical */ }

            try {
                const docs = document.getElementById('documents');
                const canvas = document.querySelector('.vmo-workspace .vmo-canvas');
                if (docs && canvas && !canvas.contains(docs)) {
                    canvas.appendChild(docs);
                }
            } catch (e) { /* no-op */ }

            // Auto-detect and save user timezone for timezone-aware daily reports
            try {
                const detectedTZ = Intl.DateTimeFormat().resolvedOptions().timeZone;
                const savedTZ = sessionStorage.getItem('vmo_tz_saved');
                if (detectedTZ && detectedTZ !== savedTZ) {
                    const params = new URLSearchParams({
                        action: 'vmo_website_chat',
                        kind: 'sd_ajax',
                        ajax_action: 'vmo_save_user_timezone',
                        security: (typeof VMO_NONCE_BUILDER !== 'undefined' ? VMO_NONCE_BUILDER : VMO_NONCE),
                        nonce: (typeof VMO_NONCE_ADMIN !== 'undefined' ? VMO_NONCE_ADMIN : VMO_NONCE),
                        timezone: detectedTZ
                    });
                    fetch(VMO_AJAX, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params })
                        .then(r => r.json())
                        .then(r => { if (r.success) sessionStorage.setItem('vmo_tz_saved', detectedTZ); })
                        .catch(() => {});
                }
            } catch (e) { /* timezone detection not critical */ }
        });

        // Document URL builder + robust download with logging and graceful fallback
        function constructDocumentUrl(slug, format = 'pdf') {
            const safeSlug = String(slug || 'document').replace(/[^a-z0-9_-]+/gi, '-').toLowerCase();
            const safeFmt = (format === 'docx') ? 'docx' : 'pdf';
            const base = (typeof VMO_DOCS_BASE_URL === 'string' && VMO_DOCS_BASE_URL) ? VMO_DOCS_BASE_URL.replace(/\/$/, '') : '';
            return base ? `${base}/${safeSlug}.${safeFmt}` : '';
        }

        window.downloadDoc = async function(docType, format = 'pdf') {
            try {
                const fmt = (format === 'docx') ? 'docx' : 'pdf';
                const url = constructDocumentUrl(docType, fmt);

                // Fire-and-forget log (non-blocking)
                try {
                    const form = new URLSearchParams();
                    form.append('action', 'vmo_documents_log_download');
                    form.append('_ajax_nonce', VMO_DOCUMENT_NONCE);
                    form.append('doc_type', String(docType||''));
                    form.append('format', fmt);
                    fetch(VMO_AJAX, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: form.toString() }).catch(()=>{});
                } catch(_) {}

                const nameMap = {
                    privacy: 'Privacy-Policy',
                    terms: 'Terms-of-Service',
                    service: 'Service-Agreement',
                    business_plan: 'Business-Plan',
                    marketing: 'Marketing-Strategy',
                    competitive: 'Competitive-Analysis'
                };
                const base = nameMap[docType] || 'Document';
                const filename = `${base}.${fmt}`;

                if (url) {
                    // Force-download (fetch->blob->a[download]) to avoid opening new tabs
                    try {
                        const res = await fetch(url, { method: 'GET' });
                        if (res && res.ok) {
                            const blob = await res.blob();
                            const blobUrl = URL.createObjectURL(blob);
                            const a = document.createElement('a');
                            a.href = blobUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                            a.remove();
                            setTimeout(() => URL.revokeObjectURL(blobUrl), 1200);
                            return;
                        }
                    } catch (_) {
                        // fall through to local placeholder
                    }
                }
            } catch(_) {}

            // Fallback: generate a lightweight placeholder PDF blob
            const nameMap = {
                privacy: 'Privacy-Policy',
                terms: 'Terms-of-Service',
                service: 'Service-Agreement',
                business_plan: 'Business-Plan',
                marketing: 'Marketing-Strategy',
                competitive: 'Competitive-Analysis'
            };
            const base = nameMap[docType] || 'Document';
            if (format === 'docx') {
                showToast('DOCX not available locally. Downloading PDF preview instead.', 'info');
            }
            const filename = `${base}.pdf`;
            const content = `VMO Preview\n\n${base}\nGenerated: ${new Date().toLocaleString()}\n\nConnect VMO Document Service for branded, production-ready PDFs & DOCX.`;
            const blob = new Blob([content], { type: 'application/pdf' });
            const blobUrl = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = blobUrl; a.download = filename; document.body.appendChild(a); a.click(); a.remove();
            setTimeout(() => URL.revokeObjectURL(blobUrl), 1200);
        }

        function bindDocumentToggles() {
            const docs = document.getElementById('documents');
            if (!docs) return;
            const toggles = docs.querySelectorAll('.doc-toggle');
            toggles.forEach(t => {
                t.addEventListener('click', () => {
                    const slug = t.dataset.doc;
                    const panel = docs.querySelector(`#doc-panel-${slug}`);
                    const isOpen = panel && panel.style.display !== 'none';
                    // Close all panels first
                    docs.querySelectorAll('.doc-panel').forEach(p => { p.style.display = 'none'; p.classList.remove('active'); });
                    docs.querySelectorAll('.doc-toggle').forEach(btn => btn.classList.remove('expanded'));
                    if (!isOpen && panel) {
                        panel.style.display = 'flex';
                        panel.classList.add('active');
                        t.classList.add('expanded');
                    }
                });
            });
        }

        // Toast notifications
        function showToast(message, variant = 'info') {
            const host = document.getElementById('vmo-toast-host');
            if (!host) return;
            const toast = document.createElement('div');
            toast.className = `vmo-toast vmo-toast-${variant}`;
            toast.textContent = message;
            host.appendChild(toast);
            requestAnimationFrame(() => toast.classList.add('show'));
            setTimeout(() => {
                toast.classList.remove('show');
                setTimeout(() => toast.remove(), 280);
            }, 3600);
        }

        // Global notification helper — hoisted function so it's available
        // everywhere in this script block from the moment parsing completes.
        function notify(msg, type) {
            type = type || 'info';
            if (typeof showToast === 'function') { showToast(msg, type); }
            else { console.log('[VMO]', type, msg); }
        }
        window.notify = notify;

        // AI Document Studio data and helpers

        const DOCUMENT_LIBRARY = [
            {
                id: 'legal_governance',
                title: 'Legal • Governance • Structure',
                summary: 'Keeps the business legitimate, clearly owned, and board-ready.',
                documents: [
                    { id: 'articles_incorporation', title: 'Articles of Incorporation / Organization', summary: 'Establishes your legal existence, ownership structure, and purpose.', priority: 'critical', when: 'Launching or restructuring the business.' },
                    { id: 'operating_agreement', title: 'Operating Agreement / Bylaws', summary: 'Defines decision rights, voting thresholds, officer roles, and amendment rules.', priority: 'critical', when: 'Multi-owner entities or when adding investors.' },
                    { id: 'shareholder_agreement', title: 'Shareholder & Partnership Agreement', summary: 'Clarifies equity splits, exit clauses, drag/tag rights, and dispute resolution.', priority: 'recommended', when: 'Any time equity is shared across partners.' },
                    { id: 'board_resolutions', title: 'Board & Owner Resolutions', summary: 'Records key approvals (banking, financing, leadership changes) for compliance.', priority: 'optional', when: 'Major decisions need a formal corporate record.' }
                ]
            },
            {
                id: 'contracts',
                title: 'Contracts & Agreements',
                summary: 'Binds relationships with suppliers, clients, and collaborators.',
                documents: [
                    { id: 'master_service_agreement', title: 'Master Service Agreement', summary: 'Defines scope, deliverables, liabilities, and acceptance terms for service work.', priority: 'critical', when: 'Engaging recurring or high-value clients.' },
                    { id: 'vendor_contract', title: 'Vendor / Supplier Contract', summary: 'Locks pricing, service levels, termination rights, and warranties.', priority: 'recommended', when: 'Managing inventory, manufacturing, or white-label partners.' },
                    { id: 'nda_mutual', title: 'Mutual Non-Disclosure Agreement (NDA)', summary: 'Protects shared confidential information during negotiations or collaboration.', priority: 'recommended', when: 'Before sharing intellectual property or customer lists.' },
                    { id: 'employment_contract', title: 'Employment & Contractor Agreements', summary: 'Sets role expectations, compensation, IP ownership, and termination clauses.', priority: 'recommended', when: 'Hiring key staff or fractional experts.' }
                ]
            },
            {
                id: 'financial',
                title: 'Financial & Accounting',
                summary: 'Shows fiscal health to leadership, banks, and investors.',
                documents: [
                    { id: 'financial_statements', title: 'Financial Statement Pack', summary: 'Branded balance sheet, income statement, and cash-flow snapshot.', priority: 'critical', when: 'Quarterly reviews, fundraising, or lender requests.' },
                    { id: 'budget_forecast', title: 'Budget & Forecast Workbook', summary: '12-month operating budget with variance tracking and rolling forecast.', priority: 'recommended', when: 'Annual planning or scaling new initiatives.' },
                    { id: 'tax_readiness', title: 'Tax & Compliance Checklist', summary: 'Prepares filings, deductions, and document backups to satisfy auditors.', priority: 'optional', when: 'Approaching fiscal year-end or audit windows.' }
                ]
            },
            {
                id: 'transactional',
                title: 'Transactional • Day-to-Day',
                summary: 'Creates a trail for every sale, purchase, and payment.',
                documents: [
                    { id: 'invoice_template', title: 'Invoice & Receipt Templates', summary: 'Standardizes branding, payment terms, and legal disclosures on invoicing.', priority: 'recommended', when: 'Client-facing billing needs polish and compliance.' },
                    { id: 'purchase_order', title: 'Purchase Order + Delivery Pack', summary: 'Tracks orders, shipments, and acknowledgements to prevent disputes.', priority: 'optional', when: 'Managing physical products or complex procurement.' },
                    { id: 'bank_reconciliation', title: 'Bank Reconciliation Checklist', summary: 'Controls daily cash flow and flags anomalies for leadership fast.', priority: 'optional', when: 'Finance team scaling beyond founders.' }
                ]
            },
            {
                id: 'operations',
                title: 'Operational • Process Excellence',
                summary: 'Codifies how work happens so teams execute consistently.',
                documents: [
                    { id: 'sop_playbook', title: 'Standard Operating Procedure (SOP) Playbook', summary: 'Step-by-step instructions for mission-critical processes and QA.', priority: 'critical', when: 'Onboarding new hires or delegating core work.' },
                    { id: 'training_manual', title: 'Training & Onboarding Manual', summary: 'Role-specific milestones, checklists, and curriculum for new hires.', priority: 'recommended', when: 'Scaling headcount or cross-training teams.' },
                    { id: 'safety_guidelines', title: 'Health, Safety & Quality Guidelines', summary: 'Meets OSHA / industry mandates and reduces incident liability.', priority: 'optional', when: 'Operating physical spaces or regulated environments.' }
                ]
            },
            {
                id: 'strategy',
                title: 'Project • Planning • Strategy',
                summary: 'Builds the roadmap for growth, capital, and execution.',
                documents: [
                    { id: 'business_plan_premium', title: 'Comprehensive Business Plan', summary: 'Executive summary, market sizing, go-to-market, and 3-year pro forma.', priority: 'critical', when: 'Seeking funding, grants, or strategic partners.' },
                    { id: 'marketing_plan', title: 'Integrated Marketing Plan', summary: 'Blends traditional, digital, social, and SEO campaigns with KPIs.', priority: 'critical', when: 'Launching products or entering new markets.' },
                    { id: 'risk_register', title: 'Risk & Contingency Register', summary: 'Prioritized risk log with impact, likelihood, mitigation owners, and triggers.', priority: 'optional', when: 'Complex projects or regulated industries.' }
                ]
            },
            {
                id: 'marketing_sales',
                title: 'Sales • Marketing • Client-Facing',
                summary: 'Equips teams to win deals and communicate value.',
                documents: [
                    { id: 'sales_proposal', title: 'Modular Sales Proposal & Statement of Work', summary: 'Configurable narrative, pricing tables, and acceptance workflow.', priority: 'recommended', when: 'Custom engagements or agency retainers.' },
                    { id: 'campaign_calendar', title: 'Campaign & Content Calendar', summary: '90-day cadence across email, social, paid, and PR touchpoints.', priority: 'recommended', when: 'Coordinating marketing squads or agencies.' },
                    { id: 'case_study_template', title: 'Case Study / Success Story Template', summary: 'Highlights outcomes, metrics, and testimonials for demand gen.', priority: 'optional', when: 'Collecting proof points for credibility.' }
                ]
            },
            {
                id: 'reporting',
                title: 'Reports • Analytics • Communication',
                summary: 'Keeps stakeholders informed and decisions transparent.',
                documents: [
                    { id: 'executive_dashboard', title: 'Executive KPI Dashboard Pack', summary: 'Story-driven slides that blend financial, marketing, and ops metrics.', priority: 'recommended', when: 'Monthly leadership syncs or board meetings.' },
                    { id: 'status_report', title: 'Project Status & Meeting Minutes', summary: 'Summarizes progress, blockers, decisions, and next actions.', priority: 'recommended', when: 'Running cross-functional initiatives.' },
                    { id: 'internal_memo', title: 'Internal Memo & Announcement Kit', summary: 'Structured memos for policy updates, org changes, and launches.', priority: 'optional', when: 'Communicating change across teams.' }
                ]
            },
            {
                id: 'compliance',
                title: 'Compliance • Regulatory • Licenses',
                summary: 'Demonstrates you are allowed to operate where you do business.',
                documents: [
                    { id: 'license_register', title: 'Licensing & Permit Register', summary: 'Tracks renewal dates, jurisdictions, and responsible owners.', priority: 'critical', when: 'Operating across multiple states or regulated sectors.' },
                    { id: 'regulatory_filing', title: 'Regulatory Filing Log', summary: 'Calendar of filings, submissions, and supporting evidence.', priority: 'recommended', when: 'Preparing for inspections or certifications.' },
                    { id: 'environmental_compliance', title: 'Environmental & Safety Compliance Pack', summary: 'Policies, spill response, and audit checklists to satisfy regulators.', priority: 'optional', when: 'Manufacturing, logistics, or public facilities.' }
                ]
            },
            {
                id: 'ip_rd',
                title: 'Intellectual Property • R&D',
                summary: 'Protects innovations and structures product development.',
                documents: [
                    { id: 'ip_protection', title: 'IP Protection Dossier', summary: 'Trademark, copyright, and patent-ready briefs with usage logs.', priority: 'recommended', when: 'Launching new brands or inventions.' },
                    { id: 'technical_spec', title: 'Technical Specification Packet', summary: 'Requirements, architecture, and acceptance criteria for builds.', priority: 'optional', when: 'Engineering new products or integrations.' },
                    { id: 'r_and_d_report', title: 'Research & Development Report', summary: 'Summarizes experiments, findings, next-step funding needs.', priority: 'optional', when: 'Pursuing grants or scientific breakthroughs.' }
                ]
            },
            {
                id: 'hr_personnel',
                title: 'HR • People Operations',
                summary: 'Creates clarity, compliance, and culture for your team.',
                documents: [
                    { id: 'employee_handbook', title: 'Employee Handbook & Policy Suite', summary: 'Culture values, benefits, code of conduct, and dispute process.', priority: 'critical', when: 'Growing beyond a handful of employees.' },
                    { id: 'performance_review', title: 'Performance & Development Review Kit', summary: 'Templates for reviews, goal-setting, and feedback loops.', priority: 'recommended', when: 'Running quarterly or semi-annual reviews.' },
                    { id: 'payroll_compliance', title: 'Payroll & Benefits Compliance Pack', summary: 'Ensures wage, overtime, benefits, and leave policies meet laws.', priority: 'recommended', when: 'Operating multi-state or remote teams.' }
                ]
            },
            {
                id: 'supporting',
                title: 'Supporting & Communications',
                summary: 'Ad-hoc documents for insurance, PR, and stakeholder updates.',
                documents: [
                    { id: 'insurance_portfolio', title: 'Insurance Policy Portfolio', summary: 'Summary of coverage, carriers, renewal dates, and proof of insurance.', priority: 'recommended', when: 'Working with enterprise clients or landlords.' },
                    { id: 'press_release', title: 'Press Release & Media Brief', summary: 'Ready-to-send copy for launches, funding, or partnerships.', priority: 'optional', when: 'Announcing milestones or market entry.' },
                    { id: 'legal_opinion', title: 'Legal Opinion Request Brief', summary: 'Structured intake for counsel to respond quickly with guidance.', priority: 'optional', when: 'Navigating complex regulatory issues.' }
                ]
            }
        ];

        const DOC_PRIORITY_LABELS = { critical: 'Critical', recommended: 'Recommended', optional: 'Optional' };
        const docState = new Map();
        const uploadedDocs = [];

        function priorityClass(priority) {
            return priority === 'critical' ? 'critical' : (priority === 'recommended' ? 'recommended' : 'optional');
        }

        function priorityWeight(priority) {
            if (priority === 'critical') return 0;
            if (priority === 'recommended') return 1;
            return 2;
        }

        function statusClass(status) {
            if (status === 'generating') return 'generating';
            if (status === 'ready') return 'ready';
            if (status === 'uploaded') return 'uploaded';
            return '';
        }

        function statusLabel(status) {
            switch (status) {
                case 'queued': return 'Queued';
                case 'generating': return 'Generating…';
                case 'ready': return 'Ready';
                case 'uploaded': return 'Uploaded';
                default: return 'Not generated';
            }
        }

        function slugify(text) {
            return String(text || '')
                .toLowerCase()
                .replace(/[^a-z0-9]+/g, '-')
                .replace(/(^-|-$)/g, '')
                || 'document';
        }

        function formatRelativeTime(date) {
            if (!(date instanceof Date)) return '';
            const diff = Math.max(0, Date.now() - date.getTime());
            const mins = Math.round(diff / 60000);
            if (mins < 1) return 'just now';
            if (mins < 60) return `${mins} min${mins === 1 ? '' : 's'} ago`;
            const hours = Math.round(mins / 60);
            if (hours < 24) return `${hours} hr${hours === 1 ? '' : 's'} ago`;
            const days = Math.round(hours / 24);
            return `${days} day${days === 1 ? '' : 's'} ago`;
        }

        function docToast(message, variant = 'info') {
            const host = document.querySelector('.vmo-toast-host');
            if (!host) { console.info('[Documents]', message); return; }
            const toast = document.createElement('div');
            toast.className = `vmo-toast vmo-toast-${variant}`;
            toast.textContent = message;
            host.appendChild(toast);
            requestAnimationFrame(() => toast.classList.add('show'));
            setTimeout(() => {
                toast.classList.remove('show');
                setTimeout(() => toast.remove(), 300);
            }, 4200);
        }

        function ensureDocumentState() {
            if (window.__vmoDocumentStateReady) return;
            DOCUMENT_LIBRARY.forEach(category => {
                category.documents.forEach(doc => {
                    if (docState.has(doc.id)) return;
                    docState.set(doc.id, {
                        ...doc,
                        categoryId: category.id,
                        categoryTitle: category.title,
                        categorySummary: category.summary,
                        selected: doc.priority !== 'optional',
                        status: 'idle',
                        url: null,
                        filename: null,
                        lastGenerated: null
                    });
                });
            });
            window.__vmoDocumentStateReady = true;
        }

        function createDocToggle(doc) {
            const wrapper = document.createElement('label');
            wrapper.className = 'doc-item';

            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.checked = !!doc.selected;
            checkbox.dataset.docId = doc.id;
            checkbox.addEventListener('change', () => toggleDocumentSelection(doc.id, checkbox.checked));
            wrapper.appendChild(checkbox);

            const body = document.createElement('div');
            body.className = 'doc-body';

            const titleRow = document.createElement('div');
            titleRow.style.display = 'flex';
            titleRow.style.alignItems = 'center';
            titleRow.style.gap = '6px';

            const title = document.createElement('strong');
            title.textContent = doc.title;
            titleRow.appendChild(title);

            const chip = document.createElement('span');
            chip.className = `doc-chip ${priorityClass(doc.priority)}`;
            chip.textContent = DOC_PRIORITY_LABELS[doc.priority] || 'Optional';
            titleRow.appendChild(chip);

            if (doc.status && doc.status !== 'idle') {
                const status = document.createElement('span');
                status.className = `doc-status ${statusClass(doc.status)}`;
                status.textContent = statusLabel(doc.status);
                titleRow.appendChild(status);
            }

            body.appendChild(titleRow);

            const desc = document.createElement('span');
            desc.textContent = doc.summary;
            body.appendChild(desc);

            if (doc.when) {
                const when = document.createElement('span');
                when.style.fontSize = '10px';
                when.style.opacity = '0.8';
                when.textContent = `Use when: ${doc.when}`;
                body.appendChild(when);
            }

            wrapper.appendChild(body);
            return wrapper;
        }

        function renderDocumentRecommendations() {
            const container = document.getElementById('doc-recommendations');
            if (!container) return;
            container.innerHTML = '';
            const docs = Array.from(docState.values())
                .filter(doc => doc.priority !== 'optional')
                .sort((a, b) => priorityWeight(a.priority) - priorityWeight(b.priority));
            if (!docs.length) {
                const empty = document.createElement('div');
                empty.className = 'doc-empty';
                empty.textContent = 'AI has no urgent recommendations right now. Add documents from the library whenever needed.';
                container.appendChild(empty);
                return;
            }
            docs.forEach(doc => container.appendChild(createDocToggle(doc)));
        }

        function renderDocumentLibrary() {
            const container = document.getElementById('doc-library');
            if (!container) return;
            const openSet = new Set(Array.from(container.querySelectorAll('details[open]')).map(el => el.dataset.catId));
            container.innerHTML = '';
            DOCUMENT_LIBRARY.forEach((category, index) => {
                const details = document.createElement('details');
                details.className = 'doc-category';
                details.dataset.catId = category.id;
                if (openSet.size ? openSet.has(category.id) : index === 0) {
                    details.open = true;
                }
                const summary = document.createElement('summary');
                summary.innerHTML = `<span>${category.title}</span><span>${category.summary}</span>`;
                details.appendChild(summary);
                const content = document.createElement('div');
                content.className = 'doc-category-content';
                category.documents.forEach(docRef => {
                    const doc = docState.get(docRef.id);
                    if (!doc) return;
                    content.appendChild(createDocToggle(doc));
                });
                details.appendChild(content);
                container.appendChild(details);
            });
        }

        function renderDocumentDownloads() {
            const container = document.getElementById('doc-generated');
            if (!container) return;
            const generated = Array.from(docState.values()).filter(doc => doc.status === 'ready');
            container.innerHTML = '';
            if (!generated.length && !uploadedDocs.length) {
                const empty = document.createElement('div');
                empty.className = 'doc-empty';
                empty.textContent = 'No documents generated yet. Select your essentials and choose “Generate Selected PDFs”.';
                container.appendChild(empty);
                return;
            }
            const ordered = generated.sort((a, b) => {
                const aTime = a.lastGenerated ? a.lastGenerated.getTime() : 0;
                const bTime = b.lastGenerated ? b.lastGenerated.getTime() : 0;
                return bTime - aTime;
            });
            ordered.forEach(doc => {
                const item = document.createElement('div');
                item.className = 'doc-generated-item';
                const info = document.createElement('div');
                info.style.flex = '1';
                const title = document.createElement('strong');
                title.textContent = doc.title;
                info.appendChild(title);
                const meta = document.createElement('small');
                meta.textContent = `${doc.categoryTitle}${doc.lastGenerated ? ` • ${formatRelativeTime(doc.lastGenerated)}` : ''}`;
                info.appendChild(meta);
                item.appendChild(info);
                const download = document.createElement('button');
                download.type = 'button';
                download.className = 'action-btn';
                download.textContent = '⬇️ Download';
                download.addEventListener('click', () => triggerDocDownload(doc));
                item.appendChild(download);
                container.appendChild(item);
            });
            uploadedDocs.forEach(entry => {
                const item = document.createElement('div');
                item.className = 'doc-generated-item';
                const info = document.createElement('div');
                info.style.flex = '1';
                const title = document.createElement('strong');
                title.textContent = entry.name;
                info.appendChild(title);
                const meta = document.createElement('small');
                meta.textContent = `Uploaded • ${formatRelativeTime(entry.added)}`;
                info.appendChild(meta);
                item.appendChild(info);
                const download = document.createElement('button');
                download.type = 'button';
                download.className = 'action-btn';
                download.textContent = '⬇️ Download';
                download.addEventListener('click', () => triggerUploadedDownload(entry));
                item.appendChild(download);
                container.appendChild(item);
            });
        }

        function triggerDocDownload(doc) {
            if (!doc || !doc.url) { docToast('Document is still generating. Please try again shortly.', 'info'); return; }
            const link = document.createElement('a');
            link.href = doc.url;
            link.download = doc.filename || `${slugify(doc.title)}.pdf`;
            document.body.appendChild(link);
            link.click();
            link.remove();
        }

        function triggerUploadedDownload(entry) {
            if (!entry || !entry.url) return;
            const link = document.createElement('a');
            link.href = entry.url;
            link.download = entry.name;
            document.body.appendChild(link);
            link.click();
            link.remove();
        }

        function toggleDocumentSelection(id, isSelected) {
            const doc = docState.get(id);
            if (!doc) return;
            doc.selected = !!isSelected;
            renderDocumentRecommendations();
            renderDocumentLibrary();
        }

        function createDocPlaceholder(doc) {
            const lines = [
                `${doc.title}`,
                `Category: ${doc.categoryTitle}`,
                `Generated: ${new Date().toLocaleString()}`,
                '',
                'Summary:',
                `• ${doc.summary}`,
                doc.when ? `• Use when: ${doc.when}` : null,
                '',
                'This is an AI-generated preview. Connect the VMO document service for full PDF formatting, branding, and compliance blocks.'
            ].filter(Boolean).join('\n');
            if (doc.url) {
                try { URL.revokeObjectURL(doc.url); } catch(_) {}
            }
            return URL.createObjectURL(new Blob([lines], { type: 'text/plain' }));
        }

        function renderAllDocuments() {
            renderDocumentRecommendations();
            renderDocumentLibrary();
            renderDocumentDownloads();
        }

        function activateDocumentPanel(panelId) {
            if (!panelId) return;
            const navButtons = document.querySelectorAll('#documents .doc-nav-link');
            const panels = document.querySelectorAll('#documents .doc-panel');
            navButtons.forEach(button => {
                const isActive = button.dataset.docPanel === panelId;
                button.classList.toggle('active', isActive);
                button.setAttribute('aria-selected', isActive ? 'true' : 'false');
            });
            panels.forEach(panel => {
                panel.classList.toggle('active', panel.id === panelId);
            });
        }

        function setupDocumentNavigation() {
            const navButtons = document.querySelectorAll('#documents .doc-nav-link');
            if (!navButtons.length) return;
            navButtons.forEach(button => {
                button.addEventListener('click', () => {
                    const target = button.dataset.docPanel;
                    if (!target) return;
                    activateDocumentPanel(target);
                    if (target === 'doc-panel-generated') {
                        renderDocumentDownloads();
                    } else if (target === 'doc-panel-library') {
                        renderDocumentLibrary();
                    } else {
                        renderDocumentRecommendations();
                    }
                });
            });
        }

        function generateSelectedDocuments() {
            ensureDocumentState();
            const toGenerate = Array.from(docState.values()).filter(doc => doc.selected && doc.status !== 'generating');
            const queue = toGenerate.filter(doc => doc.status !== 'ready');
            if (!toGenerate.length) {
                docToast('Select at least one document to generate.', 'info');
                return;
            }
            if (!queue.length) {
                docToast('All selected documents are already generated.', 'info');
                return;
            }
            queue.forEach(doc => { doc.status = 'generating'; });
            renderAllDocuments();

            const payload = queue.map(doc => ({
                id: doc.id,
                title: doc.title,
                category: doc.categoryTitle,
                priority: doc.priority
            }));

            const formData = new URLSearchParams();
            formData.append('action', 'vmo_ai_generate_documents');
            formData.append('_ajax_nonce', VMO_NONCE_BUILDER);
            formData.append('documents', JSON.stringify(payload));

            fetch(VMO_AJAX, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
                body: formData.toString()
            }).then(res => {
                if (!res.ok) throw new Error('Network error');
                return res.json();
            }).then(response => {
                if (!response || !response.success || !response.data || !Array.isArray(response.data.documents)) {
                    throw new Error('Unexpected response');
                }
                response.data.documents.forEach(entry => {
                    const doc = docState.get(entry.id);
                    if (!doc) return;
                    doc.status = 'ready';
                    doc.url = entry.url || doc.url || createDocPlaceholder(doc);
                    doc.filename = entry.filename || `${slugify(doc.title)}.pdf`;
                    doc.lastGenerated = entry.generated_at ? new Date(entry.generated_at) : new Date();
                });
                docToast('Documents generated. Downloads are ready.', 'success');
            }).catch(err => {
                console.warn('[VMO] Document service unavailable, falling back to local previews', err);
                queue.forEach((doc, index) => {
                    doc.status = 'ready';
                    doc.url = createDocPlaceholder(doc);
                    doc.filename = `${slugify(doc.title)}.pdf`;
                    doc.lastGenerated = new Date(Date.now() + index * 500);
                });
                docToast('Generated AI previews. Connect VMO Document Service for production PDFs.', 'info');
            }).finally(() => {
                renderAllDocuments();
            });
        }

        function refreshDocumentRecommendations() {
            ensureDocumentState();
            const formData = new URLSearchParams();
            formData.append('action', 'vmo_ai_refresh_document_recs');
            formData.append('_ajax_nonce', VMO_NONCE_BUILDER);
            fetch(VMO_AJAX, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
                body: formData.toString()
            }).then(res => res.ok ? res.json() : null).then(response => {
                if (response && response.success && Array.isArray(response.data)) {
                    response.data.forEach(entry => {
                        const doc = docState.get(entry.id);
                        if (!doc) return;
                        if (entry.priority) doc.priority = entry.priority;
                        if (typeof entry.selected === 'boolean') doc.selected = entry.selected;
                        if (entry.summary) doc.summary = entry.summary;
                    });
                }
            }).catch(() => {
                docState.forEach(doc => {
                    if (doc.priority === 'critical') doc.selected = true;
                });
            }).finally(() => {
                renderAllDocuments();
                docToast('Recommendations updated using the latest market intelligence.', 'info');
            });
        }

        function handleDocumentUpload(event) {
            const files = Array.from(event.target.files || []);
            if (!files.length) return;
            files.forEach(file => {
                const url = URL.createObjectURL(file);
                uploadedDocs.unshift({
                    name: file.name,
                    url,
                    size: file.size,
                    added: new Date()
                });
            });
            event.target.value = '';
            docToast('Upload complete. Your PDF is now tracked in the dashboard.', 'success');
            renderDocumentDownloads();
        }

        function initDocumentHub() {
            if (window.__vmoDocumentHubInitialized) return;
            const section = document.getElementById('documents');
            if (!section) return;
            window.__vmoDocumentHubInitialized = true;
            ensureDocumentState();
            renderAllDocuments();
            setupDocumentNavigation();
            // Bind simple card toggles to reveal rich panels with DOCX/PDF actions
            bindDocumentToggles();
            const defaultPanel = document.querySelector('#documents .doc-nav-link.active');
            if (defaultPanel) {
                activateDocumentPanel(defaultPanel.dataset.docPanel);
            }
            const generateBtn = document.getElementById('doc-generate-selected');
            if (generateBtn) generateBtn.addEventListener('click', generateSelectedDocuments);
            const refreshBtn = document.getElementById('doc-refresh');
            if (refreshBtn) refreshBtn.addEventListener('click', refreshDocumentRecommendations);
            const uploadBtn = document.getElementById('doc-upload-trigger');
            const uploadInput = document.getElementById('doc-upload-input');
            if (uploadBtn && uploadInput) {
                uploadBtn.addEventListener('click', () => uploadInput.click());
                uploadInput.addEventListener('change', handleDocumentUpload);
            }
        }

        // Tab switching

        window.switchTab = function(tabName, ev) {
            console.log('Switching to tab:', tabName);
            window.__activeTab = tabName;
            document.querySelectorAll('.vmo-tab').forEach(tab => tab.classList.remove('active'));
            document.querySelectorAll('.vmo-section').forEach(section => section.classList.remove('active'));
            if (ev && ev.currentTarget) {
                ev.currentTarget.classList.add('active');
            } else {
                const activeTabButton = Array.from(document.querySelectorAll('.vmo-tab')).find(tab => {
                    const handler = tab.getAttribute('onclick') || '';
                    return handler.indexOf("switchTab('" + tabName + "'") !== -1 || handler.indexOf('switchTab("' + tabName + '"') !== -1;
                });
                if (activeTabButton) activeTabButton.classList.add('active');
            }
            document.getElementById(tabName).classList.add('active');
            if (tabName === 'documents') {
                initDocumentHub();
            }
            if (tabName === 'email') {
                try { if (window.vmoRefreshMail) { window.vmoRefreshMail(); } else if (window.vmoSwitchMailFolder) { window.vmoSwitchMailFolder('inbox'); } } catch(e) {}
            }
            if (tabName === 'promotion') {
                try { loadPromotionPanel(); } catch(e){}
                try {
                    const strategyPanel = document.getElementById('vmo-promo-strategy-panel');
                    if (strategyPanel && getComputedStyle(strategyPanel).display === 'none') {
                        const strategyLink = strategyPanel.previousElementSibling;
                        if (strategyLink) strategyLink.click();
                    }
                } catch(e){}
            }
            if (tabName === 'payments') {
                loadPaymentsPanel();
                loadCFOExpansionData();
            }
            if (tabName === 'strategic') {
                loadStrategicPanel();
            }
            if (tabName === 'reports') {
                vmoSwitchGlobalReportTab('action-items');
            }
            if (tabName === 'phone') {
                try { loadPhoneOverview(); } catch(e){}
                try { loadPhoneAnalytics(); } catch(e){}
                // Run phone system health check, log results to console for diagnostics
                try {
                    ajaxPost('vmo_phone_system_check').then(function(r) {
                        if (r && r.success && r.data && r.data.checks) {
                            console.log('[VMO Phone Health]', JSON.stringify(r.data.checks, null, 2));
                            var c = r.data.checks;
                            var issues = [];
                            if (c.twilio_credentials !== 'ok') {
                                console.error('[VMO Phone Health] ❌ Twilio credentials missing');
                                issues.push('Twilio credentials (Account SID + Auth Token) are not configured');
                            }
                            if (c.twilio_manager !== 'ok') console.error('[VMO Phone Health] ❌ Twilio Manager class not loaded');
                            if (c.phone_number === 'none') console.warn('[VMO Phone Health] ⚠️ No phone number found for this user');
                            if (c.webhook_key === 'missing') console.error('[VMO Phone Health] ❌ Webhook key missing — inbound calls will fail');
                            if (c.twiml_app !== 'ok') console.warn('[VMO Phone Health] ⚠️ TwiML App not configured — outbound calls may fail');
                            if (c.api_key !== 'ok') console.warn('[VMO Phone Health] ⚠️ API Key not set — browser token will fail');
                            if (c.openai_key !== 'ok') {
                                console.warn('[VMO Phone Health] ⚠️ OpenAI key missing — AI conversations will fail');
                                issues.push('AI API Key is not configured');
                            }
                            if (c.voice_quality_tier && c.voice_quality_tier !== 'premium') {
                                console.warn('[VMO Phone Health] Premium bridge inactive — current voice tier is ' + c.voice_quality_tier);
                            }
                            if (c.premium_bridge_enabled_for_user && String(c.premium_bridge_enabled_for_user).indexOf('yes') !== 0) {
                                console.warn('[VMO Phone Health] Premium bridge status — ' + c.premium_bridge_enabled_for_user);
                            }
                            var listenReady = String(c.live_audio_listen_ready || '');
                            var listenReadyOk = !listenReady || listenReady === 'ok' || listenReady.indexOf('ok ') === 0 || listenReady.indexOf('ok —') === 0;
                            if (listenReady && !listenReadyOk) {
                                console.warn('[VMO Phone Health] Live Audio Listen notice — ' + listenReady);
                            }

                            // Show visible banner on the phone tab when credentials are missing
                            var existingBanner = document.getElementById('vmo-phone-cred-banner');
                            if (existingBanner) existingBanner.remove();
                            if (issues.length > 0) {
                                var banner = document.createElement('div');
                                banner.id = 'vmo-phone-cred-banner';
                                banner.style.cssText = 'background:#fef3cd;border:1px solid #ffc107;border-radius:8px;padding:16px;margin:0 0 16px;color:#856404;font-size:14px;';
                                var html = '<strong>⚠️ Phone System Configuration Required</strong><ul style="margin:8px 0 0;padding-left:20px;">';
                                issues.forEach(function(i){ html += '<li>' + i + '</li>'; });
                                html += '</ul>';
                                if (c.actions_needed) {
                                    html += '<div style="margin-top:10px;font-size:13px;">';
                                    c.actions_needed.forEach(function(a){ html += '<div>→ ' + a + '</div>'; });
                                    html += '</div>';
                                }
                                html += '<div style="margin-top:12px;"><a href="<?php echo esc_url(admin_url('admin.php?page=vmo-ai-settings')); ?>" target="_blank" style="background:#856404;color:#fff;padding:6px 16px;border-radius:4px;text-decoration:none;font-size:13px;">Open Phone System Settings</a></div>';
                                banner.innerHTML = html;
                                var phoneSection = document.getElementById('phone');
                                if (phoneSection) phoneSection.insertBefore(banner, phoneSection.firstChild);
                            }
                        }
                    }).catch(function(){});
                } catch(e){}
            }
            if (tabName === 'shipping') {
                console.log('Loading shipping tab...');
                try { loadCustomCarriers(); } catch(e){}
            }
        }

        // Task management
        document.querySelectorAll('.task-checkbox').forEach(checkbox => {
            checkbox.addEventListener('click', function() {
                this.classList.toggle('checked');
                updateProgress();
            });
        });

        // Auto top-up toggle — handled by individual onclick handlers on each toggle
        // (no global handler needed; the onclick on each toggle-switch div already toggles .active)

        // VMO Tool Integration Functions
        function openVMOTool(tool) {
            const routes = {
                'builder': '<?php echo esc_js(admin_url('admin.php?page=vmo-ai-builder-main')); ?>',
                'wizard': '<?php echo esc_js(admin_url('admin.php?page=vmo-business-wizard')); ?>',
                'preview': '<?php echo esc_js(admin_url('admin.php?page=vmo-ai-builder-main')); ?>',
                'publish': '<?php echo esc_js(admin_url('admin.php?page=vmo-ai-builder-main')); ?>'
            };
            if (routes[tool]) window.open(routes[tool], '_blank');
        }

        function openPhoneInterface() {
            // Open the in-page phone interface panel (no external windows/modals)
            try { switchPhonePanel('interface'); } catch(e) {}
            // Mark the first nav-link as active on load
            try {
                var phoneLinks = document.querySelectorAll('#phone .nav-link');
                if (phoneLinks.length) phoneLinks[0].classList.add('vmo-active');
            } catch(e) {}
        }
        // Ensure only one phone view is visible at a time
        window.switchPhonePanel = function(which) {
            const phoneSection = document.getElementById('phone');
            const cardsWraps = phoneSection ? phoneSection.querySelectorAll('.vmo-cards') : [];
            const smsPanel = document.getElementById('vmo-sms-workspace');
            const hist = document.getElementById('vmo-call-history');
            const reportsPanel = document.getElementById('vmo-reports-panel');
            const upgradePanel = document.getElementById('vmo-upgrade-panel');
            const showInterface = (which === 'interface');
            // Highlight active nav-link
            if (phoneSection) {
                phoneSection.querySelectorAll('.nav-link').forEach(function(link, idx) {
                    link.classList.remove('vmo-active');
                    var targets = ['interface','sms','history','reports','upgrade'];
                    if (targets[idx] === which) link.classList.add('vmo-active');
                });
            }
            cardsWraps.forEach(cardsWrap => {
                Array.from(cardsWrap.children).forEach(child => {
                    if (!(child instanceof HTMLElement)) return;
                    const id = child.id || '';
                    // Do not auto-toggle modals or other dedicated panels
                    if (id === 'vmo-sms-workspace' || id === 'vmo-call-history' || id === 'vmo-reports-panel' || id === 'vmo-upgrade-panel' || id === 'vmo-contacts-modal' || id === 'vmo-recording-modal' || id === 'vmo-ring-settings' || id === 'vmo-sms-activation-modal') return;
                    
                    // Show specific analytics cards in both interface and history modes
                    if (id === 'vmo-today-summary-card' || id === 'vmo-phone-analytics') {
                        child.style.display = (showInterface || which === 'history') ? '' : 'none';
                        return;
                    }
                    
                    child.style.display = showInterface ? '' : 'none';
                });
            });
            if (smsPanel) smsPanel.style.display = (which === 'sms') ? 'block' : 'none';
            if (hist) hist.style.display = (which === 'history') ? 'block' : 'none';
            if (reportsPanel) reportsPanel.style.display = (which === 'reports') ? 'block' : 'none';
            if (upgradePanel) upgradePanel.style.display = (which === 'upgrade') ? 'block' : 'none';
            // Safety: ensure playback and contacts modals are closed when switching context
            const recModal = document.getElementById('vmo-recording-modal');
            if (recModal) recModal.style.display = 'none';
            const contactsModal = document.getElementById('vmo-contacts-modal');
            if (contactsModal) contactsModal.style.display = 'none';
            const ringModal = document.getElementById('vmo-ring-settings');
            if (ringModal) ringModal.style.display = 'none';
            if (which === 'sms') { try { loadSmsWorkspace(window.__vmoSmsState && window.__vmoSmsState.activeContact ? window.__vmoSmsState.activeContact : ''); } catch(e){} }
            if (which === 'history') { try { if (typeof refreshHistory === 'function') refreshHistory(); else if (typeof window.refreshHistory === 'function') window.refreshHistory(); } catch(_rh){} try { loadPhoneOverview(); loadPhoneAnalytics(); } catch(e){} }
            if (which === 'interface') { try { loadPhoneOverview(); loadPhoneAnalytics(); } catch(e){} }
            if (which === 'reports') { vmoLoadActionItems(); }
        }
        // Phone helpers
        function formatDisplayPhone(num){
            if(!num) return '—';
            const digits = String(num).replace(/[^0-9]/g,'');
            let d = digits;
            if (d.length === 11 && d.startsWith('1')) d = d.slice(1);
            if (d.length === 10) return `(${d.slice(0,3)}) ${d.slice(3,6)}-${d.slice(6)}`;
            return num;
        }
        function toE164(raw){
            if (!raw) return '';
            let s = String(raw).trim();
            if (s.startsWith('+')) return s.replace(/[^+0-9]/g,'');
            const d = s.replace(/[^0-9]/g,'');
            if (d.length === 11 && d.startsWith('1')) return '+'+d;
            if (d.length === 10) return '+1'+d;
            return d ? ('+'+d) : '';
        }
    // Ringing + unified phone action
    let __ring = { enabled: true, preset: 'classic', ac: null, osc: null, osc2: null, gain: null, timer: null, isRinging: false, mediaEl: null, usingMedia: false, volume: 0.6, url: '', defaultUrl: (typeof VMO_DEFAULT_RING_URL!=='undefined'?VMO_DEFAULT_RING_URL:''), bannerDismissSid: null, titleTimer: null, origTitle: document.title, pendingRingRetry: false };
    function ensureAudioContext(){
        try{
            if(!__ring.ac){
                __ring.ac = new (window.AudioContext||window.webkit.AudioContext)();
                __ring.ac.addEventListener('statechange', function() {
                    if (__ring.ac && __ring.ac.state === 'running' && __ring.pendingRingRetry) {
                        console.log('[VMO Ring] AudioContext resumed — retrying deferred ring');
                        retryIncomingRingIfNeeded(true);
                    }
                });
            }
            if(__ring.ac && __ring.ac.state==='suspended'){
                const resumePromise = __ring.ac.resume();
                if(resumePromise && typeof resumePromise.catch === 'function') resumePromise.catch(()=>{});
            }
        }catch(e){
            console.warn('AudioContext error', e);
        }
        return __ring.ac || null;
    }
    function loadRingPrefs(){
        try{
            const v=localStorage.getItem('vmo.ring.volume');
            if(v!==null){ const n=Number(v); if(!Number.isNaN(n)) __ring.volume=Math.min(1,Math.max(0,n)); }
            const u=localStorage.getItem('vmo.ring.url');
            if(u!=null) __ring.url=u;
            const p=localStorage.getItem('vmo.ring.preset');
            if(p) __ring.preset=String(p);
            const en=localStorage.getItem('vmo.ring.enabled');
            if(en!==null) __ring.enabled = (String(en) === '1');
        }catch(e){}
    }
    function saveRingPrefs(){
        try{
            localStorage.setItem('vmo.ring.volume', String(__ring.volume));
            localStorage.setItem('vmo.ring.url', __ring.url||'');
            localStorage.setItem('vmo.ring.preset', __ring.preset||'classic');
            localStorage.setItem('vmo.ring.enabled', __ring.enabled ? '1' : '0');
        }catch(e){}
    }
    function applyPhonePrefsFromServer(data, options){
        if (!data || typeof data !== 'object') return false;

        const asChecked = (value) => value === true || value === 1 || value === '1';
        const persistLocal = !options || options.persistLocal !== false;
        const ringBtn = document.getElementById('vmo-ring-toggle');
        const ringVol = document.getElementById('vmo-ring-volume');
        const ringUrl = document.getElementById('vmo-ring-url');
        const ringPreset = document.getElementById('vmo-ring-preset');
        const greetingInput = document.getElementById('vmo-ai-greeting');

        if (greetingInput && typeof data.greeting !== 'undefined') greetingInput.value = String(data.greeting || '');

        const voiceSel = document.getElementById('vmo-ai-receptionist-voice');
        if (voiceSel && typeof data.ai_receptionist_voice !== 'undefined' && data.ai_receptionist_voice) {
            voiceSel.value = String(data.ai_receptionist_voice || 'ash');
        }

        if (typeof data.ring_url !== 'undefined') {
            let __incomingRingUrl = String(data.ring_url || '');
            // Defensive: never accept a video/image URL as a ringtone — browsers will
            // strip-and-loop the audio track of a .mov/.mp4 (see autoplay-loop bug).
            if (__incomingRingUrl) {
                const __audioExt = /\.(mp3|wav|ogg|m4a|aac|flac|opus|weba)(\?|#|$)/i;
                const __videoOrImageExt = /\.(mov|mp4|m4v|webm|mkv|avi|3gp|wmv|flv|jpg|jpeg|png|gif|webp|bmp|svg|pdf|heic)(\?|#|$)/i;
                if (__videoOrImageExt.test(__incomingRingUrl) || !__audioExt.test(__incomingRingUrl)) {
                    console.warn('[VMO Ring] Stored ringtone URL is not an audio file — clearing:', __incomingRingUrl);
                    __incomingRingUrl = '';
                    // Persist cleared value back to the server so it doesn't haunt future sessions.
                    try {
                        ajaxPost('vmo_save_phone_prefs', { ring_url: '', ring_attachment_id: 0 });
                    } catch(_){}
                }
            }
            __ring.url = __incomingRingUrl;
            if (ringUrl) ringUrl.value = __ring.url;
        }

        if (typeof data.ring_attachment_id !== 'undefined') {
            window.__ringAttachmentId = Number(data.ring_attachment_id) || 0;
        }

        if (typeof data.ring_preset !== 'undefined' && data.ring_preset) {
            __ring.preset = String(data.ring_preset || 'classic');
            if (ringPreset) ringPreset.value = __ring.preset;
        }

        if (typeof data.ring_enabled !== 'undefined') {
            __ring.enabled = asChecked(data.ring_enabled);
            if (ringBtn) ringBtn.classList.toggle('active', __ring.enabled);
        }

        if (typeof data.ring_volume !== 'undefined') {
            const vv = Number(data.ring_volume);
            if (!Number.isNaN(vv)) {
                __ring.volume = Math.min(1, Math.max(0, vv));
                if (ringVol) ringVol.value = String(Math.round(__ring.volume * 100));
                if (__ring.mediaEl) __ring.mediaEl.volume = __ring.volume;
            }
        }

        const recUi = document.getElementById('vmo-recording-toggle-ui');
        const recIn = document.getElementById('vmo-recording-input');
        if (recUi && recIn && typeof data.call_recording_enabled !== 'undefined') {
            const isRec = asChecked(data.call_recording_enabled);
            recUi.classList.toggle('active', isRec);
            recIn.checked = isRec;
        }

        const emailAlertsUi = document.getElementById('vmo-email-alerts-toggle-ui');
        const emailAlertsIn = document.getElementById('vmo-email-alerts-input');
        if (emailAlertsUi && emailAlertsIn && typeof data.email_incoming_alerts !== 'undefined') {
            const isAlerts = asChecked(data.email_incoming_alerts);
            emailAlertsUi.classList.toggle('active', isAlerts);
            emailAlertsIn.checked = isAlerts;
        }

        const emailSummaryUi = document.getElementById('vmo-email-summaries-toggle-ui');
        const emailSummaryIn = document.getElementById('vmo-email-summaries-input');
        if (emailSummaryUi && emailSummaryIn && typeof data.email_call_summaries !== 'undefined') {
            const isSummaries = asChecked(data.email_call_summaries);
            emailSummaryUi.classList.toggle('active', isSummaries);
            emailSummaryIn.checked = isSummaries;
        }

        const externalPhoneInput = document.getElementById('vmo-external-phone');
        if (externalPhoneInput && typeof data.external_phone !== 'undefined') {
            externalPhoneInput.value = String(data.external_phone || '');
        }

        if (typeof data.voice_quality_tier !== 'undefined' && data.voice_quality_tier) {
            const vqRadio = document.getElementById(data.voice_quality_tier === 'premium' ? 'vmo-vq-premium' : 'vmo-vq-standard');
            if (vqRadio) vqRadio.checked = true;
        }

        const exts = (data.extensions && typeof data.extensions === 'object') ? data.extensions : null;
        const extLbls = (data.extension_labels && typeof data.extension_labels === 'object') ? data.extension_labels : null;
        const deptOptions = ['Sales','Support','Billing','Customer Care','Technical Support','Reservations','Scheduling','Returns','Complaints','Human Resources','Accounts','Marketing','General Inquiries','Management'];
        if (exts || extLbls) {
            for (let i = 1; i <= 7; i++) {
                const el = document.getElementById('vmo-ext-' + i);
                const lbl = document.getElementById('vmo-ext-label-' + i);
                const dept = document.getElementById('vmo-ext-dept-' + i);
                const cust = document.getElementById('vmo-ext-custom-' + i);
                if (el && exts) el.value = (exts[String(i)] || '');
                if (lbl && extLbls) {
                    const savedLabel = extLbls[String(i)] || '';
                    lbl.value = savedLabel;
                    if (dept) {
                        if (savedLabel && deptOptions.includes(savedLabel)) {
                            dept.value = savedLabel;
                            if (cust) cust.style.display = 'none';
                        } else if (savedLabel) {
                            dept.value = 'custom';
                            if (cust) {
                                cust.style.display = 'block';
                                cust.value = savedLabel;
                            }
                        }
                    }
                }
            }
        }

        if (persistLocal) saveRingPrefs();

        if (!__ring.enabled) stopRinging();
        else if (window.__currentIncomingCall) retryIncomingRingIfNeeded(true);

        return true;
    }
    async function syncPhonePrefsFromServer(options){
        try {
            const res = await ajaxPost('vmo_get_phone_prefs', {});
            if (res && res.success && res.data) {
                applyPhonePrefsFromServer(res.data, options || {});
                return res.data;
            }
        } catch (e) {
            console.warn('Failed to sync phone preferences:', e);
        }
        return null;
    }
    // ── Title flashing: alternate page title to alert user of incoming call ──
    function startTitleFlash(callerInfo) {
        if (__ring.titleTimer) return; // already flashing
        __ring.origTitle = document.title;
        let flip = false;
        __ring.titleTimer = setInterval(function() {
            document.title = flip ? __ring.origTitle : ('📞 INCOMING CALL' + (callerInfo ? ' — ' + callerInfo : ''));
            flip = !flip;
        }, 1000);
    }
    function stopTitleFlash() {
        if (__ring.titleTimer) { clearInterval(__ring.titleTimer); __ring.titleTimer = null; }
        document.title = __ring.origTitle || 'Dashboard';
    }
    // ── Web Notification API: show OS-level notification when call arrives ──
	    function requestNotificationPermission() {
	        try { if ('Notification' in window && Notification.permission === 'default') Notification.requestPermission(); } catch(_) {}
	    }
	    let __browserLiveAudioPrimed = false;
	    let __browserLiveAudioPrimePromise = null;
	    async function primeBrowserLiveAudio(options) {
	        options = options || {};
	        const actionLabel = options.actionLabel || 'connect to the live call';
	        const required = options.required === true;
	        try {
	            ensureAudioContext();
	        } catch(_) {}
	        if (__browserLiveAudioPrimed) {
	            return true;
	        }
	        if (!navigator.mediaDevices || typeof navigator.mediaDevices.getUserMedia !== 'function') {
	            return true;
	        }
	        if (!__browserLiveAudioPrimePromise) {
	            __browserLiveAudioPrimePromise = navigator.mediaDevices.getUserMedia({ audio: true })
	                .then(function(stream) {
	                    try {
	                        stream.getTracks().forEach(function(track) { track.stop(); });
	                    } catch(_) {}
	                    __browserLiveAudioPrimed = true;
	                    return true;
	                })
	                .catch(function(err) {
	                    console.warn('[VMO] Browser live audio prime failed:', err);
	                    return required ? false : true;
	                })
	                .finally(function() {
	                    __browserLiveAudioPrimePromise = null;
	                });
	        }
	        const timeoutMs = Number.isFinite(Number(options.timeoutMs))
	            ? Math.max(250, Number(options.timeoutMs))
	            : (required ? 5000 : 900);
	        return await new Promise(function(resolve) {
	            let settled = false;
	            const finish = function(value) {
	                if (settled) {
	                    return;
	                }
	                settled = true;
	                resolve(value);
	            };
	            const timer = setTimeout(function() {
	                if (settled) {
	                    return;
	                }
	                console.warn('[VMO] Browser live audio prime timed out; proceeding with ' + actionLabel + '.');
	                finish(required ? false : true);
	            }, timeoutMs);
	            Promise.resolve(__browserLiveAudioPrimePromise).then(function(value) {
	                clearTimeout(timer);
	                finish(value);
	            }).catch(function() {
	                clearTimeout(timer);
	                finish(required ? false : true);
	            });
	        });
	    }
	    async function prepareBrowserLiveAudio(options) {
	        options = options || {};
	        const required = options.required === true;
	        const actionLabel = options.actionLabel || 'connect to the live call';
	        const primed = await primeBrowserLiveAudio({
	            actionLabel: actionLabel,
	            required: required
	        });
	        if (!primed && required) {
	            notify('Browser audio permission is required to ' + actionLabel + '.', 'error');
	            return false;
	        }
	        if (!__twilioReady || !__twilioDevice) {
	            notify('Initializing browser audio…', 'info');
	            const ready = await ensureTwilioDeviceReady();
	            if (!ready) {
	                if (required) {
	                    notify('Browser audio is unavailable. Refresh the page and try again.', 'error');
	                    return false;
	                }
	                return false;
	            }
	        }
	        return true;
	    }
	    function showCallNotification(callerInfo) {
	        try {
	            if (!('Notification' in window) || Notification.permission !== 'granted') return;
	            const n = new Notification('📞 Incoming Call', {
                body: callerInfo || 'Someone is calling',
                icon: (typeof VMO_PLUGIN_URL !== 'undefined') ? VMO_PLUGIN_URL + 'assets/phone-icon.png' : '',
                tag: 'vmo-incoming-call', // reuse same notification slot
                requireInteraction: true
            });
            n.onclick = function() { window.focus(); n.close(); };
            // Auto-close after 30s
            setTimeout(function() { try { n.close(); } catch(_) {} }, 30000);
        } catch(_) {}
    }
    function ringNeedsRestart() {
        if (!__ring.enabled) return false;
        if (__ring.pendingRingRetry) {
            if (!__ring.ac || __ring.ac.state !== 'running') return false;
            return true;
        }
        if (!__ring.isRinging) return true;
        if (__ring.usingMedia) {
            return !(__ring.mediaEl && !__ring.mediaEl.paused && __ring.mediaEl.readyState >= 2);
        }
        if (__ring.ac && __ring.ac.state === 'running') {
            return !(__ring.osc || __ring.osc2 || __ring.timer);
        }
        if (__ring.ac && __ring.ac.state !== 'running') return true;
        return false;
    }
    function kickIncomingRing(callerInfo, force){
        if(!__ring.enabled) return false;
        if(!force && !ringNeedsRestart()) return false;
        const ac = (() => { try { return ensureAudioContext(); } catch(_) { return null; } })();
        if(ac && ac.state !== 'running'){
            __ring.pendingRingRetry = true;
            startTitleFlash(callerInfo);
            showCallNotification(callerInfo);
            return true;
        }
        if(__ring.isRinging) stopRinging();
        __ring.pendingRingRetry = false;
        startRinging(callerInfo);
        return true;
    }
    function retryIncomingRingIfNeeded(force){
        if(!__ring.enabled || !__ring.pendingRingRetry) return false;
        const incoming = window.__currentIncomingCall || null;
        const bnr = document.getElementById('vmo-incoming-banner');
        const bannerVisible = !!(bnr && bnr.style.display !== 'none');
        if(!incoming && !bannerVisible) {
            __ring.pendingRingRetry = false;
            return false;
        }
        const callerInfo = incoming ? (incoming.from_number || incoming.caller_number || 'Unknown') : '';
        return kickIncomingRing(callerInfo, !!force);
    }
    // Nudge AudioContext on first user interaction to comply with autoplay policies.
    // Keep listening (not once) so suspended contexts are resumed even after
    // Chrome's power-saving puts them back to sleep.
	    try {
	        ['click','keydown','touchstart'].forEach(function(evt){
	            document.addEventListener(evt, function(){
	                try {
	                    ensureAudioContext();
	                    if (retryIncomingRingIfNeeded(true)) console.log('[VMO Ring] Retrying ringing after user gesture');
	                } catch(e){}
	            }, { passive: true });
	        });
        document.addEventListener('visibilitychange', function(){
            if (!document.hidden) retryIncomingRingIfNeeded(false);
        });
        window.addEventListener('focus', function(){ retryIncomingRingIfNeeded(false); });
    } catch(_){}
        function startRinging(callerInfo){
            if(!__ring.enabled) { console.log('[VMO Ring] Ringing disabled — skipping'); return; }
            // Guard: if already ringing, do nothing (prevents dual source)
            if(__ring.isRinging) return;
            // Always flash title + show notification (works even when audio is blocked)
            startTitleFlash(callerInfo);
            showCallNotification(callerInfo);
            // Safety: kill any lingering oscillators/media from a prior ring
            // that wasn't fully cleaned up (e.g. stopRinging race condition)
            try{ if(__ring.osc){ __ring.osc.stop(); __ring.osc.disconnect(); __ring.osc=null; } }catch(_){}
            try{ if(__ring.osc2){ __ring.osc2.stop(); __ring.osc2.disconnect(); __ring.osc2=null; } }catch(_){}
            try{ if(__ring.modOsc){ __ring.modOsc.stop(); __ring.modOsc.disconnect(); __ring.modOsc=null; } }catch(_){}
            try{ if(__ring.gain){ __ring.gain.gain.value=0; __ring.gain.disconnect(); __ring.gain=null; } }catch(_){}
            try{ if(__ring.modGain){ __ring.modGain.disconnect(); __ring.modGain=null; } }catch(_){}
            if(__ring.timer){ clearInterval(__ring.timer); __ring.timer=null; }
            if(__ring.mediaEl){ try{ __ring.mediaEl.pause(); __ring.mediaEl.oncanplay=null; __ring.mediaEl.onerror=null; }catch(_){} }
            try{
                ensureAudioContext(); const ac = __ring.ac; if(!ac){ console.warn('[VMO Ring] No AudioContext — cannot ring'); return; }
                if(ac.state !== 'running'){
                    __ring.pendingRingRetry = true;
                    console.log('[VMO Ring] AudioContext not running — deferring audible ring');
                    return;
                }
                console.log('[VMO Ring] AudioContext state:', ac.state, '| preset:', __ring.preset, '| volume:', __ring.volume);
                // Use custom/uploaded audio ONLY when explicitly provided.
                // Custom/uploaded ringtone overrides built-in presets entirely.
                let tryMediaUrl = (__ring.url && __ring.url.trim()) ? __ring.url : '';
                // Reject non-audio uploads (e.g. .mov / .mp4 / images). Browsers will
                // happily strip-and-loop the audio track of a video file, which is
                // almost never what the user intended for a ringtone.
                if (tryMediaUrl) {
                    const __audioExt = /\.(mp3|wav|ogg|m4a|aac|flac|opus|weba)(\?|#|$)/i;
                    const __videoOrImageExt = /\.(mov|mp4|m4v|webm|mkv|avi|3gp|wmv|flv|jpg|jpeg|png|gif|webp|bmp|svg|pdf|heic)(\?|#|$)/i;
                    if (__videoOrImageExt.test(tryMediaUrl) || !__audioExt.test(tryMediaUrl)) {
                        console.warn('[VMO Ring] Custom ringtone URL is not an audio file — ignoring and using synth fallback:', tryMediaUrl);
                        __ring.url = '';
                        try { localStorage.setItem('vmo_ring_prefs', JSON.stringify({ enabled: __ring.enabled, preset: __ring.preset, volume: __ring.volume, url: '' })); } catch(_){}
                        tryMediaUrl = '';
                    }
                }
                if (tryMediaUrl) {
                    try{
                        // Stop and release any previous media element to prevent overlap
                        if (__ring.mediaEl) { try { __ring.mediaEl.pause(); __ring.mediaEl.oncanplay = null; __ring.mediaEl.onerror = null; } catch(_){} }
                        if (!__ring.mediaEl) { __ring.mediaEl = new Audio(); }
                        const el = __ring.mediaEl;
                        el.loop = true;
                        // Unique ID for this load attempt — prevents stale callbacks
                        const loadId = Date.now();
                        __ring._mediaLoadId = loadId;
                        el.onerror = ()=>{
                            if (__ring._mediaLoadId !== loadId) return; // stale
                            el.oncanplay = null; // prevent late canplay from firing
                            try{ el.pause(); }catch(_){ }
                            __ring.usingMedia = false; __ring.isRinging = false;
                            // Avoid retry loop with a bad URL
                            if (tryMediaUrl === __ring.url) { __ring.url = ''; }
                            startRinging(); // fallback to synth
                        };
                        el.oncanplay = ()=>{
                            if (__ring._mediaLoadId !== loadId) return; // stale
                            if (!__ring.usingMedia || !__ring.isRinging) return; // already switched to synth
                            try{ el.volume = Math.max(0, Math.min(1, __ring.volume)); const p = el.play(); if(p && p.catch) p.catch(()=>{}); }catch(_){ }
                        };
                        el.src = tryMediaUrl;
                        __ring.pendingRingRetry = false; __ring.usingMedia = true; __ring.isRinging = true; return;
                    }catch(err){ console.warn('Ring media setup failed, fallback to synth', err); __ring.usingMedia=false; }
                }
                // Built-in ringtone synth presets (no uploaded audio required)
                const preset = String(__ring.preset || 'classic');
                const oscA = ac.createOscillator();
                const oscB = ac.createOscillator();
                const gain = ac.createGain();
                if (preset === 'pulse') {
                    oscA.type='square'; oscB.type='square';
                    oscA.frequency.value=880; oscB.frequency.value=1320;
                }
                else if (preset === 'chime') {
                    oscA.type='triangle'; oscB.type='sine';
                    oscA.frequency.value=659.25; oscB.frequency.value=987.77;
                }
                else if (preset === 'soft') {
                    oscA.type='sine'; oscB.type='sine';
                    oscA.frequency.value=523.25; oscB.frequency.value=659.25;
                }
                else {
                    // Classic old-fashioned telephone ring:
                    // 20 Hz modulator on ~440/480 Hz carriers gives the
                    // characteristic "brrring" bell sound of a rotary phone.
                    oscA.type='sine'; oscB.type='sine';
                    oscA.frequency.value=440; oscB.frequency.value=480;
                }
                gain.gain.value=0.0;
                oscA.connect(gain); oscB.connect(gain); gain.connect(ac.destination);
                oscA.start(); oscB.start();

                // For the classic preset, add a low-frequency modulator (20 Hz)
                // to create the warbling "bell" effect of a real telephone ringer.
                let modOsc = null;
                let modGain = null;
                if (preset === 'classic') {
                    modOsc = ac.createOscillator();
                    modGain = ac.createGain();
                    modOsc.type = 'sine';
                    modOsc.frequency.value = 20;
                    modGain.gain.value = 0;
                    modOsc.connect(modGain);
                    modGain.connect(gain.gain);
                    modOsc.start();
                }

                __ring.pendingRingRetry = false;
                __ring.osc=oscA; __ring.osc2=oscB; __ring.gain=gain; __ring.modOsc=modOsc; __ring.modGain=modGain; __ring.isRinging=true;
                const onLevel = Math.max(0.02, Math.min(0.4, __ring.volume*0.35));
                // For classic, modulate the gain via the modulator oscillator
                const modLevel = (preset === 'classic') ? Math.max(0.01, onLevel * 0.8) : 0;
                const ringOn = ()=>{ try{
                    gain.gain.setTargetAtTime(onLevel, ac.currentTime, 0.02);
                    if (modGain) modGain.gain.setTargetAtTime(modLevel, ac.currentTime, 0.02);
                }catch(_){} };
                const ringOff = ()=>{ try{
                    gain.gain.setTargetAtTime(0.0, ac.currentTime, 0.03);
                    if (modGain) modGain.gain.setTargetAtTime(0.0, ac.currentTime, 0.03);
                }catch(_){} };
                // Cadence varies by preset. Classic uses the standard US phone ring
                // cadence: 2 seconds on, 4 seconds off (6 second cycle).
                const cadence = (preset === 'pulse') ? { on: 300, cycle: 1800 }
                    : (preset === 'chime') ? { on: 800, cycle: 4200 }
                    : (preset === 'soft') ? { on: 1200, cycle: 4200 }
                    : { on: 2000, cycle: 6000 };
                const doCycle = ()=>{
                    if(!__ring.isRinging) return;
                    ringOn();
                    setTimeout(()=>{ if(__ring.isRinging) ringOff(); }, cadence.on);
                };
                doCycle();
                __ring.timer = setInterval(()=>{ if(__ring.isRinging) doCycle(); }, cadence.cycle);
            }catch(e){ console.warn('Ring start error', e); }
        }
        window.stopSystemRinging = stopRinging;
        function stopRinging(){ 
            if(__ring.timer){ clearInterval(__ring.timer); __ring.timer=null; } 
            if(__ring._cadenceFix){ clearInterval(__ring._cadenceFix); __ring._cadenceFix=null; } 
            try{ if(__ring.gain){ __ring.gain.gain.value=0.0; } }catch(_){ } 
            try{ if(__ring.osc){ __ring.osc.stop(); __ring.osc.disconnect(); } }catch(_){ } 
            try{ if(__ring.osc2){ __ring.osc2.stop(); __ring.osc2.disconnect(); } }catch(_){ } 
            try{ if(__ring.modOsc){ __ring.modOsc.stop(); __ring.modOsc.disconnect(); } }catch(_){ }
            try{ if(__ring.modGain){ __ring.modGain.disconnect(); } }catch(_){ }
            if(__ring.mediaEl){ try{ __ring.mediaEl.pause(); __ring.mediaEl.currentTime=0; __ring.mediaEl.oncanplay=null; __ring.mediaEl.onerror=null; }catch(_){} } 
            __ring.osc=null; __ring.osc2=null; __ring.gain=null; __ring.modOsc=null; __ring.modGain=null; __ring.isRinging=false; __ring.usingMedia=false; __ring.pendingRingRetry=false; __ring._mediaLoadId=0;
            stopTitleFlash();
            const rt = document.getElementById('vmo-ring-test');
            if(rt) { rt.innerHTML = '▶ Test'; rt.classList.remove('danger'); }
        }

        // ===== Dial Tone (Outbound Feedback) =====
        const __dialTone = window.__dialTone || { playing:false, oscA:null, oscB:null, gain:null };
        window.__dialTone = __dialTone;
        function startDialTone(){
            if(__dialTone.playing) return;
            try{
                const ac = ensureAudioContext();
                if(!ac) return;
                const oscA = ac.createOscillator();
                const oscB = ac.createOscillator();
                const gain = ac.createGain();
                oscA.type='sine'; oscB.type='sine';
                // Classic US dial tone: 350 Hz + 440 Hz
                oscA.frequency.value=350; oscB.frequency.value=440;
                gain.gain.value=0.0;
                oscA.connect(gain); oscB.connect(gain); gain.connect(ac.destination);
                oscA.start(); oscB.start();
                __dialTone.oscA=oscA; __dialTone.oscB=oscB; __dialTone.gain=gain; __dialTone.playing=true;
                try{ gain.gain.setTargetAtTime(0.05, ac.currentTime, 0.03); }catch(_){ gain.gain.value=0.05; }
            }catch(e){ console.warn('Dial tone start error', e); }
        }
        function stopDialTone(){
            if(!__dialTone.playing) return;
            try{ if(__dialTone.gain){ __dialTone.gain.gain.value=0.0; } }catch(_){ }
            try{ if(__dialTone.oscA){ __dialTone.oscA.stop(); __dialTone.oscA.disconnect(); } }catch(_){ }
            try{ if(__dialTone.oscB){ __dialTone.oscB.stop(); __dialTone.oscB.disconnect(); } }catch(_){ }
            __dialTone.oscA=null; __dialTone.oscB=null; __dialTone.gain=null; __dialTone.playing=false;
        }
        window.__lastLiveSids = new Set(); window.__currentIncomingCall = null;
        // Track call SIDs that have been handled/dismissed so polling doesn't re-trigger ringing
        window.__handledSids = new Set();
        window.__acknowledgedIncomingSids = new Set();
        window.__ringNowSeen = window.__ringNowSeen || Object.create(null);
        window.__pendingIncomingMeta = null;
        window.__vmoDialerState = window.__vmoDialerState || {
            muted: false,
            held: false,
            listenOnly: false,
            listenMode: '',
            activeSource: '',
            activeCallSid: '',
            activeConferenceName: ''
        };
        function setDialerModeChip(label, options){
            options = options || {};
            const chip = document.getElementById('vmo-dialer-mode');
            if (!chip) return;
            chip.textContent = label || 'Idle';
            chip.style.color = options.color || '#38bdf8';
            chip.style.borderColor = options.border || 'rgba(56,189,248,.28)';
            chip.style.background = options.background || 'rgba(56,189,248,.08)';
        }
        function setDialerStatus(message, tone){
            const status = document.getElementById('vmo-dialer-status');
            if (!status) return;
            status.textContent = message || '';
            status.style.color = tone || 'var(--muted)';
        }
        function getPhoneTabButton(){
            return Array.from(document.querySelectorAll('.vmo-tab')).find(btn => String(btn.textContent || '').indexOf('Phone System') !== -1) || null;
        }
        function openPhoneDialerSurface(){
            const phoneBtn = getPhoneTabButton();
            if (phoneBtn && typeof phoneBtn.click === 'function') {
                phoneBtn.click();
            } else if (typeof switchTab === 'function') {
                switchTab('phone');
            }
            const interfaceLink = document.querySelector('#vmo-phone-nav-accordion .nav-link.accordion-toggle');
            const interfacePanel = document.getElementById('panel-interface-details');
            if (interfaceLink && (!interfacePanel || !interfacePanel.classList.contains('open'))) {
                try { togglePhonePanel(interfaceLink, 'interface'); } catch (_) {}
            } else if (typeof switchPhonePanel === 'function') {
                try { switchPhonePanel('interface'); } catch (_) {}
            }
            const input = document.getElementById('vmo-dialer-input');
            if (input) input.focus();
        }
        function rememberLiveCall(callRef, extras){
            const state = window.__vmoDialerState || {};
            const source = extras && extras.source ? extras.source : (callRef && callRef.source ? callRef.source : state.activeSource || 'phone');
            const callSid = extras && extras.call_sid ? extras.call_sid : (callRef && callRef.call_sid ? callRef.call_sid : state.activeCallSid || window.__activeCallSid || '');
            const conferenceName = extras && Object.prototype.hasOwnProperty.call(extras, 'conference_name')
                ? (extras.conference_name || '')
                : (callRef && (callRef.conference_name || callRef.conference_sid) ? (callRef.conference_name || callRef.conference_sid) : (state.activeConferenceName || window.__activeConferenceName || ''));
            state.activeSource = source;
            state.activeCallSid = callSid;
            state.activeConferenceName = conferenceName;
            state.listenOnly = !!(extras && extras.listenOnly);
            state.listenMode = state.listenOnly ? ((extras && extras.listenMode) ? extras.listenMode : 'live') : '';
            state.held = !!(extras && extras.held);
            state.muted = !!(extras && extras.muted);
            window.__activeCallSid = callSid || window.__activeCallSid || '';
            window.__activeConferenceName = conferenceName || window.__activeConferenceName || '';
            updateDialerActionUI();
        }
        function clearDialerLiveState(options){
            options = options || {};
            const state = window.__vmoDialerState || {};
            state.muted = false;
            state.listenOnly = false;
            state.listenMode = '';
            state.held = false;
            if (!options.preserveCallRef) {
                state.activeSource = '';
                state.activeCallSid = '';
                state.activeConferenceName = '';
            }
            if (!options.preserveGlobals) {
                window.__activeCallSid = options.preserveCallRef ? (state.activeCallSid || '') : '';
                window.__activeConferenceName = options.preserveCallRef ? (state.activeConferenceName || '') : '';
            }
            updateDialerActionUI();
        }
        function acknowledgeIncomingSid(sid) {
            if (sid) window.__acknowledgedIncomingSids.add(sid);
        }
        function clearIncomingAcknowledgement(sid) {
            if (sid) window.__acknowledgedIncomingSids.delete(sid);
        }
        function isIncomingAcknowledged(sid) {
            return !!(sid && window.__acknowledgedIncomingSids && window.__acknowledgedIncomingSids.has(sid));
        }
        function isTerminalCallStatus(status) {
            return ['completed', 'busy', 'failed', 'canceled', 'cancelled', 'no-answer'].indexOf(String(status || '').toLowerCase()) !== -1;
        }
        function clearEndedCallUi(callSid, message) {
            if (callSid) {
                markSidHandled(callSid);
                clearIncomingAcknowledgement(callSid);
            }
            stopRinging();
            stopDialTone();
            stopBridgeListenSession();
            try { if (typeof closeLiveTranscript === 'function') closeLiveTranscript(); } catch (_) {}
            try { if (__twilioConnection) __twilioConnection.disconnect(); } catch (_) {}
            __twilioConnection = null;
            try { if (__twilioDevice) __twilioDevice.disconnectAll(); } catch (_) {}
            window.__pendingIncomingConn = null;
            clearPendingIncomingMeta();
            window.__currentIncomingCall = null;
            window.__outboundCallPending = false;
            clearDialerLiveState();
            const bnr = document.getElementById('vmo-incoming-banner');
            if (bnr) bnr.style.display = 'none';
            if (message) setDialerStatus(message, '#94a3b8');
            updateDialerActionUI();
        }
        function setPendingIncomingMeta(meta) {
            window.__pendingIncomingMeta = meta || null;
        }
        function clearPendingIncomingMeta() {
            window.__pendingIncomingMeta = null;
        }
        function getIncomingConnCallSid(conn) {
            return (conn && conn.parameters && conn.parameters.CallSid) ? String(conn.parameters.CallSid || '') : '';
        }
        function markIncomingConnReleasedForDirectBridge(conn) {
            const sid = getIncomingConnCallSid(conn);
            try { conn.__vmoReleasedForDirectBridge = true; } catch (_) {}
            if (sid) {
                window.__vmoReleasedIncomingConnSids = window.__vmoReleasedIncomingConnSids || new Set();
                window.__vmoReleasedIncomingConnSids.add(sid);
            }
        }
        function isIncomingConnReleasedForDirectBridge(conn) {
            const sid = getIncomingConnCallSid(conn);
            return !!(conn && conn.__vmoReleasedForDirectBridge) || !!(sid && window.__vmoReleasedIncomingConnSids && window.__vmoReleasedIncomingConnSids.has(sid));
        }
        async function releasePendingIncomingConnection() {
            const conn = window.__pendingIncomingConn || null;
            if (!conn) return;
            markIncomingConnReleasedForDirectBridge(conn);
            try { conn.reject(); } catch (_) {}
            if (window.__pendingIncomingConn === conn) window.__pendingIncomingConn = null;
            clearPendingIncomingMeta();
            stopRinging();
        }
        function getIncomingBrowserChildSid(callRef) {
            if (callRef && callRef.browser_call_sid) {
                return String(callRef.browser_call_sid || '');
            }
            if (window.__pendingIncomingMeta && window.__pendingIncomingMeta.browser_call_sid) {
                return String(window.__pendingIncomingMeta.browser_call_sid || '');
            }
            if (window.__pendingIncomingConn && window.__pendingIncomingConn.parameters && window.__pendingIncomingConn.parameters.CallSid) {
                return String(window.__pendingIncomingConn.parameters.CallSid || '');
            }
            return '';
        }
        function pickBestInboundLiveCall(liveCalls) {
            const calls = Array.isArray(liveCalls) ? liveCalls : [];
            const inboundLive = calls.filter(x => String(x.direction || '').toLowerCase() === 'inbound');
            if (inboundLive.length) return inboundLive[0];
            return calls.length ? calls[0] : null;
        }
        async function fetchBestInboundLiveCall() {
            const snapshotPick = pickBestInboundLiveCall(window.__lastLiveCallsSnapshot || []);
            if (snapshotPick && snapshotPick.call_sid) {
                return snapshotPick;
            }
            try {
                const liveRes = await ajaxPost('vmo_get_live_calls');
                const liveCalls = (liveRes && liveRes.success && liveRes.data && Array.isArray(liveRes.data.calls)) ? liveRes.data.calls : [];
                const bestLive = pickBestInboundLiveCall(liveCalls);
                if (bestLive) return bestLive;
            } catch (_) {
                // Fall through to locally remembered state.
            }
            if (window.__currentIncomingCall && (window.__currentIncomingCall.call_sid || window.__currentIncomingCall.browser_call_sid)) {
                return window.__currentIncomingCall;
            }
            if (window.__pendingIncomingMeta && window.__pendingIncomingMeta.browser_call_sid) {
                return Object.assign({}, window.__currentIncomingCall || {}, window.__pendingIncomingMeta);
            }
            return null;
        }
        async function resolveIncomingControlCall(explicitCall) {
            let callRef = explicitCall || window.__currentIncomingCall || null;
            if ((!callRef || (!callRef.call_sid && !getIncomingBrowserChildSid(callRef))) && window.__pendingIncomingMeta && (window.__pendingIncomingMeta.call_sid || window.__pendingIncomingMeta.browser_call_sid)) {
                callRef = Object.assign({}, callRef || {}, window.__pendingIncomingMeta);
            }
            if (!callRef || !callRef.call_sid || (!callRef.call_sid && !getIncomingBrowserChildSid(callRef)) || callRef.source === 'sdk_pending') {
                const childSid = getIncomingBrowserChildSid(callRef);
                const liveCall = await fetchBestInboundLiveCall();
                if (liveCall && liveCall.call_sid) {
                    callRef = Object.assign({}, callRef || {}, liveCall);
                    callRef.call_sid = liveCall.call_sid;
                    if (childSid && !callRef.browser_call_sid) {
                        callRef.browser_call_sid = childSid;
                    }
                } else if (!callRef || (!callRef.call_sid && !getIncomingBrowserChildSid(callRef))) {
                    callRef = liveCall;
                }
            }
            if (callRef && (callRef.call_sid || getIncomingBrowserChildSid(callRef))) {
                window.__currentIncomingCall = Object.assign({}, window.__currentIncomingCall || {}, callRef);
            }
            return callRef;
        }
        function isRetryableIncomingControlFailure(res) {
            const message = String((res && ((res.data && res.data.message) || res.message)) || '').toLowerCase();
            return message.indexOf('could not resolve the live call') !== -1
                || message.indexOf('missing call sid') !== -1
                || message.indexOf('no active call') !== -1
                || message.indexOf('call control failed') !== -1;
        }
        function waitForIncomingControlRetry(ms) {
            return new Promise(function(resolve) {
                window.setTimeout(resolve, ms);
            });
        }
        async function requestIncomingControlAction(actionType, callRef) {
            let workingCall = callRef || null;
            let lastResponse = null;

            for (let attempt = 0; attempt < 3; attempt += 1) {
                workingCall = await resolveIncomingControlCall(workingCall);
                const childSid = getIncomingBrowserChildSid(workingCall);

                if (!workingCall || (!workingCall.call_sid && !childSid)) {
                    lastResponse = {
                        success: false,
                        message: 'Could not resolve the live call to control.'
                    };
                } else {
                    lastResponse = await ajaxPost('vmo_call_action', {
                        action_type: actionType,
                        call_sid: workingCall.call_sid || '',
                        conference_sid: workingCall.conference_sid || workingCall.conference_name || '',
                        via: 'browser',
                        child_sid: childSid || ''
                    });

                    if (lastResponse && lastResponse.success) {
                        // Immediately mark the call as handled so ring_now polling stops
                        if (workingCall.call_sid) {
                            markSidHandled(workingCall.call_sid);
                            acknowledgeIncomingSid(workingCall.call_sid);
                        }
                        if (childSid) markSidHandled(childSid);
                        stopRinging();
                        if (childSid && !workingCall.browser_call_sid) {
                            workingCall = Object.assign({}, workingCall, {
                                browser_call_sid: childSid
                            });
                        }
                        return {
                            call: workingCall,
                            response: lastResponse
                        };
                    }
                }

                if (attempt >= 2 || !isRetryableIncomingControlFailure(lastResponse)) {
                    break;
                }

                await waitForIncomingControlRetry(250 * (attempt + 1));
            }

            return {
                call: workingCall,
                response: lastResponse || {
                    success: false,
                    message: 'Could not resolve the live call to control.'
                }
            };
        }
	        async function startIncomingTakeover(callRef) {
	            const c = await resolveIncomingControlCall(callRef);
	            if (!c || (!c.call_sid && !getIncomingBrowserChildSid(c))) {
	                notify('No active call to pick up', 'warning');
	                return false;
            }
            if (c.source === 'power_dialer') {
                const joined = await joinPowerDialerLiveCall(c, 'join');
                if (!joined) {
                    notify('Unable to join the live Power Dialer call.', 'error');
                    return false;
                }
	            } else {
                const initialChildSid = getIncomingBrowserChildSid(c);
	                setDialerStatus('Connecting browser to live caller…', '#10b981');
	                console.log('[VMO] Plugin takeover request:', {
	                    call_sid: c.call_sid || '',
	                    child_sid: initialChildSid || '',
	                    source: c.source || ''
	                });
	                const audioReady = await prepareBrowserLiveAudio({
	                    required: true,
	                    actionLabel: 'take over the live call'
	                });
	                if (!audioReady) {
	                    return false;
	                }
                const takeoverAction = await requestIncomingControlAction('join', c);
                const res = takeoverAction.response;
                const activeCall = takeoverAction.call || c;
                const childSid = getIncomingBrowserChildSid(activeCall) || initialChildSid;
                if (!res.success) {
                    const errMsg = (res.data && res.data.message) || res.message || 'Could not control the call';
                    console.warn('[VMO] Plugin takeover action failed:', errMsg, res, activeCall);
                    setDialerStatus('Takeover failed: ' + errMsg, '#ef4444');
                    notify(errMsg, 'error');
                    return false;
                }
                const resolvedCallSid = (res.data && res.data.call_sid) || activeCall.call_sid || '';
                if (!resolvedCallSid) {
                    notify('Could not resolve the live call to take over.', 'error');
                    return false;
                }
                const confName = (res.data && res.data.conference_name) || '';
	                if (!confName) {
	                    notify('Could not prepare the live audio bridge for takeover.', 'error');
	                    return false;
	                }
	                if (confName) {
	                    window.__currentIncomingCall = Object.assign({}, activeCall, {
	                        call_sid: resolvedCallSid,
	                        browser_call_sid: childSid || (activeCall.browser_call_sid || ''),
	                        conference_name: confName,
	                        source: activeCall.source || 'phone',
	                        status: 'in-progress'
	                    });
	                    // ── Acknowledge + stop ringing BEFORE browserJoinConference ──
	                    // The live-call polling loop runs on a timer and re-shows the
	                    // incoming banner if the call isn't acknowledged yet. Moving
	                    // acknowledgment here prevents the banner from re-appearing
	                    // while the browser is connecting to the conference.
	                    acknowledgeIncomingSid(resolvedCallSid);
	                    markSidHandled(resolvedCallSid); if(activeCall&&activeCall.call_sid&&activeCall.call_sid!==resolvedCallSid){acknowledgeIncomingSid(activeCall.call_sid);markSidHandled(activeCall.call_sid);}
	                    rememberLiveCall(activeCall, {
	                        source: activeCall.source || 'phone',
	                        call_sid: resolvedCallSid,
	                        conference_name: confName,
	                        listenOnly: false,
	                        held: false,
	                        muted: false
	                    });
	                    stopRinging();
                        stopBridgeListenSession();
	                    await releasePendingIncomingConnection();
	                    const joined = await browserJoinConference(confName, 'join');
                    if (!joined) {
                        notify('Failed to connect browser audio for this call', 'error');
                        return false;
                    }
                }
            }
            setDialerStatus('Connected to live caller.', '#10b981');
            updateIncomingAndRing(window.__lastLiveCallsSnapshot || []);
            return true;
        }
	        async function startIncomingListen(callRef) {
            const c = await resolveIncomingControlCall(callRef);
            const requestedSid = (c && c.call_sid) ? c.call_sid : '';
            if (!c || (!c.call_sid && !getIncomingBrowserChildSid(c))) {
                notify('No active call to listen to', 'warning');
                return false;
            }
            let started = false;
            let listenResult = null;
            try {
            if (c.source === 'power_dialer') {
                started = await joinPowerDialerLiveCall(c, 'listen');
            } else {
                const initialChildSid = getIncomingBrowserChildSid(c);
                setDialerStatus('Connecting browser listen mode…', '#38bdf8');
                console.log('[VMO] Plugin listen request:', {
                    call_sid: c.call_sid || '',
                    child_sid: initialChildSid || '',
                    source: c.source || ''
                });
                if (c.call_sid) {
                    acknowledgeIncomingSid(c.call_sid);
                    stopRinging();
                }
                const currentTierEl = document.querySelector('input[name="vmo-voice-quality"]:checked');
                const isPremiumListen = currentTierEl && currentTierEl.value === 'premium';
                if (!isPremiumListen) {
                    setDialerStatus('Opening transcript monitoring…', '#38bdf8');
                } else {
                    const audioReady = await prepareBrowserLiveAudio({
                        required: false,
                        actionLabel: 'listen to the live call'
                    });
                    if (!audioReady) {
                        console.warn('[VMO] Twilio browser audio is not ready yet; Premium bridge listen can still proceed without Twilio Device.');
                    }
                }
                const listenAction = await requestIncomingControlAction('listen', c);
                let res = listenAction.response;
                let activeCall = listenAction.call || c;
                let childSid = getIncomingBrowserChildSid(activeCall) || initialChildSid;
                listenResult = res;
                // Surface the backend's diagnostic so the user can immediately see WHY
                // realtime didn't engage (instead of having to dig through error_log).
                try {
                    const diag = res && res.data && res.data.diagnostic;
                    if (diag && isPremiumListen) {
                        console.warn('[VMO Listen Diagnostic] Realtime did NOT engage for this call. Reason details:', diag);
                        if (diag.hint) console.warn('[VMO Listen Diagnostic] Hint:', diag.hint);
                        if (diag.last_realtime_error) {
                            console.error('[VMO Listen Diagnostic] LAST REALTIME ERROR (server-side):', diag.last_realtime_error);
                        }
                        if (diag.voice_trace) {
                            console.error('[VMO Listen Diagnostic] VOICE WEBHOOK TRACE for this CallSid:', diag.voice_trace);
                        } else {
                            console.error('[VMO Listen Diagnostic] NO VOICE TRACE — voice webhook never ran for this CallSid (Twilio number Voice URL is wrong or cached).');
                        }
                        if (diag.openai_webhook_lasthit) {
                            console.error('[VMO Listen Diagnostic] OPENAI WEBHOOK LAST HIT:', diag.openai_webhook_lasthit);
                        }
                        if (diag.openai_webhook_lastfail) {
                            console.error('[VMO Listen Diagnostic] OPENAI WEBHOOK LAST FAIL:', diag.openai_webhook_lastfail);
                        }
                        if (diag.openai_accept_lastfail) {
                            console.error('[VMO Listen Diagnostic] OPENAI ACCEPT LAST FAIL:', diag.openai_accept_lastfail);
                        }
                    }
                } catch(_) {}
                const initialBridgePending = !!(res && res.success && res.data && res.data.bridge_pending);
                const initialConferenceName = String((res && res.data && res.data.conference_name) || '');
                const initialMode = String((res && res.data && res.data.mode) || '');
                const initialBridgeWsReady = initialMode === 'bridge_ws' && !!(res && res.data && res.data.listen_url);
                const isTranscriptMode = initialMode === 'transcript' || initialMode === 'realtime_monitor';
                if (((!res || !res.success) || initialBridgePending || (isPremiumListen && initialConferenceName === '' && !initialBridgeWsReady)) && isPremiumListen && !isTranscriptMode) {
                    setDialerStatus('Waiting for premium live audio bridge…', '#38bdf8');
                    for (let retry = 0; retry < 30; retry += 1) {
                        await waitForIncomingControlRetry(500);
                        const refreshedCall = await resolveIncomingControlCall(activeCall);
                        if (refreshedCall) {
                            activeCall = refreshedCall;
                        }
                        const retried = await requestIncomingControlAction('listen', activeCall);
                        res = retried.response;
                        activeCall = retried.call || activeCall;
                        childSid = getIncomingBrowserChildSid(activeCall) || initialChildSid;
                        listenResult = res;
                        const confNow = String((res && res.data && res.data.conference_name) || '');
                        const bridgePending = !!(res && res.data && res.data.bridge_pending);
                        const retryMode = String((res && res.data && res.data.mode) || '');
                        const bridgeWsReady = retryMode === 'bridge_ws' && !!(res && res.data && res.data.listen_url);
                        if (retryMode === 'transcript' || retryMode === 'realtime_monitor') {
                            // Backend confirmed transcript mode — no conference bridge will come.
                            // Accept this response immediately without further retrying.
                            break;
                        }
                        if (res && res.success && !bridgePending && (confNow !== '' || bridgeWsReady)) {
                            break;
                        }
                        const statusNow = String((activeCall && activeCall.status) || '').toLowerCase();
                        const premiumUnavailable = String(((res && ((res.data && res.data.message) || res.message)) || '')).toLowerCase().indexOf('premium live audio listen is not available') !== -1;
                        if (premiumUnavailable) {
                            // Backend confirmed no bridge will become available for this call;
                            // stop retrying immediately rather than waiting 15 seconds.
                            break;
                        }
                        if (isTerminalCallStatus(statusNow)) {
                            break;
                        }
                        if (!bridgePending && statusNow && statusNow !== 'ringing' && statusNow !== 'queued' && statusNow !== 'initiated') {
                            break;
                        }
                    }
                }
                if (!res || !res.success) {
                    const errMsg = (res && ((res.data && res.data.message) || res.message)) || 'Could not control the call';
                    console.warn('[VMO] Plugin listen action failed:', errMsg, res, activeCall);
                    setDialerStatus('Listen failed: ' + errMsg, '#ef4444');
                    notify(errMsg || 'Listen failed', 'error');
                    return false;
                }
                const resolvedCallSid = (res.data && res.data.call_sid) || activeCall.call_sid || '';
                if (!resolvedCallSid) {
                    notify('Could not resolve the live call to monitor.', 'error');
                    return false;
                }
                const listenRef = Object.assign({}, activeCall, {
                    call_sid: resolvedCallSid,
                    browser_call_sid: childSid || (activeCall.browser_call_sid || ''),
                    source: activeCall.source || 'phone',
                    status: 'in-progress'
                });
                // ── Acknowledge + stop ringing BEFORE browser audio join ──
                // Prevents the live-call polling loop from re-showing the
                // incoming banner while the browser is connecting.
                acknowledgeIncomingSid(resolvedCallSid);
                markSidHandled(resolvedCallSid); if(activeCall&&activeCall.call_sid&&activeCall.call_sid!==resolvedCallSid){acknowledgeIncomingSid(activeCall.call_sid);markSidHandled(activeCall.call_sid);}
                if (activeCall && activeCall.call_sid && activeCall.call_sid !== resolvedCallSid) {
                    acknowledgeIncomingSid(activeCall.call_sid);
                    markSidHandled(activeCall.call_sid);
                }
                stopRinging();
                await releasePendingIncomingConnection();
                const finalMode = String((res && res.data && res.data.mode) || '');
                if (isPremiumListen && finalMode !== 'transcript' && finalMode !== 'realtime_monitor' && finalMode !== 'bridge_ws') {
                    const finalBridgePending = !!(res && res.data && res.data.bridge_pending);
                    const finalConferenceName = String((res && res.data && res.data.conference_name) || '');
                    if (finalBridgePending || finalConferenceName === '') {
                        const errMsg = (res && ((res.data && res.data.message) || res.message)) || 'Premium listen bridge is still not ready.';
                        console.warn('[VMO] Premium listen bridge never became ready:', errMsg, res, activeCall);
                        setDialerStatus('Listen failed: ' + errMsg, '#ef4444');
                        notify(errMsg, 'error');
                        return false;
                    }
                }
                started = await startBrowserListenSession(listenRef, res);
                if (started) {
                    window.__currentIncomingCall = Object.assign({}, listenRef, {
                        conference_name: (res.data && res.data.conference_name) || '',
                    });
                }
            }
            if (!started) {
                return false;
            }
            const finalListenMode = String((listenResult && listenResult.data && listenResult.data.mode) || '');
            if (finalListenMode === 'transcript' || finalListenMode === 'realtime_monitor') {
                setDialerStatus('Monitoring transcript while the AI continues the conversation…', '#38bdf8');
            } else {
                setDialerStatus('Listening live while the AI continues the conversation…', '#38bdf8');
            }
            updateIncomingAndRing(window.__lastLiveCallsSnapshot || []);
            return true;
            } finally {
                if (requestedSid && window.__listenInFlight === requestedSid) {
                    window.__listenInFlight = '';
                }
            }
        }
        async function vmoPowerDialerBrowserAction(callSid, action) {
            const root = (window.wpApiSettings && window.wpApiSettings.root) ? String(window.wpApiSettings.root).replace(/\/$/, '') : '';
            if (!root) {
                throw new Error('Live browser bridge is not available for this Power Dialer call.');
            }
            const response = await fetch(root + '/vmo/v1/power-dialer/takeover', {
                method: 'POST',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': (window.wpApiSettings && window.wpApiSettings.nonce) ? window.wpApiSettings.nonce : ''
                },
                body: JSON.stringify({
                    call_sid: callSid,
                    action: action
                })
            });
            const payload = await response.json().catch(() => ({}));
            if (!response.ok || (payload && payload.code)) {
                throw new Error((payload && (payload.message || payload.error)) || 'Power Dialer live call action failed.');
            }
            return payload;
        }
	        async function joinPowerDialerLiveCall(callRef, mode){
	            const audioReady = await prepareBrowserLiveAudio({
	                required: true,
	                actionLabel: mode === 'listen' ? 'listen to the live Power Dialer call' : 'join the live Power Dialer call'
	            });
	            if (!audioReady) {
	                return false;
	            }
	            const action = mode === 'listen' ? 'browser_listen' : 'browser_join';
	            const payload = await vmoPowerDialerBrowserAction(callRef.call_sid, action);
            const conferenceName = (payload && payload.conference_name) ? payload.conference_name : ((callRef && callRef.conference_name) ? callRef.conference_name : ('pd_' + callRef.call_sid));
            const joined = await browserJoinConference(conferenceName, mode === 'listen' ? 'listen' : 'join');
            if (!joined) {
                return false;
            }
            rememberLiveCall(callRef, {
                source: 'power_dialer',
                call_sid: callRef.call_sid,
                conference_name: conferenceName,
                listenOnly: mode === 'listen',
                listenMode: mode === 'listen' ? 'live' : '',
                muted: false,
                held: false
            });
            setDialerStatus((payload && payload.message) ? payload.message : (mode === 'listen' ? 'Listening live to Power Dialer call…' : 'Joined live Power Dialer call.'), mode === 'listen' ? '#38bdf8' : '#10b981');
            return true;
        }
        function updateDialerActionUI(){
            const btn = document.getElementById('vmo-dialer-action');
            const holdBtn = document.getElementById('vmo-dialer-hold');
            const muteBtn = document.getElementById('vmo-dialer-mute');
            const backspaceBtn = document.getElementById('vmo-dialer-backspace');
            const input = document.getElementById('vmo-dialer-input');
            const state = window.__vmoDialerState || {};
            const hasCurrentIncoming = !!window.__currentIncomingCall;
            const hasAnyLiveCall = Array.isArray(window.__lastLiveCallsSnapshot) && window.__lastLiveCallsSnapshot.some(c => c && c.call_sid && !isTerminalCallStatus(c.status));
            const hasCallRef = !!(state.activeCallSid || window.__activeCallSid);
            const hasLiveConnection = !!__twilioConnection;
            const hasTypedNumber = !!(input && String(input.value || '').length);

            if (btn) {
                if (hasCurrentIncoming) {
                    btn.title = 'Take over incoming call';
                    btn.innerHTML = '📞 Join Live';
                    btn.classList.add('vmo-dialer-glow');
                    setDialerModeChip('Incoming', { color: '#f59e0b', border: 'rgba(245,158,11,.28)', background: 'rgba(245,158,11,.08)' });
                } else if (state.held && hasCallRef) {
                    btn.title = 'Rejoin held live call';
                    btn.innerHTML = '📞 Rejoin';
                    btn.classList.add('vmo-dialer-glow');
                    setDialerModeChip('On Hold', { color: '#a78bfa', border: 'rgba(167,139,250,.28)', background: 'rgba(167,139,250,.08)' });
                } else if (state.listenOnly && hasCallRef) {
                    btn.title = 'Take over current live call';
                    btn.innerHTML = '📞 Take Over';
                    btn.classList.add('vmo-dialer-glow');
                    setDialerModeChip('Listening', { color: '#38bdf8', border: 'rgba(56,189,248,.28)', background: 'rgba(56,189,248,.08)' });
                } else if (hasCallRef || hasLiveConnection || hasAnyLiveCall || window.__outboundCallPending) {
                    btn.title = 'Join live call';
                    btn.innerHTML = '📞 Join Live';
                    btn.classList.add('vmo-dialer-glow');
                    setDialerModeChip(window.__outboundCallPending ? 'Dialing' : 'Live Call', { color: '#10b981', border: 'rgba(16,185,129,.28)', background: 'rgba(16,185,129,.08)' });
                } else {
                    btn.title = 'Call';
                    btn.innerHTML = '📞 Call';
                    btn.classList.remove('vmo-dialer-glow');
                    setDialerModeChip('Idle', { color: '#38bdf8', border: 'rgba(56,189,248,.28)', background: 'rgba(56,189,248,.08)' });
                }
            }

            if (holdBtn) {
                const canHold = !!(hasCallRef || hasLiveConnection || state.held);
                holdBtn.disabled = !canHold;
                holdBtn.style.opacity = canHold ? '1' : '0.5';
                holdBtn.innerHTML = state.held ? '▶ Resume' : '⏸ Hold';
            }

            if (muteBtn) {
                const canMute = !!(hasLiveConnection && !state.listenOnly);
                muteBtn.disabled = !canMute;
                muteBtn.style.opacity = canMute ? '1' : '0.5';
                muteBtn.innerHTML = state.listenOnly
                    ? (state.listenMode === 'transcript' ? '📝 Monitoring' : '👂 Listening')
                    : (state.muted ? '🔊 Unmute' : '🔇 Mute');
            }

            if (backspaceBtn) {
                backspaceBtn.disabled = !hasTypedNumber;
                backspaceBtn.style.opacity = hasTypedNumber ? '1' : '0.5';
            }
        }
        function showIncomingBannerForCall(callMeta, modeText) {
            if (!callMeta) return;
            window.__currentIncomingCall = Object.assign({}, window.__currentIncomingCall || {}, callMeta);
            const bnr = document.getElementById('vmo-incoming-banner');
            const fromEl = document.getElementById('vmo-incoming-from');
            const modeEl = document.getElementById('vmo-incoming-mode');
            const bPick = document.getElementById('vmo-incoming-pick');
            const bListen = document.getElementById('vmo-incoming-listen');
            if (fromEl) {
                fromEl.textContent = `${callMeta.from_number || 'Unknown'} → ${callMeta.to_number || ''}`;
            }
            if (modeEl) {
                modeEl.textContent = modeText || 'Listen live or take over';
            }
            if (bPick) {
                bPick.textContent = '📞 Take Over';
                bPick.disabled = false;
                bPick.style.opacity = '1';
            }
            if (bListen) {
                bListen.textContent = '👂 Listen';
                bListen.disabled = false;
                bListen.style.opacity = '1';
            }
            if (bnr) {
                bnr.style.display = 'none'; // disabled duplicate banner
            }
            updateDialerActionUI();
        }
        function markSidHandled(sid) {
            if (sid) {
                window.__handledSids.add(sid);
                clearIncomingAcknowledgement(sid);
            }
        }
        function updateIncomingAndRing(calls){
            // Ensure calls is an array
            if (!Array.isArray(calls)) calls = [];
            window.__lastLiveCallsSnapshot = calls;
            const state = window.__vmoDialerState || {};

            // Any live call means outbound dial tone should stop.
            if (calls.length) {
                stopDialTone();
            }
            
            // Only inbound calls should trigger ringing/banner.
            const inbound = calls.filter(c => String(c && c.direction || '').toLowerCase() === 'inbound');
            // Prefer inbound calls targeting our business number
            const biz = (window.__businessNumber||'').replace(/\D/g,'');
            const inboundFiltered = inbound.filter(c=>{ if(!biz) return true; return String(c.to_number||'').replace(/\D/g,'') === biz; });
            const rawBase = inboundFiltered.length ? inboundFiltered : inbound;
            const terminalInbound = rawBase.filter(c => isTerminalCallStatus(c && c.status));
            const base = rawBase.filter(c => !isTerminalCallStatus(c && c.status));

            // Ring for calls that are ringing OR in-progress (AI answered).
            // The user wants the browser to keep ringing even while the AI
            // is already speaking, so they can listen in or take over.
            const ringStatuses = new Set(['ringing', 'queued', 'initiated']);
            const ringable = base.filter(c => {
                const st = String(c.status || '').toLowerCase();
                return ringStatuses.has(st) && !window.__handledSids.has(c.call_sid) && !isIncomingAcknowledged(c.call_sid) && c.owner_alert_ready !== false;
            });
            // In-progress calls the user hasn't handled yet — browser should
            // keep ringing so the owner notices even after the AI picks up.
            const inProgressUnhandled = base.filter(c => {
                const st = String(c.status || '').toLowerCase();
                return st === 'in-progress' && !window.__handledSids.has(c.call_sid) && !isIncomingAcknowledged(c.call_sid) && c.owner_alert_ready !== false;
            });

            const previousLiveSids = (window.__lastLiveSids instanceof Set) ? new Set(window.__lastLiveSids) : new Set();
            const sids = new Set(base.map(c=>c.call_sid));
            const ringableSids = new Set(ringable.map(c=>c.call_sid));
            let hasNewRingable = false;
            ringableSids.forEach(s => { if (!previousLiveSids.has(s)) hasNewRingable = true; });
            window.__lastLiveSids = sids;
            if (__ring.bannerDismissSid && !sids.has(__ring.bannerDismissSid)) {
                __ring.bannerDismissSid = null;
            }
            const bnr = document.getElementById('vmo-incoming-banner');
            const bnrMode = document.getElementById('vmo-incoming-mode');
            const bPick = document.getElementById('vmo-incoming-pick');
            const bListen = document.getElementById('vmo-incoming-listen');
            const pendingMeta = window.__pendingIncomingMeta || null;
            
            // Force hide + stop ringing when polling reports the inbound call ended.
            if (!base.length && pendingMeta && window.__pendingIncomingConn) {
                showIncomingBannerForCall(pendingMeta, 'Listen live or take over');
                if (__ring.enabled && ringNeedsRestart()) {
                    kickIncomingRing(pendingMeta.from_number || 'Unknown', true);
                }
                return;
            }
            if (terminalInbound.length) {
                terminalInbound.forEach(c => { if (c && c.call_sid) markSidHandled(c.call_sid); });
            }
            const activeCallGone = !!(state.activeCallSid && previousLiveSids.has(state.activeCallSid) && !sids.has(state.activeCallSid));
            if (!base.length && (terminalInbound.length || activeCallGone || window.__currentIncomingCall)) {
                const ended = terminalInbound.find(c => c && c.call_sid && (c.call_sid === state.activeCallSid || (window.__currentIncomingCall && c.call_sid === window.__currentIncomingCall.call_sid))) || terminalInbound[0] || window.__currentIncomingCall || {};
                clearEndedCallUi(ended.call_sid || state.activeCallSid || '', 'Call ended');
                return;
            }
            // If the call is gone from the database (!base.length) AND we don't have a live
            // active WebRTC audio connection, there is no reason to persist the banner. 
            // The call has formally disconnected.
            const shouldPersistControlBanner = false;
            if (shouldPersistControlBanner) {
                const persistedCall = Object.assign({}, window.__currentIncomingCall || pendingMeta || {}, {
                    call_sid: state.activeCallSid,
                    conference_name: state.activeConferenceName || ((window.__currentIncomingCall && window.__currentIncomingCall.conference_name) || ''),
                    source: state.activeSource || ((window.__currentIncomingCall && window.__currentIncomingCall.source) || 'phone'),
                    status: 'in-progress'
                });
                window.__currentIncomingCall = persistedCall;
                showIncomingBannerForCall(
                    persistedCall,
                    state.listenOnly
                        ? ((state.listenMode === 'transcript')
                            ? 'Monitoring transcript. Tap Take Over any time.'
                            : 'Listening live. Tap Take Over any time.')
                        : (state.held ? 'Call handed back to AI. Tap Resume or Take Over when ready.' : 'You are connected to this call')
                );
                if (bPick) {
                    if (state.listenOnly) {
                        bPick.textContent = '📞 Take Over';
                        bPick.disabled = false;
                        bPick.style.opacity = '1';
                    } else if (state.held) {
                        bPick.textContent = '📞 Resume';
                        bPick.disabled = false;
                        bPick.style.opacity = '1';
                    } else {
                        bPick.textContent = '📞 Connected';
                        bPick.disabled = true;
                        bPick.style.opacity = '0.7';
                    }
                }
                if (bListen) {
                    if (state.listenOnly) {
                        bListen.textContent = state.listenMode === 'transcript' ? '📝 Monitoring' : '👂 Listening';
                        bListen.disabled = true;
                        bListen.style.opacity = '0.7';
                    } else {
                        bListen.textContent = '👂 Listen';
                        bListen.disabled = !!__twilioConnection;
                        bListen.style.opacity = bListen.disabled ? '0.7' : '1';
                    }
                }
                stopRinging();
                updateDialerActionUI();
                return;
            }
            if(!base.length){ 
                if (!base.length) {
                    window.__pendingIncomingConn = null;
                    clearPendingIncomingMeta();
                    __ring.bannerDismissSid = null;
                }
                window.__currentIncomingCall=null; 
                if(bnr) bnr.style.display='none'; 
                stopRinging(); 
                updateDialerActionUI(); 
                return; 
            }

            // Only show banner / set currentIncomingCall for genuinely ringable calls.
            // If the call is already in-progress (AI answered), do NOT show the banner.
            const existingCurrent = window.__currentIncomingCall && window.__currentIncomingCall.call_sid
                ? base.find(c => c.call_sid === window.__currentIncomingCall.call_sid)
                : null;
            const target = existingCurrent || ringable[0] || inProgressUnhandled[0] || base[0];
            const targetStatus = String(target.status || '').toLowerCase();
            const isStillRinging = ringStatuses.has(targetStatus) && !window.__handledSids.has(target.call_sid);
            const acknowledged = isIncomingAcknowledged(target.call_sid);
            const hasActiveBrowserControl = !!((state.activeCallSid && state.activeCallSid === target.call_sid) || (window.__activeCallSid && window.__activeCallSid === target.call_sid));

            // Also filter out calls where from_number matches our own business number
            // (prevents phantom ringing from outbound call echoes after refresh).
            const fromDigits = String(target.from_number || '').replace(/\D/g, '');
            const isSelfCall = biz && fromDigits === biz;
            const isNewInProgressFallback = !isSelfCall
                && target
                && targetStatus === 'in-progress'
                && !window.__handledSids.has(target.call_sid)
                && !previousLiveSids.has(target.call_sid);

            // If there are inbound calls but NONE are ringable AND none are
            // in-progress unhandled, stop ringing. Otherwise keep going.
            if (!ringable.length && !inProgressUnhandled.length && !isNewInProgressFallback) {
                stopRinging();
            }

            const shouldShowBanner = !isSelfCall
                && !(__ring.bannerDismissSid && target.call_sid && __ring.bannerDismissSid === target.call_sid)
                && (!window.__handledSids.has(target.call_sid) || hasActiveBrowserControl);

            if (shouldShowBanner && bnr) {
                if (hasActiveBrowserControl && state.listenOnly) {
                    showIncomingBannerForCall(target, target.is_realtime ? 'Monitoring Realtime AI. Tap Take Over any time.' : 'Monitoring the call. Tap Take Over any time.');
                    if (bPick) {
                        bPick.textContent = '📞 Take Over';
                        bPick.disabled = false;
                        bPick.style.opacity = '1';
                    }
                    if (bListen) {
                        bListen.textContent = '👂 Listening';
                        bListen.disabled = true;
                        bListen.style.opacity = '0.7';
                    }
                } else if (hasActiveBrowserControl) {
                    showIncomingBannerForCall(target, 'You are connected to this call');
                    if (bPick) {
                        bPick.textContent = '📞 Connected';
                        bPick.disabled = true;
                        bPick.style.opacity = '0.7';
                    }
                    if (bListen) {
                        bListen.textContent = '👂 Listen';
                        bListen.disabled = true;
                        bListen.style.opacity = '0.7';
                    }
                } else {
                    showIncomingBannerForCall(target, (targetStatus === 'in-progress')
                        ? (target.is_realtime ? 'Realtime AI is handling this call' : 'AI is handling this call')
                        : 'Listen live or take over');
                }
            }

            if (isStillRinging && !isSelfCall) {
                window.__currentIncomingCall = target;
            } else if (!isSelfCall && target && targetStatus === 'in-progress') {
                // Call is in-progress (AI answered). Keep the banner visible so
                // the user can still Join / Listen. Keep ringing for unhandled
                // calls so the owner is alerted even while AI is speaking.
                window.__currentIncomingCall = target;
                if (!inProgressUnhandled.length && !isNewInProgressFallback) stopRinging();
            } else {
                // Call ended or is a self-echo — hide banner, no ringing
                window.__currentIncomingCall = null;
                if (bnr) bnr.style.display = 'none';
                stopRinging();
            }
            const shouldKeepAlerting = !acknowledged && (ringable.length || inProgressUnhandled.length || isNewInProgressFallback);
            if (shouldKeepAlerting && !isSelfCall && __ring.enabled && (hasNewRingable || isNewInProgressFallback || ringNeedsRestart())) {
                kickIncomingRing(target ? (target.from_number || 'Unknown') : '', hasNewRingable || isNewInProgressFallback);
            }
            updateDialerActionUI();
        }
        async function startServerOutboundFallback(to, statusEl){
            console.warn('[VMO Dialer] Falling back to server outbound bridge for:', to);
            const res = await ajaxPost('vmo_outbound_call', { to: to });
            if (!res || !res.success) {
                throw new Error((res && res.message) || 'Could not place outbound call');
            }
            const payload = res.data || {};
            window.__outboundCallPending = true;
            window.__activeCallSid = payload.sid || window.__activeCallSid || '';
            window.__activeConferenceName = payload.conference_name || window.__activeConferenceName || '';
            if (statusEl) statusEl.textContent = `Calling ${formatDisplayPhone(to)}`;
            if (window.__activeConferenceName) {
                try { browserJoinConference(window.__activeConferenceName, 'join'); } catch(_) {}
            }
            notify('Calling via phone bridge','info');
            return payload;
        }
        function collectPhonePrefsPayload(overrides){
            overrides = overrides || {};
            const greetingInput = document.getElementById('vmo-ai-greeting');
            const externalPhoneInput = document.getElementById('vmo-external-phone');
            const exts = {};
            const extLabels = {};
            for (let i=1;i<=7;i++) {
                const el = document.getElementById('vmo-ext-' + i);
                const lbl = document.getElementById('vmo-ext-label-' + i);
                if (el && (el.value||'').trim()) exts[String(i)] = (el.value||'').trim();
                if (lbl && (lbl.value||'').trim()) extLabels[String(i)] = (lbl.value||'').trim();
            }
            const vqEl = document.querySelector('input[name="vmo-voice-quality"]:checked');
            const payload = {
                greeting: (greetingInput ? greetingInput.value.trim() : ''),
                ai_receptionist_voice: (document.getElementById('vmo-ai-receptionist-voice') ? document.getElementById('vmo-ai-receptionist-voice').value : ''),
                ring_url: __ring.url || '',
                ring_attachment_id: (typeof window.__ringAttachmentId !== 'undefined' ? window.__ringAttachmentId : 0),
                external_phone: (externalPhoneInput ? externalPhoneInput.value.trim() : ''),
                ring_enabled: __ring.enabled ? 1 : 0,
                ring_volume: __ring.volume,
                ring_preset: __ring.preset || 'classic',
                voice_quality_tier: (vqEl ? vqEl.value : 'standard'),
                extensions: JSON.stringify(exts),
                extension_labels: JSON.stringify(extLabels)
            };
            const recordingInput = document.getElementById('vmo-recording-input');
            const emailAlertsInput = document.getElementById('vmo-email-alerts-input');
            const emailSummariesInput = document.getElementById('vmo-email-summaries-input');
            if (recordingInput) payload.call_recording_enabled = recordingInput.checked ? 1 : 0;
            if (emailAlertsInput) payload.email_incoming_alerts = emailAlertsInput.checked ? 1 : 0;
            if (emailSummariesInput) payload.email_call_summaries = emailSummariesInput.checked ? 1 : 0;
            return Object.assign(payload, overrides);
        }
        function bindDialer(){
            const input = document.getElementById('vmo-dialer-input');
            const actionBtn = document.getElementById('vmo-dialer-action');
            const status = document.getElementById('vmo-dialer-status');
            const listenBtn = document.getElementById('vmo-dialer-listen');
            const holdBtn = document.getElementById('vmo-dialer-hold');
            const muteBtn = document.getElementById('vmo-dialer-mute');
            const backspaceBtn = document.getElementById('vmo-dialer-backspace');
            // Removed noisy Listen Button test that mistakenly fired actual click handlers.

            const dropBtn = document.getElementById('vmo-dialer-drop');
            const ringBtn = document.getElementById('vmo-ring-toggle');
            const ringGear = document.getElementById('vmo-ring-settings-btn');
            const ringModal = document.getElementById('vmo-ring-settings');
            const ringVol = document.getElementById('vmo-ring-volume');
            const ringUrl = document.getElementById('vmo-ring-url');
            const ringPreset = document.getElementById('vmo-ring-preset');
            const ringSave = document.getElementById('vmo-ring-save');
            const ringTest = document.getElementById('vmo-ring-test');
            const ringClose = document.getElementById('vmo-ring-settings-close');
            const ringUpload = document.getElementById('vmo-ring-upload');
            const ringFile = document.getElementById('vmo-ring-file');
            const ringFileNote = document.getElementById('vmo-ring-file-note');
            const greetingInput = document.getElementById('vmo-ai-greeting');
            const bnr = document.getElementById('vmo-incoming-banner');
            const bPick = document.getElementById('vmo-incoming-pick');
            const bListen = document.getElementById('vmo-incoming-listen');
            const bOpenDialer = document.getElementById('vmo-incoming-open-dialer');
            const bDismiss = document.getElementById('vmo-incoming-dismiss');
            if (input && !input.dataset.vmoDialerInputBound) {
                input.dataset.vmoDialerInputBound = '1';
                input.addEventListener('input', updateDialerActionUI);
            }
            document.querySelectorAll('#vmo-sci-fi-dialer .action-btn[data-key]').forEach(btn=>{
                btn.addEventListener('click',()=>{
                    if (!input) return;
                    input.value = (input.value||'') + btn.getAttribute('data-key');
                    updateDialerActionUI();
                });
            });
            if (backspaceBtn) backspaceBtn.addEventListener('click', ()=>{
                if (!input) return;
                input.value = String(input.value || '').slice(0, -1);
                updateDialerActionUI();
            });
            if (ringBtn) {
                const updateSilentToggleUI = ()=>{
                    const isSilent = !__ring.enabled;
                    ringBtn.classList.toggle('active', isSilent);
                    ringBtn.textContent = '🔕 Silent';
                    ringBtn.title = isSilent ? 'Enable ringing alerts' : 'Silence ringing alerts';
                };
                updateSilentToggleUI();
                ringBtn.addEventListener('click', ()=>{
                    __ring.enabled = !__ring.enabled;
                    updateSilentToggleUI();
                    saveRingPrefs();
                    if(!__ring.enabled) stopRinging();
                    else if(window.__currentIncomingCall) { retryIncomingRingIfNeeded(true); }
                    ajaxPost('vmo_save_phone_prefs', collectPhonePrefsPayload({ ring_enabled: __ring.enabled ? 1 : 0 }))
                        .catch(()=>notify('Failed to save ring toggle','error'));
                });
            }
            if (ringGear) {
                ringGear.addEventListener('click', async ()=>{
                    if (!ringModal) return;
                    if (ringVol) ringVol.value = String(Math.round((__ring.volume||0)*100));
                    if (ringUrl) ringUrl.value = __ring.url || '';
                    if (ringPreset) ringPreset.value = __ring.preset || 'classic';
                    ringModal.style.display = 'flex';

                    await syncPhonePrefsFromServer({ persistLocal: true });
                });
            }
            if (ringClose) ringClose.addEventListener('click', ()=>{ if(ringModal) ringModal.style.display = 'none'; stopRinging(); });
            // Live volume update
            if (ringVol) ringVol.addEventListener('input', ()=>{
                const n = Number(ringVol.value);
                if(!Number.isNaN(n)) {
                    __ring.volume = Math.min(1, Math.max(0, n/100));
                    if(__ring.mediaEl) __ring.mediaEl.volume = __ring.volume;
                }
            });

            if (ringSave) ringSave.addEventListener('click', ()=>{
                if (ringVol){ const n = Number(ringVol.value); if(!Number.isNaN(n)) __ring.volume = Math.min(1, Math.max(0, n/100)); }
                if (ringUrl) __ring.url = (ringUrl.value||'').trim();
                if (ringPreset) __ring.preset = (ringPreset.value || 'classic');
                saveRingPrefs(); 
                stopRinging(); // Stop test sound on save
                
                // Persist greeting, ringtone, and external phone preference to server
                const payload = collectPhonePrefsPayload();
                ajaxPost('vmo_save_phone_prefs', payload).then(({success, message})=>{
                    if (!success) notify(message||'Failed to save preferences','error'); else notify('Preferences saved','success');
                }).catch(()=>notify('Failed to save preferences','error'));
                if (ringModal) ringModal.style.display = 'none';
            });
            
            if (ringTest) ringTest.addEventListener('click', ()=>{ 
                if(__ring.isRinging) {
                    stopRinging();
                } else {
                    // Update state from DOM inputs immediately for preview
                    if (ringVol){ const n = Number(ringVol.value); if(!Number.isNaN(n)) __ring.volume = Math.min(1, Math.max(0, n/100)); }
                    if (ringUrl) __ring.url = (ringUrl.value||'').trim();
                    if (ringPreset) __ring.preset = (ringPreset.value || 'classic');
                    
                    startRinging();
                    ringTest.innerHTML = '■ Stop';
                    ringTest.classList.add('danger');
                }
            });

            // Upload ringtone to WP Media Library and set URL
            if (ringUpload && ringFile) {
                ringUpload.addEventListener('click', ()=>{ try{ ringFile.value=''; }catch(_){} ringFile.click(); });
                ringFile.addEventListener('change', async ()=>{
                    if (!ringFile.files || !ringFile.files[0]) return;
                    const f = ringFile.files[0];
                    if (f && f.type && !String(f.type).toLowerCase().startsWith('audio/')) { notify('Please choose an audio file','warning'); return; }
                    if (ringFileNote) ringFileNote.textContent = 'Uploading…';
                    const form = new FormData();
                    form.append('action','vmo_upload_ringtone');
                    // Always send both: security (builder) and nonce (admin) for broad compatibility
                    form.append('security', VMO_NONCE_BUILDER);
                    form.append('nonce', VMO_NONCE_ADMIN);
                    form.append('file', f, f.name);
                    try{
                        const res = await fetch(VMO_AJAX, { method:'POST', body: form, credentials:'same-origin' });
                        const json = await res.json();
                        if (!json || !json.success) { notify((json && json.message) || 'Upload failed','error'); if(ringFileNote) ringFileNote.textContent=''; return; }
                        const url = json.data && (json.data.url || json.data.source_url);
                        const attId = json.data && json.data.attachment_id;
                        if (url) { if (ringUrl) ringUrl.value = url; __ring.url = url; }
                        window.__ringAttachmentId = attId || 0;
                        if (ringFileNote) ringFileNote.textContent = url ? 'Uploaded' : '';
                    }catch(e){ notify('Upload error','error'); if (ringFileNote) ringFileNote.textContent=''; }
                });
            }

            if (bOpenDialer) {
                bOpenDialer.addEventListener('click', ()=>{
                    openPhoneDialerSurface();
                });
            }
            if (bnr && bDismiss) bDismiss.addEventListener('click', ()=>{ if(window.__currentIncomingCall && window.__currentIncomingCall.call_sid){ __ring.bannerDismissSid = window.__currentIncomingCall.call_sid; markSidHandled(window.__currentIncomingCall.call_sid); } bnr.style.display='none'; stopRinging(); if(window.__pendingIncomingConn){ try{ window.__pendingIncomingConn.reject(); }catch(_){} window.__pendingIncomingConn=null; } });
	            if (bnr && bPick) bPick.addEventListener('click', async ()=>{
	                try{
	                    const started = await startIncomingTakeover(window.__currentIncomingCall);
	                    if (started) {
	                        notify('Picked up — connecting to caller…','success');
	                    }
	                }catch(e){ notify('Error picking up: '+e.message,'error'); }
	            });
	            if (bnr && bListen) bListen.addEventListener('click', async ()=>{
	                try {
	                    const started = await startIncomingListen(window.__currentIncomingCall);
	                } catch(e) { notify('Error: '+e.message,'error'); }
	            });
            if (actionBtn) actionBtn.addEventListener('click', async ()=>{
                // ✅ ISSUE 3 FIX: Do not auto-initiate calls without explicit user intent
                // Only proceed if: pending connection OR active call OR valid number entered
                const hasInput = input && toE164(input.value||'').length >= 8;
                const hasPendingConn = !!window.__pendingIncomingConn;
                const dialerState = window.__vmoDialerState || {};
                const liveSnapshotCalls = Array.isArray(window.__lastLiveCallsSnapshot) ? window.__lastLiveCallsSnapshot : [];
                const hasLiveStateRef = !!(dialerState.activeCallSid || dialerState.listenOnly || dialerState.held || window.__activeCallSid);
                const hasSnapshotLiveCall = liveSnapshotCalls.some(c => {
                    const st = String((c && c.status) || '').toLowerCase();
                    return !!(c && c.call_sid) && !isTerminalCallStatus(st);
                });
                const hasActiveCalls = !!window.__currentIncomingCall || hasLiveStateRef || hasSnapshotLiveCall;
                
                // Early safety return: if no input and no active calls, just show status
                if (!hasInput && !hasPendingConn && !hasActiveCalls) {
                    if (status) status.textContent = 'Enter a number to call or wait for incoming calls';
                    return; // ✅ PREVENT AUTO-CALLING BUG
                }

                const hasLiveControlRef = !!(dialerState.activeCallSid || dialerState.listenOnly || dialerState.held || window.__activeCallSid);

                // Determine if user typed a number — if so, they want to DIAL, but only when there is no current live/incoming call state.
                const wantsDial = !!(input && toE164(input.value||'').length >= 8) && !window.__currentIncomingCall && !window.__pendingIncomingConn && !hasLiveControlRef && !hasSnapshotLiveCall;

                // Incoming call control path: act on the parent call directly.
	                if (window.__pendingIncomingConn && !wantsDial) {
	                    try {
	                        const started = await startIncomingTakeover(window.__currentIncomingCall);
	                        if (started) {
	                            notify('Picking up — connecting to caller...','success');
	                        }
	                    } catch(e) {
	                        console.error('[VMO] Plugin takeover failed:', e);
	                        notify('Error picking up: ' + (e.message || e), 'error');
	                    }
	                    return;
	                }
                if (!wantsDial && (dialerState.listenOnly || dialerState.activeCallSid || window.__activeCallSid)) {
                    const liveSid = dialerState.activeCallSid || window.__activeCallSid || '';
                    let targetLiveCall = window.__currentIncomingCall && (window.__currentIncomingCall.call_sid === liveSid || !liveSid)
                        ? window.__currentIncomingCall
                        : null;
                    if (!targetLiveCall && liveSid) {
                        targetLiveCall = liveSnapshotCalls.find(c => c && c.call_sid === liveSid) || null;
                    }
                    if (!targetLiveCall && liveSid) {
                        targetLiveCall = { call_sid: liveSid, conference_name: dialerState.activeConferenceName || window.__activeConferenceName || '', source: dialerState.activeSource || 'phone', status: 'in-progress' };
                    }
                    if (targetLiveCall) {
                        try {
                            const started = await startIncomingTakeover(targetLiveCall);
                            if (started) {
                                notify('Joined call','success');
                                return;
                            }
                        } catch(e) {
                            console.warn('[VMO Dialer] Live takeover exception:', e.message||e);
                        }
                    }
                }

                // If there's a current incoming/active call AND user didn't type a number, join/pick up
                if (window.__currentIncomingCall && !wantsDial) {
                    try{
                        const started = await startIncomingTakeover(window.__currentIncomingCall);
                        if (started) {
                            notify('Joined call','success');
                            return;
                        }
                    }catch(e){
                        console.warn('[VMO Dialer] Join exception:', e.message||e, '— clearing stale state');
                        window.__currentIncomingCall = null;
                    }
                    // Fall through to outbound dial below
                }
                // Else, if any active call exists AND user didn't type a number, join it
                if (!wantsDial) {
                    try{
                        const {success, data} = await ajaxPost('vmo_get_live_calls');
                        const calls = success && data && Array.isArray(data.calls) ? data.calls : [];
	                        if (calls.length) {
	                            const c = calls[0];
	                            console.log('[VMO Dialer] Found live call:', c.call_sid, c.direction, c.status);
	                            const audioReady = await prepareBrowserLiveAudio({
	                                required: true,
	                                actionLabel: 'join the live call'
	                            });
	                            if (!audioReady) {
	                                return;
	                            }
	                            if (c.source === 'power_dialer') {
	                                try {
	                                    const joined = await joinPowerDialerLiveCall(c, 'join');
                                    if (joined) {
                                        notify('Joined live Power Dialer call','success');
                                        return;
                                    }
                                } catch (e) {
                                    notify('Unable to join the live Power Dialer call: ' + e.message, 'error');
                                    return;
                                }
                            }
                            const res = await ajaxPost('vmo_call_action', { action_type: 'join', call_sid: c.call_sid, conference_sid: c.conference_sid||'', via: 'browser' });
                            if (res.success) {
                                const cn=(res.data&&res.data.conference_name)||'';
                                if(cn){
                                    const joined = await browserJoinConference(cn,'join');
                                    if(!joined){
                                        notify('Failed to connect browser audio for this call','error');
                                        return;
                                    }
                                }
                                rememberLiveCall(c, { source: c.source || 'phone', conference_name: cn, listenOnly: false, held: false, muted: false });
                                notify('Joined call','success');
                                return;
                            }
                            // Join failed — call may be stale. Mark it handled so it stops blocking.
                            console.warn('[VMO Dialer] Join live call failed:', res.message||'unknown', '— skipping to outbound');
                            if(c.call_sid) markSidHandled(c.call_sid);
                        }
                    }catch(e){ /* ignore, will try outbound */ }
                }
                // Else, place an outbound call
                if (!input) return; const to = toE164(input.value);
                if (!to || to.length < 8) { if(status) status.textContent = 'Enter a valid number'; return; }
                console.log('[VMO Dialer] Placing outbound call to:', to, 'deviceReady:', __twilioReady, 'device:', !!__twilioDevice);
                actionBtn.disabled = true;
                if(status) status.textContent = 'Dialing…';
                startDialTone();
                try{
                    // Direct-dial via Twilio Voice SDK v2 — creates a single audio
                    // bridge between the browser and the callee without intermediate
                    // conference. The TwiML App VoiceUrl (handle_browser_call) receives
                    // {To: number} and returns <Dial><Number>number</Number></Dial>.
                    let browserFallbackStarted = false;
                    const tryServerFallback = async (reason) => {
                        if (browserFallbackStarted) return true;
                        browserFallbackStarted = true;
                        console.warn('[VMO Dialer] Browser outbound unavailable:', reason && (reason.message || reason));
                        stopDialTone();
                        notify('Browser phone is not ready. Please allow microphone access and try again.', 'warning');
                        return false;
                    };

                    if (__twilioReady && __twilioDevice) {
                        if (__twilioConnection) { __twilioConnection.disconnect(); __twilioConnection = null; }
                        try {
                            const call = await __twilioDevice.connect({ params: { To: to } });
                            __twilioConnection = call;
                            let outboundAccepted = false;
                            call.on('accept', function() {
                                outboundAccepted = true;
                                console.log('[VMO] Outbound call connected via browser');
                                stopDialTone();
                                rememberLiveCall({ call_sid: window.__activeCallSid || '', source: 'direct_browser' }, {
                                    source: 'direct_browser',
                                    call_sid: window.__activeCallSid || '',
                                    conference_name: '',
                                    listenOnly: false,
                                    held: false,
                                    muted: false
                                });
                                if(status) status.textContent = 'Call in progress';
                            });
                            call.on('error', function(err) {
                                console.error('[VMO] Outbound call error:', err);
                                if (!outboundAccepted) {
                                    void tryServerFallback(err);
                                    return;
                                }
                                stopDialTone();
                                notify('Call error: ' + (err.message || err), 'error');
                            });
                            call.on('disconnect', function() {
                                console.log('[VMO] Outbound call ended');
                                __twilioConnection = null;
                                window.__outboundCallPending = false;
                                if(status) status.textContent = 'Call ended';
                                // ── Full cleanup to prevent phantom ringing ──
                                stopRinging();
                                stopDialTone();
                                const bnr = document.getElementById('vmo-incoming-banner');
                                if (bnr) bnr.style.display = 'none';
                                // Mark all known SIDs as handled
                                if (window.__activeCallSid) {
                                    markSidHandled(window.__activeCallSid);
                                    // Force-complete in DB so live calls query stops returning it.
                                    // Pass caller_number + direction so the backend can INSERT
                                    // the record if the TwiML webhook never created it.
                                    const dialInput = document.getElementById('vmo-dialer-input');
                                    const callerNum = dialInput ? dialInput.value : '';
                                    ajaxPost('vmo_end_call', {
                                        call_sid: window.__activeCallSid,
                                        direction: 'outbound',
                                        caller_number: callerNum
                                    }).then(() => {
                                        // Refresh call history AFTER DB write confirms
                                        if (typeof refreshHistory === 'function') refreshHistory();
                                    }).catch(()=>{
                                        // Still try to refresh even if end_call errored
                                        if (typeof refreshHistory === 'function') setTimeout(refreshHistory, 1000);
                                    });
                                }
                                const sdkSid = call.parameters && call.parameters.CallSid;
                                if (sdkSid) markSidHandled(sdkSid);
                                if (window.__currentIncomingCall && window.__currentIncomingCall.call_sid) {
                                    markSidHandled(window.__currentIncomingCall.call_sid);
                                }
                                window.__activeCallSid = '';
                                window.__activeConferenceName = '';
                                window.__currentIncomingCall = null;
                                clearDialerLiveState();
                                // Refresh immediately so dashboard state is clean
                                if (typeof refreshLiveCalls === 'function') refreshLiveCalls();
                            });
                        } catch(err) {
                            console.error('[VMO] Connect failed:', err);
                            const recovered = await tryServerFallback(err);
                            if (!recovered) return;
                        }
                    } else {
                        const recovered = await tryServerFallback(new Error('Browser phone not ready'));
                        if (!recovered) return;
                    }

                    // Persist UI state until call ends
                    window.__outboundCallPending = true;
                    window.__activeCallSid = window.__activeCallSid || '';
                    window.__activeConferenceName = window.__activeConferenceName || '';
                    rememberLiveCall({ call_sid: window.__activeCallSid || '', conference_name: window.__activeConferenceName || '', source: 'direct_browser' }, { source: 'direct_browser', listenOnly: false, held: false, muted: false });
                    if(status && (!status.textContent || status.textContent === 'Dialing…')) status.textContent = `Calling ${formatDisplayPhone(to)}`;

                    // Poll live calls briefly to detect connection and stop dial tone.
                    const startedAt = Date.now();
                    const poll = async ()=>{
                        if (!window.__outboundCallPending) return;
                        try{
                            const res = await ajaxPost('vmo_get_live_calls');
                            const calls = (res && res.success && res.data && Array.isArray(res.data.calls)) ? res.data.calls : [];
                            if (calls.length) {
                                stopDialTone();
                                window.__outboundCallPending = false;
                                if(status) status.textContent = 'Call in progress';
                                return;
                            }
                        }catch(e){ /* ignore */ }
                        if (Date.now() - startedAt > 30000) {
                            // Stop tone after 30s to avoid hanging audio.
                            stopDialTone();
                            window.__outboundCallPending = false;
                            return;
                        }
                        setTimeout(poll, 2500);
                    };
                    setTimeout(poll, 1200);
                } catch (e) {
                    if (status) status.textContent = 'Error: ' + e.message;
                }
                actionBtn.disabled = false;
            });
            const contactsBtn = document.getElementById('vmo-dialer-contacts');
            if (contactsBtn) contactsBtn.addEventListener('click', ()=>openContactsModal());
	            if (listenBtn) listenBtn.addEventListener('click', async ()=>{
	                try{
	                    let targetCall = window.__currentIncomingCall;
	                    if (!targetCall || !targetCall.call_sid) {
                        targetCall = await fetchBestInboundLiveCall();
                    }
	                    const started = await startIncomingListen(targetCall);
	                    if (!started) {
	                        notify('No active call to listen','warning');
	                    }
	                }catch(e){ notify('Error: '+e.message,'error'); }
	            });
            if (dropBtn) dropBtn.addEventListener('click', async ()=>{
                try{
                    console.log('[VMO Drop] Ending all call sessions…');
                    const browserConnectionSid = (__twilioConnection && __twilioConnection.parameters && __twilioConnection.parameters.CallSid)
                        ? String(__twilioConnection.parameters.CallSid || '')
                        : '';
                    const pendingIncomingSid = (window.__pendingIncomingConn && window.__pendingIncomingConn.parameters && window.__pendingIncomingConn.parameters.CallSid)
                        ? String(window.__pendingIncomingConn.parameters.CallSid || '')
                        : '';
                    browserDisconnect(); // End browser audio immediately
                    stopDialTone();
                    stopRinging();

                    // Reject any pending incoming SDK connection (ringing call)
                    if (window.__pendingIncomingConn) {
                        try { window.__pendingIncomingConn.reject(); } catch(_){}
                        window.__pendingIncomingConn = null;
                    }

                    // Close live transcript panel if open
                    if (typeof closeLiveTranscript === 'function') {
                        try { closeLiveTranscript(); } catch(_){}
                    }

                    // Collect ALL call SIDs that need ending
                    const sidsToEnd = new Set();

                    if (window.__activeCallSid) sidsToEnd.add(window.__activeCallSid);
                    if (browserConnectionSid) sidsToEnd.add(browserConnectionSid);
                    if (pendingIncomingSid) sidsToEnd.add(pendingIncomingSid);
                    if (window.__currentIncomingCall && window.__currentIncomingCall.call_sid) {
                        sidsToEnd.add(window.__currentIncomingCall.call_sid);
                    }
                    if (window.__currentIncomingCall && window.__currentIncomingCall.browser_call_sid) {
                        sidsToEnd.add(window.__currentIncomingCall.browser_call_sid);
                    }

                    // Also check live calls from server — catches any calls the UI lost track of
                    try {
                        const {success, data} = await ajaxPost('vmo_get_live_calls');
                        const calls = success && data && Array.isArray(data.calls) ? data.calls : [];
                        calls.forEach(c => { if (c.call_sid) sidsToEnd.add(c.call_sid); });
                    } catch(_){}

                    if (sidsToEnd.size === 0) {
                        const fallbackEnd = await ajaxPost('vmo_end_call', {
                            call_sid: '',
                            force_active: '1',
                            reason: 'dashboard_drop_lost_sid'
                        });
                        if (!fallbackEnd.success) {
                            notify('No active call to drop','warning');
                            return;
                        }
                        notify('Call end sent','success');
                        if (typeof refreshLiveCalls === 'function') refreshLiveCalls();
                        if (typeof refreshHistory === 'function') refreshHistory();
                        return;
                    }

                    console.log('[VMO Drop] Ending', sidsToEnd.size, 'call(s):', [...sidsToEnd]);

                    // End each call on the server
                    const dialInput = document.getElementById('vmo-dialer-input');
                    const callerNum = dialInput ? dialInput.value : '';
                    const endPromises = [...sidsToEnd].map(sid =>
                        ajaxPost('vmo_end_call', {
                            call_sid: sid,
                            direction: 'outbound',
                            caller_number: callerNum,
                            force_active: '1',
                            reason: 'dashboard_drop'
                        }).then(res => {
                            if (!res.success) console.warn('[VMO Drop] end_call failed for', sid, res.message||'');
                            markSidHandled(sid);
                        }).catch(err => {
                            console.warn('[VMO Drop] end_call error for', sid, err.message||err);
                            markSidHandled(sid);
                        })
                    );
                    await Promise.all(endPromises);

                    notify('Call ended','success');

                    // Full state cleanup
                    window.__outboundCallPending = false;
                    window.__activeCallSid = '';
                    window.__activeConferenceName = '';
                    window.__currentIncomingCall = null;
                    clearDialerLiveState();
                    const bnr = document.getElementById('vmo-incoming-banner'); if(bnr) bnr.style.display='none';
                    const status = document.getElementById('vmo-dialer-status'); if(status) status.textContent = '';
                    // Re-enable the action button in case it was disabled during an outbound attempt
                    if (actionBtn) actionBtn.disabled = false;
                    updateDialerActionUI();
                    if (typeof refreshLiveCalls === 'function') refreshLiveCalls();
                    if (typeof refreshHistory === 'function') refreshHistory();
                }catch(e){ notify('Error: '+e.message,'error'); }
            });
            if (muteBtn) muteBtn.addEventListener('click', ()=>{
                const state = window.__vmoDialerState || {};
                if (state.listenOnly) {
                    notify('Listen mode already keeps you muted.', 'info');
                    return;
                }
                if (!__twilioConnection || typeof __twilioConnection.mute !== 'function') {
                    notify('Mute is available only while your browser is connected to a live call.', 'warning');
                    return;
                }
                const nextMuted = !state.muted;
                try {
                    __twilioConnection.mute(nextMuted);
                    state.muted = nextMuted;
                    updateDialerActionUI();
                    setDialerStatus(nextMuted ? 'Microphone muted.' : 'Microphone live.', nextMuted ? '#f59e0b' : '#10b981');
                } catch (e) {
                    notify('Unable to change mute state right now.', 'error');
                }
            });
            if (holdBtn) holdBtn.addEventListener('click', async ()=>{
                const state = window.__vmoDialerState || {};
                const callSid = state.activeCallSid || window.__activeCallSid || (window.__currentIncomingCall && window.__currentIncomingCall.call_sid) || '';
                if (!callSid) {
                    notify('No live call is available for hold or resume.', 'warning');
                    return;
                }
                
                try {
                    const actionType = state.held ? 'unhold' : 'hold';
                    const res = await ajaxPost('vmo_call_action', { 
                        action_type: actionType, 
                        call_sid: callSid, 
                        conference_sid: state.activeConferenceName || '', 
                        via: 'browser' 
                    });
                    
                    if (!res || !res.success) {
                        notify((res && res.message) || 'Unable to complete hold action.', 'error');
                        return;
                    }
                    
                    const isNowHeld = !state.held;
                    
                    rememberLiveCall({ call_sid: callSid, source: state.activeSource || 'phone' }, {
                        source: state.activeSource || 'phone',
                        conference_name: state.activeConferenceName || (res.data && res.data.conference_name) || '',
                        listenOnly: false,
                        held: isNowHeld,
                        muted: state.muted || false
                    });
                    
                    if (isNowHeld) {
                        notify('Caller placed on hold with music.', 'info');
                        setDialerStatus('Caller is currently on hold.', '#f59e0b');
                    } else {
                        notify('Caller resumed from hold.', 'success');
                        setDialerStatus('Live call resumed.', '#10b981');
                    }
                    updateDialerActionUI();
                } catch (e) {
                    notify('Error during hold action: ' + e.message, 'error');
                }
            });
        }
        function openContactsModal(){
            const modal = document.getElementById('vmo-contacts-modal'); 
            if(!modal) return; 
            modal.style.display='flex';
            modal.style.alignItems='center';
            modal.style.justifyContent='center';
            loadContactsList('');
            const closeBtn = document.getElementById('vmo-contacts-close'); if (closeBtn) closeBtn.onclick = closeContactsModal;
            const searchInput = document.getElementById('vmo-contacts-search');
            const refreshBtn = document.getElementById('vmo-contacts-refresh');
            const doSearch = ()=>{ loadContactsList(searchInput ? searchInput.value : ''); };
            let t; if (searchInput) searchInput.oninput = ()=>{ clearTimeout(t); t = setTimeout(doSearch, 250); };
            if (refreshBtn) refreshBtn.onclick = doSearch;
        }
        function closeContactsModal(){ const modal=document.getElementById('vmo-contacts-modal'); if(modal) modal.style.display='none'; }
        async function loadContactsList(search){
            const list = document.getElementById('vmo-contacts-list'); if (list) list.innerHTML = '<div style="color:var(--muted); padding:12px;">Loading…</div>';
            try{
                const {success, data, message} = await ajaxPost('vmo_get_quick_contacts', { search: (search||'').trim(), limit: 100 });
                if (!success) { if(list) list.innerHTML = '<div style="color:var(--muted); padding:12px;">No contacts yet</div>'; return; }
                const contacts = Array.isArray(data && data.contacts) ? data.contacts : [];
                if (!contacts.length) {
                    const q = (search||'').trim();
                    if(list) list.innerHTML = q ? '<div style="color:var(--muted); padding:12px;">No results</div>' : '<div style="color:var(--muted); padding:12px;">No contacts yet</div>';
                    return;
                }
                contacts.sort((a,b)=>String(a.name||'').localeCompare(String(b.name||'')));
                const frag = document.createDocumentFragment();
                contacts.forEach(c=>{
                    const row = document.createElement('div');
                    row.className = 'nav-link';
                    row.style.margin = '4px 0';
                    const name = String(c.name||'Unnamed').replace(/</g,'&lt;');
                    const comp = String(c.company||'').replace(/</g,'&lt;');
                    const phone = formatDisplayPhone(c.phone||'');
                    row.innerHTML = `<div class=\"nav-text\">${name} <small style=\"color:var(--muted)\">${comp}</small></div><div class=\"nav-badge\">${phone}</div>`;
                    row.addEventListener('click',()=>{
                        const input = document.getElementById('vmo-dialer-input'); if (input) input.value = c.phone || '';
                        closeContactsModal();
                    });
                    frag.appendChild(row);
                });
                if (list) { list.innerHTML = ''; list.appendChild(frag); }
            }catch(e){ console.warn('Contacts load failed', e); if(list) list.innerHTML = '<div style="color:var(--muted); padding:12px;">No contacts yet</div>'; }
        }
        // Phone overview KPIs and business number
        async function loadPhoneOverview(){
            try{
                const s = await ajaxPost('vmo_get_phone_status');
                console.log('[VMO Phone] Status response:', s && s.success ? 'success' : 'fail', 'phone=' + (s && s.data ? s.data.phone_number : '(none)'));
                if (s && s.success && s.data) {
                    const num = s.data.phone_number || '';
                    const el = document.getElementById('vmo-assigned-number');
                    if (el) {
                        if (num) {
                            el.textContent = formatDisplayPhone(num);
                        } else {
                            // Don't overwrite PHP-rendered number with blank if AJAX failed to find one
                            const currentText = el.textContent.trim();
                            if (currentText && currentText !== '—' && currentText !== '–') {
                                console.log('[VMO Phone] Keeping PHP-rendered number:', currentText);
                            } else {
                                el.textContent = '—';
                            }
                        }
                    }
                    // Persist to window for ring filtering
                    window.__businessNumber = num;
                    // Prefill ring/greeting from server if available
                    try {
                        if (typeof s.data.ring_attachment_id !== 'undefined') {
                            window.__ringAttachmentId = s.data.ring_attachment_id || 0;
                        }
                        if (s.data.ring_url) {
                            __ring.url = s.data.ring_url;
                            const ringUrlEl = document.getElementById('vmo-ring-url');
                            if (ringUrlEl) ringUrlEl.value = String(s.data.ring_url || '');
                        }
                        if (s.data.ai_greeting) {
                            const greetEl = document.getElementById('vmo-ai-greeting');
                            if (greetEl) greetEl.value = String(s.data.ai_greeting || '');
                        }
                    } catch(e){}
                }
            }catch(e){}
            try{
                const r = await ajaxPost('vmo_dashboard_stats');
                if (r && r.success && r.data) {
                    // Find Today's Call Summary card and fill first two values
                    const cards = document.querySelectorAll('#phone .vmo-card');
                    const summary = Array.from(cards).find(c => (c.querySelector('h4')||{}).textContent && c.querySelector('h4').textContent.indexOf("Today's Call Summary") !== -1);
                    if (summary) {
                        const kvs = summary.querySelectorAll('.vmo-kv strong');
                        if (kvs[0]) kvs[0].textContent = String(r.data.calls_today || 0);
                        if (kvs[1]) {
                            const secs = parseInt(r.data.avg_call_duration||0,10);
                            const txt = secs>0 ? (Math.floor(secs/60)+'m '+(secs%60)+'s') : '0s';
                            kvs[1].textContent = txt;
                        }
                        // Optional cost if backend provides it
                        if (kvs[2]) {
                            const tokens = (typeof r.data.tokens_cost_today === 'number') ? r.data.tokens_cost_today : null;
                            if (tokens != null) {
                                kvs[2].textContent = tokens.toLocaleString();
                            } else {
                                // leave as placeholder if not available
                                if (!kvs[2].textContent || kvs[2].textContent === '—') kvs[2].textContent = '—';
                            }
                        }
                    }
                }
            }catch(e){}
        }

        // Lightweight background ring poll (does not render lists)
        // Must keep ringing working even when user is on other tabs; avoid spamming failures.
        let __ringPollTimer = null;
        let __ringPollActive = false;
        let __ringPollFailures = 0;
        let __ringPollBaseMs = 6000;
        let __ringPollHadCalls = false; // Track if previous poll had active calls

        function startRingPoll(){
            if (__ringPollActive) return;
            __ringPollActive = true;
            __ringPollFailures = 0;
            __ringPollBaseMs = 6000;

            const schedule = () => {
                if (!__ringPollActive) return;
                // Browsers throttle background timers; use a slightly higher minimum when hidden.
                const minHidden = 12000;
                const base = __ringPollBaseMs;
                const delay = (document.hidden ? Math.max(base, minHidden) : base);

                __ringPollTimer = setTimeout(async () => {
                    try {
                        if (!__ringPollActive) return;
                        const r = await ajaxPost('vmo_get_live_calls');
                        const calls = (r && r.success && r.data && Array.isArray(r.data.calls)) ? r.data.calls : [];
                        if (typeof updateIncomingAndRing === 'function') {
                            try {
                                updateIncomingAndRing(calls);
                            } catch (ringUiError) {
                                console.error('[VMO Ring] updateIncomingAndRing failed during startRingPoll:', ringUiError);
                            }
                        }

                        // RING-NOW SIGNAL: force-ring on backend ring signal
                        if (r && r.success && r.data && r.data.ring_now && typeof kickIncomingRing === 'function') {
                            const rn = r.data.ring_now;
                            const rnSid = rn.call_sid || '';
                            if (rnSid && !window.__handledSids.has(rnSid)) {
                                showIncomingBannerForCall({
                                    call_sid: rnSid,
                                    from_number: (rn.from || 'Unknown'),
                                    to_number: (window.__businessNumber || ''),
                                    direction: 'inbound',
                                    status: 'ringing',
                                    source: 'ring_now'
                                }, 'Listen live or take over');
                                kickIncomingRing(rn.from || 'Unknown', true);
                            }
                        }

                        // Auto-refresh call history when a call just ended
                        // (live calls dropped to 0 but previous poll had active calls)
                        if (__ringPollHadCalls && calls.length === 0) {
                            if (typeof refreshHistory === 'function') setTimeout(refreshHistory, 1500);
                        }
                        __ringPollHadCalls = calls.length > 0;

                        // Success: reset backoff
                        __ringPollFailures = 0;
                        __ringPollBaseMs = 6000;
                    } catch (e) {
                        // Failure: exponential backoff up to 60s; don't console-spam
                        __ringPollFailures = Math.min(10, (__ringPollFailures || 0) + 1);
                        const pow = Math.min(4, __ringPollFailures); // cap at 16x
                        __ringPollBaseMs = Math.min(60000, 6000 * Math.pow(2, pow));
                    } finally {
                        schedule();
                    }
                }, delay);
            };

            schedule();
        }

        function stopRingPoll(){
            __ringPollActive = false;
            if (__ringPollTimer) { clearTimeout(__ringPollTimer); __ringPollTimer = null; }
        }
        // Phone analytics (30 days window)
        async function loadPhoneAnalytics(){
            const set = (id, val)=>{ const el=document.getElementById(id); if(el) el.textContent = val; };
            try{
                const response = await ajaxPost('vmo_get_phone_analytics');
                const {success, data, message} = response || {};
                
                if (!success) {
                    console.warn('Phone analytics error:', message || 'Unknown error');
                    // Set placeholder values on error
                    set('vmo-anl-total', '—');
                    set('vmo-anl-answered', '—');
                    set('vmo-anl-missed', '—');
                    set('vmo-anl-avg', '—');
                    set('vmo-anl-intent', '—');
                    set('vmo-anl-new', '—');
                    set('vmo-anl-return', '—');
                    return;
                }
                
                if (!data) {
                    console.warn('Phone analytics: no data received');
                    set('vmo-anl-total', '—');
                    set('vmo-anl-answered', '—');
                    set('vmo-anl-missed', '—');
                    set('vmo-anl-avg', '—');
                    set('vmo-anl-intent', '—');
                    set('vmo-anl-new', '—');
                    set('vmo-anl-return', '—');
                    return;
                }
                
                // Set all values with proper defaults
                const total = parseInt(data.total_calls) || 0;
                const answered = parseInt(data.answered_calls) || 0;
                const missed = parseInt(data.missed_calls) || 0;
                const avgDur = parseInt(data.average_duration) || 0;
                const intent = data.top_intent || '—';
                const newCust = parseInt(data.new_customers) || 0;
                const retCust = parseInt(data.return_customers) || 0;
                
                set('vmo-anl-total', String(total));
                set('vmo-anl-answered', String(answered));
                set('vmo-anl-missed', String(missed));
                
                // Format average duration properly
                if (avgDur > 0) {
                    const mins = Math.floor(avgDur / 60);
                    const secs = avgDur % 60;
                    set('vmo-anl-avg', mins + 'm ' + secs + 's');
                } else {
                    set('vmo-anl-avg', '0s');
                }
                
                set('vmo-anl-intent', intent);
                set('vmo-anl-new', String(newCust));
                set('vmo-anl-return', String(retCust));
                
                // Draw spark chart with call distribution across 30 days
                // Create an array with values distributed over the period
                const sparkData = total > 0 ? [0, Math.floor(total/2), total] : [0, 0];
                drawSpark('vmo-anl-spark', sparkData);
                
            }catch(e){
                console.error('Exception in loadPhoneAnalytics:', e);
                // Set all to dashes on exception
                set('vmo-anl-total', '—');
                set('vmo-anl-answered', '—');
                set('vmo-anl-missed', '—');
                set('vmo-anl-avg', '—');
                set('vmo-anl-intent', '—');
                set('vmo-anl-new', '—');
                set('vmo-anl-return', '—');
            }
            // Load AI call summaries
            try { loadCallSummaries(); } catch(e){ console.error('loadCallSummaries error:', e); }
        }
        
        // 🆕 PHASE 2 DAY 2: Load AI call summaries with sentiment analysis
        async function loadCallSummaries(period = '30days', limit = 50) {
            try {
                const result = await ajaxPost('vmo_ajax_get_call_summaries', { period, limit });
                
                if (result.success && result.data) {
                    displayCallSummaries(result.data.summaries, result.data.stats);
                } else {
                    console.error('Failed to load call summaries:', result);
                }
            } catch (error) {
                console.error('Error loading call summaries:', error);
            }
        }
        
        // Display call summaries in the AI Summaries panel (below call history)
        function displayCallSummaries(summaries, stats) {
            const historyList = document.getElementById('vmo-ai-summaries-list');
            if (!historyList) return;
            
            if (!summaries || summaries.length === 0) {
                historyList.innerHTML = '<div style="padding:20px; text-align:center; color:var(--muted);">No call summaries yet. AI will analyze calls automatically.</div>';
                return;
            }
            
            // Update stats in Today's Call Summary card
            if (stats) {
                const costEl = document.querySelector('#vmo-today-summary-card strong[style*="orange"]');
                if (costEl && stats.total_summaries) {
                    costEl.textContent = stats.total_summaries + ' analyzed';
                }
            }
            
            // Create summary cards
            historyList.innerHTML = summaries.map(summary => {
                const fromNumber = summary.caller_number || 'Unknown';
                const duration = summary.duration ? Math.floor(summary.duration / 60) + 'm ' + (summary.duration % 60) + 's' : 'N/A';
                const callDate = summary.created_at ? new Date(summary.created_at).toLocaleString() : '';
                const hasSummary = summary.summary && summary.summary.trim();
                const hasTranscript = summary.transcript && summary.transcript.trim();
                const statusColor = summary.status === 'completed' ? '#10b981' : '#f59e0b';
                const dirIcon = summary.direction === 'outbound' ? '📤' : '📥';
                
                return `
                    <div class="vmo-card" style="margin-bottom: 10px; border-left: 3px solid ${statusColor};">
                        <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 8px;">
                            <div>
                                <h4 style="margin: 0 0 4px 0;">${dirIcon} Call ${summary.direction === 'outbound' ? 'to' : 'from'} ${fromNumber}</h4>
                                <div style="font-size: 11px; color: var(--muted);">${callDate} • ${duration}</div>
                            </div>
                            <div style="background: ${statusColor}22; color: ${statusColor}; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase;">
                                ${summary.status || 'unknown'}
                            </div>
                        </div>
                        
                        ${hasSummary ? `
                            <div style="margin: 8px 0; padding: 10px 12px; background: rgba(26,115,232,0.06); border-left: 3px solid #1a73e8; border-radius: 4px;">
                                <strong style="font-size: 12px; color: #1a73e8;">🤖 AI Summary</strong>
                                <div style="font-size: 12px; color: var(--muted); margin-top: 4px; white-space: pre-line; line-height: 1.5;">${summary.summary}</div>
                            </div>
                        ` : ''}
                        
                        ${hasTranscript ? `
                            <div style="margin-top: 8px;">
                                <button class="action-btn" onclick="showFullTranscript('${summary.id}')" style="font-size: 11px;">
                                    📄 View Full Transcript
                                </button>
                            </div>
                        ` : ''}
                    </div>
                `;
            }).join('');
        }
        
        // Show full transcript modal
        function showFullTranscript(summaryId) {
            // Create modal dynamically
            const modal = document.createElement('div');
            modal.id = 'vmo-transcript-modal';
            modal.style.cssText = 'display:flex; position:fixed; inset:0; background:rgba(0,0,0,.6); z-index:10000; align-items:center; justify-content:center;';
            modal.innerHTML = `
                <div style="background:var(--panel-bg, #0b0f1a); border:1px solid var(--border); border-radius:12px; width:min(800px, 92vw); max-height:80vh; display:flex; flex-direction:column;">
                    <div style="display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--border);">
                        <strong>Full Call Transcript</strong>
                        <button class="action-btn" onclick="document.getElementById('vmo-transcript-modal').remove()">✖</button>
                    </div>
                    <div id="vmo-transcript-body" style="padding:14px; overflow:auto; flex:1;">
                        <div style="color:var(--muted);">Loading transcript...</div>
                    </div>
                </div>
            `;
            document.body.appendChild(modal);
            
            // Load transcript via AJAX (through gateway)
            ajaxPost('vmo_ajax_get_call_summaries', { summary_id: summaryId })
            .then(result => {
                const body = document.getElementById('vmo-transcript-body');
                if (result.success && result.data && result.data.summaries && result.data.summaries[0]) {
                    const summary = result.data.summaries[0];
                    body.innerHTML = `
                        <div style="white-space: pre-wrap; font-family: monospace; font-size: 13px; line-height: 1.6; color: var(--ink);">
                            ${summary.transcript || 'No transcript available'}
                        </div>
                    `;
                } else {
                    body.innerHTML = '<div style="color:var(--muted);">Transcript not available</div>';
                }
            })
            .catch(err => {
                const body = document.getElementById('vmo-transcript-body');
                body.innerHTML = '<div style="color:#f44336;">Error loading transcript</div>';
                console.error(err);
            });
        }
        
        // ============================================================
        // REPORTS & ACTION ITEMS PANEL
        // ============================================================

        function vmoSwitchReportTab(tab) {
            document.querySelectorAll('.vmo-report-tab-content').forEach(el => el.style.display = 'none');
            document.querySelectorAll('.vmo-report-tab').forEach(el => el.classList.remove('active'));
            const target = document.getElementById('vmo-tab-' + tab);
            if (target) target.style.display = 'block';
            const btn = document.querySelector('.vmo-report-tab[data-tab="' + tab + '"]');
            if (btn) btn.classList.add('active');
            // Auto-load data for the selected tab
            if (tab === 'action-items') vmoLoadActionItems();
            if (tab === 'call-reports') vmoLoadCallReports();
            if (tab === 'daily-reports') vmoLoadPeriodicReports('daily');
            if (tab === 'periodic-reports') vmoLoadPeriodicReports();
            if (tab === 'fulfillment-log') vmoLoadFulfillmentLog();
        }

        // --- Action Items ---
        async function vmoLoadActionItems() {
            const container = document.getElementById('vmo-action-items-list');
            if (!container) return;
            container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:20px;">Loading...</div>';
            try {
                const filterVal = document.getElementById('vmo-action-filter')?.value || '';
                const result = await ajaxPost('vmo_get_action_items', { status: filterVal, limit: 100 });
                if (!result.success || !result.data?.items?.length) {
                    container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:30px;">No action items found. Action items are auto-created after each AI phone call.</div>';
                    return;
                }
                const items = result.data.items;
                container.innerHTML = items.map(item => {
                    const priorityColors = { critical: '#ef4444', high: '#f59e0b', medium: '#3b82f6', low: '#6b7280' };
                    const pColor = priorityColors[item.priority] || '#6b7280';
                    const isChecked = item.status === 'completed' ? 'checked' : '';
                    const isOverdue = item.status === 'overdue';
                    const deadlineStr = item.deadline ? new Date(item.deadline).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }) : '—';
                    return `
                        <div class="task-card" style="display:flex; align-items:flex-start; gap:10px; padding:10px 12px; border-left:3px solid ${pColor}; ${isOverdue ? 'background:rgba(239,68,68,.06);' : ''}">
                            <input type="checkbox" ${isChecked} onchange="vmoUpdateActionItem(${item.id}, this.checked ? 'completed' : 'pending')"
                                style="margin-top:3px; cursor:pointer; accent-color:${pColor};" />
                            <div style="flex:1; min-width:0;">
                                <div style="display:flex; align-items:center; gap:6px; flex-wrap:wrap;">
                                    <span style="font-weight:600; font-size:13px; ${isChecked ? 'text-decoration:line-through; opacity:.6;' : ''}">${escH(item.title)}</span>
                                    <span style="font-size:10px; padding:2px 6px; border-radius:4px; background:${pColor}15; color:${pColor}; font-weight:600;">${item.priority?.toUpperCase()}</span>
                                    ${item.category ? `<span style="font-size:10px; padding:2px 6px; border-radius:4px; background:rgba(139,92,246,.1); color:#a78bfa;">${item.category.replace(/_/g,' ')}</span>` : ''}
                                    ${isOverdue ? '<span style="font-size:10px; padding:2px 6px; border-radius:4px; background:rgba(239,68,68,.15); color:#ef4444; font-weight:600;">OVERDUE</span>' : ''}
                                </div>
                                ${item.description ? `<div style="font-size:11px; color:var(--muted); margin-top:3px;">${escH(item.description)}</div>` : ''}
                                <div style="font-size:10px; color:var(--muted); margin-top:4px;">
                                    ⏰ ${deadlineStr}
                                    ${item.caller_name ? ` &bull; 👤 ${escH(item.caller_name)}` : ''}
                                </div>
                            </div>
                            <select onchange="vmoUpdateActionItem(${item.id}, this.value)" style="padding:4px 6px; border-radius:4px; background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--ink); font-size:11px;">
                                <option value="pending" ${item.status==='pending'?'selected':''}>Pending</option>
                                <option value="in_progress" ${item.status==='in_progress'?'selected':''}>In Progress</option>
                                <option value="completed" ${item.status==='completed'?'selected':''}>Done</option>
                                <option value="cancelled" ${item.status==='cancelled'?'selected':''}>Cancel</option>
                            </select>
                        </div>
                    `;
                }).join('');
            } catch (err) {
                console.error('[VMO Reports] Action items load error:', err);
                container.innerHTML = '<div style="color:#f59e0b;text-align:center;padding:20px;">Failed to load action items.</div>';
            }
        }

        async function vmoUpdateActionItem(id, status) {
            try {
                const result = await ajaxPost('vmo_update_action_item', { item_id: id, status: status });
                if (result.success) {
                    vmoLoadActionItems(); // refresh the list
                }
            } catch (err) {
                console.error('[VMO Reports] Update action item error:', err);
            }
        }

        // --- Call Reports ---
        async function vmoLoadCallReports() {
            const container = document.getElementById('vmo-call-reports-list');
            if (!container) return;
            container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:20px;">Loading...</div>';
            try {
                const category = document.getElementById('vmo-report-category-filter')?.value || '';
                const dateFrom = document.getElementById('vmo-report-date-from')?.value || '';
                const dateTo = document.getElementById('vmo-report-date-to')?.value || '';
                const result = await ajaxPost('vmo_get_call_reports', { category, date_from: dateFrom, date_to: dateTo, limit: 50 });
                if (result.success && result.data?.reports?.length) {
                    const reports = result.data.reports;
                    container.innerHTML = reports.map(r => {
                    const catColors = { lead:'#f59e0b', customer:'#10b981', support:'#3b82f6', inquiry:'#8b5cf6', vendor:'#6366f1' };
                    const cColor = catColors[r.crm_category] || '#6b7280';
                    const sentEmoji = { positive:'😊', negative:'😟', neutral:'😐', mixed:'🤔' };
                    const urgColors = { low:'#6b7280', medium:'#3b82f6', high:'#f59e0b', critical:'#ef4444' };
                    const actions = r.actions_required || [];
                    const promises = r.promises_made || [];
                    return `
                        <div class="task-card" style="padding:12px; margin-bottom:8px; border-left:3px solid ${cColor};">
                            <div style="display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:6px;">
                                <div>
                                    <span style="font-weight:600; font-size:13px;">${escH(r.caller_name || r.caller_phone || 'Unknown Caller')}</span>
                                    ${(!r.caller_name && r.caller_phone) ? `<span style="font-size:11px; color:var(--muted);"> ${escH(r.caller_phone)}</span>` : ''}
                                </div>
                                <div style="display:flex; gap:4px; flex-wrap:wrap;">
                                    <span style="font-size:10px; padding:2px 6px; border-radius:4px; background:${cColor}15; color:${cColor}; font-weight:600;">${(r.crm_category||'unknown').toUpperCase()}</span>
                                    <span style="font-size:10px;">${sentEmoji[r.sentiment] || '😐'}</span>
                                    <span style="font-size:10px; padding:2px 6px; border-radius:4px; background:${urgColors[r.urgency]||'#6b7280'}15; color:${urgColors[r.urgency]||'#6b7280'};">${(r.urgency||'medium').toUpperCase()}</span>
                                    ${r.fulfillment_status ? `<span style="font-size:10px; padding:2px 6px; border-radius:4px; background:${r.fulfillment_status==='complete'?'rgba(16,185,129,.12)':'rgba(239,68,68,.12)'}; color:${r.fulfillment_status==='complete'?'#10b981':'#ef4444'};">📤 ${r.fulfillment_status}</span>` : ''}
                                </div>
                            </div>
                            <div style="font-size:12px; color:var(--muted); margin-top:6px;">${escH(r.caller_intent || r.summary || '')}</div>
                            ${actions.length ? `<div style="margin-top:6px; font-size:11px;"><strong>Actions needed:</strong> ${actions.map(a => escH(typeof a === 'string' ? a : a.action || a.title || '')).join(' • ')}</div>` : ''}
                            ${promises.length ? `<div style="margin-top:3px; font-size:11px; color:#a78bfa;"><strong>AI promised:</strong> ${promises.map(p => escH(typeof p === 'string' ? p : p.content_needed || p.type || '')).join(' • ')}</div>` : ''}
                            <div style="font-size:10px; color:var(--muted); margin-top:4px;">${new Date(r.created_at).toLocaleString()}</div>
                        </div>
                    `;
                }).join('');
                    return; // AI reports rendered successfully
                }
                // Fallback: no AI-generated call reports found.
                // Show call data from call history (vmo_phone_calls) so the
                // Reports tab isn't empty when AI summaries haven't run yet.
                try {
                    const histResult = await ajaxPost('vmo_get_call_history', { limit: 30 });
                    if (histResult.success && histResult.data?.calls?.length) {
                        const calls = histResult.data.calls;
                        let html = '<div style="margin-bottom:10px; padding:8px 12px; background:rgba(15,225,255,.06); border:1px solid rgba(15,225,255,.15); border-radius:8px; font-size:12px; color:var(--cyan-soft);">📊 Showing call activity from your call log. Detailed AI reports are generated automatically when calls are recorded and transcribed.</div>';
                        html += calls.map(c => {
                            const dirIcon = c.direction === 'outbound' ? '📤' : '📥';
                            const dirColor = c.direction === 'outbound' ? '#3b82f6' : '#10b981';
                            const statusColor = (c.status === 'completed') ? '#10b981' : (c.status === 'no-answer' || c.status === 'missed') ? '#ef4444' : '#f59e0b';
                            const dur = c.duration ? (Math.floor(c.duration/60)+'m '+(c.duration%60)+'s') : '0s';
                            const callerNum = c.direction === 'outbound' ? (c.to_number || c.caller_number || '') : (c.from_number || c.caller_number || '');
                            const timeD = (c.call_start_time || c.created_at) ? new Date((c.call_start_time || c.created_at).replace(' ','T')) : null;
                            const timeStr = timeD && !isNaN(timeD) ? timeD.toLocaleString('en-US', {month:'short', day:'numeric', hour:'numeric', minute:'2-digit', hour12:true}) : (c.call_start_time || c.created_at ||'');
                            const hasSummary = c.summary && c.summary.trim();
                            let summaryText = '';
                            if (hasSummary) {
                                try { const sd = JSON.parse(c.summary); summaryText = sd.summary || sd.caller_intent || c.summary; } catch(_) { summaryText = c.summary; }
                            }
                            return `<div class="task-card" style="padding:10px 12px; margin-bottom:6px; border-left:3px solid ${dirColor};">
                                <div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:4px;">
                                    <div>
                                        <span style="color:${dirColor}; font-size:12px;">${dirIcon}</span>
                                        <strong style="font-size:13px; margin-left:4px;">${escH(callerNum)}</strong>
                                    </div>
                                    <div style="display:flex; gap:4px;">
                                        <span style="font-size:10px; padding:2px 6px; border-radius:4px; background:${statusColor}15; color:${statusColor}; font-weight:600;">${escH(c.status||'unknown')}</span>
                                        <span style="font-size:10px; color:var(--muted);">⏱ ${dur}</span>
                                    </div>
                                </div>
                                ${summaryText ? `<div style="font-size:12px; color:var(--muted); margin-top:4px;">${escH(String(summaryText).slice(0,200))}</div>` : ''}
                                <div style="font-size:10px; color:var(--muted); margin-top:3px;">${timeStr}</div>
                            </div>`;
                        }).join('');
                        container.innerHTML = html;
                        return;
                    }
                } catch(_fallbackErr) {}
                container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:30px;">No call reports or call history found yet.</div>';
            } catch (err) {
                console.error('[VMO Reports] Call reports load error:', err);
                container.innerHTML = '<div style="color:#f59e0b;text-align:center;padding:20px;">Failed to load call reports.</div>';
            }
        }

        // --- Periodic Reports (daily / weekly / monthly / yearly) ---
        async function vmoLoadPeriodicReports(periodFilter) {
            const isDailyTab = (periodFilter === 'daily');
            const container = document.getElementById(isDailyTab ? 'vmo-daily-reports-list' : 'vmo-periodic-reports-list');
            if (!container) return;
            container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:20px;">Loading...</div>';
            try {
                const filterVal = isDailyTab ? 'daily' : (document.getElementById('vmo-periodic-filter')?.value || '');
                const result = await ajaxPost('vmo_get_periodic_reports', { period: filterVal, limit: 30 });
                if (!result.success || !result.data?.reports?.length) {
                    container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:30px;">No ' + (isDailyTab ? 'daily' : 'periodic') + ' reports found yet. Reports are generated automatically at end of each day.</div>';
                    return;
                }
                const reports = result.data.reports;

                function normalizeHeadline(headline, totalCalls) {
                    const lowPattern = /\b(low|minimal|weak|sluggish|underwhelming)\b/i;
                    const highPattern = /\b(strong|high|excellent|robust|record)\b/i;
                    if (!headline || typeof headline !== 'string') {
                        if (totalCalls === 0) return 'No call activity detected for this period';
                        if (totalCalls <= 5) return 'Minimal phone activity day';
                        if (totalCalls <= 20) return 'Light phone activity day';
                        if (totalCalls <= 50) return 'Moderate phone activity day';
                        return 'Strong phone activity day';
                    }
                    if (totalCalls >= 30 && lowPattern.test(headline)) {
                        return `Strong phone activity day with ${totalCalls} calls`;
                    }
                    if (totalCalls <= 5 && highPattern.test(headline)) {
                        return `Minimal phone activity day with ${totalCalls} calls`;
                    }
                    return headline;
                }

                function formatDuration(seconds) {
                    const sec = Number(seconds) || 0;
                    return sec > 0 ? `${Math.floor(sec/60)}m ${sec%60}s` : '—';
                }

                container.innerHTML = reports.map(r => {
                    const cover = r.cover_page || {};
                    const summary = r.summary_data || {};
                    const periodLabels = { daily:'📅 Daily', weekly:'📊 Weekly', monthly:'📈 Monthly', quarterly:'📋 Quarterly', yearly:'🏆 Yearly', custom:'🔍 Custom' };
                    const periodLabel = periodLabels[r.period] || r.period;
                    const dateRange = r.start_date === r.end_date ? r.start_date : `${r.start_date} → ${r.end_date}`;
                    const headline = normalizeHeadline(cover.headline, r.total_calls || summary.total_calls || 0);
                    const totalCalls = r.total_calls || summary.total_calls || 0;
                    return `
                        <div class="task-card" style="padding:12px; margin-bottom:8px; cursor:pointer;" onclick="this.querySelector('.vmo-report-detail').style.display=this.querySelector('.vmo-report-detail').style.display==='none'?'block':'none'">
                            <div style="display:flex; justify-content:space-between; align-items:center;">
                                <div>
                                    <span style="font-size:10px; padding:2px 6px; border-radius:4px; background:rgba(139,92,246,.1); color:#a78bfa; font-weight:600;">${periodLabel}</span>
                                    <span style="font-weight:600; font-size:13px; margin-left:6px;">${dateRange}</span>
                                </div>
                                <div style="display:flex; gap:8px; font-size:12px; color:var(--muted);">
                                    <span>📞 ${totalCalls}</span>
                                    <span>✅ ${r.actions_completed || summary.actions_completed || 0}</span>
                                    <span>📤 ${r.fulfillments_sent || summary.fulfillments_sent || 0}</span>
                                </div>
                            </div>
                            <div style="font-size:12px; color:var(--ink); margin-top:6px; font-weight:500;">${escH(headline)}</div>
                            ${cover.summary ? `<div style="font-size:11px; color:var(--muted); margin-top:3px;">${escH(cover.summary)}</div>` : ''}
                            <div class="vmo-report-detail" style="display:none; margin-top:10px; padding-top:10px; border-top:1px solid rgba(255,255,255,.06);">
                                <div style="display:flex; gap:12px; flex-wrap:wrap; margin-bottom:8px;">
                                    ${(cover.key_metrics || []).map(m => `
                                        <div style="text-align:center; padding:8px 12px; background:rgba(255,255,255,.03); border-radius:8px; min-width:80px;">
                                            <div style="font-size:18px; font-weight:700; color:var(--ink);">${m.value}</div>
                                            <div style="font-size:10px; color:var(--muted);">${escH(m.label)}</div>
                                        </div>
                                    `).join('')}
                                </div>
                                ${summary.total_duration_minutes ? `<div style="font-size:11px; color:var(--muted);">⏱ Total call time: ${Math.round(summary.total_duration_minutes)} min</div>` : ''}
                                ${summary.new_leads ? `<div style="font-size:11px; color:#f59e0b;">🌟 New leads: ${summary.new_leads}</div>` : ''}
                                ${summary.new_customers ? `<div style="font-size:11px; color:#10b981;">💰 New customers: ${summary.new_customers}</div>` : ''}
                            </div>
                        </div>
                    `;
                }).join('');
            } catch (err) {
                console.error('[VMO Reports] Periodic reports load error:', err);
                container.innerHTML = '<div style="color:#f59e0b;text-align:center;padding:20px;">Failed to load reports.</div>';
            }
        }

        // --- Custom Date Range Report ---
        async function vmoGenerateCustomReport() {
            const fromDate = document.getElementById('vmo-custom-date-from')?.value;
            const toDate = document.getElementById('vmo-custom-date-to')?.value;
            if (!fromDate || !toDate) {
                alert('Please select both a From and To date.');
                return;
            }
            if (fromDate > toDate) {
                alert('From date must be before To date.');
                return;
            }
            const container = document.getElementById('vmo-custom-report-result');
            const btn = document.getElementById('vmo-custom-report-btn');
            if (btn) { btn.disabled = true; btn.textContent = '⏳ Generating...'; }
            container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:40px;"><div style="font-size:24px;margin-bottom:10px;">⏳</div>Generating custom report with AI executive summary...<br><span style="font-size:11px;">This may take a moment.</span></div>';
            try {
                const result = await ajaxPost('vmo_generate_custom_report', { start_date: fromDate, end_date: toDate });
                if (!result.success || !result.data) {
                    container.innerHTML = '<div style="color:#f59e0b;text-align:center;padding:30px;">No data found for the selected date range.</div>';
                    return;
                }
                const r = result.data;
                const cover = r.cover_page || {};
                const summary = r.summary_data || {};
                container.innerHTML = `
                    <div style="background:linear-gradient(135deg, rgba(139,92,246,.08), rgba(59,130,246,.05)); border-radius:12px; padding:20px; margin-bottom:14px;">
                        <div style="font-size:10px; color:#a78bfa; font-weight:600; text-transform:uppercase; letter-spacing:1px;">Custom Report</div>
                        <div style="font-size:18px; font-weight:700; color:var(--ink); margin-top:6px;">${escH(cover.headline || 'Activity Report')}</div>
                        <div style="font-size:13px; color:var(--muted); margin-top:4px;">${fromDate} — ${toDate}</div>
                        ${cover.summary ? `<div style="font-size:12px; color:var(--ink); margin-top:8px; line-height:1.6;">${escH(cover.summary)}</div>` : ''}
                    </div>
                    <div style="display:flex; gap:10px; flex-wrap:wrap; margin-bottom:14px;">
                        ${(cover.key_metrics || []).map(m => `
                            <div style="flex:1; min-width:100px; text-align:center; padding:12px; background:rgba(255,255,255,.03); border-radius:8px; border:1px solid rgba(255,255,255,.06);">
                                <div style="font-size:22px; font-weight:700; color:var(--ink);">${m.value}</div>
                                <div style="font-size:10px; color:var(--muted);">${escH(m.label)}</div>
                            </div>
                        `).join('')}
                    </div>
                    <div style="display:grid; grid-template-columns:1fr 1fr; gap:10px; font-size:12px;">
                        <div style="padding:10px; background:rgba(255,255,255,.02); border-radius:8px;">
                            <strong>📞 Calls:</strong> ${summary.total_calls || 0}
                        </div>
                        <div style="padding:10px; background:rgba(255,255,255,.02); border-radius:8px;">
                            <strong>⏱ Duration:</strong> ${Math.round(summary.total_duration_minutes || 0)} min
                        </div>
                        <div style="padding:10px; background:rgba(255,255,255,.02); border-radius:8px;">
                            <strong>🌟 New Leads:</strong> ${summary.new_leads || 0}
                        </div>
                        <div style="padding:10px; background:rgba(255,255,255,.02); border-radius:8px;">
                            <strong>💰 New Customers:</strong> ${summary.new_customers || 0}
                        </div>
                        <div style="padding:10px; background:rgba(255,255,255,.02); border-radius:8px;">
                            <strong>✅ Actions Done:</strong> ${summary.actions_completed || 0} / ${summary.actions_total || 0}
                        </div>
                        <div style="padding:10px; background:rgba(255,255,255,.02); border-radius:8px;">
                            <strong>📤 Fulfillments:</strong> ${summary.fulfillments_sent || 0}
                        </div>
                    </div>
                `;
            } catch (err) {
                console.error('[VMO Reports] Custom report error:', err);
                container.innerHTML = '<div style="color:#f59e0b;text-align:center;padding:30px;">Failed to generate custom report.</div>';
            } finally {
                if (btn) { btn.disabled = false; btn.textContent = '📊 Generate Report'; }
            }
        }

        // --- Fulfillment Log ---
        async function vmoLoadFulfillmentLog() {
            const container = document.getElementById('vmo-fulfillment-log-list');
            if (!container) return;
            container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:20px;">Loading...</div>';
            try {
                const result = await ajaxPost('vmo_get_fulfillment_log', { limit: 50 });
                if (!result.success || !result.data?.items?.length) {
                    container.innerHTML = '<div style="text-align:center;color:var(--muted);padding:30px;">No fulfillment entries yet. When AI promises to send information during calls, fulfillment SMS/emails will appear here.</div>';
                    return;
                }
                const items = result.data.items;
                container.innerHTML = items.map(item => {
                    const typeIcon = item.action_type === 'sms' ? '📱' : '📧';
                    const statusColor = item.status === 'sent' ? '#10b981' : (item.status === 'failed' ? '#ef4444' : '#f59e0b');
                    return `
                        <div class="task-card" style="padding:10px 12px; margin-bottom:6px; border-left:3px solid ${statusColor};">
                            <div style="display:flex; justify-content:space-between; align-items:center;">
                                <div style="font-size:13px;">
                                    ${typeIcon} <strong>${item.action_type?.toUpperCase()}</strong> → ${escH(item.recipient || 'Unknown')}
                                </div>
                                <span style="font-size:10px; padding:2px 6px; border-radius:4px; background:${statusColor}15; color:${statusColor}; font-weight:600;">${(item.status||'unknown').toUpperCase()}</span>
                            </div>
                            <div style="font-size:11px; color:var(--muted); margin-top:4px; white-space:pre-line; max-height:60px; overflow:hidden;">${escH(item.message_body || '')}</div>
                            <div style="font-size:10px; color:var(--muted); margin-top:3px;">
                                ${new Date(item.created_at).toLocaleString()}
                                ${item.error_message ? ` — <span style="color:#ef4444;">${escH(item.error_message)}</span>` : ''}
                            </div>
                        </div>
                    `;
                }).join('');
            } catch (err) {
                console.error('[VMO Reports] Fulfillment log load error:', err);
                container.innerHTML = '<div style="color:#f59e0b;text-align:center;padding:20px;">Failed to load fulfillment log.</div>';
            }
        }

        // HTML-escape helper (used by report rendering)
        function escH(str) {
            if (!str) return '';
            const div = document.createElement('div');
            div.textContent = String(str);
            return div.innerHTML;
        }

        // ============================================================
        // TESTER PLAN — MISSED OPS DISMISS HANDLERS
        // ============================================================
        window.vmoDismissMissedOp = function(index, btn) {
            const item = btn.closest('.vmo-missed-op-item');
            if (item) {
                item.style.opacity = '0';
                setTimeout(() => item.remove(), 300);
            }
            jQuery.post(vmo_ajax.ajaxurl || ajaxurl, {
                action: 'vmo_dismiss_upgrade_prompt',
                security: vmo_ajax.nonce || vmo_ajax.security,
                index: index
            });
            // If no items left, hide the banner
            setTimeout(() => {
                const list = document.getElementById('vmo-missed-ops-list');
                if (list && list.querySelectorAll('.vmo-missed-op-item').length === 0) {
                    const banner = document.getElementById('vmo-missed-ops-banner');
                    if (banner) { banner.style.opacity = '0'; setTimeout(() => banner.remove(), 400); }
                }
            }, 350);
        };

        window.vmoDismissAllMissedOps = function() {
            const banner = document.getElementById('vmo-missed-ops-banner');
            if (banner) { banner.style.opacity = '0'; setTimeout(() => banner.remove(), 400); }
            jQuery.post(vmo_ajax.ajaxurl || ajaxurl, {
                action: 'vmo_dismiss_upgrade_prompt',
                security: vmo_ajax.nonce || vmo_ajax.security,
                dismiss_all: 1
            });
        };

        // ============================================================
        // WEBSITE EXPORTS
        // ============================================================
        function vmoExportAjaxUrl() {
            return (window.vmo_ajax && vmo_ajax.ajaxurl)
                || (typeof VMO_AJAX !== 'undefined' ? VMO_AJAX : '')
                || (typeof ajaxurl !== 'undefined' ? ajaxurl : '/wp-admin/admin-ajax.php');
        }

        function vmoExportNonce() {
            return (typeof VMO_NONCE_BUILDER !== 'undefined' && VMO_NONCE_BUILDER)
                ? VMO_NONCE_BUILDER
                : ((window.vmo_ajax && (vmo_ajax.security || vmo_ajax.nonce)) || '');
        }

        function vmoDownloadBase64Zip(base64Data, filename) {
            const byteChars = atob(base64Data);
            const byteNums = new Array(byteChars.length);
            for (let i = 0; i < byteChars.length; i++) byteNums[i] = byteChars.charCodeAt(i);
            const blob = new Blob([new Uint8Array(byteNums)], { type: 'application/zip' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = filename;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }

        async function vmoRunZipExport(triggerEvent, options) {
            const fallbackEvent = (typeof event !== 'undefined') ? event : null;
            const btn = (triggerEvent && (triggerEvent.currentTarget || triggerEvent.target)) || (fallbackEvent && fallbackEvent.target) || null;
            const origText = btn ? btn.textContent : '';
            if (btn) {
                btn.textContent = options.progressText || '⏳ Exporting...';
                btn.disabled = true;
            }
            try {
                const resp = await fetch(vmoExportAjaxUrl(), {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: options.action,
                        security: vmoExportNonce()
                    })
                });
                const data = await resp.json();
                if (data.success && data.data?.data) {
                    vmoDownloadBase64Zip(data.data.data, data.data.filename || options.fallbackFilename);
                    if (btn) {
                        btn.textContent = options.successText || '✅ Downloaded!';
                        setTimeout(() => { btn.textContent = origText; btn.disabled = false; }, 3000);
                    }
                    return data.data;
                }
                alert(data.data?.message || options.failureMessage || 'Export failed. Please generate a website first.');
            } catch (err) {
                console.error(options.logLabel || 'VMO export error:', err);
                alert('Export failed: ' + err.message);
            }
            if (btn) {
                btn.textContent = origText;
                btn.disabled = false;
            }
            return null;
        }

        window.vmoExportStaticSite = function(triggerEvent) {
            return vmoRunZipExport(triggerEvent, {
                action: 'vmo_export_static_site',
                progressText: '⏳ Packaging...',
                successText: '✅ Static ZIP ready!',
                fallbackFilename: 'website-static-site.zip',
                failureMessage: 'Static export failed. Please generate a standalone website first.',
                logLabel: 'Static export error:'
            });
        };

        window.vmoExportNextJS = function(triggerEvent) {
            return vmoRunZipExport(triggerEvent, {
                action: 'vmo_export_nextjs',
                progressText: '⏳ Exporting...',
                successText: '✅ Downloaded!',
                fallbackFilename: 'website-nextjs.zip',
                failureMessage: 'Export failed. Please generate a website first.',
                logLabel: 'Next.js export error:'
            });
        };

        // ============================================================
        // MARKET INTELLIGENCE DASHBOARD
        // ============================================================
        
        async function loadMarketIntelligence(period = '90days', limit = 10) {
            try {
                const result = await ajaxPost('vmo_get_market_scans', { period, limit });
                
                if (result.success && result.data) {
                    displayMarketScans(result.data.scans || [], result.data.stats || {});
                    await loadCompetitorAnalysis();
                } else {
                    document.getElementById('vmo-market-scans-container').innerHTML = 
                        '<div style="color:var(--muted); text-align:center; padding:30px;">No market scans available</div>';
                }
            } catch (err) {
                console.error('Error loading market intelligence:', err);
                document.getElementById('vmo-market-scans-container').innerHTML = 
                    '<div style="color:#f44336; text-align:center; padding:30px;">Error loading market data</div>';
            }
        }
        
        function displayMarketScans(scans, stats) {
            const container = document.getElementById('vmo-market-scans-container');
            if (!container) return;
            
            // Update stats
            if (stats.total_scans) {
                const totalScansEl = document.getElementById('vmo-total-scans');
                if (totalScansEl) totalScansEl.textContent = stats.total_scans;
            }
            
            if (!scans || scans.length === 0) {
                container.innerHTML = `
                    <div style="text-align:center; padding:40px; color:var(--muted);">
                        <div style="font-size:48px; margin-bottom:12px;">🔍</div>
                        <h3>No Market Scans Yet</h3>
                        <p>Market scans run automatically every week.</p>
                        <p style="font-size:13px; margin-top:8px;">Your first scan will appear here soon!</p>
                    </div>
                `;
                return;
            }
            
            container.innerHTML = scans.map(scan => {
                const trends = JSON.parse(scan.key_trends || '[]');
                const threats = JSON.parse(scan.threats || '[]');
                const opportunities = JSON.parse(scan.opportunities || '[]');
                
                // Count severity levels
                const highThreats = threats.filter(t => t.severity === 'high').length;
                const highOpportunities = opportunities.filter(o => o.potential === 'high').length;
                
                // Determine scan status color
                let statusColor = 'var(--green-soft)';
                if (highThreats > 0) statusColor = '#f44336';
                else if (threats.length > 0) statusColor = '#ff9800';
                
                return `
                    <div class="vmo-card" style="border-left:3px solid ${statusColor}; margin-bottom:16px;">
                        <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;">
                            <div>
                                <strong style="font-size:15px;">${scan.industry || 'General Market'}</strong>
                                <div style="font-size:12px; color:var(--muted); margin-top:4px;">
                                    ${new Date(scan.scan_date).toLocaleDateString('en-US', {month: 'short', day: 'numeric', year: 'numeric'})}
                                </div>
                            </div>
                            <button class="action-btn" onclick="showMarketScanDetails(${scan.id})" style="padding:6px 12px; font-size:12px;">
                                View Full Report
                            </button>
                        </div>
                        
                        <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr)); gap:12px; margin-bottom:12px;">
                            <div style="padding:10px; background:var(--subtle-bg, rgba(255,255,255,.03)); border-radius:6px;">
                                <div style="font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;">Market Size</div>
                                <div style="font-size:15px; font-weight:600; margin-top:4px;">${scan.market_size || 'Unknown'}</div>
                            </div>
                            <div style="padding:10px; background:var(--subtle-bg, rgba(255,255,255,.03)); border-radius:6px;">
                                <div style="font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;">Growth Rate</div>
                                <div style="font-size:15px; font-weight:600; margin-top:4px; color:var(--green-soft);">${scan.growth_rate || 'Unknown'}</div>
                            </div>
                            <div style="padding:10px; background:var(--subtle-bg, rgba(255,255,255,.03)); border-radius:6px;">
                                <div style="font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;">Opportunities</div>
                                <div style="font-size:15px; font-weight:600; margin-top:4px; color:var(--cyan-soft);">${opportunities.length} <span style="font-size:11px; color:var(--muted);">(${highOpportunities} high)</span></div>
                            </div>
                            <div style="padding:10px; background:var(--subtle-bg, rgba(255,255,255,.03)); border-radius:6px;">
                                <div style="font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;">Threats</div>
                                <div style="font-size:15px; font-weight:600; margin-top:4px; color:#f44336;">${threats.length} <span style="font-size:11px; color:var(--muted);">(${highThreats} high)</span></div>
                            </div>
                        </div>
                        
                        ${trends.length > 0 ? `
                            <div style="margin-top:14px; padding-top:12px; border-top:1px solid var(--border);">
                                <div style="font-size:12px; color:var(--muted); margin-bottom:8px; text-transform:uppercase; letter-spacing:.5px;">Key Trends</div>
                                ${trends.slice(0, 3).map(trend => {
                                    let impactColor = trend.impact === 'high' ? 'var(--green-soft)' : 
                                                     trend.impact === 'medium' ? '#ff9800' : 'var(--muted)';
                                    return `
                                        <div style="margin-bottom:8px; display:flex; align-items:start; gap:8px;">
                                            <span style="color:${impactColor}; font-size:16px; line-height:1;">●</span>
                                            <div style="flex:1;">
                                                <strong style="font-size:13px;">${trend.trend || ''}</strong>
                                                <div style="font-size:12px; color:var(--muted); margin-top:2px;">${(trend.description || '').substring(0, 100)}...</div>
                                            </div>
                                        </div>
                                    `;
                                }).join('')}
                            </div>
                        ` : ''}
                        
                        ${highOpportunities > 0 ? `
                            <div style="margin-top:14px; padding:10px; background:rgba(76, 175, 80, .1); border-left:3px solid var(--green-soft); border-radius:6px;">
                                <strong style="font-size:12px; color:var(--green-soft);">💡 Top Opportunity:</strong>
                                <div style="font-size:13px; margin-top:6px;">
                                    ${(opportunities.find(o => o.potential === 'high') || {}).opportunity || 'Review full report for details'}
                                </div>
                            </div>
                        ` : ''}
                        
                        ${highThreats > 0 ? `
                            <div style="margin-top:14px; padding:10px; background:rgba(244, 67, 54, .1); border-left:3px solid #f44336; border-radius:6px;">
                                <strong style="font-size:12px; color:#f44336;">⚠️ Critical Threat:</strong>
                                <div style="font-size:13px; margin-top:6px;">
                                    ${(threats.find(t => t.severity === 'high') || {}).threat || 'Review full report for details'}
                                </div>
                            </div>
                        ` : ''}
                    </div>
                `;
            }).join('');
        }
        
        async function loadCompetitorAnalysis() {
            try {
                const result = await ajaxPost('vmo_get_competitors', { limit: 20 });
                
                if (result.success && result.data && result.data.competitors) {
                    displayCompetitors(result.data.competitors);
                }
            } catch (err) {
                console.error('Error loading competitors:', err);
            }
        }
        
        function displayCompetitors(competitors) {
            const container = document.getElementById('vmo-competitors-container');
            if (!container) return;
            
            if (!competitors || competitors.length === 0) {
                container.innerHTML = `
                    <div style="text-align:center; padding:30px; color:var(--muted);">
                        <div style="font-size:36px; margin-bottom:8px;">🏢</div>
                        <p>No competitors identified yet</p>
                    </div>
                `;
                return;
            }
            
            container.innerHTML = `
                <div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(300px, 1fr)); gap:14px;">
                    ${competitors.map(comp => {
                        const strengths = JSON.parse(comp.strengths || '[]');
                        const weaknesses = JSON.parse(comp.weaknesses || '[]');
                        
                        return `
                            <div class="vmo-card" style="padding:14px;">
                                <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:10px;">
                                    <strong style="font-size:14px;">${comp.name || 'Unknown'}</strong>
                                    ${comp.website ? `
                                        <a href="${comp.website}" target="_blank" class="action-btn" style="padding:4px 8px; font-size:11px;">
                                            🔗 Visit
                                        </a>
                                    ` : ''}
                                </div>
                                
                                <div style="font-size:11px; color:var(--muted); margin-bottom:10px; text-transform:uppercase; letter-spacing:.5px;">
                                    ${comp.market_position || 'Market Competitor'} • ${comp.industry || ''}
                                </div>
                                
                                ${strengths.length > 0 ? `
                                    <div style="margin-bottom:10px;">
                                        <div style="font-size:11px; color:var(--green-soft); margin-bottom:4px; font-weight:600;">Strengths:</div>
                                        ${strengths.slice(0, 2).map(s => `
                                            <div style="font-size:12px; color:var(--muted); margin-bottom:2px;">✓ ${s}</div>
                                        `).join('')}
                                    </div>
                                ` : ''}
                                
                                ${weaknesses.length > 0 ? `
                                    <div>
                                        <div style="font-size:11px; color:#f44336; margin-bottom:4px; font-weight:600;">Weaknesses:</div>
                                        ${weaknesses.slice(0, 2).map(w => `
                                            <div style="font-size:12px; color:var(--muted); margin-bottom:2px;">✗ ${w}</div>
                                        `).join('')}
                                    </div>
                                ` : ''}
                                
                                <div style="margin-top:10px; padding-top:10px; border-top:1px solid var(--border); font-size:11px; color:var(--muted);">
                                    Last updated: ${new Date(comp.last_updated).toLocaleDateString('en-US', {month: 'short', day: 'numeric'})}
                                </div>
                            </div>
                        `;
                    }).join('')}
                </div>
            `;
        }
        
        function showMarketScanDetails(scanId) {
            // Create modal for full market scan report
            const modal = document.createElement('div');
            modal.id = 'vmo-market-scan-modal';
            modal.style.cssText = 'display:flex; position:fixed; inset:0; background:rgba(0,0,0,.7); z-index:10000; align-items:center; justify-content:center; overflow:auto; padding:20px;';
            modal.innerHTML = `
                <div style="background:var(--panel-bg, #0b0f1a); border:1px solid var(--border); border-radius:12px; width:min(900px, 95vw); max-height:90vh; display:flex; flex-direction:column;">
                    <div style="display:flex; align-items:center; justify-content:space-between; padding:14px 18px; border-bottom:1px solid var(--border); position:sticky; top:0; background:var(--panel-bg); z-index:1;">
                        <strong style="font-size:16px;">Market Intelligence Report</strong>
                        <button class="action-btn" onclick="document.getElementById('vmo-market-scan-modal').remove()">✖ Close</button>
                    </div>
                    <div id="vmo-market-scan-body" style="padding:20px; overflow:auto; flex:1;">
                        <div style="color:var(--muted); text-align:center; padding:40px;">Loading full report...</div>
                    </div>
                </div>
            `;
            document.body.appendChild(modal);
            
            // Load full scan details
            ajaxPost('vmo_get_market_scans', { scan_id: scanId })
                .then(result => {
                    const body = document.getElementById('vmo-market-scan-body');
                    if (result.success && result.data && result.data.scans && result.data.scans[0]) {
                        const scan = result.data.scans[0];
                        const trends = JSON.parse(scan.key_trends || '[]');
                        const threats = JSON.parse(scan.threats || '[]');
                        const opportunities = JSON.parse(scan.opportunities || '[]');
                        
                        body.innerHTML = `
                            <div style="margin-bottom:24px;">
                                <h2 style="margin:0 0 8px 0;">${scan.industry || 'Market Analysis'}</h2>
                                <div style="color:var(--muted); font-size:13px;">
                                    Scan Date: ${new Date(scan.scan_date).toLocaleDateString('en-US', {weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'})}
                                </div>
                            </div>
                            
                            <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr)); gap:16px; margin-bottom:30px;">
                                <div class="vmo-card">
                                    <div style="font-size:12px; color:var(--muted); margin-bottom:6px;">Market Size</div>
                                    <div style="font-size:24px; font-weight:700;">${scan.market_size || 'Unknown'}</div>
                                </div>
                                <div class="vmo-card">
                                    <div style="font-size:12px; color:var(--muted); margin-bottom:6px;">Growth Rate</div>
                                    <div style="font-size:24px; font-weight:700; color:var(--green-soft);">${scan.growth_rate || 'Unknown'}</div>
                                </div>
                            </div>
                            
                            ${trends.length > 0 ? `
                                <div style="margin-bottom:30px;">
                                    <h3 style="margin:0 0 14px 0; font-size:18px;">📈 Key Market Trends</h3>
                                    <div style="display:grid; gap:12px;">
                                        ${trends.map(trend => {
                                            let impactBadge = trend.impact === 'high' ? '<span style="background:var(--green-soft); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">HIGH IMPACT</span>' :
                                                             trend.impact === 'medium' ? '<span style="background:#ff9800; color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">MEDIUM IMPACT</span>' :
                                                             '<span style="background:var(--muted); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">LOW IMPACT</span>';
                                            return `
                                                <div class="vmo-card" style="padding:14px;">
                                                    <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
                                                        <strong style="font-size:14px;">${trend.trend || ''}</strong>
                                                        ${impactBadge}
                                                    </div>
                                                    <div style="font-size:13px; color:var(--muted); line-height:1.6;">${trend.description || ''}</div>
                                                </div>
                                            `;
                                        }).join('')}
                                    </div>
                                </div>
                            ` : ''}
                            
                            ${opportunities.length > 0 ? `
                                <div style="margin-bottom:30px;">
                                    <h3 style="margin:0 0 14px 0; font-size:18px;">💡 Market Opportunities</h3>
                                    <div style="display:grid; gap:12px;">
                                        ${opportunities.map(opp => {
                                            let potentialBadge = opp.potential === 'high' ? '<span style="background:var(--green-soft); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">HIGH POTENTIAL</span>' :
                                                                opp.potential === 'medium' ? '<span style="background:#ff9800; color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">MEDIUM POTENTIAL</span>' :
                                                                '<span style="background:var(--muted); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">LOW POTENTIAL</span>';
                                            return `
                                                <div class="vmo-card" style="padding:14px; border-left:3px solid var(--green-soft);">
                                                    <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
                                                        <strong style="font-size:14px;">${opp.opportunity || ''}</strong>
                                                        ${potentialBadge}
                                                    </div>
                                                    <div style="font-size:13px; color:var(--muted); line-height:1.6; margin-bottom:10px;">${opp.description || ''}</div>
                                                    ${opp.action ? `
                                                        <div style="padding:10px; background:rgba(76, 175, 80, .1); border-radius:6px;">
                                                            <strong style="font-size:11px; color:var(--green-soft); text-transform:uppercase; letter-spacing:.5px;">Recommended Action:</strong>
                                                            <div style="font-size:13px; margin-top:4px;">${opp.action}</div>
                                                        </div>
                                                    ` : ''}
                                                </div>
                                            `;
                                        }).join('')}
                                    </div>
                                </div>
                            ` : ''}
                            
                            ${threats.length > 0 ? `
                                <div style="margin-bottom:30px;">
                                    <h3 style="margin:0 0 14px 0; font-size:18px;">⚠️ Market Threats</h3>
                                    <div style="display:grid; gap:12px;">
                                        ${threats.map(threat => {
                                            let severityBadge = threat.severity === 'high' ? '<span style="background:#f44336; color:#fff; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">HIGH SEVERITY</span>' :
                                                               threat.severity === 'medium' ? '<span style="background:#ff9800; color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">MEDIUM SEVERITY</span>' :
                                                               '<span style="background:var(--muted); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">LOW SEVERITY</span>';
                                            return `
                                                <div class="vmo-card" style="padding:14px; border-left:3px solid #f44336;">
                                                    <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
                                                        <strong style="font-size:14px;">${threat.threat || ''}</strong>
                                                        ${severityBadge}
                                                    </div>
                                                    <div style="font-size:13px; color:var(--muted); line-height:1.6; margin-bottom:10px;">${threat.description || ''}</div>
                                                    ${threat.mitigation ? `
                                                        <div style="padding:10px; background:rgba(33, 150, 243, .1); border-radius:6px;">
                                                            <strong style="font-size:11px; color:var(--cyan-soft); text-transform:uppercase; letter-spacing:.5px;">Mitigation Strategy:</strong>
                                                            <div style="font-size:13px; margin-top:4px;">${threat.mitigation}</div>
                                                        </div>
                                                    ` : ''}
                                                </div>
                                            `;
                                        }).join('')}
                                    </div>
                                </div>
                            ` : ''}
                        `;
                    } else {
                        body.innerHTML = '<div style="color:var(--muted); text-align:center; padding:40px;">Report not available</div>';
                    }
                })
                .catch(err => {
                    const body = document.getElementById('vmo-market-scan-body');
                    body.innerHTML = '<div style="color:#f44336; text-align:center; padding:40px;">Error loading report</div>';
                    console.error(err);
                });
        }
        
        // ============================================================
        // ROADMAP & BUSINESS GOALS DASHBOARD
        // ============================================================
        
        async function loadBusinessRoadmap(timeframe = 'all', status = 'active') {
            try {
                const [goalsResult, tasksResult] = await Promise.all([
                    ajaxPost('vmo_get_business_goals', { timeframe, status }),
                    ajaxPost('vmo_get_roadmap_tasks', { timeline: 'all', status: 'all' })
                ]);
                
                if (goalsResult.success && tasksResult.success) {
                    displayBusinessGoals(goalsResult.data.goals || [], goalsResult.data.stats || {});
                    displayRoadmapTasks(tasksResult.data.tasks || [], tasksResult.data.stats || {});
                } else {
                    document.getElementById('vmo-goals-container').innerHTML = 
                        '<div style="color:var(--muted); text-align:center; padding:30px;">No goals available</div>';
                }
            } catch (err) {
                console.error('Error loading business roadmap:', err);
                document.getElementById('vmo-goals-container').innerHTML = 
                    '<div style="color:#f44336; text-align:center; padding:30px;">Error loading roadmap</div>';
            }
        }
        
        function displayBusinessGoals(goals, stats) {
            const container = document.getElementById('vmo-goals-container');
            if (!container) return;
            
            // Update stats
            if (stats.total_goals) {
                const totalGoalsEl = document.getElementById('vmo-total-goals');
                if (totalGoalsEl) totalGoalsEl.textContent = stats.total_goals;
                
                const avgProgressEl = document.getElementById('vmo-avg-goal-progress');
                if (avgProgressEl) avgProgressEl.textContent = Math.round(stats.average_progress || 0) + '%';
            }
            
            if (!goals || goals.length === 0) {
                container.innerHTML = `
                    <div style="text-align:center; padding:40px; color:var(--muted);">
                        <div style="font-size:48px; margin-bottom:12px;">🎯</div>
                        <h3>No Business Goals Yet</h3>
                        <p>Complete a Business Consultant session to generate your roadmap.</p>
                        <button class="action-btn primary" onclick="window.location.href='<?php echo esc_js(admin_url('admin.php?page=vmo-business-consultant')); ?>'" style="margin-top:12px;">
                            Start Consultation
                        </button>
                    </div>
                `;
                return;
            }
            
            // Group by timeframe
            const shortTerm = goals.filter(g => g.timeframe === 'short-term');
            const longTerm = goals.filter(g => g.timeframe === 'long-term');
            
            container.innerHTML = `
                ${shortTerm.length > 0 ? `
                    <div style="margin-bottom:24px;">
                        <h3 style="margin:0 0 14px 0; font-size:16px; display:flex; align-items:center; gap:8px;">
                            <span>🎯</span> Short-Term Goals (0-6 months)
                        </h3>
                        <div style="display:grid; gap:14px;">
                            ${shortTerm.map(goal => renderGoalCard(goal)).join('')}
                        </div>
                    </div>
                ` : ''}
                
                ${longTerm.length > 0 ? `
                    <div>
                        <h3 style="margin:0 0 14px 0; font-size:16px; display:flex; align-items:center; gap:8px;">
                            <span>🚀</span> Long-Term Goals (6-24 months)
                        </h3>
                        <div style="display:grid; gap:14px;">
                            ${longTerm.map(goal => renderGoalCard(goal)).join('')}
                        </div>
                    </div>
                ` : ''}
            `;
        }
        
        function renderGoalCard(goal) {
            const progress = parseInt(goal.progress_percentage || 0);
            const priorityColors = {
                'high': '#f44336',
                'medium': '#ff9800',
                'low': 'var(--muted)'
            };
            const categoryIcons = {
                'revenue': '💰',
                'marketing': '📢',
                'operations': '⚙️',
                'product': '📦',
                'team': '👥'
            };
            
            const priorityColor = priorityColors[goal.priority] || 'var(--muted)';
            const categoryIcon = categoryIcons[goal.category] || '📋';
            const statusBadge = goal.status === 'completed' ? 
                '<span style="background:var(--green-soft); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">COMPLETED</span>' :
                goal.status === 'active' ? 
                '<span style="background:var(--cyan-soft); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">ACTIVE</span>' :
                '<span style="background:var(--muted); color:#000; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:600;">PAUSED</span>';
            
            return `
                <div class="vmo-card" style="border-left:3px solid ${priorityColor}; cursor:pointer;" onclick="showGoalDetails(${goal.id})">
                    <div style="display:flex; align-items:start; justify-content:space-between; margin-bottom:10px;">
                        <div style="flex:1;">
                            <div style="display:flex; align-items:center; gap:8px; margin-bottom:4px;">
                                <span style="font-size:18px;">${categoryIcon}</span>
                                <strong style="font-size:15px;">${goal.title || 'Untitled Goal'}</strong>
                            </div>
                            <div style="font-size:13px; color:var(--muted); line-height:1.5;">
                                ${(goal.description || '').substring(0, 120)}${goal.description && goal.description.length > 120 ? '...' : ''}
                            </div>
                        </div>
                        ${statusBadge}
                    </div>
                    
                    ${goal.target_metric ? `
                        <div style="margin-bottom:10px; padding:8px; background:rgba(33, 150, 243, .1); border-radius:6px;">
                            <div style="font-size:11px; color:var(--cyan-soft); margin-bottom:2px; text-transform:uppercase; letter-spacing:.5px;">Target</div>
                            <div style="font-size:13px; font-weight:600;">${goal.target_metric}</div>
                        </div>
                    ` : ''}
                    
                    <div style="margin-bottom:6px;">
                        <div style="display:flex; justify-content:space-between; margin-bottom:4px;">
                            <span style="font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;">Progress</span>
                            <span style="font-size:12px; font-weight:600; color:var(--cyan-soft);">${progress}%</span>
                        </div>
                        <div style="height:6px; background:var(--border); border-radius:3px; overflow:hidden;">
                            <div style="height:100%; background:var(--cyan-soft); width:${progress}%; transition:width 0.3s;"></div>
                        </div>
                    </div>
                    
                    <div style="display:flex; align-items:center; justify-content:space-between; font-size:11px; color:var(--muted); margin-top:8px;">
                        <span>Target: ${new Date(goal.target_date).toLocaleDateString('en-US', {month: 'short', day: 'numeric', year: 'numeric'})}</span>
                        <span style="color:${priorityColor}; font-weight:600; text-transform:uppercase;">${goal.priority} priority</span>
                    </div>
                </div>
            `;
        }
        
        function displayRoadmapTasks(tasks, stats) {
            const container = document.getElementById('vmo-tasks-container');
            if (!container) return;
            
            // Update stats
            if (stats.total_tasks) {
                const totalTasksEl = document.getElementById('vmo-total-tasks');
                if (totalTasksEl) totalTasksEl.textContent = stats.total_tasks;
                
                const completedTasksEl = document.getElementById('vmo-completed-tasks');
                if (completedTasksEl) completedTasksEl.textContent = stats.completed_tasks || 0;
                
                const overdueTasksEl = document.getElementById('vmo-overdue-tasks');
                if (overdueTasksEl) overdueTasksEl.textContent = stats.overdue_tasks || 0;
            }
            
            if (!tasks || tasks.length === 0) {
                container.innerHTML = `
                    <div style="text-align:center; padding:30px; color:var(--muted);">
                        <div style="font-size:36px; margin-bottom:8px;">📋</div>
                        <p>No tasks available yet</p>
                    </div>
                `;
                return;
            }
            
            // Group by timeline
            const immediate = tasks.filter(t => t.timeline === 'immediate' && t.status !== 'completed');
            const shortTerm = tasks.filter(t => t.timeline === 'short-term' && t.status !== 'completed');
            const mediumTerm = tasks.filter(t => t.timeline === 'medium-term' && t.status !== 'completed');
            const completed = tasks.filter(t => t.status === 'completed').slice(0, 5); // Show last 5 completed
            
            container.innerHTML = `
                ${immediate.length > 0 ? `
                    <div style="margin-bottom:20px;">
                        <h4 style="margin:0 0 10px 0; font-size:14px; color:#f44336;">⚡ Immediate (This Week)</h4>
                        <div style="display:grid; gap:10px;">
                            ${immediate.map(task => renderTaskCard(task)).join('')}
                        </div>
                    </div>
                ` : ''}
                
                ${shortTerm.length > 0 ? `
                    <div style="margin-bottom:20px;">
                        <h4 style="margin:0 0 10px 0; font-size:14px; color:#ff9800;">📅 Short-Term (This Month)</h4>
                        <div style="display:grid; gap:10px;">
                            ${shortTerm.map(task => renderTaskCard(task)).join('')}
                        </div>
                    </div>
                ` : ''}
                
                ${mediumTerm.length > 0 ? `
                    <div style="margin-bottom:20px;">
                        <h4 style="margin:0 0 10px 0; font-size:14px; color:var(--cyan-soft);">📆 Medium-Term (This Quarter)</h4>
                        <div style="display:grid; gap:10px;">
                            ${mediumTerm.map(task => renderTaskCard(task)).join('')}
                        </div>
                    </div>
                ` : ''}
                
                ${completed.length > 0 ? `
                    <div>
                        <h4 style="margin:0 0 10px 0; font-size:14px; color:var(--green-soft);">✅ Recently Completed</h4>
                        <div style="display:grid; gap:10px;">
                            ${completed.map(task => renderTaskCard(task)).join('')}
                        </div>
                    </div>
                ` : ''}
            `;
        }
        
        function renderTaskCard(task) {
            const isOverdue = new Date(task.due_date) < new Date() && task.status !== 'completed';
            const priorityColors = {
                'high': '#f44336',
                'medium': '#ff9800',
                'low': 'var(--muted)'
            };
            const statusColors = {
                'pending': 'var(--muted)',
                'in-progress': 'var(--cyan-soft)',
                'completed': 'var(--green-soft)',
                'cancelled': '#666'
            };
            
            const priorityColor = priorityColors[task.priority] || 'var(--muted)';
            const statusColor = statusColors[task.status] || 'var(--muted)';
            const isCompleted = task.status === 'completed';
            
            return `
                <div class="vmo-card" style="padding:12px; border-left:3px solid ${priorityColor}; ${isCompleted ? 'opacity:0.6;' : ''}">
                    <div style="display:flex; align-items:start; gap:10px;">
                        <div onclick="toggleTaskStatus(${task.id}, '${task.status}')" style="cursor:pointer; flex-shrink:0; margin-top:2px;">
                            ${isCompleted ? 
                                '<span style="font-size:20px; color:var(--green-soft);">✅</span>' :
                                '<span style="font-size:20px; opacity:0.3;">⬜</span>'
                            }
                        </div>
                        <div style="flex:1; ${isCompleted ? 'text-decoration:line-through;' : ''}">
                            <strong style="font-size:14px;">${task.title || 'Untitled Task'}</strong>
                            ${task.goal_title ? `
                                <div style="font-size:11px; color:var(--cyan-soft); margin-top:2px;">
                                    Goal: ${task.goal_title}
                                </div>
                            ` : ''}
                            <div style="font-size:12px; color:var(--muted); margin-top:4px; line-height:1.4;">
                                ${task.description || ''}
                            </div>
                            <div style="display:flex; align-items:center; gap:12px; margin-top:8px; flex-wrap:wrap;">
                                <span style="font-size:11px; padding:2px 6px; background:${statusColor}; color:#000; border-radius:4px; font-weight:600; text-transform:uppercase;">
                                    ${task.status.replace('-', ' ')}
                                </span>
                                <span style="font-size:11px; color:${isOverdue ? '#f44336' : 'var(--muted)'};">
                                    ${isOverdue ? '⚠️ Overdue: ' : 'Due: '}${new Date(task.due_date).toLocaleDateString('en-US', {month: 'short', day: 'numeric'})}
                                </span>
                                <span style="font-size:11px; color:var(--muted);">
                                    ~${task.estimated_days} days
                                </span>
                            </div>
                        </div>
                        ${!isCompleted ? `
                            <div style="flex-shrink:0;">
                                <select onchange="updateTaskStatus(${task.id}, this.value)" style="padding:4px 8px; font-size:11px; border-radius:4px; border:1px solid var(--border); background:var(--panel-bg); color:var(--ink); cursor:pointer;">
                                    <option value="pending" ${task.status === 'pending' ? 'selected' : ''}>Pending</option>
                                    <option value="in-progress" ${task.status === 'in-progress' ? 'selected' : ''}>In Progress</option>
                                    <option value="completed" ${task.status === 'completed' ? 'selected' : ''}>Completed</option>
                                    <option value="cancelled" ${task.status === 'cancelled' ? 'selected' : ''}>Cancelled</option>
                                </select>
                            </div>
                        ` : ''}
                    </div>
                </div>
            `;
        }
        
        async function toggleTaskStatus(taskId, currentStatus) {
            const newStatus = currentStatus === 'completed' ? 'pending' : 'completed';
            await updateTaskStatus(taskId, newStatus);
        }
        
        async function updateTaskStatus(taskId, newStatus) {
            try {
                const result = await ajaxPost('vmo_update_task_status', {
                    task_id: taskId,
                    status: newStatus
                });
                
                if (result.success) {
                    // Reload tasks to show updated status and recalculated progress
                    loadBusinessRoadmap();
                } else {
                    alert('Failed to update task status');
                }
            } catch (err) {
                console.error('Error updating task status:', err);
                alert('Error updating task status');
            }
        }
        
        function showGoalDetails(goalId) {
            // Create modal for goal details with related tasks
            const modal = document.createElement('div');
            modal.id = 'vmo-goal-details-modal';
            modal.style.cssText = 'display:flex; position:fixed; inset:0; background:rgba(0,0,0,.7); z-index:10000; align-items:center; justify-content:center; overflow:auto; padding:20px;';
            modal.innerHTML = `
                <div style="background:var(--panel-bg, #0b0f1a); border:1px solid var(--border); border-radius:12px; width:min(800px, 95vw); max-height:90vh; display:flex; flex-direction:column;">
                    <div style="display:flex; align-items:center; justify-content:space-between; padding:14px 18px; border-bottom:1px solid var(--border); position:sticky; top:0; background:var(--panel-bg); z-index:1;">
                        <strong style="font-size:16px;">Goal Details</strong>
                        <button class="action-btn" onclick="document.getElementById('vmo-goal-details-modal').remove()">✖ Close</button>
                    </div>
                    <div id="vmo-goal-details-body" style="padding:20px; overflow:auto; flex:1;">
                        <div style="color:var(--muted); text-align:center; padding:40px;">Loading goal details...</div>
                    </div>
                </div>
            `;
            document.body.appendChild(modal);
            
            // Load goal details and related tasks
            Promise.all([
                ajaxPost('vmo_get_business_goals', { goal_id: goalId }),
                ajaxPost('vmo_get_roadmap_tasks', { goal_id: goalId, status: 'all' })
            ])
            .then(([goalResult, tasksResult]) => {
                const body = document.getElementById('vmo-goal-details-body');
                if (goalResult.success && goalResult.data.goals && goalResult.data.goals[0]) {
                    const goal = goalResult.data.goals[0];
                    const tasks = tasksResult.success ? (tasksResult.data.tasks || []) : [];
                    const progress = parseInt(goal.progress_percentage || 0);
                    
                    body.innerHTML = `
                        <div style="margin-bottom:20px;">
                            <h2 style="margin:0 0 10px 0;">${goal.title}</h2>
                            <div style="font-size:14px; color:var(--muted); line-height:1.6; margin-bottom:16px;">
                                ${goal.description || 'No description available'}
                            </div>
                            
                            <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:12px; margin-bottom:20px;">
                                <div class="vmo-card">
                                    <div style="font-size:11px; color:var(--muted); margin-bottom:4px;">Timeframe</div>
                                    <div style="font-size:14px; font-weight:600; text-transform:capitalize;">${goal.timeframe}</div>
                                </div>
                                <div class="vmo-card">
                                    <div style="font-size:11px; color:var(--muted); margin-bottom:4px;">Category</div>
                                    <div style="font-size:14px; font-weight:600; text-transform:capitalize;">${goal.category}</div>
                                </div>
                                <div class="vmo-card">
                                    <div style="font-size:11px; color:var(--muted); margin-bottom:4px;">Priority</div>
                                    <div style="font-size:14px; font-weight:600; text-transform:capitalize;">${goal.priority}</div>
                                </div>
                                <div class="vmo-card">
                                    <div style="font-size:11px; color:var(--muted); margin-bottom:4px;">Target Date</div>
                                    <div style="font-size:14px; font-weight:600;">${new Date(goal.target_date).toLocaleDateString('en-US', {month: 'short', day: 'numeric', year: 'numeric'})}</div>
                                </div>
                            </div>
                            
                            ${goal.target_metric ? `
                                <div class="vmo-card" style="margin-bottom:20px; background:rgba(33, 150, 243, .1); border-left:3px solid var(--cyan-soft);">
                                    <div style="font-size:12px; color:var(--cyan-soft); margin-bottom:4px; font-weight:600;">Target Metric</div>
                                    <div style="font-size:16px; font-weight:700;">${goal.target_metric}</div>
                                </div>
                            ` : ''}
                            
                            <div class="vmo-card">
                                <div style="display:flex; justify-content:space-between; margin-bottom:8px;">
                                    <span style="font-size:12px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;">Overall Progress</span>
                                    <span style="font-size:16px; font-weight:700; color:var(--cyan-soft);">${progress}%</span>
                                </div>
                                <div style="height:8px; background:var(--border); border-radius:4px; overflow:hidden;">
                                    <div style="height:100%; background:var(--cyan-soft); width:${progress}%; transition:width 0.3s;"></div>
                                </div>
                            </div>
                        </div>
                        
                        ${tasks.length > 0 ? `
                            <div>
                                <h3 style="margin:0 0 14px 0; font-size:16px;">Related Tasks (${tasks.length})</h3>
                                <div style="display:grid; gap:10px;">
                                    ${tasks.map(task => renderTaskCard(task)).join('')}
                                </div>
                            </div>
                        ` : `
                            <div style="text-align:center; padding:30px; color:var(--muted);">
                                <p>No tasks associated with this goal yet</p>
                            </div>
                        `}
                    `;
                } else {
                    body.innerHTML = '<div style="color:var(--muted); text-align:center; padding:40px;">Goal not found</div>';
                }
            })
            .catch(err => {
                const body = document.getElementById('vmo-goal-details-body');
                body.innerHTML = '<div style="color:#f44336; text-align:center; padding:40px;">Error loading goal details</div>';
                console.error(err);
            });
        }
        
        function openCRMInterface() { window.open('<?php echo esc_js(admin_url('admin.php?page=vmo-crm')); ?>', '_blank'); }


        function openLeadManagement() { alert('Opening lead management…'); }
        function openSEOInterface() { togglePanel('vmo-seo-panel', loadSEOPanel); }
        function openSEOReports() { togglePanel('vmo-seo-reports-panel', loadSEOReportsPanel); }
        async function loadSEOPanel(){
            const panel = document.getElementById('vmo-seo-panel'); if(!panel) return;
            panel.innerHTML = `
                <div class="vmo-card">
                    <h4>SEO Score</h4>
                    <div id="vmo-seo-score" style="font-size:28px; color:var(--cyan-soft); font-weight:700;">—</div>
                    <div id="vmo-seo-score-note" style="color:var(--muted); font-size:12px;">Overall site health</div>
                </div>
                <div class="vmo-card">
                    <h4>Keyword Visibility</h4>
                    <svg id="vmo-seo-keyword-spark" width="100%" height="32"></svg>
                    <div id="vmo-seo-keyword-source" style="color:var(--muted); font-size:11px; margin-top:4px;">External ranking data not connected</div>
                </div>
                <div class="vmo-card">
                    <h4>Technical Health</h4>
                    <div class="vmo-kv"><span>Pages Indexed</span><strong id="vmo-seo-indexed">—</strong></div>
                    <div id="vmo-seo-indexed-source" style="color:var(--muted); font-size:11px; margin:-2px 0 4px;">WordPress content proxy</div>
                    <div class="vmo-kv"><span>Errors</span><strong id="vmo-seo-errors">—</strong></div>
                    <div class="vmo-kv"><span>Warnings</span><strong id="vmo-seo-warnings">—</strong></div>
                </div>`;
            // Append Rankings by SEO Dimension
            const dims = document.createElement('div');
            dims.className = 'vmo-card';
            dims.innerHTML = `
                <h4>Current Rankings by SEO Dimension</h4>
                <div class="vmo-kv"><span>On‑Page SEO</span><strong id="vmo-seo-onpage">—</strong></div>
                <div class="vmo-kv"><span>Technical SEO</span><strong id="vmo-seo-technical">—</strong></div>
                <div class="vmo-kv"><span>Content SEO</span><strong id="vmo-seo-content">—</strong></div>
                <div class="vmo-kv"><span>Backlink Authority</span><strong id="vmo-seo-backlink">—</strong></div>
                <div id="vmo-seo-backlink-source" style="color:var(--muted); font-size:11px; margin:-2px 0 4px;">Estimated from site content</div>
                <div class="vmo-kv"><span>Domain Authority</span><strong id="vmo-seo-da">—</strong></div>
                <div id="vmo-seo-da-source" style="color:var(--muted); font-size:11px; margin:-2px 0 4px;">Estimated from site content</div>
                <div class="vmo-kv"><span>Keyword Opportunity</span><strong id="vmo-seo-ko">—</strong></div>
                <div id="vmo-seo-ko-source" style="color:var(--muted); font-size:11px; margin:-2px 0 4px;">Estimated from consultation and site content</div>`;
            panel.appendChild(dims);

            // Append AI Recommendations
            const rec = document.createElement('div');
            rec.className = 'vmo-card';
            rec.innerHTML = `
                <h4>AI Recommendations</h4>
                <div style="color:var(--muted); font-size:12px; margin:-2px 0 8px;">Approve or edit suggested keywords, blog topics, and actions to reach your target ranking.</div>
                <div class="vmo-cards" style="grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:10px;">
                    <div class="vmo-card" style="background:rgba(255,255,255,.02)">
                        <h4>Keywords</h4>
                        <div id="vmo-seo-reco-keywords">Loading…</div>
                    </div>
                    <div class="vmo-card" style="background:rgba(255,255,255,.02)">
                        <h4>Blog Topics</h4>
                        <div id="vmo-seo-reco-blogs">Loading…</div>
                    </div>
                    <div class="vmo-card" style="background:rgba(255,255,255,.02)">
                        <h4>Other Actions</h4>
                        <div id="vmo-seo-reco-actions">Loading…</div>
                    </div>
                </div>
                <div style="display:flex; gap:8px; margin-top:10px; flex-wrap:wrap;">
                    <button class="action-btn primary" id="vmo-seo-approve-all">Approve All</button>
                    <button class="action-btn" id="vmo-seo-regenerate">🔄 Regenerate Suggestions</button>
                </div>`;
            panel.appendChild(rec);

            // Integrations & Auto-Execution card
            const integ = document.createElement('div');
            integ.className = 'vmo-card';
            integ.innerHTML = `
                <h4>Integrations & Auto-Execution</h4>
                <div class="vmo-kv"><span>Ahrefs</span><strong id="vmo-ahrefs-status">—</strong></div>
                <div class="vmo-kv"><span>SEMrush</span><strong id="vmo-semrush-status">—</strong></div>
                <div id="vmo-seo-source-note" style="color:var(--muted); font-size:11px; margin:6px 0; line-height:1.35;">Metrics use VMO site analysis until provider enrichment syncs.</div>
                <div style="display:flex; gap:8px; flex-wrap:wrap; margin:8px 0;">
                    <input id="vmo-ahrefs-key" type="password" placeholder="Ahrefs API key" style="flex:1; min-width:220px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                    <input id="vmo-semrush-key" type="password" placeholder="SEMrush API key" style="flex:1; min-width:220px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                    <button id="vmo-seo-save-integrations" class="action-btn">Save</button>
                    <button id="vmo-seo-refresh" class="action-btn">🔄 Refresh SEO Data</button>
                </div>
                <label style="display:flex; align-items:center; gap:8px; font-size:12px; color:var(--ink);">
                    <input id="vmo-seo-autoexec" type="checkbox" /> Auto-execute upon approval (AI runs tasks)
                </label>
                <div style="color:var(--muted); font-size:11px; margin-top:6px;">When enabled, approving a recommendation will immediately create tasks or drafts automatically.</div>
                <div class="vmo-kv" style="margin-top:6px;"><span>Last Refresh</span><strong id="vmo-seo-last-refresh">—</strong></div>`;
            panel.appendChild(integ);

            const growth = document.createElement('div');
            growth.className = 'vmo-card';
            growth.style.gridColumn = '1 / -1';
            growth.innerHTML = `
                <h4>SEO Growth Modules</h4>
                <div id="vmo-seo-growth-modules" style="font-size:12px; color:var(--ink); line-height:1.45;">Loading…</div>`;
            panel.appendChild(growth);
            try{
                const [{success, data}, recs, integRes, growthRes] = await Promise.all([
                    ajaxPost('vmo_get_seo_overview'),
                    ajaxPost('vmo_get_seo_recommendations').catch(()=>({success:false})),
                    ajaxPost('vmo_get_seo_integrations').catch(()=>({success:false})),
                    ajaxPost('vmo_seo_get_growth_modules').catch(()=>({success:false}))
                ]);
                const set = (id,val)=>{ const el=document.getElementById(id); if(el) el.textContent = String(val); };
                const safeValue = (value, fallback) => (value === undefined || value === null ? fallback : value);
                if(success && data){
                    set('vmo-seo-score', typeof data.score==='number'? Math.round(data.score): (data.score||'—'));
                    drawSpark('vmo-seo-keyword-spark', (data.keyword_trend||[]).length? data.keyword_trend : [0,0]);
                    set('vmo-seo-indexed', safeValue(data.pages_indexed, '—'));
                    set('vmo-seo-errors', safeValue(data.errors, 0));
                    set('vmo-seo-warnings', safeValue(data.warnings, 0));
                    // Levels/rankings
                    const lv = data.levels || {};
                    if (typeof lv.local !== 'undefined') set('vmo-seo-local', (typeof lv.local==='number'? (lv.local.toFixed(0)+'/100') : lv.local));
                    if (typeof lv.onpage !== 'undefined') set('vmo-seo-onpage', (typeof lv.onpage==='number'? (lv.onpage.toFixed(0)+'/100') : lv.onpage));
                    if (typeof lv.technical !== 'undefined') set('vmo-seo-technical', (typeof lv.technical==='number'? (lv.technical.toFixed(0)+'/100') : lv.technical));
                    if (typeof lv.content !== 'undefined') set('vmo-seo-content', (typeof lv.content==='number'? (lv.content.toFixed(0)+'/100') : lv.content));
                    if (typeof lv.backlink !== 'undefined') set('vmo-seo-backlink', (typeof lv.backlink==='number'? (lv.backlink.toFixed(0)+'/100') : lv.backlink));
                    if (typeof data.domain_authority !== 'undefined') set('vmo-seo-da', (typeof data.domain_authority==='number'? (data.domain_authority+'/100') : data.domain_authority));
                    if (typeof data.keyword_opportunity !== 'undefined') set('vmo-seo-ko', (typeof data.keyword_opportunity==='number'? (data.keyword_opportunity+'/100') : data.keyword_opportunity));
                    const labels = data.metric_labels || {};
                    set('vmo-seo-keyword-source', labels.keyword_visibility || 'External ranking data not connected');
                    set('vmo-seo-indexed-source', labels.indexed_pages || 'WordPress content proxy');
                    set('vmo-seo-backlink-source', labels.backlink_authority || 'Estimated from site content');
                    set('vmo-seo-da-source', labels.domain_authority || 'Estimated from site content');
                    set('vmo-seo-ko-source', labels.keyword_opportunity || 'Estimated from consultation and site content');
                    const sources = data.metric_sources || {};
                    const sourceNote = document.getElementById('vmo-seo-source-note');
                    if (sourceNote) {
                        const parts = [];
                        if (sources.domain_authority) parts.push('Domain authority: ' + sources.domain_authority);
                        if (sources.backlinks) parts.push('Backlinks: ' + sources.backlinks);
                        if (sources.keyword_visibility) parts.push('Keywords: ' + sources.keyword_visibility);
                        sourceNote.textContent = parts.length ? parts.join(' · ') : 'Metrics use VMO site analysis until provider enrichment syncs.';
                    }
                } else {
                    drawSpark('vmo-seo-keyword-spark', [0,0]);
                }
                // Render recommendations
                try { if (recs && recs.success && recs.data) renderSEORecommendations(recs.data); else renderSEORecommendations({}); } catch(_){ }
                try { renderSEOGrowthModules(growthRes && growthRes.success ? growthRes.data : {}); } catch(_){ }
                // Integrations + auto-exec
                try {
                    const S = (integRes && integRes.success && integRes.data) ? integRes.data : {};
                    const ahrefsStatus = document.getElementById('vmo-ahrefs-status'); if (ahrefsStatus) ahrefsStatus.textContent = S.ahrefs_status || (S.ahrefs_connected ? 'Connected - enrichment pending' : 'Not connected');
                    const semrushStatus = document.getElementById('vmo-semrush-status'); if (semrushStatus) semrushStatus.textContent = S.semrush_status || (S.semrush_connected ? 'Connected - enrichment pending' : 'Not connected');
                    const kA = document.getElementById('vmo-ahrefs-key'); if (kA && S.ahrefs_key_masked) kA.placeholder = S.ahrefs_key_masked;
                    const kS = document.getElementById('vmo-semrush-key'); if (kS && S.semrush_key_masked) kS.placeholder = S.semrush_key_masked;
                    const lr = document.getElementById('vmo-seo-last-refresh'); if (lr) lr.textContent = S.last_refresh || '—';
                    window.__seoAutoExecute = !!S.auto_execute;
                    const auto = document.getElementById('vmo-seo-autoexec'); if (auto) { auto.checked = !!S.auto_execute; auto.onchange = async ()=>{
                        try { const {success,message} = await ajaxPost('vmo_set_seo_auto_execute', { value: auto.checked ? 1 : 0 }); if (!success) { notify(message||'Failed to save', 'error'); auto.checked = !auto.checked; } else { window.__seoAutoExecute = auto.checked; notify('Auto-execution updated', 'success'); } } catch(e){ notify('Error: '+e.message,'error'); auto.checked = !auto.checked; }
                    }; }
                    const saveBtn = document.getElementById('vmo-seo-save-integrations'); if (saveBtn) saveBtn.onclick = async ()=>{
                        const ah = (document.getElementById('vmo-ahrefs-key')||{}).value || '';
                        const se = (document.getElementById('vmo-semrush-key')||{}).value || '';
                        try{ const {success, message} = await ajaxPost('vmo_save_seo_integrations', { ahrefs_key: ah, semrush_key: se }); if (!success) { notify(message||'Failed to save keys','error'); return; } notify('Integrations saved','success'); loadSEOPanel(); }catch(e){ notify('Error: '+e.message,'error'); }
                    };
                    const refreshBtn = document.getElementById('vmo-seo-refresh'); if (refreshBtn) refreshBtn.onclick = async ()=>{
                        try{ const {success, data, message} = await ajaxPost('vmo_refresh_seo_data'); if (!success) { notify(message||'Refresh failed','error'); return; } notify((message || (data && data.message) || 'Refresh queued'),'success'); const lr = document.getElementById('vmo-seo-last-refresh'); if (lr && data && data.last_refresh) lr.textContent = data.last_refresh; loadSEOPanel(); }catch(e){ notify('Error: '+e.message,'error'); }
                    };
                } catch(_){}
            }catch(e){ drawSpark('vmo-seo-keyword-spark', [0,0]); }
        }
        function renderSEOGrowthModules(data){
            const box = document.getElementById('vmo-seo-growth-modules');
            if (!box) return;
            const esc = (value)=>String(value == null ? '' : value).replace(/[&<>"']/g, ch=>({ '&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#039;' }[ch]));
            const arr = (value)=>Array.isArray(value) ? value : [];
            const authority = data.authority_growth || {};
            const authorityItems = arr(authority.items);
            const local = data.local_visibility || {};
            const localItems = arr(local.items);
            const review = data.review_growth || {};
            const reviewCandidates = arr(review.candidates);
            const reviewHistory = arr(review.campaign_status && review.campaign_status.history);
            const ai = data.ai_search_readiness || {};
            const technical = data.technical_audit || {};
            const gaps = arr(data.competitor_gaps);
            const language = data.customer_language || {};
            const gsc = data.gsc || {};
            const completedAuthority = authorityItems.filter(item=>item.status === 'completed').length;
            const completedLocal = localItems.filter(item=>item.status === 'completed').length;
            const metric = (label, value, sub)=>`<div style="border:1px solid rgba(255,255,255,.08); border-radius:6px; padding:8px; background:rgba(255,255,255,.025); min-width:130px;"><div style="color:var(--muted); font-size:11px;">${esc(label)}</div><strong>${esc(value)}</strong>${sub ? `<div style="color:var(--muted); font-size:11px;">${esc(sub)}</div>` : ''}</div>`;
            const statusBtns = (id, type)=>`<div style="display:flex; gap:6px; flex-wrap:wrap; margin-top:6px;"><button class="action-btn" data-seo-${type}-id="${esc(id)}" data-status="in_progress">Working</button><button class="action-btn primary" data-seo-${type}-id="${esc(id)}" data-status="completed">Done</button></div>`;
            const authorityHtml = authorityItems.slice(0, 6).map(item=>`
                <div style="padding:8px 0; border-top:1px solid rgba(255,255,255,.06);">
                    <div style="display:flex; justify-content:space-between; gap:8px; align-items:flex-start; flex-wrap:wrap;"><strong>${esc(item.title || 'Authority task')}</strong><span style="color:var(--muted);">${esc(item.impact || 'medium')} impact · ${esc(item.status || 'not_started')}</span></div>
                    <div style="color:var(--muted); font-size:11px; margin-top:2px;">${esc(item.source_type || 'fallback_search_url')} · ${esc(item.confidence || 'medium')} confidence</div>
                    <div style="color:var(--muted); margin-top:3px;">${esc(item.why_it_matters || '')}</div>
                    ${item.suggested_link ? `<a href="${esc(item.suggested_link)}" target="_blank" rel="noopener" style="color:var(--cyan-soft); display:inline-block; margin-top:5px;">Open opportunity</a>` : ''}
                    ${statusBtns(item.id || '', 'authority')}
                </div>`).join('') || '<div style="color:var(--muted);">Authority tasks will appear after the next scan.</div>';
            const localHtml = localItems.slice(0, 8).map(item=>`
                <div style="display:flex; justify-content:space-between; gap:8px; align-items:center; padding:6px 0; border-top:1px solid rgba(255,255,255,.06);">
                    <span>${esc(item.title || '')}</span>
                    <button class="action-btn" data-seo-local-id="${esc(item.id || '')}" data-status="completed">${item.status === 'completed' ? 'Done' : 'Mark Done'}</button>
                </div>`).join('') || '<div style="color:var(--muted);">Local visibility checklist is empty.</div>';
            const reviewHtml = reviewCandidates.slice(0, 5).map(candidate=>`
                <div style="padding:7px 0; border-top:1px solid rgba(255,255,255,.06);">
                    <div style="display:flex; justify-content:space-between; gap:8px; flex-wrap:wrap;"><strong>${esc(candidate.customer_name || 'Customer')}</strong><span style="color:var(--muted);">${esc(candidate.recommended_channel || 'email')}</span></div>
                    <div style="color:var(--muted);">${esc(candidate.reason || '')}</div>
                    <button class="action-btn" data-seo-review-contact="${esc(candidate.contact_id || '')}" data-channel="${esc(candidate.recommended_channel || 'email')}">Queue Request</button>
                </div>`).join('') || '<div style="color:var(--muted);">No high-confidence review candidates yet.</div>';
            const reviewHistoryHtml = reviewHistory.slice(-4).reverse().map(request=>`<div style="padding:6px 0; border-top:1px solid rgba(255,255,255,.06);"><div style="display:flex; justify-content:space-between; gap:8px; flex-wrap:wrap;"><span>${esc(request.platform || 'Review')}</span><strong>${esc(request.status || 'draft')}</strong></div><button class="action-btn" data-seo-review-complete="${esc(request.request_id || '')}" data-contact="${esc(request.contact_id || '')}">Mark Received</button></div>`).join('');
            const aiActions = arr(ai.recommendations).map(rec=>`<button class="action-btn" data-seo-ai-action="${esc(rec.type || '')}">${esc(rec.title || rec.type || 'Create action')}</button>`).join('');
            const aiChecks = Object.entries(ai.checks || {}).slice(0, 8).map(([key, ok])=>`<div class="vmo-kv"><span>${esc(key.replace(/_/g,' '))}</span><strong>${ok ? 'Ready' : 'Needs work'}</strong></div>`).join('') || '<div style="color:var(--muted);">AI-search readiness will appear after audit.</div>';
            const techHtml = arr(technical.issues).slice(0, 5).map(issue=>`<div class="vmo-kv"><span>${esc(issue.issue || 'Issue')}</span><strong>${esc(issue.severity || 'medium')}</strong></div>`).join('') || '<div style="color:var(--muted);">No technical issues found in the latest scan.</div>';
            const gapHtml = gaps.slice(0, 5).map(gap=>`<div style="padding:5px 0; border-top:1px solid rgba(255,255,255,.06);"><strong>${esc(gap.type || 'Gap')}</strong><div style="color:var(--muted);">${esc(gap.recommended_action || gap.what_user_lacks || '')}</div></div>`).join('') || '<div style="color:var(--muted);">No competitor gaps available yet.</div>';
            const phraseHtml = arr(language.customer_language_keywords || language.top_questions).slice(0, 8).map(phrase=>`<span style="display:inline-block; padding:3px 6px; margin:2px; border:1px solid rgba(255,255,255,.08); border-radius:6px; color:var(--muted);">${esc(phrase)}</span>`).join('') || '<span style="color:var(--muted);">Customer call/form language will appear as CRM and call history grows.</span>';
            box.innerHTML = `
                <div style="display:flex; flex-wrap:wrap; gap:8px; margin-bottom:10px;">
                    ${metric('Authority', completedAuthority + '/' + authorityItems.length, 'external tasks')}
                    ${metric('Local Visibility', completedLocal + '/' + localItems.length, 'GBP checklist')}
                    ${metric('Review Growth', (review.campaign_status && review.campaign_status.requests_sent) || 0, 'requests queued')}
                    ${metric('AI Search', (ai.readiness_score || 0) + '/100', ai.label || 'readiness')}
                    ${metric('Search Console', gsc.connected ? 'Connected' : 'Not connected', gsc.source || 'Google Search Console')}
                </div>
                <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(260px, 1fr)); gap:12px;">
                    <section><h4>Authority Growth</h4>${authorityHtml}</section>
                    <section><h4>Local Visibility</h4><div style="color:var(--muted); font-size:11px; margin-bottom:6px;">Manual setup checklist — full direct Google Business integration coming in the Promotions update.</div>${localHtml}</section>
                    <section><h4>Review Growth</h4>${reviewHtml}${reviewHistoryHtml}</section>
                    <section><h4>AI Search / GEO / AEO</h4><div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom:6px;"><button class="action-btn" id="vmo-seo-generate-llms">Generate llms.txt</button><a class="action-btn" href="/llms.txt" target="_blank" rel="noopener">View llms.txt</a></div><div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom:6px;">${aiActions}</div>${aiChecks}</section>
                    <section><h4>Search Console</h4><div style="display:flex; flex-direction:column; gap:6px;"><input id="vmo-gsc-site-url" placeholder="Verified site URL" value="${esc((authority.nap && authority.nap.website) || '')}" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"><input id="vmo-gsc-client-id" placeholder="Google OAuth client ID" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"><input id="vmo-gsc-client-secret" placeholder="Google OAuth client secret" type="password" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"><div style="display:flex; gap:6px; flex-wrap:wrap;"><button class="action-btn" id="vmo-gsc-save">Save GSC</button><button class="action-btn" id="vmo-gsc-oauth">Start OAuth</button><button class="action-btn" id="vmo-gsc-sites">Fetch Sites</button></div></div></section>
                    <section><h4>Customer Language</h4><div>${phraseHtml}</div></section>
                    <section><h4>Technical Audit</h4>${techHtml}</section>
                    <section><h4>Competitor Gaps</h4>${gapHtml}</section>
                </div>`;
            box.querySelectorAll('[data-seo-authority-id]').forEach(btn=>btn.addEventListener('click', async()=>{
                try { const res = await ajaxPost('vmo_seo_update_authority_task_status', { id: btn.dataset.seoAuthorityId, status: btn.dataset.status }); if(!res.success){ notify(res.message || 'Task update failed', 'error'); return; } notify('Authority task updated', 'success'); loadSEOPanel(); } catch(e){ notify('Error: '+e.message, 'error'); }
            }));
            box.querySelectorAll('[data-seo-local-id]').forEach(btn=>btn.addEventListener('click', async()=>{
                try { const res = await ajaxPost('vmo_seo_update_local_visibility_status', { item_id: btn.dataset.seoLocalId, status: btn.dataset.status }); if(!res.success){ notify(res.message || 'Checklist update failed', 'error'); return; } notify('Local checklist updated', 'success'); loadSEOPanel(); } catch(e){ notify('Error: '+e.message, 'error'); }
            }));
            box.querySelectorAll('[data-seo-review-contact]').forEach(btn=>btn.addEventListener('click', async()=>{
                try { const res = await ajaxPost('vmo_seo_schedule_review_request', { contact_id: btn.dataset.seoReviewContact, channel: btn.dataset.channel || 'email' }); if(!res.success){ notify(res.message || 'Review request failed', 'error'); return; } notify('Review request queued', 'success'); loadSEOPanel(); } catch(e){ notify('Error: '+e.message, 'error'); }
            }));
            box.querySelectorAll('[data-seo-review-complete]').forEach(btn=>btn.addEventListener('click', async()=>{
                try { const res = await ajaxPost('vmo_seo_mark_review_received', { request_id: btn.dataset.seoReviewComplete || '', contact_id: btn.dataset.contact || '' }); if(!res.success){ notify(res.message || 'Review update failed', 'error'); return; } notify('Review marked received', 'success'); loadSEOPanel(); } catch(e){ notify('Error: '+e.message, 'error'); }
            }));
            box.querySelectorAll('[data-seo-ai-action]').forEach(btn=>btn.addEventListener('click', async()=>{
                try { const res = await ajaxPost('vmo_seo_execute_ai_search_recommendation', { type: btn.dataset.seoAiAction || '' }); if(!res.success){ notify(res.message || 'AI-search action failed', 'error'); return; } notify((res.data && res.data.message) || 'AI-search action created', 'success'); loadSEOPanel(); } catch(e){ notify('Error: '+e.message, 'error'); }
            }));
            const llmsBtn = document.getElementById('vmo-seo-generate-llms');
            if (llmsBtn) llmsBtn.onclick = async()=>{ try { const res = await ajaxPost('vmo_seo_generate_llms_txt'); if(!res.success){ notify(res.message || 'llms.txt generation failed', 'error'); return; } notify('llms.txt generated', 'success'); loadSEOPanel(); } catch(e){ notify('Error: '+e.message, 'error'); } };
            const gscSave = document.getElementById('vmo-gsc-save');
            if (gscSave) gscSave.onclick = async()=>{ try { const res = await ajaxPost('vmo_gsc_save_credentials', { site_url: (document.getElementById('vmo-gsc-site-url')||{}).value || '', client_id: (document.getElementById('vmo-gsc-client-id')||{}).value || '', client_secret: (document.getElementById('vmo-gsc-client-secret')||{}).value || '' }); if(!res.success){ notify(res.message || 'Search Console save failed', 'error'); return; } notify('Search Console settings saved', 'success'); } catch(e){ notify('Error: '+e.message, 'error'); } };
            const gscOauth = document.getElementById('vmo-gsc-oauth');
            if (gscOauth) gscOauth.onclick = async()=>{ try { const res = await ajaxPost('vmo_gsc_start_oauth'); const url = res && res.data && res.data.oauth_url; if(url) window.open(url, '_blank'); notify((res && res.data && res.data.message) || 'OAuth started', url ? 'success' : 'error'); } catch(e){ notify('Error: '+e.message, 'error'); } };
            const gscSites = document.getElementById('vmo-gsc-sites');
            if (gscSites) gscSites.onclick = async()=>{ try { const res = await ajaxPost('vmo_gsc_fetch_sites'); notify((res && res.data && res.data.message) || 'Search Console sites checked', res && res.success ? 'success' : 'error'); } catch(e){ notify('Error: '+e.message, 'error'); } };
        }
        async function loadSEOReportsPanel(){
            const panel = document.getElementById('vmo-seo-reports-panel'); if(!panel) return;
            panel.innerHTML = `
                <div class="vmo-card">
                    <h4>Recent SEO Reports</h4>
                    <div id="vmo-seo-reports-list" style="max-height:220px; overflow:auto; font-size:12px; color:var(--ink)">Loading…</div>
                </div>
                <div class="vmo-card">
                    <h4>Core Metrics</h4>
                    <svg id="vmo-seo-core-spark" width="100%" height="32"></svg>
                </div>
                <div class="vmo-card">
                    <h4>Top Keywords</h4>
                    <div id="vmo-seo-topkw" style="font-size:12px; white-space:pre-wrap; color:var(--muted)">—</div>
                </div>
                <div class="vmo-card">
                    <h4>Backlinks Trend</h4>
                    <svg id="vmo-seo-backlinks-spark" width="100%" height="32"></svg>
                </div>
                <div class="vmo-card">
                    <h4>Index Coverage</h4>
                    <svg id="vmo-seo-index-spark" width="100%" height="32"></svg>
                </div>
                <div class="vmo-card">
                    <h4>Metric Sources</h4>
                    <div id="vmo-seo-report-sources" style="font-size:12px; color:var(--muted); line-height:1.45;">—</div>
                </div>
                <div class="vmo-card" style="grid-column:1/-1">
                    <h4>Issue Breakdown</h4>
                    <div id="vmo-seo-issues" style="columns:2; gap:12px; font-size:12px; color:var(--muted)">—</div>
                </div>
                <div class="vmo-card" style="grid-column:1/-1">
                    <h4>Growth Intelligence</h4>
                    <div id="vmo-seo-growth-report" style="font-size:12px; color:var(--muted); line-height:1.45;">—</div>
                </div>`;
            try{
                const {success, data} = await ajaxPost('vmo_get_seo_reports');
                const listEl = document.getElementById('vmo-seo-reports-list');
                if (success && data){
                    const reports = Array.isArray(data.reports)? data.reports : [];
                    if (reports.length){
                        listEl.innerHTML = reports.map(r=>{
                            const date = String(r.date||'').replace('T',' ');
                            const score = (typeof r.score==='number')? r.score : (r.score||'—');
                            const notes = (r.summary||'').toString().replace(/</g,'&lt;');
                            return `<div style="padding:6px 8px; border-bottom:1px solid rgba(255,255,255,.06)"><strong>${date}</strong> — Score: ${score}<div style="color:var(--muted); font-size:11px;">${notes}</div></div>`;
                        }).join('');
                    } else { listEl.textContent = 'No reports yet'; }
                    drawSpark('vmo-seo-core-spark', (data.core_trend||[]).length? data.core_trend : [0,0]);
                    const top = Array.isArray(data.top_keywords)? data.top_keywords : [];
                    const kwEl = document.getElementById('vmo-seo-topkw'); if(kwEl) kwEl.textContent = top.length? top.join(', ') : '—';
                    drawSpark('vmo-seo-backlinks-spark', (data.backlinks_trend||[]).length? data.backlinks_trend : [0,0]);
                    drawSpark('vmo-seo-index-spark', (data.index_trend||[]).length? data.index_trend : [0,0]);
                    const reportLabels = data.metric_labels || {};
                    const reportSources = document.getElementById('vmo-seo-report-sources');
                    if (reportSources) {
                        const rows = [
                            ['Index coverage', reportLabels.indexed_pages || (data.index_coverage && data.index_coverage.label) || 'WordPress content proxy'],
                            ['Backlinks', reportLabels.backlink_authority || 'Estimated from site content'],
                            ['Domain authority', reportLabels.domain_authority || 'Estimated from site content'],
                            ['Keyword visibility', reportLabels.keyword_visibility || 'External ranking data not connected']
                        ];
                        reportSources.innerHTML = rows.map(row=>`<div class="vmo-kv"><span>${row[0]}</span><strong>${row[1]}</strong></div>`).join('');
                    }
                    const issues = data.issue_breakdown || {};
                    const issuesEl = document.getElementById('vmo-seo-issues');
                    if (issuesEl) {
                        const keys = Object.keys(issues);
                        issuesEl.innerHTML = keys.length ? keys.map(k=>`<div class="vmo-kv"><span>${k.replace(/</g,'&lt;')}</span><strong>${issues[k]}</strong></div>`).join('') : '—';
                    }
                    const growthReport = document.getElementById('vmo-seo-growth-report');
                    if (growthReport) {
                        const esc = (value)=>String(value == null ? '' : value).replace(/[&<>"']/g, ch=>({ '&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#039;' }[ch]));
                        const outcomes = data.business_outcomes || {};
                        const content = data.content_growth || {};
                        const authority = data.authority_growth || {};
                        const local = data.local_visibility || {};
                        const reviews = data.review_growth || {};
                        const ai = data.ai_search || {};
                        const technical = data.technical_audit || {};
                        const gaps = Array.isArray(data.competitor_gaps) ? data.competitor_gaps : [];
                        const language = data.customer_language || {};
                        growthReport.innerHTML = `
                            <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(210px, 1fr)); gap:10px;">
                                <div><strong>Search Visibility</strong><div>Source: ${esc((data.search_visibility && data.search_visibility.active_source) || 'WordPress proxy metrics')}</div><div>Clicks: ${esc((data.search_visibility && data.search_visibility.clicks) || 0)} · Impressions: ${esc((data.search_visibility && data.search_visibility.impressions) || 0)}</div></div>
                                <div><strong>Business Outcomes</strong><div>Organic leads: ${esc(outcomes.organic_leads || 0)} · calls: ${esc(outcomes.organic_calls || 0)}</div><div>Sales: ${esc(outcomes.organic_sales || 0)} · revenue: ${esc(outcomes.organic_revenue || 0)}</div></div>
                                <div><strong>Content Growth</strong><div>Assets: ${esc(content.seo_assets_total || 0)} · published: ${esc(content.published_assets || 0)} · drafts: ${esc(content.draft_assets || 0)}</div></div>
                                <div><strong>Authority Growth</strong><div>Open: ${esc(authority.open_tasks || 0)} · completed: ${esc(authority.completed_tasks || 0)}</div></div>
                                <div><strong>Local Visibility</strong><div>Checklist: ${esc(local.completed_items || 0)}/${esc(local.total_items || 0)}</div></div>
                                <div><strong>Review Growth</strong><div>Requests: ${esc(reviews.requests_sent || 0)} · confirmed: ${esc(reviews.confirmed_reviews || 0)}</div></div>
                                <div><strong>AI Search</strong><div>Readiness: ${esc(ai.readiness_score || 0)}/100</div></div>
                                <div><strong>Technical Audit</strong><div>Issues: ${esc(technical.issue_count || 0)}</div></div>
                            </div>
                            <div style="margin-top:10px;"><strong>Competitor Gaps</strong><div>${gaps.length ? gaps.slice(0,4).map(g=>esc(g.recommended_action || g.what_user_lacks || '')).join('<br>') : '—'}</div></div>
                            <div style="margin-top:10px;"><strong>Customer Language</strong><div>${Array.isArray(language.customer_language_keywords) && language.customer_language_keywords.length ? language.customer_language_keywords.slice(0,8).map(esc).join(', ') : '—'}</div></div>`;
                    }
                } else {
                    const listEl = document.getElementById('vmo-seo-reports-list'); if(listEl) listEl.textContent='No reports available';
                    drawSpark('vmo-seo-core-spark', [0,0]);
                }
            }catch(e){ const listEl = document.getElementById('vmo-seo-reports-list'); if(listEl) listEl.textContent='Failed to load'; drawSpark('vmo-seo-core-spark', [0,0]); }
        }
        
        // ============================================================
        // Strategic Dashboard KPIs loader (live, nonce-secure)
        // ============================================================
        
        // Local AJAX helper (uses global constants from this template). Falls back to fetch if external helper isn't present.
        async function vmoPost(action, data) {
            try {
                // If a global ajaxPost helper exists, prefer it
                if (typeof window.ajaxPost === 'function') {
                    return await window.ajaxPost(action, data || {});
                }
            } catch (_) {}
            const form = new URLSearchParams();
            form.append('action', action);
            // Send both nonces for broad compatibility
            if (typeof VMO_NONCE_ADMIN !== 'undefined') form.append('security', VMO_NONCE_ADMIN);
            else if (typeof VMO_NONCE_BUILDER !== 'undefined') form.append('security', VMO_NONCE_BUILDER);
            if (data && typeof data === 'object') {
                Object.keys(data).forEach(k => {
                    const v = data[k];
                    if (v === undefined || v === null) return;
                    form.append(k, typeof v === 'object' ? JSON.stringify(v) : String(v));
                });
            }
            const res = await fetch(VMO_AJAX, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
                credentials: 'same-origin',
                body: form.toString()
            });
            if (!res.ok) return { success: false, message: 'Network error' };
            return res.json().catch(() => ({ success: false, message: 'Invalid JSON' }));
        }

        function setText(id, val) {
            const el = document.getElementById(id);
            if (el) el.textContent = (val === undefined || val === null) ? '—' : String(val);
        }
        function setWidth(id, percent) {
            const el = document.getElementById(id);
            if (el) el.style.width = Math.max(0, Math.min(100, Number(percent) || 0)) + '%';
        }
        function setProgressRing(selector, percent) {
            const host = document.querySelector(selector);
            if (!host) return;
            const ring = host.querySelector('.progress-ring .progress');
            if (!ring) return;
            const total = 88; // stroke-dasharray in template
            const p = Math.max(0, Math.min(100, Number(percent) || 0));
            ring.style.strokeDashoffset = String(Math.round(total - (p / 100) * total));
        }
        function formatCents(amountCents, currency = 'USD') {
            const n = Number(amountCents || 0) / 100;
            try {
                return new Intl.NumberFormat(undefined, { style: 'currency', currency: String(currency).toUpperCase() || 'USD' }).format(n);
            } catch (_) {
                return '$' + n.toFixed(2);
            }
        }

        async function loadDashboardKPIs() {
            try {
                const resp = await vmoPost('vmo_dashboard_stats', {});
                if (!resp || !resp.success || !resp.data) {
                    console.warn('[VMO] vmo_dashboard_stats failed:', resp && resp.message);
                    return;
                }
                const d = resp.data;
                // Header metrics
                setText('vmo-metric-goals', (Number(d.goals_complete_percent || 0)) + '%');
                setProgressRing('.vmo-header .vmo-metrics .vmo-metric:nth-child(1)', Number(d.goals_complete_percent || 0));
                setText('vmo-metric-alerts', Number(d.growth_alerts || 0));
                setProgressRing('.vmo-header .vmo-metrics .vmo-metric:nth-child(2)', Math.min(100, Number(d.growth_alerts || 0))); // purely cosmetic

                // Progress summary (left panel)
                const st = d.short_term || { percent: 0, completed: 0, total: 0, today_percent: 0 };
                setWidth('vmo-st-fill', st.percent || 0);
                setText('vmo-st-count', `${Number(st.completed||0)}/${Number(st.total||0)}`);
                setText('vmo-local-progress', (Number(st.today_percent||0)) + '%');
                setText('vmo-today-date', new Date().toLocaleDateString());
                const lt = d.long_term || { percent: 0, note: '—' };
                setWidth('vmo-lt-fill', lt.percent || 0);
                setText('vmo-lt-note', lt.note || '—');

                // Today action items
                const list = document.getElementById('vmo-today-list');
                if (list) {
                    const tasks = Array.isArray(d.tasks_today) ? d.tasks_today : [];
                    if (!tasks.length) {
                        list.innerHTML = '<div class="vmo-card" style="padding:10px; color: var(--muted);">No tasks scheduled for today.</div>';
                    } else {
                        list.innerHTML = tasks.map(t => {
                            const checked = t.checked ? 'checked' : '';
                            const cls = t.checked ? 'task-checkbox checked' : 'task-checkbox';
                            const safeText = String(t.text || 'Task').replace(/</g, '&lt;');
                            return `<div class="task-item"><div class="${cls}" role="checkbox" aria-checked="${!!t.checked}"></div><div class="task-text">${safeText}</div></div>`;
                        }).join('');
                        // Bind toggles (visual only)
                        list.querySelectorAll('.task-checkbox').forEach(cb => {
                            cb.addEventListener('click', function() { this.classList.toggle('checked'); });
                        });
                    }
                }

                // Weekly strategy (headline only here; full modal handled elsewhere)
                const insights = (d.weekly && Array.isArray(d.weekly.insights)) ? d.weekly.insights : [];
                setText('vmo-weekly-headline', insights.length ? String(insights[0]) : ((d.website && d.website.status_label) ? String(d.website.status_label) : 'No new insights this week yet.'));

                // Business Intelligence
                const bi = d.bi || {};
                setText('vmo-bi-ranking', bi.ranking || '—');
                setText('vmo-bi-growth', (typeof bi.growth === 'number' ? (bi.growth.toFixed(1) + '%') : (bi.growth || '0%')));
                setText('vmo-bi-next', bi.next_milestone || '—');
                setText('vmo-bi-monitored', Number(bi.monitored || 0));
                setText('vmo-bi-threats', Number(bi.new_threats || 0));
                setText('vmo-bi-opps', Number(bi.opportunities || 0));

                // Footer last update timestamp
                setText('vmo-last-update', d.last_update ? String(d.last_update) : new Date().toLocaleTimeString());
            } catch (e) {
                console.warn('[VMO] Failed to load dashboard KPIs:', e);
            }
        }

        // ═══════════════════════════════════════════════════════════════════
        // SALES TREND CHART RENDERERS (pure Canvas 2D — no external libs)
        // ═══════════════════════════════════════════════════════════════════

        /**
         * Render a 30-day daily sales line chart onto a <canvas> element.
         * @param {Array} dailySales - Array of {date, label, total} objects (cent values)
         * @param {string} canvasId - The id of the canvas element
         */
        function renderSalesTrendChart(dailySales, canvasId) {
            const canvas = document.getElementById(canvasId);
            if (!canvas || !canvas.getContext) return;
            if (!dailySales || !dailySales.length) {
                // Show "no data" message
                const ct = canvas.getContext('2d');
                const w = canvas.parentElement.clientWidth || 600;
                const h = 180;
                canvas.width = w; canvas.height = h;
                ct.fillStyle = 'rgba(255,255,255,.15)';
                ct.font = '13px system-ui, sans-serif';
                ct.textAlign = 'center';
                ct.fillText('No sales data yet', w/2, h/2);
                return;
            }

            const dpr = window.devicePixelRatio || 1;
            const w = canvas.parentElement.clientWidth || 600;
            const h = 180;
            canvas.width = w * dpr; canvas.height = h * dpr;
            canvas.style.width = w + 'px'; canvas.style.height = h + 'px';
            const ctx = canvas.getContext('2d');
            ctx.scale(dpr, dpr);

            const pad = { top: 20, right: 16, bottom: 36, left: 60 };
            const cw = w - pad.left - pad.right;
            const ch = h - pad.top - pad.bottom;

            const vals = dailySales.map(d => (Number(d.total)||0) / 100);
            const maxVal = Math.max(...vals, 1);
            const stepX = cw / Math.max(vals.length - 1, 1);

            // Background
            ctx.clearRect(0, 0, w, h);

            // Grid lines
            ctx.strokeStyle = 'rgba(255,255,255,.06)';
            ctx.lineWidth = 1;
            const gridSteps = 4;
            for (let i = 0; i <= gridSteps; i++) {
                const y = pad.top + (ch / gridSteps) * i;
                ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(w - pad.right, y); ctx.stroke();
                // Y-axis labels
                const v = maxVal - (maxVal / gridSteps) * i;
                ctx.fillStyle = 'rgba(255,255,255,.35)';
                ctx.font = '10px system-ui, sans-serif';
                ctx.textAlign = 'right';
                ctx.fillText('$' + (v >= 1000 ? (v/1000).toFixed(1) + 'k' : v.toFixed(0)), pad.left - 6, y + 3);
            }

            // Fill gradient
            const grad = ctx.createLinearGradient(0, pad.top, 0, pad.top + ch);
            grad.addColorStop(0, 'rgba(59,130,246,.25)');
            grad.addColorStop(1, 'rgba(59,130,246,.02)');
            ctx.beginPath();
            ctx.moveTo(pad.left, pad.top + ch);
            vals.forEach((v, i) => {
                const x = pad.left + stepX * i;
                const y = pad.top + ch - (v / maxVal) * ch;
                ctx.lineTo(x, y);
            });
            ctx.lineTo(pad.left + stepX * (vals.length - 1), pad.top + ch);
            ctx.closePath();
            ctx.fillStyle = grad;
            ctx.fill();

            // Line
            ctx.beginPath();
            ctx.strokeStyle = '#3b82f6';
            ctx.lineWidth = 2;
            ctx.lineJoin = 'round';
            vals.forEach((v, i) => {
                const x = pad.left + stepX * i;
                const y = pad.top + ch - (v / maxVal) * ch;
                i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
            });
            ctx.stroke();

            // Dots
            vals.forEach((v, i) => {
                const x = pad.left + stepX * i;
                const y = pad.top + ch - (v / maxVal) * ch;
                ctx.beginPath();
                ctx.arc(x, y, 3, 0, Math.PI * 2);
                ctx.fillStyle = '#3b82f6';
                ctx.fill();
            });

            // X-axis labels (show every ~5th label to avoid overlap)
            ctx.fillStyle = 'rgba(255,255,255,.35)';
            ctx.font = '9px system-ui, sans-serif';
            ctx.textAlign = 'center';
            const labelSkip = Math.max(1, Math.ceil(vals.length / 7));
            dailySales.forEach((d, i) => {
                if (i % labelSkip === 0 || i === vals.length - 1) {
                    const x = pad.left + stepX * i;
                    ctx.fillText(d.label || '', x, h - pad.bottom + 16);
                }
            });
        }

        /**
         * Render a 12-month bar chart onto a <canvas> element.
         * @param {Array} monthlySales - Array of {month, label, total} objects (cent values)
         * @param {string} canvasId - The id of the canvas element
         */
        function renderMonthlySalesChart(monthlySales, canvasId) {
            const canvas = document.getElementById(canvasId);
            if (!canvas || !canvas.getContext) return;
            if (!monthlySales || !monthlySales.length) {
                const ct = canvas.getContext('2d');
                const w = canvas.parentElement.clientWidth || 600;
                const h = 180;
                canvas.width = w; canvas.height = h;
                ct.fillStyle = 'rgba(255,255,255,.15)';
                ct.font = '13px system-ui, sans-serif';
                ct.textAlign = 'center';
                ct.fillText('No monthly data yet', w/2, h/2);
                return;
            }

            const dpr = window.devicePixelRatio || 1;
            const w = canvas.parentElement.clientWidth || 600;
            const h = 180;
            canvas.width = w * dpr; canvas.height = h * dpr;
            canvas.style.width = w + 'px'; canvas.style.height = h + 'px';
            const ctx = canvas.getContext('2d');
            ctx.scale(dpr, dpr);

            const pad = { top: 20, right: 16, bottom: 36, left: 60 };
            const cw = w - pad.left - pad.right;
            const ch = h - pad.top - pad.bottom;

            const vals = monthlySales.map(d => (Number(d.total)||0) / 100);
            const maxVal = Math.max(...vals, 1);
            const barW = Math.max(8, (cw / vals.length) - 6);

            // Background
            ctx.clearRect(0, 0, w, h);

            // Grid lines
            ctx.strokeStyle = 'rgba(255,255,255,.06)';
            ctx.lineWidth = 1;
            const gridSteps = 4;
            for (let i = 0; i <= gridSteps; i++) {
                const y = pad.top + (ch / gridSteps) * i;
                ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(w - pad.right, y); ctx.stroke();
                const v = maxVal - (maxVal / gridSteps) * i;
                ctx.fillStyle = 'rgba(255,255,255,.35)';
                ctx.font = '10px system-ui, sans-serif';
                ctx.textAlign = 'right';
                ctx.fillText('$' + (v >= 1000 ? (v/1000).toFixed(1) + 'k' : v.toFixed(0)), pad.left - 6, y + 3);
            }

            // Bars
            const stepX = cw / vals.length;
            vals.forEach((v, i) => {
                const barH = (v / maxVal) * ch;
                const x = pad.left + stepX * i + (stepX - barW) / 2;
                const y = pad.top + ch - barH;

                // Bar gradient
                const grad = ctx.createLinearGradient(x, y, x, pad.top + ch);
                grad.addColorStop(0, '#6366f1');
                grad.addColorStop(1, '#3b82f6');
                ctx.fillStyle = grad;

                // Rounded top
                const r = Math.min(4, barW / 2);
                ctx.beginPath();
                ctx.moveTo(x, pad.top + ch);
                ctx.lineTo(x, y + r);
                ctx.quadraticCurveTo(x, y, x + r, y);
                ctx.lineTo(x + barW - r, y);
                ctx.quadraticCurveTo(x + barW, y, x + barW, y + r);
                ctx.lineTo(x + barW, pad.top + ch);
                ctx.closePath();
                ctx.fill();

                // Value on top
                if (v > 0) {
                    ctx.fillStyle = 'rgba(255,255,255,.5)';
                    ctx.font = '9px system-ui, sans-serif';
                    ctx.textAlign = 'center';
                    ctx.fillText('$' + (v >= 1000 ? (v/1000).toFixed(1) + 'k' : v.toFixed(0)), x + barW/2, y - 4);
                }
            });

            // X-axis labels
            ctx.fillStyle = 'rgba(255,255,255,.35)';
            ctx.font = '9px system-ui, sans-serif';
            ctx.textAlign = 'center';
            monthlySales.forEach((d, i) => {
                const x = pad.left + stepX * i + stepX / 2;
                // Short month name
                const shortLabel = (d.label || '').split(' ')[0] || '';
                ctx.fillText(shortLabel, x, h - pad.bottom + 16);
            });
        }

        // Payments panel loader using scoped dashboard stats
        function vmoTaxRest(endpoint, method, body) {
            var root = (window.wpApiSettings && window.wpApiSettings.root) || '/wp-json/';
            var nonce = (window.wpApiSettings && window.wpApiSettings.nonce) || '';
            var opts = { method: method || 'GET', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin' };
            if (nonce) opts.headers['X-WP-Nonce'] = nonce;
            if (body && method !== 'GET') opts.body = JSON.stringify(body);
            return fetch(root + 'vmo-builder/v1/' + endpoint, opts).then(function(r) { return r.json(); });
        }

        function fmtC(n, cur) {
            try { return new Intl.NumberFormat(undefined, { style: 'currency', currency: cur || 'USD' }).format(n); }
            catch(_) { return '$' + Number(n).toFixed(2); }
        }
        function vmoNotify(msg, type) { if (typeof window.notify === 'function') window.notify(msg, type); else console.log('[VMO CFO]', msg); }
        function vmoFlowStatusDone(status) {
            status = String(status || '').toLowerCase();
            return ['completed', 'fulfilled', 'delivered', 'cancelled', 'refunded'].indexOf(status) !== -1;
        }
        function vmoPaymentHtml(value) {
            return String(value || '—').replace(/[&<>"']/g, function(ch) { return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[ch]; });
        }
        window.vmoMarkPaymentBusinessFlowComplete = async function(orderId, btn) {
            if (!orderId) return;
            if (!confirm('Mark this paid transaction completed?')) return;
            if (btn) { btn.disabled = true; btn.textContent = 'Saving...'; }
            try {
                var resp = await vmoPost('vmo_mark_business_flow_complete', {
                    order_id: orderId,
                    status: 'completed',
                    completion_notes: 'Completed from the CFO payments dashboard.'
                });
                if (resp && resp.success) {
                    vmoNotify('Order marked completed.', 'success');
                    if (typeof window.loadPaymentsPanel === 'function') window.loadPaymentsPanel();
                    if (typeof window.loadActiveOrdersPanel === 'function') window.loadActiveOrdersPanel();
                } else {
                    vmoNotify((resp && resp.data && resp.data.message) || 'Could not complete order.', 'error');
                    if (btn) { btn.disabled = false; btn.textContent = 'Complete'; }
                }
            } catch (e) {
                vmoNotify('Could not complete order.', 'error');
                if (btn) { btn.disabled = false; btn.textContent = 'Complete'; }
            }
        };

        // ── CFO Dashboard panel (KPIs, charts, transactions) + Tax Calculator boot ──
        window.loadPaymentsPanel = async function() {
            try {
                var resp = await vmoPost('vmo_dashboard_stats', { scope: 'payments' });
                if (!resp || !resp.success || !resp.data) {
                    console.warn('[VMO] payments scope failed');
                    ['vmo-pay-kpi-day','vmo-pay-kpi-week','vmo-pay-kpi-month','vmo-pay-kpi-year','vmo-pay-kpi-mom'].forEach(function(id) { setText(id, '—'); });
                    var rows = document.getElementById('vmo-pay-rows');
                    if (rows) rows.innerHTML = '<tr><td colspan="8" style="padding:8px;color:var(--muted)">No transactions</td></tr>';
                    return;
                }
                var d = resp.data;
                setText('vmo-pay-kpi-day', formatCents(d.day || 0));
                setText('vmo-pay-kpi-week', formatCents(d.week || 0));
                setText('vmo-pay-kpi-month', formatCents(d.month || 0));
                setText('vmo-pay-kpi-year', formatCents(d.year || 0));
                setText('vmo-pay-kpi-mom', (typeof d.mom_change === 'number') ? (d.mom_change.toFixed(2) + '%') : '—');
                var flowSummary = d.fulfillment_summary || {};
                setText('vmo-pay-kpi-pending-flow', formatCents(flowSummary.pending_fulfillment_revenue || 0));
                setText('vmo-pay-kpi-pending-count', String(flowSummary.pending_fulfillment_count || 0));
                setText('vmo-pay-kpi-completed-flow', formatCents(flowSummary.completed_fulfilled_revenue || 0));
                setText('vmo-pay-kpi-completed-count', String(flowSummary.completed_fulfilled_count || 0));
                setText('vmo-pay-kpi-net-revenue', formatCents(flowSummary.net_revenue || 0));
                setText('vmo-pay-kpi-fees-taxes', formatCents(flowSummary.fees || 0) + ' / ' + formatCents(flowSummary.taxes || 0));

                try { renderSalesTrendChart(d.daily_sales || [], 'vmo-pay-line'); } catch(_){}
                try { renderMonthlySalesChart(d.monthly_sales || [], 'vmo-pay-monthly'); } catch(_){}

                var tx = Array.isArray(d.transactions) ? d.transactions : [];
                window.__vmoPaymentsTransactions = tx;
                var tbody = document.getElementById('vmo-pay-rows');
                if (tbody) {
                    if (!tx.length) {
                        tbody.innerHTML = '<tr><td colspan="8" style="padding:8px;color:var(--muted)">No transactions</td></tr>';
                    } else {
                        tbody.innerHTML = tx.map(function(t) {
                            var dt = t.date ? new Date(t.date).toLocaleString() : '—';
                            var product = vmoPaymentHtml(t.product || '—');
                            var amt = formatCents(t.amount || 0, t.currency || 'USD');
                            var cur = (t.currency || 'USD').toUpperCase();
                            var status = vmoPaymentHtml(t.status || '—');
                            var flowStatus = String(t.business_flow_status || t.fulfillment_status || 'awaiting_fulfillment');
                            var flowLabel = vmoPaymentHtml(flowStatus.replace(/_/g, ' '));
                            var action = vmoFlowStatusDone(flowStatus)
                                ? '<span style="color:var(--muted)">Done</span>'
                                : '<button class="action-btn compact" type="button" onclick="window.vmoMarkPaymentBusinessFlowComplete(' + Number(t.id || 0) + ', this)">Complete</button>';
                            var receipt = t.id ? ('#' + t.id) : '—';
                            return '<tr><td style="padding:6px 8px">' + dt + '</td><td style="padding:6px 8px">' + product + '</td><td style="padding:6px 8px">' + amt + '</td><td style="padding:6px 8px">' + cur + '</td><td style="padding:6px 8px">' + status + '</td><td style="padding:6px 8px">' + flowLabel + '</td><td style="padding:6px 8px">' + action + '</td><td style="padding:6px 8px">' + receipt + '</td></tr>';
                        }).join('');
                    }
                }

                // Boot Tax Calculator
                try { vmoCFOBoot(); } catch(e) { console.warn('[VMO CFO] Boot error:', e); }
            } catch (e) {
                console.warn('[VMO] Failed to load payments KPIs:', e);
            }
        }

        // ================================================================
        // CFO TAX DASHBOARD — Auto-populated from consultation + transactions
        // ================================================================
        try { (function() {
            var cfoBound = false;
            var countriesCache = null;
            var briefingData = null;
            var currentCurrency = 'USD';

            window.vmoCFOBoot = async function() {
                var loading = document.getElementById('vmo-cfo-loading');
                try {
                    var r = await vmoTaxRest('tax/cfo-briefing', 'GET');
                    if (!r || !r.success || !r.data) {
                        if (loading) loading.textContent = '⚠️ Could not load financial briefing. Please try again.';
                        return;
                    }
                    briefingData = r.data;
                    currentCurrency = briefingData.currency || 'USD';

                    var loc = briefingData.location || {};
                    var biz = briefingData.business || {};
                    var rev = briefingData.revenue || {};
                    var exp = briefingData.expenses || {};
                    var sum = briefingData.summary || {};

                    // Location display
                    var locParts = [];
                    if (loc.state_name) locParts.push(loc.state_name);
                    if (loc.country_name) locParts.push(loc.country_name);
                    setText('vmo-cfo-location', locParts.join(', ') || 'Not detected');

                    // Business info
                    setText('vmo-cfo-biz-name', biz.name || 'Your Business');
                    setText('vmo-cfo-biz-type', biz.type || 'Business');
                    setText('vmo-cfo-currency', currentCurrency);

                    // Source badge
                    var badge = document.getElementById('vmo-cfo-source-badge');
                    if (badge) {
                        if (loc.source === 'consultation') { badge.textContent = 'Auto-detected from consultation'; badge.style.background = '#10b981'; }
                        else if (loc.source === 'saved_settings') { badge.textContent = 'Saved settings'; badge.style.background = '#3b82f6'; }
                        else { badge.textContent = 'Set location →'; badge.style.background = '#f59e0b'; }
                    }

                    // Revenue summary
                    setText('vmo-cfo-vmo-gross', fmtC(rev.vmo_gross || 0, currentCurrency));
                    setText('vmo-cfo-order-count', rev.order_count || 0);
                    setText('vmo-cfo-other-income', fmtC(rev.other_income || 0, currentCurrency));
                    setText('vmo-cfo-combined-gross', fmtC(rev.combined_gross || 0, currentCurrency));
                    setText('vmo-cfo-total-expenses', fmtC(exp.total || 0, currentCurrency));
                    setText('vmo-cfo-net-profit', fmtC(sum.net_profit || 0, currentCurrency));
                    setText('vmo-cfo-sales-tax', fmtC(sum.sales_tax_collected || 0, currentCurrency));

                    // Pre-fill user inputs from saved values
                    var overheadEl = document.getElementById('vmo-cfo-overhead');
                    if (overheadEl && exp.declared_overhead) overheadEl.value = exp.declared_overhead;
                    var otherEl = document.getElementById('vmo-cfo-other-income-input');
                    if (otherEl && rev.other_income) otherEl.value = rev.other_income;

                    // Tax regime info
                    if (briefingData.tax_regime) showCFORegimeInfo(briefingData.tax_regime);

                    // Show context, summary, hide loading
                    if (loading) loading.style.display = 'none';
                    var ctx = document.getElementById('vmo-cfo-context');
                    if (ctx) ctx.style.display = 'block';
                    var sumEl = document.getElementById('vmo-cfo-summary');
                    if (sumEl) sumEl.style.display = 'block';

                    // Bind events (once)
                    if (!cfoBound) { cfoBound = true; bindCFOEvents(); }

                    // Boot net worth
                    try { vmoLoadNetWorth(); } catch(_){}
                } catch(e) {
                    console.warn('[VMO CFO] Briefing error:', e);
                    if (loading) loading.textContent = '⚠️ Error loading financial data.';
                }
            };

            function showCFORegimeInfo(regime) {
                if (!regime) return;
                var panel = document.getElementById('vmo-tax-regime-info');
                if (!panel) return;
                var title = document.getElementById('vmo-tax-regime-title');
                var badges = document.getElementById('vmo-tax-regime-badges');
                var brackets = document.getElementById('vmo-tax-brackets-display');
                if (title) title.textContent = (regime.country_name || '') + ' Tax System';
                var bh = '';
                if (regime.has_vat) bh += '<span style="background:#3b82f6;color:#fff;padding:2px 6px;border-radius:4px;font-size:10px;">VAT ' + (regime.vat_rate||'') + '%</span> ';
                if (regime.has_gst) bh += '<span style="background:#f59e0b;color:#000;padding:2px 6px;border-radius:4px;font-size:10px;">GST ' + (regime.gst_rate||'') + '%</span> ';
                if (regime.has_sales_tax) bh += '<span style="background:#10b981;color:#fff;padding:2px 6px;border-radius:4px;font-size:10px;">Sales Tax</span> ';
                if (regime.self_employment_tax_rate) bh += '<span style="background:#a855f7;color:#fff;padding:2px 6px;border-radius:4px;font-size:10px;">SE Tax ' + regime.self_employment_tax_rate + '%</span> ';
                if (badges) badges.innerHTML = bh;
                if (brackets && regime.brackets && regime.brackets.length) {
                    brackets.innerHTML = '<strong style="font-size:11px;color:var(--muted);">Income Tax Brackets:</strong><br>' +
                        regime.brackets.map(function(b) {
                            return '<span style="color:var(--ink);">' + fmtC(b.min, currentCurrency) + ' – ' + (b.max ? fmtC(b.max, currentCurrency) : '∞') + ': <strong>' + b.rate + '%</strong></span>';
                        }).join('<br>');
                }
                panel.style.display = 'block';
            }

            function bindCFOEvents() {
                // Edit location toggle
                var editLink = document.getElementById('vmo-cfo-edit-location');
                if (editLink) editLink.addEventListener('click', function(e) {
                    e.preventDefault();
                    var panel = document.getElementById('vmo-cfo-manual-location');
                    if (panel) panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
                    loadCountryDropdowns();
                });

                // Save settings (manual location override)
                var saveSet = document.getElementById('vmo-tax-save-settings');
                if (saveSet) saveSet.addEventListener('click', async function() {
                    var country = document.getElementById('vmo-tax-country').value;
                    var state = document.getElementById('vmo-tax-state').value;
                    var filing = document.getElementById('vmo-tax-filing-status').value;
                    if (!country) { vmoNotify('Select a country', 'error'); return; }
                    try {
                        await vmoTaxRest('tax/settings', 'POST', { country: country, state: state, filing_status: filing });
                        vmoNotify('Settings saved — refreshing…', 'success');
                        vmoCFOBoot();
                    } catch(e) { vmoNotify('Save failed', 'error'); }
                });

                // Save declarations (overhead + other income)
                var saveDecl = document.getElementById('vmo-cfo-save-declarations');
                if (saveDecl) saveDecl.addEventListener('click', async function() {
                    var overhead = parseFloat(document.getElementById('vmo-cfo-overhead').value) || 0;
                    var otherIncome = parseFloat(document.getElementById('vmo-cfo-other-income-input').value) || 0;
                    try {
                        await vmoTaxRest('tax/assets-liabilities', 'POST', { declared_overhead: overhead, other_income: otherIncome, assets: [], liabilities: [] });
                        vmoNotify('Declarations saved', 'success');
                        vmoCFOBoot();
                    } catch(e) { vmoNotify('Save failed', 'error'); }
                });

                // Calculate Tax
                var calcBtn = document.getElementById('vmo-cfo-calculate-tax');
                if (calcBtn) calcBtn.addEventListener('click', async function() {
                    if (!briefingData) { vmoNotify('Financial data not loaded yet', 'error'); return; }
                    var loc = briefingData.location || {};
                    var rev = briefingData.revenue || {};
                    var biz = briefingData.business || {};
                    var overhead = parseFloat(document.getElementById('vmo-cfo-overhead').value) || (briefingData.expenses || {}).total || 0;
                    var otherIncome = parseFloat(document.getElementById('vmo-cfo-other-income-input').value) || 0;
                    var payload = {
                        country: loc.country_code || '',
                        state: loc.state_code || '',
                        filing_status: biz.filing_status || 'single',
                        use_actual_revenue: true,
                        period: 'year',
                        gross_income: (rev.vmo_gross || 0) + otherIncome,
                        expenses: overhead
                    };
                    if (!payload.country) { vmoNotify('Business location not detected. Click "Edit manually" to set it.', 'error'); return; }
                    try {
                        calcBtn.disabled = true; calcBtn.textContent = '⏳ Calculating…';
                        var r = await vmoTaxRest('tax/calculate', 'POST', payload);
                        calcBtn.disabled = false; calcBtn.textContent = '🧮 Calculate My Taxes';
                        if (!r || !r.success) { vmoNotify(r && r.message ? r.message : 'Tax calculation failed', 'error'); return; }
                        var d = r.data;
                        setText('vmo-tax-res-gross', fmtC(d.gross_income, currentCurrency));
                        setText('vmo-tax-res-expenses', fmtC(d.total_expenses, currentCurrency));
                        setText('vmo-tax-res-profit', fmtC(d.net_profit, currentCurrency));
                        setText('vmo-tax-res-total', fmtC(d.total_tax, currentCurrency));
                        setText('vmo-tax-res-rate', (d.effective_rate || 0).toFixed(2) + '%');
                        setText('vmo-tax-res-net', fmtC(d.net_after_tax, currentCurrency));
                        var bd = document.getElementById('vmo-tax-breakdown-rows');
                        if (bd && Array.isArray(d.breakdown)) {
                            bd.innerHTML = d.breakdown.map(function(b) {
                                return '<tr><td style="padding:6px 8px;">' + (b.label||'') + '</td><td style="padding:6px 8px;text-align:right;">' + (b.rate||0).toFixed(2) + '%</td><td style="padding:6px 8px;text-align:right;">' + fmtC(b.amount||0, currentCurrency) + '</td></tr>';
                            }).join('');
                        }
                        var iti = document.getElementById('vmo-tax-indirect-info');
                        if (iti) {
                            var html = '';
                            if (d.indirect_taxes) {
                                if (d.indirect_taxes.vat) html += '<div><strong>VAT:</strong> ' + d.indirect_taxes.vat.rate + '% → ' + fmtC(d.indirect_taxes.vat.estimated_annual, currentCurrency) + '/yr</div>';
                                if (d.indirect_taxes.gst) html += '<div><strong>GST:</strong> ' + d.indirect_taxes.gst.rate + '% → ' + fmtC(d.indirect_taxes.gst.estimated_annual, currentCurrency) + '/yr</div>';
                                if (d.indirect_taxes.sales_tax) html += '<div><strong>Sales Tax:</strong> varies by locality</div>';
                            }
                            if (d.sales_tax) html += '<div><strong>Sales Tax Rate:</strong> ' + (d.sales_tax.rate||0) + '%' + (d.sales_tax.local_range ? ' + local ' + d.sales_tax.local_range : '') + '</div>';
                            iti.innerHTML = html; iti.style.display = html ? 'block' : 'none';
                        }
                        var disc = document.getElementById('vmo-tax-disclaimer');
                        if (disc) { disc.innerHTML = d.disclaimer || ''; disc.style.display = 'block'; }
                        document.getElementById('vmo-tax-results').style.display = 'block';
                        vmoNotify('Tax calculation complete!', 'success');
                    } catch(e) {
                        calcBtn.disabled = false; calcBtn.textContent = '🧮 Calculate My Taxes';
                        vmoNotify('Tax error: ' + (e.message||e), 'error');
                    }
                });

                // AI Tax Advisor
                var aiBtn = document.getElementById('vmo-tax-ai-run');
                if (aiBtn) aiBtn.addEventListener('click', async function() {
                    var loc = (briefingData && briefingData.location) || {};
                    if (!loc.country_code) { vmoNotify('Business location not detected', 'error'); return; }
                    var questionEl = document.getElementById('vmo-tax-ai-question');
                    var q = questionEl ? questionEl.value.trim() : '';
                    if (!q) { vmoNotify('Type a question first', 'error'); return; }
                    var resultBox = document.getElementById('vmo-tax-ai-result');
                    if (resultBox) { resultBox.style.display = 'block'; resultBox.textContent = '🤔 Your AI CFO is analyzing…'; }
                    try {
                        var rev = (briefingData && briefingData.revenue) || {};
                        var r = await vmoTaxRest('tax/ai-analysis', 'POST', {
                            country: loc.country_code, state: loc.state_code || '',
                            gross_income: rev.combined_gross || 0, expenses: (briefingData.expenses || {}).total || 0,
                            question: q
                        });
                        if (r && r.success && r.analysis) {
                            if (resultBox) {
                                resultBox.innerHTML = r.analysis.replace(/\n/g, '<br>');
                                if (r.tokens_charged) resultBox.innerHTML += '<div style="margin-top:8px;font-size:10px;color:var(--muted);">🪙 ' + r.tokens_charged + ' tokens used</div>';
                            }
                        } else {
                            if (resultBox) resultBox.textContent = '❌ ' + (r && r.message ? r.message : 'Analysis failed');
                        }
                    } catch(e) { if (resultBox) resultBox.textContent = '❌ Error: ' + (e.message||e); }
                });

                // Balance Sheet: preset dates
                var presetSel = document.getElementById('vmo-bs-preset');
                if (presetSel) presetSel.addEventListener('change', function() {
                    var now = new Date();
                    var from = document.getElementById('vmo-bs-date-from');
                    var to = document.getElementById('vmo-bs-date-to');
                    if (!from || !to) return;
                    to.value = now.toISOString().slice(0,10);
                    switch (this.value) {
                        case 'this_week':
                            var d = new Date(now); d.setDate(d.getDate() - d.getDay());
                            from.value = d.toISOString().slice(0,10); break;
                        case 'this_month':
                            from.value = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-01'; break;
                        case 'this_quarter':
                            var qm = Math.floor(now.getMonth()/3)*3;
                            from.value = now.getFullYear() + '-' + String(qm+1).padStart(2,'0') + '-01'; break;
                        case 'this_year':
                            from.value = now.getFullYear() + '-01-01'; break;
                        case 'last_month':
                            var lm = new Date(now.getFullYear(), now.getMonth()-1, 1);
                            var le = new Date(now.getFullYear(), now.getMonth(), 0);
                            from.value = lm.toISOString().slice(0,10);
                            to.value = le.toISOString().slice(0,10); break;
                        case 'last_quarter':
                            var cq = Math.floor(now.getMonth()/3);
                            var qs = cq === 0 ? new Date(now.getFullYear()-1, 9, 1) : new Date(now.getFullYear(), (cq-1)*3, 1);
                            var qe = cq === 0 ? new Date(now.getFullYear()-1, 11, 31) : new Date(now.getFullYear(), cq*3, 0);
                            from.value = qs.toISOString().slice(0,10);
                            to.value = qe.toISOString().slice(0,10); break;
                        case 'last_year':
                            from.value = (now.getFullYear()-1) + '-01-01';
                            to.value = (now.getFullYear()-1) + '-12-31'; break;
                    }
                });

                // Balance Sheet Generate
                var bsBtn = document.getElementById('vmo-bs-generate');
                if (bsBtn) bsBtn.addEventListener('click', async function() {
                    var from = document.getElementById('vmo-bs-date-from').value;
                    var to = document.getElementById('vmo-bs-date-to').value;
                    var preset = document.getElementById('vmo-bs-preset');
                    var label = preset ? preset.options[preset.selectedIndex].text : 'Custom Period';
                    if (!from || !to) { vmoNotify('Select a date range', 'error'); return; }
                    var result = document.getElementById('vmo-bs-result');
                    if (result) { result.style.display = 'block'; result.innerHTML = '<div style="text-align:center;padding:20px;color:var(--muted);">⏳ Generating balance sheet…</div>'; }
                    try {
                        var r = await vmoTaxRest('tax/balance-sheet', 'POST', { date_from: from, date_to: to, label: label });
                        if (!r || !r.success || !r.data) { if (result) result.innerHTML = '<div style="color:#ef4444;padding:12px;">Failed to generate balance sheet</div>'; return; }
                        renderBalanceSheet(r.data, result);
                    } catch(e) { if (result) result.innerHTML = '<div style="color:#ef4444;padding:12px;">Error: ' + (e.message||e) + '</div>'; }
                });

                // Net Worth: Add asset/liability + save buttons
                var addAssetBtn = document.getElementById('vmo-nw-add-asset');
                if (addAssetBtn) addAssetBtn.addEventListener('click', function() { addNWRow('asset'); });
                var addLiabBtn = document.getElementById('vmo-nw-add-liability');
                if (addLiabBtn) addLiabBtn.addEventListener('click', function() { addNWRow('liability'); });
                var saveNWBtn = document.getElementById('vmo-nw-save');
                if (saveNWBtn) saveNWBtn.addEventListener('click', saveAssetsLiabilities);
            }

            // ── Country dropdown for manual override ──
            async function loadCountryDropdowns() {
                var sel = document.getElementById('vmo-tax-country');
                if (!sel || sel.options.length > 1) return;
                if (countriesCache) return fillCountrySel(sel);
                try {
                    var r = await vmoTaxRest('tax/countries', 'GET');
                    if (r && r.success && r.countries) { countriesCache = r.countries; fillCountrySel(sel); }
                } catch(e) { console.warn('[VMO CFO] country load fail', e); }
            }

            function fillCountrySel(sel) {
                sel.innerHTML = '<option value="">Select country…</option>';
                var keys = Object.keys(countriesCache).sort(function(a,b) { return countriesCache[a].name.localeCompare(countriesCache[b].name); });
                keys.forEach(function(code) {
                    sel.innerHTML += '<option value="' + code + '">' + countriesCache[code].name + '</option>';
                });
                if (briefingData && briefingData.location && briefingData.location.country_code) {
                    sel.value = briefingData.location.country_code;
                    loadStateSel(briefingData.location.country_code);
                }
                sel.addEventListener('change', function() { loadStateSel(this.value); });
            }

            async function loadStateSel(cc) {
                var sel = document.getElementById('vmo-tax-state');
                if (!sel) return;
                sel.innerHTML = '<option value="">Loading…</option>';
                try {
                    var r = await vmoTaxRest('tax/rates', 'POST', { country: cc });
                    if (r && r.success) {
                        var states = r.available_states || r.available_provinces || {};
                        var label = r.available_provinces ? 'province' : 'state';
                        var keys = Object.keys(states);
                        if (keys.length > 0) {
                            sel.innerHTML = '<option value="">Select ' + label + '…</option>';
                            keys.forEach(function(code) { sel.innerHTML += '<option value="' + code + '">' + states[code] + '</option>'; });
                        } else {
                            sel.innerHTML = '<option value="">N/A</option>';
                        }
                        if (briefingData && briefingData.location && briefingData.location.state_code) sel.value = briefingData.location.state_code;
                    }
                } catch(e) { sel.innerHTML = '<option value="">Error</option>'; }
            }

            // ── Balance Sheet Renderer ──
            function renderBalanceSheet(data, container) {
                if (!container) return;
                var cur = data.currency || 'USD';
                var inc = data.income || {};
                var exp = data.expenses || {};
                var prf = data.profit || {};
                var tax = data.tax || {};
                var period = data.period || {};
                container.innerHTML =
                    '<div style="margin-bottom:12px;">' +
                        '<h4 style="margin:0 0 4px;color:var(--ink);">📊 ' + (data.business_name||'Business') + ' — Balance Sheet</h4>' +
                        '<div style="font-size:11px;color:var(--muted);">' + (period.label||'') + ': ' + (period.from||'') + ' to ' + (period.to||'') + ' (' + (period.days||0) + ' days)</div>' +
                    '</div>' +
                    '<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">' +
                        '<div class="vmo-card" style="border-color:rgba(16,185,129,.3);">' +
                            '<h5 style="margin:0 0 8px;color:#10b981;font-size:13px;">💰 Income</h5>' +
                            bsRow('Gross Revenue', inc.gross_revenue, cur) +
                            bsRow('Refunds', -(inc.refunds||0), cur, true) +
                            bsRow('Processing Fees', -(inc.processing_fees||0), cur, true) +
                            bsRow('Net Revenue', inc.net_revenue, cur, false, true) +
                            bsRow('Other Income', inc.other_income, cur) +
                            '<div style="border-top:1px solid var(--border);margin-top:6px;padding-top:6px;">' + bsRow('Total Income', inc.total_income, cur, false, true) + '</div>' +
                            '<div style="font-size:10px;color:var(--muted);margin-top:4px;">' + (inc.order_count||0) + ' orders</div>' +
                        '</div>' +
                        '<div class="vmo-card" style="border-color:rgba(239,68,68,.3);">' +
                            '<h5 style="margin:0 0 8px;color:#ef4444;font-size:13px;">📤 Expenses</h5>' +
                            bsRow('Tracked Expenses', exp.tracked_expenses, cur) +
                            bsRow('Processing Fees', exp.processing_fees, cur) +
                            bsRow('Overhead (prorated)', exp.overhead, cur) +
                            '<div style="border-top:1px solid var(--border);margin-top:6px;padding-top:6px;">' + bsRow('Total Expenses', exp.total, cur, false, true) + '</div>' +
                            (Object.keys(exp.by_category||{}).length > 0 ? '<div style="margin-top:8px;font-size:11px;color:var(--muted);"><strong>By Category:</strong></div>' +
                                Object.keys(exp.by_category).map(function(cat) { return '<div style="font-size:11px;display:flex;justify-content:space-between;"><span>' + cat + '</span><span>' + fmtC(exp.by_category[cat], cur) + '</span></div>'; }).join('') : '') +
                        '</div>' +
                    '</div>' +
                    '<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-top:12px;">' +
                        '<div class="vmo-card" style="text-align:center;border-color:rgba(59,130,246,.3);"><div style="font-size:10px;color:var(--muted);">Gross Profit</div><strong style="font-size:18px;color:#3b82f6;">' + fmtC(prf.gross_profit||0, cur) + '</strong></div>' +
                        '<div class="vmo-card" style="text-align:center;border-color:rgba(16,185,129,.3);"><div style="font-size:10px;color:var(--muted);">Net Income</div><strong style="font-size:18px;color:#10b981;">' + fmtC(prf.net_income||0, cur) + '</strong></div>' +
                        '<div class="vmo-card" style="text-align:center;border-color:rgba(245,158,11,.3);"><div style="font-size:10px;color:var(--muted);">Sales Tax Collected</div><strong style="font-size:18px;color:#f59e0b;">' + fmtC(tax.sales_tax_collected||0, cur) + '</strong></div>' +
                    '</div>' +
                    '<div style="margin-top:8px;font-size:10px;color:var(--muted);text-align:right;">Generated ' + (data.generated_at||new Date().toLocaleString()) + '</div>';
            }

            function bsRow(label, value, cur, neg, bold) {
                var color = neg ? '#ef4444' : 'var(--ink)';
                var fw = bold ? '600' : '400';
                return '<div style="display:flex;justify-content:space-between;padding:2px 0;font-size:12px;"><span>' + label + '</span><span style="color:' + color + ';font-weight:' + fw + ';">' + fmtC(value||0, cur) + '</span></div>';
            }

            // ── Net Worth ──
            window.vmoLoadNetWorth = async function() {
                var loading = document.getElementById('vmo-nw-loading');
                var display = document.getElementById('vmo-nw-display');
                try {
                    var r = await vmoTaxRest('tax/net-worth', 'GET');
                    if (!r || !r.success || !r.data) {
                        if (loading) loading.textContent = 'Unable to calculate net worth';
                        return;
                    }
                    var d = r.data;
                    var cur = d.currency || 'USD';
                    setText('vmo-nw-assets', fmtC(d.assets.total, cur));
                    setText('vmo-nw-liabilities', fmtC(d.liabilities.total, cur));
                    setText('vmo-nw-total', fmtC(d.net_worth, cur));

                    var nwCard = document.getElementById('vmo-nw-card');
                    var nwTotal = document.getElementById('vmo-nw-total');
                    if (nwCard && nwTotal) {
                        if (d.health === 'positive') { nwTotal.style.color = '#10b981'; nwCard.style.borderColor = 'rgba(16,185,129,.3)'; }
                        else if (d.health === 'negative') { nwTotal.style.color = '#ef4444'; nwCard.style.borderColor = 'rgba(239,68,68,.3)'; }
                        else { nwTotal.style.color = '#f59e0b'; nwCard.style.borderColor = 'rgba(245,158,11,.3)'; }
                    }

                    var breakdown = document.getElementById('vmo-nw-breakdown');
                    if (breakdown) {
                        breakdown.innerHTML =
                            '<div class="vmo-card" style="border-color:rgba(16,185,129,.2);">' +
                                '<h5 style="margin:0 0 6px;font-size:12px;color:#10b981;">Assets</h5>' +
                                bsRow('Cash (Net Revenue)', d.assets.cash, cur) +
                                bsRow('Accounts Receivable', d.assets.accounts_receivable, cur) +
                                (d.assets.external || []).map(function(a) { return bsRow(a.name || 'Asset', a.value, cur); }).join('') +
                                '<div style="border-top:1px solid var(--border);margin-top:4px;padding-top:4px;">' + bsRow('Total Assets', d.assets.total, cur, false, true) + '</div>' +
                            '</div>' +
                            '<div class="vmo-card" style="border-color:rgba(239,68,68,.2);">' +
                                '<h5 style="margin:0 0 6px;font-size:12px;color:#ef4444;">Liabilities</h5>' +
                                bsRow('Sales Tax Owed', d.liabilities.sales_tax_owed, cur) +
                                (d.liabilities.external || []).map(function(l) { return bsRow(l.name || 'Liability', l.value, cur); }).join('') +
                                '<div style="border-top:1px solid var(--border);margin-top:4px;padding-top:4px;">' + bsRow('Total Liabilities', d.liabilities.total, cur, false, true) + '</div>' +
                            '</div>';
                    }

                    if (loading) loading.style.display = 'none';
                    if (display) display.style.display = 'block';
                } catch(e) {
                    if (loading) loading.textContent = 'Error loading net worth';
                    console.warn('[VMO NW] error', e);
                }
            };

            // ── Add Asset / Liability rows ──
            function addNWRow(type) {
                var container = document.getElementById('vmo-nw-' + type + '-list');
                if (!container) {
                    var breakdown = document.getElementById('vmo-nw-breakdown');
                    if (!breakdown) return;
                    container = document.createElement('div');
                    container.id = 'vmo-nw-' + type + '-list';
                    breakdown.appendChild(container);
                }
                var row = document.createElement('div');
                row.style.cssText = 'display:flex;gap:4px;align-items:center;margin-bottom:4px;';
                row.innerHTML = '<input type="text" placeholder="Name" class="nw-name" style="flex:1;padding:4px 6px;border-radius:4px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink);font-size:11px;" />' +
                    '<input type="number" min="0" step="0.01" placeholder="$0.00" class="nw-value" style="width:80px;padding:4px 6px;border-radius:4px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink);font-size:11px;" />' +
                    '<select class="nw-cat" style="padding:4px;border-radius:4px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink);font-size:10px;">' +
                        (type === 'asset' ?
                            '<option value="property">Property</option><option value="investment">Investment</option><option value="equipment">Equipment</option><option value="inventory">Inventory</option><option value="vehicle">Vehicle</option><option value="other">Other</option>' :
                            '<option value="loan">Loan</option><option value="credit">Credit Line</option><option value="mortgage">Mortgage</option><option value="accounts_payable">Accounts Payable</option><option value="other">Other</option>') +
                    '</select>' +
                    '<button type="button" style="background:none;border:0;color:#ef4444;cursor:pointer;font-size:14px;" title="Remove">✕</button>';
                row.querySelector('button').addEventListener('click', function() { row.remove(); });
                container.appendChild(row);
            }

            async function saveAssetsLiabilities() {
                var assets = [];
                var liabilities = [];
                var assetList = document.getElementById('vmo-nw-asset-list');
                var liabList = document.getElementById('vmo-nw-liability-list');
                if (assetList) {
                    assetList.querySelectorAll('div').forEach(function(row) {
                        var n = row.querySelector('.nw-name');
                        var v = row.querySelector('.nw-value');
                        var c = row.querySelector('.nw-cat');
                        if (n && v) assets.push({ name: n.value, value: parseFloat(v.value)||0, category: c ? c.value : 'other' });
                    });
                }
                if (liabList) {
                    liabList.querySelectorAll('div').forEach(function(row) {
                        var n = row.querySelector('.nw-name');
                        var v = row.querySelector('.nw-value');
                        var c = row.querySelector('.nw-cat');
                        if (n && v) liabilities.push({ name: n.value, value: parseFloat(v.value)||0, category: c ? c.value : 'other' });
                    });
                }
                try {
                    var overhead = parseFloat(document.getElementById('vmo-cfo-overhead').value) || 0;
                    var otherIncome = parseFloat(document.getElementById('vmo-cfo-other-income-input').value) || 0;
                    await vmoTaxRest('tax/assets-liabilities', 'POST', { assets: assets, liabilities: liabilities, declared_overhead: overhead, other_income: otherIncome });
                    vmoNotify('Assets & liabilities saved', 'success');
                    vmoLoadNetWorth();
                } catch(e) { vmoNotify('Save failed', 'error'); }
            }
        })(); } catch(__cfoErr) { console.warn('[VMO] CFO IIFE error (non-fatal):', __cfoErr); }

        // Lightweight diagnostics for payments hydration and units (cents)
        async function vmoTestPaymentsHydration(verbose = true) {
            const warn = [];
            const out = { ok: true, warnings: warn, data: null };
            try {
                const resp = await vmoPost('vmo_dashboard_stats', { scope: 'payments' });
                if (!resp || !resp.success || !resp.data) {
                    out.ok = false;
                    warn.push('payments scope returned no data');
                    if (verbose) console.warn('[VMO DIAG] payments scope failed', resp);
                    return out;
                }
                const d = resp.data; out.data = d;
                // Totals should be integers (cents) and >= 0
                ['day','week','month','year'].forEach(k => {
                    const v = Number(d[k]);
                    if (!Number.isFinite(v)) { out.ok = false; warn.push(`${k} is not a finite number`); }
                    else {
                        if (!Number.isInteger(v)) { out.ok = false; warn.push(`${k} is not integer cents (${v})`); }
                        if (v < 0) { out.ok = false; warn.push(`${k} is negative (${v})`); }
                    }
                });
                if (typeof d.mom_change !== 'number') { warn.push('mom_change missing or not a number'); }
                // Transactions array and amounts in cents
                const tx = Array.isArray(d.transactions) ? d.transactions : [];
                tx.forEach((t, i) => {
                    const a = Number(t.amount);
                    if (!Number.isInteger(a)) { out.ok = false; warn.push(`transaction[${i}].amount not integer cents (${t.amount})`); }
                    if (a < 0) { out.ok = false; warn.push(`transaction[${i}].amount negative (${a})`); }
                });
                // Soft sanity: KPI day should be >= sum of amounts for today in the listed subset
                try {
                    const today = new Date();
                    const y = today.getFullYear(), m = today.getMonth(), d0 = today.getDate();
                    const isToday = (iso) => {
                        if (!iso) return false;
                        const dt = new Date(iso);
                        return dt.getFullYear() === y && dt.getMonth() === m && dt.getDate() === d0;
                    };
                    const subset = tx.filter(t => isToday(t.date));
                    const subsetSum = subset.reduce((s, t) => s + (Number(t.amount) || 0), 0);
                    if (Number.isInteger(d.day) && subsetSum > d.day) {
                        out.ok = false; warn.push(`Listed transactions for today (${subset.length}) sum to ${subsetSum} > KPI day ${d.day}`);
                    }
                } catch(_e) {}
                if (verbose) {
                    if (out.ok) console.info('✅ [VMO DIAG] Payments hydration looks good (cents + KPIs).');
                    else console.warn('⚠️ [VMO DIAG] Payments issues detected:', warn);
                }
                return out;
            } catch (e) {
                if (verbose) console.error('[VMO DIAG] Unexpected error testing payments hydration', e);
                return { ok: false, error: String(e && e.message || e), warnings: warn };
            }
        }

        // Helper to exercise refresh pathways from console or buttons
        function vmoTriggerKPIRefresh() {
            try { if (typeof window.vmoReloadDashboardStats === 'function') window.vmoReloadDashboardStats(); } catch(_) {}
            try { document.dispatchEvent(new CustomEvent('vmo:refresh-kpis')); } catch(_) {}
            console.info('[VMO] KPI refresh triggered');
            return true;
        }

        // Expose diagnostics globally
        window.vmoTestPaymentsHydration = vmoTestPaymentsHydration;
        window.vmoTriggerKPIRefresh = vmoTriggerKPIRefresh;

        // Global reload hook + event listener so other modules can refresh the KPIs
        window.vmoReloadDashboardStats = function(){ loadDashboardKPIs(); };
        document.addEventListener('vmo:refresh-kpis', function(){ loadDashboardKPIs(); });

        // Kick things off on page load
        document.addEventListener('DOMContentLoaded', function(){
            try { loadDashboardKPIs(); } catch (_) {}
            try {
                if (window.location.search && /[?&]vmoDebug=1/.test(window.location.search)) {
                    console.info('[VMO DEBUG] Try these in console:');
                    console.info(' - vmoTestPaymentsHydration()  // checks cents + basic totals');
                    console.info(' - vmoTriggerKPIRefresh()      // exercises refresh hooks');
                }
            } catch(_) {}
        });

        // ==========================
        // Weekly briefing and actions (minimal wiring)
        // ==========================
        window.openWeeklyActions = async function() {
            try {
                const modal = document.getElementById('weeklyActionsModal');
                if (modal) modal.style.display = 'flex';
                // Populate insights/actions from dashboard stats
                const { success, data } = await vmoPost('vmo_dashboard_stats', {});
                const insights = success && data && data.weekly && Array.isArray(data.weekly.insights) ? data.weekly.insights : [];
                const actions = success && data && data.weekly && Array.isArray(data.weekly.actions) ? data.weekly.actions : [];
                const insList = document.getElementById('vmo-weekly-insights');
                if (insList) insList.innerHTML = insights.length ? insights.map(i => `<li>${String(i).replace(/</g,'&lt;')}</li>`).join('') : '<li style="color:var(--muted)">No insights yet</li>';
                const actList = document.getElementById('vmo-weekly-actions');
                if (actList) actList.innerHTML = actions.length ? actions.map(a => `<div class="task-item"><div class="task-text">${String(a.text||a).replace(/</g,'&lt;')}</div></div>`).join('') : '<div style="color:var(--muted)">No actions yet</div>';
            } catch (e) { console.warn('Weekly actions load failed', e); }
        };
        window.approveAllActions = async function() {
            try {
                const { success, message } = await vmoPost('vmo_approve_weekly_actions', {});
                if (!success) { showToast(message || 'Failed to approve actions', 'error'); return; }
                showToast('Approved. Tasks added for today.', 'success');
                loadDashboardKPIs();
            } catch (e) {
                showToast('Error approving actions', 'error');
            }
        };
        window.showWeeklyBriefing_simple = async function() {
            try {
                const modal = document.getElementById('weeklyBriefingModal');
                if (modal) modal.style.display = 'flex';
                const { success, data } = await vmoPost('vmo_get_weekly_briefing', {});
                const el = document.getElementById('weeklyBriefingContent');
                if (el) el.textContent = (success && data && data.narrative) ? String(data.narrative) : 'No briefing available yet.';
            } catch (e) { console.warn('Briefing load failed', e); }
        }
        // SEO Recommendations helpers
        function renderSEORecommendations(payload){
            const K = document.getElementById('vmo-seo-reco-keywords');
            const B = document.getElementById('vmo-seo-reco-blogs');
            const A = document.getElementById('vmo-seo-reco-actions');
            const listHtml = (arr, type)=>{
                const items = Array.isArray(arr)? arr : [];
                if (!items.length) return '<div style="color:var(--muted)">No suggestions</div>';
                return items.map((it, idx)=>{
                    const txt = (typeof it==='string') ? it : (it.text || it.topic || it.keyword || '—');
                    const approved = !!(it.approved);
                    const idAttr = `data-type="${type}" data-idx="${idx}"`;
                    return `<div class="nav-link" style="padding:8px; margin:6px 0;">
                        <div class="nav-text" contenteditable="false" ${idAttr}>${String(txt).replace(/</g,'&lt;')}</div>
                        <div style="display:flex;gap:6px;align-items:center;">
                            <button class="action-btn" ${idAttr} data-act="approve" ${approved?'disabled':''}>✔ Approve</button>
                            <button class="action-btn" ${idAttr} data-act="edit">✎ Edit</button>
                            <button class="action-btn" ${idAttr} data-act="save" style="display:none;">💾 Save</button>
                            <button class="action-btn" ${idAttr} data-act="execute" style="${(window.__seoAutoExecute? 'display:none;' : '')}">▶ Execute</button>
                        </div>
                    </div>`;
                }).join('');
            };
            if (K) K.innerHTML = listHtml(payload.keywords, 'keywords');
            if (B) B.innerHTML = listHtml(payload.blog_topics, 'blog_topics');
            if (A) A.innerHTML = listHtml((payload.actions || payload.technical_actions), 'actions');
            // Bind events
            const container = document.getElementById('vmo-seo-panel');
            if (!container) return;
            container.querySelectorAll('#vmo-seo-approve-all').forEach(btn=>{
                btn.onclick = async ()=>{
                    try{ const {success,message} = await ajaxPost('vmo_approve_seo_recommendation',{ scope:'all' }); if(!success){ notify(message||'Approve failed','error'); return; } notify('All approved','success'); loadSEOPanel(); }catch(e){ notify('Error: '+e.message,'error'); }
                };
            });
            container.querySelectorAll('#vmo-seo-regenerate').forEach(btn=>{
                btn.onclick = async ()=>{
                    try{ const {success,message} = await ajaxPost('vmo_regenerate_seo_recommendations'); if(!success){ notify(message||'Regenerate failed','error'); return; } notify('Suggestions updated','success'); loadSEOPanel(); }catch(e){ notify('Error: '+e.message,'error'); }
                };
            });
            var actBtns = container.querySelectorAll('[data-act]');
            Array.prototype.forEach.call(actBtns, function(btn){
                btn.addEventListener('click', async (e)=>{
                    const type = btn.getAttribute('data-type');
                    const idx = parseInt(btn.getAttribute('data-idx')||'0',10);
                    const act = btn.getAttribute('data-act');
                    var rowText = null; try { var row = btn.closest('.nav-link'); if (row) rowText = row.querySelector('.nav-text'); } catch(_){ rowText = null; }
                    if (!type || Number.isNaN(idx)) return;
                    if (act === 'approve'){
                        try{ const {success,message} = await ajaxPost('vmo_approve_seo_recommendation',{ type, index: idx }); if(!success){ notify(message||'Approve failed','error'); return; } notify(window.__seoAutoExecute? 'Approved — AI is executing now…' : 'Approved','success'); if (!window.__seoAutoExecute) { /* keep row, allow manual execute */ } else { loadSEOPanel(); } }catch(err){ notify('Error: '+err.message,'error'); }
                    } else if (act === 'edit'){
                        if (rowText){ rowText.setAttribute('contenteditable','true'); rowText.focus(); }
                        var saveBtn = null; try { if (btn.parentElement) saveBtn = btn.parentElement.querySelector('[data-act="save"]'); } catch(_){ saveBtn = null; } if (saveBtn) saveBtn.style.display='inline-block';
                        btn.style.display='none';
                    } else if (act === 'save'){
                        if (!rowText) return; const text = rowText.textContent || '';
                        try{ const {success,message} = await ajaxPost('vmo_update_seo_recommendation',{ type, index: idx, text }); if(!success){ notify(message||'Save failed','error'); return; } notify('Saved','success'); loadSEOPanel(); }catch(err){ notify('Error: '+err.message,'error'); }
                    } else if (act === 'execute'){
                        const text = rowText ? (rowText.textContent||'') : '';
                        try{ const {success,message} = await ajaxPost('vmo_execute_seo_recommendation',{ type, index: idx, text }); if(!success){ notify(message||'Execute failed','error'); return; } notify('Execution started','success'); loadSEOPanel(); }catch(err){ notify('Error: '+err.message,'error'); }
                    }
                });
            });
        }

        // Lightweight SEO Tasks list (for visibility of queued/executed actions)
        try { (function addSEOTasksCard(){
            const panel = document.getElementById('vmo-seo-panel'); if (!panel) return;
            const card = document.createElement('div'); card.className = 'vmo-card';
            card.innerHTML = '<h4>SEO Tasks</h4><div id="vmo-seo-tasks" style="max-height:200px; overflow:auto; font-size:12px; color:var(--ink)">Loading…</div>';
            panel.appendChild(card);
            const loadTasks = async ()=>{
                try{ const {success, data} = await ajaxPost('vmo_list_seo_tasks'); const el = document.getElementById('vmo-seo-tasks'); if (!el) return; if (!success || !data) { el.textContent = 'No tasks'; return; } const tasks = Array.isArray(data.tasks)? data.tasks: []; if (!tasks.length) { el.textContent = 'No tasks'; return; } el.innerHTML = tasks.map(t=>{ const s = (t.status||'').toUpperCase(); const dt = (t.updated_at||t.created_at||'').toString().replace('T',' '); const title = String(t.title||'Task').replace(/</g,'&lt;'); return `<div style="padding:6px 8px; border-bottom:1px solid rgba(255,255,255,.06)"><strong>${title}</strong> <span class="nav-badge">${s}</span><div style="color:var(--muted);">${dt}</div></div>`; }).join(''); }catch(_){ const el = document.getElementById('vmo-seo-tasks'); if (el) el.textContent = 'Failed to load'; }
            };
            // initial + periodic refresh every 30s for brief visibility
            loadTasks();
            setTimeout(loadTasks, 5000); // after initial panel data settles
            const iv = setInterval(loadTasks, 30000);
            // clear interval when navigating away from SEO tab to avoid leaks
            const obs = new MutationObserver(()=>{ var el = document.getElementById('seo'); var seoActive = false; try { seoActive = !!(el && el.classList && el.classList.contains('active')); } catch(_){ seoActive=false; } if (!seoActive) { clearInterval(iv); obs.disconnect(); } });
            var seoTabEl = document.getElementById('seo');
            if (seoTabEl) obs.observe(seoTabEl, { attributes: true });
        })(); } catch(__seoErr) { console.warn('[VMO] SEO Tasks IIFE error (non-fatal):', __seoErr); }

        // Promotion Command Center
        const VMO_PROMOTION_PLATFORMS = [
            'Instagram', 'Facebook', 'LinkedIn', 'TikTok', 'X', 'YouTube', 'Pinterest', 'Threads',
            'Snapchat', 'Reddit', 'Tumblr', 'Mastodon', 'Google Business Profile', 'WhatsApp Channels',
            'Telegram', 'Discord Community'
        ];

        function vmoPromotionDefaults() {
            return {
                goal: 'Help me create and distribute strategic social posts that attract the right followers, increase engagement, and promote my products effectively.',
                social_mode: 'ai',
                selected_platforms: ['Instagram', 'Facebook', 'LinkedIn', 'TikTok', 'YouTube'],
                auto_post: false,
                reply_mode: true,
                promo_budget: 6800,
                cadence: '5 posts per week',
                cta_destination: 'ai_recommend',
                manual_notes: '',
                manual_assets: [],
                latest_strategy: [],
                latest_posts: [],
                latest_engagement: []
            };
        }

        function vmoPromotionState() {
            if (!window.__vmoPromotionState) {
                window.__vmoPromotionState = {
                    settings: vmoPromotionDefaults(),
                    queue: [],
                    provider_matrix: [],
                    connected_accounts: [],
                    campaign: {}
                };
            }
            return window.__vmoPromotionState;
        }

        const VMO_PROMOTION_PREVIEW_ONLY = <?php echo $vmo_promotion_preview_only ? 'true' : 'false'; ?>;
        const VMO_PROMOTION_PREVIEW_MESSAGE = <?php echo wp_json_encode($vmo_promotion_preview_message); ?>;

        function vmoPromotionIsPreviewOnly() {
            return VMO_PROMOTION_PREVIEW_ONLY;
        }

        function vmoPromotionNotifyPreview() {
            if (typeof notify === 'function') {
                notify(VMO_PROMOTION_PREVIEW_MESSAGE, 'info');
            }
        }

        function vmoPromotionNormalizeSettings(raw) {
            const defaults = vmoPromotionDefaults();
            const merged = Object.assign({}, defaults, raw || {});
            merged.selected_platforms = Array.isArray(merged.selected_platforms) ? merged.selected_platforms : defaults.selected_platforms.slice();
            merged.manual_assets = Array.isArray(merged.manual_assets) ? merged.manual_assets : [];
            merged.latest_strategy = Array.isArray(merged.latest_strategy) ? merged.latest_strategy : [];
            merged.latest_posts = Array.isArray(merged.latest_posts) ? merged.latest_posts : [];
            merged.latest_engagement = Array.isArray(merged.latest_engagement) ? merged.latest_engagement : [];
            merged.goal = String(merged.goal || defaults.goal);
            merged.social_mode = merged.social_mode === 'manual' ? 'manual' : 'ai';
            merged.auto_post = !!merged.auto_post;
            merged.reply_mode = !!merged.reply_mode;
            merged.promo_budget = Number(merged.promo_budget || defaults.promo_budget) || 0;
            merged.cadence = String(merged.cadence || defaults.cadence);
            merged.cta_destination = String(merged.cta_destination || defaults.cta_destination);
            merged.manual_notes = String(merged.manual_notes || '');
            return merged;
        }

        function vmoPromotionFormatCurrency(value) {
            const num = Number(value || 0);
            return '$' + num.toLocaleString();
        }

        function vmoPromotionEscape(value) {
            return String(value || '').replace(/[&<>"]/g, function(ch) {
                return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' })[ch] || ch;
            });
        }

        function vmoPromotionRenderMetricCards(settings, tokenBalance) {
            const capability = document.getElementById('vmo-promo-stat-capability');
            const platforms = document.getElementById('vmo-promo-stat-platforms');
            const budget = document.getElementById('vmo-promo-stat-budget');
            const tokens = document.getElementById('vmo-promo-stat-tokens');
            const selectedCount = document.getElementById('vmo-promo-selected-count');
            if (capability) capability.textContent = vmoPromotionIsPreviewOnly() ? 'Coming Soon' : 'Available';
            if (platforms) platforms.textContent = String((settings.selected_platforms || []).length);
            if (budget) budget.textContent = vmoPromotionFormatCurrency(settings.promo_budget);
            if (tokens) tokens.textContent = Number(tokenBalance || 0).toLocaleString();
            if (selectedCount) selectedCount.textContent = String((settings.selected_platforms || []).length);
        }

        function vmoPromotionRenderStrategy(items) {
            const el = document.getElementById('vmo-promo-strategy-output');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">No strategy generated yet.</div>';
                return;
            }
            el.innerHTML = items.map(function(item) {
                const title = vmoPromotionEscape(item.title || 'Strategy');
                const text = vmoPromotionEscape(item.text || item.summary || '');
                return '<div class="vmo-promo-result-item"><strong>' + title + '</strong><p>' + text + '</p></div>';
            }).join('');
        }

        function vmoPromotionRenderPosts(items) {
            const el = document.getElementById('vmo-promo-post-output');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">No post drafts generated yet.</div>';
                return;
            }
            el.innerHTML = items.map(function(item, idx) {
                const title = vmoPromotionEscape(item.title || ('Draft ' + (idx + 1)));
                const caption = vmoPromotionEscape(item.caption || item.text || '');
                const cta = vmoPromotionEscape(item.cta || '');
                const hint = vmoPromotionEscape(item.asset_hint || '');
                return '<div class="vmo-promo-result-item">'
                    + '<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:10px;">'
                    + '<strong>' + title + '</strong>'
                    + '<button class="action-btn compact" type="button" onclick="vmoPromotionQueueGeneratedPost(' + idx + ')">➕ Queue</button>'
                    + '</div>'
                    + '<p>' + caption + '</p>'
                    + (cta ? '<p><strong>CTA:</strong> ' + cta + '</p>' : '')
                    + (hint ? '<p><strong>Media hint:</strong> ' + hint + '</p>' : '')
                    + '</div>';
            }).join('');
        }

        function vmoPromotionRenderEngagement(items) {
            const el = document.getElementById('vmo-promo-engagement-output');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">No engagement guidance generated yet.</div>';
                return;
            }
            el.innerHTML = items.map(function(item) {
                const title = vmoPromotionEscape(item.title || 'Suggestion');
                const text = vmoPromotionEscape(item.text || item.summary || '');
                return '<div class="vmo-promo-result-item"><strong>' + title + '</strong><p>' + text + '</p></div>';
            }).join('');
        }

        function vmoPromotionRenderAssets(items) {
            const el = document.getElementById('vmo-promo-assets');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">No promotion assets uploaded yet.</div>';
                return;
            }
            el.innerHTML = items.map(function(item, idx) {
                const name = vmoPromotionEscape(item.name || item.file_name || ('Asset ' + (idx + 1)));
                const kind = vmoPromotionEscape(item.kind || 'asset');
                const url = item.url ? '<a href="' + vmoPromotionEscape(item.url) + '" target="_blank" rel="noopener noreferrer" style="color:var(--cyan-soft);">Open</a>' : '';
                return '<div class="vmo-promo-asset-item">'
                    + '<div style="display:flex; align-items:center; justify-content:space-between; gap:10px;">'
                    + '<strong>' + name + '</strong>'
                    + '<div style="display:flex; gap:8px; align-items:center;">'
                    + '<span class="nav-badge">' + kind + '</span>'
                    + (url ? url : '')
                    + '<button class="action-btn compact" type="button" onclick="vmoPromotionRemoveAsset(' + idx + ')">✖</button>'
                    + '</div></div></div>';
            }).join('');
        }

        function vmoPromotionRenderQueue(queue) {
            const el = document.getElementById('vmo-promo-queue');
            if (!el) return;
            if (!Array.isArray(queue) || !queue.length) {
                el.innerHTML = '<div class="vmo-promo-empty">No posts in the queue yet.</div>';
                return;
            }
            el.innerHTML = queue.map(function(item, idx) {
                const title = vmoPromotionEscape(item.title || ('Queued Post ' + (idx + 1)));
                const status = vmoPromotionEscape(item.status || 'Draft');
                const time = vmoPromotionEscape(item.time || '');
                return '<div class="vmo-promo-queue-item">'
                    + '<div style="display:flex; align-items:center; justify-content:space-between; gap:10px;">'
                    + '<div><strong>' + title + '</strong><p>' + time + '</p></div>'
                    + '<div style="display:flex; gap:8px; align-items:center;">'
                    + '<span class="nav-badge">' + status + '</span>'
                    + '<button class="action-btn compact" type="button" onclick="vmoPromotionRemoveQueueItem(' + idx + ')">✖</button>'
                    + '</div></div></div>';
            }).join('');
        }

        function vmoPromotionRenderPlatforms(selected) {
            const el = document.getElementById('vmo-promo-platform-list');
            if (!el) return;
            const selectedSet = new Set(Array.isArray(selected) ? selected : []);
            el.innerHTML = VMO_PROMOTION_PLATFORMS.map(function(platform) {
                const active = selectedSet.has(platform);
                return '<button class="vmo-promo-chip' + (active ? ' active' : '') + '" type="button" onclick="vmoPromotionTogglePlatform(' + JSON.stringify(platform) + ')">' + vmoPromotionEscape(platform) + '</button>';
            }).join('');
        }

        function vmoPromotionRenderConnectedAccounts(items) {
            const el = document.getElementById('vmo-promo-connected-accounts');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">No provider account connections have been recorded yet.</div>';
                return;
            }
            el.innerHTML = items.map(function(item) {
                const label = vmoPromotionEscape(item.platform_label || item.platform_key || 'Platform');
                const name = vmoPromotionEscape(item.display_name || item.external_account_id || 'Connected account');
                const auth = vmoPromotionEscape(item.auth_status || 'unknown');
                const modes = [
                    item.publish_enabled ? 'publish' : '',
                    item.reply_enabled ? 'replies' : '',
                    item.metrics_enabled ? 'metrics' : ''
                ].filter(Boolean).join(' / ') || 'limited';
                return '<div class="vmo-promo-result-item">'
                    + '<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:10px;">'
                    + '<strong>' + label + '</strong>'
                    + '<span class="nav-badge">' + auth + '</span>'
                    + '</div>'
                    + '<p>' + name + '</p>'
                    + '<p><strong>Enabled:</strong> ' + vmoPromotionEscape(modes) + '</p>'
                    + '</div>';
            }).join('');
        }

        function vmoPromotionRenderProviders(items) {
            const el = document.getElementById('vmo-promo-provider-matrix');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">Provider readiness data unavailable.</div>';
                return;
            }
            function humanizeProviderField(name) {
                return vmoPromotionEscape(String(name || '').replace(/_/g, ' ').replace(/\b\w/g, function(chr) { return chr.toUpperCase(); }));
            }
            el.innerHTML = items.map(function(item) {
                const label = vmoPromotionEscape(item.label || item.platform_key || 'Provider');
                const status = vmoPromotionEscape(item.status_label || 'Unknown');
                const category = vmoPromotionEscape(item.category || 'social');
                const wave = Number(item.rollout_wave || 0);
                const support = item.effective_support || {};
                const requirements = item.capabilities || {};
                const config = item.config || {};
                const missing = Array.isArray(config.missing_required_fields) ? config.missing_required_fields : [];
                const missingLabel = missing.map(humanizeProviderField).join(', ');
                const callbackUrl = config.callback_url ? vmoPromotionEscape(config.callback_url) : '';
                const webhookUrl = config.webhook_url ? vmoPromotionEscape(config.webhook_url) : '';
                return '<div class="vmo-promo-result-item">'
                    + '<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:10px; flex-wrap:wrap;">'
                    + '<div>'
                    + '<strong>' + label + '</strong>'
                    + '<p>Category: ' + category + ' | Wave ' + wave + '</p>'
                    + '</div>'
                    + '<span class="nav-badge">' + status + '</span>'
                    + '</div>'
                    + '<p><strong>Draft Generation:</strong> ' + vmoPromotionEscape(support.draft_generation || 'Yes')
                    + ' | <strong>Direct Publish:</strong> ' + vmoPromotionEscape(support.direct_publish || 'No')
                    + ' | <strong>Media Upload:</strong> ' + vmoPromotionEscape(support.media_upload || 'No')
                    + ' | <strong>Ad Management:</strong> ' + vmoPromotionEscape(support.ad_management || 'No')
                    + ' | <strong>Replies:</strong> ' + vmoPromotionEscape(support.replies || 'No')
                    + ' | <strong>Metrics:</strong> ' + vmoPromotionEscape(support.metrics || 'No')
                    + '</p>'
                    + '<p><strong>Connector Enabled:</strong> ' + (config.connector_enabled ? 'Yes' : 'No')
                    + ' | <strong>Credentials Ready:</strong> ' + (config.credentials_ready ? 'Yes' : 'No')
                    + ' | <strong>App Review:</strong> ' + vmoPromotionEscape(config.app_review_status || 'admin_setup_required')
                    + ' | <strong>Marketing API:</strong> ' + vmoPromotionEscape(config.marketing_api_status || 'not_requested')
                    + ' | <strong>Domain Verification:</strong> ' + vmoPromotionEscape(config.domain_verification_status || 'unknown')
                    + '</p>'
                    + '<p><strong>Webhooks:</strong> ' + vmoPromotionEscape(support.webhooks || 'No')
                    + ' | <strong>Requires App Review:</strong> ' + (requirements.app_review_required ? 'Yes' : 'No')
                    + ' | <strong>Requires Domain Verification:</strong> ' + (requirements.domain_verification_required ? 'Yes' : 'No')
                    + ' | <strong>Connected Accounts:</strong> ' + String(item.connected_accounts || 0)
                    + '</p>'
                    + (config.ad_account_id ? '<p><strong>Ad Account ID:</strong> ' + vmoPromotionEscape(config.ad_account_id) + '</p>' : '')
                    + (missing.length ? '<p><strong>Missing Fields:</strong> ' + missingLabel + '</p>' : '')
                    + (callbackUrl ? '<p><strong>Callback URL:</strong> <code>' + callbackUrl + '</code></p>' : '')
                    + (webhookUrl ? '<p><strong>Webhook URL:</strong> <code>' + webhookUrl + '</code></p>' : '')
                    + '<p><a href="<?php echo esc_url(admin_url('admin.php?page=vmo-ai-settings')); ?>">Open provider settings</a></p>'
                    + '</div>';
            }).join('');
        }

        function vmoPromotionRenderMarketingProviders(items) {
            const el = document.getElementById('vmo-promo-marketing-provider-matrix');
            if (!el) return;
            if (!Array.isArray(items) || !items.length) {
                el.innerHTML = '<div class="vmo-promo-empty">Advertising readiness data unavailable.</div>';
                return;
            }
            el.innerHTML = items.map(function(item) {
                const label = vmoPromotionEscape(item.label || item.platform_key || 'Provider');
                const status = vmoPromotionEscape(item.status_label || 'Unknown');
                const support = item.effective_support || {};
                const config = item.config || {};
                return '<div class="vmo-promo-result-item">'
                    + '<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:10px;">'
                    + '<strong>' + label + '</strong>'
                    + '<span class="nav-badge">' + status + '</span>'
                    + '</div>'
                    + '<p><strong>Ad Management:</strong> ' + vmoPromotionEscape(support.ad_management || 'No')
                    + ' | <strong>Marketing API:</strong> ' + vmoPromotionEscape(config.marketing_api_status || 'not_requested')
                    + ' | <strong>Ads Enabled:</strong> ' + (config.ads_enabled ? 'Yes' : 'No')
                    + '</p>'
                    + (config.ad_account_id ? '<p><strong>Ad Account ID:</strong> ' + vmoPromotionEscape(config.ad_account_id) + '</p>' : '')
                    + '</div>';
            }).join('');
        }

        function vmoPromotionSyncDom(settings, tokenBalance) {
            const goal = document.getElementById('vmo-promo-goal');
            const budget = document.getElementById('vmo-promo-budget');
            const cadence = document.getElementById('vmo-promo-cadence');
            const autoPost = document.getElementById('vmo-promo-auto-post');
            const replyMode = document.getElementById('vmo-promo-reply-mode');
            const manualNotes = document.getElementById('vmo-promo-manual-notes');
            const modeInput = document.getElementById('vmo-promo-social-mode');
            if (goal) goal.value = settings.goal;
            if (budget) budget.value = String(settings.promo_budget || 0);
            if (cadence) cadence.value = settings.cadence || '';
            if (autoPost) autoPost.checked = !!settings.auto_post;
            if (replyMode) replyMode.checked = !!settings.reply_mode;
            if (manualNotes) manualNotes.value = settings.manual_notes || '';
            if (modeInput) modeInput.value = settings.social_mode || 'ai';
            document.querySelectorAll('input[name="vmo-promo-cta-destination"]').forEach(function(radio) {
                radio.checked = (radio.value === settings.cta_destination);
            });
            vmoPromotionSwitchMode(settings.social_mode || 'ai', true);
            vmoPromotionRenderMetricCards(settings, tokenBalance);
            vmoPromotionRenderPlatforms(settings.selected_platforms || []);
            vmoPromotionRenderStrategy(settings.latest_strategy || []);
            vmoPromotionRenderPosts(settings.latest_posts || []);
            vmoPromotionRenderEngagement(settings.latest_engagement || []);
            vmoPromotionRenderAssets(settings.manual_assets || []);
            vmoPromotionRenderQueue(vmoPromotionState().queue || []);
            vmoPromotionRenderConnectedAccounts(vmoPromotionState().connected_accounts || []);
            vmoPromotionRenderProviders(vmoPromotionState().provider_matrix || []);
            vmoPromotionRenderMarketingProviders(vmoPromotionState().provider_matrix || []);
        }

        function vmoPromotionCollectSettings() {
            const state = vmoPromotionState();
            const goal = document.getElementById('vmo-promo-goal');
            const budget = document.getElementById('vmo-promo-budget');
            const cadence = document.getElementById('vmo-promo-cadence');
            const autoPost = document.getElementById('vmo-promo-auto-post');
            const replyMode = document.getElementById('vmo-promo-reply-mode');
            const manualNotes = document.getElementById('vmo-promo-manual-notes');
            const modeInput = document.getElementById('vmo-promo-social-mode');
            const selectedCta = document.querySelector('input[name="vmo-promo-cta-destination"]:checked');
            const next = Object.assign({}, state.settings || vmoPromotionDefaults(), {
                goal: goal ? goal.value : '',
                promo_budget: budget ? Number(budget.value || 0) : 0,
                cadence: cadence ? cadence.value : '',
                auto_post: !!(autoPost && autoPost.checked),
                reply_mode: !!(replyMode && replyMode.checked),
                manual_notes: manualNotes ? manualNotes.value : '',
                social_mode: modeInput ? modeInput.value : 'ai',
                cta_destination: selectedCta ? selectedCta.value : 'ai_recommend'
            });
            return vmoPromotionNormalizeSettings(next);
        }

        function vmoBindPromotionHandlers() {
            if (window.__vmoPromotionBound) return;
            window.__vmoPromotionBound = true;

            const saveBtn = document.getElementById('vmo-promo-save-btn');
            const addQueueBtn = document.getElementById('vmo-promo-add-queue');
            const buildPlanBtn = document.getElementById('vmo-promo-build-plan-btn');
            if (saveBtn) saveBtn.addEventListener('click', function() { vmoPromotionSaveSettings(); });
            if (addQueueBtn) addQueueBtn.addEventListener('click', function() { vmoPromotionAddQueueItem(); });
            if (buildPlanBtn) buildPlanBtn.addEventListener('click', function() { vmoPromotionGenerateStrategy(); });

            [
                ['images', 'vmo-promo-upload-images'],
                ['videos', 'vmo-promo-upload-videos'],
                ['copy', 'vmo-promo-upload-copy'],
                ['voice', 'vmo-promo-upload-voice']
            ].forEach(function(pair) {
                const input = document.getElementById(pair[1]);
                if (!input) return;
                input.addEventListener('change', function() {
                    vmoPromotionUploadAsset(pair[0], input);
                });
            });
        }

        window.vmoPromotionSwitchSubtab = function(name) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const social = document.getElementById('vmo-promo-subtab-social');
            const marketing = document.getElementById('vmo-promo-subtab-marketing');
            if (social) social.classList.toggle('active', name === 'social');
            if (marketing) marketing.classList.remove('active');
        };

        window.vmoPromotionSwitchMode = function(mode, silent) {
            if (!silent && vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const normalized = mode === 'manual' ? 'manual' : 'ai';
            const modeInput = document.getElementById('vmo-promo-social-mode');
            const aiWrap = document.getElementById('vmo-promo-ai-mode');
            const manualWrap = document.getElementById('vmo-promo-manual-mode');
            const aiBtn = document.getElementById('vmo-promo-mode-ai');
            const manualBtn = document.getElementById('vmo-promo-mode-manual');
            const badge = document.getElementById('vmo-promo-mode-badge');
            if (modeInput) modeInput.value = normalized;
            if (aiWrap) aiWrap.style.display = normalized === 'ai' ? 'block' : 'none';
            if (manualWrap) manualWrap.style.display = normalized === 'manual' ? 'block' : 'none';
            if (aiBtn) aiBtn.classList.toggle('primary', normalized === 'ai');
            if (manualBtn) manualBtn.classList.toggle('primary', normalized === 'manual');
            if (badge) badge.textContent = vmoPromotionIsPreviewOnly() ? 'Preview' : (normalized === 'ai' ? 'AI' : 'Manual');
            if (!silent) {
                const state = vmoPromotionState();
                state.settings = vmoPromotionCollectSettings();
            }
        };

        window.vmoPromotionTogglePlatform = function(platform) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const state = vmoPromotionState();
            const current = new Set(state.settings.selected_platforms || []);
            if (current.has(platform)) current.delete(platform); else current.add(platform);
            state.settings.selected_platforms = Array.from(current);
            vmoPromotionRenderPlatforms(state.settings.selected_platforms);
            vmoPromotionRenderMetricCards(state.settings, state.token_balance || 0);
        };

        window.vmoPromotionSaveSettings = async function() {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const state = vmoPromotionState();
            state.settings = vmoPromotionCollectSettings();
            try {
                const res = await ajaxPost('vmo_save_promotion_settings', {
                    settings: JSON.stringify(state.settings),
                    queue: JSON.stringify(state.queue || [])
                });
                if (!res || !res.success) {
                    notify((res && res.message) || 'Unable to save promotion settings', 'error');
                    return;
                }
                state.settings = vmoPromotionNormalizeSettings((res.data && res.data.settings) || state.settings);
                state.queue = Array.isArray(res.data && res.data.queue) ? res.data.queue : (state.queue || []);
                state.token_balance = Number((res.data && res.data.token_balance) || state.token_balance || 0);
                state.provider_matrix = Array.isArray(res.data && res.data.provider_matrix) ? res.data.provider_matrix : (state.provider_matrix || []);
                state.connected_accounts = Array.isArray(res.data && res.data.connected_accounts) ? res.data.connected_accounts : (state.connected_accounts || []);
                state.campaign = (res.data && res.data.campaign) || state.campaign || {};
                vmoPromotionSyncDom(state.settings, state.token_balance);
                notify('Promotion settings saved', 'success');
            } catch (e) {
                notify('Unable to save promotion settings: ' + e.message, 'error');
            }
        };

        window.vmoPromotionAddQueueItem = async function() {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const titleEl = document.getElementById('vmo-promo-queue-title');
            const statusEl = document.getElementById('vmo-promo-queue-status');
            const timeEl = document.getElementById('vmo-promo-queue-time');
            const title = titleEl ? String(titleEl.value || '').trim() : '';
            const status = statusEl ? String(statusEl.value || 'Draft') : 'Draft';
            const time = timeEl ? String(timeEl.value || '').trim() : '';
            if (!title) {
                notify('Enter a queue item title first', 'warning');
                return;
            }
            const state = vmoPromotionState();
            state.queue = Array.isArray(state.queue) ? state.queue : [];
            state.queue.unshift({ id: 'promo_queue_' + Date.now(), title: title, status: status, time: time || 'Pending schedule' });
            if (titleEl) titleEl.value = '';
            if (timeEl) timeEl.value = '';
            vmoPromotionRenderQueue(state.queue);
            await vmoPromotionSaveSettings();
        };

        window.vmoPromotionRemoveQueueItem = async function(index) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const state = vmoPromotionState();
            state.queue = (state.queue || []).filter(function(_, idx) { return idx !== index; });
            vmoPromotionRenderQueue(state.queue);
            await vmoPromotionSaveSettings();
        };

        window.vmoPromotionQueueGeneratedPost = async function(index) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const state = vmoPromotionState();
            const draft = (state.settings.latest_posts || [])[index];
            if (!draft) {
                notify('Draft not found', 'warning');
                return;
            }
            state.queue = Array.isArray(state.queue) ? state.queue : [];
            state.queue.unshift({
                id: 'promo_queue_' + Date.now(),
                title: draft.title || ('Generated post ' + (index + 1)),
                status: 'Awaiting Approval',
                time: 'Ready to schedule'
            });
            vmoPromotionRenderQueue(state.queue);
            notify('Draft added to queue', 'success');
            await vmoPromotionSaveSettings();
        };

        window.vmoPromotionRemoveAsset = async function(index) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return;
            }
            const state = vmoPromotionState();
            state.settings.manual_assets = (state.settings.manual_assets || []).filter(function(_, idx) { return idx !== index; });
            vmoPromotionRenderAssets(state.settings.manual_assets);
            await vmoPromotionSaveSettings();
        };

        async function vmoPromotionRunGenerator(action, payload, pendingLabel) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                return null;
            }
            const state = vmoPromotionState();
            state.settings = vmoPromotionCollectSettings();
            try {
                if (pendingLabel) notify(pendingLabel, 'info');
                const res = await ajaxPost(action, Object.assign({
                    settings: JSON.stringify(state.settings),
                    queue: JSON.stringify(state.queue || [])
                }, payload || {}));
                if (!res || !res.success) {
                    notify((res && res.message) || 'Generation failed', 'error');
                    return null;
                }
                state.settings = vmoPromotionNormalizeSettings((res.data && res.data.settings) || state.settings);
                state.queue = Array.isArray(res.data && res.data.queue) ? res.data.queue : (state.queue || []);
                state.token_balance = Number((res.data && res.data.token_balance) || state.token_balance || 0);
                state.provider_matrix = Array.isArray(res.data && res.data.provider_matrix) ? res.data.provider_matrix : (state.provider_matrix || []);
                state.connected_accounts = Array.isArray(res.data && res.data.connected_accounts) ? res.data.connected_accounts : (state.connected_accounts || []);
                state.campaign = (res.data && res.data.campaign) || state.campaign || {};
                vmoPromotionSyncDom(state.settings, state.token_balance);
                return res.data || null;
            } catch (e) {
                notify('Generation failed: ' + e.message, 'error');
                return null;
            }
        }

        window.vmoPromotionGenerateStrategy = async function() {
            const data = await vmoPromotionRunGenerator('vmo_generate_promotion_strategy', {}, 'Building social strategy…');
            if (data) notify('Social strategy ready', 'success');
        };

        window.vmoPromotionGeneratePosts = async function(postType) {
            const data = await vmoPromotionRunGenerator('vmo_generate_promotion_posts', { post_type: postType || 'general' }, 'Generating social post drafts…');
            if (data) notify('Post drafts ready', 'success');
        };

        window.vmoPromotionRefinePosts = async function(instruction) {
            const state = vmoPromotionState();
            if (!Array.isArray(state.settings.latest_posts) || !state.settings.latest_posts.length) {
                notify('Generate post drafts first, then refine them.', 'info');
                return;
            }
            const data = await vmoPromotionRunGenerator('vmo_refine_promotion_posts', { instruction: instruction || '' }, 'Refining current post drafts…');
            if (data) notify('Post drafts refined', 'success');
        };

        window.vmoPromotionGenerateEngagement = async function(kind) {
            const data = await vmoPromotionRunGenerator('vmo_generate_promotion_engagement', { engagement_type: kind || 'questions' }, 'Generating engagement guidance…');
            if (data) notify('Engagement guidance ready', 'success');
        };

        async function vmoPromotionUploadAsset(kind, input) {
            if (vmoPromotionIsPreviewOnly()) {
                vmoPromotionNotifyPreview();
                if (input) input.value = '';
                return;
            }
            if (!input || !input.files || !input.files.length) return;
            const file = input.files[0];
            const form = new FormData();
            form.append('action', 'vmo_website_chat');
            form.append('kind', 'sd_ajax');
            form.append('ajax_action', 'vmo_upload_promotion_asset');
            form.append('security', (typeof VMO_NONCE_BUILDER !== 'undefined' ? VMO_NONCE_BUILDER : VMO_NONCE));
            form.append('nonce', (typeof VMO_NONCE_ADMIN !== 'undefined' ? VMO_NONCE_ADMIN : VMO_NONCE));
            form.append('asset_kind', kind || 'asset');
            form.append('file', file);
            try {
                notify('Uploading promotion asset…', 'info');
                const response = await fetch(VMO_AJAX, { method: 'POST', body: form });
                const json = await response.json();
                if (!json || !json.success) {
                    notify((json && json.message) || 'Upload failed', 'error');
                    input.value = '';
                    return;
                }
                const state = vmoPromotionState();
                state.settings = vmoPromotionNormalizeSettings((json.data && json.data.settings) || state.settings);
                state.queue = Array.isArray(json.data && json.data.queue) ? json.data.queue : (state.queue || []);
                state.token_balance = Number((json.data && json.data.token_balance) || state.token_balance || 0);
                state.provider_matrix = Array.isArray(json.data && json.data.provider_matrix) ? json.data.provider_matrix : (state.provider_matrix || []);
                state.connected_accounts = Array.isArray(json.data && json.data.connected_accounts) ? json.data.connected_accounts : (state.connected_accounts || []);
                state.campaign = (json.data && json.data.campaign) || state.campaign || {};
                vmoPromotionSyncDom(state.settings, state.token_balance);
                notify('Promotion asset uploaded', 'success');
            } catch (e) {
                notify('Upload failed: ' + e.message, 'error');
            } finally {
                input.value = '';
            }
        }

        window.loadPromotionPanel = async function(force) {
            vmoBindPromotionHandlers();
            const state = vmoPromotionState();
            if (!force && state.loaded) {
                vmoPromotionSyncDom(state.settings, state.token_balance || 0);
                return;
            }
            try {
                const res = await ajaxPost('vmo_get_promotion_settings', {});
                if (!res || !res.success || !res.data) {
                    notify((res && res.message) || 'Unable to load promotion settings', 'error');
                    return;
                }
                state.settings = vmoPromotionNormalizeSettings(res.data.settings || {});
                state.queue = Array.isArray(res.data.queue) ? res.data.queue : [];
                state.token_balance = Number(res.data.token_balance || 0);
                state.provider_matrix = Array.isArray(res.data.provider_matrix) ? res.data.provider_matrix : [];
                state.connected_accounts = Array.isArray(res.data.connected_accounts) ? res.data.connected_accounts : [];
                state.campaign = res.data.campaign || {};
                state.loaded = true;
                vmoPromotionSwitchSubtab('social');
                vmoPromotionSyncDom(state.settings, state.token_balance);
            } catch (e) {
                notify('Unable to load promotion settings: ' + e.message, 'error');
            }
        };

        // Email Marketing: in-page panels (no external navigation)
        // ✅ ENHANCED v9.0.2: Show configured email accounts from consultation
        async function loadEmailPanel(){
            const panel = document.getElementById('vmo-email-panel'); if(!panel) return;
            panel.innerHTML = `
                <div class="vmo-card">
                    <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
                        <h4 style="margin:0;">📧 Configured Email Accounts</h4>
                        <button id="vmo-email-add-account" class="action-btn primary" title="Add email account">✚ Add Account</button>
                    </div>
                    <div id="vmo-email-accounts-list" style="margin-top:8px;font-size:13px;">Loading accounts...</div>
                </div>
                <div class="vmo-card">
                    <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
                        <h4 style="margin:0;">Email Performance (Last 30 days)</h4>
                        <div style="display:flex;gap:8px;align-items:center;">
                            <button id="vmo-email-new-campaign" class="action-btn primary">✚ New Campaign</button>
                            <button id="vmo-email-refresh" class="action-btn">Refresh</button>
                        </div>
                    </div>
                    <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-top:8px;">
                        <div class="vmo-card" style="background:rgba(255,255,255,.02)">
                            <h4>Sends</h4>
                            <div id="vmo-email-metric-sent" style="font-size:22px;color:var(--cyan-soft)">—</div>
                            <svg id="vmo-email-sent-spark" width="100%" height="28"></svg>
                        </div>
                        <div class="vmo-card" style="background:rgba(255,255,255,.02)">
                            <h4>Opens</h4>
                            <div id="vmo-email-metric-open" style="font-size:22px;color:var(--cyan-soft)">—</div>
                            <svg id="vmo-email-open-spark" width="100%" height="28"></svg>
                        </div>
                        <div class="vmo-card" style="background:rgba(255,255,255,.02)">
                            <h4>Clicks</h4>
                            <div id="vmo-email-metric-click" style="font-size:22px;color:var(--cyan-soft)">—</div>
                            <svg id="vmo-email-click-spark" width="100%" height="28"></svg>
                        </div>
                    </div>
                </div>
                <div class="vmo-card">
                    <h4 style="margin:0 0 6px;">Recent Campaigns</h4>
                    <div id="vmo-email-campaigns-list" style="max-height:220px;overflow:auto;font-size:12px;color:var(--ink)">Loading…</div>
                    <div style="margin-top:8px;"><button id="vmo-email-show-more" class="action-btn">Show more</button></div>
                </div>`;
            // Bind actions
            const newBtn = document.getElementById('vmo-email-new-campaign'); if (newBtn) newBtn.onclick = function(){ if(window.VMOBusinessDashboard && VMOBusinessDashboard.createEmailCampaign){ VMOBusinessDashboard.createEmailCampaign(); } };
            const refreshBtn = document.getElementById('vmo-email-refresh'); if (refreshBtn) refreshBtn.onclick = loadEmailPanel;
            const addAccountBtn = document.getElementById('vmo-email-add-account'); if (addAccountBtn) addAccountBtn.onclick = function(){
                // Try consultation chat first, then fall back to standalone email setup modal
                if(window.vmoConsultationChat && typeof vmoConsultationChat.showEmailSetupModal === 'function'){
                    vmoConsultationChat.showEmailSetupModal('info');
                } else if (window.VMOIntelligentConsultation) {
                    // Try to instantiate or call the class method directly
                    try { new VMOIntelligentConsultation().showEmailSetupModal('info'); } catch(e) {
                        alert('To add a new email account, please open the AI Consultation chat and ask Jarvis to set up a new email address.');
                    }
                } else {
                    alert('To add a new email account, please open the AI Consultation chat and ask Jarvis to help you set up a new email address.');
                }
            };
            
            // ✅ Load configured email accounts
            await loadEmailAccounts();
            
            // Load data
            try{
                const {success, data} = await ajaxPost('vmo_get_email_overview');
                const set = (id,val)=>{ const el=document.getElementById(id); if(el) el.textContent = String(val); };
                if (success && data){
                    const sent = parseInt(data.sent_30||0,10)||0;
                    const opened = parseInt(data.opened_30||0,10)||0;
                    const clicked = parseInt(data.clicked_30||0,10)||0;
                    set('vmo-email-metric-sent', sent);
                    set('vmo-email-metric-open', opened);
                    set('vmo-email-metric-click', clicked);
                    try{ drawSpark('vmo-email-sent-spark', Array.isArray(data.sent_series)? data.sent_series : [0,0]); }catch(_){ }
                    try{ drawSpark('vmo-email-open-spark', Array.isArray(data.open_series)? data.open_series : [0,0]); }catch(_){ }
                    try{ drawSpark('vmo-email-click-spark', Array.isArray(data.click_series)? data.click_series : [0,0]); }catch(_){ }
                    const list = Array.isArray(data.campaigns)? data.campaigns : [];
                    renderCampaignsList(list);
                    // Update drafts badge if provided
                    const badge = document.getElementById('vmo-email-drafts-badge'); if (badge) badge.textContent = (data.drafts_count!=null) ? String(data.drafts_count) : (list.filter(c=>c.status==='draft').length || '—');
                } else {
                    renderCampaignsList([]);
                }
            }catch(e){ renderCampaignsList([]); }

            function renderCampaignsList(items){
                const box = document.getElementById('vmo-email-campaigns-list'); if (!box) return;
                if (!items.length){ box.textContent = 'No campaigns yet'; return; }
                const rows = items.slice(0,10).map(c=>{
                    const title = (c.title||'Campaign').toString().replace(/</g,'&lt;');
                    const when = (c.created_at||c.date||'').toString().replace('T',' ');
                    const stat = (c.status||'draft').toString();
                    const sent = (c.sent||0), open = (c.open||0), click = (c.click||0);
                    return `<div class="nav-link" style="padding:6px 8px;">
                        <div class="nav-text"><strong>${title}</strong> <span class="nav-badge">${stat.toUpperCase()}</span><div style="color:var(--muted);font-size:11px">${when}</div></div>
                        <div style="display:flex;gap:8px;align-items:center;">
                            <div class="nav-badge">✉️ ${sent}</div>
                            <div class="nav-badge">👁 ${open}</div>
                            <div class="nav-badge">🖱 ${click}</div>
                        </div>
                    </div>`;
                }).join('');
                box.innerHTML = rows;
                const more = document.getElementById('vmo-email-show-more'); if (more) {
                    const total = items.length;
                    more.style.display = (total > 10) ? 'inline-block' : 'none';
                    more.onclick = ()=>{
                        const extra = items.slice(10).map(c=>{
                            const title = (c.title||'Campaign').toString().replace(/</g,'&lt;');
                            const when = (c.created_at||c.date||'').toString().replace('T',' ');
                            const stat = (c.status||'draft').toString();
                            const sent = (c.sent||0), open = (c.open||0), click = (c.click||0);
                            return `<div class=\"nav-link\" style=\"padding:6px 8px;\">\n`+
                                   `<div class=\"nav-text\"><strong>${title}</strong> <span class=\"nav-badge\">${stat.toUpperCase()}</span><div style=\"color:var(--muted);font-size:11px\">${when}</div></div>\n`+
                                   `<div style=\"display:flex;gap:8px;align-items:center;\">`+
                                   `<div class=\"nav-badge\">✉️ ${sent}</div>`+
                                   `<div class=\"nav-badge\">👁 ${open}</div>`+
                                   `<div class=\"nav-badge\">🖱 ${click}</div>`+
                                   `</div></div>`;
                        }).join('');
                        box.insertAdjacentHTML('beforeend', extra);
                        more.style.display='none';
                    };
                }
            }
        }
        
        // ✅ NEW v9.0.2: Load configured email accounts from consultation
        async function loadEmailAccounts() {
            const accountsList = document.getElementById('vmo-email-accounts-list');
            if (!accountsList) return;
            
            try {
                const {success, data} = await ajaxPost('vmo_list_email_accounts');
                if (success && data && Array.isArray(data)) {
                    if (data.length === 0) {
                        accountsList.innerHTML = `<div style="color:var(--muted);padding:8px;text-align:center;">
                            No email accounts configured yet.<br>
                            <small>Add accounts during consultation or click "Add Account" above.</small>
                        </div>`;
                        return;
                    }
                    
                    // Role icons
                    const roleIcons = {
                        'primary': '⭐',
                        'info': 'ℹ️',
                        'support': '🛟',
                        'sales': '💰',
                        'marketing': '📢',
                        'billing': '💳',
                        'noreply': '🔇'
                    };
                    
                    const accountCards = data.map(acc => {
                        const email = (acc.email || '').replace(/</g, '&lt;');
                        const role = acc.role || 'primary';
                        const displayName = (acc.display_name || '').replace(/</g, '&lt;');
                        const status = acc.verification_status || 'pending';
                        const icon = roleIcons[role] || '📧';
                        const statusColor = status === 'verified' ? 'var(--success)' : status === 'fallback' ? 'var(--warning)' : 'var(--muted)';
                        const statusText = status === 'verified' ? '✓ Verified' : status === 'fallback' ? 'Default' : 'Pending';
                        const isPrimary = acc.is_primary ? '<span style="color:var(--cyan-soft);font-size:10px;margin-left:4px;">PRIMARY</span>' : '';
                        
                        return `<div class="nav-link" style="padding:8px 10px;display:flex;align-items:center;justify-content:space-between;gap:8px;">
                            <div style="display:flex;align-items:center;gap:8px;">
                                <span style="font-size:16px;">${icon}</span>
                                <div>
                                    <div style="font-weight:500;">${email}${isPrimary}</div>
                                    <div style="color:var(--muted);font-size:11px;">${displayName ? displayName + ' • ' : ''}${role.charAt(0).toUpperCase() + role.slice(1)}</div>
                                </div>
                            </div>
                            <span class="nav-badge" style="color:${statusColor}">${statusText}</span>
                        </div>`;
                    }).join('');
                    
                    accountsList.innerHTML = accountCards;
                } else {
                    accountsList.innerHTML = `<div style="color:var(--muted);padding:8px;text-align:center;">No accounts configured</div>`;
                }
            } catch (e) {
                console.error('Failed to load email accounts:', e);
                accountsList.innerHTML = `<div style="color:var(--muted);padding:8px;text-align:center;">Failed to load accounts</div>`;
            }
        }
        
        async function loadEmailBuilderPanel(){
            const panel = document.getElementById('vmo-email-builder-panel'); if (!panel) return;
            panel.innerHTML = `
                <div class="vmo-card">
                    <h4 style="margin-top:0">Campaign Builder</h4>
                    <p style="color:var(--muted);font-size:12px;margin-top:-4px;">Use AI to generate a campaign and approve one to send. This stays in-page.</p>
                    <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
                        <input id="vmo-email-builder-leads" type="number" min="10" max="50" value="25" style="width:90px;padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)">
                        <button id="vmo-email-builder-generate" class="action-btn primary">Generate Options</button>
                        <button id="vmo-email-builder-open-modal" class="action-btn">Open Fullscreen Modal</button>
                    </div>
                    <div id="vmo-email-builder-status" style="color:var(--muted);margin-top:6px;">Ready.</div>
                    <div id="vmo-email-builder-options" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;margin-top:10px;"></div>
                    <div id="vmo-email-builder-actions" style="display:none;margin-top:10px;display:flex;gap:8px;align-items:center;">
                        <button id="vmo-email-builder-send" class="action-btn primary">Approve & Send</button>
                        <div id="vmo-email-builder-send-status" style="color:var(--muted);"></div>
                    </div>
                </div>`;
            const openFS = document.getElementById('vmo-email-builder-open-modal'); if (openFS) openFS.onclick = function(){ if(window.VMOBusinessDashboard && VMOBusinessDashboard.createEmailCampaign){ VMOBusinessDashboard.createEmailCampaign(); } };
            const generateBtn = document.getElementById('vmo-email-builder-generate');
            const statusEl = document.getElementById('vmo-email-builder-status');
            const optsEl = document.getElementById('vmo-email-builder-options');
            const actionsEl = document.getElementById('vmo-email-builder-actions');
            const sendBtn = document.getElementById('vmo-email-builder-send');
            let currentId = null; let selectedIdx = null;

            function renderCards(opts){
                optsEl.innerHTML = '';
                (opts||[]).forEach((opt,i)=>{
                    const card = document.createElement('div');
                    card.className = 'vmo-card';
                    card.style.background = 'rgba(255,255,255,.02)';
                    card.innerHTML = `<label style="display:flex;gap:6px;align-items:flex-start;cursor:pointer;">`+
                                     `<input type=\"radio\" name=\"vmoEmailBuilderOpt\" value=\"${i}\">`+
                                     `<div><div style=\"font-weight:700\">${(opt.subject||'').toString().replace(/</g,'&lt;')}</div>`+
                                     `<div style=\"color:var(--muted);font-size:12px\">${(opt.preheader||'').toString().replace(/</g,'&lt;')}</div>`+
                                     `<div style=\"background:#09111a;border:1px solid rgba(255,255,255,.06);padding:8px;border-radius:8px;margin-top:6px;max-height:160px;overflow:auto\">${opt.html||'<em>No preview</em>'}</div>`+
                                     `</div></label>`;
                    optsEl.appendChild(card);
                });
                optsEl.addEventListener('change', function(e){ const t=e.target; if (t && t.name==='vmoEmailBuilderOpt'){ selectedIdx = parseInt(t.value,10); actionsEl.style.display='flex'; } });
            }

            const qs = (obj)=> new URLSearchParams(obj);
            const ajaxURL = (typeof VMO_AJAX !== 'undefined' ? VMO_AJAX : (window.ajaxurl || '/wp-admin/admin-ajax.php'));
            // Use explicit admin + builder nonces when available; fall back to localized vmo_ajax
            function getAdminNonce(){ try { if (typeof VMO_NONCE_ADMIN !== 'undefined' && VMO_NONCE_ADMIN) return VMO_NONCE_ADMIN; if (window.vmo_ajax && vmo_ajax.nonce) return vmo_ajax.nonce; } catch(e){} return ''; }
            function getBuilderNonce(){ try { if (typeof VMO_NONCE_BUILDER !== 'undefined' && VMO_NONCE_BUILDER) return VMO_NONCE_BUILDER; if (window.vmo_ajax && vmo_ajax.nonce) return vmo_ajax.nonce; } catch(e){} return ''; }
            function post(action, extra){
                const base = { action, security: getBuilderNonce(), nonce: getAdminNonce() };
                return fetch(ajaxURL, { method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body: qs(Object.assign(base, extra||{})) })
                    .then(r=>r.json());
            }

            if (generateBtn) generateBtn.onclick = function(){
                const leadCount = Math.max(10, Math.min(50, parseInt(document.getElementById('vmo-email-builder-leads').value||'25',10)));
                statusEl.textContent = 'Generating…'; optsEl.innerHTML=''; actionsEl.style.display='none'; selectedIdx=null; currentId=null;
                post('vmo_email_generate_campaign', { lead_count: leadCount }).then(resp=>{
                    if (resp && resp.success){ currentId = resp.data.campaign_id; renderCards(resp.data.options||[]); var leadLen = (resp && resp.data && Array.isArray(resp.data.leads)) ? resp.data.leads.length : 0; statusEl.textContent = leadLen + ' leads proposed • Select an option'; }
                    else { statusEl.textContent = (resp && resp.data && resp.data.message) ? resp.data.message : 'Generation failed'; }
                }).catch(()=>{ statusEl.textContent = 'Network error'; });
            };
            if (sendBtn) sendBtn.onclick = function(){ if(selectedIdx==null || currentId==null) return; const s = document.getElementById('vmo-email-builder-send-status'); s.textContent='Sending…'; post('vmo_email_send_campaign', { campaign_id: currentId, selected_index: selectedIdx }).then(resp=>{ if(resp && resp.success){ s.textContent = 'Sent: '+(resp.data.sent||0)+' • Failed: '+(resp.data.failed||0); } else { s.textContent = (resp && resp.data && resp.data.message) ? resp.data.message : 'Send failed'; } }).catch(()=>{ s.textContent='Network error'; }); };
        }
            // CRM panel loader: renders Leads and Customers lists with a details panel
            window.loadCRMPanel = async function(){
                const panel = document.getElementById('vmo-crm-panel');
                if (!panel) return;
                // Initial skeleton
                panel.innerHTML = `
                    <div class="vmo-card" style="grid-column:1/-1;">
                        <div style="display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;">
                            <h4 style="margin:0;">Import Contacts</h4>
                            <div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
                                <button id="vmo-crm-add-contact-btn" class="action-btn primary">Add Contact</button>
                                <input id="vmo-crm-import-file" type="file" accept=".csv,text/csv" style="max-width:280px;" />
                                <select id="vmo-crm-import-type" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                    <option value="lead">Import as Lead</option>
                                    <option value="prospect">Import as Prospect</option>
                                    <option value="customer">Import as Customer</option>
                                    <option value="partner">Import as Partner</option>
                                    <option value="vendor">Import as Vendor</option>
                                </select>
                                <button id="vmo-crm-import-btn" class="action-btn">Upload</button>
                                <span id="vmo-crm-import-status" style="color:var(--muted); font-size:12px;">—</span>
                            </div>
                        </div>
                        <div style="color:var(--muted); font-size:11px; margin-top:6px;">Upload a CSV with headers like name, email, phone, company, tags, notes.</div>
                        <div id="vmo-crm-import-mapping" style="display:none; margin-top:10px; padding:10px; border:1px solid var(--border); border-radius:6px; background:rgba(255,255,255,.03);">
                            <div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:8px; align-items:end;">
                                <label style="font-size:11px; color:var(--muted);">Name column<select id="vmo-crm-map-name" style="width:100%; margin-top:4px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></select></label>
                                <label style="font-size:11px; color:var(--muted);">Email column<select id="vmo-crm-map-email" style="width:100%; margin-top:4px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></select></label>
                                <label style="font-size:11px; color:var(--muted);">Phone column<select id="vmo-crm-map-phone" style="width:100%; margin-top:4px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></select></label>
                                <label style="font-size:11px; color:var(--muted);">Company column<select id="vmo-crm-map-company" style="width:100%; margin-top:4px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></select></label>
                                <label style="font-size:11px; color:var(--muted);">Tags column<select id="vmo-crm-map-tags" style="width:100%; margin-top:4px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></select></label>
                                <label style="font-size:11px; color:var(--muted);">Notes column<select id="vmo-crm-map-notes" style="width:100%; margin-top:4px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></select></label>
                            </div>
                            <label style="font-size:11px; color:var(--muted); display:flex; align-items:center; gap:6px; margin-top:8px;"><input id="vmo-crm-import-dedupe" type="checkbox" checked> Detect duplicates before importing</label>
                            <div style="display:flex; justify-content:flex-end; gap:8px; margin-top:8px;"><button id="vmo-crm-import-confirm" class="action-btn primary" type="button">Confirm Import</button></div>
                        </div>
                        <div id="vmo-crm-duplicate-review" style="display:none; margin-top:10px; padding:10px; border:1px solid var(--border); border-radius:6px; background:rgba(255,255,255,.03);"></div>
                    </div>
                    <div id="vmo-crm-contact-form" class="vmo-card" style="grid-column:1/-1; display:none;">
                        <div style="display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;">
                            <h4 id="vmo-crm-contact-form-title" style="margin:0;">Add Contact</h4>
                            <button id="vmo-crm-contact-cancel" class="action-btn" type="button">Cancel</button>
                        </div>
                        <input id="vmo-crm-contact-id" type="hidden" value="" />
                        <div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px; margin-top:10px;">
                            <input id="vmo-crm-contact-name" type="text" placeholder="Name" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-email" type="email" placeholder="Email" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-phone" type="tel" placeholder="Phone" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-company" type="text" placeholder="Company" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-title" type="text" placeholder="Job title" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <select id="vmo-crm-contact-type" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                <option value="lead">Lead</option>
                                <option value="prospect">Prospect</option>
                                <option value="customer">Customer</option>
                                <option value="partner">Partner</option>
                                <option value="vendor">Vendor</option>
                                <option value="support">Support Contact</option>
                                <option value="referral_source">Referral Source</option>
                                <option value="other">Other</option>
                            </select>
                            <select id="vmo-crm-contact-stage" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                <option value="new">New</option>
                                <option value="engaged">Engaged</option>
                                <option value="nurturing">Nurturing</option>
                                <option value="active_relationship">Active Relationship</option>
                                <option value="customer">Customer</option>
                                <option value="dormant">Dormant</option>
                            </select>
                            <select id="vmo-crm-contact-source" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                <option value="manual_entry">Manual Entry</option>
                                <option value="website_form">Website Form</option>
                                <option value="phone_call">Phone Call</option>
                                <option value="email_marketing">Email</option>
                                <option value="lead_generation">AI Lead Discovery</option>
                                <option value="referral">Referral</option>
                                <option value="social_media">Social Media</option>
                                <option value="other">Other</option>
                            </select>
                            <input id="vmo-crm-contact-address" type="text" placeholder="Street address" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-city" type="text" placeholder="City" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-state" type="text" placeholder="State" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-zip" type="text" placeholder="ZIP/postal code" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-country" type="text" placeholder="Country" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-tags" type="text" placeholder="Tags" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-follow-title" type="text" placeholder="Follow-up reminder" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <input id="vmo-crm-contact-follow-date" type="date" style="padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                        </div>
                        <textarea id="vmo-crm-contact-notes" placeholder="Notes" style="width:100%; min-height:72px; margin-top:8px; padding:8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);"></textarea>
                        <div style="display:flex; justify-content:flex-end; gap:8px; margin-top:8px;">
                            <span id="vmo-crm-contact-status" style="align-self:center; color:var(--muted); font-size:12px;"></span>
                            <button id="vmo-crm-contact-save" class="action-btn primary" type="button">Save Contact</button>
                        </div>
                    </div>
                    <div class="vmo-card" style="grid-column: span 1;">
                        <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
                            <h4 style="margin:0;">Leads</h4>
                            <div>
                                <span id="vmo-crm-leads-count" class="nav-badge">—</span>
                                <button id="vmo-crm-refresh-leads" class="action-btn" style="margin-left:8px;">Refresh</button>
                            </div>
                        </div>
                        <div style="display:flex; gap:8px; align-items:center; margin-top:6px;">
                            <input id="vmo-crm-leads-search" type="search" placeholder="Search leads…" style="flex:1; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <select id="vmo-crm-leads-tag" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); min-width:140px;">
                                <option value="">All tags</option>
                            </select>
                            <select id="vmo-crm-leads-sort" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                <option value="newest">Newest</option>
                                <option value="oldest">Oldest</option>
                                <option value="name">Name A→Z</option>
                                <option value="has_email">Has email first</option>
                                <option value="has_phone">Has phone first</option>
                            </select>
                        </div>
                        <div style="display:flex; gap:8px; align-items:center; margin-top:6px;">
                            <label style="font-size:11px; color:var(--muted); display:flex; align-items:center; gap:6px;"><input type="checkbox" id="vmo-crm-leads-selectall"> Select all</label>
                            <button id="vmo-crm-leads-email" class="action-btn" style="padding:6px 8px;">✉️ Email selected</button>
                            <button id="vmo-crm-leads-promote" class="action-btn" style="padding:6px 8px;">⬆ Mark selected as Customer</button>
                            <button id="vmo-crm-leads-export" class="action-btn" style="padding:6px 8px;">⬇ Download CSV</button>
                        </div>
                        <div id="vmo-crm-leads-list" style="margin-top:8px; max-height:280px; overflow:auto;">
                            <div style="color:var(--muted);">Loading leads…</div>
                        </div>
                    </div>
                    <div class="vmo-card" style="grid-column: span 1;">
                        <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
                            <h4 style="margin:0;">Customers</h4>
                            <div>
                                <span id="vmo-crm-customers-count" class="nav-badge">—</span>
                                <button id="vmo-crm-refresh-customers" class="action-btn" style="margin-left:8px;">Refresh</button>
                            </div>
                        </div>
                        <div style="display:flex; gap:8px; align-items:center; margin-top:6px;">
                            <input id="vmo-crm-customers-search" type="search" placeholder="Search customers…" style="flex:1; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                            <select id="vmo-crm-customers-tag" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink); min-width:140px;">
                                <option value="">All tags</option>
                            </select>
                            <select id="vmo-crm-customers-sort" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);">
                                <option value="newest">Newest</option>
                                <option value="oldest">Oldest</option>
                                <option value="name">Name A→Z</option>
                                <option value="has_email">Has email first</option>
                                <option value="has_phone">Has phone first</option>
                            </select>
                        </div>
                        <div style="display:flex; gap:8px; align-items:center; margin-top:6px;">
                            <label style="font-size:11px; color:var(--muted); display:flex; align-items:center; gap:6px;"><input type="checkbox" id="vmo-crm-customers-selectall"> Select all</label>
                            <button id="vmo-crm-customers-email" class="action-btn" style="padding:6px 8px;">✉️ Email selected</button>
                            <button id="vmo-crm-customers-export" class="action-btn" style="padding:6px 8px;">⬇ Download CSV</button>
                        </div>
                        <div id="vmo-crm-customers-list" style="margin-top:8px; max-height:280px; overflow:auto;">
                            <div style="color:var(--muted);">Loading customers…</div>
                        </div>
                    </div>
                    <div class="vmo-card" id="vmo-crm-details-card" style="grid-column:1/-1; display:none;">
                        <h4 id="vmo-crm-details-title" style="margin-top:0;">Contact Details</h4>
                        <div id="vmo-crm-details-meta" style="font-size:12px; color:var(--muted);"></div>
                        <div id="vmo-crm-actions" style="margin:10px 0; display:flex; gap:8px; flex-wrap:wrap;"></div>
                        <div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:12px; margin:10px 0;">
                            <div>
                                <h4 style="margin:6px 0;">Relationship Summary</h4>
                                <div id="vmo-crm-relationship-summary" style="font-size:12px; color:var(--muted); line-height:1.45;">—</div>
                            </div>
                            <div>
                                <h4 style="margin:6px 0;">Retention Action</h4>
                                <div id="vmo-crm-retention-action" style="font-size:12px; color:var(--muted); line-height:1.45;">—</div>
                            </div>
                            <div>
                                <h4 style="margin:6px 0;">Pattern Insight</h4>
                                <div id="vmo-crm-pattern-insight" style="font-size:12px; color:var(--muted); line-height:1.45;">—</div>
                            </div>
                        </div>
                        <div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:12px;">
                            <div>
                                <h4 style="margin:6px 0;">Calls</h4>
                                <div id="vmo-crm-calls" style="max-height:220px; overflow:auto; font-size:12px; color:var(--ink)">—</div>
                            </div>
                            <div>
                                <h4 style="margin:6px 0;">Emails</h4>
                                <div id="vmo-crm-emails" style="max-height:220px; overflow:auto; font-size:12px; color:var(--ink)">—</div>
                            </div>
                            <div>
                                <h4 style="margin:6px 0;">Purchases</h4>
                                <div id="vmo-crm-purchases" style="max-height:220px; overflow:auto; font-size:12px; color:var(--ink)">—</div>
                            </div>
                        </div>
                        <div style="margin-top:10px;">
                            <h4 style="margin:6px 0;">Total Spent</h4>
                            <div id="vmo-crm-total-spent" style="font-weight:700; color:var(--cyan-soft)">—</div>
                        </div>
                        <div style="margin-top:10px;">
                            <h4 style="margin:6px 0;">AI Recommendation</h4>
                            <div id="vmo-crm-reco" style="white-space:pre-wrap; color:var(--muted)">—</div>
                        </div>
                        <div style="margin-top:10px;">
                            <h4 style="margin:6px 0;">Tags</h4>
                            <div id="vmo-crm-tags" style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom:6px; color:var(--ink)">—</div>
                            <div style="display:flex; gap:6px; align-items:center; flex-wrap:wrap;">
                                <input id="vmo-crm-tags-input" type="text" placeholder="Add tags, comma-separated" style="flex:1; min-width:220px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                <button id="vmo-crm-save-tags" class="action-btn">Save Tags</button>
                            </div>
                        </div>
                        <div style="margin-top:10px;">
                            <h4 style="margin:6px 0;">Tasks & Reminders</h4>
                            <div style="display:flex; gap:6px; align-items:center; margin-bottom:6px; flex-wrap:wrap;">
                                <input id="vmo-crm-task-title" type="text" placeholder="Task title" style="flex:1; min-width:220px; padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                <input id="vmo-crm-task-due" type="date" style="padding:6px 8px; border-radius:6px; border:1px solid var(--border); background:rgba(255,255,255,.05); color:var(--ink);" />
                                <button id="vmo-crm-add-task" class="action-btn">Add Task</button>
                            </div>
                            <div id="vmo-crm-tasks" style="max-height:220px; overflow:auto; font-size:12px; color:var(--ink)">—</div>
                        </div>
                        <div style="margin-top:10px;">
                            <h4 style="margin:6px 0;">Relationship Timeline</h4>
                            <div id="vmo-crm-timeline" style="max-height:260px; overflow:auto; font-size:12px; color:var(--ink)">—</div>
                        </div>
                    </div>`;

                // initialize multi-select state and caches
                window.__crmSelected = { lead: new Set(), customer: new Set() };
                window.__crmCache = { lead: [], customer: [] };
                window.__crmImportState = null;

                function parseCSV(text){
                    const rows = [];
                    let row = [];
                    let cur = '';
                    let inQuotes = false;
                    for (let i = 0; i < text.length; i++) {
                        const ch = text[i];
                        const next = text[i+1];
                        if (inQuotes) {
                            if (ch === '"' && next === '"') { cur += '"'; i++; continue; }
                            if (ch === '"') { inQuotes = false; continue; }
                            cur += ch;
                        } else {
                            if (ch === '"') { inQuotes = true; continue; }
                            if (ch === ',') { row.push(cur); cur=''; continue; }
                            if (ch === '\n') { row.push(cur); rows.push(row); row=[]; cur=''; continue; }
                            if (ch === '\r') { continue; }
                            cur += ch;
                        }
                    }
                    if (cur.length || row.length) { row.push(cur); rows.push(row); }
                    return rows.map(r=> r.map(c=> (c||'').trim()));
                }

                function mapHeaders(h){
                    const norm = (s)=> String(s||'').trim().toLowerCase().replace(/\s+/g,'_');
                    const map = {};
                    h.forEach((k, idx)=>{
                        const key = norm(k);
                        if (!key) return;
                        map[key] = idx;
                    });
                    return map;
                }

                function pick(row, hm, keys){
                    for (const k of keys) {
                        const idx = hm[k];
                        if (typeof idx === 'number' && idx >= 0 && row[idx] !== undefined) return String(row[idx]||'').trim();
                    }
                    return '';
                }

                function escapeOptionText(value){
                    return String(value||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/"/g,'&quot;');
                }

                function escapeHtml(value){
                    return String(value||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
                }

                function populateImportSelect(id, header, preferredKeys, fallbackIndex){
                    const el = document.getElementById(id);
                    if (!el) return;
                    const headerMap = mapHeaders(header);
                    const options = ['<option value="">Do not import</option>'].concat(header.map((label, idx)=>'<option value="' + idx + '">' + escapeOptionText(label || ('Column ' + (idx + 1))) + '</option>'));
                    el.innerHTML = options.join('');
                    let selected = '';
                    for (const key of preferredKeys) {
                        if (typeof headerMap[key] === 'number') { selected = String(headerMap[key]); break; }
                    }
                    if (selected === '' && typeof fallbackIndex === 'number' && fallbackIndex < header.length) selected = String(fallbackIndex);
                    el.value = selected;
                }

                function showImportMapping(rows, header, start){
                    window.__crmImportState = { rows, header, start };
                    populateImportSelect('vmo-crm-map-name', header, ['name','full_name','fullname','contact','contact_name'], 0);
                    populateImportSelect('vmo-crm-map-email', header, ['email','e_mail'], 1);
                    populateImportSelect('vmo-crm-map-phone', header, ['phone','phone_number','mobile','tel','telephone'], 2);
                    populateImportSelect('vmo-crm-map-company', header, ['company','organization','business'], 3);
                    populateImportSelect('vmo-crm-map-tags', header, ['tags','tag'], null);
                    populateImportSelect('vmo-crm-map-notes', header, ['notes','note','description','details'], null);
                    const mapping = document.getElementById('vmo-crm-import-mapping');
                    if (mapping) mapping.style.display = 'block';
                    const statusEl = document.getElementById('vmo-crm-import-status');
                    if (statusEl) statusEl.textContent = 'Map columns, choose type, then confirm';
                }

                function mappedValue(row, selectId){
                    const el = document.getElementById(selectId);
                    const idx = el && el.value !== '' ? parseInt(el.value, 10) : -1;
                    return idx >= 0 && row[idx] !== undefined ? String(row[idx]||'').trim() : '';
                }

                function renderDuplicateReview(rows){
                    const panel = document.getElementById('vmo-crm-duplicate-review');
                    if (!panel) return;
                    if (!Array.isArray(rows) || !rows.length) {
                        panel.style.display = 'none';
                        panel.innerHTML = '';
                        return;
                    }
                    panel.style.display = 'block';
                    panel.innerHTML = '<div style="display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-bottom:8px;">'
                        + '<div><strong>Possible Duplicate Review</strong><div style="font-size:11px;color:var(--muted);margin-top:2px;">Weak matches need an owner decision before merging.</div></div>'
                        + '<button type="button" class="action-btn" data-duplicate-close>Hide</button>'
                        + '</div>'
                        + rows.map((row, rowIndex)=>{
                            const importedLabel = [row.import_name, row.import_company, row.import_email, row.import_phone].filter(Boolean).join(' • ') || 'Imported contact';
                            const matches = Array.isArray(row.matches) ? row.matches : [];
                            return '<div data-duplicate-row="' + rowIndex + '" style="border-top:1px solid var(--border);padding-top:8px;margin-top:8px;">'
                                + '<div style="font-size:12px;margin-bottom:6px;"><strong>Imported:</strong> ' + escapeHtml(importedLabel) + '</div>'
                                + (matches.length ? matches.map(match=>{
                                    const matchLabel = [match.name, match.company, match.email, match.phone].filter(Boolean).join(' • ') || ('Contact #' + match.id);
                                    return '<div style="display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin:6px 0;padding:8px;border:1px solid var(--border);border-radius:6px;background:rgba(0,0,0,.12);">'
                                        + '<button type="button" class="action-btn" data-open-contact="' + Number(match.id || 0) + '" style="text-align:left;flex:1;min-width:180px;">' + escapeHtml(matchLabel) + '</button>'
                                        + '<div style="display:flex;gap:6px;flex-wrap:wrap;">'
                                        + '<button type="button" class="action-btn primary" data-duplicate-decision="merge" data-imported-id="' + Number(row.imported_id || 0) + '" data-match-id="' + Number(match.id || 0) + '">Merge</button>'
                                        + '<button type="button" class="action-btn" data-duplicate-decision="update_existing" data-imported-id="' + Number(row.imported_id || 0) + '" data-match-id="' + Number(match.id || 0) + '">Update Existing</button>'
                                        + '</div>'
                                        + '</div>';
                                }).join('') : '<div style="font-size:12px;color:var(--muted);">No match details returned.</div>')
                                + '<div style="display:flex;gap:6px;flex-wrap:wrap;margin-top:6px;">'
                                + '<button type="button" class="action-btn" data-open-contact="' + Number(row.imported_id || 0) + '">Open Imported</button>'
                                + '<button type="button" class="action-btn" data-duplicate-decision="keep_separate" data-imported-id="' + Number(row.imported_id || 0) + '">Keep Separate</button>'
                                + '<button type="button" class="action-btn" data-duplicate-decision="ignore" data-imported-id="' + Number(row.imported_id || 0) + '">Ignore</button>'
                                + '</div>'
                                + '</div>';
                        }).join('');
                    panel.querySelectorAll('[data-duplicate-close]').forEach(button=> button.addEventListener('click', ()=> renderDuplicateReview([])));
                    panel.querySelectorAll('[data-open-contact]').forEach(button=> button.addEventListener('click', ()=>{
                        const contactId = parseInt(button.getAttribute('data-open-contact') || '0', 10);
                        if (contactId) openContactDetails(contactId, 'lead');
                    }));
                    panel.querySelectorAll('[data-duplicate-decision]').forEach(button=> button.addEventListener('click', async ()=>{
                        const decision = button.getAttribute('data-duplicate-decision') || '';
                        const importedId = parseInt(button.getAttribute('data-imported-id') || '0', 10);
                        const matchId = parseInt(button.getAttribute('data-match-id') || '0', 10);
                        button.disabled = true;
                        button.textContent = 'Saving...';
                        try {
                            const response = await ajaxPost('vmo_resolve_contact_duplicate', { decision, imported_id: importedId, match_id: matchId });
                            if (!response || !response.success) throw new Error(response && response.data && response.data.message ? response.data.message : 'Could not resolve duplicate');
                            notify(response.data && response.data.message ? response.data.message : 'Duplicate review saved', 'success');
                            const rowEl = button.closest('[data-duplicate-row]');
                            if (rowEl) rowEl.remove();
                            if (!panel.querySelector('[data-duplicate-row]')) renderDuplicateReview([]);
                            refreshLeads();
                            refreshCustomers();
                        } catch (err) {
                            notify(err && err.message ? err.message : 'Duplicate review failed', 'error');
                            button.disabled = false;
                            button.textContent = decision === 'update_existing' ? 'Update Existing' : (decision === 'keep_separate' ? 'Keep Separate' : (decision === 'ignore' ? 'Ignore' : 'Merge'));
                        }
                    }));
                }

                async function doImport(){
                    const fileEl = document.getElementById('vmo-crm-import-file');
                    const statusEl = document.getElementById('vmo-crm-import-status');
                    const file = fileEl && fileEl.files ? fileEl.files[0] : null;
                    if (!file) { if (statusEl) statusEl.textContent = 'Choose a CSV file first'; return; }
                    if (statusEl) statusEl.textContent = 'Reading…';
                    const text = await file.text();
                    const rows = parseCSV(text);
                    if (!rows.length) { if (statusEl) statusEl.textContent = 'No rows found'; return; }

                    let header = rows[0];
                    let start = 1;
                    const hm0 = mapHeaders(header);
                    const hasEmailHeader = Object.keys(hm0).some(k=>k==='email' || k==='e_mail');
                    if (!hasEmailHeader && rows.length && rows[0].length && rows[0].some(v=>/\S+@\S+/.test(String(v)))) {
                        header = rows[0].map((_, idx)=>'Column ' + (idx + 1));
                        start = 0;
                    }
                    showImportMapping(rows, header, start);
                }

                async function confirmImport(){
                    const state = window.__crmImportState;
                    const typeEl = document.getElementById('vmo-crm-import-type');
                    const dedupeEl = document.getElementById('vmo-crm-import-dedupe');
                    const statusEl = document.getElementById('vmo-crm-import-status');
                    const asType = typeEl ? (typeEl.value || 'lead') : 'lead';
                    if (!state || !Array.isArray(state.rows)) { if (statusEl) statusEl.textContent = 'Choose and map a CSV first'; return; }
                    const out = [];
                    for (let i = state.start; i < state.rows.length && out.length < 500; i++) {
                        const r = state.rows[i];
                        if (!r || !r.length) continue;
                        const name = mappedValue(r, 'vmo-crm-map-name');
                        const email = mappedValue(r, 'vmo-crm-map-email');
                        const phone = mappedValue(r, 'vmo-crm-map-phone');
                        const tags = mappedValue(r, 'vmo-crm-map-tags');
                        const company = mappedValue(r, 'vmo-crm-map-company');
                        const description = mappedValue(r, 'vmo-crm-map-notes');
                        if (!name && !email && !phone) continue;
                        out.push({ name, email, phone, tags, company, description, type: asType });
                    }
                    if (!out.length) { if (statusEl) statusEl.textContent = 'No usable rows found'; return; }
                    if (statusEl) statusEl.textContent = `Uploading ${out.length}…`;
                    try{
                        const res = await ajaxPost('vmo_import_contacts', { type: asType, rows: JSON.stringify(out), detect_duplicates: dedupeEl && dedupeEl.checked ? '1' : '0' });
                        if (!res || !res.success) { if (statusEl) statusEl.textContent = 'Import failed'; notify('Import failed', 'error'); return; }
                        const ins = (res.data && typeof res.data.inserted === 'number') ? res.data.inserted : 0;
                        const created = (res.data && typeof res.data.created === 'number') ? res.data.created : ins;
                        const updated = (res.data && typeof res.data.updated === 'number') ? res.data.updated : 0;
                        const sk = (res.data && typeof res.data.skipped === 'number') ? res.data.skipped : 0;
                        const dup = (res.data && typeof res.data.duplicates === 'number') ? res.data.duplicates : 0;
                        const possible = (res.data && typeof res.data.possible_duplicates === 'number') ? res.data.possible_duplicates : 0;
                        const msg = `Imported ${ins}: created ${created}, updated ${updated}, exact duplicates ${dup}, possible duplicates ${possible}, skipped ${sk}`;
                        if (statusEl) statusEl.textContent = msg;
                        notify(msg, possible ? 'info' : 'success');
                        renderDuplicateReview(res.data && Array.isArray(res.data.possible_duplicate_rows) ? res.data.possible_duplicate_rows : []);
                        const mapping = document.getElementById('vmo-crm-import-mapping');
                        if (mapping) mapping.style.display = 'none';
                        window.__crmImportState = null;
                        // refresh
                        if (asType === 'customer') refreshCustomers(); else refreshLeads();
                    } catch(_e){ if (statusEl) statusEl.textContent = 'Import error'; notify('Import error', 'error'); }
                }
                function openContactForm(contact){
                    if (contact) populateContactForm(contact); else clearContactForm();
                    const form = document.getElementById('vmo-crm-contact-form');
                    const status = document.getElementById('vmo-crm-contact-status');
                    if (status) status.textContent = '';
                    if (form) {
                        form.style.display = 'block';
                        form.scrollIntoView({behavior:'smooth', block:'nearest'});
                    }
                }
                function closeContactForm(){
                    const form = document.getElementById('vmo-crm-contact-form');
                    if (form) form.style.display = 'none';
                }
                function readContactFormValue(id){
                    const el = document.getElementById(id);
                    return el ? String(el.value || '').trim() : '';
                }
                function clearContactForm(){
                    ['vmo-crm-contact-id','vmo-crm-contact-name','vmo-crm-contact-email','vmo-crm-contact-phone','vmo-crm-contact-company','vmo-crm-contact-title','vmo-crm-contact-address','vmo-crm-contact-city','vmo-crm-contact-state','vmo-crm-contact-zip','vmo-crm-contact-country','vmo-crm-contact-tags','vmo-crm-contact-follow-title','vmo-crm-contact-follow-date','vmo-crm-contact-notes'].forEach(id=>{
                        const el = document.getElementById(id);
                        if (el) el.value = '';
                    });
                    const title = document.getElementById('vmo-crm-contact-form-title');
                    if (title) title.textContent = 'Add Contact';
                    const typeEl = document.getElementById('vmo-crm-contact-type');
                    if (typeEl) typeEl.value = 'lead';
                    const stageEl = document.getElementById('vmo-crm-contact-stage');
                    if (stageEl) stageEl.value = 'new';
                    const sourceEl = document.getElementById('vmo-crm-contact-source');
                    if (sourceEl) sourceEl.value = 'manual_entry';
                }
                function populateContactForm(contact){
                    clearContactForm();
                    const title = document.getElementById('vmo-crm-contact-form-title');
                    if (title) title.textContent = 'Edit Contact';
                    const setVal = (id, value)=>{ const el = document.getElementById(id); if (el) el.value = value || ''; };
                    setVal('vmo-crm-contact-id', contact.id);
                    setVal('vmo-crm-contact-name', contact.name);
                    setVal('vmo-crm-contact-email', contact.email);
                    setVal('vmo-crm-contact-phone', contact.phone);
                    setVal('vmo-crm-contact-company', contact.company);
                    setVal('vmo-crm-contact-title', contact.job_title);
                    setVal('vmo-crm-contact-address', contact.street_address || contact.address);
                    setVal('vmo-crm-contact-city', contact.city);
                    setVal('vmo-crm-contact-state', contact.state);
                    setVal('vmo-crm-contact-zip', contact.zip);
                    setVal('vmo-crm-contact-country', contact.country);
                    setVal('vmo-crm-contact-tags', Array.isArray(contact.tags) ? contact.tags.join(', ') : contact.tags);
                    setVal('vmo-crm-contact-notes', contact.notes || contact.description);
                    const typeEl = document.getElementById('vmo-crm-contact-type');
                    if (typeEl) typeEl.value = contact.primary_category || contact.type || 'lead';
                    const stageEl = document.getElementById('vmo-crm-contact-stage');
                    if (stageEl) stageEl.value = contact.lifecycle_stage || (contact.type === 'customer' ? 'customer' : 'new');
                    const sourceEl = document.getElementById('vmo-crm-contact-source');
                    if (sourceEl) sourceEl.value = contact.source || 'manual_entry';
                }
                async function saveContactForm(){
                    const status = document.getElementById('vmo-crm-contact-status');
                    const saveBtn = document.getElementById('vmo-crm-contact-save');
                    const payload = {
                        contact_id: readContactFormValue('vmo-crm-contact-id'),
                        type: readContactFormValue('vmo-crm-contact-type') || 'lead',
                        lifecycle_stage: readContactFormValue('vmo-crm-contact-stage') || 'new',
                        source: readContactFormValue('vmo-crm-contact-source') || 'manual_entry',
                        name: readContactFormValue('vmo-crm-contact-name'),
                        email: readContactFormValue('vmo-crm-contact-email'),
                        phone: readContactFormValue('vmo-crm-contact-phone'),
                        company: readContactFormValue('vmo-crm-contact-company'),
                        job_title: readContactFormValue('vmo-crm-contact-title'),
                        address: readContactFormValue('vmo-crm-contact-address'),
                        city: readContactFormValue('vmo-crm-contact-city'),
                        state: readContactFormValue('vmo-crm-contact-state'),
                        zip: readContactFormValue('vmo-crm-contact-zip'),
                        country: readContactFormValue('vmo-crm-contact-country'),
                        tags: readContactFormValue('vmo-crm-contact-tags'),
                        follow_up_title: readContactFormValue('vmo-crm-contact-follow-title'),
                        follow_up_date: readContactFormValue('vmo-crm-contact-follow-date'),
                        notes: readContactFormValue('vmo-crm-contact-notes')
                    };
                    if (!payload.name && !payload.email && !payload.phone && !payload.company) {
                        if (status) status.textContent = 'Add a name, email, phone, or company';
                        return;
                    }
                    if (status) status.textContent = 'Saving...';
                    if (saveBtn) saveBtn.disabled = true;
                    try{
                        const {success, message} = await ajaxPost('vmo_save_crm_contact', payload);
                        if (!success) {
                            if (status) status.textContent = message || 'Save failed';
                            notify(message || 'Save failed', 'error');
                            return;
                        }
                        notify('Contact saved', 'success');
                        if (status) status.textContent = 'Saved';
                        clearContactForm();
                        closeContactForm();
                        refreshLeads();
                        refreshCustomers();
                        try { loadTagFilters(); } catch(_){ }
                    }catch(e){
                        if (status) status.textContent = 'Save error';
                        notify('Save error: ' + e.message, 'error');
                    }finally{
                        if (saveBtn) saveBtn.disabled = false;
                    }
                }
                const refreshLeads = async ()=>{
                    const listEl = document.getElementById('vmo-crm-leads-list');
                    if (listEl) listEl.innerHTML = '<div style="color:var(--muted);">Loading…</div>';
                    try{
                        const {success, data, message} = await ajaxPost('vmo_get_contacts', { type: 'lead', limit: 200 });
                        const leads = (success && data && Array.isArray(data.contacts)) ? data.contacts : [];
                        window.__crmCache.lead = leads;
                        applyCRMFilters('lead');
                    }catch(e){
                        const hadAny = !!(window.__crmCache && Array.isArray(window.__crmCache.lead) && window.__crmCache.lead.length);
                        if (listEl) {
                            listEl.innerHTML = hadAny
                                ? '<div style="color:salmon;">Failed to load leads</div>'
                                : '<div style="color:var(--muted);">No leads yet</div>';
                        }
                    }
                };
                const refreshCustomers = async ()=>{
                    const listEl = document.getElementById('vmo-crm-customers-list');
                    if (listEl) listEl.innerHTML = '<div style="color:var(--muted);">Loading…</div>';
                    try{
                        const {success, data, message} = await ajaxPost('vmo_get_contacts', { type: 'customer', limit: 200 });
                        const customers = (success && data && Array.isArray(data.contacts)) ? data.contacts : [];
                        window.__crmCache.customer = customers;
                        applyCRMFilters('customer');
                    }catch(e){
                        const hadAny = !!(window.__crmCache && Array.isArray(window.__crmCache.customer) && window.__crmCache.customer.length);
                        if (listEl) {
                            listEl.innerHTML = hadAny
                                ? '<div style="color:salmon;">Failed to load customers</div>'
                                : '<div style="color:var(--muted);">No customers yet</div>';
                        }
                    }
                };
                // Bind refresh buttons
                const rl = document.getElementById('vmo-crm-refresh-leads'); if (rl) rl.onclick = refreshLeads;
                const rc = document.getElementById('vmo-crm-refresh-customers'); if (rc) rc.onclick = refreshCustomers;
                const ib = document.getElementById('vmo-crm-import-btn'); if (ib) ib.onclick = doImport;
                const ic = document.getElementById('vmo-crm-import-confirm'); if (ic) ic.onclick = confirmImport;
                const addContactBtn = document.getElementById('vmo-crm-add-contact-btn'); if (addContactBtn) addContactBtn.onclick = ()=> openContactForm();
                const cancelContactBtn = document.getElementById('vmo-crm-contact-cancel'); if (cancelContactBtn) cancelContactBtn.onclick = closeContactForm;
                const saveContactBtn = document.getElementById('vmo-crm-contact-save'); if (saveContactBtn) saveContactBtn.onclick = saveContactForm;
                const la = document.getElementById('vmo-crm-leads-selectall'); if (la) la.onchange = ()=> toggleSelectAll('lead', la.checked);
                const ca = document.getElementById('vmo-crm-customers-selectall'); if (ca) ca.onchange = ()=> toggleSelectAll('customer', ca.checked);
                const le = document.getElementById('vmo-crm-leads-email'); if (le) le.onclick = ()=> bulkEmail('lead');
                const ce = document.getElementById('vmo-crm-customers-email'); if (ce) ce.onclick = ()=> bulkEmail('customer');
                const lp = document.getElementById('vmo-crm-leads-promote'); if (lp) lp.onclick = ()=> bulkPromoteToCustomers();
                const lx = document.getElementById('vmo-crm-leads-export'); if (lx) lx.onclick = ()=> exportSelectedCSV('lead');
                const cx = document.getElementById('vmo-crm-customers-export'); if (cx) cx.onclick = ()=> exportSelectedCSV('customer');
                const ls = document.getElementById('vmo-crm-leads-search'); if (ls) { let t; ls.oninput = ()=>{ clearTimeout(t); t=setTimeout(()=>applyCRMFilters('lead'),200); }; }
                const cs = document.getElementById('vmo-crm-customers-search'); if (cs) { let t; cs.oninput = ()=>{ clearTimeout(t); t=setTimeout(()=>applyCRMFilters('customer'),200); }; }
                const lso = document.getElementById('vmo-crm-leads-sort'); if (lso) lso.onchange = ()=> applyCRMFilters('lead');
                const cso = document.getElementById('vmo-crm-customers-sort'); if (cso) cso.onchange = ()=> applyCRMFilters('customer');
                const ltg = document.getElementById('vmo-crm-leads-tag'); if (ltg) ltg.onchange = ()=> applyCRMFilters('lead');
                const ctg = document.getElementById('vmo-crm-customers-tag'); if (ctg) ctg.onchange = ()=> applyCRMFilters('customer');

                // Initial load (in parallel)
                refreshLeads(); refreshCustomers();
                // Populate tag filters
                try { loadTagFilters(); } catch(_){ /* no-op */ }
            }
            function renderContactsList(type, items){
                const listId = (type === 'lead') ? 'vmo-crm-leads-list' : 'vmo-crm-customers-list';
                const cntId = (type === 'lead') ? 'vmo-crm-leads-count' : 'vmo-crm-customers-count';
                const listEl = document.getElementById(listId);
                const cntEl = document.getElementById(cntId);
                if (cntEl) cntEl.textContent = String(items.length || 0);
                // Update overall badge
                try{
                    const lc = parseInt(((document.getElementById('vmo-crm-leads-count')||{}).textContent)||'0',10);
                    const cc = parseInt(((document.getElementById('vmo-crm-customers-count')||{}).textContent)||'0',10);
                    const badge = document.getElementById('vmo-badge-contacts'); if (badge) badge.textContent = (lc+cc).toString();
                }catch(_){}
                if (!listEl) return;
                if (!items.length) { listEl.innerHTML = '<div style="color:var(--muted);">No ' + (type==='lead'?'leads':'customers') + ' yet</div>'; return; }
                const frag = document.createDocumentFragment();
                items.forEach(c=>{
                    const row = document.createElement('div');
                    row.className = 'nav-link';
                    row.style.margin = '4px 0';
                    const name = String(c.name||'Contact').replace(/</g,'&lt;');
                    const company = String(c.company||'').replace(/</g,'&lt;');
                    const jobTitle = String(c.job_title||'').replace(/</g,'&lt;');
                    const desc = String(c.description||'').replace(/</g,'&lt;');
                    const phone = String(c.phone||'');
                    const email = String(c.email||'');
                    const address = String(c.address||c.city||'').replace(/</g,'&lt;');
                    const when = String(c.date_added||'').replace('T',' ');
                    const source = String(c.source||'');
                    const leadScore = c.lead_score || 0;
                    const isChecked = !!(window.__crmSelected && window.__crmSelected[type] && window.__crmSelected[type].has(c.id));
                    
                    // Build source badge (highlight AI-generated leads)
                    const sourceBadge = source === 'lead_generation' 
                        ? '<span style="background:#4facfe;color:#fff;font-size:9px;padding:2px 5px;border-radius:3px;margin-left:6px;">🤖 AI Lead</span>' 
                        : '';
                    
                    // Build company/title line
                    const companyLine = (company || jobTitle) 
                        ? `<div style="font-size:11px;color:var(--accent);">${company}${company && jobTitle ? ' • ' : ''}${jobTitle}</div>` 
                        : '';
                    
                    // Build contact details line
                    const contactDetails = [];
                    if (email) contactDetails.push(`📧 ${email.replace(/</g,'&lt;')}`);
                    if (phone) contactDetails.push(`📞 ${phone.replace(/</g,'&lt;')}`);
                    if (address) contactDetails.push(`📍 ${address}`);
                    const contactLine = contactDetails.length 
                        ? `<div style="font-size:10px;color:var(--muted);margin-top:2px;">${contactDetails.join(' | ')}</div>` 
                        : '';
                    
                    row.innerHTML = `
                        <div class="nav-text" style="flex:1;">
                            <div style="display:flex; align-items:center; gap:8px; flex-wrap:wrap;">
                                <input type="checkbox" class="vmo-crm-select" data-id="${c.id}" ${isChecked?'checked':''}>
                                <strong>${name}</strong>${sourceBadge}
                                <small style="color:var(--muted);">${when}</small>
                            </div>
                            ${companyLine}
                            ${contactLine}
                            ${desc ? `<div style="font-size:11px;color:var(--muted);margin-top:4px;font-style:italic;">"${desc.substring(0,100)}${desc.length > 100 ? '...' : ''}"</div>` : ''}
                        </div>
                        <div style="display:flex; gap:6px; align-items:center; flex-shrink:0;">
                            ${phone ? `<button class=\"action-btn\" data-call=\"${phone.replace(/\"/g,'&quot;')}\">📞</button>` : ''}
                            ${email ? `<button class=\"action-btn\" data-email=\"${email.replace(/\"/g,'&quot;')}\">✉️</button>` : ''}
                            ${leadScore > 0 ? `<div class=\"nav-badge\" style=\"background:${leadScore >= 80 ? '#00f2c3' : leadScore >= 50 ? '#4facfe' : '#888'};\">${leadScore}</div>` : ''}
                        </div>`;
                    // Row click opens details
                    row.addEventListener('click', (ev)=>{
                        // Ignore clicks on action buttons
                        const t = ev.target;
                        if (t && t.closest && (t.closest('button[data-call]') || t.closest('button[data-email]'))) return;
                        if (t && t.classList && t.classList.contains('vmo-crm-select')) {
                            // Toggle selection without opening details
                            const id = parseInt(t.getAttribute('data-id')||'0',10);
                            if (!window.__crmSelected) window.__crmSelected = { lead:new Set(), customer:new Set() };
                            const set = window.__crmSelected[type];
                            if (t.checked) set.add(id); else set.delete(id);
                            ev.stopPropagation(); return;
                        }
                        openContactDetails(c.id, type);
                    });
                    // Bind quick actions
                    const callBtn = row.querySelector('button[data-call]');
                    if (callBtn) callBtn.addEventListener('click', (e)=>{ e.stopPropagation(); callContact(callBtn.getAttribute('data-call')); });
                    const mailBtn = row.querySelector('button[data-email]');
                    if (mailBtn) mailBtn.addEventListener('click', (e)=>{ e.stopPropagation(); emailContact(mailBtn.getAttribute('data-email')); });
                    const cb = row.querySelector('input.vmo-crm-select');
                    if (cb) cb.addEventListener('change', (e)=>{
                        const id = parseInt(cb.getAttribute('data-id')||'0',10);
                        if (!window.__crmSelected) window.__crmSelected = { lead:new Set(), customer:new Set() };
                        const set = window.__crmSelected[type];
                        if (cb.checked) set.add(id); else set.delete(id);
                        e.stopPropagation();
                    });
                    frag.appendChild(row);
                });
                listEl.innerHTML='';
                listEl.appendChild(frag);
            }
            function applyCRMFilters(type){
                const cache = (window.__crmCache && window.__crmCache[type]) ? window.__crmCache[type] : [];
                const searchId = type==='lead' ? 'vmo-crm-leads-search' : 'vmo-crm-customers-search';
                const sortId = type==='lead' ? 'vmo-crm-leads-sort' : 'vmo-crm-customers-sort';
                const tagId = type==='lead' ? 'vmo-crm-leads-tag' : 'vmo-crm-customers-tag';
                const q = (document.getElementById(searchId)||{}).value || '';
                const sort = (document.getElementById(sortId)||{}).value || 'newest';
                const tag = (document.getElementById(tagId)||{}).value || '';
                const s = q.trim().toLowerCase();
                let filtered = cache.slice();
                if (s) {
                    filtered = filtered.filter(c=>{
                        const fields = [c.name, c.email, c.phone, c.description].map(x=>String(x||'').toLowerCase());
                        return fields.some(f=>f.includes(s));
                    });
                }
                if (tag) {
                    filtered = filtered.filter(c=>{
                        const t = Array.isArray(c.tags) ? c.tags : [];
                        return t.includes(tag);
                    });
                }
                const byDate = (a,b)=>{
                    const da = new Date(a.date_added||0).getTime()||0; const db = new Date(b.date_added||0).getTime()||0; return db-da;
                };
                if (sort==='newest') filtered.sort(byDate);
                else if (sort==='oldest') filtered.sort((a,b)=>-byDate(a,b));
                else if (sort==='name') filtered.sort((a,b)=>String(a.name||'').localeCompare(String(b.name||'')));
                else if (sort==='has_email') filtered.sort((a,b)=> (b.email?1:0)-(a.email?1:0));
                else if (sort==='has_phone') filtered.sort((a,b)=> (b.phone?1:0)-(a.phone?1:0));
                renderContactsList(type, filtered);
            }
            // Populate the tag filter dropdowns with available tags from backend
            async function loadTagFilters(){
                try{
                    const {success, data} = await ajaxPost('vmo_list_tags');
                    const tags = (success && data && Array.isArray(data.tags)) ? data.tags : [];
                    const opts = ['<option value="">All tags</option>'].concat(tags.map(t=>{
                        const v = String(t.name||t).trim();
                        const label = (t.label || t.name || t).toString().replace(/</g,'&lt;');
                        return '<option value="' + v.replace(/"/g,'&quot;') + '">' + label + '</option>';
                    }));
                    const ltg = document.getElementById('vmo-crm-leads-tag'); if (ltg) ltg.innerHTML = opts.join('');
                    const ctg = document.getElementById('vmo-crm-customers-tag'); if (ctg) ctg.innerHTML = opts.join('');
                }catch(e){ /* ignore */ }
            }
            async function bulkPromoteToCustomers(){
                const ids = Array.from(window.__crmSelected.lead||[]);
                if (!ids.length) { notify('Select leads to promote','info'); return; }
                // Promote sequentially to avoid server overload
                for (const id of ids){
                    try{
                        const {success, message} = await ajaxPost('vmo_mark_as_customer', { contact_id: id });
                        if (!success) { notify(message||('Failed to promote ID '+id),'error'); }
                    }catch(e){ notify('Error promoting ID '+id+': '+e.message,'error'); }
                }
                notify('Promotion complete','success');
                window.__crmSelected.lead.clear();
                refreshLeads(); refreshCustomers();
            }
            function exportSelectedCSV(type){
                const set = window.__crmSelected && window.__crmSelected[type];
                if (!set || !set.size) { notify('Select contacts to export','info'); return; }
                const cache = window.__crmCache && window.__crmCache[type] ? window.__crmCache[type] : [];
                const byId = new Map(cache.map(c=>[c.id, c]));
                const rows = [];
                rows.push(['id','name','email','phone','type','date_added','description']);
                Array.from(set).forEach(id=>{
                    const c = byId.get(id); if (!c) return;
                    rows.push([
                        c.id,
                        (c.name||''),
                        (c.email||''),
                        (c.phone||''),
                        (c.type||type),
                        (c.date_added||''),
                        (c.description||'').replace(/\n/g,' ')
                    ]);
                });
                const csv = rows.map(r=> r.map(x=> '"'+String(x).replace(/"/g,'""')+'"').join(',')).join('\n');
                try{
                    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url; a.download = 'vmo-' + type + '-selected.csv';
                    document.body.appendChild(a); a.click(); a.remove();
                    setTimeout(()=>URL.revokeObjectURL(url), 1000);
                }catch(e){ notify('Export failed: '+e.message,'error'); }
            }
            function toggleSelectAll(type, checked){
                const listId = (type === 'lead') ? 'vmo-crm-leads-list' : 'vmo-crm-customers-list';
                const listEl = document.getElementById(listId);
                if (!window.__crmSelected) window.__crmSelected = { lead:new Set(), customer:new Set() };
                const set = window.__crmSelected[type];
                set.clear();
                if (!listEl) return;
                listEl.querySelectorAll('input.vmo-crm-select').forEach(cb=>{
                    cb.checked = !!checked;
                    const id = parseInt(cb.getAttribute('data-id')||'0',10);
                    if (checked && id) set.add(id);
                });
            }
            function bulkEmail(type){
                const listId = (type === 'lead') ? 'vmo-crm-leads-list' : 'vmo-crm-customers-list';
                const listEl = document.getElementById(listId);
                if (!listEl) return;
                const selectedRows = Array.from(listEl.querySelectorAll('input.vmo-crm-select:checked'));
                if (!selectedRows.length) { notify('Select contacts to email','info'); return; }
                const emails = [];
                selectedRows.forEach(cb=>{
                    const row = cb.closest('.nav-link');
                    const btn = row && row.querySelector('button[data-email]');
                    const email = btn && btn.getAttribute('data-email');
                    if (email) emails.push(email);
                });
                if (!emails.length) { notify('Selected contacts do not have emails','warning'); return; }
                const to = emails.shift();
                const cc = emails.join(',');
                const subj = encodeURIComponent('Hello from ' + (document.title||'our team'));
                const body = encodeURIComponent('Hi,\n\nFollowing up on our recent conversation.\n\nBest regards,');
                // Build mailto URL via concatenation to avoid any template literal parsing quirks
                let url = 'mailto:' + encodeURIComponent(to) + '?';
                if (cc) {
                    url += 'cc=' + encodeURIComponent(cc) + '&';
                }
                url += 'subject=' + subj + '&body=' + body;
                try { window.location.href = url; } catch(e) { window.open(url, '_blank'); }
            }
            async function openContactDetails(contactId, type){
                const card = document.getElementById('vmo-crm-details-card');
                if (card) { card.style.display = 'block'; card.scrollIntoView({behavior:'smooth', block:'nearest'}); }
                try{
                    const {success, data, message} = await ajaxPost('vmo_get_crm_contact_details', { contact_id: contactId });
                    if (!success || !data) { notify(message||'Failed to load details','error'); return; }
                    renderContactDetails(data, type);
                }catch(e){ notify('Error: '+e.message, 'error'); }
            }
            function renderContactDetails(payload, type){
                const c = payload.contact || {};
                const title = document.getElementById('vmo-crm-details-title');
                const meta = document.getElementById('vmo-crm-details-meta');
                const actions = document.getElementById('vmo-crm-actions');
                const callsEl = document.getElementById('vmo-crm-calls');
                const emailsEl = document.getElementById('vmo-crm-emails');
                const purEl = document.getElementById('vmo-crm-purchases');
                const totalEl = document.getElementById('vmo-crm-total-spent');
                const recoEl = document.getElementById('vmo-crm-reco');
                const relationshipEl = document.getElementById('vmo-crm-relationship-summary');
                const retentionEl = document.getElementById('vmo-crm-retention-action');
                const patternEl = document.getElementById('vmo-crm-pattern-insight');
                const tagsWrap = document.getElementById('vmo-crm-tags');
                const tagsInput = document.getElementById('vmo-crm-tags-input');
                const tagsSave = document.getElementById('vmo-crm-save-tags');
                const tasksWrap = document.getElementById('vmo-crm-tasks');
                const timelineWrap = document.getElementById('vmo-crm-timeline');
                const taskTitle = document.getElementById('vmo-crm-task-title');
                const taskDue = document.getElementById('vmo-crm-task-due');
                const taskAdd = document.getElementById('vmo-crm-add-task');
                if (title) title.textContent = (c.name ? (c.name + ' — Contact Details') : 'Contact Details');
                if (meta) {
                    var parts = [];
                    if (c.phone) parts.push('📞 ' + formatDisplayPhone(c.phone) + ' • ');
                    if (c.email) parts.push('✉️ ' + c.email + ' • ');
                    if (c.date_added) parts.push('Added ' + c.date_added.replace('T', ' '));
                    meta.textContent = parts.join('');
                }
                if (actions) {
                    actions.innerHTML = '';
                    // Primary actions
                    if (c.phone) {
                        const cb = document.createElement('button'); cb.className = 'action-btn'; cb.textContent = '📞 Call';
                        cb.addEventListener('click', ()=> callContact(c.phone));
                        actions.appendChild(cb);
                    }
                    if (c.email) {
                        const eb = document.createElement('button'); eb.className = 'action-btn'; eb.textContent = '✉️ Email';
                        eb.addEventListener('click', ()=> emailContact(c.email));
                        actions.appendChild(eb);
                    }
                    const editBtn = document.createElement('button');
                    editBtn.className = 'action-btn';
                    editBtn.textContent = 'Edit';
                    editBtn.addEventListener('click', ()=> openContactForm(c));
                    actions.appendChild(editBtn);
                    if ((c.type||type) !== 'customer') {
                        const btn = document.createElement('button');
                        btn.className = 'action-btn primary';
                        btn.textContent = 'Mark as Customer';
                        btn.addEventListener('click', ()=> markAsCustomer(c.id));
                        actions.appendChild(btn);
                    }
                }
                if (relationshipEl) relationshipEl.textContent = payload.relationship_summary || 'Relationship history is still building.';
                if (retentionEl) retentionEl.textContent = payload.retention_recommendation || payload.ai_recommendation || 'Review the next best follow-up.';
                if (patternEl) patternEl.textContent = payload.pattern_insight || 'Not enough similar contact history yet.';
                // Tags section
                if (tagsWrap) {
                    const tags = Array.isArray(c.tags) ? c.tags : (Array.isArray(payload.tags)?payload.tags:[]);
                    if (!tags.length) { tagsWrap.innerHTML = '<span style="color:var(--muted)">—</span>'; }
                    else {
                        const frag = document.createDocumentFragment();
                        tags.forEach(t=>{
                            const chip = document.createElement('span');
                            chip.className = 'nav-badge';
                            chip.textContent = String(t);
                            frag.appendChild(chip);
                        });
                        tagsWrap.innerHTML=''; tagsWrap.appendChild(frag);
                    }
                    if (tagsInput) tagsInput.value = (Array.isArray(c.tags)?c.tags:[]).join(', ');
                    if (tagsSave) {
                        tagsSave.onclick = async ()=>{
                            const raw = (tagsInput && tagsInput.value) ? tagsInput.value : '';
                            const arr = raw.split(',').map(s=>s.trim()).filter(Boolean);
                            try{
                                const payload = { contact_id: c.id, tags: arr.join(','), tags_json: JSON.stringify(arr) };
                                const {success, message} = await ajaxPost('vmo_set_contact_tags', payload);
                                if (!success) { notify(message||'Failed to save tags','error'); return; }
                                notify('Tags saved','success');
                                try { loadTagFilters(); } catch(_){ }
                                // refresh details to reflect saved tags
                                openContactDetails(c.id, c.type||type);
                            }catch(e){ notify('Error: '+e.message,'error'); }
                        };
                    }
                }
                // Calls list — use phone_history (direct from vmo_phone_calls) for rich data
                // (includes transcript, recording_url, duration, topic, summary)
                if (callsEl) {
                    const calls = Array.isArray(payload.phone_history) ? payload.phone_history : (Array.isArray(payload.calls) ? payload.calls : []);
                    if (!calls.length) {
                        callsEl.innerHTML = '<div style="color:var(--muted);">No calls</div>';
                    } else {
                        const frag = document.createDocumentFragment();
                        calls.forEach(k=>{
                            const row = document.createElement('div');
                            row.style.padding = '6px 8px';
                            row.style.borderBottom = '1px solid rgba(255,255,255,.06)';
                            const dur = (k.duration ? (Math.floor(k.duration/60)+'m '+(k.duration%60)+'s') : '0s');
                            const time = String(k.time || k.created_at || '').replace('T',' ');
                            const status = String(k.status||'');
                            const topic = k.topic ? String(k.topic).replace(/</g,'&lt;') : '';
                            const summary = k.summary ? String(k.summary).replace(/</g,'&lt;') : '';
                            const sat = (k.satisfaction!=null) ? String(k.satisfaction) : '';
                            const sid = String(k.call_sid||'').replace(/"/g,'&quot;');
                            const hasRecording = true; // Always show Listen — backend fetches from Twilio or shows transcript
                            const hasTranscript = !!(k.transcript);
                            row.innerHTML = `
                                <div><strong>${time}</strong> <small style="color:var(--muted)">${status}</small> ${k.direction ? `<small style="color:var(--muted)">(${k.direction})</small>` : ''}</div>
                                ${topic ? `<div style="font-size:11px; color:var(--muted)">Topic: ${topic}</div>` : ''}
                                ${summary ? `<div style="font-size:11px; color:var(--muted)">${summary}</div>` : ''}
                                ${sat ? `<div style="font-size:11px; color:var(--muted)">Satisfaction: ${sat}</div>` : ''}
                                <div style="display:flex; gap:8px; align-items:center; margin-top:4px;">
                                    <span style="font-size:11px; color:var(--muted)">Duration: ${dur}</span>
                                    ${hasRecording ? `<button class="action-btn" data-listen="${sid}">▶ Listen</button>` : ''}
                                    ${(hasTranscript || sid) ? `<button class="action-btn" data-transcript="${sid}">🗒 Transcript</button>` : ''}
                                </div>`;
                            const listenBtn = row.querySelector('button[data-listen]');
                            if (listenBtn) listenBtn.addEventListener('click', async ()=>{ listenToCall(listenBtn.getAttribute('data-listen')); });
                            const trBtn = row.querySelector('button[data-transcript]');
                            if (trBtn) trBtn.addEventListener('click', async ()=>{ toggleTranscript(trBtn, trBtn.getAttribute('data-transcript'), row); });
                            frag.appendChild(row);
                        });
                        callsEl.innerHTML=''; callsEl.appendChild(frag);
                    }
                }
                // Emails section
                if (emailsEl) {
                    const emails = Array.isArray(payload.email_history) ? payload.email_history : [];
                    if (!emails.length) {
                        emailsEl.innerHTML = '<div style="color:var(--muted);">No emails</div>';
                    } else {
                        const frag = document.createDocumentFragment();
                        emails.forEach(em => {
                            const row = document.createElement('div');
                            row.style.padding = '6px 8px';
                            row.style.borderBottom = '1px solid rgba(255,255,255,.06)';
                            const subj = String(em.subject || 'Email').replace(/</g, '&lt;');
                            const preview = String(em.preview || '').replace(/</g, '&lt;');
                            const time = String(em.created_at || '').replace('T', ' ');
                            const dir = em.direction === 'outbound' ? '↗ Sent' : '↙ Received';
                            const dirColor = em.direction === 'outbound' ? '#65f1ff' : '#10b981';
                            row.innerHTML = `
                                <div style="display:flex; justify-content:space-between; align-items:flex-start;">
                                    <div style="flex:1;">
                                        <div><strong style="font-size:11px; color:var(--muted);">${time}</strong>
                                            <small style="color:${dirColor}; margin-left:6px;">${dir}</small></div>
                                        <div style="font-size:12px; color:#e6f3ff; margin-top:2px;">${subj}</div>
                                        ${preview ? `<div style="font-size:11px; color:var(--muted); margin-top:2px; max-height:40px; overflow:hidden;">${preview}</div>` : ''}
                                    </div>
                                </div>`;
                            frag.appendChild(row);
                        });
                        emailsEl.innerHTML = '';
                        emailsEl.appendChild(frag);
                    }
                }
                // Purchases
                if (purEl) {
                    const pur = Array.isArray(payload.purchases) ? payload.purchases : [];
                    if (!pur.length) {
                        purEl.innerHTML = '<div style="color:var(--muted);">No purchases</div>';
                    } else {
                        const frag = document.createDocumentFragment();
                        pur.forEach(p=>{
                            const row = document.createElement('div');
                            row.style.padding = '8px 10px';
                            row.style.borderBottom = '1px solid rgba(255,255,255,.06)';
                            const amt = (typeof p.amount==='number') ? p.amount.toLocaleString(undefined,{style:'currency',currency:(p.currency||'USD')}) : (p.amount||'');
                            const product = String(p.product_service || p.product || 'Purchase').replace(/</g,'&lt;');
                            const date = String(p.date || p.purchase_date || '').replace('T',' ');
                            const status = p.status || 'completed';
                            const statusBadge = status === 'completed' ? '<span class="nav-badge" style="background:#10b981;color:#fff;">✓ Paid</span>' : 
                                               status === 'pending' ? '<span class="nav-badge" style="background:#f59e0b;color:#fff;">⏳ Pending</span>' :
                                               status === 'refunded' ? '<span class="nav-badge" style="background:#ef4444;color:#fff;">↩ Refunded</span>' : '';
                            const txId = p.transaction_id ? `<small style="color:var(--muted); font-size:10px; display:block; margin-top:2px;">ID: ${String(p.transaction_id).substring(0,20)}...</small>` : '';
                            row.innerHTML = `
                                <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:12px;">
                                    <div style="flex:1;">
                                        <div><strong style="font-size:11px;color:var(--muted);">${date}</strong></div>
                                        <div style="font-size:13px; color:#e6f3ff; margin-top:3px;">${product}</div>
                                        ${txId}
                                    </div>
                                    <div style="text-align:right;">
                                        <div style="font-size:14px; font-weight:700; color:#65f1ff;">${amt}</div>
                                        <div style="margin-top:4px;">${statusBadge}</div>
                                    </div>
                                </div>`;
                            frag.appendChild(row);
                        });
                        purEl.innerHTML=''; purEl.appendChild(frag);
                    }
                }
                if (totalEl) {
                    const v = (typeof payload.total_spent==='number') ? payload.total_spent : parseFloat(payload.total_spent||'0')||0;
                    totalEl.textContent = v.toLocaleString(undefined,{style:'currency',currency:'USD'});
                }
                if (recoEl) {
                    const staticReco = payload.ai_recommendation || '';
                    recoEl.innerHTML = '';
                    if (staticReco) {
                        const recoText = document.createElement('div');
                        recoText.style.marginBottom = '8px';
                        recoText.textContent = String(staticReco);
                        recoEl.appendChild(recoText);
                    }
                    const recoBtn = document.createElement('button');
                    recoBtn.className = 'action-btn';
                    recoBtn.textContent = '🤖 Generate AI Analysis';
                    recoBtn.style.marginTop = '4px';
                    recoBtn.addEventListener('click', async ()=>{
                        recoBtn.disabled = true;
                        recoBtn.textContent = '⏳ Analyzing...';
                        try {
                            const contactId = c.id || c.contact_id || '';
                            const {success, data, message} = await ajaxPost('vmo_generate_contact_recommendations', { contact_id: contactId });
                            if (success && data) {
                                const rText = data.recommendations || data.recommendation || (typeof data === 'string' ? data : JSON.stringify(data));
                                recoEl.innerHTML = '';
                                const recoResult = document.createElement('div');
                                recoResult.style.whiteSpace = 'pre-wrap';
                                recoResult.style.lineHeight = '1.5';
                                recoResult.style.color = 'var(--ink)';
                                recoResult.textContent = String(rText);
                                recoEl.appendChild(recoResult);
                                // Re-add button below
                                const refreshBtn = document.createElement('button');
                                refreshBtn.className = 'action-btn';
                                refreshBtn.textContent = '🔄 Refresh Analysis';
                                refreshBtn.style.marginTop = '8px';
                                refreshBtn.addEventListener('click', recoBtn.onclick);
                                refreshBtn.onclick = recoBtn.onclick;
                                recoEl.appendChild(refreshBtn);
                            } else {
                                notify(message || 'Failed to generate recommendation', 'error');
                                recoBtn.textContent = '🤖 Generate AI Analysis';
                                recoBtn.disabled = false;
                            }
                        } catch (e) {
                            notify('Error: ' + e.message, 'error');
                            recoBtn.textContent = '🤖 Generate AI Analysis';
                            recoBtn.disabled = false;
                        }
                    });
                    recoEl.appendChild(recoBtn);
                }
                // Tasks section
                if (tasksWrap) {
                    const tasks = Array.isArray(payload.tasks) ? payload.tasks : [];
                    if (!tasks.length) {
                        tasksWrap.innerHTML = '<div style="color:var(--muted);">No tasks</div>';
                    } else {
                        const frag = document.createDocumentFragment();
                        tasks.forEach(t=>{
                            const row = document.createElement('div');
                            row.style.padding = '6px 8px';
                            row.style.borderBottom = '1px solid rgba(255,255,255,.06)';
                            const id = t.id || t.task_id || '';
                            const txt = (t.title || t.text || 'Task').toString().replace(/</g,'&lt;');
                            const due = (t.due_date || t.due_at || t.due || '').toString().replace('T',' ').replace(/</g,'&lt;');
                            const done = !!(t.completed || t.is_done || t.status==='completed' || t.status===1);
                            row.innerHTML = `
                                <div style="display:flex; align-items:center; justify-content:space-between; gap:8px;">
                                    <div>
                                        <strong>${txt}</strong>
                                        ${due ? `<small style="color:var(--muted); margin-left:6px;">Due: ${due}</small>` : ''}
                                        ${done ? `<span class="nav-badge" style="margin-left:6px;">Done</span>` : ''}
                                    </div>
                                    <div style="display:flex; gap:6px;">
                                        ${done ? '' : '<button class="action-btn" data-complete>Complete</button>'}
                                        <button class="action-btn" data-delete>Delete</button>
                                    </div>
                                </div>`;
                            const btnC = row.querySelector('button[data-complete]');
                            if (btnC) btnC.addEventListener('click', async ()=>{
                                try{
                                    const {success, message} = await ajaxPost('vmo_complete_task', { id });
                                    if (!success) { notify(message||'Failed to complete task','error'); return; }
                                    notify('Task completed','success');
                                    openContactDetails(c.id, c.type||type);
                                }catch(e){ notify('Error: '+e.message,'error'); }
                            });
                            const btnD = row.querySelector('button[data-delete]');
                            if (btnD) btnD.addEventListener('click', async ()=>{
                                try{
                                    const {success, message} = await ajaxPost('vmo_delete_task', { id });
                                    if (!success) { notify(message||'Failed to delete task','error'); return; }
                                    notify('Task deleted','success');
                                    openContactDetails(c.id, c.type||type);
                                }catch(e){ notify('Error: '+e.message,'error'); }
                            });
                            frag.appendChild(row);
                        });
                        tasksWrap.innerHTML=''; tasksWrap.appendChild(frag);
                    }
                    if (taskAdd) {
                        taskAdd.onclick = async ()=>{
                            const title = (taskTitle && taskTitle.value || '').trim();
                            const due_date = (taskDue && taskDue.value || '').trim();
                            if (!title) { notify('Enter a task title','info'); return; }
                            try{
                                const {success, message} = await ajaxPost('vmo_add_task', { contact_id: c.id, title, due_date });
                                if (!success) { notify(message||'Failed to add task','error'); return; }
                                if (taskTitle) taskTitle.value = '';
                                if (taskDue) taskDue.value = '';
                                notify('Task added','success');
                                openContactDetails(c.id, c.type||type);
                            }catch(e){ notify('Error: '+e.message,'error'); }
                        };
                    }
                }
                if (timelineWrap) {
                    const timeline = Array.isArray(payload.timeline) ? payload.timeline : [];
                    if (!timeline.length) {
                        timelineWrap.innerHTML = '<div style="color:var(--muted);">No timeline entries yet</div>';
                    } else {
                        const frag = document.createDocumentFragment();
                        timeline.forEach(item=>{
                            const row = document.createElement('div');
                            row.style.padding = '7px 8px';
                            row.style.borderBottom = '1px solid rgba(255,255,255,.06)';
                            const time = String(item.datetime || '').replace('T',' ');
                            const label = escapeOptionText(item.label || item.type || 'Activity');
                            const subject = escapeOptionText(item.subject || 'Activity');
                            const summary = escapeOptionText(item.summary || '');
                            row.innerHTML = `<div style="display:flex;justify-content:space-between;gap:8px;"><strong>${label}</strong><small style="color:var(--muted);">${escapeOptionText(time)}</small></div><div style="color:#e6f3ff;margin-top:2px;">${subject}</div>${summary ? `<div style="color:var(--muted);margin-top:2px;">${summary}</div>` : ''}`;
                            frag.appendChild(row);
                        });
                        timelineWrap.innerHTML = '';
                        timelineWrap.appendChild(frag);
                    }
                }
            }
            async function markAsCustomer(contactId){
                try{
                    const {success, data, message} = await ajaxPost('vmo_mark_as_customer', { contact_id: contactId });
                    if (!success) { notify(message||'Failed to mark as customer','error'); return; }
                    notify('Marked as customer','success');
                    // Refresh lists to reflect changes
                    if (typeof loadCRMPanel === 'function') loadCRMPanel();
                    // Optionally refresh conversion stats if panel open
                    try { if (typeof loadConversionPanel==='function') loadConversionPanel(); } catch(_){}
                }catch(e){ notify('Error: '+e.message, 'error'); }
            }
            async function callContact(rawPhone){
                const to = toE164(rawPhone||'');
                if (!to) { notify('Invalid phone number','warning'); return; }
                if (!__twilioReady || !__twilioDevice) {
                    notify('Browser phone is not ready. Please allow microphone access and try again.','warning');
                    return;
                }
                notify('Placing call…','info');
                try{
                    // Direct-dial via browser SDK v2 for immediate two-way audio
                    if (__twilioConnection) { __twilioConnection.disconnect(); __twilioConnection = null; }
                    const call = await __twilioDevice.connect({ params: { To: to } });
                    __twilioConnection = call;
                    call.on('accept', function() {
                        console.log('[VMO] Contact call connected');
                    });
                    call.on('error', function(err) {
                        console.error('[VMO] Contact call error:', err);
                        notify('Call error: ' + (err.message || err), 'error');
                    });
                    call.on('disconnect', function() {
                        __twilioConnection = null;
                    });
                    window.__activeCallSid = '';
                    window.__activeConferenceName = '';
                    notify(`Calling ${formatDisplayPhone(to)}`,'success');
                }catch(e){
                    notify('Error: ' + (e.message || e),'error');
                }
            }
            function emailContact(email){
                if (!email) { notify('No email on file','warning'); return; }
                const subj = encodeURIComponent('Hello from ' + (document.title||'our team'));
                const body = encodeURIComponent('Hi,\n\nFollowing up on our recent conversation.\n\nBest regards,');
                // Build mailto URL via concatenation to avoid any template literal parsing quirks
                const url = 'mailto:' + encodeURIComponent(email) + '?subject=' + subj + '&body=' + body;
                try { window.location.href = url; } catch(e) { window.open(url, '_blank'); }
            }
            async function listenToCall(callSid){
                if (!callSid) { notify('Missing call reference','error'); return; }
                try{
                    const {success, data, message} = await ajaxPost('vmo_get_call_recordings', { call_sid: callSid });
                    console.log('[VMO CRM Listen]', callSid, {success, data, message});
                    const recs = Array.isArray(data && data.recordings) ? data.recordings : [];
                    const transcript = Array.isArray(data && data.transcript) ? data.transcript : [];
                    const r = recs[0];
                    const mediaUrl = r && (r.media_url || r.recording_url || r.url || r.uri);
                    if (typeof openRecordingModal === 'function') openRecordingModal(mediaUrl||'', { callSid, duration: (r && r.duration)||'', created: (r && (r.date_created||r.created_at))||'', transcript });
                    else if (mediaUrl) { notify('Recording is ready. Reload the dashboard and click Listen again to open the player.', 'warning'); }
                    else { openRecordingModal(null, { callSid, transcript }); }
                }catch(e){ notify('Error: '+e.message,'error'); }
            }
            async function toggleTranscript(btn, callSid, container){
                if (!callSid || !container) return;
                // If already open, collapse
                const existing = container.querySelector('.vmo-crm-transcript');
                if (existing) { existing.remove(); return; }
                const holder = document.createElement('div');
                holder.className = 'vmo-crm-transcript';
                holder.style.marginTop = '6px';
                holder.style.padding = '8px';
                holder.style.background = 'rgba(255,255,255,.03)';
                holder.style.border = '1px solid var(--border)';
                holder.style.borderRadius = '8px';
                holder.innerHTML = '<div style="color:var(--muted);">Loading transcript…</div>';
                container.appendChild(holder);
                try{
                    const {success, data, message} = await ajaxPost('vmo_get_call_details', { call_sid: callSid });
                    if (!success || !data) { holder.innerHTML = `<div style=\"color:salmon;\">${(message||'Failed to load transcript')}</div>`; return; }
                    const logs = Array.isArray(data.logs) ? data.logs : [];
                    if (!logs.length) { holder.innerHTML = '<div style="color:var(--muted);">No transcript available</div>'; return; }
                    const frag = document.createDocumentFragment();
                    logs.forEach(l=>{
                        const line = document.createElement('div');
                        line.style.fontSize = '12px';
                        line.style.margin = '2px 0';
                        const who = (l.speaker||'').toUpperCase();
                        const msg = String(l.message||'').replace(/</g,'&lt;');
                        const ts = String(l.timestamp||'').replace('T',' ');
                        line.innerHTML = `<strong style=\"color:#8dd9e6\">${who}</strong> <small style=\"color:var(--muted)\">${ts}</small><div>${msg}</div>`;
                        frag.appendChild(line);
                    });
                    holder.innerHTML=''; holder.appendChild(frag);
                }catch(e){ holder.innerHTML = '<div style="color:salmon;">Error loading transcript</div>'; }
            }
            function openWeeklyActions_legacy(){
        const m=document.getElementById('weeklyActionsModal'); if(!m) return;
        // Clear previous content while loading
        const insightsEl = document.getElementById('vmo-weekly-insights');
        const actionsEl = document.getElementById('vmo-weekly-actions');
        if (insightsEl) insightsEl.innerHTML = '<li style="color:var(--muted)">Loading…</li>';
        if (actionsEl) actionsEl.innerHTML = '<div style="color:var(--muted); padding:6px 0;">Loading…</div>';
        // Fetch latest weekly data from dashboard stats
        ajaxPost('vmo_dashboard_stats').then(({success, data})=>{
            if(!success || !data){
                if (insightsEl) insightsEl.innerHTML = '';
                if (actionsEl) actionsEl.innerHTML = '<div style="color:var(--muted);">No recommended actions available.</div>';
                return;
            }
            const weekly = data.weekly || {};
            // Insights list
            if (insightsEl){
                const ins = Array.isArray(weekly.insights) ? weekly.insights : [];
                insightsEl.innerHTML = ins.length ? ins.map(i=>`<li>${String(i).replace(/</g,'&lt;')}</li>`).join('') : '';
                if (!ins.length) insightsEl.innerHTML = '<li style="color:var(--muted)">No insights yet</li>';
            }
            // Actions list (render like tasks)
            if (actionsEl){
                const acts = Array.isArray(weekly.actions) ? weekly.actions : [];
                actionsEl.innerHTML = acts.length ? acts.map((a,idx)=>{
                    const text = (typeof a==='string') ? a : (a && a.text ? a.text : 'Action');
                    const tokenHtml = '';
                    return '<div class="task-item"><div class="task-checkbox"></div><div class="task-text">'
                        + String(text).replace(/</g,'&lt;') + '</div>' + tokenHtml + '</div>';
                }).join('') : '<div style="color:var(--muted);">No recommended actions yet</div>';
            }
        }).catch(()=>{
            if (insightsEl) insightsEl.innerHTML = '';
            if (actionsEl) actionsEl.innerHTML = '<div style="color:var(--muted);">Failed to load actions</div>';
        }).finally(()=>{
            if(window.vmoModalUtils){ try{ vmoModalUtils.open(m);}catch(e){} }
            m.classList.add('vmo-modal-visible');
            m.style.display='flex';
        });
    }
    // Legacy approveAllActions — delegates to the primary window.approveAllActions (Block 1 / Block 3)
    function approveAllActions_legacy(){
        if (typeof window.approveAllActions === 'function') { window.approveAllActions(); return; }
        const btns=[...document.querySelectorAll('#weeklyActionsModal .action-btn.primary')]; btns.forEach(b=>b.disabled=true);
        ajaxPost('vmo_approve_weekly_actions').then(({success,data,message})=>{
            btns.forEach(b=>b.disabled=false);
            if(!success){ notify(message||'Failed to approve actions','error'); return; }
            notify('Actions scheduled for today','success');
            loadDashboardOverview && loadDashboardOverview();
        }).catch(e=>{ btns.forEach(b=>b.disabled=false); notify('Error: '+e.message,'error'); });
    }
    window.customizeStrategy = function(){ window.openAddObjective(); };
        window.showWeeklyBriefing = function(weekKey) {
            const modal = document.getElementById('weeklyModal');
            const title = document.getElementById('vmo-brief-title');
            const summary = document.getElementById('vmo-brief-summary');
            const analysis = document.getElementById('vmo-brief-analysis');
            const sectionsEl = document.getElementById('vmo-brief-sections');
            summary.textContent = 'Loading…';
            analysis.textContent = '';
            if (sectionsEl) sectionsEl.innerHTML = '';
            const payload = { action:'vmo_get_weekly_briefing', security: (typeof VMO_NONCE_BUILDER!=='undefined'?VMO_NONCE_BUILDER:VMO_NONCE), nonce: (typeof VMO_NONCE_ADMIN!=='undefined'?VMO_NONCE_ADMIN:VMO_NONCE) };
            if (weekKey) payload.week = weekKey;
            const form = new URLSearchParams(payload);
            fetch(VMO_AJAX, { method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body: form })
                .then(r=>r.json()).then(({success, data})=>{
                    if (!success) { summary.textContent = 'No current research available.'; return; }
                    if (data.title) title.textContent = '📊 ' + data.title;
                    summary.textContent = data.summary || '—';
                    analysis.textContent = data.analysis || 'No comprehensive analysis available yet.';
                    if (sectionsEl && Array.isArray(data.sections) && data.sections.length) {
                        const frag = document.createDocumentFragment();
                        data.sections.forEach(sec=>{
                            const wrap = document.createElement('div');
                            wrap.className = 'vmo-card';
                            wrap.style.marginTop = '10px';
                            const h = document.createElement('h4');
                            h.textContent = sec.title || 'Update';
                            h.style.color = 'var(--cyan-soft)';
                            h.style.margin = '0 0 6px';
                            wrap.appendChild(h);
                            if (sec.content) {
                                const p = document.createElement('div');
                                p.textContent = sec.content;
                                p.style.whiteSpace = 'pre-wrap';
                                p.style.color = 'var(--ink)';
                                wrap.appendChild(p);
                            }
                            if (Array.isArray(sec.items) && sec.items.length) {
                                const ul = document.createElement('ul');
                                ul.style.margin = '6px 0 0 18px';
                                sec.items.forEach(it=>{ const li=document.createElement('li'); li.textContent = it; ul.appendChild(li); });
                                wrap.appendChild(ul);
                            }
                            frag.appendChild(wrap);
                        });
                        sectionsEl.innerHTML = '';
                        sectionsEl.appendChild(frag);
                    }
                }).catch(()=>{ summary.textContent = 'Failed to load.'; });
            if(window.vmoModalUtils){ try{ vmoModalUtils.open(modal);}catch(e){} }
            modal.classList.add('vmo-modal-visible');
            modal.style.display='flex';
            modal.setAttribute('aria-hidden','false');
        }
        window.viewMarketAnalysis = function(){ closeWeeklyBriefing(); window.openWeeklyActions(); };
        window.showPreviousScansPicker = function(){
            const box = document.getElementById('vmo-brief-history'); if(!box) return;
            const select = document.getElementById('vmo-scan-select'); if (select) { select.innerHTML = '<option>Loading…</option>'; }
            box.style.display = 'block';
            // fetch available scan weeks
            const form = new URLSearchParams({ action:'vmo_list_weekly_scans', security: (typeof VMO_NONCE_BUILDER!=='undefined'?VMO_NONCE_BUILDER:VMO_NONCE), nonce: (typeof VMO_NONCE_ADMIN!=='undefined'?VMO_NONCE_ADMIN:VMO_NONCE) });
            fetch(VMO_AJAX, { method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body: form })
                .then(r=>r.json()).then(({success, data})=>{
                    if (!success || !Array.isArray(data)) { if(select){ select.innerHTML = '<option>No history</option>'; } return; }
                    if (select) {
                        select.innerHTML = data.map(function(it){
                            var v = String(it.week).replace(/"/g,'&quot;');
                            var l = String(it.label).replace(/</g,'&lt;');
                            return '<option value="' + v + '">' + l + '</option>';
                        }).join('');
                    }
                }).catch(()=>{ if(select){ select.innerHTML = '<option>Failed to load</option>'; } });
        }
        function hidePreviousScansPicker(){ const box=document.getElementById('vmo-brief-history'); if(box) box.style.display='none'; }
        function loadSelectedScanWeek(){
            const select = document.getElementById('vmo-scan-select'); if(!select || !select.value) { return; }
            const week = select.value; hidePreviousScansPicker();
            // reload briefing with selected week
            showWeeklyBriefing(week);
        }
        function closeWeeklyBriefing(){ hideModal('weeklyModal'); }
        function hideModal(id){ const el=document.getElementById(id); if(!el) return; if(window.vmoModalUtils){ vmoModalUtils.close(el);} else { el.classList.remove('vmo-modal-visible'); setTimeout(()=>{ el.style.display='none'; },150);} el.setAttribute('aria-hidden','true'); }
        document.addEventListener('click',function(e){
            try {
                var el = e.target;
                var closeTarget = el && el.getAttribute ? el.getAttribute('data-close') : null;
                if (closeTarget) { hideModal(closeTarget); }
                if (el && el.classList && el.classList.contains('vmo-modal-overlay')){
                    var parent = el.parentElement; if (parent && parent.id) { hideModal(parent.id); }
                }
            } catch(err) {}
        });
        document.addEventListener('keydown',e=>{ if(e.key==='Escape'){ ['weeklyModal','weeklyActionsModal'].forEach(id=>hideModal(id)); } });

        // ===== Dashboard Functional Implementations =====
        async function ajaxPost(action, extra={}, spinnerSel){
            const directPhoneActionAliases = {
                vmo_get_live_calls: 'vmo_sd_phone_live',
                vmo_call_action: 'vmo_sd_phone_control',
                vmo_twilio_browser_token: 'vmo_sd_phone_token',
                vmo_end_call: 'vmo_sd_phone_end',
                vmo_get_call_transcript: 'vmo_sd_phone_transcript',
                vmo_outbound_call: 'vmo_sd_phone_outbound',
                vmo_get_phone_status: 'vmo_sd_phone_status',
                vmo_get_phone_prefs: 'vmo_sd_phone_prefs',
                vmo_save_phone_prefs: 'vmo_sd_phone_save_prefs',
                vmo_get_phone_analytics: 'vmo_sd_phone_analytics',
                vmo_get_quick_contacts: 'vmo_sd_phone_contacts',
                vmo_get_call_history: 'vmo_sd_phone_history',
                vmo_get_call_recordings: 'vmo_sd_phone_recordings',
                vmo_get_call_details: 'vmo_sd_phone_details',
                vmo_dashboard_stats: 'vmo_sd_dashboard_stats'
            };
            // Some hosting/WAF layers block specific admin-ajax action names.
            // Route ALL vmo_* actions through the allowlisted `vmo_website_chat` gateway
            // to prevent 404s from WAF interception.
            const gatewayActions = new Set([
                'vmo_get_live_calls',
                'vmo_outbound_call',
                'vmo_call_action',
                'vmo_end_call',
                'vmo_get_quick_contacts',
                'vmo_get_phone_status',
                'vmo_get_phone_prefs',
                'vmo_save_phone_prefs',
                'vmo_get_phone_analytics',
                'vmo_dashboard_stats',
                'vmo_get_call_history',
                'vmo_get_call_recordings',
                'vmo_get_call_details',
                'vmo_twilio_browser_token',
                'vmo_get_contacts',
                'vmo_get_crm_contact_details',
                'vmo_generate_contact_recommendations',
                'vmo_get_contact_communications',
                'vmo_set_contact_tags',
                'vmo_add_task',
                'vmo_complete_task',
                'vmo_delete_task',
                'vmo_list_tags',
                'vmo_get_ai_recommendations'
            ]);

            // Use gateway for ALL vmo_* actions — the Set above is kept as documentation
            // but we no longer rely on it exclusively; any vmo_ prefix triggers gateway routing.
            const aliasedAction = directPhoneActionAliases[action] || action;
            const useGateway = action.startsWith('vmo_') && aliasedAction === action;
            const safeDirectRetryActions = new Set([
                'vmo_get_live_calls',
                'vmo_call_action',
                'vmo_end_call',
                'vmo_outbound_call',
                'vmo_twilio_browser_token',
                'vmo_get_quick_contacts',
                'vmo_get_phone_status',
                'vmo_get_phone_prefs',
                'vmo_get_sms_workspace',
                'vmo_get_sms_thread'
            ]);
            const wireAction = useGateway ? 'vmo_website_chat' : aliasedAction;

            const params = new URLSearchParams({
                action: wireAction,
                // Prefer builder nonce for 'security' (most endpoints expect this)
                security: (typeof VMO_NONCE_BUILDER !== 'undefined' ? VMO_NONCE_BUILDER : VMO_NONCE),
                // Also include admin nonce under 'nonce' for endpoints that verify that key
                nonce: (typeof VMO_NONCE_ADMIN !== 'undefined' ? VMO_NONCE_ADMIN : VMO_NONCE),
                _ajax_nonce: (typeof VMO_NONCE_ADMIN !== 'undefined' ? VMO_NONCE_ADMIN : VMO_NONCE),
                ...(useGateway ? { kind: 'sd_ajax', ajax_action: action } : {}),
                ...extra
            });
            if(spinnerSel){ const el=document.querySelector(spinnerSel); if(el) el.textContent='…'; }

            // ── Helper: perform the actual fetch and parse response ──
            const __nonJsonCounts = window.__vmoNonJsonCounts || (window.__vmoNonJsonCounts = {});
            const doFetch = (bodyParams) => fetch(VMO_AJAX,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:bodyParams})
                .then(async (r)=>{
                    const text = await r.text();
                    try {
                        const json = JSON.parse(text);
                        json.__httpStatus = r.status; // stash for fallback logic
                        // Clear non-JSON counter on success
                        if (__nonJsonCounts[action]) delete __nonJsonCounts[action];
                        return json;
                    } catch (e) {
                        const preview = String(text || '')
                            .replace(/\s+/g, ' ')
                            .trim()
                            .slice(0, 300);
                        // Throttle: only log every 10th occurrence for polling actions to avoid spam
                        __nonJsonCounts[action] = (__nonJsonCounts[action] || 0) + 1;
                        const isPolling = (action === 'vmo_get_live_calls');
                        if (!isPolling || __nonJsonCounts[action] <= 2 || __nonJsonCounts[action] % 10 === 0) {
                            console.error('[VMO ajaxPost] Non-JSON response', { action, status: r.status, preview, count: __nonJsonCounts[action] });
                        }
                        // Detect session expiration (common cause: WordPress login expired)
                        if (r.status === 403 || (preview && (preview.indexOf('wp-login') !== -1 || preview.indexOf('login_error') !== -1))) {
                            if (!window.__vmoSessionWarned) {
                                window.__vmoSessionWarned = true;
                                console.error('[VMO] ⚠️ Session may have expired — please refresh the page');
                                if (typeof notify === 'function') notify('Session may have expired — please refresh the page', 'warning');
                            }
                        }
                        return {
                            success: false,
                            __httpStatus: r.status,
                            message: 'Server returned an unexpected response. Please refresh and try again.',
                            data: { http_status: r.status, raw_preview: preview }
                        };
                    }
                });

            // Primary: try through the gateway
            const result = await doFetch(params);

            // Fallback: if the gateway is blocked or returns an unusable result for
            // read-only phone actions, bypass it and call the action directly.
            const shouldRetryDirect = useGateway
                && !extra.__noFallback
                && (
                    result.__httpStatus === 403
                    || (safeDirectRetryActions.has(action) && !result.success)
                );
            if (shouldRetryDirect) {
                const retryReason = (result.__httpStatus === 403)
                    ? 'Gateway 403'
                    : 'Gateway returned an unsuccessful result';
                console.warn('[VMO ajaxPost]', retryReason, 'for', action, '— retrying direct call');
                const directParams = new URLSearchParams({
                    action: aliasedAction,
                    security: (typeof VMO_NONCE_BUILDER !== 'undefined' ? VMO_NONCE_BUILDER : VMO_NONCE),
                    nonce: (typeof VMO_NONCE_ADMIN !== 'undefined' ? VMO_NONCE_ADMIN : VMO_NONCE),
                    _ajax_nonce: (typeof VMO_NONCE_ADMIN !== 'undefined' ? VMO_NONCE_ADMIN : VMO_NONCE),
                    ...extra,
                    __noFallback: '1'
                });
                const fallback = await doFetch(directParams);
                if (fallback.__httpStatus !== 403) return fallback;
            }

            return result;
        }
        // window.notify is now defined early (right after showToast) as a
        // hoisted function declaration — see above. Removed from here to
        // avoid any race condition where code before this line calls notify().
        
	        // ===== Twilio Voice SDK v2.x — Browser Calling =====
	        var __twilioDevice = null;
	        var __twilioReady = false;
	        var __twilioConnection = null;
	        var __twilioInitPromise = null;

	        function isActiveTwilioDevice(device) {
	            if (!device || device !== __twilioDevice) return false;
	            try {
	                if (device.state === 'destroyed') return false;
	            } catch (_) {}
	            return true;
	        }

	        function attachTwilioDeviceListeners(device, identityLabel) {
	            if (!device || device.__vmoListenersAttached) return;
	            device.__vmoListenersAttached = true;

	            device.on('registered', function() {
	                if (!isActiveTwilioDevice(device)) return;
	                __twilioReady = true;
	                console.log('[VMO Twilio] ✓ Device REGISTERED — identity:', identityLabel || '(unknown)', '— ready for incoming + outgoing calls');
	            });

	            device.on('error', function(twilioError) {
	                if (!isActiveTwilioDevice(device)) return;
	                console.error('[VMO Twilio] Device error:', twilioError.message || twilioError, twilioError.code || '');
	            });

	            device.on('incoming', function(call) {
	                if (!isActiveTwilioDevice(device)) return;
	                console.log('[VMO] Twilio Device incoming call from:', call.parameters && call.parameters.From);
                window.__pendingIncomingConn = call;
                // ── Read parent call SID from custom parameters ──
                // The server passes ParentCallSid when creating the browser
                // ring leg via REST API. This eliminates the need to poll
                // vmo_get_live_calls to discover the parent SID.
                let parentCallSid = '';
                try {
                    if (call.customParameters && typeof call.customParameters.get === 'function') {
                        parentCallSid = call.customParameters.get('ParentCallSid') || '';
                    }
                } catch (_) {}
                const incomingMeta = {
                    call_sid: parentCallSid,
                    browser_call_sid: (call.parameters && call.parameters.CallSid) || '',
                    from_number: (call.parameters && call.parameters.From) || 'Unknown',
                    to_number: (window.__businessNumber || ''),
                    direction: 'inbound',
                    status: 'ringing',
                    source: parentCallSid ? 'sdk_resolved' : 'sdk_pending'
                };
                setPendingIncomingMeta(incomingMeta);
                showIncomingBannerForCall(incomingMeta, 'Listen live or take over');

                if (__ring.enabled) {
                    try { kickIncomingRing((call.parameters && call.parameters.From) || 'Unknown', true); } catch(_) {}
                }

                call.on('accept', function() {
                    if (isIncomingConnReleasedForDirectBridge(call)) return;
                    console.log('[VMO] Incoming connection accepted — browser audio active');
                    __twilioConnection = call;
                    if (window.__pendingIncomingConn === call) window.__pendingIncomingConn = null;
                    clearPendingIncomingMeta();
                    stopRinging();
                    markSidHandled(call.parameters && call.parameters.CallSid);
                    const status = document.getElementById('vmo-dialer-status');
                    if (status) status.textContent = 'Call connected';
                });

                call.on('disconnect', function() {
                    console.log('[VMO] Incoming connection disconnected');
                    if (parentCallSid) { markSidHandled(parentCallSid); }
                    const releasedForDirectBridge = isIncomingConnReleasedForDirectBridge(call);
                    if (__twilioConnection === call) __twilioConnection = null;
                    if (window.__pendingIncomingConn === call) window.__pendingIncomingConn = null;
                    clearPendingIncomingMeta();
                    stopRinging();
                    markSidHandled(call.parameters && call.parameters.CallSid);
                    if (releasedForDirectBridge) return;
                    clearEndedCallUi(parentCallSid || (call.parameters && call.parameters.CallSid) || '', 'Call ended');
                });

                call.on('cancel', function() {
                    console.log('[VMO] Browser Client dial timed out — AI is now handling the call');
                    stopRinging();
                    markSidHandled(call.parameters && call.parameters.CallSid);
                    if (parentCallSid) markSidHandled(parentCallSid);
                    // Force-mark the known parent SID handled so the UI banner stops resurrecting
                    const activeSid = window.__currentIncomingCall ? window.__currentIncomingCall.call_sid : null;
                    if (activeSid) markSidHandled(activeSid);
                    
                    // Immediately clear fallback active tracking to stop the banner
                    const state = window.__vmoDialerState || {};
                    if (state.activeCallSid === activeSid) {
                        state.activeCallSid = '';
                        state.activeConferenceName = '';
                        state.listenOnly = false;
                        state.held = false;
                    }
                    
                    const releasedForDirectBridge = isIncomingConnReleasedForDirectBridge(call);
                    if (window.__pendingIncomingConn === call) window.__pendingIncomingConn = null;
                    clearPendingIncomingMeta();
                    if (releasedForDirectBridge) return;
                    const fromEl = document.getElementById('vmo-incoming-from');
                    if (fromEl) {
                        const existing = fromEl.textContent || '';
                        if (existing.indexOf('AI handling') === -1) {
                            fromEl.textContent = existing + ' — AI handling';
                        }
                    }
                });

                call.on('reject', function() {
                    console.log('[VMO] Incoming call rejected');
                    const releasedForDirectBridge = isIncomingConnReleasedForDirectBridge(call);
                    if (window.__pendingIncomingConn === call) window.__pendingIncomingConn = null;
                    clearPendingIncomingMeta();
                    stopRinging();
                    markSidHandled(call.parameters && call.parameters.CallSid);
                    if (releasedForDirectBridge) return;
                });
            });

	            device.on('tokenWillExpire', async function() {
	                if (!isActiveTwilioDevice(device)) return;
	                console.log('[VMO Twilio] Token expiring — refreshing...');
	                try {
	                    const r = await ajaxPost('vmo_twilio_browser_token');
	                    if (isActiveTwilioDevice(device) && r && r.success && r.data && r.data.token) {
	                        device.updateToken(r.data.token);
	                        console.log('[VMO Twilio] ✓ Token refreshed');
	                    } else {
                        console.error('[VMO Twilio] ✗ Token refresh failed:', r && r.message);
                    }
                } catch(e) { console.error('[VMO Twilio] Token refresh error:', e); }
            });

	            device.on('unregistered', function() {
	                if (!isActiveTwilioDevice(device)) return;
	                console.warn('[VMO Twilio] Device UNREGISTERED — will auto-reconnect in 3s');
	                __twilioReady = false;
	                setTimeout(async function() {
	                    if (!isActiveTwilioDevice(device)) return;
	                    try {
	                        console.log('[VMO Twilio] Attempting re-registration...');
	                        const r = await ajaxPost('vmo_twilio_browser_token');
		                        if (isActiveTwilioDevice(device) && r && r.success && r.data && r.data.token) {
		                            device.updateToken(r.data.token);
		                            await device.register();
		                            if (isActiveTwilioDevice(device)) __twilioReady = true;
		                            console.log('[VMO Twilio] ✓ Re-registered successfully');
	                        }
                    } catch(e) { console.error('[VMO Twilio] Re-registration failed:', e); }
                }, 3000);
            });
        }

	        function createTwilioDevice(token, identityLabel) {
	            __twilioReady = false;
	            __twilioDevice = new Twilio.Device(token, {
	                closeProtection: true,
	                enableImplicitPermissions: false,
	                logLevel: 'warn',
	                disableAudioContextSounds: true
	            });
            attachTwilioDeviceListeners(__twilioDevice, identityLabel);
            return __twilioDevice;
        }

	        async function initTwilioDevice() {
	            if (__twilioReady && __twilioDevice) return true;
	            if (__twilioInitPromise) return __twilioInitPromise;
	            __twilioInitPromise = (async function() {
	            console.log('[VMO Twilio] Starting Device initialization...');
	            if (typeof Twilio === 'undefined' || !Twilio.Device) {
                console.warn('[VMO Twilio] SDK not loaded yet — will retry after page load...');
                // Schedule a retry: wait for the page to finish loading, then try again.
                // This handles edge cases where the SDK script hasn't finished loading yet.
                if (!window.__twilioInitRetried) {
                    window.__twilioInitRetried = true;
                    const retryInit = function() { setTimeout(initTwilioDevice, 500); };
                    if (document.readyState === 'complete' || document.readyState === 'interactive') {
                        retryInit();
                    } else {
                        window.addEventListener('DOMContentLoaded', retryInit);
                    }
                } else {
                    console.error('[VMO Twilio] SDK still not loaded after retry — browser calling unavailable. Check if twilio-voice-sdk.min.js was loaded.');
                }
	                return false;
	            }
	            try {
	                console.log('[VMO Twilio] Requesting browser token...');
                const res = await ajaxPost('vmo_twilio_browser_token');
                console.log('[VMO Twilio] Token response:', JSON.stringify(res).slice(0, 300));
                if (!res || !res.success || !res.data || !res.data.token) {
                    console.error('[VMO Twilio] ❌ Could not obtain browser-calling token.');
                    if (res && res.message) console.error('[VMO Twilio] Server said:', res.message);
                    if (res && res.__httpStatus) console.error('[VMO Twilio] HTTP status:', res.__httpStatus);
                    setTimeout(async function() {
                        console.log('[VMO Twilio] Retrying browser token...');
                        try {
                            const retry = await ajaxPost('vmo_twilio_browser_token');
                            if (retry && retry.success && retry.data && retry.data.token) {
                                createTwilioDevice(retry.data.token, retry.data.identity);
                                console.log('[VMO Twilio] Device created on retry, registering...');
                                await __twilioDevice.register();
                                console.log('[VMO Twilio] ✓ Device registered after retry. Identity:', retry.data.identity || '(check token)');
                            } else {
                                console.error('[VMO Twilio] Retry also failed — outbound/inbound browser calls unavailable');
                            }
                        } catch(retryErr) {
                            console.error('[VMO Twilio] Retry exception:', retryErr);
                        }
                    }, 10000);
	                    return false;
	                }

		                createTwilioDevice(res.data.token, res.data.identity);
		                console.log('[VMO Twilio] Registering device for incoming calls...');
		                await __twilioDevice.register();
		                if (isActiveTwilioDevice(__twilioDevice)) __twilioReady = true;
		                console.log('[VMO Twilio] ✓ Device registered. Identity:', res.data.identity || '(check token)');
		                return __twilioReady;
	            } catch (e) {
	                console.warn('[VMO Twilio] Device init failed:', e);
	                return false;
	            }
	            })().finally(function() {
	                __twilioInitPromise = null;
	            });
	            return __twilioInitPromise;
	        }
        initTwilioDevice();

        // ===== LIVE CALLS POLLING (Backup to SDK incoming event) =====
        // Poll every 5 seconds to detect incoming calls even if the
        // Twilio Device WebSocket connection is dropped or didn't fire
        // the 'incoming' event. This ensures the banner and ring always
        // appear when a call comes in.
        (function startLiveCallsPolling() {
            let pollActive = true;
            async function pollOnce() {
                if (!pollActive) return;
                try {
                    const r = await ajaxPost('vmo_get_live_calls');
                    const calls = (r && r.success && r.data && Array.isArray(r.data.calls)) ? r.data.calls : [];
                    if (typeof updateIncomingAndRing === 'function') {
                        try {
                            updateIncomingAndRing(calls);
                        } catch (ringUiError) {
                            console.error('[VMO Ring] updateIncomingAndRing failed during live poll:', ringUiError);
                        }
                    }
                    // RING-NOW SIGNAL: backend detected an active inbound call
                    // that may have been missed by the complex filtering logic.
                    // Force-ring the browser immediately.
                    if (r && r.success && r.data && r.data.ring_now && typeof kickIncomingRing === 'function') {
                        const rn = r.data.ring_now;
                        const rnSid = rn.call_sid || '';
                        if (rnSid && !window.__handledSids.has(rnSid) && !isIncomingAcknowledged(rnSid)) {
                            const seenMap = window.__ringNowSeen || (window.__ringNowSeen = Object.create(null));
                            const nowTs = Date.now();
                            const lastTs = Number(seenMap[rnSid] || 0);
                            const sameCurrent = !!(window.__currentIncomingCall && window.__currentIncomingCall.call_sid === rnSid);
                            if (!sameCurrent && (!lastTs || (nowTs - lastTs) > 15000)) {
                                seenMap[rnSid] = nowTs;
                                console.log('[VMO Poll] ring_now signal:', rn.from, 'sid:', rnSid);
                                showIncomingBannerForCall({
                                    call_sid: rnSid,
                                    from_number: (rn.from || 'Unknown'),
                                    to_number: (window.__businessNumber || ''),
                                    direction: 'inbound',
                                    status: 'ringing',
                                    source: 'ring_now'
                                }, 'Listen live or take over');
                                kickIncomingRing(rn.from || 'Unknown', true);
                            }
                        }
                    }
                } catch(e) { console.error('[VMO Ring] Live call polling error:', e); }
                if (pollActive) setTimeout(pollOnce, 3000);
            }
            // Start first poll after a short delay to let the page finish loading
            setTimeout(pollOnce, 1000);
            // Stop polling when page unloads to prevent orphan requests
            window.addEventListener('beforeunload', function() { pollActive = false; });
        })();

        /**
         * Ensure the Twilio Device is initialized and registered.
         * Attempts on-demand token fetch + registration if not ready.
         * @returns {Promise<boolean>} true if Device is ready for calls
         */
	        async function ensureTwilioDeviceReady() {
	            if (__twilioReady && __twilioDevice) return true;
	            if (__twilioInitPromise) {
	                await __twilioInitPromise;
	                return !!(__twilioReady && __twilioDevice);
	            }
	            console.log('[VMO] Device not ready — attempting on-demand initialization...');
	            try {
	                const res = await ajaxPost('vmo_twilio_browser_token');
	                if (res && res.success && res.data && res.data.token) {
	                        if (!__twilioDevice || !isActiveTwilioDevice(__twilioDevice)) {
	                            createTwilioDevice(res.data.token, res.data.identity);
	                        } else {
	                            try { __twilioDevice.updateToken(res.data.token); } catch(_) {}
	                        }
	                    await __twilioDevice.register();
	                    if (isActiveTwilioDevice(__twilioDevice)) __twilioReady = true;
	                    console.log('[VMO] On-demand Device registration succeeded. Identity:', res.data.identity);
	                    return __twilioReady;
                }
                console.error('[VMO] On-demand Device init: token request failed');
            } catch(e) {
                console.error('[VMO] On-demand Device init failed:', e);
            }
            return false;
        }

        /**
         * Join a conference via the browser speaker/microphone.
         * @param {string} conferenceName  — conference name returned by call_action
         * @param {string} mode            — 'join' (two-way) or 'listen' (muted)
         * @returns {Promise<boolean>} true if the browser connection was initiated
         */
        async function browserJoinConference(conferenceName, mode) {
            if (!conferenceName) {
                console.warn('[VMO] browserJoinConference: no conference name');
                notify('No conference to join','warning');
                return false;
            }
            if (!__twilioReady || !__twilioDevice) {
                notify('Connecting browser audio…','info');
                const ready = await ensureTwilioDeviceReady();
                if (!ready) {
                    console.error('[VMO] Browser device not available — cannot join conference');
                    notify('Browser audio unavailable — please refresh the page and try again','error');
                    return false;
                }
            }
            try {
                if (__twilioConnection) { __twilioConnection.disconnect(); __twilioConnection = null; }
                const call = await __twilioDevice.connect({ params: { conference: conferenceName, mode: mode || 'join' } });
                __twilioConnection = call;
                call.on('accept', function() {
                    console.log('[VMO] Browser audio connected to conference:', conferenceName, 'mode:', mode);
                    const state = window.__vmoDialerState || {};
                    state.listenOnly = (mode === 'listen');
                    state.held = false;
                    state.muted = (mode === 'listen');
                    if (mode === 'listen' && call && typeof call.mute === 'function') {
                        try { call.mute(true); } catch (_) {}
                    }
                    setDialerStatus((mode === 'listen') ? 'Listening…' : 'Call connected', (mode === 'listen') ? '#38bdf8' : '#10b981');
                    updateDialerActionUI();
                });
                call.on('error', function(err) {
                    console.error('[VMO] Browser connection error:', err);
                    notify('Browser audio error: ' + (err.message || err), 'error');
                });
                call.on('disconnect', function() {
                    console.log('[VMO] Browser audio disconnected from conference');
                    __twilioConnection = null;
                    const state = window.__vmoDialerState || {};
                    state.muted = false;
                    if (!state.held && !window.__outboundCallPending) {
                        setDialerStatus(state.activeCallSid ? 'Live connection closed. You can rejoin if the call is still active.' : '', state.activeCallSid ? '#94a3b8' : 'var(--muted)');
                    }
                    updateDialerActionUI();
                });
                return true;
	            } catch (e) {
	                console.error('[VMO] browserJoinConference failed:', e);
	                const errText = String((e && e.message) ? e.message : e || '');
	                if (/user gesture is required|notallowederror|permission/i.test(errText)) {
	                    notify('Browser audio was blocked before microphone access was unlocked. Click the control again and allow microphone access.', 'error');
	                } else {
	                    notify('Failed to connect browser audio: ' + errText, 'error');
	                }
	                return false;
	            }
	        }

        /** Disconnect browser audio cleanly */
        function browserDisconnect() {
            stopBridgeListenSession();
            if (__twilioConnection) { __twilioConnection.disconnect(); __twilioConnection = null; }
            try { if (__twilioDevice) __twilioDevice.disconnectAll(); } catch(e) { /* ok */ }
            const state = window.__vmoDialerState || {};
            state.muted = false;
            updateDialerActionUI();
        }

        function stopBridgeListenSession() {
            const bridge = window.__vmoBridgeListen || null;
            if (!bridge) return;
            try { if (bridge.socket) bridge.socket.close(); } catch(e) { /* ok */ }
            try { (bridge.sources || []).forEach(src => src && src.stop && src.stop()); } catch(e) { /* ok */ }
            window.__vmoBridgeListen = null;
        }

        function decodeMulawSample(byteValue) {
            const muLawByte = (~byteValue) & 0xff;
            const sign = muLawByte & 0x80;
            const exponent = (muLawByte >> 4) & 0x07;
            const mantissa = muLawByte & 0x0f;
            const bias = 0x84;
            let sample = ((mantissa << 3) + bias) << exponent;
            sample = sign ? (bias - sample) : (sample - bias);
            return sample / 32768;
        }

        function base64ToBytes(base64Payload) {
            const binary = atob(base64Payload || '');
            const bytes = new Uint8Array(binary.length);
            for (let index = 0; index < binary.length; index += 1) {
                bytes[index] = binary.charCodeAt(index);
            }
            return bytes;
        }

        function extractBridgeMediaPayload(rawMessage) {
            if (!rawMessage) return '';
            if (typeof rawMessage !== 'string') return '';
            try {
                const msg = JSON.parse(rawMessage);
                if (msg && msg.event === 'media' && msg.media && msg.media.payload) return msg.media.payload;
                if (msg && msg.type === 'media' && msg.payload) return msg.payload;
                if (msg && msg.payload) return msg.payload;
            } catch(e) {
                if (/^[A-Za-z0-9+/=]+$/.test(rawMessage)) return rawMessage;
            }
            return '';
        }

        async function startBridgeListenSession(callRef, data) {
            stopBridgeListenSession();

            const AudioContextCtor = window.AudioContext || window.webkitAudioContext;
            if (!AudioContextCtor) {
                notify('This browser cannot play live call audio.', 'error');
                return false;
            }

            const audioContext = new AudioContextCtor();
            if (audioContext.state === 'suspended') {
                try { await audioContext.resume(); } catch(e) { /* ok */ }
            }

            const bridgeState = {
                socket: null,
                audioContext,
                nextPlayTime: audioContext.currentTime + 0.08,
                sources: []
            };
            window.__vmoBridgeListen = bridgeState;

            return await new Promise(resolve => {
                let settled = false;
                let opened = false;
                const settle = value => {
                    if (settled) return;
                    settled = true;
                    resolve(value);
                };

                try {
                    const socket = new WebSocket(data.listen_url);
                    bridgeState.socket = socket;

                    socket.onopen = () => {
                        opened = true;
                        window.__activeCallSid = callRef.call_sid || '';
                        window.__activeConferenceName = '';
                        rememberLiveCall(callRef, {
                            source: callRef.source || 'phone',
                            call_sid: callRef.call_sid || '',
                            conference_name: '',
                            listenOnly: true,
                            listenMode: 'bridge_ws',
                            held: false,
                            muted: true
                        });
                        notify(data.message || 'Listening to Premium realtime audio — you are muted', 'success');
                        settle(true);
                    };

                    socket.onmessage = event => {
                        const payload = extractBridgeMediaPayload(event.data);
                        if (!payload) return;

                        let bytes;
                        try { bytes = base64ToBytes(payload); } catch(e) { return; }
                        if (!bytes.length) return;

                        const buffer = audioContext.createBuffer(1, bytes.length, 8000);
                        const channel = buffer.getChannelData(0);
                        for (let index = 0; index < bytes.length; index += 1) {
                            channel[index] = decodeMulawSample(bytes[index]);
                        }

                        const source = audioContext.createBufferSource();
                        source.buffer = buffer;
                        source.connect(audioContext.destination);
                        const playAt = Math.max(bridgeState.nextPlayTime, audioContext.currentTime + 0.02);
                        source.start(playAt);
                        bridgeState.nextPlayTime = playAt + buffer.duration;
                        bridgeState.sources.push(source);
                        source.onended = () => {
                            bridgeState.sources = bridgeState.sources.filter(item => item !== source);
                        };
                    };

                    socket.onerror = () => {
                        if (!opened) {
                            notify('Premium live audio failed to connect.', 'error');
                            stopBridgeListenSession();
                            settle(false);
                        }
                    };

                    socket.onclose = () => {
                        const activeBridge = window.__vmoBridgeListen;
                        if (activeBridge && activeBridge.socket === socket) {
                            try { (activeBridge.sources || []).forEach(src => src && src.stop && src.stop()); } catch(e) { /* ok */ }
                            window.__vmoBridgeListen = null;
                        }
                        if (!settled) {
                            notify('Premium live audio is no longer available for this call.', opened ? 'info' : 'error');
                            settle(false);
                        } else if (opened) {
                            notify('Premium live audio ended.', 'info');
                        }
                    };
                } catch(e) {
                    notify('Premium live audio could not start.', 'error');
                    stopBridgeListenSession();
                    settle(false);
                }
            });
        }

        async function startBrowserListenSession(callRef, res) {
            if (!res || !res.success) {
                notify((res && res.message) || 'Listen failed', 'error');
                return false;
            }

            const data = res.data || {};
            if (data.mode === 'bridge_ws' && data.listen_url) {
                return await startBridgeListenSession(callRef, data);
            }

            if (data.mode === 'realtime_monitor' || data.mode === 'transcript') {
                // Note: premium tier is handled by the backend — if we reach this
                // point with transcript mode it means no live bridge is available
                // for this specific call. Show transcript monitoring regardless of
                // tier; the user can still Take Over at any time.
                showLiveTranscript(callRef.call_sid || '', (data.transcript || ''));
                if (data.mode === 'realtime_monitor') {
                    showRealtimeMonitor(callRef.call_sid || '', data);
                }
                rememberLiveCall(callRef, {
                    source: callRef.source || 'phone',
                    call_sid: callRef.call_sid || '',
                    conference_name: '',
                    listenOnly: true,
                    listenMode: 'transcript',
                    held: false,
                    muted: false
                });
                notify('Monitoring AI call via transcript — tap Take Over to speak directly', 'success');
                return true;
            }

            const confName = data.conference_name || '';
            if (data.bridge_pending) {
                notify(data.message || 'Live listen bridge is still connecting. Please try again in a moment.', 'error');
                return false;
            }
            if (!confName) {
                notify(data.message || 'Live listen bridge is not available for this call.', 'error');
                return false;
            }

	            const audioReady = await prepareBrowserLiveAudio({
	                required: true,
	                actionLabel: 'listen to the live call'
	            });
	            if (!audioReady) {
	                return false;
	            }

	            const joined = await browserJoinConference(confName, 'listen');
            if (!joined) {
                return false;
            }

            window.__activeCallSid = callRef.call_sid || '';
            window.__activeConferenceName = confName;
            rememberLiveCall(callRef, {
                source: callRef.source || 'phone',
                call_sid: callRef.call_sid || '',
                conference_name: confName,
                listenOnly: true,
                listenMode: 'live',
                held: false,
                muted: true
            });
            notify(data.message || 'Listening — you are muted', 'success');
            return true;
        }

        // ===== Live Transcript Monitor =====
        let __transcriptPollTimer = null;

        /**
         * Show a live transcript panel for an AI-handled call.
         * Polls the backend every 3s for updated transcript text.
         */
        function showLiveTranscript(callSid, initialTranscript) {
            // Create or reuse the transcript panel
            let panel = document.getElementById('vmo-live-transcript-panel');
            if (!panel) {
                panel = document.createElement('div');
                panel.id = 'vmo-live-transcript-panel';
                panel.style.cssText = 'position:fixed;bottom:80px;right:20px;width:400px;max-height:400px;background:var(--bg-dark,#1a1a2e);border:1px solid var(--accent,#00d4ff);border-radius:12px;padding:16px;z-index:10001;box-shadow:0 8px 32px rgba(0,0,0,0.5);font-family:inherit;color:var(--text,#e0e0e0);display:flex;flex-direction:column;';
                document.body.appendChild(panel);
            }
            panel.innerHTML = `
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
                    <strong style="color:var(--accent,#00d4ff);font-size:14px;">🎙️ AI Live Transcript</strong>
                    <div style="display:flex;gap:6px;">
                        <button id="vmo-transcript-takeover" style="background:var(--accent,#00d4ff);color:#000;border:none;border-radius:6px;padding:4px 10px;cursor:pointer;font-size:12px;font-weight:600;">Take Over</button>
                        <button id="vmo-transcript-close" style="background:transparent;color:var(--muted,#888);border:1px solid var(--muted,#555);border-radius:6px;padding:4px 8px;cursor:pointer;font-size:12px;">✕</button>
                    </div>
                </div>
                <div id="vmo-transcript-content" style="overflow-y:auto;max-height:300px;font-size:13px;line-height:1.5;white-space:pre-wrap;word-wrap:break-word;padding:8px;background:rgba(0,0,0,0.3);border-radius:8px;flex:1;"></div>
                <div style="margin-top:8px;font-size:11px;color:var(--muted,#888);">Refreshing every 3s • Click "Take Over" to join the call</div>
            `;
            panel.style.display = 'flex';

            const contentEl = document.getElementById('vmo-transcript-content');
            if (contentEl) contentEl.textContent = initialTranscript || 'Waiting for conversation...';

            // Close button
            document.getElementById('vmo-transcript-close').addEventListener('click', () => {
                closeLiveTranscript();
            });

            // Take Over button — joins the conference (interrupts AI)
	            document.getElementById('vmo-transcript-takeover').addEventListener('click', async () => {
	                try {
	                    const audioReady = await prepareBrowserLiveAudio({
	                        required: true,
	                        actionLabel: 'take over the live call'
	                    });
	                    if (!audioReady) {
	                        return;
	                    }
	                    const res = await ajaxPost('vmo_call_action', { action_type: 'join', call_sid: callSid, conference_sid: '', via: 'browser' });
	                    if (!res.success) { notify(res.message || 'Join failed', 'error'); return; }
                    const cn = (res.data && res.data.conference_name) || '';
                    if (cn) {
                        const joined = await browserJoinConference(cn, 'join');
                        if (!joined) {
                            notify('Failed to connect browser audio for this call', 'error');
                            return;
                        }
                    }
                    rememberLiveCall({ call_sid: callSid, source: 'phone' }, {
                        source: 'phone',
                        call_sid: callSid,
                        conference_name: cn,
                        listenOnly: false,
                        held: false,
                        muted: false
                    });
                    acknowledgeIncomingSid(callSid);
                    notify('Took over call from AI', 'success');
                    closeLiveTranscript();
                    stopRinging();
                    updateIncomingAndRing(window.__lastLiveCallsSnapshot || []);
                } catch (e) { notify('Error: ' + e.message, 'error'); }
            });

            // Start polling for transcript updates
            if (__transcriptPollTimer) clearInterval(__transcriptPollTimer);
            __transcriptPollTimer = setInterval(async () => {
                try {
                    const res = await ajaxPost('vmo_get_call_transcript', { call_sid: callSid });
                    if (res && res.success && res.data) {
                        if (contentEl && res.data.transcript) {
                            contentEl.textContent = res.data.transcript;
                            contentEl.scrollTop = contentEl.scrollHeight;
                        }
                        // If call ended or AI no longer handling, close panel
                        if (res.data.status === 'completed') {
                            closeLiveTranscript();
                            notify('Call ended', 'info');
                        }
                    }
                } catch (e) { /* silent */ }
            }, 3000);
        }

        function closeLiveTranscript() {
            if (__transcriptPollTimer) { clearInterval(__transcriptPollTimer); __transcriptPollTimer = null; }
            const panel = document.getElementById('vmo-live-transcript-panel');
            if (panel) panel.style.display = 'none';
            window.__listenCallSid = null;
        }

        /**
         * Show a Realtime AI monitoring panel for SIP-bridged calls.
         * The call is a direct SIP connection to OpenAI — no live audio
         * stream is available without breaking the AI. Shows status and
         * offers Take Over (which will disconnect the AI from the call).
         */
        function showRealtimeMonitor(callSid, data) {
            // Reuse transcript panel element
            let panel = document.getElementById('vmo-live-transcript-panel');
            if (!panel) {
                panel = document.createElement('div');
                panel.id = 'vmo-live-transcript-panel';
                panel.style.cssText = 'position:fixed;bottom:80px;right:20px;width:400px;max-height:400px;background:var(--bg-dark,#1a1a2e);border:1px solid var(--accent,#00d4ff);border-radius:12px;padding:16px;z-index:10001;box-shadow:0 8px 32px rgba(0,0,0,0.5);font-family:inherit;color:var(--text,#e0e0e0);display:flex;flex-direction:column;';
                document.body.appendChild(panel);
            }
            const recNote = data.recording_enabled
                ? '<div style="margin-top:4px;font-size:11px;color:var(--muted,#888);">🔴 Recording enabled — playback available after call ends</div>'
                : '';
            const startedAt = data.started_at ? new Date(data.started_at + ' UTC') : null;
            panel.innerHTML = `
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
                    <strong style="color:var(--accent,#00d4ff);font-size:14px;">⚡ Realtime AI Active</strong>
                    <div style="display:flex;gap:6px;">
                        <button id="vmo-rt-takeover" style="background:#ff6b35;color:#fff;border:none;border-radius:6px;padding:4px 10px;cursor:pointer;font-size:12px;font-weight:600;">Take Over</button>
                        <button id="vmo-rt-close" style="background:transparent;color:var(--muted,#888);border:1px solid var(--muted,#555);border-radius:6px;padding:4px 8px;cursor:pointer;font-size:12px;">✕</button>
                    </div>
                </div>
                <div style="padding:12px;background:rgba(0,0,0,0.3);border-radius:8px;font-size:13px;line-height:1.6;">
                    <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
                        <span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#00ff88;animation:vmo-rt-pulse 1.5s ease-in-out infinite;"></span>
                        <span>AI is speaking with the caller via Realtime voice</span>
                    </div>
                    <div id="vmo-rt-duration" style="color:var(--muted,#888);font-size:12px;"></div>
                    ${recNote}
                </div>
                <div style="margin-top:8px;font-size:11px;color:var(--muted,#888);">
                    "Take Over" disconnects the AI and connects you to the caller
                </div>
                <style>@keyframes vmo-rt-pulse{0%,100%{opacity:1}50%{opacity:.3}}</style>
            `;
            panel.style.display = 'flex';

            // Duration timer
            const durEl = document.getElementById('vmo-rt-duration');
            let rtDurTimer = null;
            if (durEl && startedAt && !isNaN(startedAt.getTime())) {
                rtDurTimer = setInterval(() => {
                    const secs = Math.floor((Date.now() - startedAt.getTime()) / 1000);
                    const m = Math.floor(secs / 60);
                    const s = secs % 60;
                    durEl.textContent = 'Duration: ' + m + ':' + String(s).padStart(2, '0');
                }, 1000);
            }

            // Close
            document.getElementById('vmo-rt-close').addEventListener('click', () => {
                if (rtDurTimer) clearInterval(rtDurTimer);
                panel.style.display = 'none';
            });

            // Take Over — redirect the call to conference (breaks SIP)
	            document.getElementById('vmo-rt-takeover').addEventListener('click', async () => {
	                if (!confirm('This will disconnect the AI from the call. Continue?')) return;
	                try {
	                    const audioReady = await prepareBrowserLiveAudio({
	                        required: true,
	                        actionLabel: 'take over the live call'
	                    });
	                    if (!audioReady) {
	                        return;
	                    }
	                    const res = await ajaxPost('vmo_call_action', { action_type: 'join', call_sid: callSid, conference_sid: '', via: 'browser' });
	                    if (!res.success) { notify(res.message || 'Take over failed', 'error'); return; }
                    const cn = (res.data && res.data.conference_name) || '';
                    if (cn) {
                        const joined = await browserJoinConference(cn, 'join');
                        if (!joined) {
                            notify('Failed to connect browser audio for this call', 'error');
                            return;
                        }
                    }
                    rememberLiveCall({ call_sid: callSid, source: 'phone' }, {
                        source: 'phone',
                        call_sid: callSid,
                        conference_name: cn,
                        listenOnly: false,
                        held: false,
                        muted: false
                    });
                    acknowledgeIncomingSid(callSid);
                    notify('Took over call from AI', 'success');
                    if (rtDurTimer) clearInterval(rtDurTimer);
                    panel.style.display = 'none';
                    stopRinging();
                    updateIncomingAndRing(window.__lastLiveCallsSnapshot || []);
                } catch (e) { notify('Error: ' + e.message, 'error'); }
            });

            // Poll to detect when call ends — close panel automatically
            if (__transcriptPollTimer) clearInterval(__transcriptPollTimer);
            __transcriptPollTimer = setInterval(async () => {
                try {
                    const res = await ajaxPost('vmo_get_live_calls');
                    const liveCalls = (res && res.success && res.data && Array.isArray(res.data.calls)) ? res.data.calls : [];
                    const stillActive = liveCalls.some(c => c.call_sid === callSid);
                    if (!stillActive) {
                        if (rtDurTimer) clearInterval(rtDurTimer);
                        closeLiveTranscript();
                        notify('Realtime call ended', 'info');
                    }
                } catch (_) { /* silent */ }
            }, 5000);
        }

        /**
         * Resume AI — hand a call back to the AI receptionist after user takeover.
         */
        async function resumeAI(callSid, options) {
            options = options || {};
            if (!callSid) { notify('No active call', 'warning'); return; }
            try {
                const res = await ajaxPost('vmo_call_action', { action_type: 'resume_ai', call_sid: callSid, conference_sid: '', via: 'browser' });
                if (!res.success) { notify(res.message || 'Resume failed', 'error'); return; }
                browserDisconnect();
                if (!options.preserveCallReference) {
                    clearDialerLiveState();
                }
                if (!options.silentNotice) {
                    notify('Call handed back to AI', 'success');
                }
                return true;
            } catch (e) { notify('Error: ' + e.message, 'error'); }
            return false;
        }

        /* =============================================
         * SMS Activation Wizard Functions
         * ============================================= */
        function openSMSActivation() {
            const modal = document.getElementById('vmo-sms-activation-modal');
            if (!modal) return;
            modal.style.display = 'flex';
            showSMSStep(1);
            vmoSyncSmsIntentUI(window.__vmoSmsState && window.__vmoSmsState.summary ? window.__vmoSmsState.summary : null);
            try {
                vmoCheckA2PStatus({ silent: true });
            } catch (e) {}
        }

        function vmoGetSelectedSmsIntent() {
            const selected = document.querySelector('input[name="a2p-registration-intent"]:checked');
            return selected ? String(selected.value || 'regular') : 'regular';
        }

        function vmoSyncSmsIntentUI(summary, options) {
            options = options || {};
            const selectedIntent = vmoGetSelectedSmsIntent();
            const intent = options.preferSelected
                ? selectedIntent
                : ((summary && summary.registration_intent) ? String(summary.registration_intent) : selectedIntent);
            const summaryBox = document.getElementById('vmo-a2p-intent-summary');
            const guidanceBox = document.getElementById('vmo-a2p-campaign-guidance');
            const useCaseSelect = document.getElementById('a2p-use-case');
            const marketingOption = useCaseSelect ? useCaseSelect.querySelector('option[value="MARKETING"]') : null;
            const confirmBox = document.getElementById('a2p-fee-confirm');
            const regularRadio = document.getElementById('a2p-intent-regular');
            const marketingRadio = document.getElementById('a2p-intent-marketing');

            if (regularRadio) regularRadio.checked = intent !== 'marketing';
            if (marketingRadio) marketingRadio.checked = intent === 'marketing';

            if (summaryBox) {
                if (intent === 'marketing') {
                    summaryBox.style.borderColor = 'rgba(245,158,11,.28)';
                    summaryBox.style.background = 'rgba(245,158,11,.08)';
                    summaryBox.innerHTML = '<strong style="color:#f59e0b;">Bulk-marketing-capable path selected.</strong> This path is for promotional or mass SMS campaigns later. Carrier/compliance monthly billing can be higher, so choose it only if you truly need marketing-ready SMS approval.';
                } else {
                    summaryBox.style.borderColor = 'rgba(56,189,248,.22)';
                    summaryBox.style.background = 'rgba(56,189,248,.08)';
                    summaryBox.innerHTML = '<strong style="color:#38bdf8;">Regular business SMS path selected.</strong> This keeps the registration focused on customer communication, reminders, support, and operational messaging. Carrier/compliance monthly billing can still apply, but you are not deliberately registering as a bulk-marketing-capable path.';
                }
            }

            if (guidanceBox) {
                guidanceBox.innerHTML = intent === 'marketing'
                    ? 'You selected the marketing-capable path. Pick a campaign use case that matches promotional or broader outreach activity, and confirm you are comfortable with the recurring carrier/compliance billing before you submit.'
                    : 'You selected the regular business SMS path. Choose a customer-care or operational use case that matches how you will actually text customers. Bulk marketing tools will stay blocked until you deliberately register for a marketing-capable path later.';
            }

            if (marketingOption) {
                marketingOption.disabled = intent !== 'marketing';
                if (intent !== 'marketing' && useCaseSelect && useCaseSelect.value === 'MARKETING') {
                    useCaseSelect.value = 'CUSTOMER_CARE';
                }
                if (intent === 'marketing' && useCaseSelect && (!useCaseSelect.value || useCaseSelect.value === 'CUSTOMER_CARE')) {
                    useCaseSelect.value = 'MARKETING';
                }
            }

            if (confirmBox) {
                if (summary && summary.registration_intent && summary.registration_intent === intent) {
                    confirmBox.checked = true;
                } else if (options.preferSelected) {
                    confirmBox.checked = false;
                }
            }
        }

        function vmoSyncSmsCampaignControls(summary) {
            const cancelBtn = document.getElementById('vmo-a2p-cancel-btn');
            const cancelMeta = document.getElementById('vmo-a2p-cancel-meta');
            if (!cancelBtn || !cancelMeta) return;

            const hasCampaign = !!(summary && (summary.campaign_status && String(summary.campaign_status).toUpperCase() !== 'NOT_STARTED'));
            const cancelled = !!(summary && summary.campaign_cancelled);
            const cancelledAt = summary && summary.campaign_cancelled_at ? vmoFormatSmsStatusDate(summary.campaign_cancelled_at) : '';
            const nextBilling = summary && summary.campaign_next_billing ? vmoFormatSmsStatusDate(summary.campaign_next_billing) : '';
            const intent = String(summary && summary.registration_intent || vmoGetSelectedSmsIntent());

            cancelBtn.disabled = !hasCampaign;
            cancelBtn.style.opacity = hasCampaign ? '1' : '0.5';

            if (!hasCampaign) {
                cancelMeta.textContent = 'Campaign cancellation becomes available after a campaign has been submitted.';
                return;
            }

            if (cancelled) {
                cancelBtn.textContent = 'Campaign Cancelled in VMO';
                cancelBtn.disabled = true;
                cancelBtn.style.opacity = '0.7';
                cancelMeta.textContent = cancelledAt
                    ? ('Cancellation recorded in VMO on ' + cancelledAt + '. Bulk marketing tools should remain blocked until you register again.')
                    : 'Cancellation has been recorded in VMO. Bulk marketing tools should remain blocked until you register again.';
                return;
            }

            cancelBtn.textContent = 'Cancel SMS Campaign Registration';
            cancelMeta.textContent = intent === 'marketing'
                ? ('Marketing-capable registration is active. ' + (nextBilling ? ('Next carrier/compliance billing reference: ' + nextBilling + '.') : 'Cancelling here removes marketing-ready status inside VMO.'))
                : 'This path is registered for regular business SMS. Cancelling may remove future marketing-ready status and may require re-registration later.';
        }

        function showSMSStep(step) {
            // Hide all panes
            for (let i = 1; i <= 4; i++) {
                const pane = document.getElementById('vmo-sms-step-' + i);
                if (pane) pane.style.display = (i === step) ? 'block' : 'none';
            }
            // Update step indicators
            document.querySelectorAll('#vmo-sms-steps .vmo-sms-step').forEach(el => {
                const s = parseInt(el.getAttribute('data-step'));
                if (s <= step) {
                    el.style.background = step === 4 ? '#10b981' : (step === 3 ? '#8b5cf6' : (step === 2 ? '#3b82f6' : '#f59e0b'));
                } else {
                    el.style.background = 'rgba(255,255,255,.12)';
                }
            });
            if (step === 1 || step === 3) {
                vmoSyncSmsIntentUI(window.__vmoSmsState && window.__vmoSmsState.summary ? window.__vmoSmsState.summary : null, { preferSelected: true });
            }
            if (step === 4) {
                vmoSyncSmsCampaignControls(window.__vmoSmsState && window.__vmoSmsState.summary ? window.__vmoSmsState.summary : null);
            }
        }

        function vmoHumanizeSmsA2PStatus(status) {
            const normalized = String(status || 'not_started').trim().toUpperCase();
            if (!normalized || normalized === 'UNKNOWN') return 'Unknown';
            if (normalized === 'NOT_STARTED') return 'Not Started';
            if (normalized === 'IN_PROGRESS') return 'In Progress';
            if (normalized === 'CANCELLED') return 'Cancelled';
            return normalized.replace(/_/g, ' ');
        }

        function vmoFormatSmsStatusDate(value) {
            if (!value) return '';
            const date = new Date(String(value).replace(' ', 'T'));
            if (Number.isNaN(date.getTime())) return String(value);
            return date.toLocaleString([], { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' });
        }

        function vmoGetSmsActivationPresentation(summary) {
            const brand = String(summary && summary.brand_status || 'not_started').toUpperCase();
            const campaign = String(summary && summary.campaign_status || 'not_started').toUpperCase();
            const isActive = !!(summary && summary.sms_active);
            const trackedInPlugin = !(summary && summary.tracked_in_plugin === false);
            const activatedAt = vmoFormatSmsStatusDate(summary && summary.sms_activated_at);
            const checkedAt = vmoFormatSmsStatusDate(summary && (summary.sms_checked_at || summary.checked_at));
            const campaignCancelled = !!(summary && summary.campaign_cancelled);
            const campaignCancelledAt = vmoFormatSmsStatusDate(summary && summary.campaign_cancelled_at);
            const registrationIntent = String(summary && summary.registration_intent || vmoGetSelectedSmsIntent());

            if (isActive) {
                if (campaignCancelled) {
                    return {
                        label: 'SMS Active',
                        tone: '#38bdf8',
                        headline: 'Regular SMS stays active, but the campaign registration is cancelled in VMO.',
                        detail: campaignCancelledAt ? ('Cancellation recorded ' + campaignCancelledAt + '.') : 'Marketing-ready status has been withdrawn inside VMO.',
                        meta: 'Bulk marketing tools should stay blocked until you deliberately register again for a marketing-capable path.'
                    };
                }
                return {
                    label: 'Active',
                    tone: '#10b981',
                    headline: 'SMS is live on this number.',
                    detail: activatedAt ? ('Activated ' + activatedAt + '.') : 'Your business number can send and receive SMS now.',
                    meta: checkedAt ? ('Last checked ' + checkedAt + '.') : 'VMO keeps this status in sync automatically.'
                };
            }

            if (['FAILED', 'REJECTED'].includes(brand) || ['FAILED', 'REJECTED'].includes(campaign)) {
                return {
                    label: 'Needs attention',
                    tone: '#ef4444',
                    headline: 'Carrier review needs attention.',
                    detail: 'Brand: ' + vmoHumanizeSmsA2PStatus(brand) + '. Campaign: ' + vmoHumanizeSmsA2PStatus(campaign) + '.',
                    meta: 'Open SMS Activation to review the registration status from inside VMO.'
                };
            }

            if (!trackedInPlugin) {
                return {
                    label: 'Activation needed',
                    tone: '#f59e0b',
                    headline: 'This number needs an internal registration sync.',
                    detail: 'VMO has not imported carrier approval records for this number yet. If this is an already approved internal test number, use Check Registration Status to validate it inside VMO.',
                    meta: checkedAt ? ('Last checked ' + checkedAt + '. Finish any remaining carrier registration outside VMO first, then return here to sync the approved number.') : 'Use Check Registration Status after the external registration is fully finished, or continue the in-plugin flow for a brand-new number.'
                };
            }

            if (campaignCancelled) {
                return {
                    label: 'Cancelled',
                    tone: '#ef4444',
                    headline: 'The SMS campaign registration has been cancelled in VMO.',
                    detail: registrationIntent === 'marketing'
                        ? 'Marketing-ready status has been withdrawn. Regular texting may require a new registration path if you need it again.'
                        : 'Bulk-marketing-ready status is no longer available for this number inside VMO.',
                    meta: 'Register again from this activation center whenever you want to restore that capability.'
                };
            }

            if ((brand === 'APPROVED' || brand === 'VERIFIED') && campaign === 'NOT_STARTED') {
                return {
                    label: 'Action required',
                    tone: '#f59e0b',
                    headline: 'Brand approved. Campaign registration is still required.',
                    detail: 'SMS cannot go live until you submit the messaging campaign inside VMO. That campaign step is required by carriers/compliance partners, not by VMO.',
                    meta: checkedAt ? ('Last checked ' + checkedAt + '. The campaign charge is an external carrier/compliance cost paid from your VMO balance for convenience.') : 'The campaign charge is an external carrier/compliance cost paid from your VMO balance for convenience.'
                };
            }

            if (campaign !== 'NOT_STARTED' && !['VERIFIED', 'APPROVED', 'ACTIVE', 'FAILED', 'REJECTED'].includes(campaign)) {
                return {
                    label: 'Pending approval',
                    tone: '#f59e0b',
                    headline: 'Campaign review is still in progress.',
                    detail: 'Your messaging campaign has been submitted for carrier review. No action is usually required right now unless the carrier requests changes.',
                    meta: checkedAt ? ('Last checked ' + checkedAt + '. VMO will email and alert you when approval is complete.') : 'VMO will email and alert you when approval is complete.'
                };
            }

            if (brand !== 'NOT_STARTED' && !['APPROVED', 'VERIFIED', 'FAILED', 'REJECTED'].includes(brand) && campaign === 'NOT_STARTED') {
                return {
                    label: 'Pending approval',
                    tone: '#f59e0b',
                    headline: 'Brand review is still in progress.',
                    detail: 'Your business brand details are under carrier review. The campaign step becomes available after brand approval is complete.',
                    meta: checkedAt ? ('Last checked ' + checkedAt + '. VMO will email and alert you when the next step is ready.') : 'VMO will email and alert you when the next step is ready.'
                };
            }

            if (brand !== 'NOT_STARTED' || campaign !== 'NOT_STARTED') {
                return {
                    label: 'Pending approval',
                    tone: '#f59e0b',
                    headline: 'Carrier review is still in progress.',
                    detail: 'Brand: ' + vmoHumanizeSmsA2PStatus(brand) + '. Campaign: ' + vmoHumanizeSmsA2PStatus(campaign) + '.',
                    meta: checkedAt ? ('Last checked ' + checkedAt + '. VMO will switch SMS to active automatically once carrier approval is confirmed and will notify you when that happens.') : 'VMO will switch SMS to active automatically once carrier approval is confirmed and will notify you when that happens.'
                };
            }

            return {
                label: 'Activation needed',
                tone: '#f59e0b',
                headline: 'SMS is not live yet.',
                detail: 'No approved A2P campaign has been recorded in VMO for this business number.',
                meta: 'Complete brand and campaign registration inside VMO to activate texting. These are carrier/compliance requirements, not VMO-created requirements.'
            };
        }

        function vmoSyncSmsActivationButton(summary) {
            const dashBtn = document.getElementById('vmo-activate-sms-btn');
            if (!dashBtn) return;

            const activation = vmoGetSmsActivationPresentation(summary || {});
            const label = summary && summary.sms_active
                ? '✅ SMS Active'
                : (activation.label === 'Pending approval' ? '⏳ SMS Pending' : '💬 Activate SMS');

            dashBtn.innerHTML = label;
            dashBtn.style.borderColor = activation.tone;
            dashBtn.style.color = activation.tone;
            dashBtn.style.background = activation.tone === '#10b981'
                ? 'rgba(16,185,129,0.08)'
                : (activation.tone === '#ef4444' ? 'rgba(239,68,68,0.08)' : 'rgba(245,158,11,0.08)');
        }

        function vmoRenderSmsActivationStatusMeta(summary) {
            const meta = document.getElementById('vmo-a2p-status-meta');
            if (!meta) return;

            const activation = vmoGetSmsActivationPresentation(summary || {});
            meta.style.borderColor = activation.tone === '#10b981'
                ? 'rgba(16,185,129,.25)'
                : (activation.tone === '#ef4444' ? 'rgba(239,68,68,.25)' : 'rgba(245,158,11,.25)');
            meta.style.background = activation.tone === '#10b981'
                ? 'rgba(16,185,129,.08)'
                : (activation.tone === '#ef4444' ? 'rgba(239,68,68,.08)' : 'rgba(245,158,11,.08)');
            meta.innerHTML = '<strong style="color:' + activation.tone + ';">' + vmoSmsEsc(activation.headline) + '</strong> '
                + vmoSmsEsc(activation.detail)
                + (activation.meta ? (' ' + vmoSmsEsc(activation.meta)) : '');
        }

        // ═══════════════════════════════════════════════════════════════
        // A2P 10DLC Registration Handlers
        // ═══════════════════════════════════════════════════════════════

        /**
         * Submit A2P Brand Registration
         * Collects business info from the Step 2 form and sends to the PHP AJAX handler.
         */
        async function vmoSubmitA2PBrand() {
            const btn = document.getElementById('vmo-a2p-brand-submit');
            const status = document.getElementById('vmo-a2p-brand-status');
            if (!btn || !status) return;
            const feeConfirm = document.getElementById('a2p-fee-confirm');
            const registrationIntent = vmoGetSelectedSmsIntent();

            // Collect form values
            const businessName = document.getElementById('a2p-business-name')?.value?.trim() || '';
            const ein = document.getElementById('a2p-ein')?.value?.trim() || '';
            const businessType = document.getElementById('a2p-business-type')?.value || '';
            const industry = document.getElementById('a2p-industry')?.value || '';
            const street = document.getElementById('a2p-street')?.value?.trim() || '';
            const city = document.getElementById('a2p-city')?.value?.trim() || '';
            const state = document.getElementById('a2p-state')?.value?.trim() || '';
            const zip = document.getElementById('a2p-zip')?.value?.trim() || '';
            const website = document.getElementById('a2p-website')?.value?.trim() || '';
            const contactName = document.getElementById('a2p-contact-name')?.value?.trim() || '';
            const contactEmail = document.getElementById('a2p-contact-email')?.value?.trim() || '';
            const contactPhone = document.getElementById('a2p-contact-phone')?.value?.trim() || '';

            // Client-side validation
            const missing = [];
            if (!businessName) missing.push('Business Name');
            if (!ein) missing.push('EIN / Tax ID');
            if (!street) missing.push('Street Address');
            if (!city) missing.push('City');
            if (!state) missing.push('State');
            if (!zip) missing.push('ZIP');
            if (!contactName) missing.push('Contact Name');
            if (!contactEmail) missing.push('Contact Email');
            if (!contactPhone) missing.push('Contact Phone');

            if (missing.length) {
                status.style.display = 'block';
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '⚠️ Please fill in: ' + missing.join(', ');
                return;
            }

            if (!feeConfirm || !feeConfirm.checked) {
                status.style.display = 'block';
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '⚠️ Please confirm the carrier/compliance fee explanation before continuing.';
                return;
            }

            // Split contact name
            const nameParts = contactName.split(' ');
            const firstName = nameParts[0] || '';
            const lastName = nameParts.slice(1).join(' ') || '';

            btn.disabled = true;
            btn.innerHTML = '<span class="vmo-spinner-sm"></span> Registering Brand...';
            btn.style.opacity = '0.7';
            status.style.display = 'block';
            status.style.background = 'rgba(59,130,246,0.08)';
            status.style.color = '#94a3b8';
            status.innerHTML = '⏳ Submitting brand registration to the carrier review service... This may take 10–20 seconds.';

            try {
                const res = await jQuery.ajax({
                    url: '<?php echo admin_url("admin-ajax.php"); ?>',
                    method: 'POST',
                    data: {
                        action: 'vmo_a2p_register_brand',
                        security: '<?php echo wp_create_nonce("vmo_admin_nonce"); ?>',
                        business_name: businessName,
                        ein: ein,
                        business_type: businessType,
                        industry: industry,
                        website: website,
                        address_street: street,
                        address_city: city,
                        address_state: state,
                        address_zip: zip,
                        address_country: 'US',
                        contact_first: firstName,
                        contact_last: lastName,
                        contact_email: contactEmail,
                        contact_phone: contactPhone,
                        registration_intent: registrationIntent,
                        fee_confirmed: '1'
                    }
                });

                if (res.success) {
                    status.style.background = 'rgba(16,185,129,0.08)';
                    status.style.color = '#10b981';
                    status.innerHTML = '✅ ' + (res.data?.message || 'Brand registration submitted. VMO will email you when review moves forward and alert you when the campaign step is ready.');
                    btn.innerHTML = '✅ Brand Submitted';
                    btn.style.background = '#10b981';
                    btn.style.color = '#fff';
                    btn.style.borderColor = '#10b981';

                    // Update checklist icon
                    const brandCheck = document.getElementById('vmo-sms-check-brand');
                    if (brandCheck) brandCheck.textContent = '⏳';

                    if (typeof notify === 'function') notify('Brand registration submitted. Watch your email for the next-step update.', 'success');
                } else {
                    status.style.background = 'rgba(239,68,68,0.08)';
                    status.style.color = '#ef4444';
                    status.innerHTML = '❌ ' + (res.data?.message || 'Registration failed. Please check your details and try again.');
                    btn.disabled = false;
                    btn.innerHTML = 'Register Brand (13,500 credits) →';
                    btn.style.opacity = '1';
                }
            } catch (e) {
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '❌ Network error. Please check your connection and try again.';
                btn.disabled = false;
                btn.innerHTML = 'Register Brand (13,500 credits) →';
                btn.style.opacity = '1';
            }
        }

        /**
         * Submit A2P Campaign Registration
         * Collects campaign details from the Step 3 form and sends to the PHP AJAX handler.
         * Auto-creates a Messaging Service on the backend if needed.
         */
        async function vmoSubmitA2PCampaign() {
            const btn = document.getElementById('vmo-a2p-campaign-submit');
            const status = document.getElementById('vmo-a2p-campaign-status');
            if (!btn || !status) return;
            const feeConfirm = document.getElementById('a2p-fee-confirm');
            const registrationIntent = vmoGetSelectedSmsIntent();

            // Collect form values
            const useCase = document.getElementById('a2p-use-case')?.value || '';
            const description = document.getElementById('a2p-description')?.value?.trim() || '';
            const sample1 = document.getElementById('a2p-sample1')?.value?.trim() || '';
            const sample2 = document.getElementById('a2p-sample2')?.value?.trim() || '';

            // Client-side validation
            const missing = [];
            if (!useCase) missing.push('Use Case');
            if (!description) missing.push('Description');
            if (!sample1) missing.push('Sample Message 1');
            if (!sample2) missing.push('Sample Message 2');

            if (missing.length) {
                status.style.display = 'block';
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '⚠️ Please fill in: ' + missing.join(', ');
                return;
            }

            if (!feeConfirm || !feeConfirm.checked) {
                status.style.display = 'block';
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '⚠️ Please confirm the carrier/compliance fee explanation before submitting this paid registration step.';
                return;
            }

            if (registrationIntent !== 'marketing' && useCase === 'MARKETING') {
                status.style.display = 'block';
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '⚠️ The marketing campaign type requires the marketing-capable SMS path. Go back to Step 1 and deliberately choose that option first.';
                return;
            }

            btn.disabled = true;
            btn.innerHTML = '<span class="vmo-spinner-sm"></span> Registering Campaign...';
            btn.style.opacity = '0.7';
            status.style.display = 'block';
            status.style.background = 'rgba(59,130,246,0.08)';
            status.style.color = '#94a3b8';
            status.innerHTML = '⏳ Creating messaging service & registering campaign... This may take 15–30 seconds.';

            try {
                const res = await jQuery.ajax({
                    url: '<?php echo admin_url("admin-ajax.php"); ?>',
                    method: 'POST',
                    data: {
                        action: 'vmo_a2p_register_campaign',
                        security: '<?php echo wp_create_nonce("vmo_admin_nonce"); ?>',
                        use_case: useCase,
                        description: description,
                        sample_message_1: sample1,
                        sample_message_2: sample2,
                        opt_in_message: 'Customers opt in via website contact form, verbal consent during phone calls, or by texting START to the business number.',
                        opt_in_type: 'VERBAL',
                        registration_intent: registrationIntent,
                        fee_confirmed: '1'
                    }
                });

                if (res.success) {
                    status.style.background = 'rgba(16,185,129,0.08)';
                    status.style.color = '#10b981';
                    status.innerHTML = '✅ ' + (res.data?.message || 'Campaign registration submitted. VMO will email you during review and alert you when SMS is approved.');
                    btn.innerHTML = '✅ Campaign Submitted';
                    btn.style.background = '#10b981';
                    btn.style.color = '#fff';
                    btn.style.borderColor = '#10b981';

                    // Update checklist icon
                    const campCheck = document.getElementById('vmo-sms-check-campaign');
                    if (campCheck) campCheck.textContent = '⏳';

                    if (typeof notify === 'function') notify('Campaign registration submitted. Watch your email for review updates.', 'success');

                    // Auto-advance to status step after short delay
                    setTimeout(() => {
                        if (typeof showSMSStep === 'function') showSMSStep(4);
                        try { vmoCheckA2PStatus({ silent: true }); } catch (_) {}
                    }, 2000);
                } else {
                    status.style.background = 'rgba(239,68,68,0.08)';
                    status.style.color = '#ef4444';
                    status.innerHTML = '❌ ' + (res.data?.message || 'Campaign registration failed. Please try again.');
                    btn.disabled = false;
                    btn.innerHTML = 'Register Campaign (30,000 credits) →';
                    btn.style.opacity = '1';
                }
            } catch (e) {
                status.style.background = 'rgba(239,68,68,0.08)';
                status.style.color = '#ef4444';
                status.innerHTML = '❌ Network error. Please check your connection and try again.';
                btn.disabled = false;
                btn.innerHTML = 'Register Campaign (30,000 credits) →';
                btn.style.opacity = '1';
            }
        }

        /**
         * Check A2P Registration Status
         * Polls the backend for brand/campaign/SMS status and updates the Step 4 UI.
         */
        async function vmoCheckA2PStatus(options) {
            options = options || {};
            const silent = !!options.silent;
            const checkBtn = document.getElementById('vmo-a2p-check-btn');
            const brandIcon = document.getElementById('vmo-a2p-status-brand-icon');
            const brandText = document.getElementById('vmo-a2p-status-brand-text');
            const campIcon = document.getElementById('vmo-a2p-status-campaign-icon');
            const campText = document.getElementById('vmo-a2p-status-campaign-text');
            const smsIcon = document.getElementById('vmo-a2p-status-sms-icon');
            const smsText = document.getElementById('vmo-a2p-status-sms-text');
            const activatedMsg = document.getElementById('vmo-a2p-activated-msg');

            if (checkBtn) {
                checkBtn.disabled = true;
                checkBtn.innerHTML = '<span class="vmo-spinner-sm"></span> Checking...';
            }

            // Status → icon/color mapping
            function statusDisplay(status) {
                const s = (status || 'unknown').toUpperCase();
                if (s === 'APPROVED' || s === 'VERIFIED') return { icon: '✅', color: '#10b981', label: s };
                if (s === 'CANCELLED')                      return { icon: '🛑', color: '#ef4444', label: 'Cancelled' };
                if (s === 'FAILED')                         return { icon: '❌', color: '#ef4444', label: 'FAILED' };
                if (s === 'IN_PROGRESS' || s === 'PENDING')  return { icon: '⏳', color: '#f59e0b', label: vmoHumanizeSmsA2PStatus(s) };
                if (s === 'NOT_STARTED')                     return { icon: '⬜', color: '#94a3b8', label: 'Not Started' };
                return { icon: '⏳', color: '#f59e0b', label: vmoHumanizeSmsA2PStatus(s) };
            }

            async function vmoValidateExistingSmsNumber() {
                try {
                    const payload = await jQuery.ajax({
                        url: '<?php echo admin_url("admin-ajax.php"); ?>',
                        method: 'POST',
                        data: {
                            action: 'vmo_validate_current_sms_number',
                            security: '<?php echo wp_create_nonce("vmo_admin_nonce"); ?>'
                        }
                    });
                    return payload;
                } catch (xhr) {
                    return (xhr && xhr.responseJSON) ? xhr.responseJSON : { success: false, data: { message: 'VMO could not validate the current number right now.' } };
                }
            }

            try {
                const res = await jQuery.ajax({
                    url: '<?php echo admin_url("admin-ajax.php"); ?>',
                    method: 'POST',
                    data: {
                        action: 'vmo_a2p_check_status',
                        security: '<?php echo wp_create_nonce("vmo_admin_nonce"); ?>'
                    }
                });

                if (res.success && res.data) {
                    let d = res.data;

                    if (!silent && !d.sms_active && d.tracked_in_plugin === false) {
                        const validation = await vmoValidateExistingSmsNumber();
                        if (validation && validation.success && validation.data) {
                            d = Object.assign({}, d, validation.data);
                            if (typeof notify === 'function') notify(validation.data.message || 'Current number validated inside VMO.', 'success');
                        }
                    }

                    // Brand status
                    const bs = statusDisplay(d.brand_status);
                    if (brandIcon) brandIcon.textContent = bs.icon;
                    if (brandText) { brandText.textContent = bs.label; brandText.style.color = bs.color; }
                    const brandCheck = document.getElementById('vmo-sms-check-brand');
                    if (brandCheck) brandCheck.textContent = bs.icon;

                    // Campaign status
                    const cs = statusDisplay(d.campaign_cancelled ? 'CANCELLED' : d.campaign_status);
                    if (campIcon) campIcon.textContent = cs.icon;
                    if (campText) { campText.textContent = cs.label; campText.style.color = cs.color; }
                    const campCheck = document.getElementById('vmo-sms-check-campaign');
                    if (campCheck) campCheck.textContent = cs.icon;

                    // SMS capability
                    if (d.sms_active) {
                        if (smsIcon) smsIcon.textContent = '✅';
                        if (smsText) { smsText.textContent = 'ACTIVE'; smsText.style.color = '#10b981'; }
                        if (activatedMsg) activatedMsg.style.display = 'block';

                        const brandCheckActive = document.getElementById('vmo-sms-check-brand');
                        const campaignCheckActive = document.getElementById('vmo-sms-check-campaign');
                        const numberCheckActive = document.getElementById('vmo-sms-check-number');
                        if (brandCheckActive) brandCheckActive.textContent = '✅';
                        if (campaignCheckActive) campaignCheckActive.textContent = d.campaign_cancelled ? '🛑' : '✅';
                        if (numberCheckActive) numberCheckActive.textContent = '✅';
                    } else {
                        if (smsIcon) smsIcon.textContent = '⏳';
                        if (smsText) { smsText.textContent = vmoGetSmsActivationPresentation(d).label.toUpperCase(); smsText.style.color = vmoGetSmsActivationPresentation(d).tone; }
                        if (activatedMsg) activatedMsg.style.display = 'none';
                        const numberCheck = document.getElementById('vmo-sms-check-number');
                        if (numberCheck) numberCheck.textContent = d.tracked_in_plugin === false ? '⬜' : '⏳';
                    }

                    vmoSyncSmsActivationButton(d);
                    vmoRenderSmsActivationStatusMeta(d);
                    vmoSyncSmsIntentUI(d);
                    vmoSyncSmsCampaignControls(d);

                    if (window.__vmoSmsState && window.__vmoSmsState.summary) {
                        window.__vmoSmsState.summary = Object.assign({}, window.__vmoSmsState.summary, d);
                        vmoRenderSmsSummary(window.__vmoSmsState.summary);
                    }

                    if (!silent && typeof notify === 'function') notify('Status updated!', 'info');
                } else {
                    if (!silent && typeof notify === 'function') notify('Could not retrieve status.', 'error');
                }
            } catch (e) {
                if (!silent && typeof notify === 'function') notify('Network error checking status.', 'error');
            }

            if (checkBtn) {
                checkBtn.disabled = false;
                checkBtn.innerHTML = '🔄 Check Registration Status';
                }
            }

        async function vmoCancelA2PCampaign() {
            const cancelBtn = document.getElementById('vmo-a2p-cancel-btn');
            if (!cancelBtn || cancelBtn.disabled) return;
            if (!confirm('Cancel this SMS campaign registration in VMO? This may remove marketing-ready status and may require re-registration later if you want to restore it.')) {
                return;
            }

            const originalLabel = cancelBtn.textContent;
            cancelBtn.disabled = true;
            cancelBtn.textContent = 'Cancelling…';

            try {
                const res = await jQuery.ajax({
                    url: '<?php echo admin_url("admin-ajax.php"); ?>',
                    method: 'POST',
                    data: {
                        action: 'vmo_a2p_cancel_campaign',
                        security: '<?php echo wp_create_nonce("vmo_admin_nonce"); ?>'
                    }
                });

                if (!res || !res.success) {
                    throw new Error((res && res.data && res.data.message) || 'Unable to cancel the campaign registration.');
                }

                if (window.__vmoSmsState && window.__vmoSmsState.summary) {
                    window.__vmoSmsState.summary = Object.assign({}, window.__vmoSmsState.summary, res.data || {});
                    vmoRenderSmsSummary(window.__vmoSmsState.summary);
                }
                vmoSyncSmsCampaignControls(res.data || {});
                vmoSyncSmsActivationButton(res.data || {});
                vmoRenderSmsActivationStatusMeta(res.data || {});
                notify((res.data && res.data.message) || 'Campaign cancellation recorded in VMO.', 'success');
            } catch (e) {
                notify('Unable to cancel the campaign registration: ' + e.message, 'error');
                cancelBtn.disabled = false;
                cancelBtn.textContent = originalLabel;
            }
        }

        window.__vmoSmsState = window.__vmoSmsState || { activeContact: '', conversations: [], summary: null, thread: [] };

        function vmoSmsEsc(value) {
            return String(value == null ? '' : value).replace(/[&<>"']/g, function(ch) {
                return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[ch] || ch;
            });
        }

        function vmoSmsTime(value) {
            if (!value) return '—';
            const date = new Date(String(value).replace(' ', 'T'));
            if (Number.isNaN(date.getTime())) return String(value);
            return date.toLocaleString([], { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' });
        }

        function vmoRefreshSmsActivationAdvisory(summary) {
            const box = document.getElementById('vmo-a2p-cost-advice-live');
            if (!box || !summary || !summary.costs) return;

            const balance = Number(summary.token_balance || 0);
            const campaignCost = Number(summary.costs.campaign_tokens || 30000);
            const recommended = Number(summary.costs.recommended_campaign_balance || 33750);
            const isHealthy = balance >= recommended;
            const isBorderline = balance >= campaignCost && balance < recommended;
            const tone = isHealthy ? '#10b981' : (isBorderline ? '#f59e0b' : '#ef4444');
            const status = isHealthy
                ? 'You have a healthy buffer for campaign registration and ongoing texting.'
                : (isBorderline
                    ? 'You can cover the campaign fee, but the remaining balance will be thin for live texting and renewals.'
                    : 'Your current balance is below the monthly campaign fee, so registration will likely fail until you top up.');

            box.style.borderColor = tone;
            box.innerHTML = '<div style="font-size:12px; line-height:1.6; color:#cbd5e1;">'
                + '<strong style="color:' + tone + ';">Balance advisory:</strong> '
                + 'This optional monthly SMS add-on fee is ' + campaignCost.toLocaleString() + ' VMO Credits. '
                + 'Your current balance is ' + balance.toLocaleString() + ' credits. '
                + 'VMO recommends keeping at least ' + recommended.toLocaleString() + ' credits available before you submit so activation and live texting do not drain your balance unexpectedly. '
                + status
                + '</div>';
        }

        function vmoRenderSmsSummary(summary) {
            const container = document.getElementById('vmo-sms-summary');
            const advice = document.getElementById('vmo-sms-advice');
            if (!container || !advice || !summary) return;

            const counts = summary.counts || {};
            const costs = summary.costs || {};
            const tokenBalance = Number(summary.token_balance || 0);
            const isActive = !!summary.sms_active;
            const activation = vmoGetSmsActivationPresentation(summary);
            const businessPhone = summary.business_phone ? formatDisplayPhone(summary.business_phone) : '—';
            const externalPhone = summary.external_phone ? formatDisplayPhone(summary.external_phone) : 'Not set';
            const tone = activation.tone;
            const registrationIntent = String(summary.registration_intent || vmoGetSelectedSmsIntent());
            const marketingReady = !!summary.bulk_marketing_ready;

            vmoSyncSmsActivationButton(summary);
            vmoRenderSmsActivationStatusMeta(summary);
            vmoSyncSmsIntentUI(summary);
            vmoSyncSmsCampaignControls(summary);

            const cards = [
                { label: 'Business SMS Number', value: businessPhone, accent: 'var(--cyan-soft)' },
                { label: 'SMS Status', value: activation.label, accent: tone },
                { label: 'SMS Path', value: registrationIntent === 'marketing' ? 'Marketing-capable' : 'Regular business SMS', accent: registrationIntent === 'marketing' ? '#f59e0b' : '#38bdf8' },
                { label: 'Bulk Marketing Ready', value: marketingReady ? 'Yes' : 'No', accent: marketingReady ? '#10b981' : '#ef4444' },
                { label: 'Token Balance', value: tokenBalance.toLocaleString(), accent: tokenBalance > 0 ? '#f8fafc' : '#ef4444' },
                { label: 'Per Reply Cost', value: (Number(costs.per_reply_tokens || 50)).toLocaleString() + ' tokens', accent: '#38bdf8' },
                { label: 'Conversations', value: String(counts.conversations || 0), accent: '#a78bfa' },
                { label: 'External Relay Phone', value: externalPhone, accent: summary.external_phone ? '#10b981' : '#f59e0b' },
            ];

            container.innerHTML = cards.map(function(card) {
                return '<div style="padding:12px; border-radius:12px; border:1px solid var(--border); background:rgba(255,255,255,.03);">'
                    + '<div style="font-size:11px; color:var(--muted); margin-bottom:6px;">' + vmoSmsEsc(card.label) + '</div>'
                    + '<div style="font-size:15px; font-weight:600; color:' + vmoSmsEsc(card.accent) + '; word-break:break-word;">' + vmoSmsEsc(card.value) + '</div>'
                    + '</div>';
            }).join('');

            let message = '';
            if (!isActive) {
                const notTracked = summary.tracked_in_plugin === false;
                message = '<div style="padding:12px 14px; border-radius:12px; border:1px solid ' + (tone === '#ef4444' ? 'rgba(239,68,68,.22)' : 'rgba(245,158,11,.22)') + '; background:' + (tone === '#ef4444' ? 'rgba(239,68,68,.08)' : 'rgba(245,158,11,.08)') + '; color:#f8fafc; font-size:12px; line-height:1.6;">'
                    + '<strong style="color:' + tone + ';">' + vmoSmsEsc(activation.headline) + '</strong> '
                    + vmoSmsEsc(activation.detail)
                    + ' '
                    + vmoSmsEsc(activation.meta)
                    + (notTracked
                        ? ' Use Check Registration Status inside SMS Activation to import an already approved existing number into VMO.'
                        : (' The optional SMS campaign add-on is ' + Number(costs.campaign_tokens || 30000).toLocaleString() + ' VMO Credits per month, so review the balance advisory before you register.'))
                    + '</div>';
            } else if (!marketingReady) {
                message = '<div style="padding:12px 14px; border-radius:12px; border:1px solid rgba(56,189,248,.22); background:rgba(56,189,248,.08); color:#e0f2fe; font-size:12px; line-height:1.6;">'
                    + '<strong style="color:#38bdf8;">SMS is active for regular business texting.</strong> Bulk SMS marketing tools should stay blocked until this number is registered for a marketing-capable path inside SMS Activation. '
                    + vmoSmsEsc(activation.detail)
                    + '</div>';
            } else if (summary.external_phone) {
                message = '<div style="padding:12px 14px; border-radius:12px; border:1px solid rgba(16,185,129,.22); background:rgba(16,185,129,.08); color:#d1fae5; font-size:12px; line-height:1.6;">'
                    + '<strong style="color:#10b981;">External relay is enabled.</strong> Inbound texts are forwarded to ' + vmoSmsEsc(formatDisplayPhone(summary.external_phone)) + '. '
                    + vmoSmsEsc(activation.detail) + ' '
                    + 'Reply to your business number from that phone to answer the latest customer, or begin with “to +15551234567:” to target a specific contact.'
                    + '</div>';
            } else {
                message = '<div style="padding:12px 14px; border-radius:12px; border:1px solid rgba(56,189,248,.22); background:rgba(56,189,248,.08); color:#e0f2fe; font-size:12px; line-height:1.6;">'
                    + '<strong style="color:#38bdf8;">Plugin-only SMS mode.</strong> You can manage SMS entirely inside the dashboard. '
                    + vmoSmsEsc(activation.detail) + ' '
                    + 'If you want inbound texts copied to your mobile, add an external phone number in Ring Settings.'
                    + '</div>';
            }

            advice.innerHTML = message;
            vmoRefreshSmsActivationAdvisory(summary);
        }

        function vmoRenderSmsConversations(conversations, activeContact) {
            const list = document.getElementById('vmo-sms-conversations');
            const count = document.getElementById('vmo-sms-conversation-count');
            if (!list || !count) return;

            const activeKey = toE164(activeContact || '');
            count.textContent = String(Array.isArray(conversations) ? conversations.length : 0);

            if (!Array.isArray(conversations) || !conversations.length) {
                list.innerHTML = '<div style="padding:16px; color:var(--muted); font-size:12px; line-height:1.6;">No SMS conversations yet. When a customer texts your business number, the thread will appear here.</div>';
                return;
            }

            list.innerHTML = conversations.map(function(convo) {
                const contact = toE164(convo.contact_number || '');
                const isActive = contact && contact === activeKey;
                const border = isActive ? '#38bdf8' : 'var(--border)';
                const bg = isActive ? 'rgba(56,189,248,.12)' : 'rgba(255,255,255,.02)';
                return '<button type="button" data-sms-contact="' + encodeURIComponent(contact) + '" '
                    + 'style="width:100%; text-align:left; padding:12px; margin-bottom:8px; border-radius:10px; border:1px solid ' + border + '; background:' + bg + '; color:var(--ink); cursor:pointer;">'
                    + '<div style="display:flex; justify-content:space-between; gap:8px; align-items:center; margin-bottom:6px;">'
                    + '<strong style="font-size:13px;">' + vmoSmsEsc(formatDisplayPhone(contact || convo.contact_number || 'Unknown')) + '</strong>'
                    + '<span style="font-size:10px; color:var(--muted); white-space:nowrap;">' + vmoSmsEsc(vmoSmsTime(convo.last_at)) + '</span>'
                    + '</div>'
                    + '<div style="font-size:11px; color:var(--muted); margin-bottom:6px;">' + vmoSmsEsc((convo.inbound_count || 0) + ' in / ' + (convo.outbound_count || 0) + ' out') + '</div>'
                    + '<div style="font-size:12px; line-height:1.5; color:var(--ink);">' + vmoSmsEsc(convo.last_preview || '') + '</div>'
                    + '</button>';
            }).join('');

            list.querySelectorAll('[data-sms-contact]').forEach(function(button) {
                button.addEventListener('click', function() {
                    const contact = decodeURIComponent(button.getAttribute('data-sms-contact') || '');
                    loadSmsThread(contact);
                });
            });
        }

        function vmoRenderSmsThread(contact, messages) {
            const title = document.getElementById('vmo-sms-thread-title');
            const meta = document.getElementById('vmo-sms-thread-meta');
            const thread = document.getElementById('vmo-sms-thread');
            const toInput = document.getElementById('vmo-sms-to');
            if (!title || !meta || !thread || !toInput) return;

            if (contact) {
                toInput.value = toE164(contact);
                title.textContent = formatDisplayPhone(contact);
                meta.textContent = (messages && messages.length) ? (messages.length + ' messages') : 'No messages yet';
            } else {
                title.textContent = 'Select a conversation';
                meta.textContent = '';
            }

            if (!messages || !messages.length) {
                thread.innerHTML = contact
                    ? '<div style="padding:16px; color:var(--muted); font-size:12px; line-height:1.6;">No messages in this thread yet. You can still send the first SMS below.</div>'
                    : '<div style="padding:16px; color:var(--muted); font-size:12px; line-height:1.6;">Choose a conversation or start a new SMS to load a thread.</div>';
                return;
            }

            thread.innerHTML = messages.map(function(message) {
                const outbound = String(message.direction || '') === 'outbound';
                const bubbleBg = outbound ? 'rgba(56,189,248,.14)' : 'rgba(255,255,255,.05)';
                const bubbleBorder = outbound ? 'rgba(56,189,248,.35)' : 'var(--border)';
                const align = outbound ? 'justify-content:flex-end;' : 'justify-content:flex-start;';
                const label = outbound ? 'Business' : 'Customer';
                return '<div style="display:flex; ' + align + '">'
                    + '<div style="max-width:85%; padding:12px; border-radius:12px; border:1px solid ' + bubbleBorder + '; background:' + bubbleBg + ';">'
                    + '<div style="display:flex; justify-content:space-between; gap:8px; align-items:center; margin-bottom:6px;">'
                    + '<strong style="font-size:11px; color:' + (outbound ? '#38bdf8' : '#cbd5e1') + ';">' + label + '</strong>'
                    + '<span style="font-size:10px; color:var(--muted);">' + vmoSmsEsc(vmoSmsTime(message.created_at)) + '</span>'
                    + '</div>'
                    + '<div style="font-size:13px; line-height:1.65; white-space:pre-wrap; word-break:break-word;">' + vmoSmsEsc(message.body || '') + '</div>'
                    + '<div style="font-size:10px; color:var(--muted); margin-top:6px; text-transform:capitalize;">' + vmoSmsEsc(message.status || (outbound ? 'queued' : 'received')) + '</div>'
                    + '</div>'
                    + '</div>';
            }).join('');

            thread.scrollTop = thread.scrollHeight;
        }

        async function loadSmsWorkspace(selectedContact) {
            try {
                const res = await ajaxPost('vmo_get_sms_workspace');
                if (!res || !res.success) {
                    notify((res && res.message) || 'Unable to load SMS workspace', 'error');
                    return;
                }

                const data = res.data || {};
                window.__vmoSmsState.summary = data;
                window.__vmoSmsState.conversations = Array.isArray(data.conversations) ? data.conversations : [];

                vmoRenderSmsSummary(data);

                const toInput = document.getElementById('vmo-sms-to');
                if (toInput && !toInput.dataset.smsBound) {
                    toInput.dataset.smsBound = '1';
                    toInput.addEventListener('keydown', function(ev) {
                        if (ev.key === 'Enter') {
                            ev.preventDefault();
                            loadSmsThread(toInput.value);
                        }
                    });
                }

                const preferredContact = selectedContact
                    || window.__vmoSmsState.activeContact
                    || data.latest_contact
                    || ((window.__vmoSmsState.conversations[0] && window.__vmoSmsState.conversations[0].contact_number) || '');

                vmoRenderSmsConversations(window.__vmoSmsState.conversations, preferredContact);

                if (preferredContact) {
                    await loadSmsThread(preferredContact);
                } else {
                    window.__vmoSmsState.activeContact = '';
                    window.__vmoSmsState.thread = [];
                    vmoRenderSmsThread('', []);
                }
            } catch (e) {
                notify('Unable to load SMS workspace: ' + e.message, 'error');
            }
        }

        async function loadSmsThread(contact) {
            const normalized = toE164(contact || ((document.getElementById('vmo-sms-to') || {}).value || ''));
            if (!normalized) {
                window.__vmoSmsState.activeContact = '';
                window.__vmoSmsState.thread = [];
                vmoRenderSmsConversations(window.__vmoSmsState.conversations || [], '');
                vmoRenderSmsThread('', []);
                return;
            }

            try {
                const res = await ajaxPost('vmo_get_sms_thread', { contact: normalized });
                if (!res || !res.success) {
                    notify((res && res.message) || 'Unable to load SMS thread', 'error');
                    return;
                }

                const messages = Array.isArray(res.data && res.data.messages) ? res.data.messages : [];
                window.__vmoSmsState.activeContact = normalized;
                window.__vmoSmsState.thread = messages;
                vmoRenderSmsConversations(window.__vmoSmsState.conversations || [], normalized);
                vmoRenderSmsThread(normalized, messages);
            } catch (e) {
                notify('Unable to load SMS thread: ' + e.message, 'error');
            }
        }

        function vmoStartNewSms() {
            window.__vmoSmsState.activeContact = '';
            window.__vmoSmsState.thread = [];
            vmoRenderSmsConversations(window.__vmoSmsState.conversations || [], '');
            vmoRenderSmsThread('', []);

            const toInput = document.getElementById('vmo-sms-to');
            if (toInput) {
                toInput.value = '';
                toInput.focus();
            }
        }

        async function vmoSendSmsMessage() {
            const toInput = document.getElementById('vmo-sms-to');
            const compose = document.getElementById('vmo-sms-compose');
            const sendBtn = document.getElementById('vmo-sms-send-btn');
            if (!toInput || !compose || !sendBtn) return;

            const to = toE164(toInput.value);
            const message = String(compose.value || '').trim();
            if (!to) {
                notify('Enter a customer number first', 'warning');
                toInput.focus();
                return;
            }
            if (!message) {
                notify('Write a message before sending', 'warning');
                compose.focus();
                return;
            }

            const originalLabel = sendBtn.innerHTML;
            sendBtn.disabled = true;
            sendBtn.innerHTML = 'Sending…';

            try {
                const res = await ajaxPost('vmo_send_sms_message', { to, message });
                if (!res || !res.success) {
                    notify((res && res.message) || 'Unable to send SMS', 'error');
                    return;
                }

                compose.value = '';
                if (window.__vmoSmsState.summary && res.data && res.data.token_balance != null) {
                    window.__vmoSmsState.summary.token_balance = Number(res.data.token_balance);
                }
                notify('SMS sent', 'success');
                await loadSmsWorkspace(to);
            } catch (e) {
                notify('Unable to send SMS: ' + e.message, 'error');
            } finally {
                sendBtn.disabled = false;
                sendBtn.innerHTML = originalLabel;
            }
        }

        async function vmoGenerateSmsDraft() {
            const toInput = document.getElementById('vmo-sms-to');
            const compose = document.getElementById('vmo-sms-compose');
            const intent = document.getElementById('vmo-sms-intent');
            const notes = document.getElementById('vmo-sms-notes');
            const draftBtn = document.getElementById('vmo-sms-ai-btn');
            if (!toInput || !compose || !intent || !notes || !draftBtn) return;

            const to = toE164(toInput.value);
            if (!to) {
                notify('Enter a customer number before requesting an AI draft', 'warning');
                toInput.focus();
                return;
            }

            const originalLabel = draftBtn.innerHTML;
            draftBtn.disabled = true;
            draftBtn.innerHTML = 'Drafting…';

            try {
                const res = await ajaxPost('vmo_generate_sms_draft', {
                    to,
                    intent: intent.value || 'General customer reply',
                    notes: notes.value || '',
                });

                if (!res || !res.success) {
                    notify((res && res.message) || 'Unable to generate SMS draft', 'error');
                    return;
                }

                compose.value = (res.data && res.data.draft) ? String(res.data.draft) : '';
                if (window.__vmoSmsState.summary && res.data && res.data.token_balance != null) {
                    window.__vmoSmsState.summary.token_balance = Number(res.data.token_balance);
                    vmoRenderSmsSummary(window.__vmoSmsState.summary);
                }
                notify('AI draft ready', 'success');
                compose.focus();
            } catch (e) {
                notify('Unable to generate draft: ' + e.message, 'error');
            } finally {
                draftBtn.disabled = false;
                draftBtn.innerHTML = originalLabel;
            }
        }

        document.addEventListener('DOMContentLoaded', function() {
            document.querySelectorAll('input[name="a2p-registration-intent"]').forEach(function(el) {
                if (el.dataset.vmoIntentBound) return;
                el.dataset.vmoIntentBound = '1';
                el.addEventListener('change', function() {
                    vmoSyncSmsIntentUI(window.__vmoSmsState && window.__vmoSmsState.summary ? window.__vmoSmsState.summary : null, { preferSelected: true });
                });
            });
            if (document.getElementById('vmo-activate-sms-btn')) {
                try {
                    vmoCheckA2PStatus({ silent: true });
                } catch (e) {}
            }
            vmoSyncSmsIntentUI(window.__vmoSmsState && window.__vmoSmsState.summary ? window.__vmoSmsState.summary : null);
        });


        window.togglePanel = function(id, onOpen){
            const panel = document.getElementById(id);
            if (!panel) return;
            const isHidden = (panel.style.display === 'none' || getComputedStyle(panel).display === 'none');
            const link = panel.previousElementSibling && panel.previousElementSibling.classList.contains('nav-link') ? panel.previousElementSibling : null;
            if (isHidden) {
                // Accordion: close other open TOP-LEVEL panels in the same group container
                // Important: Do NOT hide nested .vmo-card elements inside the opened panel.
                const container = panel.parentElement;
                if (container) {
                    // Also close sibling panel containers (e.g., .vmo-cards) at the same level
                    const siblings = Array.from(container.children).filter(el => el !== panel && el.classList && (el.classList.contains('vmo-card') || el.classList.contains('vmo-cards')));
                    siblings.forEach(p=>{
                        if (getComputedStyle(p).display !== 'none') {
                            p.style.display = 'none';
                            const l = p.previousElementSibling;
                            if (l && l.classList && l.classList.contains('nav-link')) {
                                l.classList.remove('expanded');
                                l.classList.remove('vmo-active');
                                l.setAttribute('aria-expanded','false');
                            }
                        }
                    });
                }
                panel.style.display = 'block';
                if (link) { link.classList.add('expanded'); link.classList.add('vmo-active'); link.setAttribute('aria-expanded','true'); }
                if (typeof onOpen === 'function') {
                    // Defer slightly to allow layout
                    setTimeout(()=>{ try { onOpen(); } catch(e){ console.warn('Loader error for', id, e); } }, 0);
                }
            } else {
                panel.style.display = 'none';
                if (link) { link.classList.remove('expanded'); link.classList.remove('vmo-active'); link.setAttribute('aria-expanded','false'); }
            }
        }

        // Small helpers
        function fmtCurrency(cents){
            if (typeof cents !== 'number') return '—';
            const v = cents/100; return v.toLocaleString(undefined,{style:'currency',currency:'USD'});
        }
        function drawSpark(id, data){
            const svg = document.getElementById(id); if(!svg) return;
            const w = 100, h = 24; svg.setAttribute('viewBox', `0 0 ${w} ${h}`);
            // Clear existing
            while(svg.firstChild) svg.removeChild(svg.firstChild);
            // Defensive series: ensure at least a flat baseline renders
            let series = Array.isArray(data) ? data.slice() : [];
            if (!series.length) { series = [0, 0]; }
            if (series.length < 2) { series = [series[0] || 0, series[0] || 0]; }
            const maxVal = Math.max(...series);
            const yMax = maxVal === 0 ? 1 : maxVal;
            const yMin = 0; // normalize baseline at 0 for axis
            const span = (yMax - yMin) || 1;

            // Helpers
            const NS = 'http://www.w3.org/2000/svg';
            const line = (x1,y1,x2,y2, stroke='#ffffff', width=1, opacity=0.15) => {
                const el = document.createElementNS(NS, 'line');
                el.setAttribute('x1', x1); el.setAttribute('y1', y1);
                el.setAttribute('x2', x2); el.setAttribute('y2', y2);
                el.setAttribute('stroke', stroke); el.setAttribute('stroke-width', width);
                if (opacity != null) el.setAttribute('opacity', opacity);
                svg.appendChild(el);
                return el;
            };

            // Gridlines (25%, 50%, 75%)
            [0.25, 0.5, 0.75].forEach(frac => {
                const gy = Math.round(h - frac * h);
                line(0, gy, w, gy, '#ffffff', 1, 0.08);
            });

            // Axes
            line(0, 0, 0, h, '#8dd9e6', 1, 0.25);      // Y axis (left)
            line(0, h-1, w, h-1, '#8dd9e6', 1, 0.25);  // X axis (bottom)

            // X ticks (one per datum)
            const n = series.length;
            for (let i=0; i<n; i++) {
                const x = (n===1) ? 0 : (i/(n-1))*w;
                line(x, h-4, x, h-1, '#ffffff', 1, 0.2);
            }

            // Build polyline points
            const pts = series.map((v,i)=>{
                const x = (n===1) ? 0 : (i/(n-1))*w;
                const y = h - (((v - yMin)/span) * h);
                return `${x.toFixed(2)},${y.toFixed(2)}`;
            }).join(' ');
            const pl = document.createElementNS(NS,'polyline');
            pl.setAttribute('fill','none'); pl.setAttribute('stroke','#0fe1ff'); pl.setAttribute('stroke-width','2');
            pl.setAttribute('points', pts);
            svg.appendChild(pl);
        }

        // Ensure the Demographics panel has its card skeleton even if the template is older
        function ensureDemographicsSkeleton(){
            const panel = document.getElementById('vmo-demo-panel');
            if (!panel) { console.info('[VMO] Demographics: panel not found'); return null; }
            // Presence and visibility checks
            const cardsEl = panel.querySelector('.vmo-cards');
            const tableEl = panel.querySelector('#vmo-visitors-rows');
            const looksEmpty = panel.childElementCount <= 1; // likely only the filter row exists
            if (cardsEl && tableEl && !looksEmpty) {
                // Ensure it's visible and styled
                try {
                    const style = window.getComputedStyle(cardsEl);
                    if (style.display === 'none') { cardsEl.style.display = 'grid'; }
                } catch(e) { cardsEl.style.display = 'grid'; }
                console.info('[VMO] Demographics: skeleton already present');
                return panel;
            }
            console.info('[VMO] Demographics: injecting skeleton…');
            // Find the filter row (date inputs) to insert after
            const toInput = panel.querySelector('#vmo-demo-to');
            const anchorRow = toInput ? toInput.closest('div') : panel.firstElementChild;
            // Build skeleton wrapper
            const wrapper = document.createElement('div');
            wrapper.id = 'vmo-demo-skeleton';
            wrapper.innerHTML = `
                <div class="vmo-cards" style="grid-template-columns:repeat(auto-fit, minmax(220px,1fr));">
                    <div class="vmo-card">
                        <h4>Visits Summary</h4>
                        <div class="vmo-kv"><span>Total visits</span><strong id="vmo-demo-total-visits">0</strong></div>
                        <div class="vmo-kv"><span>Unique visitors</span><strong id="vmo-demo-unique-visitors">0</strong></div>
                    </div>
                    <div class="vmo-card">
                        <h4>Gender</h4>
                        <div class="vmo-kv"><span>Male</span><strong id="vmo-gender-male">0</strong></div>
                        <div class="vmo-kv"><span>Female</span><strong id="vmo-gender-female">0</strong></div>
                        <div class="vmo-kv"><span>Other</span><strong id="vmo-gender-other">0</strong></div>
                    </div>
                    <div class="vmo-card">
                        <h4>Age Ranges</h4>
                        <div class="vmo-kv"><span>18–24</span><strong id="vmo-age-18_24">0</strong></div>
                        <div class="vmo-kv"><span>25–34</span><strong id="vmo-age-25_34">0</strong></div>
                        <div class="vmo-kv"><span>35–44</span><strong id="vmo-age-35_44">0</strong></div>
                        <div class="vmo-kv"><span>45–54</span><strong id="vmo-age-45_54">0</strong></div>
                        <div class="vmo-kv"><span>55+</span><strong id="vmo-age-55_plus">0</strong></div>
                    </div>
                    <div class="vmo-card">
                        <h4>Devices</h4>
                        <div class="vmo-kv"><span>Mobile</span><strong id="vmo-dev-mobile">0</strong></div>
                        <div class="vmo-kv"><span>Desktop</span><strong id="vmo-dev-desktop">0</strong></div>
                        <div class="vmo-kv"><span>Tablet</span><strong id="vmo-dev-tablet">0</strong></div>
                        <div class="vmo-kv"><span>Other</span><strong id="vmo-dev-other">0</strong></div>
                    </div>
                    <div class="vmo-card">
                        <h4>Operating Systems</h4>
                        <div class="vmo-kv"><span>iOS</span><strong id="vmo-os-ios">0</strong></div>
                        <div class="vmo-kv"><span>Android</span><strong id="vmo-os-android">0</strong></div>
                        <div class="vmo-kv"><span>Windows</span><strong id="vmo-os-windows">0</strong></div>
                        <div class="vmo-kv"><span>macOS</span><strong id="vmo-os-macos">0</strong></div>
                        <div class="vmo-kv"><span>Linux</span><strong id="vmo-os-linux">0</strong></div>
                        <div class="vmo-kv"><span>Other</span><strong id="vmo-os-other">0</strong></div>
                    </div>
                    <div class="vmo-card">
                        <h4>Referrers</h4>
                        <div id="vmo-referrers-list" style="font-size:12px; color:var(--muted)">—</div>
                    </div>
                    <div class="vmo-card">
                        <h4>Recent Activities</h4>
                        <div id="vmo-activities-list" style="font-size:12px; color:var(--muted)">—</div>
                    </div>
                    <div class="vmo-card">
                        <h4>Top Countries</h4>
                        <div id="vmo-top-countries" style="font-size:12px; color:var(--muted)">—</div>
                    </div>
                    <div class="vmo-card">
                        <h4>Top States</h4>
                        <div id="vmo-top-states" style="font-size:12px; color:var(--muted)">—</div>
                    </div>
                    <div class="vmo-card">
                        <h4>Top Pages Visited</h4>
                        <div id="vmo-top-pages" style="font-size:12px; color:var(--muted)">—</div>
                    </div>
                </div>
                <div class="vmo-card" style="margin-top:10px;">
                    <h4>Visitors (Top 20)</h4>
                    <div style="overflow:auto; max-height:220px;">
                        <table style="width:100%; border-collapse:collapse; min-width:520px;">
                            <thead>
                                <tr style="text-align:left; border-bottom:1px solid rgba(255,255,255,.1)">
                                    <th style="padding:6px 8px;">Contact</th>
                                    <th style="padding:6px 8px;">Email</th>
                                    <th style="padding:6px 8px;">Visits</th>
                                    <th style="padding:6px 8px;">Last Visit</th>
                                    <th style="padding:6px 8px;">Source</th>
                                </tr>
                            </thead>
                            <tbody id="vmo-visitors-rows">
                                <tr><td colspan="5" style="padding:8px; color:var(--muted)">No visitors</td></tr>
                            </tbody>
                        </table>
                    </div>
                </div>`;
            // Enforce layout visibility
            try { const first = wrapper.firstElementChild; if (first) first.style.display = 'grid'; } catch(e){}
            if (anchorRow && anchorRow.parentElement) {
                anchorRow.parentElement.insertBefore(wrapper, anchorRow.nextSibling);
            } else {
                panel.appendChild(wrapper);
            }
            // If for any reason still missing, rebuild panel contents (preserve the filter row as first child)
            if (!panel.querySelector('.vmo-cards')) {
                console.warn('[VMO] Demographics: fallback rebuild triggered');
                const first = panel.firstElementChild; // likely the filter row
                panel.innerHTML = '';
                if (first) panel.appendChild(first);
                panel.appendChild(wrapper);
            }
            console.info('[VMO] Demographics: skeleton ready');
                return panel;
        }

        function updateProgress(){
            const boxes = Array.from(document.querySelectorAll('.task-checkbox'));
            if (!boxes.length) return;
            const checked = boxes.filter(b=>b.classList.contains('checked')).length;
            const pct = Math.round((checked/boxes.length)*100);
            const el = document.getElementById('vmo-local-progress'); if(el) el.textContent = pct + '%';
        }

        // Header + roadmap + tasks
        window.loadDashboardOverview = function(){
            ajaxPost('vmo_dashboard_stats').then(({success, data})=>{
                if(!success || !data) return;
                // Stamp today's date once (local)
                const td = document.getElementById('vmo-today-date');
                if (td) {
                    const d = new Date();
                    const s = d.toLocaleDateString(undefined, { year:'numeric', month:'short', day:'2-digit' });
                    td.textContent = s;
                }
                // Header KPIs
                const g = parseInt(data.goals_complete_percent||0,10);
                const a = parseInt(data.growth_alerts||0,10);
                const goalsEl = document.getElementById('vmo-metric-goals'); if(goalsEl) goalsEl.textContent = (isFinite(g)?g:0) + '%';
                const alertsEl = document.getElementById('vmo-metric-alerts'); if(alertsEl) alertsEl.textContent = isFinite(a)?a:0;
                // Progress rings (stroke-dashoffset based on 88 total)
                const rings = document.querySelectorAll('.vmo-metric .progress');
                rings.forEach((r,i)=>{
                    const total = 88; const pct = (i===0? g : (a>0? Math.min(100,(a*10)):0));
                    const off = total - (total*(Math.max(0,Math.min(100,pct))/100));
                    r.setAttribute('stroke-dashoffset', off.toFixed(0));
                });
                // Short-term
                if (data.short_term){
                    const stp = parseInt(data.short_term.percent||0,10);
                    const stc = parseInt(data.short_term.completed||0,10);
                    const stt = parseInt(data.short_term.total||0,10);
                    const stfill = document.getElementById('vmo-st-fill'); if(stfill) stfill.style.width = Math.max(0,Math.min(100,stp)) + '%';
                    const stcount = document.getElementById('vmo-st-count'); if(stcount) stcount.textContent = `${stc}/${stt}`;
                    const todayp = document.getElementById('vmo-local-progress'); if(todayp) todayp.textContent = (parseInt(data.short_term.today_percent||0,10)) + '%';
                }
                // Long-term
                if (data.long_term){
                    const ltp = parseInt(data.long_term.percent||0,10);
                    const ltfill = document.getElementById('vmo-lt-fill'); if(ltfill) ltfill.style.width = Math.max(0,Math.min(100,ltp)) + '%';
                    const ltnote = document.getElementById('vmo-lt-note'); if(ltnote) ltnote.textContent = data.long_term.note || '—';
                }
                // Tasks today
                const list = document.getElementById('vmo-today-list');
                if (list) {
                    const items = (data.tasks_today||[]).map(t=>{
                        const tok = '';
                        return `<div class="task-item" data-id="${t.id||''}"><div class="task-checkbox${t.checked?' checked':''}"></div><div class="task-text">${t.text?String(t.text).replace(/</g,'&lt;'):'—'}</div>${tok}</div>`;
                    }).join('');
                    list.innerHTML = items || '<div style="color:var(--muted);">No action items for today.</div>';
                    // Bind checkboxes
                    list.querySelectorAll('.task-checkbox').forEach(cb=>cb.addEventListener('click',()=>{
                        cb.classList.toggle('checked');
                        updateProgress();
                        const item = cb.closest('.task-item');
                        const id = item && item.getAttribute('data-id');
                        if (id) {
                            const checked = cb.classList.contains('checked');
                            ajaxPost('vmo_update_task_status',{id, checked}).then(({success})=>{
                                if (!success) { notify('Failed to update task','error'); }
                                loadDashboardOverview && loadDashboardOverview();
                            }).catch(()=>notify('Failed to update task','error'));
                        }
                    }));
                }
                // Weekly headline
                const headline = document.getElementById('vmo-weekly-headline');
                if (headline) {
                    const insight = (data.weekly && Array.isArray(data.weekly.insights) && data.weekly.insights[0]) ? data.weekly.insights[0] : '';
                    headline.textContent = insight || (data.website && data.website.status_label ? data.website.status_label : '—');
                }
                // Business Intelligence KPIs
                const rk = document.getElementById('vmo-bi-ranking'); if (rk) rk.textContent = data.bi && data.bi.ranking ? data.bi.ranking : '—';
                const gr = document.getElementById('vmo-bi-growth'); if (gr) gr.textContent = (data.bi && typeof data.bi.growth==='number') ? ((data.bi.growth>=0?'+':'')+data.bi.growth.toFixed(1)+'%') : (data.bi && data.bi.growth ? data.bi.growth : '—');
                const nx = document.getElementById('vmo-bi-next'); if (nx) nx.textContent = data.bi && data.bi.next_milestone ? data.bi.next_milestone : '—';
                const mn = document.getElementById('vmo-bi-monitored'); if (mn) mn.textContent = data.bi && typeof data.bi.monitored==='number' ? (data.bi.monitored+' active') : '—';
                const th = document.getElementById('vmo-bi-threats'); if (th) th.textContent = data.bi && typeof data.bi.new_threats==='number' ? (data.bi.new_threats+' this week') : '—';
                const op = document.getElementById('vmo-bi-opps'); if (op) op.textContent = data.bi && typeof data.bi.opportunities==='number' ? (data.bi.opportunities+' identified') : '—';
            }).catch(()=>{});
        }

        // Date range helper (defaults to last 30 days)
        function initDateRange(fromId, toId, days=30){
            const from = document.getElementById(fromId);
            const to = document.getElementById(toId);
            const today = new Date();
            const start = new Date();
            start.setDate(today.getDate() - Math.max(1, days));
            const fmt = d => d.toISOString().slice(0,10);
            if (to && !to.value) to.value = fmt(today);
            if (from && !from.value) from.value = fmt(start);
        }

        // Visitors
        window.loadVisitorsPanel = function(){
            initDateRange('vmo-visitors-from','vmo-visitors-to',30);
            const from = (document.getElementById('vmo-visitors-from')||{}).value;
            const to = (document.getElementById('vmo-visitors-to')||{}).value;
            const params = { from: (from?from+' 00:00:00':''), to: (to?to+' 23:59:59':'') };
            ajaxPost('vmo_get_visitors_data', params).then(({success, data})=>{
                if(!success||!data) return;
                const total = parseInt(data.total_visits||0,10);
                const uniq = parseInt(data.unique_visitors||0,10);
                const badge = document.getElementById('vmo-visitors-total'); if(badge) badge.textContent = isFinite(uniq)?uniq.toString():'0';
                const cnt = document.getElementById('vmo-visitors-count'); if(cnt) cnt.textContent = isFinite(total)?total.toString():'0';
                // Query today's visitors separately
                const todayIso = new Date().toISOString().slice(0,10);
                ajaxPost('vmo_get_visitors_data', {from: todayIso+' 00:00:00', to: todayIso+' 23:59:59'}).then(({success,data})=>{
                    const tv = success && data ? parseInt(data.unique_visitors||0,10) : 0;
                    const el = document.getElementById('vmo-visitors-today'); if (el) el.textContent = isFinite(tv)?tv.toString():'0';
                }).catch(()=>{});
                drawSpark('vmo-visitors-spark', (data.chart && data.chart.data) ? data.chart.data : []);
            }).catch(()=>{});
        }

        // Demographics
        window.loadDemographicsPanel = function(){
            console.info('[VMO] Demographics: loadDemographicsPanel()');
            initDateRange('vmo-demo-from','vmo-demo-to',30);
            // Build skeleton if template markup is missing
            ensureDemographicsSkeleton();
            // Verify visibility of cards after ensuring skeleton
            try {
                const panel = document.getElementById('vmo-demo-panel');
                const cardsEl = panel && panel.querySelector('.vmo-cards');
                if (!cardsEl || window.getComputedStyle(cardsEl).display === 'none') {
                    console.warn('[VMO] Demographics: cards missing or hidden; reinjecting');
                    ensureDemographicsSkeleton();
                }
            } catch(e){}
            const from = (document.getElementById('vmo-demo-from')||{}).value;
            const to = (document.getElementById('vmo-demo-to')||{}).value;
            ajaxPost('vmo_get_demographics_data', {from: (from?from+' 00:00:00':''), to: (to?to+' 23:59:59':'')}).then(({success,data})=>{
                console.info('[VMO] Demographics: data response', success, data);
                if(!success||!data) return;
                // Totals
                const tv = document.getElementById('vmo-demo-total-visits'); if (tv) tv.textContent = (parseInt(data.total_visits||0,10)).toString();
                const uv = document.getElementById('vmo-demo-unique-visitors'); if (uv) uv.textContent = (parseInt(data.unique_visitors||0,10)).toString();
                // Gender
                const g = data.gender || {}; const set = (id,val)=>{ const el=document.getElementById(id); if(el) { const safe = (val === undefined || val === null) ? 0 : val; el.textContent = String(safe); } };
                set('vmo-gender-male', g.male||0); set('vmo-gender-female', g.female||0); set('vmo-gender-other', g.other||0);
                // Age ranges
                const age = data.age_ranges || {};
                set('vmo-age-18_24', age['18-24']||0);
                set('vmo-age-25_34', age['25-34']||0);
                set('vmo-age-35_44', age['35-44']||0);
                set('vmo-age-45_54', age['45-54']||0);
                set('vmo-age-55_plus', age['55+']||0);
                // Devices
                const dev = data.devices || {};
                set('vmo-dev-mobile', dev.mobile||0);
                set('vmo-dev-desktop', dev.desktop||0);
                set('vmo-dev-tablet', dev.tablet||0);
                set('vmo-dev-other', dev.other||0);
                // OS
                const os = data.os || {};
                set('vmo-os-ios', os.ios||0);
                set('vmo-os-android', os.android||0);
                set('vmo-os-windows', os.windows||0);
                set('vmo-os-macos', os.macos||0);
                set('vmo-os-linux', os.linux||0);
                set('vmo-os-other', os.other||0);
                // Referrers list
                const refEl = document.getElementById('vmo-referrers-list');
                if (refEl) {
                    const refs = Array.isArray(data.referrers) ? data.referrers : [];
                    if (refs.length) {
                        refEl.innerHTML = refs.map(r=>`<div class="vmo-kv"><span>${String(r.source||'Other').replace(/</g,'&lt;')}</span><strong>${parseInt(r.count||0,10)}</strong></div>`).join('');
                    } else {
                        refEl.textContent = '—';
                    }
                }
                // Locations / States / Pages
                const tc = document.getElementById('vmo-top-countries'); if(tc) tc.textContent = (data.locations&&data.locations.length) ? data.locations.join('\n') : '—';
                const ts = document.getElementById('vmo-top-states'); if(ts) ts.textContent = (data.states&&data.states.length) ? data.states.join('\n') : '—';
                const tp = document.getElementById('vmo-top-pages'); if(tp) tp.textContent = (data.pages&&data.pages.length) ? data.pages.join('\n') : '—';
                // Activities
                const act = document.getElementById('vmo-activities-list');
                if (act) {
                    const activities = Array.isArray(data.activities) ? data.activities : [];
                    act.textContent = activities.length ? activities.map(a=>String(a).replace(/</g,'&lt;')).join('\n') : '—';
                }
                // Visitors table
                const tbody = document.getElementById('vmo-visitors-rows');
                if (tbody) {
                    const list = Array.isArray(data.visitors) ? data.visitors : [];
                    if (list.length === 0) {
                        tbody.innerHTML = '<tr><td colspan="5" style="padding:8px; color:var(--muted)">No visitors</td></tr>';
                    } else {
                        tbody.innerHTML = list.map(v=>{
                            const name = (v.name||v.contact_id||'—').toString().replace(/</g,'&lt;');
                            const email = (v.email||'').toString().replace(/</g,'&lt;');
                            const visits = parseInt(v.visits||0,10);
                            const last = (v.last_visit||'').toString().replace('T',' ').replace(/</g,'&lt;');
                            const source = (v.source||'—').toString().replace(/</g,'&lt;');
                            return `<tr><td style="padding:6px 8px;">${name}</td><td style="padding:6px 8px;">${email}</td><td style="padding:6px 8px;">${visits}</td><td style="padding:6px 8px;">${last}</td><td style="padding:6px 8px;">${source}</td></tr>`;
                        }).join('');
                    }
                }
            }).catch(()=>{});
        }

        // Conversion
        window.loadConversionPanel = function(){
            initDateRange('vmo-conv-from','vmo-conv-to',30);
            const from = (document.getElementById('vmo-conv-from')||{}).value;
            const to = (document.getElementById('vmo-conv-to')||{}).value;
            const range = { from: (from?from+' 00:00:00':''), to: (to?to+' 23:59:59':'') };
            ajaxPost('vmo_get_conversions_data', range).then(({success,data})=>{
                if(!success||!data) return;
                const visitors = (data.funnel && typeof data.funnel.visitors==='number') ? data.funnel.visitors : 0;
                const orders = parseInt(data.total_conversions||0,10);
                const rate = (typeof data.conversion_rate==='number') ? data.conversion_rate.toFixed(2)+'%' : (data.conversion_rate||'0%');
                const ev = document.getElementById('vmo-conv-visitors'); if(ev) ev.textContent = visitors.toString();
                const eo = document.getElementById('vmo-conv-orders'); if(eo) eo.textContent = orders.toString();
                const er = document.getElementById('vmo-conv-rate'); if(er) er.textContent = rate;
                const series = (data.rate_series && data.rate_series.length) ? data.rate_series : ((data.chart && data.chart.data) ? data.chart.data : []);
                drawSpark('vmo-conv-spark', series);
                // Ensure the Visitors KPI reflects actual traffic by querying the visitors endpoint for the same range
                ajaxPost('vmo_get_visitors_data', range).then(({success:vs,data:vd})=>{
                    if (success && vd) {
                        const uniq = parseInt(vd.unique_visitors||0,10);
                        const ev2 = document.getElementById('vmo-conv-visitors'); if (ev2) ev2.textContent = (isFinite(uniq)?uniq:0).toString();
                        // Optionally, if conversion rate was missing, do not override existing rate here.
                    }
                }).catch(()=>{});
            }).catch(()=>{});
        }

        // Competitors
        window.loadCompetitorPanel = function(){
            initDateRange('vmo-comp-from','vmo-comp-to',30);
            const from = (document.getElementById('vmo-comp-from')||{}).value;
            const to = (document.getElementById('vmo-comp-to')||{}).value;
            ajaxPost('vmo_get_competitors_data', {from: (from?from+' 00:00:00':''), to: (to?to+' 23:59:59':'')}).then(({success,data})=>{
                if(!success||!data) return;
                const share = document.getElementById('vmo-share-user'); if(share) share.textContent = (typeof data.your_share==='number') ? (data.your_share.toFixed(1)+'%') : '—';
                const leader = document.getElementById('vmo-share-leader'); if(leader) leader.textContent = (typeof data.leader_share==='number') ? (data.leader_share.toFixed(1)+'%') : '—';
                const rank = document.getElementById('vmo-share-rank'); if(rank) rank.textContent = (typeof data.your_rank==='number') ? ('#'+data.your_rank) : '—';
                const mon = document.getElementById('vmo-share-monitored'); if(mon) mon.textContent = (typeof data.monitored==='number') ? data.monitored : '—';
                const list = document.getElementById('vmo-share-list'); if(list) {
                    const comps = Array.isArray(data.competitors) ? data.competitors : [];
                    list.textContent = comps.length ? comps.map(c=>`${c.name||'Competitor'} — ${typeof c.share==='number'?c.share.toFixed(1)+'%':'—'}`).join('\n') : '—';
                }
                drawSpark('vmo-share-spark', (data.chart && data.chart.data) ? data.chart.data : []);
            }).catch(()=>{});
        }

        // Payments
        function loadPaymentsPanel_legacy(){
            const set = (id, val)=>{ const el=document.getElementById(id); if(el) el.textContent = val; };
            ajaxPost('vmo_dashboard_stats',{scope:'payments'}).then(({success,data})=>{
                if(!success||!data) return;
                set('vmo-pay-kpi-day', fmtCurrency(data.day||0));
                set('vmo-pay-kpi-week', fmtCurrency(data.week||0));
                set('vmo-pay-kpi-month', fmtCurrency(data.month||0));
                set('vmo-pay-kpi-year', fmtCurrency(data.year||0));
                set('vmo-pay-kpi-mom', (typeof data.mom_change==='number'? (data.mom_change>0? '+':'')+data.mom_change.toFixed(2)+'%' : '—'));
                const tbody = document.getElementById('vmo-pay-rows');
                if (tbody) {
                    const rows = (data.transactions||[]).map(t=>{
                        const amt = fmtCurrency(t.amount||0);
                        const date = (t.date||'').replace('T',' ');
                        const prod = (t.product||'').replace(/</g,'&lt;');
                        const status = (t.status||'').replace(/</g,'&lt;');
                        return `<tr><td style="padding:6px 8px">${date}</td><td style=\"padding:6px 8px\">${prod}</td><td style=\"padding:6px 8px\">${amt}</td><td style=\"padding:6px 8px\">${(t.currency||'USD').toUpperCase()}</td><td style=\"padding:6px 8px\">${status}</td><td style=\"padding:6px 8px\"><button class=\"action-btn\" disabled>Receipt</button></td></tr>`;
                    }).join('');
                    tbody.innerHTML = rows || '<tr><td colspan="6" style="padding:8px;color:var(--muted)">No transactions</td></tr>';
                }
            }).catch(()=>{});
        }
        window.regenerateRoadmap = function(){
            const btns=document.querySelectorAll('[onclick*="regenerateRoadmap"]'); btns.forEach(b=>b.disabled=true);
            notify('Regenerating roadmap…','info');
            ajaxPost('vmo_regenerate_roadmap').then(({success,data,message})=>{
                btns.forEach(b=>b.disabled=false);
                if(!success){ notify(message||'Failed to regenerate roadmap','error'); return; }
                // Show a brief confirmation and refresh overview to reflect any new tasks/percentages
                notify('Roadmap updated','success');
                if (typeof loadDashboardOverview==='function') setTimeout(loadDashboardOverview, 250);
            }).catch(e=>{ btns.forEach(b=>b.disabled=false); notify('Error: '+e.message,'error'); });
        }
        function exportProgress(){
            notify('Exporting progress report…','info');
            ajaxPost('vmo_export_progress_pdf').then(async ({success,data,message})=>{
                if(success && data && data.url){
                    try{
                        const res = await fetch(data.url, { credentials: 'include' });
                        const blob = await res.blob();
                        const a = document.createElement('a');
                        a.href = URL.createObjectURL(blob);
                        a.download = 'VMO-Progress-Report.pdf';
                        document.body.appendChild(a); a.click(); a.remove();
                        setTimeout(()=>URL.revokeObjectURL(a.href), 1000);
                        notify('PDF downloaded','success');
                        return;
                    }catch(err){ /* fall through to HTML */ }
                }
                // Fallback: get HTML export, fetch content, and download as .html
                return ajaxPost('vmo_export_progress').then(async ({success,data,message})=>{
                    if(!success || !data || !data.url){ notify(message||'Export failed','error'); return; }
                    try{
                        const res = await fetch(data.url, { credentials: 'include' });
                        const blob = await res.blob();
                        const a = document.createElement('a');
                        a.href = URL.createObjectURL(blob);
                        a.download = 'VMO-Progress-Report.html';
                        document.body.appendChild(a); a.click(); a.remove();
                        setTimeout(()=>URL.revokeObjectURL(a.href), 1000);
                        notify('Report downloaded','success');
                    }catch(err){ notify('Download failed','error'); }
                });
            }).catch(e=>notify('Export error: '+e.message,'error'));
        }
        window.scheduleTask = function(){
            const existing = document.getElementById('__inlineScheduleTask');
            if (existing) { try { existing.style.display = 'flex'; } catch(_e) {} return; }

            const modal = document.createElement('div');
            modal.className = 'vmo-fs-modal vmo-modal-visible';
            modal.style.display = 'flex';
            modal.id = '__inlineScheduleTask';
            modal.innerHTML = `
                <div class="vmo-modal-overlay" data-close="__inlineScheduleTask"></div>
                <div class="modal-content vmo-modal-panel">
                    <div class="modal-header">
                        <h3 class="modal-title">Schedule Task</h3>
                        <button class="modal-close" data-close="__inlineScheduleTask" type="button">&times;</button>
                    </div>
                    <div class="modal-body">
                        <div style="display:grid; gap:10px;">
                            <label>Task Title
                                <input id="vmo-task-title" type="text" placeholder="e.g., Follow up with new leads" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)">
                            </label>
                            <div style="display:grid; grid-template-columns:1fr 1fr; gap:10px;">
                                <label>Due Date
                                    <input class="vmo-date" id="vmo-task-due" type="date" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)">
                                </label>
                                <label>Time (optional)
                                    <input id="vmo-task-time" type="time" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)">
                                </label>
                            </div>
                            <label>Notes (optional)
                                <textarea id="vmo-task-notes" rows="3" placeholder="Add details…" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)"></textarea>
                            </label>
                            <div style="display:flex; gap:10px;">
                                <button class="action-btn primary" id="vmo-task-save" type="button">Schedule</button>
                                <button class="action-btn" data-close="__inlineScheduleTask" type="button">Cancel</button>
                            </div>
                        </div>
                    </div>
                </div>`;
            document.body.appendChild(modal);

            try { if (typeof attachDatePickers === 'function') attachDatePickers(modal); } catch(_e) {}

            // Default due date = today
            const dueEl = modal.querySelector('#vmo-task-due');
            if (dueEl && !dueEl.value) {
                try { dueEl.value = new Date().toISOString().slice(0,10); } catch(_e) {}
            }

            const saveBtn = modal.querySelector('#vmo-task-save');
            if (saveBtn) {
                saveBtn.addEventListener('click', ()=>{
                    const title = (modal.querySelector('#vmo-task-title')||{}).value || '';
                    const dueDate = (modal.querySelector('#vmo-task-due')||{}).value || '';
                    const time = (modal.querySelector('#vmo-task-time')||{}).value || '';
                    const notes = (modal.querySelector('#vmo-task-notes')||{}).value || '';

                    const cleanTitle = String(title).trim();
                    const cleanDue = String(dueDate).trim();
                    const cleanTime = String(time).trim();

                    if (!cleanTitle || !cleanDue) { notify('Please provide a title and due date', 'warning'); return; }
                    const due = cleanDue + (cleanTime ? (' ' + cleanTime) : '');

                    notify('Scheduling task…', 'info');
                    ajaxPost('vmo_schedule_task', { title: cleanTitle, due, notes }).then(({success,message})=>{
                        if(!success){ notify(message||'Task scheduling failed','error'); return; }
                        notify('Task scheduled','success');
                        loadDashboardOverview && loadDashboardOverview();
                        hideModal('__inlineScheduleTask');
                    }).catch(e=>notify('Schedule error: '+e.message,'error'));
                });
            }
        }
        function openScheduleTask(){ scheduleTask(); }

        // Roadmap objective inline modal
        function openAddObjective(){
            const modal = document.createElement('div');
            modal.className = 'vmo-fs-modal vmo-modal-visible';
            modal.style.display='flex';
            modal.innerHTML = `
                <div class="vmo-modal-overlay" data-close="__inlineObjective"></div>
                <div class="modal-content vmo-modal-panel">
                    <div class="modal-header">
                        <h3 class="modal-title">Update Roadmap</h3>
                        <button class="modal-close" data-close="__inlineObjective" type="button">&times;</button>
                    </div>
                    <div class="modal-body">
                        <div style="display:grid; gap:10px;">
                            <label>Objective Title<input id="vmo-obj-title" type="text" placeholder="e.g., Publish pricing page" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)"></label>
                            <label>Due Date<input class="vmo-date" id="vmo-obj-due" type="date" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink)"></label>
                            <div style="display:flex; gap:10px;">
                                <button class="action-btn primary" id="vmo-obj-save">Save Objective</button>
                                <button class="action-btn" data-close="__inlineObjective">Cancel</button>
                            </div>
                        </div>
                    </div>
                </div>`;
            modal.id='__inlineObjective';
            document.body.appendChild(modal);
            // Ensure datepicker attaches to the due date field in this modal
            try { if (typeof attachDatePickers === 'function') attachDatePickers(modal); } catch(e){}
            // Pre-populate due date with today if empty
            const dueEl = modal.querySelector('#vmo-obj-due');
            if (dueEl && !dueEl.value) {
                const today = new Date();
                const fmt = d => d.toISOString().slice(0,10);
                try { dueEl.value = fmt(today); } catch(e){}
            }
            modal.querySelector('#vmo-obj-save').addEventListener('click',()=>{
                const title = (document.getElementById('vmo-obj-title')||{}).value || '';
                const due = (document.getElementById('vmo-obj-due')||{}).value || '';
                if(!title || !due){ notify('Please provide title and due date','warning'); return; }
                ajaxPost('vmo_add_roadmap_objective',{title, due}).then(({success,message})=>{
                    if(!success){ notify(message||'Failed to add objective','error'); return; }
                    notify('Objective added','success');
                    loadDashboardOverview && loadDashboardOverview();
                    hideModal('__inlineObjective');
                }).catch(e=>notify('Error: '+e.message,'error'));
            });
        }
        function loadPaymentsPanelLegacy(){
            const panel=document.getElementById('vmo-payments-panel'); if(!panel){ return; }
            panel.innerHTML='<div class="vmo-loading">Loading payments…</div>';
            ajaxPost('vmo_dashboard_stats',{scope:'payments'}).then(({success,data})=>{
                if(!success||!data){ panel.innerHTML='<em>No payment data</em>'; return; }
                const rows=(data.payments||[]).map(p=>`<tr><td>${p.id||''}</td><td>${p.amount||''}</td><td>${p.status||''}</td></tr>`).join('');
                panel.innerHTML=`<table class="vmo-table"><thead><tr><th>ID</th><th>Amount</th><th>Status</th></tr></thead><tbody>${rows}</tbody></table>`;
            }).catch(()=>panel.innerHTML='<em>Error loading payments</em>');
        }
        // Live calls: keep ringing/banner state fresh (monitor UI removed)
        window.refreshLiveCalls = async function(){
            try{
                const r = await ajaxPost('vmo_get_live_calls');
                const calls = (r && r.success && r.data && Array.isArray(r.data.calls)) ? r.data.calls : [];
                if (typeof updateIncomingAndRing === 'function') updateIncomingAndRing(calls);
                return { success: true, calls };
            }catch(e){
                if (typeof updateIncomingAndRing === 'function') updateIncomingAndRing([]);
                return { success: false, calls: [] };
            }
        }
        window.refreshHistory = async function(){
            const wrap = document.getElementById('vmo-history-list');
            if (wrap) wrap.innerHTML = '<div class="vmo-loading">Loading call history…</div>';
            try{
                const raw = await ajaxPost('vmo_get_call_history', { limit: 50 });
                console.log('[VMO Call History] Raw response:', JSON.stringify(raw).slice(0,1000));
                const success = raw && raw.success;
                const data = raw && raw.data;
                const message = raw && raw.message;
                if (!success) {
                    console.warn('[VMO Call History] Request failed:', message, raw);
                    if(wrap) wrap.innerHTML = '<div style="color:#f59e0b; padding:20px; text-align:center;">⚠️ Call history request failed: ' + (message||'Unknown error') + '</div>';
                    return;
                }
                const calls = Array.isArray(data && data.calls) ? data.calls : [];
                const total = data && data.total ? parseInt(data.total) : calls.length;
                const debug = (data && data.debug) ? data.debug : {};
                console.log('[VMO Call History] Calls:', calls.length, 'Total:', total, 'Debug:', debug);
                if (!calls.length) {
                    let msg = 'No calls in the last 30 days.';
                    let detail = '';
                    if (debug.total_in_table === 0 && debug.table_exists) {
                        msg = 'No calls recorded yet.';
                        detail = '<br><span style="font-size:11px;">Make or receive a call to see history here.</span>';
                        if (debug.source === 'none') detail += '<br><span style="font-size:10px; opacity:.6;">DB table: ✓ | Rows: 0 | User: ' + debug.user_id + '</span>';
                    } else if (!debug.table_exists) {
                        msg = 'Call history table is initializing.';
                        detail = '<br><span style="font-size:11px;">Please refresh in a moment.</span>';
                    } else if (debug.total_in_table > 0) {
                        msg = 'Calls exist but may be stored under a different account.';
                        detail = '<br><span style="font-size:10px; opacity:.6;">Rows in DB: ' + debug.total_in_table + ' | Your User ID: ' + debug.user_id + '</span>';
                    }
                    if(wrap) wrap.innerHTML = '<div style="color:var(--muted); padding:20px; text-align:center;">' + msg + detail + '</div>';
                    return;
                }
                
                // Summary bar
                const summaryBar = document.createElement('div');
                summaryBar.style.cssText = 'display:flex; gap:12px; align-items:center; margin-bottom:10px; padding:8px 12px; background:rgba(255,255,255,.03); border-radius:8px; flex-wrap:wrap;';
                summaryBar.innerHTML = '<span style="font-size:12px; color:var(--muted);">📊 Showing <strong style="color:var(--cyan-soft);">' + calls.length + '</strong> of <strong>' + total + '</strong> calls (last 30 days)</span>';
                
                const table = document.createElement('table'); table.style.width='100%'; table.style.borderCollapse='collapse'; table.style.fontSize='13px';
                table.innerHTML = `
                    <thead><tr style="text-align:left; border-bottom:2px solid rgba(255,255,255,.12); font-size:11px; text-transform:uppercase; letter-spacing:.5px; color:var(--muted);">
                        <th style="padding:8px">Time</th>
                        <th style="padding:8px">Caller / Number</th>
                        <th style="padding:8px">Direction</th>
                        <th style="padding:8px">Duration</th>
                        <th style="padding:8px">Status</th>
                        <th style="padding:8px">Actions</th>
                    </tr></thead><tbody></tbody>`;
                const tbody = table.querySelector('tbody');
                calls.forEach((h, i)=>{
                    const tr = document.createElement('tr');
                    tr.style.borderBottom = '1px solid rgba(255,255,255,.05)';
                    if (i % 2 === 0) tr.style.background = 'rgba(255,255,255,.015)';
                    const dur = (h.call_duration && Number(h.call_duration) > 0) ? (Math.floor(h.call_duration/60) + 'm ' + (h.call_duration % 60) + 's') : '0s';
                    const timeRaw = h.call_start_time || '';
                    const timeD = timeRaw ? new Date(timeRaw.replace(' ','T')) : null;
                    const time = timeD && !isNaN(timeD) ? timeD.toLocaleString('en-US', {month:'short', day:'numeric', hour:'numeric', minute:'2-digit', hour12:true}) : String(timeRaw).replace(/</g,'&lt;');
                    const callerNum = String(h.direction === 'outbound' ? (h.to_number||'') : (h.from_number||'')).replace(/</g,'&lt;');
                    const callerName = String(h.caller_name||'').replace(/</g,'&lt;');
                    const callerCategory = String(h.caller_category||'').replace(/</g,'&lt;');
                    const dirIcon = h.direction === 'outbound' ? '📤' : '📥';
                    const dirColor = h.direction === 'outbound' ? '#3b82f6' : '#10b981';
                    const statusColor = (h.call_status === 'completed') ? '#10b981' : (h.call_status === 'missed' || h.call_status === 'no-answer') ? '#ef4444' : '#f59e0b';
                    const catBadge = callerCategory ? '<span style="font-size:9px; padding:1px 5px; border-radius:4px; margin-left:4px; background:' + (callerCategory === 'customer' ? 'rgba(16,185,129,.15); color:#10b981' : 'rgba(59,130,246,.15); color:#3b82f6') + ';">' + callerCategory + '</span>' : '';
                    
                    tr.innerHTML = `
                        <td style="padding:8px; white-space:nowrap;">${time}</td>
                        <td style="padding:8px;">
                            <strong style="color:var(--ink);">${callerName || callerNum || 'Unknown Caller'}</strong>${callerCategory ? ' <span style="font-size:9px; padding:1px 5px; border-radius:4px; margin-left:4px; background:' + (callerCategory === 'customer' ? 'rgba(16,185,129,.15); color:#10b981' : 'rgba(59,130,246,.15); color:#3b82f6') + ';">' + callerCategory + '</span>' : ''}<br>
                            ${callerNum ? '<span style="color:var(--muted); font-size:12px;">' + callerNum + '</span>' : ''}
                        </td>
                        <td style="padding:8px;"><span style="color:${dirColor};">${dirIcon} ${h.direction||'inbound'}</span></td>
                        <td style="padding:8px;">${dur}</td>
                        <td style="padding:8px;"><span style="color:${statusColor}; font-weight:600; font-size:12px;">${String(h.call_status||'').replace(/</g,'&lt;')}</span></td>
                        <td style="padding:8px;">
                            <button class="action-btn" data-listen="1" data-callsid="${String(h.call_sid||'').replace(/"/g,'&quot;')}" data-duration="${h.call_duration||0}" data-status="${String(h.call_status||'').replace(/"/g,'&quot;')}" style="font-size:11px;">▶ Listen</button>
                            ${h.summary ? '<button class="action-btn vmo-view-summary-btn" data-callsid="' + String(h.call_sid||'').replace(/"/g,'&quot;') + '" style="font-size:11px; margin-left:4px;">📋 Summary</button>' : ''}
                        </td>`;
                    tbody.appendChild(tr);
                });
                if (wrap) { wrap.innerHTML=''; wrap.appendChild(summaryBar); wrap.appendChild(table); }
                // Bind Listen buttons
                Array.prototype.forEach.call(table.querySelectorAll('button[data-listen]'), function(btn){
                    btn.addEventListener('click', async ()=>{
                        const callSid = btn.getAttribute('data-callsid');
                        const callDuration = parseInt(btn.getAttribute('data-duration') || '0', 10);
                        const callStatus = btn.getAttribute('data-status') || '';
                        if (!callSid) { notify('Missing Call SID','error'); return; }
                        btn.disabled = true; btn.textContent = '⏳';
                        try {
                            const {success, data, message} = await ajaxPost('vmo_get_call_recordings', { call_sid: callSid });
                            console.log('[VMO Listen]', callSid, 'duration=' + callDuration, 'status=' + callStatus);
                            console.log('[VMO Listen] Full response:', JSON.stringify(data, null, 2));
                            if (data && data.debug) {
                                console.log('[VMO Listen] Debug:', JSON.stringify(data.debug, null, 2));
                            }
                            if (!success) {
                                // Even on failure, try to show something useful
                                openRecordingModal(null, { callSid, callDuration, callStatus, transcript: [], debug: (data && data.debug) || {} });
                                return;
                            }
                            const recs = Array.isArray(data && data.recordings) ? data.recordings : [];
                            const transcript = Array.isArray(data && data.transcript) ? data.transcript : [];
                            const debug = (data && data.debug) || {};
                            if (!recs.length) {
                                // No audio — open modal with transcript fallback
                                openRecordingModal(null, { callSid, callDuration, callStatus, transcript, debug });
                                return;
                            }
                            const latest = recs[0];
                            const mediaUrl = latest.media_url || latest.recording_url || latest.url || latest.uri || '';
                            openRecordingModal(mediaUrl, {
                                callSid,
                                callDuration,
                                callStatus,
                                duration: latest.duration || '',
                                created: latest.date_created || '',
                                transcript,
                                debug
                            });
                        } catch(e) { console.error('[VMO Listen] Error:', e); notify('Error: '+e.message,'error'); }
                        finally { btn.disabled = false; btn.textContent = '▶ Listen'; }
                    });
                });
                // Store summary data for each call and bind Summary buttons
                const __callSummaryMap = {};
                calls.forEach(h => {
                    if (h.summary || h.transcript) {
                        __callSummaryMap[h.call_sid] = { summary: h.summary || '', transcript: h.transcript || '', caller: h.caller_name || h.from_number || 'Unknown', direction: h.direction || 'inbound', duration: h.call_duration || 0, time: h.call_start_time || '' };
                    }
                });
                Array.prototype.forEach.call(table.querySelectorAll('.vmo-view-summary-btn'), function(btn){
                    btn.addEventListener('click', ()=>{
                        const sid = btn.getAttribute('data-callsid');
                        const info = __callSummaryMap[sid];
                        if (!info) { notify('No summary available','warning'); return; }
                        openCallSummaryModal(sid, info);
                    });
                });
            }catch(e){ console.warn('Call history load failed', e); if(wrap) wrap.innerHTML = '<div style="color:var(--muted); padding:20px; text-align:center;">Failed to load call history.</div>'; }
        }
        function openCallSummaryModal(callSid, info) {
            let existing = document.getElementById('vmo-summary-modal');
            if (!existing) {
                existing = document.createElement('div');
                existing.id = 'vmo-summary-modal';
                existing.style.cssText = 'display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.7); z-index:100000; align-items:center; justify-content:center;';
                existing.innerHTML = '<div id="vmo-summary-modal-inner" style="background:var(--bg-card, #1e1e2e); border:1px solid rgba(255,255,255,.1); border-radius:12px; padding:24px; max-width:640px; width:90%; max-height:80vh; overflow-y:auto; position:relative;"><button id="vmo-summary-close" style="position:absolute; top:12px; right:16px; background:none; border:none; color:var(--muted, #888); font-size:20px; cursor:pointer;">✕</button><div id="vmo-summary-content"></div></div>';
                document.body.appendChild(existing);
                document.getElementById('vmo-summary-close').addEventListener('click', () => { existing.style.display = 'none'; });
                existing.addEventListener('click', (e) => { if (e.target === existing) existing.style.display = 'none'; });
            }
            const content = document.getElementById('vmo-summary-content');
            let summaryText = info.summary || '';
            let parsed = null;
            try { parsed = JSON.parse(summaryText); } catch(_) {}

            let html = '<h3 style="margin:0 0 16px; color:var(--ink, #fff); font-size:16px;">📋 Call Summary</h3>';
            html += '<div style="display:flex; gap:12px; flex-wrap:wrap; margin-bottom:14px; font-size:12px; color:var(--muted, #888);">';
            html += '<span>📞 ' + (info.caller || 'Unknown') + '</span>';
            html += '<span>' + (info.direction === 'outbound' ? '📤 Outbound' : '📥 Inbound') + '</span>';
            const dur = info.duration > 0 ? (Math.floor(info.duration/60) + 'm ' + (info.duration % 60) + 's') : '0s';
            html += '<span>⏱ ' + dur + '</span>';
            if (info.time) { const d = new Date(info.time); if (!isNaN(d)) html += '<span>🕐 ' + d.toLocaleString() + '</span>'; }
            html += '</div>';

            if (parsed && typeof parsed === 'object') {
                if (parsed.summary) html += '<div style="margin-bottom:14px; padding:12px; background:rgba(26,115,232,.08); border-left:3px solid #1a73e8; border-radius:6px; font-size:13px; line-height:1.6; color:var(--ink, #fff);">' + String(parsed.summary).replace(/</g,'&lt;').replace(/\n/g,'<br>') + '</div>';
                if (parsed.caller_intent) html += '<div style="margin-bottom:8px; font-size:12px;"><strong style="color:var(--muted);">Intent:</strong> <span style="color:var(--ink, #fff);">' + String(parsed.caller_intent).replace(/</g,'&lt;') + '</span></div>';
                if (parsed.sentiment) html += '<div style="margin-bottom:8px; font-size:12px;"><strong style="color:var(--muted);">Sentiment:</strong> <span style="color:var(--ink, #fff);">' + String(parsed.sentiment).replace(/</g,'&lt;') + '</span></div>';
                if (parsed.crm_category) html += '<div style="margin-bottom:8px; font-size:12px;"><strong style="color:var(--muted);">Category:</strong> <span style="color:var(--ink, #fff);">' + String(parsed.crm_category).replace(/</g,'&lt;') + '</span></div>';
                if (Array.isArray(parsed.actions_required) && parsed.actions_required.length) {
                    html += '<div style="margin-top:12px; padding:10px; background:rgba(255,152,0,.08); border-left:3px solid #FF9800; border-radius:6px;"><strong style="font-size:12px; color:#FF9800; display:block; margin-bottom:6px;">📋 Follow-Up Actions</strong><ul style="margin:0; padding-left:16px; font-size:12px; color:var(--ink, #fff); line-height:1.8;">';
                    parsed.actions_required.forEach(a => { html += '<li>' + String(a.action || a).replace(/</g,'&lt;') + '</li>'; });
                    html += '</ul></div>';
                }
                if (Array.isArray(parsed.promises_made) && parsed.promises_made.length) {
                    html += '<div style="margin-top:10px; padding:10px; background:rgba(76,175,80,.08); border-left:3px solid #4CAF50; border-radius:6px;"><strong style="font-size:12px; color:#4CAF50; display:block; margin-bottom:6px;">🤝 Promises Made</strong><ul style="margin:0; padding-left:16px; font-size:12px; color:var(--ink, #fff); line-height:1.8;">';
                    parsed.promises_made.forEach(p => { html += '<li>' + String(p.promise || p).replace(/</g,'&lt;') + '</li>'; });
                    html += '</ul></div>';
                }
            } else if (summaryText) {
                html += '<div style="padding:12px; background:rgba(26,115,232,.08); border-left:3px solid #1a73e8; border-radius:6px; font-size:13px; line-height:1.6; color:var(--ink, #fff); white-space:pre-wrap;">' + summaryText.replace(/</g,'&lt;') + '</div>';
            }

            if (info.transcript) {
                html += '<details style="margin-top:14px;"><summary style="cursor:pointer; font-size:12px; color:var(--muted, #888); padding:6px 0;">📝 View Full Transcript</summary>';
                html += '<div style="margin-top:8px; padding:10px; background:rgba(0,0,0,.2); border-radius:6px; font-size:12px; line-height:1.6; color:var(--ink, #fff); white-space:pre-wrap; max-height:40vh; overflow-y:auto;">' + String(info.transcript).replace(/</g,'&lt;') + '</div>';
                html += '</details>';
            }

            content.innerHTML = html;
            existing.style.display = 'flex';
        }

        function openRecordingModal(url, meta){
            const modal = document.getElementById('vmo-recording-modal'); if(!modal) return;
            const audio = document.getElementById('vmo-rec-audio');
            const alt = document.getElementById('vmo-rec-alt');
            const m = document.getElementById('vmo-rec-meta');
            const transcript = (meta && Array.isArray(meta.transcript)) ? meta.transcript : [];
            const callDuration = (meta && meta.callDuration) ? parseInt(meta.callDuration, 10) : 0;
            const callStatus = (meta && meta.callStatus) ? String(meta.callStatus) : '';

            if (audio) {
                try { audio.pause(); } catch(_) {}
                try { audio.currentTime = 0; } catch(_) {}
                try { audio.autoplay = false; } catch(_) {}
                try { audio.preload = 'metadata'; } catch(_) {}
                try { audio.removeAttribute('autoplay'); } catch(_) {}
            }

            if (url) {
                audio.src = url; audio.style.display='block'; alt.style.display='none';
                m.textContent = `Call ${meta.callSid||''} • ${meta.duration?('Duration: '+meta.duration+'s • '):''}${meta.created?('Created: '+meta.created):''}`;
            } else {
                audio.removeAttribute('src'); audio.style.display='none';
                // Show transcript fallback when no audio recording
                if (transcript.length > 0) {
                    let html = '<div style="font-size:12px; color:var(--muted); margin-bottom:8px;">🎙️ No audio recording — showing AI conversation transcript:</div>';
                    html += '<div style="max-height:50vh; overflow-y:auto; padding:8px; background:rgba(0,0,0,.25); border-radius:8px; font-family:monospace; font-size:12px; line-height:1.8;">';
                    transcript.forEach(t => {
                        const speaker = String(t.speaker||'').toUpperCase();
                        const isAI = /AI|ASSISTANT|SYSTEM|BOT/.test(speaker);
                        const color = isAI ? '#3b82f6' : '#10b981';
                        const label = isAI ? '🤖 AI' : '👤 Caller';
                        const msg = String(t.message||'').replace(/</g,'&lt;');
                        const time = t.time ? '<span style="opacity:.5; font-size:10px; margin-left:6px;">' + String(t.time).replace('T',' ').slice(11,19) + '</span>' : '';
                        html += `<div style="margin-bottom:6px;"><strong style="color:${color};">${label}</strong>${time}<br><span style="color:var(--ink);">${msg}</span></div>`;
                    });
                    html += '</div>';
                    alt.innerHTML = html; alt.style.display='block';
                    m.textContent = `Call ${meta.callSid||''} • Transcript (${transcript.length} messages)`;
                } else if (callDuration === 0) {
                    // Call was never answered / connected
                    alt.innerHTML = '<div style="color:#f59e0b; font-size:13px;">📵 This call was not answered or connected (duration: 0s).<br><span style="font-size:11px; color:var(--muted);">No recording exists because the call never went through.</span></div>';
                    alt.style.display='block';
                    m.textContent = `Call ${meta.callSid||''} • Not answered`;
                } else {
                    // Build diagnostic detail from debug data
                    const debug = (meta && meta.debug) || {};
                    const tw = debug.twilio_debug || {};
                    let diagHtml = '';
                    if (Object.keys(tw).length > 0) {
                        diagHtml = '<div style="margin-top:10px; padding:8px; background:rgba(0,0,0,.25); border-radius:6px; font-family:monospace; font-size:10px; color:var(--muted); max-height:150px; overflow-y:auto;">';
                        diagHtml += '<div style="margin-bottom:4px; font-weight:bold; color:#f59e0b;">🔍 Twilio API Diagnostic:</div>';
                        if (tw.call_status) diagHtml += '<div>Call Status on Twilio: <strong>' + tw.call_status + '</strong></div>';
                        if (tw.call_direction) diagHtml += '<div>Direction: ' + tw.call_direction + '</div>';
                        if (tw.call_duration !== undefined) diagHtml += '<div>Duration (Twilio): ' + tw.call_duration + 's</div>';
                        if (tw.tier1_count !== undefined) diagHtml += '<div>Tier 1 (call-scoped): ' + tw.tier1_count + ' recordings</div>';
                        if (tw.tier1_error) diagHtml += '<div style="color:salmon;">Tier 1 error: ' + String(tw.tier1_error).replace(/</g,'&lt;') + '</div>';
                        if (tw.tier2_count !== undefined) diagHtml += '<div>Tier 2 (account filtered): ' + tw.tier2_count + ' recordings</div>';
                        if (tw.tier3_total !== undefined) diagHtml += '<div>Tier 3 (broad): ' + tw.tier3_total + ' total recordings on account</div>';
                        if (tw.tier3_sids && tw.tier3_sids.length) diagHtml += '<div>Recording SIDs found: ' + tw.tier3_sids.join(', ') + '</div>';
                        if (tw.child_calls !== undefined) diagHtml += '<div>Child calls: ' + tw.child_calls + '</div>';
                        if (tw.child_sid) diagHtml += '<div>Child SID: ' + tw.child_sid + '</div>';
                        if (tw.child_rec_count !== undefined) diagHtml += '<div style="color:#10b981;">Child recordings: ' + tw.child_rec_count + '</div>';
                        if (tw.error) diagHtml += '<div style="color:salmon;">Error: ' + String(tw.error).replace(/</g,'&lt;') + '</div>';
                        diagHtml += '</div>';
                    }
                    alt.innerHTML = '<div style="color:salmon; font-size:13px;">No recording or transcript available for this call.<br><span style="font-size:11px; color:var(--muted);">The recording may not have been saved. Check that <strong>Call Recording</strong> is enabled in Phone Settings.</span></div>' + diagHtml;
                    alt.style.display='block';
                    m.textContent = `Call ${meta.callSid||''} • No recording available`;
                }
            }
            modal.style.display='flex';
            const close = document.getElementById('vmo-rec-close'); if (close) close.onclick = ()=>{
                modal.style.display='none';
                if (audio) {
                    try { audio.pause(); } catch(_) {}
                    try { audio.currentTime = 0; } catch(_) {}
                    try { audio.removeAttribute('src'); } catch(_) {}
                    try { audio.load(); } catch(_) {}
                }
            };
        }

    // Manual window assignments removed as functions are now defined directly on window
        // Ensure modal-related actions are globally accessible for inline onclick handlers
        window.showWeeklyBriefing = window.showWeeklyBriefing || showWeeklyBriefing;
        window.openAddObjective = window.openAddObjective || openAddObjective;
        window.openScheduleTask = window.openScheduleTask || openScheduleTask;
        window.openWeeklyActions = window.openWeeklyActions || openWeeklyActions;
        window.approveAllActions = window.approveAllActions || approveAllActions;
        window.customizeStrategy = window.customizeStrategy || customizeStrategy;
        window.hideModal = window.hideModal || hideModal;
    </script>
    <script>
    console.log('[VMO] Script Block 2 Loaded');
    // Final attach once real implementations exist
    if(typeof loadVisitorsPanel==='function') window.loadVisitorsPanel = loadVisitorsPanel;
    if(typeof loadDemographicsPanel==='function') window.loadDemographicsPanel = loadDemographicsPanel;
    if(typeof loadConversionPanel==='function') window.loadConversionPanel = loadConversionPanel;
    if(typeof loadCompetitorPanel==='function') window.loadCompetitorPanel = loadCompetitorPanel;
    if(typeof togglePanel==='function') window.togglePanel = togglePanel;
    // ✅ NEW v9.0.2: Expose additional tab loaders for post-consultation automation
    if(typeof loadEmailPanel==='function') window.loadEmailPanel = loadEmailPanel;
    if(typeof loadSEOPanel==='function') window.loadSEOPanel = loadSEOPanel;
    if(typeof loadEmailBuilderPanel==='function') window.loadEmailBuilderPanel = loadEmailBuilderPanel;
    if(typeof loadEmailAccounts==='function') window.loadEmailAccounts = loadEmailAccounts;

    // Initialize cross-browser date pickers (fallback for browsers without native calendar)
    if (typeof attachDatePickers !== 'function') { window.attachDatePickers = function(){}; }
    function attachDatePickers(scope){
        if (!window.jQuery || !jQuery.fn || !jQuery.fn.datepicker) return; // jQuery UI datepicker not available
        const $scope = scope ? (scope instanceof Element ? jQuery(scope) : jQuery('body')) : jQuery('body');
        $scope.find('input.vmo-date').each(function(){
            const $i = jQuery(this);
            if ($i.data('vmoDatepickerAttached')) return;
            // Force text type to ensure jQuery UI can attach consistently
            try { if (this.type === 'date') { this.type = 'text'; } } catch(e){}
            $i.attr('autocomplete','off');
            $i.datepicker({
                dateFormat: 'yy-mm-dd',
                changeMonth: true,
                changeYear: true,
                onClose: function(){ this.dispatchEvent(new Event('change', { bubbles: true })); }
            });
            $i.data('vmoDatepickerAttached', true);
        });
    }

    // Hook date pickers on DOM ready
    document.addEventListener('DOMContentLoaded', initDocumentHub);
    document.addEventListener('DOMContentLoaded', function(){ attachDatePickers(document); });

    // Ensure date pickers also attach when panels are first opened
    const __origTogglePanel = typeof togglePanel === 'function' ? togglePanel : null;
    if (__origTogglePanel) {
        window.togglePanel = function(id, onOpen){
            __origTogglePanel(id, function(){
                // After panel is shown, attach pickers within that panel
                const panel = document.getElementById(id);
                if (panel) {
                    attachDatePickers(panel);
                    // Proactively build demographics skeleton when that panel opens
                    if (id === 'vmo-demo-panel' && typeof ensureDemographicsSkeleton === 'function') {
                        try { ensureDemographicsSkeleton(); } catch(e) {}
                        // If cards exist but are hidden, unhide them defensively
                        try {
                            const cards = panel.querySelector('.vmo-cards');
                            if (cards && window.getComputedStyle(cards).display === 'none') {
                                cards.style.display = 'grid';
                                console.info('[VMO] Demographics: unhid cards after open');
                            }
                        } catch(e){}
                    }
                }
                if (typeof onOpen === 'function') onOpen();
            });
        }
    }

    // Initial load
    if (typeof loadDashboardOverview==='function') loadDashboardOverview();

    async function bootPhoneDashboardUI(force){
        if (window.__vmoPhoneBootInProgress) return;
        if (window.__vmoPhoneBootDone && !force) return;
        window.__vmoPhoneBootInProgress = true;
        try {
            console.log('[VMO Phone] Bootstrapping dashboard phone controls...');
            try { loadRingPrefs(); } catch(e) { console.warn('[VMO Phone] loadRingPrefs failed:', e); }
            try { await syncPhonePrefsFromServer({ persistLocal: true }); } catch(e) { console.warn('[VMO Phone] syncPhonePrefsFromServer failed:', e); }
            try {
                if (!window.__vmoPhoneBindingsReady) {
                    bindDialer();
                    window.__vmoPhoneBindingsReady = true;
                }
            } catch(e) { console.warn('[VMO Phone] bindDialer failed:', e); }
            try {
                if (typeof startRingPoll === 'function') startRingPoll();
            } catch(e) { console.warn('[VMO Phone] startRingPoll failed:', e); }
	            try {
	                if (!window.__vmoPhoneAnalyticsBound) {
                    const anlBtn = document.getElementById('vmo-anl-refresh');
                    if (anlBtn) {
                        anlBtn.addEventListener('click', function(){ try{ loadPhoneAnalytics(); }catch(e){} });
                    }
                    window.__vmoPhoneAnalyticsBound = true;
                }
            } catch(_) {}
            try {
                if (!window.__vmoAssignedNotesBound) {
                    const notesEl = document.getElementById('vmo-assigned-notes');
                    if (notesEl) {
                        const existing = localStorage.getItem('vmo.assigned.notes') || '';
                        if (!notesEl.value) notesEl.value = existing;
                        notesEl.addEventListener('input', function(){
                            try { localStorage.setItem('vmo.assigned.notes', notesEl.value || ''); } catch(_) {}
                        });
                    }
                    window.__vmoAssignedNotesBound = true;
                }
            } catch(_) {}
            window.__vmoPhoneBootDone = true;
        } finally {
            window.__vmoPhoneBootInProgress = false;
        }
    }

    function schedulePhoneDashboardBoot(force){
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function(){ bootPhoneDashboardUI(!!force); }, { once: true });
            return;
        }
        setTimeout(function(){ bootPhoneDashboardUI(!!force); }, 0);
    }

    schedulePhoneDashboardBoot(false);
    window.addEventListener('pageshow', function(){ schedulePhoneDashboardBoot(true); });
    setTimeout(function(){ schedulePhoneDashboardBoot(true); }, 1500);
    setInterval(function(){
        if (document.hidden) return;
        if (!__twilioReady || !__ringPollActive || !window.__vmoPhoneBootDone) {
            schedulePhoneDashboardBoot(true);
        }
    }, 15000);
    // Safety: ensure demographics skeleton exists even before first open (in case of older markup)
    try {
        if (typeof ensureDemographicsSkeleton === 'function') {
            document.addEventListener('DOMContentLoaded', function(){
                ensureDemographicsSkeleton();
                // Watchdog: for a short window, if the panel is shown and lacks cards, inject again
                let attempts = 0;
                const maxAttempts = 20; // ~6 seconds
                const tick = setInterval(()=>{
                    attempts++;
                    const panel = document.getElementById('vmo-demo-panel');
                    if (!panel) { clearInterval(tick); return; }
                    const visible = panel.style.display === 'block' || (window.getComputedStyle(panel).display !== 'none');
                    const hasCards = !!panel.querySelector('.vmo-cards');
                    if (visible && !hasCards) {
                        console.warn('[VMO] Demographics: watchdog reinjection');
                        ensureDemographicsSkeleton();
                    }
                    if (attempts >= maxAttempts) clearInterval(tick);
                }, 300);
                // Optional: auto-open demographics once so users see it populated immediately
                try {
                    const opened = sessionStorage.getItem('vmo_demo_auto_opened');
                    if (!opened && typeof window.togglePanel === 'function') {
                        sessionStorage.setItem('vmo_demo_auto_opened','1');
                        window.togglePanel('vmo-demo-panel', window.loadDemographicsPanel);
                    }
                } catch(e){}
            });
        }
    } catch(e) { console.error('[VMO] Demographics init error:', e); }

        /* ============================================================
           SHIPPING & FULFILLMENT FUNCTIONS
        ============================================================ */
        
        // Load Active Orders Panel
        window.loadActiveOrdersPanel = function() {
            const listContainer = document.getElementById('vmo-active-orders-list');
            const countBadge = document.getElementById('vmo-active-orders-count');
            
            if (listContainer) listContainer.innerHTML = '<div class="vmo-card"><p>Loading active orders...</p></div>';
            
            ajaxPost('vmo_get_active_orders', {}).then(({success, data}) => {
                if (success && data) {
                    const orders = data.orders || [];
                    if (countBadge) countBadge.textContent = orders.length;
                    
                    if (orders.length === 0) {
                        if (listContainer) listContainer.innerHTML = '<div class="vmo-card"><p style="color: var(--muted);">No active orders found.</p></div>';
                        return;
                    }
                    
                    let ordersHtml = '';
                    orders.forEach(order => {
                        const isBusinessFlow = !!order.payment_order_id || data.source === 'business_flow_tasks';
                        const orderLabel = isBusinessFlow ? `Task #${order.id}` : `Order #${order.id}`;
                        const valueLine = isBusinessFlow
                            ? `${order.currency ? String(order.currency).toUpperCase() : 'USD'} ${order.total || '0.00'} • ${order.shipping_status || 'awaiting_fulfillment'}`
                            : `${order.items_count} items • $${order.total}`;
                        const ownerAction = order.owner_action ? `<div class="shipping-order-customer" style="color:var(--muted);">${String(order.owner_action).replace(/</g, '&lt;')}</div>` : '';
                        const actionText = isBusinessFlow ? 'Complete' : 'Ship';
                        const actionTitle = isBusinessFlow ? 'Mark this business flow completed.' : 'Approve this order for shipment.';
                        ordersHtml += `
                            <div class="shipping-order-item">
                                <div class="shipping-order-info">
                                    <div class="shipping-order-id">${orderLabel}</div>
                                    <div class="shipping-order-customer">${order.customer_name} - ${order.customer_email}</div>
                                    ${ownerAction}
                                    <div class="shipping-order-value">${valueLine}</div>
                                </div>
                                <div class="shipping-order-actions">
                                    <button class="action-btn" onclick="window.viewOrderDetails('${order.id}')" title="View full order and shipping details." style="font-size: 10px;">👁️</button>
                                    <button class="approve-shipment-btn" onclick="window.approveShipment('${order.id}', event)" title="${actionTitle}">✅ ${actionText}</button>
                                </div>
                            </div>
                        `;
                    });
                    
                    if (listContainer) listContainer.innerHTML = ordersHtml;
                } else {
                    // Handle success=false but valid response (e.g. empty)
                    if (listContainer) listContainer.innerHTML = '<div class="vmo-card"><p style="color: var(--muted);">No active orders found.</p></div>';
                }
            }).catch(() => {
                // Fallback for actual network errors
                if (listContainer) listContainer.innerHTML = '<div class="vmo-card"><p style="color: var(--muted);">No active orders found.</p></div>';
            });
        };
        
        // Load Shipping Settings Panel
        window.loadShippingSettingsPanel = function() {
            const carrierCount = document.getElementById('vmo-carriers-count');

            // If the user has unsaved edits, don't overwrite checkbox states.
            if (window.__vmoShippingDirty) {
                if (carrierCount && (!carrierCount.textContent || carrierCount.textContent === '—')) {
                    carrierCount.textContent = '…';
                }
                return;
            }

            ajaxPost('vmo_get_shipping_settings', {}).then(({success, data}) => {
                if (success && data) {
                    const enabledCarriers = (data.carriers || []).filter(c => c.enabled).length;
                    const enabledFulfillment = (data.fulfillment || []).filter(f => f.enabled).length;
                    
                    if (carrierCount) carrierCount.textContent = `${enabledCarriers + enabledFulfillment}`;
                    
                    // Update checkboxes based on current settings
                    (data.carriers || []).forEach(carrier => {
                        const checkbox = document.getElementById(carrier.id + '-enabled');
                        if (checkbox) checkbox.checked = carrier.enabled;
                    });
                    
                    (data.fulfillment || []).forEach(fulfillment => {
                        const checkbox = document.getElementById(fulfillment.id + '-enabled');
                        if (checkbox) checkbox.checked = fulfillment.enabled;
                    });

                    try { window.renderShippingProviderContacts(data); } catch(e) {}

                    // Mark panel as initialized and watch for user edits.
                    try {
                        if (!window.__vmoShippingWatchBound) {
                            window.__vmoShippingWatchBound = true;
                            window.__vmoShippingDirty = false;
                            const panel = document.getElementById('vmo-shipping-settings-panel');
                            if (panel) {
                                const boxes = panel.querySelectorAll('input[type="checkbox"]');
                                boxes.forEach(cb => {
                                    cb.addEventListener('change', () => { window.__vmoShippingDirty = true; }, { passive: true });
                                });
                            }
                        }
                    } catch(e) {}
                }
            }).catch(() => {
                if (carrierCount) carrierCount.textContent = '—';
            });
        };

        window.renderShippingProviderContacts = function(settings) {
            const toArray = (v) => Array.isArray(v) ? v : [];
            const providers = [...toArray(settings.carriers), ...toArray(settings.fulfillment)];

            const allSlots = document.querySelectorAll('.vmo-provider-contacts[data-provider]');
            allSlots.forEach(el => { el.textContent = ''; });

            const appendLink = (container, href, text) => {
                const a = document.createElement('a');
                a.href = href;
                a.target = href.startsWith('http') ? '_blank' : '';
                a.rel = href.startsWith('http') ? 'noopener noreferrer' : '';
                a.textContent = text;
                container.appendChild(a);
            };

            providers.forEach(p => {
                const id = (p && p.id) ? String(p.id) : '';
                if (!id) return;
                const slot = document.querySelector(`.vmo-provider-contacts[data-provider="${CSS.escape(id)}"]`);
                if (!slot) return;

                const links = [];
                if (p.support_phone) links.push({ href: `tel:${String(p.support_phone).replace(/\s+/g,'')}`, text: `${p.support_phone_label ? p.support_phone_label + ': ' : ''}${p.support_phone}` });
                if (p.sales_phone) links.push({ href: `tel:${String(p.sales_phone).replace(/\s+/g,'')}`, text: `${p.sales_phone_label ? p.sales_phone_label + ': ' : ''}${p.sales_phone}` });
                if (p.support_email) links.push({ href: `mailto:${p.support_email}`, text: `${p.support_email_label ? p.support_email_label + ': ' : ''}${p.support_email}` });
                if (p.support_url) links.push({ href: p.support_url, text: 'Support' });
                if (p.office_locator_url) links.push({ href: p.office_locator_url, text: 'Office locator' });
                if (p.sales_url) links.push({ href: p.sales_url, text: 'Sales' });
                if (p.contact_url) links.push({ href: p.contact_url, text: 'Contact' });

                links.forEach((l, idx) => {
                    if (idx > 0) {
                        const sep = document.createElement('span');
                        sep.textContent = '•';
                        sep.style.opacity = '0.6';
                        slot.appendChild(sep);
                    }
                    appendLink(slot, l.href, l.text);
                });
            });
        };
        
        // Load Shipping Analytics Panel
        window.loadShippingAnalyticsPanel = function() {
            const weekCount = document.getElementById('vmo-shipping-week-count');
            const avgTime = document.getElementById('vmo-avg-fulfillment-time');
            const savings = document.getElementById('vmo-shipping-savings');
            const deliveryRate = document.getElementById('vmo-delivery-rate');
            const shippedBadge = document.getElementById('vmo-shipped-this-week');
            
            ajaxPost('vmo_get_shipping_analytics', {}).then(({success, data}) => {
                if (success && data) {
                    if (weekCount) weekCount.textContent = data.week_shipped || '0';
                    if (avgTime) avgTime.textContent = data.avg_fulfillment_time || '—';
                    if (savings) savings.textContent = data.ai_savings ? `$${data.ai_savings}` : '—';
                    if (deliveryRate) deliveryRate.textContent = data.on_time_rate ? `${data.on_time_rate}%` : '—';
                    if (shippedBadge) shippedBadge.textContent = data.week_shipped || '—';
                    
                    // Update chart if data available
                    if (data.cost_breakdown) {
                        updateShippingCostsChart(data.cost_breakdown);
                    }
                }
            }).catch(() => {
                if (weekCount) weekCount.textContent = '—';
                if (avgTime) avgTime.textContent = '—';
                if (savings) savings.textContent = '—';
                if (deliveryRate) deliveryRate.textContent = '—';
            });
        };
        
        // Load AI Shipping Recommendations Panel
        window.loadShippingAIPanel = function() {
            const recommendationsContainer = document.getElementById('vmo-shipping-ai-recommendations');
            const countBadge = document.getElementById('vmo-ai-shipping-recommendations');
            
            if (recommendationsContainer) {
                recommendationsContainer.innerHTML = '<div class="vmo-card"><p>Loading AI recommendations...</p></div>';
            }
            
            ajaxPost('vmo_get_shipping_ai_recommendations', {}).then(({success, data}) => {
                if (success && data) {
                    const recommendations = data.recommendations || [];
                    if (countBadge) countBadge.textContent = recommendations.length;
                    
                    if (recommendations.length === 0) {
                        if (recommendationsContainer) {
                            recommendationsContainer.innerHTML = '<div class="vmo-card"><p style="color: var(--muted);">No recommendations available</p></div>';
                        }
                        return;
                    }
                    
                    let recsHtml = '';
                    recommendations.forEach((rec, index) => {
                        recsHtml += `
                            <div class="vmo-card">
                                <h5 style="color: var(--cyan-soft); margin: 0 0 8px;">${rec.title}</h5>
                                <p style="color: var(--ink); font-size: 11px; margin: 0 0 8px;">${rec.description}</p>
                                <div style="display: flex; justify-content: space-between; align-items: center;">
                                    <small style="color: var(--muted);">Impact: ${rec.impact} • Savings: $${rec.savings || 0}</small>
                                    <button class="action-btn primary compact" onclick="approveShippingRecommendation('${rec.id}')">✅ Apply</button>
                                </div>
                            </div>
                        `;
                    });
                    
                    if (recommendationsContainer) recommendationsContainer.innerHTML = recsHtml;
                }
            }).catch(() => {
                if (recommendationsContainer) {
                    recommendationsContainer.innerHTML = '<div class="vmo-card"><p style="color: salmon;">Error loading recommendations</p></div>';
                }
            });
        };
        
        // Shipping Action Functions
        window.refreshActiveOrders = function() {
            window.loadActiveOrdersPanel();
        };
        
        window.approveShipment = function(orderId, evt) {
            const currentText = (evt && evt.target && evt.target.textContent) ? evt.target.textContent : '';
            const completionAction = currentText.indexOf('Complete') !== -1;
            if (!confirm(completionAction ? 'Mark this business flow completed?' : 'Approve this order for shipment?')) return;
            const btn = (evt && evt.target) ? evt.target : null;
            if (btn) {
                btn.disabled = true;
                btn.textContent = '⏳ Processing...';
            }
            
            ajaxPost('vmo_approve_shipment', { order_id: orderId, status: completionAction ? 'completed' : 'approved' }).then(({success, data, message}) => {
                if (success) {
                    const msg = (data && data.message) ? data.message : (message || 'Shipment approved.');
                    notify(msg, 'success');
                    setTimeout(() => {
                        window.loadActiveOrdersPanel(); // Refresh the list
                    }, 1000);
                } else {
                    notify(message || 'Failed to approve shipment', 'error');
                    if (btn) { btn.disabled = false; btn.textContent = '✅ Ship'; }
                }
            }).catch(() => {
                notify('Error approving shipment', 'error');
                if (btn) { btn.disabled = false; btn.textContent = '✅ Ship'; }
            });
        };
        
        window.viewOrderDetails = function(orderId) {
            const modal = document.getElementById('vmo-order-details-modal');
            if (modal) {
                modal.style.display = 'flex';

                const content = document.getElementById('vmo-order-details-content');
                if (content) {
                    content.innerHTML = '<div style="text-align:center; padding: 26px; color: var(--muted);">Loading order…</div>';
                }

                ajaxPost('vmo_get_order_details', { order_id: String(orderId) })
                    .then(({success, data, message}) => {
                        if (!success || !data) {
                            if (content) content.innerHTML = `<div style="color: salmon; padding: 18px;">${(message || 'Failed to load order details')}</div>`;
                            return;
                        }

                        modal.dataset.orderId = String(data.id || orderId);
                        const address = (data.shipping_address || '').replace(/\n/g, '<br>');
                        const tracking = data.tracking_number ? String(data.tracking_number) : '—';
                        const carrier = data.carrier ? String(data.carrier) : '—';
                        const total = `${data.currency || 'USD'} ${data.total || '0.00'}`;

                        if (content) {
                            content.innerHTML = `
                                <div style="display:grid; grid-template-columns: 1fr 1fr; gap: 14px;">
                                    <div class="vmo-card" style="margin:0;">
                                        <h4 style="margin:0 0 8px;">Order #${data.id}</h4>
                                        <div style="color: var(--muted); font-size: 12px;">Created: ${data.created_at || '—'}</div>
                                        <div style="margin-top:10px;">
                                            <div><strong>Status:</strong> ${data.status || '—'}</div>
                                            <div><strong>Shipping:</strong> ${data.shipping_status || '—'}</div>
                                            <div><strong>Total:</strong> ${total}</div>
                                        </div>
                                    </div>
                                    <div class="vmo-card" style="margin:0;">
                                        <h4 style="margin:0 0 8px;">Customer</h4>
                                        <div><strong>Name:</strong> ${data.customer_name || '—'}</div>
                                        <div><strong>Email:</strong> ${data.customer_email || '—'}</div>
                                        <div style="margin-top:10px;"><strong>Ship To:</strong><div style="margin-top:6px; color: var(--muted);">${address || '—'}</div></div>
                                    </div>
                                </div>
                                <div class="vmo-card" style="margin-top: 14px;">
                                    <h4 style="margin:0 0 8px;">Shipping</h4>
                                    <div><strong>Carrier:</strong> ${carrier}</div>
                                    <div><strong>Tracking:</strong> ${tracking}</div>
                                    <div><strong>Shipped At:</strong> ${data.shipped_at || '—'}</div>
                                </div>
                            `;
                        }
                    })
                    .catch(() => {
                        if (content) content.innerHTML = '<div style="color: salmon; padding: 18px;">Error loading order details</div>';
                    });
            } else {
                notify(`Opening details for Order #${orderId}`, 'info');
            }
        };
        
        window.configureCarrier = function(carrierId) {
            const modal = document.getElementById('vmo-carrier-config-modal');
            if (modal) {
                modal.style.display = 'flex';
                const nameInput = document.getElementById('vmo-carrier-name');
                if (nameInput) nameInput.value = carrierId.toUpperCase();

                // Prefill saved config (if any)
                const carrierKey = String(carrierId || '').toLowerCase();
                if (carrierKey) {
                    ajaxPost('vmo_get_carrier_config', { carrier_id: carrierKey })
                        .then(({success, data}) => {
                            if (!success || !data) return;
                            const apiKeyEl = document.getElementById('vmo-carrier-api-key');
                            const secretEl = document.getElementById('vmo-carrier-secret');
                            const serviceEl = document.getElementById('vmo-carrier-service');
                            if (apiKeyEl && typeof data.api_key !== 'undefined') apiKeyEl.value = data.api_key || '';
                            if (secretEl && typeof data.secret !== 'undefined') secretEl.value = data.secret || '';
                            if (serviceEl && typeof data.service !== 'undefined' && data.service) serviceEl.value = data.service;
                        })
                        .catch(() => {});
                }
            } else {
                notify(`Opening ${carrierId.toUpperCase()} configuration...`, 'info');
            }
        };
        
        window.configureFulfillment = function(fulfillmentId) {
            const modal = document.getElementById('vmo-fulfillment-config-modal');
            if (modal) {
                modal.style.display = 'flex';
                const providerInput = document.getElementById('vmo-fulfillment-provider');
                if (providerInput) providerInput.value = fulfillmentId;
            } else {
                notify(`Opening ${fulfillmentId} fulfillment configuration...`, 'info');
            }
        };
        
        window.saveShippingSettings = function(evt) {
            const btn = (evt && evt.target) ? evt.target : null;
            if (btn) { btn.disabled = true; btn.textContent = '⏳ Saving...'; }

            const carrierSettings = {};
            const fulfillmentSettings = {};

            // Collect settings directly from the UI to avoid hardcoding (global + regional + networks)
            const panel = document.getElementById('vmo-shipping-settings-panel');
            if (panel) {
                const carrierBoxes = panel.querySelectorAll('#vmo-global-carrier-list input[type="checkbox"], #vmo-regional-carrier-list input[type="checkbox"]');
                carrierBoxes.forEach(cb => {
                    const id = (cb.id || '').replace(/-enabled$/, '');
                    if (id) carrierSettings[id] = !!cb.checked;
                });
                const fulfillmentBoxes = panel.querySelectorAll('#vmo-fulfillment-list input[type="checkbox"]');
                fulfillmentBoxes.forEach(cb => {
                    const id = (cb.id || '').replace(/-enabled$/, '');
                    if (id) fulfillmentSettings[id] = !!cb.checked;
                });
            }

            ajaxPost('vmo_save_shipping_settings', { carriers: carrierSettings, fulfillment: fulfillmentSettings }).then(({success, message}) => {
                if (success) {
                    notify('Shipping settings saved!', 'success');
                    window.__vmoShippingDirty = false;
                    try { window.loadShippingSettingsPanel(); } catch(e) {}
                } else {
                    notify(message || 'Failed to save settings', 'error');
                }
            }).catch(() => {
                notify('Error saving settings', 'error');
            }).finally(() => {
                if (btn) { btn.disabled = false; btn.textContent = '💾 Save Settings'; }
            });
        };
        
        window.testShippingIntegration = function() {
            notify('Checking shipping providers...', 'info');
            
            ajaxPost('vmo_test_shipping_integration', {}).then(({success, data, message}) => {
                if (success) {
                    const results = data.results || {};
                    let resultText = 'Integration Test Results:\n';
                    Object.keys(results).forEach(service => {
                        const r = results[service];
                        const ok = (r && typeof r === 'object') ? !!r.success : !!r;
                        const msg = (r && typeof r === 'object' && r.message) ? ` - ${r.message}` : '';
                        resultText += `${service}: ${ok ? '✅ Configured' : '⚠️ Manual setup'}${msg}\n`;
                    });
                    alert(resultText);
                    notify('Provider check completed', 'success');
                } else {
                    notify(message || 'Integration test failed', 'error');
                }
            }).catch(() => {
                notify('Error testing integration', 'error');
            });
        };
        
        window.generateShippingRecommendations = function(evt) {
            notify('Shipping recommendations are disabled until real carrier/fulfillment integrations are implemented.', 'info');
        };
        
        window.approveShippingRecommendation = function(recId) {
            notify('Shipping optimizations are disabled until real carrier/fulfillment integrations are implemented.', 'info');
        };
        
        window.applyAllShippingOptimizations = function(evt) {
            notify('Shipping optimizations are disabled until real carrier/fulfillment integrations are implemented.', 'info');
        };

        /* ─── Carrier Discovery ─── */
        window.vmoDiscoverCarriers = function() {
            const country = document.getElementById('vmo-discover-country')?.value;
            if (!country) { notify('Please select a country first', 'info'); return; }
            const resultsWrap = document.getElementById('vmo-carrier-discovery-results');
            if (resultsWrap) resultsWrap.style.display = 'none';

            ajaxPost('vmo_discover_carriers', { country }).then(({success, data}) => {
                if (!success || !data) { notify('Could not discover carriers', 'error'); return; }
                const renderCard = (c) => {
                    const badge = c.recommended
                        ? '<span style="background:rgba(16,185,129,.18);color:#10b981;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:600">⭐ Recommended</span>'
                        : '';
                    return `<div class="vmo-card" style="padding:10px 14px;cursor:pointer" onclick="window.vmoShowOnboarding('${c.slug}')">
                        <div style="display:flex;justify-content:space-between;align-items:center">
                            <strong style="color:var(--ink);font-size:13px">${c.name}</strong>${badge}
                        </div>
                        <div style="font-size:11px;color:var(--muted);margin-top:4px">${c.coverage}</div>
                        <div style="font-size:10px;color:var(--cyan);margin-top:4px">Click for setup instructions →</div>
                    </div>`;
                };
                const recEl = document.getElementById('vmo-recommended-carriers');
                const othEl = document.getElementById('vmo-other-carriers');
                if (recEl) recEl.innerHTML = (data.recommended || []).map(renderCard).join('') || '<p style="color:var(--muted);font-size:12px">No region-specific carriers found.</p>';
                if (othEl) othEl.innerHTML = (data.other_available || []).map(renderCard).join('') || '';
                if (resultsWrap) resultsWrap.style.display = 'block';
            }).catch(() => notify('Error discovering carriers', 'error'));
        };

        window.vmoShowOnboarding = function(slug) {
            ajaxPost('vmo_get_carrier_onboarding', { carrier_slug: slug }).then(({success, data}) => {
                if (!success || !data) { notify('Could not load onboarding', 'error'); return; }
                let stepsHtml = (data.steps || []).map((s, i) => `<div style="display:flex;gap:10px;padding:8px 0;border-bottom:1px solid rgba(255,255,255,.05)">
                    <span style="width:24px;height:24px;border-radius:50%;background:rgba(15,225,255,.15);color:var(--cyan);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0">${i+1}</span>
                    <span style="font-size:13px;color:var(--ink)">${s}</span>
                </div>`).join('');
                let linksHtml = '';
                if (data.signup_url) linksHtml += `<a href="${data.signup_url}" target="_blank" rel="noopener" class="action-btn primary" style="text-decoration:none;display:inline-block;margin-top:8px">🔗 Sign Up / Get API Keys</a> `;
                if (data.docs_url) linksHtml += `<a href="${data.docs_url}" target="_blank" rel="noopener" class="action-btn" style="text-decoration:none;display:inline-block;margin-top:8px">📖 API Docs</a>`;
                const html = `<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.7);z-index:99999;display:flex;align-items:center;justify-content:center" onclick="if(event.target===this)this.remove()">
                    <div style="width:min(480px,92vw);background:linear-gradient(135deg,rgba(14,29,41,.97),rgba(18,46,63,.97));border:1px solid var(--border);border-radius:22px;padding:28px;max-height:80vh;overflow-y:auto">
                        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
                            <h3 style="color:var(--cyan-soft);font-size:16px;margin:0">${data.name} Setup</h3>
                            <button onclick="this.closest('[style*=fixed]').remove()" style="background:none;border:none;color:var(--muted);font-size:18px;cursor:pointer">✕</button>
                        </div>
                        <div style="margin-bottom:16px">${stepsHtml}</div>
                        <div>${linksHtml}</div>
                    </div>
                </div>`;
                document.body.insertAdjacentHTML('beforeend', html);
            }).catch(() => notify('Error loading carrier setup', 'error'));
        };

        /* ─── Manual Delivery ─── */
        window.vmoLoadManualDeliveries = function() {
            const list = document.getElementById('vmo-manual-delivery-list');
            const badge = document.getElementById('vmo-manual-delivery-count');
            if (!list) return;
            list.innerHTML = '<div style="padding:12px;text-align:center;color:var(--muted)">Loading…</div>';

            // Fetch orders that are not yet delivered (manual delivery candidates)
            ajaxPost('vmo_get_shipping_orders', { status: 'pending' }).then(({success, data}) => {
                const orders = (success && data && data.orders) ? data.orders : [];
                // Also fetch processing/in_transit/shipped
                return Promise.all([
                    Promise.resolve(orders),
                    ajaxPost('vmo_get_shipping_orders', { status: 'processing' }).then(r => (r.success && r.data && r.data.orders) ? r.data.orders : []).catch(() => []),
                    ajaxPost('vmo_get_shipping_orders', { status: 'shipped' }).then(r => (r.success && r.data && r.data.orders) ? r.data.orders : []).catch(() => []),
                ]);
            }).then(([pending, processing, shipped]) => {
                const all = [...pending, ...processing, ...shipped];
                if (badge) badge.textContent = all.length || '—';
                if (all.length === 0) {
                    list.innerHTML = '<div style="padding:16px;text-align:center;color:var(--muted);border:2px dashed var(--border);border-radius:8px">No orders awaiting delivery.</div>';
                    return;
                }
                const statusColors = {pending:'#9fb2c8',processing:'#ffc107',picked_up:'#ffc107',in_transit:'#0fe1ff',out_for_delivery:'#7c5cff',shipped:'#0fe1ff'};
                list.innerHTML = all.map(o => {
                    const sc = statusColors[o.status] || '#9fb2c8';
                    return `<div class="vmo-card" style="padding:10px 14px;margin-bottom:6px;display:flex;justify-content:space-between;align-items:center">
                        <div>
                            <strong style="color:var(--ink);font-size:13px">#${o.order_ref || o.id}</strong>
                            <span style="margin-left:8px;font-size:11px;color:${sc};font-weight:600">${(o.status||'pending').replace(/_/g,' ').toUpperCase()}</span>
                            <div style="font-size:11px;color:var(--muted);margin-top:2px">${o.customer_name || 'Customer'} — ${o.city || ''} ${o.country || ''}</div>
                            ${o.tracking_number ? `<div style="font-size:10px;color:var(--cyan);margin-top:2px">📦 ${o.tracking_number}</div>` : ''}
                        </div>
                        <div style="display:flex;gap:6px;flex-shrink:0">
                            <select onchange="window.vmoUpdateDeliveryStatus(${o.id},this.value)" style="padding:4px 6px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:11px">
                                <option value="">Move to…</option>
                                <option value="processing">Processing</option>
                                <option value="picked_up">Picked Up</option>
                                <option value="in_transit">In Transit</option>
                                <option value="out_for_delivery">Out for Delivery</option>
                                <option value="delivered">Delivered ✅</option>
                            </select>
                            <button class="action-btn" onclick="window.vmoMarkDelivered(${o.id})" style="font-size:10px;padding:4px 8px" title="Mark as delivered immediately">✅</button>
                        </div>
                    </div>`;
                }).join('');
            }).catch(() => {
                list.innerHTML = '<div style="padding:12px;text-align:center;color:red">Error loading deliveries.</div>';
            });
        };

        window.vmoUpdateDeliveryStatus = function(orderId, newStatus) {
            if (!newStatus) return;
            ajaxPost('vmo_update_delivery_status', { order_id: orderId, new_status: newStatus, notes: '' }).then(({success, data}) => {
                if (success) {
                    notify(data?.message || 'Status updated', 'success');
                    window.vmoLoadManualDeliveries();
                    window.vmoLoadDeliveryPipeline();
                } else {
                    notify(data?.message || 'Failed to update status', 'error');
                }
            }).catch(() => notify('Error updating status', 'error'));
        };

        window.vmoMarkDelivered = function(orderId) {
            if (!confirm('Mark this order as delivered?')) return;
            ajaxPost('vmo_mark_delivered', { order_id: orderId, delivery_notes: 'Marked delivered from dashboard' }).then(({success, data}) => {
                if (success) {
                    notify(data?.message || 'Delivered!', 'success');
                    window.vmoLoadManualDeliveries();
                    window.vmoLoadDeliveryPipeline();
                } else {
                    notify(data?.message || 'Failed', 'error');
                }
            }).catch(() => notify('Error marking delivered', 'error'));
        };

        /* ─── Delivery Pipeline ─── */
        window.vmoLoadDeliveryPipeline = function() {
            const stagesContainer = document.getElementById('vmo-delivery-pipeline-stages');
            const orderList = document.getElementById('vmo-pipeline-order-list');
            const badge = document.getElementById('vmo-pipeline-total');
            if (!stagesContainer) return;

            const stages = [
                { key: 'pending', label: 'Pending', icon: '⏳', color: '#9fb2c8' },
                { key: 'processing', label: 'Processing', icon: '🔧', color: '#ffc107' },
                { key: 'shipped', label: 'Shipped', icon: '🚚', color: '#0fe1ff' },
                { key: 'in_transit', label: 'In Transit', icon: '✈️', color: '#54d6ff' },
                { key: 'out_for_delivery', label: 'Out for Delivery', icon: '📬', color: '#7c5cff' },
                { key: 'delivered', label: 'Delivered', icon: '✅', color: '#10b981' },
            ];

            // Fetch counts for each status
            const promises = stages.map(s => ajaxPost('vmo_get_shipping_orders', { status: s.key }).then(r => (r.success && r.data && r.data.orders) ? r.data.orders : []).catch(() => []));
            Promise.all(promises).then(results => {
                let total = 0;
                stagesContainer.innerHTML = stages.map((s, i) => {
                    const count = results[i].length;
                    total += count;
                    return `<div class="vmo-card" style="padding:10px;text-align:center;cursor:pointer;border:${window.__vmoPipelineActive === s.key ? '1px solid var(--edge)' : '1px solid var(--border)'}" onclick="window.vmoShowPipelineStage('${s.key}',${i})">
                        <div style="font-size:20px">${s.icon}</div>
                        <div style="font-size:22px;font-weight:700;color:${s.color}">${count}</div>
                        <div style="font-size:10px;color:var(--muted)">${s.label}</div>
                    </div>`;
                }).join('');
                if (badge) badge.textContent = total || '—';

                // Auto-show first non-empty stage
                if (!window.__vmoPipelineActive) {
                    const firstNonEmpty = results.findIndex(r => r.length > 0);
                    if (firstNonEmpty >= 0) {
                        window.__vmoPipelineStageData = results;
                        window.vmoShowPipelineStage(stages[firstNonEmpty].key, firstNonEmpty);
                    }
                } else {
                    // Refresh current view
                    window.__vmoPipelineStageData = results;
                    const idx = stages.findIndex(s => s.key === window.__vmoPipelineActive);
                    if (idx >= 0) window.vmoShowPipelineStage(stages[idx].key, idx);
                }
            });
        };

        window.vmoShowPipelineStage = function(stageKey, stageIndex) {
            window.__vmoPipelineActive = stageKey;
            const orderList = document.getElementById('vmo-pipeline-order-list');
            if (!orderList) return;
            const orders = (window.__vmoPipelineStageData && window.__vmoPipelineStageData[stageIndex]) ? window.__vmoPipelineStageData[stageIndex] : [];

            // Highlight active stage card
            const stageCards = document.querySelectorAll('#vmo-delivery-pipeline-stages .vmo-card');
            stageCards.forEach((c, i) => { c.style.border = i === stageIndex ? '1px solid var(--edge)' : '1px solid var(--border)'; });

            if (orders.length === 0) {
                orderList.innerHTML = '<div style="padding:12px;text-align:center;color:var(--muted)">No orders in this stage.</div>';
                return;
            }
            orderList.innerHTML = orders.map(o => `<div class="vmo-card" style="padding:8px 12px;margin-bottom:6px;display:flex;justify-content:space-between;align-items:center">
                <div>
                    <strong style="font-size:13px;color:var(--ink)">#${o.order_ref || o.id}</strong>
                    <span style="font-size:11px;color:var(--muted);margin-left:8px">${o.customer_name || 'Customer'}</span>
                    <div style="font-size:11px;color:var(--muted);margin-top:2px">${o.city || ''} ${o.state || ''} ${o.country || ''} ${o.tracking_number ? '· 📦 ' + o.tracking_number : ''}</div>
                </div>
                <div style="display:flex;gap:6px">
                    <button class="action-btn" onclick="window.viewOrderDetails('${o.id}')" style="font-size:10px;padding:4px 8px" title="View order details">👁️</button>
                    ${stageKey !== 'delivered' ? `<button class="action-btn primary" onclick="window.vmoMarkDelivered(${o.id})" style="font-size:10px;padding:4px 8px" title="Mark delivered">✅</button>` : ''}
                </div>
            </div>`).join('');
        };
        
        window.openBulkShippingModal = function() {
            const modal = document.getElementById('vmo-bulk-shipping-modal');
            if (modal) {
                modal.style.display = 'flex';
                window.loadBulkShippingOrders();
            } else {
                notify('Opening bulk shipping processor...', 'info');
            }
        };

        window.loadBulkShippingOrders = function() {
            const list = document.getElementById('vmo-bulk-shipping-list');
            const status = document.getElementById('vmo-bulk-shipping-status');
            const empty = document.getElementById('vmo-bulk-shipping-empty');
            const totalEl = document.getElementById('vmo-bulk-shipping-total');
            const actionBtn = document.getElementById('vmo-bulk-shipping-action');

            if (!list) return;

            list.innerHTML = '';
            if (status) {
                status.style.display = 'block';
                status.innerHTML = 'Checking for pending orders...';
            }
            if (empty) empty.style.display = 'none';
            if (actionBtn) {
                actionBtn.disabled = true;
                actionBtn.onclick = window.processBulkShippingOrders;
            }
            
            // Fetch real orders (or empty list if none)
            ajaxPost('vmo_get_pending_shipping_orders', {}).then(({success, data}) => {
                const orders = (data && data.orders) ? data.orders : [];
                
                if (orders.length === 0) {
                    if (status) status.style.display = 'none';
                    if (empty) empty.style.display = 'block';
                    if (totalEl) totalEl.textContent = 'Total: $0.00';
                    if (actionBtn) actionBtn.disabled = true;
                } else {
                    if (status) {
                        status.style.display = 'block';
                        status.innerHTML = `Ready to process <strong>${orders.length}</strong> pending orders.`;
                    }
                    
                    let totalCost = 0;
                    orders.forEach(order => {
                        const rateNum = parseFloat(order.rate || '0');
                        totalCost += isFinite(rateNum) ? rateNum : 0;
                        list.innerHTML += `
                            <tr data-order-id="${order.id}">
                                <td>#${order.id}</td>
                                <td>${order.customer}</td>
                                <td>${order.destination}</td>
                                <td><span class="vmo-badge vmo-badge-blue">${order.carrier}</span></td>
                                <td>$${order.rate}</td>
                                <td><button class="vmo-btn vmo-btn-sm" onclick="window.editShippingOrder(${order.id})" title="Open this order to review shipping details before processing.">Edit</button></td>
                            </tr>
                        `;
                    });
                    
                    if (totalEl) totalEl.textContent = `Total: $${totalCost.toFixed(2)}`;
                    if (actionBtn) actionBtn.disabled = false;
                    
                    // Update chart
                    if (data.cost_breakdown) {
                        window.updateShippingCostsChart(data.cost_breakdown);
                    }
                }
            }).catch(() => {
                if (status) status.style.display = 'none';
                if (empty) {
                    empty.style.display = 'block';
                    empty.innerHTML = '<p style="color:red">Error loading orders. Please try again.</p>';
                }
            });
        };

        window.processBulkShippingOrders = function(evt) {
            const actionBtn = document.getElementById('vmo-bulk-shipping-action');
            const status = document.getElementById('vmo-bulk-shipping-status');
            const rows = Array.from(document.querySelectorAll('#vmo-bulk-shipping-list tr[data-order-id]'));
            const orderIds = rows.map(r => parseInt(r.getAttribute('data-order-id'), 10)).filter(v => Number.isFinite(v) && v > 0);

            if (!orderIds.length) {
                notify('No pending orders to process', 'info');
                return;
            }

            if (actionBtn) {
                actionBtn.disabled = true;
                actionBtn.textContent = '⏳ Processing...';
            }
            if (status) {
                status.style.display = 'block';
                status.innerHTML = `Processing <strong>${orderIds.length}</strong> orders...`;
            }

            ajaxPost('vmo_bulk_approve_shipments', { order_ids: JSON.stringify(orderIds) })
                .then(({success, data, message}) => {
                    if (!success) {
                        notify(message || 'Bulk processing failed', 'error');
                        return;
                    }

                    const processed = (data && typeof data.processed !== 'undefined') ? data.processed : 0;
                    const errors = (data && Array.isArray(data.errors)) ? data.errors : [];
                    if (errors.length) {
                        notify(`Processed ${processed}. ${errors.length} failed.`, 'error');
                        if (status) {
                            status.innerHTML = `Processed <strong>${processed}</strong>. Failed: <strong>${errors.length}</strong>.`;
                        }
                    } else {
                        notify(`Processed ${processed} orders successfully`, 'success');
                        if (status) {
                            status.innerHTML = `Processed <strong>${processed}</strong> orders successfully.`;
                        }
                    }

                    try { window.loadActiveOrdersPanel(); } catch(e) {}
                    try { window.loadBulkShippingOrders(); } catch(e) {}
                })
                .catch(() => {
                    notify('Error processing bulk shipments', 'error');
                })
                .finally(() => {
                    if (actionBtn) {
                        actionBtn.disabled = false;
                        actionBtn.textContent = 'Purchase & Print Labels';
                    }
                });
        };
        
        window.updateShippingCostsChart = function(breakdown) {
            const chartContainer = document.getElementById('vmo-shipping-costs-chart');
            if (!chartContainer || !breakdown) return;
            
            // Simple bar chart representation
            let chartHtml = '<div style="display: flex; align-items: end; height: 100%; gap: 4px; padding: 8px;">';
            
            Object.keys(breakdown).forEach((service, index) => {
                const percentage = Math.max(5, (breakdown[service] / Math.max(...Object.values(breakdown))) * 80);
                chartHtml += `
                    <div style="flex: 1; display: flex; flex-direction: column; align-items: center;">
                            <div style="height: ${percentage}%; min-height: 8px; background: ${['var(--cyan)', '#54d6ff', '#ffc107', '#7c5cff'][index % 4]}; width: 100%; margin-bottom: 4px;"></div>
                        <small style="font-size: 8px; color: var(--muted);">${service}</small>
                        <small style="font-size: 7px; color: var(--muted);">$${breakdown[service]}</small>
                    </div>
                `;
            });
            
            chartHtml += '</div>';
            chartContainer.innerHTML = chartHtml;
        };

        window.editShippingOrder = function(orderId) {
            window.viewOrderDetails(orderId);
        };

        // Global Shipping Configuration Functions
        window.loadGlobalShippingPanel = function(region) {
            if (typeof region === 'undefined') region = 'all';
            try {
                var nonce = '<?php echo wp_create_nonce("vmo_nonce"); ?>';
                var ajaxUrl = '<?php echo admin_url("admin-ajax.php"); ?>';
                
                var data = {
                    'action': 'vmo_load_global_shipping',
                    'nonce': nonce,
                    'region': region
                };

                fetch(ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams(data)
                })
                .then(function(response) { return response.json(); })
                .then(function(result) {
                    if (result.success && result.data) {
                        var s = result.data;
                        // Update region display if applicable
                        if (region !== 'all' && s.carriers) {
                            window.updateRegionCarrierDisplay(region, s.carriers);
                        }
                        
                        // Populate Carriers
                        if (s.carriers) {
                            Object.keys(s.carriers).forEach(function(id) {
                                var el = document.getElementById(id);
                                if (el) el.checked = s.carriers[id];
                            });
                        }
                        // Populate Trade Settings
                        if (s.trade_settings) {
                            Object.keys(s.trade_settings).forEach(function(id) {
                                var el = document.getElementById(id);
                                if (el) el.checked = s.trade_settings[id];
                            });
                        }
                    }
                })
                .catch(function(err) { console.error(err); });
            } catch(e) {
                console.error('Global shipping panel load failed:', e);
            }
        };

        window.saveGlobalShippingSettings = function(settings) {
            try {
                // If settings not provided (called from button), collect from DOM
                if (!settings) {
                    settings = {
                        carriers: {
                            'asia-sf-express': document.getElementById('asia-sf-express') ? document.getElementById('asia-sf-express').checked : false,
                            'asia-japan-post': document.getElementById('asia-japan-post') ? document.getElementById('asia-japan-post').checked : false,
                            'asia-australia-post': document.getElementById('asia-australia-post') ? document.getElementById('asia-australia-post').checked : false,
                            'africa-aramex': document.getElementById('africa-aramex') ? document.getElementById('africa-aramex').checked : false,
                            'africa-fastway': document.getElementById('africa-fastway') ? document.getElementById('africa-fastway').checked : false,
                            'africa-posta': document.getElementById('africa-posta') ? document.getElementById('africa-posta').checked : false,
                            'sa-correios': document.getElementById('sa-correios') ? document.getElementById('sa-correios').checked : false,
                            'sa-mercado': document.getElementById('sa-mercado') ? document.getElementById('sa-mercado').checked : false,
                            'sa-chilexpress': document.getElementById('sa-chilexpress') ? document.getElementById('sa-chilexpress').checked : false
                        },
                        trade_settings: {
                            'auto-customs': document.getElementById('auto-customs') ? document.getElementById('auto-customs').checked : false,
                            'duty-calc': document.getElementById('duty-calc') ? document.getElementById('duty-calc').checked : false,
                            'restricted-items': document.getElementById('restricted-items') ? document.getElementById('restricted-items').checked : false,
                            'currency-hedge': document.getElementById('currency-hedge') ? document.getElementById('currency-hedge').checked : false
                        }
                    };
                }

                var nonce = '<?php echo wp_create_nonce("vmo_nonce"); ?>';
                var ajaxUrl = '<?php echo admin_url("admin-ajax.php"); ?>';
                
                var data = {
                    'action': 'vmo_save_global_shipping',
                    'nonce': nonce,
                    'settings': JSON.stringify(settings)
                };

                fetch(ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams(data)
                })
                .then(function(response) { return response.json(); })
                .then(function(result) {
                    if (result.success) {
                        showNotification('Global shipping settings saved successfully', 'success');
                        // Refresh carrier availability indicators
                        try { window.updateCarrierStatusIndicators(); } catch(e) {}
                    } else {
                        showNotification('Failed to save global shipping settings', 'error');
                    }
                })
                .catch(function(err) { console.error(err); });
            } catch(e) {
                console.error('Global shipping settings save failed:', e);
            }
        };

        window.testGlobalConnectivity = function() {
            try {
                const carriers = ['fedex_global', 'ups_worldwide', 'dhl_express', 'aramex', 'sf_express'];
                const testResults = document.getElementById('global-connectivity-results') || window.createTestResultsContainer();

                testResults.innerHTML = '<div class="testing-indicator">Checking global carrier configuration...</div>';

                const data = {
                    'action': 'vmo_test_global_carriers',
                    'nonce': '<?php echo wp_create_nonce("vmo_nonce"); ?>',
                    'carriers': JSON.stringify(carriers)
                };

                fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams(data)
                })
                .then(response => response.json())
                .then(result => {
                    window.displayConnectivityResults(testResults, result.data);
                })
                .catch(console.error);
            } catch(e) {
                console.error('Global connectivity test failed:', e);
            }
        };

        window.updateRegionCarrierDisplay = function(region, carriers) {
            const regionConfig = document.querySelector(`[data-region="${region}"]`);
            if (!regionConfig) return;

            const carrierList = regionConfig.querySelector('.region-carrier-list');
            if (!carrierList) return;

            const carrierArr = Array.isArray(carriers) ? carriers : [];

            let html = '';
            carrierArr.forEach(carrier => {
                const statusClass = carrier.active ? 'carrier-active' : 'carrier-inactive';
                const coveragePercent = carrier.coverage || 0;
                
                html += `
                    <div class="region-carrier-item ${statusClass}">
                        <div class="carrier-info">
                            <span class="carrier-name">${carrier.name}</span>
                            <span class="carrier-coverage">${coveragePercent}% coverage</span>
                        </div>
                        <div class="carrier-controls">
                            <label class="carrier-toggle">
                                <input type="checkbox" ${carrier.active ? 'checked' : ''} title="Enable/disable this carrier for the selected region." 
                                       onchange="window.toggleCarrier('${carrier.id}', this.checked)">
                                <span class="toggle-slider"></span>
                            </label>
                        </div>
                    </div>
                `;
            });
            
            carrierList.innerHTML = html;
        };

        // displayConnectivityResults — see full implementation below (L10316+)
        // Removed first definition to prevent duplicate overwrite conflict.

        window.updateCarrierStatusIndicators = function() {
            document.querySelectorAll('.carrier-status').forEach(indicator => {
                const carrierId = indicator.dataset.carrier;
                // Update status based on API connectivity
                window.testCarrierConnection(carrierId).then(status => {
                    const ok = status && typeof status === 'object' ? !!status.connected : !!status;
                    indicator.className = `carrier-status ${ok ? 'status-online' : 'status-offline'}`;
                    indicator.title = ok ? 'Carrier API connected' : 'Carrier API offline';
                });
            });
        };

        window.testCarrierConnection = async function(carrierId) {
            try {
                var ajaxUrl = '<?php echo admin_url("admin-ajax.php"); ?>';
                var nonce = '<?php echo wp_create_nonce("vmo_nonce"); ?>';
                
                const response = await fetch(ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        'action': 'vmo_test_carrier_connection',
                        'nonce': nonce,
                        'carrier_id': carrierId
                    })
                });
                const result = await response.json();
                if (result && result.success && result.data) {
                    return {
                        connected: !!result.data.connected,
                        message: result.data.message || '',
                        latency: result.data.latency || 0
                    };
                }
                return { connected: false, message: (result && result.data && result.data.message) ? result.data.message : 'Connection failed', latency: 0 };
            } catch(e) {
                return { connected: false, message: 'Connection failed', latency: 0 };
            }
        };

        window.createTestResultsContainer = function() {
            const container = document.createElement('div');
            container.id = 'global-connectivity-results';
            container.className = 'connectivity-results';
            
            const testSection = document.querySelector('.global-shipping-test');
            if (testSection) {
                testSection.appendChild(container);
            } else {
                const fallback = document.querySelector('.global-shipping-config') || document.querySelector('#global-shipping-panel') || document.body;
                if (fallback) fallback.appendChild(container);
            }
            
            return container;
        };

        window.displayConnectivityResults = function(container, results) {
            let html = '<div class="test-results-header">Global Carrier Connectivity Results</div>';
            
            Object.keys(results).forEach(carrier => {
                const result = results[carrier] || {};
                const state = String(result.status || '').toLowerCase();
                const isConfigured = state === 'configured';
                const isConnected = state === 'connected' || (!!result.connected && !isConfigured);
                const statusClass = (isConnected || isConfigured) ? 'test-success' : 'test-failed';
                const statusText = isConnected ? 'Connected' : (isConfigured ? 'Configured' : (state === 'inactive' ? 'Inactive' : 'Failed'));
                const latency = (typeof result.latency !== 'undefined' && result.latency !== null && result.latency !== '')
                    ? result.latency
                    : '—';
                const msg = result.message ? String(result.message) : '';
                
                html += `
                    <div class="test-result-item ${statusClass}">
                        <span class="carrier-name">${carrier}</span>
                        <span class="test-status">${statusText}${msg ? ' - ' + msg : ''}</span>
                        <span class="test-latency">${latency}</span>
                    </div>
                `;
            });
            
            container.innerHTML = html;
        };

        window.toggleCarrier = function(carrierId, enabled) {
            const settings = {
                carrier_id: carrierId,
                enabled: enabled
            };
            
            window.saveGlobalShippingSettings(settings);
        };

        // Initialize global shipping panel on page load
        document.addEventListener('DOMContentLoaded', function() {
            // Load global shipping configuration
            if (document.querySelector('.global-shipping-config')) {
                window.loadGlobalShippingPanel();
            }

            // Set up region switching
            document.querySelectorAll('.region-tab').forEach(tab => {
                tab.addEventListener('click', function() {
                    const region = this.dataset.region;
                    document.querySelectorAll('.region-tab').forEach(t => t.classList.remove('active'));
                    this.classList.add('active');
                    
                    document.querySelectorAll('.region-config').forEach(config => {
                        config.style.display = config.dataset.region === region ? 'block' : 'none';
                    });
                    
                    window.loadGlobalShippingPanel(region);
                });
            });

            // Auto-refresh carrier status every 5 minutes
            setInterval(window.updateCarrierStatusIndicators, 300000);

            // Load custom carriers on page load
            window.loadCustomCarriers();
        });

        // Custom Carrier Management Functions
        window.openAddCustomCarrierModal = function() {
            const modal = document.createElement('div');
            modal.className = 'custom-carrier-modal';
            modal.innerHTML = `
                <div class="custom-carrier-modal-content">
                    <h4 style="margin-top: 0; color: var(--cyan-soft);">Add Custom Shipping Carrier</h4>
                    
                    <div class="modal-section">
                        <label>Carrier Name *</label>
                        <input type="text" id="custom-carrier-name" placeholder="e.g., Local Express Delivery" required>
                    </div>
                    
                    <div class="modal-section">
                        <label>Company Website</label>
                        <input type="url" id="custom-carrier-website" placeholder="https://localexpress.com">
                    </div>
                    
                    <div class="modal-section">
                        <label>Service Type</label>
                        <select id="custom-carrier-type">
                            <option value="local">Local/Regional Delivery</option>
                            <option value="national">National Carrier</option>
                            <option value="international">International Shipping</option>
                            <option value="specialty">Specialty Service</option>
                            <option value="freight">Freight/Heavy Items</option>
                        </select>
                    </div>
                    
                    <div class="modal-section">
                        <label>Coverage Area</label>
                        <input type="text" id="custom-carrier-coverage" placeholder="e.g., California, USA or Sydney Metro Area">
                    </div>
                    
                    <div class="modal-section">
                        <label>Contact Information</label>
                        <textarea id="custom-carrier-contact" rows="3" placeholder="Phone, Email, Contact Person, etc."></textarea>
                    </div>
                    
                    <div class="modal-section">
                        <label>API Integration (Optional)</label>
                        <select id="custom-carrier-api-type">
                            <option value="none">No API Integration</option>
                            <option value="rest">REST API</option>
                            <option value="soap">SOAP API</option>
                            <option value="webhook">Webhook</option>
                            <option value="csv">CSV File Import</option>
                        </select>
                    </div>
                    
                    <div class="modal-section" id="api-details" style="display:none;">
                        <label>API Endpoint/Details</label>
                        <input type="text" id="custom-carrier-api-endpoint" placeholder="API URL or configuration details">
                        <label style="margin-top: 8px;">API Key/Credentials</label>
                        <input type="password" id="custom-carrier-api-key" placeholder="API Key or access credentials">
                        <button class="action-btn" onclick="window.testCustomCarrierAPI()" style="margin-top: 8px;">🧪 Test Connection</button>
                        <div id="api-test-result"></div>
                    </div>
                    
                    <div class="modal-section">
                        <label>Estimated Delivery Time</label>
                        <input type="text" id="custom-carrier-delivery-time" placeholder="e.g., 1-2 business days">
                    </div>
                    
                    <div class="modal-section">
                        <label>Base Shipping Rate ($)</label>
                        <input type="number" id="custom-carrier-base-rate" placeholder="0.00" step="0.01" min="0">
                    </div>
                    
                    <div class="modal-buttons">
                        <button class="action-btn" onclick="window.closeCustomCarrierModal()">Cancel</button>
                        <button class="action-btn" onclick="window.saveCustomCarrier()" style="background: var(--cyan); color: var(--bg);">Save Carrier</button>
                    </div>
                </div>
            `;
            
            document.body.appendChild(modal);
            
            // Show/hide API details based on selection
            document.getElementById('custom-carrier-api-type').addEventListener('change', function() {
                const apiDetails = document.getElementById('api-details');
                apiDetails.style.display = this.value !== 'none' ? 'block' : 'none';
            });
            
            // Close modal on backdrop click
            modal.addEventListener('click', function(e) {
                if (e.target === modal) {
                    window.closeCustomCarrierModal();
                }
            });
        };

        window.closeCustomCarrierModal = function() {
            const modal = document.querySelector('.custom-carrier-modal');
            if (modal) {
                modal.remove();
            }
        };

        window.saveCustomCarrier = function() {
            const carrier = {
                name: document.getElementById('custom-carrier-name').value,
                website: document.getElementById('custom-carrier-website').value,
                type: document.getElementById('custom-carrier-type').value,
                coverage: document.getElementById('custom-carrier-coverage').value,
                contact: document.getElementById('custom-carrier-contact').value,
                api_type: document.getElementById('custom-carrier-api-type').value,
                api_endpoint: document.getElementById('custom-carrier-api-endpoint').value,
                api_key: document.getElementById('custom-carrier-api-key').value,
                delivery_time: document.getElementById('custom-carrier-delivery-time').value,
                base_rate: document.getElementById('custom-carrier-base-rate').value
            };
            
            if (!carrier.name.trim()) {
                alert('Please enter a carrier name');
                return;
            }
            
            const data = {
                'action': 'vmo_save_custom_carrier',
                'nonce': '<?php echo wp_create_nonce("vmo_nonce"); ?>',
                'carrier': JSON.stringify(carrier)
            };

            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams(data)
            })
            .then(response => response.json())
            .then(result => {
                if (result.success) {
                    showNotification('Custom carrier added successfully', 'success');
                    window.closeCustomCarrierModal();
                    window.loadCustomCarriers(); // Refresh the list
                } else {
                    showNotification('Failed to add custom carrier: ' + (result.message || 'Unknown error'), 'error');
                }
            })
            .catch(error => {
                console.error('Error saving custom carrier:', error);
                showNotification('Error saving custom carrier', 'error');
            });
        };

        window.loadCustomCarriers = function() {
            const data = {
                'action': 'vmo_get_custom_carriers',
                'nonce': '<?php echo wp_create_nonce("vmo_nonce"); ?>'
            };

            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams(data)
            })
            .then(response => response.json())
            .then(result => {
                if (result.success) {
                    window.displayCustomCarriers(result.data);
                }
            })
            .catch(console.error);
        };

        window.displayCustomCarriers = function(carriers) {
            const container = document.getElementById('vmo-custom-carriers-list');
            if (!container) return;
            
            if (!carriers || carriers.length === 0) {
                container.innerHTML = `
                    <div class="custom-carrier-placeholder">
                        No custom carriers configured.<br>
                        <small>Click "Add Custom Carrier" to integrate local shipping options.</small>
                    </div>
                `;
                return;
            }
            
            let html = '';
            carriers.forEach(carrier => {
                const typeLabels = {
                    'local': 'Local/Regional',
                    'national': 'National',
                    'international': 'International',
                    'specialty': 'Specialty',
                    'freight': 'Freight'
                };
                
                html += `
                    <div class="custom-carrier-item" data-carrier-id="${carrier.id}">
                        <div class="custom-carrier-info">
                            <div class="custom-carrier-name">${carrier.name}</div>
                            <div class="custom-carrier-details">
                                ${carrier.coverage || 'Coverage not specified'} • 
                                ${carrier.delivery_time || 'Standard delivery'}
                                ${carrier.base_rate ? ' • $' + carrier.base_rate + ' base rate' : ''}
                            </div>
                            <div class="custom-carrier-type">${typeLabels[carrier.type] || carrier.type}</div>
                        </div>
                        <div class="custom-carrier-controls">
                            <div class="custom-carrier-status ${carrier.api_type !== 'none' ? 'online' : ''}" 
                                 title="${carrier.api_type !== 'none' ? 'API Connected' : 'Manual Integration'}"></div>
                            <label class="carrier-toggle">
                                <input type="checkbox" ${carrier.enabled ? 'checked' : ''} 
                                       onchange="window.toggleCustomCarrier('${carrier.id}', this.checked)">
                                <span class="toggle-slider"></span>
                            </label>
                            <button class="action-btn" onclick="window.editCustomCarrier('${carrier.id}')" style="padding: 2px 6px;">⚙️</button>
                                <button class="action-btn danger compact" onclick="window.deleteCustomCarrier('${carrier.id}')">🗑️</button>
                        </div>
                    </div>
                `;
            });
            
            container.innerHTML = html;
        };

        window.testCustomCarrierAPI = function() {
            const apiType = document.getElementById('custom-carrier-api-type').value;
            const endpoint = document.getElementById('custom-carrier-api-endpoint').value;
            const apiKey = document.getElementById('custom-carrier-api-key').value;
            const resultDiv = document.getElementById('api-test-result');
            
            if (apiType === 'none' || !endpoint.trim()) {
                resultDiv.innerHTML = '<div class="api-test-result error">Please configure API details first</div>';
                return;
            }
            
            resultDiv.innerHTML = '<div class="api-test-result">Testing connection...</div>';
            
            const data = {
                'action': 'vmo_test_custom_carrier_api',
                'nonce': '<?php echo wp_create_nonce("vmo_nonce"); ?>',
                'api_type': apiType,
                'endpoint': endpoint,
                'api_key': apiKey
            };

            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams(data)
            })
            .then(response => response.json())
            .then(result => {
                if (result.success) {
                    resultDiv.innerHTML = '<div class="api-test-result success">✅ Connection successful!</div>';
                } else {
                    resultDiv.innerHTML = `<div class="api-test-result error">❌ Connection failed: ${result.message}</div>`;
                }
            })
            .catch(error => {
                resultDiv.innerHTML = '<div class="api-test-result error">❌ Network error occurred</div>';
            });
        };

        window.toggleCustomCarrier = function(carrierId, enabled) {
            const data = {
                'action': 'vmo_toggle_custom_carrier',
                'nonce': '<?php echo wp_create_nonce("vmo_nonce"); ?>',
                'carrier_id': carrierId,
                'enabled': enabled
            };

            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams(data)
            })
            .then(response => response.json())
            .then(result => {
                if (result.success) {
                    showNotification(enabled ? 'Custom carrier enabled' : 'Custom carrier disabled', 'success');
                } else {
                    showNotification('Failed to update carrier status', 'error');
                }
            })
            .catch(console.error);
        };

        window.deleteCustomCarrier = function(carrierId) {
            if (!confirm('Are you sure you want to delete this custom carrier?')) {
                return;
            }
            
            const data = {
                'action': 'vmo_delete_custom_carrier',
                'nonce': '<?php echo wp_create_nonce("vmo_nonce"); ?>',
                'carrier_id': carrierId
            };

            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams(data)
            })
            .then(response => response.json())
            .then(result => {
                if (result.success) {
                    showNotification('Custom carrier deleted successfully', 'success');
                    window.loadCustomCarriers(); // Refresh the list
                } else {
                    showNotification('Failed to delete carrier', 'error');
                }
            })
            .catch(console.error);
        };
        window.editCustomCarrier = function(carrierId) {
            // Placeholder for edit functionality
            showNotification('Edit functionality coming soon', 'info');
        };

        window.importCarrierFromAPI = function() {
            alert('API Import Feature: This will allow you to automatically discover and configure carriers from shipping aggregator APIs like EasyPost, ShipEngine, or direct carrier APIs. Coming in next update!');
        };

        window.showNotification = function(message, type) {
            // Simple notification system
            const notification = document.createElement('div');
            notification.style.cssText = `
                position: fixed; top: 20px; right: 20px; z-index: 10001;
                padding: 12px 16px; border-radius: 6px; color: var(--ink);
                background: ${type === 'success' 
                    ? 'linear-gradient(135deg, rgba(15,225,255,0.9), rgba(124,92,255,0.45))'
                    : 'linear-gradient(135deg, rgba(124,92,255,0.9), rgba(40,8,92,0.68))'};
                border: 1px solid ${type === 'success' ? 'rgba(15,225,255,0.5)' : 'rgba(124,92,255,0.5)'};
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                transition: opacity 0.3s;
            `;
            notification.textContent = message;
            document.body.appendChild(notification);
            
            setTimeout(() => {
                notification.style.opacity = '0';
                setTimeout(() => notification.remove(), 300);
            }, 3000);
        };
    </script>
    <!-- Include Tools Modals -->
    <?php include_once plugin_dir_path(__FILE__) . 'tools-modals.php'; ?>
</body>
</html>

    <!-- AI Recommendation Approval Modal - Fix #6 -->
    <div id="vmoRecommendationApprovalModal" class="vmo-fs-modal" aria-hidden="true" role="dialog" aria-modal="true" style="display:none;">
        <div class="vmo-modal-overlay" data-close="vmoRecommendationApprovalModal"></div>
        <div class="modal-content vmo-modal-panel">
            <div class="modal-header">
                <h3 class="modal-title">🧠 AI Recommendation Approval</h3>
                <button class="modal-close" data-close="vmoRecommendationApprovalModal" type="button">&times;</button>
            </div>
            <div class="modal-body">
                <div style="color: var(--cyan-soft); font-size: 13px; margin-bottom: 16px;">
                    Review and approve the AI-generated recommendations below before they are applied to your business.
                </div>
                <div id="vmo-recommendation-preview" style="background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 16px; margin-bottom: 16px;">
                    <h4 style="color: var(--cyan-soft); margin-top: 0;">Recommendation Preview</h4>
                    <div id="vmo-recommendation-details" style="white-space: pre-wrap; line-height: 1.6; color: var(--ink);"></div>
                </div>
                <div id="vmo-recommendation-actions" style="margin-bottom: 16px;">
                    <h4 style="color: var(--cyan-soft);">Actions to be Created</h4>
                    <div id="vmo-recommendation-action-list" class="task-list"></div>
                </div>
                <div id="vmo-recommendation-impact" style="background: rgba(15,225,255,.08); border: 1px solid var(--edge); border-radius: 10px; padding: 12px; margin-bottom: 16px;">
                    <h4 style="color: var(--cyan-soft); margin-top: 0;">Expected Impact</h4>
                    <div id="vmo-recommendation-impact-details" style="font-size: 12px; line-height: 1.5; color: var(--ink);"></div>
                </div>
                <div style="display: flex; gap: 10px; margin-top: 20px;">
                    <button class="action-btn primary" style="flex: 1;" onclick="approveRecommendation()">
                        ✅ Approve & Apply
                    </button>
                    <button class="action-btn" style="flex: 1;" onclick="editRecommendation()">
                        ✏️ Edit First
                    </button>
                    <button class="action-btn" style="flex: 1;" onclick="rejectRecommendation()">
                        ❌ Reject
                    </button>
                </div>
            </div>
        </div>
    </div>

    <script>
        console.log('[VMO] Script Block 4 Loaded');
        // AI Recommendation Approval System - Fix #6
        window.vmoRecommendationApproval = {
            currentRecommendation: null,
            
            show: function(recommendation) {
                this.currentRecommendation = recommendation;
                const modal = document.getElementById('vmoRecommendationApprovalModal');
                const detailsEl = document.getElementById('vmo-recommendation-details');
                const actionsEl = document.getElementById('vmo-recommendation-action-list');
                const impactEl = document.getElementById('vmo-recommendation-impact-details');
                
                // Display recommendation details
                if (detailsEl && recommendation.description) {
                    detailsEl.textContent = recommendation.description;
                }
                
                // Display actions
                if (actionsEl && recommendation.actions && recommendation.actions.length > 0) {
                    actionsEl.innerHTML = recommendation.actions.map((action, idx) => `
                        <div class="task-item" style="margin-bottom: 8px; padding: 8px; background: var(--panel); border: 1px solid var(--border); border-radius: 8px;">
                            <div style="display: flex; align-items: center; gap: 8px;">
                                <input type="checkbox" id="action-${idx}" checked style="width: 16px; height: 16px;">
                                <label for="action-${idx}" style="flex: 1; color: var(--ink);">${action.title || action}</label>
                            </div>
                        </div>
                    `).join('');
                } else {
                    actionsEl.innerHTML = '<p style="color: var(--muted);">No specific actions will be created.</p>';
                }
                
                // Display expected impact
                if (impactEl && recommendation.impact) {
                    impactEl.innerHTML = `
                        <p><strong>Expected Benefits:</strong> ${recommendation.impact.benefits || 'Improved business performance'}</p>
                        <p><strong>Timeline:</strong> ${recommendation.impact.timeline || '1-2 weeks'}</p>
                        <p><strong>Effort Required:</strong> ${recommendation.impact.effort || 'Minimal (AI automated)'}</p>
                    `;
                } else {
                    impactEl.innerHTML = '<p>This recommendation will be automatically applied by AI agents.</p>';
                }
                
                // Show modal
                if (modal) {
                    modal.style.display = 'flex';
                    modal.classList.add('vmo-modal-visible');
                    modal.setAttribute('aria-hidden', 'false');
                }
            },
            
            hide: function() {
                const modal = document.getElementById('vmoRecommendationApprovalModal');
                if (modal) {
                    modal.classList.remove('vmo-modal-visible');
                    setTimeout(() => {
                        modal.style.display = 'none';
                        modal.setAttribute('aria-hidden', 'true');
                    }, 150);
                }
                this.currentRecommendation = null;
            }
        };
        
        window.approveRecommendation = function() {
            const rec = window.vmoRecommendationApproval.currentRecommendation;
            if (!rec) return;

            // Get checked actions
            const actions = [];
            const checkboxes = document.querySelectorAll('#vmo-recommendation-action-list input[type="checkbox"]:checked');
            checkboxes.forEach(function(cb) {
                const label = document.querySelector('label[for="' + cb.id + '"]');
                if (label) actions.push(label.textContent);
            });

            // Send approval to backend
            fetch(VMO_AJAX, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    action: 'vmo_approve_recommendation',
                    nonce: VMO_NONCE,
                    recommendation_id: rec.id || ('temp_' + Date.now()),
                    recommendation_type: rec.type || 'general',
                    actions: JSON.stringify(actions),
                    data: JSON.stringify(rec)
                })
            })
            .then(function(res) { return res.json(); })
            .then(function(result) {
                if (result && result.success) {
                    showToast('✅ Recommendation approved and applied', 'success');
                    window.vmoRecommendationApproval.hide();
                    // Refresh relevant sections
                    if (typeof loadDashboardKPIs === 'function') loadDashboardKPIs();
                } else {
                    const msg = (result && result.data && result.data.message) ? result.data.message : 'Unknown error';
                    showToast('❌ Failed to apply recommendation: ' + msg, 'error');
                }
            })
            .catch(function(err) {
                console.error('Approval error:', err);
                showToast('❌ Network error during approval', 'error');
            });
        };
        
        window.editRecommendation = function() {
            const rec = window.vmoRecommendationApproval.currentRecommendation;
            if (!rec) return;
            
            // For now, just show a toast. In full implementation, open an edit form
            showToast('📝 Edit mode not yet implemented. You can modify actions by unchecking them.', 'info');
        };
        
        window.rejectRecommendation = function() {
            const rec = window.vmoRecommendationApproval.currentRecommendation;
            if (!rec) {
                window.vmoRecommendationApproval.hide();
                return;
            }
            
            // Send rejection to backend (for learning purposes)
            fetch(VMO_AJAX, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    action: 'vmo_reject_recommendation',
                    nonce: VMO_NONCE,
                    recommendation_id: rec.id || 'temp_' + Date.now(),
                    recommendation_type: rec.type || 'general',
                    reason: 'user_rejected'
                })
            })
            .then(() => {
                showToast('Recommendation rejected', 'info');
                window.vmoRecommendationApproval.hide();
            })
            .catch(err => console.warn('Rejection tracking failed:', err));
        };
        
        // Example: Hook into existing recommendation generation
        // This will show approval modal before applying any AI recommendation
        window.addEventListener('DOMContentLoaded', function() {
            // Intercept document recommendation approvals
            const originalApprove = window.approveAllActions;
            if (typeof originalApprove === 'function') {
                window.approveAllActions = function() {
                    // Show approval modal first
                    window.vmoRecommendationApproval.show({
                        id: 'weekly_actions_' + Date.now(),
                        type: 'weekly_strategy',
                        description: 'Approve all weekly strategy actions recommended by AI market intelligence.',
                        actions: Array.from(document.querySelectorAll('#vmo-weekly-actions .task-item')).map(el => ({
                            title: el.textContent.trim()
                        })),
                        impact: {
                            benefits: 'Improved market positioning and competitive advantage',
                            timeline: '1-2 weeks',
                            effort: 'Minimal (AI automated)'
                        }
                    });
                };
            }
        });
    </script>

    <script>
    // SAFETY NET: Ensure critical shipping functions are globally available
    (function() {
        console.log('[VMO] Initializing Safety Net Functions...');

        // Helper for notifications
        const safeNotify = function(msg, type) {
            if (typeof window.notify === 'function') window.notify(msg, type);
            else if (typeof window.showNotification === 'function') window.showNotification(msg, type);
            else if (typeof window.showToast === 'function') window.showToast(msg, type);
            else console.log('[VMO Notification]', type, msg);
        };

        // Helper for AJAX
        const safeAjax = function(action, data) {
            const formData = new URLSearchParams();
            formData.append('action', action);
            formData.append('nonce', (typeof VMO_NONCE !== 'undefined' ? VMO_NONCE : ''));
            for (const key in data) {
                if (typeof data[key] === 'object') formData.append(key, JSON.stringify(data[key]));
                else formData.append(key, data[key]);
            }
            const ajaxUrl = (typeof VMO_AJAX !== 'undefined' ? VMO_AJAX : (window.ajaxurl || '/wp-admin/admin-ajax.php'));
            return fetch(ajaxUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: formData
            }).then(r => r.json());
        };

        window.configureCarrier = window.configureCarrier || function(carrierId) {
            const modal = document.getElementById('vmo-carrier-config-modal');
            if (modal) {
                modal.style.display = 'flex';
                const nameInput = document.getElementById('vmo-carrier-name');
                if (nameInput) nameInput.value = carrierId.toUpperCase();
            } else {
                safeNotify('Opening ' + carrierId.toUpperCase() + ' configuration...', 'info');
            }
        };

        window.configureFulfillment = window.configureFulfillment || function(fulfillmentId) {
            const modal = document.getElementById('vmo-fulfillment-config-modal');
            if (modal) {
                modal.style.display = 'flex';
                const providerInput = document.getElementById('vmo-fulfillment-provider');
                if (providerInput) providerInput.value = fulfillmentId;
            } else {
                safeNotify('Opening ' + fulfillmentId + ' fulfillment configuration...', 'info');
            }
        };

        window.saveShippingSettings = window.saveShippingSettings || function() {
            safeNotify('Saving shipping settings...', 'info');
            // Mock implementation if original missing
            setTimeout(() => safeNotify('Shipping settings saved (Safety Net)', 'success'), 1000);
        };

        window.testShippingIntegration = window.testShippingIntegration || function() {
            safeNotify('Testing shipping integrations...', 'info');
            safeAjax('vmo_test_shipping_integration', {}).then(res => {
                if (res.success) safeNotify('Integration test passed', 'success');
                else safeNotify('Integration test failed: ' + (res.data && res.data.message || 'Unknown error'), 'error');
            }).catch(e => safeNotify('Integration test error', 'error'));
        };

        window.generateShippingRecommendations = window.generateShippingRecommendations || function() {
            safeNotify('Generating recommendations...', 'info');
            safeAjax('vmo_generate_shipping_recommendations', {}).then(res => {
                if (res.success) {
                    safeNotify('Recommendations generated', 'success');
                    if (typeof window.loadShippingAIPanel === 'function') window.loadShippingAIPanel();
                } else safeNotify('Failed to generate recommendations', 'error');
            }).catch(e => safeNotify('Error generating recommendations', 'error'));
        };

        window.applyAllShippingOptimizations = window.applyAllShippingOptimizations || function() {
            if (!confirm('Apply ALL shipping optimizations?')) return;
            safeNotify('Applying optimizations...', 'info');
            safeAjax('vmo_apply_all_shipping_optimizations', {}).then(res => {
                if (res.success) {
                    safeNotify('Optimizations applied', 'success');
                    if (typeof window.loadShippingAIPanel === 'function') window.loadShippingAIPanel();
                } else safeNotify('Failed to apply optimizations', 'error');
            }).catch(e => safeNotify('Error applying optimizations', 'error'));
        };

        window.openBulkShippingModal = window.openBulkShippingModal || function() {
            const modal = document.getElementById('vmo-bulk-shipping-modal');
            if (modal) modal.style.display = 'flex';
            else safeNotify('Bulk shipping modal not found', 'error');
        };

        window.openAddCustomCarrierModal = window.openAddCustomCarrierModal || function() {
            // Create modal dynamically if missing
            let modal = document.querySelector('.custom-carrier-modal');
            if (!modal && typeof window.createCustomCarrierModal === 'function') {
                 modal = window.createCustomCarrierModal();
            }
            if (modal) modal.style.display = 'flex';
            else safeNotify('Custom carrier modal not initialized', 'error');
        };

        window.importCarrierFromAPI = window.importCarrierFromAPI || function() {
            alert('API Import Feature: Coming soon!');
        };
        
        console.log('[VMO] Safety Net Functions Initialized');
    })();
    </script>

<!-- ========================================
     🎤 JARVIS-STYLE FLOATING VOICE CHAT PANEL
     (Same panel as builder - shares chat history)
     ======================================== -->
<div id="vmo-ai-voice" class="vmo-ai-voice-panel">
  <div class="vmo-voice-header">
    <span class="vmo-voice-title">VMO AI Voice</span>
    <div class="vmo-voice-header-actions">
      <button class="vmo-voice-settings" id="vmo-voice-settings" title="Voice Settings" style="background:none;border:none;cursor:pointer;margin-right:4px;">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
          <path d="M19.14,12.94a7.43,7.43,0,0,0,.05-.94,7.43,7.43,0,0,0-.05-.94l2.11-1.65a.48.48,0,0,0,.11-.61l-2-3.46a.5.5,0,0,0-.6-.22l-2.49,1a7.28,7.28,0,0,0-1.63-.94l-.38-2.65A.49.49,0,0,0,13.69,2H10.31a.49.49,0,0,0-.49.41L9.44,5.06a7.28,7.28,0,0,0-1.63.94l-2.49-1a.5.5,0,0,0-.6.22l-2,3.46a.48.48,0,0,0,.11.61L5,11.06a7.43,7.43,0,0,0-.05.94,7.43,7.43,0,0,0,.05.94L2.89,14.59a.48.48,0,0,0-.11.61l2,3.46a.5.5,0,0,0,.6.22l2.49-1a7.28,7.28,0,0,0,1.63.94l.38,2.65a.49.49,0,0,0,.49.41h3.38a.49.49,0,0,0,.49-.41l.38-2.65a7.28,7.28,0,0,0,1.63-.94l2.49,1a.5.5,0,0,0,.6-.22l2-3.46a.48.48,0,0,0-.11-.61ZM12,15.5A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"></path>
        </svg>
      </button>
      <button class="vmo-voice-collapse" id="vmo-voice-collapse" title="Minimize">−</button>
    </div>
  </div>
  
  <div class="vmo-voice-status" id="vmo-voice-status">
    Voice Consultation Stopped
  </div>
  
  <!-- Chat History -->
  <div class="vmo-voice-chat-history" id="vmo-voice-chat-history">
    <!-- Chat messages will appear here -->
  </div>
  
  <!-- Input Controls -->
  <div class="vmo-voice-input-controls">
    <!-- Upload Button for Jarvis AI Chat Panel -->
    <button class="vmo-voice-btn vmo-voice-btn-upload vmo-voice-btn-wide" id="vmo-voice-upload-btn" title="Upload Images/Files">
      <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
        <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
      </svg>
    </button>
    
    <button class="vmo-voice-btn vmo-voice-btn-text vmo-voice-btn-wide" id="vmo-voice-text-btn" title="Text Input">
      <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
        <path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
      </svg>
    </button>
    
    <button class="vmo-voice-btn vmo-voice-btn-voice vmo-voice-btn-wide" id="vmo-voice-mic-btn" title="Voice Input (Speech-to-Text)">
      <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
        <path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1 1.93c-3.94-.49-7-3.85-7-7.93h2c0 3.31 2.69 6 6 6s6-2.69 6-6h2c0 4.08-3.05 7.44-7 7.93V19h4v2H8v-2h4v-3.07z"/>
      </svg>
    </button>
  </div>
  
  <!-- Start Voice Button (Prominent) -->
  <button class="vmo-voice-start-btn" id="vmo-voice-start-btn">
    <span class="vmo-voice-start-icon">🎤</span>
    <span class="vmo-voice-start-text">Start Voice</span>
  </button>
</div>

<!-- ========================================
     🎯 LISTENING MODAL (For future TTS)
     Displays when AI speaks (VMO TTS HD)
     ======================================== -->
<div id="vmo-listening-modal" class="vmo-listening-modal" style="display: none;">
  <div class="vmo-listening-content">
    <button id="vmo-listening-close" title="End Voice Conversation" style="position:absolute;top:10px;right:10px;background:#222;color:#fff;border:1px solid #444;border-radius:4px;cursor:pointer;padding:4px 8px;">✕ End</button>
    <button id="vmo-listening-mute" title="Mute / Unmute" style="position:absolute;top:10px;right:80px;background:#222;color:#fff;border:1px solid #444;border-radius:4px;cursor:pointer;padding:4px 8px;">Mute</button>
    <button id="vmo-listening-upload" title="Upload" style="position:absolute;top:10px;right:150px;background:#222;color:#fff;border:1px solid #444;border-radius:4px;cursor:pointer;padding:4px 8px;display:none;">Upload</button>
    <div class="vmo-listening-icon">
      <div class="vmo-sound-wave"></div>
    </div>
    <div class="vmo-listening-text">Listening...</div>
    <div class="vmo-listening-transcript" id="vmo-listening-transcript">
      <!-- Real-time transcript will appear here -->
    </div>
  </div>
</div>

<?php include plugin_dir_path(__FILE__) . 'strategic-dashboard-modals.php'; ?>

<!-- ═══ TODAY SUB-TABS + STRATEGIC + REPORTS + CFO EXPANSION JS ═══ -->
<script>
(function(){
    'use strict';

    /* ───────── AJAX Helper ───────── */
    function vmoAjax(action, data) {
        data = data || {};
        data.action = action;
        data._ajax_nonce = typeof vmoAjax_obj !== 'undefined' ? vmoAjax_obj.nonce : (typeof vmo_dash !== 'undefined' ? vmo_dash.nonce : '');
        return jQuery.post(typeof ajaxurl !== 'undefined' ? ajaxurl : '/wp-admin/admin-ajax.php', data);
    }

    /* ═══════════════════════════════════════════ *
     *  1. TODAY SUB-TABS (Tasks / Actions / Done)
     * ═══════════════════════════════════════════ */

    /* Priority colour map */
    var priorityColors = { urgent: '#ef4444', high: '#f59e0b', normal: '#0fe1ff', low: '#6b7280' };
    var priorityIcons  = { urgent: '🔴', high: '🟠', normal: '', low: '⚪' };
    var sourceIcons    = { phone_report: '📞', email_report: '📧', sms_report: '💬', form: '📝', crm: '👥', strategic: '📊', seo: '🔍', shipping: '📦', manual: '✋' };

    /* Track loaded data for filtering */
    var _todayTasksData   = [];
    var _todayActionsData = [];
    var _todayDoneData    = [];

    window.vmoSwitchTodaySubtab = function(tab, el) {
        document.querySelectorAll('.vmo-today-subtab').forEach(function(b){ b.classList.remove('active'); });
        document.querySelectorAll('.vmo-today-panel').forEach(function(p){ p.style.display = 'none'; p.classList.remove('active'); });
        if (el) el.classList.add('active');
        var panel = document.getElementById('vmo-today-' + tab);
        if (panel) { panel.style.display = ''; panel.classList.add('active'); }

        if (tab === 'actions')  loadActionsPanel();
        if (tab === 'done')     loadDonePanel();
    };

    /* ─── Badge updaters ─── */
    function updateBadge(id, count) {
        var el = document.getElementById(id);
        if (el) el.textContent = count > 0 ? count : '';
    }

    /* ─── Render a single task row ─── */
    function renderTaskRow(t, isOverdue) {
        var pColor = priorityColors[t.priority] || priorityColors.normal;
        var pIcon  = priorityIcons[t.priority]  || '';
        var sIcon  = sourceIcons[t.source]      || '';
        var badges = '';
        if (isOverdue) badges += '<span style="background:rgba(251,191,36,.15);color:#fbbf24;font-size:9px;padding:1px 5px;border-radius:3px;margin-right:4px;">CARRIED OVER</span>';
        if (t.priority === 'urgent') badges += '<span style="background:rgba(239,68,68,.15);color:#ef4444;font-size:9px;padding:1px 5px;border-radius:3px;margin-right:4px;">URGENT</span>';
        else if (t.priority === 'high') badges += '<span style="background:rgba(245,158,11,.12);color:#f59e0b;font-size:9px;padding:1px 5px;border-radius:3px;margin-right:4px;">HIGH</span>';

        var dueStr = '';
        if (t.due_date) {
            var d = new Date(t.due_date);
            dueStr = '<span style="font-size:9px;color:var(--muted);margin-left:4px;">' + d.toLocaleTimeString([], {hour:'2-digit',minute:'2-digit'}) + '</span>';
        }

        var isDone = (t.status === 'completed');
        var taskId = t.activity_id || t.id;
        var btnStyle = 'font-size:10px;padding:2px 6px;flex-shrink:0;margin-left:2px;';

        var buttons = '';
        if (isDone) {
            buttons = '<button class="action-btn" style="' + btnStyle + 'opacity:.7;" onclick="vmoUnmarkTask(\'' + taskId + '\')">Undo</button>';
        } else {
            buttons = '<button class="action-btn" style="' + btnStyle + '" onclick="vmoMarkTaskDone(\'' + taskId + '\')">Done</button>' +
                      '<button class="action-btn" style="' + btnStyle + 'background:rgba(251,191,36,.15);color:#fbbf24;" onclick="vmoDeferTask(\'' + taskId + '\')">Defer</button>' +
                      '<button class="action-btn" style="' + btnStyle + 'background:rgba(99,102,241,.12);color:#818cf8;" onclick="vmoRescheduleTask(\'' + taskId + '\')">Move</button>';
        }

        return '<div class="vmo-today-item" data-priority="' + (t.priority||'normal') + '" data-category="' + (t.category||'general') + '" data-source="' + (t.source||'') + '" data-overdue="' + (isOverdue ? '1' : '0') + '" ' +
            'style="display:flex;align-items:center;gap:8px;padding:7px 4px;border-bottom:1px solid rgba(255,255,255,.06);border-left:3px solid ' + pColor + ';' + (isDone ? 'opacity:.5;' : '') + '">' +
            '<span style="font-size:12px;min-width:16px;text-align:center;">' + (isDone ? '✓' : (sIcon || pIcon || '•')) + '</span>' +
            '<div style="flex:1;min-width:0;">' +
                '<div style="font-size:12px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + (isDone ? 'text-decoration:line-through;' : '') + '">' + vmoEsc(t.title || t.activity_title || '') + dueStr + '</div>' +
                '<div style="font-size:10px;margin-top:1px;">' + badges +
                    (t.category ? '<span style="color:var(--muted);font-size:9px;">' + t.category + '</span>' : '') +
                '</div>' +
            '</div>' +
            buttons +
        '</div>';
    }

    /* ─── Actions Panel ─── */
    function loadActionsPanel() {
        var list = document.getElementById('vmo-today-actions-list');
        if (!list) return;
        list.innerHTML = '<p style="color:var(--muted);padding:8px;">Loading actions…</p>';
        vmoAjax('vmo_get_actions_data').done(function(r) {
            if (!r || !r.success || !r.data || !r.data.actions || r.data.actions.length === 0) {
                _todayActionsData = [];
                updateBadge('vmo-actions-badge', 0);
                list.innerHTML = '<p style="color:var(--muted);padding:8px;">No pending actions.</p>';
                return;
            }
            _todayActionsData = r.data.actions;
            updateBadge('vmo-actions-badge', r.data.actions.length);
            var html = '';
            r.data.actions.forEach(function(a) {
                html += renderTaskRow(a, false);
            });
            list.innerHTML = html;
        }).fail(function() {
            list.innerHTML = '<p style="color:#f87171;padding:8px;">Could not load actions.</p>';
        });
    }

    /* ─── Done Panel ─── */
    function loadDonePanel() {
        var list = document.getElementById('vmo-today-done-list');
        if (!list) return;
        list.innerHTML = '<p style="color:var(--muted);padding:8px;">Loading completed items…</p>';
        vmoAjax('vmo_get_done_items').done(function(r) {
            if (!r || !r.success || !r.data || !r.data.items || r.data.items.length === 0) {
                _todayDoneData = [];
                updateBadge('vmo-done-badge', 0);
                list.innerHTML = '<p style="color:var(--muted);padding:8px;">No completed items today.</p>';
                return;
            }
            _todayDoneData = r.data.items;
            updateBadge('vmo-done-badge', r.data.items.length);
            var html = '';
            r.data.items.forEach(function(item) {
                html += '<div style="display:flex;align-items:center;gap:8px;padding:5px 4px;border-bottom:1px solid rgba(255,255,255,.04);">' +
                    '<span style="color:#22c55e;">✓</span>' +
                    '<span style="flex:1;font-size:12px;color:var(--muted);text-decoration:line-through;">' + vmoEsc(item.title) + '</span>' +
                    '<span style="font-size:10px;color:var(--muted);">' + (item.completed_at || '') + '</span>' +
                '</div>';
            });
            list.innerHTML = html;
        }).fail(function() {
            list.innerHTML = '<p style="color:#f87171;padding:8px;">Could not load done items.</p>';
        });
    }

    /* ─── Manual Action ─── */
    window.vmoAddManualAction = function() {
        var title = prompt('Enter action description:');
        if (!title || !title.trim()) return;
        vmoAjax('vmo_add_manual_action', { title: title.trim() }).done(function(r) {
            if (r && r.success) loadActionsPanel();
            else alert('Could not add action.');
        });
    };

    /* ─── Complete Action ─── */
    window.vmoCompleteAction = function(actionId) {
        vmoAjax('vmo_complete_action', { action_id: actionId }).done(function(r) {
            if (r && r.success) {
                loadActionsPanel();
                loadDonePanel();
                updateEodStatus();
            }
        });
    };

    /* ─── Mark a daily task done ─── */
    window.vmoMarkTaskDone = function(taskId) {
        vmoAjax('vmo_complete_today_task', { task_id: taskId }).done(function(r) {
            if (r && r.success) {
                if (typeof window.vmoLoadTodayTasks === 'function') window.vmoLoadTodayTasks();
                loadDonePanel();
                updateEodStatus();
            } else {
                alert((r && r.data && r.data.message) || 'Could not complete task.');
            }
        });
    };

    /* ─── Unmark (reopen) a daily task ─── */
    window.vmoUnmarkTask = function(taskId) {
        vmoAjax('vmo_unmark_today_task', { task_id: taskId }).done(function(r) {
            if (r && r.success) {
                if (typeof window.vmoLoadTodayTasks === 'function') window.vmoLoadTodayTasks();
                loadDonePanel();
                updateEodStatus();
            }
        });
    };

    /* ─── Defer a task to tomorrow ─── */
    window.vmoDeferTask = function(taskId) {
        if (!confirm('Defer this task to tomorrow?')) return;
        vmoAjax('vmo_defer_today_task', { task_id: taskId }).done(function(r) {
            if (r && r.success) {
                if (typeof window.vmoLoadTodayTasks === 'function') window.vmoLoadTodayTasks();
                updateEodStatus();
            } else {
                alert((r && r.data && r.data.message) || 'Could not defer task.');
            }
        });
    };

    /* ─── Reschedule a task to a chosen date ─── */
    window.vmoRescheduleTask = function(taskId) {
        var newDate = prompt('Reschedule to which date? (YYYY-MM-DD)', new Date(Date.now() + 86400000).toISOString().slice(0,10));
        if (!newDate || !/^\d{4}-\d{2}-\d{2}$/.test(newDate)) return;
        vmoAjax('vmo_reschedule_today_task', { task_id: taskId, new_date: newDate }).done(function(r) {
            if (r && r.success) {
                if (typeof window.vmoLoadTodayTasks === 'function') window.vmoLoadTodayTasks();
                updateEodStatus();
            } else {
                alert((r && r.data && r.data.message) || 'Could not reschedule task.');
            }
        });
    };

    /* ─── Filter Today Tasks ─── */
    window.vmoFilterTodayTasks = function() {
        var filter = (document.getElementById('vmo-today-filter') || {}).value || 'all';
        document.querySelectorAll('.vmo-today-item').forEach(function(el) {
            var show = true;
            if (filter === 'urgent')    show = el.dataset.priority === 'urgent';
            else if (filter === 'high') show = el.dataset.priority === 'high';
            else if (filter === 'overdue') show = el.dataset.overdue === '1';
            else if (filter !== 'all')  show = el.dataset.category === filter;
            el.style.display = show ? '' : 'none';
        });
    };

    /* ─── End-of-Day Report ─── */
    window.vmoSubmitDailyReport = function() {
        var form = document.getElementById('vmo-eod-form');
        if (form && form.style.display === 'none') {
            form.style.display = '';
            updateEodStatus();
            return;
        }
        var notes = (document.getElementById('vmo-eod-notes') || {}).value || '';
        var btn = document.querySelector('#vmo-eod-closure .action-btn');
        if (btn) { btn.disabled = true; btn.textContent = 'Submitting…'; }
        vmoAjax('vmo_submit_daily_report', { notes: notes }).done(function(r) {
            var status = document.getElementById('vmo-eod-status');
            if (r && r.success) {
                if (status) status.innerHTML = '<span style="color:#22c55e;">✅ Daily report submitted.</span>' +
                    (r.data && r.data.summary ? '<div style="margin-top:6px;font-size:11px;color:var(--muted);">' + r.data.summary + '</div>' : '');
                if (btn) { btn.textContent = 'Submitted'; }
            } else {
                if (status) status.innerHTML = '<span style="color:#f87171;">Could not submit report.</span>';
                if (btn) { btn.disabled = false; btn.textContent = 'Retry'; }
            }
        }).fail(function() {
            if (btn) { btn.disabled = false; btn.textContent = 'Retry'; }
        });
    };

    function updateEodStatus() {
        var status = document.getElementById('vmo-eod-status');
        if (!status) return;
        var doneCount = _todayDoneData.length;
        var tasksLeft = _todayTasksData.length;
        var actionsLeft = _todayActionsData.length;
        var total = doneCount + tasksLeft + actionsLeft;
        if (total === 0) { status.textContent = 'No tasks tracked today.'; return; }
        var pct = Math.round((doneCount / total) * 100);
        status.innerHTML = '<span style="color:var(--cyan-soft);">' + doneCount + '/' + total + ' completed (' + pct + '%)</span>' +
            (tasksLeft > 0 ? ' · <span style="color:#fbbf24;">' + tasksLeft + ' tasks remain</span>' : '') +
            (actionsLeft > 0 ? ' · <span style="color:#f59e0b;">' + actionsLeft + ' actions pending</span>' : '');
    }

    /* ─── Carryover Banner ─── */
    function checkCarryover(overdueItems) {
        var banner = document.getElementById('vmo-carryover-banner');
        var countEl = document.getElementById('vmo-carryover-count');
        if (!banner) return;
        if (overdueItems && overdueItems.length > 0) {
            banner.style.display = '';
            if (countEl) countEl.textContent = overdueItems.length;
        } else {
            banner.style.display = 'none';
        }
    }

    /* ─── Hook into existing tasks load to capture data + render with badges ─── */
    var _origLoadTasks = window.vmoLoadTodayTasks || null;
    window.vmoLoadTodayTasks = function() {
        var list = document.getElementById('vmo-today-list');
        if (!list) return;
        list.innerHTML = '<p style="color:var(--muted);padding:8px;">Loading tasks…</p>';
        vmoAjax('vmo_get_todays_tasks_full').done(function(r) {
            if (!r || !r.success || !r.data) {
                list.innerHTML = '<p style="color:var(--muted);padding:8px;">No tasks for today.</p>';
                _todayTasksData = [];
                updateBadge('vmo-tasks-badge', 0);
                checkCarryover([]);
                return;
            }
            var today   = r.data.today   || [];
            var overdue = r.data.overdue || [];
            _todayTasksData = today.concat(overdue);
            updateBadge('vmo-tasks-badge', _todayTasksData.length);
            checkCarryover(overdue);

            var html = '';
            /* Overdue first */
            overdue.forEach(function(t) { html += renderTaskRow(t, true); });
            /* Today's tasks */
            today.forEach(function(t) { html += renderTaskRow(t, false); });

            if (html === '') html = '<p style="color:var(--muted);padding:8px;">All caught up! No tasks remaining.</p>';
            list.innerHTML = html;
            updateEodStatus();
        }).fail(function() {
            list.innerHTML = '<p style="color:#f87171;padding:8px;">Could not load tasks.</p>';
        });
    };

    /* Auto-load tasks on tab switch if appropriate */
    var _origSwitchTab = window.switchTab;
    if (typeof _origSwitchTab === 'function') {
        window.switchTab = function(tab) {
            _origSwitchTab(tab);
            if (tab === 'overview') {
                setTimeout(function(){ if (typeof window.vmoLoadTodayTasks === 'function') window.vmoLoadTodayTasks(); }, 200);
            }
        };
    }

    /* ═══════════════════════════════════════════ *
     *  2. STRATEGIC DASHBOARD
     * ═══════════════════════════════════════════ */
    var strategicLoaded = false;
    window.loadStrategicPanel = function() {
        if (strategicLoaded) return;
        strategicLoaded = true;
        vmoAjax('vmo_get_strategic_data').done(function(r) {
            if (!r || !r.success || !r.data) return;
            var d = r.data;

            /* Vision Progress Ring */
            var pct = d.vision_progress || 0;
            var ring = document.getElementById('vmo-strategic-ring-fill');
            if (ring) {
                var circ = 2 * Math.PI * 54;
                ring.setAttribute('stroke-dasharray', circ);
                ring.setAttribute('stroke-dashoffset', circ - (circ * pct / 100));
            }
            setText('vmo-strategic-pct', pct + '%');
            setText('vmo-strategic-vision-label', d.vision_label || 'Your Business Vision');

            /* Strategic Position */
            setText('vmo-strat-market-pos', d.market_position || '—');
            setText('vmo-strat-growth', d.growth_rate || '—');
            setText('vmo-strat-health', d.health_score || '—');
            setText('vmo-strat-competitive', d.competitive_index || '—');
            setText('vmo-strat-readiness', d.readiness_score || '—');

            /* Opportunities */
            setList('vmo-strat-opps', d.opportunities);
            /* Risks */
            setList('vmo-strat-risks', d.risks);
            /* Competitor Movement */
            setList('vmo-strat-competitor-movement', d.competitor_movement);

            /* KPI Cards */
            if (d.kpis) {
                Object.keys(d.kpis).forEach(function(cat) {
                    var el = document.getElementById('vmo-strat-kpi-' + cat);
                    if (el) {
                        var items = d.kpis[cat];
                        var html = '';
                        items.forEach(function(k) {
                            html += '<div class="vmo-kv"><span>' + vmoEsc(k.label) + '</span><strong>' + vmoEsc(k.value) + '</strong></div>';
                        });
                        el.innerHTML = html;
                    }
                });
            }

            /* Strategic Actions */
            setList('vmo-strat-actions', d.strategic_actions);
            /* Approval Queue */
            setList('vmo-strat-approvals', d.approval_queue);
            /* Recent Changes */
            setList('vmo-strat-changes', d.recent_changes);
            /* Forecast */
            setText('vmo-strat-forecast', d.forecast || 'No forecast available yet.');

            /* Strategic Interpretation — show rule-based first, then upgrade with AI */
            var interpEl = document.getElementById('vmo-strat-interpretation');
            if (interpEl && d.interpretation) {
                interpEl.innerHTML = '<div style="background:rgba(15,225,255,.04);border:1px solid rgba(15,225,255,.12);border-radius:6px;padding:10px 12px;margin-top:6px;font-size:11px;color:var(--cyan-soft);line-height:1.5;">' +
                    '<strong>📊 Strategic Assessment:</strong> ' + vmoEsc(d.interpretation) + '</div>';
            }
            /* Upgrade to AI interpretation in background */
            if (typeof window.vmoLoadAIKpiInterpretation === 'function') {
                window.vmoLoadAIKpiInterpretation();
            }
        });
    };

    /* ═══════════════════════════════════════════ *
     *  3. REPORTS TAB
     * ═══════════════════════════════════════════ */
    window.vmoSwitchGlobalReportTab = function(tab) {
        document.querySelectorAll('.vmo-report-tab').forEach(function(b){ b.classList.remove('active'); });
        document.querySelectorAll('.vmo-report-tab-content').forEach(function(p){ p.style.display = 'none'; });
        var btn = document.querySelector('.vmo-report-tab[data-tab="' + tab + '"]');
        if (btn) btn.classList.add('active');
        var shortName = tab.replace(/^report-/, '');
        var panel = document.getElementById('vmo-global-report-' + shortName);
        if (panel) panel.style.display = 'block';
        loadReportContent(tab);
    };

    var loadedReports = {};
    var enhancedReportTypes = { 'report-payments':1, 'report-shipping':1, 'report-crm':1, 'report-forms':1 };
    function loadReportContent(tab) {
        if (loadedReports[tab]) return;
        loadedReports[tab] = true;
        var shortName = tab.replace(/^report-/, '');
        var listEl = document.getElementById('vmo-report-' + shortName + '-list');
        if (!listEl) return;
        listEl.innerHTML = '<div class="vmo-card"><p style="color:var(--muted);">Loading ' + shortName + ' reports...</p></div>';
        var action = enhancedReportTypes[tab] ? 'vmo_get_reports_enhanced' : 'vmo_get_reports_data';
        vmoAjax(action, { report_type: shortName }).done(function(r) {
            if (!r || !r.success || !r.data || !r.data.html) {
                listEl.innerHTML = '<div class="vmo-card"><p style="color:var(--muted);">No ' + shortName.replace(/-/g, ' ') + ' reports yet.</p></div>';
                return;
            }
            listEl.innerHTML = r.data.html;
        }).fail(function() {
            listEl.innerHTML = '<div class="vmo-card"><p style="color:#f87171;">Failed to load reports.</p></div>';
            loadedReports[tab] = false;
        });
    }

    /* ═══════════════════════════════════════════ *
     *  4. CFO EXPANSION DATA LOADING
     * ═══════════════════════════════════════════ */
    window.loadCFOExpansionData = function() {
        /* Token System */
        vmoAjax('vmo_get_cfo_expansion').done(function(r) {
            if (!r || !r.success || !r.data) return;
            var d = r.data;

            /* Token balance */
            setText('vmo-cfo-token-balance', formatNum(d.token_balance));
            setText('vmo-cfo-token-capacity', d.token_capacity || '—');
            setText('vmo-cfo-token-used-30d', formatNum(d.tokens_used_30d));
            setText('vmo-cfo-token-daily-avg', formatNum(d.token_daily_avg));
            setText('vmo-cfo-token-value-30d', '$' + Number(d.token_value_30d_usd || 0).toFixed(2));

            /* Cost by system */
            if (d.cost_by_system) {
                Object.keys(d.cost_by_system).forEach(function(sys) {
                    setText('vmo-cost-' + sys, formatNum(d.cost_by_system[sys]));
                });
            }

            /* Plan & billing */
            setText('vmo-cfo-plan-name', d.plan_name || '—');
            setText('vmo-cfo-billing-status', d.billing_status || '—');
            setText('vmo-cfo-billing-cycle', d.billing_cycle || '—');
            setText('vmo-cfo-renewal-date', d.renewal_date || '—');
            setText('vmo-cfo-tokens-included', formatNum(d.tokens_included || 0));
            setText('vmo-cfo-plan-usage', (d.plan_usage_percent || 0) + '%');
            setText('vmo-cfo-plan-recommendation', d.plan_recommendation || '—');

            /* VMO Pay status */
            setText('vmo-cfo-stripe-status', d.stripe_status || '—');
            setText('vmo-cfo-stripe-account', d.stripe_account_id || '—');
            setText('vmo-cfo-details-submitted', d.details_submitted ? 'Yes' : 'No');
            setText('vmo-cfo-charges-enabled', d.charges_enabled ? 'Yes' : 'No');
            setText('vmo-cfo-payouts-enabled', d.payouts_enabled ? 'Yes' : 'No');
            var blockers = document.getElementById('vmo-cfo-stripe-blockers');
            if (blockers && d.stripe_blockers && d.stripe_blockers.length > 0) {
                blockers.style.display = 'block';
                blockers.innerHTML = '<strong>Action needed:</strong> ' + d.stripe_blockers.map(vmoEsc).join(', ');
            } else if (blockers) {
                blockers.style.display = 'none';
                blockers.innerHTML = '';
            }

            /* AI Financial Inbox */
            setText('vmo-cfo-inbox-count', formatNum((d.financial_inbox && d.financial_inbox.needs_review) || 0));
            var inboxEl = document.getElementById('vmo-cfo-financial-inbox');
            if (inboxEl) {
                var inboxItems = (d.financial_inbox && d.financial_inbox.items) || [];
                if (!inboxItems.length) {
                    inboxEl.innerHTML = '<div style="padding:10px;color:var(--muted);font-size:12px;border:1px solid var(--border);border-radius:8px;">No detected financial events need review.</div>';
                } else {
                    inboxEl.innerHTML = inboxItems.map(function(item) {
                        var party = item.customer_name || item.vendor_name || 'Unknown party';
                        var amount = '$' + Number(item.amount || 0).toFixed(2) + ' ' + vmoEsc(item.currency || 'USD');
                        var confidence = Math.round(Number(item.confidence || 0) * 100);
                        var missing = item.missing_fields ? String(item.missing_fields).split(',').filter(Boolean) : [];
                        return '<div style="display:grid;grid-template-columns:1.2fr .8fr auto;gap:10px;align-items:center;padding:10px;border:1px solid var(--border);border-radius:8px;background:rgba(255,255,255,.02);">'
                            + '<div><strong>' + vmoEsc(party) + '</strong><div style="font-size:11px;color:var(--muted);margin-top:2px;">' + vmoEsc(item.source || 'source') + ' • ' + vmoEsc(item.event_status || 'needs_review') + ' • ' + confidence + '% confidence</div><div style="font-size:11px;color:var(--muted);margin-top:2px;">' + vmoEsc(item.product_service || item.category || 'Financial event') + '</div>' + (missing.length ? '<div style="font-size:11px;color:#fbbf24;margin-top:3px;">Missing: ' + missing.map(vmoEsc).join(', ') + '</div>' : '') + '</div>'
                            + '<div style="font-weight:700;color:var(--cyan-soft);">' + amount + '</div>'
                            + '<div style="display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end;">'
                            + '<button class="action-btn" style="font-size:11px;padding:5px 8px;" onclick="vmoCFOReviewFinancialEvent(' + Number(item.id) + ',\'approve\')">Approve</button>'
                            + '<button class="action-btn" style="font-size:11px;padding:5px 8px;" onclick="vmoCFOReviewFinancialEvent(' + Number(item.id) + ',\'create_invoice\')">Create Invoice Now</button>'
                            + '<button class="action-btn" style="font-size:11px;padding:5px 8px;" onclick="vmoCFOReviewFinancialEvent(' + Number(item.id) + ',\'create_payment_link\')">Create Payment Link Now</button>'
                            + '<button class="action-btn" style="font-size:11px;padding:5px 8px;background:rgba(239,68,68,.12);" onclick="vmoCFOReviewFinancialEvent(' + Number(item.id) + ',\'reject\')">Reject</button>'
                            + '</div></div>';
                    }).join('');
                }
            }

            /* Forecasting */
            var f = d.forecasts || {};
            setText('vmo-cfo-runway-days', f.token_runway_days === null || typeof f.token_runway_days === 'undefined' ? 'N/A' : formatNum(f.token_runway_days));
            setText('vmo-cfo-projected-tokens', formatNum(f.projected_30d_tokens || 0));
            setText('vmo-cfo-projected-spend', '$' + Number(f.projected_30d_token_value_usd || 0).toFixed(2));
            setText('vmo-cfo-ops-ratio', f.operating_usage_to_revenue_percent === null || typeof f.operating_usage_to_revenue_percent === 'undefined' ? 'N/A' : f.operating_usage_to_revenue_percent + '%');
            setText('vmo-cfo-goal-progress', f.monthly_goal_progress_percent === null || typeof f.monthly_goal_progress_percent === 'undefined' ? 'No goal' : f.monthly_goal_progress_percent + '%');
            setText('vmo-cfo-sustainability', f.sustainability || 'unknown');

            /* High-cost approvals */
            var approvalsEl = document.getElementById('vmo-cfo-high-cost-approvals');
            var approvals = (d.high_cost_approvals && d.high_cost_approvals.items) || [];
            if (approvalsEl) {
                if (!approvals.length) {
                    approvalsEl.innerHTML = '<div class="vmo-card"><p style="color:var(--muted);">No high-cost actions are waiting for approval.</p></div>';
                } else {
                    approvalsEl.innerHTML = approvals.map(function(item) {
                        return '<div class="vmo-card"><h4>' + vmoEsc(item.title || 'Approval') + '</h4><div style="font-size:11px;color:var(--muted);">' + vmoEsc(item.approval_type || 'approval') + ' • ' + vmoEsc(item.source_system || 'system') + '</div><p style="font-size:12px;color:var(--muted);margin-top:6px;">' + vmoEsc(item.description || '') + '</p></div>';
                    }).join('');
                }
            }

            /* Financial Alerts */
            if (d.alerts && d.alerts.length > 0) {
                var alertsEl = document.getElementById('vmo-cfo-alerts');
                if (alertsEl) {
                    var html = '';
                    d.alerts.forEach(function(a) {
                        var color = a.severity === 'critical' ? '#ef4444' : a.severity === 'warning' ? '#f59e0b' : '#3b82f6';
                        html += '<div class="vmo-card" style="border-left:3px solid ' + color + ';">' +
                            '<strong style="color:' + color + ';">' + vmoEsc(a.title) + '</strong>' +
                            '<p style="font-size:12px;color:var(--muted);margin-top:4px;">' + vmoEsc(a.message) + '</p>' +
                        '</div>';
                    });
                    alertsEl.innerHTML = html;
                }
            }

            /* Financial Insights */
            setText('vmo-cfo-insights', d.financial_insights || 'No financial insights available yet.');
        });
    };

    window.vmoCFOReviewFinancialEvent = async function(eventId, decision) {
        try {
            var resp = await ajaxPost('vmo_cfo_review_financial_event', { event_id: eventId, decision: decision });
            if (resp && resp.success) {
                if (decision === 'approve') {
                    notify('Financial event posted to ledger.', 'success');
                } else if (decision === 'create_invoice') {
                    if (resp.data && resp.data.pay_url && navigator.clipboard) navigator.clipboard.writeText(resp.data.pay_url).catch(function(){});
                    notify('Invoice created from financial event.', 'success');
                    if (typeof window.vmoLoadInvoices === 'function') window.vmoLoadInvoices();
                } else if (decision === 'create_payment_link') {
                    if (resp.data && resp.data.url && navigator.clipboard) navigator.clipboard.writeText(resp.data.url).catch(function(){});
                    notify('Payment link created and copied.', 'success');
                    if (typeof window.vmoLoadPayLinks === 'function') window.vmoLoadPayLinks();
                } else {
                    notify('Financial event updated.', 'success');
                }
                window.loadCFOExpansionData();
            } else {
                notify((resp && resp.data && resp.data.message) || 'Unable to update financial event.', 'error');
            }
        } catch (e) {
            notify('Unable to update financial event.', 'error');
        }
    };

    window.vmoCFOCaptureInstruction = async function() {
        var input = document.getElementById('vmo-cfo-instruction');
        var instruction = input ? input.value.trim() : '';
        if (!instruction) return notify('Tell VMO what happened first.', 'error');
        try {
            var resp = await ajaxPost('vmo_cfo_capture_financial_instruction', { instruction: instruction });
            if (resp && resp.success) {
                if (input) input.value = '';
                var missing = (resp.data && resp.data.missing_fields && resp.data.missing_fields.length) ? ' Missing: ' + resp.data.missing_fields.join(', ') + '.' : '';
                var followups = (resp.data && resp.data.follow_up_questions) || [];
                var followupBox = document.getElementById('vmo-cfo-instruction-followups');
                if (followupBox) {
                    if (followups.length) {
                        window.__vmoCfoFollowupEventId = resp.data && resp.data.event_id ? Number(resp.data.event_id) : 0;
                        followupBox.style.display = 'block';
                        followupBox.innerHTML = '<strong>VMO needs:</strong><br>' + followups.map(function(q) { return '• ' + vmoEsc(q); }).join('<br>')
                            + '<div style="display:grid;grid-template-columns:1fr auto;gap:8px;margin-top:8px;"><textarea id="vmo-cfo-followup-answer" placeholder="Answer the missing details here" style="min-height:42px;padding:7px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink);font-size:12px;resize:vertical;"></textarea><button class="action-btn" onclick="vmoCFOSubmitFollowupDetails()">Add Details</button></div>';
                    } else {
                        window.__vmoCfoFollowupEventId = 0;
                        followupBox.style.display = 'none';
                        followupBox.innerHTML = '';
                    }
                }
                notify((resp.data && resp.data.message) ? resp.data.message : ('Financial event added for review.' + missing), 'success');
                window.loadCFOExpansionData();
            } else {
                notify((resp && resp.data && resp.data.message) || 'Unable to add financial event.', 'error');
            }
        } catch (e) {
            notify('Unable to add financial event.', 'error');
        }
    };

    window.vmoCFOSubmitFollowupDetails = async function() {
        var eventId = Number(window.__vmoCfoFollowupEventId || 0);
        var answerEl = document.getElementById('vmo-cfo-followup-answer');
        var instruction = answerEl ? answerEl.value.trim() : '';
        if (!eventId) return notify('No financial event is selected for follow-up.', 'error');
        if (!instruction) return notify('Add the missing details first.', 'error');
        try {
            var resp = await ajaxPost('vmo_cfo_update_financial_event_details', { event_id: eventId, instruction: instruction });
            if (resp && resp.success) {
                var followups = (resp.data && resp.data.follow_up_questions) || [];
                var followupBox = document.getElementById('vmo-cfo-instruction-followups');
                if (followupBox) {
                    if (followups.length) {
                        followupBox.style.display = 'block';
                        followupBox.innerHTML = '<strong>Still needed:</strong><br>' + followups.map(function(q) { return '• ' + vmoEsc(q); }).join('<br>')
                            + '<div style="display:grid;grid-template-columns:1fr auto;gap:8px;margin-top:8px;"><textarea id="vmo-cfo-followup-answer" placeholder="Answer the remaining details here" style="min-height:42px;padding:7px;border-radius:6px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--ink);font-size:12px;resize:vertical;"></textarea><button class="action-btn" onclick="vmoCFOSubmitFollowupDetails()">Add Details</button></div>';
                    } else {
                        window.__vmoCfoFollowupEventId = 0;
                        followupBox.style.display = 'none';
                        followupBox.innerHTML = '';
                    }
                }
                notify((resp.data && resp.data.message) || 'Financial event updated.', 'success');
                window.loadCFOExpansionData();
            } else {
                notify((resp && resp.data && resp.data.message) || 'Unable to update financial event.', 'error');
            }
        } catch (e) {
            notify('Unable to update financial event.', 'error');
        }
    };

    /* ═══════════════════════════════════════════ *
     *  VMO PAY — Invoices, Payment Links, LTV
     * ═══════════════════════════════════════════ */

    /* ── Invoice Line Items ─── */
    window.vmoAddInvoiceLine = function() {
        var container = document.getElementById('vmo-inv-items');
        if (!container) return;
        var row = document.createElement('div');
        row.className = 'vmo-inv-item-row';
        row.style.cssText = 'display:grid;grid-template-columns:2fr 80px 80px 32px;gap:6px;margin-bottom:6px;align-items:center';
        row.innerHTML = '<input type="text" placeholder="Description" class="vmo-inv-desc" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px">'
            + '<input type="number" placeholder="Qty" class="vmo-inv-qty" value="1" min="1" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px;text-align:center">'
            + '<input type="number" placeholder="Price" class="vmo-inv-price" step="0.01" min="0" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px;text-align:right">'
            + '<button onclick="this.parentElement.remove();window.vmoUpdateInvoiceTotal()" style="background:rgba(239,68,68,.15);border:1px solid rgba(239,68,68,.3);border-radius:6px;color:#ef4444;cursor:pointer;font-size:14px;width:28px;height:28px;padding:0">×</button>';
        container.appendChild(row);
        // Attach change listeners
        row.querySelectorAll('.vmo-inv-qty, .vmo-inv-price').forEach(function(el) {
            el.addEventListener('input', window.vmoUpdateInvoiceTotal);
        });
    };

    window.vmoUpdateInvoiceTotal = function() {
        var rows = document.querySelectorAll('.vmo-inv-item-row');
        var total = 0;
        rows.forEach(function(r) {
            var qty = parseFloat(r.querySelector('.vmo-inv-qty')?.value) || 0;
            var price = parseFloat(r.querySelector('.vmo-inv-price')?.value) || 0;
            total += qty * price;
        });
        var cur = document.getElementById('vmo-inv-currency')?.value || 'usd';
        var sym = {usd:'$',eur:'€',gbp:'£',cad:'C$',aud:'A$',ngn:'₦',kes:'KSh',zar:'R',inr:'₹',jpy:'¥'}[cur] || '$';
        setText('vmo-inv-total-display', sym + total.toFixed(2));
    };

    // Attach listeners to initial row
    document.querySelectorAll('.vmo-inv-qty, .vmo-inv-price').forEach(function(el) {
        el.addEventListener('input', window.vmoUpdateInvoiceTotal);
    });
    var invCur = document.getElementById('vmo-inv-currency');
    if (invCur) invCur.addEventListener('change', window.vmoUpdateInvoiceTotal);

    /* ── Create Invoice ─── */
    window.vmoCreateInvoice = async function(sendNow) {
        var client_name  = document.getElementById('vmo-inv-client-name')?.value?.trim();
        var client_email = document.getElementById('vmo-inv-client-email')?.value?.trim();
        var currency     = document.getElementById('vmo-inv-currency')?.value || 'usd';
        var due_date     = document.getElementById('vmo-inv-due-date')?.value || '';
        var notes        = document.getElementById('vmo-inv-notes')?.value || '';

        if (!client_name || !client_email) return notify('Client name and email are required', 'error');

        var items = [];
        document.querySelectorAll('.vmo-inv-item-row').forEach(function(r) {
            var desc  = r.querySelector('.vmo-inv-desc')?.value?.trim();
            var qty   = parseFloat(r.querySelector('.vmo-inv-qty')?.value) || 0;
            var price = parseFloat(r.querySelector('.vmo-inv-price')?.value) || 0;
            if (desc && price > 0) items.push({description: desc, qty: qty, price: price});
        });
        if (!items.length) return notify('Add at least one line item', 'error');

        try {
            var resp = await ajaxPost('vmo_pay_create_invoice', {
                client_name: client_name,
                client_email: client_email,
                items: JSON.stringify(items),
                currency: currency,
                due_date: due_date,
                notes: notes,
                send_now: sendNow ? 1 : 0,
            });
            if (resp && resp.success) {
                notify('Invoice ' + resp.data.invoice_number + (sendNow ? ' created & sent!' : ' saved as draft'), 'success');
                // Reset form
                document.getElementById('vmo-inv-client-name').value = '';
                document.getElementById('vmo-inv-client-email').value = '';
                document.getElementById('vmo-inv-notes').value = '';
                document.getElementById('vmo-inv-items').innerHTML = '<div class="vmo-inv-item-row" style="display:grid;grid-template-columns:2fr 80px 80px 32px;gap:6px;margin-bottom:6px;align-items:center"><input type="text" placeholder="Description" class="vmo-inv-desc" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px"><input type="number" placeholder="Qty" class="vmo-inv-qty" value="1" min="1" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px;text-align:center"><input type="number" placeholder="Price" class="vmo-inv-price" step="0.01" min="0" style="padding:6px 8px;background:rgba(0,0,0,.3);border:1px solid var(--border);border-radius:6px;color:var(--ink);font-size:12px;text-align:right"><span></span></div>';
                window.vmoUpdateInvoiceTotal();
                window.vmoLoadInvoices();
            } else {
                notify(resp?.data || 'Failed to create invoice', 'error');
            }
        } catch(e) { notify('Error creating invoice', 'error'); }
    };

    /* ── Load Invoices ─── */
    window.vmoLoadInvoices = async function() {
        try {
            var resp = await ajaxPost('vmo_pay_list_invoices', {});
            if (!resp || !resp.success) return;
            var invoices = resp.data.invoices || [];
            var stats = resp.data.stats || {};
            setText('vmo-invoice-count', invoices.length || '0');
            var el = document.getElementById('vmo-invoice-list');
            if (!el) return;
            if (!invoices.length) {
                el.innerHTML = '<div style="padding:10px;text-align:center;color:var(--muted);font-size:12px">No invoices yet.</div>';
                return;
            }
            var colors = {draft:'#6b7280',sent:'#3b82f6',viewed:'#8b5cf6',paid:'#10b981',overdue:'#ef4444',cancelled:'#6b7280'};
            var html = '';
            invoices.forEach(function(inv) {
                var c = colors[inv.status] || '#6b7280';
                html += '<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border-bottom:1px solid var(--border);font-size:12px">'
                    + '<div><strong style="color:var(--ink)">' + vmoEsc(inv.invoice_number) + '</strong><br><span style="color:var(--muted)">' + vmoEsc(inv.client_name) + '</span></div>'
                    + '<div style="text-align:right">'
                    + '<span style="color:var(--cyan);font-weight:600">' + formatCur(inv.total, inv.currency) + '</span>'
                    + '<span style="display:inline-block;padding:2px 8px;background:' + c + '22;color:' + c + ';border-radius:10px;font-size:10px;margin-left:8px">' + inv.status.toUpperCase() + '</span>';
                if (inv.status === 'draft') {
                    html += '<br><button class="action-btn" onclick="window.vmoSendInvoice(' + inv.id + ')" style="font-size:10px;margin-top:4px;padding:2px 8px">📧 Send</button>';
                }
                if (inv.status !== 'paid') {
                    html += ' <button class="action-btn" onclick="navigator.clipboard.writeText(\'' + vmoEsc(inv.pay_url) + '\');notify(\'Pay link copied!\',\'success\')" style="font-size:10px;margin-top:4px;padding:2px 8px">🔗 Copy Link</button>';
                    html += ' <button class="action-btn" onclick="window.vmoDeleteInvoice(' + inv.id + ')" style="font-size:10px;margin-top:4px;padding:2px 8px;color:#ef4444">🗑️</button>';
                }
                html += '</div></div>';
            });
            el.innerHTML = html;
        } catch(e) {}
    };

    window.vmoSendInvoice = async function(id) {
        try {
            var resp = await ajaxPost('vmo_pay_send_invoice', {invoice_id: id});
            if (resp && resp.success) { notify('Invoice sent!', 'success'); window.vmoLoadInvoices(); }
            else notify(resp?.data || 'Send failed', 'error');
        } catch(e) { notify('Error sending invoice', 'error'); }
    };

    window.vmoDeleteInvoice = async function(id) {
        if (!confirm('Delete this invoice?')) return;
        try {
            var resp = await ajaxPost('vmo_pay_delete_invoice', {invoice_id: id});
            if (resp && resp.success) { notify('Invoice deleted', 'success'); window.vmoLoadInvoices(); }
            else notify(resp?.data || 'Delete failed', 'error');
        } catch(e) { notify('Error deleting invoice', 'error'); }
    };

    /* ── Payment Links ─── */
    window.vmoCreatePaymentLink = async function() {
        var name        = document.getElementById('vmo-pl-name')?.value?.trim();
        var amount      = parseFloat(document.getElementById('vmo-pl-amount')?.value) || 0;
        var currency    = document.getElementById('vmo-pl-currency')?.value || 'usd';
        var description = document.getElementById('vmo-pl-description')?.value?.trim() || '';
        var allowCustom = document.getElementById('vmo-pl-allow-custom')?.checked;

        if (!name) return notify('Link name is required', 'error');
        if (amount < 0.50 && !allowCustom) return notify('Minimum amount is $0.50', 'error');

        notify('Creating payment link…', 'info');
        try {
            var resp = await ajaxPost('vmo_pay_create_paylink', {
                name: name,
                description: description,
                amount: amount,
                currency: currency,
                allow_custom: allowCustom ? 1 : 0,
            });
            if (resp && resp.success) {
                notify('Payment link created!', 'success');
                var urlEl = document.getElementById('vmo-pl-url');
                var resultEl = document.getElementById('vmo-pl-result');
                if (urlEl) urlEl.value = resp.data.url;
                if (resultEl) resultEl.style.display = 'block';
                document.getElementById('vmo-pl-name').value = '';
                document.getElementById('vmo-pl-amount').value = '';
                document.getElementById('vmo-pl-description').value = '';
                window.vmoLoadPayLinks();
            } else {
                notify(resp?.data || 'Failed to create payment link', 'error');
            }
        } catch(e) { notify('Error creating payment link', 'error'); }
    };

    window.vmoLoadPayLinks = async function() {
        try {
            var resp = await ajaxPost('vmo_pay_list_paylinks', {});
            if (!resp || !resp.success) return;
            var links = resp.data.links || [];
            setText('vmo-paylink-count', links.length || '0');
            var el = document.getElementById('vmo-paylink-list');
            if (!el) return;
            if (!links.length) {
                el.innerHTML = '<div style="padding:10px;text-align:center;color:var(--muted);font-size:12px">No payment links yet.</div>';
                return;
            }
            var html = '';
            links.forEach(function(l) {
                var amt = l.allow_custom_amount == 1 ? 'Custom amount' : formatCur(l.amount_cents / 100, l.currency);
                var active = l.status === 'active';
                html += '<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border-bottom:1px solid var(--border);font-size:12px;opacity:' + (active ? '1' : '.5') + '">'
                    + '<div><strong style="color:var(--ink)">' + vmoEsc(l.name) + '</strong><br><span style="color:var(--muted)">' + amt + '</span></div>'
                    + '<div style="display:flex;gap:6px;align-items:center">';
                if (active && l.stripe_payment_link_url) {
                    html += '<button class="action-btn" onclick="navigator.clipboard.writeText(\'' + vmoEsc(l.stripe_payment_link_url) + '\');notify(\'Link copied!\',\'success\')" style="font-size:10px;padding:3px 8px">📋 Copy</button>';
                    html += '<button class="action-btn" onclick="window.vmoDeletePayLink(' + l.id + ')" style="font-size:10px;padding:3px 8px;color:#ef4444">🗑️</button>';
                } else {
                    html += '<span style="color:var(--muted);font-size:10px">Inactive</span>';
                }
                html += '</div></div>';
            });
            el.innerHTML = html;
        } catch(e) {}
    };

    window.vmoDeletePayLink = async function(id) {
        if (!confirm('Deactivate this payment link?')) return;
        try {
            var resp = await ajaxPost('vmo_pay_delete_paylink', {link_id: id});
            if (resp && resp.success) { notify('Link deactivated', 'success'); window.vmoLoadPayLinks(); }
            else notify(resp?.data || 'Failed', 'error');
        } catch(e) { notify('Error deactivating link', 'error'); }
    };

    /* ── Customer LTV ─── */
    window.vmoLoadLTV = async function() {
        try {
            var resp = await ajaxPost('vmo_pay_customer_ltv', {});
            if (!resp || !resp.success) return;
            var d = resp.data;
            setText('vmo-ltv-avg', formatCur(d.avg_ltv || 0));
            setText('vmo-ltv-top', formatCur(d.top_ltv || 0));
            setText('vmo-ltv-total-customers', d.total_customers || '0');
            setText('vmo-ltv-top-badge', d.total_customers || '0');

            var el = document.getElementById('vmo-ltv-list');
            if (!el) return;
            if (!d.customers || !d.customers.length) {
                el.innerHTML = '<div style="padding:12px;text-align:center;color:var(--muted)">No paying customers yet.</div>';
                return;
            }
            var html = '<table style="width:100%;font-size:12px;border-collapse:collapse"><thead><tr style="border-bottom:1px solid var(--border);color:var(--muted);text-align:left"><th style="padding:6px 8px">#</th><th style="padding:6px 8px">Customer</th><th style="padding:6px 8px;text-align:right">LTV</th><th style="padding:6px 8px;text-align:right">Purchases</th><th style="padding:6px 8px">Last Purchase</th></tr></thead><tbody>';
            d.customers.forEach(function(c, i) {
                html += '<tr style="border-bottom:1px solid var(--border)">'
                    + '<td style="padding:6px 8px;color:var(--muted)">' + (i+1) + '</td>'
                    + '<td style="padding:6px 8px"><strong style="color:var(--ink)">' + vmoEsc(c.full_name || c.email) + '</strong><br><span style="color:var(--muted);font-size:10px">' + vmoEsc(c.email) + '</span></td>'
                    + '<td style="padding:6px 8px;text-align:right;color:var(--cyan);font-weight:600">' + formatCur(c.lifetime_value) + '</td>'
                    + '<td style="padding:6px 8px;text-align:right">' + c.purchase_count + '</td>'
                    + '<td style="padding:6px 8px;color:var(--muted)">' + (c.last_purchase || '—') + '</td>'
                    + '</tr>';
            });
            html += '</tbody></table>';
            el.innerHTML = html;
        } catch(e) {}
    };

    /* ── Products List ─── */
    window.vmoLoadProducts = async function() {
        try {
            var resp = await ajaxPost('vmo_pay_list_products', {});
            if (!resp || !resp.success) return;
            var products = resp.data.products || [];
            setText('vmo-product-count', products.length || '0');
            var el = document.getElementById('vmo-product-list');
            if (!el) return;
            if (!products.length) {
                el.innerHTML = '<div style="padding:12px;text-align:center;color:var(--muted)">No products yet. Create products via the AI Consultant.</div>';
                return;
            }
            var html = '';
            products.forEach(function(p) {
                var price = formatCur(p.price_cents / 100, p.currency);
                var statusColor = p.status === 'active' ? '#10b981' : '#6b7280';
                var types = {item:'🛒 Item',subscription:'🔄 Subscription',downloadable:'📥 Download',service:'🛠️ Service'};
                html += '<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border-bottom:1px solid var(--border);font-size:12px">'
                    + '<div><strong style="color:var(--ink)">' + vmoEsc(p.name) + '</strong><br><span style="color:var(--muted)">' + (types[p.product_type] || p.product_type) + '</span></div>'
                    + '<div style="text-align:right">'
                    + '<span style="color:var(--cyan);font-weight:600">' + price + '</span>'
                    + '<span style="display:inline-block;padding:2px 6px;background:' + statusColor + '22;color:' + statusColor + ';border-radius:10px;font-size:10px;margin-left:6px">' + p.status + '</span>';
                if (p.stock_tracking == 1) {
                    html += '<br><span style="color:var(--muted);font-size:10px">Stock: ' + (p.stock_qty || 0) + '</span>';
                }
                html += '</div></div>';
            });
            el.innerHTML = html;
        } catch(e) {}
    };

    /* ── Helper: format currency from value (dollars) ─── */
    function formatCur(val, cur) {
        try { return new Intl.NumberFormat(undefined, {style:'currency',currency:(cur||'usd').toUpperCase()}).format(val||0); }
        catch(_) { return '$' + Number(val||0).toFixed(2); }
    }

    /* ── Auto-load VMO Pay data when payments tab opens ─── */
    (function() {
        var origSwitch = window.switchTab;
        if (typeof origSwitch === 'function') {
            window.switchTab = function(tab) {
                origSwitch.apply(this, arguments);
                if (tab === 'payments') {
                    window.vmoLoadInvoices();
                    window.vmoLoadPayLinks();
                }
            };
        }
    })();

    window.vmoTopUpTokens = function() {
        if (typeof window.VMOTokenManager !== 'undefined' && typeof window.VMOTokenManager.showPurchaseModal === 'function') {
            window.VMOTokenManager.showPurchaseModal();
        } else if (typeof window.switchTab === 'function') {
            window.switchTab('payments');
        } else {
            alert('Token top-up: Please visit the Payments tab.');
        }
    };

    /* ═══════════════════════════════════════════ *
     *  5. JARVIS DAILY OPERATIONAL BRIEFING
     * ═══════════════════════════════════════════ */
    (function loadDailyBriefing() {
        vmoAjax('vmo_get_daily_briefing').done(function(r) {
            if (!r || !r.success || !r.data) return;
            var d = r.data;
            var briefingEl = document.getElementById('vmo-daily-briefing');
            if (!briefingEl) return;

            // Time-based greeting
            var hour = new Date().getHours();
            var timeGreet = hour < 12 ? 'Good morning' : (hour < 17 ? 'Good afternoon' : 'Good evening');
            setText('vmo-briefing-greeting', '🤖 ' + timeGreet + ', ' + (d.user_name || '') + '!');

            // Build briefing body
            var body = '';
            if (d.summary) body += '<p style="margin:0 0 8px;">' + vmoEsc(d.summary) + '</p>';
            if (d.urgent_items && d.urgent_items.length > 0) {
                body += '<div style="margin-top:6px;"><strong style="color:#f59e0b;">⚠️ Urgent:</strong> ';
                body += d.urgent_items.map(function(i){ return vmoEsc(i); }).join(' • ');
                body += '</div>';
            }
            if (d.todays_goals && d.todays_goals.length > 0) {
                body += '<div style="margin-top:6px;"><strong>Today\'s focus:</strong> ';
                body += d.todays_goals.map(function(g){ return vmoEsc(g); }).join(' → ');
                body += '</div>';
            }
            if (d.streak && d.streak > 1) {
                body += '<div style="margin-top:6px; color:#22c55e;">🔥 ' + d.streak + '-day streak! Keep it up.</div>';
            }

            var bodyEl = document.getElementById('vmo-briefing-body');
            if (bodyEl) bodyEl.innerHTML = body;
            briefingEl.style.display = 'block';
        });
    })();

    /* ───────── Utility helpers ───────── */
    function setText(id, val) {
        var el = document.getElementById(id);
        if (el) el.textContent = String(val);
    }
    function setList(id, items) {
        var el = document.getElementById(id);
        if (!el) return;
        if (!items || items.length === 0) {
            el.innerHTML = '<li style="color:var(--muted);">None at this time.</li>';
            return;
        }
        el.innerHTML = items.map(function(item) {
            return '<li style="padding:4px 0;border-bottom:1px solid rgba(255,255,255,.04);font-size:12px;">' + vmoEsc(typeof item === 'string' ? item : item.text || item.title || JSON.stringify(item)) + '</li>';
        }).join('');
    }
    function formatNum(n) {
        if (n === undefined || n === null) return '—';
        return Number(n).toLocaleString();
    }
    function vmoEsc(s) {
        if (!s) return '';
        var div = document.createElement('div');
        div.appendChild(document.createTextNode(String(s)));
        return div.innerHTML;
    }

    /* ═══════════════════════════════════════════ *
     *  6. EMAIL TEMPLATE LIBRARY
     * ═══════════════════════════════════════════ */
    window.vmoInsertEmailTemplate = function(templateType) {
        if (typeof window.vmoOpenComposeModal === 'function') {
            window.vmoOpenComposeModal();
        }
        vmoAjax('vmo_get_email_template', { template_type: templateType }).done(function(r) {
            if (!r || !r.success || !r.data) return;
            var d = r.data;
            var subjectEl = document.getElementById('vmo-compose-subject') || document.querySelector('[name="email_subject"]');
            var bodyEl = document.getElementById('vmo-compose-body') || document.querySelector('[name="email_body"]');
            if (subjectEl && d.subject) subjectEl.value = d.subject;
            if (bodyEl && d.body) bodyEl.value = d.body;
        });
    };

    /* ═══════════════════════════════════════════ *
     *  7. JERREME RECOMMENDATION ACCORDION
     * ═══════════════════════════════════════════ */
    var jerremeRecsLoaded = false;
    window.vmoToggleJerremeRecs = function() {
        var list = document.getElementById('vmo-jerreme-list');
        var chev = document.getElementById('vmo-jerreme-chevron');
        if (!list) return;
        var open = list.style.display !== 'none';
        list.style.display = open ? 'none' : 'block';
        if (chev) chev.style.transform = open ? '' : 'rotate(180deg)';
        if (!open && !jerremeRecsLoaded) {
            jerremeRecsLoaded = true;
            vmoLoadJerremeRecs();
        }
    };

    function vmoLoadJerremeRecs() {
        var list = document.getElementById('vmo-jerreme-list');
        var badge = document.getElementById('vmo-jerreme-badge');
        if (!list) return;
        list.innerHTML = '<div style="color:var(--muted);font-size:12px;padding:8px;">Analyzing your business data...</div>';
        vmoAjax('vmo_get_jerreme_recommendations', {}).done(function(r) {
            if (!r || !r.success || !r.data || !r.data.recommendations || r.data.recommendations.length === 0) {
                list.innerHTML = '<div style="color:var(--muted);font-size:12px;padding:8px;">No recommendations right now — great work!</div>';
                if (badge) badge.textContent = '0';
                return;
            }
            var recs = r.data.recommendations;
            if (badge) badge.textContent = recs.length;
            var priorityColors = { urgent: '#ef4444', high: '#f59e0b', medium: '#0fe1ff', low: '#9fb2c8' };
            var html = '';
            recs.forEach(function(rec) {
                var pColor = priorityColors[rec.priority] || '#9fb2c8';
                html += '<div style="background:rgba(124,92,255,.06);border:1px solid rgba(124,92,255,.15);border-radius:8px;padding:10px 12px;margin-bottom:8px;">';
                html += '<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">';
                html += '<span style="font-size:16px;">' + vmoEsc(rec.icon || '💡') + '</span>';
                html += '<strong style="color:#c4b5fd;font-size:12px;flex:1;">' + vmoEsc(rec.title) + '</strong>';
                html += '<span style="font-size:9px;text-transform:uppercase;color:' + pColor + ';font-weight:600;">' + vmoEsc(rec.priority) + '</span>';
                html += '</div>';
                html += '<p style="color:var(--muted);font-size:11px;line-height:1.4;margin:0 0 6px;">' + vmoEsc(rec.body) + '</p>';
                if (rec.action) {
                    html += '<button class="action-btn" style="font-size:10px;padding:3px 10px;" onclick="switchTab(\'' + vmoEsc(rec.action) + '\', event)">' + vmoEsc(rec.action_label || 'Go') + '</button>';
                }
                html += '</div>';
            });
            list.innerHTML = html;
        }).fail(function() {
            list.innerHTML = '<div style="color:#f87171;font-size:12px;padding:8px;">Failed to load recommendations.</div>';
            jerremeRecsLoaded = false;
        });
    }

    /* ═══════════════════════════════════════════ *
     *  8. AI KPI INTERPRETATION
     * ═══════════════════════════════════════════ */
    window.vmoLoadAIKpiInterpretation = function() {
        var interpEl = document.getElementById('vmo-strat-interpretation');
        if (!interpEl) return;
        interpEl.innerHTML = '<div style="background:rgba(15,225,255,.04);border:1px solid rgba(15,225,255,.12);border-radius:6px;padding:10px 12px;margin-top:6px;font-size:11px;color:var(--muted);line-height:1.5;">' +
            '<span style="animation:pulse 1.5s infinite;">🧠</span> Generating AI strategic assessment...</div>';
        vmoAjax('vmo_ai_kpi_interpretation', {}).done(function(r) {
            if (!r || !r.success || !r.data || !r.data.interpretation) {
                interpEl.innerHTML = '';
                return;
            }
            interpEl.innerHTML = '<div style="background:rgba(124,92,255,.06);border:1px solid rgba(124,92,255,.18);border-radius:6px;padding:12px 14px;margin-top:6px;font-size:11px;color:#c4b5fd;line-height:1.6;">' +
                '<strong>🧠 AI Strategic Assessment:</strong><br>' + vmoEsc(r.data.interpretation) + '</div>';
        }).fail(function() {
            interpEl.innerHTML = '';
        });
    };

    /* ═══════════════════════════════════════════ *
     *  9. JARVIS COMMAND ROUTER (client-side)
     * ═══════════════════════════════════════════ */
    var jarvisNavMap = {
        'overview':'overview', 'home':'overview', 'dashboard':'overview',
        'builder':'builder', 'editor':'builder', 'design':'builder',
        'email':'email', 'inbox':'email', 'mail':'email',
        'sms':'sms', 'text':'sms', 'messages':'sms',
        'phone':'phone', 'dialer':'phone', 'calls':'phone',
        'payments':'payments', 'pay':'payments', 'store':'payments', 'invoices':'payments',
        'crm':'crm', 'contacts':'crm', 'leads':'crm',
        'seo':'seo', 'search':'seo',
        'shipping':'shipping', 'shipments':'shipping', 'delivery':'shipping',
        'reports':'reports', 'analytics':'reports',
        'settings':'settings', 'config':'settings',
        'templates':'templates', 'themes':'templates',
        'media':'media', 'images':'media', 'files':'media',
        'plans':'plans', 'upgrade':'plans', 'billing':'plans'
    };

    window.vmoJarvisRoute = function(command) {
        if (!command) return null;
        var cmd = command.toLowerCase().trim();

        /* Direct nav match */
        for (var key in jarvisNavMap) {
            if (cmd.indexOf(key) !== -1) {
                return { tab: jarvisNavMap[key] };
            }
        }

        /* Regex patterns */
        var showMatch = cmd.match(/(?:show|open|go to|take me to|navigate to)\s+(?:my\s+)?(.+)/);
        if (showMatch) {
            var target = showMatch[1].trim();
            for (var k in jarvisNavMap) {
                if (target.indexOf(k) !== -1) {
                    return { tab: jarvisNavMap[k] };
                }
            }
        }

        /* Action patterns */
        if (/send\s+(?:an?\s+)?email/i.test(cmd)) return { action: 'vmoOpenComposeModal' };
        if (/send\s+(?:an?\s+)?sms|text\s+someone/i.test(cmd)) return { action: 'vmoOpenSMSComposer' };
        if (/make\s+(?:a\s+)?call|dial/i.test(cmd)) return { action: 'vmoOpenDialer' };
        if (/create\s+(?:an?\s+)?invoice/i.test(cmd)) return { action: 'vmoOpenInvoiceModal' };
        if (/add\s+(?:a\s+)?contact/i.test(cmd)) return { action: 'vmoOpenAddContactModal' };

        /* Fallback: ask server */
        return null;
    };

    window.vmoJarvisExecuteRoute = function(command) {
        var local = window.vmoJarvisRoute(command);
        if (local && local.tab) {
            if (typeof switchTab === 'function') switchTab(local.tab, null);
            return true;
        }
        if (local && local.action && typeof window[local.action] === 'function') {
            window[local.action]();
            return true;
        }
        /* Fallback: server-side routing */
        vmoAjax('vmo_jarvis_command', { command: command }).done(function(r) {
            if (!r || !r.success || !r.data) return;
            if (r.data.tab && typeof switchTab === 'function') {
                switchTab(r.data.tab, null);
            } else if (r.data.action && typeof window[r.data.action] === 'function') {
                window[r.data.action]();
            }
        });
        return false;
    };
})();
</script>

<script>
jQuery(document).ready(function($) {
    // Initialize Business Dashboard Logic
    if (typeof window.VMOBusinessDashboard !== 'undefined' && typeof window.VMOBusinessDashboard.init === 'function') {
        const userData = {
            id: <?php echo get_current_user_id(); ?>,
            name: '<?php echo esc_js($current_user->display_name); ?>',
            plan: '<?php echo esc_js($plan); ?>',
            balance: <?php echo esc_js($balance); ?>
        };
        
        // Pass business info if available via global or PHP
        const businessInfo = <?php 
            $consultation_profile = function_exists('vmo_get_consultation_profile') ? vmo_get_consultation_profile(get_current_user_id()) : [];
            echo !empty($consultation_profile) ? wp_json_encode($consultation_profile) : '{}'; 
        ?>;
        
        console.log('🚀 Booting VMO Dashboard...', userData);
        window.VMOBusinessDashboard.init(userData, businessInfo);
    }
});
</script>

<!-- ═══ VMO Feature Gate — Upgrade Modal & Client-Side Gating ═══ -->
<div id="vmo-upgrade-modal" style="display:none;position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,.7);backdrop-filter:blur(6px);align-items:center;justify-content:center" onclick="if(event.target===this)window.vmoCloseUpgradeModal()">
    <div style="background:linear-gradient(135deg,#0f1520,#1a1f2e);border:1px solid rgba(15,225,255,.25);border-radius:20px;max-width:440px;width:92%;padding:0;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.5)">
        <div style="padding:28px 28px 0;text-align:center">
            <div style="font-size:48px;margin-bottom:12px" id="vmo-upgrade-icon">🔒</div>
            <h3 style="color:#0fe1ff;margin:0 0 8px;font-size:20px" id="vmo-upgrade-title">Upgrade Required</h3>
            <p style="color:#9fb2c8;font-size:13px;line-height:1.6;margin:0 0 16px" id="vmo-upgrade-benefit">This feature requires a higher plan.</p>
        </div>
        <div style="background:rgba(124,92,255,.06);border-top:1px solid rgba(124,92,255,.15);padding:20px 28px;text-align:center">
            <div style="display:flex;align-items:center;justify-content:center;gap:8px;margin-bottom:14px">
                <span style="color:#9fb2c8;font-size:12px">Available on</span>
                <span style="display:inline-block;padding:4px 14px;background:linear-gradient(135deg,#7c5cff,#0fe1ff);color:#fff;border-radius:20px;font-weight:700;font-size:13px" id="vmo-upgrade-plan-badge">Pro</span>
                <span style="color:#9fb2c8;font-size:12px">plan</span>
            </div>
            <div style="margin-bottom:16px">
                <span style="font-size:28px;font-weight:800;color:#fff" id="vmo-upgrade-price">$199.99</span>
                <span style="color:#9fb2c8;font-size:13px">/month</span>
            </div>
            <div style="display:flex;gap:10px;justify-content:center">
                <a id="vmo-upgrade-btn" href="<?php echo esc_url(admin_url('admin.php?page=vmo-my-plan')); ?>" class="action-btn primary" style="padding:12px 28px;font-size:14px;font-weight:700;text-decoration:none;border-radius:10px">⚡ View Plans</a>
                <button onclick="window.vmoCloseUpgradeModal()" class="action-btn" style="padding:12px 20px;font-size:13px;border-radius:10px">Not Now</button>
            </div>
        </div>
    </div>
</div>

<script>
(function() {
    /* ── Feature Gate Map (server-rendered) ─── */
    window.__vmoFeatureGate = <?php echo wp_json_encode($vmo_feature_gate_map); ?>;
    window.__vmoUserPlan = '<?php echo esc_js($plan); ?>';

    /**
     * Check if the current user can access a feature.
     * @param {string} feature - Feature slug from the gate map.
     * @returns {boolean}
     */
    window.vmoCanAccess = function(feature) {
        var gate = window.__vmoFeatureGate;
        if (!gate || !gate[feature]) return true; // Unknown features are allowed
        return !!gate[feature].allowed;
    };

    /**
     * Gate-check a feature: if user can access, returns true.
     * If not, shows upgrade modal and returns false.
     * Usage: if (!vmoGateCheck('sms_marketing')) return;
     *
     * @param {string} feature - Feature slug.
     * @returns {boolean}
     */
    window.vmoGateCheck = function(feature) {
        if (window.vmoCanAccess(feature)) return true;
        window.vmoShowUpgradeModal(feature);
        return false;
    };

    /**
     * Show the upgrade modal for a specific feature.
     * @param {string} feature - Feature slug.
     */
    window.vmoShowUpgradeModal = function(feature) {
        var gate = window.__vmoFeatureGate;
        var info = gate ? gate[feature] : null;
        var modal = document.getElementById('vmo-upgrade-modal');
        if (!modal) return;

        var planName = info ? info.plan_name : 'Pro';
        var planPrice = info && info.plan_price ? '$' + Number(info.plan_price).toFixed(2) : '';
        var benefit = info ? info.benefit : 'Upgrade to unlock this feature.';

        var icons = {
            email_marketing: '📧', sms_marketing: '💬', power_dialer: '📞',
            invoices: '🧾', payment_links: '🔗', customer_ltv: '💎',
            video_generation: '🎬', seo_tools: '🔍', crm_ai_summary: '🤖',
            shipping_management: '📦', competitive_intel: '🏆', advanced_analytics: '📊',
            tts_hd: '🎙️', background_ops: '⚡', financial_insights: '💡',
        };
        var icon = icons[feature] || '🔒';

        setText('vmo-upgrade-icon', icon);
        setText('vmo-upgrade-title', planName + ' Feature');
        setText('vmo-upgrade-benefit', benefit);
        setText('vmo-upgrade-plan-badge', planName);
        if (planPrice) {
            setText('vmo-upgrade-price', planPrice);
        }

        modal.style.display = 'flex';
    };

    window.vmoCloseUpgradeModal = function() {
        var modal = document.getElementById('vmo-upgrade-modal');
        if (modal) modal.style.display = 'none';
    };

    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') window.vmoCloseUpgradeModal();
    });

    /* ── Plan badge on dashboard header ─── */
    var planBadge = document.getElementById('vmo-plan-badge');
    if (planBadge) {
        var p = window.__vmoUserPlan || 'free';
        var colors = {free:'#6b7280',tester:'#f59e0b',starter:'#3b82f6',pro:'#8b5cf6',elite:'#10b981',enterprise:'#ef4444'};
        planBadge.style.background = (colors[p] || '#6b7280') + '22';
        planBadge.style.color = colors[p] || '#6b7280';
        planBadge.textContent = p.charAt(0).toUpperCase() + p.slice(1);
    }
})();
</script>
</body>
</html>
