<?php
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- input sanitization handled by Instinctor sanitization layer on save
// phpcs:disable WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended -- Instinctor uses its own token-based authentication via platform.instinctor.com; WP nonces are not applicable to this request lifecycle
if ( ! defined( 'ABSPATH' ) ) { exit; }
// Defensive: free-tier helpers (instinctor_has_pro etc.) are normally loaded by
// the bootstrap, but a stale standalone app.php may not load them yet. Load here
// so this dashboard never fatals on an undefined helper. Safe + idempotent.
if ( ! function_exists('instinctor_has_pro') && file_exists(__DIR__ . '/../../includes/free-tier.php') ) {
    require_once __DIR__ . '/../../includes/free-tier.php';
}
// Self-contained inline-SVG allowlist for wp_kses. impulse_svg_allowed() is not
// guaranteed loaded in this admin view, so the allowlist is defined here. Covers
// the curated Lucide / getElementIcon() icon markup this view echoes.
if ( ! function_exists('impulse_admin_view_svg_allowed') ) {
    function impulse_admin_view_svg_allowed() {
        $attrs = [
            'viewbox' => true, 'd' => true, 'fill' => true, 'stroke' => true,
            'stroke-width' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true,
            'cx' => true, 'cy' => true, 'r' => true, 'rx' => true, 'ry' => true,
            'x' => true, 'y' => true, 'x1' => true, 'y1' => true, 'x2' => true, 'y2' => true,
            'width' => true, 'height' => true, 'points' => true, 'transform' => true,
            'opacity' => true, 'class' => true, 'style' => true, 'gradientunits' => true,
            'offset' => true, 'stop-color' => true, 'stop-opacity' => true,
            'fill-rule' => true, 'vector-effect' => true,
        ];
        return [
            'svg' => $attrs, 'path' => $attrs, 'circle' => $attrs, 'ellipse' => $attrs,
            'rect' => $attrs, 'line' => $attrs, 'polyline' => $attrs, 'polygon' => $attrs,
            'g' => $attrs, 'defs' => $attrs, 'lineargradient' => $attrs,
            'radialgradient' => $attrs, 'stop' => $attrs, 'use' => $attrs,
        ];
    }
}
// ── Access gate ───────────────────────────────────────────────────────────────
// Defence-in-depth: enforces auth regardless of how this file is included.
// On WordPress: add_menu_page already requires 'instinctor_access' before WP
// invokes this callback — this is a belt-and-suspenders check.
// On standalone: AdminRouter performs the primary auth guard; this catches
// any misconfigured direct-include path.
if ( ! defined('INSTINCTOR_PLUGIN_DIR')
    || ( ! \Instinctor\Core\Auth::can('instinctor_access')
         && ! \Instinctor\Core\Auth::can('manage_options') )
) {
    http_response_code(403);
    exit;
}
/**
 * Impulse - Visual Page Builder
 * 
 * @package Instinctor
 * @subpackage Admin/Views
 * @since 2.3.0
 * @version 2.9.0
 * 
 * ARCHITECTURE DOCUMENTATION:
 * ==========================
 * 
 * Impulse is a visual page builder that uses a three-panel layout:
 * - Left Panel: Element picker (draggable elements and section templates)
 * - Center Panel: Live preview iframe showing the page
 * - Right Panel: Settings panel for selected element or page settings
 * 
 * DATA STORAGE (v2.3+):
 * - Pages are regular WordPress 'page' post type with '_impulse_enabled' meta = '1'
 * - Elements stored in post meta '_impulse_elements' as array of objects
 * - Page settings stored in post meta '_impulse_settings'
 * - Impulse pages appear in WordPress Pages list and Impulse dashboard
 * 
 * ELEMENT DATA STRUCTURE:
 * {
 *   id: int,           // Unique element ID within page
 *   parent_id: int|null, // Parent container ID or null for root
 *   section_type: string, // Element type (heading, text, section, etc.)
 *   settings: object,   // Element-specific settings
 *   sort_order: int     // Display order within parent
 * }
 * 
 * KEY COMPONENTS:
 * 
 * 1. Page List View (action=list):
 *    - Grid of pages with iframe thumbnail previews
 *    - One-click page creation with auto-generated date/time title
 *    - Click title to edit inline (contenteditable)
 *    - Delete moves to WordPress trash (recoverable)
 * 
 * 2. Page Editor View (action=edit):
 *    - Three-panel layout with topbar
 *    - Live preview via iframe (impulse-preview.php?impulse_preview={id})
 *    - Element drag-drop OR click-to-add from left panel
 *    - Settings panel auto-saves on change
 * 
 * 3. Navigator Panel (hamburger icon):
 *    - Hierarchical tree of page elements
 *    - Updates after each element change
 *    - Click to select, buttons for duplicate/delete
 * 
 * 4. Structure Tab (in left panel):
 *    - Alternative view of element hierarchy
 *    - Built from iframe DOM, not API
 * 
 * REST API ENDPOINTS (in RestController.php):
 * - GET/POST /pages - List/create pages
 * - GET/PUT/DELETE /pages/{id} - Single page CRUD
 * - GET /pages/{id}/elements - Get page elements tree
 * - POST /pages/{id}/elements - Create element
 * - POST /pages/{id}/section-template - Create section from template
 * - GET/PUT/DELETE /elements/{id} - Element CRUD
 * - POST /elements/{id}/duplicate - Duplicate element with children
 * - POST /elements/{id}/reorder - Reorder (move before/after sibling)
 * - POST /elements/{id}/move-into - Move into container
 * 
 * IFRAME COMMUNICATION (via postMessage):
 * 
 * From iframe to parent:
 * - impulse-select: {id, elementType} - Element clicked
 * - impulse-deselect: {} - Empty area clicked
 * - impulse-drop: {element, parentId, position} - External drop completed
 * - impulse-delete: {id} - Delete button clicked
 * - impulse-duplicate: {id} - Duplicate button clicked
 * - impulse-reorder: {sourceId, targetId, position} - Internal drag-drop
 * - impulse-move-into: {sourceId, targetId} - Moved into container
 * - impulse-content-changed: {id, field, value} - Inline edit
 * - impulse-drag-position: {x, y} - Mouse position during external drag
 * 
 * From parent to iframe:
 * - impulse-drag-start: {element, template} - External drag began
 * - impulse-drag-end: {} - External drag ended
 * - impulse-deselect: {} - Clear selection
 * - impulse-live-preview: {id, elementType, settings} - Real-time setting update
 * 
 * CRITICAL BEHAVIORS:
 * 
 * 1. Settings Auto-Save:
 *    - Settings save on blur for text inputs
 *    - Settings save on change for selects, sliders, colors
 *    - IMPORTANT: openSettings() saves current element before switching
 *    - This prevents style loss when clicking different elements
 * 
 * 2. Click-to-Add Elements:
 *    - If a container is selected, new element added inside it
 *    - Otherwise, new element added to page root
 *    - No drag required for simple element addition
 * 
 * 3. Drag-Drop External Elements:
 *    - Parent sends impulse-drag-start with element type
 *    - Iframe's drop event handler detects container at coordinates
 *    - Iframe sends impulse-drop back with parentId
 *    - Parent calls addElement() API
 * 
 * 4. Text Transform:
 *    - CSS text-transform doesn't work on already-uppercase text
 *    - Transform applied via PHP (render) and JS (live preview)
 *    - Settings store original text, display shows transformed
 * 
 * 5. Undo/Redo:
 *    - History stored in memory (max 50 items)
 *    - Actions: add, delete, update tracked
 *    - Ctrl+Z/Y keyboard shortcuts
 * 
 * ELEMENT TYPES (35 total):
 * - Layout (2): section, grid
 * - Basic (8): heading, text, button, image, video, spacer, divider, html
 * - Products (10): products, product_images, product_title,
 *   product_price, product_description, product_meta, add_to_cart,
 *   quantity_selector, categories
 * - Cart/Checkout (9): cart, checkout, order_received, mini_cart,
 *   cart_totals, shipping_calculator, coupon_form
 * 
 * CSS/STYLING NOTES:
 * - Greyscale palette ONLY: #1d2327 (primary), #666 (secondary), #888888 (hints), 
 *   #999 (muted), #e0e0e0 (borders), #f5f5f5 (backgrounds)
 * - NO RED COLORS (#c00, #f00, #dc3545, etc.) - use #666 for delete/error states
 * - Green accent allowed for success/primary actions only
 * - No emojis in UI - text labels only
 * - Minimal, premium look - no clutter
 * - Equal-length text lines where possible
 * - Never orphan short words at line end
 * 
 * SETTINGS PANEL STYLING (Dark Theme):
 * ==================================
 * Global label color rule at line ~2708:
 *   .impulse-editor .impulse-setting-label, ... { color: #888 !important; }
 * 
 * This SINGLE RULE controls ALL label colors in settings panels.
 * To change label color globally, edit this one rule.
 * 
 * Colors Reference:
 * - Panel background: #1a1d21
 * - Input/Select bg: #2a2e33, border: #3a3f44, text: #e0e0e0
 * - Button inactive: bg #2a2e33, border #3a3f44, text #888
 * - Button hover: bg #3a3f44, border #555, text #fff
 * - Button active: bg #3a3f44, text #fff
 * - Labels: #888 (controlled by global rule above)
 * - Section headers: #e0e0e0 (uppercase)
 * - Dividers: #3a3f44
 * 
 * Spacing:
 * - Section label margin-top: 10-12px
 * - Setting row margin-bottom: 8px
 * - Button group gap: 4px
 * - Color swatch size: 26x26px
 * - Slider track: 4px height, thumb 12px
 * 
 * TOOLTIPS/HINTS (use .impulse-setting-hint class):
 * - font-size: 11px
 * - color: #888888 (matches Instinctor Settings .instinctor-hint)
 * - margin: 4px 0 8px
 * - Use for explanatory text below settings
 * - Reference: Instinctor > Settings page for styling consistency
 * 
 * BUTTON GROUPS:
 * - Single row: .impulse-btn-group
 * - Two rows: .impulse-btn-group-rows containing multiple .impulse-btn-group
 * - Max 3-4 buttons per row for readability
 * 
 * FILES:
 * - impulse.php (this file): Main editor UI, ~5300 lines
 * - impulse-preview.php: Iframe preview, ~2700 lines
 * - RestController.php: API endpoints, ~2800 lines
 * - TemplateService.php: Section templates, ~1000 lines
 * - impulse-page.php: Frontend template, ~550 lines
 * 
 * POST-INSTALL REQUIREMENTS:
 * - Flush rewrite rules: Settings > Permalinks > Save Changes
 * - Pages use clean slugs: /page-slug/ (standalone) or WP permalink structure
 */

if (!defined('ABSPATH')) {
    exit;
}

// wp_enqueue_media() is WP-only (media picker); on standalone the Instinctor image library handles uploads
if (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') {
    wp_enqueue_media();
}

