/* ═══════════════════════════════════════════════════════════════
   BWPWS — Reusable Signup Form Widget
   One canonical source for the Clean Yard / Pro / Flex conversational
   form. Works two ways from any page:

   1) INLINE — add <div id="bwpws-form-mount"></div> anywhere on a page,
      then include this script anywhere after it:
      <script src="https://YOUR-HOST/bwpws-form-widget.js"></script>
      The form mounts automatically into that div on page load.

   2) POPUP — no mount div needed. From any button, call:
      <button onclick="BWPWSForm.openModal()">Get a Free Cleaning</button>
      (plus the same <script src="..."> tag once on the page)

   Do not include both an inline mount AND open the modal on the same
   page load — this widget uses fixed element IDs internally (cfZipInput,
   cfPhoneInput, etc.), so only one active instance per page is supported
   at a time. If you need both inline and popup on the same page, use the
   popup only and skip the mount div, or vice versa.
   ═══════════════════════════════════════════════════════════════ */

(function () {
  var CSS_TEXT = '    @import url(\'https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800&display=swap\');\n    .form-card { max-width: 480px; margin: 0 auto; background: #FFFFFF; border: 2px solid #E5E7EB; border-radius: 16px; padding: 28px 32px 32px; box-shadow: 0 16px 40px rgba(13, 8, 33, 0.10); overflow: hidden; opacity: 0; animation: bwpwsCardIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.1s forwards; }\n    @keyframes bwpwsCardIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }\n    @media (max-width: 480px) { .form-card { padding: 20px 16px 24px; } }\n    .form-card { --purple-dark: #231747; --purple-main: #5C2CDC; --teal: #7BCADC; --black: #0D0D0D; --gray: #6B7280; --light-gray: #F3F4F6; --border: #E5E7EB; --white: #FFFFFF; }\n    .cf-progress-track { display: flex; gap: 6px; margin-bottom: 32px; }\n    .cf-progress-seg { flex: 1; height: 4px; border-radius: 2px; background: var(--light-gray); overflow: hidden; }\n    .cf-progress-seg .cf-fill { height: 100%; width: 0%; background: var(--purple-main); transition: width 0.4s cubic-bezier(0.65, 0, 0.35, 1); }\n\n    .cf-step-wrap { min-height: 300px; display: flex; flex-direction: column; justify-content: center; }\n    .cf-step { display: none; animation: cfRise 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); }\n    .cf-step.active { display: block; }\n    @keyframes cfRise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }\n\n    .cf-eyebrow {\n      font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;\n      color: var(--purple-main); margin-bottom: 10px;\n    }\n    .cf-prompt {\n      font-family: \'Outfit\', sans-serif;\n      font-size: 22px; font-weight: 800; line-height: 1.3; color: var(--black);\n      margin-bottom: 22px; letter-spacing: -0.01em;\n    }\n    .cf-prompt .cf-name-fill { color: var(--purple-main); }\n\n    .cf-step input[type="text"], .cf-step input[type="tel"], .cf-step input[type="email"] {\n      width: 100%; font-family: \'Outfit\', sans-serif; font-weight: 500;\n      padding: 14px 16px; border: 1.5px solid var(--border); border-radius: 10px;\n      color: var(--black); background: var(--white); outline: none;\n      transition: border-color 0.2s ease, box-shadow 0.2s ease;\n    }\n    .cf-step input:focus { border-color: var(--purple-main); box-shadow: 0 0 0 4px rgba(92, 44, 220, 0.12); }\n    .cf-step input::placeholder { color: #9CA3AF; }\n    .cf-step input[readonly] {\n      background: var(--light-gray); color: var(--gray); cursor: default;\n      border-color: var(--border);\n    }\n    .cf-step input[readonly]:focus { box-shadow: none; border-color: var(--border); }\n\n    .cf-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }\n    .cf-field-group { margin-bottom: 14px; }\n\n    .cf-zip-status { font-size: 13px; font-weight: 600; margin-top: 10px; display: none; padding: 10px 14px; border-radius: 8px; }\n    .cf-zip-status.checking { display: block; color: var(--gray); background: var(--light-gray); }\n    .cf-zip-status.ok { display: block; color: #15803D; background: #DCFCE7; }\n\n    .cf-options { display: flex; flex-direction: column; gap: 10px; }\n    .cf-option-btn {\n      text-align: left; font-family: \'Outfit\', sans-serif; font-size: 15px; font-weight: 600; color: var(--black);\n      background: var(--white); border: 1.5px solid var(--border); border-radius: 10px; padding: 14px 16px;\n      cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;\n    }\n    .cf-option-btn:hover { border-color: var(--purple-main); background: #F9F6FF; }\n    .cf-option-btn:active { transform: scale(0.99); }\n    .cf-option-btn.selected { border-color: var(--purple-main); background: #F0EBFF; }\n\n    .cf-nav-row { display: flex; justify-content: space-between; align-items: center; margin-top: 24px; }\n    .cf-btn-primary {\n      font-family: \'Outfit\', sans-serif; font-size: 15px; font-weight: 700; color: white;\n      background: var(--purple-main); border: none; border-radius: 100px; padding: 13px 26px; cursor: pointer;\n      transition: background 0.15s ease, transform 0.1s ease;\n    }\n    .cf-btn-primary:hover { background: #4a22b0; }\n    .cf-btn-primary:disabled { background: #9CA3AF; cursor: not-allowed; }\n    .cf-btn-back { background: none; border: none; font-size: 13px; font-weight: 600; color: var(--gray); cursor: pointer; padding: 8px; text-decoration: underline; }\n    .cf-btn-back:hover { color: var(--black); }\n    .cf-btn-back.hidden { visibility: hidden; }\n\n    .cf-results { display: none; }\n    .cf-results.active { display: block; animation: cfRise 0.45s cubic-bezier(0.2, 0.8, 0.2, 1); }\n    .cf-results-eyebrow {\n      font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--teal);\n      background: var(--purple-dark); display: inline-block; padding: 5px 12px; border-radius: 20px; margin-bottom: 14px;\n    }\n    .cf-results-headline { font-family: \'Outfit\', sans-serif; font-size: 20px; font-weight: 800; color: var(--black); line-height: 1.35; margin-bottom: 24px; }\n\n    .cf-plan-card { border: 1.5px solid var(--border); border-radius: 14px; padding: 18px; margin-bottom: 12px; position: relative; }\n    .cf-plan-card.recommended { border-color: var(--purple-main); background: linear-gradient(180deg, #F9F6FF 0%, #FFFFFF 100%); }\n    .cf-badge { position: absolute; top: -11px; left: 18px; background: var(--purple-main); color: #fff; font-size: 11px; font-weight: 700; padding: 4px 11px; border-radius: 20px; }\n    .cf-plan-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 4px; }\n    .cf-plan-name { font-size: 17px; font-weight: 800; color: var(--black); }\n    .cf-plan-price { font-size: 20px; font-weight: 800; color: var(--purple-main); }\n    .cf-plan-price span { font-size: 12px; font-weight: 500; color: var(--gray); }\n    .cf-plan-desc { font-size: 13px; color: var(--gray); margin-bottom: 12px; line-height: 1.5; }\n    .cf-plan-features { list-style: none; font-size: 13px; color: var(--black); }\n    .cf-plan-features li { padding: 3px 0 3px 20px; position: relative; }\n    .cf-plan-features li::before { content: "✓"; position: absolute; left: 0; color: #16A34A; font-weight: 700; }\n\n    .cf-toggle-row { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); }\n    .cf-toggle-label { font-size: 13px; font-weight: 600; color: var(--black); }\n    .cf-toggle-label small { display: block; color: var(--gray); font-weight: 400; margin-top: 2px; }\n    .cf-addon-reason { font-size: 12px; color: var(--gray); font-style: italic; margin-top: 10px; line-height: 1.4; }\n\n    .cf-flex-toggle {\n      display: block; width: 100%; text-align: center; background: none; border: none; cursor: pointer;\n      font-family: \'Outfit\', sans-serif; font-size: 13px; font-weight: 700; color: var(--purple-main);\n      padding: 10px 0; margin: -2px 0 4px;\n    }\n    .cf-flex-toggle:hover { color: var(--purple-dark); }\n    .cf-flex-card { display: none; }\n    .cf-flex-card.expanded { display: block; }\n    .cf-flex-choose { width: 100%; margin-top: 14px; padding: 12px 20px; font-size: 14px; }\n    .cf-flex-card.selected { border-color: var(--purple-main); background: linear-gradient(180deg, #F9F6FF 0%, #FFFFFF 100%); }\n\n    .cf-bracket-table { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); }\n    .cf-bracket-label { font-size: 12px; color: var(--gray); font-weight: 600; margin-bottom: 6px; }\n    .cf-bracket-row { display: flex; justify-content: space-between; font-size: 13px; color: var(--black); padding: 3px 0; }\n    .cf-bracket-row span:last-child { font-weight: 700; color: var(--purple-main); }\n    .cf-switch { position: relative; width: 42px; height: 24px; flex-shrink: 0; margin-left: 12px; }\n    .cf-switch input { opacity: 0; width: 0; height: 0; }\n    .cf-slider { position: absolute; inset: 0; background: var(--border); border-radius: 20px; cursor: pointer; transition: background 0.2s ease; }\n    .cf-slider::before { content: ""; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: transform 0.2s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.25); }\n    .cf-switch input:checked + .cf-slider { background: var(--purple-main); }\n    .cf-switch input:checked + .cf-slider::before { transform: translateX(18px); }\n\n    .cf-consent-box { display: flex; align-items: flex-start; gap: 10px; background: var(--light-gray); border-radius: 10px; padding: 12px 14px; margin-top: 16px; cursor: pointer; user-select: none; }\n    .cf-consent-box input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }\n    .cf-custom-check { width: 20px; height: 20px; min-width: 20px; border: 2px solid #9CA3AF; border-radius: 5px; background: white; display: flex; align-items: center; justify-content: center; margin-top: 1px; flex-shrink: 0; transition: background 0.15s, border-color 0.15s; }\n    .cf-custom-check svg { display: none; width: 12px; height: 12px; }\n    .cf-consent-box.checked .cf-custom-check { background: var(--purple-main); border-color: var(--purple-main); }\n    .cf-consent-box.checked .cf-custom-check svg { display: block; }\n    .cf-consent-text { font-size: 12px; color: var(--gray); line-height: 1.55; font-weight: 500; }\n    .cf-consent-text strong { color: var(--black); }\n    .cf-field-error { color: #EF4444; font-size: 12px; font-weight: 600; margin-top: 6px; display: none; }\n    .cf-field-error.visible { display: block; }\n\n    .cf-cta-final { width: 100%; margin-top: 18px; padding: 16px 24px; font-size: 16px; }\n    .cf-cta-final:disabled { background: #9CA3AF; cursor: not-allowed; }\n    .cf-fine-print { text-align: center; font-size: 12px; color: #9CA3AF; margin-top: 10px; }\n\n    .cf-billing-toggle { display: flex; gap: 8px; background: var(--light-gray); border-radius: 12px; padding: 4px; margin-bottom: 18px; }\n    .cf-billing-option {\n      flex: 1; text-align: center; font-family: \'Outfit\', sans-serif; font-size: 13px; font-weight: 700;\n      color: var(--gray); background: transparent; border: none; border-radius: 9px; padding: 10px 8px; cursor: pointer;\n      transition: background 0.15s ease, color 0.15s ease;\n    }\n    .cf-billing-option.selected { background: var(--white); color: var(--purple-main); box-shadow: 0 1px 4px rgba(0,0,0,0.08); }\n    .cf-billing-note { font-size: 13px; color: var(--gray); font-weight: 500; text-align: center; margin: -8px 0 14px; line-height: 1.5; }\n    .cf-billing-note strong { color: var(--purple-main); }\n\n    .cf-guarantee-badge {\n      display: flex; align-items: flex-start; gap: 10px; background: #F0FBF9; border: 1.5px solid #B7E4DC;\n      border-radius: 12px; padding: 14px 16px; margin: 4px 0 14px;\n    }\n    .cf-guarantee-icon { font-size: 18px; line-height: 1; margin-top: 1px; }\n    .cf-guarantee-text { font-size: 13px; color: #0D6E5C; line-height: 1.5; font-weight: 500; }\n    .cf-guarantee-text strong { color: #075C4C; }\n\n    .cf-waitlist, .cf-thankyou { display: none; text-align: center; padding: 12px 0 4px; }\n    .cf-account-setup { display: none; }\n    .cf-account-setup.active { display: block; animation: cfRise 0.45s cubic-bezier(0.2, 0.8, 0.2, 1); }\n    .cf-account-setup input[type="email"] {\n      width: 100%; font-family: \'Outfit\', sans-serif; font-weight: 500; padding: 14px 16px;\n      border: 1.5px solid var(--border); border-radius: 10px; color: var(--black); background: var(--white);\n      outline: none; transition: border-color 0.2s ease, box-shadow 0.2s ease; margin-bottom: 4px;\n    }\n    .cf-account-setup input[type="email"]:focus { border-color: var(--purple-main); box-shadow: 0 0 0 4px rgba(92, 44, 220, 0.12); }\n    .cf-account-setup input[type="email"]::placeholder { color: #9CA3AF; }\n    .cf-waitlist.active, .cf-thankyou.active { display: block; animation: cfRise 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); }\n    .cf-waitlist-icon { font-size: 30px; margin-bottom: 14px; }\n    .cf-waitlist-body { font-size: 14px; color: var(--gray); line-height: 1.6; margin-bottom: 20px; }\n    .cf-waitlist-back { display: flex; justify-content: flex-start; margin-bottom: 4px; }\n\n    @media (max-width: 420px) { .cf-field-row { grid-template-columns: 1fr; gap: 12px; } }\n    @media (prefers-reduced-motion: reduce) { .cf-step, .cf-results, .cf-waitlist, .cf-thankyou, .cf-account-setup { animation: none; } }\n';
  var HTML_TEXT = '      <div class="form-card" id="form-card">\n\n        <div class="cf-progress-track" id="cfProgressTrack"></div>\n\n        <div class="cf-step-wrap" id="cfStepWrap">\n\n          <!-- Step 1: Zip -->\n          <div class="cf-step active" data-step="1">\n            <div class="cf-eyebrow">Let\'s start here</div>\n            <div class="cf-prompt">What\'s your zip code?</div>\n            <input type="text" id="cfZipInput" placeholder="35406" inputmode="numeric" maxlength="5" autocomplete="postal-code">\n            <div class="cf-zip-status" id="cfZipStatus"></div>\n          </div>\n\n          <!-- Step 2: Name -->\n          <div class="cf-step" data-step="2">\n            <div class="cf-eyebrow">Let\'s get started</div>\n            <div class="cf-prompt">First things first — what\'s your name?</div>\n            <div class="cf-field-row">\n              <div><input type="text" id="cfFirstNameInput" placeholder="First name" autocomplete="given-name"></div>\n              <div><input type="text" id="cfLastNameInput" placeholder="Last name" autocomplete="family-name"></div>\n            </div>\n          </div>\n\n          <!-- Step 3: Phone -->\n          <div class="cf-step" data-step="3">\n            <div class="cf-eyebrow">Nice to meet you</div>\n            <div class="cf-prompt"><span class="cf-name-fill" id="cfNamePhoneFill">Hey there</span> — what\'s the best number to reach you at?</div>\n            <input type="tel" id="cfPhoneInput" placeholder="(205) 555-0123" inputmode="tel" autocomplete="tel">\n          </div>\n\n          <!-- Step 4: Usage -->\n          <div class="cf-step" data-step="4">\n            <div class="cf-eyebrow">Getting a feel for your yard</div>\n            <div class="cf-prompt">How often is your yard actually being used?</div>\n            <div class="cf-options" data-question="usage">\n              <button class="cf-option-btn" data-value="constant">Dogs are out there constantly</button>\n              <button class="cf-option-btn" data-value="frequent">A few times a day</button>\n              <button class="cf-option-btn" data-value="occasional">Occasional use</button>\n            </div>\n          </div>\n\n          <!-- Step 5: Dogs -->\n          <div class="cf-step" data-step="5">\n            <div class="cf-eyebrow">Almost there</div>\n            <div class="cf-prompt">How many pups are we cleaning up after?</div>\n            <div class="cf-options" data-question="dogs">\n              <button class="cf-option-btn" data-value="1">1 dog</button>\n              <button class="cf-option-btn" data-value="2">2 dogs</button>\n              <button class="cf-option-btn" data-value="3plus">3 or more</button>\n            </div>\n          </div>\n\n          <!-- Step 6: Odor -->\n          <div class="cf-step" data-step="6">\n            <div class="cf-eyebrow">Real talk</div>\n            <div class="cf-prompt">Is the smell ever an issue — especially with guests over or windows open?</div>\n            <div class="cf-options" data-question="odor">\n              <button class="cf-option-btn" data-value="bad">Yeah, it gets bad</button>\n              <button class="cf-option-btn" data-value="sometimes">Sometimes</button>\n              <button class="cf-option-btn" data-value="notreally">Not really</button>\n            </div>\n          </div>\n\n          <!-- Step 7: Address + City + Zip (passed through, read-only) -->\n          <div class="cf-step" data-step="7">\n            <div class="cf-eyebrow">Last thing</div>\n            <div class="cf-prompt">Where do we send the crew?</div>\n            <div class="cf-field-group"><input type="text" id="cfAddressInput" placeholder="Street address" autocomplete="street-address"></div>\n            <div class="cf-field-row">\n              <div><input type="text" id="cfCityInput" placeholder="City" autocomplete="address-level2"></div>\n              <div><input type="text" id="cfZipDisplay" readonly tabindex="-1"></div>\n            </div>\n          </div>\n\n          <div class="cf-nav-row" id="cfNavRow">\n            <button class="cf-btn-back hidden" id="cfBackBtn">← Back</button>\n            <button class="cf-btn-primary" id="cfNextBtn" disabled>Continue</button>\n          </div>\n\n        </div><!-- /cf-step-wrap -->\n\n        <!-- Results -->\n        <div class="cf-results" id="cfResults">\n          <div class="cf-results-eyebrow">Your recommendation</div>\n          <div class="cf-results-headline" id="cfResultsHeadline">Based on what you told us, here\'s what we\'d recommend:</div>\n\n          <div class="cf-billing-toggle" id="cfBillingToggle">\n            <button class="cf-billing-option selected" data-mode="monthly">Monthly</button>\n            <button class="cf-billing-option" data-mode="per_visit">Pay Per Visit</button>\n          </div>\n          <div class="cf-billing-note" id="cfBillingNote"></div>\n\n          <div class="cf-plan-card" id="cfCardClean">\n            <div class="cf-plan-top">\n              <div class="cf-plan-name" id="cfCleanName">Clean Yard</div>\n              <div class="cf-plan-price" id="cfPriceClean">$89<span>/mo</span></div>\n            </div>\n            <div class="cf-plan-desc" id="cfCleanDesc">Weekly visits — your yard stays guest-ready, all week long.</div>\n            <ul class="cf-plan-features" id="cfCleanFeatures">\n              <li>1x per week service</li>\n              <li>Full yard waste removal</li>\n              <li>Gate check & yard reset</li>\n            </ul>\n            <div class="cf-toggle-row">\n              <div class="cf-toggle-label">Add Fresh Guard deodorizer<small id="cfCleanAddonLabel">+$20/mo — applied every visit</small></div>\n              <label class="cf-switch"><input type="checkbox" id="cfToggleClean"><span class="cf-slider"></span></label>\n            </div>\n            <div class="cf-addon-reason">Applied fresh every visit — odor builds back fast, especially in Alabama heat.</div>\n          </div>\n\n          <div class="cf-plan-card" id="cfCardPro">\n            <div class="cf-plan-top">\n              <div class="cf-plan-name">Clean Yard Pro</div>\n              <div class="cf-plan-price" id="cfPricePro">$159<span>/mo</span></div>\n            </div>\n            <div class="cf-plan-desc" id="cfProDesc">Built for yards where waste piles up fast — multiple dogs or heavy daily use.</div>\n            <ul class="cf-plan-features">\n              <li>2x per week service</li>\n              <li>Full yard waste removal</li>\n              <li>Gate check & yard reset</li>\n              <li>Priority scheduling</li>\n            </ul>\n            <div class="cf-toggle-row">\n              <div class="cf-toggle-label">Add Fresh Guard deodorizer<small id="cfProAddonLabel">+$40/mo — applied every visit</small></div>\n              <label class="cf-switch"><input type="checkbox" id="cfTogglePro"><span class="cf-slider"></span></label>\n            </div>\n          </div>\n\n          <button class="cf-flex-toggle" id="cfFlexToggle" type="button">Need a custom schedule instead? <span id="cfFlexToggleArrow">↓</span></button>\n\n          <div class="cf-plan-card cf-flex-card" id="cfCardFlex">\n            <div class="cf-plan-top">\n              <div class="cf-plan-name">Clean Yard Flex</div>\n              <div class="cf-plan-price" id="cfPriceFlex">$75<span>/first visit</span></div>\n            </div>\n            <div class="cf-plan-desc">Pay only for the visits you need — no monthly plan, schedule as it works for you.</div>\n            <ul class="cf-plan-features">\n              <li>Pay per visit — no monthly commitment</li>\n              <li>Full yard waste removal</li>\n              <li>Gate check & yard reset</li>\n            </ul>\n            <div class="cf-toggle-row">\n              <div class="cf-toggle-label">Add Fresh Guard deodorizer<small id="cfFlexAddonLabel">+$7/visit — added when applied</small></div>\n              <label class="cf-switch"><input type="checkbox" id="cfToggleFlex"><span class="cf-slider"></span></label>\n            </div>\n            <div class="cf-bracket-table">\n              <div class="cf-bracket-label">Pricing after your first visit depends on how long it\'s been:</div>\n              <div class="cf-bracket-row"><span>Within 20 days</span><span>$25/visit</span></div>\n              <div class="cf-bracket-row"><span>20–30 days</span><span>$35/visit</span></div>\n              <div class="cf-bracket-row"><span>30–60 days</span><span>$45/visit</span></div>\n              <div class="cf-bracket-row"><span>60+ days</span><span>$50/visit</span></div>\n            </div>\n            <div class="cf-addon-reason">Custom visits need 48 hours\' notice — just let us know two days before you\'d like us out.</div>\n            <button class="cf-btn-primary cf-flex-choose" id="cfChooseFlexBtn" type="button">Choose Flex</button>\n          </div>\n\n          <div class="cf-guarantee-badge">\n            <div class="cf-guarantee-icon">🛡️</div>\n            <div class="cf-guarantee-text"><strong>The Clean Yard Guarantee</strong> — Not happy with a visit? Text us the gate photo within 24 hours and we\'ll come back and re-clean it free. No questions, no hassle.</div>\n          </div>\n\n          <button class="cf-btn-primary cf-cta-final" id="cfResultsContinueBtn">Continue</button>\n          <div class="cf-fine-print">No contracts. Cancel anytime.</div>\n        </div>\n\n        <!-- Account Setup — email + SMS consent, shown after plan selection -->\n        <div class="cf-account-setup" id="cfAccountSetup">\n          <button class="cf-btn-back cf-waitlist-back" id="cfAccountBackBtn">← Back</button>\n          <div class="cf-eyebrow">Last step</div>\n          <div class="cf-prompt">Let\'s get your account set up.</div>\n          <div class="cf-plan-desc" style="margin-bottom: 18px;">We\'ll use this to set up your Sweep &amp; Go account and send visit confirmations.</div>\n          <input type="email" id="cfEmailInput" placeholder="Email address" inputmode="email" autocomplete="email">\n          <div class="cf-field-error" id="cfEmailError">Please enter a valid email so we can set up your account.</div>\n\n          <div class="cf-consent-box" id="cfConsentBox">\n            <input type="checkbox" id="cfSmsConsent">\n            <div class="cf-custom-check">\n              <svg viewBox="0 0 12 12" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1.5 6 4.5 9 10.5 3"/></svg>\n            </div>\n            <div class="cf-consent-text"><strong>Yes, text me!</strong> I agree to receive SMS messages from Black Warrior Pet Waste Solutions at the number provided. Message &amp; data rates may apply. Reply STOP to opt out.</div>\n          </div>\n          <div class="cf-field-error" id="cfConsentError">Please check the box so we can text you to confirm your first visit.</div>\n\n          <button class="cf-btn-primary cf-cta-final" id="cfSubmitBtn">Get Started</button>\n          <div class="cf-fine-print">No contracts. Cancel anytime.</div>\n        </div>\n\n        <!-- Out-of-area waitlist -->\n        <div class="cf-waitlist" id="cfWaitlist">\n          <button class="cf-btn-back cf-waitlist-back" id="cfWaitlistBackBtn">← Back</button>\n          <div class="cf-waitlist-icon">📍</div>\n          <div class="cf-prompt">We\'re not quite in your area yet — but we\'re growing fast.</div>\n          <div class="cf-waitlist-body">Drop your name and number and we\'ll text you the moment BWPWS opens up near you.</div>\n          <div class="cf-field-group"><input type="text" id="cfWaitlistName" placeholder="Your first name"></div>\n          <div class="cf-field-group"><input type="tel" id="cfWaitlistPhone" placeholder="(205) 555-0123" inputmode="tel"></div>\n          <button class="cf-btn-primary cf-cta-final" id="cfWaitlistBtn">Notify me when you\'re in my area</button>\n        </div>\n\n        <!-- Thank you -->\n        <div class="cf-thankyou" id="cfThankyou">\n          <div class="cf-waitlist-icon">✅</div>\n          <div class="cf-prompt" id="cfThankyouHeadline">You\'re all set!</div>\n          <div class="cf-waitlist-body" id="cfThankyouBody">We\'ll text you shortly to confirm your first visit.</div>\n        </div>\n\n      </div><!-- /form-card -->\n';
  var cssInjected = false;

  function injectCSS() {
    if (cssInjected) return;
    var style = document.createElement('style');
    style.textContent = CSS_TEXT;
    document.head.appendChild(style);
    cssInjected = true;
  }

    // ═══════════════════════════════════════════════════════════════
  // BWPWS — Conversational Recommendation Form
  // /free-initial-cleaning — replaces the old 4-step static-plan form
  // Fires to the SAME Make.com webhook / Airtable base as before.
  // ═══════════════════════════════════════════════════════════════
  function initBWPWSForm(container, uid) {
    var MAKE_WEBHOOK = 'https://hook.us2.make.com/2aijj9thswqhs9h2ap12c7g0axjeygiq';

    var SERVICE_ZIPS = new Set([
      '35022','35080','35111','35124','35209','35213','35216','35223',
      '35226','35229','35242','35243','35244','35259','35260','35401',
      '35404','35405','35406','35452','35453','35456','35463','35473',
      '35475','35476','35480','35490'
    ]);

    var TOTAL_STEPS = 7;
    var currentStep = 1;
    var answers = { zip: '', firstName: '', lastName: '', phone: '', usage: '', dogs: '', odor: '', address: '', city: '' };
    var accountEmail = '';
    var recommendedTier = 'clean';
    var billingMode = 'monthly'; // 'monthly' | 'per_visit'
    var inServiceArea = false;
    var partialFired = false;

    var PRICING = {
      monthly:   { cleanBase: 79, cleanAddon: 30, proBase: 144, proAddon: 40, suffix: '/mo' },
      per_visit: { cleanBase: 19, cleanAddon: 7,  proBase: 17,  proAddon: 5,  suffix: '/visit' }
    };
    var FLEX_PRICE = 50, FLEX_ADDON = 7; // first-visit rate; bracket pricing for later visits is informational only

    var utmParams = (function () {
      var p = new URLSearchParams(window.location.search);
      return {
        source: p.get('utm_source') || '',
        medium: p.get('utm_medium') || '',
        campaign: p.get('utm_campaign') || '',
        content: p.get('utm_content') || '',
        term: p.get('utm_term') || ''
      };
    })();

    // ?plan=clean | pro | flex — skips the diagnostic questions for pre-qualified ad traffic
    var preselectedPlan = (function () {
      var val = new URLSearchParams(window.location.search).get('plan');
      return (val === 'clean' || val === 'pro' || val === 'flex') ? val : null;
    })();

    var stepWrap = container.querySelector('#cfStepWrap' + uid);
    var progressTrack = container.querySelector('#cfProgressTrack' + uid);
    var nextBtn = container.querySelector('#cfNextBtn' + uid);
    var backBtn = container.querySelector('#cfBackBtn' + uid);
    var navRow = container.querySelector('#cfNavRow' + uid);
    var results = container.querySelector('#cfResults' + uid);
    var waitlist = container.querySelector('#cfWaitlist' + uid);
    var thankyou = container.querySelector('#cfThankyou' + uid);

    for (var i = 0; i < TOTAL_STEPS; i++) {
      var seg = document.createElement('div');
      seg.className = 'cf-progress-seg';
      seg.innerHTML = '<div class="cf-fill"></div>';
      progressTrack.appendChild(seg);
    }
    function segFills() { return container.querySelectorAll('.cf-progress-seg .cf-fill'); }
    function updateProgress() {
      var fills = segFills();
      for (var i = 0; i < fills.length; i++) fills[i].style.width = i < currentStep ? '100%' : '0%';
    }

    function scrollToFormTop() {
      var card = container.querySelector('#form-card' + uid);
      if (!card) return;
      var top = card.getBoundingClientRect().top + window.pageYOffset - 16;
      window.scrollTo({ top: top, behavior: 'smooth' });
    }

    function showStep(n) {
      container.querySelectorAll('.cf-step').forEach(function (s) {
        s.classList.toggle('active', parseInt(s.dataset.step) === n);
      });
      backBtn.classList.toggle('hidden', n === 1);
      updateProgress();
      validateCurrent();
    }

    function isValidPhone(v) { return v.replace(/\D/g, '').length === 10; }
    function isValidEmail(v) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v); }

    function validateCurrent() {
      var stepEl = container.querySelector('.cf-step[data-step="' + currentStep + '"]');
      if (currentStep === 1) {
        nextBtn.disabled = answers.zip.length !== 5;
      } else if (currentStep === 2) {
        nextBtn.disabled = !answers.firstName || !answers.lastName;
      } else if (currentStep === 3) {
        nextBtn.disabled = !isValidPhone(answers.phone);
      } else if (currentStep === 7) {
        nextBtn.disabled = !answers.address || !answers.city;
      } else {
        var q = stepEl.querySelector('.cf-options').dataset.question;
        nextBtn.disabled = !answers[q];
      }
    }

    container.querySelector('#cfZipInput' + uid).addEventListener('input', function (e) {
      var v = e.target.value.replace(/\D/g, '').substring(0, 5);
      e.target.value = v;
      answers.zip = v;
      var status = container.querySelector('#cfZipStatus' + uid);
      if (v.length === 5) {
        inServiceArea = SERVICE_ZIPS.has(v);
        status.className = 'cf-zip-status ok';
        status.textContent = inServiceArea ? "You're in our service area — let's keep going." : 'Checking your area…';
      } else {
        status.className = 'cf-zip-status';
        status.textContent = '';
      }
      validateCurrent();
    });
    container.querySelector('#cfZipInput' + uid).addEventListener('keydown', function (e) {
      if (e.key === 'Enter' && !nextBtn.disabled) nextBtn.click();
    });

    ['cfFirstNameInput', 'cfLastNameInput'].forEach(function (id) {
      container.querySelector('#' + id + uid).addEventListener('input', function (e) {
        if (id === 'cfFirstNameInput') answers.firstName = e.target.value.trim();
        else answers.lastName = e.target.value.trim();
        validateCurrent();
      });
      container.querySelector('#' + id + uid).addEventListener('keydown', function (e) {
        if (e.key === 'Enter' && !nextBtn.disabled) nextBtn.click();
      });
    });

    function refreshNameFill() {
      container.querySelector('#cfNamePhoneFill' + uid).textContent = answers.firstName ? ('Hey ' + answers.firstName) : 'Hey there';
    }

    container.querySelector('#cfPhoneInput' + uid).addEventListener('input', function (e) {
      var v = e.target.value.replace(/\D/g, '').substring(0, 10);
      if (v.length >= 7) v = '(' + v.substring(0,3) + ') ' + v.substring(3,6) + '-' + v.substring(6);
      else if (v.length >= 4) v = '(' + v.substring(0,3) + ') ' + v.substring(3);
      else if (v.length > 0) v = '(' + v;
      e.target.value = v;
      answers.phone = v;
      validateCurrent();
    });
    container.querySelector('#cfPhoneInput' + uid).addEventListener('keydown', function (e) {
      if (e.key === 'Enter' && !nextBtn.disabled) nextBtn.click();
    });

    container.querySelector('#cfEmailInput' + uid).addEventListener('input', function (e) {
      accountEmail = e.target.value.trim();
      container.querySelector('#cfEmailError' + uid).classList.remove('visible');
    });

    container.querySelectorAll('.cf-options').forEach(function (group) {
      group.addEventListener('click', function (e) {
        var btn = e.target.closest('.cf-option-btn');
        if (!btn) return;
        var q = group.dataset.question;
        answers[q] = btn.dataset.value;
        group.querySelectorAll('.cf-option-btn').forEach(function (b) { b.classList.remove('selected'); });
        btn.classList.add('selected');
        validateCurrent();
      });
    });

    container.querySelector('#cfAddressInput' + uid).addEventListener('input', function (e) {
      answers.address = e.target.value.trim();
      validateCurrent();
    });
    container.querySelector('#cfCityInput' + uid).addEventListener('input', function (e) {
      answers.city = e.target.value.trim();
      validateCurrent();
    });

    function fireWebhook(payload) {
      return fetch(MAKE_WEBHOOK, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
        mode: 'cors'
      }).catch(function () {});
    }

    function maybeFirePartial() {
      if (partialFired || !answers.phone || answers.zip.length !== 5) return;
      partialFired = true;
      fireWebhook({
        type: 'partial',
        step: 3,
        phone: answers.phone,
        phone_raw: answers.phone.replace(/\D/g, ''),
        zip: answers.zip,
        in_service_area: inServiceArea ? 'yes' : ('no — ' + answers.zip),
        page_source: 'free-initial-cleaning',
        utm_source: utmParams.source,
        utm_medium: utmParams.medium,
        utm_campaign: utmParams.campaign,
        utm_content: utmParams.content,
        utm_term: utmParams.term
      });
      if (typeof fbq !== 'undefined') fbq('track', 'Lead');
      if (typeof gtag !== 'undefined') {
        gtag('event', 'conversion', { 'send_to': 'AW-16767148360/6EUjCJOQvbYcEMjCmbs-', 'value': 110.0, 'currency': 'USD' });
      }
    }

    nextBtn.addEventListener('click', function () {
      if (currentStep === 1) {
        if (!inServiceArea) {
          stepWrap.style.display = 'none';
          navRow.style.display = 'none';
          progressTrack.style.display = 'none';
          waitlist.classList.add('active');
          scrollToFormTop();
          return;
        }
      }
      if (currentStep === 2) refreshNameFill();
      if (currentStep === 3) maybeFirePartial();
      if (currentStep === 6) container.querySelector('#cfZipDisplay' + uid).value = answers.zip;

      // Preselected-plan traffic (organic pricing page or ad) skips Usage(4) and Odor(6) —
      // both are diagnostic-only and moot once the plan is already chosen — but keeps Dogs(5),
      // since that's real operational data worth the one extra tap regardless of path.
      var next = currentStep + 1;
      if (preselectedPlan) {
        while (next === 4 || next === 6) next++;
      }

      if (next <= TOTAL_STEPS) {
        if (preselectedPlan && next === 7) container.querySelector('#cfZipDisplay' + uid).value = answers.zip;
        currentStep = next;
        showStep(currentStep);
      } else {
        if (preselectedPlan) {
          showPreselectedResults();
        } else {
          runRecommendation();
        }
        stepWrap.style.display = 'none';
        navRow.style.display = 'none';
        results.classList.add('active');
        segFills().forEach(function (f) { f.style.width = '100%'; });
        scrollToFormTop();
      }
    });

    backBtn.addEventListener('click', function () {
      if (currentStep > 1) { currentStep--; showStep(currentStep); }
    });

    function runRecommendation() {
      var usage = answers.usage, dogs = answers.dogs, odor = answers.odor;

      var cleanToggle = container.querySelector('#cfToggleClean' + uid);
      var proToggle = container.querySelector('#cfTogglePro' + uid);
      var preselect = odor === 'bad';

      var proScore = 0;
      if (dogs === '3plus') proScore += 2;
      if (usage === 'frequent' && dogs === '2') proScore += 1;
      if (usage === 'constant') proScore += 1;
      recommendedTier = proScore >= 2 ? 'pro' : 'clean';

      cleanToggle.checked = preselect;
      proToggle.checked = preselect;

      container.querySelector('#cfResultsHeadline' + uid).textContent =
        'Based on what you told us, ' + (answers.firstName || 'there') + ", here's what we'd recommend:";

      var proDesc = container.querySelector('#cfProDesc' + uid);
      if (dogs === '3plus') {
        proDesc.textContent = 'With 3+ dogs, waste piles up fast — twice-weekly keeps it from ever building up.';
      } else if (usage === 'constant') {
        proDesc.textContent = 'Your yard gets heavy daily use — twice-weekly keeps it from ever building up.';
      } else {
        proDesc.textContent = 'Built for yards where waste piles up fast — multiple dogs or heavy daily use.';
      }

      var cardClean = container.querySelector('#cfCardClean' + uid);
      var cardPro = container.querySelector('#cfCardPro' + uid);
      cardClean.classList.remove('recommended');
      cardPro.classList.remove('recommended');
      container.querySelector('#cfCardFlex' + uid).classList.remove('selected');
      container.querySelectorAll('.cf-badge').forEach(function (b) { b.remove(); });
      var recommendedCard = recommendedTier === 'pro' ? cardPro : cardClean;
      recommendedCard.classList.add('recommended');
      var badge = document.createElement('div');
      badge.className = 'cf-badge';
      badge.textContent = 'Best fit for you';
      recommendedCard.prepend(badge);

      // Auto-open the Flex option for occasional-use answers, but the named plans stay front and center either way
      var flexCard = container.querySelector('#cfCardFlex' + uid);
      var flexArrow = container.querySelector('#cfFlexToggleArrow' + uid);
      if (usage === 'occasional') {
        flexCard.classList.add('expanded');
        flexArrow.textContent = '↑';
      } else {
        flexCard.classList.remove('expanded');
        flexArrow.textContent = '↓';
      }

      updatePricing();
      updateBillingNote();
    }

    // Ad traffic with ?plan=clean|pro|flex skips the diagnostic and lands here instead of runRecommendation()
    function showPreselectedResults() {
      recommendedTier = preselectedPlan;

      container.querySelector('#cfResultsHeadline' + uid).textContent =
        'Great choice, ' + (answers.firstName || 'there') + " — here's your pricing:";

      var cardClean = container.querySelector('#cfCardClean' + uid);
      var cardPro = container.querySelector('#cfCardPro' + uid);
      var cardFlex = container.querySelector('#cfCardFlex' + uid);
      cardClean.classList.remove('recommended');
      cardPro.classList.remove('recommended');
      cardFlex.classList.remove('selected');
      container.querySelectorAll('.cf-badge').forEach(function (b) { b.remove(); });

      if (preselectedPlan === 'flex') {
        cardFlex.classList.add('expanded', 'selected');
        billingMode = 'per_visit';
      } else {
        var chosenCard = preselectedPlan === 'pro' ? cardPro : cardClean;
        chosenCard.classList.add('recommended');
        var badge = document.createElement('div');
        badge.className = 'cf-badge';
        badge.textContent = 'Your selection';
        chosenCard.prepend(badge);
      }

      updatePricing();
      updateBillingNote();
    }

    function updatePricing() {
      var p = PRICING[billingMode];
      var cleanOn = container.querySelector('#cfToggleClean' + uid).checked;
      var proOn = container.querySelector('#cfTogglePro' + uid).checked;
      var flexOn = container.querySelector('#cfToggleFlex' + uid).checked;
      container.querySelector('#cfPriceClean' + uid).innerHTML = '$' + (p.cleanBase + (cleanOn ? p.cleanAddon : 0)) + '<span>' + p.suffix + '</span>';
      container.querySelector('#cfPricePro' + uid).innerHTML = '$' + (p.proBase + (proOn ? p.proAddon : 0)) + '<span>' + p.suffix + '</span>';
      container.querySelector('#cfPriceFlex' + uid).innerHTML = '$' + (FLEX_PRICE + (flexOn ? FLEX_ADDON : 0)) + '<span>/first visit</span>';

      var addonSuffix = billingMode === 'monthly' ? ' — applied every visit' : ' — added when applied';
      container.querySelector('#cfCleanAddonLabel' + uid).textContent = '+$' + p.cleanAddon + p.suffix + addonSuffix;
      container.querySelector('#cfProAddonLabel' + uid).textContent = '+$' + p.proAddon + p.suffix + addonSuffix;
    }
    container.querySelector('#cfToggleClean' + uid).addEventListener('change', updatePricing);
    container.querySelector('#cfTogglePro' + uid).addEventListener('change', updatePricing);
    container.querySelector('#cfToggleFlex' + uid).addEventListener('change', updatePricing);

    container.querySelector('#cfFlexToggle' + uid).addEventListener('click', function () {
      var flexCard = container.querySelector('#cfCardFlex' + uid);
      var flexArrow = container.querySelector('#cfFlexToggleArrow' + uid);
      var isOpen = flexCard.classList.toggle('expanded');
      flexArrow.textContent = isOpen ? '↑' : '↓';
    });

    container.querySelector('#cfChooseFlexBtn' + uid).addEventListener('click', function () {
      recommendedTier = 'flex';
      container.querySelector('#cfCardClean' + uid).classList.remove('recommended');
      container.querySelector('#cfCardPro' + uid).classList.remove('recommended');
      container.querySelectorAll('.cf-badge').forEach(function (b) { b.remove(); });
      container.querySelector('#cfCardFlex' + uid).classList.add('selected');
    });

    function updateBillingNote() {
      var note = container.querySelector('#cfBillingNote' + uid);
      if (billingMode === 'monthly') {
        note.innerHTML = '<strong>Your first cleaning is free.</strong> Monthly billing begins after your 2nd visit.';
      } else {
        note.innerHTML = 'You\u2019re charged after each completed visit — starting with your first.';
      }
    }

    container.querySelectorAll('.cf-billing-option').forEach(function (btn) {
      btn.addEventListener('click', function () {
        billingMode = btn.dataset.mode;
        container.querySelectorAll('.cf-billing-option').forEach(function (b) { b.classList.remove('selected'); });
        btn.classList.add('selected');
        updatePricing();
        updateBillingNote();
      });
    });

    // ── Let the user click either named card to select it, overriding the recommendation ──
    function selectPlan(tier) {
      recommendedTier = tier;
      var cardClean = container.querySelector('#cfCardClean' + uid);
      var cardPro = container.querySelector('#cfCardPro' + uid);
      cardClean.classList.remove('recommended');
      cardPro.classList.remove('recommended');
      container.querySelector('#cfCardFlex' + uid).classList.remove('selected');
      container.querySelectorAll('.cf-badge').forEach(function (b) { b.remove(); });
      var chosenCard = tier === 'pro' ? cardPro : cardClean;
      chosenCard.classList.add('recommended');
      var badge = document.createElement('div');
      badge.className = 'cf-badge';
      badge.textContent = 'Selected';
      chosenCard.prepend(badge);
    }

    [['cfCardClean', 'clean'], ['cfCardPro', 'pro']].forEach(function (pair) {
      var card = container.querySelector('#' + pair[0] + uid);
      var tier = pair[1];
      card.addEventListener('click', function (e) {
        // Don't hijack clicks on the deodorizer toggle itself
        if (e.target.closest('.cf-toggle-row')) return;
        selectPlan(tier);
      });
      card.style.cursor = 'pointer';
    });

    container.querySelector('#cfResultsContinueBtn' + uid).addEventListener('click', function () {
      results.classList.remove('active');
      container.querySelector('#cfAccountSetup' + uid).classList.add('active');
      scrollToFormTop();
    });

    container.querySelector('#cfAccountBackBtn' + uid).addEventListener('click', function () {
      container.querySelector('#cfAccountSetup' + uid).classList.remove('active');
      results.classList.add('active');
      scrollToFormTop();
    });

    var consentBox = container.querySelector('#cfConsentBox' + uid);
    consentBox.addEventListener('click', function () {
      var cb = container.querySelector('#cfSmsConsent' + uid);
      cb.checked = !cb.checked;
      consentBox.classList.toggle('checked', cb.checked);
      container.querySelector('#cfConsentError' + uid).classList.remove('visible');
    });

    container.querySelector('#cfSubmitBtn' + uid).addEventListener('click', function () {
      var emailValid = isValidEmail(accountEmail);
      if (!emailValid) {
        container.querySelector('#cfEmailError' + uid).classList.add('visible');
        return;
      }
      var smsChecked = container.querySelector('#cfSmsConsent' + uid).checked;
      if (!smsChecked) {
        container.querySelector('#cfConsentError' + uid).classList.add('visible');
        return;
      }

      var cleanOn = container.querySelector('#cfToggleClean' + uid).checked;
      var proOn = container.querySelector('#cfTogglePro' + uid).checked;
      var flexOn = container.querySelector('#cfToggleFlex' + uid).checked;

      var frequency, planName, deodorizerOn, billingCadence, freeInitial, monthlyPrice, perVisitPrice;

      if (recommendedTier === 'flex') {
        frequency = 'custom';
        planName = 'Clean Yard Flex';
        deodorizerOn = flexOn;
        billingCadence = 'per_visit';
        freeInitial = 'no';
        monthlyPrice = '';
        perVisitPrice = FLEX_PRICE + (flexOn ? FLEX_ADDON : 0);
      } else {
        deodorizerOn = recommendedTier === 'pro' ? proOn : cleanOn;
        frequency = recommendedTier === 'pro' ? '2x-weekly' : 'weekly';
        planName = recommendedTier === 'pro' ? 'Clean Yard Pro' : 'Clean Yard';
        billingCadence = billingMode;
        freeInitial = billingMode === 'monthly' ? 'yes' : 'no';
        monthlyPrice = recommendedTier === 'pro'
          ? (PRICING.monthly.proBase + (proOn ? PRICING.monthly.proAddon : 0))
          : (PRICING.monthly.cleanBase + (cleanOn ? PRICING.monthly.cleanAddon : 0));
        perVisitPrice = recommendedTier === 'pro'
          ? (PRICING.per_visit.proBase + (proOn ? PRICING.per_visit.proAddon : 0))
          : (PRICING.per_visit.cleanBase + (cleanOn ? PRICING.per_visit.cleanAddon : 0));
      }

      var btn = container.querySelector('#cfSubmitBtn' + uid);
      btn.textContent = 'Sending…';
      btn.disabled = true;

      var payload = {
        type: 'complete',
        step: 7,
        phone: answers.phone,
        phone_raw: answers.phone.replace(/\D/g, ''),
        email: accountEmail,
        zip: answers.zip,
        first_name: answers.firstName,
        last_name: answers.lastName,
        address: answers.address,
        city: answers.city,
        state: 'AL',
        dogs: answers.dogs === '3plus' ? '3+' : answers.dogs,
        frequency: frequency,
        plan_name: planName,
        add_deodorizer: deodorizerOn ? 'yes' : 'no',
        billing_cadence: billingCadence,
        free_initial_cleaning: freeInitial,
        monthly_price: String(monthlyPrice),
        per_visit_price: String(perVisitPrice),
        sms_consent: 'yes',
        in_service_area: 'yes',
        page_source: 'free-initial-cleaning',
        utm_source: utmParams.source,
        utm_medium: utmParams.medium,
        utm_campaign: utmParams.campaign,
        utm_content: utmParams.content,
        utm_term: utmParams.term
      };

      var completed = false;
      function onComplete() {
        if (completed) return;
        completed = true;
        if (typeof fbq !== 'undefined') fbq('track', 'CompleteRegistration');
        window.location.href = (recommendedTier === 'flex')
          ? 'https://blackwarriorpws.com/thank-you-one-time'
          : 'https://blackwarriorpws.com/thank-you';
      }

      var fallbackTimer = setTimeout(onComplete, 4000);
      fireWebhook(payload).then(function () {
        clearTimeout(fallbackTimer);
        onComplete();
      });
    });

    container.querySelector('#cfWaitlistBtn' + uid).addEventListener('click', function () {
      var name = container.querySelector('#cfWaitlistName' + uid).value.trim();
      var phoneRaw = container.querySelector('#cfWaitlistPhone' + uid).value.trim();
      var btn = container.querySelector('#cfWaitlistBtn' + uid);
      btn.textContent = 'Sending…';
      btn.disabled = true;

      fireWebhook({
        type: 'partial',
        step: 1,
        phone: phoneRaw,
        phone_raw: phoneRaw.replace(/\D/g, ''),
        zip: answers.zip,
        first_name: name,
        in_service_area: 'no — ' + answers.zip,
        page_source: 'free-initial-cleaning',
        utm_source: utmParams.source,
        utm_medium: utmParams.medium,
        utm_campaign: utmParams.campaign,
        utm_content: utmParams.content,
        utm_term: utmParams.term
      }).then(function () {
        waitlist.classList.remove('active');
        container.querySelector('#cfThankyouHeadline' + uid).textContent = "You're on the list" + (name ? ', ' + name : '') + '.';
        container.querySelector('#cfThankyouBody' + uid).textContent = "We'll text you the moment we reach your area.";
        thankyou.classList.add('active');
        scrollToFormTop();
      });
    });

    container.querySelector('#cfWaitlistBackBtn' + uid).addEventListener('click', function () {
      waitlist.classList.remove('active');
      stepWrap.style.display = '';
      navRow.style.display = '';
      progressTrack.style.display = '';
      answers.zip = '';
      container.querySelector('#cfZipInput' + uid).value = '';
      container.querySelector('#cfZipStatus' + uid).className = 'cf-zip-status';
      container.querySelector('#cfZipStatus' + uid).textContent = '';
      currentStep = 1;
      showStep(1);
    });

    updateProgress();

    // Pricing-page / plan-specific traffic (?plan=clean|pro|flex) skips straight to the form —
    // paid/social traffic with no plan param still lands at the top and sees the full page.
    // Also handles plain #form-card links (e.g. from the homepage) where native anchor scrolling
    // isn't reliable, since Caboose's own page load/reflow can shift things after the browser's
    // automatic jump happens.
    if (preselectedPlan || window.location.hash === '#form-card') {
      function scrollToFormNow() {
        var formCard = container.querySelector('#form-card' + uid);
        if (formCard) formCard.scrollIntoView({ behavior: 'instant', block: 'start' });
      }
      window.addEventListener('load', function () {
        scrollToFormNow();
        // Re-assert a few times shortly after load in case Caboose's own scripts
        // reflow the page (fonts/images finishing, injected content, etc.)
        setTimeout(scrollToFormNow, 300);
        setTimeout(scrollToFormNow, 800);
        setTimeout(scrollToFormNow, 1500);
      });
    }
}

  var instanceCounter = 0;

  function mount(targetEl) {
    injectCSS();
    instanceCounter++;
    var uid = '-bwi' + instanceCounter;
    // Give every element in this instance a unique ID so multiple forms can
    // coexist safely on the same page without one instance's lookups
    // colliding with another's.
    var uniqueHTML = HTML_TEXT.replace(/id="(cf[A-Za-z]+|form-card)"/g, function (match, idName) {
      return 'id="' + idName + uid + '"';
    });
    targetEl.innerHTML = uniqueHTML;
    initBWPWSForm(targetEl, uid);
  }

  // ── Modal (popup) mode ──
  var modalOverlay = null;

  function openModal() {
    if (modalOverlay) { modalOverlay.style.display = 'flex'; return; }
    injectCSS();

    modalOverlay = document.createElement('div');
    modalOverlay.id = 'bwpws-modal-overlay';
    modalOverlay.style.cssText = 'position:fixed;inset:0;background:rgba(13,8,33,0.55);z-index:99999;display:flex;align-items:center;justify-content:center;padding:20px;overflow-y:auto;';

    var modalInner = document.createElement('div');
    modalInner.style.cssText = 'max-width:520px;width:100%;position:relative;margin:auto;';

    var closeBtn = document.createElement('button');
    closeBtn.setAttribute('aria-label', 'Close');
    closeBtn.innerHTML = '&times;';
    closeBtn.style.cssText = 'position:absolute;top:-44px;right:0;background:rgba(255,255,255,0.15);color:#fff;border:none;width:36px;height:36px;border-radius:50%;font-size:22px;cursor:pointer;line-height:1;';
    closeBtn.onclick = closeModal;

    var formMount = document.createElement('div');
    modalInner.appendChild(closeBtn);
    modalInner.appendChild(formMount);
    modalOverlay.appendChild(modalInner);
    document.body.appendChild(modalOverlay);

    modalOverlay.addEventListener('click', function (e) {
      if (e.target === modalOverlay) closeModal();
    });

    mount(formMount);
  }

  function closeModal() {
    if (modalOverlay) modalOverlay.style.display = 'none';
  }

  // ── Auto-mount inline if a mount point exists on the page ──
  function autoMount() {
    var target = document.getElementById('bwpws-form-mount');
    if (target) mount(target);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', autoMount);
  } else {
    autoMount();
  }

  window.BWPWSForm = { mount: mount, openModal: openModal, closeModal: closeModal };
})();
