Skip to content

InformUp Community Newsroom Setup Guide

For WordPress Sites

Overview

This guide will help community newsrooms quickly set up their WordPress sites to publish InformUp articles with embedded interactive surveys. The setup consists of two parts:

  1. One-time site setup - Add survey infrastructure to your WordPress site
  2. Per-article setup - Add survey questions to individual articles
    Important: Survey embeds are designed for web display only and should not be included in email newsletters as they will not display correctly.

Part 1: One-Time Site Setup

Step 1: Access Your WordPress Admin Panel

  1. Log into your WordPress admin dashboard (typically yoursite.com/wp-admin)
  2. Navigate to AppearanceTheme Editor or AppearanceCustomizeAdditional CSS

Step 2: Add Formbricks Survey Script

Add the following code to your site's header (typically in header.php or through a header/footer plugin):

<!-- START Formbricks Surveys -->
<script type="text/javascript">
!function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://app.formbricks.com/js/formbricks.umd.cjs",t.onload=function(){window.formbricks?window.formbricks.setup({environmentId:"cmb87q82g0111z401srx7yr8u",appUrl:"https://app.formbricks.com"}):console.error("Formbricks library failed to load properly. The formbricks object is not available.");};var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(t,e)}();
</script>
<!-- END Formbricks Surveys -->

Alternative Methods to Add Header Code:

  • Plugin Method: Install a plugin like "Insert Headers and Footers" or "Header Footer Code Manager"
  • Theme Customizer: Some themes allow adding header scripts through Appearance → Customize → Header
  • Functions.php: Add via your theme's functions.php file (requires PHP knowledge)

Step 3: Verify Installation

After adding the script, visit your site and check the browser console (F12 → Console tab) to ensure there are no errors related to Formbricks.


Part 2: Article Setup

For each InformUp article you publish, you'll receive:

  • The article content
  • HTML code blocks for embedded survey questions
  • Reporter information

Step 1: Create New Post/Article

  1. In WordPress Admin, go to PostsAdd New
  2. Add the article title
  3. Add the article content in the editor

Step 2: Add Reporter Information

Reporter Details:

  • Name: Amy Whipple
  • Bio: part-time writer, part-time writing instructor, full-time awesome // 🏳️‍🌈 // she/her
  • Photo:
    Add this information to your article's byline or author section according to your site's format.

Step 3: Insert Survey Questions

Survey questions should be inserted after each news brief within the article. You'll receive code blocks with each article. For testing, you can use the examples at the end of this document

Step 4: How to Insert HTML Code in WordPress

Method A: Classic Editor

  1. Switch to "Text" or "HTML" view (tab at top right of editor)
  2. Paste the code block where you want the survey to appear
  3. Switch back to "Visual" view to continue editing

Method B: Block Editor (Gutenberg)

  1. Click the "+" button to add a new block
  2. Search for "Custom HTML" block
  3. Paste the survey code into the HTML block
  4. The survey will appear when you preview or publish

Method C: Page Builders

  • Elementor: Use the HTML widget
  • Divi: Use the Code module
  • WPBakery: Use the Raw HTML element

Step 5: Preview and Publish

  1. Click "Preview" to see how the article looks with embedded surveys
  2. Verify surveys are loading correctly
  3. Test that survey questions appear and are interactive
  4. Publish when ready

Important Notes

Language Settings

  • Surveys default to Spanish language
  • Readers can change the language using the language selector within the survey interface

Survey Completion

  • After completing all survey questions, readers are automatically redirected to InformUp's website
  • This allows them to sign up for updates and engage further with community initiatives

Email Newsletters

⚠️ Important: Do not include survey code blocks in email newsletters. They require JavaScript to function and will not display in email clients. Include only the article text in emails with a link to the full article on your website.

Troubleshooting

Survey not loading?

  • Check browser console for JavaScript errors (F12 → Console)
  • Verify the Formbricks script is in your site header
  • Ensure you're viewing the published page (not just the editor preview)
  • Clear your browser cache
    Survey displays incorrectly?
  • Make sure you're pasting code in HTML/Text view, not Visual view
  • Check that the entire code block was copied (including opening and closing tags)
  • Verify no other plugins are conflicting with JavaScript
    Need to edit survey placement?
  • You can move the HTML blocks like any other content block
  • Surveys will display wherever you place the code

Contact & Support

For technical support or questions about article content and surveys, please reach out right away with any quesitons


Quick Checklist

One-Time Setup ✓

  • Added Formbricks script to site header
  • Verified script loads without errors
  • Tested with a sample article

Per Article ✓

  • Created new post
  • Added article content
  • Added reporter information
  • Inserted Block 1 after first topic
  • Inserted Block 2 for additional questions (if needed)
  • Inserted Block 3 at article end for sequential questions
  • Previewed article with working surveys
  • Published article
  • Excluded survey code from email version

Code samples

Survey Block 1 (First Question)

After the first article topic/section, switch to HTML/Code view and paste:

