{"id":1844,"date":"2026-05-22T02:51:37","date_gmt":"2026-05-22T02:51:37","guid":{"rendered":"https:\/\/aiper.com\/blogs\/?page_id=1844"},"modified":"2026-06-24T03:45:34","modified_gmt":"2026-06-24T03:45:34","slug":"pool-turnover-rate-calculator","status":"publish","type":"page","link":"https:\/\/aiper.com\/blogs\/pool-turnover-rate-calculator\/","title":{"rendered":"Pool Turnover Rate Calculator"},"content":{"rendered":"\n<!-- Pool Turnover Rate Calculator - WordPress HTML Block -->\n<!-- Embed via Custom HTML block, Elementor HTML widget, or page builder of choice -->\n<style>\n    :root {\n        --pool-primary: #1ecad3;\n        --pool-primary-dark: #17a8b0;\n        --pool-primary-light: #e6f9fa;\n        --pool-bg: #ffffff;\n        --pool-text: #2c3e50;\n        --pool-text-light: #5a6c7d;\n        --pool-border: #e0e8ef;\n        --pool-shadow: 0 4px 24px rgba(0, 0, 0, 0.07);\n        --pool-radius: 14px;\n        --pool-radius-sm: 8px;\n        --pool-transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n        --pool-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n    }\n\n    .pool-calc-wrapper {\n        font-family: var(--pool-font);\n        max-width: 580px;\n        margin: 0 auto;\n        background: var(--pool-bg);\n        border-radius: var(--pool-radius);\n        box-shadow: var(--pool-shadow);\n        padding: 32px 28px 28px;\n        box-sizing: border-box;\n        border: 1px solid var(--pool-border);\n        position: relative;\n        overflow: hidden;\n    }\n\n    \/* Decorative top accent bar *\/\n    .pool-calc-wrapper::before {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: 0;\n        right: 0;\n        height: 4px;\n        background: linear-gradient(90deg, #1ecad3 0%, #5de0e8 50%, #1ecad3 100%);\n        border-radius: var(--pool-radius) var(--pool-radius) 0 0;\n    }\n\n    .pool-calc-header {\n        text-align: center;\n        margin-bottom: 26px;\n        padding-top: 6px;\n    }\n\n    .pool-calc-header .pool-icon {\n        display: inline-flex;\n        align-items: center;\n        justify-content: center;\n        width: 50px;\n        height: 50px;\n        border-radius: 50%;\n        background: var(--pool-primary-light);\n        margin-bottom: 12px;\n    }\n\n    .pool-calc-header .pool-icon svg {\n        width: 26px;\n        height: 26px;\n        fill: var(--pool-primary);\n    }\n\n    .pool-calc-header h3 {\n        margin: 0 0 4px;\n        font-size: 1.35rem;\n        font-weight: 700;\n        color: var(--pool-text);\n        letter-spacing: -0.3px;\n    }\n\n    .pool-calc-header p {\n        margin: 0;\n        font-size: 0.9rem;\n        color: var(--pool-text-light);\n        line-height: 1.4;\n    }\n\n    \/* Step indicator *\/\n    .pool-steps-indicator {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        gap: 6px;\n        margin-bottom: 22px;\n        flex-wrap: wrap;\n    }\n\n    .pool-step-dot {\n        width: 30px;\n        height: 30px;\n        border-radius: 50%;\n        background: #eef2f7;\n        color: #8b9aab;\n        font-weight: 700;\n        font-size: 0.8rem;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        transition: var(--pool-transition);\n        flex-shrink: 0;\n    }\n\n    .pool-step-dot.active {\n        background: var(--pool-primary);\n        color: #fff;\n        box-shadow: 0 3px 10px rgba(30, 202, 211, 0.35);\n    }\n\n    .pool-step-dot.done {\n        background: #b8f0f4;\n        color: #0d8a90;\n    }\n\n    .pool-step-line {\n        width: 28px;\n        height: 2px;\n        background: #dce3eb;\n        border-radius: 1px;\n        flex-shrink: 0;\n    }\n\n    .pool-step-line.done {\n        background: var(--pool-primary);\n    }\n\n    \/* Form groups *\/\n    .pool-form-group {\n        margin-bottom: 20px;\n        position: relative;\n    }\n\n    .pool-form-group label {\n        display: block;\n        font-weight: 600;\n        font-size: 0.9rem;\n        color: var(--pool-text);\n        margin-bottom: 6px;\n        letter-spacing: -0.2px;\n    }\n\n    .pool-form-group label .label-number {\n        display: inline-flex;\n        align-items: center;\n        justify-content: center;\n        width: 22px;\n        height: 22px;\n        border-radius: 50%;\n        background: var(--pool-primary);\n        color: #fff;\n        font-size: 0.7rem;\n        font-weight: 700;\n        margin-right: 6px;\n        vertical-align: middle;\n    }\n\n    .pool-input-row {\n        display: flex;\n        gap: 10px;\n        align-items: stretch;\n    }\n\n    .pool-input-field {\n        flex: 1;\n        padding: 12px 14px;\n        border: 2px solid var(--pool-border);\n        border-radius: var(--pool-radius-sm);\n        font-size: 1rem;\n        font-family: var(--pool-font);\n        color: var(--pool-text);\n        background: #fafbfc;\n        transition: var(--pool-transition);\n        box-sizing: border-box;\n        min-width: 0;\n        outline: none;\n        -webkit-appearance: none;\n        -moz-appearance: textfield;\n    }\n\n    .pool-input-field:focus {\n        border-color: var(--pool-primary);\n        background: #fff;\n        box-shadow: 0 0 0 4px rgba(30, 202, 211, 0.08);\n    }\n\n    .pool-input-field::placeholder {\n        color: #b0bec5;\n    }\n\n    \/* Unit toggle buttons *\/\n    .pool-unit-toggle {\n        display: flex;\n        border-radius: var(--pool-radius-sm);\n        overflow: hidden;\n        border: 2px solid var(--pool-border);\n        flex-shrink: 0;\n        background: #fafbfc;\n    }\n\n    .pool-unit-toggle button {\n        padding: 10px 14px;\n        border: none;\n        background: transparent;\n        cursor: pointer;\n        font-family: var(--pool-font);\n        font-size: 0.82rem;\n        font-weight: 600;\n        color: #6b7d8e;\n        transition: var(--pool-transition);\n        white-space: nowrap;\n        letter-spacing: -0.2px;\n        position: relative;\n    }\n\n    .pool-unit-toggle button:not(:last-child) {\n        border-right: 1px solid var(--pool-border);\n    }\n\n    .pool-unit-toggle button:hover {\n        background: #eef7f8;\n        color: #3a5a6a;\n    }\n\n    .pool-unit-toggle button.active {\n        background: var(--pool-primary);\n        color: #ffffff;\n        box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08);\n    }\n\n    \/* Helper text \/ links *\/\n    .pool-helper-text {\n        margin-top: 6px;\n        font-size: 0.82rem;\n        color: #7d8fa0;\n        line-height: 1.4;\n    }\n\n    .pool-helper-text a {\n        color: var(--pool-primary-dark);\n        text-decoration: underline;\n        text-underline-offset: 2px;\n        font-weight: 600;\n        transition: color 0.2s;\n    }\n\n    .pool-helper-text a:hover {\n        color: #0f7a80;\n        text-decoration: none;\n    }\n\n    .pool-helper-text .helper-icon {\n        display: inline-block;\n        margin-right: 3px;\n        font-size: 0.75rem;\n    }\n\n    \/* Buttons row *\/\n    .pool-buttons-row {\n        display: flex;\n        gap: 12px;\n        margin-top: 26px;\n        flex-wrap: wrap;\n    }\n\n    .pool-btn-calculate {\n        flex: 1;\n        min-width: 140px;\n        padding: 14px 24px;\n        background: var(--pool-primary);\n        color: #ffffff;\n        border: none;\n        border-radius: var(--pool-radius-sm);\n        font-size: 1rem;\n        font-weight: 700;\n        font-family: var(--pool-font);\n        cursor: pointer;\n        transition: var(--pool-transition);\n        letter-spacing: -0.2px;\n        box-shadow: 0 4px 14px rgba(30, 202, 211, 0.3);\n        position: relative;\n        overflow: hidden;\n    }\n\n    .pool-btn-calculate:hover {\n        background: var(--pool-primary-dark);\n        box-shadow: 0 6px 20px rgba(30, 202, 211, 0.4);\n        transform: translateY(-1px);\n    }\n\n    .pool-btn-calculate:active {\n        transform: translateY(0);\n        box-shadow: 0 2px 8px rgba(30, 202, 211, 0.25);\n        background: #149ca5;\n    }\n\n    .pool-btn-reset {\n        padding: 14px 20px;\n        background: #ffffff;\n        color: #5a6c7d;\n        border: 2px solid #dce3eb;\n        border-radius: var(--pool-radius-sm);\n        font-size: 0.9rem;\n        font-weight: 600;\n        font-family: var(--pool-font);\n        cursor: pointer;\n        transition: var(--pool-transition);\n        letter-spacing: -0.2px;\n        white-space: nowrap;\n    }\n\n    .pool-btn-reset:hover {\n        background: #f5f7fa;\n        border-color: #c0ccd8;\n        color: #3a4a5a;\n    }\n\n    .pool-btn-reset:active {\n        background: #eef1f5;\n    }\n\n    \/* Result display *\/\n    .pool-result {\n        margin-top: 22px;\n        padding: 18px 20px;\n        background: linear-gradient(135deg, #f0fdfd 0%, #e6f9fa 100%);\n        border-radius: var(--pool-radius-sm);\n        border: 2px solid #c5f0f3;\n        display: none;\n        align-items: center;\n        gap: 14px;\n        animation: poolFadeIn 0.4s ease-out;\n    }\n\n    .pool-result.show {\n        display: flex;\n    }\n\n    @keyframes poolFadeIn {\n        from {\n            opacity: 0;\n            transform: translateY(8px);\n        }\n        to {\n            opacity: 1;\n            transform: translateY(0);\n        }\n    }\n\n    .pool-result-icon {\n        flex-shrink: 0;\n        width: 44px;\n        height: 44px;\n        border-radius: 50%;\n        background: var(--pool-primary);\n        display: flex;\n        align-items: center;\n        justify-content: center;\n    }\n\n    .pool-result-icon svg {\n        width: 20px;\n        height: 20px;\n        fill: #fff;\n    }\n\n    .pool-result-text {\n        flex: 1;\n        min-width: 0;\n    }\n\n    .pool-result-label {\n        font-size: 0.78rem;\n        font-weight: 600;\n        color: #5a7d82;\n        text-transform: uppercase;\n        letter-spacing: 0.5px;\n        margin-bottom: 2px;\n    }\n\n    .pool-result-value {\n        font-size: 1.6rem;\n        font-weight: 800;\n        color: #0d5c62;\n        letter-spacing: -0.5px;\n        line-height: 1.2;\n        word-break: break-all;\n    }\n\n    .pool-result-sub {\n        font-size: 0.8rem;\n        color: #5a8a8f;\n        margin-top: 2px;\n    }\n\n    \/* Error state *\/\n    .pool-input-field.error {\n        border-color: #e74c3c;\n        background: #fefafa;\n        box-shadow: 0 0 0 4px rgba(231, 76, 60, 0.06);\n    }\n\n    .pool-error-msg {\n        color: #c0392b;\n        font-size: 0.78rem;\n        margin-top: 4px;\n        display: none;\n        font-weight: 500;\n    }\n\n    .pool-error-msg.show {\n        display: block;\n    }\n\n    \/* Responsive *\/\n    @media (max-width: 500px) {\n        .pool-calc-wrapper {\n            padding: 22px 16px 20px;\n            border-radius: 10px;\n        }\n        .pool-calc-wrapper::before {\n            border-radius: 10px 10px 0 0;\n        }\n        .pool-input-row {\n            flex-direction: column;\n            gap: 8px;\n        }\n        .pool-unit-toggle {\n            align-self: flex-start;\n            border-radius: var(--pool-radius-sm);\n        }\n        .pool-unit-toggle button {\n            padding: 9px 12px;\n            font-size: 0.76rem;\n        }\n        .pool-btn-calculate {\n            font-size: 0.95rem;\n            padding: 12px 18px;\n        }\n        .pool-btn-reset {\n            padding: 12px 16px;\n            font-size: 0.85rem;\n        }\n        .pool-result-value {\n            font-size: 1.3rem;\n        }\n        .pool-calc-header h3 {\n            font-size: 1.15rem;\n        }\n        .pool-step-dot {\n            width: 26px;\n            height: 26px;\n            font-size: 0.7rem;\n        }\n        .pool-step-line {\n            width: 18px;\n        }\n    }\n<\/style>\n\n<div class=\"pool-calc-wrapper\" id=\"poolTurnoverCalculator\" role=\"form\" aria-label=\"Pool Turnover Rate Calculator\">\n    <!-- Header -->\n    <div class=\"pool-calc-header\">\n        \n      \n        <p>Find out how long it takes to circulate your entire pool volume<\/p>\n    <\/div>\n\n    <!-- Step indicators -->\n    <div class=\"pool-steps-indicator\" aria-hidden=\"true\">\n        <span class=\"pool-step-dot active\" id=\"stepDot1\">1<\/span>\n        <span class=\"pool-step-line\" id=\"stepLine1\"><\/span>\n        <span class=\"pool-step-dot\" id=\"stepDot2\">2<\/span>\n        <span class=\"pool-step-line\" id=\"stepLine2\"><\/span>\n        <span class=\"pool-step-dot\" id=\"stepDot3\">3<\/span>\n    <\/div>\n\n    <!-- Step 1: Pool Volume -->\n    <div class=\"pool-form-group\" id=\"formGroupVolume\">\n        <label for=\"poolVolumeInput\">\n            <span class=\"label-number\">1<\/span> Pool Volume\n        <\/label>\n        <div class=\"pool-input-row\">\n            <input\n            type=\"number\"\n            id=\"poolVolumeInput\"\n            class=\"pool-input-field\"\n            placeholder=\"Enter pool volume\"\n            min=\"1\"\n            step=\"any\"\n            aria-label=\"Pool Volume\"\n            autocomplete=\"off\"\n            >\n            <div class=\"pool-unit-toggle\" id=\"unitToggle\" role=\"radiogroup\" aria-label=\"Volume unit\">\n                <button type=\"button\" data-unit=\"gallons\" class=\"active\" aria-checked=\"true\" role=\"radio\">Gallons<\/button>\n                <button type=\"button\" data-unit=\"liters\" aria-checked=\"false\" role=\"radio\">Liters<\/button>\n                <button type=\"button\" data-unit=\"cubic-meters\" aria-checked=\"false\" role=\"radio\">m\u00b3<\/button>\n            <\/div>\n        <\/div>\n        <p class=\"pool-helper-text\">\n            <span class=\"helper-icon\">\ud83d\udca1<\/span> Not sure? Use our\n            <a href=\"https:\/\/aiper.com\/blogs\/pool-volume-calculator\/\" target=\"_blank\" rel=\"noopener noreferrer\">Pool Volume Calculator<\/a>\n        <\/p>\n        <p class=\"pool-error-msg\" id=\"volumeError\">Please enter a valid pool volume.<\/p>\n    <\/div>\n\n    <!-- Step 2: Pump Flow Rate -->\n    <div class=\"pool-form-group\" id=\"formGroupFlow\">\n        <label for=\"pumpFlowInput\">\n            <span class=\"label-number\">2<\/span> Pump Flow Rate\n        <\/label>\n        <div class=\"pool-input-row\">\n            <input\n            type=\"number\"\n            id=\"pumpFlowInput\"\n            class=\"pool-input-field\"\n            placeholder=\"Enter pump flow rate\"\n            min=\"1\"\n            step=\"any\"\n            aria-label=\"Pump Flow Rate in GPM\"\n            autocomplete=\"off\"\n            >\n            <span style=\"display:inline-flex;align-items:center;padding:12px 14px;background:#f0f4f7;border-radius:8px;font-weight:700;font-size:0.9rem;color:#3a5a6a;white-space:nowrap;flex-shrink:0;border:2px solid #e0e8ef;\">\n                GPM\n            <\/span>\n        <\/div>\n        <p class=\"pool-helper-text\">\n            <span class=\"helper-icon\">\ud83d\udd27<\/span> Need help finding your flow rate?\n            <a href=\"https:\/\/aiper.com\/blogs\/pool-flow-rate-calculator\/\" target=\"_blank\" rel=\"noopener noreferrer\">Pool Flow Rate Calculator<\/a>\n        <\/p>\n        <p class=\"pool-error-msg\" id=\"flowError\">Please enter a valid pump flow rate in GPM.<\/p>\n    <\/div>\n\n    <!-- Step 3: Action Buttons -->\n    <div class=\"pool-buttons-row\">\n        <button type=\"button\" class=\"pool-btn-calculate\" id=\"btnCalculate\" aria-label=\"Calculate turnover rate\">\n            \u23f1\ufe0f Calculate It\n        <\/button>\n        <button type=\"button\" class=\"pool-btn-reset\" id=\"btnReset\" aria-label=\"Reset all fields\">\n            \u21bb Reset\n        <\/button>\n    <\/div>\n\n    <!-- Result Display -->\n    <div class=\"pool-result\" id=\"poolResult\" role=\"status\" aria-live=\"polite\">\n        <div class=\"pool-result-icon\">\n            <svg viewBox=\"0 0 24 24\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                <path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\"\/>\n            <\/svg>\n        <\/div>\n        <div class=\"pool-result-text\">\n            <div class=\"pool-result-label\">Estimated Turnover Time<\/div>\n            <div class=\"pool-result-value\" id=\"resultValue\">&#8212; h &#8212; m<\/div>\n            <div class=\"pool-result-sub\" id=\"resultSub\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<script>\n    (function() {\n        \/\/ DOM references\n        const volumeInput = document.getElementById('poolVolumeInput');\n        const flowInput = document.getElementById('pumpFlowInput');\n        const unitToggle = document.getElementById('unitToggle');\n        const btnCalculate = document.getElementById('btnCalculate');\n        const btnReset = document.getElementById('btnReset');\n        const poolResult = document.getElementById('poolResult');\n        const resultValue = document.getElementById('resultValue');\n        const resultSub = document.getElementById('resultSub');\n        const volumeError = document.getElementById('volumeError');\n        const flowError = document.getElementById('flowError');\n        const stepDot1 = document.getElementById('stepDot1');\n        const stepDot2 = document.getElementById('stepDot2');\n        const stepDot3 = document.getElementById('stepDot3');\n        const stepLine1 = document.getElementById('stepLine1');\n        const stepLine2 = document.getElementById('stepLine2');\n\n        \/\/ State\n        let selectedUnit = 'gallons';\n\n        \/\/ --- Unit toggle logic ---\n        const unitButtons = unitToggle.querySelectorAll('button');\n\n        unitButtons.forEach(btn => {\n            btn.addEventListener('click', function() {\n                unitButtons.forEach(b => {\n                    b.classList.remove('active');\n                    b.setAttribute('aria-checked', 'false');\n                });\n                this.classList.add('active');\n                this.setAttribute('aria-checked', 'true');\n                selectedUnit = this.getAttribute('data-unit');\n                \/\/ Clear result on unit change\n                hideResult();\n                \/\/ Clear errors\n                clearErrors();\n                \/\/ Update placeholder based on unit\n                updatePlaceholder();\n            });\n        });\n\n        function updatePlaceholder() {\n            const placeholders = {\n                'gallons': 'e.g., 15,000',\n                'liters': 'e.g., 56,000',\n                'cubic-meters': 'e.g., 56'\n            };\n            volumeInput.placeholder = placeholders[selectedUnit] || 'Enter pool volume';\n        }\n\n        \/\/ --- Focus event: update step indicators ---\n        volumeInput.addEventListener('focus', function() {\n            setActiveStep(1);\n        });\n        flowInput.addEventListener('focus', function() {\n            setActiveStep(2);\n        });\n\n        function setActiveStep(step) {\n            \/\/ Reset all\n            [stepDot1, stepDot2, stepDot3].forEach(d => d.classList.remove('active', 'done'));\n            [stepLine1, stepLine2].forEach(l => l.classList.remove('done'));\n\n            if (step === 1) {\n                stepDot1.classList.add('active');\n            } else if (step === 2) {\n                stepDot1.classList.add('done');\n                stepLine1.classList.add('done');\n                stepDot2.classList.add('active');\n            } else if (step === 3) {\n                stepDot1.classList.add('done');\n                stepLine1.classList.add('done');\n                stepDot2.classList.add('done');\n                stepLine2.classList.add('done');\n                stepDot3.classList.add('active');\n            }\n        }\n\n        \/\/ --- Clear errors ---\n        function clearErrors() {\n            volumeInput.classList.remove('error');\n            flowInput.classList.remove('error');\n            volumeError.classList.remove('show');\n            flowError.classList.remove('show');\n        }\n\n        \/\/ --- Hide result ---\n        function hideResult() {\n            poolResult.classList.remove('show');\n        }\n\n        \/\/ --- Show result ---\n        function showResult(hours, minutes, totalMinutes) {\n            resultValue.textContent = hours + ' h ' + minutes + ' m';\n            const totalMinRounded = Math.round(totalMinutes);\n            resultSub.textContent = 'Total: ~' + totalMinRounded + ' minutes to complete one full turnover';\n            poolResult.classList.add('show');\n            setActiveStep(3);\n            \/\/ Scroll result into view smoothly\n            poolResult.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n        }\n\n        \/\/ --- Conversion helpers ---\n        function convertToGallons(value, unit) {\n            switch (unit) {\n                case 'gallons':\n                    return value;\n                case 'liters':\n                    \/\/ 1 gallon = 3.78541 liters\n                    return value \/ 3.78541;\n                case 'cubic-meters':\n                    \/\/ 1 cubic meter = 264.172 gallons\n                    return value * 264.172;\n                default:\n                    return value;\n            }\n        }\n\n        \/\/ --- Main calculation ---\n        function calculateTurnover() {\n            clearErrors();\n            hideResult();\n\n            const volumeRaw = volumeInput.value.trim();\n            const flowRaw = flowInput.value.trim();\n\n            let hasError = false;\n\n            \/\/ Validate volume\n            const volumeNum = parseFloat(volumeRaw);\n            if (!volumeRaw || isNaN(volumeNum) || volumeNum <= 0) {\n                volumeInput.classList.add('error');\n                volumeError.classList.add('show');\n                hasError = true;\n            }\n\n            \/\/ Validate flow rate\n            const flowNum = parseFloat(flowRaw);\n            if (!flowRaw || isNaN(flowNum) || flowNum <= 0) {\n                flowInput.classList.add('error');\n                flowError.classList.add('show');\n                hasError = true;\n            }\n\n            if (hasError) {\n                \/\/ Shake or focus first error\n                if (volumeInput.classList.contains('error')) {\n                    volumeInput.focus();\n                } else if (flowInput.classList.contains('error')) {\n                    flowInput.focus();\n                }\n                return;\n            }\n\n            \/\/ Convert pool volume to gallons\n            const volumeGallons = convertToGallons(volumeNum, selectedUnit);\n\n            \/\/ Turnover time in hours = Volume (gal) \/ (Flow Rate GPM \u00d7 60)\n            const turnoverHours = volumeGallons \/ (flowNum * 60);\n\n            \/\/ Convert to hours and minutes\n            const wholeHours = Math.floor(turnoverHours);\n            const remainingMinutes = Math.round((turnoverHours - wholeHours) * 60);\n\n            \/\/ Handle edge case where minutes round to 60\n            let displayHours = wholeHours;\n            let displayMinutes = remainingMinutes;\n            if (remainingMinutes >= 60) {\n                displayHours += 1;\n                displayMinutes = remainingMinutes - 60;\n            }\n            \/\/ If minutes round to 60 again (unlikely but safe)\n            if (displayMinutes === 60) {\n                displayHours += 1;\n                displayMinutes = 0;\n            }\n\n            const totalMinutes = turnoverHours * 60;\n\n            showResult(displayHours, displayMinutes, totalMinutes);\n        }\n\n        \/\/ --- Reset ---\n        function resetAll() {\n            volumeInput.value = '';\n            flowInput.value = '';\n            clearErrors();\n            hideResult();\n            \/\/ Reset unit to gallons\n            selectedUnit = 'gallons';\n            unitButtons.forEach(b => {\n                b.classList.remove('active');\n                b.setAttribute('aria-checked', 'false');\n            });\n            const gallonsBtn = unitToggle.querySelector('[data-unit=\"gallons\"]');\n            if (gallonsBtn) {\n                gallonsBtn.classList.add('active');\n                gallonsBtn.setAttribute('aria-checked', 'true');\n            }\n            updatePlaceholder();\n            setActiveStep(1);\n            volumeInput.focus({ preventScroll: true });\n            \/\/ Reset step dots\n            [stepDot1, stepDot2, stepDot3].forEach(d => d.classList.remove('active', 'done'));\n            [stepLine1, stepLine2].forEach(l => l.classList.remove('done'));\n            stepDot1.classList.add('active');\n        }\n\n        \/\/ --- Event listeners ---\n        btnCalculate.addEventListener('click', calculateTurnover);\n        btnReset.addEventListener('click', resetAll);\n\n        \/\/ Allow Enter key to trigger calculation\n        volumeInput.addEventListener('keydown', function(e) {\n            if (e.key === 'Enter') {\n                e.preventDefault();\n                flowInput.focus();\n            }\n        });\n        flowInput.addEventListener('keydown', function(e) {\n            if (e.key === 'Enter') {\n                e.preventDefault();\n                calculateTurnover();\n            }\n        });\n\n        \/\/ Clear errors on input\n        volumeInput.addEventListener('input', function() {\n            if (volumeInput.classList.contains('error')) {\n                volumeInput.classList.remove('error');\n                volumeError.classList.remove('show');\n            }\n            hideResult();\n        });\n        flowInput.addEventListener('input', function() {\n            if (flowInput.classList.contains('error')) {\n                flowInput.classList.remove('error');\n                flowError.classList.remove('show');\n            }\n            hideResult();\n        });\n\n        \/\/ Initialize\n        updatePlaceholder();\n        setActiveStep(1);\n\n        \/\/ Expose for potential external use\n        window.poolTurnoverCalc = {\n            reset: resetAll,\n            calculate: calculateTurnover,\n            getResult: function() {\n                return {\n                    hours: resultValue.textContent,\n                    visible: poolResult.classList.contains('show')\n                };\n            }\n        };\n    })();\n<\/script>\n\n\n\n<div class=\"aiper-chart-container\">\n    <h2 class=\"aiper-chart-title\">Pool Turnover Rate Quick Reference Chart<\/h2>\n    <p class=\"aiper-chart-desc\">\n        Most residential pools require a full turnover every <b>8 hours<\/b>. Move the slider below to see how your pool volume matches standard pump flows.\n    <\/p>\n\n    <!-- \u4ea4\u4e92\u5f0f\u6ed1\u5757\u5b9e\u65f6\u9ad8\u4eae\u6a21\u5757 -->\n    <div class=\"aiper-interactive-slider-box\">\n        <label for=\"chartVolumeSlider\" class=\"aiper-slider-label\">\n            Your Pool Volume: <span id=\"sliderVolumeVal\">15,000<\/span> Gallons\n        <\/label>\n        <input type=\"range\" id=\"chartVolumeSlider\" min=\"5000\" max=\"40000\" step=\"2500\" value=\"15000\" class=\"aiper-range-slider\">\n        \n        <div class=\"aiper-quick-stat-grid\">\n            <div class=\"aiper-stat-card\">\n                <span class=\"aiper-stat-meta\">Recommended Flow<\/span>\n                <span id=\"statFlow\" class=\"aiper-stat-num\">31 GPM<\/span>\n            <\/div>\n            <div class=\"aiper-stat-card\">\n                <span class=\"aiper-stat-meta\">Est. Turnover Time<\/span>\n                <span id=\"statTime\" class=\"aiper-stat-num\">8 h 0 m<\/span>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <!-- \u6838\u5fc3\u5bf9\u7167\u6570\u636e\u8868 -->\n    <div class=\"aiper-table-responsive\">\n        <table class=\"aiper-data-table\" id=\"turnoverDataTable\">\n            <thead>\n                <tr>\n                    <th>Pool Size (Gal)<\/th>\n                    <th>Pump Flow (GPM)<\/th>\n                    <th>Target Turnover Time<\/th>\n                <\/tr>\n            <\/thead>\n            <tbody>\n                <tr data-vol=\"5000\">\n                    <td>5,000 Gallons<\/td>\n                    <td>15 GPM<\/td>\n                    <td>5 h 33 m<\/td>\n                <\/tr>\n                <tr data-vol=\"10000\">\n                    <td>10,000 Gallons<\/td>\n                    <td>25 GPM<\/td>\n                    <td>6 h 40 m<\/td>\n                <\/tr>\n                <tr data-vol=\"15000\" class=\"aiper-row-highlight\">\n                    <td>15,000 Gallons<\/td>\n                    <td>35 GPM<\/td>\n                    <td>7 h 9 m<\/td>\n                <\/tr>\n                <tr data-vol=\"20000\">\n                    <td>20,000 Gallons<\/td>\n                    <td>45 GPM<\/td>\n                    <td>7 h 24 m<\/td>\n                <\/tr>\n                <tr data-vol=\"25000\">\n                    <td>25,000 Gallons<\/td>\n                    <td>55 GPM<\/td>\n                    <td>7 h 35 m<\/td>\n                <\/tr>\n                <tr data-vol=\"30000\">\n                    <td>30,000 Gallons<\/td>\n                    <td>65 GPM<\/td>\n                    <td>7 h 42 m<\/td>\n                <\/tr>\n                <tr data-vol=\"40000\">\n                    <td>40,000 Gallons<\/td>\n                    <td>85 GPM<\/td>\n                    <td>7 h 51 m<\/td>\n                <\/tr>\n            <\/tbody>\n        <\/table>\n    <\/div>\n<\/div>\n\n<style>\n    .aiper-chart-container {\n        font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n        max-width: 600px;\n        margin: 30px auto;\n        padding: 25px;\n        border: 1px solid #e1e1e1;\n        border-radius: 8px;\n        background-color: #ffffff;\n        box-shadow: 0 4px 12px rgba(0,0,0,0.05);\n    }\n    .aiper-chart-title {\n        color: #333333;\n        margin-top: 0;\n        margin-bottom: 10px;\n        font-size: 20px;\n        font-weight: 600;\n        text-align: center;\n    }\n    .aiper-chart-desc {\n        font-size: 14px;\n        color: #666666;\n        text-align: center;\n        line-height: 1.5;\n        margin-bottom: 25px;\n    }\n    .aiper-interactive-slider-box {\n        background-color: #fafafa;\n        padding: 20px;\n        border-radius: 6px;\n        margin-bottom: 25px;\n        border: 1px dashed #dedede;\n    }\n    .aiper-slider-label {\n        display: block;\n        font-size: 15px;\n        font-weight: 600;\n        color: #444444;\n        margin-bottom: 12px;\n    }\n    .aiper-slider-label span {\n        color: #1ecad3;\n        font-size: 18px;\n    }\n    .aiper-range-slider {\n        -webkit-appearance: none;\n        width: 100%;\n        height: 6px;\n        border-radius: 3px;\n        background: #e1e1e1;\n        outline: none;\n        margin-bottom: 20px;\n    }\n    .aiper-range-slider::-webkit-slider-thumb {\n        -webkit-appearance: none;\n        appearance: none;\n        width: 18px;\n        height: 18px;\n        border-radius: 50%;\n        background: #1ecad3;\n        cursor: pointer;\n        transition: transform 0.1s ease;\n    }\n    .aiper-range-slider::-webkit-slider-thumb:hover {\n        transform: scale(1.2);\n    }\n    .aiper-quick-stat-grid {\n        display: flex;\n        gap: 15px;\n    }\n    .aiper-stat-card {\n        flex: 1;\n        background: #ffffff;\n        padding: 10px;\n        border-radius: 4px;\n        border: 1px solid #eaeaea;\n        text-align: center;\n    }\n    .aiper-stat-meta {\n        display: block;\n        font-size: 11px;\n        text-transform: uppercase;\n        color: #888888;\n        margin-bottom: 4px;\n        letter-spacing: 0.5px;\n    }\n    .aiper-stat-num {\n        font-size: 16px;\n        font-weight: 700;\n        color: #333333;\n    }\n    .aiper-table-responsive {\n        width: 100%;\n        overflow-x: auto;\n    }\n    .aiper-data-table {\n        width: 100%;\n        border-collapse: collapse;\n        font-size: 14px;\n        text-align: left;\n    }\n    .aiper-data-table th {\n        background-color: #f5f5f5;\n        color: #555555;\n        font-weight: 600;\n        padding: 12px;\n        border-bottom: 2px solid #e5e5e5;\n    }\n    .aiper-data-table td {\n        padding: 12px;\n        border-bottom: 1px solid #eeeeee;\n        color: #444444;\n        transition: background-color 0.2s ease;\n    }\n    \/* \u9ad8\u4eae\u884c\u6837\u5f0f *\/\n    .aiper-data-table tr.aiper-row-highlight td {\n        background-color: #f4fdfd !important;\n        color: #1ecad3;\n        font-weight: 600;\n    }\n    .aiper-data-table tr:hover td {\n        background-color: #fcfcfc;\n    }\n<\/style>\n\n<script>\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n    const slider = document.getElementById(\"chartVolumeSlider\");\n    const volumeLabel = document.getElementById(\"sliderVolumeVal\");\n    const statFlow = document.getElementById(\"statFlow\");\n    const statTime = document.getElementById(\"statTime\");\n    const tableRows = document.querySelectorAll(\"#turnoverDataTable tbody tr\");\n\n    \/\/ \u6839\u636e\u6ed1\u5757\u4f30\u7b97\u6807\u51c6\u7684\u914d\u6bd4\u53c2\u6570\uff08\u6a21\u62df\u63a8\u8350\u6d41\u901f\u4ee5\u8fbe\u5230\u7ea68\u5c0f\u65f6\u5faa\u73af\uff09\n    function updateChartMetrics(volume) {\n        volumeLabel.textContent = Number(volume).toLocaleString();\n        \n        \/\/ \u6309\u7167 8\u5c0f\u65f6(480\u5206\u949f) \u5faa\u73af\u57fa\u51c6\u53cd\u63a8\u63a8\u8350\u6d41\u901f (GPM = Volume \/ 480)\n        \/\/ \u9002\u5f53\u5411\u4e0a\u53d6\u6574\u786e\u4fdd\u6d41\u901f\u4e3a\u6574\u6570\n        const recommendedGPM = Math.max(15, Math.ceil(volume \/ 480));\n        statFlow.textContent = recommendedGPM + \" GPM\";\n        \n        \/\/ \u8ba1\u7b97\u771f\u5b9e\u8017\u65f6\u5e76\u683c\u5f0f\u5316\n        const totalMinutes = volume \/ recommendedGPM;\n        const h = Math.floor(totalMinutes \/ 60);\n        const m = Math.round(totalMinutes % 60);\n        statTime.textContent = h + \" h \" + m + \" m\";\n\n        \/\/ \u52a8\u6001\u540c\u6b65\u9ad8\u4eae\u8868\u683c\u4e2d\u6700\u8fd1\u4f3c\u7684\u884c\n        let closestRow = null;\n        let minDiff = Infinity;\n\n        tableRows.forEach(row => {\n            row.classList.remove(\"aiper-row-highlight\");\n            const rowVol = parseInt(row.getAttribute(\"data-vol\"));\n            const diff = Math.abs(volume - rowVol);\n            if (diff < minDiff) {\n                minDiff = diff;\n                closestRow = row;\n            }\n        });\n\n        if (closestRow) {\n            closestRow.classList.add(\"aiper-row-highlight\");\n        }\n    }\n\n    slider.addEventListener(\"input\", function(e) {\n        updateChartMetrics(e.target.value);\n    });\n\n    \/\/ \u521d\u59cb\u5316\u8fd0\u884c\u4e00\u6b21\n    updateChartMetrics(slider.value);\n});\n<\/script>\n\n\n\n<!-- Pool Flow Rate Chart - Independent Module -->\n<!-- Embed via WordPress Custom HTML block or any page builder -->\n<style>\n    :root {\n        --chart-primary: #1ecad3;\n        --chart-primary-dark: #17a8b0;\n        --chart-primary-light: #e6f9fa;\n        --chart-bg: #ffffff;\n        --chart-text: #2c3e50;\n        --chart-text-light: #5a6c7d;\n        --chart-border: #e0e8ef;\n        --chart-shadow: 0 4px 24px rgba(0, 0, 0, 0.07);\n        --chart-radius: 14px;\n        --chart-radius-sm: 8px;\n        --chart-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n    }\n\n    .flow-chart-wrapper {\n        font-family: var(--chart-font);\n        max-width: 680px;\n        margin: 0 auto 24px;\n        background: var(--chart-bg);\n        border-radius: var(--chart-radius);\n        box-shadow: var(--chart-shadow);\n        padding: 28px 24px 22px;\n        box-sizing: border-box;\n        border: 1px solid var(--chart-border);\n        position: relative;\n        overflow: hidden;\n    }\n\n    \/* Top accent *\/\n    .flow-chart-wrapper::before {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: 0;\n        right: 0;\n        height: 4px;\n        background: linear-gradient(90deg, #1ecad3 0%, #5de0e8 50%, #1ecad3 100%);\n        border-radius: var(--chart-radius) var(--chart-radius) 0 0;\n    }\n\n    .flow-chart-header {\n        display: flex;\n        align-items: center;\n        gap: 12px;\n        margin-bottom: 6px;\n        padding-top: 4px;\n    }\n\n    .flow-chart-header .chart-icon {\n        flex-shrink: 0;\n        width: 44px;\n        height: 44px;\n        border-radius: 50%;\n        background: var(--chart-primary-light);\n        display: flex;\n        align-items: center;\n        justify-content: center;\n    }\n\n    .flow-chart-header .chart-icon svg {\n        width: 22px;\n        height: 22px;\n        fill: var(--chart-primary);\n    }\n\n    .flow-chart-header .chart-title-group {\n        flex: 1;\n        min-width: 0;\n    }\n\n    .flow-chart-header h4 {\n        margin: 0 0 2px;\n        font-size: 1.15rem;\n        font-weight: 700;\n        color: var(--chart-text);\n        letter-spacing: -0.3px;\n    }\n\n    .flow-chart-header .chart-subtitle {\n        font-size: 0.82rem;\n        color: var(--chart-text-light);\n        margin: 0;\n    }\n\n    .chart-container {\n        position: relative;\n        width: 100%;\n        height: 380px;\n        margin: 10px 0 6px;\n    }\n\n    .chart-container canvas {\n        width: 100% !important;\n        height: 100% !important;\n    }\n\n    \/* Legend custom row *\/\n    .chart-legend-custom {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 18px;\n        justify-content: center;\n        margin-top: 10px;\n        font-size: 0.82rem;\n        color: var(--chart-text-light);\n    }\n\n    .chart-legend-custom .legend-item {\n        display: flex;\n        align-items: center;\n        gap: 6px;\n        font-weight: 500;\n    }\n\n    .legend-dot {\n        width: 12px;\n        height: 12px;\n        border-radius: 3px;\n        flex-shrink: 0;\n    }\n\n    .legend-dot.min {\n        background: #f9c74f;\n        border: 1px solid #e0a800;\n    }\n    .legend-dot.max {\n        background: #f9844a;\n        border: 1px solid #d9662c;\n    }\n    .legend-dot.optimal {\n        background: #1ecad3;\n        border: 1px solid #149ca5;\n    }\n\n    .chart-note {\n        text-align: center;\n        margin-top: 8px;\n        font-size: 0.75rem;\n        color: #8b9aab;\n        line-height: 1.4;\n    }\n\n    .chart-note a {\n        color: var(--chart-primary-dark);\n        text-decoration: underline;\n        text-underline-offset: 2px;\n        font-weight: 600;\n    }\n\n    .chart-note a:hover {\n        color: #0f7a80;\n        text-decoration: none;\n    }\n\n    \/* Responsive *\/\n    @media (max-width: 500px) {\n        .flow-chart-wrapper {\n            padding: 20px 12px 16px;\n            border-radius: 10px;\n        }\n        .flow-chart-wrapper::before {\n            border-radius: 10px 10px 0 0;\n        }\n        .chart-container {\n            height: 290px;\n        }\n        .flow-chart-header h4 {\n            font-size: 1rem;\n        }\n        .chart-legend-custom {\n            gap: 10px;\n            font-size: 0.75rem;\n        }\n    }\n<\/style>\n\n<div class=\"flow-chart-wrapper\" id=\"poolFlowChartModule\" role=\"region\" aria-label=\"Pool Pipe Flow Rate Recommendation Chart\">\n    <!-- Header -->\n    <div class=\"flow-chart-header\">\n        <div class=\"chart-icon\">\n            <!-- Flow \/ pipe icon -->\n            <svg viewBox=\"0 0 24 24\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                <path d=\"M22 14h-2v-2h-2v2h-2v2h2v2h2v-2h2v-2zM4 8h2v2h2V8h2V6H8V4H6v2H4v2zm12-4V2H6v2H4v2H2v2h2v2h2v2h2v2h2v-2H8v-2h2v-2H8V8h2V6h-2V4h6zm-2 12v-2h-2v2h-2v2h2v2h2v-2h2v-2h-2z\" fill-rule=\"evenodd\"\/>\n            <\/svg>\n        <\/div>\n        <div class=\"chart-title-group\">\n            <h2>Recommended Flow Rates by Pipe Size<\/h2>\n            <p class=\"chart-subtitle\">Standard PVC schedule 40 pool plumbing<\/p>\n        <\/div>\n    <\/div>\n\n    <!-- Chart canvas -->\n    <div class=\"chart-container\">\n        <canvas id=\"flowRateChartCanvas\" aria-label=\"Bar chart showing minimum, maximum, and optimal flow rates in GPM for pipe sizes 1.5 to 3 inches\"><\/canvas>\n    <\/div>\n\n    <!-- Custom legend -->\n    <div class=\"chart-legend-custom\">\n        <span class=\"legend-item\"><span class=\"legend-dot min\"><\/span> Min Flow (GPM)<\/span>\n        <span class=\"legend-item\"><span class=\"legend-dot max\"><\/span> Max Flow (GPM)<\/span>\n        <span class=\"legend-item\"><span class=\"legend-dot optimal\"><\/span> Optimal (6\u20138 ft\/s)<\/span>\n    <\/div>\n\n    <p class=\"chart-note\">\n        \ud83d\udca1 Based on standard industry guidelines for PVC pool plumbing.\n   \n    <\/p>\n<\/div>\n\n<!-- Chart.js CDN -->\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@4.4.8\/dist\/chart.umd.min.js\">\n<\/script>\n\n<script>\n    (function() {\n        \/\/ Wait for Chart.js to load\n        function initChart() {\n            const canvas = document.getElementById('flowRateChartCanvas');\n            if (!canvas) return;\n\n            const ctx = canvas.getContext('2d');\n\n            \/\/ Destroy previous chart instance if any (for re-initialization safety)\n            if (window.flowRateChartInstance) {\n                window.flowRateChartInstance.destroy();\n            }\n\n            \/\/ Data: Pipe sizes (inches) vs Flow rates (GPM)\n            const pipeSizes = ['1.5\"', '2\"', '2.5\"', '3\"'];\n\n            \/\/ Typical min\/max\/optimal flow rates in GPM for each pipe size\n            const minFlow = [28, 45, 70, 100];\n            const maxFlow = [50, 80, 120, 170];\n            const optimalFlow = [38, 62, 95, 135];\n\n            \/\/ Create gradient fill for optimal bars\n            const gradientOptimal = ctx.createLinearGradient(0, 0, 0, 400);\n            gradientOptimal.addColorStop(0, 'rgba(30, 202, 211, 0.9)');\n            gradientOptimal.addColorStop(1, 'rgba(30, 202, 211, 0.45)');\n\n            const gradientMin = ctx.createLinearGradient(0, 0, 0, 400);\n            gradientMin.addColorStop(0, 'rgba(249, 199, 79, 0.85)');\n            gradientMin.addColorStop(1, 'rgba(249, 199, 79, 0.35)');\n\n            const gradientMax = ctx.createLinearGradient(0, 0, 0, 400);\n            gradientMax.addColorStop(0, 'rgba(249, 132, 74, 0.85)');\n            gradientMax.addColorStop(1, 'rgba(249, 132, 74, 0.35)');\n\n            window.flowRateChartInstance = new Chart(ctx, {\n                type: 'bar',\n                data: {\n                    labels: pipeSizes,\n                    datasets: [{\n                        label: 'Min Flow (GPM)',\n                        data: minFlow,\n                        backgroundColor: gradientMin,\n                        borderColor: '#f9c74f',\n                        borderWidth: 1.5,\n                        borderRadius: 6,\n                        borderSkipped: false,\n                        order: 3,\n                    }, {\n                        label: 'Max Flow (GPM)',\n                        data: maxFlow,\n                        backgroundColor: gradientMax,\n                        borderColor: '#f9844a',\n                        borderWidth: 1.5,\n                        borderRadius: 6,\n                        borderSkipped: false,\n                        order: 2,\n                    }, {\n                        label: 'Optimal (6\u20138 ft\/s)',\n                        data: optimalFlow,\n                        backgroundColor: gradientOptimal,\n                        borderColor: '#1ecad3',\n                        borderWidth: 2,\n                        borderRadius: 6,\n                        borderSkipped: false,\n                        order: 1,\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    maintainAspectRatio: false,\n                    interaction: {\n                        mode: 'index',\n                        intersect: false,\n                    },\n                    plugins: {\n                        legend: {\n                            display: false, \/\/ We use custom legend\n                        },\n                        tooltip: {\n                            backgroundColor: '#1e293b',\n                            titleFont: { weight: 'bold', size: 13, family: \"'Segoe UI', Roboto, sans-serif\" },\n                            bodyFont: { size: 12, family: \"'Segoe UI', Roboto, sans-serif\" },\n                            padding: 12,\n                            cornerRadius: 8,\n                            displayColors: true,\n                            callbacks: {\n                                label: function(context) {\n                                    return context.dataset.label + ': ' + context.raw + ' GPM';\n                                }\n                            }\n                        },\n                    },\n                    scales: {\n                        x: {\n                            title: {\n                                display: true,\n                                text: 'Pipe Diameter (inches)',\n                                color: '#5a6c7d',\n                                font: {\n                                    weight: '600',\n                                    size: 12,\n                                    family: \"'Segoe UI', Roboto, sans-serif\"\n                                },\n                            },\n                            grid: {\n                                display: false,\n                            },\n                            ticks: {\n                                color: '#3a4a5a',\n                                font: {\n                                    weight: '500',\n                                    size: 11,\n                                },\n                            },\n                        },\n                        y: {\n                            title: {\n                                display: true,\n                                text: 'Flow Rate (GPM)',\n                                color: '#5a6c7d',\n                                font: {\n                                    weight: '600',\n                                    size: 12,\n                                    family: \"'Segoe UI', Roboto, sans-serif\"\n                                },\n                            },\n                            beginAtZero: true,\n                            max: 190,\n                            ticks: {\n                                stepSize: 20,\n                                callback: function(value) {\n                                    return value + ' GPM';\n                                },\n                                color: '#3a4a5a',\n                                font: {\n                                    size: 10.5,\n                                },\n                            },\n                            grid: {\n                                color: '#eef2f7',\n                                drawBorder: false,\n                            },\n                        },\n                    },\n                    animation: {\n                        duration: 1000,\n                        easing: 'easeOutQuart',\n                    },\n                },\n            });\n        }\n\n        \/\/ Initialize on load\n        if (typeof Chart !== 'undefined') {\n            initChart();\n        } else {\n            \/\/ If Chart.js loads asynchronously, wait for it\n            window.addEventListener('load', function() {\n                if (typeof Chart !== 'undefined') {\n                    initChart();\n                } else {\n                    \/\/ Fallback: retry after a short delay\n                    setTimeout(function() {\n                        if (typeof Chart !== 'undefined') {\n                            initChart();\n                        }\n                    }, 600);\n                }\n            });\n        }\n\n        \/\/ Handle dynamic re-insertion (e.g., in some page builders)\n        document.addEventListener('DOMContentLoaded', function() {\n            if (typeof Chart !== 'undefined' && !window.flowRateChartInstance) {\n                initChart();\n            }\n        });\n    })();\n<\/script>\n\n\n<!-- aiper-tool-links -->\n<div class=\"aiper-tool-links\">\n  <div class=\"aiper-tl-section\">\n    <div class=\"aiper-tl-heading\">More Tools<\/div>\n    <div class=\"aiper-tl-tags\">\n      <a href=\"https:\/\/aiper.com\/blogs\/pool-flow-rate-calculator\/\" class=\"aiper-tl-tag\">Pool Flow Rate Calculator<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/pool-fill-time-calculator\/\" class=\"aiper-tl-tag\">Pool Fill Time Calculator<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/pool-saturation-index-calculator\/\" class=\"aiper-tl-tag\">Pool Saturation Index Calculator<\/a>\n    <\/div>\n  <\/div>\n  <div class=\"aiper-tl-section\">\n    <div class=\"aiper-tl-heading\">Related Articles<\/div>\n    <div class=\"aiper-tl-tags\">\n      <a href=\"https:\/\/aiper.com\/blogs\/how-to-lower-alkalinity-in-pool\/\" class=\"aiper-tl-tag\">How to Lower Alkalinity in a Pool (and When You Actually Need To)<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/pool-robot-gets-stuck-on-main-drain\/\" class=\"aiper-tl-tag\">Why Does Your Pool Robot Get Stuck on the Main Drain?<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/how-to-winterize-inground-pool\/\" class=\"aiper-tl-tag\">How to Winterize an Inground Pool: Step-by-Step<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/how-to-get-rid-of-algae-in-pool\/\" class=\"aiper-tl-tag\">The Complete Guide to Pool Algae: How to Identify, Treat, and Prevent Every Type<\/a>\n    <\/div>\n  <\/div>\n<\/div>\n\n<style>\n.aiper-tool-links{margin:2.5rem 0 1.5rem;padding:1.5rem 1.75rem;background:linear-gradient(135deg,rgba(148,134,247,.04),rgba(30,202,211,.04));border-radius:12px;border:1px solid rgba(148,134,247,.10)}\n.aiper-tl-section{margin-bottom:1.25rem}\n.aiper-tl-section:last-child{margin-bottom:0}\n.aiper-tl-heading{font-size:.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:#8899aa;margin:0 0 .65rem}\n.aiper-tl-tags{display:flex;flex-wrap:wrap;gap:.5rem}\n.aiper-tl-tag{display:inline-block;padding:.4rem .95rem;font-size:.82rem;font-weight:500;line-height:1.35;color:#9486f7;background:rgba(148,134,247,.055);border:1px solid rgba(30,202,211,.25);border-radius:22px;text-decoration:none;transition:all .18s}\n.aiper-tl-tag:hover{background:#1ecad3;color:#fff;border-color:#1ecad3;box-shadow:0 2px 10px rgba(30,202,211,.22)}\n<\/style>","protected":false},"excerpt":{"rendered":"<p>Find out how long it takes to circulate your entire pool volume 1 2 3 1 Pool Volume Gallons Liters m\u00b3 \ud83d\udca1 Not sure? Use our Pool Volume Calculator Please enter a valid pool volume. 2 Pump Flow Rate GPM \ud83d\udd27 Need help finding your flow rate? Pool Flow Rate Calculator Please enter a valid&#8230;<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-1844","page","type-page","status-publish","hentry"],"lang":"en","translations":{"en":1844,"de":2161,"fr":2162,"es":2163},"_links":{"self":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/1844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/comments?post=1844"}],"version-history":[{"count":7,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/1844\/revisions"}],"predecessor-version":[{"id":4281,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/1844\/revisions\/4281"}],"wp:attachment":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/media?parent=1844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}