PageSourceSearch

https://clevertap.com/wp-content/themes/clevertap2023/js/ct-casestudy-form-enhancement.js?ver=1790851206

js clevertap.com collected 2026-10-02 02:15:26 UTC 80,309 bytes, 2,049 lines download raw bytes

1/**
2 * Case Study & Blog Form Enhancement
3 * 
4 * Adds "Schedule 1:1 call" checkbox functionality:
5 * - Shows/hides phone number field
6 * - Dynamically updates CleverTapDemoForm to MQL or Warm Lead
7 * - Handles phone number input with intlTelInput
8 * - Uses UTM parameters for MQL attribution when checkbox is checked
9 * 
10 * MQL Attribution Logic (per markops requirements):
11 * - When checkbox is checked: Form converts from Warm Lead to MQL
12 * - ct_lead_source is set to "MQL"
13 * - MQL attribution fields use UTM parameters (utm_source, utm_medium, utm_campaign)
14 * - If UTM parameters are blank, uses "direct" for source and medium
15 * - Campaign field is empty if UTM campaign is blank
16 * 
17 * Applies to:
18 * - All case study forms (detected by URL pattern: /case-study/)
19 * - Blog form with ID: ctForm_3e9d2979-39cb-471a-96f7-419f30729742
20 * - CT University form with ID: ctForm_2d990019-01bb-4c99-8613-f78c3423c452
21 */
22
23(function() {
24	'use strict';
25
26	var schedule11TrackingConfig = window.ctSchedule11TrackingConfig && typeof window.ctSchedule11TrackingConfig === 'object'
27		? Object.assign({}, window.ctSchedule11TrackingConfig)
28		: {};
29	var schedule11TokenReady = false;
30	var pendingSchedule11Events = [];
31
32	function flushPendingSchedule11Events() {
33		var queued = pendingSchedule11Events.slice();
34		pendingSchedule11Events = [];
35		for (var i = 0; i < queued.length; i += 1) {
36			trackSchedule11Experiment(queued[i].eventName, queued[i].payload, true);
37		}
38	}
39
40	function refreshSchedule11IngestToken() {
41		var endpoint = schedule11TrackingConfig.ingestConfigEndpoint || '/wp-json/ct/v1/pmm-ingest-config';
42		if (!window.fetch) {
43			schedule11TokenReady = true;
44			flushPendingSchedule11Events();
45			return;
46		}
47		fetch(endpoint + '?_ts=' + Date.now(), {
48			method: 'GET',
49			credentials: 'same-origin',
50			cache: 'no-store',
51			headers: { 'Cache-Control': 'no-cache' }
52		})
53			.then(function (res) { return res.ok ? res.json() : null; })
54			.then(function (config) {
55				if (config && config.ingestToken) {
56					schedule11TrackingConfig.ingestToken = String(config.ingestToken);
57					if (config.ingestEndpoint) {
58						schedule11TrackingConfig.ingestEndpoint = String(config.ingestEndpoint);
59					}
60					window.ctSchedule11TrackingConfig = schedule11TrackingConfig;
61				}
62			})
63			.catch(function () {})
64			.then(function () {
65				schedule11TokenReady = true;
66				flushPendingSchedule11Events();
67			});
68	}
69	refreshSchedule11IngestToken();
70	setTimeout(function () {
71		if (!schedule11TokenReady) {
72			schedule11TokenReady = true;
73			flushPendingSchedule11Events();
74		}
75	}, 2500);
76
77	function getResourceTypeFromPath(pathname) {
78		var path = (pathname || window.location.pathname || '').toLowerCase();
79		if (path.indexOf('/ebooks/') > -1 || path.indexOf('/ebook/') > -1) return 'ebook';
80		if (path.indexOf('/webinars/') > -1 || path.indexOf('/webinar/') > -1) return 'webinar';
81		if (path.indexOf('/whitepaper') > -1) return 'whitepaper';
82		if (path.indexOf('/guides/') > -1 || path.indexOf('/guide/') > -1) return 'guide';
83		if (path.indexOf('/events/') > -1 || path.indexOf('/event/') > -1) return 'event';
84		if (path.indexOf('/benchmark-report') > -1) return 'benchmark_report';
85		if (path.indexOf('/case-study/') > -1 || path.indexOf('/case-studies/') > -1) return 'case_study';
86		if (path.indexOf('/blog/') > -1) return 'blog';
87		return 'other';
88	}
89
90	function trackSchedule11Experiment(eventName, payload, forceSend) {
91		if (!eventName || !schedule11TrackingConfig.ingestEndpoint || !schedule11TrackingConfig.ingestToken) {
92			return;
93		}
94		if (!forceSend && !schedule11TokenReady) {
95			pendingSchedule11Events.push({ eventName: eventName, payload: payload || {} });
96			return;
97		}
98		var trackingSessionId = '';
99		try {
100			trackingSessionId = sessionStorage.getItem('ct_tracking_session_id') || localStorage.getItem('ct_tracking_session_id') || '';
101		} catch (e) {}
102		var body = Object.assign({
103			event: eventName,
104			page_key: getResourceTypeFromPath(),
105			page_path: window.location.pathname,
106			resource_type: getResourceTypeFromPath(),
107			ct_tracking_session_id: trackingSessionId,
108			ingest_token: schedule11TrackingConfig.ingestToken
109		}, payload || {});
110
111		try {
112			var json = JSON.stringify(body);
113			if (navigator.sendBeacon) {
114				navigator.sendBeacon(schedule11TrackingConfig.ingestEndpoint, new Blob([json], { type: 'application/json' }));
115				return;
116			}
117			if (window.fetch) {
118				fetch(schedule11TrackingConfig.ingestEndpoint, {
119					method: 'POST',
120					headers: { 'Content-Type': 'application/json' },
121					body: json,
122					credentials: 'same-origin',
123					keepalive: true
124				});
125			}
126		} catch (e) {}
127	}
128
129	// Function to get UTM parameter from URL or cookies
130	function getUtmParameter(name) {
131		// First check URL parameters
132		var urlParams = new URLSearchParams(window.location.search);
133		var value = urlParams.get(name);
134		if (value) {
135			return decodeURIComponent(value);
136		}
137		
138		// Check cookies (stored by ct-hubspot.js)
139		var cookieName = '_mql' + name.substring(3); // utm_source -> _mqlas, utm_medium -> _mqlam, utm_campaign -> _mqlac
140		if (name === 'utm_source') cookieName = '_mqlas';
141		if (name === 'utm_medium') cookieName = '_mqlam';
142		if (name === 'utm_campaign') cookieName = '_mqlac';
143		
144		function getCookie(name) {
145			var value = '; ' + document.cookie;
146			var parts = value.split('; ' + name + '=');
147			if (parts.length === 2) return parts.pop().split(';').shift();
148			return null;
149		}
150		
151		value = getCookie(cookieName);
152		return value || null;
153	}
154
155	// Function to get attribution values from UTM parameters
156	function getAttributionFromUtm() {
157		var utmSource = getUtmParameter('utm_source');
158		var utmMedium = getUtmParameter('utm_medium');
159		var utmCampaign = getUtmParameter('utm_campaign');
160		
161		// If UTM parameters are blank, use "direct" for source and medium
162		// Per markops requirements: "If it is blank, it will be direct, no value has to be passed"
163		var source = utmSource && utmSource.trim() ? utmSource.trim() : 'direct';
164		var medium = utmMedium && utmMedium.trim() ? utmMedium.trim() : 'direct';
165		var campaign = utmCampaign && utmCampaign.trim() ? utmCampaign.trim() : '';
166		
167		return {
168			source: source,
169			medium: medium,
170			campaign: campaign
171		};
172	}
173
174	// Ensure intlTelInput CSS is loaded
175	function ensureIntlTelInputCSS() {
176		var existingLink = document.querySelector('link[href*="intlTelInput.css"]');
177		if (existingLink) return;
178
179		var link = document.createElement('link');
180		link.rel = 'stylesheet';
181		link.href = 'https://clevertap.com/wp-content/themes/clevertap2023/css/intlTelInput.css?v=20251006';
182		document.head.appendChild(link);
183	}
184
185	// Inject phone field styles
186	function injectPhoneStyles() {
187		var styleId = 'ct-casestudy-phone-styles';
188		if (document.getElementById(styleId)) return;
189
190		var style = document.createElement('style');
191		style.id = styleId;
192		style.textContent = 
193			'/* Phone input wrapper */' +
194			'.iti.iti--allow-dropdown.iti--separate-dial-code { width: 100%; }' +
195			'.iti__selected-dial-code { color: #000; }' +
196			'.iti-mobile .iti--container { z-index: 9999999; }' +
197			'/* Phone field container - applies to all forms */' +
198			'[id^="phone_field_container_"] .ctrl-block.phoneg { width: 100%; }' +
199			'[id^="phone_field_container_"] .ctrl-block.phoneg > div { width: 100%; }' +
200			'[id^="phone_"]:not([id*="_hidden"]):not([id*="_e164"]):not([id*="_dial_code"]):not([id*="_country"]) { width: 100%; }' +
201			'/* Hide input labels for case study forms */' +
202			'label.input-label { display: none; }' +
203			'/* Subscription section checkbox alignment */' +
204			'.subscription-section .ctrl-group[id*="schedule_1on1_call"], ' +
205			'.subscription-section .ctrl-group:has([name="schedule_1on1_call"][data-form-id="3e9d2979-39cb-471a-96f7-419f30729742"]) { ' +
206			'  display: flex !important; ' +
207			'  align-items: flex-start !important; ' +
208			'  width: 100% !important; ' +
209			'  margin-left: 0 !important; ' +
210			'  justify-content: flex-start !important; ' +
211			'  flex-wrap: nowrap !important; ' +
212			'}' +
213			'.subscription-section label[for*="schedule_1on1_call"] { ' +
214			'  display: flex !important; ' +
215			'  align-items: center !important; ' +
216			'  gap: 10px !important; ' +
217			'  margin: 0 !important; ' +
218			'  width: auto !important; ' +
219			'  flex-shrink: 0 !important; ' +
220			'}' +
221			'.subscription-section [name="schedule_1on1_call"][data-form-id="3e9d2979-39cb-471a-96f7-419f30729742"] { ' +
222			'  margin: 0 !important; ' +
223			'  flex-shrink: 0 !important; ' +
224			'  min-width: initial !important; ' +
225			'  flex: initial !important; ' +
226			'}' +
227			'/* Subscription section text and phone input styling */' +
228			'section.subscription-section span { ' +
229			'  color: #fff !important; ' +
230			'}' +
231			'section.subscription-section .iti__flag { ' +
232			'  display: none; ' +
233			'}' +
234			'/* Ensure flag shows in popup/modal */' +
235			'#subscribe .iti__flag, ' +
236			'.blog-subscribe-form .iti__flag, ' +
237			'.comp.modal .iti__flag { ' +
238			'  display: block !important; ' +
239			'}' +
240			'section.subscription-section span.iti__country-name { ' +
241			'  color: #000 !important; ' +
242			'}';
243		document.head.appendChild(style);
244	}
245
246	// Check if current page is a case study page (store result to avoid repeated checks)
247	var _isCaseStudyPage = null;
248	function isCaseStudyPage() {
249		if (_isCaseStudyPage === null) {
250			var pathname = window.location.pathname.toLowerCase();
251			// Check for case study URL pattern
252			var hasCaseStudyUrl = pathname.indexOf('/case-study/') > -1 || pathname.indexOf('/case-studies/') > -1;
253			
254			// Check for case study template class
255			var hasCaseStudyTemplate = document.body.classList.contains('page-template-p-casestudies') ||
256			                          document.querySelector('.page-template-p-casestudies') !== null;
257			
258			// Check for case study form with "Loved it" heading
259			var hasCaseStudyForm = false;
260			var forms = document.querySelectorAll('form[id^="ctForm_"]');
261			for (var i = 0; i < forms.length; i++) {
262				var form = forms[i];
263				var heading = form.querySelector('h2');
264				if (heading && (heading.textContent.indexOf('Loved it') > -1 || heading.textContent.indexOf('Get this in your inbox') > -1)) {
265					hasCaseStudyForm = true;
266					break;
267				}
268			}
269			
270			_isCaseStudyPage = hasCaseStudyUrl || hasCaseStudyTemplate || hasCaseStudyForm;
271		}
272		return _isCaseStudyPage;
273	}
274
275	// Check if form is a blog form
276	function isBlogForm(formId) {
277		return formId === '3e9d2979-39cb-471a-96f7-419f30729742';
278	}
279
280	// Check if form is the CT University form
281	function isCtUniversityForm(formId) {
282		return formId === '2d990019-01bb-4c99-8613-f78c3423c452';
283	}
284
285	/** Same HubSpot form id can exist twice (e.g. blog inline + popup); never use document.getElementById for scoped ids. */
286	function elByIdIn(root, id) {
287		if (!root || id == null || id === '') return null;
288		var esc = String(id).replace(/\\/g, '\\\\').replace(/"/g, '\\"');
289		return root.querySelector('[id="' + esc + '"]');
290	}
291
292	function formHasSchedule11Enhancement(frm, hubspotFormId) {
293		return !!(frm && frm.querySelector('[name="schedule_1on1_call"][data-form-id="' + hubspotFormId + '"]'));
294	}
295
296	// Get HubSpot form UUID from form element (HTML id may be ctForm_<uuid> or ctForm_blog_subscribe_*)
297	function getFormId(form) {
298		if (!form) return null;
299		var hid = form.getAttribute('data-hubspot-form-id');
300		if (hid) return hid;
301		if (!form.id) return null;
302		var match = form.id.match(/^ctForm_(.+)$/);
303		return match ? match[1] : null;
304	}
305
306	// Get ct_lead_source based on page type
307	function getDefaultLeadSource(formId, isCaseStudy) {
308		if (isCaseStudy) {
309			// For case studies, try to get from page title or use default
310			var pageTitle = document.querySelector('h1');
311			return pageTitle ? pageTitle.textContent.trim() : 'Case Study';
312		} else if (isBlogForm(formId)) {
313			return 'Mkt Asset - blogsub';
314		} else if (isCtUniversityForm(formId)) {
315			return 'CT University';
316		}
317		return 'Form Submission';
318	}
319
320	// Wait for DOM and form to be ready
321	function initFormEnhancement() {
322		// Ensure CSS is loaded
323		ensureIntlTelInputCSS();
324		injectPhoneStyles();
325		
326		var isCaseStudy = isCaseStudyPage();
327		var formsToEnhance = [];
328		
329		// ALWAYS check for blog form with ID ctForm_3e9d2979-39cb-471a-96f7-419f30729742 (regardless of page type)
330		var blogFormId = '3e9d2979-39cb-471a-96f7-419f30729742';
331		// Find all forms with this ID (can appear in subscribe popup or subscription section)
332		var allBlogForms = document.querySelectorAll('form[data-hubspot-form-id="' + blogFormId + '"]');
333		allBlogForms.forEach(function(form) {
334			if (!formHasSchedule11Enhancement(form, blogFormId)) {
335				var isInModal = form.closest('.comp.modal, [data-modal], #subscribe') !== null;
336				var isInSubscriptionSection = form.closest('.subscription-section') !== null;
337				formsToEnhance.push({ 
338					form: form, 
339					formId: blogFormId, 
340					isCaseStudy: false,
341					isInModal: isInModal,
342					isInSubscriptionSection: isInSubscriptionSection
343				});
344			}
345		});
346
347		// CT University form (supports both data-hubspot-form-id and static ctForm_<id>)
348		var ctUniversityFormId = '2d990019-01bb-4c99-8613-f78c3423c452';
349		var allCtUniversityForms = document.querySelectorAll(
350			'form[data-hubspot-form-id="' + ctUniversityFormId + '"], form#ctForm_' + ctUniversityFormId
351		);
352		allCtUniversityForms.forEach(function(form) {
353			if (!formHasSchedule11Enhancement(form, ctUniversityFormId)) {
354				formsToEnhance.push({
355					form: form,
356					formId: ctUniversityFormId,
357					isCaseStudy: false
358				});
359			}
360		});
361		
362		// Watch for subscribe modal opening (for blog form)
363		// Check for both #subscribe and .blog-subscribe-form
364		var subscribeModal = document.getElementById('subscribe') || document.querySelector('.blog-subscribe-form');
365		if (subscribeModal) {
366			var subscribeObserver = new MutationObserver(function(mutations) {
367				mutations.forEach(function(mutation) {
368					if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
369						var modal = mutation.target;
370						if (modal.classList.contains('active') || modal.classList.contains('show') || modal.classList.contains('visible')) {
371							setTimeout(function() {
372								var subscribeForm = modal.querySelector('form[data-hubspot-form-id="' + blogFormId + '"]');
373								if (subscribeForm && !formHasSchedule11Enhancement(subscribeForm, blogFormId)) {
374									enhanceForm(subscribeForm, blogFormId, false);
375								}
376							}, 200);
377						}
378					}
379				});
380			});
381			subscribeObserver.observe(subscribeModal, { attributes: true, attributeFilter: ['class'] });
382			
383			// Check immediately if modal is already open
384			if (subscribeModal.classList.contains('active') || subscribeModal.classList.contains('show') || subscribeModal.classList.contains('visible')) {
385				setTimeout(function() {
386					var subscribeForm = subscribeModal.querySelector('form[data-hubspot-form-id="' + blogFormId + '"]');
387					if (subscribeForm && !formHasSchedule11Enhancement(subscribeForm, blogFormId)) {
388						enhanceForm(subscribeForm, blogFormId, false);
389					}
390				}, 200);
391			}
392		}
393		
394		// Also watch for .blog-subscribe-form specifically (in case it's different from #subscribe)
395		var blogSubscribeForms = document.querySelectorAll('.blog-subscribe-form');
396		blogSubscribeForms.forEach(function(modal) {
397			if (modal.id !== 'subscribe') {
398				var blogFormObserver = new MutationObserver(function(mutations) {
399					mutations.forEach(function(mutation) {
400						if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
401							var modalEl = mutation.target;
402							if (modalEl.classList.contains('active') || modalEl.classList.contains('show') || modalEl.classList.contains('visible')) {
403								setTimeout(function() {
404									var subscribeForm = modalEl.querySelector('form[data-hubspot-form-id="' + blogFormId + '"]');
405									if (subscribeForm && !formHasSchedule11Enhancement(subscribeForm, blogFormId)) {
406										enhanceForm(subscribeForm, blogFormId, false);
407									}
408								}, 200);
409							}
410						}
411					});
412				});
413				blogFormObserver.observe(modal, { attributes: true, attributeFilter: ['class'] });
414				
415				// Check immediately if modal is already open
416				if (modal.classList.contains('active') || modal.classList.contains('show') || modal.classList.contains('visible')) {
417					setTimeout(function() {
418						var subscribeForm = modal.querySelector('form[data-hubspot-form-id="' + blogFormId + '"]');
419						if (subscribeForm && !formHasSchedule11Enhancement(subscribeForm, blogFormId)) {
420							enhanceForm(subscribeForm, blogFormId, false);
421						}
422					}, 200);
423				}
424			}
425		});
426		
427		// Find forms to enhance
428		if (isCaseStudy) {
429			// Find all case study forms (any form with ctForm_ prefix on case study pages)
430			// Include forms in modals (even if hidden initially)
431			var allForms = document.querySelectorAll('form[id^="ctForm_"]');
432			allForms.forEach(function(form) {
433				var formId = getFormId(form);
434				if (formId) {
435					// Check if form is in a modal
436					var isInModal = form.closest('.comp.modal') || form.closest('[data-modal]');
437					formsToEnhance.push({ 
438						form: form, 
439						formId: formId, 
440						isCaseStudy: true,
441						isInModal: !!isInModal
442					});
443				}
444			});
445			
446			// Also check for forms that might be added dynamically when modal opens
447			// Listen for modal open events
448			document.addEventListener('click', function(e) {
449				var openModalBtn = e.target.closest('.open-modal, [data-modal], button[data-modal], .open-blog-popup');
450				if (openModalBtn) {
451					var modalName = openModalBtn.getAttribute('data-modal') || openModalBtn.getAttribute('name');
452					if (modalName === 'contact' || !modalName) {
453						// Wait a bit for modal to open and form to be visible
454						setTimeout(function() {
455							var modalForms = document.querySelectorAll('.comp.modal[data-modal="contact"] form[id^="ctForm_"], .comp.modal.contact form[id^="ctForm_"], [data-modal="contact"] form[id^="ctForm_"]');
456							modalForms.forEach(function(form) {
457								var formId = getFormId(form);
458								if (formId && !formHasSchedule11Enhancement(form, formId)) {
459									enhanceForm(form, formId, true);
460								}
461							});
462						}, 400);
463					} else if (modalName === 'subscribe') {
464						// Handle subscribe modal opening
465						setTimeout(function() {
466							var subscribeModal = document.getElementById('subscribe');
467							if (subscribeModal) {
468								var subscribeForm = subscribeModal.querySelector('form[data-hubspot-form-id="3e9d2979-39cb-471a-96f7-419f30729742"]');
469								if (subscribeForm && !formHasSchedule11Enhancement(subscribeForm, '3e9d2979-39cb-471a-96f7-419f30729742')) {
470									enhanceForm(subscribeForm, '3e9d2979-39cb-471a-96f7-419f30729742', false);
471								}
472							}
473						}, 400);
474					}
475				}
476			}, true);
477			
478			// Use MutationObserver to watch for modal class changes (more reliable)
479			var modalObserver = new MutationObserver(function(mutations) {
480				mutations.forEach(function(mutation) {
481					if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
482						var modal = mutation.target;
483						if (modal.classList.contains('active') || modal.classList.contains('show') || modal.classList.contains('visible')) {
484							setTimeout(function() {
485								var modalForms = modal.querySelectorAll('form[id^="ctForm_"]');
486								modalForms.forEach(function(form) {
487									var formId = getFormId(form);
488									if (formId && !formHasSchedule11Enhancement(form, formId)) {
489										enhanceForm(form, formId, true);
490									}
491								});
492							}, 200);
493						}
494					}
495				});
496			});
497			
498			// Observe all modals on the page (including subscribe modal)
499			var allModals = document.querySelectorAll('.comp.modal, [data-modal], .modal, #subscribe');
500			allModals.forEach(function(modal) {
501				modalObserver.observe(modal, { attributes: true, attributeFilter: ['class'] });
502			});
503			
504			// Also watch for subscribe modal specifically
505			var subscribeModal = document.getElementById('subscribe');
506			if (subscribeModal) {
507				modalObserver.observe(subscribeModal, { attributes: true, attributeFilter: ['class'] });
508				// Check immediately if already open
509				if (subscribeModal.classList.contains('active') || subscribeModal.classList.contains('show') || subscribeModal.classList.contains('visible')) {
510					setTimeout(function() {
511						var subscribeForm = subscribeModal.querySelector('form[data-hubspot-form-id="3e9d2979-39cb-471a-96f7-419f30729742"]');
512						if (subscribeForm && !formHasSchedule11Enhancement(subscribeForm, '3e9d2979-39cb-471a-96f7-419f30729742')) {
513							enhanceForm(subscribeForm, '3e9d2979-39cb-471a-96f7-419f30729742', false);
514						}
515					}, 200);
516				}
517			}
518			
519			// Also watch for new modals added to DOM
520			var bodyObserver = new MutationObserver(function(mutations) {
521				mutations.forEach(function(mutation) {
522					mutation.addedNodes.forEach(function(node) {
523						if (node.nodeType === 1) { // Element node
524							// Check if it's a modal or contains a modal
525							var modals = node.matches && node.matches('.comp.modal, [data-modal]') 
526								? [node] 
527								: node.querySelectorAll ? node.querySelectorAll('.comp.modal, [data-modal]') : [];
528							modals.forEach(function(modal) {
529								modalObserver.observe(modal, { attributes: true, attributeFilter: ['class'] });
530								// Check for forms immediately
531								var modalForms = modal.querySelectorAll('form[id^="ctForm_"]');
532								modalForms.forEach(function(form) {
533									var formId = getFormId(form);
534									if (formId && !formHasSchedule11Enhancement(form, formId)) {
535										enhanceForm(form, formId, true);
536									}
537								});
538							});
539						}
540					});
541				});
542			});
543			bodyObserver.observe(document.body, { childList: true, subtree: true });
544		}
545		
546		// Watch for subscription section becoming active
547		var subscriptionSection = document.querySelector('.subscription-section');
548		if (subscriptionSection) {
549			var subscriptionObserver = new MutationObserver(function(mutations) {
550				mutations.forEach(function(mutation) {
551					if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
552						var section = mutation.target;
553						if (section.classList.contains('activeSection')) {
554							setTimeout(function() {
555								var subscriptionForm = section.querySelector('form[data-hubspot-form-id="3e9d2979-39cb-471a-96f7-419f30729742"]');
556								if (subscriptionForm && !formHasSchedule11Enhancement(subscriptionForm, '3e9d2979-39cb-471a-96f7-419f30729742')) {
557									enhanceForm(subscriptionForm, '3e9d2979-39cb-471a-96f7-419f30729742', false);
558								}
559							}, 200);
560						}
561					}
562				});
563			});
564			subscriptionObserver.observe(subscriptionSection, { attributes: true, attributeFilter: ['class'] });
565			
566			// Check immediately if already active
567			if (subscriptionSection.classList.contains('activeSection')) {
568				setTimeout(function() {
569					var subscriptionForm = subscriptionSection.querySelector('form[data-hubspot-form-id="3e9d2979-39cb-471a-96f7-419f30729742"]');
570					if (subscriptionForm && !formHasSchedule11Enhancement(subscriptionForm, '3e9d2979-39cb-471a-96f7-419f30729742')) {
571						enhanceForm(subscriptionForm, '3e9d2979-39cb-471a-96f7-419f30729742', false);
572					}
573				}, 200);
574			}
575		}
576		
577		
578		// If no forms found, retry
579		if (formsToEnhance.length === 0) {
580			setTimeout(initFormEnhancement, 200);
581			return;
582		}
583		
584		// Enhance each form
585		formsToEnhance.forEach(function(formData) {
586			enhanceForm(formData.form, formData.formId, formData.isCaseStudy);
587		});
588	}
589
590	// Enhance a single form
591	function enhanceForm(form, formId, isCaseStudy) {
592		if (!form) return;
593		
594		// Check if already enhanced
595		if (formHasSchedule11Enhancement(form, formId)) {
596			return;
597		}
598		
599		// Check if form is in a modal
600		var modal = form.closest('.comp.modal, [data-modal]');
601		var isModalHidden = false;
602		
603		if (modal) {
604			// Check if modal is hidden
605			var modalStyle = window.getComputedStyle(modal);
606			isModalHidden = (
607				modal.classList.contains('active') === false &&
608				(modal.style.display === 'none' || modalStyle.display === 'none' || modalStyle.visibility === 'hidden')
609			);
610			
611			// If modal might be hidden, set up observer
612			if (isModalHidden) {
613				var observer = new MutationObserver(function(mutations) {
614					var currentStyle = window.getComputedStyle(modal);
615					if (modal.classList.contains('active') || 
616					    currentStyle.display !== 'none' || 
617					    currentStyle.visibility !== 'hidden') {
618						// Modal is now visible, enhance the form
619						setTimeout(function() {
620							enhanceFormInternal(form, formId, isCaseStudy);
621						}, 200);
622						observer.disconnect();
623					}
624				});
625				observer.observe(modal, { 
626					attributes: true, 
627					attributeFilter: ['class', 'style'],
628					childList: false,
629					subtree: false
630				});
631				
632				// Also check immediately in case modal is already open
633				setTimeout(function() {
634					var currentStyle = window.getComputedStyle(modal);
635					if (modal.classList.contains('active') || 
636					    currentStyle.display !== 'none' || 
637					    currentStyle.visibility !== 'hidden') {
638						enhanceFormInternal(form, formId, isCaseStudy);
639						observer.disconnect();
640					}
641				}, 100);
642			}
643		}
644		
645		// Enhance immediately (works for visible forms and will be called again when modal opens)
646		enhanceFormInternal(form, formId, isCaseStudy);
647	}
648	
649	// Internal function to actually enhance the form
650	function enhanceFormInternal(form, formId, isCaseStudy) {
651		if (!form) {
652			console.warn('enhanceFormInternal: form is null for formId:', formId);
653			return;
654		}
655		
656		// Double-check if already enhanced
657		if (formHasSchedule11Enhancement(form, formId)) {
658			return;
659		}
660		
661		// Debug: uncomment to see form enhancement
662		// console.log('Enhancing form:', formId, 'on case study page:', isCaseStudy);
663
664		// CT University asks for name + work email + optional schedule call (no company field).
665		// Remove company input block before validation can consider it mandatory.
666		if (isCtUniversityForm(formId)) {
667			var companyField = form.querySelector('#company');
668			if (companyField) {
669				var companyBlock = companyField.closest('.ctrl-block');
670				if (companyBlock && companyBlock.parentNode) {
671					companyBlock.parentNode.removeChild(companyBlock);
672				} else {
673					companyField.remove();
674				}
675			}
676		}
677
678		// Find the email field group to insert checkbox after it
679		// Try multiple selectors to find email field
680		var emailInput = form.querySelector('#sdemail') || 
681		                 form.querySelector('input[type="email"]') ||
682		                 form.querySelector('input[name="email"]') ||
683		                 form.querySelector('input[placeholder*="email" i]') ||
684		                 form.querySelector('input[placeholder*="Email" i]') ||
685		                 form.querySelector('input[id*="email" i]');
686		
687		if (!emailInput) {
688			console.warn('Email field not found in form:', formId, 'Form HTML:', form.outerHTML.substring(0, 200));
689			// Try to find any input field as fallback
690			var firstInput = form.querySelector('input[type="text"]');
691			if (firstInput) {
692				emailInput = firstInput;
693				console.log('Using first text input as fallback:', firstInput.id || firstInput.name);
694			} else {
695				console.error('No input fields found in form:', formId);
696				return;
697			}
698		}
699		
700		// Debug: uncomment to see email field detection
701		// console.log('Found email input:', emailInput.id || emailInput.name || emailInput.placeholder);
702		
703		// Find the parent ctrl-group containing the email field
704		var emailGroup = emailInput.closest('.ctrl-group');
705		if (!emailGroup) {
706			// If no ctrl-group, create one or use the email input's parent
707			emailGroup = emailInput.parentElement;
708			// If parent is not a ctrl-group, wrap in one
709			if (!emailGroup.classList.contains('ctrl-group')) {
710				var wrapper = document.createElement('div');
711				wrapper.className = 'ctrl-group';
712				emailGroup.parentNode.insertBefore(wrapper, emailGroup);
713				wrapper.appendChild(emailGroup);
714				emailGroup = wrapper;
715			}
716		}
717
718		// Create checkbox container
719		var checkboxGroup = document.createElement('div');
720		checkboxGroup.className = 'ctrl-group';
721		// Check if form is in subscription section and apply specific styling
722		var isInSubscriptionSection = form.closest('.subscription-section') !== null;
723		if (isInSubscriptionSection) {
724			checkboxGroup.style.cssText = 'margin-bottom: 15px; width: 100%; display: flex; align-items: flex-start; justify-content: flex-start; margin-left: 0;';
725		} else {
726			checkboxGroup.style.cssText = 'margin-bottom: 15px;';
727		}
728
729		var checkboxBlock = document.createElement('div');
730		checkboxBlock.className = 'ctrl-block';
731
732		var checkboxLabel = document.createElement('label');
733		// Apply specific styling for subscription section
734		if (isInSubscriptionSection) {
735			checkboxLabel.style.cssText = 'display: flex !important; align-items: center !important; gap: 10px !important; cursor: pointer; font-weight: 500; color: #000d26; margin: 0 !important; width: auto !important; flex-shrink: 0 !important;';
736		} else {
737			checkboxLabel.style.cssText = 'display: flex; align-items: center; gap: 10px; cursor: pointer; font-weight: 500; color: #000d26;';
738		}
739
740		var checkbox = document.createElement('input');
741		checkbox.type = 'checkbox';
742		// Unique id per DOM form: blog inline + popup share the same HubSpot formId (duplicate ids broke label + getElementById targets).
743		var formInstancePart = (form.id || 'noid').replace(/^ctForm_/, '').replace(/[^a-zA-Z0-9_-]/g, '_') || 'noid';
744		checkbox.id = 'schedule_1on1_call_' + formId.replace(/[^a-zA-Z0-9-]/g, '_') + '_' + formInstancePart;
745		checkbox.name = 'schedule_1on1_call';
746		checkbox.value = 'Yes';
747		checkbox.setAttribute('data-form-id', formId);
748		// Apply specific styling for subscription section
749		if (isInSubscriptionSection) {
750			checkbox.style.cssText = 'width: auto !important; margin: 0 !important; cursor: pointer; accent-color: #1076fb; flex-shrink: 0 !important;';
751		} else {
752			checkbox.style.cssText = 'width: auto; margin: 0; cursor: pointer; accent-color: #1076fb;';
753		}
754
755		var checkboxText = document.createElement('span');
756		checkboxText.textContent = isCtUniversityForm(formId) ? 'Schedule a 1:1 demo call' : 'Schedule 1:1 call';
757
758		checkboxLabel.appendChild(checkbox);
759		checkboxLabel.appendChild(checkboxText);
760		checkboxBlock.appendChild(checkboxLabel);
761		checkboxGroup.appendChild(checkboxBlock);
762
763		trackSchedule11Experiment('schedule_1on1_impression', {
764			form_id: formId,
765			component_name: 'schedule_1on1_checkbox'
766		});
767
768		// Insert checkbox after email group
769		if (emailGroup && emailGroup.parentNode) {
770			emailGroup.parentNode.insertBefore(checkboxGroup, emailGroup.nextSibling);
771			// Checkbox inserted successfully
772		} else {
773			// Fallback: insert after email input's parent
774			if (emailInput && emailInput.parentNode) {
775				emailInput.parentNode.insertBefore(checkboxGroup, emailInput.nextSibling);
776			} else {
777				// Last resort: append to form
778				form.appendChild(checkboxGroup);
779			}
780		}
781
782		// Create phone field container (initially hidden) - matching exact structure from demo form
783		var phoneGroup = document.createElement('div');
784		phoneGroup.className = 'ctrl-group';
785		phoneGroup.id = 'phone_field_container_' + formId;
786		phoneGroup.style.cssText = 'display: none; margin-bottom: 0;';
787		phoneGroup.setAttribute('data-form-id', formId);
788
789		// Hidden country fields (demo form). Blog footer already has #country + #countrylist — duplicating IDs breaks DOM + queries.
790		var hiddenCountryBlock = document.createElement('div');
791		hiddenCountryBlock.className = 'ctrl-block';
792		if (form.querySelector('#country')) {
793			hiddenCountryBlock.style.cssText = 'display: none; height: 0; margin: 0; padding: 0; overflow: hidden; visibility: hidden;';
794			hiddenCountryBlock.innerHTML = '';
795		} else {
796			hiddenCountryBlock.style.cssText = 'visibility: hidden; height: 0; margin: 0; padding: 0; overflow: hidden;';
797			hiddenCountryBlock.innerHTML = '<label class="input-label" for="country">Country</label>' +
798				'<input type="hidden" list="countrylist" tabindex="-1" autocomplete="off" autocapitalize="none" autocorrect="off" spellcheck="false" id="country" placeholder="Country" name="countrylist" class="ctrl" onpaste="return false;" />' +
799				'<input type="hidden" class="country_hidden" tabindex="-1" value="" autocomplete="off" />' +
800				'<datalist type="hidden" id="countrylist" tabindex="-1"></datalist>';
801		}
802
803		// Phone input block (exact match from demo form) - use unique IDs per form
804		var phoneBlock = document.createElement('div');
805		phoneBlock.className = 'ctrl-block phoneg';
806		phoneBlock.innerHTML = '<div>' +
807			'<input id="sdphone" class="ctrl" name="phone" type="tel" inputmode="tel" placeholder="Enter phone number" autocomplete="tel" data-form-id="' + formId + '" />' +
808			'<input id="sdphone_' + formId + '" tabindex="-1" type="tel" inputmode="tel" placeholder="Enter phone number" autocomplete="tel" style="visibility: hidden; height: 0; margin: 0; padding: 0; overflow: hidden;"/>' +
809			'<input type="hidden" id="phone_e164_' + formId + '" name="phone_e164" />' +
810			'<input type="hidden" id="phone_dial_code_' + formId + '" name="phone_dial_code" />' +
811			'<input type="hidden" id="phone_country_iso2_' + formId + '" name="phone_country_iso2" />' +
812			'<input type="hidden" id="phone_country_name_' + formId + '" name="phone_country_name" />' +
813			'<input type="hidden" id="phone_number_country" name="phone_number_country" data-form-id="' + formId + '" />' +
814		'</div>';
815
816		phoneGroup.appendChild(hiddenCountryBlock);
817		phoneGroup.appendChild(phoneBlock);
818
819		// Insert phone group after checkbox
820		checkboxGroup.parentNode.insertBefore(phoneGroup, checkboxGroup.nextSibling);
821
822		// For subscription section, move the submit button after phone field
823		if (isInSubscriptionSection) {
824			// Use setTimeout to ensure phone group is in DOM first
825			setTimeout(function() {
826				var submitButton = form.querySelector('#schedule_demo, button[name="submit"], button[type="submit"]');
827				if (submitButton && submitButton.closest('.subscription-section')) {
828					// Check if button is already after phone field
829					var phoneGroupAfter = phoneGroup.nextSibling;
830					var isAlreadyAfter = false;
831					while (phoneGroupAfter) {
832						if (phoneGroupAfter.contains && phoneGroupAfter.contains(submitButton)) {
833							isAlreadyAfter = true;
834							break;
835						}
836						phoneGroupAfter = phoneGroupAfter.nextSibling;
837					}
838					
839					if (!isAlreadyAfter && submitButton && submitButton.parentNode) {
840						// Find the button's current parent
841						var buttonParent = submitButton.parentElement;
842						var buttonGroup = buttonParent.closest('.ctrl-group');
843						
844						// If button is in the same flex container as inputs, extract it
845						if (buttonGroup && buttonGroup.style.display === 'flex') {
846							// Remove button from flex container
847							submitButton.parentNode.removeChild(submitButton);
848							
849							// Create a new ctrl-group for the button
850							var newButtonGroup = document.createElement('div');
851							newButtonGroup.className = 'ctrl-group';
852							newButtonGroup.style.cssText = 'width: 100%; margin-top: 15px;';
853							newButtonGroup.appendChild(submitButton);
854							
855							// Insert new button group after phone group
856							if (phoneGroup.parentNode) {
857								phoneGroup.parentNode.insertBefore(newButtonGroup, phoneGroup.nextSibling);
858							} else {
859								form.appendChild(newButtonGroup);
860							}
861						} else if (buttonGroup && buttonGroup !== checkboxGroup && buttonGroup !== phoneGroup) {
862							// Move the entire button group after phone group
863							if (phoneGroup.parentNode) {
864								phoneGroup.parentNode.insertBefore(buttonGroup, phoneGroup.nextSibling);
865							}
866						} else if (submitButton && submitButton.parentNode) {
867							// Create a new ctrl-group for the button
868							var newButtonGroup = document.createElement('div');
869							newButtonGroup.className = 'ctrl-group';
870							newButtonGroup.style.cssText = 'width: 100%; margin-top: 15px;';
871							
872							// Move button to new group
873							submitButton.parentNode.removeChild(submitButton);
874							newButtonGroup.appendChild(submitButton);
875							
876							// Insert new button group after phone group
877							if (phoneGroup.parentNode) {
878								phoneGroup.parentNode.insertBefore(newButtonGroup, phoneGroup.nextSibling);
879							} else {
880								form.appendChild(newButtonGroup);
881							}
882						}
883					}
884				}
885			}, 100);
886		}
887
888		// Create hidden inputs for MQL attribution fields and country (for HubSpot POST)
889		var hiddenFieldsContainer = document.createElement('div');
890		hiddenFieldsContainer.style.cssText = 'display: none;';
891		
892		// Country field (hidden) - unique per form
893		var countryHiddenInput = document.createElement('input');
894		countryHiddenInput.type = 'hidden';
895		countryHiddenInput.name = 'country';
896		countryHiddenInput.id = 'country_hidden_mql_' + formId;
897		countryHiddenInput.value = '';
898		
899		// MQL Attribution fields (hidden) - unique per form
900		var mqlSourceInput = document.createElement('input');
901		mqlSourceInput.type = 'hidden';
902		mqlSourceInput.name = 'mql_attribution_source';
903		mqlSourceInput.id = 'mql_attribution_source_hidden_' + formId;
904		mqlSourceInput.value = '';
905		
906		var mqlMediumInput = document.createElement('input');
907		mqlMediumInput.type = 'hidden';
908		mqlMediumInput.name = 'mql_attribution_medium';
909		mqlMediumInput.id = 'mql_attribution_medium_hidden_' + formId;
910		mqlMediumInput.value = '';
911		
912		var mqlCampaignInput = document.createElement('input');
913		mqlCampaignInput.type = 'hidden';
914		mqlCampaignInput.name = 'mql_attribution_campaign';
915		mqlCampaignInput.id = 'mql_attribution_campaign_hidden_' + formId;
916		mqlCampaignInput.value = '';
917		
918		hiddenFieldsContainer.appendChild(countryHiddenInput);
919		hiddenFieldsContainer.appendChild(mqlSourceInput);
920		hiddenFieldsContainer.appendChild(mqlMediumInput);
921		hiddenFieldsContainer.appendChild(mqlCampaignInput);
922		
923		// Insert hidden fields into form
924		form.appendChild(hiddenFieldsContainer);
925
926		// Initialize phone input handler - using exact same technique as demo form
927		var itiInstance = null;
928		var phoneInput = null;
929		var currentFormId = formId; // Store form ID for this form instance
930		var currentIsCaseStudy = isCaseStudy; // Store page type
931
932		// Function to initialize intlTelInput (exact match from demo form)
933		function initPhoneInput() {
934			// Find phone field - use the form we're enhancing, not just any form
935			// ct-hubspot.js expects #sdphone, but we need to find it in the current form
936			var formToSearch = form; // Use the form we're currently enhancing
937			phoneInput = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
938			if (!phoneInput) {
939				// Fallback: try to find #sdphone in current form
940				phoneInput = formToSearch ? formToSearch.querySelector('#sdphone') : null;
941			}
942			if (!phoneInput) {
943				// Last fallback: try to find by data-form-id
944				phoneInput = formToSearch ? formToSearch.querySelector('[data-form-id="' + currentFormId + '"]') : null;
945			}
946			if (!phoneInput) return;
947			
948			// If already initialized, don't reinitialize
949			if (itiInstance) {
950				// Check if the instance is still valid
951				try {
952					itiInstance.getNumber();
953					return; // Instance is valid, no need to reinitialize
954				} catch(e) {
955					// Instance is broken, destroy and recreate
956					try {
957						itiInstance.destroy();
958					} catch(e2) {}
959					itiInstance = null;
960				}
961			}
962			
963			// Wait for intlTelInput library to be available
964			if (!window.intlTelInput) {
965				// Retry after a short delay
966				setTimeout(initPhoneInput, 200);
967				return;
968			}
969
970			// Make sure phone input is visible before initializing
971			if (phoneInput.offsetParent === null) {
972				// Element is hidden, wait a bit
973				setTimeout(initPhoneInput, 100);
974				return;
975			}
976
977			try {
978				// After uncheck+destroy, a bare .iti wrapper can remain with 
978no valid instance; re-init on that
979				// node breaks the widget. Reuse only when getNumber() works, else unwrap then init fresh.
980				if (phoneInput.closest('.iti')) {
981					var existingIti = phoneInput.intlTelInput || (window.intlTelInput && window.intlTelInput.getInstance && window.intlTelInput.getInstance(phoneInput));
982					var existingOk = false;
983					if (existingIti) {
984						try {
985							existingIti.getNumber();
986							existingOk = true;
987						} catch (ex) {
988							try { existingIti.destroy(); } catch (ex2) {}
989						}
990					}
991					if (existingOk) {
992						itiInstance = existingIti;
993						setupPhoneHandlers();
994						return;
995					}
996					var staleWrap = phoneInput.closest('.iti');
997					if (staleWrap && staleWrap.parentNode) {
998						staleWrap.parentNode.insertBefore(phoneInput, staleWrap);
999						staleWrap.parentNode.removeChild(staleWrap);
1000					}
1001				}
1002
1003				itiInstance = window.intlTelInput(phoneInput, {
1004					initialCountry: 'auto',
1005					separateDialCode: true,
1006					utilsScript: 'https://clevertap.com/wp-content/themes/clevertap2023/js/utils.js?v=20251006',
1007					geoIpLookup: function (cb) {
1008						fetch('https://ipinfo.io/json', { cache: 'no-store' })
1009							.then((r) => r.json())
1010							.then((d) => cb((d && d.country) || 'IN'))
1011							.catch(() => cb('IN'));
1012					}
1013				});
1014
1015				setupPhoneHandlers();
1016			} catch(e) {
1017				console.error('Error initializing intlTelInput:', e);
1018				itiInstance = null;
1019			}
1020		}
1021
1022		// Setup phone field handlers (exact match from demo form)
1023		function setupPhoneHandlers() {
1024			if (!phoneInput || !itiInstance) {
1025				console.warn('setupPhoneHandlers: phoneInput or itiInstance not available');
1026				return;
1027			}
1028			
1029			// Verify itiInstance is still valid
1030			try {
1031				itiInstance.getNumber();
1032			} catch(e) {
1033				console.error('itiInstance is invalid:', e);
1034				itiInstance = null;
1035				return;
1036			}
1037
1038			// ---- grab all fields we may need to touch ----
1039			// Use the form we're currently enhancing, not just any form
1040			var formToSearch = phoneInput.form || form; // Prefer phoneInput's form, fallback to current form
1041			if (!formToSearch) {
1042				formToSearch = document.querySelector('form[data-hubspot-form-id="' + currentFormId + '"]') ||
1043					document.getElementById('ctForm_' + currentFormId);
1044			}
1045			// Find phone_number_country field - ct-hubspot.js looks for #phone_number_country
1046			var hsISD = formToSearch ? formToSearch.querySelector('#phone_number_country') : null;
1047			if (!hsISD) {
1048				// Fallback: try to find by name attribute
1049				hsISD = form ? form.querySelector('input[name="phone_number_country"]') : document.querySelector('input[name="phone_number_country"]');
1050			}
1051			var countryInput = formToSearch ? formToSearch.querySelector('#country') : null;
1052			var countryHidden = formToSearch ? formToSearch.querySelector('.country_hidden') : null;
1053			// Find phone field - ct-hubspot.js expects #sdphone
1054			var visiblePhone = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1055			if (!visiblePhone) {
1056				// Fallback: try to find #sdphone in current form
1057				visiblePhone = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1058			}
1059			if (!visiblePhone) {
1060				// Last fallback: try to find by data-form-id
1061				visiblePhone = formToSearch ? formToSearch.querySelector('[data-form-id="' + currentFormId + '"]') : null;
1062			}
1063			var mirrorPhone = elByIdIn(formToSearch, 'sdphone_' + currentFormId);
1064
1065			function writeAll() {
1066				if (!itiInstance || !phoneInput) {
1067					console.warn('writeAll() skipped - itiInstance or phoneInput not available');
1068					return;
1069				}
1070				
1071				var c, dial, name, e164;
1072				try {
1073					c = itiInstance.getSelectedCountryData() || {};
1074					dial = c.dialCode ? '+' + c.dialCode : '';
1075					name = (c.name || '').replace(/\s*\(.*\)\s*$/, ''); // strip local-language suffix
1076					e164 = itiInstance.getNumber(); // +<code><number>
1077
1078					var rawVis = (phoneInput.value || '').trim();
1079					var natDigits = rawVis.replace(/\D/g, '');
1080					var dcDigits = (c.dialCode || '').replace(/\D/g, '');
1081
1082					if (!e164 && rawVis.indexOf('+') === 0) {
1083						e164 = rawVis.replace(/\s/g, '');
1084					}
1085					if (!e164 && natDigits && dcDigits) {
1086						e164 = '+' + dcDigits + natDigits;
1087					}
1088					if (!e164 && rawVis) {
1089						e164 = rawVis;
1090					}
1091
1092					e164 = (e164 && String(e164).trim()) ? String(e164).trim() : '';
1093				} catch(e) {
1094					console.error('Error in writeAll:', e);
1095					return;
1096				}
1097
1098				// 1) HubSpot property: Phone Number Country -> "+ISD|Country"
1099				if (hsISD) {
1100					var combined = dial && name ? dial + '|' + name : dial || name || '';
1101					hsISD.value = combined;
1102					hsISD.setAttribute('value', combined);
1103				} else {
1104					console.warn('writeAll() - hsISD (phone_number_country) field not found');
1105				}
1106
1107				// 2) Optional: keep readable country elsewhere
1108				if (countryInput) {
1109					countryInput.value = name;
1110					countryInput.setAttribute('value', name);
1111				}
1112				if (countryHidden) countryHidden.value = name;
1113				
1114				// Update hidden country field for MQL submission (with form ID)
1115				var countryHiddenMQL = elByIdIn(form, 'country_hidden_mql_' + currentFormId);
1116				if (countryHiddenMQL) {
1117					countryHiddenMQL.value = name;
1118					countryHiddenMQL.setAttribute('value', name);
1119				}
1120
1121				// 3) With separateDialCode, assigning phoneInput.value = "+91..." corrupts ITI; the next
1122				//    getNumber() is empty and later writeAll() blanks the field. Use setNumber() instead.
1123				//    Never write '' onto the visible field here — that mimics the same failure mode.
1124				if (e164) {
1125					try {
1126						if (typeof itiInstance.setNumber === 'function') {
1127							itiInstance.setNumber(e164);
1128						} else {
1129							phoneInput.value = e164;
1130						}
1131					} catch (eSet) {
1132						try {
1133							phoneInput.value = e164;
1134						} catch (e2) {}
1135					}
1136					phoneInput.setAttribute('value', phoneInput.value || e164);
1137				}
1138
1139				form.querySelectorAll('input[name="phone"]').forEach(function (el) {
1140					if (el === phoneInput) return;
1141					if (el.id === 'sdphone_' + currentFormId) return;
1142					if (e164) {
1143						el.value = e164;
1144						el.setAttribute('value', e164);
1145					}
1146				});
1147
1148				// 4) Fill optional breakout fields if present
1149				var dEl = elByIdIn(form, 'phone_dial_code_' + currentFormId);
1150				var isoEl = elByIdIn(form, 'phone_country_iso2_' + currentFormId);
1151				var nmEl = elByIdIn(form, 'phone_country_name_' + currentFormId);
1152				var eEl = elByIdIn(form, 'phone_e164_' + currentFormId);
1153				if (dEl) {
1154					dEl.value = dial;
1155					dEl.setAttribute('value', dial);
1156				}
1157				if (isoEl) {
1158					isoEl.value = (c.iso2 || '').toUpperCase();
1159					isoEl.setAttribute('value', isoEl.value);
1160				}
1161				if (nmEl) {
1162					nmEl.value = name;
1163					nmEl.setAttribute('value', name);
1164				}
1165				if (eEl && e164) {
1166					eEl.value = e164;
1167					eEl.setAttribute('value', e164);
1168				}
1169			}
1170
1171			// Bind submit/blur/mirror only once per form — re-init after Schedule 1:1 uncheck would stack
1172			// duplicate handlers and destabilize intl-tel-input; only writeAll() needs to run again.
1173			if (form.getAttribute('data-ct-phone-hooks') === '1') {
1174				try {
1175					writeAll();
1176				} catch (eRe) {}
1177				return;
1178			}
1179			form.setAttribute('data-ct-phone-hooks', '1');
1180
1181			if (visiblePhone && mirrorPhone) {
1182				mirrorPhone.removeAttribute('name');
1183				var syncMirror = function () {
1184					mirrorPhone.value = visiblePhone.value;
1185				};
1186				['input', 'change', 'blur'].forEach(function (ev) {
1187					visiblePhone.addEventListener(ev, syncMirror);
1188				});
1189			}
1190
1191			// initial populate + react to country change / blur
1192			try {
1193				writeAll();
1194			} catch(e) {
1195				console.error('Error in initial writeAll:', e);
1196			}
1197			
1198			phoneInput.addEventListener('countrychange', function() {
1199				try {
1200				writeAll();
1201				// Update country hidden field for MQL when country changes
1202				var countryHiddenMQL = elByIdIn(form, 'country_hidden_mql_' + currentFormId);
1203				if (countryHiddenMQL && checkbox && checkbox.checked && itiInstance) {
1204						var c = itiInstance.getSelectedCountryData() || {};
1205						var name = (c.name || '').replace(/\s*\(.*\)\s*$/, '');
1206						if (name) {
1207							countryHiddenMQL.value = name;
1208							countryHiddenMQL.setAttribute('value', name);
1209						}
1210					}
1211				} catch(e) {
1212					console.error('Error in countrychange handler:', e);
1213				}
1214			});
1215			phoneInput.addEventListener('blur', function() {
1216				try {
1217				writeAll();
1218				// Update country hidden field for MQL on blur
1219				var countryHiddenMQL = elByIdIn(form, 'country_hidden_mql_' + currentFormId);
1220				if (countryHiddenMQL && checkbox && checkbox.checked && itiInstance) {
1221						var c = itiInstance.getSelectedCountryData() || {};
1222						var name = (c.name || '').replace(/\s*\(.*\)\s*$/, '');
1223						if (name) {
1224							countryHiddenMQL.value = name;
1225							countryHiddenMQL.setAttribute('value', name);
1226						}
1227					}
1228				} catch(e) {
1229					console.error('Error in blur handler:', e);
1230				}
1231			});
1232
1233			function getResolvedPhoneValue() {
1234				var formToSearch = form;
1235				var currentPhone = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1236				if (!currentPhone) {
1237					currentPhone = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1238				}
1239				if (!currentPhone) {
1240					return '';
1241				}
1242
1243				var currentValue = (currentPhone.value || '').trim();
1244				if (currentValue) {
1245					return currentValue.replace(/\s/g, '');
1246				}
1247
1248				var phoneE164 = elByIdIn(formToSearch, 'phone_e164_' + currentFormId);
1249				if (phoneE164 && phoneE164.value && phoneE164.value.trim()) {
1250					return phoneE164.value.trim();
1251				}
1252				return '';
1253			}
1254
1255			function shouldSetMqlLead() {
1256				return !!(checkbox && checkbox.checked && getResolvedPhoneValue());
1257			}
1258
1259			// before any submission/CTA click, rewrite again (covers AJAX flows)
1260			function beforeSubmit() {
1261				var isChecked = !!(checkbox && checkbox.checked);
1262				var phoneVal = '';
1263				if (itiInstance && phoneInput) {
1264					try {
1265						phoneVal = itiInstance.getNumber() || phoneInput.value || '';
1266					} catch (ePhone) {
1267						phoneVal = phoneInput.value || '';
1268					}
1269				} else if (phoneInput) {
1270					phoneVal = phoneInput.value || '';
1271				}
1272				var hasPhone = !!(phoneVal && String(phoneVal).trim());
1273				var keepPhoneForSubmit = isChecked || hasPhone;
1274				var leadType = (isChecked && hasPhone) ? 'mql' : 'warm';
1275				trackSchedule11Experiment('schedule_1on1_form_submit', {
1276					form_id: currentFormId,
1277					schedule_1on1_checked: isChecked,
1278					has_phone: hasPhone,
1279					lead_type: leadType,
1280					component_name: 'schedule_1on1_checkbox'
1281				});
1282				var keepPhoneForSubmit = isChecked || hasPhone;
1283				// If checkbox is unchecked, ensure phone fields are empty and not required for submission
1284				// This must run FIRST before any validation
1285				if (!keepPhoneForSubmit) {
1286					// Use the current form, not just any form
1287					var formToSearch = form; // Use the form we're currently enhancing
1288					var phoneEl = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1289					if (!phoneEl) {
1290						phoneEl = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1291					}
1292					var sdphoneEl = elByIdIn(formToSearch, 'sdphone_' + currentFormId);
1293					
1294					if (phoneEl) {
1295						// Clear phone value
1296						phoneEl.value = '';
1297						// Remove name attribute so it's not submitted and not val
1297idated
1298						phoneEl.removeAttribute('name');
1299						// Mark as optional
1300						phoneEl.setAttribute('data-optional', 'true');
1301						// Remove required attribute if present
1302						phoneEl.removeAttribute('required');
1303						phoneEl.removeAttribute('aria-required');
1304						// Remove validation error classes and styles
1305						phoneEl.classList.remove('error', 'invalid', 'required', 'errorMsg');
1306						phoneEl.style.border = '';
1307						// DO NOT hide with display:none here - the phoneGroup container is already hidden by togglePhoneField
1308						// Just ensure it's not visible to validation
1309					}
1310					if (sdphoneEl) {
1311						sdphoneEl.value = '';
1312						sdphoneEl.removeAttribute('name');
1313						sdphoneEl.setAttribute('data-optional', 'true');
1314					}
1315					
1316					// Also clear phone_number_country field
1317					var phoneNumberCountry = formToSearch ? formToSearch.querySelector('#phone_number_country') : null;
1318					if (phoneNumberCountry) {
1319						phoneNumberCountry.value = '';
1320						phoneNumberCountry.removeAttribute('name');
1321					}
1322					
1323					// Hide any phone validation error messages
1324					var phoneErrorMsg = formToSearch ? formToSearch.querySelector('.ctFrmErrorMsg[data-id*="phone"], .error-msg-phone, [data-error="phone"]') : null;
1325					if (phoneErrorMsg) {
1326						phoneErrorMsg.style.display = 'none';
1327					}
1328					
1329					// Use jQuery to remove error styling if jQuery is available
1330					if (typeof $ !== 'undefined' && phoneEl) {
1331						$(phoneEl).css('border', '').removeClass('errorMsg');
1332					}
1333				}
1334				
1335				// Only call writeAll() if phone input is initialized (checkbox is checked)
1336				if (itiInstance && phoneInput && checkbox && checkbox.checked) {
1337					try {
1338						// Ensure phone field has name attribute before writing
1339						if (phoneInput && !phoneInput.getAttribute('name')) {
1340							phoneInput.setAttribute('name', 'phone');
1341						}
1342						// Restore display if it was hidden
1343						if (phoneInput.getAttribute('data-original-display')) {
1344							phoneInput.style.display = phoneInput.getAttribute('data-original-display');
1345							phoneInput.removeAttribute('data-original-display');
1346						}
1347						writeAll();
1348					} catch(e) {
1349						console.error('Error in beforeSubmit writeAll:', e);
1350					}
1351				}
1352				
1353				// Ensure country and MQL fields are set before submission if phone is provided.
1354				if (shouldSetMqlLead()) {
1355					// Call writeAll() again to ensure phone and country are set
1356					try {
1357						writeAll();
1358					} catch(e) {
1359						console.error('Error in beforeSubmit writeAll (second call):', e);
1360					}
1361					// Ensure CleverTapDemoForm exists and has correct formId
1362					if (typeof window.CleverTapDemoForm === 'undefined') {
1363						window.CleverTapDemoForm = {
1364							formId: currentFormId,
1365							block_free_email: false,
1366							form_prop: {}
1367						};
1368					}
1369					
1370					// Update formId to match current form
1371					window.CleverTapDemoForm.formId = currentFormId;
1372					
1373					// Ensure form_prop exists
1374					if (!window.CleverTapDemoForm.form_prop) {
1375						window.CleverTapDemoForm.form_prop = {};
1376					}
1377					
1378					// Set MQL properties - MUST be set before submission
1379					// STRICTLY set ct_lead_source to 'MQL' for all forms when checkbox is checked
1380					window.CleverTapDemoForm.form_prop.lifecyclestage = 'marketingqualifiedlead';
1381					window.CleverTapDemoForm.form_prop.ct_lead_source = 'MQL';
1382					
1383					// Force set ct_lead_source to MQL (override any existing value)
1384					Object.defineProperty(window.CleverTapDemoForm.form_prop, 'ct_lead_source', {
1385						value: 'MQL',
1386						writable: true,
1387						configurable: true,
1388						enumerable: true
1389					});
1390					
1391					var countryHiddenMQL = elByIdIn(form, 'country_hidden_mql_' + currentFormId);
1392					if (countryHiddenMQL && itiInstance) {
1393						var c = itiInstance.getSelectedCountryData() || {};
1394						var name = (c.name || '').replace(/\s*\(.*\)\s*$/, '');
1395						if (name) {
1396							countryHiddenMQL.value = name;
1397							countryHiddenMQL.setAttribute('value', name);
1398						}
1399					}
1400					
1401					// Get UTM attribution values
1402					var attribution = getAttributionFromUtm();
1403					
1404					// Ensure MQL attribution fields are set with UTM values
1405					var mqlSourceInput = elByIdIn(form, 'mql_attribution_source_hidden_' + currentFormId);
1406					var mqlMediumInput = elByIdIn(form, 'mql_attribution_medium_hidden_' + currentFormId);
1407					var mqlCampaignInput = elByIdIn(form, 'mql_attribution_campaign_hidden_' + currentFormId);
1408					
1409					if (mqlSourceInput) {
1410						mqlSourceInput.value = attribution.source;
1411						mqlSourceInput.setAttribute('value', attribution.source);
1412					}
1413					if (mqlMediumInput) {
1414						mqlMediumInput.value = attribution.medium;
1415						mqlMediumInput.setAttribute('value', attribution.medium);
1416					}
1417					if (mqlCampaignInput) {
1418						mqlCampaignInput.value = attribution.campaign;
1419						mqlCampaignInput.setAttribute('value', attribution.campaign);
1420					}
1421					
1422					// Update form_prop with UTM values - STRICTLY ensure ct_lead_source is MQL
1423					window.CleverTapDemoForm.form_prop.ct_lead_source = 'MQL';
1424					// Force set to ensure it's not overwritten
1425					Object.defineProperty(window.CleverTapDemoForm.form_prop, 'ct_lead_source', {
1426						value: 'MQL',
1427						writable: true,
1428						configurable: true,
1429						enumerable: true
1430					});
1431					window.CleverTapDemoForm.form_prop.mql_attribution_source = attribution.source;
1432					window.CleverTapDemoForm.form_prop.mql_attribution_medium = attribution.medium;
1433					window.CleverTapDemoForm.form_prop.mql_attribution_campaign = attribution.campaign;
1434					
1435					// For case studies, ensure created_campaign_id is set
1436					if (currentIsCaseStudy && !window.CleverTapDemoForm.form_prop.created_campaign_id) {
1437						window.CleverTapDemoForm.form_prop.created_campaign_id = '701OX00000kHmz3YAC';
1438					}
1439					
1440					console.log('MQL Form Config Before Submit:', {
1441						formId: window.CleverTapDemoForm.formId,
1442						ct_lead_source: window.CleverTapDemoForm.form_prop.ct_lead_source,
1443						lifecyclestage: window.CleverTapDemoForm.form_prop.lifecyclestage,
1444						mql_attribution: {
1445							source: window.CleverTapDemoForm.form_prop.mql_attribution_source,
1446							medium: window.CleverTapDemoForm.form_prop.mql_attribution_medium,
1447							campaign: window.CleverTapDemoForm.form_prop.mql_attribution_campaign
1448						}
1449					});
1450				} else {
1451					// If checkbox is unchecked, ensure MQL properties are removed
1452					if (window.CleverTapDemoForm && window.CleverTapDemoForm.form_prop) {
1453						delete window.CleverTapDemoForm.form_prop.lifecyclestage;
1454						delete window.CleverTapDemoForm.form_prop.mql_attribution_source;
1455						delete window.CleverTapDemoForm.form_prop.mql_attribution_medium;
1456						delete window.CleverTapDemoForm.form_prop.mql_attribution_campaign;
1457						// Restore default ct_lead_source
1458						window.CleverTapDemoForm.form_prop.ct_lead_source = getDefaultLeadSource(currentFormId, currentIsCaseStudy);
1459					}
1460				}
1461			}
1462			form && form.addEventListener('submit', beforeSubmit, true);
1463			// Use form-specific button selector to avoid conflicts with other forms
1464			var formButtons = form.querySelectorAll('button[type="submit"], button[name="submit"], #schedule_demo, .c-btn[type="button"]');
1465			formButtons.forEach(function(btn) {
1466				btn.addEventListener('click', function(e) {
1467					// Check if this button belongs to our form
1468					if (btn.closest('form') === form) {
1469						try {
1470							beforeSubmit();
1471						} catch (err) {
1472							console.error('Schedule 1:1 beforeSubmit failed:', err);
1473						}
1474					}
1475				}, true);
1476			});
1477			
1478		}
1479
1480		// Function to update CleverTapDemoForm config and hidden fields
1481		function updateFormConfig() {
1482			function shouldSetMqlLeadForCurrentForm() {
1483				if (!(checkbox && checkbox.checked)) {
1484					return false;
1485				}
1486				var formToSearch = form;
1487				var phoneInputEl = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1488				if (!phoneInputEl) {
1489					phoneInputEl = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1490				}
1491				var phoneValue = phoneInputEl && phoneInputEl.value ? String(phoneInputEl.value).trim() : '';
1492				if (!phoneValue) {
1493					var phoneE164El = elByIdIn(formToSearch, 'phone_e164_' + currentFormId);
1494					phoneValue = phoneE164El && phoneE164El.value ? String(phoneE164El.value).trim() : '';
1495				}
1496				return !!phoneValue;
1497			}
1498
1499			// Ensure CleverTapDemoForm exists and has correct formId
1500			// Note: If CleverTapDemoForm is already defined (e.g., in page template), use it
1501			// Otherwise, create a new one
1502			if (typeof window.CleverTapDemoForm === 'undefined') {
1503				window.CleverTapDemoForm = {
1504					formId: currentFormId,
1505					block_free_email: false,
1506					form_prop: {}
1507				};
1508			}
1509			
1510			// Update formId to match current form (important for case study pages with dynamic forms)
1511			window.CleverTapDemoForm.formId = currentFormId;
1512
1513			// Ensure form_prop exists (preserve existing values from page template)
1514			if (!window.CleverTapDemoForm.form_prop) {
1515				window.CleverTapDemoForm.form_prop = {};
1516			}
1517			
1518			// Set default ct_lead_source if not already set (preserve if already set in template)
1519			if (!window.CleverTapDemoForm.form_prop.ct_lead_source) {
1520				window.CleverTapDemoForm.form_prop.ct_lead_source = getDefaultLeadSource(currentFormId, currentIsCaseStudy);
1521			}
1522			
1523			// Store original lead source for blog forms to restore when checkbox is unchecked
1524			if (isBlogForm(currentFormId) && !window.CleverTapDemoForm._originalLeadSource) {
1525				window.CleverTapDemoForm._originalLeadSource = window.CleverTapDemoForm.form_prop.ct_lead_source || 'Mkt Asset - blogsub';
1526			}
1527			
1528			// For case studies, set created_campaign_id if not set
1529			if (currentIsCaseStudy && !window.CleverTapDemoForm.form_prop.created_campaign_id) {
1530				window.CleverTapDemoForm.form_prop.created_campaign_id = '701OX00000kHmz3YAC';
1531			}
1532			
1533			// For blog forms, ensure block_free_email is set if not already
1534			if (isBlogForm(currentFormId) && typeof window.CleverTapDemoForm.block_free_email === 'undefined') {
1535				window.CleverTapDemoForm.block_free_email = true;
1536			}
1537
1538			// Get hidden input fields (scoped to this form — same HubSpot id can exist twice on the page)
1539			var countryHiddenMQL = elByIdIn(form, 'country_hidden_mql_' + currentFormId);
1540			var mqlSourceInput = elByIdIn(form, 'mql_attribution_source_hidden_' + currentFormId);
1541			var mqlMediumInput = elByIdIn(form, 'mql_attribution_medium_hidden_' + currentFormId);
1542			var mqlCampaignInput = elByIdIn(form, 'mql_attribution_campaign_hidden_' + currentFormId);
1543
1544			if (shouldSetMqlLeadForCurrentForm()) {
1545				// MQL Configuration - merge with existing props
1546				window.CleverTapDemoForm.form_prop.lifecyclestage = 'marketingqualifiedlead';
1547				
1548				// STRICTLY set ct_lead_source to 'MQL' for all forms (case study and blog)
1549				window.CleverTapDemoForm.form_prop.ct_lead_source = 'MQL';
1550				// Force set to ensure it's not overwritten
1551				Object.defineProperty(window.CleverTapDemoForm.form_prop, 'ct_lead_source', {
1552					value: 'MQL',
1553					writable: true,
1554					configurable: true,
1555					enumerable: true
1556				});
1557				
1558				console.log('Checkbox checked - STRICTLY Setting ct_lead_source to MQL:', window.CleverTapDemoForm.form_prop);
1559				
1560				// Get attribution from UTM parameters
1561				var attribution = getAttributionFromUtm();
1562				
1563				// Use UTM values for MQL attribution (or "direct" if blank)
1564				// Instead of warm lead attribution, use MQL attribution fields
1565				window.CleverTapDemoForm.form_prop.mql_attribution_source = attribution.source;
1566				window.CleverTapDemoForm.form_prop.mql_attribution_medium = attribution.medium;
1567				window.CleverTapDemoForm.form_prop.mql_attribution_campaign = attribution.campaign;
1568				
1569				// Update hidden input fields for POST submission
1570				if (mqlSourceInput) {
1571					mqlSourceInput.value = attribution.source;
1572					mqlSourceInput.setAttribute('value', attribution.source);
1573				}
1574				if (mqlMediumInput) {
1575					mqlMediumInput.value = attribution.medium;
1576					mqlMediumInput.setAttribute('value', attribution.medium);
1577				}
1578				if (mqlCampaignInput) {
1579					mqlCampaignInput.value = attribution.campaign;
1580					mqlCampaignInput.setAttribute('value', attribution.campaign);
1581				}
1582				
1583				// Update country if phone field is already initialized
1584				if (itiInstance && countryHiddenMQL) {
1585					var c = itiInstance.getSelectedCountryData() || {};
1586					var name = (c.name || '').replace(/\s*\(.*\)\s*$/, '');
1587					if (name) {
1588						countryHiddenMQL.value = name;
1589						countryHiddenMQL.setAttribute('value', name);
1590					}
1591				}
1592			} else {
1593				// Warm Lead Configuration - remove MQL properties but keep others
1594				delete window.CleverTapDemoForm.form_prop.lifecyclestage;
1595				delete window.CleverTapDemoForm.form_prop.mql_attribution_source;
1596				delete window.CleverTapDemoForm.form_prop.mql_attribution_medium;
1597				delete window.CleverTapDemoForm.form_prop.mql_attribution_campaign;
1598				
1599				// Restore original ct_lead_source for warm lead
1600				// For blog forms, preserve original "Mkt Asset - blogsub" if it was set, otherwise use default
1601				if (isBlogForm(currentFormId)) {
1602					// Check if original lead source was preserved or use default
1603					var originalLeadSource = window.CleverTapDemoForm._originalLeadSource || 'Mkt Asset - blogsub';
1604					window.CleverTapDemoForm.form_prop.ct_lead_source = originalLeadSource;
1605				} else {
1606					window.CleverTapDemoForm.form_prop.ct_lead_source = getDefaultLeadSource(currentFormId, currentIsCaseStudy);
1607				}
1608				
1609				console.log('Checkbox unchecked - Setting ct_lead_source to warm lead:', window.CleverTapDemoForm.form_prop.ct_lead_source);
1610				
1611				// Clear hidden input fields
1612				if (mqlSourceInput) {
1613					mqlSourceInput.value = '';
1614					mqlSourceInput.removeAttribute('value');
1615				}
1616				if (mqlMediumInput) {
1617					mqlMediumInput.value = '';
1618					mqlMediumInput.removeAttribute('value');
1619				}
1620				if (mqlCampaignInput) {
1621					mqlCampaignInput.value = '';
1622					mqlCampaignInput.removeAttribute('value');
1623				}
1624				if (countryHiddenMQL) {
1625					countryHiddenMQL.value = '';
1626					countryHiddenMQL.removeAttribute('value');
1627				}
1628			}
1629		}
1630
1631		// Toggle phone field visibility
1632		function togglePhoneField() {
1633			if (checkbox.checked) {
1634				phoneGroup.style.display = 'block';
1635				// Restore phone field names for submission
1636				// Use the current form, not just any form
1637				var formToSearch = form; // Use the form we're currently enhancing
1638				var phoneEl = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1639				if (!phoneEl) {
1640					phoneEl = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1641				}
1642				var sdphoneEl = elByIdIn(formToSearch, 'sdphone_' + currentFormId);
1643				if (phoneEl) {
1644					phoneEl.setAttribute('name', 'phone');
1645					phoneEl.removeAttribute('data-optional');
1646				}
1647				if (sdphoneEl) {
1648					// sdphone is a mirror field, keep it without name to avoid duplicate
1649					sdphoneEl.removeAttribute('data-optional');
1650				}
1651				
1652				// For subscription section, ensure button is after phone field
1653				if (isBlogForm(currentFormId) && form && form.closest('.subscription-section')) {
1654					setTimeout(function() {
1655						var submitButton = form.querySelector('#schedule_demo, button[name="submit"], button[type="submit"]');
1656						var phoneGroupEl = phoneGroup;
1657						if (submitButton && phoneGroupEl && phoneGroupEl.style.display !== 'none') {
1658							// Check if button is already after phone field
1659							var isAfterPhone = false;
1660							var nextSibling = phoneGroupEl.nextSibling;
1661							while (nextSibling) {
1662								if (nextSibling.contains && nextSibling.contains(submitButton)) {
1663									isAfterPhone = true;
1664									break;
1665								}
1666								nextSibling = nextSibling.nextSibling;
1667							}
1668							
1669							if (!isAfterPhone && submitButton.parentNode) {
1670								var buttonParent = submitButton.parentElement;
1671								var buttonGroup = buttonParent.closest('.ctrl-group');
1672								
1673								// Extract button from its current location
1674								if (buttonGroup && buttonGroup.style.display === 'flex') {
1675									submitButton.parentNode.removeChild(submitButton);
1676									
1677									// Create new button group if needed
1678									var newButtonGroup = document.createElement('div');
1679									newButtonGroup.className = 'ctrl-group';
1680									newButtonGroup.style.cssText = 'width: 100%; margin-top: 15px;';
1681									newButtonGroup.appendChild(submitButton);
1682									
1683									// Insert after phone group
1684									if (phoneGroupEl.parentNode) {
1685										phoneGroupEl.parentNode.insertBefore(newButtonGroup, phoneGroupEl.nextSibling);
1686									}
1687								} else if (buttonGroup && buttonGroup !== phoneGroupEl) {
1688									// Move entire button group
1689									if (phoneGroupEl.parentNode) {
1690										phoneGroupEl.parentNode.insertBefore(buttonGroup, phoneGroupEl.nextSibling);
1691									}
1692								}
1693							}
1694						}
1695					}, 150);
1696				}
1697				// Initialize phone input when shown - wait a bit for DOM to update
1698				setTimeout(function() {
1699					// Double-check phone field is visible before initializing
1700					// Use the current form, not just any form
1701					var formToSearch = form; // Use the form we're currently enhancing
1702					var phoneEl = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1703					if (!phoneEl) {
1704						phoneEl = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1705					}
1706					if (phoneEl && phoneEl.offsetParent !== null) {
1707						initPhoneInput();
1708						// Re-run tab order enforcement after phone field appears
1709						setTimeout(enforceTabOrder, 100);
1710					} else {
1711						// Retry if not visible yet
1712						setTimeout(function() {
1713							initPhoneInput();
1714							setTimeout(enforceTabOrder, 100);
1715						}, 100);
1716					}
1717				}, 150);
1718			} else {
1719				phoneGroup.style.display = 'none';
1720				// Clear phone values when hidden and make field optional
1721				var formToSearch = form; // Use the form we're currently enhancing
1722				phoneInput = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1723				if (!phoneInput) {
1724					phoneInput = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1725				}
1726				var sdphoneEl = elByIdIn(formToSearch, 'sdphone_' + currentFormId);
1727				
1728				// Properly destroy intlTelInput instance before clearing
1729				if (itiInstance) {
1730					try {
1731						itiInstance.destroy();
1732					} catch(e) {
1733						// Ignore errors during destruction
1734					}
1735					itiInstance = null;
1736				}
1737				
1738				if (phoneInput) {
1739					phoneInput.value = '';
1740					// Remove name attribute so field is not submitted
1741					phoneInput.removeAttribute('name');
1742					// Mark as optional
1743					phoneInput.setAttribute('data-optional', 'true');
1744					// Remove required attributes
1745					phoneInput.removeAttribute('required');
1746					phoneInput.removeAttribute('aria-required');
1747					// Remove validation error classes
1748					phoneInput.classList.remove('error', 'invalid', 'required', 'errorMsg');
1749					// Clear error styling
1750					phoneInput.style.border = '';
1751					// Remove intlTelInput wrapper classes if they exist
1752					var itiWrapper = phoneInput.closest('.iti');
1753					if (itiWrapper) {
1754						// Move phone input out of iti wrapper if needed
1755						var parent = itiWrapper.parentNode;
1756						if (parent) {
1757							parent.insertBefore(phoneInput, itiWrapper);
1758							itiWrapper.remove();
1759						}
1760					}
1761					// Use jQuery to remove error styling if available
1762					if (typeof $ !== 'undefined') {
1763						$(phoneInput).css('border', '').removeClass('errorMsg');
1764					}
1765				}
1766				if (sdphoneEl) {
1767					sdphoneEl.value = '';
1768					sdphoneEl.removeAttribute('name');
1769					sdphoneEl.setAttribute('data-optional', 'true');
1770				}
1771				
1772				// Hide any phone validation error messages
1773				var phoneErrorMsg = formToSearch ? formToSearch.querySelector('.ctFrmErrorMsg[data-id*="phone"], .error-msg-phone, [data-error="phone"]') : null;
1774				if (phoneErrorMsg) {
1775					phoneErrorMsg.style.display = 'none';
1776				}
1777				['phone_e164', 'phone_dial_code', 'phone_country_iso2', 'phone_country_name', 'phone_number_country'].forEach(function(id) {
1778					var el = elByIdIn(form, id + '_' + currentFormId);
1779					if (el) {
1780						el.value = '';
1781					}
1782				});
1783			}
1784		}
1785		
1786		// Override phone validation to skip when field is hidden
1787		function overridePhoneValidation() {
1788			// Intercept form submission to handle phone validation when checkbox is unchecked
1789			// Try multiple button selectors
1790			var scheduleDemoBtn = form.querySelector('#schedule_demo') || 
1791			                      form.querySelector('button[type="submit"]') ||
1792			                      form.querySelector('button[name="submit"]') ||
1793			                      form.querySelector('.c-btn[type="button"]');
1794			
1795			if (scheduleDemoBtn) {
1796				// Add click handler that runs before validation (capture phase)
1797				var clickHandler = function(e) {
1798					// Before validation runs, check if phone field should be validated
1799					if (!checkbox.checked) {
1800						// Phone field is hidden, make it optional and remove validation requirements
1801						var formToSearch = form; // Use the form we're currently enhancing
1802						var phoneEl = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1803						if (!phoneEl) {
1804							phoneEl = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1805						}
1806						var sdphoneEl = elByIdIn(formToSearch, 'sdphone_' + currentFormId);
1807						
1808						// Make phone field optional by removing name and required attributes
1809						if (phoneEl) {
1810							phoneEl.value = '';
1811							phoneEl.removeAttribute('data-temp-value');
1812							phoneEl.removeAttribute('name');
1813							phoneEl.setAttribute('data-optional', 'true');
1814							phoneEl.removeAttribute('required');
1815							phoneEl.removeAttribute('aria-required');
1816							phoneEl.classList.remove('error', 'invalid', 'required', 'errorMsg');
1817							phoneEl.style.border = '';
1818							if (typeof $ !== 'undefined') {
1819								$(phoneEl).css('border', '').removeClass('errorMsg');
1820							}
1821						}
1822						if (sdphoneEl) {
1823							sdphoneEl.removeAttribute('name');
1824							sdphoneEl.setAttribute('data-optional', 'true');
1825							sdphoneEl.value = '';
1826						}
1827						
1828						// Hide any phone validation error messages
1829						var phoneErrorMsg = formToSearch ? formToSearch.querySelector('.ctFrmErrorMsg[data-id*="phone"], .error-msg-phone, [data-error="phone"]') : null;
1830						if (phoneErrorMsg) {
1831							phoneErrorMsg.style.display = 'none';
1832						}
1833					} else {
1834						// Checkbox is checked, ensure phone field is required and visible
1835						var formToSearch = form;
1836						var phoneEl = formToSearch ? formToSearch.querySelector('#sdphone[data-form-id="' + currentFormId + '"]') : null;
1837						if (!phoneEl) {
1838							phoneEl = formToSearch ? formToSearch.querySelector('#sdphone') : null;
1839						}
1840						if (phoneEl) {
1841							phoneEl.setAttribute('name', 'phone');
1842							phoneEl.removeAttribute('data-optional');
1843							// Restore visibility
1844							phoneEl.style.visibility = '';
1845							phoneEl.style.position = '';
1846							phoneEl.style.width = '';
1847							phoneEl.style.height = '';
1848							phoneEl.style.opacity = '';
1849							// Clear temporary value if set
1850							if (phoneEl.getAttribute('data-temp-value') === 'true' && phoneEl.value === 'OPTIONAL_FIELD') {
1851								phoneEl.value = '';
1852								phoneEl.removeAttribute('data-temp-value');
1853							}
1854						}
1855					}
1856				};
1857				// Add our handler with capture phase to run before other handlers
1858				scheduleDemoBtn.addEventListener('click', clickHandler, true);
1859			}
1860		}
1861
1862		// Tab order enforcement (from demo form)
1863		function enforceTabOrder() {
1864			if (!form) return;
1865
1866			var fullName = form.querySelector('#sdfirstname');
1867			var workEmail = form.querySelector('#sdemail');
1868			var phoneInputEl = form.querySelector('#sdphone');
1869			if (!phoneInputEl) {
1870				phoneInputEl = elByIdIn(form, 'sdphone_' + currentFormId);
1871			}
1872			var submitBtn = form.querySelector('#schedule_demo') || 
1873			                form.querySelector('button[type="submit"]') ||
1874			                form.querySelector('button[name="submit"]');
1875
1876			var selectedFlag = null;
1877			if (phoneInputEl) {
1878				var itiWrap = phoneInputEl.closest('.iti');
1879				if (itiWrap) selectedFlag = itiWrap.querySelector('.iti__selected-flag');
1880			}
1881
1882			if (fullName) fullName.tabIndex = 1;
1883			if (workEmail) workEmail.tabIndex = 2;
1884			if (checkbox) checkbox.tabIndex = 3;
1885			if (selectedFlag) selectedFlag.tabIndex = 4;
1886			if (phoneInputEl) phoneInputEl.tabIndex = 5;
1887			if (submitBtn) submitBtn.tabIndex = 6;
1888
1889			var allowed = new Set(
1890				[fullName, workEmail, checkbox, selectedFlag, phoneInputEl, submitBtn].filter(
1890Boolean)
1891			);
1892			form.querySelectorAll('a[href], button, input, select, textarea').forEach(function (el) {
1893				if (allowed.has(el)) return;
1894				el.tabIndex = -1;
1895				el.setAttribute('aria-hidden', 'true');
1896			});
1897
1898			[
1899				'#consent_checkbox',
1900				'button[name="close-modal"]',
1901				'#sdphone_' + currentFormId,
1902				'#country',
1903				'.country_hidden',
1904				'#phone_e164_' + currentFormId,
1905				'#phone_dial_code_' + currentFormId,
1906				'#phone_country_iso2_' + currentFormId,
1907				'#phone_country_name_' + currentFormId,
1908				'#phone_number_country_' + currentFormId
1909			].forEach(function (sel) {
1910				var el = form.querySelector(sel);
1911				if (el) {
1912					el.tabIndex = -1;
1913					el.setAttribute('aria-hidden', 'true');
1914				}
1915			});
1916
1917			if (selectedFlag) {
1918				var flagContainer = selectedFlag.parentNode;
1919				var list = flagContainer && flagContainer.querySelector('.iti__country-list');
1920				if (list) {
1921					list.querySelectorAll('[tabindex], li, a, input, button').forEach(function (el) {
1922						el.tabIndex = -1;
1923						el.setAttribute('aria-hidden', 'true');
1924					});
1925				}
1926			}
1927		}
1928
1929		// Schedule tab order enforcement
1930		function scheduleEnforce() {
1931			enforceTabOrder();
1932			setTimeout(enforceTabOrder, 0);
1933			setTimeout(enforceTabOrder, 50);
1934			setTimeout(enforceTabOrder, 200);
1935		}
1936
1937		// Add event listeners
1938		checkbox.addEventListener('change', function() {
1939			try {
1940				trackSchedule11Experiment('schedule_1on1_toggle', {
1941					form_id: currentFormId,
1942					schedule_1on1_checked: checkbox.checked,
1943					component_name: 'schedule_1on1_checkbox'
1944				});
1945				togglePhoneField();
1946				updateFormConfig();
1947			} catch (err) {
1948				console.error('Schedule 1:1 toggle handler failed:', err);
1949			}
1950		});
1951
1952		// Initialize
1953		try {
1954			updateFormConfig();
1955		} catch (err) {
1956			console.error('Schedule 1:1 init updateFormConfig failed:', err);
1957		}
1958		try {
1959			togglePhoneField(); // Set initial state
1960		} catch (err) {
1961			console.error('Schedule 1:1 init togglePhoneField failed:', err);
1962		}
1963		try {
1964			overridePhoneValidation(); // Override validation for hidden phone field
1965		} catch (err) {
1966			console.error('Schedule 1:1 init overridePhoneValidation failed:', err);
1967		}
1968		
1969		// Set up tab order enforcement
1970		if (document.readyState === 'loading') {
1971			document.addEventListener('DOMContentLoaded', scheduleEnforce);
1972		} else {
1973			scheduleEnforce();
1974		}
1975
1976		// Watch for form changes and re-enforce tab order
1977		if (form) {
1978			new MutationObserver(scheduleEnforce).observe(form, { childList: true, subtree: true });
1979		}
1980		document.addEventListener('countrychange', scheduleEnforce, true);
1981	}
1982
1983	// Ensure intlTelInput library is loaded
1984	function ensureIntlTelInputLibrary() {
1985		if (window.intlTelInput) return;
1986		
1987		// Check if script is already in DOM
1988		var existingScript = document.querySelector('script[src*="intlTelInput.min.js"]');
1989		if (existingScript) {
1990			// Script exists, wait for it to load
1991			var checkInterval = setInterval(function() {
1992				if (window.intlTelInput) {
1993					clearInterval(checkInterval);
1994				}
1995			}, 100);
1996			// Stop checking after 5 seconds
1997			setTimeout(function() { clearInterval(checkInterval); }, 5000);
1998			return;
1999		}
2000
2001		// Load the library
2002		var script = document.createElement('script');
2003		script.src = 'https://clevertap.com/wp-content/themes/clevertap2023/js/intlTelInput.min.js?v=20251006';
2004		script.onload = function() {
2005			// Also load utils if needed
2006			if (!document.querySelector('script[src*="utils.js"]')) {
2007				var utilsScript = document.createElement('script');
2008				utilsScript.src = 'https://clevertap.com/wp-content/themes/clevertap2023/js/utils.js?v=20251006';
2009				document.body.appendChild(utilsScript);
2010			}
2011		};
2012		document.body.appendChild(script);
2013	}
2014
2015	// Initialize when DOM is ready
2016	if (document.readyState === 'loading') {
2017		document.addEventListener('DOMContentLoaded', function() {
2018			ensureIntlTelInputLibrary();
2019			initFormEnhancement();
2020		});
2021	} else {
2022		ensureIntlTelInputLibrary();
2023		initFormEnhancement();
2024	}
2025
2026	// Also try after delays in case form loads dynamically
2027	setTimeout(function() {
2028		ensureIntlTelInputLibrary();
2029		initFormEnhancement();
2030	}, 500);
2031	setTimeout(function() {
2032		ensureIntlTelInputLibrary();
2033		initFormEnhancement();
2034	}, 1500);
2035	setTimeout(function() {
2036		ensureIntlTelInputLibrary();
2037		initFormEnhancement();
2038	}, 3000);
2039	
2040	// For case study pages, also check when window loads completely
2041	window.addEventListener('load', function() {
2042		if (isCaseStudyPage()) {
2043			setTimeout(function() {
2044				ensureIntlTelInputLibrary();
2045				initFormEnhancement();
2046			}, 500);
2047		}
2048	});
2049})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.