Question 1 code

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Formbricks Modular Survey Embed</title>
    <style>
            .gh-content {<!doctype html>
      <html lang="en">

      <head>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Formbricks Modular Survey Embed</title>
          <style>
            .gh-content {
              font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            }

            .loading {
              text-align: center;
              color: #6b7280;
              font-size: 16px;
            }

            /* Pre-allocate space for surveys to prevent reflow */
            #survey-init,
            #survey-question-2,
            #survey-sequential {
              min-height: 400px; /* Reserve space before survey loads */
              visibility: hidden; /* Hide during render to prevent scroll adjustment */
            }

            /* Make visible and remove min-height once survey is rendered */
            #survey-init.survey-loaded,
            #survey-question-2.survey-loaded,
            #survey-sequential.survey-loaded {
              min-height: 0;
              visibility: visible;
            }

            .error {
              background: #fef2f2;
              border: 1px solid #fecaca;
              color: #dc2626;
              padding: 16px;
              border-radius: 8px;
              margin: 20px 0;
            }

            .success {
              background: #f0fdf4;
              border: 1px solid #bbf7d0;
              color: #059669;
              padding: 16px;
              border-radius: 8px;
              margin: 20px 0;
            }

            .survey-embed {
              border-radius: 12px;
              overflow: visible !important;
              box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            }

            /* Fix for Formbricks container height - prevent scrollbars */
            .survey-embed > div,
            .survey-embed .fb-survey,
            .survey-embed .fb-survey-inline,
            .survey-embed [class*="fb-"],
            #survey-init > div,
            #survey-init [class*="fb-"] {
              height: auto !important;
              min-height: auto !important;
              max-height: none !important;
              overflow: visible !important;
            }

            /* Ensure all Formbricks content containers expand */
            .fb-survey-content,
            .fb-card,
            .fb-question-container,
            [class*="fb-inline"] {
              height: auto !important;
              min-height: auto !important;
              max-height: none !important;
              overflow: visible !important;
            }

            /* Enhanced auto-scroll prevention styles */
            .no-auto-scroll {
              scroll-behavior: auto !important;
            }

            .no-auto-scroll,
            .no-auto-scroll * {
              scroll-behavior: auto !important;
            }

            /* Prevent any element from causing scroll during loading */
            .preventing-focus {
              overflow: hidden !important;
            }

            .preventing-focus body {
              overflow: hidden !important;
              position: fixed !important;
              width: 100% !important;
            }

            /* Prevent focus outline during initial load */
            .preventing-focus *:focus {
              outline: none !important;
            }

            /* Custom dropdown styling to match Formbricks */
            .fb-select.fb-form-control {
              width: 100%;
              padding: 12px 16px;
              border: 2px solid #e2e8f0;
              border-radius: 8px;
              font-size: 16px;
              font-family: inherit;
              background-color: #ffffff;
              color: #1a202c;
              transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
              appearance: none;
              background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="%23718096"><path d="M4.5 6.5L8 10l3.5-3.5H4.5z"/></svg>');
              background-repeat: no-repeat;
              background-position: right 12px center;
              background-size: 16px;
              cursor: pointer;
            }

            .fb-select.fb-form-control:focus {
              outline: none;
              border-color: var(--fb-brand-color, #00C4B8);
              box-shadow: 0 0 0 3px rgba(0, 196, 184, 0.1);
            }

            .fb-select.fb-form-control:required:invalid {
              border-color: #e53e3e;
            }

            .fb-form-field {
              margin-bottom: 16px;
            }

            .fb-navigation-buttons {
              display: flex;
              gap: 12px;
              justify-content: flex-end;
            }

            .fb-button {
              padding: 12px 24px;
              border-radius: 8px;
              font-size: 16px;
              font-weight: 500;
              border: 2px solid transparent;
              cursor: pointer;
              transition: all 0.15s ease-in-out;
            }

            .fb-button-primary {
              background-color: var(--fb-brand-color, #00C4B8);
              color: white;
            }

            .fb-button-primary:hover:not(:disabled) {
              background-color: #008f87;
            }

            .fb-button-primary:disabled {
              background-color: #a0aec0;
              cursor: not-allowed;
            }

            .fb-button-secondary {
              background-color: transparent;
              color: var(--fb-brand-color, #00C4B8);
              border-color: var(--fb-brand-color, #00C4B8);
            }

            .fb-button-secondary:hover {
              background-color: var(--fb-brand-color, #00C4B8);
              color: white;
            }
    </style>
    <!-- Inter font - using Bunny Fonts (privacy-friendly, GDPR compliant) -->
    <link rel="preconnect" href="https://fonts.bunny.net">
    <link href="https://fonts.bunny.net/css?family=inter:400,500,600,700" rel="stylesheet" />

    <script>
      console.log("📝 Clean survey embed - no modifications applied");
    </script>
  </head>

  <body>
    <div class="gh-content">
      <h3>Question 1</h3>
      <div id="survey-init">
        <div class="loading">Loading survey...</div>
      </div>
    </div>

    <!-- =============================================== -->
    <!-- BLOCK 1: SURVEY MANAGER + FIRST QUESTION       -->
    <!-- Copy this block for the FIRST survey instance  -->
    <!-- =============================================== -->
    <script>
      (function () {
        // IIFE to avoid global scope pollution
        console.log("📦 [BLOCK 1] Survey Manager + First Question");

        // ========================================
        // 🔧 CONFIGURATION - EDIT THESE VALUES
        // ========================================
        const SURVEY_CONFIG = {
          formbricksBaseUrl: "https://app.formbricks.com",
          environmentId: "cmb87q82g0111z401srx7yr8u",
          targetVariableName: "meeting",
          targetVariableValue: "11.17.25",
          debug: true,
          defaultLanguage: "es", // Default language for questions/answers (en, es, fr, de, etc.). Falls back to "default" then "en"
        };

        // User Profile Configuration
        const USER_PROFILE_CONFIG = {
          enabled: false, // Enable user profile integration
          apiEndpoint: "/members/api/session/", // Ghost Members API endpoint
          saveToProfile: true, // Save survey responses to user profile
          prepopulateFromProfile: true, // Pre-fill questions from existing profile data
          profileFieldMapping: {
            // Map question IDs to profile field names
            // Example: 'eahj8ktqtt503sq3uqukkh2k': 'political_preference'
          },
        };

        const BLOCK_1_CONFIG = {
          containerId: "survey-init", // Change this for each block
          questionIndex: 0, // Which question to show (0-based)
          hideNextButton: true, // Hide next/submit buttons
          autoSave: true, // Enable auto-save
          autoSaveDelay: 1000, // Auto-save delay in ms
          useSingleSelectDropdown: false, // Render single-select questions as dropdowns
          dropdownPlaceholder: "Please select an option...", // Placeholder text for dropdowns
        };
        // ========================================
        // END CONFIGURATION
        // ========================================

        // Global error handler to catch Formbricks internal errors
        window.addEventListener('unhandledrejection', function(event) {
          // Check if error is from Formbricks
          if (event.reason && event.reason.message &&
              (event.reason.message.includes('headline') ||
               event.reason.message.includes('e.headline'))) {
            console.warn('⚠️ Caught Formbricks internal error, suppressing:', event.reason.message);
            event.preventDefault(); // Prevent error from bubbling
            return false;
          }
        });

        // Global survey manager - DO NOT EDIT BELOW THIS LINE
        if (!window.FormbricksSurveyManager) {
          window.FormbricksSurveyManager = {
            survey: null,
            formbricksLoaded: false,
            loadPromise: null,
            instances: new Map(),
            sharedResponseId: null, // Shared response ID across all blocks
            currentUser: null, // Current logged-in user data
            userProfile: null, // User profile data for pre-population
            currentLanguage: SURVEY_CONFIG.defaultLanguage || "en", // Global language state, synced across all blocks

            debug(message, data = null, level = "info") {
              if (!SURVEY_CONFIG.debug) return;
              console.log(`[MANAGER][${level.toUpperCase()}]`, message, data);
            },

            setLanguage(newLanguage) {
              console.log(`🌍 [MANAGER] setLanguage called: ${this.currentLanguage} → ${newLanguage}`);
              this.debug(`🌍 Language changed from ${this.currentLanguage} to ${newLanguage}`);
              this.currentLanguage = newLanguage;

              console.log(`🔄 [MANAGER] Re-rendering ${this.instances.size} survey instances`);

              // Re-render all survey instances with new language
              this.instances.forEach((instance, containerId) => {
                console.log(`🔄 [MANAGER] Calling reRenderWithLanguage on ${containerId}`);
                this.debug(`🔄 Re-rendering ${containerId} with language: ${newLanguage}`);
                instance.reRenderWithLanguage(newLanguage);
              });

              console.log('✅ [MANAGER] Language change complete');
            },

            async loadFormbricksJS() {
              if (this.formbricksLoaded) return;
              if (this.loadPromise) return this.loadPromise;

              // Check if global preloader already loaded the library
              if (
                window.formbricksPreloaderReady &&
                typeof window.formbricksSurveys !== "undefined"
              ) {
                this.debug("✅ Library already loaded by global preloader");
                this.formbricksLoaded = true;
                return Promise.resolve("preloaded");
              }

              // If preloader is still loading, wait for it
              if (
                window.formbricksPreloaderInitialized &&
                !window.formbricksPreloaderError
              ) {
                this.debug("⏳ Waiting for global preloader to finish...");
                this.loadPromise = new Promise((resolve) => {
                  window.addEventListener(
                    "formbricksPreloaderReady",
                    () => {
                      this.debug("✅ Global preloader finished loading");
                      this.formbricksLoaded = true;
                      resolve("preloaded");
                    },
                    { once: true },
                  );

                  // Timeout after 5 seconds and fall back to manual loading
                  setTimeout(() => {
                    if (!this.formbricksLoaded) {
                      this.debug(
                        "⚠️ Preloader timeout, falling back to manual load",
                      );
                      window.removeEventListener(
                        "formbricksPreloaderReady",
                        () => {},
                      );
                      resolve(this.loadFormbricksManually());
                    }
                  }, 5000);
                });
                return this.loadPromise;
              }

              // No preloader or preloader failed, load manually
              return this.loadFormbricksManually();
            },

            async loadFormbricksManually() {
              this.debug("Loading Formbricks JS library...");

              const endpoints = [
                "/js/surveys.umd.cjs",
                "/api/packages/surveys",
                "/_next/static/js/surveys.js",
                "/surveys.js",
              ];

              for (const endpoint of endpoints) {
                const fullUrl = `${SURVEY_CONFIG.formbricksBaseUrl}${endpoint}`;
                this.debug(`Trying endpoint: ${fullUrl}`);

                try {
                  const response = await fetch(fullUrl, { method: "HEAD" });
                  if (response.ok) {
                    return new Promise((resolve, reject) => {
                      const script = document.createElement("script");
                      script.src = fullUrl;
                      script.onload = () => {
                        this.debug(`✅ Library loaded from: ${fullUrl}`);
                        this.formbricksLoaded = true;
                        resolve(fullUrl);
                      };
                      script.onerror = () => {
                        reject(
                          new Error(`Script execution failed: ${fullUrl}`),
                        );
                      };
                      document.head.appendChild(script);
                    });
                  }
                } catch (error) {
                  this.debug(
                    `Failed to load from ${fullUrl}:`,
                    error.message,
                    "warning",
                  );
                }
              }

              throw new Error(
                "Could not load Formbricks JS library from any endpoint",
              );
            },

            async fetchSurvey() {
              if (this.survey) {
                this.debug("Using cached survey");
                return this.survey;
              }

              const url = `${SURVEY_CONFIG.formbricksBaseUrl}/api/v1/client/${SURVEY_CONFIG.environmentId}/environment`;
              this.debug("Fetching surveys from:", url);
              this.debug("🔍 Looking for variable:", {
                name: SURVEY_CONFIG.targetVariableName,
                value: SURVEY_CONFIG.targetVariableValue,
              });

              try {
                const response = await fetch(url);
                if (!response.ok)
                  throw new Error(
                    `HTTP ${response.status}: ${response.statusText}`,
                  );

                const result = await response.json();
                const surveys = result?.data?.data?.surveys || [];
                this.debug(`Found ${surveys.length} total surveys`);

                if (surveys.length === 0)
                  throw new Error("No surveys found in this environment");

                // 🔍 DEBUG: Show all surveys and their variables
                surveys.forEach((survey, index) => {
                  this.debug(`Survey ${index + 1}:`, {
                    id: survey.id,
                    name: survey.name,
                    status: survey.status,
                    createdAt: survey.createdAt,
                    updatedAt: survey.updatedAt,
                    variables: survey.variables || [],
                    questionCount: survey.questions?.length || 0,
                  });
                });

                // 🎯 FIND MATCHING SURVEYS: Only exact matches
                const matchingSurveys = surveys.filter((survey) => {
                  if (survey.status !== "inProgress") {
                    this.debug(
                      `❌ Survey ${survey.id} skipped: status = ${survey.status}`,
                    );
                    return false;
                  }

                  if (!Array.isArray(survey.variables)) {
                    this.debug(
                      `❌ Survey ${survey.id} skipped: no variables array`,
                    );
                    return false;
                  }

                  const hasMatch = survey.variables.some((variable) => {
                    const nameMatch =
                      variable.name === SURVEY_CONFIG.targetVariableName;
                    const valueMatch =
                      String(variable.value).trim() ===
                      SURVEY_CONFIG.targetVariableValue.trim();
                    const bothMatch = nameMatch && valueMatch;

                    this.debug(`🔍 Survey ${survey.id} variable check:`, {
                      variable: variable,
                      nameMatch: nameMatch,
                      valueMatch: valueMatch,
                      bothMatch: bothMatch,
                    });

                    return bothMatch;
                  });

                  if (hasMatch) {
                    this.debug(
                      `✅ Survey ${survey.id} MATCHES target criteria`,
                    );
                  } else {
                    this.debug(`❌ Survey ${survey.id} does not match`);
                  }

                  return hasMatch;
                });

                this.debug(
                  `Found ${matchingSurveys.length} surveys matching criteria`,
                );

                if (matchingSurveys.length === 0) {
                  // 🚫 NO FALLBACK - Strict error
                  const activeCount = surveys.filter(
                    (s) => s.status === "inProgress",
                  ).length;
                  throw new Error(
                    `No survey found with exact match:\n` +
                      `  Variable: ${SURVEY_CONFIG.targetVariableName} = "${SURVEY_CONFIG.targetVariableValue}"\n` +
                      `  Found ${surveys.length} total surveys, ${activeCount} active\n` +
                      `  Check console for detailed survey list`,
                  );
                }

                // 📊 SELECT MOST RECENT: Sort by updatedAt, then createdAt
                const sortedMatches = matchingSurveys.sort((a, b) => {
                  // First try updatedAt (most recent activity)
                  const aUpdated = new Date(a.updatedAt || a.createdAt);
                  const bUpdated = new Date(b.updatedAt || b.createdAt);

                  if (aUpdated.getTime() !== bUpdated.getTime()) {
                    return bUpdated.getTime() - aUpdated.getTime(); // Most recent first
                  }

                  // If updatedAt is the same, use createdAt
                  return (
                    new Date(b.createdAt).getTime() -
                    new Date(a.createdAt).getTime()
                  );
                });

                const targetSurvey = sortedMatches[0];

                this.debug("✅ Using most recent survey:", {
                  id: targetSurvey.id,
                  name: targetSurvey.name,
                  createdAt: targetSurvey.createdAt,
                  updatedAt: targetSurvey.updatedAt,
                  isNewest:
                    sortedMatches.length > 1
                      ? `YES (newest of ${sortedMatches.length} matches)`
                      : "ONLY MATCH",
                  matchingVariable: targetSurvey.variables.find(
                    (v) =>
                      v.name === SURVEY_CONFIG.targetVariableName &&
                      String(v.value).trim() ===
                        SURVEY_CONFIG.targetVariableValue.trim(),
                  ),
                });

                // Log all survey properties to check for hidden fields configuration
                console.log("📋 FULL SURVEY OBJECT:", targetSurvey);
                console.log(
                  "🔍 Survey hiddenFields:",
                  targetSurvey.hiddenFields,
                );
                console.log("🔍 Survey fields:", targetSurvey.fields);
                console.log("🔍 Survey config:", targetSurvey.config);

                this.survey = targetSurvey;
                return targetSurvey;
              } catch (error) {
                this.debug("Fetch error:", error.message, "error");
                throw error;
              }
            },

            async loadUserProfile() {
              if (!USER_PROFILE_CONFIG.enabled) {
                this.debug("👤 User profile integration disabled");
                return null;
              }

              try {
                this.debug("👤 Loading user profile...");

                // Check if Ghost members are available
                if (
                  typeof window.ghost === "undefined" ||
                  !window.ghost.members
                ) {
                  this.debug(
                    "👤 Ghost members not available, trying direct API call",
                  );
                  return await this.fetchUserProfileDirect();
                }

                // Use Ghost members API
                const member = await window.ghost.members.getCurrentMember();
                if (member) {
                  this.currentUser = member;
                  this.userProfile = member.profile || {};
                  this.debug("👤 User profile loaded:", {
                    email: member.email,
                    profileKeys: Object.keys(this.userProfile),
                  });
                  return this.userProfile;
                } else {
                  this.debug("👤 No logged-in user found");
                  return null;
                }
              } catch (error) {
                this.debug(
                  "👤 Error loading user profile:",
                  error.message,
                  "error",
                );
                return null;
              }
            },

            async fetchUserProfileDirect() {
              try {
                const response = await fetch(USER_PROFILE_CONFIG.apiEndpoint, {
                  method: "GET",
                  credentials: "include",
                  headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                  },
                });

                if (response.ok) {
                  const userData = await response.json();
                  this.currentUser = userData;
                  this.userProfile =
                    userData.profile || userData.metadata || {};
                  this.debug(
                    "👤 User profile fetched directly:",
                    userData.email,
                  );
                  return this.userProfile;
                } else {
                  this.debug("👤 User not authenticated (direct fetch)");
                  return null;
                }
              } catch (error) {
                this.debug(
                  "👤 Direct profile fetch failed:",
                  error.message,
                  "error",
                );
                return null;
              }
            },

            async saveUserProfile(questionId, selectedValue, question) {
              if (
                !USER_PROFILE_CONFIG.enabled ||
                !USER_PROFILE_CONFIG.saveToProfile
              ) {
                return;
              }

              if (!this.currentUser) {
                this.debug("👤 Cannot save to profile: no logged-in user");
                return;
              }

              try {
                this.debug("👤 Saving to user profile...", {
                  questionId,
                  selectedValue,
                });

                // Get profile field name from mapping
                const profileField =
                  USER_PROFILE_CONFIG.profileFieldMapping[questionId];
                if (!profileField) {
                  this.debug(
                    "👤 No profile field mapping for question:",
                    questionId,
                  );
                  return;
                }

                // Update local profile data
                this.userProfile[profileField] = selectedValue;

                // Save to Ghost profile (this would need Ghost API integration)
                // For now, we'll save to localStorage as a fallback
                const profileKey = `informup_profile_${this.currentUser.email}`;
                localStorage.setItem(
                  profileKey,
                  JSON.stringify(this.userProfile),
                );

                this.debug("👤 Profile saved successfully:", {
                  profileField,
                  selectedValue,
                });
              } catch (error) {
                this.debug(
                  "👤 Error saving to profile:",
                  error.message,
                  "error",
                );
              }
            },

            getProfileValue(questionId) {
              if (
                !USER_PROFILE_CONFIG.enabled ||
                !USER_PROFILE_CONFIG.prepopulateFromProfile
              ) {
                return null;
              }

              if (!this.userProfile) {
                return null;
              }

              const profileField =
                USER_PROFILE_CONFIG.profileFieldMapping[questionId];
              if (!profileField) {
                return null;
              }

              const value = this.userProfile[profileField];
              this.debug("👤 Retrieved profile value:", {
                questionId,
                profileField,
                value,
              });
              return value;
            },

            async initializeAndRenderQuestion(
              containerId,
              questionIndex,
              config = {},
            ) {
              this.debug(
                `Initializing question ${questionIndex} in container ${containerId}`,
              );

              try {
                // Load Formbricks library
                await this.loadFormbricksJS();

                // Load user profile (parallel with survey fetch)
                const [survey, userProfile] = await Promise.all([
                  this.fetchSurvey(),
                  this.loadUserProfile(),
                ]);

                // Create and render question instance
                const instance = new FormbricksSurveyInstance(
                  containerId,
                  questionIndex,
                  survey,
                  config,
                );
                this.instances.set(containerId, instance);
                await instance.render();

                this.debug(`✅ Successfully initialized ${containerId}`);
              } catch (error) {
                this.debug(
                  `❌ Failed to initialize ${containerId}:`,
                  error.message,
                  "error",
                );
                this.showError(containerId, error.message);
              }
            },

            async renderQuestion(containerId, questionIndex, config = {}) {
              this.debug(
                `Rendering question ${questionIndex} in container ${containerId}`,
              );

              if (!this.survey) {
                throw new Error(
                  "Survey not initialized. Use initializeAndRenderQuestion for the first block.",
                );
              }

              if (!this.formbricksLoaded) {
                throw new Error(
                  "Formbricks library not loaded. Use initializeAndRenderQuestion for the first block.",
                );
              }

              try {
                const instance = new FormbricksSurveyInstance(
                  containerId,
                  questionIndex,
                  this.survey,
                  config,
                );
                this.instances.set(containerId, instance);
                await instance.render();

                this.debug(`✅ Successfully rendered ${containerId}`);
              } catch (error) {
                this.debug(
                  `❌ Failed to render ${containerId}:`,
                  error.message,
                  "error",
                );
                this.showError(containerId, error.message);
              }
            },

            async renderSequentialQuestions(
              containerId,
              startQuestionIndex,
              config = {},
            ) {
              this.debug(
                `Rendering sequential questions starting from ${startQuestionIndex} in container ${containerId}`,
              );

              if (!this.survey) {
                throw new Error(
                  "Survey not initialized. Use initializeAndRenderQuestion for the first block.",
                );
              }

              if (!this.formbricksLoaded) {
                throw new Error(
                  "Formbricks library not loaded. Use initializeAndRenderQuestion for the first block.",
                );
              }

              try {
                const instance = new FormbricksSequentialSurveyInstance(
                  containerId,
                  startQuestionIndex,
                  this.survey,
                  config,
                );
                this.instances.set(containerId, instance);
                await instance.render();

                this.debug(
                  `✅ Successfully rendered sequential ${containerId}`,
                );
              } catch (error) {
                this.debug(
                  `❌ Failed to render sequential ${containerId}:`,
                  error.message,
                  "error",
                );
                this.showError(containerId, error.message);
              }
            },

            showError(containerId, message) {
              const container = document.getElementById(containerId);
              if (container) {
                container.innerHTML = `
              <div style="background: #fef2f2; border: 1px solid #fecaca; color: #dc2626; padding: 16px; border-radius: 8px; margin: 20px 0;">
                <strong>Error:</strong> ${message}
              </div>
            `;
              }
            },
          };

          // Survey Instance Class
          class FormbricksSurveyInstance {
            constructor(containerId, questionIndex, survey, config = {}) {
              this.containerId = containerId;
              this.embedId = `${containerId}-embed`;
              this.questionIndex = questionIndex;
              this.survey = survey;
              this.originalSurvey = JSON.parse(JSON.stringify(survey)); // Keep original for re-translation
              this.config = {
                hideNextButton: true,
                autoSave: true,
                autoSaveDelay: 1000,
                ...config,
              };

              this.responseData = {};
              this.saveTimeout = null;
              this.cleanupIntervals = [];
              this.isSaving = false;
              this.languageCache = new Map(); // Cache rendered HTML by language
            }

            debug(message, data = null, level = "info") {
              if (!SURVEY_CONFIG.debug) return;
              console.log(
                `[${this.containerId}][${level.toUpperCase()}]`,
                message,
                data,
              );
            }

            translateText(textObj, language) {
              if (typeof textObj === "string") return textObj;
              if (typeof textObj === "object" && textObj !== null) {
                // Try in order: language -> default -> en -> first available
                return (
                  textObj[language] ||
                  textObj.default ||
                  textObj.en ||
                  Object.values(textObj)[0] ||
                  ""
                );
              }
              return textObj || "";
            }

            translateSurvey(survey, language) {
              // Create a deep copy and translate all text fields
              const translated = JSON.parse(JSON.stringify(survey));

              // Translate questions - keep as objects with .default property for Formbricks
              if (translated.questions) {
                translated.questions = translated.questions.map(q => {
                  const newQuestion = { ...q };

                  // Translate headline - keep as object but update .default
                  if (q.headline) {
                    newQuestion.headline = {
                      default: this.translateText(q.headline, language)
                    };
                  }

                  // Translate subheader
                  if (q.subheader) {
                    newQuestion.subheader = {
                      default: this.translateText(q.subheader, language)
                    };
                  }

                  // Translate choice labels
                  if (q.choices) {
                    newQuestion.choices = q.choices.map(choice => ({
                      ...choice,
                      label: {
                        default: this.translateText(choice.label, language)
                      }
                    }));
                  }

                  return newQuestion;
                });
              }

              return translated;
            }

            prepareSingleQuestion() {
              if (
                !this.originalSurvey.questions ||
                this.originalSurvey.questions.length <= this.questionIndex
              ) {
                throw new Error(
                  `Question index ${this.questionIndex} not found in survey`,
                );
              }

              const question = this.originalSurvey.questions[this.questionIndex];
              this.debug(
                "Creating single question survey for question type:",
                question.type,
              );

              const singleQuestionSurvey = {
                ...this.originalSurvey,
                questions: [question],
                welcomeCard: { enabled: false },
                thankyouCard: { enabled: false },
              };

              // Translate survey to current language from original data
              const language = window.FormbricksSurveyManager.currentLanguage || "en";
              this.debug(`🌍 Translating from original survey to language: ${language}`);
              return this.translateSurvey(singleQuestionSurvey, language);
            }

            async render() {
              this.debug("Attempting to render survey");

              const container = document.getElementById(this.containerId);
              container.innerHTML = `<div id="${this.embedId}" class="survey-embed"></div>`;

              const singleQuestionSurvey = this.prepareSingleQuestion();
              const question = singleQuestionSurvey.questions[0];

              // Branch rendering based on question type and configuration
              if (this.shouldRenderAsDropdown(question)) {
                this.debug("Rendering as custom dropdown");
                await this.renderCustomDropdown(question);
              } else {
                this.debug("Rendering with native Formbricks JS");
                await this.renderWithFormbricks(singleQuestionSurvey);
              }
            }

            async renderWithFormbricks(singleQuestionSurvey) {
              if (
                typeof window.formbricksSurveys === "undefined" ||
                !window.formbricksSurveys.renderSurveyInline
              ) {
                throw new Error("Formbricks survey library not available");
              }

              const surveyProps = {
                survey: singleQuestionSurvey,
                containerId: this.embedId,
                mode: "inline",
                languageCode: "default", // Always use default - we translate the survey ourselves
                styling: this.survey.styling || {},
                onDisplay: () => {
                  this.debug("🎯 Survey displayed");

                  // Cache the rendered HTML for current language
                  setTimeout(() => {
                    const embedContainer = document.getElementById(this.embedId);
                    const currentLang = window.FormbricksSurveyManager.currentLanguage;

                    if (embedContainer && !this.languageCache.has(currentLang)) {
                      this.languageCache.set(currentLang, {
                        html: embedContainer.innerHTML,
                        timestamp: Date.now()
                      });
                      console.log(`💾 [${this.containerId}] Cached HTML for language: ${currentLang}`);
                    }

                    // Make container visible now that content is rendered
                    const container = document.getElementById(this.containerId);
                    if (container) {
                      container.classList.add("survey-loaded");
                      this.debug("✅ Made survey visible after render");
                    }
                  }, 50);

                  // Set up language change detection
                  this.setupLanguageChangeDetection();

                  this.setupAutoSave();
                  this.setupPeriodicSave();
                },
                onResponse: (response) => {
                  this.debug("📝 Formbricks onResponse received", response);
                  if (response.data) {
                    // Merge with existing response data, preserving what we've collected manually
                    this.responseData = {
                      ...this.responseData,
                      ...response.data,
                    };
                    this.debug(
                      "💾 Merged responseData with Formbricks data:",
                      this.responseData,
                    );
                    if (this.config.autoSave) {
                      clearTimeout(this.saveTimeout);
                      this.saveResponse("native-response");
                    }
                  }
                },
                onFinished: () => {
                  this.debug("🎉 Survey finished");
                  this.showSuccess("Thank you for your response!");
                },
                onClose: () => this.debug("Survey closed"),
                onError: (error) => {
                  this.debug("Survey error", error, "error");
                  this.showError(
                    "An error occurred while displaying the survey",
                  );
                },
              };

              try {
                window.formbricksSurveys.renderSurveyInline(surveyProps);
                this.debug("Successfully called renderSurveyInline");

                // Make visible immediately in case onDisplay doesn't fire due to Formbricks errors
                setTimeout(() => {
                  const container = document.getElementById(this.containerId);
                  if (container && !container.classList.contains('survey-loaded')) {
                    container.classList.add("survey-loaded");
                    this.debug("✅ Force-made survey visible (fallback)");
                  }
                  this.setupUICleanup();
                }, 500);
              } catch (error) {
                // Make visible even on error
                const container = document.getElementById(this.containerId);
                if (container) {
                  container.classList.add("survey-loaded");
                }

                this.debug(
                  "Error calling renderSurveyInline",
                  error.message,
                  "error",
                );
                throw new Error("Failed to render survey");
              }
            }

            setupUICleanup() {
              // Prevent auto-focus
              this.preventAutoFocus();

              this.hideOptionalRequiredText();
              this.fixSurveyContainerHeight();

              if (this.config.hideNextButton) {
                this.hideNextButtons();
              }

              const cleanupInterval = setInterval(() => {
                this.hideOptionalRequiredText();
                this.fixSurveyContainerHeight();
                if (this.config.hideNextButton) {
                  this.hideNextButtons();
                }
              }, 3000);

              this.cleanupIntervals.push(cleanupInterval);
              setTimeout(() => clearInterval(cleanupInterval), 60000);
            }

            fixSurveyContainerHeight() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              // Remove height constraints from all survey containers
              const selectors = [
                this.embedId,
                ".fb-survey",
                ".fb-survey-inline",
                ".fb-survey-content",
                ".fb-card",
                ".fb-question-container",
                '[class*="fb-inline"]',
                '[class*="fb-survey"]',
              ];

              selectors.forEach((selector) => {
                const elements = selector.startsWith("#")
                  ? [document.getElementById(selector.slice(1))]
                  : embedContainer.querySelectorAll(selector);

                if (elements) {
                  elements.forEach((el) => {
                    if (el && el.style) {
                      el.style.height = "auto";
                      el.style.minHeight = "auto";
                      el.style.maxHeight = "none";
                      el.style.overflow = "visible";
                    }
                  });
                }
              });

              this.debug("📏 Fixed survey container heights to auto-expand");
            }

            hideOptionalRequiredText() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const walker = document.createTreeWalker(
                embedContainer,
                NodeFilter.SHOW_TEXT,
                null,
                false,
              );

              const textNodes = [];
              let node;
              while ((node = walker.nextNode())) {
                const text = node.textContent.toLowerCase().trim();
                if (
                  text.includes("optional") ||
                  text.includes("required") ||
                  text === "*"
                ) {
                  textNodes.push(node);
                }
              }

              textNodes.forEach((textNode) => {
                const parent = textNode.parentElement;
                if (parent && parent.textContent.trim().length < 20) {
                  parent.style.display = "none";
                  this.debug(
                    "🧹 Hidden optional/required text:",
                    textNode.textContent.trim(),
                  );
                }
              });
            }

            hideNextButtons() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              setTimeout(() => {
                const allButtons = embedContainer.querySelectorAll("button");
                allButtons.forEach((button) => {
                  const buttonText = button.textContent.toLowerCase().trim();
                  if (
                    buttonText.includes("next") ||
                    buttonText.includes("submit") ||
                    buttonText.includes("continue") ||
                    (buttonText === "" && button.type === "submit")
                  ) {
                    button.style.display = "none";
                    button.style.visibility = "hidden";
                    this.debug(
                      `✓ Hidden button: "${button.textContent.trim()}"`,
                    );
                  }
                });
              }, 1000);
            }

            setupAutoSave() {
              if (!this.config.autoSave) return;

              this.debug("🔧 Setting up auto-save handlers");

              setTimeout(() => {
                this.setupTextAutoSave();
                this.setupChoiceAutoSave();
                this.setupNPSAutoSave();
                this.setupRadioCheckboxAutoSave();
                this.setupSelectAutoSave();
                this.setupUniversalClickHandler();
              }, 500);
            }

            setupTextAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const textInputs = embedContainer.querySelectorAll(
                'textarea, input[type="text"], input:not([type])',
              );
              this.debug(
                `📝 Setting up text auto-save for ${textInputs.length} inputs`,
              );

              textInputs.forEach((input) => {
                // Auto-save on input with delay
                input.addEventListener("input", () => {
                  clearTimeout(this.saveTimeout);
                  if (input.value.trim()) {
                    const questionId =
                      this.findQuestionId(input) ||
                      this.survey.questions[this.questionIndex]?.id ||
                      "text-response";
                    this.responseData[questionId] = input.value;
                    this.debug(`💾 Auto-saving text: "${input.value}"`);

                    this.saveTimeout = setTimeout(() => {
                      this.saveResponse("auto-text");
                    }, this.config.autoSaveDelay);
                  }
                });

                // Immediate save on blur (when user clicks away)
                input.addEventListener("blur", () => {
                  if (input.value.trim()) {
                    const questionId =
                      this.findQuestionId(input) ||
                      this.survey.questions[this.questionIndex]?.id ||
                      "text-response";
                    this.responseData[questionId] = input.value;
                    this.debug(`💾 Immediate save on blur: "${input.value}"`);
                    clearTimeout(this.saveTimeout);
                    this.saveResponse("blur-text");
                  }
                });

                // Save on Enter key
                input.addEventListener("keypress", (e) => {
                  if (e.key === "Enter" && input.value.trim()) {
                    const questionId =
                      this.findQuestionId(input) ||
                      this.survey.questions[this.questionIndex]?.id ||
                      "text-response";
                    this.responseData[questionId] = input.value;
                    this.debug(`💾 Save on Enter: "${input.value}"`);
                    clearTimeout(this.saveTimeout);
                    this.saveResponse("enter-text");
                  }
                });
              });
            }

            setupChoiceAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              // Set up click handlers for choice elements
              const setupClickHandlers = () => {
                const choices = embedContainer.querySelectorAll(
                  'button, div[role="button"], [data-value], .choice-option, [class*="choice"], [class*="option"]',
                );
                this.debug(
                  `🎯 Setting up click handlers for ${choices.length} choice elements`,
                );

                choices.forEach((choice) => {
                  if (!choice.hasAttribute("data-auto-save-attached")) {
                    choice.setAttribute("data-auto-save-attached", "true");

                    choice.addEventListener("click", () => {
                      // Small delay to allow Formbricks to update selection state
                      setTimeout(() => {
                        const choiceValue =
                          choice.getAttribute("data-value") ||
                          choice.getAttribute("value") ||
                          choice.textContent.trim();

                        // Skip language selector options
                        const choiceClass = choice.className || "";
                        const choiceAria = choice.getAttribute("aria-label") || "";
                        const isLanguage =
                          choiceClass.toLowerCase().includes("language") ||
                          choiceClass.toLowerCase().includes("lang") ||
                          choiceAria.toLowerCase().includes("language") ||
                          choiceValue === "English" ||
                          choiceValue === "Spanish; Castilian" ||
                          choiceValue === "Spanish" ||
                          choiceValue === "Español";

                        if (isLanguage) {
                          this.debug(`🚫 Skipping language option in choice handler: "${choiceValue}"`);
                          return;
                        }

                        if (choiceValue) {
                          const questionId =
                            this.findQuestionId(choice) ||
                            this.survey.questions[this.questionIndex]?.id ||
                            "choice-response";
                          this.responseData[questionId] = choiceValue;
                          this.debug(`🎯 Choice clicked: "${choiceValue}"`);

                          // Immediate save on choice selection
                          clearTimeout(this.saveTimeout);
                          this.saveResponse("click-choice");
                        }
                      }, 100);
                    });
                  }
                });
              };

              // Initial setup
              setTimeout(setupClickHandlers, 500);

              // Observer for dynamically added choices
              const observer = new MutationObserver((mutations) => {
                let shouldSetupHandlers = false;

                mutations.forEach((mutation) => {
                  if (
                    mutation.type === "childList" &&
                    mutation.addedNodes.length > 0
                  ) {
                    shouldSetupHandlers = true;
                  }

                  // Also watch for selection changes
                  if (
                    mutation.type === "attributes" &&
                    (mutation.attributeName === "data-selected" ||
                      mutation.attributeName === "aria-checked" ||
                      mutation.attributeName === "class")
                  ) {
                    const element = mutation.target;
                    const isSelected =
                      element.getAttribute("data-selected") === "true" ||
                      element.getAttribute("aria-checked") === "true" ||
                      element.classList.contains("selected");

                    if (isSelected) {
                      const choiceValue =
                        element.getAttribute("data-value") ||
                        element.getAttribute("value") ||
                        element.textContent.trim();

                      if (choiceValue) {
                        const questionId =
                          this.findQuestionId(element) ||
                          this.survey.questions[this.questionIndex]?.id ||
                          "choice-response";
                        this.responseData[questionId] = choiceValue;
                        this.debug(
                          `🎯 Choice selected via attribute: "${choiceValue}"`,
                        );

                        clearTimeout(this.saveTimeout);
                        this.saveResponse("attr-choice");
                      }
                    }
                  }
                });

                if (shouldSetupHandlers) {
                  setTimeout(setupClickHandlers, 100);
                }
              });

              observer.observe(embedContainer, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeFilter: ["data-selected", "aria-checked", "class"],
              });
              this.cleanupIntervals.push({ type: "observer", observer });
            }

            setupNPSAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              // Set up click handlers for NPS buttons
              const setupNPSClickHandlers = () => {
                const npsButtons = embedContainer.querySelectorAll(
                  'button[class*="nps"], [role="button"][class*="nps"], button[data-value], .nps-option, [class*="rating"] button',
                );
                this.debug(
                  `📊 Setting up NPS click handlers for ${npsButtons.length} buttons`,
                );

                npsButtons.forEach((button) => {
                  if (!button.hasAttribute("data-nps-save-attached")) {
                    button.setAttribute("data-nps-save-attached", "true");

                    button.addEventListener("click", () => {
                      setTimeout(() => {
                        const npsValue = parseInt(
                          button.getAttribute("data-value") ||
                            button.textContent.trim(),
                        );
                        if (
                          !isNaN(npsValue) &&
                          npsValue >= 0 &&
                          npsValue <= 10
                        ) {
                          const questionId =
                            this.findQuestionId(button) ||
                            this.survey.questions[this.questionIndex]?.id ||
                            "nps-response";
                          this.responseData[questionId] = npsValue;
                          this.debug(`📊 NPS clicked: ${npsValue}`);

                          // Immediate save on NPS selection
                          clearTimeout(this.saveTimeout);
                          this.saveResponse("click-nps");
                        }
                      }, 100);
                    });
                  }
                });
              };

              // Initial setup
              setTimeout(setupNPSClickHandlers, 500);

              // Observer for dynamically added NPS buttons and selection changes
              const observer = new MutationObserver((mutations) => {
                let shouldSetupHandlers = false;

                mutations.forEach((mutation) => {
                  if (
                    mutation.type === "childList" &&
                    mutation.addedNodes.length > 0
                  ) {
                    shouldSetupHandlers = true;
                  }

                  // Watch for selection changes on NPS buttons
                  if (
                    mutation.type === "attributes" &&
                    (mutation.attributeName === "data-selected" ||
                      mutation.attributeName === "aria-checked" ||
                      mutation.attributeName === "class")
                  ) {
                    const element = mutation.target;
                    const isSelected =
                      element.getAttribute("data-selected") === "true" ||
                      element.getAttribute("aria-checked") === "true" ||
                      element.classList.contains("selected");

                    if (isSelected) {
                      const npsValue = parseInt(
                        element.getAttribute("data-value") ||
                          element.textContent.trim(),
                      );
                      if (!isNaN(npsValue) && npsValue >= 0 && npsValue <= 10) {
                        const questionId =
                          this.findQuestionId(element) ||
                          this.survey.questions[this.questionIndex]?.id ||
                          "nps-response";
                        this.responseData[questionId] = npsValue;
                        this.debug(
                          `📊 NPS selected via attribute: ${npsValue}`,
                        );

                        clearTimeout(this.saveTimeout);
                        this.saveResponse("attr-nps");
                      }
                    }
                  }
                });

                if (shouldSetupHandlers) {
                  setTimeout(setupNPSClickHandlers, 100);
                }
              });

              observer.observe(embedContainer, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeFilter: ["data-selected", "aria-checked", "class"],
              });
              this.cleanupIntervals.push({ type: "observer", observer });
            }

            setupRadioCheckboxAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const radioCheckboxes = embedContainer.querySelectorAll(
                'input[type="radio"], input[type="checkbox"]',
              );
              this.debug(
                `📋 Setting up radio/checkbox auto-save for ${radioCheckboxes.length} inputs`,
              );

              radioCheckboxes.forEach((input) => {
                input.addEventListener("change", () => {
                  const questionId =
                    this.findQuestionId(input) ||
                    this.survey.questions[this.questionIndex]?.id ||
                    "radio-checkbox-response";

                  if (input.type === "radio") {
                    this.responseData[questionId] = input.value;
                    this.debug(`📋 Radio selected: "${input.value}"`);
                  } else if (input.type === "checkbox") {
                    if (!this.responseData[questionId])
                      this.responseData[questionId] = [];

                    if (input.checked) {
                      if (
                        !this.responseData[questionId].includes(input.value)
                      ) {
                        this.responseData[questionId].push(input.value);
                      }
                    } else {
                      this.responseData[questionId] = this.responseData[
                        questionId
                      ].filter((v) => v !== input.value);
                    }
                    this.debug(
                      `📋 Checkbox updated: "${input.value}" = ${input.checked}`,
                    );
                  }

                  clearTimeout(this.saveTimeout);
                  this.saveResponse("change-radio-checkbox");
                });
              });
            }

            setupSelectAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const selects = embedContainer.querySelectorAll("select");
              this.debug(
                `📋 Setting up select auto-save for ${selects.length} dropdowns`,
              );

              selects.forEach((select) => {
                select.addEventListener("change", () => {
                  const questionId =
                    this.findQuestionId(select) ||
                    this.survey.questions[this.questionIndex]?.id ||
                    "select-response";
                  this.responseData[questionId] = select.value;
                  this.debug(`📋 Select changed: "${select.value}"`);

                  clearTimeout(this.saveTimeout);
                  this.saveResponse("change-select");
                });
              });
            }

            setupUniversalClickHandler() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              this.debug("🌐 Setting up universal click handler");

              embedContainer.addEventListener("click", (e) => {
                const target = e.target;

                // Skip if it's already handled by specific handlers
                if (
                  target.hasAttribute("data-auto-save-attached") ||
                  target.hasAttribute("data-nps-save-attached")
                ) {
                  return;
                }

                // Skip navigation/action buttons and language selectors
                const value =
                  target.getAttribute("data-value") ||
                  target.getAttribute("value") ||
                  target.textContent.trim();

                const targetClass = target.className || "";
                const targetAria = target.getAttribute("aria-label") || "";

                // Check if this is a language selector
                const isLanguageSelector =
                  targetClass.toLowerCase().includes("language") ||
                  targetClass.toLowerCase().includes("lang") ||
                  targetAria.toLowerCase().includes("language") ||
                  targetAria.toLowerCase().includes("lang") ||
                  value === "English" ||
                  value === "Spanish; Castilian" ||
                  value === "Spanish" ||
                  value === "Español" ||
                  value === "French" ||
                  value === "Français" ||
                  value === "German" ||
                  value === "Deutsch";

                if (isLanguageSelector) {
                  this.debug(`🚫 Skipping language selector: "${value}"`);
                  return;
                }

                const isNavigationButton =
                  value &&
                  (value.toLowerCase() === "next" ||
                    value.toLowerCase() === "submit" ||
                    value.toLowerCase() === "continue" ||
                    value.toLowerCase() === "back" ||
                    value.toLowerCase() === "previous" ||
                    target.type === "submit" ||
                    target.classList.contains("submit-button") ||
                    target.classList.contains("next-button") ||
                    target.classList.contains("continue-button"));

                if (isNavigationButton) {
                  this.debug(`🚫 Skipping navigation button: "${value}"`);
                  return;
                }

                // Handle clicks on interactive elements that might not be caught otherwise
                if (
                  target.tagName === "BUTTON" ||
                  target.tagName === "A" ||
                  target.getAttribute("role") === "button" ||
                  target.getAttribute("role") === "option" ||
                  target.classList.contains("clickable") ||
                  target.classList.contains("option") ||
                  target.classList.contains("choice")
                ) {
                  setTimeout(() => {
                    if (value) {
                      const questionId =
                        this.findQuestionId(target) ||
                        this.survey.questions[this.questionIndex]?.id ||
                        "universal-response";
                      this.responseData[questionId] = value;
                      this.debug(`🌐 Universal click captured: "${value}"`);

                      clearTimeout(this.saveTimeout);
                      this.saveResponse("universal-click");
                    }
                  }, 150);
                }
              });
            }

            setupPeriodicSave() {
              this.debug("⏰ Setting up periodic backup save");

              const periodicSaveInterval = setInterval(() => {
                if (Object.keys(this.responseData).length > 0) {
                  this.debug("⏰ Periodic backup save triggered");
                  this.saveResponse("periodic-backup");
                }
              }, 30000); // Save every 30 seconds if there's data

              this.cleanupIntervals.push(periodicSaveInterval);
            }

            findQuestionId(element) {
              let current = element;
              while (
                current &&
                current !== document.getElementById(this.embedId)
              ) {
                if (
                  current.getAttribute &&
                  current.getAttribute("data-question-id")
                ) {
                  return current.getAttribute("data-question-id");
                }
                current = current.parentElement;
              }
              return null;
            }

            async saveResponse(trigger = "background") {
              console.log(`🚀 [${this.containerId}] SAVE ATTEMPT: ${trigger}`);
              console.log(
                `📊 [${this.containerId}] ResponseData:`,
                this.responseData,
              );
              console.log(
                `🆔 [${this.containerId}] Shared Response ID:`,
                window.FormbricksSurveyManager.sharedResponseId,
              );

              if (Object.keys(this.responseData).length === 0) {
                this.debug("⚠️ No response data to save");
                return;
              }

              if (this.isSaving) {
                this.debug("⏳ Save already in progress, skipping");
                return;
              }

              this.isSaving = true;

              try {
                // Check if user is signed in
                const isSignedIn = await this.checkUserSignedIn();
                console.log("🔐 User signed in status:", isSignedIn);

                // Get referrer URL (fallback to "direct" if empty)
                const referrerUrl = document.referrer || "direct";

                // Log to help debug
                console.log("🔍 Hidden fields being added:", {
                  url: window.location.href,
                  signed_in: isSignedIn ? "1" : "0",
                  referrer: referrerUrl,
                });

                // Revert to the working approach: put hidden fields in data object like the URL was working
                const dataWithHiddenFields = {
                  ...this.responseData,
                  url: window.location.href,
                  signed_in: isSignedIn ? "1" : "0", // String like URL
                  referrer: referrerUrl, // Add referrer URL
                  language: window.FormbricksSurveyManager.currentLanguage || "en", // Add current language
                };

                console.log(
                  "📦 Data being sent to Formbricks:",
                  dataWithHiddenFields,
                );
                console.log("🌐 Current URL:", window.location.href);
                console.log(
                  "🔑 Signed in value being sent:",
                  dataWithHiddenFields.signed_in,
                );
                console.log("🔗 Referrer being sent:", referrerUrl);

                const requestData = {
                  data: dataWithHiddenFields,
                  finished: false,
                  meta: {
                    trigger: trigger,
                    timestamp: new Date().toISOString(),
                    containerId: this.containerId,
                    questionIndex: this.questionIndex,
                    pageUrl: window.location.href,
                  },
                };

                console.log(
                  "📤 Data with hidden fields:",
                  dataWithHiddenFields,
                );

                let response;
                const sharedResponseId =
                  window.FormbricksSurveyManager.sharedResponseId;

                if (sharedResponseId) {
                  // Update existing shared response
                  response = await fetch(
                    `${SURVEY_CONFIG.formbricksBaseUrl}/api/v1/client/${SURVEY_CONFIG.environmentId}/responses/${sharedResponseId}`,
                    {
                      method: "PUT",
                      headers: { "Content-Type": "application/json" },
                      body: JSON.stringify(requestData),
                    },
                  );
                } else {
                  // Create new shared response
                  response = await fetch(
                    `${SURVEY_CONFIG.formbricksBaseUrl}/api/v1/client/${SURVEY_CONFIG.environmentId}/responses`,
                    {
                      method: "POST",
                      headers: { "Content-Type": "application/json" },
                      body: JSON.stringify({
                        surveyId: this.survey.id,
                        ...requestData,
                      }),
                    },
                  );
                }

                if (response.ok) {
                  const result = await response.json();
                  console.log(`✅ [${this.containerId}] SAVE SUCCESSFUL`);
                  console.log(`📋 [${this.containerId}] API Response:`, result);

                  // Store shared response ID if this was the first save
                  if (!sharedResponseId) {
                    const responseId =
                      result.data?.id ||
                      result.id ||
                      result.responseId ||
                      result.data?.responseId;
                    if (responseId) {
                      window.FormbricksSurveyManager.sharedResponseId =
                        responseId;
                      console.log(
                        `🆔 [${this.containerId}] Created shared response ID: ${responseId}`,
                      );
                      this.debug(
                        `🆔 Created shared response ID: ${responseId}`,
                      );
                    } else {
                      console.warn(
                        `⚠️ [${this.containerId}] Could not extract response ID from:`,
                        result,
                      );
                    }
                  } else {
                    this.debug(
                      `🔄 Updated shared response: ${sharedResponseId}`,
                    );
                  }
                } else {
                  const errorText = await response.text();
                  console.error(
                    `❌ [${this.containerId}] SAVE FAILED: ${response.status}`,
                    errorText,
                  );
                }
              } catch (error) {
                console.error(
                  `💥 [${this.containerId}] SAVE EXCEPTION:`,
                  error,
                );
              } finally {
                this.isSaving = false;
              }
            }

            showSuccess(message) {
              const container = document.getElementById(this.containerId);
              if (container) {
                container.innerHTML = `
              <div style="background: #f0fdf4; border: 1px solid #bbf7d0; color: #059669; padding: 16px; border-radius: 8px; margin: 20px 0;">
                ${message}
              </div>
            `;
              }
            }

            showError(message) {
              const container = document.getElementById(this.containerId);
              if (container) {
                container.innerHTML = `
              <div style="background: #fef2f2; border: 1px solid #fecaca; color: #dc2626; padding: 16px; border-radius: 8px; margin: 20px 0;">
                <strong>Error:</strong> ${message}
              </div>
            `;
              }
            }

            async checkUserSignedIn() {
              try {
                // Check multiple methods to detect if user is signed in

                // Method 1: Check for member_status in URL (most reliable)
                // ANY member_status parameter means user is logged in (free, paid, complimentary, etc.)
                const urlParams = new URLSearchParams(window.location.search);
                const memberStatus = urlParams.get("member_status");
                if (memberStatus) {
                  this.debug(
                    `👤 User IS signed in (member_status: ${memberStatus})`,
                  );
                  return true;
                }

                // Method 2: Check Ghost members API
                if (
                  typeof window.ghost !== "undefined" &&
                  window.ghost.members
                ) {
                  try {
                    const member =
                      await window.ghost.members.getCurrentMember();
                    if (member) {
                      this.debug(
                        "👤 User is signed in (via Ghost members API)",
                      );
                      return true;
                    }
                  } catch (e) {
                    // Continue to next method
                  }
                }

                // Method 3: Check Ghost session API
                try {
                  const response = await fetch("/members/api/session/", {
                    method: "GET",
                    credentials: "include",
                  });

                  if (response.ok) {
                    const data = await response.json();
                    if (data && data.email) {
                      this.debug("👤 User is signed in (via session API)");
                      return true;
                    }
                  }
                } catch (e) {
                  // Continue to next method
                }

                this.debug("👤 User is NOT signed in");
                return false;
              } catch (error) {
                this.debug("⚠️ Error checking sign-in status:", error.message);
                return false;
              }
            }

            preventAutoFocus() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              // Temporarily disable focus on all focusable elements
              const focusableElements = embedContainer.querySelectorAll(
                "input, textarea, button, select, [tabindex]",
              );

              focusableElements.forEach((element) => {
                const originalTabIndex = element.tabIndex;
                element.tabIndex = -1;
                element.setAttribute(
                  "data-original-tabindex",
                  originalTabIndex,
                );

                // Restore after a delay
                setTimeout(() => {
                  const savedTabIndex = element.getAttribute(
                    "data-original-tabindex",
                  );
                  element.tabIndex =
                    savedTabIndex === "null" ? 0 : parseInt(savedTabIndex);
                  element.removeAttribute("data-original-tabindex");
                }, 1000);
              });
            }

            setupLanguageChangeDetection() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              this.debug("🌍 Setting up language change detection");

              // Map language names to codes
              const languageMap = {
                'english': 'en',
                'spanish': 'es',
                'spanish; castilian': 'es',
                'español': 'es',
                'french': 'fr',
                'français': 'fr',
                'german': 'de',
                'deutsch': 'de',
                'portuguese': 'pt',
                'português': 'pt',
                'italian': 'it',
                'italiano': 'it',
                'chinese': 'zh',
                '中文': 'zh',
                'japanese': 'ja',
                '日本語': 'ja'
              };

              // Listen for ALL button clicks
              embedContainer.addEventListener('click', (e) => {
                const target = e.target.closest('button');
                if (!target) return;

                const buttonClass = target.className || "";
                const buttonAria = target.getAttribute('aria-label') || "";
                const buttonText = target.textContent.trim();

                // Detect if this is a language-related click
                const isLanguageContext =
                  buttonAria.toLowerCase().includes('language') ||
                  buttonAria.toLowerCase().includes('lang') ||
                  buttonClass.toLowerCase().includes('language') ||
                  buttonClass.toLowerCase().includes('lang');

                // Or if the button text matches a language name
                const textLower = buttonText.toLowerCase();
                const matchesLanguage = languageMap.hasOwnProperty(textLower);

                if (isLanguageContext || matchesLanguage) {
                  console.log('🌍 LANGUAGE-RELATED CLICK:', buttonText || buttonAria);

                  setTimeout(() => {
                    // Map language name to code
                    const langCode = languageMap[textLower] ||
                                     target.getAttribute('data-language') ||
                                     target.getAttribute('lang') ||
                                     target.getAttribute('value');

                    if (langCode && langCode !== window.FormbricksSurveyManager.currentLanguage) {
                      console.log(`🌍 LANGUAGE CHANGE: ${window.FormbricksSurveyManager.currentLanguage} → ${langCode}`);
                      window.FormbricksSurveyManager.setLanguage(langCode);
                    }
                  }, 300);
                }
              });
            }

            detectCurrentLanguage() {
              // Try to detect the currently selected language from Formbricks UI
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return null;

              // Look for selected language indicators
              const selectedLangElement = embedContainer.querySelector(
                '[data-language][data-selected="true"], [class*="language"][class*="selected"], button[aria-pressed="true"][class*="language"]'
              );

              if (selectedLangElement) {
                const lang = selectedLangElement.getAttribute('data-language') ||
                            selectedLangElement.getAttribute('lang') ||
                            selectedLangElement.textContent.trim().toLowerCase();
                this.debug(`🔍 Detected language from UI: ${lang}`);
                return lang;
              }

              return null;
            }

            reRenderWithLanguage(newLanguage) {
              console.log(`🔄 [${this.containerId}] reRenderWithLanguage called with: ${newLanguage}`);
              this.debug(`🔄 Updating text content with language: ${newLanguage}`);

              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) {
                console.error(`❌ Embed container not found: ${this.embedId}`);
                return;
              }

              // Get the question data from original survey
              const question = this.originalSurvey.questions[this.questionIndex];

              // Update headline text - it's inside a <p class="fb-text-base fb-font-semibold">
              const headline = embedContainer.querySelector('p.fb-text-base.fb-font-semibold');

              if (headline && question.headline) {
                const translatedHeadline = this.translateText(question.headline, newLanguage);
                headline.textContent = translatedHeadline;
                console.log(`📝 [${this.containerId}] Updated headline to: ${translatedHeadline.substring(0, 50)}...`);
              } else {
                console.warn(`⚠️ [${this.containerId}] Could not find headline element`);
              }

              // Update subheader if exists
              const subheader = embedContainer.querySelector('[class*="subheader"], .fb-question-subheader');
              if (subheader && question.subheader) {
                const translatedSubheader = this.translateText(question.subheader, newLanguage);
                subheader.textContent = translatedSubheader;
                console.log(`📝 [${this.containerId}] Updated subheader`);
              }

              // Update choice labels - these are inside <span class="fb-flex fb-items-center fb-text-sm">
              if (question.choices && question.choices.length > 0) {
                const choiceSpans = embedContainer.querySelectorAll('span.fb-flex.fb-items-center.fb-text-sm');
                console.log(`🔍 [${this.containerId}] Found ${choiceSpans.length} choice spans for ${question.choices.length} choices`);

                question.choices.forEach((choice, index) => {
                  if (choiceSpans[index]) {
                    const translatedLabel = this.translateText(choice.label, newLanguage);
                    choiceSpans[index].textContent = translatedLabel;
                    console.log(`📝 [${this.containerId}] Updated choice ${index}: ${translatedLabel.substring(0, 30)}...`);
                  }
                });
              }

              console.log(`✅ [${this.containerId}] Language updated without re-render!`);
            }

            shouldRenderAsDropdown(question) {
              this.debug(
                "🔍 Checking if question should render as dropdown...",
              );
              this.debug(
                "Config useSingleSelectDropdown:",
                this.config.useSingleSelectDropdown,
              );
              this.debug("Question object:", question);

              if (!this.config.useSingleSelectDropdown) {
                this.debug("❌ Dropdown disabled in config");
                return false;
              }

              if (!question || !question.type) {
                this.debug("❌ No question or question type found");
                return false;
              }

              // Check for single-select question types that should be converted to dropdowns
              const singleSelectTypes = [
                "multiplechoicesingle", // Fixed: all lowercase to match normalized type
                "multiplechoicemulti", // Fixed: all lowercase to match normalized type
                "singleselect", // Fixed: all lowercase to match normalized type
                "radio",
                "choice",
                "select",
              ];

              const questionType = question.type.toLowerCase();
              const isSingleSelect = singleSelectTypes.includes(questionType);
              const hasChoices =
                question.choices && question.choices.length > 0;

              this.debug(`📋 Question analysis:`);
              this.debug(
                `  - Type: "${question.type}" (normalized: "${questionType}")`,
              );
              this.debug(`  - Is single select: ${isSingleSelect}`);
              this.debug(`  - Has choices: ${hasChoices}`);
              this.debug(
                `  - Choices count: ${question.choices ? question.choices.length : 0}`,
              );
              if (question.choices) {
                this.debug(`  - Choices:`, question.choices);
              }

              const shouldRender = isSingleSelect && hasChoices;
              this.debug(
                `🎯 Final decision: ${shouldRender ? "RENDER AS DROPDOWN" : "RENDER WITH FORMBRICKS"}`,
              );

              return shouldRender;
            }

            async renderCustomDropdown(question) {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) {
                throw new Error("Embed container not found");
              }

              // Helper function to extract text from object or return string
              const extractText = (textObj) => {
                if (typeof textObj === "string") return textObj;
                if (typeof textObj === "object" && textObj !== null) {
                  const lang = SURVEY_CONFIG.defaultLanguage || "en";

                  // Try in order: configured language -> default -> en -> english -> first available
                  return (
                    textObj[lang] ||
                    textObj.default ||
                    textObj.en ||
                    textObj.english ||
                    Object.values(textObj)[0] ||
                    "[No text available]"
                  );
                }
                return textObj || "";
              };

              const questionText = extractText(
                question.headline || question.text,
              );
              const questionSubtext = question.subheader
                ? extractText(question.subheader)
                : "";

              // Check for pre-existing value from user profile
              const profileValue =
                window.FormbricksSurveyManager.getProfileValue(question.id);

              this.debug("🎨 Rendering dropdown with extracted text:", {
                questionText,
                questionSubtext,
                choicesCount: question.choices.length,
                profileValue,
              });

              // Create Formbricks-style HTML structure
              const html = `
            <div class="fb-survey fb-survey-inline" style="--fb-brand-color: #00C4B8;">
              <div class="fb-survey-content">
                <div class="fb-question-container">
                  <div class="fb-question-text">
                    <h3 class="fb-question-headline">${questionText || "Please select an option"}</h3>
                    ${questionSubtext ? `<p class="fb-question-subheader">${questionSubtext}</p>` : ""}
                  </div>
                  <div class="fb-question-form">
                    <div class="fb-form-field">
                      <select 
                        id="custom-dropdown-${question.id}" 
                        class="fb-select fb-form-control" 
                        data-question-id="${question.id}"
                        ${question.required !== false ? "required" : ""}
                      >
                        <option value="" disabled ${profileValue ? "" : "selected"}>
                          ${this.config.dropdownPlaceholder}
                        </option>
                        ${question.choices
                          .map((choice) => {
                            const choiceValue =
                              choice.id ||
                              choice.value ||
                              extractText(choice.label);
                            const choiceLabel = extractText(
                              choice.label || choice.value || choice,
                            );
                            const isSelected =
                              profileValue && profileValue === choiceValue;
                            this.debug("Choice mapping:", {
                              choiceValue,
                              choiceLabel,
                              isSelected,
                              originalChoice: choice,
                            });
                            return `<option value="${choiceValue}" ${isSelected ? "selected" : ""}>${choiceLabel}</option>`;
                          })
                          .join("")}
                      </select>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          `;

              embedContainer.innerHTML = html;

              // Pre-populate response data if profile value exists
              if (profileValue) {
                this.responseData[question.id] = profileValue;
                this.debug("👤 Pre-populated response from profile:", {
                  questionId: question.id,
                  value: profileValue,
                });
              }

              // Set up event handling
              this.setupCustomDropdownEvents(question);

              // Call the same setup as regular questions
              setTimeout(() => this.setupUICleanup(), 100);

              this.debug("Custom dropdown rendered successfully");
            }

            setupCustomDropdownEvents(question) {
              const dropdown = document.getElementById(
                `custom-dropdown-${question.id}`,
              );
              if (!dropdown) return;

              dropdown.addEventListener("change", (event) => {
                const selectedValue = event.target.value;
                this.debug(`Dropdown selection: ${selectedValue}`);

                // Store response data
                this.responseData[question.id] = selectedValue;

                // Save to user profile if enabled
                if (window.FormbricksSurveyManager) {
                  window.FormbricksSurveyManager.saveUserProfile(
                    question.id,
                    selectedValue,
                    question,
                  );
                }

                // Trigger auto-save if enabled
                if (this.config.autoSave) {
                  clearTimeout(this.saveTimeout);
                  this.saveTimeout = setTimeout(() => {
                    this.saveResponse("dropdown-change");
                  }, this.config.autoSaveDelay);
                }

                // Find the choice object for the selected value
                const selectedChoice = question.choices.find(
                  (choice) =>
                    (choice.id || choice.value || choice.label) ===
                    selectedValue,
                );

                this.debug("Response data updated:", this.responseData);
              });
            }
          }

          // Sequential Survey Instance Class
          class FormbricksSequentialSurveyInstance {
            constructor(containerId, startQuestionIndex, survey, config = {}) {
              this.containerId = containerId;
              this.embedId = `${containerId}-embed`;
              this.currentQuestionIndex = startQuestionIndex;
              this.survey = survey;
              this.originalSurvey = JSON.parse(JSON.stringify(survey)); // Keep original for re-translation
              this.config = {
                hideNextButton: false,
                autoSave: true,
                autoSaveDelay: 1000,
                enableNavigation: true,
                completionUrl: "https://informup.org/survey-complete/",
                ...config,
              };

              this.responseData = {};
              this.saveTimeout = null;
              this.cleanupIntervals = [];
              this.isSaving = false;
              this.closeObserverSetup = false; // Track if close button observer is set up
              this.languageCache = new Map(); // Cache rendered HTML by language and question index
            }

            debug(message, data = null, level = "info") {
              if (!SURVEY_CONFIG.debug) return;
              console.log(
                `[${this.containerId}][${level.toUpperCase()}]`,
                message,
                data,
              );
            }

            async render() {
              this.debug(
                `Rendering question ${this.currentQuestionIndex} of ${this.survey.questions.length}`,
              );
              await this.renderCurrentQuestion();
            }

            async renderCurrentQuestion() {
              if (this.currentQuestionIndex >= this.survey.questions.length) {
                this.showComplete();
                return;
              }

              const singleQuestionSurvey = this.prepareSingleQuestion(
                this.currentQuestionIndex,
              );
              const question = singleQuestionSurvey.questions[0];

              const container = document.getElementById(this.containerId);
              container.innerHTML = `<div id="${this.embedId}" class="survey-embed"></div>`;

              // Branch rendering based on question type and configuration
              if (this.shouldRenderAsDropdown(question)) {
                this.debug("Rendering sequential question as custom dropdown");
                await this.renderCustomDropdown(question);
              } else {
                this.debug(
                  "Rendering sequential question with native Formbricks JS",
                );
                await this.renderSequentialWithFormbricks(singleQuestionSurvey);
              }
            }

            async renderSequentialWithFormbricks(singleQuestionSurvey) {
              const surveyProps = {
                survey: singleQuestionSurvey,
                containerId: this.embedId,
                mode: "inline",
                languageCode: "default", // Always use default - we translate the survey ourselves
                styling: this.survey.styling || {},
                onDisplay: () => {
                  this.debug("🎯 Sequential question displayed");

                  // Cache the rendered HTML for current language + question
                  setTimeout(() => {
                    const embedContainer = document.getElementById(this.embedId);
                    const currentLang = window.FormbricksSurveyManager.currentLanguage;
                    const cacheKey = `${currentLang}-q${this.currentQuestionIndex}`;

                    if (embedContainer && !this.languageCache.has(cacheKey)) {
                      this.languageCache.set(cacheKey, {
                        html: embedContainer.innerHTML,
                        questionIndex: this.currentQuestionIndex,
                        timestamp: Date.now()
                      });
                      console.log(`💾 [${this.containerId}] Cached HTML for: ${cacheKey}`);
                    }

                    // Make container visible now that content is rendered
                    const container = document.getElementById(this.containerId);
                    if (container) {
                      container.classList.add("survey-loaded");
                      this.debug(
                        "✅ Made sequential survey visible after render",
                      );
                    }
                  }, 50);

                  // Set up language change detection
                  this.setupLanguageChangeDetection();

                  this.setupAutoSave();
                  this.setupNavigationHandler();
                },
                onResponse: (response) => {
                  this.debug("📝 Sequential response received", response);
                  if (response.data) {
                    this.responseData = {
                      ...this.responseData,
                      ...response.data,
                    };
                    this.debug(
                      "💾 Merged sequential responseData:",
                      this.responseData,
                    );
                    if (this.config.autoSave) {
                      clearTimeout(this.saveTimeout);
                      this.saveResponse("native-response");
                    }
                  }
                },
                onFinished: () => {
                  this.debug(
                    "🎉 Question finished - preventing default completion",
                  );
                  // Don't automatically move to next question here
                  // The navigation handler will handle this to avoid conflicts
                },
                onClose: () => this.debug("Question closed"),
                onError: (error) => {
                  this.debug("Question error", error, "error");
                  this.showError(
                    "An error occurred while displaying the question",
                  );
                },
              };

              try {
                window.formbricksSurveys.renderSurveyInline(surveyProps);
                this.debug("Successfully rendered sequential question");

                // Make visible immediately in case onDisplay doesn't fire due to Formbricks errors
                setTimeout(() => {
                  const container = document.getElementById(this.containerId);
                  if (container && !container.classList.contains('survey-loaded')) {
                    container.classList.add("survey-loaded");
                    this.debug("✅ Force-made sequential survey visible (fallback)");
                  }
                  this.setupUICleanup();
                }, 500);
              } catch (error) {
                // Make visible even on error
                const container = document.getElementById(this.containerId);
                if (container) {
                  container.classList.add("survey-loaded");
                }

                this.debug(
                  "Error rendering sequential question",
                  error.message,
                  "error",
                );
                throw new Error("Failed to render sequential question");
              }
            }

            translateText(textObj, language) {
              if (typeof textObj === "string") return textObj;
              if (typeof textObj === "object" && textObj !== null) {
                // Try in order: language -> default -> en -> first available
                return (
                  textObj[language] ||
                  textObj.default ||
                  textObj.en ||
                  Object.values(textObj)[0] ||
                  ""
                );
              }
              return textObj || "";
            }

            translateSurvey(survey, language) {
              // Create a deep copy and translate all text fields
              const translated = JSON.parse(JSON.stringify(survey));

              // Translate questions - keep as objects with .default property for Formbricks
              if (translated.questions) {
                translated.questions = translated.questions.map(q => {
                  const newQuestion = { ...q };

                  // Translate headline - keep as object but update .default
                  if (q.headline) {
                    newQuestion.headline = {
                      default: this.translateText(q.headline, language)
                    };
                  }

                  // Translate subheader
                  if (q.subheader) {
                    newQuestion.subheader = {
                      default: this.translateText(q.subheader, language)
                    };
                  }

                  // Translate choice labels
                  if (q.choices) {
                    newQuestion.choices = q.choices.map(choice => ({
                      ...choice,
                      label: {
                        default: this.translateText(choice.label, language)
                      }
                    }));
                  }

                  return newQuestion;
                });
              }

              return translated;
            }

            prepareSingleQuestion(questionIndex) {
              if (
                !this.originalSurvey.questions ||
                this.originalSurvey.questions.length <= questionIndex
              ) {
                throw new Error(
                  `Question index ${questionIndex} not found in survey`,
                );
              }

              const question = this.originalSurvey.questions[questionIndex];
              this.debug(
                "Creating sequential single question survey for question type:",
                question.type,
              );

              const singleQuestionSurvey = {
                ...this.originalSurvey,
                questions: [question],
                welcomeCard: { enabled: false },
                thankyouCard: { enabled: false },
              };

              // Translate survey to current language from original data
              const language = window.FormbricksSurveyManager.currentLanguage || "en";
              this.debug(`🌍 [SEQUENTIAL] Translating from original survey to language: ${language}`);
              return this.translateSurvey(singleQuestionSurvey, language);
            }

            setupNavigationHandler() {
              if (!this.config.enableNavigation) return;

              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              // Listen for next button clicks with event capture to intercept before Formbricks
              embedContainer.addEventListener(
                "click",
                (e) => {
                  const target = e.target;
                  const buttonText = target.textContent.toLowerCase().trim();

                  if (
                    (buttonText.includes("next") ||
                      buttonText.includes("submit") ||
                      buttonText.includes("continue")) &&
                    (target.tagName === "BUTTON" || target.type === "submit")
                  ) {
                    this.debug(`🔄 Navigation button clicked: "${buttonText}"`);

                    // Prevent default Formbricks navigation behavior
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation();

                    // Extract any response data from the current question before moving
                    this.extractCurrentQuestionData();

                    // Save current response before moving to next
                    if (Object.keys(this.responseData).length > 0) {
                      this.saveResponse("navigation-save").then(() => {
                        setTimeout(() => this.nextQuestion(), 200);
                      });
                    } else {
                      setTimeout(() => this.nextQuestion(), 200);
                    }

                    return false;
                  }
                },
                true,
              ); // Use capture phase to intercept before Formbricks handlers
            }

            extractCurrentQuestionData() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const questionId =
                this.survey.questions[this.currentQuestionIndex]?.id ||
                `question-${this.currentQuestionIndex}`;

              // Extract text input values
              const textInputs = embedContainer.querySelectorAll(
                'textarea, input[type="text"], input:not([type])',
              );
              textInputs.forEach((input) => {
                if (input.value.trim()) {
                  this.responseData[questionId] = input.value.trim();
                  this.debug(
                    `📤 Extracted text value: "${input.value.trim()}"`,
                  );
                }
              });

              // Extract radio button values
              const checkedRadio = embedContainer.querySelector(
                'input[type="radio"]:checked',
              );
              if (checkedRadio) {
                this.responseData[questionId] = checkedRadio.value;
                this.debug(`📤 Extracted radio value: "${checkedRadio.value}"`);
              }

              // Extract checkbox values
              const checkedCheckboxes = embedContainer.querySelectorAll(
                'input[type="checkbox"]:checked',
              );
              if (checkedCheckboxes.length > 0) {
                this.responseData[questionId] = Array.from(
                  checkedCheckboxes,
                ).map((cb) => cb.value);
                this.debug(
                  `📤 Extracted checkbox values: ${this.responseData[questionId]}`,
                );
              }

              // Extract select values
              const selects = embedContainer.querySelectorAll("select");
              selects.forEach((select) => {
                if (select.value) {
                  this.responseData[questionId] = select.value;
                  this.debug(`📤 Extracted select value: "${select.value}"`);
                }
              });

              // Extract selected choice buttons
              const selectedChoices = embedContainer.querySelectorAll(
                '[data-selected="true"], .selected, [aria-checked="true"]',
              );
              selectedChoices.forEach((choice) => {
                const value =
                  choice.getAttribute("data-value") ||
                  choice.textContent.trim();
                if (
                  value &&
                  !value.toLowerCase().includes("next") &&
                  !value.toLowerCase().includes("submit")
                ) {
                  this.responseData[questionId] = value;
                  this.debug(`📤 Extracted choice value: "${value}"`);
                }
              });
            }

            nextQuestion() {
              this.currentQuestionIndex++;
              this.debug(`Moving to question ${this.currentQuestionIndex}`);

              // Clear current question's cleanup
              this.cleanupCurrentQuestion();

              // Render next question
              this.renderCurrentQuestion();
            }

            cleanupCurrentQuestion() {
              this.cleanupIntervals.forEach((item) => {
                if (item.type === "observer") {
                  item.observer.disconnect();
                } else {
                  clearInterval(item);
                }
              });
              this.cleanupIntervals = [];
              clearTimeout(this.saveTimeout);
            }

            showComplete() {
              this.debug(
                `🎉 Survey complete! Redirecting to: ${this.config.completionUrl}`,
              );

              // Show temporary completion message while saving and redirecting
              const container = document.getElementById(this.containerId);
              if (container) {
                container.innerHTML = `
              <div style="background: #f0fdf4; border: 1px solid #bbf7d0; color: #059669; padding: 24px; border-radius: 8px; margin: 20px 0; text-align: center;">
                <h3 style="margin: 0 0 10px 0;">Survey Complete!</h3>
                <p style="margin: 0;">Thank you for completing all questions. Redirecting...</p>
              </div>
            `;
              }

              // Final save and then redirect
              if (Object.keys(this.responseData).length > 0) {
                this.saveResponse("survey-complete")
                  .then(() => {
                    // Short delay to ensure save completes, then redirect
                    setTimeout(() => {
                      window.location.href = this.config.completionUrl;
                    }, 500);
                  })
                  .catch(() => {
                    // Even if save fails, still redirect
                    setTimeout(() => {
                      window.location.href = this.config.completionUrl;
                    }, 500);
                  });
              } else {
                // No data to save, redirect immediately
                setTimeout(() => {
                  window.location.href = this.config.completionUrl;
                }, 1000);
              }
            }

            setupUICleanup() {
              // Prevent auto-focus
              this.preventAutoFocus();

              // Immediate cleanup
              if (this.config.hideNextButton) {
                this.hideNextButtons();
              }
              this.hideOptionalRequiredText();

              // More frequent cleanup for sequential questions (every 1 second for first 10 seconds)
              const frequentCleanupInterval = setInterval(() => {
                if (this.config.hideNextButton) {
                  this.hideNextButtons();
                }
                this.hideOptionalRequiredText();
              }, 1000);

              this.cleanupIntervals.push(frequentCleanupInterval);

              // Stop frequent cleanup after 10 seconds and switch to normal interval
              setTimeout(() => {
                clearInterval(frequentCleanupInterval);

                // Continue with less frequent cleanup
                const normalCleanupInterval = setInterval(() => {
                  if (this.config.hideNextButton) {
                    this.hideNextButtons();
                  }
                  this.hideOptionalRequiredText();
                }, 3000);

                this.cleanupIntervals.push(normalCleanupInterval);

                // Stop normal cleanup after 60 seconds total
                setTimeout(() => clearInterval(normalCleanupInterval), 50000);
              }, 10000);
            }

            hideOptionalRequiredText() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const walker = document.createTreeWalker(
                embedContainer,
                NodeFilter.SHOW_TEXT,
                null,
                false,
              );

              const textNodes = [];
              let node;
              while ((node = walker.nextNode())) {
                const text = node.textContent.toLowerCase().trim();
                if (
                  text.includes("optional") ||
                  text.includes("required") ||
                  text === "*"
                ) {
                  textNodes.push(node);
                }
              }

              textNodes.forEach((textNode) => {
                const parent = textNode.parentElement;
                if (parent && parent.textContent.trim().length < 20) {
                  parent.style.display = "none";
                  this.debug(
                    "🧹 Hidden optional/required text:",
                    textNode.textContent.trim(),
                  );
                }
              });
            }

            hideNextButtons() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              setTimeout(() => {
                const allButtons = embedContainer.querySelectorAll("button");
                allButtons.forEach((button) => {
                  const buttonText = button.textContent.toLowerCase().trim();
                  if (
                    buttonText.includes("next") ||
                    buttonText.includes("submit") ||
                    buttonText.includes("continue") ||
                    (buttonText === "" && button.type === "submit")
                  ) {
                    button.style.display = "none";
                    button.style.visibility = "hidden";
                    this.debug(
                      `✓ Hidden button: "${button.textContent.trim()}"`,
                    );
                  }
                });
              }, 1000);
            }

            setupAutoSave() {
              if (!this.config.autoSave) return;

              this.debug("🔧 Setting up sequential auto-save handlers");

              setTimeout(() => {
                this.setupTextAutoSave();
                this.setupChoiceAutoSave();
                this.setupNPSAutoSave();
                this.setupRadioCheckboxAutoSave();
                this.setupSelectAutoSave();
              }, 500);
            }

            setupTextAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const textInputs = embedContainer.querySelectorAll(
                'textarea, input[type="text"], input:not([type])',
              );
              this.debug(
                `📝 Setting up sequential text auto-save for ${textInputs.length} inputs`,
              );

              textInputs.forEach((input) => {
                input.addEventListener("input", () => {
                  clearTimeout(this.saveTimeout);
                  if (input.value.trim()) {
                    const questionId =
                      this.survey.questions[this.currentQuestionIndex]?.id ||
                      `question-${this.currentQuestionIndex}`;
                    this.responseData[questionId] = input.value;
                    this.debug(
                      `💾 Sequential auto-saving text: "${input.value}"`,
                    );

                    this.saveTimeout = setTimeout(() => {
                      this.saveResponse("auto-text");
                    }, this.config.autoSaveDelay);
                  }
                });

                input.addEventListener("blur", () => {
                  if (input.value.trim()) {
                    const questionId =
                      this.survey.questions[this.currentQuestionIndex]?.id ||
                      `question-${this.currentQuestionIndex}`;
                    this.responseData[questionId] = input.value;
                    this.debug(
                      `💾 Sequential immediate save on blur: "${input.value}"`,
                    );
                    clearTimeout(this.saveTimeout);
                    this.saveResponse("blur-text");
                  }
                });
              });
            }

            setupChoiceAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const setupClickHandlers = () => {
                const choices = embedContainer.querySelectorAll(
                  'button, div[role="button"], [data-value], .choice-option, [class*="choice"], [class*="option"]',
                );
                this.debug(
                  `🎯 Setting up sequential click handlers for ${choices.length} choice elements`,
                );

                choices.forEach((choice) => {
                  if (!choice.hasAttribute("data-sequential-save-attached")) {
                    choice.setAttribute(
                      "data-sequential-save-attached",
                      "true",
                    );

                    choice.addEventListener("click", () => {
                      const buttonText = choice.textContent
                        .toLowerCase()
                        .trim();

                      // Skip navigation buttons - they're handled separately
                      if (
                        buttonText.includes("next") ||
                        buttonText.includes("submit") ||
                        buttonText.includes("continue")
                      ) {
                        return;
                      }

                      setTimeout(() => {
                        const choiceValue =
                          choice.getAttribute("data-value") ||
                          choice.getAttribute("value") ||
                          choice.textContent.trim();

                        if (choiceValue) {
                          const questionId =
                            this.survey.questions[this.currentQuestionIndex]
                              ?.id || `question-${this.currentQuestionIndex}`;
                          this.responseData[questionId] = choiceValue;
                          this.debug(
                            `🎯 Sequential choice clicked: "${choiceValue}"`,
                          );

                          clearTimeout(this.saveTimeout);
                          this.saveResponse("click-choice");
                        }
                      }, 100);
                    });
                  }
                });
              };

              setTimeout(setupClickHandlers, 500);

              const observer = new MutationObserver(() => {
                setTimeout(setupClickHandlers, 100);
              });

              observer.observe(embedContainer, {
                childList: true,
                subtree: true,
              });
              this.cleanupIntervals.push({ type: "observer", observer });
            }

            setupNPSAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const setupNPSClickHandlers = () => {
                const npsButtons = embedContainer.querySelectorAll(
                  'button[class*="nps"], [role="button"][class*="nps"], button[data-value], .nps-option, [class*="rating"] button',
                );
                this.debug(
                  `📊 Setting up sequential NPS click handlers for ${npsButtons.length} buttons`,
                );

                npsButtons.forEach((button) => {
                  if (!button.hasAttribute("data-sequential-nps-attached")) {
                    button.setAttribute("data-sequential-nps-attached", "true");

                    button.addEventListener("click", () => {
                      setTimeout(() => {
                        const npsValue = parseInt(
                          button.getAttribute("data-value") ||
                            button.textContent.trim(),
                        );
                        if (
                          !isNaN(npsValue) &&
                          npsValue >= 0 &&
                          npsValue <= 10
                        ) {
                          const questionId =
                            this.survey.questions[this.currentQuestionIndex]
                              ?.id || `question-${this.currentQuestionIndex}`;
                          this.responseData[questionId] = npsValue;
                          this.debug(`📊 Sequential NPS clicked: ${npsValue}`);

                          clearTimeout(this.saveTimeout);
                          this.saveResponse("click-nps");
                        }
                      }, 100);
                    });
                  }
                });
              };

              setTimeout(setupNPSClickHandlers, 500);

              const observer = new MutationObserver(() => {
                setTimeout(setupNPSClickHandlers, 100);
              });

              observer.observe(embedContainer, {
                childList: true,
                subtree: true,
              });
              this.cleanupIntervals.push({ type: "observer", observer });
            }

            setupRadioCheckboxAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const radioCheckboxes = embedContainer.querySelectorAll(
                'input[type="radio"], input[type="checkbox"]',
              );
              this.debug(
                `📋 Setting up sequential radio/checkbox auto-save for ${radioCheckboxes.length} inputs`,
              );

              radioCheckboxes.forEach((input) => {
                input.addEventListener("change", () => {
                  const questionId =
                    this.survey.questions[this.currentQuestionIndex]?.id ||
                    `question-${this.currentQuestionIndex}`;

                  if (input.type === "radio") {
                    this.responseData[questionId] = input.value;
                    this.debug(
                      `📋 Sequential radio selected: "${input.value}"`,
                    );
                  } else if (input.type === "checkbox") {
                    if (!this.responseData[questionId])
                      this.responseData[questionId] = [];

                    if (input.checked) {
                      if (
                        !this.responseData[questionId].includes(input.value)
                      ) {
                        this.responseData[questionId].push(input.value);
                      }
                    } else {
                      this.responseData[questionId] = this.responseData[
                        questionId
                      ].filter((v) => v !== input.value);
                    }
                    this.debug(
                      `📋 Sequential checkbox updated: "${input.value}" = ${input.checked}`,
                    );
                  }

                  clearTimeout(this.saveTimeout);
                  this.saveResponse("change-radio-checkbox");
                });
              });
            }

            setupSelectAutoSave() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              const selects = embedContainer.querySelectorAll("select");
              this.debug(
                `📋 Setting up sequential select auto-save for ${selects.length} dropdowns`,
              );

              selects.forEach((select) => {
                select.addEventListener("change", () => {
                  const questionId =
                    this.survey.questions[this.currentQuestionIndex]?.id ||
                    `question-${this.currentQuestionIndex}`;
                  this.responseData[questionId] = select.value;
                  this.debug(`📋 Sequential select changed: "${select.value}"`);

                  clearTimeout(this.saveTimeout);
                  this.saveResponse("change-select");
                });
              });
            }

            async saveResponse(trigger = "background") {
              console.log(
                `🚀 [${this.containerId}] SEQUENTIAL SAVE ATTEMPT: ${trigger}`,
              );
              console.log(
                `📊 [${this.containerId}] Sequential ResponseData:`,
                this.responseData,
              );
              console.log(
                `🆔 [${this.containerId}] Shared Response ID:`,
                window.FormbricksSurveyManager.sharedResponseId,
              );

              if (Object.keys(this.responseData).length === 0) {
                this.debug("⚠️ No sequential response data to save");
                return;
              }

              if (this.isSaving) {
                this.debug("⏳ Sequential save already in progress, skipping");
                return;
              }

              this.isSaving = true;

              try {
                // Check if user is signed in
                const isSignedIn = await this.checkUserSignedIn();
                console.log("🔐 User signed in status:", isSignedIn);

                // Get referrer URL (fallback to "direct" if empty)
                const referrerUrl = document.referrer || "direct";

                // Log to help debug
                console.log("🔍 Hidden fields being added:", {
                  url: window.location.href,
                  signed_in: isSignedIn ? "1" : "0",
                  referrer: referrerUrl,
                });

                // Create data with hidden fields (same approach as working URL)
                const dataWithHiddenFields = {
                  ...this.responseData,
                  url: window.location.href,
                  signed_in: isSignedIn ? "1" : "0", // String like URL
                  referrer: referrerUrl, // Add referrer URL
                  language: window.FormbricksSurveyManager.currentLanguage || "en", // Add current language
                };

                console.log(
                  "📦 Data being sent to Formbricks:",
                  dataWithHiddenFields,
                );
                console.log("🌐 Current URL:", window.location.href);
                console.log(
                  "🔑 Signed in value being sent:",
                  dataWithHiddenFields.signed_in,
                );
                console.log("🔗 Referrer being sent:", referrerUrl);

                const requestData = {
                  data: dataWithHiddenFields,
                  finished: false,
                  meta: {
                    trigger: trigger,
                    timestamp: new Date().toISOString(),
                    containerId: this.containerId,
                    currentQuestion: this.currentQuestionIndex,
                    isSequential: true,
                    pageUrl: window.location.href,
                  },
                };

                let response;
                const sharedResponseId =
                  window.FormbricksSurveyManager.sharedResponseId;

                if (sharedResponseId) {
                  // Update existing shared response
                  response = await fetch(
                    `${SURVEY_CONFIG.formbricksBaseUrl}/api/v1/client/${SURVEY_CONFIG.environmentId}/responses/${sharedResponseId}`,
                    {
                      method: "PUT",
                      headers: { "Content-Type": "application/json" },
                      body: JSON.stringify(requestData),
                    },
                  );
                } else {
                  // Create new shared response
                  response = await fetch(
                    `${SURVEY_CONFIG.formbricksBaseUrl}/api/v1/client/${SURVEY_CONFIG.environmentId}/responses`,
                    {
                      method: "POST",
                      headers: { "Content-Type": "application/json" },
                      body: JSON.stringify({
                        surveyId: this.survey.id,
                        ...requestData,
                      }),
                    },
                  );
                }

                if (response.ok) {
                  const result = await response.json();
                  console.log(
                    `✅ [${this.containerId}] SEQUENTIAL SAVE SUCCESSFUL`,
                  );
                  console.log(
                    `📋 [${this.containerId}] Sequential API Response:`,
                    result,
                  );

                  // Store shared response ID if this was the first save
                  if (!sharedResponseId) {
                    const responseId =
                      result.data?.id ||
                      result.id ||
                      result.responseId ||
                      result.data?.responseId;
                    if (responseId) {
                      window.FormbricksSurveyManager.sharedResponseId =
                        responseId;
                      console.log(
                        `🆔 [${this.containerId}] Created shared response ID: ${responseId}`,
                      );
                      this.debug(
                        `🆔 Created shared response ID: ${responseId}`,
                      );
                    } else {
                      console.warn(
                        `⚠️ [${this.containerId}] Could not extract response ID from:`,
                        result,
                      );
                    }
                  } else {
                    this.debug(
                      `🔄 Updated shared response: ${sharedResponseId}`,
                    );
                  }
                } else {
                  const errorText = await response.text();
                  console.error(
                    `❌ [${this.containerId}] SEQUENTIAL SAVE FAILED: ${response.status}`,
                    errorText,
                  );
                }
              } catch (error) {
                console.error(
                  `💥 [${this.containerId}] SEQUENTIAL SAVE EXCEPTION:`,
                  error,
                );
              } finally {
                this.isSaving = false;
              }
            }

            showError(message) {
              const container = document.getElementById(this.containerId);
              if (container) {
                container.innerHTML = `
              <div style="background: #fef2f2; border: 1px solid #fecaca; color: #dc2626; padding: 16px; border-radius: 8px; margin: 20px 0;">
                <strong>Error:</strong> ${message}
              </div>
            `;
              }
            }

            async checkUserSignedIn() {
              try {
                // Check multiple methods to detect if user is signed in

                // Method 1: Check for member_status in URL (most reliable)
                // ANY member_status parameter means user is logged in (free, paid, complimentary, etc.)
                const urlParams = new URLSearchParams(window.location.search);
                const memberStatus = urlParams.get("member_status");
                if (memberStatus) {
                  this.debug(
                    `👤 User IS signed in (member_status: ${memberStatus})`,
                  );
                  return true;
                }

                // Method 2: Check Ghost members API
                if (
                  typeof window.ghost !== "undefined" &&
                  window.ghost.members
                ) {
                  try {
                    const member =
                      await window.ghost.members.getCurrentMember();
                    if (member) {
                      this.debug(
                        "👤 User is signed in (via Ghost members API)",
                      );
                      return true;
                    }
                  } catch (e) {
                    // Continue to next method
                  }
                }

                // Method 3: Check Ghost session API
                try {
                  const response = await fetch("/members/api/session/", {
                    method: "GET",
                    credentials: "include",
                  });

                  if (response.ok) {
                    const data = await response.json();
                    if (data && data.email) {
                      this.debug("👤 User is signed in (via session API)");
                      return true;
                    }
                  }
                } catch (e) {
                  // Continue to next method
                }

                this.debug("👤 User is NOT signed in");
                return false;
              } catch (error) {
                this.debug("⚠️ Error checking sign-in status:", error.message);
                return false;
              }
            }

            preventAutoFocus() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              // Temporarily disable focus on all focusable elements
              const focusableElements = embedContainer.querySelectorAll(
                "input, textarea, button, select, [tabindex]",
              );

              focusableElements.forEach((element) => {
                const originalTabIndex = element.tabIndex;
                element.tabIndex = -1;
                element.setAttribute(
                  "data-original-tabindex",
                  originalTabIndex,
                );

                // Restore tabindex after a delay
                setTimeout(() => {
                  const savedTabIndex = element.getAttribute(
                    "data-original-tabindex",
                  );
                  element.tabIndex =
                    savedTabIndex === "null" ? 0 : parseInt(savedTabIndex);
                  element.removeAttribute("data-original-tabindex");
                }, 1000);
              });
            }

            setupLanguageChangeDetection() {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return;

              this.debug("🌍 [SEQUENTIAL] Setting up language change detection");

              // Map language names to codes
              const languageMap = {
                'english': 'en',
                'spanish': 'es',
                'spanish; castilian': 'es',
                'español': 'es',
                'french': 'fr',
                'français': 'fr',
                'german': 'de',
                'deutsch': 'de',
                'portuguese': 'pt',
                'português': 'pt',
                'italian': 'it',
                'italiano': 'it',
                'chinese': 'zh',
                '中文': 'zh',
                'japanese': 'ja',
                '日本語': 'ja'
              };

              // Listen for ALL button clicks
              embedContainer.addEventListener('click', (e) => {
                const target = e.target.closest('button');
                if (!target) return;

                const buttonClass = target.className || "";
                const buttonAria = target.getAttribute('aria-label') || "";
                const buttonText = target.textContent.trim();

                // Detect if this is a language-related click
                const isLanguageContext =
                  buttonAria.toLowerCase().includes('language') ||
                  buttonAria.toLowerCase().includes('lang') ||
                  buttonClass.toLowerCase().includes('language') ||
                  buttonClass.toLowerCase().includes('lang');

                // Or if the button text matches a language name
                const textLower = buttonText.toLowerCase();
                const matchesLanguage = languageMap.hasOwnProperty(textLower);

                if (isLanguageContext || matchesLanguage) {
                  console.log('🌍 [SEQUENTIAL] LANGUAGE-RELATED CLICK:', buttonText || buttonAria);

                  setTimeout(() => {
                    // Map language name to code
                    const langCode = languageMap[textLower] ||
                                     target.getAttribute('data-language') ||
                                     target.getAttribute('lang') ||
                                     target.getAttribute('value');

                    if (langCode && langCode !== window.FormbricksSurveyManager.currentLanguage) {
                      console.log(`🌍 [SEQUENTIAL] LANGUAGE CHANGE: ${window.FormbricksSurveyManager.currentLanguage} → ${langCode}`);
                      window.FormbricksSurveyManager.setLanguage(langCode);
                    }
                  }, 300);
                }
              });
            }

            detectCurrentLanguage() {
              // Try to detect the currently selected language from Formbricks UI
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) return null;

              // Look for selected language indicators
              const selectedLangElement = embedContainer.querySelector(
                '[data-language][data-selected="true"], [class*="language"][class*="selected"], button[aria-pressed="true"][class*="language"]'
              );

              if (selectedLangElement) {
                const lang = selectedLangElement.getAttribute('data-language') ||
                            selectedLangElement.getAttribute('lang') ||
                            selectedLangElement.textContent.trim().toLowerCase();
                this.debug(`🔍 [SEQUENTIAL] Detected language from UI: ${lang}`);
                return lang;
              }

              return null;
            }

            reRenderWithLanguage(newLanguage) {
              console.log(`🔄 [${this.containerId}] SEQUENTIAL reRenderWithLanguage called with: ${newLanguage}`);
              this.debug(`🔄 [SEQUENTIAL] Updating text content with language: ${newLanguage}`);

              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) {
                console.error(`❌ Embed container not found: ${this.embedId}`);
                return;
              }

              // Get the current question data from original survey
              const question = this.originalSurvey.questions[this.currentQuestionIndex];

              // Update headline text - try multiple selectors
              const headlineSelectors = [
                'h1[class*="headline"]',
                'h2[class*="headline"]',
                'h3[class*="headline"]',
                '[class*="headline"]',
                '.fb-question-headline',
                'h1', 'h2', 'h3'
              ];

              let headline = null;
              for (const selector of headlineSelectors) {
                headline = embedContainer.querySelector(selector);
                if (headline && headline.textContent.trim().length > 10) {
                  break; // Found a headline with actual content
                }
              }

              if (headline && question.headline) {
                const translatedHeadline = this.translateText(question.headline, newLanguage);
                headline.textContent = translatedHeadline;
                console.log(`📝 [${this.containerId}] SEQUENTIAL updated headline to: ${translatedHeadline.substring(0, 50)}...`);
              } else {
                console.warn(`⚠️ [${this.containerId}] SEQUENTIAL could not find headline element`);
                // Debug: Show what elements we DO have
                const allHeadings = embedContainer.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="text"], [class*="question"]');
                console.log(`🔍 [${this.containerId}] SEQUENTIAL found ${allHeadings.length} potential headline elements:`);
                allHeadings.forEach((el, i) => {
                  console.log(`  ${i}: <${el.tagName}> class="${el.className}" text="${el.textContent.substring(0, 60)}..."`);
                });
              }

              // Update subheader if exists
              const subheader = embedContainer.querySelector('[class*="subheader"], .fb-question-subheader');
              if (subheader && question.subheader) {
                const translatedSubheader = this.translateText(question.subheader, newLanguage);
                subheader.textContent = translatedSubheader;
                console.log(`📝 [${this.containerId}] SEQUENTIAL updated subheader`);
              }

              // Update choice labels
              if (question.choices && question.choices.length > 0) {
                const labels = embedContainer.querySelectorAll('label span, label');
                question.choices.forEach((choice, index) => {
                  if (labels[index]) {
                    const translatedLabel = this.translateText(choice.label, newLanguage);
                    // Find the text node within the label (avoid changing nested elements)
                    const textNode = Array.from(labels[index].childNodes).find(n => n.nodeType === Node.TEXT_NODE);
                    if (textNode) {
                      textNode.textContent = translatedLabel;
                    } else {
                      labels[index].textContent = translatedLabel;
                    }
                    console.log(`📝 [${this.containerId}] SEQUENTIAL updated choice ${index}: ${translatedLabel.substring(0, 30)}...`);
                  }
                });
              }

              console.log(`✅ [${this.containerId}] SEQUENTIAL language updated without re-render!`);
            }

            shouldRenderAsDropdown(question) {
              this.debug(
                "🔍 [SEQUENTIAL] Checking if question should render as dropdown...",
              );
              this.debug(
                "Config useSingleSelectDropdown:",
                this.config.useSingleSelectDropdown,
              );
              this.debug("Question object:", question);

              if (!this.config.useSingleSelectDropdown) {
                this.debug("❌ [SEQUENTIAL] Dropdown disabled in config");
                return false;
              }

              if (!question || !question.type) {
                this.debug(
                  "❌ [SEQUENTIAL] No question or question type found",
                );
                return false;
              }

              // Check for single-select question types that should be converted to dropdowns
              const singleSelectTypes = [
                "multiplechoicesingle", // Fixed: all lowercase to match normalized type
                "multiplechoicemulti", // Fixed: all lowercase to match normalized type
                "singleselect", // Fixed: all lowercase to match normalized type
                "radio",
                "choice",
                "select",
              ];

              const questionType = question.type.toLowerCase();
              const isSingleSelect = singleSelectTypes.includes(questionType);
              const hasChoices =
                question.choices && question.choices.length > 0;

              this.debug(`📋 [SEQUENTIAL] Question analysis:`);
              this.debug(
                `  - Type: "${question.type}" (normalized: "${questionType}")`,
              );
              this.debug(`  - Is single select: ${isSingleSelect}`);
              this.debug(`  - Has choices: ${hasChoices}`);
              this.debug(
                `  - Choices count: ${question.choices ? question.choices.length : 0}`,
              );
              if (question.choices) {
                this.debug(`  - Choices:`, question.choices);
              }

              const shouldRender = isSingleSelect && hasChoices;
              this.debug(
                `🎯 [SEQUENTIAL] Final decision: ${shouldRender ? "RENDER AS DROPDOWN" : "RENDER WITH FORMBRICKS"}`,
              );

              return shouldRender;
            }

            async renderCustomDropdown(question) {
              const embedContainer = document.getElementById(this.embedId);
              if (!embedContainer) {
                throw new Error("Embed container not found");
              }

              // Helper function to extract text from object or return string
              const extractText = (textObj) => {
                if (typeof textObj === "string") return textObj;
                if (typeof textObj === "object" && textObj !== null) {
                  const lang = SURVEY_CONFIG.defaultLanguage || "en";

                  // Try in order: configured language -> default -> en -> english -> first available
                  return (
                    textObj[lang] ||
                    textObj.default ||
                    textObj.en ||
                    textObj.english ||
                    Object.values(textObj)[0] ||
                    "[No text available]"
                  );
                }
                return textObj || "";
              };

              const questionText = extractText(
                question.headline || question.text,
              );
              const questionSubtext = question.subheader
                ? extractText(question.subheader)
                : "";

              // Check for pre-existing value from user profile
              const profileValue =
                window.FormbricksSurveyManager.getProfileValue(question.id);

              this.debug(
                "🎨 [SEQUENTIAL] Rendering dropdown with extracted text:",
                {
                  questionText,
                  questionSubtext,
                  choicesCount: question.choices.length,
                  profileValue,
                },
              );

              // Create Formbricks-style HTML structure
              const html = `
            <div class="fb-survey fb-survey-inline" style="--fb-brand-color: #00C4B8;">
              <div class="fb-survey-content">
                <div class="fb-question-container">
                  <div class="fb-question-text">
                    <h3 class="fb-question-headline">${questionText || "Please select an option"}</h3>
                    ${questionSubtext ? `<p class="fb-question-subheader">${questionSubtext}</p>` : ""}
                  </div>
                  <div class="fb-question-form">
                    <div class="fb-form-field">
                      <select 
                        id="custom-dropdown-${question.id}" 
                        class="fb-select fb-form-control" 
                        data-question-id="${question.id}"
                        ${question.required !== false ? "required" : ""}
                      >
                        <option value="" disabled ${profileValue ? "" : "selected"}>
                          ${this.config.dropdownPlaceholder}
                        </option>
                        ${question.choices
                          .map((choice) => {
                            const choiceValue =
                              choice.id ||
                              choice.value ||
                              extractText(choice.label);
                            const choiceLabel = extractText(
                              choice.label || choice.value || choice,
                            );
                            const isSelected =
                              profileValue && profileValue === choiceValue;
                            this.debug("[SEQUENTIAL] Choice mapping:", {
                              choiceValue,
                              choiceLabel,
                              isSelected,
                              originalChoice: choice,
                            });
                            return `<option value="${choiceValue}" ${isSelected ? "selected" : ""}>${choiceLabel}</option>`;
                          })
                          .join("")}
                      </select>
                    </div>
                    ${
                      this.config.enableNavigation
                        ? `
                      <div class="fb-navigation-buttons" style="margin-top: 16px;">
                        ${
                          this.currentQuestionIndex > 0
                            ? '<button type="button" class="fb-button fb-button-secondary" onclick="window.sequentialInstance.previousQuestion()">Previous</button>'
                            : ""
                        }
                        <button type="button" class="fb-button fb-button-primary" onclick="window.sequentialInstance.nextQuestion()" disabled id="next-btn-${question.id}">Next</button>
                      </div>
                    `
                        : ""
                    }
                  </div>
                </div>
              </div>
            </div>
          `;

              embedContainer.innerHTML = html;

              // Pre-populate response data if profile value exists
              if (profileValue) {
                this.responseData[question.id] = profileValue;
                this.debug(
                  "👤 [SEQUENTIAL] Pre-populated response from profile:",
                  { questionId: question.id, value: profileValue },
                );
              }

              // Set up event handling
              this.setupCustomDropdownEvents(question);

              // Call the same setup as regular questions but skip hiding next buttons if navigation is enabled
              setTimeout(() => this.setupUICleanup(), 100);

              this.debug("Sequential custom dropdown rendered successfully");
            }

            setupCustomDropdownEvents(question) {
              const dropdown = document.getElementById(
                `custom-dropdown-${question.id}`,
              );
              const nextBtn = document.getElementById(
                `next-btn-${question.id}`,
              );

              if (!dropdown) return;

              dropdown.addEventListener("change", (event) => {
                const selectedValue = event.target.value;
                this.debug(`Sequential dropdown selection: ${selectedValue}`);

                // Store response data
                this.responseData[question.id] = selectedValue;

                // Save to user profile if enabled
                if (window.FormbricksSurveyManager) {
                  window.FormbricksSurveyManager.saveUserProfile(
                    question.id,
                    selectedValue,
                    question,
                  );
                }

                // Enable next button if navigation is enabled
                if (nextBtn) {
                  nextBtn.disabled = false;
                }

                // Trigger auto-save if enabled
                if (this.config.autoSave) {
                  clearTimeout(this.saveTimeout);
                  this.saveTimeout = setTimeout(() => {
                    this.saveResponse("sequential-dropdown-change");
                  }, this.config.autoSaveDelay);
                }

                this.debug(
                  "Sequential response data updated:",
                  this.responseData,
                );
              });

              // Store reference for navigation methods
              window.sequentialInstance = this;
            }
          }

          // Page cleanup
          window.addEventListener("beforeunload", () => {
            if (window.FormbricksSurveyManager) {
              window.FormbricksSurveyManager.instances.forEach((instance) => {
                if (instance.cleanupIntervals) {
                  instance.cleanupIntervals.forEach((item) => {
                    if (item.type === "observer") {
                      item.observer.disconnect();
                    } else {
                      clearInterval(item);
                    }
                  });
                }
                clearTimeout(instance.saveTimeout);
              });
            }
          });
        }

        // Initialize first question
        window.FormbricksSurveyManager.initializeAndRenderQuestion(
          BLOCK_1_CONFIG.containerId,
          BLOCK_1_CONFIG.questionIndex,
          {
            hideNextButton: BLOCK_1_CONFIG.hideNextButton,
            autoSave: BLOCK_1_CONFIG.autoSave,
            autoSaveDelay: BLOCK_1_CONFIG.autoSaveDelay,
            useSingleSelectDropdown: BLOCK_1_CONFIG.useSingleSelectDropdown,
            dropdownPlaceholder: BLOCK_1_CONFIG.dropdownPlaceholder,
          },
        );
      })(); // End IIFE
    </script>
  </body>
