{"id":821,"date":"2025-09-12T14:16:52","date_gmt":"2025-09-12T14:16:52","guid":{"rendered":"https:\/\/vodalandusport.wpenginepowered.com\/?page_id=821"},"modified":"2025-10-03T17:07:41","modified_gmt":"2025-10-03T17:07:41","slug":"catchment-area-calculator","status":"publish","type":"page","link":"https:\/\/www.vodalandsolutions.com\/es\/catchment-area-calculator\/","title":{"rendered":"Catchment Area Calculator"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"821\" class=\"elementor elementor-821\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9b7d647 e-con-full e-flex e-con e-parent\" data-id=\"9b7d647\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a293536 elementor-widget__width-inherit elementor-widget elementor-widget-template\" data-id=\"a293536\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"template.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-template\">\n\t\t\t\t\t<div data-elementor-type=\"section\" data-elementor-id=\"1788\" class=\"elementor elementor-1788\" data-elementor-post-type=\"elementor_library\">\n\t\t\t<div class=\"elementor-element elementor-element-5586d153 e-con-full header-sub e-flex e-con e-parent\" data-id=\"5586d153\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-5d39881a e-grid e-con-boxed e-con e-child\" data-id=\"5d39881a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-495f3aa0 elementor-nav-menu__align-end elementor-nav-menu--dropdown-none below-links elementor-widget elementor-widget-nav-menu\" data-id=\"495f3aa0\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;layout&quot;:&quot;horizontal&quot;,&quot;submenu_icon&quot;:{&quot;value&quot;:&quot;&lt;svg aria-hidden=\\&quot;true\\&quot; class=\\&quot;e-font-icon-svg e-fas-caret-down\\&quot; viewBox=\\&quot;0 0 320 512\\&quot; xmlns=\\&quot;http:\\\/\\\/www.w3.org\\\/2000\\\/svg\\&quot;&gt;&lt;path d=\\&quot;M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z\\&quot;&gt;&lt;\\\/path&gt;&lt;\\\/svg&gt;&quot;,&quot;library&quot;:&quot;fa-solid&quot;}}\" data-widget_type=\"nav-menu.default\">\n\t\t\t\t\t\t\t\t<nav aria-label=\"Menu\" class=\"elementor-nav-menu--main elementor-nav-menu__container elementor-nav-menu--layout-horizontal e--pointer-underline e--animation-fade\">\n\t\t\t\t<ul id=\"menu-1-495f3aa0\" class=\"elementor-nav-menu\"><li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-118\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/dashboard\/\" class=\"elementor-item menu-link\">Dashboard<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-122\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/my-projects\/\" class=\"elementor-item menu-link\">My Projects<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-201\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/my-documents\/\" class=\"elementor-item menu-link\">My Documents<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1638\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/technical-calculations\/\" class=\"elementor-item menu-link\">Technical Calculations<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-907\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/technical-request\/\" class=\"elementor-item menu-link\">Technical Requests<\/a><\/li>\n<\/ul>\t\t\t<\/nav>\n\t\t\t\t\t\t<nav class=\"elementor-nav-menu--dropdown elementor-nav-menu__container\" aria-hidden=\"true\">\n\t\t\t\t<ul id=\"menu-2-495f3aa0\" class=\"elementor-nav-menu\"><li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-118\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/dashboard\/\" class=\"elementor-item menu-link\" tabindex=\"-1\">Dashboard<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-122\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/my-projects\/\" class=\"elementor-item menu-link\" tabindex=\"-1\">My Projects<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-201\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/my-documents\/\" class=\"elementor-item menu-link\" tabindex=\"-1\">My Documents<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1638\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/technical-calculations\/\" class=\"elementor-item menu-link\" tabindex=\"-1\">Technical Calculations<\/a><\/li>\n<li class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-907\"><a href=\"https:\/\/www.vodalandsolutions.com\/es\/technical-request\/\" class=\"elementor-item menu-link\" tabindex=\"-1\">Technical Requests<\/a><\/li>\n<\/ul>\t\t\t<\/nav>\n\t\t\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-441a7b70 e-con-full user-sec e-flex e-con e-child\" data-id=\"441a7b70\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-3765e1b7 e-con-full e-flex e-con e-child\" data-id=\"3765e1b7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-247f8006 e-con-full elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"247f8006\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ffb3262 elementor-widget elementor-widget-shortcode\" data-id=\"ffb3262\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1f4f2ef e-flex e-con-boxed e-con e-parent\" data-id=\"1f4f2ef\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32d9629 elementor-widget elementor-widget-shortcode\" data-id=\"32d9629\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-25088a1 e-flex e-con-boxed e-con e-parent\" data-id=\"25088a1\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f732b93 elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"f732b93\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Select a Channel Based on Catchment Area<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f28d7c4 elementor-widget elementor-widget-image\" data-id=\"f28d7c4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"389\" height=\"237\" src=\"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png\" class=\"attachment-large size-large wp-image-3355\" alt=\"\" srcset=\"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png 389w, https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1-300x183.png 300w, https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1-18x12.png 18w\" sizes=\"(max-width: 389px) 100vw, 389px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a815a48 e-flex e-con-boxed e-con e-parent\" data-id=\"a815a48\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;sticky&quot;:&quot;top&quot;,&quot;sticky_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;,&quot;mobile&quot;],&quot;sticky_offset&quot;:0,&quot;sticky_effects_offset&quot;:0,&quot;sticky_anchor_link_offset&quot;:0}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-984bea0 elementor-icon-list--layout-inline elementor-align-center elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list\" data-id=\"984bea0\" data-element_type=\"widget\" data-e-type=\"widget\" id=\"calc-nav\" data-widget_type=\"icon-list.default\">\n\t\t\t\t\t\t\t<ul class=\"elementor-icon-list-items elementor-inline-items\">\n\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#step-1\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"#00928D\"><\/circle><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.375 8.66667L5 10L9.125 14L16 7.33333L14.625 6L9.125 11.3333L6.375 8.66667Z\" fill=\"white\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">Step 1<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#step-2\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"#00928D\"><\/circle><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.375 8.66667L5 10L9.125 14L16 7.33333L14.625 6L9.125 11.3333L6.375 8.66667Z\" fill=\"white\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">Step 2<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#step-3\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"#00928D\"><\/circle><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.375 8.66667L5 10L9.125 14L16 7.33333L14.625 6L9.125 11.3333L6.375 8.66667Z\" fill=\"white\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">Step 3<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#step-4\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"#00928D\"><\/circle><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.375 8.66667L5 10L9.125 14L16 7.33333L14.625 6L9.125 11.3333L6.375 8.66667Z\" fill=\"white\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">Step 4<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#step-4\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"#00928D\"><\/circle><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.375 8.66667L5 10L9.125 14L16 7.33333L14.625 6L9.125 11.3333L6.375 8.66667Z\" fill=\"white\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">Results<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ul>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3def81b e-flex e-con-boxed e-con e-parent\" data-id=\"3def81b\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9a9b12c elementor-widget__width-inherit elementor-widget elementor-widget-shortcode\" data-id=\"9a9b12c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n  <div id=\"drainage-calculator\">\n    \n\n    <!-- Loader Overlay (Minimal U-channel with water fill) -->\n <!-- Loader Overlay -->\n<div id=\"rainLoaderOverlay\" style=\" position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(255,255,255,0.85); z-index:9999; align-items:center; justify-content:center;\">\n  <div id=\"rainLoader\">\n    <div class=\"loader-wrap\" aria-hidden=\"true\">\n      <!-- Your SVG cloud -->\n      <svg class=\"cloud\" viewBox=\"0 0 24 24\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n           fill-rule=\"evenodd\" clip-rule=\"evenodd\" aria-hidden=\"true\">\n        <path d=\"M18.5 20h-13c-2.481 0-4.5-2.019-4.5-4.5 0-2.178 1.555-4.038 3.698-4.424l.779-.14.043-.79c.185-3.447 3.031-6.146 6.48-6.146 3.449 0 6.295 2.699 6.479 6.146l.043.79.78.14c2.142.386 3.698 2.246 3.698 4.424 0 2.481-2.019 4.5-4.5 4.5m.979-9.908c-.212-3.951-3.473-7.092-7.479-7.092s-7.267 3.141-7.479 7.092c-2.57.463-4.521 2.706-4.521 5.408 0 3.037 2.463 5.5 5.5 5.5h13c3.037 0 5.5-2.463 5.5-5.5 0-2.702-1.951-4.945-4.521-5.408\"\/>\n      <\/svg>\n\n      <!-- Drops -->\n      <div class=\"drops\">\n        <span class=\"drop\" style=\"--x: 35%; --delay: 0ms;\"><\/span>\n        <span class=\"drop\" style=\"--x: 48%; --delay: 200ms;\"><\/span>\n        <span class=\"drop\" style=\"--x: 60%; --delay: 400ms;\"><\/span>\n        <span class=\"drop\" style=\"--x: 70%; --delay: 600ms;\"><\/span>\n        <span class=\"drop\" style=\"--x: 42%; --delay: 800ms;\"><\/span>\n      <\/div>\n    <\/div>\n    <div class=\"loader-text\">Fetching design rainfall\u2026<\/div>\n  <\/div>\n<\/div>\n\n    <!-- STEP 1: Choose path for rainfall intensity -->\n    <fieldset class=\"step-1 active\">\n\t\n\t\t\n\t\t\t<div class=\"row row-calculation-name\">\n  <label style=\"margin-bottom:8px;\"><strong style=\"    font-size: 1.5rem;\n    font-weight: 600;\n    line-height: 1.3em; display:block; margin-bottom:1rem;\">Calculation Name<\/strong>\n    <input type=\"text\" id=\"calcName\" placeholder=\"e.g., Lot 12 \u2013 North Parking Drainage\">\n  <\/label>\n<\/div>\n\n\n\n      <h3>How do you want to set rainfall intensity?<\/h3>\n\n      <div class=\"choice-cards\">\n        <label class=\"choice\">\n          <input type=\"radio\" name=\"intensityMode\" value=\"manual\">\n          <div class=\"choice-body\">\n            <div class=\"choice-icon\"><svg width=\"54\" height=\"54\" viewBox=\"0 0 54 54\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M28.6875 50.625C28.4 50.6249 28.1172 50.5512 27.8661 50.4111C27.6151 50.271 27.4039 50.0691 27.2528 49.8245C27.1017 49.5799 27.0155 49.3007 27.0026 49.0134C26.9897 48.7262 27.0503 48.4404 27.1789 48.1832L30.5539 41.4332C30.6487 41.228 30.7837 41.044 30.9509 40.892C31.1182 40.74 31.3142 40.6232 31.5275 40.5484C31.7408 40.4736 31.9669 40.4425 32.1924 40.4567C32.418 40.471 32.6384 40.5305 32.8405 40.6315C33.0426 40.7326 33.2224 40.8732 33.3692 41.0451C33.5159 41.217 33.6266 41.4166 33.6948 41.632C33.7629 41.8475 33.7871 42.0745 33.7659 42.2995C33.7446 42.5245 33.6784 42.7429 33.5711 42.9418L30.1961 49.6918C30.0561 49.9721 29.8408 50.2078 29.5743 50.3726C29.3079 50.5375 29.0008 50.6248 28.6875 50.625ZM13.5 50.625C13.2125 50.6249 12.9297 50.5512 12.6786 50.4111C12.4276 50.271 12.2164 50.0691 12.0653 49.8245C11.9142 49.5799 11.828 49.3007 11.8151 49.0134C11.8022 48.7262 11.8628 48.4404 11.9914 48.1832L15.3664 41.4332C15.4611 41.228 15.5962 41.044 15.7634 40.892C15.9307 40.74 16.1267 40.6232 16.34 40.5484C16.5533 40.4736 16.7794 40.4425 17.0049 40.4567C17.2305 40.471 17.4509 40.5305 17.653 40.6315C17.8551 40.7326 18.0349 40.8732 18.1817 41.0451C18.3284 41.217 18.4391 41.4166 18.5073 41.632C18.5754 41.8475 18.5996 42.0745 18.5784 42.2995C18.5571 42.5245 18.4909 42.7429 18.3836 42.9418L15.0086 49.6918C14.8686 49.9721 14.6533 50.2078 14.3868 50.3726C14.1204 50.5375 13.8133 50.6248 13.5 50.625Z\" fill=\"currentColor\"\/>\n<path d=\"M50.625 26.1562C50.6137 23.6319 49.7361 21.1879 48.1388 19.2331C46.5415 17.2783 44.3215 15.9311 41.85 15.417C41.1309 12.0113 39.2631 8.95618 36.5595 6.76379C33.8559 4.5714 30.4808 3.37494 27 3.37494C23.5192 3.37494 20.1441 4.5714 17.4405 6.76379C14.7369 8.95618 12.8691 12.0113 12.15 15.417C9.89748 15.8736 7.8457 17.0274 6.28523 18.7148C4.72477 20.4022 3.73473 22.5378 3.4553 24.8191C3.17588 27.1004 3.62125 29.4117 4.72833 31.4259C5.8354 33.44 7.54808 35.0548 9.62382 36.0416L6.92888 41.4332C6.82777 41.6316 6.76695 41.8481 6.74991 42.0702C6.73287 42.2922 6.75996 42.5155 6.82961 42.727C6.89927 42.9386 7.0101 43.1342 7.15573 43.3027C7.30136 43.4712 7.47891 43.6092 7.67813 43.7088C7.87735 43.8083 8.09431 43.8675 8.3165 43.8828C8.53868 43.8981 8.7617 43.8693 8.97269 43.798C9.18368 43.7267 9.37848 43.6143 9.54584 43.4674C9.7132 43.3204 9.84981 43.1418 9.94781 42.9418L12.8537 37.125H24.2696L22.1164 41.4332C22.0153 41.6316 21.9544 41.8481 21.9374 42.0702C21.9204 42.2922 21.9475 42.5155 22.0171 42.727C22.0868 42.9386 22.1976 43.1342 22.3432 43.3027C22.4889 43.4712 22.6664 43.6092 22.8656 43.7088C23.0649 43.8083 23.2818 43.8675 23.504 43.8828C23.7262 43.8981 23.9492 43.8693 24.1602 43.798C24.3712 43.7267 24.566 43.6143 24.7333 43.4674C24.9007 43.3204 25.0373 43.1418 25.1353 42.9418L28.0429 37.125H39.4571L37.3039 41.4332C37.2028 41.6316 37.1419 41.8481 37.1249 42.0702C37.1079 42.2922 37.135 42.5155 37.2046 42.727C37.2743 42.9386 37.3851 43.1342 37.5307 43.3027C37.6764 43.4712 37.8539 43.6092 38.0531 43.7088C38.2524 43.8083 38.4693 43.8675 38.6915 43.8828C38.9137 43.8981 39.1367 43.8693 39.3477 43.798C39.5587 43.7267 39.7535 43.6143 39.9208 43.4674C40.0882 43.3204 40.2248 43.1418 40.3228 42.9418L43.6033 36.3774C45.6669 35.579 47.4414 34.1761 48.6942 32.3523C49.9471 30.5285 50.6201 28.3689 50.625 26.1562ZM39.6563 33.75H14.3438C12.3859 33.7453 10.5056 32.9842 9.09565 31.6257C7.68572 30.2673 6.85523 28.4166 6.77769 26.4603C6.70014 24.504 7.38153 22.5933 8.67951 21.1276C9.97749 19.6618 11.7917 18.7543 13.743 18.5946L15.12 18.4866L15.2871 17.1163C15.6393 14.2577 17.0247 11.6266 19.1823 9.71856C21.3398 7.81054 24.1206 6.75733 27.0008 6.75733C29.8811 6.75733 32.6619 7.81054 34.8194 9.71856C36.977 11.6266 38.3624 14.2577 38.7146 17.1163L38.8817 18.4866L40.257 18.5946C42.2083 18.7543 44.0225 19.6618 45.3205 21.1276C46.6185 22.5933 47.2999 24.504 47.2223 26.4603C47.1448 28.4166 46.3143 30.2673 44.9044 31.6257C43.4944 32.9842 41.6141 33.7453 39.6563 33.75Z\" fill=\"currentColor\"\/>\n<\/svg>\n<\/div>\n            <div class=\"choice-title\">I know my rainfall intensity<\/div>\n            <div class=\"choice-desc\">Enter a value you already have (in\/hr).<\/div>\n          <\/div>\n        <\/label>\n\n        <label class=\"choice\">\n          <input type=\"radio\" name=\"intensityMode\" value=\"zip-custom\">\n          <div class=\"choice-body\">\n             <div class=\"choice-icon\"><svg width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<g clip-path=\"url(#clip0_1003_7608)\">\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M7.75 28C7.86643 27.8448 8.01741 27.7188 8.19098 27.632C8.36455 27.5452 8.55594 27.5 8.75 27.5H15C15.3315 27.5 15.6495 27.6317 15.8839 27.8661C16.1183 28.1005 16.25 28.4185 16.25 28.75C16.25 29.0815 16.1183 29.3995 15.8839 29.6339C15.6495 29.8683 15.3315 30 15 30H9.375L3.75 37.5H36.25L30.625 30H25C24.6685 30 24.3505 29.8683 24.1161 29.6339C23.8817 29.3995 23.75 29.0815 23.75 28.75C23.75 28.4185 23.8817 28.1005 24.1161 27.8661C24.3505 27.6317 24.6685 27.5 25 27.5H31.25C31.4441 27.5 31.6354 27.5452 31.809 27.632C31.9826 27.7188 32.1336 27.8448 32.25 28L39.75 38C39.8893 38.1857 39.9741 38.4065 39.9949 38.6377C40.0158 38.8689 39.9718 39.1014 39.868 39.309C39.7642 39.5167 39.6046 39.6913 39.4072 39.8133C39.2097 39.9354 38.9821 40 38.75 40H1.25C1.01786 40 0.790307 39.9354 0.592837 39.8133C0.395367 39.6913 0.235783 39.5167 0.131967 39.309C0.0281505 39.1014 -0.015796 38.8689 0.00505145 38.6377C0.0258989 38.4065 0.110717 38.1857 0.250001 38L7.75 28Z\" fill=\"currentColor\"\/>\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M20 2.49999C19.0151 2.49999 18.0398 2.69398 17.1299 3.07089C16.2199 3.4478 15.3931 4.00025 14.6967 4.69669C14.0003 5.39313 13.4478 6.21992 13.0709 7.12986C12.694 8.0398 12.5 9.01507 12.5 9.99999C12.5 10.9849 12.694 11.9602 13.0709 12.8701C13.4478 13.7801 14.0003 14.6069 14.6967 15.3033C15.3931 15.9997 16.2199 16.5522 17.1299 16.9291C18.0398 17.306 19.0151 17.5 20 17.5C21.9891 17.5 23.8968 16.7098 25.3033 15.3033C26.7098 13.8968 27.5 11.9891 27.5 9.99999C27.5 8.01087 26.7098 6.10321 25.3033 4.69669C23.8968 3.29017 21.9891 2.49999 20 2.49999ZM10 9.99999C10.0002 8.07555 10.5556 6.19204 11.5997 4.57547C12.6438 2.95889 14.1322 1.67792 15.8863 0.886255C17.6403 0.0945926 19.5856 -0.174131 21.4885 0.112331C23.3915 0.398792 25.1715 1.22827 26.6147 2.50123C28.058 3.77419 29.1033 5.43656 29.6252 7.28887C30.1471 9.14118 30.1235 11.1047 29.5571 12.944C28.9908 14.7832 27.9057 16.4199 26.4322 17.6577C24.9587 18.8956 23.1593 19.6819 21.25 19.9225V33.75C21.25 34.0815 21.1183 34.3995 20.8839 34.6339C20.6495 34.8683 20.3315 35 20 35C19.6685 35 19.3505 34.8683 19.1161 34.6339C18.8817 34.3995 18.75 34.0815 18.75 33.75V19.925C16.3324 19.6204 14.1092 18.4436 12.498 16.6156C10.8869 14.7876 9.99856 12.4367 10 9.99999Z\" fill=\"currentColor\"\/>\n<\/g>\n<defs>\n<clipPath id=\"clip0_1003_7608\">\n<rect width=\"40\" height=\"40\" fill=\"white\"\/>\n<\/clipPath>\n<\/defs>\n<\/svg>\n\n<\/div>\n            <div class=\"choice-title\">Calculate from ZIP <em>(pick my own duration + ARI)<\/em><\/div>\n            <div class=\"choice-desc\">We\u2019ll look up the PFDS table using your ZIP, but you choose duration & frequency.<\/div>\n          <\/div>\n        <\/label>\n\n        <label class=\"choice\">\n          <input type=\"radio\" name=\"intensityMode\" value=\"zip-site\">\n          <div class=\"choice-body\">\n                         <div class=\"choice-icon\"><svg width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<g clip-path=\"url(#clip0_1003_7608)\">\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M7.75 28C7.86643 27.8448 8.01741 27.7188 8.19098 27.632C8.36455 27.5452 8.55594 27.5 8.75 27.5H15C15.3315 27.5 15.6495 27.6317 15.8839 27.8661C16.1183 28.1005 16.25 28.4185 16.25 28.75C16.25 29.0815 16.1183 29.3995 15.8839 29.6339C15.6495 29.8683 15.3315 30 15 30H9.375L3.75 37.5H36.25L30.625 30H25C24.6685 30 24.3505 29.8683 24.1161 29.6339C23.8817 29.3995 23.75 29.0815 23.75 28.75C23.75 28.4185 23.8817 28.1005 24.1161 27.8661C24.3505 27.6317 24.6685 27.5 25 27.5H31.25C31.4441 27.5 31.6354 27.5452 31.809 27.632C31.9826 27.7188 32.1336 27.8448 32.25 28L39.75 38C39.8893 38.1857 39.9741 38.4065 39.9949 38.6377C40.0158 38.8689 39.9718 39.1014 39.868 39.309C39.7642 39.5167 39.6046 39.6913 39.4072 39.8133C39.2097 39.9354 38.9821 40 38.75 40H1.25C1.01786 40 0.790307 39.9354 0.592837 39.8133C0.395367 39.6913 0.235783 39.5167 0.131967 39.309C0.0281505 39.1014 -0.015796 38.8689 0.00505145 38.6377C0.0258989 38.4065 0.110717 38.1857 0.250001 38L7.75 28Z\" fill=\"currentColor\"\/>\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M20 2.49999C19.0151 2.49999 18.0398 2.69398 17.1299 3.07089C16.2199 3.4478 15.3931 4.00025 14.6967 4.69669C14.0003 5.39313 13.4478 6.21992 13.0709 7.12986C12.694 8.0398 12.5 9.01507 12.5 9.99999C12.5 10.9849 12.694 11.9602 13.0709 12.8701C13.4478 13.7801 14.0003 14.6069 14.6967 15.3033C15.3931 15.9997 16.2199 16.5522 17.1299 16.9291C18.0398 17.306 19.0151 17.5 20 17.5C21.9891 17.5 23.8968 16.7098 25.3033 15.3033C26.7098 13.8968 27.5 11.9891 27.5 9.99999C27.5 8.01087 26.7098 6.10321 25.3033 4.69669C23.8968 3.29017 21.9891 2.49999 20 2.49999ZM10 9.99999C10.0002 8.07555 10.5556 6.19204 11.5997 4.57547C12.6438 2.95889 14.1322 1.67792 15.8863 0.886255C17.6403 0.0945926 19.5856 -0.174131 21.4885 0.112331C23.3915 0.398792 25.1715 1.22827 26.6147 2.50123C28.058 3.77419 29.1033 5.43656 29.6252 7.28887C30.1471 9.14118 30.1235 11.1047 29.5571 12.944C28.9908 14.7832 27.9057 16.4199 26.4322 17.6577C24.9587 18.8956 23.1593 19.6819 21.25 19.9225V33.75C21.25 34.0815 21.1183 34.3995 20.8839 34.6339C20.6495 34.8683 20.3315 35 20 35C19.6685 35 19.3505 34.8683 19.1161 34.6339C18.8817 34.3995 18.75 34.0815 18.75 33.75V19.925C16.3324 19.6204 14.1092 18.4436 12.498 16.6156C10.8869 14.7876 9.99856 12.4367 10 9.99999Z\" fill=\"currentColor\"\/>\n<\/g>\n<defs>\n<clipPath id=\"clip0_1003_7608\">\n<rect width=\"40\" height=\"40\" fill=\"white\"\/>\n<\/clipPath>\n<\/defs>\n<\/svg>\n\n<\/div>\n            <div class=\"choice-title\">Calculate from ZIP <em>(suggested by site type)<\/em><\/div>\n            <div class=\"choice-desc\">We\u2019ll use site type to suggest duration & frequency; you can still edit later.<\/div>\n          <\/div>\n        <\/label>\n      <\/div>\n\n      <!-- Subpanel: Manual -->\n      <div class=\"mode-panel\" id=\"panel-manual\" hidden>\n        <label>Rainfall Intensity (in\/hr)\n          <input type=\"number\" id=\"manualRainInput\" step=\"0.01\" placeholder=\"e.g., 1.44\">\n        <\/label>\n        <div class=\"actions\">\n          <button type=\"button\" id=\"btnManualNext\" class=\"primary\">Continue<\/button>\n        <\/div>\n      <\/div>\n\n      <!-- Subpanel: ZIP + Custom duration\/ARI -->\n      <div class=\"mode-panel\" id=\"panel-zip-custom\" hidden>\n        <label>ZIP Code\n          <input type=\"text\" id=\"zipInputCustom\" placeholder=\"e.g., 60304\">\n        <\/label>\n\n        <div class=\"row\">\n          <label>Rainfall Duration\n            <select id=\"durationSelect\">\n              <option>5-min<\/option><option>10-min<\/option><option>15-min<\/option><option>30-min<\/option>\n              <option selected>60-min<\/option><option>2-hr<\/option><option>3-hr<\/option><option>6-hr<\/option>\n              <option>12-hr<\/option><option>24-hr<\/option><option>2-day<\/option><option>3-day<\/option>\n              <option>4-day<\/option><option>7-day<\/option><option>10-day<\/option><option>20-day<\/option>\n              <option>30-day<\/option><option>45-day<\/option><option>60-day<\/option>\n            <\/select>\n          <\/label>\n          <label>Rainfall Frequency (ARI)\n            <select id=\"ariSelect\">\n              <option value=\"1\">1-year<\/option><option value=\"2\" selected>2-year<\/option><option value=\"5\">5-year<\/option>\n              <option value=\"10\">10-year<\/option><option value=\"25\">25-year<\/option><option value=\"50\">50-year<\/option>\n              <option value=\"100\">100-year<\/option><option value=\"200\">200-year<\/option><option value=\"500\">500-year<\/option>\n              <option value=\"1000\">1000-year<\/option>\n            <\/select>\n          <\/label>\n        <\/div>\n\n        <div class=\"actions\">\n          <button type=\"button\" id=\"btnZipCustomFetch\" class=\"primary\">Get Design Rainfall<\/button>\n        <\/div>\n      <\/div>\n\n      <!-- Subpanel: ZIP + Site type suggestion -->\n      <div class=\"mode-panel\" id=\"panel-zip-site\" hidden>\n        <label>ZIP Code\n          <input type=\"text\" id=\"zipInputSite\" placeholder=\"e.g., 60304\">\n        <\/label>\n\n        <label>Site Type\n          <select id=\"siteType\">\n            <option value=\"\">Select Site Type<\/option>\n            <option value=\"Single-Family Residential\">Single-Family Residential<\/option>\n            <option value=\"Multi-Family Housing\/Townhomes\">Multi-Family Housing\/Townhomes<\/option>\n            <option value=\"Commercial \/ Parking Lot \/ Retail\">Commercial \/ Parking Lot \/ Retail<\/option>\n            <option value=\"Industrial\/Warehouses\">Industrial\/Warehouses<\/option>\n            <option value=\"Public Facilities - Schools \/ Hospitals\/Public Buildings\">Public Facilities - Schools \/ Hospitals\/Public Buildings<\/option>\n            <option value=\"Critical Infrastructure - Emergency \/ Utility \/ Airports \/ Fire Stations \/ Pump Stations\">Critical Infrastructure<\/option>\n            <option value=\"Major Roads and Highways - Normal Risk\">Major Roads - Normal Risk<\/option>\n            <option value=\"Major Roads and Highways - High Risk (Interstates or High Risk Zones)\">Major Roads - High Risk<\/option>\n            <option value=\"Major Roads and Highways - Very High Risk (Evacuation Routes)\">Major Roads - Very High Risk<\/option>\n          <\/select>\n        <\/label>\n\n        <div class=\"hint\">We\u2019ll suggest duration & ARI from your site type. You can still change them in Step 2 if needed.<\/div>\n        <div class=\"actions\">\n          <button type=\"button\" id=\"btnZipSiteFetch\" class=\"primary\">Get Design Rainfall<\/button>\n        <\/div>\n      <\/div>\n    <\/fieldset>\n\n    <!-- STEP 2: Catchment surfaces -->\n    <fieldset class=\"step-2 closed\">\n       <h3 class=\"header-1\">Define Catchment Areas<\/h3>\n        <div class=\"fieldset-inner\">\n      <div class=\"step-header\">\n        <div class=\"step-header-text\">\n      <h3 class=\"header-2\">Define Catchment Areas<\/h3>\n      <p>Enter the square footage for each surface type. You can also tweak the rainfall intensity if needed.<\/p>\n    <\/div>\n          <svg width=\"339\" height=\"210\" viewBox=\"0 0 339 210\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<g opacity=\"0.5\" filter=\"url(#filter0_f_1003_7898)\">\n<path d=\"M165.426 43.4854L298.764 119.764L175.082 193.41L40.8661 116.253L165.426 43.4854Z\" fill=\"#3F4B50\"\/>\n<\/g>\n<path d=\"M173.189 84.4369L238.983 46.072L238.975 49.1269L173.181 87.4918L173.189 84.4369Z\" fill=\"#470A09\"\/>\n<path d=\"M103.098 43.8312L168.884 5.46631L238.983 46.072L173.189 84.4369L103.098 43.8312Z\" fill=\"#946E47\"\/>\n<path d=\"M173.189 84.4369L173.181 87.4918L103.09 46.8861L103.098 43.8312L173.189 84.4369Z\" fill=\"#876441\"\/>\n<path d=\"M173.204 78.9629L238.99 40.6057L238.982 46.072L173.188 84.4369L173.204 78.9629Z\" fill=\"#118A72\"\/>\n<path d=\"M103.106 38.3649L168.9 0L238.99 40.6057L173.204 78.9628L103.106 38.3649Z\" fill=\"#50E1C4\"\/>\n<path d=\"M173.204 78.9628L173.189 84.4369L103.098 43.8312L103.106 38.3649L173.204 78.9628Z\" fill=\"#29B99D\"\/>\n<path d=\"M98.0983 129.385L163.892 91.0275L163.884 94.0824L98.0983 132.44V129.385Z\" fill=\"#470A09\"\/>\n<path d=\"M28 88.7789L93.7939 50.4218L163.892 91.0274L98.0982 129.385L28 88.7789Z\" fill=\"#946E47\"\/>\n<path d=\"M98.0982 129.385V132.44L28 91.8339V88.7789L98.0982 129.385Z\" fill=\"#876441\"\/>\n<path d=\"M98.1137 123.918L163.908 85.5535L163.892 91.0275L98.0983 129.385L98.1137 123.918Z\" fill=\"#118A72\"\/>\n<path d=\"M28.0155 83.3126L93.8094 44.9554L163.908 85.5534L98.1137 123.918L28.0155 83.3126Z\" fill=\"#50E1C4\"\/>\n<path d=\"M98.1137 123.918L98.0982 129.385L28 88.7789L28.0155 83.3126L98.1137 123.918Z\" fill=\"#29B99D\"\/>\n<path d=\"M179.803 175.945L245.597 137.58L245.59 140.635L179.803 179V175.945Z\" fill=\"#470A09\"\/>\n<path d=\"M109.713 135.339L175.499 96.9745L245.598 137.58L179.804 175.945L109.713 135.339Z\" fill=\"#946E47\"\/>\n<path d=\"M179.804 175.945V179L109.705 138.394L109.713 135.339L179.804 175.945Z\" fill=\"#876441\"\/>\n<path d=\"M179.819 170.479L245.613 132.114L245.597 137.58L179.803 175.945L179.819 170.479Z\" fill=\"#118A72\"\/>\n<path d=\"M109.721 129.873L175.515 91.5082L245.613 132.114L179.819 170.479L109.721 129.873Z\" fill=\"#50E1C4\"\/>\n<path d=\"M179.819 170.479L179.804 175.945L109.713 135.339L109.721 129.873L179.819 170.479Z\" fill=\"#29B99D\"\/>\n<path d=\"M254.198 130.99L319.985 92.6324L319.977 95.6874L254.191 134.045L254.198 130.99Z\" fill=\"#470A09\"\/>\n<path d=\"M184.1 90.3916L249.894 52.0267L319.984 92.6324L254.198 130.99L184.1 90.3916Z\" fill=\"#946E47\"\/>\n<path d=\"M254.198 130.99L254.191 134.045L184.093 93.4389L184.1 90.3917L254.198 130.99Z\" fill=\"#876441\"\/>\n<path d=\"M254.206 125.523L320 87.1661L319.985 92.6324L254.198 130.99L254.206 125.523Z\" fill=\"#118A72\"\/>\n<path d=\"M184.116 84.9176L249.902 46.5604L320 87.1661L254.206 125.523L184.116 84.9176Z\" fill=\"#50E1C4\"\/>\n<path d=\"M254.206 125.523L254.198 130.99L184.1 90.3917L184.116 84.9176L254.206 125.523Z\" fill=\"#29B99D\"\/>\n<defs>\n<filter id=\"filter0_f_1003_7898\" x=\"0.866089\" y=\"3.48535\" width=\"337.898\" height=\"229.925\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\">\n<feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"\/>\n<feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"\/>\n<feGaussianBlur stdDeviation=\"20\" result=\"effect1_foregroundBlur_1003_7898\"\/>\n<\/filter>\n<\/defs>\n<\/svg>\n  <\/div>\n \n      <div class=\"row\">\n        <label>Rainfall Intensity (in\/hr)\n          <input type=\"number\" id=\"rainfall\" step=\"0.01\" value=\"2\">\n        <\/label>\n      <\/div>\n\n      <div class=\"row two-col\">\n        <label>Asphalt\/Concrete (sq. ft)\n          <input type=\"number\" id=\"asphalt\" value=\"0\">\n        <\/label>\n        <label>Brick (sq. ft)\n          <input type=\"number\" id=\"brick\" value=\"0\">\n        <\/label>\n      <\/div>\n\n      <div class=\"row two-col\">\n        <label>Roofs (sq. ft)\n          <input type=\"number\" id=\"roofs\" value=\"0\">\n        <\/label>\n        <label>Lawns - Sandy Soil (sq. ft)\n          <input type=\"number\" id=\"sandy\" value=\"0\">\n        <\/label>\n      <\/div>\n\n      <div class=\"row\">\n        <label>Lawns - Heavy Soil (sq. ft)\n          <input type=\"number\" id=\"heavy\" value=\"0\">\n        <\/label>\n      <\/div>\n\n    \n\n      <div class=\"actions\">\n        <button type=\"button\" class=\"back-btn\" data-back=\"1\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M3.52087 7.83337L8.18754 12.5L7.00004 13.6667L0.333374 7.00004L7.00004 0.333374L8.18754 1.50004L3.52087 6.16671H13.6667V7.83337H3.52087Z\" fill=\"currentColor\"\/>\n<\/svg>Back<\/button>\n        <button type=\"button\" class=\"primary\" id=\"btnCalcFlow\">Calculate Flow<\/button>\n      <\/div>\n    <\/div>\n    <\/fieldset>\n\n    <!-- STEP 3: Drainage properties + filters for trays -->\n    <fieldset class=\"step-3 closed\">\n      <div class=\"step-header\">\n        <div class=\"step-header-text\">\n      <h3>Define Drainage Channel and Project Properties<\/h3>\n     \n    <\/div>\n\n\n\t\t  <\/div>\n\t\t  <div class=\"fieldset-inner\">\n         <p>We\u2019ll use these to compute velocities and match channels.<\/p>\n\t\t  <div id=\"flowOutput\"><\/div>\n\n\n      <div class=\"row two-col required-material-wrapper\">\n        <label>Required Material\n          <select id=\"requiredMaterial\" name=\"requiredMaterial\">\n            <option value=\"\">Select required material<\/option>\n                          <option value=\"concrete\" data-term-id=\"24\">\n                Concrete              <\/option>\n                          <option value=\"plastic\" data-term-id=\"26\">\n                Plastic              <\/option>\n                          <option value=\"polymer\" data-term-id=\"27\">\n                Polymer              <\/option>\n                          <option value=\"steel\" data-term-id=\"28\">\n                Steel              <\/option>\n                      <\/select>\n        <\/label>\n\n        <label>Required Load Class\n          <select id=\"requiredLoadClass\" name=\"requiredLoadClass\">\n            <option value=\"\">Select required load class<\/option>\n                          <option value=\"a15\" data-term-id=\"29\">\n                A15              <\/option>\n                          <option value=\"b125\" data-term-id=\"30\">\n                B125              <\/option>\n                          <option value=\"c250\" data-term-id=\"31\">\n                C250              <\/option>\n                          <option value=\"d400\" data-term-id=\"25\">\n                D400              <\/option>\n                          <option value=\"e600\" data-term-id=\"32\">\n                E600              <\/option>\n                          <option value=\"f900\" data-term-id=\"33\">\n                F900              <\/option>\n                      <\/select>\n        <\/label>\n      <\/div>\n\n      <div class=\"row three-col length-slope-outlets-wrapper\">\n        <label>Line Length (ft)\n          <input type=\"number\" id=\"length\" value=\"100\" step=\"25\">\n        <\/label>\n        <label>Longitudinal Slope <span class=\"tooltip\">?<span class=\"tooltip-text\">To calculate the slope of a trench drain, divide the height difference between the start and end points by the length of the drain; the slope is a dimensionless value (not a percent). A slope of at least 0.005 is recommended to ensure proper water flow.<\/span><\/span>\n          <input type=\"number\" id=\"slope\" step=\"0.0001\" value=\"0.005\" placeholder=\"e.g., 0.005\">\n        <\/label>\n        <label class=\"field-number-of-outlets\">Number of Outlets\n          <input type=\"number\" id=\"outlets\" value=\"1\" min=\"1\" step=\"1\">\n        <\/label>\n      <\/div>\n\n      <div class=\"actions\">\n        <button type=\"button\" class=\"back-btn\" data-back=\"2\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M3.52087 7.83337L8.18754 12.5L7.00004 13.6667L0.333374 7.00004L7.00004 0.333374L8.18754 1.50004L3.52087 6.16671H13.6667V7.83337H3.52087Z\" fill=\"currentColor\"\/>\n<\/svg>\n Back<\/button>\n        <button type=\"button\" class=\"primary\" id=\"btnFindTrays\">Find Matching Channels<\/button> <span class = \"disclaimer\">\u201cNote: *The hydraulic calculation is calculated based on the last trench drain in the system, taking into account the slope and full line capacity.<\/span>\n      <\/div>\n    <\/div>\n    <\/fieldset>\n\n    <!-- STEP 4: Tray recommendations -->\n    <fieldset class=\"step-4 closed\">\n      <h3>Channel Recommendations<\/h3>\n      <div class=\"fieldset-inner\">\n      <div id=\"trayResults\" class=\"output\" style=\"font-weight:normal;\"><\/div>\n      <!-- Optional: static mount point for filters\/pager; the JS will fill these -->\n<div id=\"trayControls\"><\/div>\n      <div class=\"actions\">\n        <button type=\"button\" class=\"back-btn\" data-back=\"3\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M3.52087 7.83337L8.18754 12.5L7.00004 13.6667L0.333374 7.00004L7.00004 0.333374L8.18754 1.50004L3.52087 6.16671H13.6667V7.83337H3.52087Z\" fill=\"currentColor\"\/>\n<\/svg>Back<\/button>\n        <button type=\"button\" class=\"primary\" id=\"btnUseTray\">Use Selected Channel &amp; Show Final Results<\/button>\n      <\/div>\n    <\/div>\n    <\/fieldset>\n\n    <!-- STEP 5: Final summary + PDF -->\n    <fieldset class=\"step-5 closed\">\n      <h3 id=\"resultsTop\">Your Results<\/h3>\n      <div class=\"fieldset-inner\">\n      <div id=\"resultsCard\" class=\"results-card\"><\/div>\n\n <div class=\"actions\">\n  <button type=\"button\" class=\"back-btn\" data-back=\"4\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M3.52087 7.83337L8.18754 12.5L7.00004 13.6667L0.333374 7.00004L7.00004 0.333374L8.18754 1.50004L3.52087 6.16671H13.6667V7.83337H3.52087Z\" fill=\"currentColor\"\/>\n<\/svg>Back<\/button>\n    <!--  <button type=\"button\" class=\"secondary\" id=\"btnLoginToSave\">Log in to save your calculation<\/button> -->\n    \n    <button type=\"button\" class=\"primary\" id=\"btnAddToProject\">Add Calculation to a Project<\/button>\n  <button type=\"button\" class=\"secondary\" id=\"downloadPDF\">Download PDF<\/button>\n<\/div>\n<\/div>\n    <\/fieldset>\n\t  \n\t  <!-- Overwrite \/ Save-as-new Modal -->\n<div id=\"overwriteModal\" class=\"modal\">\n  <div data-backdrop><\/div>\n  <div class=\"modal-body\">\n    <div class=\"modal-header\">\n      <strong>Update saved calculation?<\/strong>\n    <\/div>\n    <div class=\"modal-content\">\n      You're working on a calculation you previously saved. If you continue, the existing saved version will be <strong>overwritten<\/strong>.<br><br>\n      Would you like to overwrite it, or <strong>save as a new calculation<\/strong>?\n      <div id=\"saveAsNewBlock\" style=\" display:none;\">\n        <label>New calculation name<\/label>\n        <input type=\"text\" id=\"newCalcName\">\n      <\/div>\n    <\/div>\n    <div class=\"actions modal-actions\">\n      <button type=\"button\" id=\"btnCancelOverwrite\" class=\"cancel secondary\">Cancel<\/button>\n      <button type=\"button\" id=\"btnSaveAsNew\" class=\"primary\">Save as New<\/button>\n      <button type=\"button\" id=\"btnOverwrite\" class=\"primary\">Overwrite Existing<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- Login Modal -->\n<div id=\"dcLoginModal\" class=\"modal\">\n  <div data-backdrop><\/div>\n  <div class=\"modal-body\">\n    <div class=\"modal-header\">\n      <strong>Log in to save your calculation<\/strong>\n    <\/div>\n    <form id=\"dcLoginForm\" style=\"padding:16px 18px;\">\n      <label style=\"display:block; margin-bottom:10px;\">\n        <div style=\"margin-bottom:6px;\">Username or Email<\/div>\n        <input type=\"text\" name=\"log\" required style=\"width:100%; padding:10px; border:1px solid #ddd; border-radius:8px;\">\n      <\/label>\n      <label style=\"display:block; margin-bottom:6px;\">\n        <div style=\"margin-bottom:6px;\">Password<\/div>\n        <input type=\"password\" name=\"pwd\" required style=\"width:100%; padding:10px; border:1px solid #ddd; border-radius:8px;\">\n      <\/label>\n      <div id=\"dcLoginErr\" style=\"display:none; color:#cc0000; font-size:13px; margin:8px 0 4px;\"><\/div>\n      <div class=\"dc-login-actions actions modal-actions\" style=\"display:flex; gap:10px; justify-content:flex-end; margin-top:14px;\">\n  <button type=\"button\" id=\"btnViewWithoutSaving\" class=\"secondary\">\n    View Results Without Saving\n  <\/button>\n  <button type=\"button\" id=\"btnLoginConfirm\" class=\"primary\">\n    Log In & Save\n  <\/button>\n<\/div>\n    <\/form>\n  <\/div>\n<\/div>\n<!-- No-Match Modal -->\n<div id=\"noMatchModal\" class=\"modal\">\n  <div data-backdrop><\/div>\n  <div role=\"dialog\" aria-labelledby=\"noMatchTitle\" aria-modal=\"true\" class=\"modal-body\">\n    <div class=\"modal-header\">\n      <strong id=\"noMatchTitle\">No matching channels found<\/strong>\n    <\/div>\n    <div class=\"modal-content\">\n      We couldn\u2019t find any channels for the current filters and flow. You can contact our engineering team for help, or try using different parameters.\n    <\/div>\n    <div class=\"actions modal-actions\">\n      <button type=\"button\" id=\"btnTryAnother\" class=\"primary\">Try Another Calculation<\/button>\n      <a id=\"btnContactEng\" class=\"secondary\" href=\"\/contact-us\/\">Contact Us<\/a>\n    <\/div>\n  <\/div>\n<\/div>\n\t  \n  <\/div>\n\n  <style>\n    #drainage-calculator { font-family: Arial, sans-serif; max-width: 900px; margin: auto; padding: 20px; }\n    h2 { margin-bottom: 12px; }\n    h3 { margin: 18px 0 8px; }\n    label { display: block; margin-top: 10px; }\n\t  table label {\n\t\t  margin-top:0;\n\t  }\n\t  table td {\n\t\t      font-size: 14px;\n\t\t  vertical-align:top;\n\t  }\n    input, select { width: 100%; padding: 8px; margin-top: 6px; box-sizing: border-box; }\n    .row { display: grid; gap: 12px; }\n    .two-col { grid-template-columns: 1fr 1fr; }\n    .three-col { grid-template-columns: 1fr 1fr 1fr; }\n    .muted { color: #555; margin-top: 10px; }\n\n    fieldset { margin: 18px 0; opacity: .5; pointer-events: none; border: 0; padding: 0; }\n    fieldset.active { opacity: 1; pointer-events: auto; }\n\n    .actions { display: flex; gap: 10px; margin-top: 16px; }\n    .back-btn { display: none; background: #e5e7eb; border:0; padding: 10px 14px; border-radius: 8px; cursor:pointer; }\n    fieldset.active .back-btn { display: inline-block; }\n\n    button.primary,\n    button.secondary,\n    a.primary,\n    a.secondary{\n      font-weight:bold;\n      text-align:center;\n      line-height:1.3;\n      text-transform:uppercase !important;\n      display:inline-flex !important;\n      align-items:center;\n      font-size:16px;\n\n    }\n    .modal {\n     position:fixed; inset:0; display:none; align-items:center; justify-content:center; z-index:10000;\n}\n\n.modal div[data-backdrop] {\n     position:absolute; inset:0; background:rgba(0,0,0,.35);\n}\n\n.modal .modal-body {\n     position:relative; width:560px; max-width:90vw; background:#fff; border-radius:12px; box-shadow:0 10px 30px rgba(0,0,0,.2);\n}\n\n\n.modal .modal-body {\n    background:#FAFAFA;\n    padding:40px;\n    color:#3F4B50;\n}\n\n.modal .modal-header {\n    font-size:30px;\n    color:#2D3648;\n    margin:0 0 10px 0;\n}\n\n#drainage-calculator .modal .actions {\n    display:flex;\n    flex-direction:row;\n    align-items:stretch;\n    margin-top:20px;\n    flex-wrap:wrap;\n}\n\n#drainage-calculator .modal .actions button {\n    font-size:15px;\n    padding-left:20px !important;\n    padding-right:20px !important;\n}\n\n\n#drainage-calculator .modal .actions button.secondary,\n#drainage-calculator .actions button.secondary{\n    border:1px solid #000;\n    background:transparent;\n    color:#000;\n    \n}\n\n\n#drainage-calculator .modal .actions button.secondary:hover,\n#drainage-calculator .actions button.secondary:hover{\n    background:#000;\n    color:#fff;\n}\n\n.modal label {\n    font-size:16px;\n    margin-top:20px;\n}\n\n\n    .choice-cards { display:grid; gap:12px; margin:12px 0 16px;  }\n\t  \n\t  @media(min-width:768px) {\n\t\t  .choice-cards { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }\n\t  }\n    .choice { display:block; cursor:pointer; }\n    .choice input { display:none; }\n    .choice-body { border:1px solid #dcdfe3; border-radius:10px; padding:12px 14px; background:#fff; }\n    .choice input:checked + .choice-body { border-color:#2d6cdf; box-shadow:0 0 0 3px rgba(45,108,223,.12); }\n    .choice-title { font-weight:700; margin-bottom:4px; }\n    .choice-desc { color:#667085; font-size:0.925rem; }\n    .mode-panel { margin-top:12px; }\n    .hint { color:#667085; font-size:.92rem; margin-top:6px; }\n\n    \/* Results card for HTML->PDF *\/\n    .results-card {\n      border:1px solid #e5e7eb; border-radius:12px; padding:18px; background:#fff;\n      max-width: 1200px;\n    }\n    .results-header { display:flex; align-items:center; gap:16px; margin-bottom:12px; }\n    .results-title { font-size:18px; font-weight:700; }\n    .results-sub { color:#6b7280; }\n    .grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }\n    .kv { padding:10px; background:#f9fafb; border-radius:8px; }\n    .kv .k { font-size:12px; color:#6b7280; }\n    .kv .v { font-weight:600; }\n\n\n.results-card#resultsCard {\n    border:none;\n    padding:0;\n}\n\n.results-card .disclaimer {\n  font-size:12px;\n  font-style:none;\n  color:#999999;\n}\n\n\n.results-layout .results-section {\n     background:#fafafa;\n    border:1px solid #D1D5DB;\n    border-radius:10px;\n    padding:16px;\n    margin-bottom:12px;\n}\n\n.results-layout .results-section h5 {\n    margin-top:0;\n    font-size:20px;\n    margin-bottom:14px;\n}\n\n.results-layout .grid {\n   \n    gap:8px;\n}\n\n.results-layout .grid .kv {\n    border:1px solid #D1D5DB;\n    background:#fff;\n    padding:16px;\n    color:#334155\n \n}\n\n\n.results-layout .grid .kv .k {\n    color:#334155;\n    font-size:14px;\n    line-height: 1.3;\n    margin-bottom: 3px;\n}\n\n.results-layout .grid .kv .v {\n    line-height:1.3;\n}\n\n.results-card {\n    border:none;\n    padding:0;\n}\n\nfieldset.step-5 {\n    padding-top:40px !important;\n}\n\n.row-calculation-name {\n  margin-top:2em;\n  margin-bottom:2em;\n}\n\n.step-2.active .header-1 {\n    display:none;\n}\n\n#drainage-calculator fieldset.step-5 h3 {\n  margin-bottom:12px;\n}\n\n#drainage-calculator fieldset.step-5 .actions {\n  flex-direction:row;\n  flex-wrap:wrap;\n}\n\n#drainage-calculator fieldset.step-5 .actions button.back-btn {\nwidth:100%;\ntext-align:left;\n}\n\n#drainage-calculator fieldset.step-5 .actions button.back-btn:hover {\n  color:#00AAA3;\n}\n\n\n    @media(min-width:768px) {\n      .grid { grid-template-columns:1fr 1fr 1fr; }\n    }\n\n    \/* Loader overlay *\/\n    #rainLoaderOverlay {\n      position: fixed; inset: 0; background: rgba(255,255,255,.8);\n      display: none; align-items: center; justify-content: center; flex-direction: column; z-index: 9999;\n    }\n    #rainLoaderOverlay.show { display: flex; }\n    :root {\n  --cloud-size: 64px;\n  --drop-width: 2px;\n  --drop-height: 7px;\n  --drop-speed: 1100ms;\n}\n\n#rainLoader { text-align: center; }\n\n.loader-wrap {\n  position: relative;\n  width: var(--cloud-size);\n  height: calc(var(--cloud-size) + 24px);\n\tmargin-left:auto;\n\tmargin-right:auto;\n}\n\n.cloud {\n  width: var(--cloud-size);\n  height: var(--cloud-size);\n  display: block;\n  margin: 0 auto;\n}\n.cloud path {\n  fill: #000;\n  stroke: none;\n}\n\n.drops {\n  position: absolute;\n  top: calc(var(--cloud-size) - 2px);\n  left: 0; right: 0;\n  height: 24px;\n  overflow: hidden;\n}\n\n.drop {\n  --x: 50%;\n  --delay: 0ms;\n  position: absolute;\n  left: var(--x);\n  top: 0;\n  width: var(--drop-width);\n  height: var(--drop-height);\n  background: #000;\n  border-radius: 2px;\n  transform: translate(-50%, -10px);\n  opacity: 0;\n  animation: rain var(--drop-speed) linear infinite;\n  animation-delay: var(--delay);\n}\n\n@keyframes rain {\n  0%   { transform: translate(-50%, -8px);  opacity: 0; }\n  10%  { opacity: 1; }\n  100% { transform: translate(-50%, 24px);  opacity: 0; }\n}\n\n.loader-text {\n  margin-top: 10px;\n  color: #000;\n  font-size: 0.95rem;\n}\n    @keyframes waveSlide { from { transform: translateX(0); } to { transform: translateX(-50px); } }\n\t  \n\t  \/* Two-up images at the bottom of results *\/\n.results-images {\n  margin-top: 16px;\n  display: grid;\n  grid-template-columns: repeat(3, 1fr);\n  gap: 12px;\n}\n.results-images img {\n  width: 100%;\n  height: auto;\n  display: block;\n  border: 1px solid #e5e7eb;\n  border-radius: 8px;\n  background: #fff;\n  object-fit: contain;\n}\n\n\/* Stack on small screens *\/\n@media (max-width: 640px) {\n  .results-images {\n    grid-template-columns: 1fr;\n  }\n}\n\t  \n\t  \n\t  \/* Two-column results layout with images on the right *\/\n.results-layout {\n  display: grid;\n  grid-template-columns: 2fr 1fr;\n  gap: 16px;\n  align-items: start;\n}\n\n\/* Left column groups the 4 sections (General, Site, Line, Selection) *\/\n.results-left > h5 { margin-top: 1rem; }\n\n\/* Right column: stack images\/cards vertically *\/\n.results-images-right {\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n}\n\n\/* Reuse existing card styles for image\/fill visuals *\/\n.results-images-right img,\n.results-images-right > div {\n  width: 100%;\n  height: auto;\n  border: 1px solid #e5e7eb;\n  border-radius: 8px;\n  background: #fff;\n  object-fit: contain;\n}\n\n\n    .select-a-channel-using-wastewater-flow-rate-gpm .zip-code-item,\n    .select-a-channel-using-wastewater-flow-rate-gpm .rainfall-intensity-item,\n    .select-a-channel-using-wastewater-flow-rate-gpm .drainage-area-item,\n    .select-a-channel-using-wastewater-flow-rate-gpm .calculation-type-item,\n    .channel-capacity-calculator .zip-code-item,\n    .channel-capacity-calculator .rainfall-intensity-item,\n    .channel-capacity-calculator .drainage-area-item,\n    .channel-capacity-calculator .calculation-type-item,\n    .channel-capacity-calculator .number-of-drainage-channels-item,\n    .channel-capacity-calculator .gpm-per-outlet-item ,\n    .channel-capacity-calculator .site-characteristics-header, \n    .channel-capacity-calculator .site-characteristics-grid,\n    .channel-capacity-calculator .filling-level-card,\n    .channel-capacity-calculator .filling-degree-item,\n    .flow-rate-100-item,\n    .flow-rate-70-item {\n      display:none !important;\n    }\n\n    .channel-capacity-calculator .flow-rate-100-item,\n    .channel-capacity-calculator .flow-rate-70-item {\n      display:block !important;\n    }\n\n\n\n\n    .channel-capacity-calculator .outlets-item {\n      display:none !important;\n    }\n\n\t  \n\t  \n\/* Small screens: stack columns *\/\n@media (max-width: 900px) {\n  .results-layout { grid-template-columns: 1fr; }\n}\n\t  \n\t  \n\t  .tooltip {\n  position: relative;\n  display: inline-block;\n  border-bottom: 1px dotted black; \/* If you want dots under the hoverable text *\/\n}\n\n\/* Tooltip text *\/\n.tooltip .tooltip-text {\n  visibility: hidden;\n  width: 240px;\n  bottom: 100%;\n  left: 50%;\n  margin-left: -120px;\n\tfont-size:12px;\n\tline-height:1.3;\n  background-color: rgba(0,0,0,.8);\n  color: #fff;\n  text-align: center;\n  padding: 10px;\n  border-radius: 6px;\n \n  \/* Position the tooltip text - see examples below! *\/\n  position: absolute;\n  z-index: 1;\n}\n\n\/* Show the tooltip text when you mouse over the tooltip container *\/\n.tooltip:hover .tooltip-text {\n  visibility: visible;\n}\n\t  \n\t  .disclaimer {\n\t\t  font-size:12px;\n\t\t  opacity:.8;\n\t\t  font-style:italic;\n\t\t  line-height:1.3;\n\t\t  margin-top:1.3em;\n\t\t  color:#cc0000;\n\t  }\n\t  \n\t  hr {\n    margin:30px 0 !important;\n    display:block;\n}\n\nspan.indicator {\n    width:10px;\n    height:10px;\n    border-radius:50%; \n    display:inline-block;\n    margin-left:.15em;\n}\n\t  \n\t  .results-card h5 {\n\t\t  margin-top:2rem;\n\t\t  margin-bottom:.5rem;\n\t  }\n\t  \n\t  \n\t \/* Highlight summary box in Step 3 *\/\n.flow-summary {\n  border: 1px solid #dbe2f3;\n  background: #f7fbff;\n  border-radius: 10px;\n  padding: 14px 16px;\n  margin: 12px 0 18px;\n}\n.flow-summary h4 {\n  margin: 0 0 8px;\n  font-size: 1rem;\n}\n.flow-summary .grid-3 {\n  display: grid; \n  grid-template-columns: 1fr 1fr 1fr; \n  gap: 10px;\n}\n.flow-summary .metric {\n  background: #fff;\n  border: 1px solid #e8eef9;\n  border-radius: 8px;\n  padding: 10px;\n}\n.flow-summary .metric .k { font-size: 12px; color: #6b7280; }\n.flow-summary .metric .v { font-weight: 700; font-size: 1.05rem; }\n\t  \/* Force native steppers to appear for the outlets field *\/\n\/* Force native steppers to appear for the outlets field *\/\n#outlets, #length {\n  appearance: auto !important;\n  -webkit-appearance: auto !important;  \/* Chrome\/Safari *\/\n  -moz-appearance: number-input;     \/* Firefox *\/\n  min-height: 2.25em;                    \/* ensure there\u2019s room to render *\/\n  line-height: normal;\n  \n}\n\n\/* Make sure WebKit steppers aren\u2019t suppressed *\/\n#outlets::-webkit-inner-spin-button,\n#outlets::-webkit-outer-spin-button,\n#length::-webkit-inner-spin-button,\n#length::-webkit-outer-spin-button {\n  -webkit-appearance: auto !important;\n  margin: 0;\n   opacity: 1 !important;\n  visibility: visible !important;\n  display: inline !important;\n  -webkit-appearance: inner-spin-button !important;\n  margin: 0;\n  pointer-events: auto;\n}\n\n\/* Filling level gauge (blue water) *\/\n\t  \n\t  .results-images {\n    margin-bottom:15px;\n}\n\n.results-images img,\n.results-images > div {\n    aspect-ratio:1\/1 !important;\n    display:flex;\n    align-items:center;\n    justify-content:center;\n    flex-direction:column;\n}\n\t  \n.filling-level-outer {\n  display: inline-block;\n  width: 55%;               \/* a bit wider for readability in PDF *\/\n  height: auto;\n\taspect-ratio:4\/5;\n  border-left:2px solid #000;\n    border-right:2px solid #000;\n    border-bottom:2px solid #000;\n    border-top:none;\n    padding:0 10px 10px 10px;\n  background: #fff;\n}\n\n.filling-level-inner {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  background: #f3f4f6;\n  border-bottom-left-radius:50%;\n    border-bottom-right-radius:50%;\n    border-top-left-radius:0;\n    border-top-right-radius:0;\n    border-left:2px solid #000;\n    border-right:2px solid #000;\n    border-bottom:2px solid #000;\n  overflow: hidden;\n}\n\n.filling-level-indicator {\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 0;                 \n  background: #3b82f6;       \n  display: flex;\n  align-items: flex-end;\n  justify-content: center;\n}\n\n.filling-level-label {\n  display: block;\n    margin-bottom: 10px;\n  line-height: 1.1;\n  font-size:16px;\n\tfont-weight:600;\n  \n  \n  \n  \n}\n\n\n.filling-level-card {\n  border: 1px solid #e5e7eb;\n  border-radius: 8px;\n  background: #fff;\n  padding: 10px;\n  text-align: center;\n}\n\n.filling-level-title {\n      font-size: 12px;\n    color: #6b7280;\n  margin-bottom: 4px;\n}\n\t  \n\t  .secondary {\n  background:#eef2ff; color:#1e40af; border:0; padding:10px 14px; border-radius:8px; cursor:pointer;\n}\n.secondary:hover { background:#e0e7ff; }\n\t  .section { margin: 14px 0 10px; }\n.section-title { font-size: 16px; font-weight: 700; margin: 8px 0 10px; }\n\n.kv.highlight {\n  background: #f0f9ff;\n  border: 1px solid #bae6fd;\n}\n.kv .big {\n  font-size: 1.2rem;\n  font-weight: 800;\n}\n\n.warn-card {\n  margin: 10px 0 12px;\n  padding: 10px 12px;\n  border: 1px solid #f3d6d6;\n  background: #fff6f6;\n  color: #cc0000;\n  border-radius: 8px;\n  font-size: 13px;\n}\n\t  \n\t  \/* Keep the target from hiding under the WP admin bar \/ sticky headers *\/\n#resultsTop, #calcResultsTop, #resultsCard { scroll-margin-top: 72px; }\n\n\/* Manual-GPM mode: keep Step 1 visible (for name + manual GPM),\n   hide only the chooser & ZIP panels; hide Step 2 entirely. *\/\nbody.dc-manual-gpm #drainage-calculator fieldset.step-2 { display:none !important; }\nbody.dc-manual-gpm .choice-cards,\nbody.dc-manual-gpm #panel-zip-custom,\nbody.dc-manual-gpm #panel-zip-site { display:none !important; }\nbody.dc-manual-gpm #panel-manual { display:block !important; }\n\n#trayPrimarySection {\n    margin-bottom:30px;\n    padding-bottom:30px;\n    border-bottom:1px solid #ccc;\n    padding-top:10px;\n}\n\n\n#trayPrimarySection {\n    border-bottom:1px solid #eaeaea !important;\n}\n\n\n#trayPrimarySection,\n#trayOtherSection{\n    border:1px solid #CCCCCC;\n    border-radius:5px;\n    padding:0 20px 20px 20px !important;\n    margin-top:20px;\n    box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05);\n\n}\n\n#trayOtherSection:has(.no-matching-channels) .tray-controls {\n    display:none !important;\n}\n\n\n.tray-meta {\n  text-align:right;\n}\n\n .tray-toolbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:10px 0 12px}\n .tray-toolbar .tray-group label {font-size:14px;}\n  .tray-toolbar select{padding:3px 4px;  font-size:14px;}\n  .tray-pager{display:flex;gap:6px;align-items:flex-end;justify-content:flex-end;margin-top:10px}\n  \n \n.tray-pager button {\n    color:#111827;\n    font-weight:normal;\n    font-size:14px;\n    padding:3px 4px;\n    border:none;\n    background:transparent;\n    box-shadow:none;\n    cursor:pointer;\n}\n\n.tray-pager select {\n    font-size:14px;\n    padding:4px 4px;\n    height:2em;\n    margin-top:0;\n    width:4em;\n}\n\n.tray-pager button.tray-next,\n.tray-pager button.tray-prev{\n    background-image: url(\"data:image\/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cpath d='M6.70711 6.29289C6.31658 5.90237 5.68342 5.90237 5.29289 6.29289C4.90237 6.68342 4.90237 7.31658 5.29289 7.70711L9.58579 12L5.29289 16.2929C4.90237 16.6834 4.90237 17.3166 5.29289 17.7071C5.68342 18.0976 6.31658 18.0976 6.70711 17.7071L11.7071 12.7071C12.0976 12.3166 12.0976 11.6834 11.7071 11.2929L6.70711 6.29289Z' fill='%232D3648'\/%3E%3Cpath d='M13.7071 6.29289C13.3166 5.90237 12.6834 5.90237 12.2929 6.29289C11.9024 6.68342 11.9024 7.31658 12.2929 7.70711L16.5858 12L12.2929 16.2929C11.9024 16.6834 11.9024 17.3166 12.2929 17.7071C12.6834 18.0976 13.3166 18.0976 13.7071 17.7071L18.7071 12.7071C19.0976 12.3166 19.0976 11.6834 18.7071 11.2929L13.7071 6.29289Z' fill='%232D3648'\/%3E%3C\/svg%3E%0A\");\n    background-size:100% auto;\n    width:16px;\n    height:16px;\n    text-indent:-9999px;\n}\n\n\n\n.tray-pager button.tray-prev {\n    transform:rotate(180deg);\n}\n\n.tray-pager button.is-active {\n    font-weight:bold;\n    text-decoration:underline;\n}\n\n\n\n .tray-pager button[disabled]{opacity:.5;cursor:not-allowed}\n  .tray-table{width:100%;border-collapse:collapse;font-size:13px}\n  .tray-table th,.tray-table td{padding:8px;border-bottom:1px solid #eee;text-align:left;}\n  .tray-table th.sortable{cursor:pointer;user-select:none}\n  .tray-table th.sortable .arrow{opacity:.45;margin-left:6px}\n  .tray-table th.sortable.active.asc .arrow::after{content:\"\u25b2\"}\n  .tray-table th.sortable.active.desc .arrow::after{content:\"\u25bc\"}\n  .muted-note{font-size:12px;opacity:.75;margin:6px 0}\n\n  .recommended {\n        font-size: .85em;\n    font-style: italic;\n    display: block;\n    font-weight:normal;\n  }\n<\/style>\n\n\n\n  <!-- jsPDF + html2canvas for reliable HTML->PDF -->\n  <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js\" crossorigin=\"anonymous\" referrerpolicy=\"no-referrer\"><\/script>\n  <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html2canvas\/1.4.1\/html2canvas.min.js\" crossorigin=\"anonymous\" referrerpolicy=\"no-referrer\"><\/script>\n<script>\n  window.DRAINAGE_CALC = {\n    ajaxUrl: \"https:\/\/www.vodalandsolutions.com\/wp-admin\/admin-ajax.php\",\n    nonce: \"9c3738f297\",\n    preload: null,\n    preloadPostId: null,\n    containerUrl: \"https:\/\/www.vodalandsolutions.com\/es\/catchment-area-calculator\/\", \/\/ <\u2014 use this to build \u201crevisit\u201d links\n\t  savedListUrl: \"\/my-saved-calculations\/\",\n    mode: \"full\",\n  };\n<\/script>\n\n\n<script>\ndocument.getElementById('btnViewSaved')?.addEventListener('click', () => {\n  const url = window.DRAINAGE_CALC?.savedListUrl || '\/';\n  window.location.href = url;\n});\n<\/script>\n<script>\ndocument.addEventListener('DOMContentLoaded', () => {\n  if (window.DRAINAGE_CALC?.preload) {\n    applyPreload(window.DRAINAGE_CALC.preload);\n  }\n});\n\n\n\t  \nfunction scrollToResults() {\n  const target =\n    document.getElementById('resultsTop') ||\n    document.getElementById('calcResultsTop') ||\n    document.getElementById('resultsCard');\n\n  if (!target) return;\n\n  const doScroll = () => target.scrollIntoView({ behavior: 'smooth', block: 'start' });\n\n  \/\/ Try immediately, then again after layout settles\n  doScroll();\n  requestAnimationFrame(doScroll);\n  setTimeout(doScroll, 200);\n  setTimeout(doScroll, 600);\n\n  \/\/ Keep the current URL but set #results without wiping query params\n  try {\n    const url = new URL(window.location.href);\n    url.hash = 'results';\n    history.replaceState(null, '', url);\n  } catch(e) {}\n}\n\t\t\t\t\t\t  \n\t\t\t\t\t\t  function showSavedBanner() {\n  const step5  = document.querySelector('fieldset.step-5');\n  const h3     = step5?.querySelector('h3');\n  if (!h3) return;\n\n  \/\/ avoid duplicates\n  step5.querySelector('#saveNoticeOutside')?.remove();\n\n  const href = window.DRAINAGE_CALC?.savedListUrl || '\/';\n  \/\/ Add Calculation to a Project - link 1\n  h3.insertAdjacentHTML('afterend', `\n    <div id=\"saveNoticeOutside\" style=\"\n      margin: 10px 0 12px 0; padding:10px 12px;\n      border:1px solid #d1fae5; background:#ecfdf5; color:#065f46;\n      border-radius:8px; font-size:14px;\">\n      \u2705 <strong>Your calculation has been saved.<\/strong>\n      <a href=\"${href}\" style=\"margin-left:8px; text-decoration:underline;\">View Saved Calculations<\/a> |  <a href=\"${href}\" style=\"margin-left:8px; text-decoration:underline;\">Add Calculation to a Project<\/a>\n    <\/div>\n  `);\n}\n\nfunction applyPreload(saved) {\n  \/\/ Name\n  if (saved.calcName) document.getElementById('calcName').value = saved.calcName;\n\n  \/\/ Step 2 inputs\n  if (saved.inputs?.rainfall != null) document.getElementById('rainfall').value = saved.inputs.rainfall;\n  if (saved.inputs?.areas) {\n    ['asphalt', 'brick', 'roofs', 'sandy', 'heavy'].forEach(k => {\n      if (saved.inputs.areas[k] != null) document.getElementById(k).value = saved.inputs.areas[k];\n    });\n  }\n\n  \/\/ Step 3 inputs\n  if (saved.inputs?.requiredMaterial) document.getElementById('requiredMaterial').value = saved.inputs.requiredMaterial;\n  if (saved.inputs?.requiredLoadClass) document.getElementById('requiredLoadClass').value = saved.inputs.requiredLoadClass;\n  if (saved.inputs?.length != null) document.getElementById('length').value = saved.inputs.length;\n  if (saved.inputs?.slope  != null) document.getElementById('slope').value  = saved.inputs.slope;\n  if (saved.inputs?.outlets!= null) document.getElementById('outlets').value= saved.inputs.outlets;\n\n  renderFlowSummaryBox();\n\n  \/\/ Restore calcMeta\n  if (saved.calcMeta) window.calcMeta = saved.calcMeta;\n\n\/\/ Ensure tray selection persists\nif (!window.calcMeta) window.calcMeta = {};\n\n\/\/ Restore tray ID from saved calc\nif (saved?.calcMeta?.selectedTrayId != null) {\n  window.calcMeta.selectedTrayId = saved.calcMeta.selectedTrayId;\n} else if (saved?.finalResults?.selectedTrayId != null) {\n  window.calcMeta.selectedTrayId = saved.finalResults.selectedTrayId;\n}\n\n\/\/ Restore tray label (article number + name) into input field\nif (saved?.calcMeta?.selectedTrayLabel) {\n  const labelInput = document.getElementById('articleNumberSearch');\n  if (labelInput) labelInput.value = saved.calcMeta.selectedTrayLabel;\n}\n\n\/\/ Set the hidden input (needed for backend logic)\nconst trayInput = document.getElementById('selectedTrayId');\nif (trayInput && window.calcMeta.selectedTrayId) {\n  trayInput.value = window.calcMeta.selectedTrayId;\n}\n\n  \/\/ \u2705 Fix: Directly handle wastewater calculators (`manual_gpm`)\n  if (window.DRAINAGE_CALC?.mode === 'manual_gpm' && saved.finalResults) {\n    window.finalResults = saved.finalResults;\n\n      \/\/ \u2705 Ensure selected tray ID is preserved for later preselect\n      if (saved.finalResults.selectedTrayId) {\n        if (!window.calcMeta) window.calcMeta = {};\n        window.calcMeta.selectedTrayId = saved.finalResults.selectedTrayId;\n      }\n\n       if (saved.inputs?.requiredMaterial && saved.inputs?.requiredLoadClass) {\n    document.getElementById('requiredMaterial').value = saved.inputs.requiredMaterial;\n    document.getElementById('requiredLoadClass').value = saved.inputs.requiredLoadClass;\n\n    findTrays().then(() => {\n      preselectTrayIfAvailable();\n      buildFinalResults(true);\n      gotoStep(5);\n    });\n    return;\n   \/\/ findTrays(); \/\/ rebuild table with rows + preselect\n  \/\/  return;\n  }\n\n\n    buildFinalResults(true); \/\/ rebuild results without re-saving\n    preselectTrayIfAvailable();\n    gotoStep(5);\n\n    \/\/ Auto-scroll to results\n    setTimeout(() => {\n      document.getElementById('calcResultsTop')?.scrollIntoView({ behavior: 'smooth' });\n    }, 200);\n    return;\n  }\n\n\n\nif (window.DRAINAGE_CALC?.mode === 'capacity' && saved.finalResults) {\n  document.body.classList.add('dc-capacity');\n  window.calcMeta = saved.calcMeta || {};\n  window.finalResults = saved.finalResults;\n\n  \/\/ Restore material + load class\n  if (saved.inputs?.requiredMaterial) {\n    document.getElementById('requiredMaterial').value = saved.inputs.requiredMaterial;\n  }\n  if (saved.inputs?.requiredLoadClass) {\n    document.getElementById('requiredLoadClass').value = saved.inputs.requiredLoadClass;\n  }\n\n  \/\/ Rebuild tray list, then preselect and go to results\n  findTrays().then(() => {\n    preselectTrayIfAvailable();\n    buildFinalResults(true);\n    gotoStep(5);\n    setTimeout(() => {\n      document.getElementById('calcResultsTop')?.scrollIntoView({ behavior: 'smooth' });\n    }, 200);\n  });\n\n  return;\n}\n\n  \/\/ Normal mode logic\n  if (saved.resultsHtml) {\n    document.getElementById('resultsCard').innerHTML = saved.resultsHtml;\n    window.finalResults = saved.finalResults || { totalGpm: saved.calcMeta?.totalGpm ?? null };\n    gotoStep(5);\n     scrollToResults();\n  } else {\n    gotoStep(3);\n  }\n}\n\n\/\/ \u2014\u2014 Overwrite modal helpers \u2014\u2014\nfunction openOverwriteModal() {\n  const m = document.getElementById('overwriteModal');\n  if (!m) return;\n  \/\/ default name: Copy of [current calculator name]\n  const current = (document.getElementById('calcName')?.value || '').trim() || 'Untitled Calculation';\n  const def = `Copy of ${current}`;\n  const input = m.querySelector('#newCalcName');\n  input.value = def;\n  m.querySelector('#saveAsNewBlock').style.display = 'none'; \/\/ hidden until user picks \"Save as New\"\n  m.style.display = 'flex';\n}\n\n\/\/ before: always wiped the flags (bug)\n\/\/ after: only wipe when called with { cancel: true }\nfunction closeOverwriteModal(opts = {}) {\n  const { cancel = false } = opts;\n  const m = document.getElementById('overwriteModal');\n  if (m) m.style.display = 'none';\n  if (cancel) {\n    window._confirmedSaveMode = null;\n    window._forceSaveAsNew = false;\n    window._forceNewTitle = null;\n  }\n}\n\n\/\/ Cancel \/ backdrop (actually cancel)\ndocument.getElementById('btnCancelOverwrite')?.addEventListener('click', () => {\n  closeOverwriteModal({ cancel: true });\n  gotoStep(4);            \/\/ <- keep the user where they were\n  scrollStepTop(4);\n});\ndocument.querySelector('#overwriteModal [data-backdrop]')?.addEventListener('click', () => {\n  closeOverwriteModal({ cancel: true });\n  gotoStep(4);            \/\/ <- same for clicking outside\n  scrollStepTop(4);\n});\n\n\/\/ Save as New (confirm)\ndocument.getElementById('btnSaveAsNew')?.addEventListener('click', () => {\n  const block = document.querySelector('#saveAsNewBlock');\n  if (!block) return;\n  if (block.style.display === 'none') {\n    block.style.display = 'block';\n    return; \/\/ first click just reveals the name field\n  }\n  const name = (document.getElementById('newCalcName')?.value || '').trim();\n  window._forceSaveAsNew = true;\n  window._forceNewTitle = name || (document.getElementById('newCalcName')?.placeholder || 'Copy');\n  window._confirmedSaveMode = 'new';\n  closeOverwriteModal({ cancel: false }); \/\/ <-- keep flags!\n  buildFinalResults();\n});\n\n\/\/ Overwrite (confirm)\ndocument.getElementById('btnOverwrite')?.addEventListener('click', () => {\n  window._confirmedSaveMode = 'overwrite';\n  window._forceSaveAsNew = false;\n  window._forceNewTitle = null;\n  closeOverwriteModal({ cancel: false }); \/\/ <-- keep state as-is\n  buildFinalResults();\n});\n\n\/\/ Cancel \/ backdrop (actually cancel)\ndocument.getElementById('btnCancelOverwrite')?.addEventListener('click', () => closeOverwriteModal({ cancel: true }));\ndocument.querySelector('#overwriteModal [data-backdrop]')?.addEventListener('click', () => closeOverwriteModal({ cancel: true }));\n\nfunction openNoMatchModal() {\n  const m = document.getElementById('noMatchModal');\n  if (!m) return;\n  m.style.display = 'flex';\n  \/\/ optional: focus the primary action for accessibility\n  setTimeout(() => m.querySelector('#btnContactEng')?.focus(), 50);\n}\n\nfunction closeNoMatchModal() {\n  const m = document.getElementById('noMatchModal');\n  if (!m) return;\n  m.style.display = 'none';\n}\n\ndocument.getElementById('btnTryAnother')?.addEventListener('click', () => {\n  closeNoMatchModal();\n  \/\/ If you prefer to jump the user back to Step 3 automatically, uncomment:\n  \/\/ gotoStep(3);\n  \/\/ scrollStepTop(3);\n});\n\ndocument.querySelector('#noMatchModal [data-backdrop]')?.addEventListener('click', closeNoMatchModal);\n\n<\/script>\n<script>\ndocument.addEventListener('DOMContentLoaded', () => {\n  if (window.DRAINAGE_CALC?.mode === 'manual_gpm') {\n    document.body.classList.add('dc-manual-gpm');\n\n    \/\/ If a saved calc already has full results, applyPreload has moved us to Step 5.\n      \/\/ Leave the step state alone so we don't fight it here.\n      if (window.DRAINAGE_CALC?.preload?.finalResults) {\n        return;\n      }\n\n    \/\/ Don\u2019t run Step 1 mode logic in manual-GPM\n    window.__DC_SKIP_STEP1_INIT__ = true;\n\n    \/\/ Make Step 1 (name) and Step M (manual GPM) both interactive\n    document.querySelectorAll('#drainage-calculator fieldset').forEach(fs => fs.classList.remove('active'));\n    document.querySelector('fieldset.step-1')?.classList.add('active'); \/\/ shows name row\n    document.querySelector('fieldset.step-1')?.classList.remove('closed'); \/\/ shows name row\n    document.querySelector('fieldset.step-m')?.classList.add('active'); \/\/ shows manual GPM entry\n     document.querySelector('fieldset.step-m')?.classList.remove('closed'); \/\/ shows manual GPM entry\n\n    \/\/ If a saved calc already has totalGpm, jump to Step 3 as before\n    if (window.DRAINAGE_CALC?.preload?.calcMeta?.totalGpm) {\n      const gpm = Number(window.DRAINAGE_CALC.preload.calcMeta.totalGpm) || 0;\n      const card = document.getElementById('resultsCard');\n      if (card) card.dataset.flow = gpm;\n      if (!window.calcMeta) window.calcMeta = {};\n      window.calcMeta.totalGpm = gpm;\n\n      if (window.DRAINAGE_CALC.preload.calcMeta.selectedTrayId) {\n    window.calcMeta.selectedTrayId = String(window.DRAINAGE_CALC.preload.calcMeta.selectedTrayId);\n  }\n\n      renderFlowSummaryBox();\n      \/\/ Keep name visible, go to Step 3 for editing\n      document.querySelector('fieldset.step-m')?.classList.remove('active');\n      document.querySelector('fieldset.step-3')?.classList.add('active');\n      document.querySelector('fieldset.step-3')?.classList.remove('closed');\n      return;\n    }\n\n    \/\/ Manual GPM \u201cContinue\u201d behavior (unchanged)\n \/\/ Handle manual GPM entry \"Next\" button\ndocument.getElementById('btnManualGpmNext')?.addEventListener('click', () => {\n  const v = parseFloat(document.getElementById('manualTotalGpm')?.value);\n\n  \/\/ Validate positive GPM\n  if (!(v > 0)) {\n    alert('Please enter a positive total flow (GPM).');\n    return;\n  }\n\n  \/\/ Stash the value in the results card dataset\n  const card = document.getElementById('resultsCard');\n  if (card) card.dataset.flow = v;\n\n  \/\/ Update calcMeta for downstream formulas and results\n  if (!window.calcMeta) window.calcMeta = {};\n  window.calcMeta.totalGpm = v;\n  window.calcMeta.rainfallIntensity = null; \/\/ Not used in manual mode\n  window.calcMeta.mode = 'manual_gpm';\n\n  \/\/ Update the flow summary at the top of Step 3+\n  renderFlowSummaryBox();\n\n  \/\/ Go directly from Step 1 to Step 3 (skip Step 2 entirely)\n  document.querySelector('fieldset.step-1')?.classList.remove('active');\n  document.querySelector('fieldset.step-3')?.classList.add('active');\n    document.querySelector('fieldset.step-3')?.classList.remove('closed');\n\n          document.body.classList.forEach(cls => {\n    if (cls.startsWith('step-active-')) {\n      document.body.classList.remove(cls);\n    }\n  });\n      document.querySelector('body')?.classList.add(`step-active-3`);\n\n  \/\/ Ensure we scroll to Step 3 top\n  scrollStepTop(3);\n});\n  }\n\nif (window.DRAINAGE_CALC?.mode === 'capacity') {\n  document.body.classList.add('dc-capacity');\n\n  if (!window.calcMeta) window.calcMeta = {};\n  window.calcMeta.mode = 'capacity';\n\n  \/\/ If a saved calc already has results, go straight to Step 5\n  if (window.DRAINAGE_CALC?.preload?.finalResults) {\n    buildFinalResults(true);\n    gotoStep(5);\n    setTimeout(() => {\n      document.getElementById('calcResultsTop')?.scrollIntoView({ behavior: 'smooth' });\n    }, 200);\n    return;\n  }\n\n  \/\/ Otherwise, show Step 1 (name) + Step 3 (project properties) to start fresh\n  document.querySelector('fieldset.step-1')?.classList.add('active');\n  document.querySelector('fieldset.step-3')?.classList.add('active');\n\n    document.querySelector('fieldset.step-1')?.classList.remove('closed');\n  document.querySelector('fieldset.step-3')?.classList.remove('closed');\n}\n\n});\n<\/script>\n  <script>\n    \/\/ Expose current user for PDF file naming & summary\n    window.wpCurrentUser = { name: \"Guest\" };\n\t\t\t\t\t\t\t\n\t\/\/ Scratchpad for what the user picked so we can show it in results\/PDF\n\twindow.calcMeta = {\n\t  mode: null,            \/\/ 'manual' | 'zip-custom' | 'zip-site'\n\t  zip: null,\n\t  siteType: null,\n\t  duration: null,\n\t  ariYear: null,\n\t  rainfallIntensity: null,  \/\/ in\/hr\n\t  totalGpm: null,           \/\/ from Step 2\n\t  selectedMaterialName: null,\n\t  lineLength: null,\n\t  slope: null,\n\t  outlets: null,\n\t};\n\n    \/\/ Site type -> duration + ARI index\/year\n    const siteSettings = {\n      \"Single-Family Residential\": { duration: \"30-min\", ariIndex: 2, ariYear: 2 },\n      \"Multi-Family Housing\/Townhomes\": { duration: \"30-min\", ariIndex: 3, ariYear: 5 },\n      \"Commercial \/ Parking Lot \/ Retail\": { duration: \"30-min\", ariIndex: 4, ariYear: 10 },\n      \"Industrial\/Warehouses\": { duration: \"60-min\", ariIndex: 5, ariYear: 25 },\n      \"Public Facilities - Schools \/ Hospitals\/Public Buildings\": { duration: \"60-min\", ariIndex: 5, ariYear: 25 },\n      \"Critical Infrastructure - Emergency \/ Utility \/ Airports \/ Fire Stations \/ Pump Stations\": { duration: \"60-min\", ariIndex: 7, ariYear: 100 },\n      \"Major Roads and Highways - Normal Risk\": { duration: \"60-min\", ariIndex: 5, ariYear: 25 },\n      \"Major Roads and Highways - High Risk (Interstates or High Risk Zones)\": { duration: \"60-min\", ariIndex: 6, ariYear: 50 },\n      \"Major Roads and Highways - Very High Risk (Evacuation Routes)\": { duration: \"60-min\", ariIndex: 7, ariYear: 100 }\n    };\n    function ariYearToCsvIndex(year) {\n      const map = {1:1,2:2,5:3,10:4,25:5,50:6,100:7,200:8,500:9,1000:10};\n      return map[year] ?? 2;\n    }\n\n    \/\/ Loader controls\n    function showRainLoader(show) {\n      const el = document.getElementById('rainLoaderOverlay');\n      if (!el) return;\n      el.classList.toggle('show', !!show);\n      if (show) {\n        \/\/ reset and animate fill 0 -> 50% height\n        const rect = el.querySelector('.water-fill');\n        if (rect) {\n          rect.setAttribute('y', 50);\n          rect.setAttribute('height', 0);\n          let start = null;\n          const targetY = 25; \/\/ halfway (50% fill)\n          const targetH = 25;\n          const duration = 1400; \/\/ slower rise\n          function step(ts) {\n            if (!start) start = ts;\n            const t = Math.min(1, (ts - start) \/ duration);\n            const ease = 1 - Math.pow(1 - t, 3);\n            const y = 50 - ease * (50 - targetY);\n            const h = ease * targetH;\n            rect.setAttribute('y', y);\n            rect.setAttribute('height', h);\n            if (t < 1 && el.classList.contains('show')) requestAnimationFrame(step);\n          }\n          requestAnimationFrame(step);\n        }\n      }\n    }\n\t  \n\t  function renderFlowSummaryBox() {\n  const flowEl   = document.getElementById('flowOutput');\n  if (!flowEl) return;\n\n  \/\/ total GPM was set when clicking \"Calculate Flow\" (Step 2)\n  const totalGpm = Number(calcMeta.totalGpm || 0);\n\n  \/\/ dynamic inputs in Step 3\n  const outlets  = Math.max(1, Number(document.getElementById('outlets')?.value || 1));\n  const lengthFt = Number(document.getElementById('length')?.value || 0);\n\n  \/\/ metrics\n  const gpmPerOutlet = outlets > 0 ? (totalGpm \/ outlets) : totalGpm;\n  const numDrainageChannels = lengthFt * 0.3048; \/\/ per spec (ft \u00d7 0.3048)\n\n  \/\/ stash so we can show it in final results\n  calcMeta.outlets = outlets;\n  calcMeta.lineLength = lengthFt;\n  calcMeta.numDrainageChannels = numDrainageChannels;\n\n  \/\/ render\n  const fmt = (n, d=2) => (Number.isFinite(n) ? n.toFixed(d) : '\u2014');\n  flowEl.innerHTML = `\n    <div class=\"flow-summary\">\n      <h4>Estimated Flow & Layout<\/h4>\n      <div class=\"grid-3\">\n        <div class=\"metric metric-estimated-flow-rate\">\n          <div class=\"k\">Estimated Flow Rate<\/div>\n          <div class=\"v\">${fmt(totalGpm)} GPM<\/div>\n        <\/div>\n        <div class=\"metric metric-flow-rate-per-outlet\">\n          <div class=\"k\">Flow Rate per Outlet<\/div>\n          <div class=\"v\">${fmt(gpmPerOutlet)} GPM<\/div>\n        <\/div>\n        <div class=\"metric metric-number-of-drainage-channels\">\n          <div class=\"k\">Number of Drainage Channels<\/div>\n          <div class=\"v\">${fmt(numDrainageChannels)}<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  `;\n}\n\n['outlets', 'length'].forEach(id => {\n  document.getElementById(id)?.addEventListener('input', renderFlowSummaryBox);\n});\n\n\nfunction scrollStepTop(n) {\n  const stepEl = document.querySelector(`fieldset.step-${n}`);\n  const header = stepEl;\n\n  if (header) {\n    \/\/ Wait 500ms (e.g. for transitions) + 1 animation frame\n    setTimeout(() => {\n      requestAnimationFrame(() => {\n        const offset = 120;\n        const elementTop = header.getBoundingClientRect().top + window.scrollY;\n        const targetPosition = elementTop - offset;\n        console.log(\"n:\"+  n);\n        console.log(\"target \" + elementTop);\n        console.log(\"targetwithoffset: \" + targetPosition);\n        window.scrollTo({\n          top: targetPosition,\n          behavior: 'smooth'\n        });\n      });\n    }, 50); \/\/ Delay before scrolling\n  }\n}\n    \/\/ Step navigation (Back buttons)\n\n\/\/ Step navigation (Back buttons)\ndocument.addEventListener('click', (e) => {\n  const btn = e.target.closest('.back-btn');\n  if (!btn) return;\n\n  let backTo = parseInt(btn.dataset.back, 10);\n  const isManual   = window.DRAINAGE_CALC?.mode === 'manual_gpm';\n  const isCapacity = window.DRAINAGE_CALC?.mode === 'capacity';\n\n   \/\/ Identify the currently active step and mark it as closed\n  const currentStep = document.querySelector('#drainage-calculator fieldset.active');\n  if (currentStep) {\n    currentStep.classList.add('closed');\n    currentStep.classList.remove('active');\n  }\n\n  \/\/ Deactivate all steps\n  document.querySelectorAll('#drainage-calculator fieldset')\n    .forEach(fs => fs.classList.remove('active'));\n\n  \/\/ Step 1 (name row) should always be active in manual\/capacity\n  if (isManual || isCapacity) {\n\n\n\n    document.querySelector('fieldset.step-1')?.classList.add('active');\n    document.querySelector('fieldset.step-1')?.classList.remove('closed');\n\n    \/\/ Never land on Step 2 in these modes\n    if (backTo === 2) backTo = 1;\n  }\n\n  \/\/ Activate requested step\n  const stepEl = document.querySelector(`fieldset.step-${backTo}`);\n  stepEl?.classList.add('active');\n   stepEl?.classList.remove('closed');\n  stepEl?.removeAttribute('disabled');\n\n  if (stepEl) {\n  document.body.classList.forEach(cls => {\n    if (cls.startsWith('step-active-')) {\n      document.body.classList.remove(cls);\n    }\n  });\n  document.body.classList.add(`step-active-${backTo}`);\n}\n\n  \/\/ \u2705 If we navigated to Step 3, always show the Estimated Flow & Layout box\n  if (backTo === 3) {\n    renderFlowSummaryBox();\n  }\n\n  \/\/ If we navigated to Step 4 and the table isn't built yet, rebuild it\n  if (backTo === 4) {\n    const mat = document.getElementById('requiredMaterial')?.value || '';\n    const load = document.getElementById('requiredLoadClass')?.value || '';\n    const trayWrap = document.getElementById('trayResults');\n\n    if (mat && load && trayWrap && !trayWrap.querySelector('input[name=\"selectedTray\"]')) {\n      if (!window.calcMeta) window.calcMeta = {};\n\n      if (window.calcMeta.totalGpm == null) {\n        const flow = parseFloat(document.getElementById('resultsCard')?.dataset.flow || '0') || 0;\n        window.calcMeta.totalGpm = flow;\n      }\n\n      \/\/ carry forward saved selection if coming back from Step 5\n      if (!window.calcMeta.selectedTrayId && window.finalResults?.selectedTrayId) {\n        window.calcMeta.selectedTrayId = String(window.finalResults.selectedTrayId);\n      }\n\n      findTrays().then(() => {\n        preselectTrayIfAvailable();\n      });\n    }\n  }\n\n  \/\/ Scroll to the top of the active step\n  scrollStepTop(backTo);\n});\n\n\n\/\/ Track selected tray ID whenever a radio is clicked\ndocument.addEventListener('change', (e) => {\n  if (e.target.matches('input[name=\"selectedTray\"]')) {\n    const selectedId = e.target.dataset.postId || e.target.value.replace('tray_', '');\n    if (!window.calcMeta) window.calcMeta = {};\n    window.calcMeta.selectedTrayId = selectedId;\n  }\n});\n\n    \/\/ Progressive disclosure for Step 1 modes\n    (function initStep1Modes() {\n       if (window.DRAINAGE_CALC?.mode === 'manual_gpm' || window.DRAINAGE_CALC?.mode === 'capacity') return;\n\n\n      const radios = document.querySelectorAll('input[name=\"intensityMode\"]');\n      const panels = {\n        manual: document.getElementById('panel-manual'),\n        'zip-custom': document.getElementById('panel-zip-custom'),\n        'zip-site': document.getElementById('panel-zip-site')\n      };\n      radios.forEach(r => {\n        r.addEventListener('change', () => {\n          Object.values(panels).forEach(p => p.hidden = true);\n          panels[r.value].hidden = false;\n        });\n      });\n\n      \/\/ Manual \u2192 Step 2\n    document.getElementById('btnManualNext')?.addEventListener('click', () => {\n  const v = parseFloat(document.getElementById('manualRainInput').value);\n  if (!(v > 0)) return alert('Please enter a positive rainfall intensity.');\n  document.getElementById('rainfall').value = v.toFixed(2);\n\n  \/\/ record meta\n  calcMeta.mode = 'manual';\n  calcMeta.zip = null;\n  calcMeta.siteType = null;\n  calcMeta.duration = null;\n  calcMeta.ariYear = null;\n  calcMeta.rainfallIntensity = v;\n\n  gotoStep(2);\n});\n\n      \/\/ ZIP + custom duration\/ARI\n      document.getElementById('btnZipCustomFetch')?.addEventListener('click', async () => {\n  const zip = (document.getElementById('zipInputCustom').value || '').trim();\n  if (!zip) return alert('Please enter a ZIP code.');\n  const duration = document.getElementById('durationSelect')?.value || '60-min';\n  const ariYear  = parseInt(document.getElementById('ariSelect')?.value || '2', 10);\n  const idx      = ariYearToCsvIndex(ariYear);\n\n  showRainLoader(true);\n  try {\n    const res = await fetch(`\/wp-admin\/admin-ajax.php?action=get_pfds_intensity&zip=${encodeURIComponent(zip)}&duration=${encodeURIComponent(duration)}&index=${idx}`);\n    const data = await res.json();\n    if (!data.success) throw new Error(data?.data?.message || 'Lookup failed');\n    const intensity = Number(data.data.intensity);\n    document.getElementById('rainfall').value = intensity.toFixed(2);\n\n    \/\/ record meta\n    calcMeta.mode = 'zip-custom';\n    calcMeta.zip = zip;\n    calcMeta.siteType = null;\n    calcMeta.duration = duration;\n    calcMeta.ariYear = ariYear;\n    calcMeta.rainfallIntensity = intensity;\n\n    gotoStep(2);\n  } catch (e) {\n    alert('Rainfall lookup failed: ' + e.message);\n  } finally {\n    showRainLoader(false);\n  }\n});\n\n      \/\/ ZIP + site type suggestion\n   document.getElementById('btnZipSiteFetch')?.addEventListener('click', async () => {\n  const zip = (document.getElementById('zipInputSite').value || '').trim();\n  const siteType = document.getElementById('siteType').value;\n  if (!zip || !siteType) return alert('Enter ZIP and select Site Type.');\n\n  const s = siteSettings[siteType];\n  const duration = s.duration;\n  const idx = s.ariIndex;\n  const ariYear = s.ariYear;\n\n  showRainLoader(true);\n  try {\n    const res = await fetch(`\/wp-admin\/admin-ajax.php?action=get_pfds_intensity&zip=${encodeURIComponent(zip)}&duration=${encodeURIComponent(duration)}&index=${idx}`);\n    const data = await res.json();\n    if (!data.success) throw new Error(data?.data?.message || 'Lookup failed');\n    const intensity = Number(data.data.intensity);\n    document.getElementById('rainfall').value = intensity.toFixed(2);\n\n    \/\/ record meta\n    calcMeta.mode = 'zip-site';\n    calcMeta.zip = zip;\n    calcMeta.siteType = siteType;\n    calcMeta.duration = duration;\n    calcMeta.ariYear = ariYear;\n    calcMeta.rainfallIntensity = intensity;\n\n    gotoStep(2);\n  } catch (e) {\n    alert('Rainfall lookup failed: ' + e.message);\n  } finally {\n    showRainLoader(false);\n  }\n});\n    })();\n\n    function gotoStep(n) {\n      prevStep = n-1;\n      console.log(\"went to step \" + n);\n      document.querySelectorAll('#drainage-calculator fieldset').forEach(fs => fs.classList.remove('active'));\n      document.querySelector(`fieldset.step-${n}`)?.classList.add('active');\n      document.querySelector(`fieldset.step-${n}`)?.classList.remove('closed');\n      document.body.classList.forEach(cls => {\n    if (cls.startsWith('step-active-')) {\n      document.body.classList.remove(cls);\n    }\n  });\n      document.querySelector('body')?.classList.add(`step-active-${n}`);\n\n\n        scrollStepTop(n);\n\n\t\tif (n === 3) renderFlowSummaryBox();\n\n\n    }\n\n    \/\/ Step 2: Calculate Flow (advances to Step 3)\n    document.getElementById('btnCalcFlow')?.addEventListener('click', () => {\n      const c = { asphalt: 0.9, brick: 0.8, roofs: 0.9, sandy: 0.2, heavy: 0.3 };\n      const rain = parseFloat(document.getElementById('rainfall').value);\n      const ids = ['asphalt','brick','roofs','sandy','heavy'];\n      let totalFlow = 0, totalArea = 0;\n\n      ids.forEach(id => {\n        const sqft = parseFloat(document.getElementById(id).value) || 0;\n        totalFlow += c[id] * sqft * rain * 0.623 \/ 60; \/\/ GPM\n        totalArea += sqft;\n      });\n\n     document.getElementById('flowOutput').textContent = `Estimated Flow Rate: ${totalFlow.toFixed(2)} GPM`;\n\/\/ stash for downstream\nconst resultsEl = document.getElementById('resultsCard');\nresultsEl.dataset.flow = totalFlow;\nresultsEl.dataset.area = totalArea;\n\n\/\/ record meta\ncalcMeta.rainfallIntensity = rain;\ncalcMeta.totalGpm = totalFlow;\ncalcMeta.totalArea = totalArea;   \/\/ \u2190 ADD THIS\nrenderFlowSummaryBox();\ngotoStep(3);\n    });\n\n    \/\/ Step 3 \u2192 Step 4: Find trays\n    const DEFAULT_MANNING_N = 0.015;\n    const STEEL_MANNING_N   = 0.012;\n\n    document.getElementById('btnFindTrays')?.addEventListener('click', findTrays);\n    async function findTrays() {\n      const material = document.getElementById('requiredMaterial')?.value || '';\n      const load     = document.getElementById('requiredLoadClass')?.value || '';\n      const isCapacityMode = document.body.classList.contains('dc-capacity'); \/\/ or however you're flagging it\n\nif (!isCapacityMode && (!material || !load)) {\n  return alert('Please select both Required Material and Required Load Class.');\n}\n\n\/\/ store human-friendly selected material name\nconst matSel = document.getElementById('requiredMaterial');\ncalcMeta.selectedMaterialName = matSel && matSel.options[matSel.selectedIndex] ? matSel.options[matSel.selectedIndex].text : '';\n\n\/\/ also store line inputs\ncalcMeta.lineLength = parseFloat(document.getElementById('length').value) || null;\ncalcMeta.slope = parseFloat(document.getElementById('slope').value) || null;\ncalcMeta.outlets = Math.max(1, parseFloat(document.getElementById('outlets').value) || 1);\n\n      try {\n        const selectedTrayId = window.calcMeta?.selectedTrayId || '';\n\n        const res = await fetch(`\/wp-admin\/admin-ajax.php?action=get_tray_recommendations&material=${encodeURIComponent(material)}&load=${encodeURIComponent(load)}&selected_tray_id=${encodeURIComponent(selectedTrayId)}`);\n        const data = await res.json();\n        if (!data.success) throw new Error(data?.data?.message || 'Unknown error');\n\n        const rows = data.data.rows || [];\n        const wrap = document.getElementById('trayResults');\n        wrap.innerHTML = '';\n\n        if (!rows.length) {\n          wrap.innerHTML = '<p>No matching channels found for that combination. Please <a href=\"\/contact-us\">contact us<\/a> to talk through options with our engineering team.<\/p>';\n          openNoMatchModal(); \n          return;\n        } else {\n          const slope   = parseFloat(document.getElementById('slope').value);                \/\/ G49\n          const length  = parseFloat(document.getElementById('length').value);               \/\/ G48\n       \/\/   const Qr      = parseFloat(document.getElementById('resultsCard').dataset.flow) || 0;  \/\/ G53 (GPM)\n\n\/\/ G36: total flow (GPM) calculated in Step 2\nconst QrTotal  = parseFloat(document.getElementById('resultsCard').dataset.flow) || 0;\n\n\/\/ G50: number of outlets from Step 3 (min 1)\nconst outlets  = Math.max(1, parseFloat(document.getElementById('outlets').value) || 1);\n\n\/\/ G53: flow per outlet (GPM) = G36 \/ G50\nconst Qr = QrTotal \/ outlets;\n\n          if (!(slope > 0)) { alert('Please enter a positive longitudinal slope.'); return; }\n\n          const selectedLoadText = document.querySelector('#requiredLoadClass option:checked')?.textContent?.trim() || '';\nconst primaryRows = [];\nconst otherRows   = [];\n\/\/ ---------- NEW: unified\/enriched dataset + UI state ----------\nconst wrap = document.getElementById('trayResults');\nconst controlsMount = document.getElementById('trayControls') || wrap;\n\nfunction depthBucket(inches){\n  const d = parseFloat(inches);\n  if (!isFinite(d)) return 'none';\n  if (d <= 6) return 'shallow';\n  if (d < 12) return 'medium';\n  return 'deep';\n}\n\n\/\/ Enrich rows with computed hydraulics + normalized fields so we can sort\/filter quickly\nconst enriched = rows.map(r => {\n  const id    = r.id;\n  const name  = r.name ?? '';\n  const artno = r.article_number ?? '';\n\n  const P55 = parseFloat(r.width_of_hydraulic_channel); \/\/ width (in)\n  const P56 = parseFloat(r.depth_of_flow);              \/\/ depth (in)\n  const P57 = parseFloat(r.channel_radius);             \/\/ radius (in)\n\n  let P58 = parseFloat(r.cross_sectional_area); \/\/ ft\u00b2\n  let P59 = parseFloat(r.wetted_perimeter);     \/\/ ft\n\n  if (!isFinite(P58) && isFinite(P55) && isFinite(P56) && isFinite(P57)) {\n    P58 = (((P55 * (P56 - P57)) + (Math.PI * (P57 ** 2) \/ 2)) \/ 144);\n  }\n  if (!isFinite(P59) && isFinite(P56) && isFinite(P57)) {\n    P59 = ((3.14 * P57) + (2 * P56)) \/ 12;\n  }\n  const P60 = (isFinite(P58) && isFinite(P59) && P59 > 0) ? (P58 \/ P59) : NaN;\n\n  const slugs = Array.isArray(r.material_slugs) ? r.material_slugs.map(s => (s || '').toLowerCase()) : [];\n  const isSteel = slugs.some(s => s.includes('steel'));\n  const n = isSteel ? STEEL_MANNING_N : DEFAULT_MANNING_N;\n\n  const P62 = (isFinite(P60) && P60 > 0)\n    ? (1.486 \/ n) * Math.pow(P60, 2\/3) * Math.sqrt(slope)\n    : NaN;\n\n  const g = 32.2;\n  const hf = (isFinite(P62) && isFinite(P60) && P60 > 0)\n    ? (n * (length \/ (P60 * 4)) * ((P62 ** 2) \/ (2 * g)))\n    : NaN;\n  const hl = isFinite(P62) ? 0.2 * ((P62 ** 2) \/ (2 * g)) : NaN;\n  const G64 = (isFinite(P62) && isFinite(hf) && isFinite(hl)) ? (P62 - (hf + hl)) : NaN;\n\n  const Qcfs = (isFinite(G64) && isFinite(P58) && G64 > 0 && P58 > 0) ? (G64 * P58) : NaN; \/\/ cfs\n  const Qgpm = isFinite(Qcfs) ? (Qcfs * 448.831) : NaN;                                     \/\/ GPM\n  const g68Val = isFinite(Qgpm) ? Qgpm : null;\n  const g6870Val = isFinite(Qgpm) ? (Qgpm * 0.7) : NaN;\n\n\n  const g73Val = (isFinite(Qr) && isFinite(Qgpm) && Qgpm > 0) ? (Qr \/ Qgpm) : NaN;\n\n  \/\/ Normalize product type(s) to an array of strings\n  let pt = (r.channel_product_type || '').split(',').map(s => s.trim()).filter(Boolean);\n  if (!pt.length && r.channel_product_type) pt = [String(r.channel_product_type).trim()];\n\n  const overallHeight = r.overall_height ?? ''; \/\/ ACF string like \"12\"\n  const groupNames = Array.isArray(r.group_terms_names) ? r.group_terms_names : [];\n  const groupSlugs = Array.isArray(r.group_terms_slugs) ? r.group_terms_slugs : [];\n  return {\n    \/\/ identity + display\n    id, name, artno,\n    loadNames: r.load_class_names || [],\n    img3d: r.img3d_url || '',\n    diagram: r.diagram_url || '',\n    active: r.active !== false,\n    widthIn: isFinite(P55) ? P55 : null,\n    depthIn: isFinite(P56) ? P56 : null,\n    radiusIn: isFinite(P57) ? P57 : null,\n    \/\/ computed\n    velocity: isFinite(G64) ? G64 : null,\n    filling: isFinite(g73Val) ? g73Val : null, \/\/ Qr\/Ql\n    g68: g68Val,\n    g6870: g6870Val,\n    fillingColor: (isFinite(g73Val) && g73Val <= 0.70) ? '#00938D' : '#EEC90E',\n    fillingColorBG: (isFinite(g73Val) && g73Val <= 0.70) ? '#ffffff' : '#FFFAEE',\n    \/\/ taxonomy\/meta helpers\n    overallHeight,\n    inSelectedLoad: !!r.in_selected_load,\n    primaryLoadName: r.primary_load_name || '',\n    \/\/ filters\n    productTypes: pt,              \/\/ array\n    depthBucket: depthBucket(P56), \/\/ 'shallow'|'medium'|'deep'|'none'\n    \/\/ keep raw for data attributes\n    groupNames,\n    groupSlugs,\n    raw: r,\n  };\n});\n\nconst selectedTrayId = document.getElementById('selectedTrayId')?.value;\n\nlet primaryData = [];\nlet otherData = [];\n\nif (selectedTrayId && parseInt(selectedTrayId) > 0) {\n  console.log(\"got here\");\n  \/\/ Peak Flow mode \u2013 we know enriched has just 1 item\n  primaryData = enriched;\n  otherData = [];\n} else {\n  \/\/ Normal mode \u2013 do load class filtering\n  primaryData = enriched.filter(e => e.inSelectedLoad);\n  otherData   = enriched.filter(e => !e.inSelectedLoad && Number.isFinite(e.filling) && e.filling <= 0.70);\n}\n\n\/\/ Collect dynamic product-type options\nconst allPT = new Set();\nenriched.forEach(e => e.productTypes.forEach(p => allPT.add(p)));\nconst ptOptions = Array.from(allPT).sort((a,b)=>a.localeCompare(b));\n\n\/\/ ---------- State ----------\n\/\/ Mount two sections\nwrap.innerHTML = `\n  <div id=\"trayPrimarySection\"><\/div>\n  <div id=\"trayOtherSection\"><\/div>\n`;\n\n\/\/ Reusable section renderer (scoped state\/controls\/table)\nfunction renderSection(mountId, title, dataset){\n  const state = {\n    data: dataset,\n    filters: { productType: '', depth: 'all', trenchGroup: '' },\n    sort: { key: 'filling', dir: 'asc' },\n    page: 1,\n    perPage: 10,\n  };\n\n  const mount = document.getElementById(mountId);\n  if (!mount) return;\n\n  mount.innerHTML = `\n    <h4 style=\"margin:18px 0 6px;\">${title}<\/h4>\n    <div class=\"tray-controls\"><\/div>\n    <div class=\"tray-table-wrap\"><\/div>\n  `;\n\n  const controlsEl = mount.querySelector('.tray-controls');\n  const tableEl    = mount.querySelector('.tray-table-wrap');\n\n  function renderControls(){\n    const allPT = new Set();\n    state.data.forEach(e => e.productTypes.forEach(p => allPT.add(p)));\n    const ptOptions = Array.from(allPT).sort((a,b)=>a.localeCompare(b));\n\n    const allGroups = new Set();\nstate.data.forEach(e => (e.groupNames || []).forEach(g => allGroups.add(g)));\nconst groupOptions = Array.from(allGroups).sort((a,b)=>a.localeCompare(b));\n\n    controlsEl.innerHTML = `\n      <div class=\"tray-toolbar\">\n        <div class=\"group\">\n          <label><strong>Channel Product Type:<\/strong><\/label>\n          <select class=\"pt\">\n            <option value=\"\">All types<\/option>\n            ${ptOptions.map(o => `<option value=\"${escapeHtml(o)}\"${state.filters.productType===o?' selected':''}>${escapeHtml(o)}<\/option>`).join('')}\n          <\/select>\n        <\/div>\n                     <!-- ADD: Group of Trench Drains -->\n    <div class=\"group\">\n      <label><strong>Width:<\/strong><\/label>\n      <select class=\"tg\">\n        <option value=\"\">All widths<\/option>\n        ${groupOptions.map(g => `<option value=\"${escapeHtml(g)}\"${state.filters.trenchGroup===g?' selected':''}>${escapeHtml((g || '').replace(\/^DN\\s*\/i, ''))}<\/option>`).join('')}\n      <\/select>\n    <\/div>\n        <div class=\"group\">\n          <label><strong>Depth:<\/strong><\/label>\n          <select class=\"depth\">\n            <option value=\"all\"${state.filters.depth==='all'?' selected':''}>All depths<\/option>\n            <option value=\"shallow\"${state.filters.depth==='shallow'?' selected':''}>Shallow (up to 6\u2033)<\/option>\n            <option value=\"medium\"${state.filters.depth==='medium'?' selected':''}>Medium (6\u2033\u201312\u2033)<\/option>\n            <option value=\"deep\"${state.filters.depth==='deep'?' selected':''}>Deep (12\u2033 and more)<\/option>\n          <\/select>\n        <\/div>\n   \n      \n      <\/div>\n    `;\n\n    controlsEl.querySelector('.pt')?.addEventListener('change', e => { state.filters.productType = e.target.value; state.page=1; renderTable(); });\n    controlsEl.querySelector('.depth')?.addEventListener('change', e => { state.filters.depth = e.target.value; state.page=1; renderTable(); });\n    controlsEl.querySelector('.tg')?.addEventListener('change', e => {\n  state.filters.trenchGroup = e.target.value;\n  state.page = 1;\n  renderTable();\n});\n  \n  }\n\n  function applyFilters(items){\n    return items.filter(it => {\n      if (state.filters.productType && !it.productTypes.includes(state.filters.productType)) return false;\n      if (state.filters.depth !== 'all' && it.depthBucket !== state.filters.depth) return false;\n      \/\/ ADD: group filter (match by name)\n    if (state.filters.trenchGroup) {\n      const names = it.groupNames || [];\n      if (!names.includes(state.filters.trenchGroup)) return false;\n    }\n\n      return true;\n    });\n  }\n  function applySort(items){\n    const { key, dir } = state.sort; const mul = dir==='desc'?-1:1;\n    return items.slice().sort((a,b)=>{\n      let A,B;\n      switch(key){\n        case 'name':    A=(a.name||'').toLowerCase(); B=(b.name||'').toLowerCase(); return A.localeCompare(B)*mul;\n        case 'article': A=(a.artno||'').toLowerCase(); B=(b.artno||'').toLowerCase(); return A.localeCompare(B)*mul;\n        case 'depth':   A=isFinite(a.depthIn)?a.depthIn:Infinity; B=isFinite(b.depthIn)?b.depthIn:Infinity; return (A-B)*mul;\n        case 'filling': A=isFinite(a.filling)?a.filling:Infinity; B=isFinite(b.filling)?b.filling:Infinity; return (A-B)*mul;\n        case 'load':    A=(a.primaryLoadName||'').toLowerCase(); B=(b.primaryLoadName||'').toLowerCase(); return A.localeCompare(B)*mul;\n        default: return 0;\n      }\n    });\n  }\n  function paginate(items){\n    const total = items.length;\n    const pages = Math.max(1, Math.ceil(total \/ state.perPage));\n    const page  = Math.min(state.page, pages);\n    const start = (page-1)*state.perPage;\n    return { page, pages, total, slice: items.slice(start, start+state.perPage) };\n  }\n  function headerTh(label, key){\n    const isActive = state.sort.key===key;\n    const dirClass = isActive ? (' '+state.sort.dir) : '';\n    return `<th class=\"sortable${isActive?' active':''}${dirClass}\" data-sort=\"${key}\">${label}<span class=\"arrow\"><\/span><\/th>`;\n  }\nfunction buildPager(pages, page, total) {\n  if (pages <= 1) {\n    \/\/ still show per-page so users can expand page size on small result sets\n    return `\n      <div class=\"tray-pager\">\n        <div class=\"pager-controls\">\n          <button class=\"tray-prev\" disabled>&lsaquo;<\/button>\n          <button class=\"tray-next\" disabled>&rsaquo;<\/button>\n         \n        <\/div>\n        <label class=\"pager-size\">\n          <strong>Show:<\/strong>\n          <select class=\"pp\">\n            ${[5,10,15,25,50].map(n=>`<option value=\"${n}\" ${state.perPage===n?'selected':''}>${n}<\/option>`).join('')}\n          <\/select>\n        <\/label>\n      <\/div>\n    `;\n  }\n\n  \/\/ windowed page numbers\n  const windowSize = 5;\n  let start = Math.max(1, page - Math.floor(windowSize\/2));\n  let end   = Math.min(pages, start + windowSize - 1);\n  start = Math.max(1, Math.min(start, pages - windowSize + 1));\n\n  let nums = '';\n  if (start > 1) {\n    nums += `<button class=\"tray-page\" data-page=\"1\">1<\/button>`;\n    if (start > 2) nums += `<span class=\"tray-ellipsis\">\u2026<\/span>`;\n  }\n  for (let i=start; i<=end; i++) {\n    nums += `<button class=\"tray-page ${i===page?'is-active':''}\" data-page=\"${i}\">${i}<\/button>`;\n  }\n  if (end < pages) {\n    if (end < pages-1) nums += `<span class=\"tray-ellipsis\">\u2026<\/span>`;\n    nums += `<button class=\"tray-page\" data-page=\"${pages}\">${pages}<\/button>`;\n  }\n\n  return `\n    <div class=\"tray-pager\">\n      <div class=\"pager-controls\">\n        <button class=\"tray-prev\"  ${page===1?'disabled':''}>&lsaquo;<\/button>\n        ${nums}\n        <button class=\"tray-next\"  ${page===pages?'disabled':''}>&rsaquo;<\/button>\n       \n      <\/div>\n      <label class=\"pager-size\">\n        <strong>Show:<\/strong>\n        <select class=\"pp\">\n          ${[5,10,15,25,50].map(n=>`<option value=\"${n}\" ${state.perPage===n?'selected':''}>${n}<\/option>`).join('')}\n        <\/select>\n      <\/label>\n    <\/div>\n  `;\n}\n  function renderTable(){\n    const filtered = applyFilters(state.data);\n    const sorted   = applySort(filtered);\n    const { page, pages, total, slice } = paginate(sorted);\n    const isCapacityMode = window.calcMeta?.mode === 'capacity';\n\n    if (!filtered.length) {\n      tableEl.innerHTML = `<p class=\"no-matching-channels\">No matching channels for those settings.<\/p>`;\n      return;\n    }\n\n    const rowsHtml = slice.map(e => {\n      const depthTxt = isFinite(e.depthIn) ? e.depthIn.toFixed(2) : '\u2014';\n      const widthTxt = isFinite(e.widthIn) ? e.widthIn.toFixed(2) : '\u2014';\n      const radiusTxt = isFinite(Number(e.radiusIn)) ? Number(e.radiusIn).toFixed(2) : '\u2014';\nlet g73Text;\n\nif (typeof e.filling === 'number' && isFinite(e.filling)) {\n  \/\/ Valid number, check the thresholds\n  g73Text = e.filling > 1 ? '> 1' : e.filling.toFixed(2);\n} else {\n  \/\/ If NaN, negative, or missing, assume system is overloaded\n  g73Text = '> 1';\n}\n      const g64Text  = isFinite(e.velocity) ? e.velocity.toFixed(3) : '\u2014';\n      const disabled = e.active ? '' : 'disabled';\n      const styleRow = e.active ? '' : 'opacity:.6; background:#f7f7f7;';\n      const radioValue = `tray_${e.id}`;\n      const g68Text   = isFinite(e.g68) ? e.g68.toFixed(2) : '\u2014';\n      const g68_70Txt = isFinite(e.g68) ? (e.g68 * 0.7).toFixed(2) : '\u2014';\n      return `\n        <tr style=\"${styleRow}; background-color:${e.fillingColorBG};\">\n          <td>\n            <input type=\"radio\" name=\"selectedTray\" value=\"${radioValue}\" id=\"${radioValue}\" ${disabled}\n        ${isCapacityMode ? 'checked' : ''}\n              data-name=\"${escapeHtml(e.name)}\"\n              data-article=\"${escapeHtml(e.artno||'')}\"\n              data-load=\"${escapeHtml((e.loadNames||[]).join(', '))}\"\n              data-depth=\"${depthTxt}\"\n              data-width=\"${widthTxt}\"\n              data-radius=\"${radiusTxt}\"\n              data-overall-height=\"${escapeHtml(String(e.overallHeight||''))}\"\n              data-g64=\"${g64Text}\"\n              data-g73=\"${g73Text}\"\n              data-img3d=\"${escapeHtml(e.img3d)}\"\n              data-diagram=\"${escapeHtml(e.diagram)}\"\n              data-product-type=\"${escapeHtml(e.productTypes.join(', '))}\"\n              data-group=\"${escapeHtml(e.raw.group_of_trench_drains || '')}\"\n              data-post-id=\"${e.id}\"\n              data-g68=\"${g68Text}\"\n              data-g6870=\"${g68_70Txt}\"\n                    >\n          <\/td>\n          <td><label for=\"${radioValue}\" style=\"${e.active?'':'pointer-events:none;'}\">${escapeHtml(e.name)}\n            ${(e.loadNames?.length?` <span>(${escapeHtml(e.loadNames.join(', '))})<\/span>`:'')}\n            ${e.active?'':' <span style=\"font-size:12px;\">(Not Available)<\/span>'}\n          <\/label><\/td>\n          <td>${depthTxt}<\/td>\n          <td>${escapeHtml(e.artno || '\u2014')}<\/td>\n         ${\n            isCapacityMode\n              ? `<td>${g64Text} ft\/s<\/td><td>${g68Text} GPM <span class=\"indicator\" style=\"background-color:#EEC90E\"><\/span><\/td><td>${g68_70Txt} GPM <span class=\"indicator\" style=\"background-color:#00938D\"><\/span><\/td>`\n              : `<td>${g73Text} <span class=\"indicator\" style=\"background-color:${e.fillingColor}\"><\/span><\/td>`\n          }\n        <\/tr>`;\n    }).join('');\n\n    tableEl.innerHTML = `\n      <table class=\"tray-table\">\n        <thead>\n          <tr>\n            <th>Select<\/th>\n            ${headerTh('Channel Name','name')}\n            ${headerTh('Depth of Flow (in)','depth')}\n            ${headerTh('Article Number','article')}\n            ${\n              isCapacityMode\n                ? `<th>Flow Velocity<\/th><th>Flow Rate (100% Capacity)<\/th><th>Flow Rate (70% Capacity) <span class=\"recommended\">Recommended<\/span><\/th>`\n                : headerTh('Channel Filling (Qr\/Ql)','filling')\n            }\n\n          <\/tr>\n        <\/thead>\n        <tbody>${rowsHtml}<\/tbody>\n      <\/table>\n<div class=\"tray-meta muted-note\">\n  Page ${page} of ${pages} \u2022 ${total} result${total===1?'':'s'}\n<\/div>\n${buildPager(pages, page, total)}\n    `;\n\n    if (isCapacityMode) {\n        tableEl.insertAdjacentHTML('beforeend', `\n          <div class=\"tray-meta muted-note\">\n            <em>Note: We recommend using the flow rate at 70% of capacity when selecting a channel.<\/em>\n          <\/div>\n        `);\n      }\n\n\/\/ --- Preselect previously chosen tray (back navigation + preload) ---\nconst selId = String(window.calcMeta?.selectedTrayId || '');\nif (selId) {\n  const radio =\n    tableEl.querySelector(`input[name=\"selectedTray\"][data-post-id=\"${selId}\"]`) ||\n    tableEl.querySelector(`input[name=\"selectedTray\"][value=\"tray_${selId}\"]`);\n  if (radio && !radio.disabled) radio.checked = true;\n}\n\n    \/\/ Sorting (unchanged)\ntableEl.querySelectorAll('th.sortable').forEach(th => {\n  th.addEventListener('click', () => {\n    const key = th.getAttribute('data-sort');\n    if (state.sort.key === key) state.sort.dir = state.sort.dir === 'asc' ? 'desc' : 'asc';\n    else { state.sort.key = key; state.sort.dir = 'asc'; }\n    renderTable();\n  });\n});\n\n\/\/ NEW: one delegated handler for all pager buttons\nconst pager = tableEl.querySelector('.tray-pager');\nif (pager) {\n  pager.addEventListener('click', (ev) => {\n    const btn = ev.target.closest('button');\n    if (!btn || btn.disabled) return;\n\n    const pages = Math.max(1, Math.ceil(applyFilters(state.data).length \/ state.perPage));\n    const p = parseInt(btn.dataset.page, 10);\n\n    if (btn.classList.contains('tray-first')) {\n      state.page = 1;\n    } else if (btn.classList.contains('tray-prev') || btn.classList.contains('prev')) {\n      state.page = Math.max(1, state.page - 1);\n    } else if (btn.classList.contains('tray-next') || btn.classList.contains('next')) {\n      state.page = Math.min(pages, state.page + 1);\n    } else if (btn.classList.contains('tray-last')) {\n      state.page = pages;\n    } else if (!isNaN(p)) {\n      state.page = p;\n    }\n\n    renderTable();\n  });\n\n  \/\/ existing click handler stays as-is...\n\n\/\/ NEW: handle \"Per page\" next to the pager\npager?.addEventListener('change', (ev) => {\n  if (!ev.target.matches('select.pp')) return;\n  state.perPage = parseInt(ev.target.value, 10) || 10;\n  state.page = 1;\n  renderTable();\n});\n}\n\npreselectTrayIfAvailable();\n\n  }\n\n  renderControls();\n  renderTable();\n}\n\n\n\n\/\/ Render both sections\nif (selectedTrayId && parseInt(selectedTrayId) > 0) {\n  \/\/ Only show one section if a specific tray was selected\n  renderSection('trayPrimarySection', '', primaryData);\n  document.getElementById('trayOtherSection').style.display = 'none';\n} else {\n  \/\/ Show both sections normally\n  renderSection('trayPrimarySection', 'Matching Channels (Selected Load Class)', primaryData);\n  renderSection('trayOtherSection', 'Matching Channels from Other Load Classes', otherData);\n}\npreselectTrayIfAvailable();\n\/\/ proceed to Step 4\n\ngotoStep(4);\n        }\n      } catch (e) {\n        console.error(e);\n        alert('Channel lookup failed: ' + e.message);\n      }\n    }\n\n    \/\/ Step 4 \u2192 Step 5: Build final results from selected tray\n    document.getElementById('btnUseTray')?.addEventListener('click', () => {\n  const isEditingExisting = !!window.DRAINAGE_CALC?.preloadPostId;\n  \/\/ If editing an existing saved calc and user hasn't chosen a save mode yet, show modal\n  if (isEditingExisting && !window._confirmedSaveMode) {\n    openOverwriteModal();\n    return;\n  }\n  buildFinalResults();\n});\nfunction preselectTrayIfAvailable() {\n  const selId = String(window.calcMeta?.selectedTrayId || '');\n  if (!selId) return;\n\n  const radio =\n    document.querySelector(`#trayResults input[name=\"selectedTray\"][data-post-id=\"${selId}\"]`) ||\n    document.querySelector(`#trayResults input[name=\"selectedTray\"][value=\"tray_${selId}\"]`);\n\n  if (radio && !radio.disabled) {\n    radio.checked = true;\n  }\n}\n\nfunction buildFinalResults(fromPreload = false) {\n  let picked;\n\n  \/\/ Prefer DOM radio if available\n  const radioChecked = document.querySelector('input[name=\"selectedTray\"]:checked');\n\n  if (radioChecked) {\n    picked = radioChecked;\n  } else if (fromPreload && window.finalResults) {\n    \/\/ Try to find by saved ID\n    const selId = window.finalResults.selectedTrayId || window.calcMeta?.selectedTrayId;\n    if (selId) {\n      picked =\n        document.querySelector(`input[name=\"selectedTray\"][data-post-id=\"${selId}\"]`) ||\n        document.querySelector(`input[name=\"selectedTray\"][value=\"tray_${selId}\"]`);\n    }\n    \/\/ If still not found, fabricate from saved finalResults (no alert!)\n    if (!picked) {\n      const fr = window.finalResults;\n      picked = {\n        dataset: {\n          name: fr.trayName || '\u2014',\n          article: fr.trayArt || '\u2014',\n          load: fr.loadClass || '\u2014',\n          depth: fr.depthFlow || '\u2014',\n          g64: fr.g64 || '\u2014',\n          g73: fr.g73 || '\u2014',\n          img3d: fr.img3d || '',\n          diagram: fr.diagramImg || '',\n          width: fr.selectedWidth || '\u2014',\n          radius: fr.selectedRadius || '\u2014',\n          productType: fr.productType || '',\n          group: fr.groupDrains || '',\n          overallHeight: fr.overallHeight || '\u2014',\n          g68: fr.g68 || fr.flow100 || '\u2014',\n          g6870: fr.g68_70 || fr.flow70 || '\u2014',\n        }\n      };\n    }\n  } else {\n    \/\/ Not a preload and no radio selected \u2192 user interaction required\n    const radio = document.querySelector('input[name=\"selectedTray\"]');\n    if (!radio) {\n      alert('Please select a channel first.');\n      return;\n    }\n    picked = radio;\n  }\n\n  \/\/ At this point `picked` is guaranteed\n  const card = document.getElementById('resultsCard');\n\n  const calcType =\n    (window.DRAINAGE_CALC?.mode === 'manual_gpm')\n      ? (window.VODALAND_CALC_TYPE_MANUAL_FLOW || 'Select a Channel Using Wastewater Flow Rate (GPM)')\n      : (window.DRAINAGE_CALC?.mode === 'capacity')\n        ? (window.VODALAND_CALC_TYPE_CAPACITY || 'Channel Capacity Calculator')\n        : (window.VODALAND_CALC_TYPE_CATCHMENT || 'Select a Channel Based on Catchment Area');\n\n  \/\/ Drainage area (robust)\n  const drainageAreaSqft = (card?.dataset?.area && !isNaN(parseFloat(card.dataset.area)))\n    ? Number(card.dataset.area)\n    : (function sumAreasFromInputs() {\n        const ids = ['asphalt','brick','roofs','sandy','heavy'];\n        let total = 0;\n        ids.forEach(id => { total += parseFloat(document.getElementById(id)?.value) || 0; });\n        if (card) card.dataset.area = total;\n        return total;\n      })();\n  calcMeta.totalArea = drainageAreaSqft;\n\n  \/\/ Remember which tray was chosen\n  const selectedTrayId = (picked.value || '').startsWith('tray_')\n    ? parseInt((picked.value || '').replace('tray_', ''), 10)\n    : (window.finalResults?.selectedTrayId ?? null);\n  if (!window.calcMeta) window.calcMeta = {};\n  if (selectedTrayId != null && !Number.isNaN(selectedTrayId)) {\n    window.calcMeta.selectedTrayId = String(selectedTrayId);\n  }\n\n  const trayName   = picked.dataset.name || '\u2014';\n  const trayArt    = picked.dataset.article || '\u2014';\n  const loadClass  = picked.dataset.load || '\u2014';\n  const depthFlow  = picked.dataset.depth || '\u2014';\n  const overallHeight = picked.dataset.overallHeight || '\u2014';\n  const g64        = picked.dataset.g64 || '\u2014';\n  const g73        = picked.dataset.g73 || '\u2014';\n  const g68        = picked.dataset.g68 || '\u2014';     \/\/ 100% capacity GPM\n  const g68_70     = picked.dataset.g6870 || '\u2014';   \/\/ 70% capacity GPM\n\n  const g73Num = parseFloat(g73);\n  const showChannelWarning = Number.isFinite(g73Num) && g73Num > 0.70;\n\n  \/\/ % full \u2192 visual\n  const rawPct   = Number.isFinite(g73Num) ? g73Num * 100 : null;\n  const fillPct  = rawPct !== null ? Math.min(rawPct, 100) : null;\n  const fillLabel = rawPct !== null\n    ? (rawPct > 100 ? '> 100% Full' : `${Math.round(rawPct)}% Full`)\n    : '\u2014';\n\n  const createdBy  = (window.wpCurrentUser && window.wpCurrentUser.name) ? window.wpCurrentUser.name : 'Guest';\n  const createdOn  = new Date();\n  const createdStr = createdOn.toLocaleDateString(undefined, { year:'numeric', month:'long', day:'numeric' });\n  const calcName   = (document.getElementById('calcName')?.value || '').trim();\n\n  const img3d      = picked.dataset.img3d || '';\n  const diagramImg = picked.dataset.diagram || '';\n  const selectedWidth  = picked.dataset.width || '\u2014';\n  const selectedRadius = picked.dataset.radius || '\u2014';\n  const productType = picked.dataset.productType && picked.dataset.productType !== 'undefined'\n    ? picked.dataset.productType : '\u2014';\n  const groupDrains = picked.dataset.group && picked.dataset.group !== 'undefined'\n    ? picked.dataset.group : '\u2014';\n\n  \/\/ Compute GPM per outlet (for display only)\n  const totalGpm  = Number(calcMeta.totalGpm || 0);\n  const outlets   = Math.max(1, Number(calcMeta.outlets || document.getElementById('outlets')?.value || 1));\n  const gpmPerOut = (outlets > 0 ? (totalGpm \/ outlets) : totalGpm);\n\n  \/\/ labels\n  const modeLabel = (m => {\n    if (m === 'manual' || m === 'manual_gpm') return 'Manual input';\n    if (m === 'zip-custom') return 'ZIP lookup (custom duration\/ARI)';\n    if (m === 'zip-site')   return 'ZIP lookup (suggested by site type)';\n    if (m === 'capacity')   return 'Capacity comparison';\n    return '\u2014';\n  })(calcMeta.mode || window.DRAINAGE_CALC?.mode);\n\n  const durationLabel = calcMeta.duration || '\u2014';\n  const ariLabel      = (calcMeta.ariYear ? `${calcMeta.ariYear}-year` : '\u2014');\n  const zipLabel      = calcMeta.zip || '\u2014';\n  const siteLabel     = calcMeta.siteType || '\u2014';\n  const slopeLabel    = (calcMeta.slope != null ? String(calcMeta.slope) : (document.getElementById('slope')?.value || '\u2014'));\n  const lenLabel      = (calcMeta.lineLength != null ? String(calcMeta.lineLength) : (document.getElementById('length')?.value || '\u2014'));\n  const outletsLabel  = String(outlets);\n  const materialLabel = calcMeta.selectedMaterialName || '\u2014';\n  const totalGpmLabel = (isFinite(totalGpm) ? totalGpm.toFixed(2) : '\u2014');\n  const gpmPerOutLbl  = (isFinite(gpmPerOut) ? gpmPerOut.toFixed(2) : '\u2014');\n  const rainLbl       = (isFinite(calcMeta.rainfallIntensity) ? Number(calcMeta.rainfallIntensity).toFixed(2) : (document.getElementById('rainfall')?.value || '\u2014'));\n\n  const resultsEl = document.getElementById('resultsCard');\n  const calcTypeSlug = calcType.toLowerCase().replace(\/[^\\w\\s-]\/g, '').trim().replace(\/\\s+\/g, '-');\nresultsEl.innerHTML = `\n  <a id=\"calcResultsTop\"><\/a>\n  <div class=\"results-header\">\n    <img decoding=\"async\" src=\"\/wp-content\/uploads\/2025\/08\/Layer_1-3.svg\" alt=\"Vodaland\" style=\"height:auto; width:200px;\">\n    <div>\n      <div class=\"results-title\">${escapeHtml('Calculator Results: ' + (calcName || ''))}<\/div>\n      <div class=\"results-sub\">Created ${createdStr} by ${escapeHtml(createdBy)}<\/div>\n    <\/div>\n  <\/div>\n\n  <!-- SUCCESS BANNER gets injected at top after save -->\n\n  <div class=\"results-layout ${calcTypeSlug}\">\n    <!-- LEFT: all data sections -->\n    <div class=\"results-left\">\n  <div class=\"results-section\">\n      <h5>General Data<\/h5>\n      <div class=\"grid\">\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  \n\t\t<div class=\"kv\" style=\"grid-column:1\/4\"><div class=\"k\">Calculator<\/div><div class=\"v\">${calcType}<\/div><\/div>\n        <div class=\"kv calculation-type-item\" style=\"grid-column:1\/4\"><div class=\"k\">Calculation Type<\/div><div class=\"v\">${modeLabel}<\/div><\/div>\n        <div class=\"kv\" style=\"grid-column:1\/4\"><div class=\"k\">Calculation Name<\/div><div class=\"v\">${escapeHtml(calcName || '\u2014')}<\/div><\/div>\n        <div class=\"kv\">\n  <div class=\"k\">Calculation Number<\/div>\n  <div class=\"v\"><span id=\"calcNumber\">${\n    window.DRAINAGE_CALC?.preloadPostId ? String(window.DRAINAGE_CALC.preloadPostId) : 'Pending (after save)'\n  }<\/span><\/div>\n<\/div>\n        <div class=\"kv\"><div class=\"k\">Date<\/div><div class=\"v\">${createdStr}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Author<\/div><div class=\"v\">${escapeHtml(createdBy)}<\/div><\/div>\n      <\/div>\n<\/div>\n      <div class=\"results-section\">\n      <h5 class=\"site-characteristics-header\">Site Characteristics<\/h5>\n      <div class=\"grid site-characteristics-header\">\n        <div class=\"kv zip-code-item\"><div class=\"k\">ZIP Code<\/div><div class=\"v\">${zipLabel}<\/div><\/div>\n        <div class=\"kv rainfall-intensity-item\"><div class=\"k\">Rainfall Intensity (in\/hr)<\/div><div class=\"v\">${rainLbl}<\/div><\/div>\n        <div class=\"kv drainage-area-item\"><div class=\"k\">Drainage Area (sq ft)<\/div><div class=\"v\">${\n          Number.isFinite(calcMeta.totalArea) ? calcMeta.totalArea.toLocaleString() :\n          (card?.dataset?.area ? Number(card.dataset.area).toLocaleString() : '\u2014')\n        }<\/div><\/div>\n        <div class=\"kv final-flow-item\" style=\"grid-column:1\/4\">\n          <div class=\"k\">Final Flow (Total GPM)<\/div>\n          <div class=\"v\" style=\"font-size:1.15rem;\">${totalGpmLabel}<\/div>\n        <\/div>\n      <\/div>\n<\/div>\n            <div class=\"results-section\">\n      <h5>Line Characteristics<\/h5>\n      <div class=\"grid\">\n        <div class=\"kv material-item\"><div class=\"k\">Material<\/div><div class=\"v\">${materialLabel}<\/div><\/div>\n        <div class=\"kv load-class-item\"><div class=\"k\">Load Class<\/div><div class=\"v\">${loadClass}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Length (ft)<\/div><div class=\"v\">${lenLabel}<\/div><\/div>\n        <div class=\"kv number-of-drainage-channels-item\"><div class=\"k\"># of Drainage Channels<\/div><div class=\"v\">${\n          (Number.isFinite(calcMeta.numDrainageChannels) ? calcMeta.numDrainageChannels.toFixed(2) : '\u2014')\n        }<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Slope (ft\/ft)<\/div><div class=\"v\">${slopeLabel}<\/div><\/div>\n        <div class=\"kv outlets-item\"><div class=\"k\">Outlets<\/div><div class=\"v\">${outletsLabel}<\/div><\/div>\n        <div class=\"kv gpm-per-outlet-item\"><div class=\"k\">GPM per Outlet<\/div><div class=\"v\">${gpmPerOutLbl}<\/div><\/div>\n      <\/div>\n<\/div>\n          <div class=\"results-section\">\n      <h5>Selection Results<\/h5>\n      ${ showChannelWarning\n          ? `<div style=\"margin:10px 0 16px; padding:10px 12px; border:1px solid #ccc; background:#FFFAEE; color:#1E293B; border-radius:8px; font-size:12px;\">\n               \u26a0\ufe0f <strong>Not recommended.<\/strong> Channel filling exceeds the recommended limit. Consider adjusting inputs or selecting a higher-capacity channel.\n             <\/div>` : ''\n        }\n      <div class=\"grid\">\n        <div class=\"kv\" style=\"grid-column:1\/4\"><div class=\"k\">Trench Drain Name<\/div><div class=\"v\">${trayName}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Article<\/div><div class=\"v\">${trayArt}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Load Class<\/div><div class=\"v\">${loadClass}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Width (in)<\/div><div class=\"v\">${selectedWidth}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Hydraulic Depth (in)<\/div><div class=\"v\">${depthFlow}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Overall Height (in)<\/div><div class=\"v\">${overallHeight}<\/div><\/div>\n        <div class=\"kv\"><div class=\"k\">Velocity in Channel (ft\/s)<\/div><div class=\"v\">${g64}<\/div><\/div>\n        <div class=\"kv filling-degree-item\">\n          <div class=\"k\">Filling Degree (Qr\/Ql)<\/div>\n          <div class=\"v\">\n            ${g73} <span class=\"indicator\" style=\"background-color:${(parseFloat(g73) <= 0.7 ? '#00938D' : '#EEC90E')}\"><\/span>\n          <\/div>\n        <\/div>\n             <div class=\"kv flow-rate-100-item\">\n          <div class=\"k\">Flow Rate (100% of Capacity)<\/div>\n          <div class=\"v\">\n            ${g68} <span class=\"indicator\" style=\"background-color:#EEC90E\"><\/span>\n          <\/div>\n        <\/div>\n             <div class=\"kv flow-rate-70-item\">\n          <div class=\"k\">Flow Rate (70% of Capacity)<\/div>\n          <div class=\"v\">\n            ${g68_70} <span class=\"indicator\" style=\"background-color:#00938D\"><\/span> <span class=\"recommended\">Recommended<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n<\/div>\n    <!-- RIGHT: images stacked -->\n    <div class=\"results-images-right\">\n      ${img3d ? `<img decoding=\"async\" src=\"${img3d}\" alt=\"Channel 3D Rendering\">` : ''}\n      ${diagramImg ? `<img decoding=\"async\" src=\"${diagramImg}\" alt=\"Channel Diagram\">` : ''}\n\n      ${\n        (fillPct != null)\n          ? `<div class=\"filling-level-card\">\n               <div class=\"filling-level-title\">Channel Filling (Qr\/Ql)<\/div>\n               <div class=\"filling-level-label\">${fillLabel}<\/div>\n               <div class=\"filling-level-outer\">\n                 <div class=\"filling-level-inner\">\n                   <div class=\"filling-level-indicator\" style=\"height:${fillPct}%\"><\/div>\n                 <\/div>\n               <\/div>\n             <\/div>`\n          : ''\n      }\n    <\/div>\n  <\/div>\n\n  <!-- Disclaimer (full width under both columns) -->\n  <p class=\"disclaimer\">* Calculation performed using Rational Method per HEC-22, IPC 2024, and ASCE MOP 77. For preliminary use only. Final design must be approved by a licensed engineer based on site-specific data and applicable local codes.<\/p>\n`;\n\n   \/\/ Persist for PDF \/ save\n  window.finalResults = {\n    createdStr, createdBy, trayName, trayArt, loadClass, depthFlow, g64, g73, calcName,\n    mode: calcMeta.mode,\n    zip: calcMeta.zip,\n    siteType: calcMeta.siteType,\n    duration: calcMeta.duration,\n    ariYear: calcMeta.ariYear,\n    rainfallIntensity: calcMeta.rainfallIntensity,\n    totalGpm: calcMeta.totalGpm,\n    selectedMaterialName: calcMeta.selectedMaterialName,\n    lineLength: calcMeta.lineLength,\n    slope: calcMeta.slope,\n    outlets: calcMeta.outlets,\n    gpmPerOutlet: gpmPerOut,\n    selectedWidth,\n    selectedRadius,\n    overallHeight,\n    productType,\n    groupDrains,\n    selectedTrayId,\n    numDrainageChannels: calcMeta.numDrainageChannels,\n    calcType,\n    calcTypeSlug,\n    \/\/ ensure these are saved too\n    g68,\n    g68_70\n  };\n\n  \/\/ Handle \u201cSave as New\u201d rename\n  if (window._forceSaveAsNew && window._forceNewTitle) {\n    const nameInput = document.getElementById('calcName');\n    if (nameInput) nameInput.value = window._forceNewTitle;\n  }\n\n  const basePayload = {\n    force_new: !!window._forceSaveAsNew,\n    calcName: (window._forceSaveAsNew\n      ? (window._forceNewTitle || 'Copy')\n      : ((document.getElementById('calcName')?.value || '').trim() || 'Untitled Calculation')),\n    inputs: {\n      rainfall: parseFloat(document.getElementById('rainfall')?.value) || null,\n      areas: {\n        asphalt: parseFloat(document.getElementById('asphalt')?.value) || 0,\n        brick:   parseFloat(document.getElementById('brick')?.value)   || 0,\n        roofs:   parseFloat(document.getElementById('roofs')?.value)   || 0,\n        sandy:   parseFloat(document.getElementById('sandy')?.value)   || 0,\n        heavy:   parseFloat(document.getElementById('heavy')?.value)   || 0,\n      },\n      requiredMaterial: document.getElementById('requiredMaterial')?.value || '',\n      requiredLoadClass: document.getElementById('requiredLoadClass')?.value || '',\n      length:  parseFloat(document.getElementById('length')?.value)  || null,\n      slope:   parseFloat(document.getElementById('slope')?.value)   || null,\n      outlets: parseFloat(document.getElementById('outlets')?.value) || 1,\n    },\n    calcMeta,\n    finalResults: window.finalResults,\n    resultsHtml: document.getElementById('resultsCard')?.innerHTML || '',\n    calc_type: calcType\n  };\n\n  if (!window._forceSaveAsNew) {\n    basePayload.post_id = (window.DRAINAGE_CALC?.preloadPostId || null);\n  }\n\n  fetch(window.DRAINAGE_CALC.ajaxUrl, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application\/x-www-form-urlencoded; charset=UTF-8' },\n    body: new URLSearchParams({\n      action: 'save_drainage_calc',\n      _wpnonce: window.DRAINAGE_CALC.nonce,\n      container_url: window.DRAINAGE_CALC.containerUrl,\n      calc: JSON.stringify(basePayload)\n    })\n  })\n  .then(r => r.json())\n  .then(res => {\n    if (!res?.success) {\n      if (window.dcPromptLoginThenSave) window.dcPromptLoginThenSave();\n      else alert('Please log in to save your calculation.');\n      gotoStep(5);\n      scrollToResults();\n      return;\n    }\n\n    if (res.data?.post_id) {\n      const numEl = document.getElementById('calcNumber');\n      if (numEl) numEl.textContent = String(res.data.post_id);\n    }\n\n    window.DRAINAGE_CALC.preloadPostId = res.data.post_id;\n    if (res.data.permalink) {\n      try { history.replaceState(null, '', res.data.permalink); } catch(e){}\n    }\n\n    showSavedBanner();\n    window._confirmedSaveMode = null;\n    window._forceSaveAsNew = false;\n    window._forceNewTitle = null;\n\n    gotoStep(5);\n    scrollToResults();\n  })\n  .catch(err => {\n    console.error(err);\n    if (window.dcPromptLoginThenSave) window.dcPromptLoginThenSave();\n    else alert('Please log in to save your calculation.');\n    gotoStep(5);\n    scrollToResults();\n  });\n}\n\n    \/\/ HTML -> Letter PDF (clamped)\n    document.getElementById('downloadPDF')?.addEventListener('click', async () => {\n       if (!window.finalResults && window.DRAINAGE_CALC?.preload?.finalResults) {\n    window.finalResults = window.DRAINAGE_CALC.preload.finalResults;\n  }\n\n  \/\/ If we STILL have nothing and no card content, ask them to pick a tray\n  const card = document.getElementById('resultsCard');\n  if (!window.finalResults && (!card || !card.innerHTML.trim())) {\n    alert('Please select a tray and build the results first.');\n    return;\n  }\n      if (!card) return;\n\n      \/\/ Render card to canvas at devicePixelRatio for crispness\n      const canvas = await html2canvas(card, { scale: Math.min(window.devicePixelRatio || 1, 2) });\n      const imgData = canvas.toDataURL('image\/png');\n\n      const { jsPDF } = window.jspdf || {};\n      if (!jsPDF) { alert('PDF library not loaded.'); return; }\n\n      \/\/ Letter size in mm\n      const pdf = new jsPDF({ unit: 'mm', format: 'letter', putOnlyUsedFonts: true });\n      const pageW = pdf.internal.pageSize.getWidth();\n      const pageH = pdf.internal.pageSize.getHeight();\n      const margin = 10;\n      const maxW = pageW - margin * 2;\n      const maxH = pageH - margin * 2;\n\n      \/\/ Image dimensions in mm\n      const pxToMm = 0.2645833333; \/\/ 1px \u2248 0.26458 mm\n      const imgWmm = canvas.width * pxToMm;\n      const imgHmm = canvas.height * pxToMm;\n\n      \/\/ Clamp & scale to fit inside page\n      const scale = Math.min(maxW \/ imgWmm, maxH \/ imgHmm, 1);\n      const drawW = imgWmm * scale;\n      const drawH = imgHmm * scale;\n      const x = (pageW - drawW) \/ 2;\n      const y = (pageH - drawH) \/ 2;\n\n      pdf.addImage(imgData, 'PNG', x, y, drawW, drawH, undefined, 'FAST');\n\n      \/\/ Filename with timestamp + username\n      const now = new Date();\n      const stamp = [\n        now.getFullYear(),\n        String(now.getMonth()+1).padStart(2,'0'),\n        String(now.getDate()).padStart(2,'0'),\n        '_',\n        String(now.getHours()).padStart(2,'0'),\n        String(now.getMinutes()).padStart(2,'0')\n      ].join('');\n      const user = (window.wpCurrentUser && window.wpCurrentUser.name)\n        ? window.wpCurrentUser.name.toLowerCase().replace(\/\\s+\/g,'-')\n        : 'user';\n      const filename = `drainage-results_${stamp}_${user}.pdf`;\n      pdf.save(filename);\n    });\n\n    \/\/ Helpers\n    function escapeHtml(s) {\n      return String(s)\n        .replaceAll('&','&amp;')\n        .replaceAll('<','&lt;')\n        .replaceAll('>','&gt;')\n        .replaceAll('\"','&quot;')\n        .replaceAll(\"'\",'&#039;');\n    }\n  <\/script>\n  <script>\n(function(){\n  const loginBtn   = document.getElementById('btnLoginToSave');\n  const modal      = document.getElementById('dcLoginModal');\n  const form       = document.getElementById('dcLoginForm');\n  const cancelBtn  = document.getElementById('dcLoginCancel');\n  const errEl      = document.getElementById('dcLoginErr');\n  const submitBtn  = document.getElementById('dcLoginSubmit');\n\n  function openLoginModal() {\n    if (!modal) return;\n    errEl.style.display = 'none';\n    errEl.textContent = '';\n    modal.style.display = 'flex';\n    \/\/ focus first input\n    const first = form?.querySelector('input[name=\"log\"]');\n    if (first) setTimeout(()=>first.focus(), 50);\n  }\n  function closeLoginModal() {\n    if (!modal) return;\n    modal.style.display = 'none';\n  }\n\n  \/\/ Open from Step 5 button\n  loginBtn?.addEventListener('click', openLoginModal);\n\n  \/\/ Close actions\nfunction closeLoginModal() {\n  if (!modal) return;\n  modal.style.display = 'none';\n\n  \/\/ Ensure we reset any disabled state on Step 5 buttons\n  document.querySelectorAll('.step-5 button').forEach(btn => btn.disabled = false);\n\n  \/\/ Remove any leftover overlays just in case\n  document.querySelectorAll('#dcLoginModal [data-backdrop]').forEach(el => {\n    el.style.display = 'none';\n  });\n}\n\ncancelBtn?.addEventListener('click', closeLoginModal);\nmodal?.querySelector('[data-backdrop]')?.addEventListener('click', closeLoginModal);\n\n  \/\/ Submit -> AJAX login -> immediately save\n  form?.addEventListener('submit', async (e) => {\n    e.preventDefault();\n    if (!window.DRAINAGE_CALC?.ajaxUrl) return;\n\n    \/\/ Disable UI\n    submitBtn.disabled = true;\n    submitBtn.textContent = 'Logging in\u2026';\n\n    try {\n      const fd = new FormData(form);\n      fd.append('action', 'dc_login_and_save');\n      fd.append('_wpnonce', window.DRAINAGE_CALC.nonce);\n\n      const res = await fetch(window.DRAINAGE_CALC.ajaxUrl, {\n        method: 'POST',\n        body: fd,\n        credentials: 'same-origin'\n      });\n      const data = await res.json();\n\n      if (!data?.success) {\n        const msg = data?.data?.message || data?.message || 'Login failed.';\n        errEl.textContent = msg;\n        errEl.style.display = 'block';\n        return;\n      }\n\n      \/\/ Logged in! Update the header name for PDF if you want:\n      if (data?.data?.user?.display_name) {\n        window.wpCurrentUser = { name: data.data.user.display_name };\n      }\n\n      \/\/ Close modal and trigger a save (uses your existing path)\n      closeLoginModal();\n\n      \/\/ If Step 5 results exist already, we can just re-save:\n      if (typeof buildFinalResults === 'function') {\n        buildFinalResults(); \/\/ will now save successfully and show the saved banner\n      }\n    } catch (e2) {\n      errEl.textContent = 'Network error. Please try again.';\n      errEl.style.display = 'block';\n    } finally {\n      submitBtn.disabled = false;\n      submitBtn.textContent = 'Log In';\n    }\n  });\n\n  \/\/ BONUS: if the user tries to save and gets a 401 in your existing code,\n  \/\/ open the login modal instead of alerting.\n  \/\/ Hook the fetch error paths by monkey-patching alert (optional).\n  \/\/ Easier: expose a small helper you can call from your catch blocks:\n  window.dcPromptLoginThenSave = function(){\n    openLoginModal();\n  };\n})();\n<\/script>\n\n<p>You must be logged in to save the calculation.<\/p><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Select a Channel Based on Catchment Area Step 1 Step 2 Step 3 Step 4 Results<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-821","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Catchment Area Calculator - Vodaland Engineering Portal<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.vodalandsolutions.com\/es\/catchment-area-calculator\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Catchment Area Calculator - Vodaland Engineering Portal\" \/>\n<meta property=\"og:description\" content=\"Select a Channel Based on Catchment Area Step 1 Step 2 Step 3 Step 4 Results\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vodalandsolutions.com\/es\/catchment-area-calculator\/\" \/>\n<meta property=\"og:site_name\" content=\"Vodaland Engineering Portal\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-03T17:07:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"389\" \/>\n\t<meta property=\"og:image:height\" content=\"237\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/\",\"url\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/\",\"name\":\"Catchment Area Calculator - Vodaland Engineering Portal\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/istockphoto-1316493798-2048x2048-1.png\",\"datePublished\":\"2025-09-12T14:16:52+00:00\",\"dateModified\":\"2025-10-03T17:07:41+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/istockphoto-1316493798-2048x2048-1.png\",\"contentUrl\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/istockphoto-1316493798-2048x2048-1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/catchment-area-calculator\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Catchment Area Calculator\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/#website\",\"url\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/\",\"name\":\"Vodaland Solutions Portal\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/#organization\",\"name\":\"Vodaland\",\"url\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/wp-content\\\/uploads\\\/2025\\\/08\\\/VodaLand_logo_deskriptor_RGB-EN_8f22a342-0b80-4931-9065-261ba8a8225a.png\",\"contentUrl\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/wp-content\\\/uploads\\\/2025\\\/08\\\/VodaLand_logo_deskriptor_RGB-EN_8f22a342-0b80-4931-9065-261ba8a8225a.png\",\"width\":300,\"height\":49,\"caption\":\"Vodaland\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vodalandsolutions.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Catchment Area Calculator - Vodaland Engineering Portal","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.vodalandsolutions.com\/es\/catchment-area-calculator\/","og_locale":"es_MX","og_type":"article","og_title":"Catchment Area Calculator - Vodaland Engineering Portal","og_description":"Select a Channel Based on Catchment Area Step 1 Step 2 Step 3 Step 4 Results","og_url":"https:\/\/www.vodalandsolutions.com\/es\/catchment-area-calculator\/","og_site_name":"Vodaland Engineering Portal","article_modified_time":"2025-10-03T17:07:41+00:00","og_image":[{"width":389,"height":237,"url":"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/","url":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/","name":"Catchment Area Calculator - Vodaland Engineering Portal","isPartOf":{"@id":"https:\/\/www.vodalandsolutions.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/#primaryimage"},"image":{"@id":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/#primaryimage"},"thumbnailUrl":"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png","datePublished":"2025-09-12T14:16:52+00:00","dateModified":"2025-10-03T17:07:41+00:00","breadcrumb":{"@id":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/#primaryimage","url":"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png","contentUrl":"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/10\/istockphoto-1316493798-2048x2048-1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.vodalandsolutions.com\/catchment-area-calculator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.vodalandsolutions.com\/"},{"@type":"ListItem","position":2,"name":"Catchment Area Calculator"}]},{"@type":"WebSite","@id":"https:\/\/www.vodalandsolutions.com\/#website","url":"https:\/\/www.vodalandsolutions.com\/","name":"Vodaland Solutions Portal","description":"","publisher":{"@id":"https:\/\/www.vodalandsolutions.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.vodalandsolutions.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.vodalandsolutions.com\/#organization","name":"Vodaland","url":"https:\/\/www.vodalandsolutions.com\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.vodalandsolutions.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/08\/VodaLand_logo_deskriptor_RGB-EN_8f22a342-0b80-4931-9065-261ba8a8225a.png","contentUrl":"https:\/\/www.vodalandsolutions.com\/wp-content\/uploads\/2025\/08\/VodaLand_logo_deskriptor_RGB-EN_8f22a342-0b80-4931-9065-261ba8a8225a.png","width":300,"height":49,"caption":"Vodaland"},"image":{"@id":"https:\/\/www.vodalandsolutions.com\/#\/schema\/logo\/image\/"}}]}},"featured_image_src":null,"featured_image_src_square":null,"_links":{"self":[{"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/pages\/821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/comments?post=821"}],"version-history":[{"count":0,"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/pages\/821\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.vodalandsolutions.com\/es\/wp-json\/wp\/v2\/media?parent=821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}