{
  "version": 3,
  "sources": ["/cdn/shop/t/242/assets/shopping-agent.js?t=1792001768"],
  "sourcesContent": ["console.log(\"%c[Discovery-AI] Loaded shopping-agent.js v2026.10.01 (Native Shopify Contact Mailer)\", \"color: #00e676; font-weight: bold; font-size: 13px;\");\n\n/**\n * Smart Recommendation Engine for RUG Assistant\n * Tracks user behavior and generates personalized recommendations\n */\n\nclass RecommendationEngine {\n  constructor(store) {\n    this.store = store;\n    this.preferences = this.loadPreferences();\n    this.clickHistory = this.loadClickHistory();\n    this.viewDuration = {}; // Track how long user looks at products\n  }\n\n  loadPreferences() {\n    try {\n      const saved = localStorage.getItem(\"rug_preferences\");\n      return saved ? JSON.parse(saved) : this.defaultPreferences();\n    } catch (e) {\n      return this.defaultPreferences();\n    }\n  }\n\n  defaultPreferences() {\n    return {\n      preferredStyles: {},\n      preferredColors: {},\n      preferredMaterials: {},\n      preferredRooms: {},\n      priceRange: { min: 0, max: 10000 },\n      engagementScore: {},\n      clickCount: {},\n      lastUpdated: new Date().toISOString(),\n    };\n  }\n\n  loadClickHistory() {\n    try {\n      const saved = localStorage.getItem(\"rug_click_history\");\n      return saved ? JSON.parse(saved).slice(-100) : []; // Keep last 100\n    } catch (e) {\n      return [];\n    }\n  }\n\n  savePreferences() {\n    localStorage.setItem(\"rug_preferences\", JSON.stringify(this.preferences));\n  }\n\n  saveClickHistory() {\n    localStorage.setItem(\n      \"rug_click_history\",\n      JSON.stringify(this.clickHistory),\n    );\n  }\n\n  /**\n   * Track product view/click\n   */\n  trackProductView(product, action = \"view\") {\n    const timestamp = new Date().toISOString();\n\n    // Update click history\n    this.clickHistory.push({\n      productId: product.id,\n      action, // 'view', 'click', 'add-to-cart', 'wishlist'\n      timestamp,\n      metadata: {\n        style: product.style,\n        color: product.color,\n        material: product.material,\n        room: product.room,\n        price: product.price,\n      },\n    });\n\n    // Update preference scores\n    if (product.style) {\n      this.preferences.preferredStyles[product.style] =\n        (this.preferences.preferredStyles[product.style] || 0) +\n        this.getActionWeight(action);\n    }\n    if (product.color) {\n      this.preferences.preferredColors[product.color] =\n        (this.preferences.preferredColors[product.color] || 0) +\n        this.getActionWeight(action);\n    }\n    if (product.material) {\n      this.preferences.preferredMaterials[product.material] =\n        (this.preferences.preferredMaterials[product.material] || 0) +\n        this.getActionWeight(action);\n    }\n    if (product.room) {\n      this.preferences.preferredRooms[product.room] =\n        (this.preferences.preferredRooms[product.room] || 0) +\n        this.getActionWeight(action);\n    }\n\n    // Track price interest\n    const price =\n      parseFloat(String(product.price).replace(/[^0-9.]/g, \"\")) || 0;\n    if (price > 0) {\n      this.preferences.clickCount[price] =\n        (this.preferences.clickCount[price] || 0) + 1;\n    }\n\n    this.savePreferences();\n    this.saveClickHistory();\n  }\n\n  getActionWeight(action) {\n    const weights = {\n      view: 1,\n      click: 3,\n      \"add-to-cart\": 10,\n      wishlist: 8,\n      compare: 5,\n      \"room-view\": 7,\n    };\n    return weights[action] || 1;\n  }\n\n  /**\n   * Get top user preferences\n   */\n  getTopPreferences(type = \"styles\", limit = 3) {\n    const preferences = this.preferences[`preferred${type}`];\n    if (!preferences) return [];\n\n    return Object.entries(preferences)\n      .sort((a, b) => b[1] - a[1])\n      .slice(0, limit)\n      .map(([name, score]) => ({ name, score }));\n  }\n\n  /**\n   * Generate recommendation reason\n   */\n  generateReason() {\n    const topStyles = this.getTopPreferences(\"Styles\", 1);\n    const topColors = this.getTopPreferences(\"Colors\", 1);\n    const topRooms = this.getTopPreferences(\"Rooms\", 1);\n\n    const reasons = [];\n    if (topStyles.length > 0) reasons.push(`${topStyles[0].name} style`);\n    if (topColors.length > 0) reasons.push(`${topColors[0].name} tones`);\n    if (topRooms.length > 0) reasons.push(`perfect for ${topRooms[0].name}`);\n\n    if (reasons.length === 0) return \"Based on your browsing history\";\n    return `Based on your interest in ${reasons.join(\", \")}`;\n  }\n\n  /**\n   * Get engagement score for trending recommendations\n   */\n  getEngagementMetrics() {\n    const last7Days = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n    const recentClicks = this.clickHistory.filter(\n      (click) => new Date(click.timestamp) > last7Days,\n    );\n\n    return {\n      viewCount: recentClicks.filter((c) => c.action === \"view\").length,\n      cartCount: recentClicks.filter((c) => c.action === \"add-to-cart\").length,\n      wishlistCount: recentClicks.filter((c) => c.action === \"wishlist\").length,\n      comparisonCount: recentClicks.filter((c) => c.action === \"compare\")\n        .length,\n      totalEngagement: recentClicks.length,\n    };\n  }\n\n  /**\n   * Get similar products based on user history\n   */\n  getSimilarProductCriteria() {\n    const topStyles = this.getTopPreferences(\"Styles\", 2).map((s) => s.name);\n    const topColors = this.getTopPreferences(\"Colors\", 2).map((c) => c.name);\n    const topMaterials = this.getTopPreferences(\"Materials\", 2).map(\n      (m) => m.name,\n    );\n\n    return {\n      styles: topStyles,\n      colors: topColors,\n      materials: topMaterials,\n    };\n  }\n\n  /**\n   * Get user behavioral score (0-100)\n   */\n  getUserEngagementLevel() {\n    const metrics = this.getEngagementMetrics();\n    const score = Math.min(100, (metrics.totalEngagement / 50) * 100);\n    return Math.round(score);\n  }\n\n  /**\n   * Get user profile summary (for display in dashboard)\n   */\n  getUserProfile() {\n    const topStyles = this.getTopPreferences(\"Styles\", 3);\n    const topColors = this.getTopPreferences(\"Colors\", 3);\n    const topRooms = this.getTopPreferences(\"Rooms\", 3);\n    const metrics = this.getEngagementMetrics();\n\n    return {\n      favoriteStyles: topStyles.map((s) => s.name),\n      favoriteColors: topColors.map((c) => c.name),\n      favoriteRooms: topRooms.map((r) => r.name),\n      engagementLevel: this.getUserEngagementLevel(),\n      totalViews: metrics.viewCount,\n      totalCartsAdded: metrics.cartCount,\n      totalWishlistedItems: metrics.wishlistCount,\n      lastUpdated: this.preferences.lastUpdated,\n    };\n  }\n\n  /**\n   * Get next product recommendations (for \"View all\" expansion)\n   */\n  getRecommendedProducts(products = [], limit = 6) {\n    if (!products.length) return [];\n\n    const criteria = this.getSimilarProductCriteria();\n    const scored = products.map((product) => {\n      let score = 0;\n\n      if (criteria.styles.includes(product.style)) score += 30;\n      if (criteria.colors.includes(product.color)) score += 25;\n      if (criteria.materials.includes(product.material)) score += 20;\n\n      // Boost items not yet viewed\n      const isViewed = this.clickHistory.some(\n        (h) => h.productId === product.id,\n      );\n      if (!isViewed) score += 15;\n\n      return { product, score };\n    });\n\n    return scored\n      .sort((a, b) => b.score - a.score)\n      .slice(0, limit)\n      .map((s) => s.product);\n  }\n\n  /**\n   * Clear all data (for testing/reset)\n   */\n  reset() {\n    this.preferences = this.defaultPreferences();\n    this.clickHistory = [];\n    localStorage.removeItem(\"rug_preferences\");\n    localStorage.removeItem(\"rug_click_history\");\n  }\n}\n\nif (typeof window !== \"undefined\") {\n  window.RecommendationEngine = RecommendationEngine;\n}\n\n/**\n * Touch Gesture Handler for RUG Assistant\n * Provides swipe, long-press, and haptic feedback\n */\n\nclass GestureHandler {\n  constructor() {\n    this.touchStartX = 0;\n    this.touchEndX = 0;\n    this.touchStartTime = 0;\n    this.longPressTimer = null;\n    this.minSwipeDistance = 50;\n    this.longPressDuration = 500;\n  }\n\n  // Initialize gesture listeners\n  init(element) {\n    if (!element) return;\n\n    element.addEventListener(\"touchstart\", (e) => this.onTouchStart(e), false);\n    element.addEventListener(\"touchend\", (e) => this.onTouchEnd(e), false);\n    element.addEventListener(\n      \"touchcancel\",\n      (e) => this.onTouchCancel(e),\n      false,\n    );\n    element.addEventListener(\"touchmove\", (e) => this.onTouchMove(e), false);\n  }\n\n  onTouchStart(e) {\n    this.touchStartX = e.changedTouches[0].screenX;\n    this.touchStartTime = Date.now();\n    this.longPressTimer = setTimeout(() => {\n      this.triggerLongPress(e);\n    }, this.longPressDuration);\n  }\n\n  onTouchEnd(e) {\n    this.touchEndX = e.changedTouches[0].screenX;\n    clearTimeout(this.longPressTimer);\n\n    const diff = this.touchStartX - this.touchEndX;\n    const duration = Date.now() - this.touchStartTime;\n\n    // Swipe detected\n    if (Math.abs(diff) > this.minSwipeDistance && duration < 500) {\n      if (diff > 0) {\n        this.triggerSwipeLeft(e);\n      } else {\n        this.triggerSwipeRight(e);\n      }\n    }\n  }\n\n  onTouchMove(e) {\n    // Clear long press if user moves\n    if (Math.abs(e.changedTouches[0].screenX - this.touchStartX) > 10) {\n      clearTimeout(this.longPressTimer);\n    }\n  }\n\n  onTouchCancel(e) {\n    clearTimeout(this.longPressTimer);\n  }\n\n  triggerSwipeLeft(e) {\n    const event = new CustomEvent(\"swipe-left\", { detail: e });\n    document.dispatchEvent(event);\n    this.haptic(\"light\");\n  }\n\n  triggerSwipeRight(e) {\n    const event = new CustomEvent(\"swipe-right\", { detail: e });\n    document.dispatchEvent(event);\n    this.haptic(\"light\");\n  }\n\n  triggerLongPress(e) {\n    const event = new CustomEvent(\"long-press\", { detail: e });\n    document.dispatchEvent(event);\n    this.haptic(\"medium\");\n  }\n\n  // Haptic feedback (if supported)\n  haptic(type = \"light\") {\n    if (navigator.vibrate) {\n      const patterns = {\n        light: 10,\n        medium: 20,\n        heavy: 40,\n        success: [20, 10, 20],\n      };\n      const pattern = patterns[type] || 10;\n      navigator.vibrate(pattern);\n    }\n  }\n\n  // Setup carousel with swipe support\n  initCarousel(carouselElement, options = {}) {\n    if (!carouselElement) return;\n\n    const { onNext, onPrev } = options;\n    let currentIndex = 0;\n    const items = carouselElement.querySelectorAll(\"[data-carousel-item]\");\n\n    document.addEventListener(\"swipe-left\", (e) => {\n      if (e.target.closest(carouselElement)) {\n        currentIndex = (currentIndex + 1) % items.length;\n        this.scrollCarouselTo(carouselElement, currentIndex);\n        onNext && onNext(currentIndex);\n        this.haptic(\"light\");\n      }\n    });\n\n    document.addEventListener(\"swipe-right\", (e) => {\n      if (e.target.closest(carouselElement)) {\n        currentIndex = (currentIndex - 1 + items.length) % items.length;\n        this.scrollCarouselTo(carouselElement, currentIndex);\n        onPrev && onPrev(currentIndex);\n        this.haptic(\"light\");\n      }\n    });\n\n    this.init(carouselElement);\n  }\n\n  scrollCarouselTo(carousel, index) {\n    const item = carousel.querySelector(`[data-carousel-item=\"${index}\"]`);\n    if (item) {\n      carousel.scrollTo({\n        left: item.offsetLeft - carousel.offsetLeft,\n        behavior: \"smooth\",\n      });\n    }\n  }\n\n  // Long press quick action\n  setupQuickAction(element, callback) {\n    document.addEventListener(\"long-press\", (e) => {\n      if (e.target.closest(element) || element.contains(e.target)) {\n        callback(e);\n        this.haptic(\"success\");\n      }\n    });\n  }\n}\n\n// Export for use\nif (typeof window !== \"undefined\") {\n  window.GestureHandler = GestureHandler;\n}\n\n/**\n * Personal Dashboard for RUG Assistant\n * Displays user profile, wishlists, and saved items\n */\n\nclass PersonalDashboard {\n  constructor(store, recommendationEngine) {\n    this.store = store;\n    this.engine = recommendationEngine;\n  }\n\n  /**\n   * Render user profile card\n   */\n  renderProfileCard() {\n    const profile = this.engine.getUserProfile();\n    const initials = this.getInitials();\n\n    return `\n        <div class=\"profile-card\">\n            <div class=\"profile-header\">\n                <div class=\"profile-avatar\">${initials}</div>\n                <div class=\"profile-info\">\n                    <h3>Your Shopping Profile</h3>\n                    <p class=\"profile-level\">Engagement Level: <span class=\"level-${profile.engagementLevel}\">${profile.engagementLevel}%</span></p>\n                </div>\n            </div>\n            \n            <div class=\"profile-stats\">\n                <div class=\"stat\">\n                    <i class=\"fa fa-eye\"></i>\n                    <span>${profile.totalViews}</span>\n                    <small>Viewed</small>\n                </div>\n                <div class=\"stat\">\n                    <i class=\"fa fa-heart\"></i>\n                    <span>${profile.totalWishlistedItems}</span>\n                    <small>Saved</small>\n                </div>\n                <div class=\"stat\">\n                    <i class=\"fa fa-shopping-bag\"></i>\n                    <span>${profile.totalCartsAdded}</span>\n                    <small>Carted</small>\n                </div>\n            </div>\n\n            <div class=\"profile-preferences\">\n                <h4>Your Preferences</h4>\n                <div class=\"preference-tags\">\n                    <div class=\"pref-category\">\n                        <strong>Styles:</strong>\n                        ${profile.favoriteStyles.map((s) => `<span class=\"tag\">${s}</span>`).join(\"\")}\n                    </div>\n                    <div class=\"pref-category\">\n                        <strong>Colors:</strong>\n                        ${profile.favoriteColors.map((c) => `<span class=\"tag\">${c}</span>`).join(\"\")}\n                    </div>\n                    <div class=\"pref-category\">\n                        <strong>Rooms:</strong>\n                        ${profile.favoriteRooms.map((r) => `<span class=\"tag\">${r}</span>`).join(\"\")}\n                    </div>\n                </div>\n            </div>\n        </div>\n        `;\n  }\n\n  /**\n   * Render wishlisted items\n   */\n  renderWishlists() {\n    const wishlist = this.store.data.wishlist || [];\n\n    if (wishlist.length === 0) {\n      return `\n            <div class=\"empty-state\">\n                <i class=\"fa fa-heart\"></i>\n                <p>No saved items yet</p>\n                <button class=\"discovery-btn btn-accent btn-sm\" data-app-action=\"openAssistantWith\" data-arg0=\"Show me trending rugs\">\n                    Explore Recommendations\n                </button>\n            </div>\n            `;\n    }\n\n    return `\n        <div class=\"wishlist-grid\">\n            ${wishlist.map((item) => this.renderWishlistCard(item)).join(\"\")}\n        </div>\n        `;\n  }\n\n  renderWishlistCard(item) {\n    return `\n        <div class=\"wishlist-card\">\n            <img src=\"${item.imgUrl}\" alt=\"${item.title}\" loading=\"lazy\">\n            <div class=\"wishlist-card-body\">\n                <h4>${item.title}</h4>\n                <p class=\"price\">${item.price}</p>\n                <div class=\"actions\">\n                    <button class=\"discovery-btn btn-primary btn-sm\" data-app-action=\"openProduct\" data-arg0=\"${item.id}\">\n                        <i class=\"fa fa-eye\"></i> View\n                    </button>\n                    <button class=\"discovery-btn btn-secondary btn-sm\" data-app-action=\"quickAddProduct\" data-arg0=\"${item.id}\">\n                        <i class=\"fa fa-shopping-bag\"></i> Add\n                    </button>\n                </div>\n            </div>\n        </div>\n        `;\n  }\n\n  /**\n   * Render recently viewed items\n   */\n  renderRecentlyViewed() {\n    const viewed = (this.store.data.viewed || []).slice(0, 6);\n\n    if (viewed.length === 0) {\n      return `<p class=\"text-muted\">No recently viewed items</p>`;\n    }\n\n    return `\n        <div class=\"carousel-horizontal\">\n            ${viewed\n              .map(\n                (item, idx) => `\n            <div class=\"carousel-item\" data-carousel-item=\"${idx}\">\n                <img src=\"${item.imgUrl}\" alt=\"${item.title}\" loading=\"lazy\">\n                <p class=\"text-sm\">${item.title}</p>\n            </div>\n            `,\n              )\n              .join(\"\")}\n        </div>\n        `;\n  }\n\n  /**\n   * Render saved searches\n   */\n  renderSavedSearches() {\n    const searches = (this.store.data.searchHistory || []).slice(0, 5);\n\n    if (searches.length === 0) {\n      return `<p class=\"text-muted\">No search history</p>`;\n    }\n\n    return `\n        <div class=\"saved-searches\">\n            ${searches\n              .map(\n                (query) => `\n            <button class=\"search-chip\" data-app-action=\"sendAction\" data-arg0=\"${query}\">\n                <i class=\"fa fa-search\"></i> ${query}\n            </button>\n            `,\n              )\n              .join(\"\")}\n        </div>\n        `;\n  }\n\n  /**\n   * Render full personal dashboard\n   */\n  renderFullDashboard() {\n    return `\n        <div class=\"personal-dashboard\">\n            <div class=\"dashboard-header\">\n                <h2><i class=\"fa fa-user-circle\"></i> Your Personal Assistant</h2>\n                <p class=\"subtitle\">Personalized recommendations based on your preferences</p>\n            </div>\n\n            <!-- Profile Card -->\n            <section class=\"dashboard-section\">\n                <h3>Profile & Preferences</h3>\n                ${this.renderProfileCard()}\n            </section>\n\n            <!-- Wishlists -->\n            <section class=\"dashboard-section\">\n                <h3><i class=\"fa fa-heart\"></i> Saved Items (${this.store.data.wishlist?.length || 0})</h3>\n                ${this.renderWishlists()}\n            </section>\n\n            <!-- Recently Viewed -->\n            <section class=\"dashboard-section\">\n                <h3><i class=\"fa fa-history\"></i> Recently Viewed</h3>\n                ${this.renderRecentlyViewed()}\n            </section>\n\n            <!-- Saved Searches -->\n            <section class=\"dashboard-section\">\n                <h3><i class=\"fa fa-bookmark\"></i> Quick Search</h3>\n                ${this.renderSavedSearches()}\n            </section>\n\n            <!-- Loyalty/Stats -->\n            <section class=\"dashboard-section loyalty-section\">\n                <h3><i class=\"fa fa-star\"></i> Your Benefits</h3>\n                <div class=\"benefits-grid\">\n                    <div class=\"benefit-card\">\n                        <i class=\"fa fa-truck\"></i>\n                        <strong>Free Shipping</strong>\n                        <p>On orders over $50</p>\n                    </div>\n                    <div class=\"benefit-card\">\n                        <i class=\"fa fa-undo\"></i>\n                        <strong>30-Day Returns</strong>\n                        <p>No questions asked</p>\n                    </div>\n                    <div class=\"benefit-card\">\n                        <i class=\"fa fa-headset\"></i>\n                        <strong>Expert Support</strong>\n                        <p>Chat with AI assistant</p>\n                    </div>\n                </div>\n            </section>\n        </div>\n        `;\n  }\n\n  /**\n   * Get user initials for avatar\n   */\n  getInitials() {\n    const name = localStorage.getItem(\"rug_user_name\") || \"Guest\";\n    return (\n      name\n        .split(\" \")\n        .map((n) => n[0])\n        .join(\"\")\n        .toUpperCase()\n        .slice(0, 2) || \"RU\"\n    );\n  }\n}\n\nif (typeof window !== \"undefined\") {\n  window.PersonalDashboard = PersonalDashboard;\n}\n\n/**\n * Discovery-AI Rug Assistant \u2014 Frontend v2.0\n * Complete rewrite: accessible, functional, zero hardcoding\n */\n\n// ============================================================\n// CONFIG\n// ============================================================\nconst API_BASE =\n  window.ASSISTANT_API_BASE || \"https://assistant.productadvisorai.com\";\nconst PRODUCT_API_BASE =\n  window.BACKEND_BASE_URL || \"https://assistant.productadvisorai.com\";\n\n// ============================================================\n// API Client\n// ============================================================\nclass DiscoveryAPI {\n  constructor(base) {\n    this.base = base || API_BASE; // Rug Assistant (agent/assistant endpoints)\n    this.productBase = PRODUCT_API_BASE; // ProductAdvisor (browse/search/discover/recommendations)\n  }\n\n  async _fetch(url, opts = {}) {\n    const resp = await fetch(url, opts);\n    const data = await resp.json().catch(() => null);\n    if (!resp.ok) {\n      const detail =\n        data?.detail || data?.error || `Request failed (${resp.status})`;\n      throw new Error(detail);\n    }\n    return data;\n  }\n\n  get tenant() {\n    if (window.shopkeeperTenant) return window.shopkeeperTenant;\n    if (window.ShopifyContextPayload?.shop?.permanent_domain) {\n      return window.ShopifyContextPayload.shop.permanent_domain\n        .replace(\".myshopify.com\", \"\")\n        .replace(/[-.]/g, \"_\");\n    }\n    if (window.Shopify?.shop) {\n      return window.Shopify.shop.replace(\".myshopify.com\", \"\").replace(/[-.]/g, \"_\");\n    }\n    return \"vogue_rugs\";\n  }\n\n  // \u2500\u2500 Agent endpoints (Rug Assistant) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  message(text, sessionId, facts = {}, context = {}, memory = {}) {\n    return this._fetch(`${this.base}/assistant/message`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({\n        tenant_id: this.tenant,\n        message: text,\n        session_id: sessionId,\n        facts,\n        context,\n        memory,\n      }),\n    });\n  }\n\n  syncContext(sessionId, context, memory) {\n    return this._fetch(`${this.base}/assistant/context`, {\n      method: \"PUT\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({\n        tenant_id: this.tenant,\n        session_id: sessionId,\n        context,\n        memory,\n      }),\n    });\n  }\n\n  pdpQuestions(product) {\n    return this._fetch(`${this.base}/assistant/pdp-questions`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({ tenant_id: this.tenant, product }),\n    });\n  }\n\n  tenantKnowledge() {\n    return this._fetch(\n      `${this.base}/tenant/${encodeURIComponent(this.tenant)}/knowledge`,\n    );\n  }\n\n  // \u2500\u2500 Product endpoints (ProductAdvisor direct) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  discover(text, mode, state, facts) {\n    return this._fetch(`${this.productBase}/api/discover`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({\n        tenant_id: this.tenant,\n        user_msg: text,\n        mode: mode || \"conversational\",\n        state,\n        facts,\n      }),\n    });\n  }\n\n  search(q, page = 1) {\n    return this._fetch(`${this.base}/assistant/search`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({ tenant_id: this.tenant, q, page }),\n    });\n  }\n\n  browse(facts, page = 1, pageSize = 12) {\n    return this._fetch(`${this.base}/assistant/browse`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({\n        tenant_id: this.tenant,\n        facts,\n        page,\n        page_size: pageSize,\n      }),\n    });\n  }\n\n  recommend(productId, productHandle = \"\") {\n    return this._fetch(`${this.base}/assistant/recommendations`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({\n        tenant_id: this.tenant,\n        product_id: String(productId),\n        product_handle: productHandle ? String(productHandle) : String(productId),\n      }),\n    });\n  }\n\n  analyzeImage(file, options = {}) {\n    const fd = new FormData();\n    fd.append(\"file\", file);\n    fd.append(\"tenant\", this.tenant);\n    fd.append(\n      \"skip_visualizer_points\",\n      options.skipVisualizerPoints ? \"true\" : \"false\",\n    );\n    return this._fetch(`${this.base}/api/analyze-image`, {\n      method: \"POST\",\n      body: fd,\n    });\n  }\n\n  contactStore(payload) {\n    return this._fetch(`${this.base}/assistant/contact-store`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({ tenant_id: this.tenant, ...payload }),\n    });\n  }\n\n  trackOrder(payload) {\n    return this._fetch(`${this.base}/orders/track`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({ tenant_id: this.tenant, ...payload }),\n    });\n  }\n}\n\n// ============================================================\n// IndexedDB Wrapper (AgentDB)\n// ============================================================\nclass AgentDB {\n  constructor() {\n    this.dbName = \"RugbieAgentDB\";\n    this.version = 1;\n    this.db = null;\n    this.ready = this.init();\n  }\n\n  init() {\n    return new Promise((resolve, reject) => {\n      const req = indexedDB.open(this.dbName, this.version);\n      req.onupgradeneeded = (e) => {\n        const db = e.target.result;\n        if (!db.objectStoreNames.contains(\"messages\")) {\n          db.createObjectStore(\"messages\", {\n            keyPath: \"id\",\n            autoIncrement: true,\n          });\n        }\n        if (!db.objectStoreNames.contains(\"context\")) {\n          db.createObjectStore(\"context\", { keyPath: \"sessionId\" });\n        }\n      };\n      req.onsuccess = (e) => {\n        this.db = e.target.result;\n        resolve();\n      };\n      req.onerror = () => reject(req.error);\n    });\n  }\n\n  async saveMessage(sessionId, role, content) {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"messages\", \"readwrite\");\n      tx.objectStore(\"messages\").add({\n        sessionId,\n        role,\n        content,\n        timestamp: Date.now(),\n      });\n      tx.oncomplete = () => resolve();\n      tx.onerror = () => reject(tx.error);\n    });\n  }\n\n  async getMessages(sessionId) {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"messages\", \"readonly\");\n      const req = tx.objectStore(\"messages\").getAll();\n      req.onsuccess = () => {\n        const msgs = req.result\n          .filter((m) => m.sessionId === sessionId)\n          .filter(\n            (m) =>\n              m.content &&\n              !m.content.includes(\"skeleton-card\") &&\n              !m.content.includes(\"typing-status\"),\n          )\n          .sort((a, b) => a.timestamp - b.timestamp)\n          .slice(-50);\n        resolve(msgs);\n      };\n      req.onerror = () => reject(req.error);\n    });\n  }\n\n  async getSessionSummaries() {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"messages\", \"readonly\");\n      const req = tx.objectStore(\"messages\").getAll();\n      req.onsuccess = () => {\n        const sessions = {};\n        req.result.forEach((m) => {\n          if (\n            m.content &&\n            !m.content.includes(\"skeleton-card\") &&\n            !m.content.includes(\"typing-status\")\n          ) {\n            if (!sessions[m.sessionId]) {\n              sessions[m.sessionId] = {\n                id: m.sessionId,\n                startTime: m.timestamp,\n                lastTime: m.timestamp,\n                messages: [],\n              };\n            }\n            sessions[m.sessionId].messages.push(m);\n            sessions[m.sessionId].lastTime = Math.max(\n              sessions[m.sessionId].lastTime,\n              m.timestamp,\n            );\n          }\n        });\n        const summaries = Object.values(sessions)\n          .map((s) => {\n            s.messages.sort((a, b) => a.timestamp - b.timestamp);\n            const firstUserMsg = s.messages.find((m) => m.role === \"user\");\n            const titleText = firstUserMsg\n              ? firstUserMsg.content.replace(/<[^>]+>/g, \"\").trim()\n              : \"Shopping Session\";\n            const title =\n              titleText.substring(0, 40) + (titleText.length > 40 ? \"...\" : \"\");\n            return {\n              id: s.id,\n              startTime: s.startTime,\n              lastTime: s.lastTime,\n              title,\n              count: s.messages.length,\n            };\n          })\n          .sort((a, b) => b.lastTime - a.lastTime);\n        resolve(summaries);\n      };\n      req.onerror = () => reject(tx.error);\n    });\n  }\n\n  async pruneOldMessages(maxAgeMs = 24 * 60 * 60 * 1000) {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"messages\", \"readwrite\");\n      const store = tx.objectStore(\"messages\");\n      const req = store.getAll();\n      const cutoff = Date.now() - maxAgeMs;\n      req.onsuccess = () => {\n        req.result\n          .filter((m) => (m.timestamp || 0) < cutoff)\n          .forEach((m) => store.delete(m.id));\n      };\n      tx.oncomplete = () => resolve();\n      tx.onerror = () => reject(tx.error);\n    });\n  }\n\n  async clearMessages(sessionId) {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"messages\", \"readwrite\");\n      const store = tx.objectStore(\"messages\");\n      const req = store.getAll();\n      req.onsuccess = () => {\n        const toDelete = req.result.filter((m) => m.sessionId === sessionId);\n        toDelete.forEach((m) => store.delete(m.id));\n        resolve();\n      };\n      req.onerror = () => reject(req.error);\n    });\n  }\n\n  async saveContext(sessionId, contextData) {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"context\", \"readwrite\");\n      tx.objectStore(\"context\").put({ sessionId, ...contextData });\n      tx.oncomplete = () => resolve();\n      tx.onerror = () => reject(tx.error);\n    });\n  }\n\n  async getContext(sessionId) {\n    await this.ready;\n    return new Promise((resolve, reject) => {\n      const tx = this.db.transaction(\"context\", \"readonly\");\n      const req = tx.objectStore(\"context\").get(sessionId);\n      req.onsuccess = () => resolve(req.result);\n      req.onerror = () => reject(req.error);\n    });\n  }\n}\n\n// ============================================================\n// Store (localStorage persistence)\n// ============================================================\nclass Store {\n  constructor() {\n    this.sessionId = this._loadOrCreateSession();\n    this.data = this._load();\n  }\n\n  _loadOrCreateSession() {\n    try {\n      localStorage.removeItem(\"rug_session_id\");\n    } catch (e) {\n      /* ignore */\n    }\n    let id = sessionStorage.getItem(\"rug_session_id\");\n    if (!id) {\n      id = crypto.randomUUID\n        ? crypto.randomUUID()\n        : \"sess_\" + Math.random().toString(36).slice(2) + Date.now();\n      sessionStorage.setItem(\"rug_session_id\", id);\n      sessionStorage.setItem(\"rug_session_started_at\", String(Date.now()));\n    } else if (!sessionStorage.getItem(\"rug_session_started_at\")) {\n      sessionStorage.setItem(\"rug_session_started_at\", String(Date.now()));\n    }\n    return id;\n  }\n\n  _load() {\n    try {\n      const raw =\n        localStorage.getItem(\"rug_store\") ||\n        sessionStorage.getItem(\"rug_store\");\n      if (raw) return { ...this._defaults(), ...JSON.parse(raw) };\n    } catch (e) {\n      /* ignore corrupt data */\n    }\n    return this._defaults();\n  }\n\n  _defaults() {\n    return {\n      cart: [],\n      wishlist: [],\n      compare: [],\n      viewed: [],\n      facts: {},\n      searchHistory: [],\n      uploadedPhotos: [],\n\n      // Canonical Behavior Context\n      preferred_categories: [],\n      preferred_attributes: {},\n      interaction_flags: {\n        room_uploaded: false,\n        visualizer_used: false,\n        filter_used: false,\n        sort_used: false,\n      },\n      conversation_state: {\n        intent: \"browse\",\n        stage: \"discovery\",\n        active_category: null,\n      },\n    };\n  }\n\n  save() {\n    const json = JSON.stringify(this.data);\n    localStorage.setItem(\"rug_store\", json);\n    sessionStorage.setItem(\"rug_store\", json);\n    if (window.app && window.app.db) {\n      window.app.db\n        .saveContext(this.sessionId, this.data)\n        .catch((e) => console.warn(\"IDB context save failed\", e));\n    }\n  }\n\n  // --- Cart (Shopify API Integration) ---\n  async init() {\n    try {\n      const res = await fetch(\"/cart.js\");\n      this._cart = await res.json();\n      this._syncMemory();\n    } catch (e) {\n      console.warn(\"Failed to init Shopify cart:\", e);\n    }\n  }\n\n  _syncMemory() {\n    if (!this._cart) return;\n    this.data.cart = (this._cart.items || []).map((item, index) => ({\n      key: item.key,\n      line: index + 1,\n      variant_id: item.variant_id,\n      product_id: item.product_id,\n      id: item.product_id, // For fallback compatibility\n      size: item.variant_options ? item.variant_options[0] : null,\n      title: item.title,\n      handle: item.handle,\n      url: item.url,\n      product_url: item.url,\n      qty: item.quantity,\n      quantity: item.quantity,\n      price: item.price / 100, // Shopify returns cents\n      imgUrl: item.image,\n      image: item.image,\n    }));\n    this.save();\n  }\n\n  // Resolve a real Shopify numeric variant ID from a product handle or id\n  async _resolveVariantId(idOrHandle, preferredSize = \"\") {\n    // If it's already a pure numeric ID (Shopify variant), use it directly\n    if (/^\\d+$/.test(String(idOrHandle))) return Number(idOrHandle);\n\n    // Try to look it up from the product catalog for a handle\n    const handle = idOrHandle;\n    try {\n      const res = await fetch(`/products/${handle}.js`);\n      if (res.ok) {\n        const product = await res.json();\n        if (product.variants && product.variants.length > 0) {\n          const normalizedSize = String(preferredSize || \"\")\n            .toLowerCase()\n            .replace(/\\s+/g, \"\");\n          if (normalizedSize) {\n            const bySize = product.variants.find((v) => {\n              const title = String(v.title || \"\")\n                .toLowerCase()\n                .replace(/\\s+/g, \"\");\n              const options = (v.options || []).map((o) =>\n                String(o || \"\")\n                  .toLowerCase()\n                  .replace(/\\s+/g, \"\"),\n              );\n              return (\n                v.available !== false &&\n                (title.includes(normalizedSize) ||\n                  options.includes(normalizedSize))\n              );\n            });\n            if (bySize) return bySize.id;\n          }\n          // Return the first available variant, or just the first one.\n          const available = product.variants.find((v) => v.available);\n          return (available || product.variants[0]).id;\n        }\n      }\n    } catch (e) {\n      console.warn(\"Variant resolution from /products/ failed:\", e);\n    }\n\n    // Fallback: try the numeric id as-is (will likely 422)\n    return idOrHandle;\n  }\n\n  async addToCart(item, quantity = 1, properties = {}) {\n    // Resolve variant ID: prefer explicit variant_id, else resolve from handle\n    let variantId = item.variant_id;\n    if (!variantId || !/^\\d+$/.test(String(variantId))) {\n      // item.id could be a product handle like \"charleston-distressed-blue\" or a product numeric id\n      // item.handle is also possible\n      const lookup = item.handle || item.id;\n      variantId = await this._resolveVariantId(lookup, item.size);\n    }\n\n    try {\n      const dawnCart =\n        document.querySelector(\"cart-notification\") ||\n        document.querySelector(\"cart-drawer\");\n      let sections = [];\n      if (dawnCart && typeof dawnCart.getSectionsToRender === \"function\") {\n        sections = dawnCart.getSectionsToRender().map((s) => s.id);\n      }\n\n      const body = { id: Number(variantId), quantity, properties };\n      if (sections.length > 0) {\n        body.sections = sections;\n        body.sections_url = window.location.pathname;\n      }\n\n      console.log(\"[Discovery-AI] Adding to cart, variant:\", variantId, body);\n\n      const res = await fetch(\"/cart/add.js\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify(body),\n      });\n\n      if (!res.ok) {\n        const errBody = await res.json().catch(() => null);\n        console.error(\"Add to cart failed:\", res.status, errBody);\n        throw new Error(errBody?.description || \"Add to cart failed\");\n      }\n\n      const addResponse = await res.json();\n\n      if (\n        dawnCart &&\n        typeof dawnCart.renderContents === \"function\" &&\n        addResponse.sections\n      ) {\n        dawnCart.renderContents(addResponse);\n      }\n\n      const cartRes = await fetch(\"/cart.js\");\n      this._cart = await cartRes.json();\n      this._syncMemory();\n\n      // Update header badges and dispatch events to update theme cart components in real time\n      const itemCount = this._cart.item_count || 0;\n      const evtDetail = {\n        resource: this._cart,\n        sourceId: \"shopping-agent\",\n        data: { itemCount, source: \"shopping-agent\" },\n        item_count: itemCount,\n      };\n\n      document.dispatchEvent(new CustomEvent(\"cart:update\", { bubbles: true, detail: evtDetail }));\n      document.dispatchEvent(new CustomEvent(\"cart:updated\", { bubbles: true, detail: evtDetail }));\n      window.dispatchEvent(new CustomEvent(\"cart:updated\", { bubbles: true, detail: evtDetail }));\n      document.documentElement.dispatchEvent(new CustomEvent(\"cart:updated\", { bubbles: true, detail: evtDetail }));\n\n      return { success: true, cart: this.data.cart };\n    } catch (e) {\n      console.error(\"addToCart error\", e);\n      return { success: false, error: e.message };\n    }\n  }\n\n  async removeFromCart(variantId, size = \"\", lineKey = \"\") {\n    try {\n      const dawnCart =\n        document.querySelector(\"cart-notification\") ||\n        document.querySelector(\"cart-drawer\");\n      let sections = [];\n      if (dawnCart && typeof dawnCart.getSectionsToRender === \"function\") {\n        sections = dawnCart.getSectionsToRender().map((s) => s.id);\n      }\n\n      const body = lineKey\n        ? { id: lineKey, quantity: 0 }\n        : { id: variantId, quantity: 0 };\n      if (sections.length > 0) {\n        body.sections = sections;\n        body.sections_url = window.location.pathname;\n      }\n\n      const res = await fetch(\"/cart/change.js\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify(body),\n      });\n      if (!res.ok) throw new Error(\"Remove from cart failed\");\n\n      const changeResponse = await res.json();\n\n      // To update Dawn's drawer on removal, we can re-render it if we have sections\n      if (\n        dawnCart &&\n        dawnCart.classList.contains(\"is-empty\") === false &&\n        changeResponse.sections\n      ) {\n        // Dawn's cart-drawer doesn't have a direct render for change, but replacing innerHTML of sections works\n        const cartDrawerWrapper = document.querySelector(\"cart-drawer\");\n        if (cartDrawerWrapper) {\n          sections.forEach((id) => {\n            const el = document.getElementById(id);\n            if (el && changeResponse.sections[id]) {\n              // Dawn section HTML parsing\n              const html = new DOMParser().parseFromString(\n                changeResponse.sections[id],\n                \"text/html\",\n              );\n              const newEl = html.getElementById(id);\n              if (newEl) el.innerHTML = newEl.innerHTML;\n            }\n          });\n        }\n      }\n\n      const cartRes = await fetch(\"/cart.js\");\n      this._cart = await cartRes.json();\n      this._syncMemory();\n      document.dispatchEvent(\n        new CustomEvent(\"cart:refresh\", { detail: this._cart }),\n      );\n      document.documentElement.dispatchEvent(\n        new CustomEvent(\"cart:updated\", { bubbles: true }),\n      );\n    } catch (e) {\n      console.error(\"removeFromCart error\", e);\n    }\n    return this.data.cart;\n  }\n\n  async updateCartQty(variantId, size, delta, lineKey = \"\") {\n    // Find current qty\n    const item = this.data.cart.find(\n      (c) =>\n        (lineKey && String(c.key) === String(lineKey)) ||\n        String(c.variant_id) === String(variantId) ||\n        String(c.id) === String(variantId),\n    );\n    if (item) {\n      const newQty = Math.max(0, (item.quantity || 1) + delta);\n      try {\n        const res = await fetch(\"/cart/change.js\", {\n          method: \"POST\",\n          headers: { \"Content-Type\": \"application/json\" },\n          body: JSON.stringify({ id: lineKey || variantId, quantity: newQty }),\n        });\n        const cartRes = await fetch(\"/cart.js\");\n        this._cart = await cartRes.json();\n        this._syncMemory();\n        document.dispatchEvent(\n          new CustomEvent(\"cart:refresh\", { detail: this._cart }),\n        );\n      } catch (e) {\n        console.error(\"updateCartQty error\", e);\n      }\n    }\n    return this.data.cart;\n  }\n  getCartTotal() {\n    return this._cart ? this._cart.total_price / 100 : 0;\n  }\n\n  // --- Wishlist ---\n  toggleWishlist(item) {\n    const idx = this.data.wishlist.findIndex((w) => w.id === item.id);\n    if (idx >= 0) {\n      this.data.wishlist.splice(idx, 1);\n    } else {\n      this.data.wishlist.push(item);\n    }\n    this.save();\n    return idx < 0; // true = added\n  }\n  isWishlisted(id) {\n    return this.data.wishlist.some((w) => w.id === id);\n  }\n\n  // --- Compare ---\n  addToCompare(item) {\n    if (this.data.compare.length >= 4) return false;\n    if (this.data.compare.some((c) => c.id === item.id)) return false;\n    this.data.compare.push(item);\n    this.save();\n    return true;\n  }\n  removeFromCompare(id) {\n    this.data.compare = this.data.compare.filter((c) => c.id !== id);\n    this.save();\n  }\n  clearCompare() {\n    this.data.compare = [];\n    this.save();\n  }\n\n  // --- Viewed ---\n  addViewed(item) {\n    this.data.viewed = [\n      item,\n      ...this.data.viewed.filter((v) => v.id !== item.id),\n    ].slice(0, 20);\n    this.save();\n  }\n\n  // --- Facts ---\n  updateFacts(newFacts, overwrite = false) {\n    if (overwrite) {\n      const filterKeys = [\n        \"color\",\n        \"room\",\n        \"budget\",\n        \"style\",\n        \"size\",\n        \"size_bucket\",\n        \"shape\",\n        \"material\",\n        \"pattern\",\n        \"collection\",\n        \"washable\",\n        \"pet_friendly\",\n      ];\n      filterKeys.forEach((k) => {\n        if (!(k in newFacts)) {\n          delete this.data.facts[k];\n        }\n      });\n    }\n    this.data.facts = { ...this.data.facts, ...newFacts };\n    this.save();\n  }\n\n  addSearch(query) {\n    this.data.searchHistory = [\n      query,\n      ...this.data.searchHistory.filter((item) => item !== query),\n    ].slice(0, 50);\n    this.save();\n  }\n\n  clearFacts(keys = []) {\n    keys.forEach((key) => delete this.data.facts[key]);\n    this.save();\n  }\n\n  addUploadedPhoto(file, facts = {}) {\n    this.data.uploadedPhotos = [\n      {\n        name: file.name,\n        type: file.type,\n        size: file.size,\n        analyzedAt: new Date().toISOString(),\n        facts,\n      },\n      ...this.data.uploadedPhotos,\n    ].slice(0, 10);\n    this.save();\n  }\n\n  assistantMemory(messages = []) {\n    return {\n      viewed_products: this.data.viewed,\n      compared_products: this.data.compare,\n      budget: this.data.facts.budget || null,\n      preferred_styles: this.data.facts.style || [],\n      preferred_colors: this.data.facts.color || [],\n      room_type: this.data.facts.room || null,\n      search_history: this.data.searchHistory,\n      uploaded_room_images: this.data.uploadedPhotos,\n      cart_activity: this.data.cart,\n      messages: messages.slice(-20).map((msg) => ({\n        role: msg.role,\n        content: String(msg.content || \"\")\n          .replace(/\\s+/g, \" \")\n          .trim()\n          .slice(0, 1200),\n        timestamp: msg.timestamp || null,\n      })),\n    };\n  }\n\n  getLastViewed() {\n    return this.data.viewed?.[0] || null;\n  }\n}\n\n// ============================================================\n// UIRenderer \u2014 builds HTML strings (accessible, <img> based)\n// ============================================================\nclass UIRenderer {\n  esc(str) {\n    if (!str) return \"\";\n    // Decode any pre-existing HTML entities safely first\n    const decoder = document.createElement(\"textarea\");\n    decoder.innerHTML = String(str);\n    const decoded = decoder.value;\n    \n    // Then safely escape for HTML display\n    const d = document.createElement(\"div\");\n    d.textContent = decoded;\n    return d.innerHTML;\n  }\n  escAttr(str) {\n    return this.esc(str).replace(/\"/g, \"&quot;\").replace(/'/g, \"&#39;\");\n  }\n  escJS(str) {\n    return this.esc(str)\n      .replace(/\\\\/g, \"\\\\\\\\\")\n      .replace(/'/g, \"\\\\'\")\n      .replace(/\"/g, \"&quot;\");\n  }\n\n  formatPrice(p) {\n    if (!p) return \"\";\n    const s = String(p);\n    if (s.startsWith(\"$\")) return s;\n    const n = parseFloat(s.replace(/[^0-9.]/g, \"\"));\n    return isNaN(n)\n      ? s\n      : `$${n.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;\n  }\n\n  priceNumber(value) {\n    if (value === undefined || value === null || value === \"\") return 0;\n    if (typeof value === \"number\") return value;\n    const raw = String(value).replace(/,/g, \"\").trim();\n    const n = parseFloat(raw.replace(/[^0-9.]/g, \"\"));\n    if (isNaN(n)) return 0;\n    return n;\n  }\n\n  priceBlock(product = {}) {\n    const priceNum = this.priceNumber(\n      product.price ||\n        product.sale_price ||\n        product.discounted_price ||\n        product.final_price,\n    );\n    const compareNum = this.priceNumber(\n      product.compare_at_price ||\n        product.original_price ||\n        product.regular_price ||\n        product.msrp ||\n        product.was_price,\n    );\n    const price = this.formatPrice(priceNum);\n    if (compareNum && priceNum && compareNum > priceNum) {\n      return `<div class=\"dai-chat-price dai-chat-price--sale\">\n                <s>${this.formatPrice(compareNum)}</s>\n                <strong>${price}</strong>\n            </div>`;\n    }\n    return price\n      ? `<div class=\"dai-chat-price\"><strong>${price}</strong></div>`\n      : \"\";\n  }\n\n  loading(statusText) {\n    const text = statusText || \"Thinking\u2026\";\n    return `<div class=\"typing-status\" role=\"status\" aria-label=\"${this.escAttr(text)}\">\n            <div class=\"status-icon\"><svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"11\"/><g transform=\"translate(12,12) rotate(45) scale(0.5) translate(-12,-12)\"><path d=\"M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z\"></path></g></svg></div>\n            <span class=\"status-text\">${this.esc(text)}</span>\n        </div>`;\n  }\n\n  skeletonGrid(count = 3) {\n    let cards = \"\";\n    for (let i = 0; i < count; i++) {\n      cards += `<div class=\"skeleton-card\" style=\"animation-delay:${i * 40}ms\">\n                <div class=\"skeleton-img\"></div>\n                <div class=\"skeleton-body\">\n                    <div class=\"skeleton-line medium\"></div>\n                    <div class=\"skeleton-line short\"></div>\n                    <div class=\"skeleton-line price\"></div>\n                </div>\n            </div>`;\n    }\n    return `<div class=\"chat-product-grid\">${cards}</div>`;\n  }\n\n  browseLoading(query = \"\") {\n    const label = query\n      ? `Matching best rugs for \"${query}\"...`\n      : \"Matching best rugs for your room...\";\n    return `<div class=\"match-loader\" role=\"status\" aria-label=\"${this.escAttr(label)}\">\n            <div class=\"match-loader__loom\"><span></span><span></span><span></span><span></span></div>\n            <div><strong>${this.esc(label)}</strong><small>Checking color, size, material, price and availability</small></div>\n        </div>`;\n  }\n\n  chatLoading(query = \"\") {\n    const label = query\n      ? \"Reading product and store details...\"\n      : \"Thinking...\";\n    return `<div class=\"chat-loader\" role=\"status\" aria-label=\"${this.escAttr(label)}\">\n            <span></span><span></span><span></span><strong>${this.esc(label)}</strong>\n        </div>`;\n  }\n\n  // --- Welcome ---\n  welcomePrompt() {\n    return `<p class=\"welcome-prompt\">Ask me to find rugs by size, color, room, budget, material, care needs, order status, or services.</p>`;\n  }\n\n  // --- Quick Chips ---\n  chips(items) {\n    if (!items || !Array.isArray(items)) return \"\";\n    const validItems = items.filter(\n      (i) => typeof i === \"string\" && i.trim().length > 0,\n    );\n    if (validItems.length === 0) return \"\";\n    return `<div class=\"quick-actions\">${validItems.map((i) => `<button class=\"chip action-chip-btn\" data-action=\"${this.escAttr(i)}\">${this.esc(i)}</button>`).join(\"\")}</div>`;\n  }\n\n  toolMenu(items) {\n    if (!items || !Array.isArray(items)) return \"\";\n    return `<div class=\"tool-grid\">\n            ${items\n              .map(\n                (\n                  item,\n                ) => `<button class=\"tool-tile\" data-app-action=\"openTool\" data-arg0=\"${this.escAttr(item.id)}\">\n                <div class=\"tool-icon\" style=\"margin-bottom:8px;color:var(--color-brass)\">${item.icon}</div>\n                <span>${this.esc(item.label)}</span>\n            </button>`,\n              )\n              .join(\"\")}\n        </div>`;\n  }\n\n  // --- Horizontal Product Carousel ---\n  horizontalProductCarousel(products, title = null) {\n    window.app?.registerProducts(products);\n    let html = \"\";\n    if (title) {\n      html += `<h4 class=\"carousel-title\" style=\"margin-bottom:var(--space-xs); font-family:var(--font-heading);\">${this.esc(title)}</h4>`;\n    }\n    html += `<div class=\"chat-carousel-container\" style=\"position: relative; width: 100%; margin: var(--space-md) 0;\">\n            <button type=\"button\" class=\"carousel-scroll-btn carousel-scroll-prev\" aria-label=\"Scroll left\" title=\"Scroll left\" style=\"display: none;\">\n                <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 18 9 12 15 6\"></polyline></svg>\n            </button>\n            <div class=\"chat-product-carousel\" style=\"display:flex; overflow-x:auto; gap:var(--space-md); padding-bottom:var(--space-sm); scroll-behavior:smooth; -webkit-overflow-scrolling:touch; width:100%; scrollbar-width: none;\">\n                ${products.map((p) => this.productCard(p, false, true)).join(\"\")}\n            </div>\n            ${\n              products.length > 1\n                ? `<button type=\"button\" class=\"carousel-scroll-btn carousel-scroll-next\" aria-label=\"Scroll right\" title=\"Scroll right\">\n                <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"></polyline></svg>\n            </button>`\n                : \"\"\n            }\n        </div>`;\n    return html;\n  }\n\n  // --- Product Grid (in-chat) ---\n  productGrid(products, isRecommended = false) {\n    window.app?.registerProducts(products);\n    return `<div class=\"chat-product-grid\">${products.map((p) => this.productCard(p, isRecommended)).join(\"\")}</div>`;\n  }\n\n  // --- Curated Picks (AI-Recommended) ---\n  curatedPicks(\n    products,\n    reason = \"Based on your preferences\",\n    totalResults = 0,\n  ) {\n    if (!products || products.length === 0) return \"\";\n    window.app?.registerProducts(products);\n    const shown = Math.min(products.length, 3);\n    const remaining = Math.max(0, totalResults - shown);\n\n    let html = `<div class=\"curated-recommendation\">\n            <p class=\"curated-reason\">${this.esc(reason)}</p>\n            <div class=\"curated-products\">\n                ${products\n                  .slice(0, 3)\n                  .map((p) => this.productCard(p, true))\n                  .join(\"\")}\n            </div>`;\n\n    if (remaining > 0) {\n      html += `<button class=\"discovery-btn btn-secondary\" style=\"width:100%; margin-top:var(--space-md)\" data-app-action=\"showAllResults\"><i class=\"fa fa-arrow-right\"></i> View all ${totalResults} results</button>`;\n    }\n\n    html += `</div>`;\n\n    // Add contextual action chips\n    html += `<div class=\"quick-actions\" style=\"margin-top: var(--space-sm);\">\n            <button class=\"chip action-chip-btn\" data-action=\"See in my room\"><i class=\"fa fa-cube\"></i> See in my room</button>\n            <button class=\"chip action-chip-btn\" data-action=\"Filter results\"><i class=\"fa fa-sliders-h\"></i> Filter results</button>\n            <button class=\"chip action-chip-btn\" data-action=\"More like these\"><i class=\"fa fa-search\"></i> More like these</button>\n        </div>`;\n\n    return html;\n  }\n\n  productCard(p, isCurated = false, isHorizontal = false) {\n    const id = this.escAttr(p.id);\n    let rawHandle = p.shopify_handle || p.handle || \"\";\n    if (!rawHandle && (p.url || p.product_url || p.uri)) {\n      const pUrl = p.product_url || p.url || p.uri || \"\";\n      const m = pUrl.match(/\\/products\\/([^\\/\\?#]+)/);\n      if (m) rawHandle = m[1];\n    }\n    if (!rawHandle && p.id && !/^\\d+$/.test(String(p.id)) && !String(p.id).startsWith(\"rec_\")) {\n      rawHandle = String(p.id);\n    }\n    const cleanHandle = String(rawHandle || \"\")\n      .replace(/^owfam-/, \"\")\n      .replace(/^\\/products\\//, \"\")\n      .split(\"?\")[0]\n      .split(\"#\")[0]\n      .trim();\n    const handle = this.escAttr(cleanHandle || p.id);\n    const title = this.esc(p.title);\n    const safeTitle = this.escJS(p.title);\n\n    const priceNum = this.priceNumber(\n      p.price || p.sale_price || p.discounted_price || p.final_price,\n    );\n    const compareNum = this.priceNumber(\n      p.compare_at_price ||\n        p.original_price ||\n        p.regular_price ||\n        p.msrp ||\n        p.was_price,\n    );\n    const priceMarkup = this.priceBlock(p);\n\n    const discountPct =\n      compareNum && compareNum > priceNum\n        ? Math.round(((compareNum - priceNum) / compareNum) * 100)\n        : null;\n\n    const invQty = p.inventory_quantity || 0;\n    const lowStock = invQty <= 5 && invQty > 0;\n\n    const size = this.esc(\n      p.size ||\n        p.dimensions ||\n        (p.tags && p.tags.find((t) => t.match(/\\d+x\\d+/i))) ||\n        \"8' x 10'\",\n    );\n    const material = this.esc(\n      p.material ||\n        (p.tags &&\n          p.tags.find((t) =>\n            [\"wool\", \"jute\", \"synthetic\", \"cotton\"].includes(t.toLowerCase()),\n          )) ||\n        \"Wool Blend\",\n    );\n    const pileHeight = this.esc(p.pile_height || \"Medium Pile\");\n    const vendor = this.esc(p.vendor || p.brand || \"\");\n\n    const img = this.escAttr(p.image_url || p.imgUrl || p.image || \"\");\n    const rawSizes = Array.isArray(p.sizes)\n      ? p.sizes\n      : Array.isArray(p.variants)\n        ? p.variants.filter(v => v.available !== false).map((v) => v.title).filter(Boolean)\n        : [];\n    const sizes = rawSizes\n      .filter((s) => s && String(s).toLowerCase() !== \"default title\")\n      .slice(0, 6);\n\n    const isRug = typeof window.isRugProduct === \"function\"\n      ? window.isRugProduct(p)\n      : !(\n          title.toLowerCase().includes(\"pad\") ||\n          (p.type && String(p.type).toLowerCase().includes(\"pad\")) ||\n          (p.tags && p.tags.some((t) => String(t).toLowerCase().includes(\"pad\")))\n        );\n\n    const cardClass = isCurated\n      ? \"chat-product-curated card-enter\"\n      : \"chat-product card-enter\";\n    const productUrl = p.url || p.product_url || p.uri || `/products/${handle}`;\n\n    const orientationClass = isHorizontal\n      ? \"layout-horizontal\"\n      : \"layout-vertical\";\n\n    const tagHtml = `<div class=\"card-badge card-badge-texture\" style=\"background: rgba(255,255,255,0.1); padding: 4px 8px; border-radius: 4px; font-size: 12px; text-transform: uppercase;\">${material} &middot; ${pileHeight}</div>`;\n    const discountBadge = discountPct\n      ? `<span class=\"dai-badge-discount badge price__badge-sale color-accent-1\" style=\"position:absolute; top:8px; left:8px; z-index:2;\">${discountPct}% OFF</span>`\n      : \"\";\n    const lowStockBanner = lowStock\n      ? `<div class=\"dai-low-stock\" style=\"color: #e53935; font-size: 0.8rem; margin: 4px 0;\">\u26A1 Only ${invQty} left!</div>`\n      : \"\";\n\n    if (cleanHandle && (!p.variants || p.variants.length === 0 || !p.options)) {\n      const candidates = [cleanHandle, cleanHandle.replace(/^owfam-/, ''), 'owfam-' + cleanHandle.replace(/^owfam-/, '')].filter(Boolean);\n      (async () => {\n        let prodData = null;\n        let matchedHandle = cleanHandle;\n        for (const h of candidates) {\n          try {\n            const r = await fetch(`/products/${h}.js`);\n            if (r.ok) {\n              prodData = await r.json();\n              matchedHandle = h;\n              break;\n            }\n          } catch (_) {}\n        }\n        if (!prodData || !Array.isArray(prodData.variants) || prodData.variants.length === 0) return;\n\n        p.variants = prodData.variants;\n        p.options = prodData.options;\n        p.handle = matchedHandle;\n        if (window.app?.productCatalog) {\n          window.app.productCatalog.set(String(p.id), p);\n        }\n\n        const updateDom = () => {\n          const rows = Array.from(document.querySelectorAll('.result-size-row')).filter(\n            (r) => r.getAttribute('data-product-id') === String(id) || r.getAttribute('data-handle') === cleanHandle || r.getAttribute('data-handle') === matchedHandle\n          );\n          if (rows.length > 0) {\n            const sizeIdx = Array.isArray(prodData.options)\n              ? prodData.options.findIndex((o) => (typeof o === \"string\" ? o : o.name || \"\").toLowerCase() === \"size\")\n              : -1;\n            const extractedSizes = [];\n            prodData.variants.forEach((v) => {\n              if (v.available === false) return;\n              const vOpts = Array.isArray(v.options) ? v.options : [v.option1, v.option2, v.option3].filter(Boolean);\n              let sVal = sizeIdx !== -1 && vOpts[sizeIdx] ? vOpts[sizeIdx] : v.option1 || v.title || \"\";\n              if (sVal && String(sVal).toLowerCase() !== \"default title\") {\n                extractedSizes.push(sVal);\n              }\n            });\n            const uniqueSizes = [...new Set(extractedSizes)].slice(0, 6);\n            if (uniqueSizes.length > 0) {\n              rows.forEach((sizeRow) => {\n                if (sizeRow.children.length === 0) {\n                  sizeRow.innerHTML = uniqueSizes\n                    .map(\n                      (s) =>\n                        `<button type=\"button\" class=\"result-size-chip\" data-app-action=\"selectResultSize\" data-arg0=\"${id}\" data-arg1=\"${this.escAttr(s)}\" style=\"padding: 2px 8px; font-size: 11px; border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; background: transparent; color: #ccc; cursor: pointer; transition: all 0.2s;\">${this.esc(s)}</button>`\n                    )\n                    .join(\"\");\n                  sizeRow.style.display = \"flex\";\n                }\n              });\n            }\n          }\n\n          const seeBtns = Array.from(document.querySelectorAll('.see-in-room-btn')).filter(\n            (b) => b.getAttribute('data-id') === String(id) || b.getAttribute('data-product-handle') === cleanHandle || b.getAttribute('data-product-handle') === matchedHandle\n          );\n          seeBtns.forEach((seeBtn) => {\n            seeBtn.setAttribute(\"data-product-handle\", matchedHandle);\n            const firstVar = prodData.variants.find((v) => v.available) || prodData.variants[0];\n            if (firstVar) {\n              seeBtn.setAttribute(\"data-variant-id\", firstVar.id);\n              const vImg = firstVar.featured_image?.src || firstVar.featured_image;\n              if (vImg) seeBtn.setAttribute(\"data-rug\", vImg);\n            }\n          });\n        };\n\n        updateDom();\n        setTimeout(updateDom, 150);\n        setTimeout(updateDom, 500);\n      })();\n    }\n\n    return `<div class=\"${cardClass} ${orientationClass}\" data-product-id=\"${id}\" style=\"margin-bottom: 12px; border-radius: var(--radius-md); overflow: hidden; position: relative;\">\n            ${discountBadge}\n            <div class=\"chat-product-img-wrapper\" style=\"background-color: #f5f5f5; padding: 12px; display: flex; align-items: center; justify-content: center;\">\n                <a href=\"${productUrl}\" class=\"view-product-btn\" data-id=\"${id}\" data-url=\"${productUrl}\" style=\"display: block; width: 100%; height: 100%;\">\n                    <img src=\"${img}\" alt=\"${title}\" class=\"main-img\" loading=\"lazy\" style=\"border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); width: 100%; height: 100%; object-fit: cover; max-height: 200px;\" onerror=\"if(this.dataset.retried){this.style.display='none';}else{this.dataset.retried='true';if(this.src.includes('owimages.com')){this.src=this.src.replace('https://www.owimages.com/hr_3200/','https://cdn.shopify.com/s/files/1/0728/3549/8122/files/');}}\">\n                </a>\n            </div>\n            <div class=\"chat-product-body surface-commerce\" style=\"padding: 12px; background: #1a1a1a; color: white;\">\n                ${p.reason ? `<div class=\"recommendation-reason\" style=\"font-size: 12px; color: #b89f71; font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; gap: 6px;\"><i class=\"fa fa-magic\"></i> ${this.esc(p.reason)}</div>` : \"\"}\n                <div class=\"card-badges-row\" style=\"display: flex; gap: 8px; margin-bottom: 8px;\">\n                    ${tagHtml}\n                </div>\n                ${vendor ? `<div class=\"meta-vendor\" style=\"font-size: 12px; text-transform: uppercase; color: #aaa; margin-bottom: 4px;\">${vendor}</div>` : \"\"}\n                <h4 class=\"product-title\" style=\"margin: 0 0 8px 0; font-size: 14px; font-weight: 600;\">\n                    <a href=\"${productUrl}\" class=\"view-product-btn\" data-id=\"${id}\" data-url=\"${productUrl}\" style=\"color: white; text-decoration: none;\">${title}</a>\n                </h4>\n                \n                ${priceMarkup}\n\n                ${lowStockBanner}\n\n                <style>.result-size-chip.selected { background: #fff !important; color: #000 !important; font-weight: 600; border-color: #fff !important; }</style>\n                <div class=\"result-size-row\" data-product-id=\"${id}\" data-handle=\"${handle}\" aria-label=\"Available sizes\" style=\"display: ${sizes.length ? 'flex' : 'none'}; flex-wrap: wrap; gap: 4px; margin-top: 8px;\">${sizes.map((s) => `<button type=\"button\" class=\"result-size-chip\" data-app-action=\"selectResultSize\" data-arg0=\"${id}\" data-arg1=\"${this.escAttr(s)}\" style=\"padding: 2px 8px; font-size: 11px; border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; background: transparent; color: #ccc; cursor: pointer; transition: all 0.2s;\">${this.esc(s)}</button>`).join(\"\")}</div>\n                \n                <div class=\"chat-product-actions\" style=\"margin-top: 12px; display: flex; flex-direction: column; gap: 8px; width: 100%;\">\n                    <button class=\"discovery-btn btn-primary add-to-cart-dominant\" data-app-action=\"quickAddProduct\" data-arg0=\"${id}\" style=\"width: 100%; background: #ffffff; color: #000000; font-weight: 700; border-radius: 50px; padding: 10px; display: flex; align-items: center; justify-content: center; gap: 6px; border: none; cursor: pointer; font-size: 13px;\">\n                        <i class=\"fa fa-plus\"></i> Add to cart\n                    </button>\n                    ${\n                      isRug\n                        ? `<button class=\"discovery-btn btn-ghost see-in-room-btn\" data-app-action=\"seeProductInRoom\" data-arg0=\"${id}\" data-id=\"${id}\" data-product-handle=\"${handle}\" data-rug=\"${img}\" data-size=\"${size}\" data-is-chat-card=\"true\" style=\"width: 100%; border: 1px solid rgba(255, 255, 255, 0.35); color: #ffffff; background: transparent; border-radius: 50px; padding: 10px; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 13px; font-weight: 600;\" title=\"See in my room\">\n                        <i class=\"fa fa-cube\" style=\"margin-right: 6px;\"></i> See in my room\n                    </button>`\n                        : \"\"\n                    }\n                </div>\n            </div>\n        </div>`;\n  }\n\n  recentlyViewed(items) {\n    if (!items.length) {\n      return this.knowledgeCard(\n        \"Recently Viewed\",\n        \"<p>Your recently viewed rugs will appear here as you browse.</p>\",\n        \"fa-clock-rotate-left\",\n      );\n    }\n    return `<div class=\"knowledge-card\">\n            <h4><i class=\"fa fa-clock-rotate-left\" style=\"color:var(--color-accent)\" aria-hidden=\"true\"></i> Recently Viewed</h4>\n            <div class=\"recent-list\">\n                ${items\n                  .map(\n                    (\n                      item,\n                    ) => `<button class=\"recent-item\" data-app-action=\"openStoredProduct\" data-arg0=\"${this.escAttr(item.id)}\">\n                    <img src=\"${this.escAttr(item.imgUrl || item.image_url || \"\")}\" alt=\"${this.esc(item.title)}\" loading=\"lazy\" onerror=\"this.style.display='none'\">\n                    <span><strong>${this.esc(item.title)}</strong><small>${this.formatPrice(item.price)}</small></span>\n                </button>`,\n                  )\n                  .join(\"\")}\n            </div>\n        </div>`;\n  }\n\n  confidenceCard(score, reasons, product) {\n    return `<div class=\"confidence-card\">\n            <div class=\"confidence-score\" aria-label=\"Buying confidence score ${score} out of 100\">\n                <span>${score}</span><small>/100</small>\n            </div>\n            <div>\n                <h4>Buying Confidence Score</h4>\n                <p>${product ? `For <strong>${this.esc(product.title)}</strong>, based on your current product context, browsing activity, and saved preferences.` : \"Based on your current browsing activity and saved preferences.\"}</p>\n                <ul>${reasons.map((reason) => `<li>${this.esc(reason)}</li>`).join(\"\")}</ul>\n            </div>\n        </div>`;\n  }\n\n  // --- Compare Card Grid ---\n  compareTable(items) {\n    return this.knowledgeCard(\n      \"Selection guidance\",\n      \"<p>Product comparison is turned off for this store. I can help choose by size, material, price, care, or rug pad fit.</p>\",\n      \"fa-lightbulb\",\n    );\n    if (items.length < 2)\n      return `<div class=\"compare-card\"><p>Add at least 2 products to compare. Use the <strong>compare</strong> button on product cards.</p></div>`;\n    const attrs = [\"Price\", \"Size\", \"Color\", \"Style\", \"Material\"];\n    const keys = [\"price\", \"size\", \"color\", \"style\", \"material\"];\n\n    // Detect which attributes differ across items\n    const differs = keys.map((k) => {\n      const vals = items.map((p) =>\n        String(p[k] || \"\")\n          .toLowerCase()\n          .trim(),\n      );\n      return new Set(vals).size > 1;\n    });\n\n    return `<div class=\"compare-card\">\n            <h4><i class=\"fa fa-lightbulb\" aria-hidden=\"true\"></i> Selection Guidance</h4>\n            <div class=\"compare-grid\" role=\"table\" aria-label=\"Selection guidance\">\n                ${items\n                  .map(\n                    (p) => `<div class=\"compare-column\">\n                    <div class=\"compare-column-img\">\n                        <img src=\"${this.escAttr(p.imgUrl || p.image_url || \"\")}\" alt=\"${this.esc(p.title)}\" loading=\"lazy\" onload=\"this.classList.add('loaded')\">\n                    </div>\n                    <div class=\"compare-column-title\">${this.esc(p.title)}</div>\n                    <div class=\"compare-column-remove\">\n                        <button class=\"discovery-btn btn-ghost btn-sm\" style=\"font-size:0.65rem; padding:2px 6px;\" data-app-action=\"removeCompare\" data-arg0=\"${this.escAttr(p.id)}\"><i class=\"fa fa-times\"></i> Remove</button>\n                    </div>\n                    <div class=\"compare-attrs\">\n                        ${attrs\n                          .map(\n                            (\n                              a,\n                              i,\n                            ) => `<div class=\"compare-attr-row${differs[i] ? \" differs\" : \"\"}\">\n                            <span class=\"compare-attr-label\">${a}</span>\n                            <span class=\"compare-attr-value\">${this.esc(keys[i] === \"price\" ? this.formatPrice(p[keys[i]]) : p[keys[i]] || \"\u2014\")}</span>\n                        </div>`,\n                          )\n                          .join(\"\")}\n                    </div>\n                </div>`,\n                  )\n                  .join(\"\")}\n            </div>\n            <div style=\"margin-top:var(--space-md)\"><button class=\"discovery-btn btn-ghost btn-sm\" data-app-action=\"clearCompare\">Clear All</button></div>\n        </div>`;\n  }\n\n  // --- Knowledge Cards ---\n  knowledgeCard(title, content, icon) {\n    return `<div class=\"knowledge-card\"><h4><i class=\"fa ${icon || \"fa-info-circle\"}\" style=\"color:var(--color-accent)\" aria-hidden=\"true\"></i> ${this.esc(title)}</h4><div class=\"knowledge-content\">${content}</div></div>`;\n  }\n\n  materialCard(mat) {\n    const pros = (mat.pros || [])\n      .map((p) => `<li class=\"knowledge-pros\">${this.esc(p)}</li>`)\n      .join(\"\");\n    const cons = (mat.cons || [])\n      .map((c) => `<li class=\"knowledge-cons\">${this.esc(c)}</li>`)\n      .join(\"\");\n    return this.knowledgeCard(\n      mat.name,\n      `\n            <p><strong>Durability:</strong> ${this.esc(mat.durability)} \u00B7 <strong>Feel:</strong> ${this.esc(mat.feel)}</p>\n            <p><strong>Price:</strong> ${this.esc(mat.price_range)} \u00B7 <strong>Best for:</strong> ${this.esc((mat.best_rooms || []).join(\", \"))}</p>\n            <p>${mat.pet_friendly ? \"\u2705 Pet-friendly\" : \"\u274C Not pet-friendly\"} \u00B7 ${mat.kid_friendly ? \"\u2705 Kid-safe\" : \"\u274C Not ideal for kids\"} \u00B7 ${mat.washable ? \"\u2705 Washable\" : \"\u274C Not machine washable\"}</p>\n            <p><strong>Care:</strong> ${this.esc(mat.cleaning)}</p>\n            ${pros ? `<p><strong>Pros:</strong></p><ul>${pros}</ul>` : \"\"}\n            ${cons ? `<p><strong>Cons:</strong></p><ul>${cons}</ul>` : \"\"}\n        `,\n      \"fa-gem\",\n    );\n  }\n\n  sizeGuideCard(guide) {\n    const rows = (guide.recommendations || [])\n      .map(\n        (r) =>\n          `<tr><td>${this.esc(r.room_size)}</td><td><strong>${this.esc(r.rug_size)}</strong></td><td>${this.esc(r.note)}</td></tr>`,\n      )\n      .join(\"\");\n    return `<div class=\"knowledge-card\"><h4><i class=\"fa fa-ruler-combined\" style=\"color:var(--color-accent)\" aria-hidden=\"true\"></i> ${this.esc(guide.title)}</h4>\n            <div class=\"size-tip\"><i class=\"fa fa-lightbulb\" aria-hidden=\"true\"></i> ${this.esc(guide.tip)}</div>\n            <table class=\"size-table\"><thead><tr><th>Room / Furniture</th><th>Rug Size</th><th>Tip</th></tr></thead><tbody>${rows}</tbody></table>\n        </div>`;\n  }\n\n  serviceCard(svc) {\n    return this.knowledgeCard(\n      svc.name,\n      `\n            <p>${this.esc(svc.description)}</p>\n            <p><strong>Turnaround:</strong> ${this.esc(svc.turnaround)}</p>\n            ${svc.appointment_required ? `<button class=\"discovery-btn btn-accent btn-sm\" style=\"margin-top:var(--space-sm)\" data-app-action=\"sendAction\" data-arg0=\"Book an appointment\"><i class=\"fa fa-calendar-alt\"></i> Book Appointment</button>` : \"\"}\n        `,\n      \"fa-concierge-bell\",\n    );\n  }\n\n  servicesList(services) {\n    const items = services\n      .map(\n        (\n          s,\n        ) => `<div style=\"padding:var(--space-sm) 0;border-bottom:1px solid var(--color-border)\">\n            <strong>${this.esc(s.name)}</strong><br><span style=\"font-size:var(--text-sm);color:var(--color-text-secondary)\">${this.esc(s.description)}</span><br>\n            <span style=\"font-size:var(--text-xs);color:var(--color-text-muted)\">Turnaround: ${this.esc(s.turnaround)}</span>\n        </div>`,\n      )\n      .join(\"\");\n    return this.knowledgeCard(\"Our Services\", items, \"fa-store\");\n  }\n\n  // --- Visualizer ---\n  visualizerUpload(mode) {\n    const isVisualizing = mode === \"visualize\";\n    return `<div class=\"visualizer-card\">\n            <h4><i class=\"${isVisualizing ? \"fa-cube\" : \"fa-camera\"}\" style=\"color:var(--color-accent)\" aria-hidden=\"true\"></i> ${isVisualizing ? \"See this rug in your room\" : \"Analyze my room\"}</h4>\n            <p class=\"viz-desc\">${isVisualizing ? \"Upload a room photo and I will place the selected rug into the space.\" : \"Upload a room photo and I will detect room style, colors, and layout, then suggest matching rugs.\"}</p>\n            <div class=\"visualizer-drop viz-drop\" role=\"button\" tabindex=\"0\" data-mode=\"${mode}\" aria-label=\"Click or drag to upload room photo\">\n                <div class=\"viz-upload-icon\"><i class=\"fa fa-cloud-upload-alt\" aria-hidden=\"true\"></i></div>\n                <strong>Upload room photo</strong>\n                <span>Drag a photo here, or choose one from your device.</span>\n                <span class=\"discovery-btn btn-secondary btn-sm viz-file-label\"><i class=\"fa fa-image\"></i> Choose room photo</span>\n                <small>JPEG, PNG, WEBP - max 10MB</small>\n            </div>\n            <input type=\"file\" class=\"viz-file\" accept=\"image/jpeg,image/png,image/webp\" style=\"display:none\" aria-label=\"Select room photo\">\n            <button class=\"discovery-btn btn-accent viz-analyze\" disabled style=\"width:100%\"><i class=\"fa fa-magic\"></i> ${isVisualizing ? \"See in My Room\" : \"Analyze and Suggest Rugs\"}</button>\n        </div>`;\n  }\n\n  roomAnalysis(data) {\n    const facts = data.facts || data.payload?.facts || data.filter_state || {};\n    const tags = Object.entries(facts)\n      .filter(([k]) => !k.startsWith(\"_\"))\n      .map(([k, v]) => {\n        const val = Array.isArray(v) ? v.join(\", \") : v;\n        return `<span class=\"fact-tag\"><i class=\"fa fa-tag\" aria-hidden=\"true\"></i>${this.esc(k)}: ${this.esc(val)}</span>`;\n      })\n      .join(\"\");\n    return `<div class=\"room-analysis\">\n            <h4><i class=\"fa fa-check-circle\" aria-hidden=\"true\"></i> Room Analysis Complete</h4>\n            <p>${this.esc(data.text || \"Analysis complete\")}</p>\n            <div class=\"fact-tags\">${tags}</div>\n        </div>`;\n  }\n\n  // --- Appointment ---\n  appointmentForm() {\n    return `<div class=\"appointment-card\">\n            <h4><i class=\"fa fa-comments\" style=\"color:var(--color-accent)\" aria-hidden=\"true\"></i> Contact Store Team</h4>\n            <form id=\"appointment-form\" class=\"app-managed-form\" data-form-type=\"appointment\">\n                <div class=\"form-row\">\n                    <div class=\"form-group\"><label for=\"appt-name\">Full Name <span aria-hidden=\"true\">*</span></label>\n                        <input id=\"appt-name\" name=\"full_name\" class=\"form-control\" placeholder=\"e.g. Jane Smith\" required></div>\n                    <div class=\"form-group\"><label for=\"appt-phone\">Phone Number <span aria-hidden=\"true\">*</span></label>\n                        <input id=\"appt-phone\" name=\"phone\" class=\"form-control\" type=\"tel\" placeholder=\"e.g. (281) 719-0487\" required></div>\n                </div>\n                <div class=\"form-group\"><label for=\"appt-email\">Email <span>(optional)</span></label>\n                    <input id=\"appt-email\" name=\"email\" class=\"form-control\" type=\"email\" placeholder=\"e.g. jane@email.com\"></div>\n                <div class=\"form-group\"><label for=\"appt-service\">Service Needed <span>(optional)</span></label>\n                    <select id=\"appt-service\" name=\"service\" class=\"form-control\" required>\n                        <option value=\"\">Select a service</option>\n                        <option value=\"cleaning\">Professional Rug Cleaning</option>\n                        <option value=\"repair\">Rug Repair</option>\n                        <option value=\"restoration\">Rug Restoration</option>\n                        <option value=\"appraisal\">Rug Appraisal</option>\n                        <option value=\"custom_rugs\">Custom Rugs</option>\n                        <option value=\"consultation\">Consultation</option>\n                        <option value=\"other\">Other</option>\n                    </select></div>\n                <div class=\"form-group\"><label for=\"appt-notes\">Short Description / Notes <span>(optional)</span></label>\n                    <textarea id=\"appt-notes\" name=\"notes\" class=\"form-control\" rows=\"4\" placeholder=\"Tell us more about your rug or project...\"></textarea></div>\n                <div class=\"form-group\"><label for=\"appt-photo\">Upload Photo <span>(optional)</span></label>\n                    <label class=\"service-upload-box\" for=\"appt-photo\"><i class=\"fa fa-image\"></i><strong>Click to upload or drag and drop</strong><small>JPG, PNG up to 10MB</small></label>\n                    <input id=\"appt-photo\" name=\"photo\" type=\"file\" accept=\"image/jpeg,image/png\" style=\"display:none\"></div>\n                <button type=\"submit\" class=\"discovery-btn btn-accent\" style=\"width:100%\"><i class=\"fa fa-arrow-right\"></i> Send to Store Team</button>\n            </form>\n            <p class=\"viz-note\"><i class=\"fa fa-info-circle\"></i> We will pass these details to the store team and open Shopify Inbox when it is available.</p>\n        </div>`;\n  }\n\n  serviceConfirmationCard(req) {\n    return `<div class=\"confirmation-card interactive-service-card\" style=\"background: #1a1a1a; border: 1px solid #333; border-radius: 12px; padding: 16px; margin-top: 8px; color: #fff;\">\n            <h4 style=\"margin-top: 0; color: #4caf50; display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n                <i class=\"fa fa-check-circle\"></i> Service Request Received\n            </h4>\n            <p style=\"font-size: 13px; color: #aaa; margin-bottom: 12px;\">Our store team will reach out to you shortly.</p>\n            <div style=\"background: rgba(255,255,255,0.06); padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-bottom: 12px; display: flex; flex-direction: column; gap: 4px;\">\n                <div><strong style=\"color:#ddd;\">Service:</strong> ${this.esc(req.service || \"Rug Service\")}</div>\n                <div><strong style=\"color:#ddd;\">Name:</strong> ${this.esc(req.name || \"\")}</div>\n                <div><strong style=\"color:#ddd;\">Phone:</strong> ${this.esc(req.phone || \"\")}</div>\n            </div>\n            <div class=\"service-card-actions\" style=\"display: flex; gap: 8px; flex-wrap: wrap;\">\n                <button class=\"discovery-btn btn-secondary btn-sm\" data-app-action=\"_openStoreOwnerChat\"><i class=\"fa fa-comments\"></i> Chat Live</button>\n                <button class=\"discovery-btn btn-ghost btn-sm\" data-app-action=\"startServiceFlow\"><i class=\"fa fa-redo\"></i> Request Another Service</button>\n            </div>\n        </div>`;\n  }\n\n  // --- Order Track ---\n  orderTrackForm() {\n    const formId = \"track-form-\" + Date.now();\n    return `<div class=\"interactive-service-card order-track-card\" style=\"background: var(--color-surface, #18181b); border: 1px solid var(--color-border, #27272a); border-radius: 12px; padding: 16px; margin-top: 8px; color: var(--color-text, #ffffff);\">\n        <h4 style=\"margin-top: 0; margin-bottom: 8px; color: var(--color-text, #ffffff); display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n            \uD83D\uDCE6 Track My Order\n        </h4>\n        <p style=\"font-size: 12px; color: var(--color-text-secondary, #a1a1aa); margin-top: 0; margin-bottom: 12px; line-height: 1.4;\">\n            Enter your order number along with your checkout email to check real-time status.\n        </p>\n        <form id=\"${formId}\" class=\"interactive-order-track-form app-managed-form\" data-form-type=\"track-order\">\n            <div class=\"form-group\" style=\"margin-bottom: 10px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Order Number <span style=\"color: #ef4444;\">*</span></label>\n                <input type=\"text\" name=\"order_id\" id=\"track-order-id\" class=\"form-control\" placeholder=\"e.g. #1001 or 1001\" required style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 10px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Checkout Email <span style=\"color: #ef4444;\">*</span></label>\n                <input type=\"email\" name=\"email\" id=\"track-email\" class=\"form-control\" placeholder=\"e.g. you@example.com\" required style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 12px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Phone Number <span style=\"font-size: 11px; opacity: 0.7;\">(Optional)</span></label>\n                <input type=\"tel\" name=\"phone\" id=\"track-phone\" class=\"form-control\" placeholder=\"e.g. (281) 719-0487 or last 4 digits\" style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n            </div>\n            <button type=\"submit\" class=\"discovery-btn btn-primary\" style=\"width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; font-weight: 600; border-radius: 8px; background: var(--color-accent, #2563eb); color: #ffffff; border: none; cursor: pointer; font-size: 14px; transition: opacity 0.2s;\">\n                <i class=\"fa fa-search\"></i> Track Order\n            </button>\n        </form>\n    </div>`;\n  }\n\n  inboxHandoffCard(body, shopEmail, handoffId, inboxOpened, copied) {\n    return `<div class=\"confirmation-card compact\">\n            <h4><i class=\"fa fa-comments\" aria-hidden=\"true\"></i> Shopify Chat Handoff Ready</h4>\n            <p>${inboxOpened ? \"I opened Shopify Chat.\" : \"Open Shopify Chat to send this to the store team.\"} ${copied ? \"Your message is copied.\" : \"Copy your message, then send it in chat.\"}</p>\n            ${handoffId ? `<p class=\"text-muted\" style=\"font-size:var(--text-xs)\">Handoff ID: ${this.esc(handoffId)}</p>` : \"\"}\n            <textarea class=\"form-control\" rows=\"5\" readonly style=\"margin:10px 0\">${this.esc(body)}</textarea>\n            <div class=\"btn-group\" style=\"display:flex;gap:8px;flex-wrap:wrap\">\n                <button class=\"discovery-btn btn-accent btn-sm\" data-app-action=\"_openStoreOwnerChat\"><i class=\"fa fa-comments\"></i> Open Chat</button>\n                <button class=\"discovery-btn btn-secondary btn-sm\" data-app-action=\"copyHandoffMessage\" data-arg0=\"${this.escAttr(body)}\"><i class=\"fa fa-copy\"></i> Copy Message</button>\n                <a class=\"discovery-btn btn-secondary btn-sm\" href=\"mailto:${encodeURIComponent(shopEmail)}?subject=${encodeURIComponent(\"Service Request\")}&body=${encodeURIComponent(body)}\"><i class=\"fa fa-envelope\"></i> Email Instead</a>\n            </div>\n        </div>`;\n  }\n\n  orderStatusCard(order) {\n    const statusEmoji =\n      {\n        processing: \"\uD83D\uDD04\",\n        shipped: \"\uD83D\uDE9A\",\n        delivered: \"\u2705\",\n        cancelled: \"\u274C\",\n      }[order.status?.toLowerCase()] || \"\uD83D\uDCE6\";\n\n    const trackingLink = order.tracking_url\n      ? `<a href=\"${order.tracking_url}\" target=\"_blank\" class=\"discovery-btn btn-primary btn-sm\" style=\"margin-top:12px; display:inline-block;\">Track Package \u2192</a>`\n      : \"\";\n\n    return `<div class=\"confirmation-card compact\">\n            <h4>${statusEmoji} ${this.esc(order.status_label || order.status)}</h4>\n            <div style=\"font-size: 0.9rem; margin-top: 8px;\">\n                <div><strong>Order #${this.esc(order.order_number)}</strong> &middot; ${order.item_count || 1} item(s)</div>\n                ${order.estimated_delivery ? `<div>ETA: ${this.esc(order.estimated_delivery)}</div>` : \"\"}\n            </div>\n            ${trackingLink}\n        </div>`;\n  }\n\n  orderStatusCard(order) {\n    const status =\n      order.fulfillment_status ||\n      order.status_label ||\n      order.status ||\n      \"Processing\";\n    const trackingUrl =\n      order.tracking_url ||\n      (Array.isArray(order.tracking_urls) ? order.tracking_urls[0] : \"\");\n    const trackingNumber =\n      order.tracking_number ||\n      (Array.isArray(order.tracking_numbers) ? order.tracking_numbers[0] : \"\");\n    const items = Array.isArray(order.line_items) ? order.line_items : [];\n    const normalizedStatus = String(status || \"\").toLowerCase();\n    const currentStep = /delivered/.test(normalizedStatus)\n      ? 3\n      : /shipped|fulfilled|in_transit|out_for_delivery/.test(normalizedStatus)\n        ? 2\n        : 1;\n    const statusLabel =\n      currentStep === 3\n        ? \"Delivered\"\n        : currentStep === 2\n          ? \"On the way\"\n          : \"Confirmed\";\n    const statusCopy =\n      currentStep === 3\n        ? \"Your order has been delivered.\"\n        : currentStep === 2\n          ? \"Your order is on the way.\"\n          : \"We're preparing these items for shipping.\";\n    const steps = [\"Confirmed\", \"Shipped\", \"Delivered\"]\n      .map((label, index) => {\n        const step = index + 1;\n        const state =\n          step < currentStep\n            ? \"done\"\n            : step === currentStep\n              ? \"active\"\n              : \"pending\";\n        return `<div class=\"dai-order-step ${state}\">\n                <span class=\"dai-order-dot\">${step < currentStep ? '<i class=\"fa fa-check\"></i>' : \"\"}</span>\n                <span>${label}</span>\n            </div>`;\n      })\n      .join(\"\");\n    const itemRows = items.length\n      ? `<div class=\"dai-order-items\">\n            ${items\n              .map((item) => {\n                const productUrl = item.product_url || item.url || \"\";\n                const itemImage =\n                  item.image || item.image_url || item.imgUrl || \"\";\n                const itemBody = `\n                <div class=\"dai-order-thumb\">${itemImage ? `<img src=\"${this.escAttr(itemImage)}\" alt=\"${this.escAttr(item.title || \"Item\")}\" loading=\"lazy\" onerror=\"this.remove(); this.parentElement.classList.add('is-missing'); this.parentElement.textContent='No image';\">` : \"<span>No image</span>\"}</div>\n                <div class=\"dai-order-item-main\">\n                    <strong>${this.esc(item.title || \"Item\")}</strong>\n                    ${item.variant_title ? `<span>${this.esc(item.variant_title)}</span>` : \"\"}\n                    <small>Qty: ${this.esc(item.quantity || 1)}${item.price ? ` - ${this.formatPrice(item.price)}` : \"\"}</small>\n                </div>\n                ${productUrl ? '<i class=\"fa fa-chevron-right dai-order-item-arrow\" aria-hidden=\"true\"></i>' : \"\"}`;\n                return productUrl\n                  ? `<a class=\"dai-order-item dai-order-item-link\" href=\"${this.escAttr(productUrl)}\" aria-label=\"View ${this.escAttr(item.title || \"order item\")}\">${itemBody}</a>`\n                  : `<div class=\"dai-order-item\">${itemBody}</div>`;\n              })\n              .join(\"\")}\n        </div>`\n      : \"\";\n    const total = order.total_price\n      ? `<div class=\"dai-order-total\"><span>Total</span><strong>${this.esc(order.currency || \"USD\")} ${this.formatPrice(order.total_price)}</strong></div>`\n      : \"\";\n    const trackingLink = trackingUrl\n      ? `<a href=\"${this.escAttr(trackingUrl)}\" target=\"_blank\" class=\"dai-order-action primary\">Track package</a>`\n      : \"\";\n\n    return `<div class=\"dai-order-card\">\n            <div class=\"dai-order-head\">\n                <div>\n                    <div class=\"dai-order-kicker\">Order status</div>\n                    <h4>${this.esc(statusLabel)}</h4>\n                    <p>${this.esc(statusCopy)}</p>\n                </div>\n                <div class=\"dai-order-badge\">${this.esc(status)}</div>\n            </div>\n            <div class=\"dai-order-progress\">${steps}</div>\n            <div class=\"dai-order-meta\">\n                ${order.order_number ? `<span><strong>Order #${this.esc(order.order_number)}</strong></span>` : \"\"}\n                <span>${this.esc(order.item_count || items.length || 1)} item(s)</span>\n                ${order.financial_status ? `<span>Payment: ${this.esc(order.financial_status)}</span>` : \"\"}\n                ${trackingNumber ? `<span>Tracking: ${this.esc(trackingNumber)}</span>` : \"\"}\n            </div>\n            ${itemRows}\n            ${total}\n            <div class=\"dai-order-actions\">\n                ${order.order_status_url ? `<a href=\"${this.escAttr(order.order_status_url)}\" target=\"_blank\" class=\"dai-order-action\">View order</a>` : \"\"}\n                <button class=\"dai-order-action\" data-app-action=\"sendAction\" data-arg0=\"what is in my cart\">View cart</button>\n                <button class=\"dai-order-action\" data-app-action=\"sendAction\" data-arg0=\"care instructions\">Care tips</button>\n            </div>\n            ${trackingLink}\n        </div>`;\n  }\n\n  cartStateCardLegacy(cartItems) {\n    if (!cartItems || !cartItems.length) {\n      return `<div class=\"knowledge-card\">Your cart is empty.</div>`;\n    }\n    const rows = cartItems\n      .map(\n        (item) => `\n            <div class=\"dai-cart-item\" style=\"display:flex; gap:12px; margin-bottom:12px; align-items:center;\">\n                <img src=\"${this.escAttr(item.image || item.imgUrl)}\" alt=\"${this.escAttr(item.title)}\" width=\"48\" height=\"48\" style=\"border-radius:4px; object-fit:cover;\" />\n                <div class=\"dai-cart-item-info\" style=\"flex:1;\">\n                    <div style=\"font-size:0.9rem; font-weight:bold;\">${this.esc(item.title)}</div>\n                    <div style=\"font-size:0.8rem; color:#aaa;\">Qty: ${item.quantity || item.qty} \u2014 $${Number(item.price).toFixed(2)}</div>\n                </div>\n                <div class=\"dai-cart-item-actions\" style=\"display:flex; flex-direction:column; gap:4px;\">\n                    <button class=\"discovery-btn btn-ghost btn-sm\" style=\"padding:2px 8px; font-size:0.7rem;\" data-app-action=\"removeFromCart\" data-arg0=\"${item.variant_id || item.id}\">Remove</button>\n                    <button class=\"discovery-btn btn-secondary btn-sm\" style=\"padding:2px 8px; font-size:0.7rem;\" data-app-action=\"showSimilar\" data-arg0=\"${item.product_id || item.id}\">Find Similar</button>\n                </div>\n            </div>\n        `,\n      )\n      .join(\"\");\n    return `<div class=\"knowledge-card\"><h4><i class=\"fa fa-shopping-cart\"></i> Your Cart</h4>${rows}</div>`;\n  }\n\n  cartStateCard(cartItems) {\n    if (!cartItems || !cartItems.length) {\n      return `<div class=\"knowledge-card\">Your cart is empty.</div>`;\n    }\n    const itemCount = cartItems.reduce(\n      (sum, item) => sum + Number(item.quantity || item.qty || 1),\n      0,\n    );\n    const subtotal = cartItems.reduce((sum, item) => {\n      const qty = Number(item.quantity || item.qty || 1);\n      return sum + this.priceNumber(item.price) * qty;\n    }, 0);\n    const rows = cartItems\n      .map(\n        (item) => `\n            <div class=\"dai-cart-item\" style=\"display:flex; gap:12px; margin-bottom:12px; align-items:center;\">\n                ${item.image || item.imgUrl ? `<img src=\"${this.escAttr(item.image || item.imgUrl)}\" alt=\"${this.escAttr(item.title)}\" width=\"48\" height=\"48\" style=\"border-radius:4px; object-fit:cover;\" />` : \"\"}\n                <div class=\"dai-cart-item-info\" style=\"flex:1;\">\n                    <div style=\"font-size:0.9rem; font-weight:bold;\">${this.esc(item.title)}</div>\n                    ${item.size && String(item.size).toLowerCase() !== \"default title\" ? `<div style=\"font-size:0.78rem; color:#aaa;\">Size: ${this.esc(item.size)}</div>` : \"\"}\n                    <div style=\"font-size:0.8rem; color:#aaa;\">Qty: ${this.esc(item.quantity || item.qty || 1)} - ${this.formatPrice(item.price)}</div>\n                </div>\n                <div class=\"dai-cart-item-actions\" style=\"display:flex; flex-direction:column; gap:4px;\">\n                    <button class=\"discovery-btn btn-ghost btn-sm\" style=\"padding:2px 8px; font-size:0.7rem;\" data-app-action=\"removeFromCart\" data-arg0=\"${item.variant_id || item.id}\">Remove</button>\n                    <button class=\"discovery-btn btn-secondary btn-sm\" style=\"padding:2px 8px; font-size:0.7rem;\" data-app-action=\"showSimilar\" data-arg0=\"${item.product_id || item.id}\">Find Similar</button>\n                </div>\n            </div>\n        `,\n      )\n      .join(\"\");\n    return `<div class=\"knowledge-card\">\n            <h4><i class=\"fa fa-shopping-cart\"></i> Your Cart</h4>\n            <p style=\"margin:0 0 12px; color:#aaa;\">${itemCount} item${itemCount === 1 ? \"\" : \"s\"} - Subtotal ${this.formatPrice(subtotal)}</p>\n            ${rows}\n        </div>`;\n  }\n\n  productActionCard(product) {\n    if (!product) return \"\";\n    const url =\n      product.url ||\n      product.product_url ||\n      (product.handle || product.shopify_handle\n        ? `/products/${product.handle || product.shopify_handle}`\n        : \"\");\n    if (!url) return \"\";\n    let rawImg =\n      product.image_url ||\n      product.imgUrl ||\n      product.image ||\n      product.featured_image ||\n      (product.selected_variant &&\n        (product.selected_variant.featured_image ||\n          product.selected_variant.image_url)) ||\n      \"\";\n    if (typeof rawImg === \"object\" && rawImg !== null) {\n      rawImg = rawImg.src || rawImg.url || \"\";\n    }\n    if (!rawImg && this._getActiveProduct()) {\n      const active = this._getActiveProduct();\n      rawImg = active.imgUrl || active.image_url || active.image || \"\";\n    }\n    if (!rawImg && window.location.pathname.includes(\"/products/\")) {\n      rawImg = this._extractPDPImageFromDOM();\n    }\n    const img = rawImg;\n    const title = product.title || \"Selected rug\";\n    const priceMarkup = this.priceBlock(product);\n    const meta = [\n      product.material,\n      product.size,\n      product.style || product.color,\n    ]\n      .filter(Boolean)\n      .join(\" \u00B7 \");\n    const description =\n      product.description ||\n      product.summary ||\n      `${title} is ready to view, add to cart, or preview in your room.`;\n    const productId = this.escAttr(product.id || product.handle || product.shopify_handle || \"\");\n    return `<div class=\"dai-product-action-card\">\n            ${\n              img\n                ? `<a class=\"dai-product-action-image\" href=\"${this.escAttr(url)}\" aria-label=\"View ${this.escAttr(title)}\">\n                <img src=\"${this.escAttr(img)}\" alt=\"${this.escAttr(title)}\" loading=\"lazy\" onerror=\"this.closest('.dai-product-action-image').style.display='none'\">\n            </a>`\n                : \"\"\n            }\n            <div class=\"dai-product-action-body\">\n                ${meta ? `<div class=\"dai-product-action-meta\">${this.esc(meta)}</div>` : \"\"}\n                <a class=\"dai-product-action-title\" href=\"${this.escAttr(url)}\">${this.esc(title)}</a>\n                ${priceMarkup}\n                <p class=\"dai-product-action-copy\">${this.esc(description).slice(0, 150)}</p>\n                <div class=\"dai-product-action-buttons\">\n                    <button class=\"dai-product-action-link primary\" data-app-action=\"quickAddProduct\" data-arg0=\"${productId}\">Add to my cart</button>\n                </div>\n            </div>\n        </div>`;\n  }\n\n  cartCareCard(cartItems, title = \"Care instructions for your cart\") {\n    if (!cartItems || !cartItems.length)\n      return this.knowledgeCard(\n        title,\n        \"<p>Your cart is empty. Add a rug and I can give care guidance for it.</p>\",\n        \"fa-droplet\",\n      );\n    const rows = cartItems\n      .map((item) => {\n        const text = `${item.title || \"\"} ${item.material || \"\"}`.toLowerCase();\n        let care =\n          \"Vacuum regularly without a beater bar, rotate occasionally, and blot spills immediately with a clean dry cloth.\";\n        if (/polyester|polypropylene|synthetic|washable/.test(text))\n          care =\n            \"Vacuum regularly to keep it fresh, and blot any spills quickly with a dry cloth. For deeper cleans, spot clean with a mild detergent and water, or machine wash on a gentle cycle if applicable.\";\n        if (/wool/.test(text))\n          care =\n            \"Vacuum gently without a beater bar to avoid shedding. Blot spills immediately with a clean cloth, avoid soaking, and use professional cleaning for deep stains.\";\n        if (/jute|sisal|natural/.test(text))\n          care =\n            \"Vacuum regularly to remove dirt. Keep the rug dry and avoid wet cleaning, as natural fibers can stain or warp when exposed to moisture. Blot spills immediately.\";\n        return `<li><strong>${this.esc(item.title)}</strong>: ${this.esc(care)}</li>`;\n      })\n      .join(\"\");\n    return this.knowledgeCard(title, `<ul>${rows}</ul>`, \"fa-droplet\");\n  }\n\n  stainCareCard() {\n    return this.knowledgeCard(\n      \"Quick stain care\",\n      `\n            <ul>\n                <li>Blot the stain immediately with a clean, dry white cloth. Do not rub.</li>\n                <li>Keep the area as dry as possible until the rug material is confirmed.</li>\n                <li>For wool, silk, antique, pet odor, water damage, or deep stains, request professional cleaning.</li>\n            </ul>\n            <p style=\"margin-top:8px\">Upload a photo in the service form so the store can review the rug condition.</p>\n        `,\n      \"fa-droplet\",\n    );\n  }\n\n  rugPadAdviceCard(cartItems) {\n    if (!cartItems || !cartItems.length)\n      return this.knowledgeCard(\n        \"Rug pad\",\n        \"<p>Your cart is empty. Add a rug and I can recommend the right pad size.</p>\",\n        \"fa-layer-group\",\n      );\n    const rows = cartItems\n      .map((item) => {\n        const size =\n          item.size && String(item.size).toLowerCase() !== \"default title\"\n            ? ` for ${this.esc(item.size)}`\n            : \"\";\n        return `<li><strong>${this.esc(item.title)}</strong>: yes, use a rug pad${size}. It helps prevent slipping, protects the floor, and makes the rug feel cushier.</li>`;\n      })\n      .join(\"\");\n    return this.knowledgeCard(\n      \"Do you need a rug pad?\",\n      `<ul>${rows}</ul><p style=\"margin-top:8px\">For best fit, choose a pad slightly smaller than the rug so it stays hidden under the edges.</p>`,\n      \"fa-layer-group\",\n    );\n  }\n\n  rugPadFallbackCard() {\n    return this.knowledgeCard(\n      \"Rug pads\",\n      `\n            <p>Use a rug pad slightly smaller than your rug to help prevent slipping, protect the floor, and add cushion.</p>\n            <div class=\"btn-group\" style=\"margin-top:var(--space-sm)\">\n                <a class=\"discovery-btn btn-accent btn-sm\" href=\"/search?q=rug%20pad\"><i class=\"fa fa-search\"></i> Search rug pads</a>\n                <a class=\"discovery-btn btn-secondary btn-sm\" href=\"/collections/rug-pads\"><i class=\"fa fa-layer-group\"></i> Rug Pads collection</a>\n            </div>\n        `,\n      \"fa-layer-group\",\n    );\n  }\n\n  // --- Cart Item Added ---\n  cartAdded(title) {\n    return `<div class=\"confirmation-card compact\">\n            <p><i class=\"fa fa-check-circle\" style=\"color:var(--color-success)\" aria-hidden=\"true\"></i> <strong>${this.esc(title)}</strong> added to cart!</p>\n            <div class=\"btn-group\" style=\"margin-top:var(--space-sm)\">\n                <button class=\"discovery-btn btn-accent btn-sm\" data-app-action=\"sendAction\" data-arg0=\"What rug pad should I use?\">Add Rug Pad</button>\n                <button class=\"discovery-btn btn-secondary btn-sm\" data-app-action=\"toggleDrawer\">Continue Shopping</button>\n            </div>\n        </div>`;\n  }\n}\n\n// ============================================================\n// Homepage Product Card Builder\n// ============================================================\nfunction buildHomepageCard(p) {\n  const ui = new UIRenderer();\n  window.app?.registerProducts([p]);\n  const id = ui.escAttr(p.id);\n  const handle = ui.escAttr(p.handle || p.shopify_handle || p.id || \"\");\n  const title = ui.esc(p.title);\n  const price = ui.formatPrice(p.price);\n  const style = ui.esc(p.style || \"\");\n  const color = ui.esc(p.color || \"\");\n  const img = ui.escAttr(p.image_url || \"\");\n  const wishlisted = window.app?.store.isWishlisted(p.id) ? \" wishlisted\" : \"\";\n  const isRug = typeof window.isRugProduct === \"function\"\n    ? window.isRugProduct(p)\n    : !(\n        title.toLowerCase().includes(\"pad\") ||\n        (p.type && String(p.type).toLowerCase().includes(\"pad\"))\n      );\n\n  return `<div class=\"product-card\" data-app-action=\"openProduct\" data-arg0=\"${id}\">\n        <div class=\"product-card-image\">\n            <img src=\"${img}\" alt=\"${title}\" loading=\"lazy\" onerror=\"this.style.display='none'\">\n            <div class=\"product-card-overlay\" onclick=\"event.stopPropagation()\">\n                <div class=\"hover-sizes\">${p.sizes ? (Array.isArray(p.sizes) ? p.sizes.join(\", \") : p.sizes) : p.size || \"Size available\"}</div>\n                <div class=\"overlay-actions\">\n                    <button class=\"overlay-btn${wishlisted}\" aria-label=\"Save to wishlist\" data-app-action=\"toggleWishlistHP\" data-arg0=\"${id}\" data-arg1=\"${ui.escJS(p.title)}\" data-arg2=\"${ui.escJS(p.price)}\" data-arg3=\"${img}\"><i class=\"fa fa-heart\"></i></button>\n                    <button class=\"overlay-btn\" aria-label=\"Quick add to cart\" data-app-action=\"quickAddProduct\" data-arg0=\"${id}\"><i class=\"fa fa-shopping-bag\"></i></button>\n                </div>\n            </div>\n        </div>\n        <div class=\"product-card-body\">\n            <h3 class=\"product-card-title\">${title}</h3>\n            <p class=\"product-card-price\">${price}</p>\n            <div class=\"product-card-actions\" onclick=\"event.stopPropagation()\">\n                <button class=\"discovery-btn btn-primary btn-sm\" data-app-action=\"openProduct\" data-arg0=\"${id}\">View Product</button>\n                <button class=\"discovery-btn btn-secondary btn-sm\" data-app-action=\"quickAddProduct\" data-arg0=\"${id}\">Add to Cart</button>\n                ${isRug ? `<button class=\"discovery-btn btn-ghost btn-sm see-in-room-btn\" data-app-action=\"seeProductInRoom\" data-arg0=\"${id}\" data-id=\"${id}\" data-product-handle=\"${handle}\" data-rug=\"${img}\" data-size=\"${ui.escAttr(p.size || \"\")}\" data-is-chat-card=\"true\">See in my room</button>` : \"\"}\n            </div>\n            <p class=\"product-card-meta\">${[style, color].filter(Boolean).join(\" \u00B7 \")}</p>\n        </div>\n    </div>`;\n}\n\n// ============================================================\n// Main Application\n// ============================================================\n(function () {\n  try {\n    const pending = sessionStorage.getItem(\"pending_see_in_room\");\n    if (pending) {\n      sessionStorage.removeItem(\"pending_see_in_room\");\n      window.pendingSeeInRoom = JSON.parse(pending);\n    }\n  } catch (e) {}\n})();\n\nclass App {\n  constructor() {\n    this.api = new DiscoveryAPI(API_BASE);\n    this.db = new AgentDB();\n    this.store = new Store();\n    this.ui = new UIRenderer();\n\n    // State\n    this.drawerOpen = false;\n    this.cartOpen = false;\n    this.contextProduct = null;\n    if (\n      window.ShopifyContextPayload &&\n      window.ShopifyContextPayload.product &&\n      window.ShopifyContextPayload.template === \"product\"\n    ) {\n      const p = window.ShopifyContextPayload.product;\n      this.contextProduct = this._productFromShopifyPayload(p);\n    } else if (\n      window.location.pathname.includes(\"/products/\") &&\n      window.meta &&\n      window.meta.product\n    ) {\n      const p = window.meta.product;\n      this.contextProduct = {\n        id: String(p.id),\n        handle:\n          (window.location.pathname.split(\"/products/\")[1] || \"\").split(\n            /[?/#]/,\n          )[0] || \"\",\n        title:\n          p.variants?.[0]?.name?.split(\" - \")?.[0] ||\n          window.document.title.split(\" - \")[0] ||\n          \"\",\n        size: p.variants?.[0]?.public_title || \"\",\n        price: p.variants?.[0]?.price || p.price || 0,\n        imgUrl:\n          p.variants?.[0]?.featured_image?.src ||\n          p.featured_image ||\n          p.image ||\n          \"\",\n        url: window.location.pathname,\n        collection: p.vendor || \"\",\n        vendor: p.vendor || \"\",\n        brand: p.vendor || \"\",\n        material: this._materialFromProductPayload(p),\n        style: p.type || \"\",\n      };\n    }\n    this.productCatalog = new Map();\n    if (this.contextProduct) {\n      const domDetails = this._extractPDPDetailsFromDOM();\n      if (!this.contextProduct.origin && domDetails.origin) {\n        this.contextProduct.origin = this.contextProduct.country_of_origin = this.contextProduct.made_in = domDetails.origin;\n      }\n      if (!this.contextProduct.material && domDetails.material) {\n        this.contextProduct.material = domDetails.material;\n      }\n      if (!this.contextProduct.construction && domDetails.construction) {\n        this.contextProduct.construction = domDetails.construction;\n      }\n      if (window.location.pathname.includes(\"/products/\")) {\n        this.pdpProduct = { ...this.contextProduct };\n      }\n      this.productCatalog.set(this.contextProduct.id, this.contextProduct);\n    }\n    this.sending = false;\n    this._previousView = \"home\";\n    this.currentBrowseResults = [];\n    this.currentSearchResults = [];\n    this.lastShownProducts = [];\n    this.pendingCartIntent = null;\n    this.pendingVisualizerIntent = null;\n    this.pendingServiceRequest = null;\n    this.toolsOpen = false;\n    this.tools = [\n      {\n        id: \"analyze\",\n        label: \"Analyze my room\",\n        icon: '<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 10.5 12 4l9 6.5\"></path><path d=\"M5 10v9h14v-9\"></path><path d=\"M9 19v-5h6v5\"></path><path d=\"m8 7 8 10\"></path></svg>',\n      },\n      {\n        id: \"visualizer\",\n        label: \"See in my room\",\n        icon: '<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line></svg>',\n      },\n      {\n        id: \"track-order\",\n        label: \"Track My Order\",\n        icon: '<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"1\" y=\"3\" width=\"15\" height=\"13\"></rect><polygon points=\"16 8 20 8 23 11 23 16 16 16 16 8\"></polygon><circle cx=\"5.5\" cy=\"18.5\" r=\"2.5\"></circle><circle cx=\"18.5\" cy=\"18.5\" r=\"2.5\"></circle></svg>',\n      },\n      {\n        id: \"services\",\n        label: \"Services\",\n        icon: '<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.1-3.1a6 6 0 0 1-7.9 7.9l-5.6 5.6a2.1 2.1 0 0 1-3-3l5.6-5.6a6 6 0 0 1 7.9-7.9l-3.1 3.1z\"></path></svg>',\n      },\n      {\n        id: \"contact-store\",\n        label: \"Contact Store\",\n        icon: '<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15a4 4 0 0 1-4 4H8l-5 3V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z\"></path></svg>',\n      },\n    ];\n    this.pdpTools = this.tools;\n\n    // DOM refs\n    this.drawer = document.getElementById(\"assistant-drawer\");\n    this.chatArea = document.getElementById(\"chat-area\");\n    this.chatInput = document.getElementById(\"chat-input\");\n    this.sendBtn = document.getElementById(\"send-btn\");\n    this.menuBtn = document.getElementById(\"assistant-menu-btn\");\n    this.toolMenu = document.getElementById(\"assistant-tool-menu\");\n    this.fab = document.getElementById(\"assistant-fab\");\n    this.fabText = document.getElementById(\"assistant-fab-text\");\n    this.liveContext = document.getElementById(\"assistant-live-context\");\n    this.overlay = document.getElementById(\"discovery-overlay\");\n    this.cartDrawer = document.getElementById(\"assistant-cart-panel\") || document.getElementById(\"cart-drawer\");\n\n    this.historyBtn = document.getElementById(\"assistant-history-btn\");\n    this.historyArea = document.getElementById(\"history-area\");\n    this.historyList = document.getElementById(\"history-list\");\n    this.newChatBtn = document.getElementById(\"new-chat-btn\");\n    this.chatInputBar = document.querySelector(\".chat-input-bar\");\n    this.scrollIndicator = document.getElementById(\"chat-scroll-indicator\");\n\n    this._bindEvents();\n    this._renderToolMenu();\n    this._updateLiveContext();\n    this._loadClientKnowledge();\n    this._startFabPromos();\n    // Disabled: legacy homepage browse grids are not used in current themes.\n    // Prevents unnecessary Retail Search calls during agent initialization.\n    // this._loadHomepage();\n    this._updateCartUI();\n\n    // Recommendation engine, dashboard and gesture handler\n    try {\n      this.recommender = new RecommendationEngine(this.store);\n      this.dashboard = new PersonalDashboard(this.store, this.recommender);\n      this.gestures = new GestureHandler();\n\n      // Render dashboard and initialize carousels (if present)\n      try {\n        this.dashboard.renderFullDashboard();\n      } catch (e) {\n        console.warn(\"Dashboard init failed:\", e);\n      }\n      try {\n        const carouselEl = document.getElementById(\"pdp-reco-carousel\");\n        if (carouselEl) this.gestures.initCarousel(carouselEl);\n      } catch (e) {\n        console.warn(\"Gesture init failed:\", e);\n      }\n    } catch (e) {\n      console.warn(\"Optional frontend modules not available:\", e);\n    }\n\n    if (this.historyBtn) {\n      this.historyBtn.addEventListener(\"click\", () => this.toggleHistoryView());\n    }\n    if (this.newChatBtn) {\n      this.newChatBtn.addEventListener(\"click\", () => this.startNewChat());\n    }\n  }\n\n  async _restoreChatHistory() {\n    try {\n      this.db\n        .pruneOldMessages(30 * 24 * 60 * 60 * 1000)\n        .catch((e) => console.warn(\"IDB message prune failed\", e));\n      const msgs = await this.db.getMessages(this.store.sessionId);\n      if (msgs && msgs.length > 0) {\n        this.chatArea.innerHTML = \"\";\n        msgs\n          .filter((m) => !this._isStoreHandoffStatus(m?.content))\n          .forEach((m) => {\n            const div = document.createElement(\"div\");\n            div.className = `message ${m.role}`;\n            div.innerHTML = m.content;\n            this.chatArea.appendChild(div);\n          });\n        this.chatArea.scrollTop = this.chatArea.scrollHeight;\n        this._chatRestored = true;\n      } else {\n        this._chatRestored = false;\n      }\n    } catch (e) {\n      console.warn(\"Failed to restore chat history\", e);\n      this._chatRestored = false;\n    }\n  }\n\n  async toggleHistoryView() {\n    const isHidden = this.historyArea.hasAttribute(\"hidden\");\n    if (isHidden) {\n      this.chatArea.setAttribute(\"hidden\", \"\");\n      if (this.chatInputBar) this.chatInputBar.setAttribute(\"hidden\", \"\");\n      this.historyArea.style.display = \"flex\";\n      this.historyArea.removeAttribute(\"hidden\");\n      const recoRail = document.getElementById(\"picked-for-you-rail\");\n      if (recoRail) recoRail.setAttribute(\"hidden\", \"\");\n\n      this.historyList.innerHTML =\n        '<div style=\"text-align:center; padding: 20px;\"><i class=\"fa fa-spinner fa-spin\"></i> Loading...</div>';\n\n      try {\n        const sessions = await this.db.getSessionSummaries();\n        if (sessions.length === 0) {\n          this.historyList.innerHTML =\n            '<div style=\"text-align:center; padding: 20px; color: #666;\">No previous chat history found.</div>';\n          return;\n        }\n\n        let html =\n          '<div style=\"display: flex; flex-direction: column; gap: 8px;\">';\n        sessions.forEach((s) => {\n          const date = new Date(s.lastTime).toLocaleString(undefined, {\n            month: \"short\",\n            day: \"numeric\",\n            hour: \"2-digit\",\n            minute: \"2-digit\",\n          });\n          const isActive = s.id === this.store.sessionId;\n          html += `\n                        <div class=\"history-item\" style=\"padding: 12px; border: 1px solid ${isActive ? \"var(--color-primary)\" : \"#eee\"}; border-radius: 8px; cursor: pointer; background: ${isActive ? \"rgba(var(--color-primary-rgb), 0.05)\" : \"#fff\"}; transition: all 0.2s;\" data-session-id=\"${this.ui.escAttr(s.id)}\">\n                            <div style=\"font-weight: 600; font-size: 14px; margin-bottom: 4px;\">${this.ui.esc(s.title)}</div>\n                            <div style=\"font-size: 12px; color: #666; display: flex; justify-content: space-between;\">\n                                <span>${date}</span>\n                                <span>${s.count} msgs</span>\n                            </div>\n                        </div>\n                    `;\n        });\n        html += \"</div>\";\n\n        this.historyList.innerHTML = html;\n\n        this.historyList.querySelectorAll(\".history-item\").forEach((item) => {\n          item.addEventListener(\"click\", () =>\n            this.loadSession(item.getAttribute(\"data-session-id\")),\n          );\n        });\n      } catch (e) {\n        console.error(\"Failed to load history\", e);\n        this.historyList.innerHTML =\n          '<div style=\"text-align:center; padding: 20px; color: red;\">Failed to load history.</div>';\n      }\n    } else {\n      this.historyArea.style.display = \"none\";\n      this.historyArea.setAttribute(\"hidden\", \"\");\n      this.chatArea.removeAttribute(\"hidden\");\n      if (this.chatInputBar) this.chatInputBar.removeAttribute(\"hidden\");\n      this.chatArea.scrollTop = this.chatArea.scrollHeight;\n    }\n  }\n\n  async loadSession(sessionId) {\n    if (sessionId !== this.store.sessionId) {\n      this.store.sessionId = sessionId;\n      sessionStorage.setItem(\"rug_session_id\", sessionId);\n      this.chatArea.innerHTML = \"\";\n      await this._restoreChatHistory();\n    }\n    this.toggleHistoryView();\n  }\n\n  async startNewChat() {\n    const id = crypto.randomUUID\n      ? crypto.randomUUID()\n      : \"sess_\" + Math.random().toString(36).slice(2) + Date.now();\n    this.store.sessionId = id;\n    sessionStorage.setItem(\"rug_session_id\", id);\n    sessionStorage.setItem(\"rug_session_started_at\", String(Date.now()));\n    this.store.data.conversation_state = {\n      intent: \"browse\",\n      stage: \"discovery\",\n      active_category: null,\n    };\n    this.store.save();\n\n    this.chatArea.innerHTML = \"\";\n    this.toggleHistoryView();\n\n    const welcomeHtml = `\n            <div class=\"welcome-card\" style=\"margin-bottom: var(--space-md);\">\n                <h3>Welcome to ${window.ShopifyContextPayload?.shop?.name || \"our store\"} AI! \u2728</h3>\n                <p>I'm your personal shopping assistant. I can help you find products, answer questions, or give recommendations based on your preferences.</p>\n                <div class=\"suggestion-chips\" style=\"margin-top: var(--space-sm);\">\n                    <button class=\"discovery-btn btn-outline btn-sm\" data-app-action=\"sendAction\" data-arg0=\"Show me trending items\">Show me trending items</button>\n                    <button class=\"discovery-btn btn-outline btn-sm\" data-app-action=\"sendAction\" data-arg0=\"Help me find a gift\">Help me find a gift</button>\n                </div>\n            </div>\n        `;\n    this._addMsg(welcomeHtml, \"assistant\", true);\n  }\n\n  _startFabPromos() {\n    this._initFabTimer();\n  }\n\n  _initFabTimer() {\n    if (!this.fab) return;\n    const SEVEN_SECONDS_MS = 7 * 1000;\n    setTimeout(() => {\n      this._dockFabRight();\n    }, SEVEN_SECONDS_MS);\n  }\n\n  _dockFabRight() {\n    if (!this.fab) return;\n    this.fab.classList.add(\"fab-docked-right\");\n  }\n\n  _materialFromProductPayload(product = {}) {\n    const direct =\n      product.material || product.metafields?.custom?.material || \"\";\n    if (\n      direct &&\n      !/collection:|construction:|shape normalized:/i.test(String(direct))\n    )\n      return String(direct);\n\n    const tags = Array.isArray(product.tags) ? product.tags : [];\n    const known = [\n      \"polyester\",\n      \"wool\",\n      \"cotton\",\n      \"jute\",\n      \"viscose\",\n      \"silk\",\n      \"polypropylene\",\n      \"nylon\",\n      \"acrylic\",\n      \"seagrass\",\n      \"sisal\",\n    ];\n    const materialTag = tags.find((tag) =>\n      known.includes(String(tag).trim().toLowerCase()),\n    );\n    if (materialTag) return materialTag;\n\n    const haystack = [\n      product.description,\n      product.product_description,\n      tags.join(\"; \"),\n    ]\n      .filter(Boolean)\n      .join(\"; \");\n    const match = haystack.match(/\\bmaterial\\s*:\\s*([^,;.]+)/i);\n    return match ? match[1].trim() : \"\";\n  }\n\n  _getActiveProduct() {\n    if (window.location.pathname.includes(\"/products/\") && this.pdpProduct) {\n      return this.pdpProduct;\n    }\n    return (\n      this.pdpProduct ||\n      this.contextProduct ||\n      (this.store && typeof this.store.getLastViewed === \"function\"\n        ? this.store.getLastViewed()\n        : null) ||\n      null\n    );\n  }\n\n  _extractPDPImageFromDOM() {\n    try {\n      const vizBtn = document.querySelector(\n        \"#pdp-see-in-room, .pdp-view-in-room .see-in-room-btn, [data-rug]\",\n      );\n      if (vizBtn) {\n        const rug = vizBtn.getAttribute(\"data-rug\") || vizBtn.dataset.rug;\n        if (rug) return rug;\n      }\n      const imgEl = document.querySelector(\n        \".product__media img, .product-single__photo img, .product-gallery img, .featured-media img, img[src*='/products/']\",\n      );\n      if (imgEl) {\n        const src = imgEl.src || imgEl.dataset.src || imgEl.srcset?.split(\" \")[0];\n        if (src) return src;\n      }\n    } catch (e) {\n      console.warn(\"DOM image extract error:\", e);\n    }\n    return \"\";\n  }\n\n  _extractPDPDetailsFromDOM() {\n    const details = {\n      origin: \"\",\n      country_of_origin: \"\",\n      made_in: \"\",\n      material: \"\",\n      construction: \"\",\n    };\n    try {\n      const textNodes = Array.from(\n        document.querySelectorAll(\n          \".product-single__description, .product__description, .product-specifications, .product-details, .tech-specs, [data-product-details]\",\n        ),\n      );\n      if (document.body) textNodes.push(document.body);\n      for (const node of textNodes) {\n        const text = node.innerText || node.textContent || \"\";\n        if (!details.origin) {\n          const originMatch = text.match(\n            /(?:origin|country of origin|made in|manufactured in)\\s*:\\s*([A-Za-z\\s]+)/i,\n          );\n          if (originMatch)\n            details.origin =\n              details.country_of_origin =\n              details.made_in =\n                originMatch[1].trim();\n        }\n        if (!details.material) {\n          const matMatch = text.match(\n            /(?:material|composition|content|fiber)\\s*:\\s*([A-Za-z0-9\\s,\\/]+)/i,\n          );\n          if (matMatch) details.material = matMatch[1].trim();\n        }\n        if (!details.construction) {\n          const constMatch = text.match(\n            /(?:construction|technique|weaving|make)\\s*:\\s*([A-Za-z0-9\\s,\\/]+)/i,\n          );\n          if (constMatch) details.construction = constMatch[1].trim();\n        }\n      }\n    } catch (e) {\n      console.warn(\"Error extracting PDP details from DOM\", e);\n    }\n    return details;\n  }\n\n  _productFromShopifyPayload(p = {}) {\n    const selectedVariant =\n      this._selectedVariantForPayload(p) || p.variant || {};\n    const domDetails = this._extractPDPDetailsFromDOM();\n    const product = {\n      id: String(p.id),\n      handle: p.handle,\n      title: p.title || p.name || \"\",\n      imgUrl:\n        selectedVariant.featured_image ||\n        selectedVariant.image_url ||\n        p.image_url ||\n        p.featured_image ||\n        p.image ||\n        \"\",\n      collection: p.collection || \"\",\n      vendor: p.vendor || \"\",\n      brand: p.brand || p.vendor || \"\",\n      origin: p.origin || p.country_of_origin || p.made_in || domDetails.origin || \"\",\n      country_of_origin: p.country_of_origin || p.origin || p.made_in || domDetails.country_of_origin || \"\",\n      made_in: p.made_in || p.origin || p.country_of_origin || domDetails.made_in || \"\",\n      construction: p.construction || domDetails.construction || \"\",\n      manufacturer: p.manufacturer || \"\",\n      url: p.url || window.location.pathname,\n      variants: p.variants || [],\n      options: p.options || [],\n      material: p.material || this._materialFromProductPayload(p) || domDetails.material || \"\",\n      style: p.type || \"\",\n      selected_variant: selectedVariant,\n    };\n    return this._applyVariantToProduct(product, selectedVariant, false);\n  }\n\n  _selectedVariantForPayload(product = {}) {\n    const variants = Array.isArray(product.variants) ? product.variants : [];\n    const selectedId =\n      this._selectedVariantIdFromPage() ||\n      product.variant?.id ||\n      product.selected_variant?.id;\n    if (selectedId) {\n      const match = variants.find(\n        (variant) => String(variant.id) === String(selectedId),\n      );\n      if (match) return match;\n    }\n    return (\n      product.variant ||\n      product.selected_variant ||\n      variants.find((variant) => variant.available) ||\n      variants[0] ||\n      null\n    );\n  }\n\n  _selectedVariantIdFromPage() {\n    const selectors = [\n      'form[action*=\"/cart/add\"] input[name=\"id\"]',\n      'form[action*=\"/cart/add\"] select[name=\"id\"]',\n      'input[name=\"id\"]',\n      'select[name=\"id\"]',\n    ];\n    for (const selector of selectors) {\n      const el = document.querySelector(selector);\n      if (el?.value) return el.value;\n    }\n    try {\n      return (\n        new URLSearchParams(window.location.search || \"\").get(\"variant\") || \"\"\n      );\n    } catch (_) {\n      return \"\";\n    }\n  }\n\n  _variantOption(product = {}, variant = {}, optionName = \"\") {\n    const wanted = String(optionName || \"\").toLowerCase();\n    const options = Array.isArray(product.options) ? product.options : [];\n    const index = options.findIndex(\n      (option) => String(option.name || option).toLowerCase() === wanted,\n    );\n    if (index >= 0) return variant[`option${index + 1}`] || \"\";\n    if (wanted === \"size\")\n      return variant.title &&\n        String(variant.title).toLowerCase() !== \"default title\"\n        ? variant.title\n        : \"\";\n    return \"\";\n  }\n\n  _applyVariantToProduct(product = {}, variant = {}, explicitSize = false) {\n    if (!product) return product;\n    const next = { ...product };\n    const selected = variant || {};\n    next.selected_variant = selected;\n    next.variant_id = selected.id || next.variant_id;\n    next.size =\n      this._variantOption(next, selected, \"Size\") ||\n      selected.title ||\n      next.size ||\n      \"\";\n    next.shape =\n      this._variantOption(next, selected, \"Shape\") || next.shape || \"\";\n    next.color =\n      this._variantOption(next, selected, \"Color\") || next.color || \"\";\n    if (selected.price !== undefined && selected.price !== null)\n      next.price = selected.price;\n    else if (next.price === undefined || next.price === null) next.price = 0;\n    next.compare_at_price =\n      selected.compare_at_price ||\n      next.compare_at_price ||\n      next.original_price ||\n      next.regular_price;\n    next.original_price = next.original_price || next.compare_at_price;\n    if (selected.available !== undefined) next.available = selected.available;\n    if (selected.inventory_quantity !== undefined)\n      next.inventory_quantity = selected.inventory_quantity;\n    if (selected.featured_image || selected.image_url) {\n      const fi = selected.featured_image;\n      next.imgUrl = (fi && typeof fi === 'object' && fi.src) ? fi.src : (fi || selected.image_url);\n    }\n    if (explicitSize) {\n      next.sizeSelected = true;\n      next.selectedSizeExplicit = true;\n    }\n    return next;\n  }\n\n  _syncSelectedVariantContext(explicitSize = true) {\n    if (!this.contextProduct?.variants?.length) return;\n    const variantId = this._selectedVariantIdFromPage();\n    if (!variantId) return;\n    const variant = this.contextProduct.variants.find(\n      (item) => String(item.id) === String(variantId),\n    );\n    if (!variant) return;\n    this.contextProduct = this._applyVariantToProduct(\n      this.contextProduct,\n      variant,\n      explicitSize,\n    );\n    if (this.contextProduct.id)\n      this.productCatalog.set(\n        String(this.contextProduct.id),\n        this.contextProduct,\n      );\n    if (window.ShopifyContextPayload?.product) {\n      window.ShopifyContextPayload.product.variant = variant;\n      window.ShopifyContextPayload.product.price = variant.price;\n    }\n    this._updateLiveContext();\n    this._syncContext();\n  }\n\n  _updateLiveContext() {\n    if (!this.liveContext) return;\n    const product = this.contextProduct;\n    if (product && product.title) {\n      let metaParts = [];\n      if (product.shape) metaParts.push(product.shape.toLowerCase());\n      if (product.size) metaParts.push(product.size);\n      if (product.color) metaParts.push(product.color);\n\n      let metaText = metaParts.join(\" / \");\n\n      const isWashable =\n        product.tags &&\n        product.tags.some(\n          (t) => typeof t === \"string\" && t.toLowerCase().includes(\"washable\"),\n        );\n      if (isWashable) {\n        metaText = metaText ? metaText + \" | Washable\" : \"Washable\";\n      }\n\n      this.liveContext.hidden = false;\n      this.liveContext.innerHTML = `\n                <span class=\"live-dot\" aria-hidden=\"true\"></span>\n                <span class=\"live-label\">Viewing</span>\n                <strong>${this.ui.esc(product.title)}</strong>\n                ${metaText ? `<small>${this.ui.esc(metaText)}</small>` : \"\"}\n            `;\n      return;\n    }\n    this.liveContext.hidden = true;\n  }\n\n  registerProducts(products = []) {\n    this.lastShownProductIds = products.map((p) => String(p.id));\n    this.lastShownProducts = products.slice(0, 12);\n    products.forEach((product) => {\n      if (product?.id) this.productCatalog.set(String(product.id), product);\n    });\n  }\n\n  _visibleResultProducts() {\n    const seen = new Set();\n    const products = [];\n    const cards = Array.from(\n      this.chatArea?.querySelectorAll(\"[data-product-id]\") || [],\n    );\n    cards.forEach((card) => {\n      const id = String(card.getAttribute(\"data-product-id\") || \"\");\n      if (!id || seen.has(id)) return;\n      const product = this.productCatalog.get(id);\n      if (product) {\n        seen.add(id);\n        products.push(product);\n      }\n    });\n    return products.length ? products : this.lastShownProducts || [];\n  }\n\n  _recentProductHistory() {\n    const seen = new Set();\n    const sources = [\n      ...(this.store.data.viewed || []),\n      ...(this.contextProduct ? [this.contextProduct] : []),\n      ...(this._visibleResultProducts() || []),\n      ...(this.lastShownProducts || []),\n      ...Array.from(this.productCatalog.values()),\n    ];\n    return sources\n      .filter((product) => {\n        const key = String(\n          product?.id || product?.handle || product?.title || \"\",\n        );\n        if (!key || seen.has(key)) return false;\n        seen.add(key);\n        return product?.title;\n      })\n      .slice(0, 12);\n  }\n\n  _compactProductForMemory(product = {}) {\n    return {\n      id: product.id,\n      title: product.title,\n      handle: product.handle || product.shopify_handle,\n      url: product.url || product.product_url,\n      price: product.price,\n      compare_at_price:\n        product.compare_at_price ||\n        product.original_price ||\n        product.regular_price ||\n        product.msrp ||\n        product.was_price,\n      original_price:\n        product.original_price ||\n        product.compare_at_price ||\n        product.regular_price ||\n        product.msrp ||\n        product.was_price,\n      size: product.size,\n      color: product.color,\n      style: product.style,\n      material: product.material,\n      vendor: product.vendor,\n      brand: product.brand,\n      origin: product.origin || product.country_of_origin || product.made_in,\n      country_of_origin:\n        product.country_of_origin || product.origin || product.made_in,\n      made_in: product.made_in || product.origin || product.country_of_origin,\n      manufacturer: product.manufacturer,\n      image_url: product.image_url || product.imgUrl || product.image,\n      selected_variant: product.selected_variant,\n      variant_id: product.variant_id,\n      variants: (product.variants || []).slice(0, 30).map((variant) => ({\n        id: variant.id,\n        title: variant.title,\n        available: variant.available,\n        price: variant.price,\n        compare_at_price: variant.compare_at_price,\n        option1: variant.option1,\n        option2: variant.option2,\n        option3: variant.option3,\n      })),\n      options: product.options,\n    };\n  }\n\n  _detectShopifyContext() {\n    const shopifyCtx = {\n      is_shopify: !!window.Shopify,\n      path: window.location.pathname,\n      url: window.location.href,\n    };\n\n    // Deeply merge ShopifyContextPayload if available\n    if (window.ShopifyContextPayload) {\n      // Create a shallow copy of the payload to avoid mutating the global object\n      const payloadCopy = { ...window.ShopifyContextPayload };\n\n      // Strip large product lists to prevent massive API payloads (context issues)\n      if (payloadCopy.collection) {\n        payloadCopy.collection = { ...payloadCopy.collection };\n        delete payloadCopy.collection.products;\n      }\n      if (payloadCopy.search) {\n        payloadCopy.search = { ...payloadCopy.search };\n        delete payloadCopy.search.results;\n      }\n\n      Object.assign(shopifyCtx, payloadCopy);\n    }\n\n    // Extract Shopify meta product if on a PDP and not provided by Payload\n    if (!shopifyCtx.product && window.meta && window.meta.product) {\n      shopifyCtx.product = window.meta.product;\n    }\n\n    // Extract from Shopify Analytics\n    if (\n      window.Shopify &&\n      window.Shopify.analytics &&\n      window.Shopify.analytics.meta\n    ) {\n      const page = window.Shopify.analytics.meta.page;\n      if (page) {\n        shopifyCtx.page_type = shopifyCtx.page_type || page.pageType;\n        if (page.resourceId) shopifyCtx.resource_id = page.resourceId;\n      }\n    }\n\n    return shopifyCtx;\n  }\n\n  async _pageContext() {\n    const product = this._getActiveProduct();\n    const shopifyContext = this._detectShopifyContext();\n\n    // Scrape PDP recommendations if on PDP\n    let pdpRecommendations = [];\n    if (window.location.pathname.includes(\"/products/\")) {\n      try {\n        const recContainer = document.querySelector(\".product-recommendations, .related-products, #shopify-section-product-recommendations, .similar-products, [id*='product-recommendations']\");\n        if (recContainer) {\n          const productAnchors = recContainer.querySelectorAll(\"a[href*='/products/']\");\n          const seenHandles = new Set();\n          productAnchors.forEach(anchor => {\n            const card = anchor.closest('.card-wrapper, .product-card-wrapper, .grid__item') || anchor.parentElement;\n            const url = anchor.getAttribute(\"href\");\n            const handleMatch = url.match(/\\/products\\/([^?/#]+)/);\n            if (!handleMatch) return;\n            const handle = handleMatch[1];\n            \n            if (seenHandles.has(handle) || (product && (product.handle === handle || product.id === handle))) return;\n            seenHandles.add(handle);\n            \n            const titleEl = card.querySelector(\".card__heading, .card-information__text, .product-title, .h3, .h4, .title\");\n            const title = titleEl ? titleEl.textContent.trim() : handle.replace(/-/g, \" \");\n            \n            const priceEl = card.querySelector(\".price-item--sale, .price-item--regular, .price, .money\");\n            const priceText = priceEl ? priceEl.textContent.replace(/[^\\d.]/g, \"\") : \"0\";\n            const price = parseFloat(priceText) || 0;\n            \n            const imgEl = card.querySelector(\"img\");\n            const image_url = imgEl ? (imgEl.src || imgEl.dataset.src || \"\") : \"\";\n            \n            pdpRecommendations.push({\n              handle,\n              title,\n              price,\n              image_url: image_url,\n              url: url\n            });\n          });\n          \n          if (pdpRecommendations.length > 0) {\n            pdpRecommendations = await Promise.all(pdpRecommendations.map(async (rec) => {\n              try {\n                const res = await fetch(`/products/${rec.handle}.js`);\n                if (res.ok) {\n                  const shopifyProduct = await res.json();\n                  rec.variants = shopifyProduct.variants || [];\n                  let matchedVariant = null;\n                  if (Array.isArray(shopifyProduct.variants)) {\n                    const targetId = String(rec.selected_variant?.id || rec.variant_id || \"\");\n                    const targetSize = String(rec.size || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                    matchedVariant = shopifyProduct.variants.find((v) => {\n                      if (targetId && String(v.id) === targetId) return true;\n                      if (targetSize) {\n                        const vTitle = String(v.title || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                        const vOpt1 = String(v.option1 || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                        const vOpt2 = String(v.option2 || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                        if (vTitle === targetSize || vOpt1 === targetSize || vOpt2 === targetSize) return true;\n                      }\n                      return false;\n                    });\n                  }\n                  if (matchedVariant) {\n                    if (matchedVariant.price) rec.price = matchedVariant.price / 100;\n                    if (matchedVariant.compare_at_price) {\n                      rec.compare_at_price = matchedVariant.compare_at_price / 100;\n                      rec.was_price = rec.compare_at_price;\n                    }\n                    rec.selected_variant = matchedVariant;\n                    rec.variant_id = matchedVariant.id;\n                  } else {\n                    if (!rec.price && shopifyProduct.price) {\n                      rec.price = shopifyProduct.price / 100;\n                    }\n                    if (!rec.compare_at_price) {\n                      const compareAt = shopifyProduct.compare_at_price || (shopifyProduct.variants?.[0]?.compare_at_price);\n                      if (compareAt) {\n                        rec.compare_at_price = compareAt / 100;\n                        rec.was_price = compareAt / 100;\n                      }\n                    }\n                  }\n                }\n              } catch (e) {\n                console.warn(\"Failed to enrich pdp recommendation\", rec.handle, e);\n              }\n              return rec;\n            }));\n          }\n        }\n      } catch (e) {\n        console.warn(\"Error scraping PDP recommendations\", e);\n      }\n    }\n\n    return {\n      page_type: window.location.pathname.includes(\"/products/\")\n        ? \"pdp\"\n        : shopifyContext.page_type || \"homepage\",\n      pdp_recommendations: pdpRecommendations,\n      shopify_context: shopifyContext,\n      comparison_room: this.store.data.facts.comparison_room,\n      comparison_room_rugs: this.store.data.facts.comparison_room_rugs,\n      current_product: product\n        ? {\n            id: product.id,\n            handle:\n              product.handle ||\n              product.shopify_handle ||\n              (window.location.pathname.split(\"/products/\")[1] || \"\").split(\n                /[?/#]/,\n              )[0] ||\n              \"\",\n            title: product.title,\n            price: product.price,\n            compare_at_price: product.compare_at_price,\n            material: product.material,\n            vendor: product.vendor,\n            brand: product.brand,\n            origin:\n              product.origin || product.country_of_origin || product.made_in,\n            country_of_origin:\n              product.country_of_origin || product.origin || product.made_in,\n            made_in:\n              product.made_in || product.origin || product.country_of_origin,\n            manufacturer: product.manufacturer,\n            collection: product.collection,\n            style: product.style,\n            color: product.color,\n            size: product.size,\n            shape: product.shape,\n            thickness:\n              product.thickness ||\n              (product.metafields\n                ? product.metafields.thickness || product.metafields.pile_height\n                : null),\n            tags: product.tags,\n            metafields: product.metafields,\n            url:\n              product.url ||\n              product.product_url ||\n              (product.handle\n                ? `/products/${product.handle}`\n                : window.location.pathname),\n            available: product.available,\n            inventory_quantity: product.inventory_quantity,\n            selected_variant: product.selected_variant,\n            variant_id: product.variant_id,\n            variants: (product.variants || []).slice(0, 30).map((variant) => ({\n              id: variant.id,\n              title: variant.title,\n              available: variant.available,\n              price: variant.price,\n              compare_at_price: variant.compare_at_price,\n              option1: variant.option1,\n              option2: variant.option2,\n              option3: variant.option3,\n            })),\n            options: product.options,\n            discount_pct:\n              product.compare_at_price &&\n              product.compare_at_price > product.price\n                ? Math.round(\n                    ((product.compare_at_price - product.price) /\n                      product.compare_at_price) *\n                      100,\n                  )\n                : null,\n          }\n        : null,\n      last_shown_products: this._visibleResultProducts(),\n      last_shown_product_ids: this.lastShownProductIds || [],\n      recent_products: this.store.data.viewed.slice(0, 8),\n      cart_count: this.store.data.cart.reduce(\n        (sum, item) => sum + (item.qty || 1),\n        0,\n      ),\n      wishlist_count: this.store.data.wishlist.length,\n\n      // Canonical Behavior Context\n      preferred_categories: this.store.data.preferred_categories,\n      preferred_attributes: this.store.data.preferred_attributes,\n      interaction_flags: this.store.data.interaction_flags,\n      conversation_state: this.store.data.conversation_state,\n    };\n  }\n\n  _syncContext() {\n    this.store.save();\n  }\n\n  async _assistantMemoryWithMessages() {\n    let messages = [];\n    try {\n      messages = await this.db.getMessages(this.store.sessionId);\n    } catch (e) {\n      console.warn(\"Failed to load recent chat memory\", e);\n    }\n    const query = messages[messages.length - 1]?.content || \"\";\n    const visibleProducts = this._visibleResultProducts()\n      .map((product) => this._compactProductForMemory(product))\n      .filter((product) => product.id || product.title);\n    return {\n      ...this.store.assistantMemory(messages),\n      visible_product_graph: visibleProducts,\n      product_graph: visibleProducts,\n      client_rag: this._clientRagSnippets(query, messages),\n    };\n  }\n\n  async _refreshCartMemory() {\n    try {\n      await this.store.init();\n    } catch (e) {\n      console.warn(\"Cart refresh failed\", e);\n    }\n    this._updateCartUI();\n    if (this.cartOpen) this._renderCart();\n    return this.store.data.cart || [];\n  }\n\n  async _loadClientKnowledge() {\n    const cacheKey = `rug_client_knowledge:${this.api.tenant}`;\n    try {\n      const cached = localStorage.getItem(cacheKey);\n      if (cached) this.clientKnowledge = JSON.parse(cached);\n    } catch (e) {\n      this.clientKnowledge = null;\n    }\n    try {\n      const data = await this.api.tenantKnowledge();\n      this.clientKnowledge = data || {};\n      localStorage.setItem(cacheKey, JSON.stringify(this.clientKnowledge));\n    } catch (e) {\n      console.warn(\n        \"Client knowledge load failed; using cached knowledge if available\",\n        e,\n      );\n    }\n  }\n\n  _flattenKnowledge(value, path = []) {\n    if (!value) return [];\n    if (typeof value === \"string\")\n      return [{ title: path.join(\" / \") || \"Knowledge\", text: value }];\n    if (Array.isArray(value)) {\n      return value.flatMap((item, index) =>\n        this._flattenKnowledge(item, [...path, String(index + 1)]),\n      );\n    }\n    if (typeof value === \"object\") {\n      return Object.entries(value).flatMap(([key, val]) =>\n        this._flattenKnowledge(val, [...path, key]),\n      );\n    }\n    return [{ title: path.join(\" / \") || \"Knowledge\", text: String(value) }];\n  }\n\n  _clientRagSnippets(query = \"\", messages = []) {\n    const docs = this._flattenKnowledge(this.clientKnowledge || {});\n    if (!docs.length) return [];\n    const recentText = messages\n      .slice(-6)\n      .map((m) => m.content || \"\")\n      .join(\" \");\n    const tokens = new Set(\n      String(`${query} ${recentText}`)\n        .toLowerCase()\n        .match(/[a-z0-9]{3,}/g) || [],\n    );\n    if (!tokens.size) return docs.slice(0, 4);\n\n    return docs\n      .map((doc) => {\n        const haystack = `${doc.title} ${doc.text}`.toLowerCase();\n        let score = 0;\n        tokens.forEach((token) => {\n          if (haystack.includes(token)) score += 1;\n        });\n        return { ...doc, score };\n      })\n      .filter((doc) => doc.score > 0)\n      .sort((a, b) => b.score - a.score)\n      .slice(0, 6)\n      .map(({ title, text }) => ({ title, text: String(text).slice(0, 700) }));\n  }\n\n  _renderToolMenu() {\n    if (!this.toolMenu) return;\n    const currentTools = this.contextProduct ? this.pdpTools : this.tools;\n    this.toolMenu.innerHTML = this.ui.toolMenu(currentTools);\n  }\n\n  toggleToolMenu(force) {\n    this.toolsOpen = typeof force === \"boolean\" ? force : !this.toolsOpen;\n    this.toolMenu.hidden = !this.toolsOpen;\n    this.menuBtn.setAttribute(\"aria-expanded\", String(this.toolsOpen));\n  }\n\n  _ensureDrawer() {\n    if (!this.drawerOpen) this.toggleDrawer();\n  }\n\n  _currentProductOrRecent() {\n    return this.contextProduct || this.store.getLastViewed();\n  }\n\n  _lastAssistantText() {\n    const messages = Array.from(\n      this.chatArea?.querySelectorAll(\".message.assistant\") || [],\n    );\n    const last = messages[messages.length - 1];\n    return (last?.textContent || \"\").replace(/\\s+/g, \" \").trim();\n  }\n\n  _resolveProductReference(text = \"\") {\n    const query = String(text).toLowerCase();\n    const products = this._visibleResultProducts();\n    const ordinals = {\n      first: 0,\n      \"1st\": 0,\n      one: 0,\n      second: 1,\n      \"2nd\": 1,\n      two: 1,\n      third: 2,\n      \"3rd\": 2,\n      three: 2,\n      fourth: 3,\n      \"4th\": 3,\n      four: 3,\n      fifth: 4,\n      \"5th\": 4,\n      five: 4,\n      sixth: 5,\n      \"6th\": 5,\n      six: 5,\n    };\n    for (const [word, index] of Object.entries(ordinals)) {\n      if (new RegExp(`\\\\b${word}\\\\b`).test(query) && products[index])\n        return products[index];\n    }\n    const match = query.match(\n      /\\b(?:rug|item|product)\\s*(\\d{1,2})\\b|\\b(\\d{1,2})(?:st|nd|rd|th)?\\s+(?:rug|item|product)\\b/,\n    );\n    if (match) {\n      const index = Number(match[1] || match[2]) - 1;\n      if (products[index]) return products[index];\n    }\n    return null;\n  }\n\n  _rewriteContextualFollowup(query = \"\") {\n    const normalized = String(query).trim().toLowerCase();\n    if (\n      !/^(yes|yeah|yep|sure|ok|okay|tell me more|more|know more)$/.test(\n        normalized,\n      )\n    )\n      return query;\n    const lastAssistant = this._lastAssistantText().toLowerCase();\n    const product = this.contextProduct || this.store.getLastViewed();\n    if (!product) return query;\n    if (\n      lastAssistant.includes(\"would you like to know more\") ||\n      lastAssistant.includes(\"want to know more\") ||\n      lastAssistant.includes(\"ready to\")\n    ) {\n      return `Tell me more about ${product.title}. Include material, size, care, and why it is a good choice.`;\n    }\n    return query;\n  }\n\n  _isProductInfoQuery(text = \"\") {\n    return /\\b(what about|tell me about|tell me more|more about|know more|details?)\\b/i.test(\n      text,\n    );\n  }\n\n  _isProductSizeQuery(text = \"\") {\n    return (\n      /\\b(size|sizes)\\b/i.test(text) &&\n      /\\b(this|current|same|rug|product|available|availability|other|another)\\b/i.test(\n        text,\n      )\n    );\n  }\n\n  _isProductPriceQuery(text = \"\") {\n    if (/\\b(cleaning|clean|stain|repair|restoration|appraisal|sizing|service|consultation)\\b/i.test(text)) return false;\n    return (\n      /\\b(price|cost|how much)\\b/i.test(text) &&\n      /\\b(this|current|same|rug|product)\\b/i.test(text)\n    );\n  }\n\n  _availableVariantRows(product = {}) {\n    const variants = Array.isArray(product.variants) ? product.variants : [];\n    const rows = variants\n      .map((variant) => ({\n        id: variant.id,\n        size:\n          this._variantOption(product, variant, \"Size\") || variant.title || \"\",\n        shape: this._variantOption(product, variant, \"Shape\") || \"\",\n        color: this._variantOption(product, variant, \"Color\") || \"\",\n        price: variant.price,\n        compare_at_price: variant.compare_at_price,\n        available: variant.available,\n      }))\n      .filter(\n        (row) => row.size && String(row.size).toLowerCase() !== \"default title\",\n      );\n    const seen = new Set();\n    return rows.filter((row) => {\n      const key = `${row.size}|${row.shape}|${row.color}`;\n      if (seen.has(key)) return false;\n      seen.add(key);\n      return true;\n    });\n  }\n\n  _productSizeText(product = {}) {\n    const rows = this._availableVariantRows(product);\n    if (!rows.length) {\n      return `I don't see other size options listed for ${this.ui.esc(product.title || \"this rug\")}.`;\n    }\n    const selectedId = String(\n      product.variant_id || product.selected_variant?.id || \"\",\n    );\n    const selected =\n      rows.find((row) => selectedId && String(row.id) === selectedId) ||\n      rows.find((row) => row.size === product.size) ||\n      null;\n    const available = rows.filter((row) => row.available !== false);\n    \n    available.sort((a, b) => parseFloat(a.price || 0) - parseFloat(b.price || 0));\n\n    const chips = available.slice(0, 12).map((row) => {\n        const isSelected = selected && row.id === selected.id;\n        const sizeStr = `${row.size}${row.shape ? ` ${row.shape}` : \"\"}`;\n        const priceStr = row.price ? `${this.ui.formatPrice(row.price)}` : \"\";\n        \n        return `<div class=\"size-buy-chip ${isSelected ? 'selected' : ''}\" style=\"display:flex; justify-content:space-between; align-items:center; border: 1px solid var(--color-border); border-radius: 8px; padding: 12px; margin-bottom: 8px; background: var(--color-surface); box-shadow: 0 1px 3px rgba(0,0,0,0.05);\">\n            <div style=\"display:flex; flex-direction:column; gap:4px; flex: 1;\">\n                <span style=\"font-weight:600; font-size:0.95rem; line-height: 1.2;\">${this.ui.esc(sizeStr)}</span>\n                <span style=\"font-size:0.85rem; color:var(--color-text-secondary);\">${priceStr}</span>\n            </div>\n            <button class=\"discovery-btn btn-primary btn-sm\" style=\"margin:0; padding:6px 16px; font-weight: 600;\" data-app-action=\"quickAddVariant\" data-arg0=\"${row.id}\">Add to Cart</button>\n        </div>`;\n    }).join('');\n\n    return `\n        <div class=\"product-sizes-container\">\n            <p style=\"margin-bottom: 12px; font-size: 0.95rem;\">Available sizes for <strong>${this.ui.esc(product.title || \"this rug\")}</strong>:</p>\n            ${chips}\n        </div>\n    `;\n  }\n\n  _productPriceText(product = {}) {\n    this._syncSelectedVariantContext(true);\n    const activeProduct = this.contextProduct || product;\n    const size =\n      activeProduct.size &&\n      String(activeProduct.size).toLowerCase() !== \"default title\"\n        ? ` for ${activeProduct.size}`\n        : \"\";\n    const shape = activeProduct.shape ? ` ${activeProduct.shape}` : \"\";\n    const compare =\n      activeProduct.compare_at_price &&\n      this.ui.priceNumber(activeProduct.compare_at_price) >\n        this.ui.priceNumber(activeProduct.price)\n        ? `, marked down from ${this.ui.formatPrice(activeProduct.compare_at_price)}`\n        : \"\";\n    return `The selected ${this.ui.esc(activeProduct.title || \"rug\")}${size}${shape} is ${this.ui.formatPrice(activeProduct.price)}${compare}.`;\n  }\n\n  _productInfoText(product) {\n    const bits = [];\n    if (product.material) bits.push(`made from ${product.material}`);\n    if (product.size) bits.push(`sized ${product.size}`);\n    if (product.style) bits.push(`${product.style} style`);\n    if (product.color) bits.push(`${product.color} color`);\n    const price =\n      product.price !== undefined &&\n      product.price !== null &&\n      product.price !== \"\"\n        ? ` It is priced at ${this.ui.formatPrice(product.price)}.`\n        : \"\";\n    const detail = bits.length ? ` It is ${bits.join(\", \")}.` : \"\";\n    return `<strong>${this.ui.esc(product.title || \"This rug\")}</strong>${detail}${price} You can view the PDP, add it to cart, or preview it in your room.`;\n  }\n\n  _openCurrentProductPage() {\n    const product = this.contextProduct || this.store.getLastViewed();\n    if (!product) {\n      this._addMsg(\n        \"Please select a rug first, then I can open its product page.\",\n        \"assistant\",\n      );\n      return true;\n    }\n    const url =\n      product.url ||\n      product.product_url ||\n      (product.handle || product.shopify_handle\n        ? `/products/${product.handle || product.shopify_handle}`\n        : \"\");\n    if (!url) {\n      this._addMsg(\n        \"I do not have a product page URL for that rug yet. Please open it from the product card.\",\n        \"assistant\",\n      );\n      return true;\n    }\n    sessionStorage.setItem(\"rugbie_open_agent_on_load\", \"true\");\n    window.location.href = url;\n    return true;\n  }\n\n  _classifyRoomIntent(text = \"\") {\n    // Room features are intentionally separate:\n    // analyze = recommend rugs from room facts; visualize = place a selected rug.\n    const query = String(text || \"\")\n      .trim()\n      .toLowerCase();\n    if (!query) return \"none\";\n\n    const wantsRecommendations =\n      /\\b(analy[sz]e|recommend|suggest|suit|fits?|match|choose|find)\\b.*\\b(room|space|home|decor)\\b/.test(\n        query,\n      ) ||\n      /\\b(what rug|which rug|rug recommendations?|suggest a rug|recommend a rug)\\b/.test(\n        query,\n      ) ||\n      /\\b(analy[sz]e my room|what fits my room|what would suit my room|for this room)\\b/.test(\n        query,\n      );\n    const wantsVisualization =\n      /\\b(see|show|view|visuali[sz]e|preview|place|try)\\b.*\\b(room|space|my room|home|photo)\\b/.test(\n        query,\n      ) ||\n      /\\b(see|show|view|visuali[sz]e|preview|place|try) (this|it|rug)\\b/.test(\n        query,\n      ) ||\n      /\\bsee in (my )?room\\b/.test(query) ||\n      /\\bshow in (my )?room\\b/.test(query);\n    const roomOnly =\n      /\\b(my room|this room|room photo|room)\\b/.test(query) &&\n      !wantsRecommendations &&\n      !wantsVisualization;\n\n    if (wantsRecommendations && !wantsVisualization) return \"analyze\";\n    if (wantsVisualization && !wantsRecommendations) return \"visualize\";\n    if (wantsRecommendations && wantsVisualization)\n      return this.contextProduct ? \"visualize\" : \"ambiguous\";\n    if (roomOnly) return this.contextProduct ? \"visualize\" : \"ambiguous\";\n    return \"none\";\n  }\n\n  _handleRoomIntent(query, referencedProduct = null) {\n    const intent = this._classifyRoomIntent(query);\n    if (intent === \"none\") return false;\n    if (intent === \"analyze\") {\n      this._triggerVisualizer(\"analyze\");\n      return true;\n    }\n    if (intent === \"visualize\") {\n      return this._handleLocalVisualizerCommand(query, referencedProduct, true);\n    }\n    this._askRoomIntentClarification();\n    return true;\n  }\n\n  _askRoomIntentClarification() {\n    this._addMsg(\n      \"Do you want me to recommend rugs based on your room, or show this specific rug placed in your room?\",\n      \"assistant\",\n    );\n    this._addMsg(\n      this.ui.chips([\"Analyze my room\", \"See in my room\"]),\n      \"assistant\",\n      true,\n    );\n  }\n\n  _productForVisualizer(query = \"\", referencedProduct = null) {\n    return (\n      referencedProduct ||\n      this.contextProduct ||\n      this.store.getLastViewed() ||\n      this._visibleResultProducts()[0] ||\n      null\n    );\n  }\n\n  _prepareVisualizerProduct(product) {\n    if (!product) return null;\n    const sizes = this._availableSizesForProduct(product);\n    const selectedSize =\n      product.size && String(product.size).toLowerCase() !== \"default title\"\n        ? product.size\n        : \"\";\n    return {\n      ...product,\n      size: selectedSize || sizes[0] || product.size || \"\",\n    };\n  }\n\n  _handleLocalVisualizerCommand(\n    query,\n    referencedProduct = null,\n    alreadyClassified = false,\n  ) {\n    if (!alreadyClassified && this._classifyRoomIntent(query) !== \"visualize\")\n      return false;\n    const baseProduct = this._productForVisualizer(query, referencedProduct);\n    if (this._requestVisualizerSize(baseProduct)) return true;\n    const product = this._prepareVisualizerProduct(baseProduct);\n    if (!product) {\n      this._addMsg(\n        \"Please select a rug first before visualizing it in your room.\",\n        \"assistant\",\n      );\n      return true;\n    }\n    this._launchRoomManagerForProduct(product);\n    return true;\n  }\n\n  _handleLocalProductCommand(query, referencedProduct = null) {\n    const normalized = String(query || \"\")\n      .trim()\n      .toLowerCase();\n    if (\n      /^(view product|open product|product page|view product page|open pdp|view pdp)$/i.test(\n        normalized,\n      )\n    ) {\n      return this._openCurrentProductPage();\n    }\n    const product = referencedProduct || this.contextProduct;\n    if (!product) return false;\n    this._syncSelectedVariantContext(true);\n    const activeProduct = this.contextProduct || product;\n    if (this._isProductSizeQuery(query)) {\n      this._setContextProduct(activeProduct);\n      this._addMsg(this._productSizeText(activeProduct), \"assistant\", true);\n      return true;\n    }\n    if (this._isProductPriceQuery(query)) {\n      this._setContextProduct(activeProduct);\n      this._addMsg(this._productPriceText(activeProduct), \"assistant\", true);\n      return true;\n    }\n    if (!this._isProductInfoQuery(query)) return false;\n    this._setContextProduct(product);\n    this._addMsg(this._productInfoText(product), \"assistant\", true);\n    this._addMsg(this.ui.productActionCard(product), \"assistant\", true);\n    return true;\n  }\n\n  async openTool(toolId) {\n    this._ensureDrawer();\n    this.toggleToolMenu(false);\n    this._syncContext();\n\n    const product = this._currentProductOrRecent();\n    switch (toolId) {\n      case \"visualizer\":\n        this._triggerVisualizer(\"visualize\");\n        break;\n      case \"analyze\":\n        this._triggerVisualizer(\"analyze\");\n        break;\n      case \"compare\":\n        this._addMsg(\n          \"Product comparison is turned off for this store. I can still help with size, material, care, and rug pad guidance.\",\n          \"assistant\",\n        );\n        break;\n      case \"similar-rugs\":\n        await this._showSimilarRugs(product);\n        break;\n      case \"budget-alternatives\":\n        await this._showBudgetAlternatives(product);\n        break;\n      case \"rug-pads\":\n        this.sendAction(\n          product\n            ? `Recommend a rug pad for ${product.title}`\n            : \"Recommend rug pads for my rug and room\",\n        );\n        break;\n      case \"perfect-size\":\n        this.sendAction(`Help me find the perfect rug size for my room`);\n        break;\n      case \"material-finder\":\n        this.sendAction(`What's the best rug material for me?`);\n        break;\n      case \"care-guide\":\n        this.sendAction(`How do I clean and care for this rug?`);\n        break;\n      case \"recently-viewed\":\n      case \"viewed-products\":\n        this.sendAction(\"recently-viewed\");\n        break;\n      case \"better-value\":\n        this.sendAction(`Show me cheaper alternatives to this rug`);\n        break;\n      case \"style-match\":\n        this.sendAction(`Show me rugs with a similar style to this one`);\n        break;\n      case \"consultation\":\n      case \"services\":\n        this.startServiceFlow();\n        break;\n      case \"contact-store\":\n        this._openStoreOwnerChat();\n        break;\n      case \"track-order\":\n        this.startOrderTrackFlow();\n        break;\n      default:\n        this.sendAction(\"Help me find a rug\");\n    }\n  }\n\n  async _showSimilarRugs(product) {\n    const targetProduct = (product && (product.id || product.handle)) ? product : this._getActiveProduct();\n    if (!targetProduct) {\n      await this._doBrowse(this.store.data.facts, 6);\n      return;\n    }\n    const loadId = \"load-\" + Date.now();\n    this._addMsg(this.ui.loading(\"Finding similar rugs...\"), \"assistant\", true, loadId);\n    try {\n      let products = [];\n      const prodId = targetProduct.id || targetProduct.handle || \"\";\n      const prodHandle = targetProduct.handle || targetProduct.id || \"\";\n      if (prodId || prodHandle) {\n        try {\n          const reco = await this.api.recommend(prodId, prodHandle);\n          if (Array.isArray(reco)) {\n            products = reco;\n          } else if (reco && typeof reco === \"object\") {\n            products = reco.products || reco.results || reco.recommendations || reco.payload?.products || [];\n            if (!products.length && Array.isArray(reco.sections)) {\n              for (const sec of reco.sections) {\n                const secRecs = sec.recommendations || sec.products || sec.results || [];\n                if (secRecs.length > 0) {\n                  products.push(...secRecs);\n                }\n              }\n            }\n          }\n        } catch (e) {\n          console.warn(\"api.recommend failed, falling back to search\", e);\n        }\n      }\n      if (!products.length) {\n        const query = targetProduct.title || targetProduct.style || targetProduct.color || targetProduct.material || \"rugs\";\n        const searchRes = await this.api.search(query);\n        products = (searchRes?.products || searchRes?.results || searchRes || []).filter(\n          p => String(p.id) !== String(targetProduct.id) && p.handle !== targetProduct.handle\n        );\n      }\n      this._removeMsg(loadId);\n      if (Array.isArray(products) && products.length) {\n        this.registerProducts(products);\n        this.currentBrowseResults = products;\n        this._addMsg(\n          `Here are similar rugs to <strong>${this.ui.esc(targetProduct.title || \"this rug\")}</strong>:`,\n          \"assistant\"\n        );\n        this._addMsg(\n          this.ui.horizontalProductCarousel(\n            products.slice(0, 6),\n            `Similar to ${targetProduct.title || \"this rug\"}`\n          ),\n          \"assistant\",\n          true\n        );\n      } else {\n        await this._doBrowse(this.store.data.facts, 6);\n      }\n    } catch (err) {\n      this._removeMsg(loadId);\n      console.error(\"Similar rugs error:\", err);\n      await this._doBrowse(this.store.data.facts, 6);\n    }\n  }\n\n  async _showBudgetAlternatives(product) {\n    if (!product?.id) {\n      this.sendAction(\"Show budget alternatives based on my browsing context\");\n      return;\n    }\n    const loadId = \"load-\" + Date.now();\n    this._addMsg(this.ui.loading(), \"assistant\", true, loadId);\n    try {\n      const reco = await this.api.recommend(product.id);\n      const products = Array.isArray(reco)\n        ? reco\n        : reco.products || reco.payload?.products || [];\n      const currentPrice = this._numericPrice(product.price);\n      const alternatives = (Array.isArray(products) ? products : [])\n        .filter(\n          (item) =>\n            !currentPrice || this._numericPrice(item.price) < currentPrice,\n        )\n        .sort(\n          (a, b) => this._numericPrice(a.price) - this._numericPrice(b.price),\n        );\n      this._removeMsg(loadId);\n      if (alternatives.length) {\n        this.registerProducts(alternatives);\n        this.currentBrowseResults = alternatives;\n        this._addMsg(\n          this.ui.curatedPicks(\n            alternatives,\n            `Lower-priced alternatives to ${product.title}`,\n            alternatives.length,\n          ),\n          \"assistant\",\n          true,\n        );\n      } else {\n        this.sendAction(`Find lower-priced alternatives to ${product.title}`);\n      }\n    } catch (err) {\n      this._removeMsg(loadId);\n      console.error(\"Budget alternatives error:\", err);\n      this.sendAction(`Find lower-priced alternatives to ${product.title}`);\n    }\n  }\n\n  async _styleMatch() {\n    const facts = { ...this.store.data.facts };\n    if (this.contextProduct) {\n      if (this.contextProduct.style) facts.style = [this.contextProduct.style];\n      if (this.contextProduct.color) facts.color = [this.contextProduct.color];\n    }\n    if (Object.keys(facts).length) {\n      await this._doBrowse(facts, 6);\n    } else {\n      this.sendAction(\n        \"Match my style using my browsing activity and ask only what is missing\",\n      );\n    }\n  }\n\n  _numericPrice(price) {\n    return this.ui.priceNumber(price);\n  }\n\n  _productDisplayPrice(product = {}) {\n    return this.ui.priceNumber(\n      product.price ||\n        product.sale_price ||\n        product.discounted_price ||\n        product.final_price,\n    );\n  }\n\n  _extractMaxPrice(text = \"\") {\n    const patterns = [\n      /\\b(?:under|below|less\\s+than|up\\s+to|maximum|max|budget|within)\\b[^0-9$]{0,24}\\$?\\s*([0-9]+(?:\\.[0-9]{1,2})?)\\s*\\$?/i,\n      /\\$?\\s*([0-9]+(?:\\.[0-9]{1,2})?)\\s*\\$?\\s*(?:or\\s+less|and\\s+under|or\\s+under|max(?:imum)?|budget)/i,\n    ];\n    for (const pattern of patterns) {\n      const match = String(text || \"\").match(pattern);\n      const value = parseFloat(match?.[1]);\n      if (Number.isFinite(value) && value > 0) return value;\n    }\n    return null;\n  }\n\n  _isBudgetClearingQuery(text = \"\") {\n    return /\\b(any\\s*price|anyprice|all\\s+prices?|no\\s+(?:budget|price\\s*limit|price\\s*filter)|remove\\s+(?:budget|price\\s*(?:limit|filter)?)|clear\\s+(?:budget|price\\s*(?:limit|filter)?))\\b/i.test(\n      text,\n    );\n  }\n\n  _hasExplicitBudgetQuery(text = \"\") {\n    return (\n      Boolean(this._extractMaxPrice(text)) ||\n      /\\b(under|below|less\\s+than|up\\s+to|max(?:imum)?|budget|cheaper\\s+than|price\\s+limit)\\b/i.test(\n        text,\n      )\n    );\n  }\n\n  _shouldClearStoredBudgetForQuery(text = \"\") {\n    const query = String(text || \"\");\n    if (this._isBudgetClearingQuery(query)) return true;\n    if (this._hasExplicitBudgetQuery(query)) return false;\n    return (\n      /\\b(show|find|search|browse|recommend|looking\\s+for|need|want)\\b/i.test(\n        query,\n      ) &&\n      /\\b(rug|rugs|runner|pad|carpet|blue|red|green|beige|ivory|maharaja|oriental|traditional|washable|wool|jute|outdoor|indoor)\\b/i.test(\n        query,\n      )\n    );\n  }\n\n  _clearStoredBudget() {\n    this.store.clearFacts?.([\"budget\", \"max_price\", \"price\"]);\n    if (this.store.data?.facts) {\n      delete this.store.data.facts.budget;\n      delete this.store.data.facts.max_price;\n      delete this.store.data.facts.price;\n    }\n  }\n\n  _factsWithoutStoredBudget(facts = {}) {\n    const next = { ...(facts || {}) };\n    delete next.budget;\n    delete next.max_price;\n    delete next.price;\n    return next;\n  }\n\n  _extractRequestedProductCount(text = \"\") {\n    const match = String(text || \"\").match(\n      /\\b(?:show|find|browse|recommend|display|list)\\s+(?:me\\s+)?(\\d{1,2})\\s+(?:area\\s+)?(?:rug|rugs|runner|runners|pad|pads)\\b/i,\n    );\n    if (!match) return null;\n    const count = Number(match[1]);\n    if (!Number.isFinite(count) || count < 1) return null;\n    return Math.min(count, 20);\n  }\n\n  _isOrderTrackingQuery(text = \"\") {\n    const clean = String(text || \"\").trim().toLowerCase();\n    if (!clean) return false;\n    return (\n      /\\b(track|tracking|status|where)\\b.*\\b(order|package|shipment|delivery)\\b/i.test(\n        clean,\n      ) ||\n      /\\b(where\\s+is\\s+my\\s+order|track\\s+my\\s+order|track\\s+order|order\\s+status|order\\s+tracking|check\\s+order)\\b/i.test(\n        clean,\n      ) ||\n      /^(order\\s+tracking|track\\s+my\\s+order|track\\s+order|track\\s+package|order\\s+status|where\\s+is\\s+my\\s+order\\??)$/i.test(\n        clean,\n      )\n    );\n  }\n\n  _isServiceIntentQuery(text = \"\") {\n    if (\n      /\\b(this|current|same)\\s+rug\\b/i.test(text) &&\n      /\\b(size|sizes?|price|cost|available|availability)\\b/i.test(text)\n    )\n      return false;\n    return (\n      /\\b(service|services|consultation|concultation|appointment|cleaning|clean|stain|repair|restoration|appraisal|custom rug)\\b/i.test(\n        text,\n      ) && !this._isOrderTrackingQuery(text)\n    );\n  }\n\n  _isRugPadProductQuery(text = \"\") {\n    return /\\brug\\s*pad\\b|\\bpads?\\b/i.test(text);\n  }\n\n  _browseFactsForQuery(query = \"\", facts = {}) {\n    const next = this._shouldClearStoredBudgetForQuery(query)\n      ? this._factsWithoutStoredBudget(facts)\n      : { ...(facts || {}) };\n    if (this._isRugPadProductQuery(query)) {\n      next.category = [\"Rug Pads\"];\n      next.product_type = [\"Rug Pads\"];\n    } else if (/\\b(rug|rugs|runner|runners|carpet|carpets)\\b/i.test(query)) {\n      next.category = [\"Rug\"];\n    }\n    return next;\n  }\n\n  _cleanAssistantText(text = \"\") {\n    return String(text || \"\")\n      .replace(/\\*\\*(.*?)\\*\\*/g, \"$1\")\n      .replace(/\\*(.*?)\\*/g, \"$1\")\n      .replace(/\u00E2\u20AC\u2122/g, \"'\")\n      .replace(/\u00E2\u20AC\u0153|\u00E2\u20AC\uFFFD/g, '\"')\n      .replace(/\u00E2\u20AC\u201C|\u00E2\u20AC\u201D/g, \"-\")\n      .replace(/\u00E2\u20AC\u00A6/g, \"...\")\n      .trim();\n  }\n\n  _noProductMatchMessage(query = \"\", facts = {}) {\n    const mergedFacts = {\n      ...(facts || {}),\n      ...this._browseFactsForQuery(query, {}),\n    };\n    const queryText = String(query || \"\").toLowerCase();\n    if (!mergedFacts.color) {\n      const colorMatch = queryText.match(\n        /\\b(blue|red|green|beige|ivory|cream|black|white|gray|grey|brown|pink|orange|yellow|navy|teal|multi)\\b/,\n      );\n      if (colorMatch) mergedFacts.color = colorMatch[1];\n    }\n    if (!mergedFacts.size) {\n      const sizeMatch = queryText.match(\n        /\\b\\d{1,2}\\s*(?:'|ft|feet)\\s*(?:x|by|\\*)\\s*\\d{1,2}\\s*(?:'|ft|feet)?\\s*(?:\\d{1,2}\\s*(?:\"|in|inch|inches))?/,\n      );\n      if (sizeMatch) mergedFacts.size = sizeMatch[0].replace(/\\s+/g, \" \");\n    }\n    if (\n      !mergedFacts.room &&\n      /\\b(kids?|children|pets?|pet-friendly|dog|cat)\\b/.test(queryText)\n    ) {\n      mergedFacts.room = \"kids and pets\";\n    }\n    const parts = [];\n    const addFact = (label, value) => {\n      const text = Array.isArray(value) ? value.join(\", \") : value;\n      if (text) parts.push(label ? `${label} ${text}` : String(text));\n    };\n    addFact(\"\", mergedFacts.color);\n    addFact(\"around\", mergedFacts.size);\n    addFact(\"for\", mergedFacts.room);\n    addFact(\"\", mergedFacts.material);\n\n    const criteria = parts.length ? ` for ${parts.join(\", \")}` : \"\";\n    return `I couldn't find exact rug matches${criteria}. Try removing one filter, like color or exact size, and I can show the closest durable options for kids and pets.`;\n  }\n\n  _productsForBudget(products = [], query = \"\", facts = {}) {\n    const queryMaxPrice = this._extractMaxPrice(query);\n    const useStoredBudget = !this._shouldClearStoredBudgetForQuery(query);\n    const factBudget = useStoredBudget\n      ? facts?.budget ||\n        facts?.max_price ||\n        this.store.data.facts?.budget ||\n        this.store.data.facts?.max_price\n      : null;\n    const maxPrice = queryMaxPrice || this.ui.priceNumber(factBudget);\n    if (!maxPrice) return { products, maxPrice: null, removed: 0 };\n    const filtered = (products || []).filter((product) => {\n      const price = this._productDisplayPrice(product);\n      return price > 0 && price <= maxPrice + 0.01;\n    });\n    return {\n      products: filtered,\n      maxPrice,\n      removed: (products || []).length - filtered.length,\n    };\n  }\n\n  // --- Event Binding ---\n  _bindEvents() {\n    // FAB & Drawer\n    this.fab?.addEventListener(\"click\", () => this.toggleDrawer());\n    document\n      .getElementById(\"close-drawer\")\n      ?.addEventListener(\"click\", () => this.toggleDrawer());\n    this.menuBtn?.addEventListener(\"click\", () => this.toggleToolMenu());\n    this.overlay?.addEventListener(\"click\", () => this._closeAll());\n\n    // Chat\n    this.sendBtn?.addEventListener(\"click\", () => this._send());\n    this.chatInput?.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Enter\" && !e.shiftKey) {\n        e.preventDefault();\n        this._send();\n      }\n    });\n    document\n      .getElementById(\"camera-btn\")\n      ?.addEventListener(\"click\", () => this.sendAction(\"visualizer\"));\n    document.addEventListener(\"variant-change\", () =>\n      this._syncSelectedVariantContext(true),\n    );\n    document.addEventListener(\"change\", (e) => {\n      if (\n        e.target?.matches?.(\n          'input[name=\"id\"], select[name=\"id\"], .product-form__input input, .product-form__input select',\n        )\n      ) {\n        setTimeout(() => this._syncSelectedVariantContext(true), 0);\n      }\n      const fileInput = e.target?.closest?.('form[data-service-form=\"true\"] input[name=\"image\"], form[data-service-form=\"true\"] input[name=\"attachment\"]');\n      if (fileInput) {\n        const form = fileInput.closest(\"form\");\n        const file = fileInput.files?.[0];\n        const previewWrap = form?.querySelector(\".image-preview-container\");\n        const previewImg = form?.querySelector(\".svc-preview-thumb\");\n        const previewName = form?.querySelector(\".svc-preview-name\");\n        const previewSize = form?.querySelector(\".svc-preview-size\");\n        const labelText = form?.querySelector(\".file-name-text\");\n        if (file && previewWrap && previewImg) {\n          const reader = new FileReader();\n          reader.onload = (ev) => {\n            previewImg.src = ev.target.result;\n            if (previewName) previewName.textContent = file.name;\n            if (previewSize) previewSize.textContent = (file.size / 1024).toFixed(1) + \" KB\";\n            previewWrap.style.display = \"flex\";\n            if (labelText) labelText.textContent = \"Change photo...\";\n          };\n          reader.readAsDataURL(file);\n        }\n      }\n    });\n    document.addEventListener(\"click\", (e) => {\n      const removeBtn = e.target?.closest?.(\".svc-preview-remove\");\n      if (removeBtn) {\n        e.preventDefault();\n        const form = removeBtn.closest(\"form\");\n        const fileInput = form?.querySelector('input[name=\"image\"], input[name=\"attachment\"]');\n        const previewWrap = form?.querySelector(\".image-preview-container\");\n        const previewImg = form?.querySelector(\".svc-preview-thumb\");\n        const labelText = form?.querySelector(\".file-name-text\");\n        if (fileInput) fileInput.value = \"\";\n        if (previewImg) previewImg.src = \"\";\n        if (previewWrap) previewWrap.style.display = \"none\";\n        if (labelText) labelText.textContent = \"Choose rug photo (JPG, PNG)\";\n      }\n    });\n    document.addEventListener(\"submit\", (e) => {\n      const form = e.target?.closest?.('form[data-service-form=\"true\"]');\n      if (form) {\n        e.preventDefault();\n        this._handleServiceFormSubmit(form);\n      }\n    });\n    // Vertical Scroll Indicator Listener\n    if (this.chatArea) {\n      this.chatArea.addEventListener(\"scroll\", () =>\n        this._updateScrollIndicator(),\n      );\n    }\n    if (this.scrollIndicator) {\n      this.scrollIndicator.addEventListener(\"click\", () => {\n        if (this.chatArea) {\n          this.chatArea.scrollTo({\n            top: this.chatArea.scrollHeight,\n            behavior: \"smooth\",\n          });\n        }\n      });\n    }\n\n    const chatContainer =\n      document.querySelector(\"#chat-container\") || this.chatArea;\n    if (chatContainer) {\n      chatContainer.addEventListener(\n        \"scroll\",\n        (e) => {\n          if (\n            e.target &&\n            e.target.classList &&\n            e.target.classList.contains(\"chat-product-carousel\")\n          ) {\n            const carousel = e.target;\n            const container = carousel.closest(\".chat-carousel-container\");\n            if (container) {\n              const prevBtn = container.querySelector(\".carousel-scroll-prev\");\n              const nextBtn = container.querySelector(\".carousel-scroll-next\");\n              if (prevBtn) {\n                prevBtn.style.display = carousel.scrollLeft > 0 ? \"block\" : \"none\";\n              }\n              if (nextBtn) {\n                const maxScroll = carousel.scrollWidth - carousel.clientWidth;\n                nextBtn.style.display =\n                  carousel.scrollLeft >= maxScroll - 2 ? \"none\" : \"block\";\n              }\n            }\n          }\n        },\n        true,\n      );\n\n      chatContainer.addEventListener(\"click\", (e) => {\n        const prevScrollBtn = e.target.closest(\".carousel-scroll-prev\");\n        const nextScrollBtn = e.target.closest(\".carousel-scroll-next\");\n        const viewBtn = e.target.closest(\".view-product-btn\");\n        const seeInRoomBtn = e.target.closest(\".see-in-room-btn\");\n        const showSimilarBtn = e.target.closest(\".show-similar-btn\");\n        const actionChipBtn = e.target.closest(\".action-chip-btn\");\n\n        if (prevScrollBtn) {\n          e.preventDefault();\n          e.stopPropagation();\n          const container = prevScrollBtn.closest(\".chat-carousel-container\");\n          const carousel = container?.querySelector(\".chat-product-carousel\");\n          if (carousel) carousel.scrollBy({ left: -240, behavior: \"smooth\" });\n        } else if (nextScrollBtn) {\n          e.preventDefault();\n          e.stopPropagation();\n          const container = nextScrollBtn.closest(\".chat-carousel-container\");\n          const carousel = container?.querySelector(\".chat-product-carousel\");\n          if (carousel) carousel.scrollBy({ left: 240, behavior: \"smooth\" });\n        } else if (viewBtn) {\n          e.preventDefault();\n          e.stopPropagation();\n          const url = viewBtn.dataset.url;\n          const id = viewBtn.dataset.id;\n          if (id && window.app) {\n            window.app.openProduct(id, url);\n          } else if (url) {\n            window.location.href = url;\n          }\n        } else if (seeInRoomBtn) {\n          e.preventDefault();\n          e.stopPropagation();\n          const handle = seeInRoomBtn.dataset.handle;\n          const id = seeInRoomBtn.dataset.id;\n          if (id && window.app) {\n            window.app.seeProductInRoom(id, seeInRoomBtn);\n          } else if (handle && window.app) {\n            window.app.sendAction(\"visualizer\");\n          }\n        } else if (showSimilarBtn) {\n          e.preventDefault();\n          e.stopPropagation();\n          const id = showSimilarBtn.dataset.id;\n          const title = showSimilarBtn.dataset.title;\n          if (id && window.app) {\n            window.app._showSimilarRugs({ id, title });\n          }\n        } else if (actionChipBtn) {\n          e.preventDefault();\n          e.stopPropagation();\n          const action = actionChipBtn.dataset.action;\n          if (action && window.app) {\n            window.app.sendAction(action);\n          }\n        }\n      });\n    }\n\n    // Global handler for dynamic data-app-action buttons\n    document.body.addEventListener(\"click\", (e) => {\n      const actionBtn = e.target.closest(\"[data-app-action]\");\n      if (actionBtn && window.app) {\n        if (actionBtn.tagName === \"A\" || actionBtn.tagName === \"BUTTON\") {\n          e.preventDefault();\n          if (actionBtn.tagName !== \"A\") e.stopPropagation();\n        }\n        const action = actionBtn.dataset.appAction;\n        if (typeof window.app[action] === \"function\") {\n          const args = [];\n          let i = 0;\n          while (`arg${i}` in actionBtn.dataset) {\n            args.push(actionBtn.dataset[`arg${i}`]);\n            i++;\n          }\n          args.push(actionBtn);\n          window.app[action](...args);\n        }\n      }\n    });\n\n    // Global handler for forms\n    document.body.addEventListener(\"submit\", (e) => {\n      if (e.target.matches(\".app-managed-form\")) {\n        e.preventDefault();\n        const formType = e.target.dataset.formType;\n        if (formType === \"appointment\") {\n          if (typeof window.app?.submitAppointment === \"function\") {\n            window.app.submitAppointment(e);\n          }\n        } else if (formType === \"track-order\") {\n          if (typeof window.app?.submitOrderTrack === \"function\") {\n            window.app.submitOrderTrack(e);\n          }\n        }\n      }\n    });\n\n    // Header search\n    const headerSearch = document.getElementById(\"header-search-input\");\n    headerSearch?.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Enter\" && e.target.value.trim()) {\n        this.openAssistantWith(e.target.value.trim());\n        e.target.value = \"\";\n      }\n    });\n\n    // Cart\n    document\n      .getElementById(\"cart-toggle\")\n      ?.addEventListener(\"click\", () => this.openCart());\n    document\n      .getElementById(\"close-cart\")\n      ?.addEventListener(\"click\", () => this.closeCart());\n    document\n      .getElementById(\"header-cart-btn\")\n      ?.addEventListener(\"click\", () => this.openCart());\n\n    // Mobile menu\n    document\n      .getElementById(\"menu-toggle\")\n      ?.addEventListener(\"click\", () => this.openMobileMenu());\n    document\n      .getElementById(\"close-mobile-menu\")\n      ?.addEventListener(\"click\", () => this.closeMobileMenu());\n\n    // Hero CTA\n    document\n      .getElementById(\"hero-cta-ai\")\n      ?.addEventListener(\"click\", () => this.openTool(\"style-match\"));\n\n    // PDP buttons\n    document\n      .getElementById(\"pdp-back-btn\")\n      ?.addEventListener(\"click\", () => this.goHome());\n    document\n      .getElementById(\"pdp-add-cart\")\n      ?.addEventListener(\"click\", () => this._pdpAddToCart());\n    document\n      .getElementById(\"pdp-wishlist\")\n      ?.addEventListener(\"click\", () => this._pdpToggleWishlist());\n    document.getElementById(\"pdp-visualizer\")?.addEventListener(\"click\", () => {\n      if (!this.drawerOpen) this.toggleDrawer();\n      this.sendAction(\"visualizer\");\n    });\n\n    // Keyboard: Escape to close\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\") this._closeAll();\n    });\n\n    // Visualizer Lifecycle Sync\n    window.addEventListener(\"visualizerOpened\", () => this._setVisualizerState(true));\n    window.addEventListener(\"visualizerClosed\", () => this._setVisualizerState(false));\n\n    // Dynamic Observer for Visualizer Modal\n    const vizModal = document.getElementById(\"see-in-room-modal\");\n    if (vizModal) {\n      const syncVizModalState = () => {\n        const isVisible = vizModal.style.display !== \"none\" && vizModal.style.display !== \"\";\n        this._setVisualizerState(isVisible);\n      };\n      try {\n        const vizObserver = new MutationObserver(syncVizModalState);\n        vizObserver.observe(vizModal, { attributes: true, attributeFilter: [\"style\", \"class\"] });\n        syncVizModalState();\n      } catch (e) {\n        console.warn(\"Visualizer observer setup warning:\", e);\n      }\n    }\n\n    // Click outside to close (desktop)\n    document.addEventListener(\"click\", (e) => {\n      if (this.drawerOpen && window.innerWidth > 768) {\n        if (\n          !this.drawer.contains(e.target) &&\n          !this.fab.contains(e.target) &&\n          !e.target.closest(\".toast\")\n        ) {\n          this.toggleDrawer();\n        }\n      }\n      if (\n        this.cartOpen &&\n        this.cartDrawer &&\n        !this.cartDrawer.contains(e.target) &&\n        !e.target.closest(\".assistant-cart-button\")\n      ) {\n        this.closeCart();\n      }\n    });\n\n    // Shopify Route and Variant Change Detection\n    const handleRouteChange = () => {\n      setTimeout(() => {\n        const path = window.location.pathname;\n        const isPDP = path.includes(\"/products/\");\n\n        if (isPDP) {\n          const parts = path.split(\"/\");\n          const handleIndex = parts.indexOf(\"products\") + 1;\n          const handle = parts[handleIndex];\n\n          const currentHandle =\n            this.contextProduct?.handle || this.contextProduct?.shopify_handle;\n\n          if (handle && handle.split(\"?\")[0] !== currentHandle) {\n            const cleanHandle = handle.split(\"?\")[0];\n            fetch(`/products/${cleanHandle}.js`)\n              .then((res) => res.json())\n              .then((data) => {\n                const product = {\n                  id: String(data.id),\n                  handle: data.handle,\n                  title: data.title,\n                  price: (data.price / 100).toFixed(2),\n                  imgUrl: data.images && data.images[0] ? data.images[0] : \"\",\n                  url: `/products/${data.handle}`,\n                  collection: data.vendor || \"\",\n                  vendor: data.vendor || \"\",\n                  brand: data.vendor || \"\",\n                };\n                const urlParams = new URLSearchParams(window.location.search);\n                const variantId = urlParams.get(\"variant\");\n                if (variantId && data.variants) {\n                  const v = data.variants.find(\n                    (v) => String(v.id) === variantId,\n                  );\n                  if (v) {\n                    product.size = v.public_title || v.title || \"\";\n                    product.price = (v.price / 100).toFixed(2);\n                  }\n                } else if (data.variants && data.variants[0]) {\n                  product.size =\n                    data.variants[0].public_title ||\n                    data.variants[0].title ||\n                    \"\";\n                }\n                this._setContextProduct(product);\n                this._syncContext();\n              })\n              .catch((err) =>\n                console.error(\"Failed to fetch product data:\", err),\n              );\n          } else {\n            const urlParams = new URLSearchParams(window.location.search);\n            const variantId = urlParams.get(\"variant\");\n            if (variantId && window.ShopifyContextPayload?.product) {\n              if (\n                window.ShopifyContextPayload.product.variant?.id != variantId\n              ) {\n                this._syncContext();\n              }\n            }\n          }\n        } else if (this.contextProduct) {\n          this.contextProduct = null;\n          this._syncContext();\n        }\n      }, 100);\n    };\n    document.addEventListener(\"change\", (e) => {\n      if (\n        e.target.matches(\n          'input[name=\"id\"], select[name=\"id\"], input[name=\"id\"] ~ *, select[name=\"id\"] ~ *',\n        )\n      ) {\n        handleRouteChange();\n      }\n    });\n\n    // Intercept pushState for SPA themes\n    const originalPushState = history.pushState;\n    history.pushState = function () {\n      originalPushState.apply(this, arguments);\n      handleRouteChange();\n    };\n\n    // Swipe down to close (mobile)\n    const drawerHeader = document.querySelector(\".drawer-header\");\n    if (drawerHeader) {\n      let startY = 0;\n      drawerHeader.addEventListener(\n        \"touchstart\",\n        (e) => {\n          startY = e.touches[0].clientY;\n        },\n        { passive: true },\n      );\n\n      drawerHeader.addEventListener(\n        \"touchmove\",\n        (e) => {\n          if (!startY) return;\n          const currentY = e.touches[0].clientY;\n          const diff = currentY - startY;\n          if (diff > 50 && this.drawerOpen) {\n            this.toggleDrawer();\n            startY = 0;\n          }\n        },\n        { passive: true },\n      );\n\n      drawerHeader.addEventListener(\"touchend\", () => {\n        startY = 0;\n      });\n    }\n  }\n\n  // --- Visualizer State Sync ---\n  _setVisualizerState(isOpen) {\n    this._visualizerOpen = Boolean(isOpen);\n    if (this._visualizerOpen) {\n      if (this.drawerOpen) {\n        this.toggleDrawer();\n      }\n      if (this.fab) {\n        this.fab.classList.add(\"hidden\");\n        this.fab.setAttribute(\"aria-hidden\", \"true\");\n        this.fab.style.pointerEvents = \"none\";\n      }\n    } else {\n      if (this.fab && !this.drawerOpen) {\n        this.fab.classList.remove(\"hidden\");\n        this.fab.removeAttribute(\"aria-hidden\");\n        this.fab.style.pointerEvents = \"\";\n      }\n    }\n  }\n\n  // --- Drawer ---\n  _isPDP() {\n    return (\n      document.getElementById(\"pdp-view\")?.style.display === \"block\" ||\n      window.location.pathname.includes(\"/products/\")\n    );\n  }\n\n  toggleDrawer() {\n    this.drawerOpen = !this.drawerOpen;\n    this.drawer.classList.toggle(\"open\", this.drawerOpen);\n\n    const isPDP = this._isPDP();\n\n    if (this.drawerOpen) {\n      this.drawer.removeAttribute(\"inert\");\n      if (this.chatArea.children.length === 0)\n        this.drawer.classList.add(\"unroll\");\n      // On PDP (desktop), add side-by-side class\n      if (isPDP) {\n        document.body.classList.add(\"pdp-assistant-open\");\n      }\n      setTimeout(() => this._updateScrollIndicator(), 150);\n    } else {\n      this.drawer.setAttribute(\"inert\", \"\");\n      this.drawer.classList.remove(\"unroll\");\n      this.toggleToolMenu(false);\n      document.body.classList.remove(\"pdp-assistant-open\");\n      // Accessibility focus restoration\n      if (this.fab) this.fab.focus();\n    }\n\n    if (this._visualizerOpen) {\n      this.fab.classList.add(\"hidden\");\n    } else {\n      this.fab.classList.toggle(\"hidden\", this.drawerOpen);\n    }\n\n    // On PDP desktop, don't show overlay (side-by-side mode)\n    const isMobile = window.innerWidth <= 768;\n    if (isPDP && !isMobile) {\n      // No overlay needed in side-by-side mode\n      this.overlay.classList.remove(\"active\");\n      this.overlay.setAttribute(\"inert\", \"\");\n    } else {\n      const active = this.cartOpen || this.drawerOpen;\n      this.overlay.classList.toggle(\"active\", active);\n      if (active) this.overlay.removeAttribute(\"inert\");\n      else this.overlay.setAttribute(\"inert\", \"\");\n    }\n\n    if (this.drawerOpen) {\n      if (this.chatArea.children.length === 0 && !this._chatRestored)\n        this._sendGreeting();\n\n      // Greet with the current product if on a PDP\n      if (isPDP) {\n        const activeProduct = this._getActiveProduct();\n        if (activeProduct) {\n          this.contextProduct = activeProduct;\n          const greeting = `Now viewing <strong>${this.ui.esc(activeProduct.title)}</strong>. I can help with sizing, care, similar styles, or show it in your room.`;\n          const msgs = document.querySelectorAll(\".message.assistant\");\n          if (\n            msgs.length === 0 ||\n            !msgs[msgs.length - 1].innerHTML.includes(\n              this.ui.esc(activeProduct.title),\n            )\n          ) {\n            this._addMsg(greeting, \"assistant\", true);\n            this._loadPDPSuggestedQuestions();\n          } else if (!document.getElementById(\"load-pdp-dynamic-chips\")) {\n            this._loadPDPSuggestedQuestions();\n          }\n        }\n      }\n\n      setTimeout(() => {\n        if (this.chatInput) this.chatInput.focus();\n      }, 300);\n    }\n  }\n\n  openAssistantWith(msg) {\n    if (!this.drawerOpen) this.toggleDrawer();\n    setTimeout(() => this.sendAction(msg), 350);\n  }\n\n  // --- Cart Drawer ---\n  async openCart() {\n    try {\n      await this.store.init();\n    } catch (e) {\n      console.warn(\"Cart sync warning:\", e);\n    }\n    this._setCartOpen(true);\n  }\n\n  closeCart() {\n    this._setCartOpen(false);\n  }\n\n  async toggleCart() {\n    if (!this.cartOpen) {\n      try {\n        await this.store.init();\n      } catch (e) {\n        console.warn(\"Cart sync warning:\", e);\n      }\n    }\n    this._setCartOpen(!this.cartOpen);\n  }\n\n  _setCartOpen(open) {\n    if (!this.cartDrawer) return;\n    this.cartOpen = !!open;\n    this.cartDrawer.classList.toggle(\"open\", this.cartOpen);\n    this.cartDrawer.setAttribute(\n      \"aria-hidden\",\n      this.cartOpen ? \"false\" : \"true\",\n    );\n    if (this.cartOpen) this.cartDrawer.removeAttribute(\"inert\");\n    else this.cartDrawer.setAttribute(\"inert\", \"\");\n\n    document\n      .querySelectorAll(\".assistant-cart-button, #cart-toggle\")\n      .forEach((btn) => {\n        btn.setAttribute(\"aria-expanded\", this.cartOpen ? \"true\" : \"false\");\n      });\n\n    const active = this.cartOpen || this.drawerOpen;\n    this.overlay.classList.toggle(\"active\", active);\n    if (active) this.overlay.removeAttribute(\"inert\");\n    else this.overlay.setAttribute(\"inert\", \"\");\n\n    if (this.cartOpen) this._renderCart();\n  }\n\n  _renderCart() {\n    const container = document.getElementById(\"cart-items\");\n    const footer = document.getElementById(\"cart-footer\");\n    if (this.store.data.cart.length === 0) {\n      container.innerHTML = `<div class=\"cart-empty\"><i class=\"fa fa-shopping-bag\" aria-hidden=\"true\"></i><p>Your cart is empty</p><button class=\"discovery-btn btn-primary btn-sm\" style=\"margin-top:var(--space-md)\" data-app-action=\"closeCart\">Start Shopping</button></div>`;\n      footer.style.display = \"none\";\n      return;\n    }\n    footer.style.display = \"block\";\n    container.innerHTML = this.store.data.cart\n      .map(\n        (\n          item,\n          i,\n        ) => `<div class=\"cart-item\" style=\"animation: slideInRight 0.3s ease both; animation-delay: ${i * 40}ms\">\n            <img class=\"cart-item-img\" src=\"${this.ui.escAttr(item.imgUrl || \"\")}\" alt=\"${this.ui.esc(item.title)}\" onerror=\"this.style.display='none'\">\n            <div class=\"cart-item-info\">\n                <div class=\"cart-item-title\">${this.ui.esc(item.title)}</div>\n                <div class=\"cart-item-price\">${this.ui.formatPrice(item.price)}</div>\n                <div style=\"font-size:var(--text-xs);color:var(--color-text-muted);margin-bottom:var(--space-xs)\">${this.ui.esc(item.size || \"\")} ${this.ui.esc(item.color || \"\")}</div>\n                <div style=\"display:flex; align-items:center; gap:var(--space-sm);\">\n                    <div style=\"display:flex; align-items:center; border:1px solid var(--color-border); border-radius:var(--radius-sm); overflow:hidden;\">\n                        <button style=\"border:none;background:var(--color-surface-alt);padding:4px 8px;cursor:pointer;\" aria-label=\"Decrease quantity\" data-app-action=\"updateCartQty\" data-arg0=\"${this.ui.escJS(item.variant_id || item.id)}\" data-arg1=\"${this.ui.escJS(item.size || \"\")}\" data-arg2=\"-1\" data-arg3=\"${this.ui.escJS(item.key || \"\")}\"><svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" style=\"vertical-align: middle;\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg></button>\n                        <span style=\"padding:0 8px;font-size:var(--text-sm);\">${item.qty || 1}</span>\n                        <button style=\"border:none;background:var(--color-surface-alt);padding:4px 8px;cursor:pointer;\" aria-label=\"Increase quantity\" data-app-action=\"updateCartQty\" data-arg0=\"${this.ui.escJS(item.variant_id || item.id)}\" data-arg1=\"${this.ui.escJS(item.size || \"\")}\" data-arg2=\"1\" data-arg3=\"${this.ui.escJS(item.key || \"\")}\"><svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" style=\"vertical-align: middle;\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg></button>\n                    </div>\n                    <button class=\"cart-item-remove\" data-app-action=\"removeCartItem\" data-arg0=\"${this.ui.escJS(item.variant_id || item.id)}\" data-arg1=\"${this.ui.escJS(item.size || \"\")}\" data-arg2=\"${this.ui.escJS(item.key || \"\")}\" style=\"margin-top:0;\"><i class=\"fa fa-trash-alt\"></i> Remove</button>\n                </div>\n            </div>\n        </div>`,\n      )\n      .join(\"\");\n    document.getElementById(\"cart-subtotal\").textContent =\n      `$${this.store.getCartTotal().toFixed(2)}`;\n  }\n\n  async removeCartItem(variantId, size = \"\", lineKey = \"\") {\n    await this.store.removeFromCart(variantId, size, lineKey);\n    this._updateCartUI();\n    this._renderCart();\n    this.toast(\"Item removed from cart\");\n  }\n\n  async removeFromCart(variantId, size = \"\", lineKey = \"\") {\n    await this.removeCartItem(variantId, size, lineKey);\n  }\n\n  async updateCartQty(id, size, delta, lineKey = \"\") {\n    await this.store.updateCartQty(id, size, Number(delta), lineKey);\n    this._updateCartUI();\n    this._renderCart();\n  }\n\n  _updateCartUI() {\n    const count = this.store.data.cart.reduce((s, c) => s + (c.qty || c.quantity || 1), 0);\n    const badges = document.querySelectorAll(\n      \"#cart-count, .assistant-cart-count, [data-cart-count], .cart-bubble__text-count, [data-testid='cart-bubble']\",\n    );\n    badges.forEach((badge) => {\n      badge.textContent = count ? String(count) : \"\";\n      badge.setAttribute(\"data-count\", count);\n      badge.setAttribute(\n        \"aria-label\",\n        count ? `${count} items in cart` : \"Cart is empty\",\n      );\n      badge.classList.toggle(\"hidden\", count === 0);\n    });\n\n    document.querySelectorAll(\".cart-bubble\").forEach((bubble) => {\n      bubble.classList.toggle(\"visually-hidden\", count === 0);\n    });\n\n    document.querySelectorAll(\"cart-icon\").forEach((icon) => {\n      if (typeof icon.renderCartBubble === \"function\") {\n        icon.renderCartBubble(count, false);\n      }\n    });\n\n    const evtDetail = {\n      resource: this.store._cart || { item_count: count, items: this.store.data.cart },\n      sourceId: \"shopping-agent\",\n      data: { itemCount: count, source: \"shopping-agent\" },\n      item_count: count,\n    };\n\n    document.dispatchEvent(new CustomEvent(\"cart:update\", { bubbles: true, detail: evtDetail }));\n    document.dispatchEvent(new CustomEvent(\"cart:updated\", { bubbles: true, detail: evtDetail }));\n    window.dispatchEvent(new CustomEvent(\"cart:updated\", { bubbles: true, detail: evtDetail }));\n    document.documentElement.dispatchEvent(new CustomEvent(\"cart:updated\", { bubbles: true, detail: evtDetail }));\n\n    if (this.cartOpen) {\n      this._renderCart();\n    }\n  }\n\n  // --- Mobile Menu ---\n  openMobileMenu() {\n    document.getElementById(\"mobile-menu\").classList.add(\"open\");\n    document.getElementById(\"mobile-menu\").removeAttribute(\"inert\");\n    document\n      .getElementById(\"menu-toggle\")\n      .setAttribute(\"aria-expanded\", \"true\");\n  }\n  closeMobileMenu() {\n    document.getElementById(\"mobile-menu\").classList.remove(\"open\");\n    document.getElementById(\"mobile-menu\").setAttribute(\"inert\", \"\");\n    document\n      .getElementById(\"menu-toggle\")\n      .setAttribute(\"aria-expanded\", \"false\");\n  }\n\n  // --- Close All ---\n  _closeAll() {\n    this.toggleToolMenu(false);\n    if (this.drawerOpen) this.toggleDrawer();\n    if (this.cartOpen) this.closeCart();\n    this.closeMobileMenu();\n  }\n\n  // --- Toast ---\n  toast(msg, duration = 2500) {\n    const el = document.getElementById(\"toast\");\n    el.innerHTML = `<i class=\"fa fa-check-circle\" aria-hidden=\"true\"></i> ${this.ui.esc(msg)}\n            <div class=\"toast-progress\" style=\"animation-duration: ${duration}ms\"></div>`;\n    el.classList.add(\"show\");\n    clearTimeout(this._toastTimer);\n    this._toastTimer = setTimeout(() => el.classList.remove(\"show\"), duration);\n  }\n\n  // --- Chat Messages ---\n  _addMsg(content, role = \"assistant\", isHTML = false, id = null) {\n    const div = document.createElement(\"div\");\n    div.className = `message ${role}`;\n    if (id) div.id = id;\n    if (isHTML) {\n      div.innerHTML = content;\n    } else {\n      div.textContent = content;\n    }\n    this.chatArea.appendChild(div);\n    this.chatArea.scrollTop = this.chatArea.scrollHeight;\n    setTimeout(() => this._updateScrollIndicator(), 60);\n\n    // Save to IDB (unless it's a temporary loading message)\n    if (!id || (!id.startsWith(\"load-\") && !id.startsWith(\"skel-\"))) {\n      this.db\n        .saveMessage(\n          this.store.sessionId,\n          role,\n          isHTML ? div.innerHTML : div.textContent,\n        )\n        .catch(console.warn);\n    }\n  }\n\n  _updateScrollIndicator() {\n    if (!this.scrollIndicator || !this.chatArea) return;\n    const { scrollTop, scrollHeight, clientHeight } = this.chatArea;\n    const isScrollable = scrollHeight - clientHeight > 30;\n    const isNotAtBottom = scrollTop + clientHeight < scrollHeight - 45;\n    if (isScrollable && isNotAtBottom) {\n      this.scrollIndicator.removeAttribute(\"hidden\");\n    } else {\n      this.scrollIndicator.setAttribute(\"hidden\", \"\");\n    }\n  }\n\n  _removeMsg(id) {\n    const el = document.getElementById(id);\n    if (el) el.remove();\n  }\n\n  // --- Greeting ---\n  _sendGreeting() {\n    const payload = window.ShopifyContextPayload || {};\n\n    let greeting = `Hello! I'm your personal rug consultant. How can I help you today?`;\n    let chips = [];\n    let showWelcomePrompt = true;\n\n    if (this.contextProduct) {\n      greeting = `Looking at the <strong>${this.ui.esc(this.contextProduct.title)}</strong>? I can show you how it looks in your room, or find similar styles.`;\n      chips = [\"See in my room\", \"Is it easy to clean?\", \"Show similar styles\"];\n      showWelcomePrompt = false;\n    } else if (payload.template === \"collection\" && payload.collection) {\n      greeting = `Browsing the <strong>${this.ui.esc(payload.collection.title)}</strong> collection? I can help you narrow down by size, color, or budget.`;\n      chips = [\"Show top rated\", \"Filter by size\", \"What materials are best?\"];\n      showWelcomePrompt = false;\n    } else if (payload.cart && payload.cart.item_count > 0) {\n      greeting = `You have ${payload.cart.item_count} item${payload.cart.item_count > 1 ? \"s\" : \"\"} in your cart \u2014 want a second opinion before you check out?`;\n      chips = [\"Do I need a rug pad?\", \"Care instructions\", \"Track my order\"];\n      showWelcomePrompt = false;\n    }\n\n    this._addMsg(greeting, \"assistant\", true);\n\n    if (showWelcomePrompt) {\n      this._addMsg(this.ui.welcomePrompt(), \"assistant\", true);\n    } else if (chips.length > 0) {\n      this._addMsg(this.ui.chips(chips), \"assistant\", true);\n    }\n  }\n\n  // --- Send ---\n  async _send() {\n    const text = this.chatInput.value.trim();\n    if (!text || this.sending) return;\n\n    this.sending = true;\n    this.sendBtn.disabled = true;\n    this.chatInput.value = \"\";\n    this._addMsg(text, \"user\");\n\n    // Order tracking intercept: open in-chat order tracking form immediately\n    if (this._isOrderTrackingQuery(text)) {\n      this.startOrderTrackFlow();\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n\n    // Agent transfer: intercept before any backend call or chat message\n    if (this._isStoreContactQuery(text)) {\n      await this._openStoreOwnerChat();\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n\n    await this._processQuery(text);\n    this.sending = false;\n    this.sendBtn.disabled = false;\n  }\n\n  startOrderTrackFlow() {\n    this._ensureDrawer();\n    this.toggleToolMenu(false);\n    this._addMsg(\n      \"I can help check your order status. Please enter your order details below:\",\n      \"assistant\",\n    );\n    const formHtml = this.ui.orderTrackForm();\n    this._addMsg(formHtml, \"assistant\", true);\n\n    setTimeout(() => {\n      if (this.chatArea) {\n        this.chatArea.scrollTop = this.chatArea.scrollHeight;\n        this._updateScrollIndicator();\n      }\n    }, 80);\n  }\n\n  serviceRequestForm(initialService = \"\") {\n    const defaultServices = [\n      \"Custom Rug Sizing\",\n      \"Professional Rug Cleaning\",\n      \"Repair & Restoration\",\n      \"In-Home Consultation\",\n      \"Delivery & Installation\",\n      \"Rug Appraisal\",\n      \"Other\"\n    ];\n\n    const rawService = (initialService || \"\").trim();\n    const selectedService = rawService || \"Custom Rug Sizing\";\n    const optionsHtml = defaultServices.map(svc => {\n      const isSelected = svc.toLowerCase() === selectedService.toLowerCase() ||\n        (rawService && selectedService.toLowerCase().includes(svc.toLowerCase()) && svc !== \"Other\");\n      return `<option value=\"${this.ui.esc(svc)}\"${isSelected ? ' selected' : ''}>${this.ui.esc(svc)}</option>`;\n    }).join(\"\");\n\n    const formId = \"svc-form-\" + Date.now();\n    return `<div class=\"interactive-service-card\" style=\"background: var(--color-surface, #18181b); border: 1px solid var(--color-border, #27272a); border-radius: 12px; padding: 16px; margin-top: 8px; color: var(--color-text, #ffffff);\">\n        <h4 style=\"margin-top: 0; margin-bottom: 14px; color: var(--color-text, #ffffff); display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n            \uD83D\uDEE0\uFE0F Request Store Service\n        </h4>\n        <form id=\"${formId}\" class=\"interactive-service-form\" data-service-form=\"true\">\n            <div class=\"form-group\" style=\"margin-bottom: 12px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Service Needed</label>\n                <select name=\"service\" class=\"form-control\" style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n                    ${optionsHtml}\n                </select>\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 12px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Full Name <span style=\"color: #ef4444;\">*</span></label>\n                <input type=\"text\" name=\"name\" class=\"form-control\" placeholder=\"e.g. Jane Smith\" required style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 12px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Phone Number <span style=\"color: #ef4444;\">*</span></label>\n                <input type=\"tel\" name=\"phone\" class=\"form-control\" placeholder=\"e.g. (281) 719-0487\" required style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 12px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Email (Optional)</label>\n                <input type=\"email\" name=\"email\" class=\"form-control\" placeholder=\"e.g. jane@example.com\" style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit;\">\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 12px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Description / Project Details (Optional)</label>\n                <textarea name=\"notes\" class=\"form-control\" rows=\"3\" placeholder=\"Tell us about your rug, dimensions, or questions...\" style=\"width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46); background: var(--color-bg, #09090b); color: var(--color-text, #ffffff); font-size: 13px; font-family: inherit; resize: vertical;\"></textarea>\n            </div>\n            <div class=\"form-group\" style=\"margin-bottom: 14px;\">\n                <label style=\"display: block; font-size: 12px; font-weight: 600; color: var(--color-text-secondary, #a1a1aa); margin-bottom: 6px;\">Upload Photo (Optional)</label>\n                <div class=\"service-upload-wrapper\" style=\"position: relative;\">\n                    <label class=\"service-file-upload-box\" style=\"display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 14px; border: 1px dashed var(--color-border, #3f3f46); border-radius: 8px; background: var(--color-bg, #09090b); cursor: pointer; text-align: center; transition: border-color 0.2s;\">\n                        <i class=\"fa fa-camera\" style=\"font-size: 14px; color: var(--color-accent, #3b82f6);\"></i>\n                        <span class=\"file-name-text\" style=\"font-size: 12px; color: var(--color-text-secondary, #a1a1aa);\">Choose rug photo (JPG, PNG)</span>\n                        <input type=\"file\" name=\"attachment\" accept=\"image/*\" style=\"display: none;\">\n                    </label>\n                    <div class=\"image-preview-container\" style=\"display: none; margin-top: 8px; align-items: center; gap: 10px; background: rgba(255,255,255,0.04); padding: 6px 10px; border-radius: 8px; border: 1px solid var(--color-border, #3f3f46);\">\n                        <img class=\"svc-preview-thumb\" src=\"\" alt=\"Rug photo preview\" style=\"width: 44px; height: 44px; object-fit: cover; border-radius: 6px; border: 1px solid var(--color-border, #3f3f46);\">\n                        <div style=\"flex: 1; min-width: 0;\">\n                            <div class=\"svc-preview-name\" style=\"font-size: 12px; font-weight: 600; color: var(--color-text, #fff); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"></div>\n                            <div class=\"svc-preview-size\" style=\"font-size: 10px; color: var(--color-text-secondary, #a1a1aa);\"></div>\n                        </div>\n                        <button type=\"button\" class=\"svc-preview-remove\" style=\"background: none; border: none; color: #ef4444; font-size: 16px; cursor: pointer; padding: 4px 8px; line-height: 1;\">&times;</button>\n                    </div>\n                </div>\n            </div>\n            <button type=\"submit\" class=\"discovery-btn btn-primary\" style=\"width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; font-weight: 600; border-radius: 8px; background: var(--color-accent, #2563eb); color: #ffffff; border: none; cursor: pointer; font-size: 14px; transition: opacity 0.2s;\">\n                <i class=\"fa fa-paper-plane\"></i> Submit Request\n            </button>\n        </form>\n    </div>`;\n  }\n  startServiceFlow(initialService = null) {\n    this._ensureDrawer();\n    this.toggleToolMenu(false);\n    this.pendingServiceRequest = null;\n\n    const rawService = initialService ? String(initialService).trim() : \"\";\n    const cleanServiceName = rawService\n      ? rawService.replace(/^[^\\w\\s]+/, \"\").trim()\n      : \"\";\n\n    const formHtml = this.serviceRequestForm(cleanServiceName);\n    this._addMsg(formHtml, \"assistant\", true);\n\n    setTimeout(() => {\n      if (this.chatArea) {\n        this.chatArea.scrollTop = this.chatArea.scrollHeight;\n        this._updateScrollIndicator();\n      }\n    }, 80);\n  }\n\n  _resolveStoreEmail() {\n    const tenant = (this.tenant || \"\").toLowerCase();\n    if (tenant.includes(\"vogue\")) return \"voguerugs@outlook.com\";\n    if (tenant.includes(\"rugtown\")) return \"rugtown01@gmail.com\";\n    if (tenant.includes(\"reza\")) return \"rezasrugnmore@gmail.com\";\n    if (window.DiscoveryAIStoreEmail) return window.DiscoveryAIStoreEmail;\n    if (window.ShopifyContextPayload?.shop?.email) return window.ShopifyContextPayload.shop.email;\n    return \"bsnarenofficial@gmail.com\";\n  }\n\n  async _sendNativeShopifyContact({ name, email, phone, service, notes, body }) {\n    try {\n      console.log(\"[Discovery-AI] Dispatching native Shopify contact mailer to /contact...\");\n      const params = new URLSearchParams();\n      params.append(\"form_type\", \"contact\");\n      params.append(\"utf8\", \"\u2713\");\n      if (name) params.append(\"contact[name]\", name);\n      if (phone) params.append(\"contact[phone]\", phone);\n\n      const cleanDigits = (phone || \"\").replace(/\\D/g, \"\") || \"shopper\";\n      const fallbackEmail = `inquiry+${cleanDigits}@${window.location.hostname}`;\n      params.append(\"contact[email]\", email || fallbackEmail);\n\n      if (service) params.append(\"contact[Service]\", service);\n      params.append(\"contact[body]\", body || notes || `Service Request for ${service}`);\n\n      const res = await fetch(\"/contact\", {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/x-www-form-urlencoded\",\n          \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        },\n        body: params.toString(),\n      });\n      console.log(\"[Discovery-AI] Direct Shopify contact mailer status:\", res.status);\n      return res.ok || res.status === 302 || res.status === 303;\n    } catch (err) {\n      console.warn(\"[Discovery-AI] Direct Shopify contact mailer error:\", err);\n      return false;\n    }\n  }\n\n  async _compressImage(file, maxDimension = 1600, quality = 0.85) {\n    if (!file || !file.type || !file.type.startsWith(\"image/\")) return file;\n    try {\n      return await new Promise((resolve) => {\n        const img = new Image();\n        const url = URL.createObjectURL(file);\n        img.onload = () => {\n          URL.revokeObjectURL(url);\n          let { width, height } = img;\n          if (width > maxDimension || height > maxDimension) {\n            if (width > height) {\n              height = Math.round((height * maxDimension) / width);\n              width = maxDimension;\n            } else {\n              width = Math.round((width * maxDimension) / height);\n              height = maxDimension;\n            }\n          }\n          const canvas = document.createElement(\"canvas\");\n          canvas.width = width;\n          canvas.height = height;\n          const ctx = canvas.getContext(\"2d\");\n          ctx.drawImage(img, 0, 0, width, height);\n          canvas.toBlob(\n            (blob) => {\n              if (blob) {\n                const cleanName = (file.name || \"photo.jpg\").replace(/\\.[^/.]+$/, \"\") + \".jpg\";\n                const compressedFile = new File([blob], cleanName, {\n                  type: \"image/jpeg\",\n                  lastModified: Date.now(),\n                });\n                resolve(compressedFile);\n              } else {\n                resolve(file);\n              }\n            },\n            \"image/jpeg\",\n            quality\n          );\n        };\n        img.onerror = () => {\n          URL.revokeObjectURL(url);\n          resolve(file);\n        };\n        img.src = url;\n      });\n    } catch (e) {\n      console.warn(\"[Discovery-AI] Image compression fallback:\", e);\n      return file;\n    }\n  }\n\n  async _handleServiceFormSubmit(formEl) {\n    const submitBtn = formEl.querySelector('button[type=\"submit\"]');\n    const nameInput = formEl.querySelector('input[name=\"name\"]');\n    const phoneInput = formEl.querySelector('input[name=\"phone\"]');\n    const emailInput = formEl.querySelector('input[name=\"email\"]');\n    const serviceSelect = formEl.querySelector('select[name=\"service\"]');\n    const notesTextarea = formEl.querySelector('textarea[name=\"notes\"]');\n    const imageInput = formEl.querySelector('input[name=\"attachment\"], input[name=\"image\"], input[type=\"file\"]');\n\n    const name = (nameInput?.value || \"\").trim();\n    const phone = (phoneInput?.value || \"\").trim();\n    const email = (emailInput?.value || \"\").trim();\n    const service = (serviceSelect?.value || \"Service Request\").trim();\n    const notes = (notesTextarea?.value || \"\").trim();\n    const rawImageFile = imageInput?.files?.[0] || null;\n\n    if (!name || name.length < 2) {\n      if (nameInput) nameInput.focus();\n      return;\n    }\n    if (!phone || phone.replace(/\\D/g, \"\").length < 7) {\n      if (phoneInput) phoneInput.focus();\n      return;\n    }\n\n    if (submitBtn) {\n      submitBtn.disabled = true;\n      submitBtn.innerHTML = '<i class=\"fa fa-spinner fa-spin\"></i> Submitting...';\n    }\n    formEl.querySelectorAll(\"input, select, textarea, button\").forEach((el) => {\n      el.disabled = true;\n    });\n\n    try {\n      const leadService = window.DiscoveryAIAssistantLead;\n      if (!leadService?.submit) {\n        throw new Error(\"Assistant lead module is unavailable\");\n      }\n\n      const result = await leadService.submit({\n        tenant: this.api?.tenant || window.shopkeeperTenant || \"discovery_ai_llc\",\n        name,\n        phone,\n        email,\n        service,\n        notes,\n        file: rawImageFile,\n        product: this.contextProduct || window.ShopifyContextPayload?.product || null,\n        pageUrl: window.location.href,\n      });\n\n      if (result.success) {\n        if (submitBtn) {\n          submitBtn.innerHTML = '<i class=\"fa fa-check\"></i> Submitted';\n          submitBtn.style.background = '#16a34a';\n          submitBtn.style.opacity = '1';\n        }\n\n        const contactInfo = email\n          ? `${this.ui.esc(phone)} / ${this.ui.esc(email)}`\n          : this.ui.esc(phone);\n\n        this._addMsg(\n          `<div class=\"confirmation-card interactive-service-card\" style=\"background: var(--color-surface, #ffffff); border: 1px solid var(--color-border, #e2e8f0); border-radius: 12px; padding: 16px; margin-top: 8px;\">\n              <h4 style=\"margin-top: 0; color: #16a34a; display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n                  <i class=\"fa fa-check-circle\"></i> Service Request Sent!\n              </h4>\n              <p style=\"font-size: 13px; color: var(--color-text-secondary, #475569); margin-bottom: 0;\">Thanks for contacting us, <strong>${this.ui.esc(name)}</strong>! Our team has received your request for <strong>${this.ui.esc(service)}</strong> and will reach out to you shortly at <strong>${contactInfo}</strong>.</p>\n          </div>`,\n          \"assistant\",\n          true,\n        );\n        return;\n      }\n\n      if (result.activationRequired) {\n        console.warn(\"[Discovery-AI] FormSubmit activation is required for this storefront origin.\");\n      }\n\n      const storePhone =\n        window.ShopifyContextPayload?.shop?.phone || \"our store team\";\n      this._addMsg(\n        `<div class=\"confirmation-card interactive-service-card\" style=\"background: var(--color-surface, #ffffff); border: 1px solid var(--color-border, #e2e8f0); border-radius: 12px; padding: 16px; margin-top: 8px;\">\n            <h4 style=\"margin-top: 0; color: #dc2626; display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n                <i class=\"fa fa-exclamation-triangle\"></i> Request Delivery Pending\n            </h4>\n            <p style=\"font-size: 13px; color: var(--color-text-secondary, #475569); margin-bottom: 8px;\">We could not deliver your request automatically right now.</p>\n            <p style=\"font-size: 13px; color: var(--color-text-secondary, #475569); margin-bottom: 0;\">Please call or text <strong>${this.ui.esc(storePhone)}</strong> directly or tap below to open Live Chat.</p>\n            <button class=\"discovery-btn btn-primary btn-sm\" data-app-action=\"_openStoreOwnerChat\" style=\"margin-top: 10px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;\"><i class=\"fa fa-comments\"></i> Chat Live with Store</button>\n        </div>`,\n        \"assistant\",\n        true,\n      );\n    } catch (err) {\n      console.warn(\"[Discovery-AI] Service form error:\", err);\n      if (submitBtn) {\n        submitBtn.disabled = false;\n        submitBtn.innerHTML =\n          '<i class=\"fa fa-paper-plane\"></i> Submit Request';\n      }\n      formEl.querySelectorAll(\"input, select, textarea, button\").forEach((el) => {\n        el.disabled = false;\n      });\n    }\n  }\n\n  sendAction(action) {\n    this._ensureDrawer();\n    this.toggleToolMenu(false);\n    if (this.pendingVisualizerIntent) {\n      const size = this._findSizeFromText(\n        action,\n        this.pendingVisualizerIntent.product,\n      );\n      if (size) {\n        this._addMsg(action, \"user\");\n        const product = {\n          ...this.pendingVisualizerIntent.product,\n          size,\n          sizeSelected: true,\n          selectedSizeExplicit: true,\n        };\n        this.pendingVisualizerIntent = null;\n        this._launchRoomManagerForProduct(product);\n        return;\n      }\n    }\n    if (this.pendingCartIntent) {\n      const size = this._findSizeFromText(\n        action,\n        this.pendingCartIntent.product,\n      );\n      if (size) {\n        this._addMsg(action, \"user\");\n        const product = {\n          ...this.pendingCartIntent.product,\n          size,\n          sizeSelected: true,\n          selectedSizeExplicit: true,\n        };\n        this.pendingCartIntent = null;\n        this._addProductToCartWithSize(product, null);\n        return;\n      }\n    }\n    if (\n      action === \"visualizer\" ||\n      /^see in my room$/i.test(action || \"\") ||\n      /^visualize in my room$/i.test(action || \"\")\n    ) {\n      this._handleLocalVisualizerCommand(\"see in my room\", null, true);\n    } else if (\n      /^analy[sz]e my room$/i.test(action || \"\") ||\n      /^analy[sz]e room$/i.test(action || \"\")\n    ) {\n      this._triggerVisualizer(\"analyze\");\n    } else if (\n      action === \"Book an appointment\" ||\n      action === \"consultation\" ||\n      action === \"services\"\n    ) {\n      this.startServiceFlow();\n    } else if (\n      action === \"contact-store\" ||\n      this._isStoreContactQuery(action)\n    ) {\n      void this._openStoreOwnerChat();\n    } else if (/^compare/i.test(action || \"\")) {\n      this._addMsg(\n        \"Product comparison is turned off for this store. I can help narrow by size, material, care, price, or rug pads.\",\n        \"assistant\",\n      );\n      this.chatArea.scrollTop = this.chatArea.scrollHeight;\n    } else if (\n      action === \"track-order\" ||\n      action === \"Track my order\" ||\n      action === \"track order\" ||\n      action === \"where-is-my-order\" ||\n      this._isOrderTrackingQuery(action)\n    ) {\n      this.startOrderTrackFlow();\n    } else if (action === \"history\" || action === \"recently-viewed\") {\n      this._handleLocalHistoryCommand(\"recently viewed\");\n    } else {\n      this._addMsg(action, \"user\");\n      this._processQuery(action);\n    }\n  }\n\n  async _processQuery(query) {\n    this._syncSelectedVariantContext(true);\n    if (this._isOrderTrackingQuery(query)) {\n      this.startOrderTrackFlow();\n      return;\n    }\n    if (this._isStoreContactQuery(query)) {\n      await this._openStoreOwnerChat();\n      return;\n    }\n    const referencedProduct = this._resolveProductReference(query);\n    if (referencedProduct) this._setContextProduct(referencedProduct);\n    if (this._handleRoomIntent(query, referencedProduct)) return;\n    query = this._rewriteContextualFollowup(query);\n    const budgetClearingQuery = this._isBudgetClearingQuery(query);\n    const shouldClearStoredBudget =\n      this._shouldClearStoredBudgetForQuery(query);\n    if (shouldClearStoredBudget) this._clearStoredBudget();\n    if (budgetClearingQuery) {\n      const recentSearch = (this.store.data.searchHistory || []).find(\n        (item) => item && !this._isBudgetClearingQuery(item),\n      );\n      if (recentSearch && !this._isProductSeekingQuery(query)) {\n        query = recentSearch;\n      }\n    }\n    this.sending = true;\n    this.sendBtn.disabled = true;\n    const loadId = \"load-\" + Date.now();\n    const skelId = \"skel-\" + Date.now();\n    const historyHandled = this._handleLocalHistoryCommand(query);\n    if (historyHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const orderTrackingHandled = this._handleLocalOrderTrackingCommand(query);\n    if (orderTrackingHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const productHandled = this._handleLocalProductCommand(\n      query,\n      referencedProduct,\n    );\n    if (productHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const serviceHandled = this._handleLocalServiceCommand(query);\n    if (serviceHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const explicitCountHandled =\n      await this._handleExplicitProductCountQuery(query);\n    if (explicitCountHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const rugPadBrowseHandled = await this._handleRugPadProductBrowse(query);\n    if (rugPadBrowseHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const visualizerHandled = this._handleRoomIntent(query, referencedProduct);\n    if (visualizerHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const cartHandled = await this._handleLocalCartCommand(query);\n    if (cartHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n    const localHandled = await this._handleLocalCommerceIntent(query);\n    if (localHandled) {\n      this.sending = false;\n      this.sendBtn.disabled = false;\n      return;\n    }\n\n    const avatar = document.querySelector(\".sparky-avatar\");\n    if (avatar) avatar.classList.add(\"thinking\");\n\n    const productSeeking = this._isProductSeekingQuery(query);\n    this._addMsg(\n      productSeeking\n        ? this.ui.browseLoading(query)\n        : this.ui.chatLoading(query),\n      \"assistant\",\n      true,\n      loadId,\n    );\n    if (productSeeking)\n      this._addMsg(this.ui.skeletonGrid(3), \"assistant\", true, skelId);\n\n    const stages = productSeeking\n      ? [\"Filtering by your preferences...\", \"Ranking best matches...\"]\n      : [\"Checking product context...\", \"Preparing a clear answer...\"];\n    const stageTimers = stages.map((stageText, i) =>\n      setTimeout(\n        () => {\n          const statusEl = document.querySelector(`#${loadId} .status-text`);\n          if (statusEl) statusEl.textContent = stageText;\n        },\n        800 * (i + 1),\n      ),\n    );\n\n    try {\n      this.store.addSearch(query);\n      const queryMaxPrice = this._extractMaxPrice(query);\n      if (queryMaxPrice)\n        this.store.updateFacts({ budget: queryMaxPrice }, true);\n      const memory = await this._assistantMemoryWithMessages();\n      if (shouldClearStoredBudget && memory) memory.budget = null;\n      const data = await this.api.message(\n        query,\n        this.store.sessionId,\n        {},\n        await this._pageContext(),\n        memory,\n      );\n\n      this._removeMsg(loadId);\n      this._removeMsg(skelId);\n      stageTimers.forEach((t) => clearTimeout(t));\n      if (avatar) avatar.classList.remove(\"thinking\");\n\n      if (!data || data.error) {\n        this._addMsg(\n          data?.message || \"Sorry, I couldn't process that. Please try again.\",\n          \"assistant\",\n        );\n        return;\n      }\n\n      const type = data.type || data.intent;\n      const payload = data.payload || {};\n      const isProductResponse =\n        type === \"products\" ||\n        type === \"product_discovery\" ||\n        type === \"search\";\n      const hasProductList = Array.isArray(payload.products);\n      const zeroProductResponse =\n        isProductResponse && hasProductList && payload.products.length === 0;\n      const budgetFilteredResponse = payload.products?.length\n        ? this._productsForBudget(payload.products, query, payload.facts)\n        : null;\n      if (budgetFilteredResponse?.maxPrice) {\n        payload.products = budgetFilteredResponse.products;\n        payload.total_size = budgetFilteredResponse.products.length;\n      }\n      \n      if (payload.products && payload.products.length > 0) {\n        payload.products = await Promise.all(payload.products.map(async (rec) => {\n          try {\n            const res = await fetch(`/products/${rec.handle || rec.id}.js`);\n            if (res.ok) {\n              const shopifyProduct = await res.json();\n              rec.variants = shopifyProduct.variants || [];\n              let matchedVariant = null;\n              if (Array.isArray(shopifyProduct.variants)) {\n                const targetId = String(rec.selected_variant?.id || rec.variant_id || \"\");\n                const targetSize = String(rec.size || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                matchedVariant = shopifyProduct.variants.find((v) => {\n                  if (targetId && String(v.id) === targetId) return true;\n                  if (targetSize) {\n                    const vTitle = String(v.title || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                    const vOpt1 = String(v.option1 || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                    const vOpt2 = String(v.option2 || \"\").toLowerCase().replace(/[\\s\\-_'\"]/g, \"\");\n                    if (vTitle === targetSize || vOpt1 === targetSize || vOpt2 === targetSize) return true;\n                  }\n                  return false;\n                });\n              }\n              if (matchedVariant) {\n                if (matchedVariant.price) rec.price = matchedVariant.price / 100;\n                if (matchedVariant.compare_at_price) {\n                  rec.compare_at_price = matchedVariant.compare_at_price / 100;\n                  rec.was_price = rec.compare_at_price;\n                }\n                rec.selected_variant = matchedVariant;\n                rec.variant_id = matchedVariant.id;\n              } else {\n                if (!rec.price && shopifyProduct.price) {\n                  rec.price = shopifyProduct.price / 100;\n                }\n                if (!rec.compare_at_price) {\n                  const compareAt = shopifyProduct.compare_at_price || (shopifyProduct.variants?.[0]?.compare_at_price);\n                  if (compareAt) {\n                    rec.compare_at_price = compareAt / 100;\n                    rec.was_price = compareAt / 100;\n                  }\n                }\n              }\n            }\n          } catch (e) {\n            console.warn(\"Failed to enrich payload product\", rec.handle || rec.id, e);\n          }\n          return rec;\n        }));\n      }\n      if (payload.product) {\n        const cachedProduct = this.productCatalog.get(\n          String(payload.product.id),\n        );\n        this._setContextProduct({\n          ...(cachedProduct || {}),\n          ...payload.product,\n        });\n      }\n\n      if (data.message) {\n        let msgContent = this._cleanAssistantText(data.message);\n        let msgIsHtml = false;\n        if (type === \"review_summary\")\n          msgContent = `<div class=\"review-summary-card\">${data.message}</div>`;\n        if (type === \"review_summary\") msgIsHtml = true;\n        else if (type === \"room_suitability\") {\n          msgContent = `<div class=\"suitability-card\"><i class=\"fa fa-home\"></i> ${this.ui.esc(msgContent)}</div>`;\n          msgIsHtml = true;\n        }\n        const staleProductMessage =\n          budgetFilteredResponse?.removed > 0 &&\n          (type === \"products\" ||\n            type === \"product_discovery\" ||\n            type === \"search\");\n        if (!staleProductMessage && !zeroProductResponse)\n          this._addMsg(msgContent, \"assistant\", msgIsHtml);\n        if (payload.product) {\n          const cachedProduct = this.productCatalog.get(\n            String(payload.product.id),\n          );\n          this._addMsg(\n            this.ui.productActionCard({\n              ...(cachedProduct || {}),\n              ...payload.product,\n            }),\n            \"assistant\",\n            true,\n          );\n        }\n      }\n\n      if (\n        !zeroProductResponse &&\n        payload.follow_up_questions &&\n        payload.follow_up_questions.length > 0\n      ) {\n        this._addMsg(\n          this.ui.chips(payload.follow_up_questions.slice(0, 3)),\n          \"assistant\",\n          true,\n        );\n      }\n\n      // Handle intent-specific actions\n      if (\n        data.action_trigger === \"OPEN_LIVE_CHAT\" ||\n        payload.action_trigger === \"OPEN_LIVE_CHAT\" ||\n        (payload.payload && payload.payload.action_trigger === \"OPEN_LIVE_CHAT\")\n      ) {\n        this._openLiveChat();\n      } else if (type === \"products\") {\n        if (payload.products?.length > 0) {\n          const filtered = this._productsForBudget(\n            payload.products,\n            query,\n            payload.facts,\n          );\n          if (!filtered.products.length) {\n            this._addMsg(\n              `I found rugs, but none were under ${this.ui.formatPrice(filtered.maxPrice)}. Try raising the budget a little or changing the style/color.`,\n              \"assistant\",\n            );\n          } else {\n            this._addMsg(\n              this.ui.horizontalProductCarousel(filtered.products),\n              \"assistant\",\n              true,\n            );\n            this.currentBrowseResults = filtered.products;\n          }\n        } else if (budgetFilteredResponse?.maxPrice) {\n          this._addMsg(\n            `I found rugs, but none were under ${this.ui.formatPrice(budgetFilteredResponse.maxPrice)}. Try raising the budget a little or changing the style/color.`,\n            \"assistant\",\n          );\n        } else if (zeroProductResponse) {\n          this._addMsg(\n            this._noProductMatchMessage(query, payload.facts),\n            \"assistant\",\n          );\n        }\n      } else if (type === \"product_discovery\" || type === \"search\") {\n        if (payload.products?.length > 0) {\n          const filtered = this._productsForBudget(\n            payload.products,\n            query,\n            payload.facts,\n          );\n          if (!filtered.products.length) {\n            this._addMsg(\n              `I found rugs, but none were under ${this.ui.formatPrice(filtered.maxPrice)}. Try raising the budget a little or changing the style/color.`,\n              \"assistant\",\n            );\n          } else {\n            const reason = payload.reasoning || \"Matching products\";\n            this._addMsg(\n              this.ui.horizontalProductCarousel(filtered.products, reason),\n              \"assistant\",\n              true,\n            );\n            this.currentBrowseResults = filtered.products;\n          }\n        } else if (budgetFilteredResponse?.maxPrice) {\n          this._addMsg(\n            `I found rugs, but none were under ${this.ui.formatPrice(budgetFilteredResponse.maxPrice)}. Try raising the budget a little or changing the style/color.`,\n            \"assistant\",\n          );\n        } else if (zeroProductResponse) {\n          this._addMsg(\n            this._noProductMatchMessage(query, payload.facts),\n            \"assistant\",\n          );\n        } else if (payload.query) {\n          await this._doSearch(payload.query);\n        } else {\n          await this._doBrowse(payload.facts || this.store.data.facts);\n        }\n      } else if (type === \"style_discovery\" || type === \"conversational\") {\n        if (!data.message && payload.new_messages) {\n          payload.new_messages.forEach((msg) => {\n            if (msg.role === \"assistant\")\n              this._addMsg(msg.content, \"assistant\");\n          });\n        }\n      } else if (type === \"visualizer_prompt\") {\n        this._triggerVisualizer(\"visualize\");\n      } else if (type === \"analyze_room_prompt\") {\n        this._triggerVisualizer(\"analyze\");\n      } else if (\n        type === \"product_comparison\" ||\n        type === \"comparison_prompt\"\n      ) {\n        this._addMsg(\n          \"Product comparison is turned off for this store. Ask me about size, care, material, price, or rug pads instead.\",\n          \"assistant\",\n        );\n      } else if (type === \"add_to_cart\") {\n        let success = false;\n        if (payload.product) {\n          const cachedProduct = this.productCatalog.get(\n            String(payload.product.id),\n          );\n          const handle =\n            payload.product.handle ||\n            cachedProduct?.handle ||\n            cachedProduct?.shopify_handle ||\n            payload.product.id;\n          success = await this.quickAddToCart(\n            handle,\n            payload.product.title,\n            payload.product.price,\n            payload.product.image_url || payload.product.imgUrl,\n            payload.product.size,\n            payload.product.color,\n          );\n        }\n\n        const msgs = [];\n        if (success && payload.product)\n          msgs.push(\n            `Added <strong>${payload.product.title}</strong> to your cart.`,\n          );\n        if (payload.similar_rugs?.length > 0)\n          msgs.push(\n            this.ui.horizontalProductCarousel(\n              payload.similar_rugs,\n              \"You may also like\",\n            ),\n          );\n        if (payload.rug_pads?.length > 0)\n          msgs.push(\n            this.ui.horizontalProductCarousel(\n              payload.rug_pads,\n              \"Recommended Rug Pads\",\n            ),\n          );\n        if (msgs.length > 0)\n          this._addMsg(msgs.join(\"<br><br>\"), \"assistant\", true);\n      }\n\n      let backendFacts = null;\n      if (data.facts && Object.keys(data.facts).length > 0)\n        backendFacts = data.facts;\n      else if (payload.facts && Object.keys(payload.facts).length > 0)\n        backendFacts = payload.facts;\n      else if (data.filter_state && Object.keys(data.filter_state).length > 0)\n        backendFacts = data.filter_state;\n      else if (payload.filter_state) backendFacts = payload.filter_state;\n      if (backendFacts) {\n        const factsToStore = shouldClearStoredBudget\n          ? this._factsWithoutStoredBudget(backendFacts)\n          : backendFacts;\n        this.store.updateFacts(factsToStore, true);\n      }\n    } catch (err) {\n      this._removeMsg(loadId);\n      this._removeMsg(skelId);\n      stageTimers.forEach((t) => clearTimeout(t));\n      if (avatar) avatar.classList.remove(\"thinking\");\n      console.error(\"Backend error:\", err);\n      this._addMsg(\n        \"I'm having trouble connecting right now. Please try again in a moment.\",\n        \"assistant\",\n      );\n    }\n\n    this.sending = false;\n    this.sendBtn.disabled = false;\n  }\n\n  _isStoreContactQuery(text = \"\") {\n    const q = String(text || \"\")\n      .trim()\n      .toLowerCase();\n    if (!q || this._isOrderTrackingQuery(q)) return false;\n    // Broad match for agent transfer / store contact intents\n    return /\\b(talk\\s+to\\s+(the\\s+)?(store\\s*)?owner|talk\\s+to\\s+(the\\s+)?store|contact\\s+(the\\s+)?(store|owner|team|us)|message\\s+(the\\s+)?(store|owner|team)|speak\\s+(to|with)\\s+(the\\s+)?(store|owner|human|team|agent|support|representative|rep)|open\\s+(shopify\\s+)?(inbox|chat)|shopify\\s+(inbox|chat)|chat\\s+with\\s+(us|owner|store|team|support)|live\\s+chat|start\\s+chat|human\\s+(agent|support|help)|\\bagent\\b|\\bhuman\\b|\\brepresentative\\b|\\breal\\s+person\\b|\\bsupport\\s*(team|agent)?\\b|\\bcustomer\\s+(service|support|care)\\b|\\bhelp\\s+desk\\b|\\bescalate\\b|\\btransfer\\b|\\bconnect\\s+(me\\s+)?(to|with)\\s+(a\\s+)?(human|agent|person|owner|store|team|support|representative|rep)\\b)\\b/i.test(\n      q,\n    );\n  }\n\n  _isStoreHandoffStatus(content = \"\") {\n    const text = String(content)\n      .replace(/<[^>]+>/g, \" \")\n      .replace(/\\s+/g, \" \")\n      .trim();\n    return (\n      /I opened Shopify Inbox/i.test(text) ||\n      /I found the chat widget on this page/i.test(text) ||\n      /I could not find a live chat widget on this page/i.test(text) ||\n      /Open Shopify Chat to send this to the store team/i.test(text) ||\n      /Shopify Chat Handoff Ready/i.test(text) ||\n      /The backend prepared the Shopify Inbox handoff/i.test(text)\n    );\n  }\n\n  _removeStoreHandoffStatusMessages() {\n    Array.from(\n      this.chatArea?.querySelectorAll(\".message.assistant\") || [],\n    ).forEach((el) => {\n      if (this._isStoreHandoffStatus(el.innerHTML || el.textContent))\n        el.remove();\n    });\n  }\n\n  async _openStoreOwnerChat() {\n    this._removeStoreHandoffStatusMessages();\n    this._addMsg(\"Switching to a store agent. Opening chat...\", \"assistant\");\n    this.toast(\"Connecting you to a store agent...\");\n    await new Promise((r) => setTimeout(r, 3000));\n    // Close the Discovery-AI drawer first\n    if (this.drawerOpen) {\n      this.toggleDrawer();\n      // Brief delay to let the drawer animation finish and Shopify launcher reappear\n      await new Promise((r) => setTimeout(r, 350));\n    }\n    const status = await this.openShopifyInbox();\n    if (status !== \"opened\") {\n      this.toast(\"Click the Chat button in the bottom-right corner\");\n    }\n    return status === \"opened\";\n  }\n\n  // --- Conversational Discovery (direct API) ---\n  async _doConversational(query) {\n    try {\n      let facts = { ...this.store.data.facts };\n      if (this.contextProduct) facts._current_product = this.contextProduct;\n\n      const data = await this.api.discover(\n        query,\n        \"conversational\",\n        this.store.data.conversationState,\n        facts,\n      );\n      this.store.data.conversationState = data.state;\n      if (data.facts) this.store.updateFacts(data.facts, true);\n      this.store.save();\n\n      if (data.new_messages) {\n        data.new_messages.forEach((msg) => {\n          if (msg.role === \"assistant\") this._addMsg(msg.content, \"assistant\");\n        });\n      }\n    } catch (err) {\n      console.error(\"Conversational error:\", err);\n    }\n  }\n\n  // --- Search ---\n  async _doSearch(q) {\n    try {\n      const data = await this.api.search(q);\n      if (data.products?.length > 0) {\n        const filtered = this._productsForBudget(\n          data.products,\n          q,\n          this.store.data.facts,\n        );\n        if (!filtered.products.length) {\n          this._addMsg(\n            `I found rugs, but none were under ${this.ui.formatPrice(filtered.maxPrice)}. Try a higher budget or fewer filters.`,\n            \"assistant\",\n          );\n          return;\n        }\n        const reason = `Found ${filtered.products.length} products matching \"${q}\"`;\n        this._addMsg(\n          this.ui.horizontalProductCarousel(filtered.products, reason),\n          \"assistant\",\n          true,\n        );\n        this.currentSearchResults = filtered.products;\n      } else {\n        this._addMsg(\n          \"No exact matches found. Try different keywords or tell me more about what you're looking for.\",\n          \"assistant\",\n        );\n      }\n    } catch (err) {\n      console.error(\"Search error:\", err);\n    }\n  }\n\n  // --- Browse ---\n  async _doBrowse(facts, limit = 4, options = {}) {\n    try {\n      const data = await this.api.browse(facts, 1, limit);\n      let products = data.products || [];\n      if (options.requireRugPads)\n        products = products.filter((product) => this._isRugPadProduct(product));\n      if (!products.length && options.requireRugPads) {\n        const fallbackFacts = {\n          ...facts,\n          category: undefined,\n          product_type: undefined,\n          query: \"rug pad non slip rug grip underlay\",\n          search_query: \"rug pad\",\n        };\n        const fallbackData = await this.api.browse(\n          fallbackFacts,\n          1,\n          Math.max(limit, 8),\n        );\n        products = (\n          fallbackData.products ||\n          fallbackData.payload?.products ||\n          []\n        ).filter((product) => this._isRugPadProduct(product));\n      }\n      if (!products.length && options.requireRugPads) {\n        products = await this._fetchRugPadProducts(facts?.size, limit);\n      }\n      if (products.length > 0) {\n        const filtered = this._productsForBudget(\n          products,\n          options.query || \"\",\n          facts,\n        );\n        if (!filtered.products.length) {\n          const label = options.requireRugPads ? \"rug pads\" : \"rugs\";\n          this._addMsg(\n            `I found ${label}, but none were under ${this.ui.formatPrice(filtered.maxPrice)}. Try a higher budget or fewer filters.`,\n            \"assistant\",\n          );\n          return;\n        }\n        const reason = this._generateReason(facts);\n        if (options.title || limit > 4) {\n          const title = options.title || reason;\n          this._addMsg(\n            this.ui.horizontalProductCarousel(\n              filtered.products.slice(0, limit),\n              title,\n            ),\n            \"assistant\",\n            true,\n          );\n        } else {\n          this._addMsg(\n            this.ui.curatedPicks(\n              filtered.products,\n              reason,\n              filtered.products.length,\n            ),\n            \"assistant\",\n            true,\n          );\n        }\n        this.currentBrowseResults = filtered.products;\n      } else if (options.requireRugPads) {\n        this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n      }\n    } catch (err) {\n      console.error(\"Browse error:\", err);\n      if (options.requireRugPads) {\n        this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n      }\n    }\n  }\n\n  _generateReason(facts) {\n    const reasons = [];\n    if (facts.style) reasons.push(`${facts.style} style`);\n    if (facts.color) reasons.push(`${facts.color} tones`);\n    if (facts.material) reasons.push(`${facts.material} material`);\n    if (facts.room) reasons.push(`perfect for ${facts.room}`);\n    if (facts.budget) reasons.push(`within your budget`);\n    return reasons.length > 0\n      ? `Based on your preferences (${reasons.join(\", \")})`\n      : \"Based on your preferences\";\n  }\n\n  showAllResults() {\n    if (this.currentBrowseResults && this.currentBrowseResults.length > 0) {\n      this._addMsg(\n        this.ui.productGrid(this.currentBrowseResults, true),\n        \"assistant\",\n        true,\n      );\n      this.toast(\"Showing all results\");\n    }\n  }\n\n  // --- Compare ---\n  _showCompare() {\n    this._addMsg(\n      this.ui.compareTable(this.store.data.compare),\n      \"assistant\",\n      true,\n    );\n  }\n  addCompare(item) {\n    const added = this.store.addToCompare(item);\n    if (added) {\n      this.toast(\n        `${item.title} added to compare (${this.store.data.compare.length}/4)`,\n      );\n      if (this.store.data.compare.length >= 3) {\n        this.toast(\"Opening Comparison Room...\");\n        this._openComparisonRoom();\n      }\n    } else {\n      this.toast(\n        this.store.data.compare.some((c) => c.id === item.id)\n          ? \"Already in compare list\"\n          : \"Compare list is full (max 4)\",\n      );\n    }\n  }\n  removeCompare(id) {\n    this.store.removeFromCompare(id);\n    this._showCompare();\n  }\n  clearCompare() {\n    this.store.clearCompare();\n    this._addMsg(\"Compare list cleared.\", \"assistant\");\n  }\n\n  async _openCompareSelector() {\n    //\n    //\n\n    let cv = document.getElementById(\"compare-selector-view\");\n    if (!cv) {\n      cv = document.createElement(\"div\");\n      cv.id = \"compare-selector-view\";\n      cv.className = \"view-section\";\n      document.getElementById(\"main-content\").appendChild(cv);\n    }\n    cv.style.display = \"block\";\n\n    let products = this.currentBrowseResults || [];\n    if (products.length < 10) {\n      try {\n        const res = await this.api.browse({}, 1, 20);\n        products = res.products || [];\n      } catch (e) {}\n    }\n\n    const ui = new UIRenderer();\n\n    cv.innerHTML = `\n            <div class=\"container\" style=\"padding-top:var(--space-2xl); padding-bottom:100px;\">\n                <h2><i class=\"fa fa-th-large\"></i> Select Rugs to Compare</h2>\n                <p style=\"color:var(--color-text-muted); margin-top:var(--space-sm);\">Click \"Add\" on any rug to select it for comparison. Choose at least 2 rugs.</p>\n                <div class=\"compare-selector-grid\">\n                    ${products\n                      .map((p) => {\n                        const isSelected = this.store.data.compare.some(\n                          (c) => c.id === p.id,\n                        );\n                        return `<div class=\"compare-item\" id=\"cs-${p.id}\" style=\"${isSelected ? \"border-color:var(--color-success)\" : \"\"}\">\n                            <img src=\"${p.image_url}\" alt=\"${ui.escAttr(p.title)}\">\n                            <div class=\"ci-body\">\n                                <div class=\"ci-price\">${ui.formatPrice(p.price)}</div>\n                                <button class=\"discovery-btn btn-sm ${isSelected ? \"btn-success\" : \"btn-secondary\"} ci-add\" data-app-action=\"toggleCompareSelection\" data-arg0=\"${p.id}\" data-arg1=\"${ui.escJS(p.title)}\" data-arg2=\"${ui.escJS(p.price)}\" data-arg3=\"${p.image_url}\" data-arg4=\"${ui.escJS(p.size || \"\")}\" data-arg5=\"${ui.escJS(p.color || \"\")}\" data-arg6=\"${ui.escJS(p.style || \"\")}\" data-arg7=\"${ui.escJS(p.material || \"\")}\">${isSelected ? \"Added\" : \"Add\"}</button>\n                            </div>\n                        </div>`;\n                      })\n                      .join(\"\")}\n                </div>\n            </div>\n            <div class=\"compare-sticky-bar\">\n                <span id=\"compare-sticky-count\" style=\"font-weight:600\">${this.store.data.compare.length} Selected</span>\n                <button class=\"discovery-btn btn-primary\" data-app-action=\"executeCompareSelection\">Compare Selected</button>\n            </div>\n        `;\n    window.scrollTo(0, 0);\n\n    if (this.drawerOpen) this.toggleDrawer(); // Hide chat so they can select\n  }\n\n  toggleCompareSelection(\n    id,\n    title,\n    price,\n    imgUrl,\n    size,\n    color,\n    style,\n    material,\n    btn,\n  ) {\n    const item = { id, title, price, imgUrl, size, color, style, material };\n    const exists = this.store.data.compare.some((c) => c.id === id);\n\n    if (exists) {\n      this.store.removeFromCompare(id);\n      btn.textContent = \"Add\";\n      btn.className = \"discovery-btn btn-sm btn-secondary ci-add\";\n      btn.closest(\".compare-item\").style.borderColor = \"var(--color-border)\";\n    } else {\n      const added = this.store.addToCompare(item);\n      if (added) {\n        btn.textContent = \"Added\";\n        btn.className = \"discovery-btn btn-sm btn-success ci-add\";\n        btn.closest(\".compare-item\").style.borderColor = \"var(--color-success)\";\n      } else {\n        this.toast(\"Compare list is full (max 4)\");\n      }\n    }\n\n    const countSpan = document.getElementById(\"compare-sticky-count\");\n    if (countSpan)\n      countSpan.textContent = `${this.store.data.compare.length} Selected`;\n  }\n\n  executeCompareSelection() {\n    if (this.store.data.compare.length < 2) {\n      this.toast(\"Please select at least 2 rugs to compare.\");\n      return;\n    }\n    this._openComparisonRoom();\n  }\n\n  _openComparisonRoom() {\n    const items = this.store.data.compare;\n    this.store.updateFacts({\n      comparison_room: true,\n      comparison_room_rugs: items,\n    });\n\n    //\n    //\n    let cr = document.getElementById(\"comparison-room\");\n    if (!cr) {\n      cr = document.createElement(\"div\");\n      cr.id = \"comparison-room\";\n      cr.className = \"view-section\";\n      document.getElementById(\"main-content\").appendChild(cr);\n    }\n    cr.style.display = \"block\";\n    cr.innerHTML = `\n            <div class=\"container comparison-room-container\" style=\"padding-top:var(--space-2xl); padding-bottom: 80px;\">\n                <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-lg);\">\n                    <h2 style=\"margin:0;\"><i class=\"fa fa-balance-scale\"></i> Comparison Room</h2>\n                    <button class=\"discovery-btn btn-secondary btn-sm\" data-app-action=\"exitComparisonRoom\"><i class=\"fa fa-arrow-left\"></i> Exit Comparison Room</button>\n                </div>\n                \n                <div class=\"comparison-cards\">\n                    ${items\n                      .map(\n                        (p, i) => `\n                        <div class=\"comparison-card\">\n                            <img src=\"${p.imgUrl || p.image_url}\" alt=\"${this.ui.escAttr(p.title)}\" onerror=\"this.style.display='none'\">\n                            <div class=\"cc-info\">\n                                <div class=\"cc-number\">Rug ${i + 1}:</div>\n                                <h3 class=\"cc-title\">${this.ui.esc(p.title)}</h3>\n                                <div class=\"cc-rating\"><i class=\"fa fa-star\" style=\"color:#2f6b49\"></i><i class=\"fa fa-star\" style=\"color:#2f6b49\"></i><i class=\"fa fa-star\" style=\"color:#2f6b49\"></i><i class=\"fa fa-star\" style=\"color:#2f6b49\"></i><i class=\"fa fa-star-half-alt\" style=\"color:#2f6b49\"></i> <span style=\"font-size:13px; color:#555;\">(4.8, 112 reviews)</span></div>\n                                <p class=\"cc-desc\">${this.ui.esc(p.style || \"Premium Area Rug\")}</p>\n                                <button class=\"discovery-btn btn-ghost cc-quick-view\" style=\"width:100%; border: 1px solid #ccc; margin-bottom:8px;\" data-app-action=\"openProduct\" data-arg0=\"${p.id}\">Quick View</button>\n                                <button class=\"discovery-btn btn-primary cc-add-cart\" style=\"width:100%; background:#5b8a6a; border-color:#5b8a6a;\" data-app-action=\"quickAddProduct\" data-arg0=\"${p.id}\">Add to Cart</button>\n                            </div>\n                        </div>\n                    `,\n                      )\n                      .join(\"\")}\n                </div>\n\n                <h3 class=\"comparison-table-heading\">COMPARISON TABLE</h3>\n                <div class=\"comparison-table-wrapper\">\n                    <table class=\"comparison-detailed-table\">\n                        <tbody>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-dollar-sign\"></i> PRICE</td>\n                                ${items.map((p) => `<td>${this.ui.formatPrice(p.price)}</td>`).join(\"\")}\n                            </tr>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-layer-group\"></i> MATERIAL</td>\n                                ${items.map((p) => `<td>${this.ui.esc(p.material || \"100% Polypropylene, Machine-woven\")}</td>`).join(\"\")}\n                            </tr>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-expand-arrows-alt\"></i> SIZE</td>\n                                ${items.map((p) => `<td>${this.ui.esc(p.size || \"8' x 10' Rectangle\")}</td>`).join(\"\")}\n                            </tr>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-folder\"></i> COLLECTION</td>\n                                ${items.map((p) => `<td>${this.ui.esc(p.collection || p.style || \"Heritage Collection\")}</td>`).join(\"\")}\n                            </tr>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-palette\"></i> COLOR PALETTE</td>\n                                ${items.map((p) => `<td>${this.ui.esc(p.color || \"Sapphire Blue, Cream\")}</td>`).join(\"\")}\n                            </tr>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-shield-alt\"></i> DURABILITY</td>\n                                ${items.map((p) => `<td>High, suitable for high traffic</td>`).join(\"\")}\n                            </tr>\n                            <tr>\n                                <td class=\"attr-label\"><i class=\"fa fa-tint\"></i> CARE INSTRUCTIONS</td>\n                                ${items.map((p) => `<td>Professional clean, regular vacuum</td>`).join(\"\")}\n                            </tr>\n                        </tbody>\n                    </table>\n                </div>\n            </div>\n        `;\n    if (!this.drawerOpen) this.toggleDrawer();\n    this._addMsg(\n      `You are now in the <strong>Comparison Room</strong> with ${items.length} rugs. What would you like to know to help you decide?`,\n      \"assistant\",\n      true,\n    );\n    const actionChips = [\n      \"Which is most durable?\",\n      \"Which is best for kids?\",\n      \"Which is the softest?\",\n      \"Compare prices\",\n      \"Compare materials\",\n      \"Show me a table\",\n    ];\n    this._addMsg(this.ui.chips(actionChips), \"assistant\", true);\n    this._syncContext();\n    window.scrollTo(0, 0);\n  }\n\n  exitComparisonRoom() {\n    this.store.updateFacts({\n      comparison_room: false,\n      comparison_room_rugs: null,\n    });\n    const cr = document.getElementById(\"comparison-room\");\n    if (cr) cr.style.display = \"none\";\n    this.goHome();\n  }\n\n  // --- Live Chat Handoff ---\n  _openLiveChat() {\n    const chatHost = document.querySelector(\"shopify-chat\");\n    let opened = false;\n\n    // Check for public API first (if Shopify Inbox adds one in the future)\n    if (\n      window.Shopify &&\n      window.Shopify.Inbox &&\n      typeof window.Shopify.Inbox.open === \"function\"\n    ) {\n      window.Shopify.Inbox.open();\n      opened = true;\n    } else if (chatHost && chatHost.shadowRoot) {\n      // Fallback: Simulate click on shadow DOM activator\n      const activator = chatHost.shadowRoot.querySelector(\n        '[part=\"activator\"], button',\n      );\n      if (activator) {\n        activator.click();\n        opened = true;\n\n        // Verify/retry if aria-expanded didn't flip\n        setTimeout(() => {\n          if (activator.getAttribute(\"aria-expanded\") === \"false\") {\n            activator.click();\n          }\n        }, 300);\n      }\n    }\n\n    if (opened) {\n      this.toast(\"Opening live chat...\");\n      if (this.drawerOpen) this.toggleDrawer(); // Hide our AI chat so user can see human chat\n    } else {\n      this._addMsg(\n        \"I couldn't open the live chat widget directly. Please look for the chat icon on your screen or use our Contact page.\",\n        \"assistant\",\n      );\n    }\n  }\n\n  // --- Visualizer ---\n  openVisualizerDirectly() {\n    if (!this.contextProduct) return;\n    \n    let rawRug = this.contextProduct.imgUrl ||\n      this.contextProduct.image_url ||\n      this.contextProduct.image ||\n      this.contextProduct.featured_image ||\n      \"\";\n\n    let extractedRugUrl = \"\";\n    if (typeof rawRug === 'string') {\n      extractedRugUrl = rawRug;\n    } else if (rawRug && typeof rawRug === 'object') {\n      extractedRugUrl = rawRug.src || rawRug.url || rawRug.gcs_image_url || \"\";\n    }\n\n    const isInvalidUrl = (url) => {\n      if (!url || typeof url !== 'string') return true;\n      const clean = url.trim().toLowerCase();\n      return clean === \"\" || clean === \"no image\" || clean === \"no_image\" || clean.includes(\"no-image\") || clean.includes(\"no_image\") || clean.includes(\"placeholder\");\n    };\n\n    let extractedProductUrl = this.contextProduct.url || this.contextProduct.product_url || this.contextProduct.uri || \"\";\n    let extractedHandle = this.contextProduct.handle || this.contextProduct.shopify_handle || \"\";\n    if (!extractedHandle && extractedProductUrl) {\n      const match = extractedProductUrl.match(/\\/products\\/([^\\/\\?#]+)/);\n      if (match) extractedHandle = match[1];\n    }\n    if (extractedHandle) {\n      extractedHandle = String(extractedHandle).replace(/^owfam-/, '').replace(/^\\/products\\//, '').split('?')[0].split('#')[0].trim();\n    }\n\n    const currentPdpHandle = window.location.pathname.includes('/products/')\n      ? (window.location.pathname.split('/products/')[1] || '').split('?')[0].split('/')[0].replace(/^owfam-/, '').trim()\n      : '';\n    const isCurrentPdpProduct = Boolean(\n      currentPdpHandle && extractedHandle && (\n        currentPdpHandle === extractedHandle ||\n        currentPdpHandle === extractedHandle.replace(/^owfam-/, '').trim()\n      )\n    );\n\n    // Only fallback to PDP DOM image if extractedRugUrl is invalid OR if this product IS the current PDP product and missing image\n    if (isInvalidUrl(extractedRugUrl) || (isCurrentPdpProduct && isInvalidUrl(extractedRugUrl))) {\n      const pdpBtn = document.querySelector('#pdp-see-in-room, .pdp-view-in-room .see-in-room-btn, [data-rug]');\n      if (pdpBtn) {\n        const btnRug = pdpBtn.getAttribute('data-rug') || pdpBtn.dataset.rug || '';\n        if (!isInvalidUrl(btnRug)) {\n          extractedRugUrl = btnRug;\n        }\n      }\n      if (isInvalidUrl(extractedRugUrl) && window.RugVariantData && window.RugVariantData.images) {\n        const selectedVarId = this._selectedVariantIdFromPage();\n        if (selectedVarId && window.RugVariantData.images[selectedVarId]) {\n          const varImg = window.RugVariantData.images[selectedVarId];\n          if (!isInvalidUrl(varImg)) extractedRugUrl = varImg;\n        }\n        if (isInvalidUrl(extractedRugUrl)) {\n          const firstImg = Object.values(window.RugVariantData.images).find(img => !isInvalidUrl(img));\n          if (firstImg) extractedRugUrl = firstImg;\n        }\n      }\n      if (isInvalidUrl(extractedRugUrl)) {\n        const galleryImg = document.querySelector('.product__media img, .product-single__photo img, .product-gallery img, .product-card-gallery img, main img[src*=\"cdn.shopify.com\"]');\n        if (galleryImg) {\n          const src = galleryImg.getAttribute('data-current-url') || galleryImg.currentSrc || galleryImg.src || '';\n          if (!isInvalidUrl(src)) extractedRugUrl = src;\n        }\n      }\n    }\n\n    if (extractedRugUrl && extractedRugUrl.startsWith('//')) {\n      extractedRugUrl = 'https:' + extractedRugUrl;\n    }\n\n    let transformedVariantData = null;\n    if (this.contextProduct.variants && Array.isArray(this.contextProduct.variants)) {\n      const sizes = {}; const shapes = {}; const colors = {}; const images = {}; const availability = {};\n      const prodOptions = Array.isArray(this.contextProduct.options) ? this.contextProduct.options : [];\n      const sizeIdx = prodOptions.findIndex(o => (typeof o === 'string' ? o : o.name || '').toLowerCase() === 'size');\n      const shapeIdx = prodOptions.findIndex(o => (typeof o === 'string' ? o : o.name || '').toLowerCase() === 'shape');\n      const colorIdx = prodOptions.findIndex(o => (typeof o === 'string' ? o : o.name || '').toLowerCase() === 'color');\n\n      this.contextProduct.variants.forEach(v => {\n        const vOpts = Array.isArray(v.options) ? v.options : [v.option1, v.option2, v.option3].filter(Boolean);\n        sizes[v.id] = (sizeIdx !== -1 && vOpts[sizeIdx]) ? vOpts[sizeIdx] : (v.option1 || v.title || \"\");\n        shapes[v.id] = (shapeIdx !== -1 && vOpts[shapeIdx]) ? vOpts[shapeIdx] : (v.option2 || \"\");\n        colors[v.id] = (colorIdx !== -1 && vOpts[colorIdx]) ? vOpts[colorIdx] : (v.option3 || \"\");\n        let vImg = v.primary_image_url || v.image_url || (v.image && (v.image.src || v.image)) \n          || v.featured_image?.src || v.featured_image || extractedRugUrl;\n        if (vImg && vImg.startsWith('//')) vImg = 'https:' + vImg;\n        images[v.id] = vImg;\n        availability[v.id] = v.available !== false;\n      });\n      transformedVariantData = { \n        sizes, \n        shapes, \n        colors, \n        images, \n        availability, \n        isRecommendation: !isCurrentPdpProduct,\n        productUrl: extractedProductUrl || `/products/${extractedHandle}`\n      };\n    }\n\n    const activeVid = this.contextProduct.variant_id || this.contextProduct.variantId || (this.contextProduct.variants && this.contextProduct.variants[0]?.id);\n    if (activeVid) window.activeVisualizerVariantId = String(activeVid);\n\n    const launchParams = {\n      source: \"assistant\",\n      productId: this.contextProduct.id || \"\",\n      productHandle: extractedHandle,\n      variantId: activeVid ? String(activeVid) : \"\",\n      rugUrl: extractedRugUrl,\n      productUrl: extractedProductUrl,\n      sizeStr: this.contextProduct.size || \"\",\n      shapeStr: this.contextProduct.shape || this.contextProduct.style || \"\",\n      variantData: transformedVariantData, // Transformed for the visualizer\n      forceRoomManager: true,\n      onLoading: (msg) =>\n        this._addMsg(msg || \"Preparing your room preview...\", \"assistant\"),\n      onError: (msg) => {\n        this._addMsg(\n          msg ||\n            \"Sorry, we couldn't load the room visualizer. Please try again.\",\n          \"assistant\",\n        );\n      },\n    };\n\n    if (this.drawerOpen) {\n      this.toggleDrawer();\n    }\n\n    window.activeVisualizerSource = \"assistant\";\n    window.activeVisualizerProductHandle = extractedHandle;\n    window.activeVisualizerProductId = this.contextProduct.id || \"\";\n    window.activeVisualizerRugUrl = extractedRugUrl;\n    window.activeVisualizerVariantData = transformedVariantData;\n    window.activeVisualizerSize = this.contextProduct.size || \"\";\n    window.activeVisualizerShape = this.contextProduct.shape || this.contextProduct.style || \"\";\n\n    if (!window.activeVisualizerButton && typeof document !== \"undefined\") {\n      const cardBtn = document.querySelector(\n        `[data-id=\"${this.contextProduct.id}\"][data-is-chat-card=\"true\"], [data-product-handle=\"${extractedHandle}\"][data-is-chat-card=\"true\"], .see-in-room-btn[data-id=\"${this.contextProduct.id}\"]`\n      );\n      if (cardBtn) window.activeVisualizerButton = cardBtn;\n    }\n    if (window.activeVisualizerButton && !window.activeVisualizerButton.getAttribute(\"data-is-chat-card\")) {\n      window.activeVisualizerButton.setAttribute(\"data-is-chat-card\", \"true\");\n    }\n\n    window.pendingSeeInRoom = {\n      source: \"assistant\",\n      rugUrl: launchParams.rugUrl,\n      productUrl: launchParams.productUrl,\n      productHandle: extractedHandle,\n      variantId: activeVid ? String(activeVid) : \"\",\n      sizeStr: launchParams.sizeStr,\n      shapeStr: launchParams.shapeStr,\n    };\n\n    if (typeof window.launchUnifiedVisualizer === \"function\") {\n      window.launchUnifiedVisualizer(launchParams).catch((err) => {\n        console.error(\"Room visualizer launch failed:\", err);\n        launchParams.onError();\n      });\n    } else if (typeof window.openRoomManager === \"function\") {\n      window.openRoomManager({ rugUrl: launchParams.rugUrl });\n    } else {\n      this.toast(\"Room visualizer is not available on this page.\");\n    }\n  }\n\n  _triggerVisualizer(mode) {\n    const actualMode = mode || (this.contextProduct ? \"visualize\" : \"analyze\");\n\n    if (actualMode === \"visualize\") {\n      if (!this.contextProduct) {\n        this._addMsg(\n          \"Please select a rug first before visualizing it in your room.\",\n          \"assistant\",\n        );\n        return;\n      }\n      if (this._requestVisualizerSize(this.contextProduct)) return;\n      if (typeof window.openRoomManager === \"function\") {\n        this._launchRoomManagerForProduct(this.contextProduct);\n        return;\n      }\n      this._addMsg(this.ui.visualizerUpload(\"visualize\"), \"assistant\", true);\n      setTimeout(() => {\n        const drops = document.querySelectorAll(\".viz-drop\");\n        const drop = drops[drops.length - 1];\n        if (!drop) return;\n        const fileInput = drop.nextElementSibling;\n        const analyzeBtn = fileInput.nextElementSibling;\n\n        drop.addEventListener(\"click\", () => {\n          fileInput.click();\n        });\n        drop.addEventListener(\"keydown\", (e) => {\n          if (e.key === \"Enter\" || e.key === \" \") {\n            e.preventDefault();\n            fileInput.click();\n          }\n        });\n        drop.addEventListener(\"dragover\", (e) => {\n          e.preventDefault();\n          drop.style.borderColor = \"var(--color-accent)\";\n          drop.classList.add(\"drag-over\");\n        });\n        drop.addEventListener(\"dragleave\", () => {\n          drop.style.borderColor = \"var(--color-border)\";\n          drop.classList.remove(\"drag-over\");\n        });\n        drop.addEventListener(\"drop\", (e) => {\n          e.preventDefault();\n          drop.style.borderColor = \"var(--color-border)\";\n          drop.classList.remove(\"drag-over\");\n          if (e.dataTransfer.files.length) {\n            fileInput.files = e.dataTransfer.files;\n            this._previewFile(\n              fileInput.files[0],\n              drop,\n              analyzeBtn,\n              \"visualize\",\n            );\n          }\n        });\n        fileInput.addEventListener(\"change\", () => {\n          if (fileInput.files.length)\n            this._previewFile(\n              fileInput.files[0],\n              drop,\n              analyzeBtn,\n              \"visualize\",\n            );\n        });\n      }, 100);\n      return;\n    }\n\n    // Analyze Room is intentionally separate from See in My Room:\n    // it uploads one room photo, extracts room facts, and suggests rugs.\n    this._addMsg(this.ui.visualizerUpload(\"analyze\"), \"assistant\", true);\n    setTimeout(() => {\n      const drops = document.querySelectorAll(\".viz-drop\");\n      const drop = drops[drops.length - 1];\n      if (!drop) return;\n      const fileInput = drop.nextElementSibling;\n      const analyzeBtn = fileInput.nextElementSibling;\n\n      drop.addEventListener(\"click\", () => {\n        fileInput.click();\n      });\n      drop.addEventListener(\"keydown\", (e) => {\n        if (e.key === \"Enter\" || e.key === \" \") {\n          e.preventDefault();\n          fileInput.click();\n        }\n      });\n      drop.addEventListener(\"dragover\", (e) => {\n        e.preventDefault();\n        drop.classList.add(\"drag-over\");\n      });\n      drop.addEventListener(\"dragleave\", () =>\n        drop.classList.remove(\"drag-over\"),\n      );\n      drop.addEventListener(\"drop\", (e) => {\n        e.preventDefault();\n        drop.classList.remove(\"drag-over\");\n        if (e.dataTransfer.files.length) {\n          fileInput.files = e.dataTransfer.files;\n          this._previewFile(fileInput.files[0], drop, analyzeBtn, \"analyze\");\n        }\n      });\n      fileInput.addEventListener(\"change\", () => {\n        if (fileInput.files.length)\n          this._previewFile(fileInput.files[0], drop, analyzeBtn, \"analyze\");\n      });\n    }, 100);\n  }\n\n  _previewFile(file, drop, btn, mode) {\n    const reader = new FileReader();\n    reader.onload = (e) => {\n      drop.classList.add(\"has-file\");\n      drop.innerHTML = `<img src=\"${e.target.result}\" class=\"viz-preview-img\" alt=\"Selected room photo preview\">\n                <div class=\"viz-file-meta\">\n                    <strong>${this.ui.esc(file.name)}</strong>\n                    <small>Ready to ${mode === \"visualize\" ? \"visualize this rug\" : \"analyze this room\"}</small>\n                </div>\n                <span class=\"discovery-btn btn-secondary btn-sm viz-file-label\"><i class=\"fa fa-sync-alt\"></i> Choose different photo</span>`;\n    };\n    reader.readAsDataURL(file);\n    btn.disabled = false;\n    btn.onclick = () => this._analyzeRoom(file, mode);\n  }\n\n  async _analyzeRoom(file, mode) {\n    const loadId = \"load-\" + Date.now();\n    const isVisualizing = mode === \"visualize\";\n\n    if (isVisualizing && !this.contextProduct) {\n      this._addMsg(\n        \"Please select a rug first before visualizing it in your room.\",\n        \"assistant\",\n      );\n      return;\n    }\n\n    const msg = isVisualizing\n      ? \"Visualizing rug in your room\u2026\"\n      : \"Analyzing your room\u2026\";\n    this._addMsg(\n      `<div style=\"display:flex;align-items:center;gap:var(--space-xs)\"><i class=\"fa fa-spinner fa-spin\" aria-hidden=\"true\"></i> ${msg}</div>`,\n      \"assistant\",\n      true,\n      loadId,\n    );\n    try {\n      const data = await this.api.analyzeImage(file, {\n        skipVisualizerPoints: !isVisualizing,\n      });\n      this._removeMsg(loadId);\n\n      // Draw AR Rug Overlay or Open JS Visualizer\n      if (data.points && data.points.length > 0 && isVisualizing) {\n        if (typeof window.handleAnalyzerSuccess === \"function\") {\n          this._addMsg(\"Opening the room manager...\", \"assistant\");\n          await window.handleAnalyzerSuccess(data, file, false);\n        } else {\n          this._drawAROverlay(file, data.points);\n          this._addMsg(\"Here is how the rug looks in your space!\", \"assistant\");\n        }\n      } else if (isVisualizing) {\n        this._addMsg(\"Here is how the rug looks in your space!\", \"assistant\");\n      }\n\n      if (isVisualizing) {\n        if (data.facts) {\n          this.store.updateFacts(data.facts, true);\n          this.store.addUploadedPhoto(file, data.facts);\n          this._syncContext();\n        }\n      } else {\n        this._addMsg(this.ui.roomAnalysis(data), \"assistant\", true);\n        const roomFacts = this._factsFromRoomAnalysis(data);\n        if (Object.keys(roomFacts).length) {\n          this.store.updateFacts(roomFacts, true);\n          this.store.addUploadedPhoto(file, roomFacts);\n          this._syncContext();\n          this._addMsg(\"Here are rugs that match your room:\", \"assistant\");\n          await this._doBrowse(roomFacts, 6);\n        } else {\n          this._addMsg(\n            \"I analyzed the photo, but did not get enough room details to filter rugs. Try a wider, brighter room photo.\",\n            \"assistant\",\n          );\n        }\n      }\n    } catch (err) {\n      this._removeMsg(loadId);\n      console.error(\"Room analysis error:\", err);\n      const errMsg = isVisualizing\n        ? \"We hit a snag visualizing the rug. Could you try a clearer photo or different angle?\"\n        : \"We hit a snag analyzing your room. Could you try a clearer photo or different angle?\";\n      this._addMsg(errMsg, \"assistant\");\n    }\n  }\n\n  _factsFromRoomAnalysis(data = {}) {\n    const facts = data.facts || data.payload?.facts || data.filter_state || {};\n    return Object.fromEntries(\n      Object.entries(facts).filter(\n        ([key, value]) =>\n          key &&\n          !key.startsWith(\"_\") &&\n          value !== undefined &&\n          value !== null &&\n          value !== \"\",\n      ),\n    );\n  }\n\n  _drawAROverlay(file, points) {\n    const drop = document.getElementById(\"viz-drop\");\n    const imgUrl = this.contextProduct ? this.contextProduct.imgUrl : null;\n    if (!drop || !imgUrl) return;\n\n    const reader = new FileReader();\n    reader.onload = (e) => {\n      const bgImg = new Image();\n      bgImg.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        canvas.width = bgImg.width;\n        canvas.height = bgImg.height;\n        canvas.style.maxWidth = \"100%\";\n        canvas.style.borderRadius = \"var(--radius-sm)\";\n        const ctx = canvas.getContext(\"2d\");\n\n        // Draw room\n        ctx.drawImage(bgImg, 0, 0);\n\n        // Draw rug polygon\n        const rugImg = new Image();\n        rugImg.crossOrigin = \"Anonymous\";\n        rugImg.onload = () => {\n          ctx.save();\n          ctx.beginPath();\n          // Sort points clockwise to prevent bow-tie clipping masks\n          const center = points\n            .reduce((acc, p) => [acc[0] + p[0], acc[1] + p[1]], [0, 0])\n            .map((val) => val / points.length);\n          const sortedPoints = [...points].sort((a, b) => {\n            return (\n              Math.atan2(a[1] - center[1], a[0] - center[0]) -\n              Math.atan2(b[1] - center[1], b[0] - center[0])\n            );\n          });\n          sortedPoints.forEach((p, i) => {\n            const x = p[0] <= 1 ? p[0] * canvas.width : p[0];\n            const y = p[1] <= 1 ? p[1] * canvas.height : p[1];\n            if (i === 0) ctx.moveTo(x, y);\n            else ctx.lineTo(x, y);\n          });\n          ctx.closePath();\n          ctx.clip();\n          // Basic bounding box for the image mapping\n          const xs = points.map((p) =>\n            p[0] <= 1 ? p[0] * canvas.width : p[0],\n          );\n          const ys = points.map((p) =>\n            p[1] <= 1 ? p[1] * canvas.height : p[1],\n          );\n          const minX = Math.min(...xs),\n            maxX = Math.max(...xs);\n          const minY = Math.min(...ys),\n            maxY = Math.max(...ys);\n          ctx.globalCompositeOperation = \"multiply\";\n          ctx.drawImage(rugImg, minX, minY, maxX - minX, maxY - minY);\n          ctx.restore();\n        };\n        rugImg.src = imgUrl;\n\n        drop.innerHTML = \"\";\n        drop.appendChild(canvas);\n        drop.insertAdjacentHTML(\n          \"beforeend\",\n          `<p style=\"font-size:var(--text-xs);color:var(--color-text-muted);margin-top:var(--space-xs)\">AR Overlay Rendered</p>`,\n        );\n      };\n      bgImg.src = e.target.result;\n    };\n    reader.readAsDataURL(file);\n  }\n\n  // --- PDP ---\n  openProduct(id, fallbackUrl = null) {\n    const p = this.productCatalog.get(String(id));\n    if (!p && !fallbackUrl) {\n      this.toast(\n        \"Product details are no longer available. Refresh the results and try again.\",\n      );\n      return;\n    }\n\n    // Save state to pre-open the agent on the next page\n    sessionStorage.setItem(\"rugbie_open_agent_on_load\", \"true\");\n\n    // Navigate to the product page\n    if (p) {\n      const handle = p.handle || p.shopify_handle || p.id;\n      window.location.href = p.url || `/products/${handle}`;\n    } else {\n      window.location.href = fallbackUrl;\n    }\n  }\n\n  openStoredProduct(id) {\n    const cached = this.productCatalog.get(String(id));\n    const stored =\n      cached ||\n      this.store.data.viewed.find((item) => String(item.id) === String(id));\n    if (!stored) {\n      this.toast(\"Product details are no longer available.\");\n      return;\n    }\n\n    // Save state to pre-open the agent on the next page\n    sessionStorage.setItem(\"rugbie_open_agent_on_load\", \"true\");\n\n    // Navigate to the product page\n    const handle = stored.handle || stored.shopify_handle || stored.id;\n    window.location.href = stored.url || `/products/${handle}`;\n  }\n\n  _isAddToCartQuery(text = \"\") {\n    return /\\b(add|put|place)\\b.*\\b(cart|bag)\\b|\\bbuy this\\b|\\badd to cart\\b/i.test(\n      text,\n    );\n  }\n\n  _isCartCompareQuery(text = \"\") {\n    return /\\bcompare\\b/i.test(text) && /\\b(cart|bag|items?)\\b/i.test(text);\n  }\n\n  _isCartContentsQuery(text = \"\") {\n    const normalized = String(text || \"\")\n      .toLowerCase()\n      .replace(/[^\\w\\s]/g, \" \")\n      .replace(/\\s+/g, \" \")\n      .trim();\n    return (\n      /\\b(what|whats|what is|show|view|see|list|display|open|check|review)\\b.*\\b(cart|bag)\\b/.test(\n        normalized,\n      ) ||\n      /\\b(cart|bag)\\b.*\\b(contents?|items?|summary|details?)\\b/.test(\n        normalized,\n      ) ||\n      /^(cart|bag|my cart|my bag|show cart|view cart|cart contents)$/.test(\n        normalized,\n      )\n    );\n  }\n\n  _isCartRugPadQuery(text = \"\") {\n    return (\n      /\\brug\\s*pad\\b|\\bpad\\b/i.test(text) &&\n      /\\b(cart|need|recommend|should|use)\\b/i.test(text)\n    );\n  }\n\n  _isRugPadProduct(product = {}) {\n    const haystack = [\n      product.title,\n      product.handle,\n      product.shopify_handle,\n      product.url,\n      product.product_url,\n      product.product_type,\n      product.type,\n      product.category,\n      product.categories,\n      product.collection,\n      product.collection_name,\n      product.collections,\n      product.tags,\n      product.description,\n      product.body_html,\n      product.variants?.map?.((variant) => [\n        variant.title,\n        variant.option1,\n        variant.option2,\n        variant.option3,\n      ]),\n      product.vendor,\n    ]\n      .flat()\n      .join(\" \")\n      .toLowerCase();\n    return /\\brug\\s*pads?\\b|\\bpadding\\b|\\bcarpet\\s*pads?\\b|\\bnon[-\\s]?slip\\b|\\brug\\s*grip\\b|\\bgripper\\b|\\bunderlay\\b|\\bcushion(?:ed|ing)?\\s*pad\\b/.test(\n      haystack,\n    );\n  }\n\n  _rugPadProductsFromResponse(data) {\n    const products = data?.products || data?.payload?.products || [];\n    return (Array.isArray(products) ? products : []).filter((product) =>\n      this._isRugPadProduct(product),\n    );\n  }\n\n  _imageFromShopifySuggestProduct(product = {}) {\n    const image =\n      product.image ||\n      product.featured_image ||\n      product.image_url ||\n      product.imgUrl ||\n      \"\";\n    if (typeof image === \"string\") return image;\n    return (\n      image.url || image.src || image.originalSrc || image.transformedSrc || \"\"\n    );\n  }\n\n  _normalizeShopifySuggestProduct(product = {}) {\n    const url = product.url || product.product_url || \"\";\n    const handleFromUrl = url\n      ? String(url).split(\"/products/\")[1]?.split(/[?#/]/)[0]\n      : \"\";\n    const handle = product.handle || handleFromUrl || product.id;\n    const price =\n      product.price ||\n      product.price_min ||\n      product.min_price ||\n      product.price_varies ||\n      product.variants?.[0]?.price ||\n      \"\";\n    const imageUrl = this._imageFromShopifySuggestProduct(product);\n    return {\n      ...product,\n      id: product.id || handle,\n      handle,\n      title: product.title || product.text || product.name || \"Rug Pad\",\n      url: url || (handle ? `/products/${handle}` : \"/search?q=rug%20pad\"),\n      product_url:\n        url || (handle ? `/products/${handle}` : \"/search?q=rug%20pad\"),\n      image_url: imageUrl,\n      imgUrl: imageUrl,\n      price,\n      product_type:\n        product.product_type || product.type || product.category || \"\",\n      category: product.category || product.product_type || product.type || \"\",\n    };\n  }\n\n  async _fetchShopifySuggestProducts(query = \"rug pad\", limit = 8) {\n    try {\n      const params = new URLSearchParams({\n        q: query,\n        \"resources[type]\": \"product\",\n        \"resources[limit]\": String(limit),\n      });\n      const response = await fetch(\n        `/search/suggest.json?${params.toString()}`,\n        {\n          headers: { Accept: \"application/json\" },\n        },\n      );\n      if (!response.ok) return [];\n      const data = await response.json().catch(() => ({}));\n      const products =\n        data?.resources?.results?.products ||\n        data?.products ||\n        data?.results?.products ||\n        [];\n      return (Array.isArray(products) ? products : []).map((product) =>\n        this._normalizeShopifySuggestProduct(product),\n      );\n    } catch (err) {\n      console.warn(\"Shopify predictive rug pad search failed\", err);\n      return [];\n    }\n  }\n\n  async _fetchRugPadProducts(size = undefined, limit = 4) {\n    const baseFacts = {\n      category: [\"Rug Pad\", \"Rug Pads\"],\n      product_type: [\"Rug Pad\", \"Rug Pads\"],\n    };\n    if (size) baseFacts.size = size;\n    let products = [];\n    try {\n      const data = await this.api.browse(baseFacts, 1, limit);\n      products = this._rugPadProductsFromResponse(data);\n    } catch (err) {\n      console.warn(\"Rug pad category browse failed\", err);\n    }\n    if (!products.length) {\n      try {\n        const fallbackData = await this.api.browse(\n          {\n            query: \"rug pad non slip rug grip underlay\",\n            search_query: \"rug pad\",\n            size,\n          },\n          1,\n          Math.max(limit, 8),\n        );\n        products = this._rugPadProductsFromResponse(fallbackData);\n      } catch (err) {\n        console.warn(\"Rug pad keyword browse failed\", err);\n      }\n    }\n    if (!products.length) {\n      const seen = new Set();\n      const suggestQueries = [\n        \"rug pad\",\n        \"rug pads\",\n        \"non slip rug pad\",\n        \"rug grip\",\n        \"underlay\",\n      ];\n      for (const query of suggestQueries) {\n        const suggested = await this._fetchShopifySuggestProducts(\n          query,\n          Math.max(limit, 8),\n        );\n        suggested.forEach((product) => {\n          const key = String(\n            product.id || product.handle || product.url || product.title || \"\",\n          );\n          if (key && !seen.has(key) && this._isRugPadProduct(product)) {\n            seen.add(key);\n            products.push(product);\n          }\n        });\n        if (products.length >= limit) break;\n      }\n    }\n    return products.slice(0, limit);\n  }\n\n  _isCartCareQuery(text = \"\") {\n    return (\n      /\\b(care|clean|cleaning|wash|instructions?)\\b/i.test(text) &&\n      !/\\btrack\\b/i.test(text)\n    );\n  }\n\n  _isHistoryQuery(text = \"\") {\n    return /^(history|recently viewed|recent rugs|viewed rugs|show history)$/i.test(\n      String(text || \"\").trim(),\n    );\n  }\n\n  _handleLocalHistoryCommand(query) {\n    if (!this._isHistoryQuery(query)) return false;\n    const history = this._recentProductHistory();\n    if (history.length > 0) {\n      this._addMsg(\n        \"Here are the rugs you've recently viewed or interacted with:\",\n        \"assistant\",\n      );\n      this._addMsg(\n        this.ui.horizontalProductCarousel(history),\n        \"assistant\",\n        true,\n      );\n    } else {\n      this._addMsg(\n        \"You haven't viewed any rugs yet. Try searching or opening a rug, then I'll keep it here.\",\n        \"assistant\",\n      );\n    }\n    return true;\n  }\n\n  _handleLocalOrderTrackingCommand(query) {\n    if (!this._isOrderTrackingQuery(query)) return false;\n    this.startOrderTrackFlow();\n    return true;\n  }\n\n  _handleLocalServiceCommand(query) {\n    if (!this._isServiceIntentQuery(query)) return false;\n    \n    const wantsCostInfo = /\\b(cost|price|pricing|how much|fee|quote|estimate)\\b/i.test(query);\n    if (wantsCostInfo) {\n      this._addMsg(`For information regarding the cost of our services, please reach out to our team directly. Our staff will be happy to provide an estimate and assist you during store hours.<br><br><button class=\"discovery-btn btn-primary btn-sm\" data-app-action=\"_openStoreOwnerChat\" style=\"margin-top: 8px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font-weight: 600; padding: 10px 16px; border-radius: 6px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); border: 1px solid var(--color-border); background: var(--color-accent); color: #fff;\"><i class=\"fa fa-comments\"></i> Chat Live with Store</button>`, \"assistant\", true);\n      return true;\n    }\n\n    let initialService = null;\n    if (/\\b(stain|spill|clean|cleaning|wash|odor|pet)\\b/i.test(query)) {\n      initialService = \"Professional Rug Cleaning\";\n    } else if (/\\b(repair|restor|stitch|hole|tear|fringe|binding)\\b/i.test(query)) {\n      initialService = \"Repair & Restoration\";\n    } else if (/\\b(custom|customization|bespoke|size|sizing)\\b/i.test(query)) {\n      initialService = \"Custom Rug Sizing\";\n    } else if (/\\b(apprais|value|worth|valuation)\\b/i.test(query)) {\n      initialService = \"Rug Appraisal\";\n    } else if (/\\b(consult|appointment|consultation|in-home|visit)\\b/i.test(query)) {\n      initialService = \"In-Home Consultation\";\n    } else if (/\\b(deliver|install|installation|setup)\\b/i.test(query)) {\n      initialService = \"Delivery & Installation\";\n    }\n\n    this.startServiceFlow(initialService);\n    return true;\n  }\n\n  async _handleExplicitProductCountQuery(query) {\n    const count = this._extractRequestedProductCount(query);\n    if (!count) return false;\n    const facts = this._browseFactsForQuery(query, {\n      ...this.store.data.facts,\n    });\n    if (this._extractMaxPrice(query))\n      facts.budget = this._extractMaxPrice(query);\n    const wantsRugPads = this._isRugPadProductQuery(query);\n    await this._doBrowse(facts, count, {\n      title: `Showing ${count} ${wantsRugPads ? \"rug pads\" : \"rugs\"}`,\n      requireRugPads: wantsRugPads,\n      query,\n    });\n    return true;\n  }\n\n  async _handleRugPadProductBrowse(query) {\n    if (!this._isRugPadProductQuery(query)) return false;\n    const facts = this._browseFactsForQuery(query, {});\n    if (this._extractMaxPrice(query))\n      facts.budget = this._extractMaxPrice(query);\n    try {\n      const products = await this._fetchRugPadProducts(facts?.size, 4);\n      const filtered = this._productsForBudget(products, query, facts);\n      if (filtered.products.length) {\n        this.registerProducts(filtered.products);\n        this.currentBrowseResults = filtered.products;\n        this._addMsg(\n          this.ui.horizontalProductCarousel(\n            filtered.products.slice(0, 4),\n            \"Recommended Rug Pads\",\n          ),\n          \"assistant\",\n          true,\n        );\n      } else if (products.length && filtered.maxPrice) {\n        this._addMsg(\n          `I found rug pads, but none were under ${this.ui.formatPrice(filtered.maxPrice)}. Try a higher budget or fewer filters.`,\n          \"assistant\",\n        );\n      } else {\n        this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n      }\n    } catch (err) {\n      console.warn(\"Rug pad product browse failed\", err);\n      this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n    }\n    return true;\n  }\n\n  _cartItemsForCompare(cartItems) {\n    return (cartItems || []).map((item) => ({\n      id: item.product_id || item.id || item.variant_id,\n      variant_id: item.variant_id,\n      title: item.title,\n      price: item.price,\n      size: item.size,\n      color: item.color || \"\",\n      style: item.style || \"\",\n      material: item.material || \"\",\n      imgUrl: item.imgUrl || item.image,\n      image_url: item.imgUrl || item.image,\n      url: item.url || item.product_url,\n      handle: item.handle,\n    }));\n  }\n\n  async _handleLocalCartCommand(query) {\n    if (\n      !this._isCartContentsQuery(query) &&\n      !this._isCartCompareQuery(query) &&\n      !this._isCartRugPadQuery(query) &&\n      !this._isCartCareQuery(query)\n    ) {\n      return false;\n    }\n\n    const cartItems = await this._refreshCartMemory();\n    const activeProduct = this._getActiveProduct();\n\n    if (!cartItems.length) {\n      if (this._isCartCareQuery(query)) {\n        if (activeProduct) {\n          const title = `Care guide for ${activeProduct.title || \"this rug\"}`;\n          this._addMsg(\n            this.ui.cartCareCard([activeProduct], title),\n            \"assistant\",\n            true,\n          );\n        } else {\n          this._addMsg(\n            this.ui.knowledgeCard(\n              \"Rug Care & Cleaning Guide\",\n              `<p>Here are essential care instructions for keeping your rugs in top condition:</p>\n              <ul>\n                <li><strong>Regular Vacuuming:</strong> Vacuum regularly without a beater bar to avoid pulling fibers.</li>\n                <li><strong>Spot Cleaning:</strong> Blot spills immediately with a clean, dry white cloth. Never rub.</li>\n                <li><strong>Deep Clean:</strong> Rotate every 6 months for even wear. For tough stains, professional cleaning is recommended.</li>\n              </ul>\n              <p style=\"margin-top:8px\">Open any rug page to see care guidance specific to its material!</p>`,\n              \"fa-droplet\"\n            ),\n            \"assistant\",\n            true\n          );\n        }\n        return true;\n      }\n      if (this._isCartRugPadQuery(query)) {\n        if (activeProduct) {\n          this._addMsg(this.ui.rugPadAdviceCard([activeProduct]), \"assistant\", true);\n          try {\n            const sizes = this._availableSizesForProduct(activeProduct);\n            const products = await this._fetchRugPadProducts(\n              sizes.length ? sizes : undefined,\n              4,\n            );\n            if (products.length)\n              this._addMsg(\n                this.ui.horizontalProductCarousel(\n                  products.slice(0, 4),\n                  \"Recommended Rug Pads\",\n                ),\n                \"assistant\",\n                true,\n              );\n            else this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n          } catch (e) {\n            console.warn(\"Rug pad search failed\", e);\n            this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n          }\n          return true;\n        }\n      }\n      this._addMsg(\n        \"Your cart is empty right now. Add a rug first, then I can suggest a rug pad.\",\n        \"assistant\",\n      );\n      return true;\n    }\n\n    if (this._isCartContentsQuery(query)) {\n      this._addMsg(this.ui.cartStateCard(cartItems), \"assistant\", true);\n      return true;\n    }\n\n    if (this._isCartCompareQuery(query)) {\n      this._addMsg(\n        \"I can help you choose based on size, care, material, or price, but this assistant does not compare cart items side by side.\",\n        \"assistant\",\n      );\n      this._addMsg(this.ui.cartStateCard(cartItems), \"assistant\", true);\n      return true;\n    }\n\n    if (this._isCartRugPadQuery(query)) {\n      this._addMsg(this.ui.rugPadAdviceCard(cartItems), \"assistant\", true);\n      try {\n        const sizes = [\n          ...new Set(cartItems.map((item) => item.size).filter(Boolean)),\n        ];\n        const products = await this._fetchRugPadProducts(\n          sizes.length ? sizes[0] : undefined,\n          4,\n        );\n        if (products.length)\n          this._addMsg(\n            this.ui.horizontalProductCarousel(\n              products.slice(0, 4),\n              \"Recommended Rug Pads\",\n            ),\n            \"assistant\",\n            true,\n          );\n        else this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n      } catch (e) {\n        console.warn(\"Rug pad search failed\", e);\n        this._addMsg(this.ui.rugPadFallbackCard(), \"assistant\", true);\n      }\n      return true;\n    }\n\n    if (this._isCartCareQuery(query)) {\n      if (activeProduct && !/\\bcart\\b/i.test(query)) {\n        const title = `Care guide for ${activeProduct.title || \"this rug\"}`;\n        this._addMsg(\n          this.ui.cartCareCard([activeProduct], title),\n          \"assistant\",\n          true,\n        );\n      } else {\n        this._addMsg(this.ui.cartCareCard(cartItems), \"assistant\", true);\n      }\n      return true;\n    }\n\n    return false;\n  }\n\n  _isProductSeekingQuery(text = \"\") {\n    return (\n      /\\b(show|find|search|browse|recommend|looking for|need|want)\\b/i.test(\n        text,\n      ) &&\n      /\\b(rug|rugs|runner|pad|carpet|blue|red|green|washable|wool|jute|outdoor|indoor|cheap|under)\\b/i.test(\n        text,\n      )\n    );\n  }\n\n  _availableSizesForProduct(product = {}) {\n    const sizes = [];\n    if (Array.isArray(product.variants)) {\n      product.variants.forEach((v) => {\n        let title =\n          this._variantOption(product, v, \"Size\") || v.option1 || v.title;\n        \n        if (title && title.includes(\"/\")) {\n          const parts = title.split(\"/\").map((p) => p.trim());\n          const sizePart = parts.find(\n            (p) => /\\d+['\"]/.test(p) || (p.toLowerCase().includes('x') && /\\d/.test(p))\n          );\n          if (sizePart) title = sizePart;\n        }\n\n        if (title && String(title).toLowerCase() !== \"default title\")\n          sizes.push(title);\n      });\n    }\n    if (\n      product.size &&\n      String(product.size).toLowerCase() !== \"default title\"\n    ) {\n      if (!product.size.includes(\"/\") || sizes.length === 0) {\n        sizes.push(product.size);\n      }\n    }\n    if (Array.isArray(product.sizes)) sizes.push(...product.sizes);\n    return [...new Set(sizes.map((s) => String(s).trim()).filter(Boolean))];\n  }\n\n  _findSizeFromText(text = \"\", product = null) {\n    const normalizeStr = (s) =>\n      String(s)\n        .toLowerCase()\n        .replace(/[\\s\\-_]+/g, \" \")\n        .replace(/[\"'\u201D\u2019]/g, \"\")\n        .trim();\n    const normalized = normalizeStr(text);\n    const knownSizes = product ? this._availableSizesForProduct(product) : [];\n    const exact = knownSizes.find((size) =>\n      normalized.includes(normalizeStr(size)),\n    );\n    if (exact) return exact;\n    const normalizedForRegex = String(text).toLowerCase().trim();\n    const match = normalizedForRegex.match(\n      /(\\d{1,2})\\s*(?:'|ft|feet|\")?\\s*(?:x|by|x)\\s*(\\d{1,2})\\s*(?:'|ft|feet|\")?/i,\n    );\n    return match ? `${match[1]}' x ${match[2]}'` : \"\";\n  }\n\n  async _handleLocalCommerceIntent(query) {\n    if (/\\b(store\\s+(hours|time|timing|schedule)|opening\\s+hours|when\\s+are\\s+you\\s+open|business\\s+hours)\\b/i.test(query)) {\n      const shopName = window.ShopifyContextPayload?.shop?.name || \"Vogue Rugs\";\n      this._addMsg(\n        `<strong>${this.ui.esc(shopName)} Store Hours:</strong><br/>` +\n        `\u2022 Monday - Saturday: 10:00 AM - 6:00 PM<br/>` +\n        `\u2022 Sunday: Closed<br/>` +\n        `\u2022 Online Store: Open 24/7`,\n        \"assistant\",\n        true\n      );\n      return true;\n    }\n\n    if (/\\b(show|see|find|get)?\\s*similar\\s*(rugs|styles|products|items)?\\b/i.test(query) || /^\\s*similar\\s*$/i.test(query)) {\n      const activeProduct = this._getActiveProduct();\n      await this._showSimilarRugs(activeProduct);\n      return true;\n    }\n\n    if (this.pendingCartIntent) {\n      const size = this._findSizeFromText(\n        query,\n        this.pendingCartIntent.product,\n      );\n      if (!size) return false;\n      const product = {\n        ...this.pendingCartIntent.product,\n        size,\n        sizeSelected: true,\n        selectedSizeExplicit: true,\n      };\n      this.pendingCartIntent = null;\n      await this._addProductToCartWithSize(product, null);\n      return true;\n    }\n\n    if (this.pendingVisualizerIntent) {\n      const size = this._findSizeFromText(\n        query,\n        this.pendingVisualizerIntent.product,\n      );\n      if (!size) return false;\n      const product = {\n        ...this.pendingVisualizerIntent.product,\n        size,\n        sizeSelected: true,\n        selectedSizeExplicit: true,\n      };\n      this.pendingVisualizerIntent = null;\n      this._setContextProduct(product);\n      this._launchRoomManagerForProduct(product);\n      return true;\n    }\n\n    if (!this._isAddToCartQuery(query)) return false;\n    const product =\n      this.contextProduct ||\n      (this.lastShownProducts && this.lastShownProducts[0]) ||\n      this.store.getLastViewed();\n    if (!product) {\n      this._addMsg(\n        \"Please choose a rug first, then I can add it to your cart.\",\n        \"assistant\",\n      );\n      return true;\n    }\n\n    let sizes = this._availableSizesForProduct(product);\n\n    if (sizes.length === 0) {\n      const handle = product.handle || product.shopify_handle || product.id;\n      if (handle) {\n        try {\n          const res = await fetch(`/products/${handle}.js`);\n          if (res.ok) {\n            const fullProd = await res.json();\n            if (fullProd && fullProd.variants) {\n              product.variants = fullProd.variants;\n              product.options = fullProd.options;\n              sizes = this._availableSizesForProduct(product);\n            }\n          }\n        } catch (e) {\n          console.warn(\"[Discovery-AI] Could not fetch variants for typed size selection:\", e);\n        }\n      }\n    }\n\n    const typedSize = this._findSizeFromText(query, product);\n    const userSelectedSizeExplicitly = product._sizeSelectedByUser === true || product.selectedSizeExplicitByUser === true;\n    const hasExplicitSizeInCommand = !!typedSize || userSelectedSizeExplicitly;\n\n    if (sizes.length > 0 && !hasExplicitSizeInCommand) {\n      this.pendingCartIntent = { product };\n      this._addMsg(\n        `Which size would you like for <strong>${this.ui.esc(product.title)}</strong>?`,\n        \"assistant\",\n        true,\n      );\n      this._addMsg(this.ui.chips(sizes.slice(0, 8)), \"assistant\", true);\n      return true;\n    }\n\n    const selectedSize = typedSize || (userSelectedSizeExplicitly ? product.size : sizes[0]);\n    await this._addProductToCartWithSize(\n      {\n        ...product,\n        size: selectedSize || product.size,\n        sizeSelected: true,\n        selectedSizeExplicit: true,\n        _sizeSelectedByUser: true,\n      },\n      null,\n    );\n    return true;\n  }\n\n  async selectResultSize(id, size, button) {\n    const product = this.productCatalog.get(String(id));\n    if (!product) return;\n    const previousSize =\n      product.size && String(product.size).toLowerCase() !== \"default title\"\n        ? String(product.size)\n        : \"\";\n    const sizeChanged = previousSize !== String(size);\n    const matchingVariant = Array.isArray(product.variants)\n      ? product.variants.find(\n          (variant) =>\n            (this._variantOption(product, variant, \"Size\") || variant.title) ===\n            size,\n        )\n      : null;\n    const updatedProduct = matchingVariant\n      ? this._applyVariantToProduct(product, matchingVariant, true)\n      : { ...product, size, sizeSelected: true, selectedSizeExplicit: true };\n    updatedProduct._sizeSelectedByUser = true;\n    Object.assign(product, updatedProduct);\n    this.productCatalog.set(String(id), product);\n    if (this.contextProduct && String(this.contextProduct.id) === String(id)) {\n      this.contextProduct = { ...this.contextProduct, ...updatedProduct };\n    }\n    button\n      ?.closest(\".result-size-row\")\n      ?.querySelectorAll(\".result-size-chip\")\n      .forEach((chip) => chip.classList.remove(\"selected\"));\n    button?.classList.add(\"selected\");\n    if (sizeChanged) this.toast(`Selected ${size}`);\n    if (\n      this.pendingCartIntent &&\n      String(this.pendingCartIntent.product.id) === String(id)\n    ) {\n      this.pendingCartIntent = null;\n      await this._addProductToCartWithSize(product, button);\n    } else if (\n      this.pendingVisualizerIntent &&\n      String(this.pendingVisualizerIntent.product.id) === String(id)\n    ) {\n      this.pendingVisualizerIntent = null;\n      this._setContextProduct(product);\n      this._launchRoomManagerForProduct(product);\n    }\n  }\n\n  async _addProductToCartWithSize(product, button) {\n    const handle = product.handle || product.shopify_handle || product.id;\n    await this.quickAddToCart(\n      handle,\n      product.title,\n      product.price,\n      product.image_url || product.imgUrl || \"\",\n      product.size || \"\",\n      product.color || \"\",\n      button,\n      product,\n    );\n  }\n\n  _setContextProduct(product) {\n    if (!product) return;\n    this.contextProduct = {\n      ...product,\n      imgUrl: product.imgUrl || product.image_url || product.image || \"\",\n    };\n    if (this.contextProduct.id) {\n      this.productCatalog.set(\n        String(this.contextProduct.id),\n        this.contextProduct,\n      );\n    }\n    this._updateLiveContext();\n    this._renderToolMenu();\n    this._syncContext();\n  }\n\n  _hasExplicitProductSize(product = {}) {\n    return !!(\n      product.sizeSelected ||\n      product.selectedSizeExplicit ||\n      product.explicitSizeSelected ||\n      product._sizeSelectedByUser ||\n      product.userSelectedSize\n    );\n  }\n\n  _requestVisualizerSize(product) {\n    if (!product) {\n      this._addMsg(\n        \"Please select a rug first before visualizing it in your room.\",\n        \"assistant\",\n      );\n      return true;\n    }\n    const sizes = this._availableSizesForProduct(product);\n    // Always ask the user to pick a size so the visualizer uses the correct\n    // dimensions. Only skip when there are no size variants at all, or user already selected one.\n    if (sizes.length > 0 && !this._hasExplicitProductSize(product)) {\n      this.pendingVisualizerIntent = { product };\n      this._ensureDrawer();\n      this._addMsg(\n        `Please select the size for <strong>${this.ui.esc(product.title)}</strong> before I open the room preview.`,\n        \"assistant\",\n        true,\n      );\n      this._addMsg(this.ui.chips(sizes.slice(0, 8)), \"assistant\", true);\n      return true;\n    }\n    return false;\n  }\n\n\n\n  _launchRoomManagerForProduct(product) {\n    const prepared = this._prepareVisualizerProduct(product);\n    if (!prepared) {\n      this._addMsg(\n        \"Please select a rug first before visualizing it in your room.\",\n        \"assistant\",\n      );\n      return;\n    }\n    this._setContextProduct(prepared);\n    const sizeCopy = prepared.size\n      ? ` using <strong>${this.ui.esc(prepared.size)}</strong>`\n      : \"\";\n    this._addMsg(\n      `Opening the room manager${sizeCopy}. Select a room photo and I'll place the rug there.`,\n      \"assistant\",\n      true,\n    );\n    this.openVisualizerDirectly();\n  }\n\n  async quickAddProduct(id, button) {\n    const p = this.productCatalog.get(String(id));\n    if (!p) {\n      console.warn(\"[Discovery-AI] Product not in catalog:\", id);\n      return;\n    }\n    const sizes = this._availableSizesForProduct(p);\n    if (sizes.length > 0 && !p._sizeSelectedByUser) {\n      this.pendingCartIntent = { product: p };\n      this._ensureDrawer();\n      this._addMsg(\n        `Which size would you like for <strong>${this.ui.esc(p.title)}</strong>?`,\n        \"assistant\",\n        true,\n      );\n      this._addMsg(this.ui.chips(sizes.slice(0, 8)), \"assistant\", true);\n      return;\n    }\n    // Pass the handle so Store can resolve variant from Shopify\n    const handle = p.handle || p.shopify_handle || p.id;\n    await this.quickAddToCart(\n      handle,\n      p.title,\n      p.price,\n      p.image_url || \"\",\n      p.size || \"\",\n      p.color || \"\",\n      button,\n    );\n  }\n\n  async seeProductInRoom(id, button) {\n    let p = this.productCatalog.get(String(id));\n    if (!p) return;\n\n    let rawHandle = p.shopify_handle || p.handle || '';\n    if (!rawHandle && (p.url || p.product_url || p.uri)) {\n      const pUrl = p.product_url || p.url || p.uri || '';\n      const m = pUrl.match(/\\/products\\/([^\\/\\?#]+)/);\n      if (m) rawHandle = m[1];\n    }\n    if (!rawHandle && p.id && !/^\\d+$/.test(String(p.id)) && !String(p.id).startsWith('rec_')) {\n      rawHandle = String(p.id);\n    }\n    const cleanHandle = String(rawHandle || '')\n      .replace(/^owfam-/, '')\n      .replace(/^\\/products\\//, '')\n      .split('?')[0]\n      .split('#')[0]\n      .trim();\n\n    const btn = button || (typeof document !== 'undefined' ? document.querySelector(`[data-app-action=\"seeProductInRoom\"][data-arg0=\"${id}\"], [data-id=\"${id}\"][data-is-chat-card=\"true\"]`) : null);\n    if (btn) {\n      window.activeVisualizerButton = btn;\n      btn.setAttribute('data-is-chat-card', 'true');\n      if (cleanHandle) btn.setAttribute('data-product-handle', cleanHandle);\n      if (p.image_url || p.imgUrl) btn.setAttribute('data-rug', p.image_url || p.imgUrl);\n      if (p.size) btn.setAttribute('data-size', p.size);\n    }\n    window.activeVisualizerSource = 'assistant';\n    window.activeVisualizerProductHandle = cleanHandle || p.id || '';\n    window.activeVisualizerProductId = p.id || '';\n\n    if ((!p.variants || p.variants.length === 0 || !p.options || !p.variants[0]?.options) && cleanHandle) {\n      const candidates = [cleanHandle, cleanHandle.replace(/^owfam-/, ''), 'owfam-' + cleanHandle.replace(/^owfam-/, '')].filter(Boolean);\n      for (const h of candidates) {\n        try {\n          let shopifyProduct = null;\n          try {\n            const rMeta = await fetch(`/products/${h}?view=variants-json`);\n            if (rMeta.ok) {\n              const metaJson = await rMeta.json();\n              if (metaJson && Array.isArray(metaJson.variants) && metaJson.variants.length) {\n                shopifyProduct = metaJson;\n              }\n            }\n          } catch (_) {}\n\n          if (!shopifyProduct) {\n            const resp = await fetch(`/products/${h}.js`);\n            if (resp.ok) {\n              shopifyProduct = await resp.json();\n            }\n          }\n\n          if (shopifyProduct && Array.isArray(shopifyProduct.variants)) {\n            p = {\n              ...p,\n              handle: h,\n              variants: shopifyProduct.variants,\n              options: shopifyProduct.options\n            };\n            this.productCatalog.set(String(id), p);\n            window.activeVisualizerProductHandle = h;\n            break;\n          }\n        } catch (_) {}\n      }\n    }\n    this._launchRoomManagerForProduct(p);\n  }\n\n\n  showSimilar(id) {\n    const p = this.productCatalog.get(String(id));\n    if (p)\n      this.contextProduct = {\n        ...p,\n        imgUrl: p.imgUrl || p.image_url || p.image || p.featured_image || \"\",\n      };\n    this._updateLiveContext();\n    if (!this.drawerOpen) this.toggleDrawer();\n    this.sendAction(\"Show similar rugs\");\n    this._syncContext();\n  }\n\n  viewProduct(\n    id,\n    title,\n    size,\n    color,\n    price,\n    style,\n    material,\n    imgUrl,\n    raw = {},\n  ) {\n    this.contextProduct = {\n      ...raw,\n      id,\n      title,\n      size,\n      color,\n      price,\n      style,\n      material,\n      imgUrl,\n      url:\n        raw.url ||\n        raw.product_url ||\n        (raw.handle ? `/products/${raw.handle}` : \"\"),\n      available: raw.available,\n      shape: raw.shape,\n      collection: raw.collection || raw.collection_name || \"\",\n    };\n    this._updateLiveContext();\n    this._renderToolMenu();\n    this.store.addViewed(this.contextProduct);\n    try {\n      if (this.recommender)\n        this.recommender.trackProductView(this.contextProduct, \"view\");\n    } catch (e) {\n      console.warn(\"Recommender track failed:\", e);\n    }\n    this._previousView =\n      document.getElementById(\"home-view\")?.style.display !== \"none\"\n        ? \"home\"\n        : \"pdp\";\n\n    // Update PDP UI\n    const pdpMainImg = document.getElementById(\"pdp-main-img\");\n    if (pdpMainImg) {\n      pdpMainImg.src = imgUrl;\n      pdpMainImg.alt = title;\n    }\n    document.getElementById(\"pdp-title\").textContent = title;\n    document.getElementById(\"pdp-price\").textContent =\n      this.ui.formatPrice(price);\n    document.getElementById(\"pdp-color\").textContent = color || \"\u2014\";\n    document.getElementById(\"pdp-style\").textContent = style || \"\u2014\";\n    document.getElementById(\"pdp-material\").textContent = material || \"\u2014\";\n    document.getElementById(\"pdp-collection\").textContent =\n      this.contextProduct.collection || \"\u2014\";\n    document.getElementById(\"pdp-description\").textContent =\n      raw.description || raw.product_description || \"\";\n\n    // Size selector\n    const sizes = Array.isArray(raw.sizes) ? raw.sizes : size ? [size] : [];\n    document.getElementById(\"pdp-sizes\").innerHTML = sizes.length\n      ? sizes\n          .map(\n            (s) =>\n              `<button class=\"size-btn ${s === size ? \"active\" : \"\"}\" data-size=\"${this.ui.escAttr(s)}\" data-app-action=\"updateSelectedSize\" data-arg0=\"${this.ui.escAttr(s)}\">${this.ui.esc(s)}</button>`,\n          )\n          .join(\"\")\n      : '<span class=\"product-card-meta\">See product availability for size options.</span>';\n\n    // Wishlist button state\n    const wishBtn = document.getElementById(\"pdp-wishlist\");\n    if (this.store.isWishlisted(id)) {\n      wishBtn.innerHTML =\n        '<i class=\"fa fa-heart\" style=\"color:#e53935\"></i> Saved';\n    } else {\n      wishBtn.innerHTML = '<i class=\"fa fa-heart\"></i> Save';\n    }\n\n    // Show PDP\n\n    //\n    //\n    //\n\n    window.scrollTo(0, 0);\n\n    // Update assistant context\n    // Banner UI removed in favor of inline chat bubbles\n\n    // Update assistant greeting\n    this._addMsg(\n      `Now viewing <strong>${this.ui.esc(title)}</strong>. I can help with sizing, care, similar styles, or show it in your room.`,\n      \"assistant\",\n      true,\n    );\n    // Suggested question chips will be loaded dynamically by _autoOpenPDPAssistant\n\n    // Load recommendations\n    this._loadPDPRecommendations(id);\n    this._syncContext();\n\n    // Update style facts\n    if (style) this.store.updateFacts({ style: [style] });\n\n    // Auto-open assistant with product context (Rufus-style)\n    this._autoOpenPDPAssistant();\n  }\n\n  async _autoOpenPDPAssistant() {\n    // Open the drawer if not already open\n    if (!this.drawerOpen) {\n      // Small delay to let PDP render first\n      setTimeout(() => this.toggleDrawer(), 300);\n    }\n\n    // Load dynamic suggested questions from backend\n    await this._loadPDPSuggestedQuestions();\n\n    // Bind the inline Ask bar\n    this._bindPDPAskBar();\n  }\n\n  async _loadPDPSuggestedQuestions() {\n    if (!this.contextProduct) return;\n\n    // Prevent duplicate chip bubbles\n    const existing = document.getElementById(\"load-pdp-dynamic-chips\");\n    if (existing) existing.remove();\n\n    let dynamicQuestions = [];\n\n    // Generate deterministic questions based strictly on available PDP data\n    if (this.contextProduct.options && this.contextProduct.options.length > 0) {\n      dynamicQuestions.push(\n        `What sizes are available for the ${this.contextProduct.title}?`,\n      );\n    } else {\n      dynamicQuestions.push(\"What are the dimensions of this rug?\");\n    }\n\n    // Material is a core attribute almost always handled well by the assistant context\n    dynamicQuestions.push(\"What material is this rug made of?\");\n\n    // Add a specific third question if data exists, otherwise fallback to care\n    if (this.contextProduct.thickness) {\n      dynamicQuestions.push(\"What is the pile height of this rug?\");\n    } else {\n      dynamicQuestions.push(\"What are the care instructions for this rug?\");\n    }\n\n    // Combine dynamic questions and exactly two static actions\n    const allChips = [...dynamicQuestions, \"See in my room\", \"Care Guide\"];\n\n    // Render chips in the chat panel with a non-saving ID\n    this._addMsg(\n      this.ui.chips(allChips),\n      \"assistant\",\n      true,\n      \"load-pdp-dynamic-chips\",\n    );\n  }\n\n  _bindPDPAskBar() {\n    const input = document.getElementById(\"pdp-ask-input\");\n    const sendBtn = document.getElementById(\"pdp-ask-send\");\n    if (!input || !sendBtn) return;\n\n    // Remove old listeners by cloning\n    const newInput = input.cloneNode(true);\n    const newSend = sendBtn.cloneNode(true);\n    input.parentNode.replaceChild(newInput, input);\n    sendBtn.parentNode.replaceChild(newSend, sendBtn);\n\n    newInput.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Enter\") {\n        e.preventDefault();\n        if (newInput.value.trim()) {\n          this.askFromPDP(newInput.value.trim());\n          newInput.value = \"\";\n        }\n      }\n    });\n\n    newSend.addEventListener(\"click\", (e) => {\n      e.preventDefault();\n      if (newInput.value.trim()) {\n        this.askFromPDP(newInput.value.trim());\n        newInput.value = \"\";\n      }\n    });\n  }\n\n  askFromPDP(question) {\n    // Open drawer if not already open\n    if (!this.drawerOpen) this.toggleDrawer();\n    // Send the question through the chat\n    this._addMsg(question, \"user\");\n    this._processQuery(question);\n  }\n\n  async _loadPDPRecommendations(productId) {\n    try {\n      const reco = await this.api.recommend(productId);\n      const products = Array.isArray(reco)\n        ? reco\n        : reco.products || reco.payload?.products || [];\n      if (Array.isArray(products) && products.length > 0) {\n        this.registerProducts(products);\n        const carousel = document.getElementById(\"pdp-reco-carousel\");\n        carousel.innerHTML = products\n          .map(\n            (\n              p,\n            ) => `<div class=\"reco-card\" data-app-action=\"openProduct\" data-arg0=\"${this.ui.escAttr(p.id)}\">\n                    <img src=\"${this.ui.escAttr(p.image_url)}\" alt=\"${this.ui.escAttr(p.title)}\">\n                    <div class=\"reco-card-body\">\n                        <h4>${this.ui.esc(p.title)}</h4>\n                        <p>${this.ui.esc(p.price)}</p>\n                        ${p.llm_reason ? `<p class=\"llm-reason\"><i class=\"fa fa-sparkles\"></i> ${this.ui.esc(p.llm_reason)}</p>` : \"\"}\n                    </div>\n                </div>`,\n          )\n          .join(\"\");\n        document.getElementById(\"pdp-reco-section\").style.display = \"block\";\n      }\n    } catch (err) {\n      console.error(\"Recommendations error:\", err);\n    }\n  }\n\n  async _pdpAddToCart() {\n    if (!this.contextProduct) return;\n    const p = this.contextProduct;\n    const handle = p.handle || p.shopify_handle || p.id;\n    await this.store.addToCart({\n      id: handle,\n      handle: handle,\n      title: p.title,\n      price: p.price,\n      imgUrl: p.imgUrl,\n      size: p.size,\n      color: p.color,\n    });\n    this._updateCartUI();\n\n    // Button animation\n    const btn = document.getElementById(\"pdp-add-cart\");\n    btn.innerHTML = '<i class=\"fa fa-check\"></i> Added!';\n    btn.classList.add(\"discovery-btn-success-flash\");\n    setTimeout(() => {\n      btn.innerHTML = '<i class=\"fa fa-shopping-bag\"></i> Add to Cart';\n      btn.classList.remove(\"btn-success-flash\");\n    }, 2000);\n\n    // Chat notification\n    if (this.drawerOpen) {\n      this._addMsg(this.ui.cartAdded(p.title), \"assistant\", true);\n    }\n    this.toast(`${p.title} added to cart`);\n  }\n\n  _pdpToggleWishlist() {\n    if (!this.contextProduct) return;\n    const p = this.contextProduct;\n    const added = this.store.toggleWishlist({\n      id: p.id,\n      title: p.title,\n      price: p.price,\n      imgUrl: p.imgUrl,\n    });\n    const btn = document.getElementById(\"pdp-wishlist\");\n    if (added) {\n      btn.innerHTML = '<i class=\"fa fa-heart\" style=\"color:#e53935\"></i> Saved';\n      this.toast(`${p.title} saved to wishlist`);\n    } else {\n      btn.innerHTML = '<i class=\"fa fa-heart\"></i> Save';\n      this.toast(`${p.title} removed from wishlist`);\n    }\n  }\n\n  goHome() {\n    document.getElementById(\"pdp-reco-section\").style.display = \"none\";\n    this.contextProduct = null;\n    this._updateLiveContext();\n    this._renderToolMenu();\n    this.pdpBanner?.classList.remove(\"visible\");\n    document.body.classList.remove(\"pdp-assistant-open\");\n    if (this.drawerOpen) this.toggleDrawer();\n    this._syncContext();\n    window.scrollTo(0, 0);\n  }\n\n  // --- Quick actions from product cards ---\n  async quickAddVariant(variantId, btnElem) {\n    if (btnElem) {\n      const originalText = btnElem.innerHTML;\n      btnElem.innerHTML = `<i class=\"fa fa-spinner fa-spin\"></i>`;\n      btnElem.disabled = true;\n      try {\n        const result = await this.store.addToCart({ variant_id: variantId });\n        this._updateCartUI();\n        if (result?.success) {\n          this.toast(`Added to cart`);\n          this._addMsg(\n            `<div class=\"confirmation-card compact\">\n                <p><i class=\"fa fa-check-circle\" style=\"color:var(--color-success)\" aria-hidden=\"true\"></i> Successfully added to your cart.</p>\n            </div>`,\n            \"assistant\",\n            true\n          );\n          // Show dynamic recommendations\n          this._handlePostCartAddition(result.cartItem);\n        } else {\n          this.toast(\"Failed to add to cart\");\n        }\n      } finally {\n        btnElem.innerHTML = originalText;\n        btnElem.disabled = false;\n      }\n    } else {\n      const result = await this.store.addToCart({ variant_id: variantId });\n      this._updateCartUI();\n      if (result?.success) {\n        this.toast(`Added to cart`);\n        this._addMsg(\n          `<div class=\"confirmation-card compact\">\n              <p><i class=\"fa fa-check-circle\" style=\"color:var(--color-success)\" aria-hidden=\"true\"></i> Successfully added to your cart.</p>\n          </div>`,\n          \"assistant\",\n          true\n        );\n        this._handlePostCartAddition(result.cartItem);\n      }\n    }\n  }\n\n  async quickAddToCart(\n    idOrHandle,\n    title,\n    price,\n    imgUrl,\n    size,\n    color,\n    btnElem,\n    product = null,\n  ) {\n    const result = await this.store.addToCart({\n      id: idOrHandle,\n      handle: idOrHandle,\n      title,\n      price,\n      imgUrl,\n      size,\n      color,\n    });\n    this._updateCartUI();\n\n    if (result?.success) {\n      this.toast(`${title} added to cart`);\n      const formattedSize =\n        size && String(size).toLowerCase() !== \"default title\" ? size : \"\";\n      const sizeMsg = formattedSize\n        ? ` of size <strong>${this.ui.esc(formattedSize)}</strong>`\n        : \"\";\n      this._addMsg(\n        `<div class=\"confirmation-card compact\">\n                <p><i class=\"fa fa-check-circle\" style=\"color:var(--color-success)\" aria-hidden=\"true\"></i> Added <strong>${this.ui.esc(title)}</strong>${sizeMsg} to your cart.</p>\n            </div>`,\n        \"assistant\",\n        true,\n      );\n      if (product) this._setContextProduct(product);\n      if (btnElem) {\n        const orig = btnElem.innerHTML;\n        btnElem.innerHTML = '<i class=\"fa fa-check\"></i> Added!';\n        btnElem.classList.add(\"discovery-btn-success-flash\");\n        setTimeout(() => {\n          btnElem.innerHTML = orig;\n          btnElem.classList.remove(\"btn-success-flash\");\n        }, 1500);\n      }\n\n      // Auto-suggest rug pads matching the rug\n      try {\n        const padRes = await this.api.search(\"rug pad\");\n        let rawPads = padRes?.results || padRes?.products || (Array.isArray(padRes) ? padRes : []);\n        let pads = rawPads.filter((p) => {\n          const pTitle = String(p.title || p.name || \"\").toLowerCase();\n          const pType = String(p.product_type || p.category || \"\").toLowerCase();\n          const pTags = Array.isArray(p.tags) ? p.tags.join(\" \").toLowerCase() : String(p.tags || \"\").toLowerCase();\n          return pTitle.includes(\"pad\") || pTitle.includes(\"grip\") || pTitle.includes(\"underlay\") || pType.includes(\"pad\") || pTags.includes(\"pad\");\n        });\n        if (pads.length === 0) {\n          const colRes = await fetch(\"/collections/rug-pads/products.json?limit=8\").then(r => r.ok ? r.json() : null).catch(() => null);\n          if (colRes && colRes.products) {\n            pads = colRes.products.map(p => ({\n              id: p.id,\n              title: p.title,\n              price: p.variants?.[0]?.price || \"0.00\",\n              imgUrl: p.images?.[0]?.src || \"\",\n              handle: p.handle,\n              product_type: \"Rug Pad\",\n              sizes: (p.options?.find(o => /size/i.test(o.name))?.values) || []\n            }));\n          }\n        }\n        if (pads.length > 0) {\n          this.registerProducts(pads);\n          this._addMsg(\n            this.ui.horizontalProductCarousel(\n              pads.slice(0, 4),\n              \"Rug Pads\",\n            ),\n            \"assistant\",\n            true,\n          );\n        }\n      } catch (padErr) {\n        console.warn(\"[Discovery-AI] Auto rug pad fetch failed:\", padErr);\n      }\n\n      return true;\n    }\n\n    this.toast(`Failed to add ${title} - ${result?.error || \"unknown error\"}`);\n    console.error(\"[Discovery-AI] quickAddToCart failed:\", result);\n    return false;\n  }\n\n  toggleWishlistHP(id, title, price, imgUrl, btnElem) {\n    const added = this.store.toggleWishlist({ id, title, price, imgUrl });\n    if (btnElem) btnElem.classList.toggle(\"wishlisted\", added);\n    this.toast(added ? `${title} saved` : `${title} removed from wishlist`);\n  }\n\n  async _getShopifyCaptchaToken() {\n    try {\n      const siteKey = window.Shopify?.recaptchaV3SiteKey || '6LdfnToaAAAAAL6w2532h1a7y05u2f52x683_32';\n      \n      if (!window.grecaptcha || typeof window.grecaptcha.execute !== 'function') {\n        await new Promise((resolve) => {\n          const script = document.createElement('script');\n          script.src = `https://www.google.com/recaptcha/api.js?render=${siteKey}`;\n          script.onload = () => resolve();\n          script.onerror = () => resolve();\n          document.head.appendChild(script);\n        });\n      }\n\n      if (window.grecaptcha && typeof window.grecaptcha.ready === 'function') {\n        return await new Promise((resolve) => {\n          window.grecaptcha.ready(async () => {\n            try {\n              const token = await window.grecaptcha.execute(siteKey, { action: 'contact' });\n              resolve(token);\n            } catch (_) {\n              resolve(null);\n            }\n          });\n        });\n      }\n    } catch (_) {\n      return null;\n    }\n    return null;\n  }\n\n  async _sendNativeShopifyContact(payload = {}) {\n    try {\n      const name = payload.name || 'Store Customer';\n      const phone = payload.phone || '';\n      const cleanPhone = phone.replace(/\\D/g, '') || '0000000000';\n      const email = payload.email || (cleanPhone.length >= 7 ? `customer.${cleanPhone}@gmail.com` : 'customer.inquiry@gmail.com');\n      const service = payload.service || 'Service Request';\n      const notes = payload.notes || payload.body || '';\n      const pageUrl = payload.page_url || window.location.href;\n\n      const bodyContent = [\n        `Service Requested: ${service}`,\n        `Full Name: ${name}`,\n        `Phone Number: ${phone || 'Not provided'}`,\n        `Email: ${payload.email || 'Not provided'}`,\n        `Notes / Description: ${notes || 'None'}`,\n        `Page URL: ${pageUrl}`\n      ].filter(Boolean).join('\\n\\n');\n\n      console.warn('[Shopify Mailer] \uD83D\uDE80 Submitting native contact form to store owner for:', name, phone, service);\n\n      // Create an invisible iframe target to receive the form response in background\n      const iframeName = 'shopify_contact_target_' + Date.now();\n      const iframe = document.createElement('iframe');\n      iframe.name = iframeName;\n      iframe.id = iframeName;\n      iframe.style.cssText = 'display:none !important; width:0; height:0; border:0; visibility:hidden;';\n      iframe.onload = () => {\n        console.warn('[Shopify Mailer] \u2705 Service request form submitted successfully to store owner!');\n      };\n      document.body.appendChild(iframe);\n\n      // Create a hidden form pointing to the iframe target\n      const form = document.createElement('form');\n      form.method = 'POST';\n      form.action = '/contact#contact_form';\n      form.target = iframeName;\n      form.style.cssText = 'display:none !important;';\n\n      const fields = {\n        'form_type': 'contact',\n        'utf8': '\u2713',\n        'contact[name]': name,\n        'contact[phone]': phone,\n        'contact[email]': email,\n        'contact[Inquiry Type]': `Service Request - ${service}`,\n        'contact[body]': bodyContent\n      };\n\n      Object.keys(fields).forEach(key => {\n        const input = document.createElement('input');\n        input.type = 'hidden';\n        input.name = key;\n        input.value = fields[key];\n        form.appendChild(input);\n      });\n\n      document.body.appendChild(form);\n\n      const submitFormNow = () => {\n        try {\n          if (typeof form.requestSubmit === 'function') {\n            form.requestSubmit();\n          } else {\n            form.submit();\n          }\n        } catch (_) {\n          form.submit();\n        }\n      };\n\n      // Get reCAPTCHA v3 token and append as hidden input prior to submitting\n      const siteKey = window.Shopify?.recaptchaV3SiteKey || '6LdfnToaAAAAAL6w2532h1a7y05u2f52x683_32';\n      if (window.grecaptcha && typeof window.grecaptcha.ready === 'function') {\n        window.grecaptcha.ready(async () => {\n          try {\n            const token = await window.grecaptcha.execute(siteKey, { action: 'contact' });\n            if (token) {\n              const recaptchaInput = document.createElement('input');\n              recaptchaInput.type = 'hidden';\n              recaptchaInput.name = 'g-recaptcha-response';\n              recaptchaInput.value = token;\n              form.appendChild(recaptchaInput);\n\n              const recaptchaV3Input = document.createElement('input');\n              recaptchaV3Input.type = 'hidden';\n              recaptchaV3Input.name = 'recaptcha-v3-token';\n              recaptchaV3Input.value = token;\n              form.appendChild(recaptchaV3Input);\n            }\n          } catch (_) {}\n          submitFormNow();\n        });\n      } else {\n        submitFormNow();\n      }\n\n      setTimeout(() => {\n        form.remove();\n        iframe.remove();\n      }, 6000);\n\n      return true;\n    } catch (err) {\n      console.warn('[Discovery-AI] Native Shopify contact mailer submit warning:', err);\n      return false;\n    }\n  }\n\n  // --- Appointment ---\n  async submitAppointment(event) {\n    event.preventDefault();\n\n    const form = event.target;\n    const service =\n      form.service?.options[form.service.selectedIndex]?.text || \"Consultation\";\n    const name = form.full_name?.value?.trim() || \"Not provided\";\n    const phone = form.phone?.value?.trim() || \"Not provided\";\n    const email = form.email?.value?.trim() || \"\";\n    const notes = form.notes?.value?.trim() || \"\";\n    const product =\n      this.contextProduct || window.ShopifyContextPayload?.product || null;\n\n    const card = form.closest(\".appointment-card\");\n    if (card) card.remove();\n\n    const loadId = \"load-contact-\" + Date.now();\n    this._addMsg(\n      this.ui.loading(\"Sending this to the store team...\"),\n      \"assistant\",\n      true,\n      loadId,\n    );\n\n    let delivered = false;\n    try {\n      const leadService = window.DiscoveryAIAssistantLead;\n      if (!leadService?.submit) {\n        throw new Error(\"Assistant lead module is unavailable\");\n      }\n\n      const result = await leadService.submit({\n        tenant: this.api?.tenant || window.shopkeeperTenant || \"discovery_ai_llc\",\n        name,\n        phone,\n        email,\n        service,\n        notes,\n        product,\n        pageUrl: window.location.href,\n      });\n      delivered = result.success;\n\n      if (result.activationRequired) {\n        console.warn(\"[Discovery-AI] FormSubmit activation is required for this storefront origin.\");\n      }\n    } catch (err) {\n      console.warn(\"[Discovery-AI] Assistant appointment lead error:\", err);\n    } finally {\n      this._removeMsg(loadId);\n    }\n\n    if (delivered) {\n      this._addMsg(\n        `<div class=\"confirmation-card interactive-service-card\" style=\"background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 12px; padding: 16px; margin-top: 8px;\">\n            <h4 style=\"margin-top: 0; color: var(--color-success); display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n                <i class=\"fa fa-check-circle\"></i> Service Request Sent!\n            </h4>\n            <p style=\"font-size: 13px; color: var(--color-text-secondary); margin-bottom: 0;\">Thanks for contacting us! Our team has received your request for <strong>${this.ui.esc(service)}</strong> and will reach out to you shortly at <strong>${this.ui.esc(phone)}</strong>.</p>\n        </div>`,\n        \"assistant\",\n        true,\n      );\n      return;\n    }\n\n    const storePhone =\n      window.ShopifyContextPayload?.shop?.phone || \"our store team\";\n    this._addMsg(\n      `<div class=\"confirmation-card interactive-service-card\" style=\"background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 12px; padding: 16px; margin-top: 8px;\">\n          <h4 style=\"margin-top: 0; color: var(--color-warning, #dc2626); display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600;\">\n              <i class=\"fa fa-exclamation-triangle\"></i> Request Delivery Pending\n          </h4>\n          <p style=\"font-size: 13px; color: var(--color-text-secondary); margin-bottom: 8px;\">We could not deliver your request automatically right now.</p>\n          <p style=\"font-size: 13px; color: var(--color-text-secondary); margin-bottom: 0;\">Please call or text <strong>${this.ui.esc(storePhone)}</strong> directly or tap below to open Live Chat.</p>\n          <button class=\"discovery-btn btn-primary btn-sm\" data-app-action=\"_openStoreOwnerChat\" style=\"margin-top: 10px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;\"><i class=\"fa fa-comments\"></i> Chat Live with Store</button>\n      </div>`,\n      \"assistant\",\n      true,\n    );\n  }\n\n  async _copyTextToClipboard(text) {\n    try {\n      if (!navigator.clipboard?.writeText) return false;\n      await navigator.clipboard.writeText(text);\n      return true;\n    } catch (_) {\n      return false;\n    }\n  }\n\n  async copyHandoffMessage(message, button) {\n    const copied = await this._copyTextToClipboard(message || \"\");\n    this.toast(copied ? \"Message copied\" : \"Could not copy message\");\n    if (copied && button) {\n      const original = button.innerHTML;\n      button.innerHTML = '<i class=\"fa fa-check\"></i> Copied';\n      setTimeout(() => {\n        button.innerHTML = original;\n      }, 1200);\n    }\n  }\n\n  async openShopifyInbox() {\n    // --- Helper: full-event click sequence ---\n    const clickEl = (el) => {\n      if (!el) return false;\n      try {\n        // Focus first \u2014 Shopify's widget may require focus for re-activation\n        if (typeof el.focus === \"function\") el.focus();\n        el.dispatchEvent(\n          new PointerEvent(\"pointerdown\", {\n            bubbles: true,\n            cancelable: true,\n            composed: true,\n            pointerId: 1,\n            pointerType: \"mouse\",\n          }),\n        );\n        el.dispatchEvent(\n          new MouseEvent(\"mousedown\", {\n            bubbles: true,\n            cancelable: true,\n            composed: true,\n          }),\n        );\n        el.dispatchEvent(\n          new PointerEvent(\"pointerup\", {\n            bubbles: true,\n            cancelable: true,\n            composed: true,\n            pointerId: 1,\n            pointerType: \"mouse\",\n          }),\n        );\n        el.dispatchEvent(\n          new MouseEvent(\"mouseup\", {\n            bubbles: true,\n            cancelable: true,\n            composed: true,\n          }),\n        );\n        el.click();\n        return true;\n      } catch (_) {\n        try {\n          el.click();\n          return true;\n        } catch (__) {\n          return false;\n        }\n      }\n    };\n\n    // --- Helper: keyboard activation (Enter + Space) ---\n    const keyboardActivate = (el) => {\n      if (!el) return false;\n      try {\n        if (typeof el.focus === \"function\") el.focus();\n        for (const key of [\"Enter\", \" \"]) {\n          el.dispatchEvent(\n            new KeyboardEvent(\"keydown\", {\n              key,\n              code: key === \" \" ? \"Space\" : \"Enter\",\n              bubbles: true,\n              cancelable: true,\n              composed: true,\n            }),\n          );\n          el.dispatchEvent(\n            new KeyboardEvent(\"keyup\", {\n              key,\n              code: key === \" \" ? \"Space\" : \"Enter\",\n              bubbles: true,\n              cancelable: true,\n              composed: true,\n            }),\n          );\n        }\n        return true;\n      } catch (_) {\n        return false;\n      }\n    };\n\n    // --- Helper: find the best Shopify Chat launcher button ---\n    const findLauncher = () => {\n      const isInDiscoveryWidget = (el) => {\n        if (el.closest?.(\".discovery-ai-widget\")) return true;\n        const root = el.getRootNode?.();\n        return !!root?.host?.closest?.(\".discovery-ai-widget\");\n      };\n      const collect = (root = document, seen = new Set()) => {\n        if (!root || seen.has(root)) return [];\n        seen.add(root);\n        const nodes = Array.from(\n          root.querySelectorAll?.(\n            'shopify-chat, button, [role=\"button\"], a, [part=\"activator\"], .activator, [aria-label=\"Chat\"]',\n          ) || [],\n        );\n        for (const node of nodes) {\n          if (node.shadowRoot) nodes.push(...collect(node.shadowRoot, seen));\n        }\n        return nodes;\n      };\n      const candidates = collect().filter((el) => !isInDiscoveryWidget(el));\n      const launchers = candidates\n        .map((el) => {\n          const rect = el.getBoundingClientRect();\n          const style = window.getComputedStyle(el);\n          const className =\n            typeof el.className === \"object\"\n              ? el.className.baseVal || \"\"\n              : el.className || \"\";\n          const text =\n            `${el.tagName} ${el.getAttribute(\"aria-label\") || \"\"} ${el.getAttribute(\"title\") || \"\"} ${el.textContent || \"\"} ${el.id || \"\"} ${className}`.toLowerCase();\n          const visible =\n            rect.width > 8 &&\n            rect.height > 8 &&\n            style.display !== \"none\" &&\n            style.visibility !== \"hidden\" &&\n            style.opacity !== \"0\";\n          const chatLike = /\\b(chat|inbox|message|messenger|support)\\b/.test(\n            text,\n          );\n          const exactActivator = el.matches?.(\n            'button[part=\"activator\"], button.activator, [part=\"activator\"][aria-label=\"Chat\"], .activator[aria-label=\"Chat\"]',\n          );\n          const floating =\n            style.position === \"fixed\" ||\n            style.position === \"sticky\" ||\n            (rect.right > window.innerWidth * 0.55 &&\n              rect.bottom > window.innerHeight * 0.55);\n          return {\n            el,\n            rect,\n            text,\n            visible,\n            chatLike,\n            exactActivator,\n            floating,\n          };\n        })\n        .filter(\n          (item) => item.visible && (item.chatLike || item.exactActivator),\n        );\n\n      launchers.sort((a, b) => {\n        const aScore =\n          (a.exactActivator ? 1000 : 0) +\n          (a.floating ? 100 : 0) +\n          a.rect.right +\n          a.rect.bottom;\n        const bScore =\n          (b.exactActivator ? 1000 : 0) +\n          (b.floating ? 100 : 0) +\n          b.rect.right +\n          b.rect.bottom;\n        return bScore - aScore;\n      });\n      return launchers[0]?.el || null;\n    };\n\n    // --- Helper: find the deepest clickable button inside a shopify-chat shadow root ---\n    const findShopifyChatButton = () => {\n      const chatEl = document.querySelector(\"shopify-chat\");\n      if (!chatEl?.shadowRoot) return null;\n      // Walk shadow roots recursively to find the activator button\n      const walk = (root) => {\n        if (!root) return null;\n        const btn = root.querySelector(\n          'button[part=\"activator\"], button.activator, [aria-label=\"Chat\"], button',\n        );\n        if (btn) {\n          // If this button itself has a shadow root, go deeper\n          if (btn.shadowRoot) {\n            const deeper = walk(btn.shadowRoot);\n            if (deeper) return deeper;\n          }\n          return btn;\n        }\n        // Check child elements with shadow roots\n        for (const child of root.querySelectorAll(\"*\")) {\n          if (child.shadowRoot) {\n            const found = walk(child.shadowRoot);\n            if (found) return found;\n          }\n        }\n        return null;\n      };\n      return walk(chatEl.shadowRoot);\n    };\n\n    // --- Attempt Strategy: try click + keyboard on both generic launcher and direct shopify-chat button ---\n    const attemptOpen = () => {\n      // Strategy 1: Direct shopify-chat shadow button (most reliable for re-opens)\n      const directBtn = findShopifyChatButton();\n      if (directBtn) {\n        clickEl(directBtn);\n        keyboardActivate(directBtn);\n        return true;\n      }\n      // Strategy 2: Generic launcher search\n      const launcher = findLauncher();\n      if (launcher) {\n        // Try the shadow button first, then the outer element\n        const shadowBtn = launcher.shadowRoot?.querySelector(\n          'button, [role=\"button\"], .activator, [part=\"activator\"]',\n        );\n        if (shadowBtn) {\n          clickEl(shadowBtn);\n          keyboardActivate(shadowBtn);\n        }\n        clickEl(launcher);\n        return true;\n      }\n      return false;\n    };\n\n    // --- Execute with retries ---\n    // Attempt 1: immediate\n    if (attemptOpen()) return \"opened\";\n\n    // Attempt 2: short delay (widget may be re-rendering after drawer close)\n    await new Promise((r) => setTimeout(r, 350));\n    if (attemptOpen()) return \"opened\";\n\n    // Attempt 3: longer delay (some widgets are slow to re-initialize)\n    await new Promise((r) => setTimeout(r, 600));\n    if (attemptOpen()) return \"opened\";\n\n    // Fallback: try global API objects\n    if (window.ShopifyInbox && typeof window.ShopifyInbox.open === \"function\") {\n      try {\n        window.ShopifyInbox.open();\n        return \"opened\";\n      } catch (_) {}\n    }\n    if (window.ShopifyChat && typeof window.ShopifyChat.open === \"function\") {\n      try {\n        window.ShopifyChat.open();\n        return \"opened\";\n      } catch (_) {}\n    }\n    if (\n      window.Shopify?.inbox &&\n      typeof window.Shopify.inbox.open === \"function\"\n    ) {\n      try {\n        window.Shopify.inbox.open();\n        return \"opened\";\n      } catch (_) {}\n    }\n\n    return \"not_found\";\n  }\n\n  async submitOrderTrack(event) {\n    event.preventDefault();\n    const form = event.target;\n    const orderId = (form.querySelector('input[name=\"order_id\"], #track-order-id')?.value || \"\").trim();\n    const phone = (form.querySelector('input[name=\"phone\"], #track-phone')?.value || \"\").trim();\n    const email = (form.querySelector('input[name=\"email\"], #track-email')?.value || \"\").trim();\n\n    if (!orderId) {\n      this.toast(\"Please enter your order number.\");\n      return;\n    }\n    if (!email) {\n      this.toast(\"Please enter your checkout email address.\");\n      return;\n    }\n\n    form.closest(\".interactive-service-card, .order-track-card, .appointment-card\")?.remove();\n\n    const loadId = \"load-track-\" + Date.now();\n    this._addMsg(\n      this.ui.loading(\"Locating your order...\"),\n      \"assistant\",\n      true,\n      loadId,\n    );\n\n    try {\n      const tenant = window.shopkeeperTenant || this.api?.tenant || \"vogue_rugs\";\n      const apiEndpoint = `${this.api?.base || API_BASE}/orders/track`;\n      const res = await fetch(apiEndpoint, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({\n          tenant_id: tenant,\n          order_number: orderId,\n          phone: phone || null,\n          email: email || null,\n        }),\n      });\n      this._removeMsg(loadId);\n      const data = await res.json();\n      if (!res.ok || data.error || data.success === false) {\n        throw new Error(data.message || data.error || \"Tracking lookup failed\");\n      }\n      await this._hydrateOrderLineItemImages(data);\n      this._addMsg(this.ui.orderStatusCard(data), \"assistant\", true);\n    } catch (e) {\n      this._removeMsg(loadId);\n      console.error(\"Order tracking error:\", e);\n      const detail =\n        e?.message || \"Please verify your order number and phone/email.\";\n      this._addMsg(\n        `Sorry, we could not locate that order. ${this.ui.esc(detail)}`,\n        \"assistant\",\n        true,\n      );\n    }\n  }\n\n  async _hydrateOrderLineItemImages(order) {\n    const items = Array.isArray(order?.line_items) ? order.line_items : [];\n    await Promise.all(\n      items.map(async (item) => {\n        if (!item) return;\n        const handle =\n          item.handle ||\n          String(item.product_url || \"\")\n            .split(\"/products/\")[1]\n            ?.split(/[?#/]/)[0];\n        const existingImage = this._normalizeOrderImageUrl(\n          item.image || item.imgUrl || item.image_url || \"\",\n        );\n        if (existingImage) item.image = existingImage;\n        const applyProduct = (product) => {\n          if (!product) return false;\n          item.handle = product.handle || item.handle;\n          item.product_url =\n            product.url ||\n            (product.handle ? `/products/${product.handle}` : item.product_url);\n          const variantId = String(item.variant_id || \"\");\n          const variantTitle = String(item.variant_title || \"\").toLowerCase();\n          const matchedVariant = Array.isArray(product.variants)\n            ? product.variants.find(\n                (variant) => String(variant.id || \"\") === variantId,\n              ) ||\n              product.variants.find(\n                (variant) =>\n                  String(variant.title || \"\").toLowerCase() === variantTitle,\n              )\n            : null;\n          const image =\n            matchedVariant?.featured_image?.src ||\n            matchedVariant?.featured_image ||\n            product.featured_image ||\n            product.image ||\n            product.image_url ||\n            product.images?.[0] ||\n            product.media?.[0]?.src ||\n            \"\";\n          const normalized = this._normalizeOrderImageUrl(image);\n          if (normalized) item.image = normalized;\n          return !!item.product_url;\n        };\n        try {\n          if (handle) {\n            const res = await fetch(\n              `/products/${encodeURIComponent(handle)}.js`,\n            );\n            if (res.ok) {\n              applyProduct(await res.json());\n              return;\n            }\n          }\n\n          const matchedProduct = await this._findOrderProductByTitle(\n            item.title,\n          );\n          if (matchedProduct) {\n            applyProduct(matchedProduct);\n            return;\n          }\n\n          delete item.product_url;\n          delete item.url;\n        } catch (e) {\n          console.warn(\"Order item image lookup failed:\", e);\n        }\n      }),\n    );\n  }\n\n  async _findOrderProductByTitle(title = \"\") {\n    const query = String(title || \"\").trim();\n    if (!query) return null;\n    const searches = [\n      query,\n      query\n        .replace(/[^\\w\\s'-]/g, \" \")\n        .replace(/\\s+/g, \" \")\n        .trim(),\n    ].filter((value, index, list) => value && list.indexOf(value) === index);\n\n    for (const search of searches) {\n      try {\n        const params = new URLSearchParams({\n          q: search,\n          \"resources[type]\": \"product\",\n          \"resources[limit]\": \"4\",\n          \"resources[options][unavailable_products]\": \"show\",\n        });\n        const res = await fetch(`/search/suggest.json?${params.toString()}`);\n        if (!res.ok) continue;\n        const data = await res.json();\n        const products = data?.resources?.results?.products || [];\n        if (!products.length) continue;\n        const lowerTitle = query.toLowerCase();\n        return (\n          products.find(\n            (product) =>\n              String(product.title || \"\").toLowerCase() === lowerTitle,\n          ) || products[0]\n        );\n      } catch (e) {\n        console.warn(\"Order product search failed:\", e);\n      }\n    }\n    return null;\n  }\n\n  _normalizeOrderImageUrl(src = \"\") {\n    if (!src) return \"\";\n    let value = src;\n    if (typeof value === \"object\") {\n      value = value.src || value.url || value.preview_image?.src || \"\";\n    }\n    value = String(value || \"\").trim();\n    if (!value) return \"\";\n    if (value.startsWith(\"//\")) value = `${window.location.protocol}${value}`;\n    if (value.startsWith(\"/\")) value = `${window.location.origin}${value}`;\n    try {\n      const url = new URL(value, window.location.origin);\n      const shopDomain = window.ShopifyContextPayload?.shop?.domain;\n      if (\n        shopDomain &&\n        /\\.myshopify\\.com$/i.test(url.hostname) &&\n        url.hostname !== shopDomain\n      ) {\n        url.hostname = shopDomain;\n      }\n      if (!url.searchParams.has(\"width\")) url.searchParams.set(\"width\", \"220\");\n      return url.toString();\n    } catch (_) {\n      return value;\n    }\n  }\n\n  // --- Homepage Loading ---\n  async _loadHomepage() {\n    const renderGrid = (gridId, products) => {\n      const grid = document.getElementById(gridId);\n      if (!grid || !products?.length) return;\n      grid.innerHTML = products.map((p) => buildHomepageCard(p)).join(\"\");\n    };\n    try {\n      const personalFacts = Object.keys(this.store.data.facts || {}).length\n        ? this.store.data.facts\n        : { room: [\"Living Room\"] };\n      const [trending, best, personalized, living] = await Promise.allSettled([\n        this.api.browse({}, 1, 4),\n        this.api.browse({}, 2, 4),\n        this.api.browse(personalFacts, 1, 4),\n        this.api.browse({ room: [\"Living Room\"] }, 1, 4),\n      ]);\n      if (trending.status === \"fulfilled\")\n        renderGrid(\"grid-trending\", trending.value.products);\n      if (best.status === \"fulfilled\")\n        renderGrid(\"grid-bestsellers\", best.value.products);\n      if (personalized.status === \"fulfilled\")\n        renderGrid(\"grid-personalized\", personalized.value.products);\n      if (living.status === \"fulfilled\")\n        renderGrid(\"grid-livingroom\", living.value.products);\n    } catch (err) {\n      console.error(\"Homepage load error:\", err);\n    }\n  }\n}\n\n// ============================================================\n// Initialize\n// ============================================================\ndocument.addEventListener(\"DOMContentLoaded\", async () => {\n  window.app = new App();\n  await window.app.store.init();\n  await window.app._restoreChatHistory();\n\n  if (sessionStorage.getItem(\"rugbie_open_agent_on_load\") === \"true\") {\n    sessionStorage.removeItem(\"rugbie_open_agent_on_load\");\n    if (window.app && window.app.toggleDrawer) {\n      // Slight delay to ensure UI is ready\n      setTimeout(() => {\n        window.app.toggleDrawer();\n      }, 100);\n    }\n  }\n});\n\n/**\n * Dynamic CTA logic for Discovery-AI\n */\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n  const liveContext = document.getElementById(\"assistant-live-context\");\n\n  // Add base classes\n  if (liveContext) liveContext.classList.add(\"discovery-ticker\");\n\n  let currentMessages = [];\n  let currentLiveContexts = [];\n  let tickerIndex = 0;\n  let tickerInterval = null;\n\n  const startTicker = () => {\n    if (tickerInterval) clearInterval(tickerInterval);\n    tickerIndex = 0;\n\n    if (currentMessages.length === 0) return;\n\n    const updateUI = () => {\n      const msg = currentMessages[tickerIndex];\n      const ctx = currentLiveContexts[tickerIndex];\n\n      // Add swap out animation\n      if (liveContext && ctx) {\n        liveContext.style.transition = \"all 0.3s ease\";\n        liveContext.style.opacity = \"0\";\n        liveContext.style.transform = \"translateY(-5px)\";\n        setTimeout(() => {\n          liveContext.innerHTML = ctx;\n          liveContext.style.opacity = \"1\";\n          liveContext.style.transform = \"translateY(0)\";\n        }, 300);\n      }\n\n      tickerIndex = (tickerIndex + 1) % currentMessages.length;\n    };\n\n    // Initial update\n    updateUI();\n\n    // Loop every 4 seconds\n    tickerInterval = setInterval(updateUI, 4000);\n  };\n\n  const generateMessages = (variant, product) => {\n    let messages = [];\n    let contexts = [];\n\n    const currency =\n      window.ShopifyContextPayload &&\n      window.ShopifyContextPayload.shop &&\n      window.ShopifyContextPayload.shop.currency\n        ? window.ShopifyContextPayload.shop.currency\n        : \"$\";\n    const formatMoney = (dollars) => {\n      if (currency === \"$\") return \"$\" + Number(dollars).toFixed(2);\n      return Number(dollars).toLocaleString(\"en-US\", {\n        style: \"currency\",\n        currency: \"USD\",\n      });\n    };\n\n    const safeTitle = product.title || \"this product\";\n    const optionsText =\n      variant && variant.title !== \"Default Title\" ? variant.title : \"\";\n\n    const addState = (fabMsg, ctxTitle, ctxVal1, ctxVal2) => {\n      messages.push(fabMsg);\n      contexts.push(\n        '<div class=\"live-indicator\"><span class=\"live-dot\" aria-hidden=\"true\"></span><span class=\"live-label\">' +\n          ctxTitle +\n          \"</span></div>\" +\n          '<div class=\"live-details\"><strong>' +\n          ctxVal1 +\n          \"</strong><small>\" +\n          ctxVal2 +\n          \"</small></div>\",\n      );\n    };\n\n    if (!variant) {\n      addState(\n        \"\u2728 Discovery-AI knows \" + safeTitle,\n        \"Viewing\",\n        safeTitle,\n        \"Ask me anything\",\n      );\n      return { messages, contexts };\n    }\n\n    if (\n      variant.inventory_management === \"shopify\" &&\n      variant.inventory_quantity <= 5 &&\n      variant.inventory_quantity > 0\n    ) {\n      addState(\n        \"\u26A1 Only \" + variant.inventory_quantity + \" left in this size\",\n        \"Availability\",\n        \"Only \" + variant.inventory_quantity + \" Left\",\n        \"Order soon\",\n      );\n    }\n\n    if (variant.compare_at_price && variant.compare_at_price > variant.price) {\n      const pct = Math.round(\n        ((variant.compare_at_price - variant.price) /\n          variant.compare_at_price) *\n          100,\n      );\n      const savings = formatMoney(variant.compare_at_price - variant.price);\n      addState(\n        \"\uD83D\uDD25 Save \" + savings + \" today\",\n        \"Savings\",\n        \"Save \" + savings,\n        \"Compared to MSRP\",\n      );\n      addState(\n        \"\uD83C\uDFF7\uFE0F Up to \" + pct + \"% Off\",\n        \"Price\",\n        \"Starting at \" + formatMoney(variant.price),\n        pct + \"% Off Today\",\n      );\n    }\n\n    if (\n      !variant.compare_at_price ||\n      variant.compare_at_price <= variant.price\n    ) {\n      addState(\n        \"\uD83D\uDCB0 Starting from \" + formatMoney(variant.price),\n        \"Price\",\n        \"Starting at \" + formatMoney(variant.price),\n        \"Great value\",\n      );\n    }\n\n    if (optionsText) {\n      addState(\"\uD83C\uDFA8 Viewing \" + optionsText, \"Variant\", optionsText, safeTitle);\n    } else {\n      addState(\"\uD83D\uDC40 Viewing \" + safeTitle, \"Viewing\", safeTitle, \"\");\n    }\n\n    if (product.rating) {\n      const ratingVal =\n        typeof product.rating === \"object\" && product.rating.rating\n          ? product.rating.rating\n          : product.rating;\n      const countStr = product.rating_count\n        ? product.rating_count + \" Verified Buyers\"\n        : \"Verified Buyers\";\n      addState(\n        \"\u2B50 Rated \" + ratingVal + \"\u2605 by customers\",\n        \"Reviews\",\n        \"\u2B50 \" + ratingVal + \" Rating\",\n        countStr,\n      );\n    }\n\n    addState(\n      \"Explore all available sizes\",\n      \"AI Suggestions\",\n      \"Available Sizes\",\n      \"Find the perfect fit\",\n    );\n\n    const isOutdoor = safeTitle.toLowerCase().includes(\"outdoor\");\n    if (isOutdoor) {\n      addState(\n        \"\uD83E\uDD14 Ask if this works outdoors\",\n        \"Need Help?\",\n        \"Outdoor Use\",\n        \"Weather resistant?\",\n      );\n    } else {\n      addState(\n        \"\uD83E\uDD14 Ask where this works best\",\n        \"Need Help?\",\n        \"Room Placement\",\n        \"Styling tips\",\n      );\n    }\n\n    const isLoop = safeTitle.toLowerCase().includes(\"loop\");\n    if (isLoop) {\n      addState(\n        \"\uD83E\uDDF5 Learn about the loop pile material\",\n        \"Material\",\n        \"Loop Pile\",\n        \"Durability & Texture\",\n      );\n    } else {\n      addState(\n        \"\uD83E\uDDF5 Learn about this material\",\n        \"Need Help?\",\n        \"Material & Texture\",\n        \"Ask our AI\",\n      );\n    }\n\n    addState(\n      \"\uD83E\uDDFC Ask how to clean this rug\",\n      \"Need Help?\",\n      \"Cleaning & Care\",\n      \"Maintenance guide\",\n    );\n    addState(\n      \"\u2764\uFE0F Customers also buy matching runners\",\n      \"Popular Choice\",\n      \"Matching Runners\",\n      \"Complete the look\",\n    );\n    addState(\n      \"\u2728 Discovery-AI knows this product\",\n      \"AI Assistant\",\n      \"Ask Anything\",\n      \"Your personal shopper\",\n    );\n    addState(\n      \"\uD83D\uDCCF Need help choosing the right size?\",\n      \"Need Help?\",\n      \"Sizing Guide\",\n      \"Ask about dimensions\",\n    );\n    addState(\n      \"\uD83C\uDFE1 See how this rug fits your room\",\n      \"AI Suggestions\",\n      \"Room Visualizer\",\n      \"Try it in your space\",\n    );\n    addState(\n      \"\uD83D\uDCAC Ask anything about this product\",\n      \"Need Help?\",\n      \"Product Q&A\",\n      \"Ask our AI\",\n    );\n\n    return { messages, contexts };\n  };\n\n  const updateCTA = (variantId, product) => {\n    if (!product) return;\n\n    let variant = null;\n    if (variantId) {\n      if (product.variants && Array.isArray(product.variants)) {\n        variant = product.variants.find(\n          (v) => v.id === variantId || String(v.id) === String(variantId),\n        );\n      }\n      if (\n        !variant &&\n        product.variant &&\n        (product.variant.id === variantId ||\n          String(product.variant.id) === String(variantId))\n      ) {\n        variant = product.variant;\n      }\n    }\n\n    const data = generateMessages(variant, product);\n    currentMessages = data.messages;\n    currentLiveContexts = data.contexts;\n\n    if (liveContext) liveContext.hidden = false;\n\n    startTicker();\n  };\n\n  if (window.ShopifyContextPayload && window.ShopifyContextPayload.product) {\n    const initialVariantId = window.ShopifyContextPayload.product.variant\n      ? window.ShopifyContextPayload.product.variant.id\n      : null;\n    updateCTA(initialVariantId, window.ShopifyContextPayload.product);\n  }\n\n  document.addEventListener(\"variant:changed\", function (e) {\n    if (\n      e.detail &&\n      e.detail.variant &&\n      window.ShopifyContextPayload &&\n      window.ShopifyContextPayload.product\n    ) {\n      updateCTA(e.detail.variant.id, window.ShopifyContextPayload.product);\n    }\n  });\n});\n"],
  "mappings": "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",
  "names": ["v", "history", "product"]
}