</html>

Question 2 code

For additional individual questions, insert this code:

<!-- =============================================== -->
<!-- BLOCK 2: ADDITIONAL QUESTION                   -->
<!-- Copy this block for additional questions       -->
<!-- =============================================== -->
<div class="gh-content">
  <h3>Question 2</h3>
  <div id="survey-question-2">
    <div class="loading">Loading survey...</div>
  </div>
</div>
<script>
  console.log("📝 [BLOCK 2] Additional Question");
  // ========================================
  // 🔧 CONFIGURATION - EDIT THESE VALUES
  // ========================================
  const BLOCK_2_CONFIG = {
    containerId: "survey-question-2", // Change this for each block
    questionIndex: 1, // Which question to show (0-based)
    hideNextButton: true, // Hide next/submit buttons
    autoSave: true, // Enable auto-save
    autoSaveDelay: 1000, // Auto-save delay in ms
    useSingleSelectDropdown: false, // Render single-select questions as dropdowns
    dropdownPlaceholder: "Please select an option...", // Placeholder text for dropdowns
  };
  // ========================================
  // END CONFIGURATION
  // ========================================
  // Wait for manager to be ready, then render question
  (function checkManagerAndRender() {
    if (
      window.FormbricksSurveyManager &&
      window.FormbricksSurveyManager.survey
    ) {
      console.log("✅ [BLOCK 2] Manager ready, rendering question");
      window.FormbricksSurveyManager.renderQuestion(
        BLOCK_2_CONFIG.containerId,
        BLOCK_2_CONFIG.questionIndex,
        {
          hideNextButton: BLOCK_2_CONFIG.hideNextButton,
          autoSave: BLOCK_2_CONFIG.autoSave,
          autoSaveDelay: BLOCK_2_CONFIG.autoSaveDelay,
          useSingleSelectDropdown: BLOCK_2_CONFIG.useSingleSelectDropdown,
          dropdownPlaceholder: BLOCK_2_CONFIG.dropdownPlaceholder,
        },
      );
    } else {
      console.log("⏳ [BLOCK 2] Waiting for manager...");
      setTimeout(checkManagerAndRender, 500);
    }
  })();
