{"id":463,"date":"2026-06-20T22:45:46","date_gmt":"2026-06-20T22:45:46","guid":{"rendered":"https:\/\/rpmwes.com\/blog\/?page_id=463"},"modified":"2026-07-03T02:40:53","modified_gmt":"2026-07-03T02:40:53","slug":"water-savings-calculator","status":"publish","type":"page","link":"https:\/\/rpmwes.com\/blog\/water-savings-calculator\/","title":{"rendered":"Water Savings ROI Calculator"},"content":{"rendered":"\n<style>@media (max-width:781px){#rpm-roi-frame{margin-left:-24px !important;margin-right:-24px !important;width:calc(100% + 48px) !important;}}<\/style>\n<iframe id=\"rpm-roi-frame\" title=\"Water Savings ROI Calculator\" scrolling=\"no\" style=\"width:100%;border:0;display:block;overflow:hidden;min-height:600px\" srcdoc=\"&lt;!DOCTYPE html&gt;&lt;html lang=&quot;en&quot;&gt;&lt;head&gt;&lt;meta charset=&quot;utf-8&quot;&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;&lt;base target=&quot;_parent&quot;&gt;&lt;link rel=&quot;preconnect&quot; href=&quot;https:\/\/fonts.googleapis.com&quot;&gt;&lt;link rel=&quot;preconnect&quot; href=&quot;https:\/\/fonts.gstatic.com&quot; crossorigin&gt;&lt;link href=&quot;https:\/\/fonts.googleapis.com\/css2?family=Playfair+Display:wght@500;600;700&amp;family=DM+Sans:wght@400;600&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;&lt;style&gt;\n    \/* ========================================\n       1. CSS RESET &amp; BASE STYLES\n       ======================================== *\/\n\n    *, *::before, *::after {\n      box-sizing: border-box;\n      margin: 0;\n      padding: 0;\n    }\n\n    html {\n      scroll-behavior: smooth;\n    }\n\n    body {\n      font-family: var(--font-body);\n      line-height: 1.6;\n      color: var(--color-text);\n      background-color: var(--color-cream);\n      overflow-x: hidden;\n    }\n\n    \/* ========================================\n       2. CSS CUSTOM PROPERTIES (DESIGN TOKENS)\n       ======================================== *\/\n\n    :root {\n      \/* Colors *\/\n      --color-navy-dark: #0a1628;\n      --color-navy-medium: #0f2847;\n      --color-navy-accent: #1e4976;\n      --color-blue-light: #60a5fa;\n      --color-blue-accent: #3b82f6;\n      --color-cream: #f8fafc;\n      --color-white: #ffffff;\n      --color-text: #1e293b;\n      --color-text-light: #64748b;\n      --color-error: #ef4444;\n      --color-success: #10b981;\n      --color-warning: #fbbf24;\n      --color-warning-dark: #78350f;\n\n      \/* Typography *\/\n      --font-heading: &#x27;Playfair Display&#x27;, serif;\n      --font-body: &#x27;DM Sans&#x27;, sans-serif;\n\n      \/* Spacing *\/\n      --space-xs: 0.25rem;\n      --space-sm: 0.5rem;\n      --space-md: 1rem;\n      --space-lg: 2rem;\n      --space-xl: 3rem;\n      --space-2xl: 4rem;\n\n      \/* Border Radius *\/\n      --radius-input: 12px;\n      --radius-button: 50px;\n      --radius-card: 16px;\n      --radius-sm: 8px;\n\n      \/* Shadows *\/\n      --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n      --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n      --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n      --shadow-focus: 0 0 0 3px rgba(96, 165, 250, 0.3);\n\n      \/* Transitions *\/\n      --transition-fast: 150ms ease-in-out;\n      --transition-medium: 300ms ease-in-out;\n\n      \/* Breakpoints (for reference in media queries) *\/\n      --bp-tablet: 640px;\n      --bp-desktop: 768px;\n      --bp-large: 1024px;\n    }\n\n    \/* ========================================\n       3. TYPOGRAPHY SYSTEM\n       ======================================== *\/\n\n    h1, h2, h3, h4, h5, h6 {\n      font-family: var(--font-heading);\n      font-weight: 600;\n      line-height: 1.2;\n      color: var(--color-navy-dark);\n    }\n\n    h1 {\n      font-size: clamp(2rem, 5vw, 3.5rem);\n      font-weight: 700;\n      margin-bottom: var(--space-md);\n    }\n\n    h2 {\n      font-size: clamp(1.75rem, 4vw, 2.5rem);\n      margin-bottom: var(--space-md);\n    }\n\n    h3 {\n      font-size: clamp(1.25rem, 3vw, 1.75rem);\n      margin-bottom: var(--space-sm);\n    }\n\n    p {\n      margin-bottom: var(--space-md);\n    }\n\n    a {\n      color: var(--color-navy-accent);\n      text-decoration: underline;\n      transition: color var(--transition-fast);\n    }\n\n    a:hover {\n      color: var(--color-blue-light);\n    }\n\n    \/* ========================================\n       4. LAYOUT &amp; CONTAINER\n       ======================================== *\/\n\n    .container {\n      max-width: 1200px;\n      margin: 0 auto;\n      padding: 0 var(--space-md);\n    }\n\n    section {\n      padding: var(--space-xl) 0;\n    }\n\n    \/* ========================================\n       5. HEADER\n       ======================================== *\/\n\n    header {\n      background: linear-gradient(135deg, var(--color-navy-dark) 0%, var(--color-navy-medium) 100%);\n      padding: var(--space-lg) 0;\n      box-shadow: var(--shadow-md);\n    }\n\n    .header-content {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      flex-wrap: wrap;\n      gap: var(--space-md);\n    }\n\n    .logo-link {\n      display: flex;\n      align-items: center;\n    }\n\n    .logo {\n      height: 50px;\n      width: auto;\n    }\n\n    .nav-link {\n      color: var(--color-white);\n      font-weight: 600;\n      padding: var(--space-sm) var(--space-md);\n      border-radius: var(--radius-sm);\n      transition: background-color var(--transition-fast);\n    }\n\n    .nav-link:hover {\n      background-color: rgba(255, 255, 255, 0.1);\n      color: var(--color-white);\n    }\n\n    \/* ========================================\n       6. HERO SECTION\n       ======================================== *\/\n\n    #hero {\n      background: linear-gradient(135deg, var(--color-navy-medium) 0%, var(--color-navy-accent) 100%);\n      color: var(--color-white);\n      text-align: center;\n      padding: var(--space-2xl) 0;\n    }\n\n    #hero h1 {\n      color: var(--color-white);\n      margin-bottom: var(--space-md);\n    }\n\n    .hero-subtitle {\n      font-size: clamp(1.125rem, 2.5vw, 1.5rem);\n      font-weight: 600;\n      color: var(--color-blue-light);\n      margin-bottom: var(--space-md);\n    }\n\n    .hero-description {\n      font-size: clamp(1rem, 2vw, 1.125rem);\n      max-width: 800px;\n      margin: 0 auto var(--space-lg);\n      opacity: 0.9;\n    }\n\n    \/* ========================================\n       7. FORM COMPONENTS\n       ======================================== *\/\n\n    .form-section {\n      background: var(--color-white);\n      border-radius: var(--radius-card);\n      padding: var(--space-xl);\n      box-shadow: var(--shadow-lg);\n      margin-bottom: var(--space-lg);\n    }\n\n    \/* Slim down panel padding on small screens so narrow embeds aren&#x27;t cramped *\/\n    @media (max-width: 640px) {\n      .form-section {\n        padding: var(--space-lg) var(--space-md);\n      }\n      .container {\n        padding: 0 var(--space-sm);\n      }\n      section {\n        padding: var(--space-lg) 0;\n      }\n    }\n\n    .form-section-header {\n      font-family: var(--font-heading);\n      font-size: 1.5rem;\n      color: var(--color-navy-dark);\n      margin-bottom: var(--space-md);\n      padding-bottom: var(--space-sm);\n      border-bottom: 2px solid var(--color-cream);\n    }\n\n    .form-section-description {\n      color: var(--color-text-light);\n      font-size: 0.9375rem;\n      margin-bottom: var(--space-lg);\n    }\n\n    .form-grid {\n      display: grid;\n      grid-template-columns: 1fr;\n      gap: var(--space-lg);\n    }\n\n    @media (min-width: 768px) {\n      .form-grid {\n        grid-template-columns: repeat(2, 1fr);\n      }\n    }\n\n    .form-group {\n      position: relative;\n      display: flex;\n      flex-direction: column;\n    }\n\n    .form-group.full-width {\n      grid-column: 1 \/ -1;\n    }\n\n    label {\n      display: flex;\n      align-items: center;\n      font-weight: 600;\n      color: var(--color-navy-dark);\n      margin-bottom: var(--space-sm);\n      font-size: 0.9375rem;\n    }\n\n    .required-indicator {\n      color: var(--color-error);\n      margin-left: var(--space-xs);\n    }\n\n    .info-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 18px;\n      height: 18px;\n      background: var(--color-blue-accent);\n      color: var(--color-white);\n      border-radius: 50%;\n      border: none;\n      cursor: help;\n      margin-left: var(--space-sm);\n      font-size: 0.75rem;\n      font-weight: 700;\n      padding: 0;\n      line-height: 1;\n      transition: background-color var(--transition-fast);\n    }\n\n    .info-icon:hover {\n      background: var(--color-blue-light);\n    }\n\n    .info-icon:focus {\n      outline: none;\n      box-shadow: var(--shadow-focus);\n    }\n\n    .input-with-helper {\n      display: flex;\n      align-items: flex-start;\n      gap: var(--space-sm);\n      flex-wrap: wrap;\n    }\n\n    .input-with-helper input,\n    .input-with-helper select {\n      flex: 1;\n      min-width: 200px;\n    }\n\n    input[type=&quot;text&quot;],\n    input[type=&quot;email&quot;],\n    input[type=&quot;number&quot;],\n    select {\n      width: 100%;\n      padding: 0.75rem 1rem;\n      border: 2px solid var(--color-navy-accent);\n      border-radius: var(--radius-input);\n      font-family: var(--font-body);\n      font-size: 1rem;\n      color: var(--color-text);\n      transition: all var(--transition-fast);\n      background-color: var(--color-white);\n    }\n\n    input:focus,\n    select:focus {\n      outline: none;\n      border-color: var(--color-blue-accent);\n      box-shadow: var(--shadow-focus);\n    }\n\n    input::placeholder {\n      color: var(--color-text-light);\n    }\n\n    input[aria-invalid=&quot;true&quot;] {\n      border-color: var(--color-error);\n    }\n\n    .help-text {\n      display: block;\n      font-size: 0.875rem;\n      color: var(--color-text-light);\n      margin-top: var(--space-xs);\n      line-height: 1.4;\n    }\n\n    .error-message {\n      display: none;\n      color: var(--color-error);\n      font-size: 0.875rem;\n      margin-top: var(--space-xs);\n      font-weight: 600;\n    }\n\n    .error-message.visible {\n      display: block;\n    }\n\n    .btn-helper {\n      display: inline-flex;\n      align-items: center;\n      background: transparent;\n      border: 2px solid var(--color-navy-accent);\n      color: var(--color-navy-accent);\n      padding: 0.625rem 1rem;\n      border-radius: var(--radius-sm);\n      font-size: 0.875rem;\n      font-weight: 600;\n      cursor: pointer;\n      transition: all var(--transition-fast);\n      white-space: nowrap;\n      font-family: var(--font-body);\n    }\n\n    .btn-helper:hover {\n      background: rgba(96, 165, 250, 0.1);\n    }\n\n    .btn-helper:focus {\n      outline: none;\n      box-shadow: var(--shadow-focus);\n    }\n\n    .btn-helper.active {\n      background: var(--color-blue-accent);\n      color: var(--color-white);\n    }\n\n    .tooltip {\n      position: absolute;\n      background: var(--color-navy-dark);\n      color: var(--color-white);\n      padding: 0.75rem;\n      border-radius: var(--radius-sm);\n      max-width: 280px;\n      font-size: 0.875rem;\n      line-height: 1.5;\n      z-index: 1000;\n      box-shadow: var(--shadow-lg);\n      top: 100%;\n      left: 0;\n      margin-top: var(--space-xs);\n    }\n\n    .tooltip::before {\n      content: &#x27;&#x27;;\n      position: absolute;\n      bottom: 100%;\n      left: 20px;\n      border: 6px solid transparent;\n      border-bottom-color: var(--color-navy-dark);\n    }\n\n    \/* ========================================\n       8. BUTTONS\n       ======================================== *\/\n\n    .btn {\n      display: inline-block;\n      padding: 1rem 2rem;\n      border-radius: var(--radius-button);\n      font-family: var(--font-body);\n      font-size: 1rem;\n      font-weight: 600;\n      text-align: center;\n      cursor: pointer;\n      transition: all var(--transition-medium);\n      border: none;\n      text-decoration: none;\n    }\n\n    .btn-primary {\n      background: linear-gradient(135deg, var(--color-blue-light) 0%, var(--color-blue-accent) 100%);\n      color: var(--color-white);\n      box-shadow: var(--shadow-md);\n    }\n\n    .btn-primary:hover {\n      transform: translateY(-2px);\n      box-shadow: var(--shadow-lg);\n      color: var(--color-white);\n    }\n\n    .btn-primary:active {\n      transform: translateY(0);\n    }\n\n    .btn-primary:focus {\n      outline: none;\n      box-shadow: var(--shadow-focus), var(--shadow-lg);\n    }\n\n    .btn-primary:disabled {\n      opacity: 0.6;\n      cursor: not-allowed;\n      transform: none;\n    }\n\n    .btn-submit {\n      width: 100%;\n      margin-top: var(--space-lg);\n      padding: 1.25rem 2rem;\n      font-size: 1.125rem;\n    }\n\n    \/* ========================================\n       9. RESULTS SECTION\n       ======================================== *\/\n\n    #results {\n      background: var(--color-white);\n      border-radius: var(--radius-card);\n      padding: var(--space-xl);\n      box-shadow: var(--shadow-lg);\n      margin-bottom: var(--space-lg);\n    }\n\n    #results[hidden] {\n      display: none;\n    }\n\n    .results-header {\n      text-align: center;\n      margin-bottom: var(--space-xl);\n    }\n\n    .results-grid {\n      display: grid;\n      grid-template-columns: 1fr;\n      gap: var(--space-lg);\n      margin-bottom: var(--space-xl);\n    }\n\n    @media (min-width: 640px) {\n      .results-grid {\n        grid-template-columns: repeat(2, 1fr);\n      }\n    }\n\n    @media (min-width: 1024px) {\n      .results-grid {\n        grid-template-columns: repeat(3, 1fr);\n      }\n    }\n\n    .result-card {\n      background: linear-gradient(135deg, var(--color-navy-medium) 0%, var(--color-navy-accent) 100%);\n      color: var(--color-white);\n      padding: var(--space-lg);\n      border-radius: var(--radius-card);\n      box-shadow: var(--shadow-md);\n      transition: transform var(--transition-medium);\n    }\n\n    .result-card:hover {\n      transform: translateY(-4px);\n    }\n\n    .result-label {\n      font-size: 0.875rem;\n      font-weight: 600;\n      text-transform: uppercase;\n      letter-spacing: 0.05em;\n      color: var(--color-blue-light);\n      margin-bottom: var(--space-sm);\n      display: flex;\n      align-items: center;\n      gap: var(--space-sm);\n    }\n\n    .result-value {\n      font-size: clamp(1.75rem, 4vw, 2.5rem);\n      font-weight: 700;\n      font-family: var(--font-heading);\n      margin-bottom: var(--space-sm);\n      line-height: 1.1;\n    }\n\n    .result-description {\n      font-size: 0.875rem;\n      opacity: 0.9;\n      line-height: 1.5;\n    }\n\n    .estimate-badge {\n      display: inline-block;\n      background: var(--color-warning);\n      color: var(--color-warning-dark);\n      padding: 0.25rem 0.5rem;\n      border-radius: 4px;\n      font-size: 0.75rem;\n      font-weight: 600;\n      text-transform: uppercase;\n      letter-spacing: 0.03em;\n    }\n\n    .results-notice {\n      background: rgba(96, 165, 250, 0.1);\n      border-left: 4px solid var(--color-blue-accent);\n      padding: var(--space-md);\n      border-radius: var(--radius-sm);\n      margin-bottom: var(--space-lg);\n    }\n\n    .results-notice p {\n      margin-bottom: 0;\n      color: var(--color-navy-dark);\n    }\n\n    .results-cta {\n      text-align: center;\n      padding-top: var(--space-lg);\n      border-top: 2px solid var(--color-cream);\n    }\n\n    \/* ========================================\n       10. CTA SECTION\n       ======================================== *\/\n\n    #cta {\n      background: linear-gradient(135deg, var(--color-navy-dark) 0%, var(--color-navy-medium) 100%);\n      color: var(--color-white);\n      text-align: center;\n      padding: var(--space-2xl) 0;\n      border-radius: var(--radius-card);\n    }\n\n    #cta h2 {\n      color: var(--color-white);\n      margin-bottom: var(--space-md);\n    }\n\n    #cta p {\n      font-size: 1.125rem;\n      max-width: 600px;\n      margin: 0 auto var(--space-lg);\n      opacity: 0.9;\n    }\n\n    \/* ========================================\n       11. EDUCATIONAL CONTENT\n       ======================================== *\/\n\n    #educational-content {\n      background: var(--color-white);\n      padding: var(--space-2xl) 0;\n    }\n\n    .content-grid {\n      display: grid;\n      grid-template-columns: 1fr;\n      gap: var(--space-xl);\n    }\n\n    @media (min-width: 768px) {\n      .content-grid {\n        grid-template-columns: repeat(2, 1fr);\n      }\n    }\n\n    .content-card {\n      background: var(--color-cream);\n      padding: var(--space-lg);\n      border-radius: var(--radius-card);\n      border-left: 4px solid var(--color-blue-accent);\n    }\n\n    .content-card h3 {\n      color: var(--color-navy-dark);\n      margin-bottom: var(--space-md);\n    }\n\n    .content-card ul {\n      list-style: none;\n      padding-left: 0;\n    }\n\n    .content-card li {\n      padding-left: 1.5rem;\n      margin-bottom: var(--space-sm);\n      position: relative;\n    }\n\n    .content-card li::before {\n      content: &#x27;\u2713&#x27;;\n      position: absolute;\n      left: 0;\n      color: var(--color-blue-accent);\n      font-weight: 700;\n    }\n\n    \/* ========================================\n       12. FAQ SECTION\n       ======================================== *\/\n\n    #faq {\n      background: var(--color-cream);\n      padding: var(--space-2xl) 0;\n    }\n\n    .faq-header {\n      text-align: center;\n      margin-bottom: var(--space-xl);\n    }\n\n    .faq-item {\n      background: var(--color-white);\n      padding: var(--space-lg);\n      border-radius: var(--radius-card);\n      margin-bottom: var(--space-md);\n      box-shadow: var(--shadow-sm);\n    }\n\n    .faq-question {\n      font-family: var(--font-heading);\n      font-size: 1.125rem;\n      color: var(--color-navy-dark);\n      margin-bottom: var(--space-sm);\n      font-weight: 600;\n    }\n\n    .faq-answer {\n      color: var(--color-text);\n      line-height: 1.7;\n    }\n\n    .faq-answer p:last-child {\n      margin-bottom: 0;\n    }\n\n    \/* ========================================\n       13. FOOTER\n       ======================================== *\/\n\n    footer {\n      background: var(--color-navy-dark);\n      color: var(--color-white);\n      padding: var(--space-lg) 0;\n      text-align: center;\n    }\n\n    footer p {\n      margin-bottom: var(--space-sm);\n      opacity: 0.8;\n    }\n\n    footer a {\n      color: var(--color-blue-light);\n    }\n\n    footer a:hover {\n      color: var(--color-white);\n    }\n\n    \/* ========================================\n       14. ANIMATIONS\n       ======================================== *\/\n\n    @keyframes fadeIn {\n      from {\n        opacity: 0;\n        transform: translateY(20px);\n      }\n      to {\n        opacity: 1;\n        transform: translateY(0);\n      }\n    }\n\n    .fade-in {\n      animation: fadeIn 0.6s ease-out;\n    }\n\n    \/* ========================================\n       15. UTILITY CLASSES\n       ======================================== *\/\n\n    .text-center {\n      text-align: center;\n    }\n\n    .mt-lg {\n      margin-top: var(--space-lg);\n    }\n\n    .mb-lg {\n      margin-bottom: var(--space-lg);\n    }\n\n    [hidden] {\n      display: none !important;\n    }\n\n    \/* ========================================\n       16. RESPONSIVE ADJUSTMENTS\n       ======================================== *\/\n\n    @media (max-width: 767px) {\n      .form-section {\n        padding: var(--space-lg);\n      }\n\n      #results {\n        padding: var(--space-lg);\n      }\n\n      .input-with-helper {\n        flex-direction: column;\n      }\n\n      .btn-helper {\n        width: 100%;\n        justify-content: center;\n      }\n    }\n  &lt;\/style&gt;&lt;\/head&gt;&lt;body&gt;&lt;main&gt;&lt;section id=&quot;calculator&quot;&gt;\n      &lt;div class=&quot;container&quot;&gt;\n        &lt;form id=&quot;roi-calculator-form&quot; novalidate&gt;\n          &lt;!-- Water Usage Data Section --&gt;\n          &lt;div class=&quot;form-section&quot;&gt;\n            &lt;h2 class=&quot;form-section-header&quot;&gt;Water Usage Data&lt;\/h2&gt;\n            &lt;p class=&quot;form-section-description&quot;&gt;\n              Optional but helps us provide more accurate savings estimates. Don&#x27;t have this data? No problem\u2014click\n              &quot;I don&#x27;t know&quot; and we&#x27;ll estimate based on industry averages.\n            &lt;\/p&gt;\n\n            &lt;div class=&quot;form-grid&quot;&gt;\n              &lt;!-- Facility Type (drives the estimate when volume is left blank) --&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;facilityType&quot;&gt;Facility Type&lt;\/label&gt;\n                &lt;select id=&quot;facilityType&quot; name=&quot;facilityType&quot; aria-describedby=&quot;facilityType-help&quot;&gt;\n                  &lt;option value=&quot;&quot;&gt;Select your facility type\u2026&lt;\/option&gt;\n                  &lt;option value=&quot;school&quot;&gt;School \/ campus&lt;\/option&gt;\n                  &lt;option value=&quot;hotel&quot;&gt;Hotel \/ hospitality&lt;\/option&gt;\n                  &lt;option value=&quot;industrial&quot;&gt;Industrial \/ manufacturing&lt;\/option&gt;\n                  &lt;option value=&quot;office&quot;&gt;Commercial office&lt;\/option&gt;\n                  &lt;option value=&quot;other&quot;&gt;Other commercial&lt;\/option&gt;\n                &lt;\/select&gt;\n                &lt;span class=&quot;help-text&quot; id=&quot;facilityType-help&quot;&gt;\n                  Don&#x27;t know your non-sewered water volume? Pick your facility type and we&#x27;ll estimate from industry averages.\n                &lt;\/span&gt;\n              &lt;\/div&gt;\n\n              &lt;!-- Annual Water Utility Spend --&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;annualSpend&quot;&gt;\n                  Annual Water Utility Spend\n                  &lt;button type=&quot;button&quot; class=&quot;info-icon&quot; aria-label=&quot;More information about annual water utility spend&quot; data-tooltip=&quot;annualSpend&quot;&gt;\n                    ?\n                  &lt;\/button&gt;\n                &lt;\/label&gt;\n                &lt;div class=&quot;input-with-helper&quot;&gt;\n                  &lt;input\n                    type=&quot;number&quot;\n                    id=&quot;annualSpend&quot;\n                    name=&quot;annualSpend&quot;\n                    placeholder=&quot;e.g., 50000&quot;\n                    min=&quot;0&quot;\n                    step=&quot;1&quot;\n                    aria-describedby=&quot;annualSpend-help annualSpend-error&quot;\n                  &gt;\n                  &lt;button type=&quot;button&quot; class=&quot;btn-helper&quot; data-field=&quot;annualSpend&quot;&gt;I don&#x27;t know&lt;\/button&gt;\n                &lt;\/div&gt;\n                &lt;span class=&quot;help-text&quot; id=&quot;annualSpend-help&quot;&gt;\n                  Your total yearly water and sewer bill. We&#x27;ll show your projected credit savings as a percentage of this. If unsure, estimate from monthly bills.\n                &lt;\/span&gt;\n                &lt;div class=&quot;tooltip&quot; id=&quot;annualSpend-tooltip&quot; hidden&gt;\n                  This helps us understand your baseline costs. Not required for ROI calculation.\n                &lt;\/div&gt;\n                &lt;span class=&quot;error-message&quot; id=&quot;annualSpend-error&quot; role=&quot;alert&quot;&gt;&lt;\/span&gt;\n              &lt;\/div&gt;\n\n              &lt;!-- Annual Water Loss --&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;waterLoss&quot;&gt;\n                  Annual Non-Sewered Water (gallons)\n                  &lt;button type=&quot;button&quot; class=&quot;info-icon&quot; aria-label=&quot;More information about annual non-sewered water&quot; data-tooltip=&quot;waterLoss&quot;&gt;\n                    ?\n                  &lt;\/button&gt;\n                &lt;\/label&gt;\n                &lt;div class=&quot;input-with-helper&quot;&gt;\n                  &lt;input\n                    type=&quot;number&quot;\n                    id=&quot;waterLoss&quot;\n                    name=&quot;waterLoss&quot;\n                    placeholder=&quot;e.g., 500000&quot;\n                    min=&quot;0&quot;\n                    step=&quot;1&quot;\n                    aria-describedby=&quot;waterLoss-help waterLoss-error&quot;\n                  &gt;\n                  &lt;button type=&quot;button&quot; class=&quot;btn-helper&quot; data-field=&quot;waterLoss&quot;&gt;I don&#x27;t know&lt;\/button&gt;\n                &lt;\/div&gt;\n                &lt;span class=&quot;help-text&quot; id=&quot;waterLoss-help&quot;&gt;\n                  Water that evaporates and never enters the sewer (mainly cooling tower evaporation). This is the volume eligible for sewer credits. If unsure, click &quot;I don&#x27;t know.&quot;\n                &lt;\/span&gt;\n                &lt;div class=&quot;tooltip&quot; id=&quot;waterLoss-tooltip&quot; hidden&gt;\n                  You pay sewer charges based on total water use, but evaporated water never reaches the sewer \u2014 so it&#x27;s creditable. Cooling towers typically lose 15-40% of water to evaporation; a 100-ton tower may evaporate 100,000+ gallons\/year.\n                  School campus: ~500,000 gal\/yr | Hotel (200 rooms): ~800,000 gal\/yr | Manufacturing: ~2,000,000 gal\/yr\n                &lt;\/div&gt;\n                &lt;span class=&quot;error-message&quot; id=&quot;waterLoss-error&quot; role=&quot;alert&quot;&gt;&lt;\/span&gt;\n              &lt;\/div&gt;\n\n              &lt;!-- Cost Per Gallon --&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;costPerGallon&quot;&gt;\n                  Sewer Rate ($ per 1,000 gallons)\n                  &lt;button type=&quot;button&quot; class=&quot;info-icon&quot; aria-label=&quot;More information about sewer rate&quot; data-tooltip=&quot;costPerGallon&quot;&gt;\n                    ?\n                  &lt;\/button&gt;\n                &lt;\/label&gt;\n                &lt;div class=&quot;input-with-helper&quot;&gt;\n                  &lt;input\n                    type=&quot;number&quot;\n                    id=&quot;costPerGallon&quot;\n                    name=&quot;costPerGallon&quot;\n                    placeholder=&quot;e.g., 5.20&quot;\n                    min=&quot;0&quot;\n                    step=&quot;0.01&quot;\n                    aria-describedby=&quot;costPerGallon-help costPerGallon-error&quot;\n                  &gt;\n                  &lt;button type=&quot;button&quot; class=&quot;btn-helper&quot; data-field=&quot;costPerGallon&quot;&gt;I don&#x27;t know&lt;\/button&gt;\n                &lt;\/div&gt;\n                &lt;span class=&quot;help-text&quot; id=&quot;costPerGallon-help&quot;&gt;\n                  Your sewer (wastewater) volume charge per 1,000 gallons \u2014 find it on your utility bill. Leave blank to use a Texas-typical default.\n                &lt;\/span&gt;\n                &lt;div class=&quot;tooltip&quot; id=&quot;costPerGallon-tooltip&quot; hidden&gt;\n                  Sewer credits apply only to the sewer portion of your bill, not the water portion. Texas commercial sewer rates typically run $5-$12 per 1,000 gallons (City of Dallas general service is ~$5.20). We use a conservative default if you leave this blank.\n                &lt;\/div&gt;\n                &lt;span class=&quot;error-message&quot; id=&quot;costPerGallon-error&quot; role=&quot;alert&quot;&gt;&lt;\/span&gt;\n              &lt;\/div&gt;\n\n              &lt;!-- Time Horizon --&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;timeHorizon&quot;&gt;\n                  Time Horizon (years)\n                  &lt;button type=&quot;button&quot; class=&quot;info-icon&quot; aria-label=&quot;More information about time horizon&quot; data-tooltip=&quot;timeHorizon&quot;&gt;\n                    ?\n                  &lt;\/button&gt;\n                &lt;\/label&gt;\n                &lt;select\n                  id=&quot;timeHorizon&quot;\n                  name=&quot;timeHorizon&quot;\n                  aria-describedby=&quot;timeHorizon-help&quot;\n                &gt;\n                  &lt;option value=&quot;1&quot;&gt;1 year&lt;\/option&gt;\n                  &lt;option value=&quot;2&quot;&gt;2 years&lt;\/option&gt;\n                  &lt;option value=&quot;3&quot;&gt;3 years&lt;\/option&gt;\n                  &lt;option value=&quot;4&quot;&gt;4 years&lt;\/option&gt;\n                  &lt;option value=&quot;5&quot; selected&gt;5 years&lt;\/option&gt;\n                  &lt;option value=&quot;6&quot;&gt;6 years&lt;\/option&gt;\n                  &lt;option value=&quot;7&quot;&gt;7 years&lt;\/option&gt;\n                  &lt;option value=&quot;8&quot;&gt;8 years&lt;\/option&gt;\n                  &lt;option value=&quot;9&quot;&gt;9 years&lt;\/option&gt;\n                  &lt;option value=&quot;10&quot;&gt;10 years&lt;\/option&gt;\n                &lt;\/select&gt;\n                &lt;span class=&quot;help-text&quot; id=&quot;timeHorizon-help&quot;&gt;\n                  How many years to project savings? Most facilities evaluate 3-7 years.\n                &lt;\/span&gt;\n                &lt;div class=&quot;tooltip&quot; id=&quot;timeHorizon-tooltip&quot; hidden&gt;\n                  Choose a time horizon that matches your facility planning cycle. 5 years is typical for capital planning.\n                &lt;\/div&gt;\n              &lt;\/div&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n\n          &lt;!-- Submit Button --&gt;\n          &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary btn-submit&quot;&gt;\n            Calculate My Water Savings\n          &lt;\/button&gt;\n        &lt;\/form&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n\n    &lt;!-- Results Section (Hidden Initially) --&gt;\n    &lt;section id=&quot;results&quot; hidden aria-live=&quot;polite&quot;&gt;\n      &lt;div class=&quot;container&quot;&gt;\n        &lt;div class=&quot;results-header&quot;&gt;\n          &lt;h2&gt;Your Water Savings Potential&lt;\/h2&gt;\n          &lt;p&gt;Here&#x27;s what we calculated based on your facility data:&lt;\/p&gt;\n        &lt;\/div&gt;\n\n        &lt;!-- Notice for estimates --&gt;\n        &lt;div class=&quot;results-notice&quot; id=&quot;results-notice&quot; hidden&gt;\n          &lt;p&gt;\n            &lt;strong&gt;Note:&lt;\/strong&gt; Some values are estimated based on industry averages.\n            &lt;a href=&quot;#cta&quot;&gt;Get a free water audit&lt;\/a&gt; for precise calculations tailored to your facility.\n          &lt;\/p&gt;\n        &lt;\/div&gt;\n\n        &lt;!-- Results Grid --&gt;\n        &lt;div class=&quot;results-grid&quot; id=&quot;results-grid&quot;&gt;\n          &lt;!-- Dynamic result cards will be inserted here --&gt;\n        &lt;\/div&gt;\n\n        &lt;!-- Done-for-you offer \/ lead capture --&gt;\n        &lt;div class=&quot;form-section&quot; id=&quot;offer-cta&quot; style=&quot;margin-top: var(--space-lg);&quot;&gt;\n          &lt;h2 class=&quot;form-section-header&quot;&gt;Want to capture these savings \u2014 fully managed?&lt;\/h2&gt;\n          &lt;p class=&quot;form-section-description&quot;&gt;\n            RPM can handle the entire process for you. We&#x27;ll analyze your last few months of water and sewer bills,\n            confirm exactly what your facility qualifies for, and set up a fully managed solution. Leave your name\n            and email and we&#x27;ll reach out to make it happen.\n          &lt;\/p&gt;\n          &lt;form id=&quot;roi-offer-form&quot; novalidate&gt;\n            &lt;div class=&quot;form-grid&quot;&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;offerName&quot;&gt;Name&lt;\/label&gt;\n                &lt;input type=&quot;text&quot; id=&quot;offerName&quot; name=&quot;offerName&quot; placeholder=&quot;Your name&quot;\n                  autocomplete=&quot;name&quot; aria-describedby=&quot;offerName-error&quot;&gt;\n                &lt;span class=&quot;error-message&quot; id=&quot;offerName-error&quot; role=&quot;alert&quot;&gt;&lt;\/span&gt;\n              &lt;\/div&gt;\n              &lt;div class=&quot;form-group&quot;&gt;\n                &lt;label for=&quot;offerEmail&quot;&gt;Email&lt;\/label&gt;\n                &lt;input type=&quot;email&quot; id=&quot;offerEmail&quot; name=&quot;offerEmail&quot; placeholder=&quot;you@company.com&quot;\n                  autocomplete=&quot;email&quot; aria-describedby=&quot;offerEmail-error&quot;&gt;\n                &lt;span class=&quot;error-message&quot; id=&quot;offerEmail-error&quot; role=&quot;alert&quot;&gt;&lt;\/span&gt;\n              &lt;\/div&gt;\n            &lt;\/div&gt;\n            &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary btn-submit&quot; style=&quot;margin-top: var(--space-md);&quot;&gt;\n              Analyze My Bills &amp;amp; Set It Up\n            &lt;\/button&gt;\n          &lt;\/form&gt;\n          &lt;p id=&quot;offer-confirmation&quot; role=&quot;status&quot; hidden\n             style=&quot;margin-top: var(--space-md); font-weight: 600; color: var(--color-success);&quot;&gt;&lt;\/p&gt;\n        &lt;\/div&gt;\n\n        &lt;!-- Cross-promotion to the quiz --&gt;\n        &lt;p style=&quot;text-align: center; margin-top: var(--space-lg); font-size: 0.9375rem; color: var(--color-text-light);&quot;&gt;\n          Not sure where your facility stands?\n          &lt;a href=&quot;https:\/\/rpmwes.com\/blog\/water-equity-quiz\/&quot;&gt;Take the 60-second Water Equity Assessment \u2192&lt;\/a&gt;\n        &lt;\/p&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n\n    &lt;!-- CTA Section --&gt;\n    &lt;section id=&quot;cta&quot;&gt;\n      &lt;div class=&quot;container&quot;&gt;\n        &lt;h2&gt;Ready to Maximize Your Water Savings?&lt;\/h2&gt;\n        &lt;p&gt;\n          Our water management experts will conduct a comprehensive facility audit, identify all savings opportunities,\n          and handle the entire evaporation credit application process for you.\n        &lt;\/p&gt;\n        &lt;a href=&quot;https:\/\/rpmwes.com\/#contact&quot; class=&quot;btn btn-primary&quot;&gt;Request Full Savings Report&lt;\/a&gt;\n        &lt;p style=&quot;margin-top: var(--space-md); font-size: 0.9375rem;&quot;&gt;\n          Or email us at &lt;a href=&quot;mailto:info@rpmwes.com&quot; style=&quot;color: var(--color-blue-light);&quot;&gt;info@rpmwes.com&lt;\/a&gt;\n        &lt;\/p&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n\n    &lt;!-- Educational Content --&gt;\n    &lt;section id=&quot;educational-content&quot;&gt;\n      &lt;div class=&quot;container&quot;&gt;\n        &lt;h2 class=&quot;text-center mb-lg&quot;&gt;Understanding Evaporation Credits &amp; Water Savings&lt;\/h2&gt;\n\n        &lt;div class=&quot;content-grid&quot;&gt;\n          &lt;div class=&quot;content-card&quot;&gt;\n            &lt;h3&gt;What Are Evaporation Credits?&lt;\/h3&gt;\n            &lt;p&gt;\n              Evaporation credits (also called sewer credits) reduce your sewer charges for water that doesn&#x27;t enter\n              the sewer system. This includes water lost through:\n            &lt;\/p&gt;\n            &lt;ul&gt;\n              &lt;li&gt;Cooling tower evaporation&lt;\/li&gt;\n              &lt;li&gt;Irrigation and landscaping&lt;\/li&gt;\n              &lt;li&gt;Manufacturing processes&lt;\/li&gt;\n              &lt;li&gt;Swimming pools and water features&lt;\/li&gt;\n            &lt;\/ul&gt;\n            &lt;p&gt;\n              Most municipalities charge sewer fees based on total water consumption\u2014but if water doesn&#x27;t go down\n              the drain, you shouldn&#x27;t pay sewer charges on it. That&#x27;s where evaporation credits come in.\n            &lt;\/p&gt;\n          &lt;\/div&gt;\n\n          &lt;div class=&quot;content-card&quot;&gt;\n            &lt;h3&gt;How RPM Services Help&lt;\/h3&gt;\n            &lt;p&gt;\n              RPM Water Equity Solutions provides comprehensive water management services to maximize your savings:\n            &lt;\/p&gt;\n            &lt;ul&gt;\n              &lt;li&gt;&lt;strong&gt;24\/7 Real-Time Monitoring:&lt;\/strong&gt; IoT-enabled meters track water usage continuously&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Leak Detection:&lt;\/strong&gt; Catch stuck fill valves, overflows, and hidden leaks before they cost thousands&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Evaporation Credit Programs:&lt;\/strong&gt; We handle all applications, documentation, and compliance&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Utility Bill Analysis:&lt;\/strong&gt; Identify billing errors and optimization opportunities&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Water Usage Analytics:&lt;\/strong&gt; Understand consumption patterns and anomalies&lt;\/li&gt;\n            &lt;\/ul&gt;\n          &lt;\/div&gt;\n\n          &lt;div class=&quot;content-card&quot;&gt;\n            &lt;h3&gt;Industries We Serve&lt;\/h3&gt;\n            &lt;p&gt;\n              RPM has helped facilities across multiple sectors reduce water costs and achieve sustainability goals:\n            &lt;\/p&gt;\n            &lt;ul&gt;\n              &lt;li&gt;&lt;strong&gt;Education:&lt;\/strong&gt; K-12 schools, universities, and campus facilities&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Hospitality:&lt;\/strong&gt; Hotels, resorts, and conference centers&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Industrial:&lt;\/strong&gt; Manufacturing plants and distribution centers&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Commercial Real Estate:&lt;\/strong&gt; Office buildings, shopping centers, and mixed-use developments&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Airports:&lt;\/strong&gt; Large campus water management and HVAC optimization&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Healthcare:&lt;\/strong&gt; Hospitals and medical facilities&lt;\/li&gt;\n            &lt;\/ul&gt;\n          &lt;\/div&gt;\n\n          &lt;div class=&quot;content-card&quot;&gt;\n            &lt;h3&gt;Why Water Monitoring Matters&lt;\/h3&gt;\n            &lt;p&gt;\n              Without real-time monitoring, facilities often discover water waste months later through high utility bills.\n              Common issues we catch include:\n            &lt;\/p&gt;\n            &lt;ul&gt;\n              &lt;li&gt;&lt;strong&gt;Stuck Fill Valves:&lt;\/strong&gt; Can waste 50,000+ gallons before detection&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Cooling Tower Overflows:&lt;\/strong&gt; Often caused by faulty float valves&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Hidden Leaks:&lt;\/strong&gt; Underground or in-wall leaks that go unnoticed&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Equipment Malfunctions:&lt;\/strong&gt; HVAC system inefficiencies&lt;\/li&gt;\n              &lt;li&gt;&lt;strong&gt;Billing Errors:&lt;\/strong&gt; Incorrect meter readings or rate classifications&lt;\/li&gt;\n            &lt;\/ul&gt;\n            &lt;p&gt;\n              Our monitoring systems alert you instantly when anomalies occur, preventing costly water loss and\n              enabling proactive maintenance.\n            &lt;\/p&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n\n    &lt;!-- FAQ Section --&gt;\n    &lt;section id=&quot;faq&quot; itemscope itemtype=&quot;https:\/\/schema.org\/FAQPage&quot;&gt;\n      &lt;div class=&quot;container&quot;&gt;\n        &lt;div class=&quot;faq-header&quot;&gt;\n          &lt;h2&gt;Frequently Asked Questions&lt;\/h2&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=&quot;faq-item&quot; itemscope itemprop=&quot;mainEntity&quot; itemtype=&quot;https:\/\/schema.org\/Question&quot;&gt;\n          &lt;h3 class=&quot;faq-question&quot; itemprop=&quot;name&quot;&gt;\n            How do evaporation credits work for commercial buildings?\n          &lt;\/h3&gt;\n          &lt;div class=&quot;faq-answer&quot; itemscope itemprop=&quot;acceptedAnswer&quot; itemtype=&quot;https:\/\/schema.org\/Answer&quot;&gt;\n            &lt;div itemprop=&quot;text&quot;&gt;\n              &lt;p&gt;\n                Evaporation credits reduce your sewer charges by deducting water that doesn&#x27;t enter the sewer system.\n                Municipalities typically calculate sewer fees based on total water consumption, but water lost to evaporation\n                (from cooling towers, irrigation, etc.) never reaches the sewer.\n              &lt;\/p&gt;\n              &lt;p&gt;\n                To qualify, you need to install sub-meters that measure non-sewered water separately and submit documentation\n                to your utility provider. RPM handles the entire application process, ensuring compliance and maximizing your credits.\n              &lt;\/p&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=&quot;faq-item&quot; itemscope itemprop=&quot;mainEntity&quot; itemtype=&quot;https:\/\/schema.org\/Question&quot;&gt;\n          &lt;h3 class=&quot;faq-question&quot; itemprop=&quot;name&quot;&gt;\n            What utilities allow evaporation or sewer credits?\n          &lt;\/h3&gt;\n          &lt;div class=&quot;faq-answer&quot; itemscope itemprop=&quot;acceptedAnswer&quot; itemtype=&quot;https:\/\/schema.org\/Answer&quot;&gt;\n            &lt;div itemprop=&quot;text&quot;&gt;\n              &lt;p&gt;\n                Most major municipalities in Texas and across the U.S. offer evaporation credit programs, including Dallas,\n                Fort Worth, Houston, Austin, San Antonio, and many others. Requirements vary by jurisdiction.\n              &lt;\/p&gt;\n              &lt;p&gt;\n                RPM has relationships with utility providers throughout Texas and can determine your facility&#x27;s eligibility quickly.\n                Even if your municipality doesn&#x27;t have a formal program, we can often negotiate custom arrangements.\n              &lt;\/p&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=&quot;faq-item&quot; itemscope itemprop=&quot;mainEntity&quot; itemtype=&quot;https:\/\/schema.org\/Question&quot;&gt;\n          &lt;h3 class=&quot;faq-question&quot; itemprop=&quot;name&quot;&gt;\n            How to qualify for sewer credits on cooling towers?\n          &lt;\/h3&gt;\n          &lt;div class=&quot;faq-answer&quot; itemscope itemprop=&quot;acceptedAnswer&quot; itemtype=&quot;https:\/\/schema.org\/Answer&quot;&gt;\n            &lt;div itemprop=&quot;text&quot;&gt;\n              &lt;p&gt;\n                Qualifying for cooling tower sewer credits requires:\n              &lt;\/p&gt;\n              &lt;ul&gt;\n                &lt;li&gt;&lt;strong&gt;Sub-metering:&lt;\/strong&gt; Installing dedicated meters on cooling tower make-up water lines&lt;\/li&gt;\n                &lt;li&gt;&lt;strong&gt;Documentation:&lt;\/strong&gt; Submitting meter readings and facility diagrams to your utility&lt;\/li&gt;\n                &lt;li&gt;&lt;strong&gt;Compliance:&lt;\/strong&gt; Meeting local regulations for meter accuracy and reporting frequency&lt;\/li&gt;\n                &lt;li&gt;&lt;strong&gt;Application:&lt;\/strong&gt; Completing utility-specific forms and approval processes&lt;\/li&gt;\n              &lt;\/ul&gt;\n              &lt;p&gt;\n                RPM simplifies this process by handling all technical requirements, installations, and ongoing compliance reporting.\n                Most facilities see approved credits within 60-90 days.\n              &lt;\/p&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=&quot;faq-item&quot; itemscope itemprop=&quot;mainEntity&quot; itemtype=&quot;https:\/\/schema.org\/Question&quot;&gt;\n          &lt;h3 class=&quot;faq-question&quot; itemprop=&quot;name&quot;&gt;\n            What is the ROI of evaporation credits for commercial facilities?\n          &lt;\/h3&gt;\n          &lt;div class=&quot;faq-answer&quot; itemscope itemprop=&quot;acceptedAnswer&quot; itemtype=&quot;https:\/\/schema.org\/Answer&quot;&gt;\n            &lt;div itemprop=&quot;text&quot;&gt;\n              &lt;p&gt;\n                ROI varies by facility size and water usage, but most commercial buildings achieve 300-500% ROI within\n                the first year. For a facility losing 1 million gallons annually to evaporation at typical rates, sewer\n                credits can save $8,000-$15,000 per year.\n              &lt;\/p&gt;\n              &lt;p&gt;\n                When combined with RPM&#x27;s leak detection and water monitoring services, total savings often exceed service\n                costs by 4-6x. Payback periods typically range from 3-9 months.\n              &lt;\/p&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=&quot;faq-item&quot; itemscope itemprop=&quot;mainEntity&quot; itemtype=&quot;https:\/\/schema.org\/Question&quot;&gt;\n          &lt;h3 class=&quot;faq-question&quot; itemprop=&quot;name&quot;&gt;\n            How much water does a cooling tower waste?\n          &lt;\/h3&gt;\n          &lt;div class=&quot;faq-answer&quot; itemscope itemprop=&quot;acceptedAnswer&quot; itemtype=&quot;https:\/\/schema.org\/Answer&quot;&gt;\n            &lt;div itemprop=&quot;text&quot;&gt;\n              &lt;p&gt;\n                Cooling towers typically lose 15-40% of their water to evaporation during normal operation. A 100-ton\n                cooling tower can lose 100,000-200,000 gallons per year to evaporation alone.\n              &lt;\/p&gt;\n              &lt;p&gt;\n                However, malfunctions like stuck fill valves, faulty float mechanisms, or overflow conditions can waste\n                significantly more\u2014often 50,000+ gallons in a single incident. Without real-time monitoring, these issues\n                may go undetected for weeks, resulting in massive water loss and utility costs.\n              &lt;\/p&gt;\n              &lt;p&gt;\n                RPM&#x27;s monitoring systems detect anomalies within minutes, sending instant alerts to facility managers so\n                issues can be resolved quickly.\n              &lt;\/p&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n  &lt;\/main&gt;&lt;script&gt;\n    &#x27;use strict&#x27;;\n\n    \/* ========================================\n       1. CONFIGURATION\n       ======================================== *\/\n\n    const CONFIG = {\n      emailRegex: \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/,\n      localStorageKey: &#x27;rpm_calculator_leads&#x27;,\n      currencyFormatter: new Intl.NumberFormat(&#x27;en-US&#x27;, {\n        style: &#x27;currency&#x27;,\n        currency: &#x27;USD&#x27;,\n        minimumFractionDigits: 0,\n        maximumFractionDigits: 0\n      }),\n      percentFormatter: new Intl.NumberFormat(&#x27;en-US&#x27;, {\n        style: &#x27;percent&#x27;,\n        minimumFractionDigits: 0,\n        maximumFractionDigits: 0\n      }),\n      decimalFormatter: new Intl.NumberFormat(&#x27;en-US&#x27;, {\n        minimumFractionDigits: 2,\n        maximumFractionDigits: 2\n      })\n    };\n\n    \/* ========================================\n       2. SMART DEFAULTS\n       ======================================== *\/\n\n    const DEFAULTS = {\n      \/\/ Sewer rate in $ per 1,000 gallons. Anchored to the City of Dallas\n      \/\/ general-service (commercial) wastewater volume charge (~$5.20\/1,000 gal,\n      \/\/ FY2025-26). Conservative for Texas; many municipalities bill more\n      \/\/ (e.g. Cedar Hill ~$11.60\/1,000 gal). Source: City of Dallas Water Utilities.\n      sewerRatePer1000: 5.20,\n      industryAverages: {\n        school: { waterLoss: 500000, description: &#x27;typical K-12 campus&#x27; },\n        hotel: { waterLoss: 800000, description: &#x27;200-room property&#x27; },\n        industrial: { waterLoss: 2000000, description: &#x27;manufacturing facility&#x27; },\n        office: { waterLoss: 300000, description: &#x27;commercial office building&#x27; },\n        other: { waterLoss: 300000, description: &#x27;commercial facility&#x27; }\n      }\n    };\n\n    \/* ========================================\n       3. STATE MANAGEMENT\n       ======================================== *\/\n\n    const AppState = {\n      formData: {},\n      calculationResults: null,\n      isValid: false,\n      leadQualification: {\n        unknownFields: [],\n        needsAudit: false,\n        estimatedFields: []\n      }\n    };\n\n    \/* ========================================\n       4. VALIDATION RULES\n       ======================================== *\/\n\n    const ValidationRules = {\n      annualSpend: {\n        required: false,\n        validate: (value) =&gt; !value || (parseFloat(value) &gt;= 0),\n        message: &#x27;Please enter a valid positive number&#x27;\n      },\n      waterLoss: {\n        required: false,\n        validate: (value) =&gt; !value || (parseFloat(value) &gt;= 0),\n        message: &#x27;Please enter a valid positive number&#x27;\n      },\n      costPerGallon: {\n        required: false,\n        validate: (value) =&gt; !value || (parseFloat(value) &gt;= 0),\n        message: &#x27;Please enter a valid positive number&#x27;\n      },\n      timeHorizon: {\n        required: true,\n        validate: (value) =&gt; value &amp;&amp; parseInt(value) &gt;= 1 &amp;&amp; parseInt(value) &lt;= 10,\n        message: &#x27;Please select a valid time horizon&#x27;\n      }\n    };\n\n    \/* ========================================\n       5. CALCULATION ENGINE\n       ======================================== *\/\n\n    \/**\n     * Calculate ROI with support for partial data\n     * @param {Object} formData - User input data\n     * @returns {Object} Calculation results with metadata about estimates\n     *\/\n    function calculateROI(formData) {\n      const results = {\n        usedDefaults: {\n          sewerRate: false,\n          waterLoss: false\n        }\n      };\n\n      \/\/ Extract and parse form data\n      let waterLoss = parseFloat(formData.waterLoss) || 0; \/\/ non-sewered (evaporated) gallons\/yr\n      let sewerRatePer1000 = parseFloat(formData.costPerGallon); \/\/ $ per 1,000 gallons\n      const annualSpend = parseFloat(formData.annualSpend) || 0;\n      const timeHorizon = parseInt(formData.timeHorizon) || 5;\n\n      \/\/ Estimate the non-sewered volume from facility type when left blank\n      if (waterLoss &lt;= 0 &amp;&amp; formData.facilityType &amp;&amp; DEFAULTS.industryAverages[formData.facilityType]) {\n        waterLoss = DEFAULTS.industryAverages[formData.facilityType].waterLoss;\n        results.usedDefaults.waterLoss = true;\n      }\n\n      \/\/ Apply the Texas-typical sewer rate default when not provided\n      if (!sewerRatePer1000 &amp;&amp; waterLoss &gt; 0) {\n        sewerRatePer1000 = DEFAULTS.sewerRatePer1000;\n        results.usedDefaults.sewerRate = true;\n      } else if (!sewerRatePer1000) {\n        sewerRatePer1000 = 0;\n      }\n\n      results.sewerRatePer1000 = sewerRatePer1000;\n      results.waterLoss = waterLoss;\n\n      \/\/ Core, defensible number: sewer charges avoided on water that never\n      \/\/ enters the sewer = non-sewered gallons billed at the sewer volume rate.\n      results.annualCreditSavings = (waterLoss \/ 1000) * sewerRatePer1000;\n      results.totalAnnualSavings = results.annualCreditSavings;\n\n      \/\/ Savings as a share of the total water\/sewer bill (only if spend provided)\n      results.hasSpend = annualSpend &gt; 0;\n      results.savingsPctOfSpend = results.hasSpend\n        ? results.totalAnnualSavings \/ annualSpend\n        : null;\n\n      \/\/ Cumulative savings over the chosen horizon\n      results.cumulativeSavings = results.totalAnnualSavings * timeHorizon;\n      results.timeHorizon = timeHorizon;\n\n      \/\/ Determine if this lead needs an audit (3+ unknown fields)\n      results.needsAudit = AppState.leadQualification.unknownFields.length &gt;= 3;\n\n      return results;\n    }\n\n    \/* ========================================\n       6. VALIDATION FUNCTIONS\n       ======================================== *\/\n\n    \/**\n     * Validate the entire form\n     * @param {Object} formData - Form data to validate\n     * @returns {Object} Validation result with isValid flag and errors object\n     *\/\n    function validateForm(formData) {\n      const errors = {};\n      let isValid = true;\n\n      \/\/ Validate each field according to rules\n      for (const [fieldName, rules] of Object.entries(ValidationRules)) {\n        const value = formData[fieldName];\n\n        \/\/ Check required fields\n        if (rules.required &amp;&amp; (!value || value.trim() === &#x27;&#x27;)) {\n          errors[fieldName] = rules.message;\n          isValid = false;\n          continue;\n        }\n\n        \/\/ Skip validation if field is optional and empty\n        if (!rules.required &amp;&amp; (!value || value.trim() === &#x27;&#x27;)) {\n          continue;\n        }\n\n        \/\/ Run field-specific validation\n        if (value &amp;&amp; !rules.validate(value)) {\n          errors[fieldName] = rules.message;\n          isValid = false;\n        }\n      }\n\n      return { isValid, errors };\n    }\n\n    \/**\n     * Show error message for a specific field\n     * @param {string} fieldId - ID of the field element\n     * @param {string} message - Error message to display\n     *\/\n    function showFieldError(fieldId, message) {\n      const field = document.getElementById(fieldId);\n      const errorElement = document.getElementById(`${fieldId}-error`);\n\n      if (field) {\n        field.setAttribute(&#x27;aria-invalid&#x27;, &#x27;true&#x27;);\n      }\n\n      if (errorElement) {\n        errorElement.textContent = message;\n        errorElement.classList.add(&#x27;visible&#x27;);\n      }\n    }\n\n    \/**\n     * Clear error message for a specific field\n     * @param {string} fieldId - ID of the field element\n     *\/\n    function clearFieldError(fieldId) {\n      const field = document.getElementById(fieldId);\n      const errorElement = document.getElementById(`${fieldId}-error`);\n\n      if (field) {\n        field.removeAttribute(&#x27;aria-invalid&#x27;);\n      }\n\n      if (errorElement) {\n        errorElement.textContent = &#x27;&#x27;;\n        errorElement.classList.remove(&#x27;visible&#x27;);\n      }\n    }\n\n    \/**\n     * Clear all form errors\n     *\/\n    function clearAllErrors() {\n      const errorElements = document.querySelectorAll(&#x27;.error-message&#x27;);\n      errorElements.forEach(el =&gt; {\n        el.textContent = &#x27;&#x27;;\n        el.classList.remove(&#x27;visible&#x27;);\n      });\n\n      const invalidFields = document.querySelectorAll(&#x27;[aria-invalid=&quot;true&quot;]&#x27;);\n      invalidFields.forEach(field =&gt; {\n        field.removeAttribute(&#x27;aria-invalid&#x27;);\n      });\n    }\n\n    \/* ========================================\n       7. LEAD CAPTURE FUNCTIONS\n       ======================================== *\/\n\n    \/**\n     * Save lead to localStorage\n     * @param {Object} leadData - Complete lead data including contact info and calculation inputs\n     *\/\n    function saveLeadToLocalStorage(leadData) {\n      try {\n        \/\/ Get existing leads\n        const existingLeads = localStorage.getItem(CONFIG.localStorageKey);\n        const leads = existingLeads ? JSON.parse(existingLeads) : [];\n\n        \/\/ Add new lead with timestamp and qualification data\n        const newLead = {\n          ...leadData,\n          timestamp: new Date().toISOString(),\n          synced: false,\n          leadQualification: AppState.leadQualification\n        };\n\n        leads.push(newLead);\n\n        \/\/ Save back to localStorage\n        localStorage.setItem(CONFIG.localStorageKey, JSON.stringify(leads));\n\n        console.log(&#x27;Lead saved to localStorage:&#x27;, newLead);\n\n        \/\/ Attempt to sync to backend\n        syncLeadToBackend(newLead);\n      } catch (error) {\n        console.error(&#x27;Error saving lead to localStorage:&#x27;, error);\n      }\n    }\n\n    \/**\n     * Sync lead to backend (placeholder with integration examples)\n     * @param {Object} leadData - Lead data to sync\n     *\/\n    function syncLeadToBackend(leadData) {\n      \/\/ Lead capture via Web3Forms \u2014 emails each submission to RPM.\n      \/\/ Create a FREE access key at https:\/\/web3forms.com using mark@masonworld.com\n      \/\/ (just enter the email, no password\/account) and paste it below.\n      \/\/ Until a real key is set, leads still save to localStorage; only the\n      \/\/ email step is skipped, so the calculator keeps working.\n      const WEB3FORMS_ACCESS_KEY = &#x27;9f370fcb-d2f0-4803-b30a-1a6babc9a181&#x27;;\n\n      if (!WEB3FORMS_ACCESS_KEY || WEB3FORMS_ACCESS_KEY.indexOf(&#x27;REPLACE_&#x27;) === 0) {\n        console.warn(&#x27;Web3Forms access key not set \u2014 lead saved locally but not emailed.&#x27;);\n        return;\n      }\n\n      const q = leadData.leadQualification || { unknownFields: [], estimatedFields: [], needsAudit: false };\n      const r = leadData.calculationResults || {};\n      const money = (n) =&gt; (typeof n === &#x27;number&#x27; ? CONFIG.currencyFormatter.format(n) : &#x27;&#x27;);\n\n      const payload = {\n        access_key: WEB3FORMS_ACCESS_KEY,\n        subject: &#x27;ROI Calculator \u2014 managed-solution request: &#x27; + (leadData.name || leadData.companyName || &#x27;Unknown&#x27;),\n        from_name: &#x27;RPM ROI Calculator&#x27;,\n        \/\/ Contact\n        contact_name: leadData.name || leadData.companyName || &#x27;&#x27;,\n        email: leadData.email || &#x27;&#x27;,\n        request_type: leadData.requestType || &#x27;managed solution \/ bill analysis&#x27;,\n        \/\/ Inputs\n        facility_type: leadData.facilityType || &#x27;(not provided)&#x27;,\n        annual_water_spend: leadData.annualSpend || &#x27;(not provided)&#x27;,\n        non_sewered_gallons: leadData.waterLoss || &#x27;(estimated from facility type)&#x27;,\n        sewer_rate_per_1000_gal: leadData.costPerGallon || &#x27;(default used)&#x27;,\n        time_horizon_years: leadData.timeHorizon || &#x27;&#x27;,\n        \/\/ Results\n        annual_credit_savings: money(r.annualCreditSavings),\n        cumulative_savings: money(r.cumulativeSavings),\n        savings_pct_of_bill: (typeof r.savingsPctOfSpend === &#x27;number&#x27;)\n          ? CONFIG.percentFormatter.format(r.savingsPctOfSpend)\n          : &#x27;(spend not provided)&#x27;,\n        \/\/ Lead qualification\n        unknown_fields: (q.unknownFields || []).join(&#x27;, &#x27;) || &#x27;none&#x27;,\n        estimated_fields: (q.estimatedFields || []).join(&#x27;, &#x27;) || &#x27;none&#x27;,\n        needs_audit: q.needsAudit ? &#x27;YES - 3+ unknowns&#x27; : &#x27;no&#x27;,\n        submitted_at: leadData.timestamp || &#x27;&#x27;\n      };\n\n      fetch(&#x27;https:\/\/api.web3forms.com\/submit&#x27;, {\n        method: &#x27;POST&#x27;,\n        headers: { &#x27;Content-Type&#x27;: &#x27;application\/json&#x27;, &#x27;Accept&#x27;: &#x27;application\/json&#x27; },\n        body: JSON.stringify(payload)\n      })\n        .then((response) =&gt; response.json())\n        .then((data) =&gt; {\n          if (data &amp;&amp; data.success) {\n            console.log(&#x27;Lead emailed via Web3Forms.&#x27;);\n            markLeadAsSynced(leadData.timestamp);\n          } else {\n            console.error(&#x27;Web3Forms submission failed:&#x27;, data);\n          }\n        })\n        .catch((error) =&gt; {\n          console.error(&#x27;Error emailing lead via Web3Forms:&#x27;, error);\n        });\n    }\n\n    \/**\n     * Mark a lead as synced in localStorage\n     * @param {string} timestamp - Timestamp of the lead to mark as synced\n     *\/\n    function markLeadAsSynced(timestamp) {\n      try {\n        const existingLeads = localStorage.getItem(CONFIG.localStorageKey);\n        if (!existingLeads) return;\n\n        const leads = JSON.parse(existingLeads);\n        const updatedLeads = leads.map(lead =&gt; {\n          if (lead.timestamp === timestamp) {\n            return { ...lead, synced: true };\n          }\n          return lead;\n        });\n\n        localStorage.setItem(CONFIG.localStorageKey, JSON.stringify(updatedLeads));\n      } catch (error) {\n        console.error(&#x27;Error marking lead as synced:&#x27;, error);\n      }\n    }\n\n    \/* ========================================\n       8. RESULTS DISPLAY FUNCTIONS\n       ======================================== *\/\n\n    \/**\n     * Show results section with calculated values\n     * @param {Object} results - Calculation results from calculateROI()\n     *\/\n    function showResults(results) {\n      const resultsSection = document.getElementById(&#x27;results&#x27;);\n      const resultsGrid = document.getElementById(&#x27;results-grid&#x27;);\n      const resultsNotice = document.getElementById(&#x27;results-notice&#x27;);\n\n      \/\/ Clear existing results\n      resultsGrid.innerHTML = &#x27;&#x27;;\n\n      \/\/ Reset the managed-solution offer so each new calculation re-offers capture\n      const offerForm = document.getElementById(&#x27;roi-offer-form&#x27;);\n      const offerConf = document.getElementById(&#x27;offer-confirmation&#x27;);\n      if (offerForm) {\n        offerForm.reset();\n        offerForm.removeAttribute(&#x27;hidden&#x27;);\n        clearFieldError(&#x27;offerName&#x27;);\n        clearFieldError(&#x27;offerEmail&#x27;);\n      }\n      if (offerConf) { offerConf.setAttribute(&#x27;hidden&#x27;, &#x27;&#x27;); }\n\n      \/\/ Determine if we should show the &quot;estimates&quot; notice\n      const hasEstimates = results.usedDefaults.sewerRate ||\n                          results.usedDefaults.waterLoss ||\n                          results.needsAudit;\n\n      if (hasEstimates) {\n        resultsNotice.removeAttribute(&#x27;hidden&#x27;);\n      } else {\n        resultsNotice.setAttribute(&#x27;hidden&#x27;, &#x27;&#x27;);\n      }\n\n      \/\/ Build result cards dynamically\n      const cards = [];\n\n      \/\/ Card 1: Annual Sewer-Credit Savings (the primary, provable number)\n      cards.push(createResultCard(\n        &#x27;Annual Sewer-Credit Savings&#x27;,\n        CONFIG.currencyFormatter.format(results.annualCreditSavings),\n        &#x27;Sewer charges you stop paying on water that evaporates and never enters the sewer&#x27;,\n        results.usedDefaults.sewerRate || results.usedDefaults.waterLoss\n      ));\n\n      \/\/ Card 2: Savings as a percentage of the total water bill (if spend provided)\n      if (results.hasSpend) {\n        cards.push(createResultCard(\n          &#x27;Savings vs. Your Water Bill&#x27;,\n          CONFIG.percentFormatter.format(results.savingsPctOfSpend),\n          &#x27;Projected annual credit savings as a share of your total water + sewer spend&#x27;,\n          false\n        ));\n      }\n\n      \/\/ Card 3: Cumulative Savings (always show)\n      cards.push(createResultCard(\n        `${results.timeHorizon}-Year Cumulative Savings`,\n        CONFIG.currencyFormatter.format(results.cumulativeSavings),\n        `Total projected sewer-credit savings over ${results.timeHorizon} years`,\n        false\n      ));\n\n      \/\/ Append all cards to the grid\n      cards.forEach(card =&gt; resultsGrid.appendChild(card));\n\n      \/\/ Show results section with animation\n      resultsSection.removeAttribute(&#x27;hidden&#x27;);\n      resultsSection.classList.add(&#x27;fade-in&#x27;);\n\n      \/\/ Smooth scroll to results\n      setTimeout(() =&gt; {\n        resultsSection.scrollIntoView({ behavior: &#x27;smooth&#x27;, block: &#x27;start&#x27; });\n      }, 100);\n    }\n\n    \/**\n     * Create a result card element\n     * @param {string} label - Card label\n     * @param {string} value - Formatted value\n     * @param {string} description - Card description\n     * @param {boolean} isEstimated - Whether this value uses defaults\n     * @returns {HTMLElement} Result card element\n     *\/\n    function createResultCard(label, value, description, isEstimated) {\n      const card = document.createElement(&#x27;div&#x27;);\n      card.className = &#x27;result-card&#x27;;\n\n      const labelElement = document.createElement(&#x27;div&#x27;);\n      labelElement.className = &#x27;result-label&#x27;;\n      labelElement.textContent = label;\n\n      \/\/ Add estimate badge if needed\n      if (isEstimated) {\n        const badge = document.createElement(&#x27;span&#x27;);\n        badge.className = &#x27;estimate-badge&#x27;;\n        badge.textContent = &#x27;Estimated&#x27;;\n        labelElement.appendChild(badge);\n      }\n\n      const valueElement = document.createElement(&#x27;div&#x27;);\n      valueElement.className = &#x27;result-value&#x27;;\n      valueElement.textContent = value;\n\n      const descElement = document.createElement(&#x27;div&#x27;);\n      descElement.className = &#x27;result-description&#x27;;\n      descElement.textContent = description;\n\n      card.appendChild(labelElement);\n      card.appendChild(valueElement);\n      card.appendChild(descElement);\n\n      return card;\n    }\n\n    \/**\n     * Hide results section\n     *\/\n    function hideResults() {\n      const resultsSection = document.getElementById(&#x27;results&#x27;);\n      resultsSection.setAttribute(&#x27;hidden&#x27;, &#x27;&#x27;);\n      resultsSection.classList.remove(&#x27;fade-in&#x27;);\n    }\n\n    \/* ========================================\n       9. EVENT HANDLERS\n       ======================================== *\/\n\n    \/**\n     * Handle form submission\n     * @param {Event} event - Form submit event\n     *\/\n    function handleFormSubmit(event) {\n      event.preventDefault();\n\n      \/\/ Clear previous errors\n      clearAllErrors();\n\n      \/\/ Collect form data\n      const form = event.target;\n      const formData = {\n        facilityType: form.facilityType.value,\n        annualSpend: form.annualSpend.value,\n        waterLoss: form.waterLoss.value,\n        costPerGallon: form.costPerGallon.value,\n        timeHorizon: form.timeHorizon.value\n      };\n\n      \/\/ Validate form\n      const validation = validateForm(formData);\n\n      if (!validation.isValid) {\n        \/\/ Show errors\n        for (const [fieldName, errorMessage] of Object.entries(validation.errors)) {\n          showFieldError(fieldName, errorMessage);\n        }\n\n        \/\/ Focus first error field\n        const firstErrorField = Object.keys(validation.errors)[0];\n        if (firstErrorField) {\n          document.getElementById(firstErrorField)?.focus();\n        }\n\n        return;\n      }\n\n      \/\/ Store form data in app state\n      AppState.formData = formData;\n      AppState.isValid = true;\n\n      \/\/ Track which fields were estimated\n      AppState.leadQualification.estimatedFields = [];\n      if (!formData.costPerGallon &amp;&amp; formData.waterLoss) {\n        AppState.leadQualification.estimatedFields.push(&#x27;sewerRate&#x27;);\n      }\n\n      \/\/ Calculate ROI\n      const results = calculateROI(formData);\n      AppState.calculationResults = results;\n\n      \/\/ Show results. The lead is captured later via the managed-solution offer\n      \/\/ (handleOfferSubmit), so no contact info is required to see the numbers.\n      showResults(results);\n\n      \/\/ Track with Google Analytics (if available)\n      if (typeof gtag !== &#x27;undefined&#x27;) {\n        gtag(&#x27;event&#x27;, &#x27;roi_calculation_complete&#x27;, {\n          &#x27;event_category&#x27;: &#x27;Calculator&#x27;,\n          &#x27;event_label&#x27;: &#x27;ROI Calculated&#x27;,\n          &#x27;value&#x27;: Math.round(results.totalAnnualSavings)\n        });\n      }\n    }\n\n    \/**\n     * Handle the managed-solution offer submission (lead capture).\n     * Fires from the results section after the user has seen their numbers.\n     * @param {Event} event - Form submit event\n     *\/\n    function handleOfferSubmit(event) {\n      event.preventDefault();\n\n      const nameEl = document.getElementById(&#x27;offerName&#x27;);\n      const emailEl = document.getElementById(&#x27;offerEmail&#x27;);\n      const name = nameEl.value.trim();\n      const email = emailEl.value.trim();\n\n      clearFieldError(&#x27;offerName&#x27;);\n      clearFieldError(&#x27;offerEmail&#x27;);\n\n      let ok = true;\n      if (name.length &lt; 2) { showFieldError(&#x27;offerName&#x27;, &#x27;Please enter your name&#x27;); ok = false; }\n      if (!CONFIG.emailRegex.test(email)) { showFieldError(&#x27;offerEmail&#x27;, &#x27;Please enter a valid email address&#x27;); ok = false; }\n      if (!ok) { (name.length &lt; 2 ? nameEl : emailEl).focus(); return; }\n\n      \/\/ Combine the contact with the inputs\/results already computed\n      const leadRecord = {\n        name: name,\n        email: email,\n        requestType: &#x27;managed solution \/ bill analysis&#x27;,\n        ...(AppState.formData || {}),\n        calculationResults: AppState.calculationResults || {},\n        leadQualification: { ...AppState.leadQualification }\n      };\n\n      \/\/ Save locally (backup) and email RPM via Web3Forms\n      saveLeadToLocalStorage(leadRecord);\n\n      \/\/ Confirmation\n      document.getElementById(&#x27;roi-offer-form&#x27;).setAttribute(&#x27;hidden&#x27;, &#x27;&#x27;);\n      const conf = document.getElementById(&#x27;offer-confirmation&#x27;);\n      conf.textContent = &#x27;Thanks, &#x27; + name + &#x27; \u2014 an RPM specialist will reach out shortly to review your bills and map your savings.&#x27;;\n      conf.removeAttribute(&#x27;hidden&#x27;);\n      conf.focus &amp;&amp; conf.focus();\n\n      if (typeof gtag !== &#x27;undefined&#x27;) {\n        gtag(&#x27;event&#x27;, &#x27;roi_lead_capture&#x27;, {\n          &#x27;event_category&#x27;: &#x27;Calculator&#x27;,\n          &#x27;event_label&#x27;: &#x27;Managed solution request&#x27;\n        });\n      }\n    }\n\n    \/**\n     * Handle input field changes (clear errors)\n     * @param {Event} event - Input event\n     *\/\n    function handleFieldInput(event) {\n      const fieldId = event.target.id;\n      if (fieldId) {\n        clearFieldError(fieldId);\n      }\n    }\n\n    \/**\n     * Handle &quot;I don&#x27;t know&quot; button clicks\n     * @param {Event} event - Click event\n     *\/\n    function handleDontKnowClick(event) {\n      event.preventDefault();\n\n      const button = event.currentTarget;\n      const fieldName = button.getAttribute(&#x27;data-field&#x27;);\n      const field = document.getElementById(fieldName);\n\n      if (!field) return;\n\n      \/\/ Toggle active state\n      button.classList.toggle(&#x27;active&#x27;);\n\n      if (button.classList.contains(&#x27;active&#x27;)) {\n        \/\/ Mark as unknown\n        field.value = &#x27;&#x27;;\n        field.disabled = true;\n\n        \/\/ Add to unknown fields array\n        if (!AppState.leadQualification.unknownFields.includes(fieldName)) {\n          AppState.leadQualification.unknownFields.push(fieldName);\n        }\n\n        \/\/ Update button text\n        button.textContent = &#x27;Estimate for me&#x27;;\n\n        \/\/ Check if needs audit (3+ unknowns)\n        AppState.leadQualification.needsAudit = AppState.leadQualification.unknownFields.length &gt;= 3;\n      } else {\n        \/\/ Re-enable field\n        field.disabled = false;\n\n        \/\/ Remove from unknown fields array\n        const index = AppState.leadQualification.unknownFields.indexOf(fieldName);\n        if (index &gt; -1) {\n          AppState.leadQualification.unknownFields.splice(index, 1);\n        }\n\n        \/\/ Update button text\n        button.textContent = &quot;I don&#x27;t know&quot;;\n\n        \/\/ Check if needs audit\n        AppState.leadQualification.needsAudit = AppState.leadQualification.unknownFields.length &gt;= 3;\n      }\n    }\n\n    \/**\n     * Handle info icon clicks (show\/hide tooltips)\n     * @param {Event} event - Click event\n     *\/\n    function handleInfoIconClick(event) {\n      event.preventDefault();\n\n      const button = event.currentTarget;\n      const tooltipId = button.getAttribute(&#x27;data-tooltip&#x27;);\n      const tooltip = document.getElementById(`${tooltipId}-tooltip`);\n\n      if (!tooltip) return;\n\n      \/\/ Toggle tooltip visibility\n      const isHidden = tooltip.hasAttribute(&#x27;hidden&#x27;);\n\n      \/\/ Hide all other tooltips first\n      document.querySelectorAll(&#x27;.tooltip&#x27;).forEach(t =&gt; {\n        t.setAttribute(&#x27;hidden&#x27;, &#x27;&#x27;);\n      });\n\n      if (isHidden) {\n        tooltip.removeAttribute(&#x27;hidden&#x27;);\n\n        \/\/ Close tooltip when clicking outside\n        setTimeout(() =&gt; {\n          document.addEventListener(&#x27;click&#x27;, closeTooltipOnOutsideClick, { once: true });\n        }, 10);\n      }\n    }\n\n    \/**\n     * Close tooltip when clicking outside\n     * @param {Event} event - Click event\n     *\/\n    function closeTooltipOnOutsideClick(event) {\n      const tooltips = document.querySelectorAll(&#x27;.tooltip:not([hidden])&#x27;);\n      tooltips.forEach(tooltip =&gt; {\n        if (!tooltip.contains(event.target) &amp;&amp; !event.target.classList.contains(&#x27;info-icon&#x27;)) {\n          tooltip.setAttribute(&#x27;hidden&#x27;, &#x27;&#x27;);\n        }\n      });\n    }\n\n    \/* ========================================\n       10. INITIALIZATION\n       ======================================== *\/\n\n    \/**\n     * Initialize the calculator\n     *\/\n    function initializeCalculator() {\n      \/\/ Get form element\n      const form = document.getElementById(&#x27;roi-calculator-form&#x27;);\n      if (!form) {\n        console.error(&#x27;Calculator form not found&#x27;);\n        return;\n      }\n\n      \/\/ Attach form submit handler\n      form.addEventListener(&#x27;submit&#x27;, handleFormSubmit);\n\n      \/\/ Managed-solution offer form (lead capture in the results section)\n      const offerForm = document.getElementById(&#x27;roi-offer-form&#x27;);\n      if (offerForm) {\n        offerForm.addEventListener(&#x27;submit&#x27;, handleOfferSubmit);\n      }\n\n      \/\/ Attach input handlers for real-time error clearing\n      const inputs = form.querySelectorAll(&#x27;input, select&#x27;);\n      inputs.forEach(input =&gt; {\n        input.addEventListener(&#x27;input&#x27;, handleFieldInput);\n      });\n\n      \/\/ Attach &quot;I don&#x27;t know&quot; button handlers\n      const helperButtons = form.querySelectorAll(&#x27;.btn-helper&#x27;);\n      helperButtons.forEach(button =&gt; {\n        button.addEventListener(&#x27;click&#x27;, handleDontKnowClick);\n      });\n\n      \/\/ Attach info icon handlers\n      const infoIcons = form.querySelectorAll(&#x27;.info-icon&#x27;);\n      infoIcons.forEach(icon =&gt; {\n        icon.addEventListener(&#x27;click&#x27;, handleInfoIconClick);\n      });\n\n      \/\/ Attempt to sync any unsynced leads from localStorage\n      attemptSyncUnsyncedLeads();\n\n      console.log(&#x27;RPM Water Savings Calculator initialized&#x27;);\n    }\n\n    \/**\n     * Attempt to sync unsynced leads from localStorage\n     *\/\n    function attemptSyncUnsyncedLeads() {\n      try {\n        const existingLeads = localStorage.getItem(CONFIG.localStorageKey);\n        if (!existingLeads) return;\n\n        const leads = JSON.parse(existingLeads);\n        const unsyncedLeads = leads.filter(lead =&gt; !lead.synced);\n\n        if (unsyncedLeads.length &gt; 0) {\n          console.log(`Attempting to sync ${unsyncedLeads.length} unsynced leads`);\n          unsyncedLeads.forEach(lead =&gt; {\n            syncLeadToBackend(lead);\n          });\n        }\n      } catch (error) {\n        console.error(&#x27;Error syncing unsynced leads:&#x27;, error);\n      }\n    }\n\n    \/* ========================================\n       11. RUN ON DOM READY\n       ======================================== *\/\n\n    if (document.readyState === &#x27;loading&#x27;) {\n      document.addEventListener(&#x27;DOMContentLoaded&#x27;, initializeCalculator);\n    } else {\n      initializeCalculator();\n    }\n  &lt;\/script&gt;&lt;\/body&gt;&lt;\/html&gt;\"><\/iframe>\n<script>(function(){var f=document.getElementById('rpm-roi-frame');if(!f)return;function r(){try{var d=f.contentWindow.document;f.style.height=d.documentElement.scrollHeight+'px';}catch(e){}}f.addEventListener('load',function(){r();try{var d=f.contentWindow.document;if(window.ResizeObserver){new ResizeObserver(r).observe(d.documentElement);}d.addEventListener('click',function(){setTimeout(r,450);});}catch(e){}});window.addEventListener('resize',r);setTimeout(r,1200);})();<\/script>\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"How do evaporation credits work for commercial buildings?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Evaporation credits reduce your sewer charges by deducting water that doesn't enter the sewer system.\\n                Municipalities typically calculate sewer fees based on total water consumption, but water lost to evaporation\\n                (from cooling towers, irrigation, etc.) never reaches the sewer.\"}}, {\"@type\": \"Question\", \"name\": \"What utilities allow evaporation or sewer credits?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Most major municipalities in Texas and across the U.S. offer evaporation credit programs, including Dallas,\\n                Fort Worth, Houston, Austin, San Antonio, and many others. Requirements vary by jurisdiction.\"}}, {\"@type\": \"Question\", \"name\": \"How to qualify for sewer credits on cooling towers?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Qualifying for cooling tower sewer credits requires: Sub-metering: Installing dedicated meters on cooling tower make-up water lines; Documentation: Submitting meter readings and facility diagrams to your utility; Compliance: Meeting local regulations for meter accuracy and reporting frequency; Application: Completing utility-specific forms and approval processes; RPM simplifies this process by handling all technical requirements, installations, and ongoing compliance reporting. Most facilities see approved credits within 60-90 days.\"}}, {\"@type\": \"Question\", \"name\": \"What is the ROI of evaporation credits for commercial facilities?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"ROI varies by facility size and water usage, but most commercial buildings achieve 300-500% ROI within\\n                the first year. For a facility losing 1 million gallons annually to evaporation at typical rates, sewer\\n                credits can save $8,000-$15,000 per year.\"}}, {\"@type\": \"Question\", \"name\": \"How much water does a cooling tower waste?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Cooling towers typically lose 15-40% of their water to evaporation during normal operation. A 100-ton\\n                cooling tower can lose 100,000-200,000 gallons per year to evaporation alone.\"}}]}<\/script>","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-463","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/pages\/463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/comments?post=463"}],"version-history":[{"count":8,"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/pages\/463\/revisions"}],"predecessor-version":[{"id":530,"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/pages\/463\/revisions\/530"}],"wp:attachment":[{"href":"https:\/\/rpmwes.com\/blog\/wp-json\/wp\/v2\/media?parent=463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}