// Handle actions
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- navigation
$action = isset($_GET['action']) ? sanitize_text_field(wp_unslash($_GET['action'])) : 'list';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- navigation
$view = isset($_GET['view']) ? sanitize_text_field(wp_unslash($_GET['view'])) : 'pages';
// Page identifier: ?p=<slug> or ?p=<id>. Slug is the canonical form (e.g.
// "instinctor") and what shows in the address bar; ID is accepted for
// back-compat with old bookmarks (e.g. "?p=124"). When the URL comes in
// as numeric AND the page has a real (non-numeric) slug, 302-redirect to
// the slug URL so users always see the human-readable form. Every other
// query param (workspace, action, t-cache-bust, etc.) is preserved through
// the redirect. Sergei 2026-06-05.
$_rawP   = isset($_GET['p']) ? trim((string) wp_unslash($_GET['p'])) : '';
$_rawPid = isset($_GET['page_id']) ? trim((string) wp_unslash($_GET['page_id'])) : '';
$page_id = 0;
$_canonical_slug = '';
if ($_rawP !== '') {
    if (ctype_digit($_rawP)) {
        $page_id = intval($_rawP);
        // URL came in numeric; if the page has a real (non-numeric) slug,
        // queue a client-side history.replaceState rewrite below. No server
        // hop, no POST->GET coercion (a 302 would force any in-flight POST to
        // the admin URL into a GET). Sergei 2026-06-05 (replaced 302 path).
        if (class_exists('\\Instinctor\\Services\\PageService')) {
            $_resolved = \Instinctor\Services\PageService::getById($page_id);
            if ($_resolved && !empty($_resolved['slug'])
                && !ctype_digit((string) $_resolved['slug'])
                && (string) $_resolved['slug'] !== $_rawP) {
                $_canonical_slug = (string) $_resolved['slug'];
            }
        }
    } else {
        // Non-numeric ?p=<slug> -> resolve to id.
        if (class_exists('\\Instinctor\\Services\\PageService')) {
            $_resolved = \Instinctor\Services\PageService::getByPublicSlug($_rawP);
            if ($_resolved) $page_id = intval($_resolved['id'] ?? 0);
        }
    }
} elseif ($_rawPid !== '') {
    $page_id = intval($_rawPid);
}
// Canonicalisation: rewrite the address bar to ?p=<slug> via
// history.replaceState when the URL came in numeric and a real slug exists.
// The slug is carried on .impulse-editor[data-canonical-slug] and applied by
// InstinctorAdmin.initCanonicalSlug() in assets/js/admin.js (kept out of an
// inline <script> for WordPress.org compliance). Sergei 2026-06-05.
// Treat page_id presence as implicit edit action (URL scheme uses ?p=X)
if ($page_id && $action === 'list') {
    $action = 'edit';
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- navigation
$workspace = isset($_GET['workspace']) ? sanitize_text_field(wp_unslash($_GET['workspace'])) : 'operations';

// Valid workspaces
$valid_workspaces = ['impulse', 'chat', 'store', 'seo', 'settings'];

// Settings workspace shares the Store DOM (admin-store.js aliases it
// with switchStoreSection('settings') on workspace-change). On a hard
// refresh with ?workspace=settings, however, switchWorkspace() never
// runs and every workspace div renders display:none — that's the
// "white screen on refresh from Settings" the user reported. Normalise
// 'settings' → 'store' for the visibility checks below so the Store
// DOM is server-rendered visible; the JS still scopes to the Settings
// section once it boots.
$workspace_visible = $workspace === 'settings' ? 'store' : $workspace;

// Role-based workspace access
$role_manager = \Instinctor\Core\RoleManager::instance();
$accessible_workspaces = $role_manager->getAccessibleWorkspaces();
$can_manage_chat_settings = $role_manager->canManageChatSettings();
$is_admin = \Instinctor\Core\Auth::can('manage_options');

// Load per-user workspace preferences
$current_user_id = \Instinctor\Core\Auth::userId();
if (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') {
    // WP: stored in wp_usermeta
    $workspace_order        = get_user_meta($current_user_id, 'instinctor_workspace_order', true);
    $store_section_default  = get_user_meta($current_user_id, 'instinctor_store_section_default', true) ?: '';
    $seo_tab_default        = get_user_meta($current_user_id, 'instinctor_seo_tab_default', true) ?: '';
    $device_default         = get_user_meta($current_user_id, 'instinctor_device_default', true) ?: '';
} else {
    // Standalone: stored per-user in config table
    $workspace_order        = \Instinctor\Core\Config::get('instinctor_workspace_order_' . $current_user_id, null);
    $store_section_default  = \Instinctor\Core\Config::get('instinctor_store_section_default_' . $current_user_id, '') ?: '';
    $seo_tab_default        = \Instinctor\Core\Config::get('instinctor_seo_tab_default_' . $current_user_id, '') ?: '';
    $device_default         = \Instinctor\Core\Config::get('instinctor_device_default_' . $current_user_id, '') ?: '';
}
if (!is_array($workspace_order) || count($workspace_order) < 3) {
    $workspace_order = ['chat', 'store', 'impulse', 'seo', 'settings'];
}
// Filter workspace order by accessible workspaces
$workspace_order = array_values(array_intersect($workspace_order, $accessible_workspaces));
// Add any accessible workspaces not in saved order
foreach ($accessible_workspaces as $aws) {
    if (!in_array($aws, $workspace_order)) {
        $workspace_order[] = $aws;
    }
}

if (!in_array($workspace, $valid_workspaces) || !in_array($workspace, $accessible_workspaces)) {
    // If editing a page and has impulse access, default to impulse workspace
    if ($action === 'edit' && $page_id && in_array('impulse', $accessible_workspaces)) {
        $workspace = 'impulse';
    } else {
        // Default to first accessible workspace
        $workspace = !empty($workspace_order) ? $workspace_order[0] : 'chat';
    }
}

// Get all Impulse-enabled pages via PageService (works on WP and standalone)
$_all_pages      = \Instinctor\Services\PageService::getAll();   // non-trash only
$_trashed_rows   = \Instinctor\Core\DB::get_results(
    "SELECT id, name, slug, role, created_at, updated_at FROM " .
    \Instinctor\Core\DB::prefix() . "instinctor_pages WHERE status = 'trash' ORDER BY updated_at DESC",
    'ARRAY_A'
) ?: [];

// Build page objects
$pages           = [];
$published_count = 0;
$draft_count     = 0;
$posts_count     = 0;
// How many missing grid previews may be generated during this request. Keeps a
// large site responsive; anything left over is generated on later page loads.
$_thumb_budget   = 12;
foreach ($_all_pages as $_row) {
    if (in_array($_row['type'] ?? 'page', ['global_header', 'global_footer'], true)) {
        continue;
    }
    $page             = new \stdClass();
    $page->id         = (int) $_row['id'];
    $page->name       = $_row['name'];
    $page->slug       = $_row['slug'];
    $page->permalink  = \Instinctor\Services\PageService::getPageUrl($page->id);
    $page->status     = $_row['status'];
    $page->type       = $_row['type'] ?? 'page';
    $page->created_at = $_row['created_at'];
    $page->updated_at = $_row['updated_at'];
    // Whose page is this? A tenant's published site and one of ours look identical
    // in the grid otherwise, and after a recording run a dozen of theirs sit among
    // the templates and the SEO pages (Sergei 2026-07-28).
    $page->owner_id   = $_row['owner_id'] ?? null;
    $page->role       = $_row['role'] ?? '';
    // Manual drag order. The grid re-groups cards into folders client-side, so
    // it has to know each card's saved position or every drag is undone by the
    // next regroup (Sergei 2026-07-30).
    $page->sort_order = (int) ($_row['sort_order'] ?? 0);
    $page->thumbnail  = $_row['thumbnail'] ?? '';
    $_ps              = is_array($_row['settings']) ? $_row['settings'] : (json_decode($_row['settings'] ?? '{}', true) ?: []);
    $page->screen_infinite_loop = !empty($_ps['screen_infinite_loop']);

    // Only trust file-based thumbnails (URL), not old base64 data
    if ($page->thumbnail && strpos($page->thumbnail, 'data:') === 0) {
        $page->thumbnail = '';
    }
    // Normalize legacy http:// thumbnail URLs to https:// so they don't trigger
    // Mixed Content warnings on HTTPS admin pages (Chrome auto-upgrades anyway
    // but the console gets spammed with one warning per thumbnail).
    if ($page->thumbnail && is_ssl() && strpos($page->thumbnail, 'http://') === 0) {
        $page->thumbnail = 'https://' . substr($page->thumbnail, 7);
    }
    // Grid preview. The card only ever shows a real file at
    // impulse-previews/page-<id>.jpg; the `thumbnail` column is not trusted on
    // its own (for posts it holds the author's cover, not a grid preview).
    // That file is normally written by the browser html2canvas capture on
    // editor close, but that capture fails silently on many pages, leaving a
    // permanent placeholder. So when it is missing, generate it server-side.
    // Budgeted per request so a site with hundreds of pages doesn't stall on
    // first load — the remainder fill in over the next few visits.
    $preview_file = \Instinctor\Core\Storage::basedir('impulse-previews') . '/page-' . $page->id . '.jpg';
    $_has_preview = class_exists('\\Instinctor\\Core\\PagePreview')
        ? \Instinctor\Core\PagePreview::exists($page->id)          // also rejects blank captures
        : (file_exists($preview_file) && filesize($preview_file) >= 500);
    if ($_has_preview) {
        $page->thumbnail = \Instinctor\Core\Storage::url('impulse-previews/page-' . $page->id . '.jpg');
    } else {
        if (file_exists($preview_file)) wp_delete_file($preview_file);
        $page->thumbnail = '';
        if ($_thumb_budget > 0 && class_exists('\\Instinctor\\Core\\PagePreview')) {
            $_thumb_budget--;
            if (\Instinctor\Core\PagePreview::ensure($page->id, (string) $page->name)) {
                $page->thumbnail = \Instinctor\Core\Storage::url('impulse-previews/page-' . $page->id . '.jpg');
            }
        }
    }

    $pages[] = $page;
    // Posts are counted separately so the page-status tabs (All/Published/Draft)
    // stay pages-only; the Posts tab shows blog posts.
    if ($page->type === 'post') {
        $posts_count++;
    } elseif ($page->status === 'published') {
        $published_count++;
    } else {
        $draft_count++;
    }
}

// Trashed pages
$trashed_pages = [];
foreach ($_trashed_rows as $_row) {
    $page             = new \stdClass();
    $page->id         = (int) $_row['id'];
    $page->name       = $_row['name'];
    $page->slug       = $_row['slug'];
    $page->status     = 'trash';
    $page->created_at = $_row['created_at'];
    $page->updated_at = $_row['updated_at'];
    $page->thumbnail  = '';
    $trashed_pages[]  = $page;
}
$trash_count = count($trashed_pages);

// Front page ID — used to mark which page card shows the home icon
$_front_page_id = (int) \Instinctor\Core\Config::get('instinctor_front_page_id', 0);
if (!$_front_page_id && function_exists('get_option')) {
    $show_on_front = get_option('show_on_front');
    if ($show_on_front === 'page') {
        $_front_page_id = (int) get_option('page_on_front', 0);
    }
}
// Also detect by permalink matching home URL (catches cases where WP front page
// and Instinctor page IDs diverge or instinctor_front_page_id was never saved)
$_home_url = rtrim(function_exists('home_url') ? home_url('/') : '', '/') . '/';

// Get categories for product queries (from Instinctor table)
$categories_table = \Instinctor\Core\DB::prefix() . 'instinctor_categories';
$categories = \Instinctor\Core\DB::get_results(
    "SELECT id as term_id, name, slug FROM {$categories_table} WHERE status = 'active' OR status IS NULL ORDER BY name ASC"
);
if (!is_array($categories)) $categories = [];

// Get card design templates for Product Grid element
$card_templates_raw = \Instinctor\Core\Config::get('instinctor_card_templates', []);
$card_templates = [];
foreach ((array) $card_templates_raw as $slug => $template) {
    $card_templates[] = ['slug' => $slug, 'name' => $template['name']];
}

// API nonce (used as X-WP-Nonce header on WP; standalone REST uses session auth)
$api_nonce = \Instinctor\Core\Session::token('wp_rest');

// Logo
$logo_url = plugins_url('assets/images/logo.svg', dirname(dirname(__FILE__)));

// Element definitions
$elements = [
    'layout' => [
        'label' => __('Layout', 'instinctor'),
        'items' => [
            'grid'       => ['label' => 'Grid',       'icon' => 'grid'],
            'rows'  => ['label' => 'Rows',       'icon' => 'table-cells-merge'],
            'columns'   => ['label' => 'Columns',    'icon' => 'table-cells-merge-90']]
    ],
    'blocks' => [
        'label' => __('Blocks', 'instinctor'),
        'items' => [
            'title' => ['label' => '3D Title', 'icon' => 'heading'],
            // Animator hidden from picker — merged into Title (the heading element).
            // The renderer case is still alive so existing animator elements keep
            // working, but new content uses the Title block.
            'text' => ['label' => 'Text', 'icon' => 'align-left'],
            'kinetic' => ['label' => 'Kinetic', 'icon' => 'zap'],
            'image' => ['label' => 'Image', 'icon' => 'image'],
            // Lightbox card removed 2.1.420 — merged into Image as a
            // `lightbox_enabled` toggle in the Image settings panel.
            'video' => ['label' => 'Video', 'icon' => 'play-circle'],
            'button' => ['label' => 'Button', 'icon' => 'pointer'],
            'divider' => ['label' => 'Divider', 'icon' => 'git-commit'],
            'icon_card' => ['label' => 'Icon Card', 'icon' => 'circle-star'],
            // Internal type stays `table` for backward compat with existing
            // pages; user-facing name is "Table" since icons are now optional
            // and the block handles up to 6 columns with zebra + alignment.
            'table' => ['label' => 'Table', 'icon' => 'table'],
            'carousel' => ['label' => 'Carousel', 'icon' => 'gallery-horizontal'],
            'flip_box' => ['label' => 'Flip Box', 'icon' => 'flip-box'],
            'map' => ['label' => 'Map', 'icon' => 'map'],
            'social' => ['label' => 'Social', 'icon' => 'instagram'],
            'chart' => ['label' => 'Chart', 'icon' => 'chart-pie'],
            'reviews' => ['label' => 'Reviews', 'icon' => 'star'],
            'network' => ['label' => 'Network', 'icon' => 'waypoints'],
            'marquee' => ['label' => 'Marquee', 'icon' => 'move-horizontal'],
            'countdown' => ['label' => 'Countdown', 'icon' => 'timer'],
            'unfold' => ['label' => 'Unfold', 'icon' => 'gallery-vertical'],
            // NB: no draggable "Posts" tile. The blog index is auto-managed — the
            // first published post auto-creates the /blog page with a Posts block
            // (AdminController::ensureBlogIndexPage). The `posts` element type, its
            // renderer, and its settings panel all stay registered so that page
            // (and any hand-placed instance) renders and is editable.
            // Popup + Off-Canvas merged into one "Overlay" block — position setting covers centre
            // (classic popup) and edge-docked (drawer / off-canvas) modes.
            'modal' => ['label' => 'Modal', 'icon' => 'picture-in-picture-2'],
            // 'gig_grid' block removed 2.1.413 — marketplace teardown.
            'code' => ['label' => 'Code', 'icon' => 'code'],
            // Plans and Price List DISPLAY prices, they do not take money: every
            // other Store Tool is transaction machinery (cart, checkout, receipt,
            // account). Moved here 2026-08-07 so the split reads without
            // explanation, and so neither category is left with a ragged row.
            'plans' => ['label' => 'Plans', 'icon' => 'layout-list-90', 'ecomOnly' => true],
            'price_list' => ['label' => 'Price List', 'icon' => 'receipt'],
            
        ]
    ],
    'store' => [
        'label' => __('Store Tools', 'instinctor'),
        'items' => [
            'products' => ['label' => 'Products', 'icon' => 'grip', 'ecomOnly' => true],
            'bundle' => ['label' => 'Bundle', 'icon' => 'package', 'ecomOnly' => true],
            'cart' => ['label' => 'Cart', 'icon' => 'shopping-cart', 'ecomOnly' => true],
            'receipt' => ['label' => 'Receipt', 'icon' => 'circle-check-big'],
            'account' => ['label' => 'Account', 'icon' => 'circle-user'],
            // Booking and Quote are types of the Form block now, not their own
            // chips. Their store-type gates moved to the Form panel's type
            // selector, so a salon still never sees Quote. Sergei 2026-08-03.
            
            'checkout' => ['label' => 'Checkout', 'icon' => 'banknote-arrow-up', 'ecomOnly' => true],
            'shipping' => ['label' => 'Shipping', 'icon' => 'truck', 'shippingOnly' => true]]
    ],
    'forms' => [
        'label' => __('Forms', 'instinctor'),
        'items' => [
            // One chip for every lead-capture form. The type (Contact / Booking /
            // Quote) is chosen in the panel instead of by picking a different
            // block, so the palette stops carrying three chips that all mean
            // "collect an enquiry". Login and Register stay separate: they are
            // auth flows, not lead capture. Sergei 2026-08-03.
            'form' => ['label' => 'Form', 'icon' => 'square-pen'],
            'login' => ['label' => 'Login', 'icon' => 'log-in'],
            'register' => ['label' => 'Register', 'icon' => 'user-plus']]
    ],
    'navigation' => [
        'label' => __('Site', 'instinctor'),
        'items' => [
            'header' => ['label' => 'Header', 'icon' => 'app-window', 'nav' => true],
            'footer' => ['label' => 'Footer', 'icon' => 'app-window-flip', 'nav' => true]]
    ]];

// If editing a page
$current_page = null;
$page_elements = [];
$page_type = ''; // 'global_header', 'global_footer', or empty for regular pages
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only flag
$convert_page = isset($_GET['convert']) && ($_GET['convert'] ?? '') === '1';

if ($action === 'edit' && $page_id) {

    // Try the new canonical store first (instinctor_pages — WP + standalone)
    $_page_row = \Instinctor\Services\PageService::getById($page_id);

    if ($_page_row) {
        // ── Data lives in instinctor_pages ───────────────────────────────────
        if ($convert_page && empty($_page_row['elements'])) {
            // Converting: initialise empty elements + default settings
            \Instinctor\Services\PageService::saveElements($page_id, []);
            \Instinctor\Services\PageService::saveSettings($page_id, \Instinctor\Services\PageService::defaultSettings());
            $_page_row = \Instinctor\Services\PageService::getById($page_id);
        }

        $current_page              = new \stdClass();
        $current_page->id          = $_page_row['id'];
        $current_page->name        = $_page_row['name'];
        $current_page->slug        = $_page_row['slug'];
        $current_page->permalink   = \Instinctor\Services\PageService::getPageUrl($page_id);
        $current_page->status      = $_page_row['status'];
        $current_page->settings    = is_array($_page_row['settings']) ? $_page_row['settings'] : [];
        // Designer-owned pages live under /designer/, marketing under /.
        // Expose the flag so the slug-modal prefix can reflect this.
        $current_page->owner_id = (int) ($_page_row['owner_id'] ?? 0);
        $page_type               = $_page_row['type'] === 'global_header' || $_page_row['type'] === 'global_footer'
                                     ? $_page_row['type'] : '';
        // Elements are loaded by the editor via REST (/pages/{id}/elements) — no PHP pass-through needed.

    } elseif (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') {
        // ── Fallback: page not yet in instinctor_pages — read from wp_postmeta ──
        // This covers pages on WP installs that have not been migrated yet.
        $post = get_post($page_id);

        if ($post && $post->post_type === 'page') {
            if ($convert_page && !get_post_meta($page_id, '_impulse_enabled', true)) {
                update_post_meta($page_id, '_impulse_enabled', '1');
                update_post_meta($page_id, '_impulse_elements', []);
                update_post_meta($page_id, '_impulse_settings', \Instinctor\Services\PageService::defaultSettings());

                // Eagerly migrate this page into instinctor_pages so subsequent
                // loads use the new store.
                \Instinctor\Services\PageService::create([
                    'name'     => $post->post_title,
                    'slug'     => $post->post_name,
                    'status'   => $post->post_status === 'publish' ? 'published' : 'draft',
                    'type'     => get_post_meta($page_id, '_impulse_type', true) ?: 'page',
                    'settings' => \Instinctor\Services\PageService::defaultSettings(),
                    'elements' => []]);
            }

            $current_page            = new \stdClass();
            $current_page->id        = $post->ID;
            $current_page->name      = $post->post_title;
            $current_page->slug      = $post->post_name;
            $current_page->permalink = get_permalink($post->ID);
            $current_page->status    = $post->post_status === 'publish' ? 'published' : 'draft';
            $current_page->settings  = get_post_meta($page_id, '_impulse_settings', true);
            if (!is_array($current_page->settings)) {
                $current_page->settings = [];
            }
            $page_type = get_post_meta($page_id, '_impulse_type', true) ?: '';
        }
    }
}

// Filter elements for global header/footer
if ($page_type === 'global_header' || $page_type === 'global_footer') {
    $allowed_categories = ['layout', 'basic'];
    $filtered_elements = [];
    foreach ($allowed_categories as $cat) {
        if (isset($elements[$cat])) {
            $filtered_elements[$cat] = $elements[$cat];
        }
    }
    // Add cart_icon from cart category
    $filtered_elements['cart'] = [
        'label' => __('Cart', 'instinctor'),
        'items' => [
            'cart' => ['label' => 'Cart', 'icon' => 'shopping-cart']]
    ];
    
    // Add contextual theme elements
    if ($page_type === 'global_header') {
        $filtered_elements['theme'] = [
            'label' => __('Header', 'instinctor'),
            'items' => [
                'site_logo' => ['label' => 'Site Logo', 'icon' => 'image'],
                'site_title' => ['label' => 'Site Title', 'icon' => 'type'],
                'social' => ['label' => 'Social Icons', 'icon' => 'share-2']]
        ];
    } else {
        $filtered_elements['theme'] = [
            'label' => __('Footer', 'instinctor'),
            'items' => [
                'social' => ['label' => 'Social Icons', 'icon' => 'share-2'],
                'copyright' => ['label' => 'Copyright', 'icon' => 'at-sign']]
        ];
    }
    
    $elements = $filtered_elements;
}

// Quick start templates
$quick_templates = [
    'page' => [
        'homepage' => ['name' => 'Homepage', 'preview' => ''],
        'landing' => ['name' => 'Landing Page', 'preview' => ''],
        'about' => ['name' => 'About Us', 'preview' => ''],
        'contact' => ['name' => 'Contact', 'preview' => ''],
        'product_showcase' => ['name' => 'Product Showcase', 'preview' => '']],
    'section' => [
        'hero_centered' => ['name' => 'Hero Centered', 'preview' => ''],
        'hero_split' => ['name' => 'Hero Split', 'preview' => ''],
        'features_3col' => ['name' => 'Features 3 Column', 'preview' => ''],
        'products_grid' => ['name' => 'Products Grid', 'preview' => ''],
        'newsletter_centered' => ['name' => 'Newsletter', 'preview' => '']]
];

// Instagent palette teaser — surfaces only when SectionGeneratorService is absent
// (the WP.org build strips both the class and the real palette entry above).
// Honest upsell: visible card, no platform call, click opens an in-editor upgrade
// modal. On standalone, the real Section Generator entry is present so this skips.
if (!class_exists('\Instinctor\Services\SectionGeneratorService')) {
    $elements['blocks']['items']['instagent_teaser'] = [
        'label' => 'Instagent',
        'icon'  => 'aperture',
        'pro'   => true,
        'tease' => 'Generate complete sections from a one-line brief.',
    ];
}

// Premium commerce blocks — Pro-teased in the free build. The basic store is
// free (products, cart, standard checkout, Stripe); these are the WooCommerce
// paid-extension equivalents, so the palette tile opens the upgrade modal.
if (function_exists('instinctor_locked')) {
    if (instinctor_locked('store_bundles') && isset($elements['store']['items']['bundle'])) {
        $elements['store']['items']['bundle']['pro']   = true;
        $elements['store']['items']['bundle']['tease'] = 'Bundle products and build-your-own kits to lift order value.';
    }
    if (instinctor_locked('store_bookings') && isset($elements['store']['items']['booking'])) {
        $elements['store']['items']['booking']['pro']   = true;
        $elements['store']['items']['booking']['tease'] = 'Take appointments and service bookings online.';
    }
}

// Marketing section elements (shown in Templates tab)
$marketing_elements = [
    'modal' => ['label' => 'Modal', 'icon' => 'maximize-2']];

// ============================================================================
// CHAT WORKSPACE DATA
// ============================================================================
$chat_data = [];
$chat_nonce = '';
$chat_page_toggle_nonce = '';
// Always load chat data so workspace switching works
$chatService = \Instinctor\Services\ChatService::instance();
$chat_nonce = \Instinctor\Core\Session::token('instinctor_chat_admin');
$chat_page_toggle_nonce = \Instinctor\Core\Session::token('instinctor_chat');

// Chat settings
$chat_data['settings'] = [
    'enabled' => \Instinctor\Core\Config::get('instinctor_chat_enabled', '1'),
    'title' => \Instinctor\Core\Config::get('instinctor_chat_title', 'Chat with us'),
    'greeting' => \Instinctor\Core\Config::get('instinctor_chat_greeting', 'Hi! How can we help you today?'),
    'online_text' => \Instinctor\Core\Config::get('instinctor_chat_online_text', 'Online now'),
    'position' => \Instinctor\Core\Config::get('instinctor_chat_position', 'right'),
    'avatar' => \Instinctor\Core\Config::get('instinctor_chat_avatar', ''),
    'show_online' => \Instinctor\Core\Config::get('instinctor_chat_show_online', '1'),
    'sound_enabled' => \Instinctor\Core\Config::get('instinctor_chat_sound_enabled', '1'),
    'screenshots' => \Instinctor\Core\Config::get('instinctor_chat_screenshots', '0'),
    'attachments' => \Instinctor\Core\Config::get('instinctor_chat_attachments', '0'),
    'widget_height' => \Instinctor\Core\Config::get('instinctor_chat_widget_height', '480'),
    'color_button' => \Instinctor\Core\Config::get('instinctor_chat_color_button', '#000000'),
    'color_input_border' => \Instinctor\Core\Config::get('instinctor_chat_color_input_border', '#e0e0e0'),
    'input_border_width' => \Instinctor\Core\Config::get('instinctor_chat_input_border_width', '1'),
    'bubble_opacity'       => \Instinctor\Core\Config::get('instinctor_chat_bubble_opacity', '20'),
    'chat_greeting_text'  => \Instinctor\Core\Config::get('instinctor_chat_greeting_text', ''),
    'chat_greeting_color' => \Instinctor\Core\Config::get('instinctor_chat_greeting_color', '#ffffff'),
    'collect_name' => \Instinctor\Core\Config::get('instinctor_chat_collect_name', '0'),
    'collect_email' => \Instinctor\Core\Config::get('instinctor_chat_collect_email', '0'),
    'collect_phone' => \Instinctor\Core\Config::get('instinctor_chat_collect_phone', '0'),
    'email_address' => \Instinctor\Core\Config::get('instinctor_chat_email_address', \Instinctor\Core\Config::get('admin_email')),
    'email_include_cart' => \Instinctor\Core\Config::get('instinctor_chat_email_include_cart', '1'),
    'email_frequency' => \Instinctor\Core\Config::get('instinctor_chat_email_frequency', 'first'),
    'sms_number' => \Instinctor\Core\Config::get('instinctor_chat_sms_number', ''),
    'sms_include_cart' => \Instinctor\Core\Config::get('instinctor_chat_sms_include_cart', '0'),
    'whatsapp_number' => \Instinctor\Core\Config::get('instinctor_chat_whatsapp_number', ''),
    'whatsapp_include_cart' => \Instinctor\Core\Config::get('instinctor_chat_whatsapp_include_cart', '0'),
    'ai_enabled' => \Instinctor\Core\Config::get('instinctor_chat_ai_enabled', '0'),
    'ai_store_info' => \Instinctor\Core\Config::get('instinctor_chat_ai_store_info', ''),
    'ai_tone' => \Instinctor\Core\Config::get('instinctor_chat_ai_tone', 'friendly'),
    'handoff_timeout' => \Instinctor\Core\Config::get('instinctor_chat_handoff_timeout', '5'),
    'handoff_message' => \Instinctor\Core\Config::get('instinctor_chat_handoff_message', "Our team members are currently assisting other customers. Please leave your email or phone number and we'll get back to you as soon as possible!"),
    'auto_close_minutes' => \Instinctor\Core\Config::get('instinctor_chat_auto_close_minutes', '60')];

// Quick replies
$chat_data['quick_replies'] = array_map(function($r) {
    if (is_string($r)) return ['text' => $r, 'cat' => ''];
    return ['text' => (string)($r['text'] ?? $r), 'cat' => (string)($r['cat'] ?? '')];
}, (array)\Instinctor\Core\Config::get('instinctor_chat_quick_actions', [
    'Thanks for reaching out! How can I help you today?',
    'Let me check on that for you — one moment!',
    'Could you provide your order number so I can look that up?',
    'I\'d be happy to help with that.',
    'I\'m sorry to hear that! Let me make this right for you.',
    'Your order has been shipped and should arrive in 3–5 business days.',
    'Our return policy allows returns within 30 days of purchase.',
    'We\'re open Monday–Friday, 9am–6pm EST.',
    'Feel free to reach out anytime — we typically respond within a few hours.',
    'Is there anything else I can help you with today?']));

// Conversations (loaded via AJAX for real-time)
$chat_data['conversations'] = $chatService->getConversations('active');

// Pro features check
$chat_data['has_pro'] = instinctor_has_pro();

// Include cart default
$chat_data['include_cart_default'] = \Instinctor\Core\Config::get('instinctor_chat_include_cart_default', '0') === '1';

// Bubble colors for message styling
$chat_data['visitor_bubble'] = \Instinctor\Core\Config::get('instinctor_chat_color_visitor_bubble', '#3a3f44');
$chat_data['agent_bubble'] = \Instinctor\Core\Config::get('instinctor_chat_color_agent_bubble', '#f0f0f0');
$chat_data['chat_background'] = \Instinctor\Core\Config::get('instinctor_chat_color_background', '#f5f5f5');

// ============================================================================
// OPERATIONS WORKSPACE DATA (Orders, Reviews, Q&A, Returns, Bookings, Subscriptions, Quotes, Vendors, Dropshipping, Tracking)
// ============================================================================
$_p = \Instinctor\Core\DB::prefix();
$dashboard_data = [];

// Currency
$dashboard_data['currency'] = \Instinctor\Core\Config::get('instinctor_currency_symbol', '$');

// Order counts by status
$dashboard_data['status_counts'] = [
    'all' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders"),
    'pending' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE status = 'pending'"),
    'processing' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE status = 'processing'"),
    'completed' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE status = 'completed'"),
    'shipped' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE status = 'shipped'"),
    'cancelled' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE status = 'cancelled'"),
    'refunded' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE status = 'refunded'")];

// Recent orders (initial load)
$dashboard_data['orders'] = \Instinctor\Core\DB::get_results(
    "SELECT o.id, o.order_number, o.status, o.total, o.created_at, o.billing_address, o.customer_id, c.email as customer_email, c.first_name, c.last_name
     FROM {$_p}instinctor_orders o
     LEFT JOIN {$_p}instinctor_customers c ON o.customer_id = c.id
     ORDER BY o.created_at DESC LIMIT 50"
);

// Customers loaded via AJAX on demand
$dashboard_data['customers'] = [];

// Developer mode - bypasses license checks but respects activation toggles
// Set via License Manager toggle or wp-config.php: define('INSTINCTOR_DEV_MODE', true);
$dev_mode = \Instinctor\Core\TierManager::isDevMode();

// Check if user has a paid tier (pro or agency)
$tierManager = \Instinctor\Core\TierManager::instance();
$has_pro_license = instinctor_editor_has_license();

// Finance summary
$dashboard_data['finance'] = [
    'today_revenue' => (float)\Instinctor\Core\DB::get_var("SELECT COALESCE(SUM(total), 0) FROM {$_p}instinctor_orders WHERE status IN ('completed', 'processing') AND DATE(created_at) = CURDATE()"),
    'today_orders' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE DATE(created_at) = CURDATE()"),
    'month_revenue' => (float)\Instinctor\Core\DB::get_var("SELECT COALESCE(SUM(total), 0) FROM {$_p}instinctor_orders WHERE status IN ('completed', 'processing') AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)"),
    'month_orders' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_orders WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)"),
    'total_revenue' => (float)\Instinctor\Core\DB::get_var("SELECT COALESCE(SUM(total), 0) FROM {$_p}instinctor_orders WHERE status IN ('completed', 'processing')"),
    'total_refunds' => (float)\Instinctor\Core\DB::get_var("SELECT COALESCE(SUM(total), 0) FROM {$_p}instinctor_orders WHERE status = 'refunded'")];

// Active addons for dashboard sections
$dashboard_data['dev_mode'] = $dev_mode;
$licenses = \Instinctor\Core\Config::get('instinctor_addon_licenses', []);
if (!is_array($licenses)) $licenses = [];

// Check each manageable addon and get counts
$dashboard_data['addon_counts'] = [];

// Helper function for addon check
$check_addon = function($key) use ($dev_mode) {
    // Tier/store-type driven since the addons layer collapse (2026-07-29):
    // bookings/subscriptions follow the store type inside isFeatureEnabled.
    return $dev_mode || \Instinctor\Core\StoreFeatures::isFeatureEnabled($key);
};

// RMA / Returns
$dashboard_data['has_rma'] = $check_addon('rma');
if ($dashboard_data['has_rma']) {
    $dashboard_data['addon_counts']['rma'] = (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_rma WHERE status IN ('pending', 'approved')");
    $dashboard_data['rma_items'] = \Instinctor\Core\DB::get_results("
        SELECT r.*, o.id as order_id
        FROM {$_p}instinctor_rma r
        LEFT JOIN {$_p}instinctor_orders o ON r.order_id = o.id
        ORDER BY r.created_at DESC
        LIMIT 50
    ");
    $dashboard_data['rma_counts'] = [
        'pending' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_rma WHERE status = 'pending'"),
        'approved' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_rma WHERE status = 'approved'"),
        'shipped' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_rma WHERE status = 'shipped'"),
        'completed' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_rma WHERE status = 'completed'")];
}

// Bookings
$dashboard_data['has_bookings'] = $check_addon('bookings');
if ($dashboard_data['has_bookings']) {
    $dashboard_data['addon_counts']['bookings'] = (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_bookings WHERE status = 'pending' OR (status = 'confirmed' AND DATE(start_time) >= CURDATE())");
    $dashboard_data['booking_items'] = \Instinctor\Core\DB::get_results("
        SELECT b.*, p.name as service_name
        FROM {$_p}instinctor_bookings b
        LEFT JOIN {$_p}instinctor_products p ON b.product_id = p.id
        ORDER BY b.start_time ASC
        LIMIT 50
    ");
    $dashboard_data['booking_counts'] = [
        'pending' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_bookings WHERE status = 'pending'"),
        'confirmed' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_bookings WHERE status = 'confirmed'"),
        'completed' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_bookings WHERE status = 'completed'"),
        'cancelled' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_bookings WHERE status = 'cancelled'")];
}

// Subscriptions
$dashboard_data['has_subscriptions'] = $check_addon('subscriptions');
if ($dashboard_data['has_subscriptions']) {
    $dashboard_data['addon_counts']['subscriptions'] = (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_subscriptions WHERE status = 'active'");
    $dashboard_data['subscription_items'] = \Instinctor\Core\DB::get_results("
        SELECT s.*, u.display_name as customer_name, u.user_email as customer_email
        FROM {$_p}instinctor_subscriptions s
        LEFT JOIN {$_p}users u ON s.user_id = u.ID
        ORDER BY s.next_payment DESC
        LIMIT 50
    ");
    $dashboard_data['subscription_counts'] = [
        'active' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_subscriptions WHERE status = 'active'"),
        'past_due' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_subscriptions WHERE status = 'past_due'"),
        'paused' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_subscriptions WHERE status = 'paused'"),
        'cancelled' => (int)\Instinctor\Core\DB::get_var("SELECT COUNT(*) FROM {$_p}instinctor_subscriptions WHERE status = 'cancelled'")];
}

// Dropshipping
$dashboard_data['has_dropshipping'] = $check_addon('dropshipping');
if ($dashboard_data['has_dropshipping']) {
    $dashboard_data['addon_counts']['dropshipping'] = (int)\Instinctor\Core\DB::get_var("SELECT COUNT(DISTINCT f.order_id) FROM {$_p}instinctor_dropship_fulfillments f JOIN {$_p}instinctor_orders o ON o.id = f.order_id WHERE o.status = 'processing'");
    $dashboard_data['dropship_items'] = \Instinctor\Core\DB::get_results("
        SELECT o.id, o.order_number, o.status, o.total, o.created_at, f.status as fulfillment_status, s.name as supplier_name
        FROM {$_p}instinctor_dropship_fulfillments f
        JOIN {$_p}instinctor_orders o ON o.id = f.order_id
        LEFT JOIN {$_p}instinctor_dropship_suppliers s ON f.supplier_id = s.id
        ORDER BY f.created_at DESC
        LIMIT 50
    ");
}

// Order Tracking

$marketing_data = [];

// Feature availability is tier-driven since the addons layer collapse
// (2026-07-29): commerce features ship with the product; free is render-gated.
$check_addon_active = function($key) use ($dev_mode) {
    return $dev_mode || \Instinctor\Core\StoreFeatures::isFeatureEnabled($key);
};
$check_marketing_addon = function($key) use ($check_addon_active) {
    return $check_addon_active($key);
};

// Marketing addon flags
$marketing_data['has_gift_cards'] = $check_marketing_addon('gift_cards');
$marketing_data['has_loyalty'] = $check_marketing_addon('loyalty');
$marketing_data['has_free_gifts'] = $check_marketing_addon('coupons');
$marketing_data['has_upsells'] = $check_marketing_addon('recommendations');
$marketing_data['has_volume_discounts'] = $check_marketing_addon('volume_discounts');
$marketing_data['has_memberships'] = $check_marketing_addon('subscriptions');
$marketing_data['has_badges'] = true; // always-on core feature

// Coupons
$coupon_service = new \Instinctor\Services\CouponService();
$marketing_data['coupons'] = $coupon_service->getAllCoupons(['limit' => 100]);

// Gift Cards (if addon active)
$marketing_data['gift_cards'] = [];
if ($marketing_data['has_gift_cards']) {
    $marketing_data['gift_cards'] = \Instinctor\Services\GiftCardService::getAll();
}

// Loyalty settings
$marketing_data['loyalty'] = [
    'enabled' => \Instinctor\Core\Config::get('instinctor_loyalty_enabled', false),
    'points_per_currency' => \Instinctor\Core\Config::get('instinctor_loyalty_points_per_currency', 1),
    'points_value' => \Instinctor\Core\Config::get('instinctor_loyalty_points_value', 0.01),
    'min_redeem' => \Instinctor\Core\Config::get('instinctor_loyalty_min_redeem', 100),
    'signup_points' => \Instinctor\Core\Config::get('instinctor_loyalty_signup_points', 100)];

// Email templates (simplified - just names and enabled status)
$email_templates = \Instinctor\Services\EmailService::getTemplates();
$email_footer_settings = \Instinctor\Services\EmailService::getFooterSettings();
$marketing_data['emails'] = [];
foreach ($email_templates as $key => $template) {
    $marketing_data['emails'][] = [
        'key' => $key,
        'name' => $template['name'] ?? ucwords(str_replace('_', ' ', $key)),
        'subject' => $template['subject'] ?? '',
        'body' => $template['body'] ?? '',
        'enabled' => $template['enabled'] ?? false,
        'include_footer' => $template['include_footer'] ?? true];
}
$marketing_data['email_footer'] = $email_footer_settings;

// Currency for display
$marketing_data['currency'] = \Instinctor\Core\Config::get('instinctor_currency_symbol', '$');

// ============================================================================
// STORE DASHBOARD DATA
// ============================================================================
$addons_data = [];

?>

<?php if ($view === 'pages'): ?>
<!-- Page Editor View -->
<div class="impulse-editor<?php echo $page_id ? ' editing' : ''; ?>" data-page-id="<?php echo esc_attr($page_id); ?>" data-workspace="<?php echo esc_attr($workspace); ?>"<?php echo $_canonical_slug !== '' ? ' data-canonical-slug="' . esc_attr($_canonical_slug) . '"' : ''; ?>>
    <!-- Mobile Blocker -->
    <div class="impulse-mobile-blocker">
        <div class="impulse-mobile-blocker-content">
            <img src="<?php echo esc_url(INSTINCTOR_PLUGIN_URL . 'assets/images/placeholder-logo-dark.svg'); ?>" alt="Instinctor" style="width:120px;margin-bottom:24px;opacity:0.9">
            <h2>Desktop Required</h2>
            <p>The page builder requires a larger screen to work properly.</p>
            <p style="opacity:0.7;font-size:13px">Please use a desktop or tablet device.</p>
            <a href="<?php echo esc_url(admin_url()); ?>" class="impulse-mobile-blocker-btn">← Back to Dashboard</a>
        </div>
    </div>
    <!-- Top Bar -->
    <div class="impulse-topbar">
        <div class="impulse-topbar-left">
            <?php if (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress'): ?>
            <a href="<?php echo esc_url(admin_url()); ?>" class="impulse-back-wp" title="Back to WordPress">
                <svg viewBox="0 0 24 24" width="22" height="22" color="currentColor"><g transform="scale(2.288)" fill="currentColor" stroke="none"><path d="M3.02 0.02l2.23 0c1.44,0 2.75,0.59 3.7,1.54 0.95,0.95 1.54,2.26 1.54,3.7 0,1.44 -0.59,2.75 -1.54,3.7 -0.95,0.95 -2.26,1.54 -3.7,1.54 -1.44,0 -2.75,-0.59 -3.7,-1.54 -0.95,-0.95 -1.54,-2.26 -1.54,-3.7l0 -2.23 2.31 0 0 2.23c0,0.8 0.33,1.53 0.86,2.06 0.53,0.53 1.26,0.86 2.06,0.86 0.8,0 1.53,-0.33 2.06,-0.86 0.53,-0.53 0.86,-1.26 0.86,-2.06 0,-0.8 -0.33,-1.53 -0.86,-2.06 -0.53,-0.53 -1.26,-0.86 -2.06,-0.86l-2.23 0 0 -2.31z"/><rect x="0.02" y="0.02" width="2.31" height="2.31"/></g></svg>
            </a>
            <?php else: ?>
            <button type="button" class="impulse-back-wp" title="Settings" onclick="switchWorkspace('settings')">
                <svg viewBox="0 0 24 24" width="22" height="22" color="currentColor"><g transform="scale(2.288)" fill="currentColor" stroke="none"><path d="M3.02 0.02l2.23 0c1.44,0 2.75,0.59 3.7,1.54 0.95,0.95 1.54,2.26 1.54,3.7 0,1.44 -0.59,2.75 -1.54,3.7 -0.95,0.95 -2.26,1.54 -3.7,1.54 -1.44,0 -2.75,-0.59 -3.7,-1.54 -0.95,-0.95 -1.54,-2.26 -1.54,-3.7l0 -2.23 2.31 0 0 2.23c0,0.8 0.33,1.53 0.86,2.06 0.53,0.53 1.26,0.86 2.06,0.86 0.8,0 1.53,-0.33 2.06,-0.86 0.53,-0.53 0.86,-1.26 0.86,-2.06 0,-0.8 -0.33,-1.53 -0.86,-2.06 -0.53,-0.53 -1.26,-0.86 -2.06,-0.86l-2.23 0 0 -2.31z"/><rect x="0.02" y="0.02" width="2.31" height="2.31"/></g></svg>
            </button>
            <?php endif; ?>
            <span class="impulse-brand-name"<?php echo ($page_id) ? ' style="display:none"' : ''; ?>>Instinctor</span>
            <span class="impulse-topbar-divider impulse-editing-only impulse-only"<?php echo !$page_id ? ' style="display:none"' : ''; ?>></span>
            <div class="impulse-page-title impulse-editing-only impulse-only"<?php echo !$page_id ? ' style="display:none"' : ''; ?>>
                <div class="impulse-page-name-edit" data-id="<?php echo esc_attr($current_page ? $current_page->id : 0); ?>">
                    <span id="impulse-page-name" class="impulse-title-text"><?php echo esc_html($current_page ? $current_page->name : 'Untitled'); ?></span>
                    <input type="text" id="impulse-page-name-input" class="impulse-title-input" value="<?php echo esc_attr($current_page ? $current_page->name : 'Untitled'); ?>" style="display:none" autocomplete="off">
                    <button type="button" id="impulse-page-name-ok" class="impulse-title-ok" style="display:none">OK</button>
                    <button type="button" id="impulse-slug-btn" class="impulse-slug-link-btn" title="Page URL">
                        <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
                    </button>
                </div>
                <div id="impulse-slug-modal" class="impulse-slug-modal" style="display:none">
                    <div class="impulse-slug-modal-content">
                        <div class="impulse-slug-modal-row">
                            <?php
                                // Two URL namespaces: top-level for marketing,
                                // /designer/ for everything a designer owns.
                                $_slugPrefix = rtrim(home_url('/'), '/') . '/';
                                if ($current_page && !empty($current_page->owner_id)) {
                                    $_slugPrefix .= 'designer/';
                                }
                            ?>
                            <span class="impulse-slug-modal-prefix"><?php echo esc_url($_slugPrefix); ?></span>
                            <input type="text" id="impulse-page-slug-input" class="impulse-slug-modal-input" value="<?php echo esc_attr($current_page ? $current_page->slug : ''); ?>">
                            <button type="button" id="impulse-slug-copy" class="impulse-slug-modal-btn" title="Copy URL">
                                <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
                            </button>
                            <button type="button" id="impulse-slug-ok" class="impulse-slug-modal-btn impulse-slug-ok-btn" title="Save">OK</button>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Page switcher: chevron button right after page name, shows page list dropdown -->
            <div class="impulse-page-switcher impulse-editing-only impulse-only" id="impulse-page-switcher"<?php echo !$page_id ? ' style="display:none"' : ''; ?>>
                <button type="button" class="impulse-page-switcher-btn" id="impulse-page-switcher-btn" title="Switch page">
                    <svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
                </button>
                <div class="impulse-page-switcher-dropdown" id="impulse-page-switcher-dropdown"></div>
            </div>

<?php // Page complexity meter removed 2026-05-09 — Sergei: noise, not signal. ?>

        </div>

        <div class="impulse-topbar-center">
            <div class="impulse-workspace-nav" id="impulse-workspace-nav">
                <div class="impulse-workspace-track" id="impulse-workspace-track"></div>
                <?php
                $ws_icons = [
                    'impulse' => '<path d="M3 3h7v7H3z"/><path d="M14 3h7v7h-7z"/><path d="M14 14h7v7h-7z"/><path d="M3 14h7v7H3z"/>',
                    'chat'    => '<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.71 12 19.79 19.79 0 0 1 1.62 3.41 2 2 0 0 1 3.6 1.21h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.89a16 16 0 0 0 6 6l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21.73 16"/>',
                    'store'   => '<path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/>',
                    'seo'     => '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
                    'settings'=> '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>'];
                $ws_labels = [
                    'impulse' => 'Impulse',
                    'chat'    => 'Chat',
                    'store'   => 'Store',
                    'seo'     => 'SEO',
                    'settings'=> 'Settings'];
                foreach ($workspace_order as $ws):
                    // In standalone mode, Settings is accessed via logo — hide from nav
                    if ($ws === 'settings' && defined('INSTINCTOR_ENV') && INSTINCTOR_ENV !== 'wordpress') continue;
                    $icon  = $ws_icons[$ws]  ?? '';
                    $label = $ws_labels[$ws] ?? ucfirst($ws);
                ?>
                <button type="button" class="impulse-workspace-btn<?php echo $workspace === $ws ? ' active' : ''; ?>" data-workspace="<?php echo esc_attr($ws); ?>" draggable="true"><?php echo esc_html(strtoupper($label)); ?></button>
                <?php endforeach; ?>
            </div>
        </div>
        <div class="impulse-topbar-right">
            <!-- Builder controls (editing only) -->
            <div class="impulse-topbar-builder-controls<?php echo $workspace !== 'impulse' ? ' impulse-hidden' : ''; ?>">
                <button type="button" class="instinctor-btn instinctor-btn-icon impulse-editing-only" id="impulse-close-editor" title="Close Editor"<?php echo !$page_id ? ' style="display:none"' : ''; ?>>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                </button>
                <button type="button" class="instinctor-btn instinctor-btn-icon impulse-editing-only" id="impulse-undo" title="Undo (Ctrl+Z)" disabled<?php echo !$page_id ? ' style="display:none"' : ''; ?>>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/></svg>
                </button>
                <button type="button" class="instinctor-btn instinctor-btn-icon impulse-editing-only" id="impulse-redo" title="Redo (Ctrl+Y)" disabled<?php echo !$page_id ? ' style="display:none"' : ''; ?>>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 14 20 9 15 4"/><path d="M4 20v-7a4 4 0 0 1 4-4h12"/></svg>
                </button>

        </div><!-- /impulse-topbar-builder-controls -->
            <!-- Relay controls (only for users who can manage chat settings) -->
            <?php if ($can_manage_chat_settings) : ?>
            <button type="button" class="instinctor-btn instinctor-btn-sm" id="impulse-chat-toggle" data-enabled="<?php echo $chat_data['settings']['enabled'] === '1' ? '1' : '0'; ?>"<?php echo $workspace !== 'chat' ? ' style="display:none"' : ''; ?>><?php echo $chat_data['settings']['enabled'] === '1' ? 'Chat Enabled' : 'Chat Disabled'; ?></button>
            <?php endif; ?>
            <!-- Add Product button — shown in Store > Products section -->
            <button type="button" class="instinctor-btn instinctor-btn-sm" id="topbar-add-product" style="display:none;gap:5px;background:#fff;color:#1d2327;border-color:#fff">
                <svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2.5"><path d="M12 5v14M5 12h14"/></svg>
                <?php echo esc_html('Add ' . \Instinctor\Core\StoreFeatures::productNoun(false)); ?>
            </button>
            <!-- Add Service + Add Booking buttons — shown in Store > Bookings section -->
            <button type="button" class="instinctor-btn instinctor-btn-sm" id="topbar-add-service" style="display:none;background:#fff;color:#1d2327;border-color:#fff">
                <svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2.5" style="margin-right:5px"><path d="M12 5v14M5 12h14"/></svg>
                Add Service
            </button>
            <button type="button" class="instinctor-btn instinctor-btn-sm" id="topbar-add-booking" style="display:none;background:#fff;color:#1d2327;border-color:#fff">
                <svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2.5" style="margin-right:5px"><path d="M12 5v14M5 12h14"/></svg>
                Add Booking
            </button>
            <!-- Instagent Help trigger — slide-out KB chat panel. The
                 _instagent-help.php partial (included near the end of this
                 view) inlines its own JS that binds to this button id.
                 Always visible in the admin topbar so help is one click
                 away in any workspace. -->
            <button type="button" class="instinctor-btn instinctor-btn-icon" id="impulse-instagent-help-toggle" title="Instagent Help" aria-label="Open Instagent Help" style="margin-right:6px">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
            </button>
            <!-- Preview button - rightmost (editing only) -->
            <button type="button" class="instinctor-btn instinctor-btn-sm impulse-only impulse-editing-only" id="impulse-preview"<?php echo $workspace !== 'impulse' || !$page_id ? ' style="display:none"' : ''; ?>>Preview</button>
            <?php
            // Updates surface — standalone only. Renders ONLY when a newer
            // version is actually available; the "no updates" idle state is
            // never shown, so the editor topbar isn't permanently polluted
            // with a button that does nothing 99% of the time. Designers
            // wanting to manually check still reach /admin/updates directly.
            // Stripped on WP entirely — WP surfaces updates through its
            // Plugins page via Core\AutoUpdater's transient filters.
            // Idle-state rendering removed 2026-06-09 (Sergei: most
            // inappropriate spot in the editor).
            if (defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone'):
                $_au_available = class_exists('\\Instinctor\\Core\\Config')
                    ? trim((string) \Instinctor\Core\Config::get('instinctor_autoupdate_last_available', ''))
                    : '';
                $_au_current   = defined('INSTINCTOR_VERSION') ? (string) INSTINCTOR_VERSION : '0';
                $_au_has_new   = $_au_available !== '' && version_compare($_au_available, $_au_current, '>');
                if ($_au_has_new):
            ?>
            <a href="/admin/updates" id="instinctor-updates-link"
               title="<?php echo esc_attr('Update available: ' . $_au_available); ?>"
               style="display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 10px;font-size:11px;font-weight:500;border-radius:3px;text-decoration:none;white-space:nowrap;flex-shrink:0;background:#fff;color:#1d2327;">
                <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-3-6.7"/><polyline points="21 3 21 9 15 9"/></svg>
                Update <?php echo esc_html($_au_available); ?>
            </a>
            <?php endif; endif; ?>
            <!-- New page button — list mode only. One unified page type. -->
            <button type="button" class="instinctor-btn instinctor-btn-sm impulse-only impulse-list-only" id="impulse-new-page" title="New page" style="gap:5px;background:#fff;color:#1d2327;border-color:#fff<?php echo ($workspace !== 'impulse' || $page_id) ? ';display:none' : ''; ?>">
                <svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2.5"><path d="M12 5v14M5 12h14"/></svg>
                New Page
            </button>
            <!-- New post — opens the simple post editor (no builder needed). -->
            <a href="/admin/post/new" class="instinctor-btn instinctor-btn-sm impulse-only impulse-list-only" id="impulse-new-post" title="Write a blog post" style="gap:5px;text-decoration:none;align-items:center<?php echo ($workspace !== 'impulse' || $page_id) ? ';display:none' : ''; ?>">
                <svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2.5"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
                New Post
            </a>
        </div><!-- /impulse-topbar-right -->
        <!-- Second row: filter tabs + page controls (list mode only) -->
        <div class="impulse-topbar-list-row impulse-list-only impulse-only" id="impulse-topbar-list-row"<?php echo ($workspace !== 'impulse' || $page_id) ? ' style="display:none"' : ''; ?>>
            <div class="impulse-canvas-tabs" id="impulse-topbar-canvas-tabs">
                <button type="button" class="impulse-canvas-tab active" data-filter="all">All <span class="count"><?php echo count($pages) - $posts_count; ?></span></button>
                <button type="button" class="impulse-canvas-tab" data-filter="published">Published <span class="count"><?php echo esc_html($published_count); ?></span></button>
                <button type="button" class="impulse-canvas-tab" data-filter="draft">Draft <span class="count"><?php echo esc_html($draft_count); ?></span></button>
                <button type="button" class="impulse-canvas-tab" data-filter="posts">Posts <span class="count"><?php echo esc_html($posts_count); ?></span></button>
                <button type="button" class="impulse-canvas-tab" data-filter="trash">Trash <span class="count"><?php echo esc_html($trash_count); ?></span></button>
                <button type="button" class="impulse-canvas-empty-trash" style="display:none;">Empty Trash</button>
            </div>
            <span class="impulse-topbar-divider"></span>
            <!-- Bulk actions (hidden until select mode) -->
            <div class="impulse-bulk-actions" id="impulse-bulk-actions" style="display:none;">
                <button type="button" class="impulse-bulk-btn" id="impulse-select-all" title="Select All">
                    <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 12l2 2 4-4"/></svg>
                    All
                </button>
                <span class="impulse-bulk-count" id="impulse-bulk-count">0 selected</span>
                <button type="button" class="impulse-bulk-btn" id="impulse-bulk-publish" title="Publish selected" disabled>
                    <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
                    Publish
                </button>
                <button type="button" class="impulse-bulk-btn" id="impulse-bulk-unpublish" title="Unpublish selected" disabled>
                    <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
                    Unpublish
                </button>
                <button type="button" class="impulse-bulk-btn impulse-bulk-btn-danger" id="impulse-bulk-trash" title="Trash selected" disabled>
                    <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
                    Trash
                </button>
                <span class="impulse-topbar-divider"></span>
            </div>
            <!-- Select toggle -->
            <button type="button" class="impulse-select-toggle" id="impulse-select-toggle" title="Select pages">
                <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><polyline points="9 11 12 14 22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
            </button>
            <!-- Card size slider -->
            <div class="impulse-size-slider">
                <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
                <input type="range" id="impulse-card-size" min="150" max="350" value="150">
                <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>
            </div>
            <?php if (!empty($pages) && count($pages) >= 8): ?>
            <!-- Page search: filters the grid by name + slug (see regroup() in instinctor-admin-core.js).
                 margin-left:auto parks it at the right end of the filter row. -->
            <div class="impulse-pg-search-wrap" style="margin-left:auto;position:relative;flex-shrink:0">
                <svg style="position:absolute;left:9px;top:50%;transform:translateY(-50%);pointer-events:none" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#777" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
                <input type="text" id="impulse-pg-search" placeholder="Search pages by name or slug" autocomplete="off" spellcheck="false" style="width:230px;height:26px;padding:0 10px 0 29px;background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;color:#e0e0e0;font-size:12px;outline:none;box-sizing:border-box">
            </div>
            <?php endif; ?>

        </div><!-- /impulse-topbar-list-row -->
    </div><!-- /impulse-topbar -->
    
    <!-- ============================================================================ -->
    <!-- CHAT WORKSPACE v3 - Single Screen Messenger Layout -->
    <!-- ============================================================================ -->
    <?php if ($role_manager->canAccessWorkspace('chat')) : ?>
    <div class="impulse-workspace" data-workspace="chat"<?php echo $workspace !== 'chat' ? ' style="display:none"' : ''; ?>>
    <div class="impulse-main impulse-chat-workspace">
        <!-- Left: Conversations List -->
        <div class="impulse-chat-left">
            <div class="impulse-chat-list-header">
                <div class="impulse-chat-left-tabs">
                    <button type="button" class="impulse-chat-left-tab active" data-left-tab="conversations">Conversations</button>
                    <button type="button" class="impulse-chat-left-tab" data-left-tab="history">History</button>
                </div>
            </div>
            <!-- Conversations pane -->
            <div class="impulse-chat-left-pane active" id="impulse-chat-pane-conversations">
            <div class="impulse-chat-conversations" id="impulse-chat-conversations">
                <?php if (empty($chat_data['conversations'])): ?>
                <div class="impulse-chat-empty-state">
                    <svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
                    <p>No conversations</p>
                </div>
                <?php else: ?>
                <?php foreach ($chat_data['conversations'] as $conv): ?>
                    <div class="impulse-chat-conv-item <?php echo $conv->unread_count > 0 ? 'unread' : ''; ?>" data-id="<?php echo esc_attr($conv->id); ?>" data-email="<?php echo esc_attr($conv->visitor_email ?? ''); ?>" data-phone="<?php echo esc_attr($conv->visitor_phone ?? ''); ?>">
                        <div class="impulse-chat-conv-info">
                            <div class="impulse-chat-conv-name"><?php echo esc_html($conv->visitor_name ?: 'Visitor'); ?></div>
                            <div class="impulse-chat-conv-preview"><?php echo esc_html(wp_trim_words($conv->last_message ?? '', 6, "\xE2\x80\xA6")); ?></div>
                        </div>
                        <button type="button" class="impulse-chat-note-btn<?php echo !empty($conv->visitor_note) ? ' has-note' : ''; ?>" data-id="<?php echo esc_attr($conv->id); ?>" title="<?php echo !empty($conv->visitor_note) ? 'Edit note' : 'Add note'; ?>"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>
                    </div>
                <?php endforeach; ?>
                <?php endif; ?>
            </div>
            </div>
            <!-- History pane — closed conversations -->
            <div class="impulse-chat-left-pane" id="impulse-chat-pane-history" style="display:none">
                <div class="impulse-chat-conversations" id="impulse-chat-closed-conversations">
                    <div class="impulse-chat-empty-state">
                        <svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
                        <p>No closed conversations</p>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- Center: Conversation View -->
        <div class="impulse-chat-center">
            <!-- Empty State -->
            <div class="impulse-chat-no-selection" id="impulse-chat-no-selection">
                <svg viewBox="0 0 24 24" width="52" height="52" color="currentColor" style="opacity:0.12"><g transform="scale(2.288)" fill="currentColor" stroke="none"><path d="M3.02 0.02l2.23 0c1.44,0 2.75,0.59 3.7,1.54 0.95,0.95 1.54,2.26 1.54,3.7 0,1.44 -0.59,2.75 -1.54,3.7 -0.95,0.95 -2.26,1.54 -3.7,1.54 -1.44,0 -2.75,-0.59 -3.7,-1.54 -0.95,-0.95 -1.54,-2.26 -1.54,-3.7l0 -2.23 2.31 0 0 2.23c0,0.8 0.33,1.53 0.86,2.06 0.53,0.53 1.26,0.86 2.06,0.86 0.8,0 1.53,-0.33 2.06,-0.86 0.53,-0.53 0.86,-1.26 0.86,-2.06 0,-0.8 -0.33,-1.53 -0.86,-2.06 -0.53,-0.53 -1.26,-0.86 -2.06,-0.86l-2.23 0 0 -2.31z"/><rect x="0.02" y="0.02" width="2.31" height="2.31"/></g></svg>
            </div>
            
            <!-- Active Conversation -->
            <div class="impulse-chat-active" id="impulse-chat-active" style="display:none;">
                <!-- Header with collapsible visitor info -->
                <div class="impulse-chat-header">
                    <div class="impulse-chat-header-main">
                        <div class="impulse-chat-header-left">
                            <h3 id="impulse-chat-visitor-name">Visitor</h3>
                            <span id="impulse-chat-visitor-status" class="impulse-chat-status">active</span>
                        </div>
                        <div class="impulse-chat-header-actions">
                            <button type="button" class="impulse-btn-sm" id="impulse-chat-close-conv">Close</button>
                            <button type="button" class="impulse-btn-sm impulse-btn-danger" id="impulse-chat-delete-conv">Delete</button>
                        </div>
                    </div>
                    <!-- Visitor Info - always visible -->
                    <div class="impulse-chat-visitor-info" id="impulse-chat-visitor-info">
                        <div class="impulse-chat-info-grid">
                            <div class="impulse-chat-info-item" id="impulse-chat-info-row-email"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg><span id="impulse-chat-info-email"></span></div>
                            <div class="impulse-chat-info-item" id="impulse-chat-info-row-phone"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.58 2.81.7A2 2 0 0 1 22 16.92z"/></svg><span id="impulse-chat-info-phone"></span></div>
                            <div class="impulse-chat-info-item impulse-chat-info-full" id="impulse-chat-info-row-cart"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg><span id="impulse-chat-info-cart"></span></div>
                        </div>
                    </div>
                </div>
                
                <!-- Visitor page context -->
                <div class="impulse-chat-visitor-page" id="impulse-chat-visitor-page" style="display:none;"></div>
                <div class="impulse-chat-claim-bar" id="impulse-chat-claim-bar" style="display:none;">
                    <span class="impulse-chat-claim-label" id="impulse-chat-claim-label"></span>
                    <div class="impulse-chat-claim-actions">
                        <button type="button" class="impulse-btn-sm" id="impulse-chat-btn-claim">Claim</button>
                        <button type="button" class="impulse-btn-sm" id="impulse-chat-btn-takeover" style="display:none;">Take Over</button>
                        <button type="button" class="impulse-btn-sm" id="impulse-chat-btn-release" style="display:none;">Release</button>
                    </div>
                </div>

                <!-- Messages -->
                <div class="impulse-chat-messages" id="impulse-chat-messages"></div>
                <div class="impulse-chat-typing-row" id="impulse-chat-typing-row" style="display:none;">
                    <div class="impulse-chat-typing-indicator"><span></span><span></span><span></span></div>
                    <span class="impulse-chat-typing-label">typing</span>
                </div>
                
                <!-- / Quick Reply Menu -->
                <div id="impulse-chat-slash-menu" class="impulse-chat-slash-menu" style="display:none;">
                    <div class="impulse-chat-slash-search">
                        <input type="text" id="impulse-chat-slash-input" placeholder="Search replies..." autocomplete="off" spellcheck="false">
                    </div>
                    <div class="impulse-chat-slash-list" id="impulse-chat-slash-list"></div>
                </div>
                
                <!-- Compose -->
                <div class="impulse-chat-compose">
                    <textarea id="impulse-chat-reply-input" placeholder="Type your reply..." rows="1"></textarea>
                    <div class="impulse-chat-compose-footer">
                        <button type="button" class="impulse-chat-send-btn" id="impulse-chat-send-reply">Send</button>
                    </div>
                </div>
            </div>
            
        </div>
        
        <!-- Right: Quick Replies / Settings -->
        <div class="impulse-chat-right">
            <div class="impulse-chat-right-content">
                <!-- Quick Replies Panel -->
                <div class="impulse-chat-right-panel" id="impulse-chat-panel-replies" data-panel="replies">
                    <div class="impulse-chat-quick-replies" id="impulse-chat-quick-replies">
                        <?php foreach ($chat_data['quick_replies'] as $i => $reply): 
                            $qr_text = is_array($reply) ? ($reply['text'] ?? '') : $reply;
                        ?>
                        <div class="impulse-chat-quick-reply" data-index="<?php echo (int) $i; ?>" data-message="<?php echo esc_attr($qr_text); ?>" draggable="true">
                            <span class="impulse-qr-drag" title="Drag to reorder"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 5h16"/><path d="M4 12h16"/><path d="M4 19h16"/></svg></span>
                            <span class="impulse-qr-text" spellcheck="false" title="Double-click to edit"><?php echo esc_html($qr_text); ?></span>
                            <button type="button" class="impulse-qr-remove-btn" data-index="<?php echo (int) $i; ?>" title="Remove"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button>
                        </div>
                        <?php endforeach; ?>
                    </div><!-- end quick-replies -->

                    <div class="impulse-chat-add-reply" id="impulse-chat-add-reply-bar">
                        <!-- Honeypot fields: fool browser + password managers into autofilling these instead -->
                        <form autocomplete="off" onsubmit="return false" style="display:none!important;position:absolute;left:-9999px;opacity:0;height:0;width:0;margin:0;padding:0;border:0">
                        <input type="text" name="username_fake" tabindex="-1" aria-hidden="true" autocomplete="username">
                        <input type="password" name="password_fake" tabindex="-1" aria-hidden="true" autocomplete="current-password">
                        </form>
                        <input type="text" id="impulse-chat-new-quick-reply" placeholder="Add reply..." autocomplete="new-password" readonly data-lpignore="true" data-1p-ignore="true" data-bwignore="true" data-form-type="other" spellcheck="false">
                        <button type="button" id="impulse-chat-add-quick-reply">+</button>
                    </div>

                    <!-- InstAgent context panel -->
                    <div class="impulse-instagent-panel" id="impulse-instagent-panel" style="display:none">
                        <div class="impulse-instagent-header">
                            <svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
                            INSTAGENT
                            <span id="impulse-instagent-status-badge" class="impulse-instagent-status"></span>
                        </div>
                        <div class="impulse-instagent-body" id="impulse-instagent-body">
                            <span class="impulse-instagent-empty">No conversation selected.</span>
                        </div>
                    </div>
                </div>
                
                <!-- Chat settings moved to Settings workspace -->
            </div><!-- End right-content -->
        </div><!-- End chat-right -->
        <!-- Column resize handles -->
        <div class="impulse-chat-resize-handle" data-edge="left"></div>
        <div class="impulse-chat-resize-handle" data-edge="right"></div>
    </div><!-- End impulse-main -->
    </div><!-- End Chat Workspace -->
    <?php endif; ?>
    
    <!-- ============================================================================ -->
    <!-- STORE WORKSPACE -->
    <!-- ============================================================================ -->
    <?php if ($role_manager->canAccessWorkspace('store')) : ?>
    <div class="impulse-workspace" data-workspace="store"<?php echo $workspace_visible !== 'store' ? ' style="display:none"' : ''; ?>>
    <div class="impulse-workspace-grid impulse-store-grid">

        <!-- ==================== LEFT PANEL ==================== -->
        <div class="impulse-panel-left">
            <!-- Nav Tabs (4-tab strip) -->
            <?php
            // Single source of truth for store-nav labels + section visibility.
            // storeUiConfigFor() drives the server render; storeUiConfigMap() is
            // handed to instinctor-admin-store.js (data-store-ui-config) so a live
            // store-type switch relabels/shows the same way without a reload. The
            // two can never drift because they read the one method.
            $_st   = \Instinctor\Core\Config::get('instinctor_store_type', 'mixed');
            $_cfg  = \Instinctor\Core\StoreFeatures::storeUiConfigFor($_st);
            $_lbl  = $_cfg['labels'];
            $_show = $_cfg['show'];
            ?>
            <div class="impulse-store-nav" id="impulse-store-nav" data-store-ui-config="<?php echo esc_attr(wp_json_encode(\Instinctor\Core\StoreFeatures::storeUiConfigMap())); ?>">
                <button type="button" class="impulse-store-nav-btn active" data-store-section="orders"><?php echo esc_html($_lbl['orders']); ?></button>
                <button type="button" class="impulse-store-nav-btn" data-store-section="products" id="store-nav-products-btn"<?php echo !$_show['products'] ? ' style="display:none"' : ''; ?>><?php echo esc_html($_lbl['products']); ?></button>
                <button type="button" class="impulse-store-nav-btn" data-store-section="bookings" id="store-nav-bookings-btn"<?php echo !$_show['bookings'] ? ' style="display:none"' : ''; ?>><?php echo esc_html($_lbl['bookings']); ?></button>
                <button type="button" class="impulse-store-nav-btn" data-store-section="schedule" id="store-nav-schedule-btn"<?php echo !$_show['schedule'] ? ' style="display:none"' : ''; ?>><?php echo esc_html($_lbl['schedule']); ?></button>
                <button type="button" class="impulse-store-nav-btn" data-store-section="staff" id="store-nav-staff-btn"<?php echo !$_show['staff'] ? ' style="display:none"' : ''; ?>><?php echo esc_html($_lbl['staff']); ?></button>
                <button type="button" class="impulse-store-nav-btn" data-store-section="inquiries" id="store-nav-inquiries-btn">Inquiries</button>
            </div>

            <!-- === Orders/Clients/Returns Left === -->
            <div class="impulse-store-left-content" data-section="orders" style="display:flex;flex-direction:column">
                <div class="impulse-scroll" id="orders-status-panel" style="flex:1;min-height:0;overflow-y:auto;display:none">

                    <!-- Orders filters -->
                    <div id="orders-left-block">
                        <div style="padding:10px 12px 4px">
                            <input type="text" id="impulse-orders-search" placeholder="<?php echo esc_attr('Search ' . strtolower(\Instinctor\Core\StoreFeatures::orderListLabel()) . '...'); ?>" style="width:100%;height:26px;padding:0 8px;background:#1a1d21;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;box-sizing:border-box" autocomplete="off" name="search_x<?php echo esc_attr(wp_rand(1000,9999)); ?>" data-lpignore="true" data-form-type="other">
                        </div>
                        <div class="impulse-filter-section" id="orders-filter-section" style="padding:12px 16px">
                            <label class="impulse-filter-option active"><input type="radio" name="order_status_filter" value="all" checked> <?php echo esc_html('All ' . \Instinctor\Core\StoreFeatures::orderListLabel()); ?> <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['all']); ?></span></label>
                            <label class="impulse-filter-option"><input type="radio" name="order_status_filter" value="pending"> Pending <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['pending']); ?></span></label>
                            <label class="impulse-filter-option"><input type="radio" name="order_status_filter" value="processing"> Processing <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['processing']); ?></span></label>
                            <?php if (\Instinctor\Core\StoreFeatures::hasPhysicalProducts()): ?><label class="impulse-filter-option"><input type="radio" name="order_status_filter" value="shipped"> Shipped <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['shipped']); ?></span></label><?php endif; ?>
                            <label class="impulse-filter-option"><input type="radio" name="order_status_filter" value="completed"> Completed <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['completed']); ?></span></label>
                            <label class="impulse-filter-option"><input type="radio" name="order_status_filter" value="refunded"> Refunded <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['refunded']); ?></span></label>
                            <label class="impulse-filter-option"><input type="radio" name="order_status_filter" value="cancelled"> Cancelled <span class="impulse-filter-count"><?php echo esc_html($dashboard_data['status_counts']['cancelled'] ?? 0); ?></span></label>
                        </div>
                        <div style="padding:4px 16px 12px;border-top:1px solid #2a2e33;margin-top:4px">
                            <div style="font-size:10px;text-transform:uppercase;letter-spacing:1px;color:#666;margin:8px 0 6px">Billing</div>
                            <a href="/admin/invoices" style="display:block;font-size:12px;color:#999;text-decoration:none;padding:4px 0">Invoices</a>
                            <a href="/admin/estimates" style="display:block;font-size:12px;color:#999;text-decoration:none;padding:4px 0">Estimates</a>
                        </div>
                    </div>

                    <!-- Returns filters -->
                    <div id="returns-left-block" style="display:none">
                        <div class="impulse-filter-section" id="returns-filter-section" style="padding:12px 16px">
                            <label class="impulse-filter-option active" id="rma-filter-all"><input type="radio" name="rma_status_filter" value="" checked> <?php echo esc_html('All ' . \Instinctor\Core\StoreFeatures::returnsLabel()); ?> <span class="impulse-filter-count" id="rma-count-all">0</span></label>
                            <label class="impulse-filter-option"><input type="radio" name="rma_status_filter" value="pending"> Pending <span class="impulse-filter-count" id="rma-count-pending">0</span></label>
                            <label class="impulse-filter-option"><input type="radio" name="rma_status_filter" value="approved"> Approved <span class="impulse-filter-count" id="rma-count-approved">0</span></label>
                            <label class="impulse-filter-option"><input type="radio" name="rma_status_filter" value="shipped"> Shipped <span class="impulse-filter-count" id="rma-count-shipped">0</span></label>
                            <label class="impulse-filter-option"><input type="radio" name="rma_status_filter" value="refunded"> Refunded <span class="impulse-filter-count" id="rma-count-refunded">0</span></label>
                            <label class="impulse-filter-option"><input type="radio" name="rma_status_filter" value="completed"> Completed <span class="impulse-filter-count" id="rma-count-completed">0</span></label>
                        </div>
                    </div>

                    <!-- Clients filters -->
                    <div id="clients-left-block" style="display:none">
                        <div style="padding:10px 12px 4px">
                            <input type="search" id="clients-search" placeholder="<?php echo esc_attr('Search ' . strtolower(\Instinctor\Core\StoreFeatures::customerNoun()) . '…'); ?>" style="width:100%;height:26px;padding:0 8px;background:#1a1d21;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;box-sizing:border-box" autocomplete="off" data-lpignore="true">
                        </div>
                        <div class="impulse-filter-section" id="clients-filter-section" style="padding:8px 16px">
                            <label class="impulse-filter-option active" data-clients-mode="clients" data-segment="all"><input type="radio" name="clients_nav" value="clients" checked> <?php echo esc_html('All ' . \Instinctor\Core\StoreFeatures::customerNoun()); ?> <span class="impulse-filter-count" id="clients-count-all"></span></label>
<?php if (\Instinctor\Core\StoreFeatures::getStoreType() === 'memberships'): ?>
                            <label class="impulse-filter-option" data-clients-mode="clients" data-segment="active"><input type="radio" name="clients_nav" value="active"> Active <span class="impulse-filter-count" id="clients-count-active"></span></label>
                            <label class="impulse-filter-option" data-clients-mode="clients" data-segment="canceled"><input type="radio" name="clients_nav" value="canceled"> Cancelled <span class="impulse-filter-count" id="clients-count-canceled"></span></label>
                            <label class="impulse-filter-option" data-clients-mode="clients" data-segment="new"><input type="radio" name="clients_nav" value="new"> New <span class="impulse-filter-count" id="clients-count-new"></span></label>
<?php else: ?>
                            <label class="impulse-filter-option" data-clients-mode="clients" data-segment="repeat"><input type="radio" name="clients_nav" value="repeat"> Repeat Buyers <span class="impulse-filter-count" id="clients-count-repeat"></span></label>
                            <label class="impulse-filter-option" data-clients-mode="clients" data-segment="high_value"><input type="radio" name="clients_nav" value="high_value"> High Value <span class="impulse-filter-count" id="clients-count-high_value"></span></label>
                            <label class="impulse-filter-option" data-clients-mode="clients" data-segment="inactive"><input type="radio" name="clients_nav" value="inactive"> Inactive <span class="impulse-filter-count" id="clients-count-inactive"></span></label>
<?php endif; ?>
                        </div>
                    </div>

                </div>
                <div class="impulse-store-left-bottom">
                    <div id="store-stats-revenue">
                        <div class="impulse-section-divider">Revenue</div>
                        <div class="impulse-inventory-stats">
                            <div class="impulse-stat-item"><span class="impulse-stat-num"><?php echo esc_html($dashboard_data['currency'] . number_format($dashboard_data['finance']['today_revenue'], 0)); ?></span><span class="impulse-stat-label">Today</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num"><?php echo esc_html($dashboard_data['finance']['today_orders']); ?></span><span class="impulse-stat-label"><?php echo esc_html(\Instinctor\Core\StoreFeatures::orderListLabel()); ?></span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num"><?php echo esc_html($dashboard_data['currency'] . number_format($dashboard_data['finance']['month_revenue'], 0)); ?></span><span class="impulse-stat-label">Month</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num"><?php echo esc_html($dashboard_data['status_counts']['pending']); ?></span><span class="impulse-stat-label">Pending</span></div>
                        </div>
                    </div>
                    <div id="store-stats-clients" style="display:none">
                        <div class="impulse-section-divider"><?php echo esc_html(\Instinctor\Core\StoreFeatures::customerNoun()); ?></div>
                        <div class="impulse-inventory-stats">
<?php if (\Instinctor\Core\StoreFeatures::getStoreType() === 'memberships'): ?>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-total">—</span><span class="impulse-stat-label">Total</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-active">—</span><span class="impulse-stat-label">Active</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-new">—</span><span class="impulse-stat-label">New (30d)</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-canceled">—</span><span class="impulse-stat-label">Cancelled</span></div>
<?php else: ?>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-total">—</span><span class="impulse-stat-label">Total</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-repeat">—</span><span class="impulse-stat-label">Repeat</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-new">—</span><span class="impulse-stat-label">New (30d)</span></div>
                            <div class="impulse-stat-item"><span class="impulse-stat-num" id="cstat-inactive">—</span><span class="impulse-stat-label">Inactive</span></div>
<?php endif; ?>
                        </div>
                    </div>
                </div>
            </div>

            <!-- === Products Left: Categories (shown only when products bar open) + Inventory at bottom === -->
            <div class="impulse-store-left-content" data-section="products" style="display:none;flex-direction:column">
                <div class="impulse-scroll" id="products-cats-panel" style="flex:1;min-height:0;overflow-y:auto;display:none">
                    <div class="impulse-products-search">
                        <div class="impulse-search-input">
                            <input type="search" id="impulse-products-search" name="impulse_product_filter_q" placeholder="<?php echo esc_attr('Search ' . strtolower(\Instinctor\Core\StoreFeatures::productNoun(true)) . '...'); ?>" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-form-type="other" data-lpignore="true" aria-autocomplete="none">
                        </div>
                    </div>
                    <div class="impulse-products-filters">
                        <div class="impulse-filter-section">
                            <div class="impulse-section-divider" style="margin-top:0;margin-bottom:8px">Categories</div>
                            <div class="impulse-categories-tree" id="impulse-categories-tree">
                                <div class="impulse-loading">Loading...</div>
                            </div>
                            <button type="button" class="impulse-btn-sm" id="impulse-add-category" style="width:100%;margin-top:6px">+ Add Category</button>
                        </div>
                    </div>
                </div>
                <div class="impulse-store-left-bottom">
                    <div class="impulse-section-divider">Inventory</div>
                    <div class="impulse-inventory-stats">
                        <div class="impulse-stat-item" data-filter="all"><span class="impulse-stat-num">0</span><span class="impulse-stat-label">Total</span></div>
                        <div class="impulse-stat-item" data-filter="in_stock"><span class="impulse-stat-num">0</span><span class="impulse-stat-label">In Stock</span></div>
                        <div class="impulse-stat-item" data-filter="low_stock"><span class="impulse-stat-num">0</span><span class="impulse-stat-label">Low</span></div>
                        <div class="impulse-stat-item" data-filter="out_of_stock"><span class="impulse-stat-num">0</span><span class="impulse-stat-label">Out</span></div>
                    </div>
                </div>
            </div>

            <!-- === Bookings Left: mini-calendar + stats === -->
            <div class="impulse-store-left-content" data-section="bookings" style="display:none;flex-direction:column">
                <div class="impulse-scroll" id="bookings-filter-panel" style="flex:1;min-height:0;overflow-y:auto">
                    <div id="bookings-months-scroll" style="padding:6px 30px 8px"></div>
                </div>
                <div style="border-top:1px solid #2a2e33;flex-shrink:0">
                    <div class="impulse-section-divider" style="padding:0 30px">Overview</div>
                    <div class="impulse-inventory-stats" style="padding:0 30px 10px">
                        <div class="impulse-stat-item" id="bstat-today"><span class="impulse-stat-num">—</span><span class="impulse-stat-label">Today</span></div>
                        <div class="impulse-stat-item" id="bstat-pending"><span class="impulse-stat-num">—</span><span class="impulse-stat-label">Pending</span></div>
                        <div class="impulse-stat-item" id="bstat-week"><span class="impulse-stat-num">—</span><span class="impulse-stat-label">This week</span></div>
                        <div class="impulse-stat-item" id="bstat-month"><span class="impulse-stat-num">—</span><span class="impulse-stat-label">This month</span></div>
                    </div>
                </div>
            </div>

            <!-- === Settings Left: General Store Info === -->
            <div class="impulse-store-left-content" data-section="settings" style="display:none;flex-direction:column">
                <?php
                $isg_name         = \Instinctor\Core\Config::get('instinctor_store_name', get_bloginfo('name'));
                $isg_tagline      = \Instinctor\Core\Config::get('instinctor_store_tagline', '');
                $isg_desc         = \Instinctor\Core\Config::get('instinctor_store_description', get_bloginfo('description'));
                $isg_type         = \Instinctor\Core\Config::get('instinctor_store_type', 'mixed');
                $isg_addr1        = \Instinctor\Core\Config::get('instinctor_store_address_1', '');
                $isg_addr2        = \Instinctor\Core\Config::get('instinctor_store_address_2', '');
                $isg_city         = \Instinctor\Core\Config::get('instinctor_store_city', '');
                $isg_state        = \Instinctor\Core\Config::get('instinctor_store_state', '');
                $isg_postcode     = \Instinctor\Core\Config::get('instinctor_store_postcode', '');
                $isg_country      = \Instinctor\Core\Config::get('instinctor_country', 'US');
                $isg_phone        = \Instinctor\Core\Config::get('instinctor_store_phone', '');
                $isg_email        = \Instinctor\Core\Config::get('instinctor_store_email', \Instinctor\Core\Config::get('admin_email'));
                $isg_form_sms     = \Instinctor\Core\Config::get('instinctor_form_notify_sms', '');
                $isg_form_email   = \Instinctor\Core\Config::get('instinctor_lead_notify_email', '');
                $isg_review_url   = \Instinctor\Core\Config::get('instinctor_google_review_url', '');
                $isg_review_msg   = \Instinctor\Core\Config::get('instinctor_review_request_message', '');
                // Private mobile link to the on-the-spot review tool (token-auth, no login).
                $isg_review_token = \Instinctor\Core\Config::get('instinctor_review_tool_token', '');
                if ($isg_review_token === '') { $isg_review_token = bin2hex(random_bytes(18)); \Instinctor\Core\Config::set('instinctor_review_tool_token', $isg_review_token); }
                $isg_review_link  = (function_exists('home_url') ? home_url('/admin/review-request') : '/admin/review-request') . '?k=' . $isg_review_token;
                $isg_types = [
                    'physical_goods' => 'Physical Goods',
                    'digital_goods'  => 'Digital Goods',
                    'services'       => 'Services',
                    'salon'          => 'Beauty / Salon',
                    'instructor'     => 'Instructor (Fitness & Lessons)',
                    'home_services'  => 'Home Services',
                    'automotive'     => 'Automotive',
                    'subscriptions'  => 'Subscriptions',
                    'memberships'    => 'Memberships',
                    'restaurant'     => 'Restaurant',
                    'mixed'          => 'Mixed'];
                $isg_countries = ['US'=>'United States','CA'=>'Canada','GB'=>'United Kingdom','AU'=>'Australia','NZ'=>'New Zealand','AT'=>'Austria','BE'=>'Belgium','BG'=>'Bulgaria','HR'=>'Croatia','CY'=>'Cyprus','CZ'=>'Czech Republic','DK'=>'Denmark','EE'=>'Estonia','FI'=>'Finland','FR'=>'France','DE'=>'Germany','GR'=>'Greece','HU'=>'Hungary','IE'=>'Ireland','IT'=>'Italy','LV'=>'Latvia','LT'=>'Lithuania','LU'=>'Luxembourg','MT'=>'Malta','NL'=>'Netherlands','NO'=>'Norway','PL'=>'Poland','PT'=>'Portugal','RO'=>'Romania','SK'=>'Slovakia','SI'=>'Slovenia','ES'=>'Spain','SE'=>'Sweden','CH'=>'Switzerland','UA'=>'Ukraine','IS'=>'Iceland','RS'=>'Serbia','CN'=>'China','HK'=>'Hong Kong','IN'=>'India','ID'=>'Indonesia','JP'=>'Japan','MY'=>'Malaysia','PH'=>'Philippines','SG'=>'Singapore','KR'=>'South Korea','TW'=>'Taiwan','TH'=>'Thailand','VN'=>'Vietnam','BD'=>'Bangladesh','PK'=>'Pakistan','LK'=>'Sri Lanka','AE'=>'UAE','SA'=>'Saudi Arabia','IL'=>'Israel','TR'=>'Turkey','QA'=>'Qatar','MX'=>'Mexico','BR'=>'Brazil','AR'=>'Argentina','CL'=>'Chile','CO'=>'Colombia','ZA'=>'South Africa','NG'=>'Nigeria','KE'=>'Kenya','RU'=>'Russia'];
                $isp_stripe_pub   = \Instinctor\Core\Config::get('instinctor_stripe_publishable_key', '');
                $isp_stripe_sec   = \Instinctor\Core\Config::get('instinctor_stripe_secret_key', '');
                $isp_stripe_wh    = \Instinctor\Core\Config::get('instinctor_stripe_webhook_secret', '');
                $isp_stripe_conn  = !empty($isp_stripe_pub) && !empty($isp_stripe_sec);
                // Domain reseller (NameSilo) — instinctor.com global, AI Domain Finder. Array option.
                $isp_ns           = (array) \Instinctor\Core\Config::get('instinctor_namesilo', []);
                $isp_ns_key       = (string) ($isp_ns['api_key'] ?? '');
                $isp_ns_base      = (string) ($isp_ns['base'] ?? '');
                $isp_ns_ns1       = (string) ($isp_ns['ns1'] ?? '');
                $isp_ns_ns2       = (string) ($isp_ns['ns2'] ?? '');
                $isp_ns_mpct      = (string) ($isp_ns['markup_pct'] ?? '40');
                $isp_ns_mflat     = (string) ($isp_ns['markup_flat'] ?? '0');
                $isp_ns_conn      = $isp_ns_key !== '';
                $isp_pp_sandbox   = (bool) \Instinctor\Core\Config::get('instinctor_paypal_sandbox', true);
                $isp_pp_client    = \Instinctor\Core\Config::get('instinctor_paypal_client_id', '');
                $isp_pp_secret    = \Instinctor\Core\Config::get('instinctor_paypal_secret', '');
                $isp_pp_conn      = !empty($isp_pp_client) && !empty($isp_pp_secret);
                $isp_an_sandbox   = (bool) \Instinctor\Core\Config::get('instinctor_authorizenet_sandbox', true);
                $isp_an_login     = \Instinctor\Core\Config::get('instinctor_authorizenet_api_login_id', '');
                $isp_an_txkey     = \Instinctor\Core\Config::get('instinctor_authorizenet_transaction_key', '');
                $isp_an_pubkey    = \Instinctor\Core\Config::get('instinctor_authorizenet_public_client_key', '');
                $isp_an_conn      = !empty($isp_an_login) && !empty($isp_an_txkey) && !empty($isp_an_pubkey);
                $isp_cod_enabled      = (bool)   \Instinctor\Core\Config::get('instinctor_cod_enabled', false);
                $isp_cod_instructions = (string) \Instinctor\Core\Config::get('instinctor_cod_instructions', '');
                $isp_bank_enabled     = (bool)   \Instinctor\Core\Config::get('instinctor_bank_transfer_enabled', false);
                $isp_bank_details     = (string) \Instinctor\Core\Config::get('instinctor_bank_transfer_details', '');
                ?>


                <div class="impulse-scroll" style="flex:1;min-height:0;overflow-y:auto;padding:10px 14px 14px">

                    <!-- Store Info — section divider removed; the column itself
                         is the Store Info column, the explicit heading was
                         redundant and added visual noise above the first field. -->
                    <div id="settings-storeinfo-body">
                        <div class="impulse-settings-left-row">
                            <?php /* Labels are business-framed, not store-framed (2026-08-12):
                                     most installs are a salon, a trainer or a plumber, and the
                                     first field a new owner reads should not tell them this is
                                     an ecommerce plugin. The form key stays store_type and the
                                     config key stays instinctor_store_type: everything from
                                     Verticals to Instagent already reads them, same precedent
                                     as the Description field below. */ ?>
                            <label class="field-label">Business type</label>
                            <?php
                            $isg_industry_keys = ['restaurant', 'salon', 'instructor', 'home_services', 'automotive'];
                            $isg_pro_keys      = array_merge(['mixed', 'subscriptions', 'memberships'], $isg_industry_keys);
                            ?>
                            <select name="store_type" id="settings-store-type" class="impulse-settings-input impulse-autosave impulse-sel" data-panel="general" style="width:100%">
                                <option value="" disabled<?php echo empty($isg_type) ? ' selected' : ''; ?>>Business type</option>
                                <optgroup label="Business type">
                                <?php foreach ($isg_types as $val => $label): if (in_array($val, $isg_industry_keys, true)) continue; ?>
                                <option value="<?php echo esc_attr($val); ?>"<?php echo in_array($val, $isg_pro_keys, true) ? ' data-pro-type="1"' : ''; ?><?php selected($isg_type, $val); ?>><?php echo esc_html($label); ?></option>
                                <?php endforeach; ?>
                                </optgroup>
                                <optgroup label="Industry">
                                <?php foreach ($isg_types as $val => $label): if (!in_array($val, $isg_industry_keys, true)) continue; ?>
                                <option value="<?php echo esc_attr($val); ?>" data-pro-type="1"<?php selected($isg_type, $val); ?>><?php echo esc_html($label); ?></option>
                                <?php endforeach; ?>
                                </optgroup>
                            </select>
                        </div>
                        <?php  ?>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Business name</label>
                            <input type="text" name="store_name" value="<?php echo esc_attr($isg_name); ?>" placeholder="Business name" class="impulse-settings-input impulse-autosave" data-panel="general" style="height:26px;box-sizing:border-box">
                        </div>
                        <div class="impulse-settings-left-row">
                            <!-- Tagline — short one-liner used in the site footer
                                 and any other "what is this site?" surface that
                                 needs a single sentence. Kept separate from
                                 Description (below) because they have
                                 incompatible needs: the footer wants ~6 words,
                                 Instagent / SEO meta-description want a real
                                 paragraph. One field for both would either
                                 bloat the footer or starve the AI/SEO
                                 prompts — so two fields, two purposes. -->
                            <label class="field-label">Tagline</label>
                            <input type="text" name="store_tagline" value="<?php echo esc_attr($isg_tagline); ?>" placeholder="A short one-liner (e.g. The web production platform)" class="impulse-settings-input impulse-autosave" data-panel="general" style="height:26px;box-sizing:border-box">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Description</label>
                            <!-- The field key stays store_description (and the config key
                                 instinctor_store_description) — both AIContentService
                                 (Instagent prompts) and SEOService (meta descriptions)
                                 already read from it, so renaming the label only
                                 surfaces what's actually there. The earlier "Tagline"
                                 label hid the fact that THIS is the field Instagent
                                 needs and made site owners think no description field
                                 existed. impulse-autoexpand grows the textarea
                                 vertically as the user types past one line. -->
                            <textarea name="store_description" rows="2" placeholder="A few sentences about your business — what you sell, who it's for, what makes you different. Used by Instagent when generating sections and as your SEO meta description." class="impulse-settings-input impulse-autosave impulse-autoexpand" data-panel="general" style="width:100%;min-height:52px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:4px 8px;font-size:11px;box-sizing:border-box;resize:none;display:block;line-height:1.5;overflow:hidden"><?php echo esc_textarea($isg_desc); ?></textarea>
                        </div>
                        <?php
                        // Site Logo - standalone only. WordPress already exposes Site
                        // Identity via the Customizer. impulse_site_logo_url is read by
                        // MarketingShell::nav() and the Impulse nav block. The favicon is
                        // GENERATED from the logo on save (AdminController
                        // ajaxImpulseSaveSettings -> generateFaviconFromLogo), stored in
                        // instinctor_favicon_url and consumed by impulse-page.php,
                        // MarketingShell::render(), AdminShell and the /favicon.ico
                        // route. Empty logo falls back to the bundled Instinctor mark.
                        if (defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone'):
                            $isg_logo_url = (string) \Instinctor\Core\Config::get('instinctor_site_logo_url', '');
                            $_brand_swatch_btn_style = 'flex:1;min-width:0;height:48px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#888;padding:0;font-size:11px;overflow:hidden';
                            $_brand_remove_btn_style = 'position:absolute;top:-6px;right:-6px;width:16px;height:16px;border-radius:50%;background:#1d2327;border:1px solid #3a3f44;color:#999;cursor:pointer;display:none;align-items:center;justify-content:center;padding:0;line-height:0';
                        ?>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Logo</label>
                            <div style="position:relative">
                                <button type="button" id="settings-brand-logo-btn" class="settings-brand-pick" data-label="Site logo" style="<?php echo esc_attr($_brand_swatch_btn_style); ?>;width:100%">
                                    <?php if ($isg_logo_url): ?>
                                        <img id="settings-brand-logo-preview" src="<?php echo esc_url($isg_logo_url); ?>" style="max-width:100%;max-height:46px;object-fit:contain">
                                    <?php else: ?>
                                        <span id="settings-brand-logo-preview">+ Site Logo</span>
                                    <?php endif; ?>
                                </button>
                                <button type="button" id="settings-brand-logo-clear" class="settings-brand-clear" title="Remove" style="<?php echo esc_attr($_brand_remove_btn_style); ?><?php echo $isg_logo_url ? ';display:flex' : ''; ?>">
                                    <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                                </button>
                                <input type="hidden" name="site_logo_url" id="settings-brand-logo-url" value="<?php echo esc_attr($isg_logo_url); ?>" class="impulse-autosave" data-panel="general">
                            </div>
                            <div style="font-size:11px;color:#555;margin:4px 0 0">The favicon is generated automatically from the logo.</div>
                        </div>
                        <?php // Logo swatch wiring moved to InstinctorAdmin.initBrandLogoSwatch() in assets/js/admin.js (WordPress.org compliance). ?>
                        <?php endif; // standalone-only logo ?>
                        <?php
                        // Brand profile fields — feed the Instagent (AI Section Generator) store-level context.
                        // Industry is a vocab-controlled dropdown so Claude can filter templates by
                        // `industries` tag; audience + tone are free-text / preset briefs.
                        $isg_industry   = \Instinctor\Core\Config::get('instinctor_store_industry',   '');
                        $isg_audience   = \Instinctor\Core\Config::get('instinctor_store_audience',   '');
                        $isg_tone       = \Instinctor\Core\Config::get('instinctor_store_tone',       '');
                        $isg_valueprop  = \Instinctor\Core\Config::get('instinctor_store_value_prop', '');
                        $isg_primarycta = \Instinctor\Core\Config::get('instinctor_store_primary_cta','');
                        $isg_primary    = \Instinctor\Core\Config::get('instinctor_store_primary_color', '#1d2327');
                        $isg_accent     = \Instinctor\Core\Config::get('instinctor_store_accent_color',  '#1d2327');
                        $isg_voicesample= \Instinctor\Core\Config::get('instinctor_store_voice_sample',  '');
                        $isg_locale     = \Instinctor\Core\Config::get('instinctor_store_locale',        'en');
                        // Migrate legacy regional codes (en-US, en-GB, ...) to flat language code.
                        if (strpos((string) $isg_locale, '-') !== false) { $isg_locale = strtolower(substr((string) $isg_locale, 0, 2)); }
                        // Industry feeds Instagent's section-template ranking and copy
                        // tone — granular categories produce sharper output. The custom
                        // dropdown hides its scrollbar (instinctor-admin.css), so length
                        // doesn't add UI cost. Keep alphabetised for findability.
                        $isg_industries = [
                            ''               => 'Industry',
                            'agriculture'    => 'Agriculture',
                            'automotive'     => 'Automotive',
                            'beauty'         => 'Beauty / cosmetics',
                            'coaching'       => 'Coaching / personal brand',
                            'construction'   => 'Construction / trades',
                            'consulting'     => 'Consulting / professional services',
                            'creative'       => 'Creative / portfolio',
                            'ecommerce'      => 'E-commerce / retail',
                            'education'      => 'Education / training',
                            'entertainment'  => 'Entertainment / events',
                            'fashion'        => 'Fashion / apparel',
                            'financial'      => 'Financial services',
                            'fitness'        => 'Fitness / sports',
                            'food'           => 'Food & beverage',
                            'health'         => 'Healthcare / medical',
                            'hospitality'    => 'Hospitality / travel / restaurants',
                            'legal'          => 'Legal services',
                            'manufacturing'  => 'Manufacturing / industrial',
                            'marketing'      => 'Marketing / advertising',
                            'media'          => 'Media / publishing',
                            'music'          => 'Music / audio',
                            'nonprofit'      => 'Non-profit / charity',
                            'photo_video'    => 'Photography / video',
                            'realestate'     => 'Real estate',
                            'saas'           => 'SaaS / tech',
                            'wellness'       => 'Wellness / spa',
                            'other'          => 'Other',
                        ];
                        ?>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Industry</label>
                            <select name="store_industry" class="impulse-settings-input impulse-autosave impulse-sel" data-panel="general" style="width:100%;height:26px;box-sizing:border-box">
                                <?php foreach ($isg_industries as $val => $label): ?>
                                <option value="<?php echo esc_attr($val); ?>"<?php selected($isg_industry, $val); ?>><?php echo esc_html($label); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Audience</label>
                            <textarea name="store_audience" rows="1" placeholder="e.g. urban professionals, 25–45" class="impulse-settings-input impulse-autosave impulse-autoexpand" data-panel="general" style="width:100%;height:26px;min-height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:4px 8px;font-size:11px;box-sizing:border-box;resize:none;display:block;line-height:1.5;overflow:hidden"><?php echo esc_textarea($isg_audience); ?></textarea>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Value proposition</label>
                            <textarea name="store_value_prop" rows="1" placeholder="One sentence: what you offer, plainly" class="impulse-settings-input impulse-autosave impulse-autoexpand" data-panel="general" style="width:100%;height:26px;min-height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:4px 8px;font-size:11px;box-sizing:border-box;resize:none;display:block;line-height:1.5;overflow:hidden"><?php echo esc_textarea($isg_valueprop); ?></textarea>
                        </div>
                        <?php
                        // Primary CTA — the dominant action verb across the brand. Drives
                        // Instagent's button copy strategy ("Start your pack" vs "Book a class"
                        // vs "Apply now") and informs hero subhead phrasing.
                        // Primary CTA — drives Instagent's button copy strategy. Custom
                        // dropdown hides its scrollbar so a long list is fine.
                        $isg_ctas = [
                            ''            => 'Primary CTA',
                            'buy'         => 'Buy / Order',
                            'add_to_cart' => 'Add to cart',
                            'subscribe'   => 'Subscribe',
                            'signup'      => 'Sign up',
                            'register'    => 'Register / Create account',
                            'book'        => 'Book a call',
                            'schedule'    => 'Schedule a meeting',
                            'reserve'     => 'Reserve / Make a reservation',
                            'apply'       => 'Apply',
                            'enroll'      => 'Enroll / Join',
                            'inquire'     => 'Inquire / Get a quote',
                            'request_demo'=> 'Request a demo',
                            'contact'     => 'Contact us',
                            'download'    => 'Download',
                            'learn_more'  => 'Read more / Learn',
                            'donate'      => 'Donate',
                            'support'     => 'Support / Pledge',
                            'volunteer'   => 'Volunteer',
                            'follow'      => 'Follow / Subscribe to updates',
                        ];
                        ?>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Primary CTA</label>
                            <select name="store_primary_cta" class="impulse-settings-input impulse-autosave impulse-sel" data-panel="general" style="width:100%;height:26px;box-sizing:border-box">
                                <?php foreach ($isg_ctas as $val => $label): ?>
                                <option value="<?php echo esc_attr($val); ?>"<?php selected($isg_primarycta, $val); ?>><?php echo esc_html($label); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <?php
                        // Tone presets — short list (under 8) so the native select doesn't
                        // scrollbar. The value strings are what Claude reads in the system
                        // prompt as "brand tone"; keep them descriptive (multi-word) so
                        // they survive into the prompt as useful guidance.
                        $isg_tones = [
                            ''                                  => 'Tone',
                            'minimal quiet premium'             => 'Minimal & quiet',
                            'warm friendly hand-crafted'        => 'Warm & friendly',
                            'bold punchy energetic'             => 'Bold & punchy',
                            'professional precise direct'       => 'Professional & precise',
                            'playful casual conversational'     => 'Playful & casual',
                            'cinematic premium aspirational'    => 'Cinematic & premium',
                            'technical confident matter-of-fact'=> 'Technical & confident',
                        ];
                        ?>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Tone</label>
                            <select name="store_tone" class="impulse-settings-input impulse-autosave impulse-sel" data-panel="general" style="width:100%;height:26px;box-sizing:border-box">
                                <?php foreach ($isg_tones as $val => $label): ?>
                                <option value="<?php echo esc_attr($val); ?>"<?php selected($isg_tone, $val); ?>><?php echo esc_html($label); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Voice sample</label>
                            <textarea name="store_voice_sample" rows="1" placeholder="Optional — paste 1–2 sentences of existing brand copy" class="impulse-settings-input impulse-autosave impulse-autoexpand" data-panel="general" style="width:100%;height:26px;min-height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:4px 8px;font-size:11px;box-sizing:border-box;resize:none;display:block;line-height:1.5;overflow:hidden"><?php echo esc_textarea($isg_voicesample); ?></textarea>
                        </div>
                        <?php
                        // Locale drives the language Instagent writes in. One entry per
                        // language — regional variants don't change copy in any meaningful
                        // way for Claude, so keep the list flat.
                        $isg_locales = [
                            'en' => 'English',
                            'es' => 'Español',
                            'fr' => 'Français',
                            'de' => 'Deutsch',
                            'it' => 'Italiano',
                            'pt' => 'Português',
                            'nl' => 'Nederlands',
                            'sv' => 'Svenska',
                            'no' => 'Norsk',
                            'da' => 'Dansk',
                            'fi' => 'Suomi',
                            'pl' => 'Polski',
                            'cs' => 'Čeština',
                            'el' => 'Ελληνικά',
                            'tr' => 'Türkçe',
                            'ru' => 'Русский',
                            'uk' => 'Українська',
                            'ar' => 'العربية',
                            'he' => 'עברית',
                            'fa' => 'فارسی',
                            'hi' => 'हिन्दी',
                            'th' => 'ไทย',
                            'vi' => 'Tiếng Việt',
                            'id' => 'Bahasa Indonesia',
                            'ms' => 'Bahasa Melayu',
                            'tl' => 'Filipino',
                            'zh' => '中文',
                            'ja' => '日本語',
                            'ko' => '한국어',
                        ];
                        ?>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Language</label>
                            <select name="store_locale" class="impulse-settings-input impulse-autosave impulse-sel" data-panel="general" style="width:100%;height:26px;box-sizing:border-box">
                                <?php foreach ($isg_locales as $val => $label): ?>
                                <option value="<?php echo esc_attr($val); ?>"<?php selected($isg_locale, $val); ?>><?php echo esc_html($label); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div id="settings-storeinfo-address">
                            <div class="impulse-settings-left-row">
                                <label class="field-label">Street address</label>
                                <input type="text" name="store_address_1" value="<?php echo esc_attr($isg_addr1); ?>" placeholder="123 Main St" class="impulse-settings-input impulse-autosave" data-panel="general" style="height:26px;box-sizing:border-box">
                            </div>
                            <div class="impulse-settings-left-row">
                                <label class="field-label">Suite / Unit (optional)</label>
                                <input type="text" name="store_address_2" value="<?php echo esc_attr($isg_addr2); ?>" placeholder="Suite 200" class="impulse-settings-input impulse-autosave" data-panel="general" style="height:26px;box-sizing:border-box">
                            </div>
                            <div class="impulse-settings-left-row">
                                <label class="field-label">City &amp; state</label>
                                <div style="display:flex;gap:5px">
                                <input type="text" name="store_city" value="<?php echo esc_attr($isg_city); ?>" placeholder="City" class="impulse-settings-input impulse-autosave" data-panel="general" style="flex:1;min-width:0">
                                <input type="text" name="store_state" value="<?php echo esc_attr($isg_state); ?>" placeholder="ST" class="impulse-settings-input impulse-autosave" data-panel="general" style="width:44px;flex-shrink:0">
                                </div>
                            </div>
                            <div class="impulse-settings-left-row">
                                <label class="field-label">Postcode &amp; country</label>
                                <div style="display:flex;gap:5px">
                                <input type="text" name="store_postcode" value="<?php echo esc_attr($isg_postcode); ?>" placeholder="ZIP" class="impulse-settings-input impulse-autosave" data-panel="general" style="width:64px;flex-shrink:0">
                                <input type="hidden" name="store_country" id="store-country-value" class="impulse-autosave" data-panel="general" value="<?php echo esc_attr($isg_country); ?>">
                                <div class="impulse-country-dropdown" id="store-country-wrap" style="flex:1;min-width:0;position:relative">
                                    <input type="text" id="store-country-search" autocomplete="off" placeholder="<?php echo esc_attr($isg_countries[$isg_country] ?? 'Country'); ?>" value="<?php echo esc_attr($isg_countries[$isg_country] ?? ''); ?>" style="width:100%;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:0 24px 0 8px;font-size:11px;box-sizing:border-box;cursor:pointer" readonly>
                                    <svg style="position:absolute;right:6px;top:50%;transform:translateY(-50%);pointer-events:none;color:#999" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
                                    <div id="store-country-list" style="display:none;position:absolute;top:100%;left:0;right:0;z-index:9999;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;margin-top:2px;overflow:hidden">
                                        <input type="text" id="store-country-filter" placeholder="Search..." autocomplete="off" style="width:100%;height:26px;background:#1a1d21;border:none;border-bottom:1px solid #3a3f44;color:#e0e0e0;padding:0 8px;font-size:11px;box-sizing:border-box;outline:none">
                                        <div id="store-country-options" style="max-height:160px;overflow-y:auto;scrollbar-width:none;-ms-overflow-style:none">
                                            <?php foreach ($isg_countries as $code => $clabel): ?>
                                            <div class="store-country-opt" data-code="<?php echo esc_attr($code); ?>" style="padding:5px 8px;font-size:11px;color:#e0e0e0;cursor:pointer<?php echo $code === $isg_country ? ';background:#3a3f44' : ''; ?>"><?php echo esc_html($clabel); ?></div>
                                            <?php endforeach; ?>
                                        </div>
                                    </div>
                                </div>
                                </div>
                            </div>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Support email</label>
                            <input type="email" name="store_email" value="<?php echo esc_attr($isg_email); ?>" placeholder="hello@example.com" class="impulse-settings-input impulse-autosave" data-panel="general">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Phone (optional)</label>
                            <input type="tel" name="store_phone" value="<?php echo esc_attr($isg_phone); ?>" placeholder="+1 555 123 4567" class="impulse-settings-input impulse-autosave" data-panel="general">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Inquiry alerts (SMS)</label>
                            <input type="tel" name="form_notify_sms" value="<?php echo esc_attr($isg_form_sms); ?>" placeholder="+1 555 123 4567" class="impulse-settings-input impulse-autosave" data-panel="general">
                            <div style="font-size:10px;color:#777;margin-top:4px">Texted to this number whenever someone submits a form. Leave blank to turn off.</div>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Inquiry alerts (email)</label>
                            <input type="text" name="lead_notify_email" value="<?php echo esc_attr($isg_form_email); ?>" placeholder="you@example.com, partner@example.com" class="impulse-settings-input impulse-autosave" data-panel="general">
                            <div style="font-size:10px;color:#777;margin-top:4px">Where form submissions are emailed. Separate several addresses with commas. Leave blank to use the site admin address.</div>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Google review link</label>
                            <input type="url" name="google_review_url" value="<?php echo esc_attr($isg_review_url); ?>" placeholder="https://g.page/r/..." class="impulse-settings-input impulse-autosave" data-panel="general">
                            <div style="font-size:10px;color:#777;margin-top:4px">Your Google "write a review" link. Powers the Request-a-Review tool (QR + text) at /admin/review-request.</div>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Review request message</label>
                            <input type="text" name="review_request_message" value="<?php echo esc_attr($isg_review_msg); ?>" placeholder="Thanks for visiting {business}! Leave us a review: {link}" class="impulse-settings-input impulse-autosave" data-panel="general">
                            <div style="font-size:10px;color:#777;margin-top:4px">{business} and {link} are filled in automatically.</div>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label class="field-label">Review tool (for your phone)</label>
                            <div style="display:flex;gap:12px;align-items:flex-start">
                                <div data-instinctor-qr="<?php echo esc_attr($isg_review_link); ?>" data-qr-size="86" role="img" aria-label="Review tool QR" style="width:96px;height:96px;background:#fff;padding:5px;border-radius:6px;flex-shrink:0;box-sizing:border-box"></div>
                                <div style="flex:1;min-width:0">
                                    <input type="text" readonly value="<?php echo esc_attr($isg_review_link); ?>" onclick="this.select()" class="impulse-settings-input" style="height:26px;box-sizing:border-box;cursor:pointer">
                                    <div style="font-size:10px;color:#777;margin-top:4px">Scan with your phone (or copy the link), then add it to your home screen. Opens the on-the-spot Request-a-Review tool: no login needed.</div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Social Profiles (rendered by JS) -->
                    <div class="impulse-section-divider">Social Profiles</div>
                    <div id="store-seo-settings-left">
                        <div style="padding:10px 0;text-align:center;color:#555;font-size:11px">Loading…</div>
                    </div>

                    <!-- Local Business Schema (rendered by JS) -->
                    <div id="store-lb-schema-wrap" style="display:none">
                        <div class="impulse-section-divider">Local Business Schema</div>
                        <div id="store-lb-schema-content"></div>
                    </div>

                    <!-- Downloads — digital_goods + mixed only -->
                    <div id="settings-section-downloads" style="display:none">
                        <div class="impulse-section-divider">Downloads</div>
                        <div class="impulse-settings-left-row" style="display:flex;gap:6px;align-items:center">
                            <input type="number" name="dd_default_limit" value="<?php echo esc_attr(\Instinctor\Core\Config::get('instinctor_dd_default_limit','')); ?>" placeholder="∞" class="impulse-settings-input impulse-autosave" data-panel="general" style="width:52px;text-align:right">
                            <span style="font-size:11px;color:#888">Limit</span>
                            <span style="flex:1"></span>
                            <span style="font-size:11px;color:#888">Day expiry</span>
                            <input type="number" name="dd_default_expiry" value="<?php echo esc_attr(\Instinctor\Core\Config::get('instinctor_dd_default_expiry','')); ?>" placeholder="∞" class="impulse-settings-input impulse-autosave" data-panel="general" style="width:52px;text-align:right">
                        </div>
                        <div class="impulse-settings-left-row">
                            <input type="text" name="dd_email_subject" value="<?php echo esc_attr(\Instinctor\Core\Config::get('instinctor_dd_email_subject','Your download is ready')); ?>" placeholder="Download email subject" class="impulse-settings-input impulse-autosave" data-panel="general">
                        </div>
                    </div>

                    <!-- Return Policy -->
                    <div id="settings-section-returns" style="display:none">
                        <div class="impulse-section-divider">Return Policy</div>
                        <div class="impulse-settings-left-row" style="display:flex;gap:6px;align-items:center">
                            <input type="text" name="return_days" value="<?php echo esc_attr(\Instinctor\Core\Config::get('instinctor_return_days', 30)); ?>" class="impulse-autosave" data-panel="general" style="width:52px;text-align:right">
                            <span style="font-size:11px;color:#888">Day window</span>
                            <span style="flex:1"></span>
                            <span style="font-size:11px;color:#888">% restock</span>
                            <input type="text" name="restocking_fee" value="<?php echo esc_attr(\Instinctor\Core\Config::get('instinctor_restocking_fee', 0)); ?>" class="impulse-autosave" data-panel="general" style="width:44px;text-align:right">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="display:flex;align-items:center;justify-content:space-between;font-size:11px;color:#999;cursor:pointer;gap:8px">
                                <span>Auto-approve return request</span>
                                <input type="checkbox" name="rma_auto_approve" class="impulse-autosave" data-panel="general"<?php checked((bool) \Instinctor\Core\Config::get('instinctor_rma_auto_approve', false)); ?> style="margin:0;flex-shrink:0">
                            </label>
                        </div>
                    </div>

                    <!-- Checkout Options -->
                    <div class="impulse-section-divider" style="margin-top:16px">Checkout</div>
                    <div class="impulse-settings-left-row impulse-checkbox-group" style="display:flex;flex-direction:column;gap:6px">
                        <label class="impulse-checkbox-row" style="display:flex;align-items:center;gap:6px;font-size:11px;color:#999;cursor:pointer">
                            <input type="checkbox" name="guest_checkout" class="impulse-autosave" data-panel="general"<?php checked((bool) \Instinctor\Core\Config::get('instinctor_guest_checkout', true)); ?>>
                            <span>Allow guest checkout</span>
                        </label>
                        <label class="impulse-checkbox-row" style="display:flex;align-items:center;gap:6px;font-size:11px;color:#999;cursor:pointer">
                            <input type="checkbox" name="create_account" class="impulse-autosave" data-panel="general"<?php checked((bool) \Instinctor\Core\Config::get('instinctor_create_account', true)); ?>>
                            <span>Allow account creation</span>
                        </label>
                        <label class="impulse-checkbox-row" style="display:flex;align-items:center;gap:6px;font-size:11px;color:#999;cursor:pointer">
                            <input type="checkbox" name="show_coupon" class="impulse-autosave" data-panel="general"<?php checked((bool) \Instinctor\Core\Config::get('instinctor_show_coupon', true)); ?>>
                            <span>Show coupon field</span>
                        </label>
                        <label class="impulse-checkbox-row" style="display:flex;align-items:center;gap:6px;font-size:11px;color:#999;cursor:pointer">
                            <input type="checkbox" name="show_gift_card" class="impulse-autosave" data-panel="general"<?php checked((bool) \Instinctor\Core\Config::get('instinctor_show_gift_card', true)); ?>>
                            <span>Show gift card field</span>
                        </label>
                        <label class="impulse-checkbox-row" style="display:flex;align-items:center;gap:6px;font-size:11px;color:#999;cursor:pointer">
                            <input type="checkbox" name="email_first" class="impulse-autosave" data-panel="general"<?php checked((bool) \Instinctor\Core\Config::get('instinctor_email_first', true)); ?>>
                            <span>Collect email before checkout</span>
                        </label>
                    </div>

                    <!-- Currencies -->
                    <div class="impulse-section-divider" style="margin-top:16px">Currencies</div>
                    <div id="currency-list-wrap">
                        <div style="font-size:11px;color:#555;text-align:center;padding:12px 0">Loading...</div>
                    </div>

                    </div><!-- /settings scroll -->

            </div>
        </div><!-- End Left Panel -->

        <!-- ==================== CENTER PANEL ==================== -->
        <div class="impulse-panel-center">

            <!-- === Orders / Clients / Returns Center === -->
            <div class="impulse-store-section" data-section="orders" style="display:flex;flex-direction:column;min-height:0">
                <!-- Three-tab toolbar -->
                <div style="flex-shrink:0;height:38px;background:#2a2e33;border-bottom:1px solid #3a3f44;display:flex;align-items:center;padding:0 30px;gap:0;position:relative;z-index:2">
<?php if (\Instinctor\Core\StoreFeatures::getStoreType() !== 'memberships'): ?>
                    <button type="button" id="orders-mode-orders" class="impulse-btn-sm active" style="font-size:11px;border-radius:3px 0 0 3px"><?php echo esc_html(\Instinctor\Core\StoreFeatures::orderListLabel()); ?></button>
                    <button type="button" id="orders-mode-clients" class="impulse-btn-sm" style="font-size:11px;border-radius:0"><?php echo esc_html(\Instinctor\Core\StoreFeatures::customerNoun()); ?></button>
                    <button type="button" id="orders-mode-returns" class="impulse-btn-sm" style="font-size:11px;border-radius:0 3px 3px 0"><?php echo esc_html(\Instinctor\Core\StoreFeatures::returnsLabel()); ?></button>
<?php endif; ?>
                    <div id="orders-col-toggles" style="display:flex;gap:10px;align-items:center;margin-left:auto">
                        <label style="display:flex;align-items:center;gap:4px;font-size:11px;color:#888;cursor:pointer;user-select:none"><input type="checkbox" id="col-show-date" style="margin:0;cursor:pointer"> Date</label>
                    </div>
                    <div id="clients-toolbar-extra" style="display:none;margin-left:auto">
                        <span id="clients-toolbar-count" style="font-size:11px;color:#555;margin-right:8px"></span>
                    </div>
                </div>
                <!-- Sort header -->
                <div id="orders-sort-header" style="flex-shrink:0;display:flex;align-items:center;height:26px;padding:0 30px;background:#1a1d21;border-bottom:1px solid #3a3f44;font-size:11px;color:#888;user-select:none;gap:8px;position:relative;z-index:2">
                    <span style="width:95px;flex-shrink:0"></span>
                    <span class="orders-sort-col" data-sort="customer" style="flex:1;cursor:pointer;display:flex;align-items:center;gap:3px"><?php echo esc_html(\Instinctor\Core\StoreFeatures::customerNoun(false)); ?></span>
                    <span class="orders-sort-col" data-sort="status" style="width:90px;text-align:center;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:3px">Status</span>
                    <span class="orders-sort-col active" data-sort="date" style="width:80px;text-align:right;cursor:pointer;display:flex;align-items:center;justify-content:flex-end;gap:3px">Date <svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor" class="sort-arrow desc"><path d="M4 6L1 2h6z"/></svg></span>
                    <span class="orders-sort-col" data-sort="total" style="width:70px;text-align:right;cursor:pointer;display:flex;align-items:center;justify-content:flex-end;gap:3px">Amount</span>
                </div>
                <!-- Orders list -->
                <ul class="impulse-list impulse-scroll" id="dashboard-orders-list" style="flex:1;min-height:0;margin:0">
                    <li style="padding:20px;text-align:center;color:#555;font-size:11px">Loading orders...</li>
                </ul>
                <!-- Returns list -->
                <ul class="impulse-list impulse-scroll" id="dashboard-returns-list" style="flex:1;min-height:0;margin:0;display:none">
                    <li style="padding:20px;text-align:center;color:#555;font-size:11px">Loading returns...</li>
                </ul>
                <!-- Clients list -->
                <ul class="impulse-list impulse-scroll" id="clients-center-list" style="flex:1;min-height:0;margin:0;display:none">
                    <li style="padding:20px;text-align:center;color:#555;font-size:11px">Loading…</li>
                </ul>
            </div>

            <!-- === Products Center === -->
            <div class="impulse-store-section" data-section="products" style="display:none;flex-direction:column;min-height:0">
                <!-- Top bar: Products/Bundles toggle + contextual controls -->
                <div style="flex-shrink:0;height:38px;background:#2a2e33;border-bottom:1px solid #3a3f44;display:flex;align-items:center;padding:0 30px;gap:0;position:relative;z-index:2">
                    <button type="button" id="products-mode-products" class="impulse-btn-sm active" style="font-size:11px;border-radius:3px 0 0 3px"><?php echo esc_html(\Instinctor\Core\StoreFeatures::productNoun(true)); ?></button>
                    <button type="button" id="products-mode-bundles" class="impulse-btn-sm" style="font-size:11px;border-radius:0 3px 3px 0">Bundles</button>
                    <!-- Products-mode right controls -->
                    <div id="products-topbar-controls" style="display:flex;align-items:center;gap:4px;margin-left:auto">
                        <div class="impulse-products-status-tabs" style="display:flex">
                            <button type="button" class="impulse-status-tab" data-status="all">All</button>
                            <button type="button" class="impulse-status-tab active" data-status="published">Published</button>
                            <button type="button" class="impulse-status-tab" data-status="draft">Draft</button>
                            <button type="button" class="impulse-status-tab" data-status="archived">Archived</button>
                        </div>
                        <div class="impulse-products-actions">
                            <div class="impulse-size-slider" id="impulse-product-size-slider">
                                <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
                                <input type="range" id="impulse-product-card-size" min="140" max="350" value="200">
                                <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>
                            </div>
                            <button type="button" class="impulse-view-toggle" data-view="table" title="Table View"><svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" fill="none" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></button>
                            <button type="button" class="impulse-view-toggle active" data-view="cards" title="Card View"><svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg></button>
                        </div>
                    </div>
                    <!-- Bundles-mode right controls -->
                    <div id="bundles-toolbar-extra" style="display:none;margin-left:auto">
                        <button type="button" id="bundles-new-btn" class="impulse-btn-sm">+ New Bundle</button>
                    </div>
                </div>
                <!-- Products tab content -->
                <div id="products-tab-content" style="flex:1;min-height:0;overflow:hidden;display:flex;flex-direction:column">
                    <div id="products-bar-card" data-feature="products" data-section="products" style="flex:1;min-height:0;display:flex;flex-direction:column">
                        <div class="impulse-bulk-toolbar" id="impulse-bulk-toolbar" style="display:none;">
                            <span class="impulse-bulk-count">0 selected</span>
                            <div class="impulse-bulk-actions">
                                <button type="button" class="impulse-bulk-btn impulse-bulk-ai-btn" data-action="ai_generate" data-tip="Generate AI content for selected products"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg> AI</button>
                                <button type="button" class="impulse-bulk-btn" data-action="publish">Publish</button>
                                <button type="button" class="impulse-bulk-btn" data-action="draft">Draft</button>
                                <button type="button" class="impulse-bulk-btn" data-action="archive">Archive</button>
                                <button type="button" class="impulse-bulk-btn impulse-bulk-btn-danger" data-action="delete">Delete</button>
                            </div>
                            <button type="button" class="impulse-bulk-clear">Clear</button>
                        </div>
                        <div class="impulse-products-list" id="impulse-products-list" style="flex:1;overflow-y:auto">
                            <div class="impulse-loading">Loading products...</div>
                        </div>
                    </div>

                </div>
                <!-- Bundles tab content -->
                <ul class="impulse-list impulse-scroll" id="bundles-center-list" style="flex:1;min-height:0;margin:0;display:none">
                    <li style="padding:20px;text-align:center;color:#555;font-size:11px">Loading…</li>
                </ul>
            </div>


            <!-- === Settings Center === -->
            <!-- === Bookings Center === -->
            <div class="impulse-store-section" data-section="bookings" style="display:none;flex-direction:column;min-height:0">
                <!-- Top bar: status tabs -->
                <div style="flex-shrink:0;height:38px;background:#2a2e33;border-bottom:1px solid #3a3f44;display:flex;align-items:center;padding:0 30px;gap:0;position:relative;z-index:2">
                    <div class="impulse-products-status-tabs" style="display:flex">
                        <button type="button" class="impulse-status-tab active" data-bstatus="upcoming">Upcoming</button>
                        <button type="button" class="impulse-status-tab" data-bstatus="pending">Pending</button>
                        <button type="button" class="impulse-status-tab" data-bstatus="confirmed">Confirmed</button>
                        <button type="button" class="impulse-status-tab" data-bstatus="completed">Completed</button>
                        <button type="button" class="impulse-status-tab" data-bstatus="cancelled">Cancelled</button>
                        <button type="button" class="impulse-status-tab" data-bstatus="all">All</button>
                    </div>
                </div>
                <!-- Bookings list -->
                <div class="impulse-panel-body impulse-scroll" id="bookings-list" style="flex:1;min-height:0;overflow-y:auto">
                    <div class="impulse-loading">Loading bookings...</div>
                </div>
            </div>

            <!-- === Inquiries (form submissions) === -->
            <div class="impulse-store-section" data-section="inquiries" style="display:none;flex-direction:column;min-height:0">
                <div style="flex-shrink:0;height:38px;background:#2a2e33;border-bottom:1px solid #3a3f44;display:flex;align-items:center;justify-content:space-between;padding:0 30px;position:relative;z-index:2">
                    <span style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:#888"><span id="inquiries-count">0</span> Inquiries</span>
                    <a id="inquiries-export" href="/admin/inquiries?format=csv" style="font-size:11px;color:#999;text-decoration:none;border:1px solid #3a3f44;border-radius:4px;padding:4px 10px">Export CSV</a>
                </div>
                <div class="impulse-panel-body impulse-scroll" id="inquiries-list" style="flex:1;min-height:0;overflow-y:auto;padding:14px 18px">
                    <div class="impulse-loading">Loading inquiries...</div>
                </div>
            </div>

            <!-- === Schedule (Instructor: recurring class timetable) === -->
            <div class="impulse-store-section" data-section="schedule" style="display:none;flex-direction:column;min-height:0">
                <div style="flex-shrink:0;height:38px;background:#2a2e33;border-bottom:1px solid #3a3f44;display:flex;align-items:center;justify-content:space-between;padding:0 30px">
                    <div style="display:flex;gap:4px">
                        <button type="button" id="schedule-mode-rules" class="sched-mode-btn" style="font-size:11px;color:#e0e0e0;background:#3a3f44;border:1px solid #555;border-radius:4px;padding:5px 12px;cursor:pointer">Schedule</button>
                        <button type="button" id="schedule-mode-checkin" class="sched-mode-btn" style="font-size:11px;color:#999;background:transparent;border:1px solid #3a3f44;border-radius:4px;padding:5px 12px;cursor:pointer">Check-in</button>
                    </div>
                    <button type="button" id="schedule-add-btn" style="font-size:11px;color:#e0e0e0;background:#3a3f44;border:1px solid #555;border-radius:4px;padding:5px 12px;cursor:pointer">+ Add class</button>
                </div>
                <div class="impulse-panel-body impulse-scroll" id="impulse-schedule-mgr" style="flex:1;min-height:0;overflow-y:auto;padding:16px 24px">
                    <div class="impulse-loading">Loading schedule...</div>
                </div>
            </div>

            <!-- === Staff (bookable team members) === -->
            <div class="impulse-store-section" data-section="staff" style="display:none;flex-direction:column;min-height:0">
                <div style="flex-shrink:0;height:38px;background:#2a2e33;border-bottom:1px solid #3a3f44;display:flex;align-items:center;justify-content:space-between;padding:0 30px">
                    <span style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:#888">Staff</span>
                    <button type="button" id="impulse-new-staff-btn" style="font-size:11px;color:#e0e0e0;background:#3a3f44;border:1px solid #555;border-radius:4px;padding:5px 12px;cursor:pointer">+ Add Staff</button>
                </div>
                <div style="flex:1;min-height:0;display:flex;flex-direction:row">
                    <div id="staff-list-left" class="impulse-scroll" style="width:240px;background:#1a1d21;border-right:1px solid #3a3f44;overflow-y:auto;flex-shrink:0;padding:4px 0"></div>
                    <div id="staff-form-right" class="impulse-scroll" style="flex:1;min-width:0;overflow-y:auto"><div style="padding:20px;font-size:11px;color:#555">Select a team member, or add one.</div></div>
                </div>
            </div>

            <div class="impulse-store-section" data-section="settings" style="display:none;flex-direction:column;min-height:0;height:100%;overflow-y:auto">

                <!-- Team -->
                <div style="padding:0 30px 8px">
                    <div style="display:flex;align-items:center;justify-content:space-between;padding:12px 0 10px">
                        <span style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:#888">Team</span>
                        <div style="display:flex;align-items:center;gap:6px">
                            <span id="team-member-count" style="font-size:11px;color:#555"></span>
                            <button type="button" id="team-add-btn" class="impulse-btn-sm" style="height:26px;padding:0 10px">+ Invite</button>
                        </div>
                    </div>
                    <div id="team-list" style="margin:0;padding:0">
                        <table class="impulse-products-table" style="width:100%"><tbody><tr><td colspan="5" style="text-align:center;color:#555;padding:16px">Loading...</td></tr></tbody></table>
                    </div>
                </div>

                <!-- Two-column: SEO (left) | Payments (right) -->
                <div class="impulse-settings-cardflow" style="padding:12px 30px 16px;border-top:1px solid #3a3f44;margin-top:4px">

                    <!-- Left group: SEO cards, rendered by JS. display:contents so each card
                         joins the shared flow instead of forming its own fixed stack. -->
                    <div class="impulse-cardflow-pass">
                        <div id="store-seo-settings-center-inner"></div>

                        <?php if (defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone'): // Global head/body code injection — standalone only. WP.org disallows site-wide arbitrary code injection (Guideline 11). ?>
                        <!-- Code Snippets -->
                        <div class="settings-card">
                            <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
                                <div class="impulse-section-divider" style="margin:0;flex:1">Code Snippets</div>
                                <button type="button" id="gsnip-add-btn" class="impulse-btn-sm" style="height:26px;padding:0 10px;flex-shrink:0;margin-left:8px">+ Add Snippet</button>
                            </div>
                            <div style="font-size:11px;color:#555;margin-bottom:8px;line-height:1.5">Scripts and styles injected on every page. Use for analytics, pixels, consent banners, and custom CSS.</div>
                            <div id="gsnip-list" style="margin-bottom:4px"></div>
                            <div id="gsnip-editor" style="display:none;margin-top:8px">
                                <input type="hidden" id="gsnip-editor-id">
                                <div style="display:flex;gap:4px;margin-bottom:6px">
                                    <input type="text" id="gsnip-editor-name" placeholder="Snippet name (e.g. Google Analytics, Custom CSS)"
                                           style="flex:1;height:26px;padding:0 8px;background:#1a1d21;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;outline:none;min-width:0">
                                    <select id="gsnip-editor-location"
                                            style="height:26px;padding:0 6px;background:#1a1d21;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;outline:none;cursor:pointer;flex-shrink:0">
                                        <option value="head">&lt;head&gt;</option>
                                        <option value="css">CSS</option>
                                        <option value="body_start">Body start</option>
                                        <option value="body_end">Body end</option>
                                    </select>
                                </div>
                                <textarea id="gsnip-editor-code" rows="8" placeholder="Paste your script tag, CSS rules, or code here..."
                                          style="width:100%;background:#1a1d21;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;font-family:monospace;line-height:1.5;padding:6px 8px;resize:vertical;box-sizing:border-box;outline:none;display:block;margin-bottom:6px"></textarea>
                                <div style="display:flex;gap:4px">
                                    <button type="button" id="gsnip-editor-save"
                                            style="height:26px;padding:0 14px;font-size:11px;background:#fff;border:1px solid #fff;border-radius:3px;color:#1d2327;font-weight:600;cursor:pointer">Save</button>
                                    <button type="button" id="gsnip-editor-cancel"
                                            style="height:26px;padding:0 10px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#999;cursor:pointer">Cancel</button>
                                    <div id="gsnip-editor-msg" style="flex:1;font-size:11px;color:#555;line-height:26px;padding-left:4px"></div>
                                </div>
                            </div>
                        </div>
                        <?php endif; ?>
                    </div>

                    <?php if (!\Instinctor\Core\Plugin::isInstinctorApp()): // On the tenant app every owner already has the panel and signs in as themselves; this card is for designer-built sites. ?>
                    <!-- Mobile control panel: turn it on, name the owner, send the link. -->
                    <div class="settings-card" id="panel-access-card">
                        <div class="impulse-section-divider" style="margin-bottom:8px">Mobile control panel</div>
                        <div style="font-size:11px;color:#555;margin-bottom:10px;line-height:1.5">The owner runs the business from their phone: the day ahead, the people writing in, prices, photos. They never see this admin. Turn it on, say who they are, and send them the link.</div>

                        <div class="impulse-settings-left-row" style="display:flex;align-items:center;gap:8px;margin-bottom:10px">
                            <button type="button" id="pa-toggle" class="impulse-btn-sm" style="height:26px;padding:0 12px;flex-shrink:0">Enable</button>
                            <span id="pa-state" style="font-size:11px;color:#555"></span>
                        </div>

                        <div id="pa-body" style="display:none">
                            <div class="impulse-settings-left-row">
                                <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Owner email</label>
                                <div style="display:flex;gap:4px">
                                    <input type="email" id="pa-email" placeholder="owner@theirbusiness.com"
                                           style="flex:1;height:26px;padding:0 8px;background:#1a1d21;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;outline:none;min-width:0">
                                    <button type="button" id="pa-save-owner" class="impulse-btn-sm" style="height:26px;padding:0 12px;flex-shrink:0">Save</button>
                                </div>
                                <div style="font-size:11px;color:#555;margin-top:4px;line-height:1.5">An account is created for them if there is not one already. It can do nothing in WordPress: the panel is all it opens.</div>
                            </div>

                            <div class="impulse-settings-left-row" id="pa-link-row" style="display:none;margin-top:10px">
                                <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Their sign-in link</label>
                                <div style="display:flex;gap:4px">
                                    <input type="text" id="pa-link" readonly
                                           style="flex:1;height:26px;padding:0 8px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#999;font-size:11px;outline:none;min-width:0">
                                    <button type="button" id="pa-copy" class="impulse-btn-sm" style="height:26px;padding:0 12px;flex-shrink:0">Copy</button>
                                    <button type="button" id="pa-send" class="impulse-btn-sm" style="height:26px;padding:0 12px;flex-shrink:0">Email it</button>
                                </div>
                                <div style="font-size:11px;color:#555;margin-top:4px;line-height:1.5">Signs them in for 30 days, no password. The link itself stops working after two weeks, so send a fresh one if they lose it.</div>
                            </div>

                            <div class="impulse-settings-left-row" style="margin-top:10px">
                                <button type="button" id="pa-revoke" class="impulse-btn-sm" style="height:26px;padding:0 12px">Revoke every link</button>
                                <span id="pa-msg" style="font-size:11px;color:#555;margin-left:8px"></span>
                            </div>
                        </div>
                    </div>

                    <?php endif; ?>

                    <!-- Right group: payment gateways. Same pass-through. -->
                    <div class="impulse-cardflow-pass">
                    <div class="impulse-cardflow-pass" data-no-autocomplete="1">

                        <div class="settings-card">
                        <!-- Stripe -->
                        <div class="impulse-section-divider" style="margin-bottom:10px">Stripe<?php if ($isp_stripe_conn): ?> <span style="font-weight:400;text-transform:none;letter-spacing:0;color:#555;font-size:11px">· Connected</span><?php elseif (str_starts_with($isp_stripe_pub,'pk_test_') || str_starts_with($isp_stripe_sec,'sk_test_')): ?> <span style="font-weight:400;text-transform:none;letter-spacing:0;color:#555;font-size:11px">· Test mode</span><?php endif; ?></div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Publishable key</label>
                            <input type="text" name="stripe_publishable_key" value="<?php echo esc_attr($isp_stripe_pub); ?>" placeholder="pk_..." class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Secret key</label>
                            <form autocomplete="off" onsubmit="return false" style="display:flex;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;overflow:hidden;margin:0"><input type="text" name="_a11y_user" autocomplete="username" value="instinctor" tabindex="-1" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none" readonly>
                                <input type="password" name="stripe_secret_key" autocomplete="new-password" value="<?php echo esc_attr($isp_stripe_sec); ?>" placeholder="sk_..." class="impulse-settings-input impulse-autosave impulse-pw-field" data-panel="payments" style="flex:1;border:none;background:transparent;height:26px;padding:0 8px;font-size:11px;color:#e0e0e0;outline:none;min-width:0">
                                <button type="button" class="impulse-pw-toggle" style="width:26px;height:26px;background:none;border:none;border-left:1px solid #3a3f44;cursor:pointer;color:#555;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
                            </form>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Webhook secret</label>
                            <form autocomplete="off" onsubmit="return false" style="display:flex;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;overflow:hidden;margin:0"><input type="text" name="_a11y_user" autocomplete="username" value="instinctor" tabindex="-1" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none" readonly>
                                <input type="password" name="stripe_webhook_secret" autocomplete="new-password" value="<?php echo esc_attr($isp_stripe_wh); ?>" placeholder="whsec_..." class="impulse-settings-input impulse-autosave impulse-pw-field" data-panel="payments" style="flex:1;border:none;background:transparent;height:26px;padding:0 8px;font-size:11px;color:#e0e0e0;outline:none;min-width:0">
                                <button type="button" class="impulse-pw-toggle" style="width:26px;height:26px;background:none;border:none;border-left:1px solid #3a3f44;cursor:pointer;color:#555;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
                            </form>
                        </div>
                        <div class="impulse-settings-left-row">
                            <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:3px;padding:6px 8px">
                                <div style="font-size:11px;color:#555;margin-bottom:2px;text-transform:uppercase;letter-spacing:0.4px">Webhook URL</div>
                                <code style="font-size:11px;color:#888;word-break:break-all"><?php echo esc_html(\Instinctor\Core\Config::restUrl('instinctor/v1/stripe-webhook')); ?></code>
                            </div>
                        </div>

                        </div>
                        <div class="settings-card">
                        <!-- PayPal -->
                        <div style="display:flex;align-items:center;gap:8px;margin:16px 0 10px">
                            <div class="impulse-section-divider" style="flex:1;margin:0">PayPal<?php if ($isp_pp_conn): ?> <span style="font-weight:400;text-transform:none;letter-spacing:0;color:#555;font-size:11px">· Connected</span><?php endif; ?></div>
                            <button type="button" id="paypal-sandbox-toggle"
                                data-value="<?php echo $isp_pp_sandbox ? '1' : '0'; ?>"
                                title="Toggle sandbox / live"
                                style="margin-left:auto;height:26px;padding:0 10px;font-size:11px;border-radius:3px;border:1px solid;cursor:pointer;transition:background .15s,color .15s;<?php echo $isp_pp_sandbox ? 'background:#2a2e33;border-color:#3a3f44;color:#888' : 'background:#2a2e33;border-color:#3a3f44;color:#e0e0e0'; ?>"><?php echo $isp_pp_sandbox ? 'Sandbox' : 'Live'; ?></button>
                            <input type="hidden" name="paypal_sandbox" id="paypal-sandbox-val" class="impulse-autosave" data-panel="payments" value="<?php echo $isp_pp_sandbox ? '1' : '0'; ?>">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Client ID</label>
                            <input type="text" name="paypal_client_id" value="<?php echo esc_attr($isp_pp_client); ?>" placeholder="AY..." class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Secret</label>
                            <form autocomplete="off" onsubmit="return false" style="display:flex;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;overflow:hidden;margin:0"><input type="text" name="_a11y_user" autocomplete="username" value="instinctor" tabindex="-1" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none" readonly>
                                <input type="password" name="paypal_secret" autocomplete="new-password" value="<?php echo esc_attr($isp_pp_secret); ?>" placeholder="EL..." class="impulse-settings-input impulse-autosave impulse-pw-field" data-panel="payments" style="flex:1;border:none;background:transparent;height:26px;padding:0 8px;font-size:11px;color:#e0e0e0;outline:none;min-width:0">
                                <button type="button" class="impulse-pw-toggle" style="width:26px;height:26px;background:none;border:none;border-left:1px solid #3a3f44;cursor:pointer;color:#555;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
                            </form>
                        </div>
                        <div class="impulse-settings-left-row">
                            <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:3px;padding:6px 8px">
                                <div style="font-size:11px;color:#555;margin-bottom:2px;text-transform:uppercase;letter-spacing:0.4px">Webhook URL</div>
                                <code style="font-size:11px;color:#888;word-break:break-all"><?php echo esc_html(\Instinctor\Core\Config::restUrl('instinctor/v1/paypal-webhook')); ?></code>
                            </div>
                        </div>

                        </div>
                        <div class="settings-card">
                        <!-- Authorize.net -->
                        <div style="display:flex;align-items:center;gap:8px;margin:16px 0 10px">
                            <div class="impulse-section-divider" style="flex:1;margin:0">Authorize.net<?php if ($isp_an_conn): ?> <span style="font-weight:400;text-transform:none;letter-spacing:0;color:#555;font-size:11px">· Connected</span><?php elseif ($isp_an_login): ?> <span style="font-weight:400;text-transform:none;letter-spacing:0;color:#555;font-size:11px">· Incomplete</span><?php endif; ?></div>
                            <button type="button" id="authorizenet-sandbox-toggle"
                                data-value="<?php echo $isp_an_sandbox ? '1' : '0'; ?>"
                                title="Toggle sandbox / live"
                                style="height:26px;padding:0 10px;font-size:11px;border-radius:3px;border:1px solid;cursor:pointer;transition:background .15s,color .15s;background:#2a2e33;border-color:#3a3f44;color:<?php echo $isp_an_sandbox ? '#888' : '#e0e0e0'; ?>"><?php echo $isp_an_sandbox ? 'Sandbox' : 'Live'; ?></button>
                            <input type="hidden" name="authorizenet_sandbox" id="authorizenet-sandbox-val" class="impulse-autosave" data-panel="payments" value="<?php echo $isp_an_sandbox ? '1' : '0'; ?>">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">API Login ID</label>
                            <input type="text" name="authorizenet_api_login_id" value="<?php echo esc_attr($isp_an_login); ?>" placeholder="Login ID" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Transaction Key</label>
                            <form autocomplete="off" onsubmit="return false" style="display:flex;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;overflow:hidden;margin:0"><input type="text" name="_a11y_user" autocomplete="username" value="instinctor" tabindex="-1" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none" readonly>
                                <input type="password" name="authorizenet_transaction_key" autocomplete="new-password" value="<?php echo esc_attr($isp_an_txkey); ?>" placeholder="Transaction Key" class="impulse-settings-input impulse-autosave impulse-pw-field" data-panel="payments" style="flex:1;border:none;background:transparent;height:26px;padding:0 8px;font-size:11px;color:#e0e0e0;outline:none;min-width:0">
                                <button type="button" class="impulse-pw-toggle" style="width:26px;height:26px;background:none;border:none;border-left:1px solid #3a3f44;cursor:pointer;color:#555;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
                            </form>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Public Client Key</label>
                            <input type="text" name="authorizenet_public_client_key" value="<?php echo esc_attr($isp_an_pubkey); ?>" placeholder="Public Client Key" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                        </div>
                        <div class="impulse-settings-left-row" style="font-size:11px;color:#555;line-height:1.5">
                            Get these from Authorize.net merchant portal: Account &rarr; Settings &rarr; Security Settings &rarr; General Security Settings.
                        </div>

                        </div>
                        <div class="settings-card">
                        <!-- Offline payment methods: Cash on Delivery + Bank Transfer. No gateway; the
                             order is placed Pending and the owner marks it paid when the money arrives. -->
                        <div style="display:flex;align-items:center;gap:8px;margin:16px 0 10px">
                            <div class="impulse-section-divider" style="flex:1;margin:0">Cash on Delivery</div>
                            <button type="button" id="cod-enabled-toggle" class="inst-onoff-toggle" data-target="cod-enabled-val" data-value="<?php echo $isp_cod_enabled ? '1' : '0'; ?>" title="Enable / disable" style="height:26px;padding:0 12px;font-size:11px;border-radius:3px;border:1px solid #3a3f44;cursor:pointer;background:#2a2e33;color:<?php echo $isp_cod_enabled ? '#e0e0e0' : '#888'; ?>"><?php echo $isp_cod_enabled ? 'On' : 'Off'; ?></button>
                            <input type="hidden" name="cod_enabled" id="cod-enabled-val" class="impulse-autosave" data-panel="payments" value="<?php echo $isp_cod_enabled ? '1' : '0'; ?>">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Checkout note (optional)</label>
                            <input type="text" name="cod_instructions" value="<?php echo esc_attr($isp_cod_instructions); ?>" placeholder="e.g. Pay the courier in cash on delivery." class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                        </div>

                        </div>
                        <div class="settings-card">
                        <div style="display:flex;align-items:center;gap:8px;margin:16px 0 10px">
                            <div class="impulse-section-divider" style="flex:1;margin:0">Bank Transfer</div>
                            <button type="button" id="bank-transfer-enabled-toggle" class="inst-onoff-toggle" data-target="bank-transfer-enabled-val" data-value="<?php echo $isp_bank_enabled ? '1' : '0'; ?>" title="Enable / disable" style="height:26px;padding:0 12px;font-size:11px;border-radius:3px;border:1px solid #3a3f44;cursor:pointer;background:#2a2e33;color:<?php echo $isp_bank_enabled ? '#e0e0e0' : '#888'; ?>"><?php echo $isp_bank_enabled ? 'On' : 'Off'; ?></button>
                            <input type="hidden" name="bank_transfer_enabled" id="bank-transfer-enabled-val" class="impulse-autosave" data-panel="payments" value="<?php echo $isp_bank_enabled ? '1' : '0'; ?>">
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Bank details shown to the customer</label>
                            <textarea name="bank_transfer_details" rows="4" placeholder="Account name&#10;Account number / IBAN&#10;Sort code / routing&#10;Reference: your order number" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;box-sizing:border-box;padding:8px;font-size:11px;line-height:1.5;resize:vertical;color:#e0e0e0;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px"><?php echo esc_html($isp_bank_details); ?></textarea>
                        </div>
                        <div class="impulse-settings-left-row" style="font-size:11px;color:#555;line-height:1.5">
                            Offline orders arrive as Pending. Mark them paid in Orders once the cash or transfer lands; stock and emails complete automatically.
                        </div>

                        </div>
                        <?php if (\Instinctor\Core\Plugin::isInstinctorApp()): ?>
                        <div class="settings-card">
                        <!-- Domain reseller (NameSilo) — instinctor.com ONLY. Global key for the AI
                             Domain Finder + self-serve buy in InCommand. Feature is off until set. -->
                        <div style="display:flex;align-items:center;gap:8px;margin:16px 0 10px">
                            <div class="impulse-section-divider" style="flex:1;margin:0">Domain reseller (NameSilo)<?php if ($isp_ns_conn): ?> <span style="font-weight:400;text-transform:none;letter-spacing:0;color:#555;font-size:11px">&middot; On</span><?php endif; ?></div>
                        </div>
                        <div class="impulse-settings-left-row" style="font-size:11px;color:#555;line-height:1.5;margin-bottom:8px">
                            Instinctor only. Powers the AI domain finder + buy in InCommand. The whole feature stays off until an API key is set. Point the API base at the sandbox to test, then clear it for live.
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">API key</label>
                            <form autocomplete="off" onsubmit="return false" style="display:flex;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;overflow:hidden;margin:0"><input type="text" name="_a11y_user" autocomplete="username" value="instinctor" tabindex="-1" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none" readonly>
                                <input type="password" name="namesilo_api_key" autocomplete="new-password" value="<?php echo esc_attr($isp_ns_key); ?>" placeholder="NameSilo API key" class="impulse-settings-input impulse-autosave impulse-pw-field" data-panel="payments" style="flex:1;border:none;background:transparent;height:26px;padding:0 8px;font-size:11px;color:#e0e0e0;outline:none;min-width:0">
                                <button type="button" class="impulse-pw-toggle" style="width:26px;height:26px;background:none;border:none;border-left:1px solid #3a3f44;cursor:pointer;color:#555;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
                            </form>
                        </div>
                        <div class="impulse-settings-left-row">
                            <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">API base (blank = live; set sandbox base to test)</label>
                            <input type="text" name="namesilo_base" value="<?php echo esc_attr($isp_ns_base); ?>" placeholder="https://www.namesilo.com/api/" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                        </div>
                        <div style="display:flex;gap:8px">
                            <div class="impulse-settings-left-row" style="flex:1">
                                <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Nameserver 1</label>
                                <input type="text" name="namesilo_ns1" value="<?php echo esc_attr($isp_ns_ns1); ?>" placeholder="ns1.instinctor.com" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                            </div>
                            <div class="impulse-settings-left-row" style="flex:1">
                                <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Nameserver 2</label>
                                <input type="text" name="namesilo_ns2" value="<?php echo esc_attr($isp_ns_ns2); ?>" placeholder="ns2.instinctor.com" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                            </div>
                        </div>
                        <div style="display:flex;gap:8px">
                            <div class="impulse-settings-left-row" style="flex:1">
                                <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Markup %</label>
                                <input type="number" name="namesilo_markup_pct" value="<?php echo esc_attr($isp_ns_mpct); ?>" placeholder="40" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                            </div>
                            <div class="impulse-settings-left-row" style="flex:1">
                                <label style="font-size:11px;color:#888;display:block;margin-bottom:3px">Or flat $ (overrides %)</label>
                                <input type="number" name="namesilo_markup_flat" value="<?php echo esc_attr($isp_ns_mflat); ?>" placeholder="0" class="impulse-settings-input impulse-autosave" data-panel="payments" style="width:100%;height:26px;box-sizing:border-box">
                            </div>
                        </div>
                        </div>
                        <?php endif; ?>

                    </div>

                    <!-- AfterShip Auto-Tracking -->
                    <div class="settings-card">
                        <div class="impulse-section-divider" style="margin-bottom:8px">AfterShip Auto-Tracking</div>
                        <div id="shipping-aftership-form">
                            <div style="font-size:11px;color:#555;text-align:center;padding:16px 0">Loading...</div>
                        </div>
                    </div>

                    </div>
                </div>

                <!-- Feature panels: shown via openFeaturePanel/switchSettingsTab — appended here when needed -->

<div class="impulse-settings-panel" data-settings="tax" style="display:none">
                    <div class="impulse-panel-header" style="padding:12px 16px;border-bottom:1px solid #2a2e33">
                        <span style="font-weight:600;color:#e0e0e0">Tax</span>
                    </div>
                    <div class="impulse-panel-body impulse-scroll" style="padding:16px">
                        <div style="font-size:11px;color:#888;margin-bottom:16px">Tax rates, classes, and exemptions.</div>
                    </div>
                </div>

<div class="impulse-settings-panel" data-settings="coupons" style="display:none">
                    <div class="impulse-panel-header" style="display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid #2a2e33">
                        <span style="font-size:11px;color:#888">Coupons</span>
                    </div>
                    <div class="impulse-panel-body impulse-scroll" data-for="coupons">
                        <ul class="impulse-list" id="dashboard-coupons-list">
                            <?php
                            $coupon_service_list = new \Instinctor\Services\CouponService();
                            $coupons_list = $coupon_service_list->getAllCoupons(['limit' => 200]);
                            if (empty($coupons_list)): ?>
                            <li class="impulse-empty">
                                <div class="impulse-empty-icon"><svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"><path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/></svg></div>
                                <div class="impulse-empty-title">No coupons yet</div>
                                <div class="impulse-empty-desc">Create discount codes to boost sales.</div>
                            </li>
                            <?php else: foreach ($coupons_list as $coupon_item): ?>
                            <li class="impulse-list-item" data-coupon-id="<?php echo esc_attr($coupon_item->id); ?>" data-status="<?php echo esc_attr($coupon_item->status); ?>">
                                <div class="impulse-list-item-content">
                                    <div class="impulse-list-item-title" style="font-family:monospace"><?php echo esc_html($coupon_item->code); ?></div>
                                    <div class="impulse-list-item-subtitle">
                                        <span style="color:#999"><?php echo $coupon_item->discount_type === 'percent' ? esc_html($coupon_item->amount) . '%' : esc_html(\Instinctor\Core\Config::get('instinctor_currency_symbol','$')) . number_format($coupon_item->amount, 2); ?> off</span>
                                        <?php if (!empty($coupon_item->usage_count)): ?>
                                        <span style="margin-left:8px;color:#888">Used <?php echo esc_html($coupon_item->usage_count); ?>×</span>
                                        <?php endif; ?>
                                    </div>
                                </div>
                                <span class="impulse-list-item-meta" style="color:<?php echo $coupon_item->status === 'active' ? '#e0e0e0' : '#555'; ?>"><?php echo esc_html(ucfirst($coupon_item->status)); ?></span>
                            </li>
                            <?php endforeach; endif; ?>
                        </ul>
                    </div>
                </div>

<div class="impulse-settings-panel" data-settings="product_addons" style="display:none">
                    <div class="impulse-panel-body impulse-scroll" style="padding:16px">
                        <div style="font-size:12px;color:#888;text-align:center;padding:20px 0;line-height:1.7">
                            Add-Ons are now configured directly in each Products block.<br>
                            <span style="font-size:11px;color:#555">Open any Products block in Impulse and scroll to the Add-Ons section.</span>
                        </div>
                    </div>
                </div>

<div class="impulse-settings-panel" data-settings="volume_discounts" style="display:none">
                    <div class="impulse-panel-header" style="display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid #2a2e33;flex-shrink:0">
                        <span style="font-size:11px;color:#888;flex:1">Volume Discounts</span>
                        <button type="button" id="volume-add-btn" class="impulse-btn-sm" style="height:26px;padding:0 10px">+ Add Discount</button>
                    </div>
                    <div class="impulse-panel-body impulse-scroll" style="padding:12px">
                        <div id="volume-list-wrap">
                            <div style="font-size:11px;color:#555;text-align:center;padding:24px 0">Loading...</div>
                        </div>
                    </div>
                </div>

<div class="impulse-settings-panel" data-settings="loyalty" style="display:none">
                    <div class="impulse-panel-body impulse-scroll" style="padding:12px">
                        <div style="max-width:300px">
                            <div id="loyalty-stats-row" style="margin-bottom:12px"></div>
                            <div id="loyalty-form">
                                <div style="font-size:11px;color:#555;text-align:center;padding:24px 0">Loading...</div>
                            </div>
                        </div>
                    </div>
                </div>

<div class="impulse-settings-panel" data-settings="gift_cards" style="display:none">
                    <div class="impulse-panel-header" style="display:flex;align-items:center;gap:16px;padding:12px 16px;border-bottom:1px solid #2a2e33">
                        <span style="font-weight:600;color:#e0e0e0">Gift Cards</span>
                        <div style="flex:1"></div>
                        <select id="gc-filter-status" style="height:26px;background:#2a2e33;border:1px solid #3a3f44;color:#999;font-size:11px;border-radius:3px;padding:0 6px">
                            <option value="">All</option>
                            <option value="active">Active</option>
                            <option value="depleted">Depleted</option>
                            <option value="cancelled">Cancelled</option>
                        </select>
                    </div>
                    <div class="impulse-panel-body impulse-scroll">
                        <ul class="impulse-list" id="gc-list">
                            <li class="impulse-empty">
                                <div class="impulse-empty-title">Loading...</div>
                            </li>
                        </ul>
                    </div>
                </div>



            </div>
        </div><!-- End Center Panel -->

        <!-- ==================== RIGHT PANEL ==================== -->
        <div class="impulse-panel-right">
            <!-- Orders / Clients / Returns: Detail -->
            <div class="impulse-store-right-content" data-section="orders">
                <!-- Order detail header -->
                <div class="impulse-products-right-header" id="order-detail-header" style="display:none">
                    <span>Order Details</span>
                </div>
                <!-- Client detail header -->
                <div class="impulse-products-right-header" id="clients-right-header" style="display:none">
                    <span id="clients-right-title">Client</span>
                </div>
                <div class="impulse-panel-body impulse-scroll" style="padding:0">
                    <div id="dashboard-detail-content"></div>
                    <div id="customer-detail-content"></div>
                </div>
            </div>

            <!-- Products: Product Editor -->
            <div class="impulse-store-right-content" data-section="products" style="display:none">

                <!-- Title header: hidden by default, shown only when a panel is open -->
                <div class="impulse-products-right-header" id="products-right-header" style="display:none">
                    <span id="products-right-title"></span>
                </div>
                <div class="impulse-products-right-content" id="impulse-products-edit">
                    <!-- Content loaded dynamically when product selected -->
                </div>
            </div>

            <!-- Settings: Contextual -->
            <div class="impulse-store-right-content" data-section="bookings" style="display:none">
                <!-- Services list — default state, hidden when editing -->
                <div id="bookings-services-panel" style="display:flex;flex-direction:column;height:100%;min-height:0">
                    <div id="bookings-services-right" class="impulse-scroll" style="flex:1;min-height:0;overflow-y:auto;padding:4px 0">
                        <div style="padding:8px 12px;font-size:11px;color:#555">Loading...</div>
                    </div>
                </div>
                <!-- Edit form — shown when booking or service is opened -->
                <div id="bookings-edit-panel" style="display:none;flex-direction:column;height:100%;min-height:0">
                    <div class="impulse-products-right-header bookings-right-header" id="bookings-right-header">
                        <span id="bookings-right-title"></span>
                    </div>
                    <div class="impulse-panel-body impulse-scroll" id="impulse-bookings-edit" style="padding:0;flex:1;min-height:0;overflow-y:auto"></div>
                </div>
            </div>

            <div class="impulse-store-right-content" data-section="settings" style="display:none">
                <div class="impulse-products-right-header" id="settings-right-header" style="display:none">
                    <span></span>
                </div>
                <div class="impulse-panel-body impulse-scroll" style="padding:0;display:flex;flex-direction:column;height:100%">

                    <!-- Feature status panel — shown when a feature tab is open -->
                    <div id="feature-status-panel" style="display:none;padding:14px;border-bottom:1px solid #2a2e33;flex-shrink:0" data-feature="">
                        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
                            <span id="feature-status-name" style="font-size:12px;font-weight:600;color:#e0e0e0"></span>
                            <span id="feature-autosave-indicator" style="font-size:11px;color:#555;opacity:0;transition:opacity 0.3s">Saved</span>
                        </div>
                        <div style="display:flex;align-items:center;justify-content:space-between;padding:8px 10px;background:#2a2e33;border-radius:4px;margin-bottom:12px">
                            <span style="font-size:11px;color:#999">Status</span>
                            <div style="display:flex;align-items:center;gap:8px">
                                <span id="feature-status-label" style="font-size:11px;color:#555">Inactive</span>
                                <label class="impulse-toggle" style="position:relative;display:inline-block;width:32px;height:18px;flex-shrink:0">
                                    <input type="checkbox" id="feature-status-toggle">
                                    <span class="impulse-toggle-slider"></span>
                                </label>
                            </div>
                        </div>
                        <div id="feature-stats-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:6px"></div>
                    </div>

                    <!-- Emails — collapsible list -->
                    <div id="settings-email-panel" style="flex-shrink:0;border-bottom:1px solid #2a2e33">
                        <div class="impulse-section-divider" id="settings-email-toggle" style="cursor:pointer;user-select:none">Emails <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-1px;margin-left:2px"><path d="M6 9l6 6 6-6"/></svg></div>
                        <div id="email-list-wrap" style="display:none;padding:0 0 4px">
                            <div style="font-size:11px;color:#555;padding:12px;text-align:center">Loading...</div>
                        </div>
                    </div>

                    <?php if ($can_manage_chat_settings) : ?>
                    <?php $_sms_pro_s = instinctor_has_pro(); ?>
                    <!-- Chat -->
                    <div id="settings-chat-panel" style="flex-shrink:0;border-bottom:1px solid #2a2e33">
                        <div class="impulse-section-divider" id="settings-chat-toggle" style="cursor:pointer;user-select:none">Chat <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-1px;margin-left:2px"><path d="M6 9l6 6 6-6"/></svg></div>
                        <div id="settings-chat-body" style="padding:0 12px 12px">

                            <!-- INSTAGENT -->
                            <div class="impulse-settings-section" id="impulse-instagent-section">
                                <!-- Response Delay removed 2.1.1501: it only
                                     faked typing time before INSTAGENT replies.
                                     Instant answers win; Escalate moved up here
                                     so the config column stays tight. -->
                                <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:center;margin-bottom:4px">
                                    <label class="impulse-cb-left" title="Enable the Instagent assistant for this chat widget. When on, the agent automatically uses order history and customer profile data for more precise answers.">
                                        <input type="checkbox" id="impulse-chat-ai_enabled" <?php checked($chat_data['settings']['ai_enabled'] === '1'); ?>>
                                        <span>INSTAGENT</span>
                                    </label>
                                    <div id="impulse-instagent-escalate" style="<?php echo $chat_data['settings']['ai_enabled'] === '1' ? '' : 'display:none;'; ?>">
                                        <div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:2px">
                                            <label for="impulse-ai-handoff-timeout" style="font-size:11px;color:#999" title="Seconds without a resolution before INSTAGENT hands off to a human agent">Escalate after</label>
                                            <span id="impulse-ai-handoff-val" style="font-size:11px;color:#999"><?php echo intval($chat_data['settings']['handoff_timeout']); ?>s</span>
                                        </div>
                                        <div class="impulse-slider-row" data-unit="s" style="display:block">
                                            <input type="range" id="impulse-ai-handoff-timeout" min="10" max="300" step="5" value="<?php echo intval($chat_data['settings']['handoff_timeout']); ?>" style="width:100%">
                                        </div>
                                    </div>
                                </div>
                                <div id="impulse-instagent-config" style="<?php echo $chat_data['settings']['ai_enabled'] === '1' ? '' : 'display:none;'; ?>">
                                    <label for="impulse-ai-handoff-msg" style="display:block;font-size:11px;color:#999;margin-bottom:4px">Handoff message</label>
                                    <textarea id="impulse-ai-handoff-msg" rows="2" placeholder="Thanks for your patience, our team will reply here shortly. Leave your email if you step away and we will follow up." style="width:100%;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;padding:5px 8px;resize:vertical;box-sizing:border-box;line-height:1.5;outline:none;margin-bottom:6px"><?php echo esc_textarea($chat_data['settings']['handoff_message']); ?></textarea>
                                    <label for="impulse-ai-store-info" style="display:block;font-size:11px;color:#999;margin-bottom:4px" title="Tell INSTAGENT about your store: policies, hours, FAQs.">Instructions</label>
                                    <textarea id="impulse-ai-store-info" rows="4" placeholder="Example: We sell handmade ceramics. Free shipping over $75. Returns within 30 days." style="width:100%;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;padding:5px 8px;resize:vertical;box-sizing:border-box;line-height:1.5;outline:none"><?php echo esc_textarea($chat_data['settings']['ai_store_info']); ?></textarea>
                                </div>
                            </div>

                            <input type="hidden" name="ai_tone" id="impulse-chat-ai_tone" value="friendly">
                            <input type="hidden" name="widget_theme" id="impulse-chat-widget_theme" value="light">
                            <!-- color_button stub removed — duplicate id collided with the
                                 authoritative swatch input below at line ~2559. jQuery
                                 was resolving #impulse-chat-color_button to this empty
                                 stub, so the autosave sent color_button="" every time. -->
                            <input type="hidden" name="avatar" id="impulse-chat-avatar" value="">
                            <input type="hidden" name="color_input_border" id="impulse-chat-color_input_border" value="<?php echo esc_attr($chat_data['settings']['color_input_border']); ?>">
                            <input type="hidden" name="title" id="impulse-chat-title" value="<?php echo esc_attr($chat_data['settings']['title']); ?>">
                            <input type="hidden" name="online_text" value="<?php echo esc_attr($chat_data['settings']['online_text'] ?? 'We\'re online'); ?>">

                            <!-- Features + Collect -->
                            <div class="impulse-settings-section" style="margin-top:10px">
                                <div class="impulse-padding-grid" style="margin-bottom:8px;gap:6px">
                                    <label class="impulse-cb-left"><input type="checkbox" name="attachments" id="impulse-chat-attachments" <?php checked($chat_data['settings']['attachments'] === '1'); ?>><span>Attach file</span></label>
                                    <label class="impulse-cb-right"><span>Collect Name</span><input type="checkbox" name="collect_name" id="impulse-chat-collect_name" <?php checked($chat_data['settings']['collect_name'], '1'); ?>></label>
                                    <label class="impulse-cb-left"><input type="checkbox" name="screenshots" id="impulse-chat-screenshots" <?php checked($chat_data['settings']['screenshots'] === '1'); ?>><span>Screenshot</span></label>
                                    <label class="impulse-cb-right"><span>Collect Phone</span><input type="checkbox" name="collect_phone" id="impulse-chat-collect_phone" <?php checked($chat_data['settings']['collect_phone'], '1'); ?>></label>
                                    <span aria-hidden="true"></span>
                                    <label class="impulse-cb-right"><span>Collect Email</span><input type="checkbox" name="collect_email" id="impulse-chat-collect_email" <?php checked($chat_data['settings']['collect_email'], '1'); ?>></label>
                                </div>
                                <input type="hidden" name="greeting" id="impulse-chat-greeting" value="<?php echo esc_attr($chat_data['settings']['greeting']); ?>">
                                <input type="hidden" name="position" id="impulse-chat-position" value="auto">
                                <input type="hidden" name="show_online" value="0">
                                <input type="hidden" name="sound_enabled" value="0">
                            </div>

                            <!-- Greeting + Widget color row removed: widget now uses
                                 frosted glass + white icons throughout, no per-site
                                 brand-colour configuration. CTA greeting text input
                                 also removed (greeting CTA no longer shown). -->

                            <!-- Notifications -->
                            <div class="impulse-settings-section">
                                <div class="impulse-section-divider">NOTIFICATIONS</div>
                                <div style="font-size:11px;color:#555;margin:2px 0 8px">Leave a field empty to disable that channel.</div>
                                <?php if (!$_sms_pro_s): ?>
                                <div style="margin:8px 0 10px;padding:8px 10px;background:#1a1d21;border:1px solid #2a2d33;border-radius:4px;font-size:11px;color:#999;line-height:1.5">
                                    SMS and WhatsApp delivery channels are available on the subscription plan. <button type="button" class="impulse-upgrade-link" style="background:transparent;border:none;color:#e0e0e0;font-weight:600;cursor:pointer;padding:0;font:inherit">Subscribe &rarr;</button>
                                </div>
                                <?php endif; ?>
                                <div class="impulse-chat-notif-row">
                                    <span style="font-size:11px;color:#999;min-width:62px;flex-shrink:0">Email</span>
                                    <div class="impulse-chat-notif-input">
                                        <input type="email" name="email_address" id="impulse-chat-email_address" value="<?php echo esc_attr($chat_data['settings']['email_address']); ?>" placeholder="Email address" autocomplete="off" data-form-type="other" data-lpignore="true" readonly onfocus="this.removeAttribute('readonly')">
                                    </div>
                                    <button type="button" class="impulse-btn-sm" id="impulse-chat-test-email" style="height:26px;padding:0 8px;font-size:10px;flex-shrink:0">Test</button>
                                </div>
                                <div class="impulse-chat-notif-row<?php echo !$_sms_pro_s ? ' notif-pro-locked' : ''; ?>" id="notif-row-sms">
                                    <span style="font-size:11px;color:#999;min-width:62px;flex-shrink:0">SMS</span>
                                    <div class="impulse-chat-notif-input">
                                        <input type="tel" name="sms_number" id="impulse-chat-sms_number" value="<?php echo esc_attr($chat_data['settings']['sms_number']); ?>" placeholder="SMS number"<?php echo !$_sms_pro_s ? ' disabled' : ''; ?>>
                                    </div>
                                    <?php if ($_sms_pro_s): ?>
                                    <button type="button" class="impulse-btn-sm" id="impulse-chat-test-sms" style="height:26px;padding:0 8px;font-size:10px;flex-shrink:0">Test</button>
                                    <?php else: ?>
                                    <button type="button" class="impulse-notif-pro-badge" data-settings-tab="license" title="Pro feature — click to upgrade">PRO</button>
                                    <?php endif; ?>
                                </div>
                                <div class="impulse-chat-notif-row<?php echo !$_sms_pro_s ? ' notif-pro-locked' : ''; ?>" id="notif-row-whatsapp">
                                    <span style="font-size:11px;color:#999;min-width:62px;flex-shrink:0">WhatsApp</span>
                                    <div class="impulse-chat-notif-input">
                                        <input type="tel" name="whatsapp_number" id="impulse-chat-whatsapp_number" value="<?php echo esc_attr($chat_data['settings']['whatsapp_number']); ?>" placeholder="WhatsApp number"<?php echo !$_sms_pro_s ? ' disabled' : ''; ?>>
                                    </div>
                                    <?php if ($_sms_pro_s): ?>
                                    <button type="button" class="impulse-btn-sm" id="impulse-chat-test-whatsapp" style="height:26px;padding:0 8px;font-size:10px;flex-shrink:0">Test</button>
                                    <?php else: ?>
                                    <button type="button" class="impulse-notif-pro-badge" data-settings-tab="license" title="Pro feature — click to upgrade">PRO</button>
                                    <?php endif; ?>
                                </div>
                            </div>

                        </div>
                    </div>
                    <?php endif; ?>

                    <!-- License -->
                    <div id="settings-license-panel" style="flex-shrink:0;border-bottom:1px solid #2a2e33">
                        <div class="impulse-section-divider">License</div>
                        <div style="padding:0 12px 12px">
                            <?php
                            $_lic_tier        = instinctor_tier();
                            $_tier_label      = ['pro' => 'Pro', 'agency' => 'Agency', 'free' => 'Free', 'degraded' => 'Degraded'];
                            // "Has a working subscription" = tier is Pro. The legacy
                            // instinctor_subscription_active config was never wired by
                            // doValidate() so it sat false on every install, leaving the
                            // Upgrade button visible to paying customers. tier="pro" is
                            // the authoritative signal that comes from the platform's
                            // /api/validate response.
                            $_has_subscription = instinctor_has_pro();
                            ?>
                            <div id="lic-status-row" style="padding:0 0 10px">
                                <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:2px">
                                    <span style="font-size:11px;color:#999">Current plan</span>
                                    <span id="lic-tier-label" style="font-size:11px;font-weight:600;color:#e0e0e0"><?php echo esc_html($_tier_label[$_lic_tier] ?? ucfirst($_lic_tier)); ?></span>
                                </div>
                                <div style="display:flex;align-items:center;justify-content:space-between">
                                    <div id="lic-email-label" style="font-size:11px;color:#555;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1"><?php echo esc_html(\Instinctor\Core\Config::get('instinctor_registered_email', '')); ?></div>
                                    <span id="lic-expires-label" style="font-size:11px;color:#555;flex-shrink:0;margin-left:8px"></span>
                                </div>
                            </div>
                            <div style="display:flex;gap:4px;margin-bottom:4px">
                                <?php $_lic_key = (string) \Instinctor\Core\Config::get('instinctor_license_key', ''); ?>
                                <input type="text" id="lic-key-input" value="<?php echo esc_attr($_lic_key); ?>" placeholder="License key..." autocomplete="off"
                                       style="flex:1;height:26px;padding:0 8px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px 0 0 3px;color:#e0e0e0;outline:none;font-family:monospace;min-width:0">
                                <button type="button" id="lic-activate-btn" style="height:26px;padding:0 10px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-left:none;border-radius:0 3px 3px 0;color:#999;cursor:pointer;white-space:nowrap;flex-shrink:0"><?php echo $_lic_key ? 'Re-activate' : 'Activate'; ?></button>
                            </div>
                            <div id="lic-activate-msg" style="font-size:11px;color:#555;min-height:14px;margin-bottom:6px"></div>
                            <div id="lic-upgrade-section"<?php echo $_has_subscription ? ' style="display:none"' : ''; ?>>
                                <!-- Plan toggle: Pro (1 site) / Pro Studio (5 sites). Pro is
                                     the default; Pro Studio bumps the upgrade button to the
                                     studio price. Both toggles drive lic-upgrade-btn's label
                                     via updateUpgradeBtnLabel() in instinctor-admin-store.js. -->
                                <div style="display:flex;gap:3px;margin-bottom:6px">
                                    <button type="button" id="lic-plan-btn-pro" class="lic-plan-btn active" data-plan="pro" style="flex:1;height:26px;font-size:11px;background:#3a3f44;border:1px solid #3a3f44;border-radius:3px 0 0 3px;color:#e0e0e0;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:5px">
                                        <span style="font-weight:600">Pro</span>
                                        <span style="font-size:10px;color:#888">1 site</span>
                                    </button>
                                    <button type="button" id="lic-plan-btn-studio" class="lic-plan-btn" data-plan="pro_studio" style="flex:1;height:26px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-left:none;border-radius:0 3px 3px 0;color:#999;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:5px">
                                        <span style="font-weight:600">Studio</span>
                                        <span style="font-size:10px;color:#555">5 sites</span>
                                    </button>
                                </div>
                                <button type="button" id="lic-upgrade-btn" style="width:100%;height:26px;font-size:11px;font-weight:600;background:#fff;border:none;border-radius:3px;color:#1d2327;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px">
                                    <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
                                    Upgrade to Pro — $29.90/month
                                </button>
                                <div style="font-size:10px;color:#999;line-height:1.5;margin-top:8px;text-align:center">Pro publishes live 3D backgrounds and unlocks custom checkout, bookings, and unlimited pages.</div>
                                <div id="lic-checkout-msg" style="font-size:11px;color:#555;min-height:14px;margin-top:5px;text-align:center"></div>
                            </div>
                            <?php if (\Instinctor\Core\TierManager::isDevMode()): ?>
                            <div style="border-top:1px solid #2a2e33;margin-top:10px;padding-top:10px">
                                <div style="display:flex;align-items:center;justify-content:space-between">
                                    <span style="font-size:11px;color:#555">Preview mode</span>
                                    <button type="button" id="dev-preview-toggle" class="impulse-btn-sm" style="height:26px;padding:0 10px"><?php echo \Instinctor\Core\Config::get('instinctor_site_status') === 'preview' ? 'Stop' : 'Test'; ?></button>
                                </div>
                                <div id="dev-preview-msg" style="font-size:11px;color:#555;margin-top:4px;min-height:14px"></div>
                            </div>
                            <?php endif; ?>
                        </div>
                    </div>

                    <!-- Account — current signed-in user's email + password
                         change. Password stored as bcrypt-12 in the install's
                         instinctor_users table (or wp_users in WP mode); never
                         leaves the site. v2.1.1312. -->
                    <div id="settings-account-panel" style="flex-shrink:0;border-bottom:1px solid #2a2e33">
                        <div class="impulse-section-divider">Account</div>
                        <div style="padding:0 12px 12px">
                            <?php
                            $_curUser = \Instinctor\Core\Auth::user();
                            $_curEmail = is_object($_curUser) ? ($_curUser->user_email ?? $_curUser->email ?? '') : '';
                            ?>
                            <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px">
                                <span style="font-size:11px;color:#999">Signed in as</span>
                                <span style="font-size:11px;color:#e0e0e0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-left:8px"><?php echo esc_html($_curEmail); ?></span>
                            </div>
                            <form id="settings-pwd-form" autocomplete="on" onsubmit="return false" style="margin:0">
                            <div style="display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:6px">
                                <input type="password" id="settings-pwd-current" placeholder="Current password" autocomplete="current-password"
                                       style="width:100%;height:26px;padding:0 8px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;outline:none;box-sizing:border-box">
                                <input type="password" id="settings-pwd-new" placeholder="New password" autocomplete="new-password"
                                       style="width:100%;height:26px;padding:0 8px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;outline:none;box-sizing:border-box">
                            </div>
                            <div style="display:flex;gap:6px">
                                <input type="password" id="settings-pwd-confirm" placeholder="Confirm new password" autocomplete="new-password"
                                       style="flex:1;height:26px;padding:0 8px;font-size:11px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;outline:none;box-sizing:border-box;min-width:0">
                                <button type="button" id="settings-pwd-save" style="width:80px;flex-shrink:0;height:26px;font-size:11px;font-weight:600;background:#fff;border:none;border-radius:3px;color:#1d2327;cursor:pointer;display:flex;align-items:center;justify-content:center">
                                    Save
                                </button>
                            </div>
                            <div id="settings-pwd-msg" style="font-size:11px;color:#555;min-height:14px;margin-top:5px;text-align:center"></div>
                            </form>
                        </div>
                    </div>

                    <!-- Backup & Migration — full-site snapshot for backups,
                         in-place rollback, or moving the site to another server.
                         Sites live on the owner's own hosting from day one; the
                         license travels with the user, so pro features work
                         wherever the active subscription is recognised. -->
                    <div id="settings-backup-panel" style="flex-shrink:0;border-bottom:1px solid #2a2e33">
                        <div class="impulse-section-divider">Backup &amp; Migration</div>
                        <div style="padding:0 12px 12px">
                            <div style="font-size:11px;color:#999;line-height:1.6;margin-bottom:10px">
                                Snapshot of every page, setting, and store config in one file. Use it for backups, rollback, or moving this site to another server. Your license stays active wherever the plugin runs.
                            </div>
                            <button type="button" id="settings-backup-download" style="width:100%;height:30px;padding:0 12px;font-size:11px;font-weight:600;background:#fff;border:none;border-radius:3px;color:#1d2327;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px">
                                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
                                Download site snapshot
                            </button>
                            <div id="settings-backup-msg" style="font-size:11px;color:#555;min-height:14px;margin-top:5px;text-align:center"></div>

                            <!-- Restore — load a snapshot back into THIS install. Used
                                 either for migration target (after installing the plugin
                                 on a new host) or for in-place rollback. -->
                            <div style="border-top:1px solid #2a2e33;margin-top:10px;padding-top:10px">
                                <div style="font-size:11px;color:#999;line-height:1.6;margin-bottom:8px">
                                    Load a snapshot into this install (rollback or migration target).
                                </div>
                                <input type="file" id="settings-restore-file" accept=".json,application/json" style="display:none">
                                <button type="button" id="settings-restore-btn" style="width:100%;height:30px;padding:0 12px;font-size:11px;font-weight:600;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px">
                                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V9"/><polyline points="17 14 12 9 7 14"/><line x1="12" y1="9" x2="12" y2="21"/></svg>
                                    Load a snapshot
                                </button>
                                <div id="settings-restore-msg" style="font-size:11px;color:#555;min-height:14px;margin-top:5px;text-align:center"></div>
                            </div>

                            <details style="margin-top:10px">
                                <summary style="font-size:11px;color:#999;cursor:pointer;padding:4px 0">Move this site to another server</summary>
                                <ol style="font-size:11px;color:#999;line-height:1.6;margin:6px 0 0;padding-left:18px">
                                    <li>Install the Instinctor plugin on the new server (WordPress, or a Standalone PHP server).</li>
                                    <li>Sign in there as admin, open Settings &rarr; Backup &amp; Migration.</li>
                                    <li>Click Load a snapshot and pick the JSON you downloaded here.</li>
                                    <li>Activate your license key in Settings &rarr; License. Your subscription continues unchanged.</li>
                                </ol>
                            </details>
                        </div>
                    </div>

                    <!-- Contact Support -->
                    <div id="settings-support-panel" style="flex-shrink:0;border-top:1px solid #2a2e33;margin-top:auto">
                        <div class="impulse-section-divider">Contact Support</div>
                        <div style="padding:0 12px 12px">
                            <?php require __DIR__ . '/../partials/support-panel.php'; ?>
                        </div>
                    </div>

                    <!-- Feature-specific detail panel (RMA, bookings, subscriptions, etc.) -->
                    <div id="settings-detail-content" style="display:none;flex:1;min-height:0;overflow-y:auto"></div>

                </div><!-- end panel-body -->
            </div><!-- end settings right content -->
        </div><!-- End Right Panel -->

    </div>
    </div><!-- End Store Workspace -->

    <!-- Email Editor Modal -->
    <div id="email-editor-modal" style="display:none;position:fixed;inset:0;z-index:100050;background:rgba(0,0,0,0.6);align-items:center;justify-content:center">
        <div style="background:#22252a;border:1px solid #3a3f44;border-radius:6px;width:520px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 8px 32px rgba(0,0,0,0.5)">
            <div style="display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #2a2e33;flex-shrink:0">
                <span id="email-modal-title" style="font-size:12px;font-weight:600;color:#e0e0e0"></span>
                <button type="button" id="email-modal-close" style="background:none;border:none;color:#555;cursor:pointer;padding:2px;display:flex;align-items:center">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                </button>
            </div>
            <div id="email-modal-body" class="impulse-scroll" style="flex:1;min-height:0;overflow-y:auto;padding:16px">
            </div>
            <div style="display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:10px 16px;border-top:1px solid #2a2e33;flex-shrink:0">
                <span id="email-modal-saved" style="font-size:11px;color:#555;opacity:0;transition:opacity 0.3s">Saved</span>
                <button type="button" id="email-modal-test" class="impulse-btn-sm">Send Test</button>
                <button type="button" id="email-modal-save" class="impulse-btn-sm" style="background:#fff;color:#1d2327;border-color:#fff">Save</button>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <!-- ============================================================================ -->
    <!-- SEO WORKSPACE -->
    <!-- ============================================================================ -->
    <?php if ($role_manager->canAccessWorkspace('seo')) : ?>
    <div class="impulse-workspace" data-workspace="seo"<?php echo $workspace !== 'seo' ? ' style="display:none"' : ''; ?>>
    <div class="impulse-workspace-grid impulse-seo-grid">

        <!-- ==================== LEFT PANEL ==================== -->
        <div class="impulse-panel-left">
            <div class="impulse-panel-body">

                <!-- ── MODE TOGGLE: SEO ⇄ Traffic ──
                     Stays in the SEO workspace because the audience overlaps
                     (site owner / marketer). Click the chart icon to flip
                     the whole center panel to the analytics dashboard;
                     left panel becomes a date-range picker + per-page
                     filter. 2026-05-30. -->
                <div id="seo-mode-tabs" style="padding:8px 12px;border-bottom:1px solid #22252a;display:flex;gap:4px">
                    <button type="button" class="seo-mode-tab active" data-mode="seo" style="flex:1;height:26px;padding:0 10px;background:transparent;border:1px solid #2a2e33;border-radius:3px;color:#e0e0e0;font-size:11px;cursor:pointer">SEO</button>
                    <button type="button" class="seo-mode-tab" data-mode="traffic" style="flex:1;height:26px;padding:0 10px;background:transparent;border:1px solid #2a2e33;border-radius:3px;color:#888;font-size:11px;cursor:pointer">Traffic</button>
                </div>

                <!-- ── PAGES LIST (SEO mode) ── -->
                    <div id="seo-health-strip" style="padding:10px 12px;border-bottom:1px solid #22252a;display:flex;align-items:center;gap:10px">
                        <span id="seo-strip-score" style="font-size:20px;font-weight:700;color:#e0e0e0;line-height:1">—</span>
                        <div style="flex:1;min-width:0">
                            <div style="font-size:11px;color:#888">Avg SEO Score</div>
                            <div id="seo-strip-issues" style="font-size:11px;color:#555;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"></div>
                        </div>
                        <div style="display:flex;gap:2px;flex-shrink:0">
                            <button type="button" id="seo-view-list" class="seo-view-btn active" title="List view"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></button>
                            <button type="button" id="seo-view-grid" class="seo-view-btn" title="Grid view"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg></button>
                        </div>
                    </div>

                <!-- ── RANGE PICKER (Traffic mode) ── -->
                <div id="traffic-range-picker" style="display:none;padding:10px 12px;border-bottom:1px solid #22252a">
                    <div style="font-size:11px;color:#888;margin-bottom:6px">Range</div>
                    <div style="display:flex;flex-wrap:nowrap;gap:4px">
                        <button type="button" class="traffic-range-btn active" data-range="today" style="flex:1;min-width:0;height:26px;background:#e0e0e0;border:1px solid #e0e0e0;border-radius:3px;color:#1d2327;font-size:11px;cursor:pointer">Today</button>
                        <button type="button" class="traffic-range-btn" data-range="7d" style="flex:1;min-width:0;height:26px;background:transparent;border:1px solid #2a2e33;border-radius:3px;color:#999;font-size:11px;cursor:pointer">7d</button>
                        <button type="button" class="traffic-range-btn" data-range="30d" style="flex:1;min-width:0;height:26px;background:transparent;border:1px solid #2a2e33;border-radius:3px;color:#999;font-size:11px;cursor:pointer">30d</button>
                        <button type="button" class="traffic-range-btn" data-range="all" style="flex:1;min-width:0;height:26px;background:transparent;border:1px solid #2a2e33;border-radius:3px;color:#999;font-size:11px;cursor:pointer">All</button>
                    </div>
                    <!-- Referrer exclusions. A reporting filter, never a delete: the
                         rows stay in the table, so clearing a host restores its history.
                         Gallery referrers send sessions that look human and never
                         convert; this keeps them out of the numbers without pretending
                         they were bots. Sergei 2026-08-03. -->
                    <div style="margin-top:16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px">Excluded referrers</div>
                        <textarea id="traffic-excl" rows="3" placeholder="awwwards.com&#10;betalist.com"
                            style="width:100%;box-sizing:border-box;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;font-family:inherit;padding:6px 8px;resize:vertical;line-height:1.5"></textarea>
                        <div style="display:flex;align-items:center;gap:8px;margin-top:6px">
                            <button type="button" id="traffic-excl-save" class="impulse-btn-sm" style="height:24px;padding:0 10px;font-size:11px">Apply</button>
                            <span id="traffic-excl-note" style="font-size:11px;color:#555;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"></span>
                        </div>
                    </div>

                    <div style="margin-top:16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px">Devices</div>
                        <div id="traffic-devices" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                    <div style="margin-top:16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px">Countries</div>
                        <div id="traffic-countries" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                </div>
                    <div id="seo-pages-list">
                        <div style="padding:20px;text-align:center;color:#555;font-size:11px">Loading…</div>
                    </div>

            </div>
        </div><!-- /panel-left -->

        <!-- ==================== CENTER PANEL ==================== -->
        <div class="impulse-seo-center">

            <!-- PAGES: no page selected. Shows Google Search performance when
                 the GSC service account is configured, else the classic hint. -->
            <div id="seo-center-empty" style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%">
                <div id="gsc-fallback" style="display:flex;flex-direction:column;align-items:center">
                    <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#3a3f44" stroke-width="1.5"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
                    <div style="font-size:11px;margin-top:10px;color:#444">Select a page to edit its SEO</div>
                </div>
                <div id="gsc-panel" style="display:none;width:100%;height:100%;overflow-y:auto;padding:20px 24px">
                    <div style="display:flex;align-items:baseline;justify-content:space-between;margin-bottom:6px">
                        <div style="font-size:13px;color:#e0e0e0;font-weight:600">Search performance</div>
                        <div style="display:flex;gap:4px">
                            <button type="button" class="gsc-range-btn" data-range="7d" style="height:24px;padding:0 10px;background:transparent;border:1px solid #2a2e33;color:#999;border-radius:3px;font-size:11px;cursor:pointer">7 days</button>
                            <button type="button" class="gsc-range-btn active" data-range="28d" style="height:24px;padding:0 10px;background:#e0e0e0;border:1px solid #e0e0e0;color:#1d2327;border-radius:3px;font-size:11px;cursor:pointer">28 days</button>
                            <button type="button" class="gsc-range-btn" data-range="3mo" style="height:24px;padding:0 10px;background:transparent;border:1px solid #2a2e33;color:#999;border-radius:3px;font-size:11px;cursor:pointer">3 months</button>
                        </div>
                    </div>
                    <!-- Actual window, not the label: Search Console data lags a
                         couple of days, so every range ends two days back and the
                         dates say so rather than implying "up to today". -->
                    <div id="gsc-range" style="font-size:11px;color:#555;margin-bottom:16px"></div>
                    <div style="display:flex;gap:12px;margin-bottom:20px">
                        <div style="flex:1;background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                            <div style="font-size:10px;color:#888;text-transform:uppercase;letter-spacing:.5px">Clicks</div>
                            <div id="gsc-kpi-clicks" style="font-size:28px;font-weight:600;color:#e0e0e0;line-height:1.2;margin-top:6px">&mdash;</div>
                        </div>
                        <div style="flex:1;background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                            <div style="font-size:10px;color:#888;text-transform:uppercase;letter-spacing:.5px">Impressions</div>
                            <div id="gsc-kpi-impressions" style="font-size:28px;font-weight:600;color:#e0e0e0;line-height:1.2;margin-top:6px">&mdash;</div>
                        </div>
                    </div>
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px;margin-bottom:20px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Almost ranking (positions 8-20)</div>
                        <div id="gsc-nearmiss" class="imp-list-scroll" style="font-size:12px;color:#999"><div style="color:#555;font-size:11px">&mdash;</div></div>
                    </div>
                    <div style="display:grid;grid-template-columns:1.2fr 1fr;gap:12px">
                        <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                            <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Top queries</div>
                            <div id="gsc-queries" class="imp-list-scroll" style="font-size:12px;color:#999"><div style="color:#555;font-size:11px">&mdash;</div></div>
                        </div>
                        <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                            <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Top pages in Google</div>
                            <div id="gsc-pages" class="imp-list-scroll" style="font-size:12px;color:#999"><div style="color:#555;font-size:11px">&mdash;</div></div>
                        </div>
                    </div>
                    <div style="font-size:10px;color:#444;margin-top:14px;text-align:right">Google Search Console · last 28 days · data lags about 2 days</div>
                </div>
            </div>

            <!-- ── TRAFFIC DASHBOARD ──
                 Mounted in the SEO workspace center; visibility flipped by
                 the Traffic mode toggle in the left panel. Fed by one round-
                 trip to /analytics/summary. No third-party deps. 2026-05-30. -->
            <div id="traffic-dashboard" style="display:none;height:100%;overflow-y:auto;padding:20px 24px">
                <!-- KPI cards -->
                <!-- Views over time -->
                <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:16px 18px 12px;margin-bottom:20px">
                    <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:12px">Views over time</div>
                    <div id="traffic-chart-host" style="position:relative;height:200px">
                        <svg id="traffic-chart-svg" width="100%" height="200" style="display:block;overflow:visible"></svg>
                        <div id="traffic-chart-empty" style="position:absolute;inset:0;display:none;align-items:center;justify-content:center;color:#444;font-size:11px">No data in this range yet.</div>
                    </div>
                </div>

                <!-- Channels + conversion (leads with per-surface split live in the conversion rows) -->
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:20px">
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Channels</div>
                        <div id="traffic-channels" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Conversion by channel</div>
                        <div id="traffic-conversion" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                </div>

                <!-- Landing pages by channel + most common visitor journeys -->
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:20px">
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Landing pages by channel</div>
                        <div id="traffic-landing" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Common journeys</div>
                        <div id="traffic-journeys" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                </div>

                <!-- Referrers + per-screen drop-off -->
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:20px">
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Referrers</div>
                        <div id="traffic-referrers" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                    <div style="background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div id="traffic-dropoff-title" style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Where visitors leave</div>
                        <div id="traffic-dropoff" class="imp-list-scroll" style="font-size:12px;color:#999"><div style="color:#555;font-size:11px">&mdash;</div></div>
                    </div>
                </div>

                <!-- Converting pages: hidden until a page has an attributed lead -->
                <div id="traffic-conv-pages-card" style="display:none;background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px;margin-bottom:20px">
                    <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Converting pages</div>
                    <div id="traffic-conv-pages" class="imp-list-scroll" style="font-size:12px;color:#999">
                        <div style="color:#555;font-size:11px">&mdash;</div>
                    </div>
                </div>

                <!-- Top pages + campaign sources, side by side. flex (not grid)
                     so that when the sources card is hidden - it only appears once
                     tagged traffic exists - Top pages takes the full width instead
                     of leaving a dead column. -->
                <div style="display:flex;gap:12px;margin-bottom:20px;align-items:flex-start">
                    <div style="flex:1;min-width:0;background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Top pages</div>
                        <!-- Capped + scrolling: the list is as long as the site has
                             pages (958px on instinctor.com), which next to the short
                             sources card left most of the row empty. 320px shows ~10
                             rows, the rest scrolls in place. -->
                        <div id="traffic-pages" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                    <!-- UTM campaign sources: shown only when tagged traffic exists in the range -->
                    <div id="traffic-sources-card" style="display:none;flex:1;min-width:0;background:#1a1d21;border:1px solid #2a2e33;border-radius:4px;padding:14px 16px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px">Top sources &amp; campaigns</div>
                        <div id="traffic-sources" class="imp-list-scroll" style="font-size:12px;color:#999">
                            <div style="color:#555;font-size:11px">&mdash;</div>
                        </div>
                    </div>
                </div>

            </div>

            <!-- PAGES: editor -->
            <div id="seo-page-editor" style="display:none;height:100%;overflow-y:auto">
                <div style="padding:14px 16px 24px">

                    <!-- SERP Preview + Noindex/Nofollow -->
                    <div style="margin-bottom:14px">
                        <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px">Search Preview</div>
                        <div style="display:flex;gap:0;align-items:stretch">
                            <div class="impulse-seo-serp-preview" style="width:calc(100% - 80px);min-width:0;border-radius:3px 0 0 3px">
                                <div class="seo-serp-url" id="seo-serp-url">example.com/page-slug</div>
                                <div class="seo-serp-title" id="seo-serp-title">Page Title | Site Name</div>
                                <div class="seo-serp-desc" id="seo-serp-desc">Your meta description will appear here…</div>
                            </div>
                            <div style="width:80px;flex-shrink:0;display:flex;flex-direction:column;justify-content:center;gap:8px;padding:0 0 0 10px">
                                <label style="display:flex;align-items:center;gap:5px;font-size:11px;color:#999;cursor:pointer;white-space:nowrap">
                                    <input type="checkbox" id="seo-field-noindex" class="seo-field" data-field="noindex" title="Prevents this page from appearing in search results.">
                                    Noindex
                                </label>
                                <label style="display:flex;align-items:center;gap:5px;font-size:11px;color:#999;cursor:pointer;white-space:nowrap">
                                    <input type="checkbox" id="seo-field-nofollow" class="seo-field" data-field="nofollow" title="Tells search engines not to follow links on this page.">
                                    Nofollow
                                </label>
                            </div>
                        </div>
                    </div>

                    <!-- Two-column main layout -->
                    <div class="seo-editor-cols">

                        <!-- LEFT: Search -->
                        <div class="seo-editor-col">
                            <div class="seo-col-heading">Search</div>

                            <!-- Meta Title + Description with single Analyze button -->
                            <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">
                                <label class="seo-field-label" style="margin:0" title="Shown in search results. Keep under 60 characters. Put your focus keyword near the start.">Meta Title</label>
                                <span id="seo-title-count" style="font-size:11px;color:#777">0/60</span>
                            </div>
                            <div style="margin-bottom:8px">
                                <input type="text" id="seo-field-meta-title" class="seo-field seo-dark-input" data-field="meta_title" maxlength="120"
                                    placeholder="Page title for search results…">
                            </div>

                            <!-- Meta Description -->
                            <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">
                                <label class="seo-field-label" style="margin:0" title="Shown below the title in search results. Keep under 160 characters. Write to earn the click, not just to describe.">Meta Description</label>
                                <span id="seo-desc-count" style="font-size:11px;color:#777">0/160</span>
                            </div>
                            <div style="margin-bottom:4px">
                                <textarea id="seo-field-meta-desc" class="seo-field seo-dark-input" data-field="meta_description" rows="4" maxlength="320"
                                    placeholder="Compelling description for search results…"
                                    style="resize:vertical;line-height:1.5"></textarea>
                            </div>
                            <div style="margin-bottom:8px">
                                <button type="button" class="impulse-btn-sm seo-analyze-btn" style="width:100%;height:26px;font-size:11px">Analyze</button>
                            </div>

                            <!-- Focus Keyword + OG Image inline -->
                            <div style="margin-top:auto">
                                <input type="hidden" id="seo-field-og-image" class="seo-field" data-field="og_image_url">
                                <div style="display:flex;gap:6px;margin-bottom:4px">
                                    <label class="seo-field-label" style="flex:1;margin:0" title="The one keyword this page targets. One per page — use separate pages for separate keywords.">Focus Keyword</label>
                                    <label class="seo-field-label" style="flex:1;margin:0" title="Image shown in social share cards. Recommended: 1200×630px.">Open Graph Image</label>
                                </div>
                                <div style="display:flex;gap:6px;align-items:stretch">
                                    <input type="text" id="seo-field-focus-keyword" class="seo-field seo-dark-input" data-field="focus_keyword" style="flex:1;min-width:0" placeholder="Primary keyword…">
                                    <div style="flex:1;min-width:0;display:flex;gap:4px;align-items:stretch">
                                        <div id="seo-og-thumb" style="display:none;width:26px;height:26px;border-radius:2px;overflow:hidden;flex-shrink:0;background:#2a2e33;align-self:center">
                                            <img id="seo-og-thumb-img" src="" style="width:100%;height:100%;object-fit:cover;display:block">
                                        </div>
                                        <div id="seo-og-pick-btn" role="button" tabindex="0" style="flex:1;min-width:0;cursor:pointer;display:flex;align-items:center;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;font-family:inherit;padding:0 8px;box-sizing:border-box;overflow:hidden" title="Select image from Instinctor library">Pick</div>
                                        <button type="button" class="impulse-btn-sm" id="seo-og-clear-btn" style="display:none;flex-shrink:0;width:26px;height:26px;padding:0" title="Remove OG image">✕</button>
                                    </div>
                                </div>
                            </div>
                        </div><!-- /left col -->

                        <!-- RIGHT: Social & Technical -->
                        <div class="seo-editor-col">
                            <div class="seo-col-heading">Social &amp; Technical</div>



                            <!-- OG Title -->
                            <div style="margin-bottom:8px">
                                <label class="seo-field-label" title="Title shown when this page is shared on Facebook, LinkedIn, and other social platforms. Defaults to meta title if blank.">Open Graph Title</label>
                                <input type="text" id="seo-field-og-title" class="seo-field seo-dark-input" data-field="og_title" maxlength="95"
                                    placeholder="Blank = meta title">
                            </div>

                            <!-- OG Description -->
                            <div style="margin-bottom:8px">
                                <label class="seo-field-label" title="Description shown in social share cards. Keep under 160 characters. Defaults to meta description if blank.">Open Graph Description</label>
                                <input type="text" id="seo-field-og-desc" class="seo-field seo-dark-input" data-field="og_description" maxlength="300"
                                    placeholder="Blank = meta description">
                            </div>

                            <!-- OG Type -->
                            <div style="margin-bottom:8px">
                                <label class="seo-field-label" title="Tells social platforms what kind of content this page is. Affects how share cards are rendered.">Open Graph Type</label>
                                <div class="impulse-btn-group" id="seo-og-type-group" style="display:flex">
                                    <button type="button" class="impulse-btn-sm seo-og-type-btn active" data-value="website" style="flex:1">Website</button>
                                    <button type="button" class="impulse-btn-sm seo-og-type-btn" data-value="article" style="flex:1">Article</button>
                                    <button type="button" class="impulse-btn-sm seo-og-type-btn" data-value="product" style="flex:1">Product</button>
                                </div>
                                <input type="hidden" id="seo-field-og-type" class="seo-field" data-field="og_type" value="website">
                            </div>

                            <!-- Canonical URL -->
                            <div style="margin-top:auto">
                                <label class="seo-field-label" title="Points search engines to the preferred version of this page. Leave blank unless this content exists at multiple URLs.">Canonical URL</label>
                                <input type="text" id="seo-field-canonical" class="seo-field seo-dark-input" data-field="canonical_url"
                                    placeholder="Blank = page URL">
                            </div>



                        </div><!-- /right col -->

                    </div><!-- /seo-editor-cols -->

                    <!-- Page Images optimisation -->
                    <div id="seo-images-panel" style="display:none;margin-top:16px">
                        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;background:#22252a;padding:6px 10px;border-radius:3px">
                            <div class="seo-col-heading" style="margin:0;padding:0;border:none;color:#e0e0e0">Page Images</div>
                            <div id="seo-images-summary" style="font-size:11px;color:#555"></div>
                        </div>
                        <div id="seo-images-list" style="margin-bottom:10px"></div>
                        <div style="display:flex;align-items:center;gap:8px">
                            <button type="button" id="seo-images-optimize-btn" class="impulse-btn-sm" style="height:26px;padding:0 16px;background:#fff;color:#1d2327;border-color:#fff">Optimize page images</button>
                            <div id="seo-images-result" style="font-size:11px;color:#888"></div>
                        </div>
                    </div>

                    <!-- Page Speed (Google PageSpeed Insights).
                         Measured on demand: each run is a live Lighthouse render on
                         Google's servers and takes 10-30s, so nothing here fires on
                         open. Lab and field numbers are shown apart because they
                         answer different questions. -->
                    <div id="seo-speed-panel" style="display:none;margin-top:16px">
                        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;background:#22252a;padding:6px 10px;border-radius:3px">
                            <div class="seo-col-heading" style="margin:0;padding:0;border:none;color:#e0e0e0">Page Speed</div>
                            <div id="seo-speed-stamp" style="font-size:11px;color:#555"></div>
                        </div>
                        <div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">
                            <div class="impulse-btn-group" id="seo-speed-strategy" style="display:flex">
                                <button type="button" class="impulse-btn-sm active" data-strategy="mobile" style="height:26px;padding:0 12px;font-size:11px">Mobile</button>
                                <button type="button" class="impulse-btn-sm" data-strategy="desktop" style="height:26px;padding:0 12px;font-size:11px">Desktop</button>
                            </div>
                            <button type="button" id="seo-speed-run-btn" class="impulse-btn-sm" style="height:26px;padding:0 16px;background:#fff;color:#1d2327;border-color:#fff">Measure</button>
                            <div id="seo-speed-status" style="font-size:11px;color:#888"></div>
                        </div>
                        <div id="seo-speed-body" style="display:none">
                            <div style="display:flex;gap:10px;align-items:stretch;margin-bottom:10px">
                                <div style="width:96px;flex-shrink:0;background:#22252a;border-radius:3px;padding:10px;text-align:center">
                                    <div id="seo-speed-score" style="font-size:28px;font-weight:600;color:#e0e0e0;line-height:1.2">&mdash;</div>
                                    <div style="font-size:11px;color:#555;margin-top:2px">Performance</div>
                                </div>
                                <div id="seo-speed-metrics" style="flex:1;min-width:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:6px"></div>
                            </div>
                            <div id="seo-speed-field-wrap" style="display:none;margin-bottom:10px">
                                <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px">Real visitors, last 28 days</div>
                                <div id="seo-speed-field" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:6px"></div>
                            </div>
                            <div id="seo-speed-opps-wrap" style="display:none">
                                <div style="font-size:11px;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px">Biggest wins</div>
                                <div id="seo-speed-opps" style="font-size:12px;color:#999"></div>
                            </div>
                        </div>
                    </div>

                    <!-- Auto-save status -->
                    <div id="seo-save-status" style="font-size:11px;color:#555;margin-top:10px;height:14px;text-align:right"></div>

                </div>
            </div><!-- /seo-page-editor -->


            <!-- Schema preview modal -->
            <div id="seo-schema-modal" class="impulse-modal" style="display:none">
                <div class="impulse-modal-content" style="max-width:560px">
                    <div class="impulse-modal-header">
                        <span>Local Business Schema Preview</span>
                        <button type="button" class="impulse-modal-close">&#x2715;</button>
                    </div>
                    <div class="impulse-modal-body" style="padding:16px">
                        <p style="font-size:11px;color:#777;margin:0 0 10px">This JSON-LD block is injected into every page &lt;head&gt;. Test it at <a href="https://search.google.com/test/rich-results" target="_blank" style="color:#999">Google Rich Results Test</a>.</p>
                        <pre id="seo-schema-content" style="background:#2a2e33;padding:12px;border-radius:3px;font-size:11px;color:#e0e0e0;overflow-x:auto;white-space:pre-wrap;margin:0;font-family:monospace;max-height:360px;overflow-y:auto"></pre>
                    </div>
                </div>
            </div>
            <!-- Cannibalization modal -->
            <div id="seo-cannibal-modal" class="impulse-modal" style="display:none">
                <div class="impulse-modal-content" style="max-width:480px">
                    <div class="impulse-modal-header">
                        <span>Keyword Cannibalization</span>
                        <button type="button" class="impulse-modal-close">&#x2715;</button>
                    </div>
                    <div class="impulse-modal-body" style="padding:16px">
                        <p style="font-size:11px;color:#777;margin:0 0 10px">These keywords are targeted by more than one page. Each keyword should have exactly one page — duplicate targeting confuses Google and splits ranking authority.</p>
                        <div id="seo-cannibal-list"></div>
                    </div>
                </div>
            </div>
            <!-- Batch AI progress modal -->
            <div id="seo-batch-modal" class="impulse-modal" style="display:none">
                <div class="impulse-modal-content" style="max-width:400px">
                    <div class="impulse-modal-header">
                        <span id="seo-batch-modal-title">Generating Meta…</span>
                        <button type="button" class="impulse-modal-close" id="seo-batch-close-btn">&#x2715;</button>
                    </div>
                    <div class="impulse-modal-body" style="padding:16px">
                        <div id="seo-batch-progress-bar-wrap" style="background:#2a2e33;border-radius:3px;height:4px;margin-bottom:10px;overflow:hidden">
                            <div id="seo-batch-progress-bar" style="background:#e0e0e0;height:4px;width:0%;transition:width .3s"></div>
                        </div>
                        <div id="seo-batch-progress-text" style="font-size:11px;color:#888;text-align:center;margin-bottom:8px"></div>
                        <div id="seo-batch-log" style="font-size:11px;color:#555;max-height:200px;overflow-y:auto;font-family:monospace;line-height:1.6"></div>
                    </div>
                </div>
            </div>

        </div><!-- /seo-center -->

        <!-- ==================== RIGHT PANEL ==================== -->
        <div class="impulse-panel-right" id="seo-right-panel">

            <!-- PAGES: analysis -->
            <div id="seo-right-analysis" style="height:100%;overflow-y:auto;display:flex;flex-direction:column">
                <div class="impulse-section-divider" style="margin:0;border-radius:0;flex-shrink:0">Analysis</div>

                <!-- Empty / select state -->
                <div id="seo-right-empty" style="flex:1;display:flex;align-items:center;justify-content:center;padding:20px;text-align:center;font-size:11px;color:#444">
                    Select a page to analyze
                </div>

                <!-- Score display — hidden until analyzed -->
                <div id="seo-right-score-area" style="display:none;flex-direction:column;align-items:center;padding:20px 12px 12px;flex-shrink:0">
                    <!-- Big SVG ring -->
                    <div style="position:relative;width:110px;height:110px">
                        <svg width="110" height="110" viewBox="0 0 110 110" style="transform:rotate(-90deg)">
                            <circle cx="55" cy="55" r="46" fill="none" stroke="#2a2e33" stroke-width="10"/>
                            <circle id="seo-ring-arc" cx="55" cy="55" r="46" fill="none" stroke="#e0e0e0" stroke-width="10"
                                stroke-dasharray="289.0" stroke-dashoffset="289.0" stroke-linecap="round"/>
                        </svg>
                        <div style="position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center">
                            <span id="seo-right-score-num" style="font-size:28px;font-weight:700;color:#e0e0e0;line-height:1">—</span>
                            <span style="font-size:11px;color:#555;margin-top:1px">/100</span>
                        </div>
                    </div>
                    <button type="button" class="impulse-btn-sm" id="seo-analyze-btn" style="height:26px;padding:0 16px;margin-top:10px">Analyze</button>
                </div>

                <!-- Analyze button when no score yet (page selected but not analyzed) -->
                <div id="seo-right-analyze-prompt" style="display:none;flex-direction:column;align-items:center;padding:20px 12px;flex-shrink:0">
                    <button type="button" class="impulse-btn-sm" id="seo-analyze-btn-prompt" style="height:26px;padding:0 16px">Analyze</button>
                </div>

                <!-- Checks list -->
                <div id="seo-checks-list" style="padding:0 12px 12px;flex:1;overflow-y:auto"></div>
            </div>

            <!-- REDIRECTS: stats -->
            <!-- SETTINGS: health overview -->
            <div id="seo-settings-right" style="display:none;height:100%;overflow-y:auto">
                <div style="padding:14px 12px 20px" id="seo-settings-right-inner">
                    <div style="padding:20px;text-align:center;font-size:11px;color:#555">Loading…</div>
                </div>
            </div>

            <!-- TRAFFIC: the headline numbers (replaces SEO analysis in the
                 right column when the Traffic mode tab is active). Same
                 .seo-stat-card grid as the Site Health panel so both right-column
                 views read as one component; the range caption sits under the grid
                 rather than on every card, since one range governs all four. -->
            <div id="traffic-right-panel" style="display:none;height:100%;overflow-y:auto">
                <div class="impulse-section-divider" style="margin:0;border-radius:0;flex-shrink:0">Overview</div>
                <div style="padding:8px 12px 12px">
                    <div style="display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-bottom:6px">
                    <div class="seo-stat-card">
                        <div class="seo-stat-card-num" id="traffic-kpi-views">—</div>
                        <div class="seo-stat-card-label">Views</div>
                    </div>
                    <div class="seo-stat-card">
                        <div class="seo-stat-card-num" id="traffic-kpi-visitors">—</div>
                        <div class="seo-stat-card-label">Visitors</div>
                    </div>
                    <div class="seo-stat-card">
                        <div class="seo-stat-card-num" id="traffic-kpi-time">—</div>
                        <div class="seo-stat-card-label">Avg time</div>
                    </div>
                    <div class="seo-stat-card">
                        <div class="seo-stat-card-num" id="traffic-kpi-bounce">—</div>
                        <div class="seo-stat-card-label">Bounce</div>
                    </div>
                    </div>
                    <div id="traffic-kpi-views-range" style="font-size:11px;color:#555;text-align:center">Today</div>
                    <!-- Same range, written by the same JS line; kept so that write
                         stays harmless now that one caption covers the grid. -->
                    <span id="traffic-kpi-visitors-range" style="display:none"></span>
                </div>
            </div>
        </div><!-- /panel-right -->

    </div><!-- /workspace-grid -->
    </div><!-- /workspace seo -->
    <?php endif; ?>
    
    <!-- ============================================================================ -->
    <!-- IMPULSE WORKSPACE (Page Builder) -->
    <!-- ============================================================================ -->
<!-- robots.txt modal -->
            <div id="seo-robots-modal" class="impulse-modal" style="display:none">
                <div class="impulse-modal-content" style="max-width:560px">
                    <div class="impulse-modal-header">
                        <span>robots.txt Preview</span>
                        <button type="button" class="impulse-modal-close">&#x2715;</button>
                    </div>
                    <div class="impulse-modal-body" style="padding:16px">
                        <pre id="seo-robots-content" style="background:#2a2e33;padding:12px;border-radius:3px;font-size:11px;color:#e0e0e0;overflow-x:auto;white-space:pre-wrap;margin:0;font-family:monospace"></pre>
                    </div>
                </div>
            </div>

        <?php if ($role_manager->canAccessWorkspace('impulse')) : ?>
    <div class="impulse-workspace" data-workspace="impulse"<?php echo $workspace !== 'impulse' ? ' style="display:none"' : ''; ?>>
    <!-- Main Editor Area -->
    <div class="impulse-main">
        <!-- Left Panel: Blocks -->
        <div class="impulse-panel impulse-panel-left">
            <div class="impulse-panel-tabs">
                <button type="button" class="impulse-panel-tab active" data-tab="blocks">Blocks</button>
                <button type="button" class="impulse-panel-tab" data-tab="structure">Structure</button>
                <button type="button" class="impulse-panel-tab" data-tab="templates">Library</button>
                <button type="button" class="impulse-compact-toggle" title="Compact palette" aria-label="Toggle compact palette"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m11 17-5-5 5-5"/><path d="m18 17-5-5 5-5"/></svg></button>
            </div>
            <?php // Compact palette toggle moved to InstinctorAdmin.initCompactPalette() in assets/js/admin.js (WordPress.org compliance). ?>
            <div class="impulse-panel-body">
                <div class="impulse-blocks-panel">
                    <div class="impulse-blocks-panel-inner">
                    <?php foreach ($elements as $cat_key => $category): ?>
                    <div class="impulse-block-category" data-category="<?php echo esc_attr($cat_key); ?>">
                        <?php /* Category LABELS are gone: the icons already say what each
                                 chip is, and five labels plus their margins cost ~100px of a
                                 panel whose height follows the viewport, taken straight out
                                 of the chips. Grouping is carried by adjacency now, so the
                                 order is load-bearing (Sergei 2026-08-07, accepted). The one
                                 boundary icons cannot convey is kept as a rule below:
                                 Layout holds containers you drop things INTO, everything
                                 after it is content that goes IN them. */ ?>
                        <?php
                        // Split items: nav-style (text buttons) vs regular (icon grid)
                        $nav_items = [];
                        $grid_items = [];
                        $isg_store_type = \Instinctor\Core\Config::get('instinctor_store_type', 'mixed');
                        $isg_has_shipping = in_array($isg_store_type, ['physical_goods', 'mixed']);
                        $isg_has_booking  = in_array($isg_store_type, ['services', 'mixed', 'salon', 'home_services', 'instructor', 'restaurant', 'automotive']);
                        // Service-first verticals (salon, home services, automotive) hide ecommerce
                        // blocks (products/cart/checkout/plans/bundle) unless retail is switched on;
                        // instructor never shows them.
                        $isg_hide_ecom = (($isg_store_type === 'salon') && !\Instinctor\Core\StoreFeatures::salonRetailEnabled())
                                       || (($isg_store_type === 'home_services') && !\Instinctor\Core\StoreFeatures::hsRetailEnabled())
                                       || (($isg_store_type === 'automotive') && !\Instinctor\Core\StoreFeatures::autoRetailEnabled())
                                       || ($isg_store_type === 'instructor');
                        // Configurator (build-a-pizza) is a bespoke, Instinctor-installed pack —
                        // never a palette block. It's placed via page data + configured in its own
                        // panel, so it has no Add-block entry at all (removed 2026-06-22).
                        foreach ($category['items'] as $el_key => $element) {
                            // Gated entries may be null in the items array;
                            // skip so the loop doesn't index a null value.
                            if (!is_array($element)) continue;
                            if (!empty($element['shippingOnly']) && !$isg_has_shipping) continue;
                            if (!empty($element['bookingOnly']) && !$isg_has_booking) continue;
                            if (!empty($element['ecomOnly']) && $isg_hide_ecom) continue;
                            if (!empty($element['instructorOnly']) && $isg_store_type !== 'instructor') continue;
                            // Quote form: trades that price a job after seeing it. A salon
                            // books a slot at a known price and has no use for it.
                            if (!empty($element['quoteOnly']) && !in_array($isg_store_type, ['home_services', 'automotive'], true)) continue;
                            if ($cat_key === 'navigation' || !empty($element['nav'])) {
                                $nav_items[$el_key] = $element;
                            } else {
                                $grid_items[$el_key] = $element;
                            }
                        }
                        ?>
                        <?php if ($nav_items): ?>
                        <div class="impulse-block-grid impulse-block-grid-nav">
                            <?php foreach ($nav_items as $el_key => $element): ?>
                            <div class="impulse-block impulse-block-nav" draggable="true" data-element="<?php echo esc_attr($el_key); ?>" data-label="<?php echo esc_attr($element['label']); ?>">
                                <?php if (!empty($element['icon'])): ?><svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" fill="none" stroke-width="2" style="flex-shrink:0"><?php echo wp_kses(\Instinctor\Services\TemplateService::getElementIcon($element['icon']), impulse_admin_view_svg_allowed()); ?></svg>
                                <span><?php echo esc_html($element['label']); ?></span>
                                <?php else: ?><span><?php echo esc_html($element['label']); ?></span>
                                <?php endif; ?>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <?php endif; ?>
                        <?php if ($grid_items): ?>
                        <div class="impulse-block-grid"<?php echo $nav_items ? ' style="margin-top:7px"' : ''; ?>>
                            <?php foreach ($grid_items as $el_key => $element): ?>
                            <?php
                            // Pro-teaser tiles: not draggable, click handler in admin-core.js
                            // opens an upgrade modal. No platform call.
                            $isProTease = !empty($element['pro']);
                            $blockCls   = 'impulse-block' . ($isProTease ? ' impulse-block-pro' : '');
                            $dragAttr   = $isProTease ? 'false' : 'true';
                            ?>
                            <div class="<?php echo esc_attr($blockCls); ?>" draggable="<?php echo esc_attr($dragAttr); ?>" data-element="<?php echo esc_attr($el_key); ?>" data-label="<?php echo esc_attr($element['label']); ?>"<?php if ($isProTease): ?> data-pro="1" data-pro-feature="<?php echo esc_attr($element['label']); ?>" data-pro-tease="<?php echo esc_attr($element['tease'] ?? ''); ?>" title="<?php echo esc_attr__('Pro feature', 'instinctor'); ?>"<?php endif; ?>>
                                <?php if (!empty($element['icon'])): ?><div class="impulse-block-icon"><svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" fill="none" stroke-width="2"><?php echo wp_kses(\Instinctor\Services\TemplateService::getElementIcon($element['icon']), impulse_admin_view_svg_allowed()); ?></svg></div><?php endif; ?>
                                <span><?php echo wp_kses($element['label'], ['br' => []]); ?></span>
                                <?php if ($isProTease): ?><svg class="impulse-block-pro-lock" viewBox="0 0 24 24" width="11" height="11" stroke="currentColor" fill="none" stroke-width="2" aria-hidden="true"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg><?php endif; ?>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <?php endif; ?>
                    </div>
                    <?php endforeach; ?>
                    </div><!-- /.impulse-blocks-panel-inner -->

                </div>
                <div class="impulse-templates-panel" style="display:none;">
                    <div class="impulse-library-subtabs">
                        <button type="button" class="impulse-library-subtab active" data-subtab="graphics">Graphics</button>
                        <button type="button" class="impulse-library-subtab" data-subtab="media">Media</button>
                    </div>
                    <div class="impulse-library-content impulse-library-graphics active">
                        <div class="impulse-graphics-subtabs" style="display:flex;gap:0;margin-bottom:8px;padding:0 4px;">
                            <button type="button" class="impulse-graphics-subtab active" data-gfx-subtab="shapes" style="flex:1;height:26px;font-size:11px;font-weight:600;background:#e0e0e0;color:#1d2327;border:1px solid #3a3f44;border-radius:3px 0 0 3px;cursor:pointer;text-transform:uppercase;letter-spacing:0.5px;box-sizing:border-box">Shapes</button>
                            <button type="button" class="impulse-graphics-subtab" data-gfx-subtab="images" style="flex:1;height:26px;font-size:11px;font-weight:600;background:#2a2e33;color:#999;border:1px solid #3a3f44;border-left:none;border-radius:0 3px 3px 0;cursor:pointer;text-transform:uppercase;letter-spacing:0.5px;box-sizing:border-box">Stock</button>
                        </div>
                        <div class="impulse-gfx-content impulse-gfx-shapes active">
                            <div class="impulse-block-grid" id="impulse-library-shapes-grid">
                                <div style="grid-column:1/-1;text-align:center;padding:20px 0;color:#888;font-size:11px">Loading shapes...</div>
                            </div>
                        </div>
                        <div class="impulse-gfx-content impulse-gfx-images" style="display:none;">
                            <div class="impulse-block-grid" id="impulse-library-images-grid">
                                <div style="grid-column:1/-1;text-align:center;padding:20px 0;color:#888;font-size:11px">Click Images to load...</div>
                            </div>
                        </div>
                    </div>
                    <!-- Media (local uploads) — inline grid, same pattern as Shapes/Stock -->
                    <div class="impulse-library-content impulse-library-media" style="display:none;">
                        <!-- Toolbar -->
                        <div style="display:flex;align-items:center;gap:6px;padding:0 4px 6px">
                            <label class="impulse-btn-sm" style="cursor:pointer;display:flex;align-items:center;gap:4px">
                                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
                                Upload
                                <input type="file" id="media-lib-upload-input" accept="image/*" multiple style="display:none">
                            </label>
                            <div class="impulse-medialib-tabs" style="display:flex;gap:3px;margin-left:2px">
                                <button type="button" class="impulse-medialib-filter" data-mfilter="all" style="font-size:10px;line-height:1;padding:4px 9px;border:1px solid #1d2327;background:#1d2327;color:#fff;cursor:pointer;border-radius:3px">All</button>
                                <button type="button" class="impulse-medialib-filter" data-mfilter="3d" style="font-size:10px;line-height:1;padding:4px 9px;border:1px solid #e0e0e0;background:#fff;color:#555;cursor:pointer;border-radius:3px">3D</button>
                                <button type="button" class="impulse-medialib-filter" data-mfilter="industry" style="font-size:10px;line-height:1;padding:4px 9px;border:1px solid #e0e0e0;background:#fff;color:#555;cursor:pointer;border-radius:3px">Industry</button>
                            </div>
                            <div style="flex:1"></div>
                            <span id="media-lib-count" style="font-size:10px;color:#555"></span>
                        </div>
                        <!-- Grid -->
                        <div class="impulse-block-grid" id="impulse-library-media-grid">
                            <div style="grid-column:1/-1;text-align:center;padding:20px 0;color:#888;font-size:11px">Loading...</div>
                        </div>
                    </div>
                </div>
                <div class="impulse-structure-panel" style="display:none;">
                    <div class="impulse-structure-tree" id="impulse-structure-tree">
                        <!-- Dynamic structure tree -->
                    </div>
                    <div class="impulse-structure-root-drop" data-parent="0">
                        <?php esc_html_e('Drop here to move to page root', 'instinctor'); ?>
                    </div>
                    <div class="impulse-structure-add-screen" id="impulse-structure-add-screen" style="display:none;padding-top:8px">
                        <button type="button" class="instinctor-btn instinctor-btn-sm" id="impulse-add-screen-btn" style="width:100%">+ Add Screen</button>
                    </div>
                </div>
            </div>
            <div id="impulse-bug-report-bar" style="padding:6px 16px 10px;border-top:1px solid #2a2e33;flex-shrink:0;box-sizing:border-box;width:100%;display:flex;align-items:flex-end;gap:4px">
                <textarea id="impulse-bug-text" placeholder="Report a bug / Suggest a feature…" rows="1" style="flex:1;min-width:0;height:26px;max-height:88px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;padding:4px 8px;box-sizing:border-box;resize:none;line-height:1.4;font-family:inherit;overflow:hidden"></textarea>
                <button type="button" id="impulse-bug-submit" style="display:none;flex-shrink:0;height:26px;padding:0 10px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#888;font-size:11px;cursor:pointer;transition:color 0.15s">Send</button>
            </div>
        </div>
        
        <!-- Center: Preview -->
        <div class="impulse-preview-area">
            <?php if (!$has_pro_license): ?>
            <div class="impulse-free-banner" id="impulse-free-banner"><span>Go Pro to publish live 3D backgrounds, plus custom checkout, bookings, and unlimited pages. <button type="button" class="impulse-upgrade-link">Subscribe &rarr;</button></span><button type="button" id="impulse-free-banner-dismiss" title="Dismiss" aria-label="Dismiss" style="background:transparent;border:none;color:#999;cursor:pointer;font-size:16px;line-height:1;padding:0 2px 0 12px;flex-shrink:0">&times;</button></div>
            <?php endif; ?>
            <div class="impulse-canvas-scroll">
            <!-- Canvas Header Bar -->
            <!-- Canvas header removed - tabs/controls moved to topbar -->
            
            <!-- Page List (shown by default) -->
            <div class="impulse-page-list" id="impulse-page-list">
                <div id="impulse-canvas-empty" class="impulse-canvas-empty"<?php echo (!empty($pages) || !empty($trashed_pages)) ? ' style="display:none"' : ''; ?>>
                    <p>Create a new page to begin</p>
                </div>
                <?php if (!empty($pages) && count($pages) >= 8): ?>
                <!-- Empty state for the topbar page search (input lives in .impulse-topbar-list-row). -->
                <div id="impulse-pg-noresults" style="display:none;padding:20px 4px;color:#666;font-size:12px">No pages match your search.</div>
                <?php endif; ?>
                <?php
                /**
                 * --card-size baseline. The grid CSS uses:
                 *   grid-template-columns: repeat(auto-fill, minmax(var(--card-size), 1fr))
                 * so the smaller this value, the more columns fit per row.
                 *
                 * Auto-responsive default with clamp(min, ideal, max):
                 *   - On wide laptops/desktops (>=1250px viewport): clamps to 150px
                 *     — the value Sergei tuned to on his laptop as the "best".
                 *   - As the viewport narrows, 12vw shrinks below 150 and cards
                 *     follow: 1024w → ~123, 768w → ~92, 480w → 100 (floor).
                 *   - 100px floor keeps cards readable on the smallest screens.
                 *
                 * The manual size slider in the topbar still works — once the
                 * user drags it, JS writes a flat pixel value to this same var
                 * and the slider position wins until the user resets it.
                 */
                ?>
                <div class="impulse-canvas-grid" id="impulse-canvas-grid" style="--card-size: clamp(100px, 12vw, 150px);">
                    <?php foreach ($pages as $page): ?>
                    <?php
    $isFront = ($page->id === $_front_page_id);
    // Fallback: match by permalink when ID-based detection fails
    if (!$isFront && $_front_page_id === 0 && !empty($page->permalink)) {
        $isFront = (rtrim($page->permalink, '/') . '/' === $_home_url);
    }
?>
                    <div class="impulse-page-card<?php echo $isFront ? ' is-frontpage' : ''; ?> is-sequence" data-id="<?php echo esc_attr($page->id); ?>" data-status="<?php echo esc_attr($page->status); ?>" data-type="<?php echo esc_attr($page->type); ?>" data-slug="<?php echo esc_attr($page->slug); ?>" data-url="<?php echo esc_attr($page->permalink); ?>" data-updated="<?php echo esc_attr($page->updated_at ?? ''); ?>" data-created="<?php echo esc_attr($page->created_at ?? ''); ?>" data-owner="<?php echo esc_attr((string) ($page->owner_id ?? '')); ?>" data-role="<?php echo esc_attr((string) ($page->role ?? '')); ?>" data-sort="<?php echo esc_attr((string) ($page->sort_order ?? 0)); ?>"<?php echo $page->type === 'post' ? ' style="display:none"' : ''; ?>>
                        <div class="impulse-page-preview" data-name="<?php echo esc_attr($page->name); ?>">
                            <?php if ($page->thumbnail): ?>
                            <img src="<?php echo esc_attr($page->thumbnail); ?>" class="impulse-preview-img" loading="lazy" alt="">
                            <?php else: ?>
                            <div class="impulse-preview-placeholder" data-needs-thumb="1"><img src="<?php echo esc_url(INSTINCTOR_PLUGIN_URL . 'assets/images/placeholder-logo.svg'); ?>" alt=""></div>
                            <?php endif; ?>
                            <div class="impulse-card-status <?php echo $page->status === 'published' ? 'is-live' : ''; ?>" data-id="<?php echo esc_attr($page->id); ?>" title="<?php echo $page->status === 'published' ? 'Live - click to unpublish' : 'Draft - click to publish'; ?>">
                                <span class="status-circle"></span>
                            </div>
                        </div>
                        <div class="impulse-page-info">
                            <div class="impulse-page-name" data-id="<?php echo esc_attr($page->id); ?>">
                                <?php if ($isFront): ?>
                                <span class="name-text" style="letter-spacing:0.08em;font-size:12px;font-weight:600">HOME PAGE</span>
                                <?php else: ?>
                                <span class="name-text" title="Click to rename"><?php echo esc_html($page->name); ?></span>
                                <input type="text" class="name-input" value="<?php echo esc_attr($page->name); ?>" autocomplete="off">
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>
                    <?php endforeach; ?>

                    <?php foreach ($trashed_pages as $page): ?>
                    <div class="impulse-page-card trashed" data-id="<?php echo esc_attr($page->id); ?>" data-status="trash" data-role="<?php echo esc_attr((string) ($page->role ?? '')); ?>" style="display:none;">
                        <div class="impulse-page-preview" data-name="<?php echo esc_attr($page->name); ?>">
                            <?php if ($page->thumbnail): ?>
                            <img src="<?php echo esc_attr($page->thumbnail); ?>" class="impulse-preview-img" loading="lazy" alt="">
                            <?php else: ?>
                            <div class="impulse-preview-placeholder" data-needs-thumb="1"><img src="<?php echo esc_url(INSTINCTOR_PLUGIN_URL . 'assets/images/placeholder-logo.svg'); ?>" alt=""></div>
                            <?php endif; ?>
                            <div class="impulse-card-status is-trash">
                                <span>Trashed</span>
                            </div>
                        </div>
                        <div class="impulse-page-info">
                            <div class="impulse-page-name">
                                <span class="name-text"><?php echo esc_html($page->name); ?></span>
                            </div>
                        </div>
                    </div>
                    <?php endforeach; ?>
                </div>
                <div class="impulse-grid-loading" id="impulse-grid-loading" style="display:none">
                    <div class="impulse-grid-spinner"></div>
                    <span>Loading pages...</span>
                </div>
            </div>
            
            <!-- Canvas/Editor (hidden by default, shown when editing) -->
            <?php
            $_canvas_sm = '1'; // every page is a screen sequence
            $_canvas_bg = ($_canvas_sm === '1') ? '#000000' : '#1a1d21';
            ?>
            <div class="impulse-canvas" data-device="desktop" data-screen-mode="<?php echo esc_attr($_canvas_sm); ?>" style="background:<?php echo esc_attr($_canvas_bg); ?>;<?php echo !$page_id ? 'display:none;' : ''; ?>"><?php // data-screen-mode set in PHP so CSS aspect-ratio applies before JS ?>
                <div id="impulse-load-bar"><div id="impulse-load-bar-fill"></div></div>
                <!-- Editor-only toggle: flip cell-border outlines off across the
                     whole iframe (Grid / Rows / Columns / Table). Frontend never
                     sees this state. State persists in sessionStorage. -->
                <button type="button" class="impulse-canvas-cellborders-toggle" id="impulse-cellborders-toggle" title="Toggle cell borders (editor only)">
                    <svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="1"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="12" y1="3" x2="12" y2="21"/></svg>
                </button>
                <iframe id="impulse-iframe" src="<?php
                if ($page_id) {
                    if (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') {
                        echo esc_url(home_url('/?impulse_preview=' . $page_id . '&edit=1&device=desktop&t=' . time()));
                    } else {
                        echo esc_url('/admin/preview/' . $page_id . '?edit=1&t=' . time());
                    }
                } else {
                    echo 'about:blank';
                }
                ?>"></iframe>
                <div id="impulse-drop-overlay" class="impulse-drop-overlay"></div>
            </div>
            </div><!-- /impulse-canvas-scroll -->
            <!-- Screen Sequence Bar — always visible below canvas in screen sequence mode -->
        </div>

        <!-- Right Panel: Settings -->
        <div class="impulse-panel impulse-panel-right">
            <div class="impulse-device-tabs" id="impulse-device-tabs" style="position:relative">
                <button type="button" class="impulse-device-tab active" data-device="desktop">Desktop</button>
                <button type="button" class="impulse-device-tab" data-device="tablet">Tablet</button>
                <button type="button" class="impulse-device-tab" data-device="mobile">Mobile</button>
                <!-- QR-on-phone hand-off: surfaces only when Mobile is active.
                     Click → tiny popover with a QR code for the published page URL,
                     so the designer can scan it on a real phone instead of
                     trusting the 375px iframe simulation. -->
                <button type="button" id="impulse-mobile-qr-btn" title="Open on your phone" style="display:none;background:transparent;border:1px solid #3a3f44;color:#999;width:26px;height:26px;border-radius:3px;margin-left:6px;cursor:pointer;padding:0;align-items:center;justify-content:center" onmouseover="this.style.color='#e0e0e0';this.style.borderColor='#555'" onmouseout="this.style.color='#999';this.style.borderColor='#3a3f44'">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><line x1="14" y1="14" x2="14" y2="14"/><line x1="21" y1="14" x2="21" y2="14"/><line x1="14" y1="21" x2="14" y2="21"/><line x1="21" y1="21" x2="21" y2="21"/><line x1="17.5" y1="17.5" x2="17.5" y2="17.5"/></svg>
                </button>
                <div id="impulse-mobile-qr-popover" style="display:none;position:absolute;top:32px;right:0;z-index:10000;background:#fff;border:1px solid #2a2e33;border-radius:6px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,0.4);width:200px">
                    <div id="impulse-mobile-qr-canvas" style="width:176px;height:176px;background:#fff"></div>
                    <div id="impulse-mobile-qr-url" style="font-size:10px;color:#666;text-align:center;margin-top:8px;word-break:break-all"></div>
                </div>
            </div>
            <?php // QR hand-off wiring moved to InstinctorAdmin.initMobileQr() in assets/js/admin.js (WordPress.org compliance). ?>
            <div class="impulse-panel-header">
                <h3 id="impulse-settings-title">Page Settings</h3>
            </div>
            <div class="impulse-panel-content" id="impulse-settings-body">
                <!-- Dynamic settings content -->
            </div>
            <!-- Screen list — shown only in screen sequence mode, pinned at bottom -->
            <?php /* The canvas-edge chips (#impulse-section-chips) are the visible selector
             now. This list stays in the DOM because the chips delegate their clicks
             to its rows, keeping selection and every side effect single-sourced. */ ?>
            <div id="impulse-screen-sidebar" class="impulse-screen-sidebar-hidden" style="display:none;flex-shrink:0;border-top:1px solid #2a2e33">
                <div id="impulse-sequence-toggle" style="margin:0;padding:10px 14px 8px;border-bottom:1px solid #2a2e33;font-size:11px;text-transform:uppercase;letter-spacing:0.5px;color:#888;cursor:pointer;user-select:none;display:flex;align-items:center;justify-content:space-between" title="Click to collapse">
                    <span id="impulse-screens-label">Screens</span>
                    <svg id="impulse-sequence-chevron" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="transition:transform 0.15s"><polyline points="6 9 12 15 18 9"/></svg>
                </div>
                <div id="impulse-sequence-body" class="impulse-sequence-body" style="padding:8px 10px">
                    <div id="impulse-screen-list"></div>
                    <button type="button" class="instinctor-btn instinctor-btn-sm" id="impulse-add-screen-btn" style="width:100%;margin-top:6px">+ Add Screen</button>
                </div>
            </div>
            <!-- Mobile Optimizer — pinned above chat footer -->
            <div id="impulse-mobile-optimize-footer" style="flex-shrink:0;padding:8px 14px 0">
                <button type="button" id="impulse-mobile-optimize-btn" style="width:100%;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px;transition:background 0.15s" onmouseover="this.style.background='#3a3f44'" onmouseout="this.style.background='#2a2e33'">
                    Optimize for Mobile
                </button>
            </div>
            <!-- Chat Widget pinned footer — always at the very bottom of the settings column -->
            <div id="impulse-chat-toggle-footer" style="display:none;flex-shrink:0;padding:8px 14px 10px">
                <div class="impulse-section-divider impulse-divider-with-toggle" style="margin:0">
                    <span>Chat Widget</span>
                    <span class="impulse-divider-line" style="flex:1;height:1px;background:#3a3f44"></span>
                    <input type="checkbox" name="chat_visible" value="1" checked>
                </div>
                <div class="impulse-section-divider impulse-divider-with-toggle" style="margin:6px 0 0">
                    <span title="Mobile only. The pill inviting visitors to tilt the phone.">Tilt Hint</span>
                    <span class="impulse-divider-line" style="flex:1;height:1px;background:#3a3f44"></span>
                    <input type="checkbox" name="motion_hint_visible" value="1" checked>
                </div>
            </div>

        </div>
    </div>
    </div><!-- End Impulse Workspace -->
    <?php endif; ?>


<!-- old image picker layer removed v2.1.1783 (Library pick mode replaces it) -->


</div>

<!-- Product Picker Modal -->
<div id="impulse-product-modal" class="impulse-modal" style="display:none;">
    <div class="impulse-modal-content impulse-modal-lg">
        <div class="impulse-modal-header" style="padding:8px 16px;gap:8px">
            <input type="text" id="impulse-product-search" placeholder="Search products..." style="flex:1;height:26px;padding:0 8px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;box-sizing:border-box">
            <select id="impulse-product-category" style="height:26px;padding:0 6px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;box-sizing:border-box;min-width:120px">
                <option value="">All Categories</option>
                <?php foreach ($categories as $cat): ?>
                <option value="<?php echo esc_attr($cat->term_id); ?>"><?php echo esc_html($cat->name); ?></option>
                <?php endforeach; ?>
            </select>
            <button type="button" class="impulse-modal-close">&times;</button>
        </div>
        <div class="impulse-modal-body">
            <div class="impulse-product-picker">
                <div class="impulse-product-list" id="impulse-product-list">
                    <!-- Products loaded via AJAX -->
                </div>
                <div class="impulse-selected-products" id="impulse-selected-products">
                    <h4>Selected Products</h4>
                    <div class="impulse-selected-list"></div>
                </div>
            </div>
        </div>
        <div class="impulse-modal-footer" style="display:flex;justify-content:space-between;align-items:center">
            <div class="impulse-btn-group impulse-product-view-toggle" style="display:flex">
                <button type="button" class="active" data-view="card" style="height:26px;padding:0 10px;font-size:11px">Card</button>
                <button type="button" data-view="list" style="height:26px;padding:0 10px;font-size:11px">List</button>
            </div>
            <div style="display:flex;gap:6px">
                <button type="button" class="impulse-modal-close" style="padding:0 16px;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:4px;cursor:pointer;color:#999;font-size:11px">Cancel</button>
                <button type="button" class="instinctor-btn" id="impulse-apply-products" style="padding:0 16px;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:4px;cursor:pointer;font-size:11px;font-weight:500;color:#e0e0e0">Apply</button>
            </div>
        </div>
    </div>
</div>

<!-- Icon Picker Modal -->
<div id="impulse-icon-modal" class="impulse-modal" style="display:none;">
    <div class="impulse-modal-content impulse-modal-lg">
        <div class="impulse-modal-header" style="padding:10px 16px;min-height:0">
            <span style="font-size:12px;color:#999">Choose Icon</span>
            <button type="button" class="impulse-modal-close">&times;</button>
        </div>
        <div style="padding:8px 16px 0">
            <input type="text" id="impulse-icon-search" placeholder="Search icons..." autocomplete="off" style="width:100%;height:30px;padding:0 10px;background:#1a1d21;border:1px solid #3a3f45;border-radius:4px;color:#e0e0e0;font-size:12px;box-sizing:border-box">
        </div>
        <div class="impulse-modal-body" style="padding:8px 16px 16px;max-height:400px;overflow-y:auto">
            <div class="impulse-icon-picker">
                <div class="impulse-icon-grid" id="impulse-icon-grid"></div>
            </div>
        </div>
    </div>
</div>

<!-- Context Menu (Right Click) -->
<div id="impulse-context-menu" class="impulse-context-menu" style="display:none;"></div>

<!-- Scene row hover peek: floating tree preview of a screen's contents -->

<!-- Page History Modal (revisions per page) -->
<div id="impulse-page-history-modal" class="impulse-modal" style="display:none">
    <div class="impulse-modal-content" style="max-width:480px">
        <div class="impulse-modal-header">
            <span id="impulse-page-history-title">History</span>
            <button type="button" class="impulse-modal-close">&#x2715;</button>
        </div>
        <div class="impulse-modal-body" id="impulse-page-history-body" style="padding:16px;max-height:60vh;overflow-y:auto"></div>
    </div>
</div>

<!-- Global Styles Panel -->

<!-- Save Template Name Modal -->
<div id="impulse-template-name-modal" class="impulse-modal" style="display:none;">
    <div class="impulse-modal-content" style="max-width:360px">
        <div class="impulse-modal-header">
            <h2>Save as Template</h2>
            <button type="button" class="impulse-modal-close">&times;</button>
        </div>
        <div class="impulse-modal-body" style="padding:16px">
            <label style="font-size:11px;color:#999;display:block;margin-bottom:6px">Template Name</label>
            <input type="text" id="impulse-template-name-input" placeholder="My Template" style="width:100%;height:30px;padding:0 10px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;font-size:12px;color:#e0e0e0;box-sizing:border-box">
        </div>
        <div class="impulse-modal-footer">
            <button type="button" class="impulse-modal-close" style="padding:6px 14px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;cursor:pointer;color:#999;font-size:11px">Cancel</button>
            <button type="button" id="impulse-template-name-save" style="padding:6px 14px;background:#fff;border:none;border-radius:3px;cursor:pointer;color:#1d2327;font-size:11px;font-weight:500">Save</button>
        </div>
    </div>
</div>

<div id="impulse-global-styles" class="impulse-modal" style="display:none;">
    <div class="impulse-modal-content impulse-modal-lg">
        <div class="impulse-modal-header">
            <h2>Global Styles</h2>
            <button type="button" class="impulse-modal-close">&times;</button>
        </div>
        <div class="impulse-modal-body">
            <div class="impulse-global-tabs">
                <button type="button" class="active" data-gtab="colors">Colors</button>
                <button type="button" data-gtab="fonts">Fonts</button>
                <button type="button" data-gtab="buttons">Buttons</button>
                <button type="button" data-gtab="spacing">Spacing</button>
            </div>
            <div class="impulse-global-content">
                <div class="impulse-global-pane active" data-gpane="colors">
                    <p class="impulse-global-hint">Define your color palette. These are available as CSS variables.</p>
                    <div class="impulse-global-row"><label>Primary</label><input type="color" name="global_primary" value="#1d2327"></div>
                    <div class="impulse-global-row"><label>Secondary</label><input type="color" name="global_secondary" value="#666666"></div>
                    <div class="impulse-global-row"><label>Accent</label><input type="color" name="global_accent" value="#888888"></div>
                    <div class="impulse-global-row"><label>Text</label><input type="color" name="global_text" value="#1d2327"></div>
                    <div class="impulse-global-row"><label>Text Light</label><input type="color" name="global_text_light" value="#666666"></div>
                    <div class="impulse-global-row"><label>Background</label><input type="color" name="global_background" value="#ffffff"></div>
                    <div class="impulse-global-row"><label>Background Alt</label><input type="color" name="global_background_alt" value="#f5f5f5"></div>
                </div>
                <div class="impulse-global-pane" data-gpane="fonts">
                    <p class="impulse-global-hint">Per-element font picker available in each block's settings. Cross-OS system fonts only, no external webfonts.</p>
                    <div class="impulse-global-row">
                        <label>Base Font Size</label>
                        <input type="range" name="global_base_size" value="16" min="12" max="24" step="1">
                        <span class="impulse-slider-value">16px</span>
                    </div>
                </div>
                <div class="impulse-global-pane" data-gpane="buttons">
                    <p class="impulse-global-hint">Default button styles. Individual buttons can override.</p>
                    <div class="impulse-global-row">
                        <label>Button Style</label>
                        <select name="global_button_style">
                            <option value="solid">Solid</option>
                            <option value="outline">Outline</option>
                            <option value="ghost">Ghost</option>
                        </select>
                    </div>
                    <div class="impulse-global-row">
                        <label>Border Radius</label>
                        <input type="range" name="global_button_radius" value="6" min="0" max="30" step="1">
                        <span class="impulse-slider-value">6px</span>
                    </div>
                    <div class="impulse-global-row">
                        <label>Padding X</label>
                        <input type="range" name="global_button_padding_x" value="24" min="12" max="48" step="2">
                        <span class="impulse-slider-value">24px</span>
                    </div>
                    <div class="impulse-global-row">
                        <label>Padding Y</label>
                        <input type="range" name="global_button_padding_y" value="12" min="6" max="24" step="2">
                        <span class="impulse-slider-value">12px</span>
                    </div>
                </div>
                <div class="impulse-global-pane" data-gpane="spacing">
                    <p class="impulse-global-hint">Define consistent spacing across your pages.</p>
                    <div class="impulse-global-row">
                        <label>Section Padding</label>
                        <input type="range" name="global_section_padding" value="80" min="20" max="160" step="10">
                        <span class="impulse-slider-value">80px</span>
                    </div>
                    <div class="impulse-global-row">
                        <label>Section Padding Mobile</label>
                        <input type="range" name="global_section_padding_mobile" value="40" min="20" max="80" step="10">
                        <span class="impulse-slider-value">40px</span>
                    </div>
                    <div class="impulse-global-row">
                        <label>Element Gap</label>
                        <input type="range" name="global_element_gap" value="20" min="0" max="60" step="4">
                        <span class="impulse-slider-value">20px</span>
                    </div>
                    <div class="impulse-global-row">
                        <label>Container Max Width</label>
                        <input type="number" name="global_container_width" value="1200" min="800" max="1600" step="20">
                        <span style="margin-left:8px">px</span>
                    </div>
                </div>
            </div>
        </div>
        <div class="impulse-modal-footer">
            <button type="button" class="instinctor-btn impulse-modal-close">Cancel</button>
            <button type="button" class="instinctor-btn instinctor-btn-primary" id="impulse-save-global-styles">Save Styles</button>
        </div>
    </div>
</div>

<!-- Confirmation Modal (pages view) -->
<div id="impulse-confirm-modal" class="impulse-modal" style="display:none;">
    <div class="impulse-modal-content impulse-modal-sm">
        <div class="impulse-modal-header">
            <h2 id="impulse-confirm-title">Confirm</h2>
            <button type="button" class="impulse-modal-close">&times;</button>
        </div>
        <div class="impulse-modal-body">
            <p id="impulse-confirm-message"></p>
        </div>
        <div class="impulse-modal-footer">
            <button type="button" class="instinctor-btn impulse-confirm-cancel">Cancel</button>
            <button type="button" class="instinctor-btn instinctor-btn-primary" id="impulse-confirm-ok">Confirm</button>
        </div>
    </div>
</div>

<?php endif; ?>

<?php if ($action === 'list' && $view === 'theme'): ?>
<?php
// Get or create special header/footer pages
$headerPage = get_posts([
    'post_type' => 'page',
    'posts_per_page' => 1,
    'post_status' => ['publish', 'draft'],
    'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- one-off lookup of the global header/footer page on editor load, not a hot path
        [
            'key' => '_impulse_type',
            'value' => 'global_header']
    ]
]);
$footerPage = get_posts([
    'post_type' => 'page',
    'posts_per_page' => 1,
    'post_status' => ['publish', 'draft'],
    'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- one-off lookup of the global header/footer page on editor load, not a hot path
        [
            'key' => '_impulse_type',
            'value' => 'global_footer']
    ]
]);

$headerPageId = !empty($headerPage) ? $headerPage[0]->ID : 0;
$footerPageId = !empty($footerPage) ? $footerPage[0]->ID : 0;

// Get element counts
$headerElements = $headerPageId ? get_post_meta($headerPageId, '_impulse_elements', true) : [];
$footerElements = $footerPageId ? get_post_meta($footerPageId, '_impulse_elements', true) : [];
$headerCount = is_array($headerElements) ? count($headerElements) : 0;
$footerCount = is_array($footerElements) ? count($footerElements) : 0;
?>
<div class="wrap instinctor-wrap impulse-wrap">
    <?php $active_tab = 'theme'; include __DIR__ . '/partials/impulse-header.php'; ?>
    
    <!-- Header & Footer Launcher -->
    <div class="impulse-hf-launcher"
        data-edit-base-url="<?php echo esc_attr(admin_url('admin.php?page=instinctor&action=edit&page_id=')); ?>"
        data-create-url="<?php echo esc_attr(\Instinctor\Core\Config::restUrl('instinctor/v1/impulse/global-page')); ?>"
        data-rest-nonce="<?php echo esc_attr(\Instinctor\Core\Session::token('wp_rest')); ?>">
        <div class="impulse-hf-cards">
            <!-- Header Card -->
            <div class="impulse-hf-card">
                <div class="impulse-hf-card-icon">
                    <svg viewBox="0 0 24 24" width="28" height="28" stroke="currentColor" fill="none" stroke-width="1.5">
                        <rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/>
                    </svg>
                </div>
                <div class="impulse-hf-card-content">
                    <h3>Global Header</h3>
                    <p class="impulse-hf-status">
                        <?php if ($headerCount > 0): ?>
                            <span class="status-configured"><?php echo esc_html($headerCount); ?> element<?php echo $headerCount !== 1 ? 's' : ''; ?></span>
                        <?php else: ?>
                            <span class="status-empty">Not configured</span>
                        <?php endif; ?>
                    </p>
                </div>
                <button type="button" class="instinctor-btn instinctor-btn-primary impulse-hf-edit" data-type="global_header" data-id="<?php echo esc_attr($headerPageId); ?>">
                    <?php echo $headerPageId ? 'Edit Header' : 'Create Header'; ?>
                </button>
            </div>
            
            <!-- Footer Card -->
            <div class="impulse-hf-card">
                <div class="impulse-hf-card-icon" style="transform:rotate(180deg);">
                    <svg viewBox="0 0 24 24" width="28" height="28" stroke="currentColor" fill="none" stroke-width="1.5">
                        <rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/>
                    </svg>
                </div>
                <div class="impulse-hf-card-content">
                    <h3>Global Footer</h3>
                    <p class="impulse-hf-status">
                        <?php if ($footerCount > 0): ?>
                            <span class="status-configured"><?php echo esc_html($footerCount); ?> element<?php echo $footerCount !== 1 ? 's' : ''; ?></span>
                        <?php else: ?>
                            <span class="status-empty">Not configured</span>
                        <?php endif; ?>
                    </p>
                </div>
                <button type="button" class="instinctor-btn instinctor-btn-primary impulse-hf-edit" data-type="global_footer" data-id="<?php echo esc_attr($footerPageId); ?>">
                    <?php echo $footerPageId ? 'Edit Footer' : 'Create Footer'; ?>
                </button>
            </div>
        </div>
    </div>
</div>

<?php // Header/Footer launcher styles moved to assets/css/instinctor-admin.css;
     // its JS moved to InstinctorAdmin.initHfLauncher() in assets/js/admin.js (WordPress.org compliance). ?>
<?php endif; ?>


<?php  ?>

<?php
$_head_handles = [
    'instinctor-sortable',
    'instinctor-element-config',
    'instinctor-live-preview',
];
\Instinctor\Core\Assets::enqueueMany($_head_handles);
// Emit immediately. There's no wp_head() call in this view (admin shell is
// hand-built, not a WP-themed page) so without explicit emit the scripts get
// stuck in the standalone registry, the <script> tags never print, and
// window.ImpulseElementConfig stays undefined at runtime — which makes the
// universal change detector treat every settings change as "unregistered"
// and forces a structural refresh on every slider drag.
if (defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone') {
    if (function_exists('_instinctor_emit_script')) {
        foreach ($_head_handles as $_h) {
            _instinctor_emit_script($_h, false);
            _instinctor_emit_script($_h, true);
        }
    }
} elseif (function_exists('wp_print_scripts')) {
    wp_print_scripts($_head_handles);
}
// Impulse editor config. Emitted as inline JS attached to the
// 'instinctor-admin-core' handle (via wp_add_inline_script below) instead of a
// raw <script> block, so it satisfies the WordPress.org no-inline-script rule
// while still flushing in both runtimes: WP prints it just before admin-core
// during wp_print_scripts(); the standalone shim prints it via the same
// handle's inline_before during _instinctor_emit_script(). Built with
// output-buffering so every esc_js()/wp_json_encode() call below is preserved
// verbatim. Must remain a 'before' inline on a handle that prints BEFORE the
// admin bundle so window.Impulse exists when admin-core boots.
ob_start();
?>
window.Impulse = {
    api: '<?php echo esc_js(\Instinctor\Core\Config::restUrl('instinctor/v1/')); ?>',
    nonce: '<?php echo esc_js($api_nonce); ?>',
    ajaxUrl: '<?php echo esc_js(admin_url('admin-ajax.php')); ?>',
    storeType: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::getStoreType()); ?>',
    storeLabels: {
        orders: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::orderListLabel()); ?>',
        order: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::orderListLabel(false)); ?>',
        spent: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::spentLabel()); ?>',
        customers: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::customerNoun(true)); ?>',
        customer: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::customerNoun(false)); ?>',
        products: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::productNoun(true)); ?>',
        product: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::productNoun(false)); ?>',
        returns: '<?php echo esc_js(\Instinctor\Core\StoreFeatures::returnsLabel()); ?>'
    },
    adminBaseUrl: '<?php echo (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') ? esc_js(admin_url('admin.php?page=instinctor')) : '/admin'; ?>',
    postEditBaseUrl: <?php echo wp_json_encode((!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') ? admin_url('admin.php?page=instinctor-post&post_id=') : '/admin/post/edit/'); ?>,
    previewBaseUrl: '<?php echo (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') ? esc_js(home_url('/?impulse_preview=')) : '/admin/preview/'; ?>',
    previewEditSuffix: '<?php echo (!defined('INSTINCTOR_ENV') || INSTINCTOR_ENV === 'wordpress') ? '&edit=1' : ''; ?>',
    ilmNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('ilm_nonce')); ?>',
    graphicDownloadNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('impulse_download_graphic')); ?>',
    maskCacheNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('impulse_cache_mask')); ?>',
    shapesApiUrl: 'https://platform.instinctor.com/api/shapes',
    cardTemplateNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_card_designer')); ?>',
    canUploadToPlatform: <?php echo (defined('INSTINCTOR_PLATFORM_TOKEN') && INSTINCTOR_PLATFORM_TOKEN !== '') ? 'true' : 'false'; ?>,
    // instinctor.com (the app) only. Gates app-specific admin affordances that
    // make no sense on a client site, e.g. the page-grid slug folders.
    isApp: <?php echo \Instinctor\Core\Plugin::isInstinctorApp() ? 'true' : 'false'; ?>,
    pageId: <?php echo $page_id ? (int) $page_id : 'null'; ?>,
    pageType: '<?php echo esc_js($page_type); ?>',
    pageSlug: '<?php echo $current_page ? esc_js($current_page->permalink) : ''; ?>',
    siteUrl: '<?php echo esc_js(home_url()); ?>',
    pluginUrl: '<?php echo esc_js(INSTINCTOR_PLUGIN_URL); ?>',
    devMode: <?php echo $dev_mode ? 'true' : 'false'; ?>,
    hasProLicense: <?php echo instinctor_has_pro() ? 'true' : 'false'; ?>,
    hasActiveLicense: <?php echo (instinctor_editor_has_license() && empty($_GET['simulate_free'])) ? 'true' : 'false'; ?>,
    // TENANT tier, which hasActiveLicense above cannot answer: that flag reports
    // the INSTALL's licence, and instinctor.com is licensed even while the tenant
    // editing on it is free. Video is the one asset gated per tenant (Pro only,
    // one per site), so the panel needs the tenant's own answer to show the
    // control locked instead of letting them upload and meet a server refusal.
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only editor preview toggle, no state change
    canUploadVideo: <?php echo (\Instinctor\Core\TenantPlan::videoUploadAllowed(\Instinctor\Core\Tenant::currentOwnerId()) && empty($_GET['simulate_free'])) ? 'true' : 'false'; ?>,
    videoCap: <?php echo (int) \Instinctor\Core\TenantPlan::MAX_VIDEOS_PER_SITE; ?>,
    // Depth-map generator is hosted on instinctor.com only; the WP plugin
    // ships no proxy for /api/depth-map.php, so on WP installs (Pro or free)
    // the button must be hidden. Standalone = local depth service available.
    isStandalone: <?php echo (defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone') ? 'true' : 'false'; ?>,
    // Depth/relief generation reachable: standalone bridge, or the WP ajax
    // proxy on Pro (the local depth service answers only on this VPS; an
    // off-VPS Pro install gets a clean unreachable error from the proxy).
    depthAvailable: <?php echo ((defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone') || \Instinctor\Core\TierManager::instance()->isPro()) ? 'true' : 'false'; ?>,
    isPro: <?php echo (instinctor_has_pro() && empty($_GET['simulate_free'])) ? 'true' : 'false'; ?>,
    tier: '<?php echo esc_js(instinctor_tier()); ?>',
    subscriptionActive: <?php echo instinctor_has_pro() ? 'true' : 'false'; ?>,
    licenseEmail: '<?php echo esc_js(\Instinctor\Core\Config::get('instinctor_registered_email', '')); ?>',
    userEmail: '<?php echo esc_js(function_exists("wp_get_current_user") ? (string)(wp_get_current_user()->user_email ?? "") : (string)(\Instinctor\Core\Config::get("instinctor_registered_email", "") ?? "")); ?>',
    licenseNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_admin')); ?>',
    elements: <?php echo wp_json_encode($elements); ?>,
    categories: <?php echo wp_json_encode($categories); ?>,
    cardTemplates: <?php echo wp_json_encode($card_templates); ?>,
    pageSettings: <?php echo $current_page && is_array($current_page->settings) ? wp_json_encode($current_page->settings) : '{}'; ?>,
    checkoutConfig: <?php 
        $checkoutCfg = \Instinctor\Services\CheckoutConfig::get();
        $checkoutFields = \Instinctor\Services\CheckoutConfig::getFields();
        echo wp_json_encode([
            'layout' => $checkoutCfg['layout'] ?? 'one-page',
            'style' => $checkoutCfg['style'] ?? 'modern',
            'colors' => $checkoutCfg['colors'] ?? [],
            'field_border_width' => $checkoutCfg['field_border_width'] ?? 1,
            'fields' => $checkoutFields
        ]); 
    ?>,
    adminEmail: '<?php echo esc_js(\Instinctor\Core\Config::get('admin_email')); ?>',
    pages: <?php
        $pagesList = [];
        foreach ($_all_pages as $_pRow) {
            if (in_array($_pRow['type'] ?? 'page', ['global_header','global_footer','post'], true)) continue;
            $_pPs = is_array($_pRow['settings']) ? $_pRow['settings'] : (json_decode($_pRow['settings'] ?? '{}', true) ?: []);
            $pagesList[] = [
                'id'                    => (int)$_pRow['id'],
                'name'                  => $_pRow['name'],
                'slug'                  => $_pRow['slug'],
                'screen_infinite_loop'  => !empty($_pPs['screen_infinite_loop']),
                'thumbnail'             => (string) ($_pRow['thumbnail'] ?? ''),
                'permalink'             => \Instinctor\Services\PageService::getPageUrl((int)$_pRow['id']),
            ];
        }
        echo wp_json_encode($pagesList);
    ?>,
    frontPageId: <?php echo (int)$_front_page_id; ?>,
    workspace: '<?php echo esc_js($workspace); ?>',
    workspaceOrder: <?php echo wp_json_encode($workspace_order); ?>,
    storeSectionDefault: '<?php echo esc_js($store_section_default); ?>',
    seoTabDefault: '<?php echo esc_js($seo_tab_default); ?>',
    deviceDefault: '<?php echo esc_js($device_default); ?>',
    isAdmin: <?php echo $is_admin ? 'true' : 'false'; ?>,
    canManageChatSettings: <?php echo $can_manage_chat_settings ? 'true' : 'false'; ?>,
    adminNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_admin')); ?>',
    currencyNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_currency')); ?>',
    marketingNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_marketing')); ?>',
    chat: <?php echo wp_json_encode([
        'nonce' => $chat_nonce,
            'pageToggleNonce' => $chat_page_toggle_nonce,
        'settings' => $chat_data['settings'] ?? [],
        'has_pro' => instinctor_has_pro(),
        'ajaxurl' => admin_url('admin-ajax.php'),
        'currentUserId' => \Instinctor\Core\Auth::userId() ?: 0]); ?>,
    products: {
        ajaxurl: '<?php echo esc_js(admin_url('admin-ajax.php')); ?>',
        currency: '<?php echo esc_js(\Instinctor\Core\Config::get('instinctor_currency_symbol', '$')); ?>',
        stockManagement: <?php echo \Instinctor\Core\Config::get('instinctor_stock_management', true) ? 'true' : 'false'; ?>,
        hasAiContent: true // gate removed — AI buttons always available
    },
    imgopt: <?php
        $_io = \Instinctor\Core\Config::get('instinctor_image_optimizer', []);
        $_io = array_merge(['quality'=>75,'max_width'=>1600,'max_height'=>1600,'webp'=>true,'webp_quality'=>75], is_array($_io) ? $_io : []);
        echo wp_json_encode(['quality'=>(int)$_io['quality'],'max_width'=>(int)$_io['max_width'],'max_height'=>(int)$_io['max_height'],'webp'=>!empty($_io['webp']),'webp_quality'=>(int)$_io['webp_quality']]);
    ?>,
    aiNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_ai_content')); ?>',
    brandProfile: <?php echo wp_json_encode([
        'industry'      => (string) \Instinctor\Core\Config::get('instinctor_store_industry',    ''),
        'audience'      => (string) \Instinctor\Core\Config::get('instinctor_store_audience',    ''),
        'tone'          => (string) \Instinctor\Core\Config::get('instinctor_store_tone',        ''),
        'value_prop'    => (string) \Instinctor\Core\Config::get('instinctor_store_value_prop',  ''),
        'primary_cta'   => (string) \Instinctor\Core\Config::get('instinctor_store_primary_cta', ''),
        'primary_color' => (string) \Instinctor\Core\Config::get('instinctor_store_primary_color',''),
        'accent_color'  => (string) \Instinctor\Core\Config::get('instinctor_store_accent_color', ''),
        'voice_sample'  => (string) \Instinctor\Core\Config::get('instinctor_store_voice_sample', ''),
        'locale'        => (string) \Instinctor\Core\Config::get('instinctor_store_locale',       'en-US'),
    ]); ?>,
    storeType: '<?php echo esc_js(\Instinctor\Core\Config::get('instinctor_store_type', 'mixed')); ?>',
    aftershipSettings: <?php echo wp_json_encode(\Instinctor\Services\AfterShipService::getSettings()); ?>,
    operationsNonce: '<?php echo esc_js(\Instinctor\Core\Session::token('instinctor_operations')); ?>',
    globalSnippets: <?php $raw_snips=\Instinctor\Core\Config::get('instinctor_global_snippets','[]');$decoded=json_decode($raw_snips,true);echo wp_json_encode(is_array($decoded)?$decoded:[]); ?>,
    emailTemplateStates: <?php $et_states2=[];foreach($email_templates as $key=>$tpl){$et_states2[$key]=['label'=>$tpl['name']??ucwords(str_replace('_',' ',$key)),'subject'=>$tpl['subject']??'','enabled'=>!empty($tpl['enabled'])];}echo wp_json_encode($et_states2); ?>,
    currentUser: <?php
        $_cu_id   = \Instinctor\Core\Auth::userId();
        $_cu_role = 'none';
        if (\Instinctor\Core\Auth::can('manage_options')) {
            $_cu_role = 'owner';
        } elseif (\Instinctor\Core\Auth::can('instinctor_store')) {
            $_cu_role = 'manager';
        } elseif (\Instinctor\Core\Auth::can('instinctor_chat')) {
            $_cu_role = 'agent';
        }
        echo wp_json_encode(['id' => $_cu_id, 'role' => $_cu_role]);
    ?>
};
window.instinctorAdminEmail = window.Impulse.adminEmail;
<?php
$_impulse_config_js = ob_get_clean();
$_admin_handles = [
    'instinctor-admin-core',
    'instinctor-admin-timeline',
    'instinctor-admin-products',
    'instinctor-admin-chat',
    'instinctor-admin-store',
    'instinctor-admin-media',
    'instinctor-admin-seo',
    'instinctor-admin-configurator',
];
\Instinctor\Core\Assets::enqueueMany($_admin_handles);
// Attach window.Impulse as a 'before' inline on admin-core so it is defined
// before the admin bundle executes. Flushes in WP (wp_print_scripts) and in
// standalone (shim inline_before) when the handle is emitted below.
if (function_exists('wp_add_inline_script')) {
    wp_add_inline_script('instinctor-admin-core', $_impulse_config_js, 'before');
}
// Emit now so admin bundle code runs in expected order. Standalone uses our
// shim's emit; WP context uses wp_print_scripts.
if (defined('INSTINCTOR_ENV') && INSTINCTOR_ENV === 'standalone') {
    if (function_exists('_instinctor_emit_script')) {
        foreach ($_admin_handles as $_h) {
            _instinctor_emit_script($_h, false);
            _instinctor_emit_script($_h, true);
        }
    }
} elseif (function_exists('wp_print_scripts')) {
    wp_print_scripts($_admin_handles);
}

// Instagent Help — slide-out KB chat panel. Inlines its own CSS + JS,
// binds to the #impulse-instagent-help-toggle button in the topbar.
// AJAX bridge lives in InstagentHelpService.php (registered in Plugin.php)
// and forwards to platform.instinctor.com/api/relay/ai-help.
$_instagentHelpPartial = INSTINCTOR_PLUGIN_DIR . 'admin/views/_instagent-help.php';
if (file_exists($_instagentHelpPartial)) {
    include $_instagentHelpPartial;
}
?>
<script>
jQuery(function ($) {
    var $card = $('#panel-access-card');
    if (!$card.length) return;

    function post(verb, extra, done) {
        var data = $.extend({ action: 'instinctor_panel_access', nonce: (window.Impulse && Impulse.adminNonce) || '', 'do': verb }, extra || {});
        $.post((window.Impulse && Impulse.ajaxUrl) || ajaxurl, data, function (res) {
            if (res && res.success) { paint(res.data); if (done) done(res.data); }
            else { $('#pa-msg').text((res && res.data && res.data.message) || 'That did not work.'); }
        });
    }

    function paint(d) {
        $('#pa-toggle').text(d.enabled ? 'Turn off' : 'Enable');
        $('#pa-state').text(d.enabled
            ? (d.named ? 'On, and ' + d.email + ' can open it.' : 'On. Nobody can open it until you name the owner.')
            : 'Off. The panel does not answer on this site.');
        $('#pa-body').toggle(!!d.enabled);
        if (d.email && !$('#pa-email').is(':focus')) $('#pa-email').val(d.email);
        $('#pa-link-row').toggle(!!d.link);
        if (d.link) $('#pa-link').val(d.link);
    }

    post('state');

    $('#pa-toggle').on('click', function () {
        post($('#pa-toggle').text() === 'Enable' ? 'enable' : 'disable', {}, function () { $('#pa-msg').text(''); });
    });
    $('#pa-save-owner').on('click', function () {
        $('#pa-msg').text('Saving...');
        post('owner', { email: $('#pa-email').val(), name: '' }, function () { $('#pa-msg').text('Saved.'); });
    });
    $('#pa-copy').on('click', function () {
        var el = document.getElementById('pa-link');
        el.select(); el.setSelectionRange(0, 99999);
        (navigator.clipboard ? navigator.clipboard.writeText(el.value) : Promise.reject())
            .then(function () { $('#pa-msg').text('Copied.'); }, function () { document.execCommand('copy'); $('#pa-msg').text('Copied.'); });
    });
    $('#pa-send').on('click', function () {
        $('#pa-msg').text('Sending...');
        post('send', {}, function (d) { $('#pa-msg').text('Sent to ' + d.email + '.'); });
    });
    $('#pa-revoke').on('click', function () {
        $('#pa-msg').text('Revoking...');
        post('revoke', {}, function () { $('#pa-msg').text('Old links are dead. Send the new one.'); });
    });
});
</script>