</script>

Question 3 code

<!-- =============================================== -->
<!-- BLOCK 3: SEQUENTIAL QUESTIONS WITH NAVIGATION -->
<!-- This block shows questions one by one with Next buttons -->
<!-- =============================================== -->

<div class="gh-content">
  <h3>Question 3</h3>
  <div id="survey-sequential">
    <div class="loading">Loading survey...</div>
  </div>
</div>

<script>
  console.log("🔄 [BLOCK 3] Sequential Questions");

  // ========================================
  // 🔧 CONFIGURATION - EDIT THESE VALUES
  // ========================================
  const BLOCK_3_CONFIG = {
    containerId: "survey-sequential", // Change this for each block
    startQuestionIndex: 2, // Which question to start with (0-based)
    hideNextButton: false, // Show next/submit buttons for navigation
    autoSave: true, // Enable auto-save
    autoSaveDelay: 1000, // Auto-save delay in ms
    enableNavigation: true, // Enable sequential navigation
    completionUrl: "https://informup.org/survey-complete/", // URL to redirect to when survey is complete
    useSingleSelectDropdown: false, // Render single-select questions as dropdowns
    dropdownPlaceholder: "Please select an option...", // Placeholder text for dropdowns
  };
  // ========================================
  // END CONFIGURATION
  // ========================================

  // Wait for manager to be ready, then render sequential questions
  (function checkManagerAndRenderSequential() {
    if (
      window.FormbricksSurveyManager &&
      window.FormbricksSurveyManager.survey
    ) {
      console.log("✅ [BLOCK 3] Manager ready, rendering sequential questions");
      window.FormbricksSurveyManager.renderSequentialQuestions(
        BLOCK_3_CONFIG.containerId,
        BLOCK_3_CONFIG.startQuestionIndex,
        {
          hideNextButton: BLOCK_3_CONFIG.hideNextButton,
          autoSave: BLOCK_3_CONFIG.autoSave,
          autoSaveDelay: BLOCK_3_CONFIG.autoSaveDelay,
          enableNavigation: BLOCK_3_CONFIG.enableNavigation,
          completionUrl: BLOCK_3_CONFIG.completionUrl,
          useSingleSelectDropdown: BLOCK_3_CONFIG.useSingleSelectDropdown,
          dropdownPlaceholder: BLOCK_3_CONFIG.dropdownPlaceholder,
        },
      );
    } else {
      console.log("⏳ [BLOCK 3] Waiting for manager...");
      setTimeout(checkManagerAndRenderSequential, 500);
    }
  })();
</script>

Last updated: November 2025 Guide Version: 1.0

  • Pittsburgh City Council
  • Pittsburgh Public School Board
  • Allegheny County Council
  • Forward Township
  • Westmoreland County