{"id":2109,"date":"2025-06-18T12:28:53","date_gmt":"2025-06-18T16:28:53","guid":{"rendered":"https:\/\/farmtab.com\/growingdirtfarm\/?page_id=2109"},"modified":"2026-07-06T19:53:20","modified_gmt":"2026-07-06T23:53:20","slug":"csa","status":"publish","type":"page","link":"https:\/\/farmtab.com\/growingdirtfarm\/csa\/","title":{"rendered":"Community Supported Agriculture Order Form"},"content":{"rendered":"\n<div id=\"csa-container-message\" class=\"csa-order-form-container\">\n        <!-- \u2500\u2500 Step Progress Bar \u2500\u2500 -->\n    <div class=\"csa-steps\" id=\"csa-steps\">\n        <div class=\"csa-step active\" data-step=\"1\">\n            <div class=\"step-circle\">1<\/div>\n            <span class=\"step-label\">Location &amp; Pickup<\/span>\n        <\/div>\n        <div class=\"step-connector\"><\/div>\n        <div class=\"csa-step\" data-step=\"2\">\n            <div class=\"step-circle\">2<\/div>\n            <span class=\"step-label\">Choose Products<\/span>\n        <\/div>\n        <div class=\"step-connector\"><\/div>\n        <div class=\"csa-step\" data-step=\"3\">\n            <div class=\"step-circle\">3<\/div>\n            <span class=\"step-label\">Review &amp; Pay<\/span>\n        <\/div>\n    <\/div>\n\n    <form id=\"csa-order-form\">\n\n        <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n             SECTION 1 \u2014 Location & Pickup\n             \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n        <div class=\"csa-section active\" id=\"csa-section-1\">\n            <div class=\"csa-section-header\">\n                <span class=\"section-badge\">1<\/span>\n                <div>\n                    <h2>Select Your Location &amp; Pickup Day<\/h2>\n                    <p class=\"section-subtitle\">Choose a pickup location and day. Enter your address to sort locations by distance.<\/p>\n                <\/div>\n            <\/div>\n\n            <div class=\"csa-loc-address-bar\">\n                <input id=\"user-address\" type=\"text\" placeholder=\"Enter your address to see how far each location is\u2026\">\n            <\/div>\n\n            <div class=\"csa-loc-layout\">\n                <!-- LEFT: selectable location list -->\n                <div class=\"csa-loc-list\" id=\"csa-loc-list\" role=\"radiogroup\" aria-label=\"Pickup locations\">\n                                        <div class=\"csa-loc-card\"\n                         data-loc-id=\"1\"\n                         data-places=\"51 Lenape Ln, Great Meadows, NJ 07838, USA\"\n                         data-lat=\"40.9257611\"\n                         data-lng=\"-74.8782863\"\n                         data-pickup-days='[&quot;Saturday&quot;]'\n                         data-pickup-times='{&quot;Saturday&quot;:{&quot;start&quot;:&quot;09:00&quot;,&quot;end&quot;:&quot;12:00&quot;}}'\n                         data-delivery='[{&quot;title&quot;:&quot;Free Local Pickup&quot;,&quot;description&quot;:&quot;Customer picks up their shares at this location.&quot;,&quot;price&quot;:&quot;0.00&quot;},{&quot;title&quot;:&quot;DoorDash Delivery&quot;,&quot;description&quot;:&quot;Starts at $7.00 plus tip per delivery.&quot;,&quot;price&quot;:&quot;7.00&quot;}]'\n                         role=\"radio\" aria-checked=\"false\" tabindex=\"0\">\n                        <div class=\"csa-loc-card__main\">\n                            <div class=\"csa-loc-card__head\">\n                                <span class=\"csa-loc-card__name\">Farm pickup-Allamuchy<\/span>\n                                <span class=\"csa-loc-card__distance\" data-distance-for=\"1\"><\/span>\n                            <\/div>\n                                                            <div class=\"csa-loc-card__addr\">51 Lenape Ln, Great Meadows, NJ 07838, USA<\/div>\n                                                                                        <div class=\"csa-loc-card__days\">\n                                                                            <span class=\"csa-loc-daychip\">Saturday \u00b7 9:00am\u201312:00pm<\/span>\n                                                                    <\/div>\n                                                                                        <div class=\"csa-loc-card__delivery\">Free Local Pickup \u2022 DoorDash Delivery<\/div>\n                                                        <!-- Pickup-day radios injected here by JS when this card is selected (Task 4a) -->\n                            <div class=\"csa-loc-card__pickup\" hidden><\/div>\n                        <\/div>\n                        <span class=\"csa-loc-card__check\" aria-hidden=\"true\"><\/span>\n                    <\/div>\n                                        <div class=\"csa-loc-card\"\n                         data-loc-id=\"2\"\n                         data-places=\"Bald Eagle Rd N, Allamuchy Township, NJ 07840, USA\"\n                         data-lat=\"40.9026519\"\n                         data-lng=\"-74.8363662\"\n                         data-pickup-days='[&quot;Friday&quot;]'\n                         data-pickup-times='{&quot;Friday&quot;:{&quot;start&quot;:&quot;09:30&quot;,&quot;end&quot;:&quot;11:00&quot;}}'\n                         data-delivery='[{&quot;title&quot;:&quot;DoorDash Delivery&quot;,&quot;description&quot;:&quot;Starts at $7.00 plus tip per delivery.&quot;,&quot;price&quot;:&quot;7.00&quot;},{&quot;title&quot;:&quot;PV resident only)&quot;,&quot;description&quot;:&quot;Delivery within the gated community, Panther Valley&quot;,&quot;price&quot;:3}]'\n                         role=\"radio\" aria-checked=\"false\" tabindex=\"0\">\n                        <div class=\"csa-loc-card__main\">\n                            <div class=\"csa-loc-card__head\">\n                                <span class=\"csa-loc-card__name\">Panther Valley Resident (only within gated community)<\/span>\n                                <span class=\"csa-loc-card__distance\" data-distance-for=\"2\"><\/span>\n                            <\/div>\n                                                            <div class=\"csa-loc-card__addr\">Bald Eagle Rd N, Allamuchy Township, NJ 07840, USA<\/div>\n                                                                                        <div class=\"csa-loc-card__days\">\n                                                                            <span class=\"csa-loc-daychip\">Friday \u00b7 9:30am\u201311:00am<\/span>\n                                                                    <\/div>\n                                                                                        <div class=\"csa-loc-card__delivery\">DoorDash Delivery \u2022 PV resident only)<\/div>\n                                                        <!-- Pickup-day radios injected here by JS when this card is selected (Task 4a) -->\n                            <div class=\"csa-loc-card__pickup\" hidden><\/div>\n                        <\/div>\n                        <span class=\"csa-loc-card__check\" aria-hidden=\"true\"><\/span>\n                    <\/div>\n                                        <div class=\"csa-loc-card\"\n                         data-loc-id=\"3\"\n                         data-places=\"Main St, Boonton, NJ 07005, USA\"\n                         data-lat=\"40.9071319\"\n                         data-lng=\"-74.4148302\"\n                         data-pickup-days='[&quot;Thursday&quot;]'\n                         data-pickup-times='{&quot;Thursday&quot;:{&quot;start&quot;:&quot;10:00&quot;,&quot;end&quot;:&quot;13:00&quot;}}'\n                         data-delivery='[{&quot;title&quot;:&quot;Boonton area&quot;,&quot;description&quot;:&quot;delivery for the general Boonton NJ area&quot;,&quot;price&quot;:7}]'\n                         role=\"radio\" aria-checked=\"false\" tabindex=\"0\">\n                        <div class=\"csa-loc-card__main\">\n                            <div class=\"csa-loc-card__head\">\n                                <span class=\"csa-loc-card__name\">Boonton area<\/span>\n                                <span class=\"csa-loc-card__distance\" data-distance-for=\"3\"><\/span>\n                            <\/div>\n                                                            <div class=\"csa-loc-card__addr\">Main St, Boonton, NJ 07005, USA<\/div>\n                                                                                        <div class=\"csa-loc-card__days\">\n                                                                            <span class=\"csa-loc-daychip\">Thursday \u00b7 10:00am\u20131:00pm<\/span>\n                                                                    <\/div>\n                                                                                        <div class=\"csa-loc-card__delivery\">Boonton area<\/div>\n                                                        <!-- Pickup-day radios injected here by JS when this card is selected (Task 4a) -->\n                            <div class=\"csa-loc-card__pickup\" hidden><\/div>\n                        <\/div>\n                        <span class=\"csa-loc-card__check\" aria-hidden=\"true\"><\/span>\n                    <\/div>\n                                        <div class=\"csa-loc-card\"\n                         data-loc-id=\"4\"\n                         data-places=\"Paramus, NJ 07652, USA\"\n                         data-lat=\"40.94827919999999\"\n                         data-lng=\"-74.0672769\"\n                         data-pickup-days='[&quot;Thursday&quot;]'\n                         data-pickup-times='{&quot;Thursday&quot;:{&quot;start&quot;:&quot;11:00&quot;,&quot;end&quot;:&quot;14:00&quot;}}'\n                         data-delivery='[{&quot;title&quot;:&quot;Paramus delivery&quot;,&quot;description&quot;:&quot;(Paramus, Ridgewood, River edge\\\/Oradell, to GArfield also&quot;,&quot;price&quot;:10}]'\n                         role=\"radio\" aria-checked=\"false\" tabindex=\"0\">\n                        <div class=\"csa-loc-card__main\">\n                            <div class=\"csa-loc-card__head\">\n                                <span class=\"csa-loc-card__name\">Paramus NJ area<\/span>\n                                <span class=\"csa-loc-card__distance\" data-distance-for=\"4\"><\/span>\n                            <\/div>\n                                                            <div class=\"csa-loc-card__addr\">Paramus, NJ 07652, USA<\/div>\n                                                                                        <div class=\"csa-loc-card__days\">\n                                                                            <span class=\"csa-loc-daychip\">Thursday \u00b7 11:00am\u20132:00pm<\/span>\n                                                                    <\/div>\n                                                                                        <div class=\"csa-loc-card__delivery\">Paramus delivery<\/div>\n                                                        <!-- Pickup-day radios injected here by JS when this card is selected (Task 4a) -->\n                            <div class=\"csa-loc-card__pickup\" hidden><\/div>\n                        <\/div>\n                        <span class=\"csa-loc-card__check\" aria-hidden=\"true\"><\/span>\n                    <\/div>\n                                    <\/div>\n\n                <!-- RIGHT: map (shrunk) -->\n                <div class=\"csa-loc-map-wrap\">\n                    <div id=\"map\"><\/div>\n                <\/div>\n            <\/div>\n\n            <!-- Hidden field holds the chosen location id (replaces the old select) -->\n            <input type=\"hidden\" id=\"csa-location-selector\" name=\"csa_location\" value=\"\">\n\n            <!-- Delivery-option summary for the chosen location (pickup days now live inside the card) -->\n            <div id=\"location-details\"><\/div>\n\n            <div class=\"section-footer\">\n                <button type=\"button\" class=\"btn-next\" id=\"next-to-step-2\">\n                    Continue to Products \u2192\n                <\/button>\n            <\/div>\n        <\/div>\n\n        <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n             SECTION 2 \u2014 Products & Add-Ons\n             \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n        <div class=\"csa-section\" id=\"csa-section-2\">\n            <div class=\"csa-section-header\">\n                <span class=\"section-badge\">2<\/span>\n                <div>\n                    <h2>Select Your CSA Products<\/h2>\n                    <p class=\"section-subtitle\">Choose a CSA share and any add-ons you'd like.<\/p>\n                <\/div>\n            <\/div>\n\n            <!-- Selected location + pickup day summary (Task 4b) -->\n            <div class=\"csa-step2-summary\" id=\"csa-step2-summary\"><\/div>\n\n            <h3 class=\"product-group-label\">CSA Shares<\/h3>\n            <div class=\"csa-products\">\n                                    <div class=\"csa-product\"\n                         data-id=\"1\"\n                         data-price=\"200.00\">\n\n                                                    <img decoding=\"async\" src=\"https:\/\/farmtab.com\/growingdirtfarm\/wp-content\/uploads\/sites\/71\/2026\/03\/original-13.jpeg\" alt=\"Pastured Egg (4 doz) subscription\">\n                        \n                        <h3>Pastured Egg (4 doz) subscription<\/h3>\n                        <p class=\"product-price\">$200.00<\/p>\n                        <p class=\"price-per-share\">$25.00 per share<\/p>\n                        <span class=\"renewal-freq\">monthly<\/span>\n\n                        <button type=\"button\" class=\"product-details-toggle\" aria-expanded=\"false\">Show details \u25be<\/button>\n                        <div class=\"product-meta\"\n                             data-total-shares=\"8\"\n                             data-renewal-freq=\"monthly\"\n                             data-start-date=\"2026-05-01\">\n                            <p>Get 4 dozen pasture raised eggs once a month.\r\n\r\nNote-  each CSA week you will get a reminder before which allows you to select whatever pickup or delivery options there may be, including Door dash where available.<\/p>\n                            <p><strong>Total Shares:<\/strong> 8<\/p>\n                            <p><strong>Start Date:<\/strong> Friday, May 1, 2026<\/p>\n                        <\/div>\n\n                        <div class=\"product-actions\">\n                            <button type=\"button\" class=\"add-to-order-btn button\">Add to Order<\/button>\n                            <div class=\"quantity-container\">\n                                <label>Qty:<\/label>\n                                <input type=\"number\" class=\"product-quantity\" min=\"1\" value=\"1\">\n                            <\/div>\n                        <\/div>\n\n                        <input type=\"hidden\" class=\"selected-product-id\" value=\"\">\n                    <\/div>\n                                    <div class=\"csa-product\"\n                         data-id=\"2\"\n                         data-price=\"224.00\">\n\n                                                    <img decoding=\"async\" src=\"https:\/\/farmtab.com\/growingdirtfarm\/wp-content\/uploads\/sites\/71\/2026\/03\/original-13.jpeg\" alt=\"Pastured Egg (2 doz)subscription\">\n                        \n                        <h3>Pastured Egg (2 doz)subscription<\/h3>\n                        <p class=\"product-price\">$224.00<\/p>\n                        <p class=\"price-per-share\">$14.00 per share<\/p>\n                        <span class=\"renewal-freq\">biweekly<\/span>\n\n                        <button type=\"button\" class=\"product-details-toggle\" aria-expanded=\"false\">Show details \u25be<\/button>\n                        <div class=\"product-meta\"\n                             data-total-shares=\"16\"\n                             data-renewal-freq=\"biweekly\"\n                             data-start-date=\"2026-05-01\">\n                            <p>2 dozen pastured eggs twice a month<\/p>\n                            <p><strong>Total Shares:<\/strong> 16<\/p>\n                            <p><strong>Start Date:<\/strong> Friday, May 1, 2026<\/p>\n                        <\/div>\n\n                        <div class=\"product-actions\">\n                            <button type=\"button\" class=\"add-to-order-btn button\">Add to Order<\/button>\n                            <div class=\"quantity-container\">\n                                <label>Qty:<\/label>\n                                <input type=\"number\" class=\"product-quantity\" min=\"1\" value=\"1\">\n                            <\/div>\n                        <\/div>\n\n                        <input type=\"hidden\" class=\"selected-product-id\" value=\"\">\n                    <\/div>\n                            <\/div>\n\n            <h3 class=\"product-group-label\">Add-Ons<\/h3>\n            <div class=\"csa-products\">\n                                                            <div class=\"csa-product\"\n                             data-id=\"3\"\n                             data-price=\"110.00\">\n\n                                                            <img decoding=\"async\" src=\"https:\/\/farmtab.com\/growingdirtfarm\/wp-content\/uploads\/sites\/71\/2026\/03\/original-16.jpeg\" alt=\"Select a Sausage add-on\">\n                            \n                            <h3>Select a Sausage add-on<\/h3>\n                            <p class=\"product-price\">$110.00<\/p>\n                            <p class=\"price-per-share\">$13.75 per share<\/p>\n                            <span class=\"renewal-freq\">monthly<\/span>\n\n                            <button type=\"button\" class=\"product-details-toggle\" aria-expanded=\"false\">Show details \u25be<\/button>\n                            <div class=\"product-meta\"\n                                 data-total-shares=\"8\"\n                                 data-renewal-freq=\"monthly\"\n                                 data-start-date=\"2026-05-01\">\n                                <p>add on a selection of our pasture raised pork, nitrate free sausage once a month to go along with your other CSA deliveries.\r\n\r\nYou will be able to select one style from a choice of 4 each month.\r\n\r\nNote-  you can also shop items ala carte if you wish without subscribing.<\/p>\n                                <p><strong>Total Shares:<\/strong> 8<\/p>\n                                <p><strong>Start Date:<\/strong> Friday, May 1, 2026<\/p>\n                            <\/div>\n\n                            <div class=\"product-actions\">\n                                <button type=\"button\" class=\"add-to-order-btn button\">Add to Order<\/button>\n                                <div class=\"quantity-container\">\n                                    <label>Qty:<\/label>\n                                    <input type=\"number\" class=\"product-quantity\" min=\"1\" value=\"1\">\n                                <\/div>\n                            <\/div>\n\n                            <input type=\"hidden\" class=\"selected-product-id\" value=\"\">\n                        <\/div>\n                                                <\/div>\n\n            <div id=\"delivery-options\"><\/div>\n\n            <!-- Running total moved to the bottom of Step 2 (Task 4b) -->\n            <div id=\"order-total\">Total: $0.00<\/div>\n\n            <div class=\"section-footer two-col\">\n                <button type=\"button\" class=\"btn-back\" id=\"back-to-step-1\">\u2190 Back<\/button>\n                <button type=\"button\" class=\"btn-next\" id=\"next-to-step-3\">\n                    Continue to Review &amp; Pay \u2192\n                <\/button>\n            <\/div>\n        <\/div>\n\n        <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n             SECTION 3 \u2014 Review & Pay\n             \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n        <div class=\"csa-section\" id=\"csa-section-3\">\n            <div class=\"csa-section-header\">\n                <span class=\"section-badge\">3<\/span>\n                <div>\n                    <h2>Review &amp; Pay<\/h2>\n                    <p class=\"section-subtitle\">Confirm your order details and complete your payment.<\/p>\n                <\/div>\n            <\/div>\n\n            <!-- Order Summary -->\n\n            <div id=\"payment-options\">\n                <h3>Payment Options<\/h3>\n                <div class=\"csa-payment-radios\" id=\"csa-payment-radios\">\n                    <label class=\"csa-payment-radio\">\n                        <input type=\"radio\" name=\"payment_method\" value=\"full\" required>\n                        <span class=\"csa-payment-radio__dot\" aria-hidden=\"true\"><\/span>\n                        <span class=\"csa-payment-radio__text\">\n                            <span class=\"csa-payment-radio__title\">Pay in Full<\/span>\n                            <span class=\"csa-payment-radio__desc\">One payment today for the whole season.<\/span>\n                        <\/span>\n                    <\/label>\n                                        <label class=\"csa-payment-radio\">\n                        <input type=\"radio\" name=\"payment_method\" value=\"monthly\">\n                        <span class=\"csa-payment-radio__dot\" aria-hidden=\"true\"><\/span>\n                        <span class=\"csa-payment-radio__text\">\n                            <span class=\"csa-payment-radio__title\">Pay in 3 Monthly Installments<\/span>\n                            <span class=\"csa-payment-radio__desc\">Split evenly across 3 monthly charges.<\/span>\n                        <\/span>\n                    <\/label>\n                                        <label class=\"csa-payment-radio\">\n                        <input type=\"radio\" name=\"payment_method\" value=\"weekly\">\n                        <span class=\"csa-payment-radio__dot\" aria-hidden=\"true\"><\/span>\n                        <span class=\"csa-payment-radio__text\">\n                            <span class=\"csa-payment-radio__title\">Pay in 10 Weekly Installments<\/span>\n                            <span class=\"csa-payment-radio__desc\">Split evenly across 10 weekly charges.<\/span>\n                        <\/span>\n                    <\/label>\n                                    <\/div>\n            <\/div>\n\n            <div id=\"installment-breakdown\"><\/div>\n            <div id=\"cart-totals\"><\/div>\n\n            <!-- Billing Details -->\n            <h3 class=\"billing-heading\">Billing Details<\/h3>\n            <p class=\"billing-subtext\">Please enter your billing information below.<\/p>\n            <div class=\"billing-fields\">\n                <div>\n                    <label for=\"billing_first_name\">First Name<\/label>\n                    <input type=\"text\" id=\"billing_first_name\" name=\"billing_first_name\" placeholder=\"Jane\" required>\n                <\/div>\n                <div>\n                    <label for=\"billing_last_name\">Last Name<\/label>\n                    <input type=\"text\" id=\"billing_last_name\" name=\"billing_last_name\" placeholder=\"Smith\" required>\n                <\/div>\n                <div>\n                    <label for=\"billing_phone\">Phone Number<\/label>\n                    <input type=\"tel\" id=\"billing_phone\" name=\"billing_phone\" placeholder=\"(555) 000-0000\" required>\n                <\/div>\n                <div class=\"full-width\">\n                    <label for=\"billing_street\">Street Address<\/label>\n                    <input type=\"text\" id=\"billing_street\" name=\"billing_street\" placeholder=\"123 Main St\" required>\n                <\/div>\n                <div>\n                    <label for=\"billing_city\">City<\/label>\n                    <input type=\"text\" id=\"billing_city\" name=\"billing_city\" placeholder=\"Springfield\" required>\n                <\/div>\n                <div>\n                    <label for=\"billing_state\">State<\/label>\n                    <input type=\"text\" id=\"billing_state\" name=\"billing_state\" placeholder=\"NJ\" required>\n                <\/div>\n                <div>\n                    <label for=\"billing_zip\">ZIP Code<\/label>\n                    <input type=\"text\" id=\"billing_zip\" name=\"billing_zip\" placeholder=\"08540\" required>\n                <\/div>\n            <\/div>\n\n            <!-- Payment -->\n            <div id=\"stripe-payment-section\">\n                <h3>Payment Information<\/h3>\n                <div id=\"card-element\"><\/div>\n                <div id=\"card-errors\"><\/div>\n                <button type=\"submit\" id=\"submit-button\" class=\"button button-primary\">Submit and Pay<\/button>\n            <\/div>\n\n            <!-- Message for logged-out users \u2014 triggers the login\/register modal -->\n            <div id=\"login-required-message\">\n                <h3>Please log in or register to continue<\/h3>\n                <p>You must be logged in to submit this form and complete your payment.<\/p>\n                <div class=\"csa-login-actions\">\n                    <button type=\"button\" id=\"csa-open-login-modal\" class=\"button button-primary\">Log In<\/button>\n                    <button type=\"button\" id=\"csa-open-register-modal\" class=\"button button-secondary\">Create Account<\/button>\n                <\/div>\n            <\/div>\n\n            <!-- Login \/ Register Modal -->\n            <div id=\"csa-auth-modal\" style=\"display:none;position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,0.55);overflow-y:auto;\" role=\"dialog\" aria-modal=\"true\">\n                <div style=\"background:#fff;border-radius:10px;max-width:420px;width:calc(100% - 32px);margin:60px auto;padding:28px;position:relative;box-shadow:0 8px 32px rgba(0,0,0,0.2);\">\n                    <button id=\"csa-auth-modal-close\" type=\"button\" aria-label=\"Close\" style=\"position:absolute;top:12px;right:14px;background:none;border:none;font-size:24px;cursor:pointer;color:#555;line-height:1;\">&times;<\/button>\n\n                    <!-- Tab switcher -->\n                    <div style=\"display:flex;gap:0;margin-bottom:20px;border-bottom:2px solid #eee;\">\n                        <button type=\"button\" class=\"csa-auth-tab active\" data-tab=\"login\" style=\"flex:1;padding:10px;border:none;background:none;font-size:15px;font-weight:600;cursor:pointer;border-bottom:2px solid #333;margin-bottom:-2px;\">Log In<\/button>\n                        <button type=\"button\" class=\"csa-auth-tab\" data-tab=\"register\" style=\"flex:1;padding:10px;border:none;background:none;font-size:15px;font-weight:400;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;\">Create Account<\/button>\n                    <\/div>\n\n                    <!-- Login form -->\n                    <div id=\"csa-tab-login\">\n                        <p id=\"csa-login-msg\" style=\"display:none;color:red;margin-bottom:10px;\"><\/p>\n                        <label style=\"display:block;margin-bottom:10px;\">Username or Email\n                            <input type=\"text\" id=\"csa-login-user\" autocomplete=\"username\" style=\"display:block;width:100%;margin-top:4px;padding:8px;border:1px solid #ccc;border-radius:4px;\">\n                        <\/label>\n                        <label style=\"display:block;margin-bottom:14px;\">Password\n                            <input type=\"password\" id=\"csa-login-pass\" autocomplete=\"current-password\" style=\"display:block;width:100%;margin-top:4px;padding:8px;border:1px solid #ccc;border-radius:4px;\">\n                        <\/label>\n                        <button type=\"button\" id=\"csa-login-btn\" style=\"width:100%;padding:11px;background:#333;color:#fff;border:none;border-radius:5px;font-size:15px;cursor:pointer;\">Log In<\/button>\n                        <p style=\"text-align:center;margin-top:12px;font-size:13px;\">\n                            <a href=\"https:\/\/farmtab.com\/my-account\/lost-password\/\" target=\"_blank\">Forgot password?<\/a>\n                        <\/p>\n                    <\/div>\n\n                    <!-- Register form -->\n                    <div id=\"csa-tab-register\" style=\"display:none;\">\n                        <p id=\"csa-register-msg\" style=\"display:none;color:red;margin-bottom:10px;\"><\/p>\n                        <label style=\"display:block;margin-bottom:10px;\">First Name\n                            <input type=\"text\" id=\"csa-reg-first\" autocomplete=\"given-name\" style=\"display:block;width:100%;margin-top:4px;padding:8px;border:1px solid #ccc;border-radius:4px;\">\n                        <\/label>\n                        <label style=\"display:block;margin-bottom:10px;\">Last Name\n                            <input type=\"text\" id=\"csa-reg-last\" autocomplete=\"family-name\" style=\"display:block;width:100%;margin-top:4px;padding:8px;border:1px solid #ccc;border-radius:4px;\">\n                        <\/label>\n                        <label style=\"display:block;margin-bottom:10px;\">Email Address\n                            <input type=\"email\" id=\"csa-reg-email\" autocomplete=\"email\" style=\"display:block;width:100%;margin-top:4px;padding:8px;border:1px solid #ccc;border-radius:4px;\">\n                        <\/label>\n                        <label style=\"display:block;margin-bottom:14px;\">Password\n                            <input type=\"password\" id=\"csa-reg-pass\" autocomplete=\"new-password\" style=\"display:block;width:100%;margin-top:4px;padding:8px;border:1px solid #ccc;border-radius:4px;\">\n                        <\/label>\n                        <button type=\"button\" id=\"csa-register-btn\" style=\"width:100%;padding:11px;background:#333;color:#fff;border:none;border-radius:5px;font-size:15px;cursor:pointer;\">Create Account<\/button>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"section-footer two-col\">\n                <button type=\"button\" class=\"btn-back\" id=\"back-to-step-2\">\u2190 Back to Products<\/button>\n            <\/div>\n        <\/div>\n\n    <\/form>\n\n    <script>\n    \/\/ Product details toggle\n    document.addEventListener('DOMContentLoaded', function () {\n        document.querySelectorAll('.product-details-toggle').forEach(function (btn) {\n            btn.addEventListener('click', function () {\n                var meta = btn.nextElementSibling;\n                var open = meta.classList.toggle('open');\n                btn.setAttribute('aria-expanded', open);\n                btn.textContent = open ? 'Hide details \u25b4' : 'Show details \u25be';\n            });\n        });\n    });\n    <\/script>\n\n    <script>\n    \/\/ \u2500\u2500 Stepper Navigation \u2500\u2500\n    document.addEventListener('DOMContentLoaded', function () {\n        var currentStep = 1;\n\n        function goToStep(n) {\n            document.querySelectorAll('.csa-section').forEach(function(s) {\n                s.classList.remove('active');\n            });\n            var target = document.getElementById('csa-section-' + n);\n            if (target) target.classList.add('active');\n\n            document.querySelectorAll('.csa-step').forEach(function(s) {\n                var num = parseInt(s.getAttribute('data-step'));\n                s.classList.remove('active', 'completed');\n                if (num === n) s.classList.add('active');\n                if (num < n)  s.classList.add('completed');\n            });\n\n            document.querySelectorAll('.step-connector').forEach(function(c, i) {\n                c.classList.toggle('filled', i < n - 1);\n            });\n\n            currentStep = n;\n\n            var stepsEl = document.getElementById('csa-steps');\n            if (stepsEl) stepsEl.scrollIntoView({ behavior: 'smooth', block: 'start' });\n        }\n\n        var next1 = document.getElementById('next-to-step-2');\n        if (next1) next1.addEventListener('click', function() {\n            var loc = document.getElementById('csa-location-selector');\n            if (!loc || !loc.value) {\n                var list = document.getElementById('csa-loc-list');\n                if (list) {\n                    list.style.outline = '2px solid #dc2626';\n                    list.style.borderRadius = '10px';\n                    list.scrollIntoView({ behavior: 'smooth', block: 'center' });\n                    setTimeout(function(){ list.style.outline = ''; }, 2000);\n                }\n                return;\n            }\n            var pickupChecked = document.querySelector('input[name=\"selected_pickup_day\"]:checked');\n            if (!pickupChecked) {\n                var details = document.getElementById('location-details');\n                if (details) {\n                    details.style.outline = '2px solid #dc2626';\n                    details.style.borderRadius = '8px';\n                    setTimeout(function(){ details.style.outline = ''; }, 2000);\n                }\n                return;\n            }\n            goToStep(2);\n        });\n\n        var next2 = document.getElementById('next-to-step-3');\n        if (next2) next2.addEventListener('click', function() {\n            var anySelected = document.querySelector('.csa-product .selected-product-id[value]:not([value=\"\"])');\n            if (!anySelected) {\n                var grid = document.querySelector('.csa-products');\n                if (grid) {\n                    grid.style.outline = '2px solid #dc2626';\n                    grid.style.borderRadius = '10px';\n                    setTimeout(function(){ grid.style.outline = ''; }, 2000);\n                }\n                return;\n            }\n            goToStep(3);\n        });\n\n        var back1 = document.getElementById('back-to-step-1');\n        if (back1) back1.addEventListener('click', function(){ goToStep(1); });\n\n        var back2 = document.getElementById('back-to-step-2');\n        if (back2) back2.addEventListener('click', function(){ goToStep(2); });\n    });\n    <\/script>\n\n<script>\ndocument.addEventListener('DOMContentLoaded', function () {\n\n    function formatTime24to12(timeStr) {\n        if (!timeStr) return '';\n        const [hour, minute] = timeStr.split(':');\n        const date = new Date();\n        date.setHours(hour);\n        date.setMinutes(minute || 0);\n        return date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });\n    }\n\n    \/\/ \u2500\u2500 Use the platform publishable key (shared with WooCommerce Stripe Connect Gateway) \u2500\u2500\n    const stripeKey  = \"pk_live_51MrtHzFHwmClpvVk2FVSJWoTNSSK2WjZREbSBDdefLM47b91kgCJzxLLCgxeoomwmj3erRT7pMZNViDDFrVCdvBZ000vRh38Kn\";\n    const serviceFee = 7.99;\n    const ajaxUrl    = \"https:\/\/farmtab.com\/growingdirtfarm\/wp-admin\/admin-ajax.php\";\n    const isLoggedIn      = false;\n    const csaMonthlyCount = 3;\n    const csaWeeklyCount  = 10;\n\n    document.getElementById(\"stripe-payment-section\").style.display  = isLoggedIn ? \"block\" : \"none\";\n    document.getElementById(\"login-required-message\").style.display = isLoggedIn ? \"none\"  : \"block\";\n\n    if (!stripeKey) {\n        console.error(\"Error: Stripe publishable key is missing.\");\n        alert(\"Stripe is not configured properly. Please check your settings.\");\n        return;\n    }\n\n    const stripe     = Stripe(stripeKey);\n    const elements   = stripe.elements();\n    const cardElement = elements.create(\"card\");\n    cardElement.mount(\"#card-element\");\n\n    const form                 = document.getElementById('csa-order-form');\n    const locationSelector     = document.getElementById('csa-location-selector');\n    const locationDetails      = document.getElementById('location-details');\n    const deliveryOptions      = document.getElementById('delivery-options');\n    const totalDisplay         = document.getElementById('order-total');\n    \/\/ Payment method is now a set of radio cards (Task 4c). This shim exposes a\n    \/\/ `.value` getter reading the checked radio and forwards change events, so\n    \/\/ the rest of the code that used the old <select id=\"payment-method\"> works.\n    const paymentSelect = {\n        get value() {\n            const checked = document.querySelector('input[name=\"payment_method\"]:checked');\n            return checked ? checked.value : '';\n        },\n        addEventListener(evt, handler) {\n            document.querySelectorAll('input[name=\"payment_method\"]').forEach(r => {\n                r.addEventListener(evt, handler);\n            });\n        }\n    };\n    const installmentBreakdown = document.getElementById('installment-breakdown');\n    const cartTotalsContainer  = document.getElementById('cart-totals');\n    const submitButton         = form.querySelector('button[type=\"submit\"]');\n\n    let clientSecret  = null;\n    let dueNowAmount  = 0;\n    let fullAmount    = 0;\n    let monthlyAmount = 0;\n    let weeklyAmount  = 0;\n\n    \/\/ \u2500\u2500 Location selector (card list) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    \/\/ The old <select> is now a hidden input (#csa-location-selector) fed by\n    \/\/ clickable location cards. renderLocationDetails() mirrors the original\n    \/\/ change-handler logic so downstream code (pickup day, delivery, total)\n    \/\/ keeps working unchanged.\n    function renderLocationDetails(card) {\n        const address        = card.getAttribute(\"data-places\") || \"\";\n        const pickupDays     = JSON.parse(card.getAttribute(\"data-pickup-days\") || \"[]\");\n        const pickupTimes    = JSON.parse(card.getAttribute(\"data-pickup-times\") || \"{}\");\n        const deliveryOpts   = JSON.parse(card.getAttribute(\"data-delivery\") || \"[]\");\n\n        let customDeliveryFee   = 0;\n        let customDeliveryTitle = \"\";\n\n        \/\/ Build the pickup-day radios and inject them INSIDE this card (Task 4a).\n        \/\/ Clear pickup UI from every other card first so only the selected card\n        \/\/ shows day options.\n        document.querySelectorAll('.csa-loc-card__pickup').forEach(el => {\n            el.innerHTML = '';\n            el.hidden = true;\n        });\n\n        const pickupBox = card.querySelector('.csa-loc-card__pickup');\n        if (pickupBox && pickupDays.length > 0) {\n            let pickupHtml = '<span class=\"csa-loc-pickup__label\">Select a pickup day:<\/span>';\n            pickupHtml += '<div class=\"csa-loc-pickup__options\">';\n            pickupDays.forEach(day => {\n                const time      = pickupTimes[day] || {};\n                const startTime = formatTime24to12(time.start);\n                const endTime   = formatTime24to12(time.end);\n                const timeStr   = (startTime || endTime)\n                    ? `${startTime}${startTime && endTime ? ' - ' : ''}${endTime}` : '';\n                pickupHtml += `\n                    <label class=\"csa-loc-pickup__opt\">\n                        <input type=\"radio\" name=\"selected_pickup_day\" value=\"${day}\" required>\n                        <span class=\"csa-loc-pickup__optlabel\">${day}${timeStr ? ` <span class=\"csa-loc-pickup__time\">(${timeStr})<\/span>` : ''}<\/span>\n                    <\/label>`;\n            });\n            pickupHtml += '<\/div>';\n            pickupBox.innerHTML = pickupHtml;\n            pickupBox.hidden = false;\n        }\n\n        \/\/ Delivery-options summary stays in the separate #location-details area.\n        let deliveryHtml = \"<h3>Available Delivery Options<\/h3><ul>\";\n        deliveryOpts.forEach(option => {\n            if (typeof option === \"object\" && option.title && option.price && option.description) {\n                deliveryHtml += `<li><strong>${option.title}<\/strong>: ${option.description} ($${parseFloat(option.price).toFixed(2)})<\/li>`;\n                if (option.title !== \"Free Local Pickup\" && option.title !== \"DoorDash Delivery\") {\n                    customDeliveryFee   = parseFloat(option.price);\n                    customDeliveryTitle = option.title;\n                }\n            }\n        });\n        deliveryHtml += \"<\/ul>\";\n\n        const deliveryOptionsContainer = document.getElementById(\"delivery-options\");\n        if (deliveryOptionsContainer) {\n            deliveryOptionsContainer.innerHTML = deliveryHtml;\n        }\n        if (locationDetails) locationDetails.innerHTML = '';\n\n        window.selectedDeliveryFee   = customDeliveryFee;\n        window.selectedDeliveryTitle = customDeliveryTitle;\n\n        \/\/ Capture the chosen location's name + address for the Step 2 summary \/\n        \/\/ Cart Totals (Task 4b\/4c)\n        const nameEl = card.querySelector('.csa-loc-card__name');\n        window.selectedLocationName    = nameEl ? nameEl.textContent.trim() : '';\n        window.selectedLocationAddress = address;\n        window.selectedPickupDay = ''; \/\/ reset \u2014 a day must be chosen for the new location\n        updateStep2Summary();\n        updateTotal();\n    }\n\n    document.querySelectorAll('.csa-loc-card').forEach(function (card) {\n        function selectThisCard() {\n            document.querySelectorAll('.csa-loc-card').forEach(c => {\n                c.classList.remove('selected');\n                c.setAttribute('aria-checked', 'false');\n            });\n            card.classList.add('selected');\n            card.setAttribute('aria-checked', 'true');\n            if (locationSelector) locationSelector.value = card.getAttribute('data-loc-id');\n            renderLocationDetails(card);\n        }\n        \/\/ Clicking anywhere on the card selects it \u2014 EXCEPT when interacting with\n        \/\/ the pickup-day radios inside it (so choosing a day doesn't re-toggle).\n        card.addEventListener('click', function (e) {\n            if (e.target.closest('.csa-loc-card__pickup')) return;\n            selectThisCard();\n        });\n        card.addEventListener('keydown', function (e) {\n            if (e.target.closest('.csa-loc-card__pickup')) return;\n            if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); selectThisCard(); }\n        });\n    });\n\n    \/\/ Keep the Step 2 summary's pickup-day in sync when the user picks a day\n    document.addEventListener('change', function (e) {\n        if (e.target && e.target.name === 'selected_pickup_day') {\n            window.selectedPickupDay = e.target.value;\n            updateStep2Summary();\n        }\n    });\n\n    \/\/ \u2500\u2500 Step 2 summary (selected location + pickup day) \u2014 Task 4b \u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    function updateStep2Summary() {\n        const el = document.getElementById('csa-step2-summary');\n        if (!el) return;\n        const loc = window.selectedLocationName || '\u2014';\n        const day = window.selectedPickupDay || '\u2014';\n        el.innerHTML =\n            `<div class=\"csa-step2-summary__item\"><span class=\"csa-step2-summary__label\">Location<\/span><span class=\"csa-step2-summary__value\">${loc}<\/span><\/div>` +\n            `<div class=\"csa-step2-summary__item\"><span class=\"csa-step2-summary__label\">Pickup Day<\/span><span class=\"csa-step2-summary__value\">${day}<\/span><\/div>`;\n    }\n    window.updateStep2Summary = updateStep2Summary;\n\n    \/\/ \u2500\u2500 Add \/ remove products \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    form.addEventListener('click', function (event) {\n        if (event.target.classList.contains('add-to-order-btn')) {\n            const product         = event.target.closest('.csa-product');\n            const hiddenInput     = product.querySelector('.selected-product-id');\n            const quantityContainer = product.querySelector('.quantity-container');\n\n            if (!hiddenInput.value) {\n                event.target.textContent = 'Added \u2713';\n                event.target.classList.add('added');\n                hiddenInput.value = product.dataset.id;\n                product.classList.add('selected');\n                quantityContainer.classList.add('visible');\n            } else {\n                event.target.textContent = 'Add to Order';\n                event.target.classList.remove('added');\n                hiddenInput.value = '';\n                product.classList.remove('selected');\n                quantityContainer.classList.remove('visible');\n            }\n            updateTotal();\n        }\n    });\n\n    form.addEventListener('change', function (event) {\n        if (event.target.classList.contains('product-quantity')) {\n            updateTotal();\n        }\n    });\n\n    \/\/ \u2500\u2500 Pro-rate helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    \/\/ Returns the dollar amount to deduct from a product line when the customer\n    \/\/ is ordering after the product's start date.\n    \/\/\n    \/\/ Logic:\n    \/\/   \u2022 per-share cost = price \/ total_shares\n    \/\/   \u2022 elapsed shares = number of share periods that have *fully* passed since\n    \/\/     start_date as of today (each period = renewal interval in days)\n    \/\/   \u2022 discount = elapsed_shares \u00d7 per_share_cost \u00d7 qty\n    \/\/   \u2022 capped at the line total (can never create a negative product cost)\n    \/\/   \u2022 only applies when payment plan = \"full\" (installment customers pay\n    \/\/     the full split amount \u2014 the subscription handles timing automatically)\n    \/\/\n    \/\/ renewal_frequency values (from the DB): weekly, biweekly, monthly\n    function calcProration(price, totalShares, renewalFreq, startDateStr, qty) {\n        if (!startDateStr || !totalShares || totalShares <= 0) return 0;\n\n        const today     = new Date();\n        today.setHours(0, 0, 0, 0);\n        \/\/ Parse YYYY-MM-DD start date without UTC shift\n        const parts     = startDateStr.split('-');\n        const startDate = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]));\n        startDate.setHours(0, 0, 0, 0);\n\n        if (today <= startDate) return 0; \/\/ hasn't started yet \u2014 no proration\n\n        const msPerDay     = 1000 * 60 * 60 * 24;\n        const daysSinceStart = Math.floor((today - startDate) \/ msPerDay);\n\n        \/\/ Share interval in days\n        const freq = (renewalFreq || '').toLowerCase().trim();\n        let intervalDays;\n        if      (freq === 'weekly')    intervalDays = 7;\n        else if (freq === 'biweekly')  intervalDays = 14;\n        else if (freq === 'monthly')   intervalDays = 30;\n        else return 0; \/\/ unknown frequency \u2014 skip proration to be safe\n\n        \/\/ Fully elapsed share periods (floor \u2014 don't count the current active period)\n        const elapsedShares = Math.min(\n            Math.floor(daysSinceStart \/ intervalDays),\n            totalShares - 1  \/\/ never deduct the last share (customer still receives value)\n        );\n\n        if (elapsedShares <= 0) return 0;\n\n        const perShareCost = price \/ totalShares;\n        const discount     = elapsedShares * perShareCost * qty;\n\n        \/\/ Cap at the full line total so we never go negative\n        return Math.min(discount, price * qty);\n    }\n\n    \/\/ \u2500\u2500 Update cart total and request a fresh PaymentIntent \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    async function updateTotal() {\n        let productSubtotal = 0;  \/\/ raw product cost before proration\n        let totalProration  = 0;  \/\/ total discount from elapsed shares\n        let cartHTML = '<h3>Cart Totals<\/h3>';\n\n        \/\/ Pickup Day + Location summary above the product table (Task 4c)\n        const cartLoc = window.selectedLocationName || '\u2014';\n        const cartDay = window.selectedPickupDay   || '\u2014';\n        cartHTML += `<div class=\"csa-cart-pickup\">\n            <div class=\"csa-cart-pickup__row\"><span class=\"csa-cart-pickup__label\">Location<\/span><span class=\"csa-cart-pickup__value\">${cartLoc}<\/span><\/div>\n            <div class=\"csa-cart-pickup__row\"><span class=\"csa-cart-pickup__label\">Pickup Day<\/span><span class=\"csa-cart-pickup__value\">${cartDay}<\/span><\/div>\n        <\/div>`;\n\n        cartHTML += '<table style=\"width:100%; border-collapse: collapse;\">';\n        cartHTML    += '<tr><th style=\"text-align:left;\">Product<\/th><th>Qty<\/th><th>Price<\/th><th>Total<\/th><\/tr>';\n\n        const selectedPlanForProrate = paymentSelect?.value || 'full';\n\n        document.querySelectorAll(\".csa-product\").forEach(product => {\n            const selectedId = product.querySelector(\".selected-product-id\")?.value;\n            if (selectedId) {\n                const name        = product.querySelector(\"h3\").textContent.split(\" - \")[0];\n                const price       = parseFloat(product.dataset.price);\n                const qty         = parseInt(product.querySelector(\".product-quantity\")?.value) || 1;\n                const lineTotal   = price * qty;\n                productSubtotal  += lineTotal;\n\n                \/\/ Read product metadata for proration\n                const meta        = product.querySelector('.product-meta');\n                const totalShares = parseInt(meta?.dataset.totalShares) || 0;\n                const renewalFreq = meta?.dataset.renewalFreq || '';\n                const startDate   = meta?.dataset.startDate   || '';\n\n                \/\/ Proration only on Pay in Full \u2014 installment plans divide the\n                \/\/ full cost across the subscription schedule automatically.\n                let lineProration = 0;\n                if (selectedPlanForProrate === 'full') {\n                    lineProration = calcProration(price, totalShares, renewalFreq, startDate, qty);\n                    totalProration += lineProration;\n                }\n\n                const discountedLine = lineTotal - lineProration;\n\n                cartHTML += `\n                    <tr>\n                        <td>${name}${lineProration > 0 ? ' <em style=\"color:#888;font-size:0.85em;\">(prorated)<\/em>' : ''}<\/td>\n                        <td style=\"text-align:center;\">${qty}<\/td>\n                        <td style=\"text-align:right;\">$${price.toFixed(2)}<\/td>\n                        <td style=\"text-align:right;\">${lineProration > 0\n                            ? `<span style=\"text-decoration:line-through;color:#999;\">$${lineTotal.toFixed(2)}<\/span> $${discountedLine.toFixed(2)}`\n                            : `$${lineTotal.toFixed(2)}`\n                        }<\/td>\n                    <\/tr>`;\n            }\n        });\n\n        cartHTML += \"<\/table>\";\n        cartHTML += `<p><strong>Subtotal:<\/strong> $${productSubtotal.toFixed(2)}<\/p>`;\n\n        \/\/ Show proration line if any discount applies\n        if (totalProration > 0) {\n            cartHTML += `<p style=\"color:#2a7d4f;\">\n                <strong>Prorated Discount:<\/strong>\n                &minus;$${totalProration.toFixed(2)}\n                <span class=\"proration-discount-value\" data-amount=\"${totalProration.toFixed(2)}\" style=\"display:none;\"><\/span>\n                <span style=\"font-size:0.85em;color:#666;display:block;margin-top:2px;\">\n                    Shares that have already passed since the product start date have been\n                    deducted from your product total. Your service fee and delivery fee are not affected.\n                <\/span>\n            <\/p>`;\n        }\n\n        \/\/ Start building the running total from the prorated product cost\n        let total = productSubtotal - totalProration;\n\n        if (serviceFee > 0) {\n            total    += serviceFee;\n            cartHTML += `<p><strong>Service Fee:<\/strong> $${serviceFee.toFixed(2)}<\/p>`;\n        }\n\n        if (window.selectedDeliveryFee && window.selectedDeliveryFee > 0) {\n            total    += window.selectedDeliveryFee;\n            cartHTML += `<p><strong>Delivery Fee (${window.selectedDeliveryTitle}):<\/strong> $${window.selectedDeliveryFee.toFixed(2)}<\/p>`;\n        }\n\n        fullAmount    = total;\n        monthlyAmount = total \/ csaMonthlyCount;\n        weeklyAmount  = total \/ csaWeeklyCount;\n\n        dueNowAmount = calculateDueNow(total);\n\n        \/\/ Per-installment service fee sent to server so application_fee_amount\n        \/\/ is the correct fraction per charge, not the full option value.\n        const plan = paymentSelect?.value || 'full';\n        if      (plan === 'monthly') window.csaServiceFeeInstallment = serviceFee \/ csaMonthlyCount;\n        else if (plan === 'weekly')  window.csaServiceFeeInstallment = serviceFee \/ csaWeeklyCount;\n        else                         window.csaServiceFeeInstallment = serviceFee;\n\n        totalDisplay.textContent = `Total: $${total.toFixed(2)}`;\n        cartHTML += `<p><strong>Amount Due Today:<\/strong> $${dueNowAmount.toFixed(2)}<\/p>`;\n\n        const cartTotalsEl = document.getElementById(\"cart-totals\");\n        if (cartTotalsEl) cartTotalsEl.innerHTML = cartHTML;\n\n        \/\/ The breakdown box now shows only the amount owed today (Task 4c) \u2014\n        \/\/ no per-installment schedule of future dates\/amounts.\n        if (installmentBreakdown) {\n            installmentBreakdown.innerHTML = getAmountDueTodayHTML();\n        }\n\n        if (submitButton) {\n            submitButton.textContent = `Pay now ($${dueNowAmount.toFixed(2)})`;\n        }\n\n        await fetchPaymentIntent();\n    }\n\n    function calculateDueNow(total) {\n        const method = paymentSelect?.value || 'full';\n        if (method === 'monthly') return total \/ csaMonthlyCount;\n        if (method === 'weekly')  return total \/ csaWeeklyCount;\n        return total;\n    }\n\n    function getAmountDueTodayHTML() {\n        const method = paymentSelect?.value || 'full';\n        const dueToday = calculateDueNow(fullAmount);\n        let planLabel = 'Pay in Full';\n        if (method === 'monthly') planLabel = `${csaMonthlyCount} Monthly Installments`;\n        else if (method === 'weekly') planLabel = `${csaWeeklyCount} Weekly Installments`;\n        return `<p class=\"csa-due-today\"><span class=\"csa-due-today__label\">Amount Owed Today<\/span>\n                <span class=\"csa-due-today__amount\">$${dueToday.toFixed(2)}<\/span>\n                <span class=\"csa-due-today__plan\">${planLabel}<\/span><\/p>`;\n    }\n\n    function getInstallmentScheduleHTML(total) {\n        \/\/ Deprecated (Task 4c): the per-installment schedule of future dates was\n        \/\/ replaced by getAmountDueTodayHTML(), which shows only today's amount.\n        \/\/ Kept as a no-op for backward safety in case any external code calls it.\n        return '';\n    }\n\n    if (paymentSelect) {\n        paymentSelect.addEventListener('change', async function () {\n            const selectedPlan = this.value;\n            switch (selectedPlan) {\n                case 'full':    dueNowAmount = fullAmount;                          break;\n                case 'monthly': dueNowAmount = fullAmount \/ csaMonthlyCount;        break;\n                case 'weekly':  dueNowAmount = fullAmount \/ csaWeeklyCount;         break;\n                default: return;\n            }\n            \/\/ Keep per-installment fee in sync with the chosen plan\n            if      (selectedPlan === 'monthly') window.csaServiceFeeInstallment = serviceFee \/ csaMonthlyCount;\n            else if (selectedPlan === 'weekly')  window.csaServiceFeeInstallment = serviceFee \/ csaWeeklyCount;\n            else                                  window.csaServiceFeeInstallment = serviceFee;\n            await updateTotal();\n        });\n    }\n\n    \/\/ \u2500\u2500 Fetch a Stripe Connect split PaymentIntent from the server \u2500\u2500\u2500\u2500\u2500\n    \/\/ The AJAX handler (csa_create_payment_intent in csa-plugin.php) now\n    \/\/ creates the intent with:\n    \/\/   - platform key            \u2192 charges go through the platform account\n    \/\/   - application_fee_amount  \u2192 service fee stays on the platform\n    \/\/   - transfer_data           \u2192 product cost forwarded to the farmer's\n    \/\/                               Stripe Connect account\n    async function fetchPaymentIntent() {\n        console.log(\"Requesting new CSA split PaymentIntent...\");\n        clientSecret = null;\n\n        \/\/ Send both the total amount and the delivery fee so the server can\n        \/\/ compute the correct application_fee_amount (service fee only;\n        \/\/ delivery fee goes to the platform, not the farmer).\n        const deliveryFeeForServer = window.selectedDeliveryFee\n            ? parseFloat(window.selectedDeliveryFee)\n            : 0;\n\n        const response = await fetch(ajaxUrl, {\n            method: \"POST\",\n            headers: { \"Content-Type\": \"application\/x-www-form-urlencoded\" },\n            body: new URLSearchParams({\n                action:                  \"csa_create_payment_intent\",\n                amount:                  dueNowAmount,\n                delivery_fee:            deliveryFeeForServer,\n                service_fee_installment: window.csaServiceFeeInstallment ?? serviceFee,\n                payment_plan:            paymentSelect?.value || 'full'\n            })\n        });\n\n        const rawText = await response.text();\n        try {\n            const data = JSON.parse(rawText);\n            if (data.success && data.data && data.data.clientSecret) {\n                clientSecret = data.data.clientSecret;\n                console.log(\"CSA split PaymentIntent ready.\");\n            } else {\n                throw new Error(\"PaymentIntent creation failed.\");\n            }\n        } catch (err) {\n            console.error(\"PaymentIntent error:\", err, rawText);\n            alert(\"Error initializing payment. Please refresh and try again.\");\n        }\n    }\n\n    \/\/ \u2500\u2500 Form submission \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    form.addEventListener('submit', async function (e) {\n        e.preventDefault();\n        const submitBtn = document.getElementById(\"submit-button\");\n        submitBtn.disabled    = true;\n        submitBtn.textContent = \"Processing...\";\n\n        if (!clientSecret) {\n            await fetchPaymentIntent();\n        }\n\n        if (!clientSecret) {\n            alert(\"Payment not initialized. Please try again.\");\n            submitBtn.disabled    = false;\n            submitBtn.textContent = \"Submit and Pay\";\n            return;\n        }\n\n        try {\n            const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {\n                payment_method: { card: cardElement }\n            });\n\n            if (error) {\n                document.getElementById(\"card-errors\").textContent = error.message;\n                submitBtn.disabled    = false;\n                submitBtn.textContent = \"Submit and Pay\";\n                return;\n            }\n\n            if (!paymentIntent || paymentIntent.status !== \"succeeded\") {\n                alert(\"Payment processing failed.\");\n                submitBtn.disabled    = false;\n                submitBtn.textContent = \"Submit and Pay\";\n                return;\n            }\n\n            \/\/ \u2500\u2500 Save card for subscription recurring payments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n            \/\/ For installment plans, run a SetupIntent so the card is saved and\n            \/\/ WooCommerce Subscriptions can charge it for future instalments.\n            let savedPaymentMethodId = paymentIntent.payment_method || null;\n\n            const selectedPlan = paymentSelect?.value || 'full';\n            if (selectedPlan === 'monthly' || selectedPlan === 'weekly') {\n                try {\n                    submitBtn.textContent = \"Saving payment method\u2026\";\n                    const siRes  = await fetch(ajaxUrl, {\n                        method: 'POST',\n                        headers: { 'Content-Type': 'application\/x-www-form-urlencoded' },\n                        body: new URLSearchParams({ action: 'csa_create_setup_intent' })\n                    });\n                    const siData = await siRes.json();\n\n                    if (siData.success && siData.data?.clientSecret) {\n                        const { setupIntent, error: siError } = await stripe.confirmCardSetup(\n                            siData.data.clientSecret,\n                            { payment_method: { card: cardElement } }\n                        );\n                        if (siError) {\n                            console.warn('Card save warning (non-fatal):', siError.message);\n                        } else if (setupIntent?.payment_method) {\n                            savedPaymentMethodId = setupIntent.payment_method;\n                            console.log('Card saved for subscription:', savedPaymentMethodId);\n                        }\n                    }\n                } catch (siErr) {\n                    console.warn('SetupIntent error (non-fatal):', siErr);\n                }\n                submitBtn.textContent = \"Finalising order\u2026\";\n            }\n\n            const formData = new FormData(form);\n\n            const totalText  = document.getElementById(\"order-total\")?.textContent || \"Total: $0.00\";\n            const totalMatch = totalText.match(\/\\$([\\d.]+)\/);\n            const totalAmount = totalMatch ? parseFloat(totalMatch[1]) : 0;\n\n            if (window.selectedDeliveryFee > 0) {\n                formData.append(\"custom_delivery_fee\",    window.selectedDeliveryFee.toFixed(2));\n                formData.append(\"custom_delivery_option\", window.selectedDeliveryTitle);\n            }\n\n            formData.append(\"billing_first_name\", document.getElementById(\"billing_first_name\").value);\n            formData.append(\"billing_last_name\",  document.getElementById(\"billing_last_name\").value);\n            formData.append(\"billing_phone\",      document.getElementById(\"billing_phone\").value);\n            formData.append(\"billing_street\",     document.getElementById(\"billing_street\").value);\n            formData.append(\"billing_city\",       document.getElementById(\"billing_city\").value);\n            formData.append(\"billing_state\",      document.getElementById(\"billing_state\").value);\n            formData.append(\"billing_zip\",        document.getElementById(\"billing_zip\").value);\n            formData.append(\"action\",             \"csa_handle_form_submission\");\n            formData.append(\"payment_intent_id\",  paymentIntent.id);\n            formData.append(\"total_amount\",       totalAmount.toFixed(2));\n            \/\/ Send the prorated discount so the server can record it on the order\n            const proratedDiscount = parseFloat(\n                document.querySelector('#cart-totals .proration-discount-value')?.dataset.amount || '0'\n            );\n            if (proratedDiscount > 0) {\n                formData.append(\"proration_discount\", proratedDiscount.toFixed(2));\n            }\n            if (savedPaymentMethodId) {\n                formData.append(\"saved_payment_method_id\", savedPaymentMethodId);\n            }\n\n            const selectedPickupDay = document.querySelector('input[name=\"selected_pickup_day\"]:checked');\n            formData.append(\"pickup_day\", selectedPickupDay ? selectedPickupDay.value : \"Not Selected\");\n\n            if (paymentSelect && paymentSelect.value) {\n                formData.append(\"payment_plan\", paymentSelect.value);\n            } else {\n                alert(\"Please choose a payment plan.\");\n                submitBtn.disabled    = false;\n                submitBtn.textContent = \"Submit and Pay\";\n                return;\n            }\n\n            document.querySelectorAll('.csa-product').forEach(product => {\n                const id  = product.querySelector('.selected-product-id')?.value;\n                const qty = product.querySelector('.product-quantity')?.value;\n\n                if (id) {\n                    formData.append(\"products[]\",  id);\n                    formData.append(\"quantities[]\", qty);\n\n                    \/\/ Read product metadata from data-* attributes set directly by PHP.\n                    \/\/ The old nth-of-type selectors broke because renewal_frequency is\n                    \/\/ rendered as a <span>, not a <p>, causing \"undefined\" to be stored.\n                    const meta        = product.querySelector('.product-meta');\n                    const name        = product.querySelector('h3')?.textContent.split(\" - $\")[0].trim();\n                    const totalShares = meta?.dataset.totalShares || '';\n                    const renewalFreq = meta?.dataset.renewalFreq  || '';\n                    const startDate   = meta?.dataset.startDate    || '';\n\n                    formData.append(\"product_names[]\",               name);\n                    formData.append(\"product_total_shares[]\",        totalShares);\n                    formData.append(\"product_renewal_frequencies[]\", renewalFreq);\n                    formData.append(\"product_start_dates[]\",         startDate);\n                }\n            });\n\n            const submitResponse = await fetch(ajaxUrl, {\n                method: \"POST\",\n                body:   formData\n            });\n\n            const result = await submitResponse.json();\n\n            if (result.success) {\n                alert(\"Order placed successfully!\");\n                const pathSegments = window.location.pathname.split('\/');\n                const subsitePath  = pathSegments.length > 1 ? '\/' + pathSegments[1] : '';\n                const subsiteUrl   = window.location.origin + subsitePath;\n                const redirectUrl  = subsiteUrl + \"\/my-account\/csa-orders\";\n                window.location.href = result.redirect_url || redirectUrl;\n            } else {\n                alert(\"Order failed: \" + result.data);\n                submitBtn.disabled    = false;\n                submitBtn.textContent = \"Submit and Pay\";\n            }\n\n        } catch (error) {\n            console.error(\"Error during payment confirmation:\", error);\n            alert(\"An unexpected error occurred. Please try again later.\");\n            submitBtn.disabled    = false;\n            submitBtn.textContent = \"Submit and Pay\";\n        }\n    });\n\n    \/\/ Initialise totals on load\n    updateTotal();\n});\n\n    \/\/ \u2500\u2500 Auth Modal JS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    (function() {\n        const modal      = document.getElementById('csa-auth-modal');\n        const closeBtn   = document.getElementById('csa-auth-modal-close');\n        const tabs       = document.querySelectorAll('.csa-auth-tab');\n        const loginTab   = document.getElementById('csa-tab-login');\n        const regTab     = document.getElementById('csa-tab-register');\n        const authAjax   = \"https:\\\/\\\/farmtab.com\\\/growingdirtfarm\\\/wp-admin\\\/admin-ajax.php\";\n        const csaNonce   = \"78b17598cd\";\n\n        function openModal(tab) {\n            if (!modal) return;\n            modal.style.display = 'block';\n            document.body.style.overflow = 'hidden';\n            switchTab(tab || 'login');\n        }\n        function closeModal() {\n            if (!modal) return;\n            modal.style.display = 'none';\n            document.body.style.overflow = '';\n        }\n        function switchTab(name) {\n            tabs.forEach(t => {\n                const active = t.dataset.tab === name;\n                t.style.fontWeight   = active ? '600' : '400';\n                t.style.borderBottom = active ? '2px solid #333' : '2px solid transparent';\n            });\n            if (loginTab) loginTab.style.display = (name === 'login')    ? 'block' : 'none';\n            if (regTab)   regTab.style.display   = (name === 'register') ? 'block' : 'none';\n        }\n\n        document.getElementById('csa-open-login-modal')?.addEventListener('click',    () => openModal('login'));\n        document.getElementById('csa-open-register-modal')?.addEventListener('click', () => openModal('register'));\n        closeBtn?.addEventListener('click', closeModal);\n        modal?.addEventListener('click', e => { if (e.target === modal) closeModal(); });\n        document.addEventListener('keydown', e => { if (e.key === 'Escape') closeModal(); });\n        tabs.forEach(t => t.addEventListener('click', () => switchTab(t.dataset.tab)));\n\n        document.getElementById('csa-login-pass')?.addEventListener('keydown', e => {\n            if (e.key === 'Enter') document.getElementById('csa-login-btn')?.click();\n        });\n\n        document.getElementById('csa-login-btn')?.addEventListener('click', async function() {\n            const btn  = this;\n            const msg  = document.getElementById('csa-login-msg');\n            const user = document.getElementById('csa-login-user').value.trim();\n            const pass = document.getElementById('csa-login-pass').value;\n            msg.style.display = 'none';\n            if (!user || !pass) { msg.textContent='Please enter your username and password.'; msg.style.color='red'; msg.style.display='block'; return; }\n            btn.disabled=true; btn.textContent='Logging in\u2026';\n            const fd = new FormData();\n            fd.append('action','csa_ajax_login'); fd.append('nonce',csaNonce);\n            fd.append('log',user); fd.append('pwd',pass);\n            try {\n                const res  = await fetch(authAjax,{method:'POST',body:fd});\n                const data = await res.json();\n                if (data.success) {\n                    msg.style.color='green'; msg.textContent='Logged in! Reloading\u2026'; msg.style.display='block';\n                    setTimeout(()=>location.reload(),800);\n                } else {\n                    msg.style.color='red'; msg.textContent=data.data||'Login failed. Please try again.'; msg.style.display='block';\n                    btn.disabled=false; btn.textContent='Log In';\n                }\n            } catch(e) {\n                msg.style.color='red'; msg.textContent='An error occurred. Please try again.'; msg.style.display='block';\n                btn.disabled=false; btn.textContent='Log In';\n            }\n        });\n\n        document.getElementById('csa-register-btn')?.addEventListener('click', async function() {\n            const btn   = this;\n            const msg   = document.getElementById('csa-register-msg');\n            const first = document.getElementById('csa-reg-first').value.trim();\n            const last  = document.getElementById('csa-reg-last').value.trim();\n            const email = document.getElementById('csa-reg-email').value.trim();\n            const pass  = document.getElementById('csa-reg-pass').value;\n            msg.style.display='none';\n            if (!email||!pass) { msg.textContent='Email and password are required.'; msg.style.color='red'; msg.style.display='block'; return; }\n            btn.disabled=true; btn.textContent='Creating account\u2026';\n            const fd = new FormData();\n            fd.append('action','csa_ajax_register'); fd.append('nonce',csaNonce);\n            fd.append('first_name',first); fd.append('last_name',last);\n            fd.append('email',email); fd.append('password',pass);\n            try {\n                const res  = await fetch(authAjax,{method:'POST',body:fd});\n                const data = await res.json();\n                if (data.success) {\n                    msg.style.color='green'; msg.textContent='Account created! Logging you in\u2026'; msg.style.display='block';\n                    setTimeout(()=>location.reload(),1000);\n                } else {\n                    msg.style.color='red'; msg.textContent=data.data||'Registration failed. Please try again.'; msg.style.display='block';\n                    btn.disabled=false; btn.textContent='Create Account';\n                }\n            } catch(e) {\n                msg.style.color='red'; msg.textContent='An error occurred. Please try again.'; msg.style.display='block';\n                btn.disabled=false; btn.textContent='Create Account';\n            }\n        });\n    })();\n<\/script>\n<script src=\"https:\/\/maps.googleapis.com\/maps\/api\/js?key=AIzaSyCTt6H3axL0IZ7QpLfJTCVMrEMGCkUt_WI&libraries=places,geometry\" async defer><\/script>\n\n<script>\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n    let map;\n    let markers = [];\n    let userLocation = null;\n\n    \/\/ Haversine distance in miles between two {lat,lng} points (no API cost).\n    function haversineMiles(a, b) {\n        const toRad = deg => deg * Math.PI \/ 180;\n        const R = 3958.8; \/\/ Earth radius in miles\n        const dLat = toRad(b.lat - a.lat);\n        const dLng = toRad(b.lng - a.lng);\n        const lat1 = toRad(a.lat);\n        const lat2 = toRad(b.lat);\n        const h = Math.sin(dLat\/2)**2 + Math.cos(lat1)*Math.cos(lat2)*Math.sin(dLng\/2)**2;\n        return 2 * R * Math.asin(Math.sqrt(h));\n    }\n\n    function getLocationCards() {\n        return Array.from(document.querySelectorAll('.csa-loc-card'));\n    }\n\n    function initMap() {\n        const mapEl = document.getElementById('map');\n        if (mapEl) {\n            mapEl.style.position = 'relative';\n            mapEl.style.width    = '100%';\n            if (!mapEl.style.height) mapEl.style.height = '340px';\n            mapEl.style.overflow = 'hidden';\n        }\n        map = new google.maps.Map(document.getElementById(\"map\"), {\n            center: { lat: 40.7128, lng: -74.006 },\n            zoom: 8,\n        });\n        setTimeout(() => {\n            google.maps.event.trigger(map, 'resize');\n        }, 150);\n\n        const addressInput = document.getElementById(\"user-address\");\n        const autocomplete = new google.maps.places.Autocomplete(addressInput);\n        autocomplete.addListener(\"place_changed\", () => {\n            const place = autocomplete.getPlace();\n            if (!place.geometry) return;\n            userLocation = {\n                lat: place.geometry.location.lat(),\n                lng: place.geometry.location.lng()\n            };\n            map.setCenter(place.geometry.location);\n            addUserMarker(place.geometry.location);\n            updateDistances();\n        });\n\n        plotLocationMarkers();\n    }\n\n    function addUserMarker(position) {\n        new google.maps.Marker({\n            map,\n            position,\n            icon: { url: \"http:\/\/maps.google.com\/mapfiles\/ms\/icons\/blue-dot.png\" }\n        });\n    }\n\n    \/\/ Plot a marker for each location card using its stored lat\/lng.\n    function plotLocationMarkers() {\n        markers = [];\n        const bounds = new google.maps.LatLngBounds();\n        let plotted = 0;\n\n        getLocationCards().forEach(card => {\n            const lat = parseFloat(card.getAttribute(\"data-lat\"));\n            const lng = parseFloat(card.getAttribute(\"data-lng\"));\n            if (isNaN(lat) || isNaN(lng)) return;\n\n            const title = (card.querySelector('.csa-loc-card__name')||{}).textContent || '';\n            const position = { lat, lng };\n            const marker = new google.maps.Marker({ map, position, title });\n            const infoWindow = new google.maps.InfoWindow({\n                content: `<div class=\"map-label\">${title}<\/div>`\n            });\n            marker.addListener(\"click\", () => infoWindow.open(map, marker));\n            marker._locId = card.getAttribute(\"data-loc-id\");\n            markers.push(marker);\n            bounds.extend(position);\n            plotted++;\n        });\n\n        if (plotted > 1) map.fitBounds(bounds);\n        else if (plotted === 1) { map.setCenter(bounds.getCenter()); map.setZoom(11); }\n    }\n\n    \/\/ Compute \"Distance From\" for each card via haversine and sort cards.\n    function updateDistances() {\n        if (!userLocation) return;\n        const list = document.getElementById('csa-loc-list');\n        const cards = getLocationCards();\n        const withDistance = [];\n\n        cards.forEach(card => {\n            const lat = parseFloat(card.getAttribute(\"data-lat\"));\n            const lng = parseFloat(card.getAttribute(\"data-lng\"));\n            const badge = card.querySelector('.csa-loc-card__distance');\n            if (isNaN(lat) || isNaN(lng)) {\n                if (badge) badge.textContent = '';\n                withDistance.push({ card, dist: Number.POSITIVE_INFINITY });\n                return;\n            }\n            const miles = haversineMiles(userLocation, { lat, lng });\n            if (badge) badge.textContent = `${miles.toFixed(1)} mi away`;\n            withDistance.push({ card, dist: miles });\n        });\n\n        \/\/ Reorder the list nearest-first.\n        withDistance.sort((a, b) => a.dist - b.dist);\n        if (list) withDistance.forEach(item => list.appendChild(item.card));\n    }\n\n    window.addEventListener(\"load\", initMap);\n});\n<\/script>\n\n\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-csa-form.php","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-2109","page","type-page","status-publish","hentry"],"acf":{"enter_farm_name":"","enter_email":"","enter_website_url":"","enter_phone_number":"","enter_description":"","enter_featured_image":false,"enter_profile_image":false,"farmers_markets":["Not attending any markets"],"farmers_markets_hours":[],"farmers_markets_dates":[],"address_street":"Street","city":"City","state":"Alabama","zip_code":"Zip Code","monday_is_open":"","tuesday_is_open":"","wednesday_is_open":"","thursday_is_open":"","friday_is_open":"","saturday_is_open":"","sunday_is_open":"","monday_is_closed":"","tuesday_is_closed":"","wednesday_is_closed":"","thursday_is_closed":"","friday_is_closed":"","saturday_is_closed":"","sunday_is_closed":""},"ams_acf":[{"key":"enter_farm_name","value":""},{"key":"enter_email","value":""},{"key":"enter_website_url","value":""},{"key":"enter_phone_number","value":""},{"key":"enter_description","value":""},{"key":"enter_featured_image","value":false},{"key":"enter_profile_image","value":false},{"key":"farmers_markets","value":["Not attending any markets"]},{"key":"farmers_markets_hours","value":[]},{"key":"farmers_markets_dates","value":[]},{"key":"address_street","value":"Street"},{"key":"city","value":"City"},{"key":"state","value":"Alabama"},{"key":"zip_code","value":"Zip Code"},{"key":"monday_is_open","value":""},{"key":"tuesday_is_open","value":""},{"key":"wednesday_is_open","value":""},{"key":"thursday_is_open","value":""},{"key":"friday_is_open","value":""},{"key":"saturday_is_open","value":""},{"key":"sunday_is_open","value":""},{"key":"monday_is_closed","value":""},{"key":"tuesday_is_closed","value":""},{"key":"wednesday_is_closed","value":""},{"key":"thursday_is_closed","value":""},{"key":"friday_is_closed","value":""},{"key":"saturday_is_closed","value":""},{"key":"sunday_is_closed","value":""}],"_links":{"self":[{"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/pages\/2109","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/comments?post=2109"}],"version-history":[{"count":3,"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/pages\/2109\/revisions"}],"predecessor-version":[{"id":2305,"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/pages\/2109\/revisions\/2305"}],"wp:attachment":[{"href":"https:\/\/farmtab.com\/growingdirtfarm\/wp-json\/wp\/v2\/media?parent=2109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}