=== Freeze Shipping Alert and Global Hardiness Zones and Frost Data ===
Contributors: whatsmyzone
Tags: shipping, freeze, gardening, climate, protection
Requires at least: 6.0
Tested up to: 7.0
Stable tag: 3.7.2
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Protect freeze-sensitive WooCommerce shipments with climate lookups, forecast checks, and checkout protection options.

== Description ==
**Freeze Shipping Alert and Global Hardiness Zones and Frost Data** is a WooCommerce extension that combines the WhatsMy.Zone climate lookup service with live forecast and geocoding services to detect freeze risk for shipping addresses worldwide.

= Features =
* **Automatic Freeze Detection** - Detects freeze risk at checkout based on the customer's shipping address, estimated delivery window, and climate data.
* **Protection Products** - Offer one or more freeze-protection products at checkout and add them as real WooCommerce cart items.
* **Complimentary Protection Rules** - Automatically include configured protection products for free on risky shipments, with customer-facing included/unavailable notices.
* **Protected Shipping Recommendations** - Suggest one or more merchant-defined shipping options when those methods are safer during frost season.
* **Delivery Scheduling** - Customers can schedule later delivery when their area is safe from freezing, with an optional delayed-shipping discount.
* **Risk Acceptance** - Customers can acknowledge and accept freeze risk with a customizable disclaimer.
* **Worldwide Hardiness Zone Shortcodes** - Display hardiness zone, frost dates, and growing season information on any page.
* **Admin Weather Forecast** - Check current weather forecast data for an order's shipping address.
* **Admin Shipping Controls** - Configure shipping lead time, protection products, complimentary protection rules, recommended shipping labels, disclaimers, and delayed-shipping discounts.
* **Service-Backed Climate Lookups** - Zone, frost, growing-season, and shipping-risk lookups are provided through the WhatsMy.Zone service.
* **Global Coverage** - Worldwide climate lookups for supported destinations.
* **WooCommerce HPOS Compatible** - Works with both legacy and High-Performance Order Storage.

= Shortcodes =
* [freeze_alert_zone] - Interactive hardiness zone checker with search
* [freeze_alert_frost] - Last/first frost date cards
* [freeze_alert_season] - Growing season visualizer with month bar

= Data Sources =
* **Climate Lookups:** WhatsMy.Zone service for zone, frost date, growing-season, and shipping-risk lookups
* **Weather Forecast:** Open-Meteo API (free, no API key required)
* **Geocoding / Address Lookup:** Nominatim/OpenStreetMap

= WhatsMy.Zone Account and API Usage =
Freeze Alert uses a WhatsMy.Zone API key so this site can make authenticated climate lookups and show usage and plan details in the WordPress admin. Create or access an account at https://whatsmy.zone/account.html, copy an API key, and paste it into the plugin settings. The initial service plan is free and gives the site 100 WhatsMy.Zone API calls per month. If a site needs more calls, open the account dashboard from the plugin settings to upgrade the service plan.

WhatsMy.Zone API calls are used when Freeze Alert requests hardiness zone, frost date, growing-season, or shipping-risk data for a coordinate. This includes shortcode lookups, checkout freeze-risk checks, order/admin checks, and configured route exposure points when those features are used. Paid WhatsMy.Zone plans change only the service-side API usage limit; they do not unlock a separate premium version of the WordPress plugin.

== Installation ==
1. Upload the `freeze-alert` folder to `/wp-content/plugins/`
2. Activate the plugin through the 'Plugins' menu
3. Go to **Freeze Alert -> Settings** to configure sensitive products, protection options, checkout behavior, and your WhatsMy.Zone service connection
4. Go to **Freeze Alert -> Shortcodes** to review shortcode usage
5. Add shortcodes to your product pages as needed

== External services ==

Freeze Alert uses the following external service connections:
* WhatsMy.Zone: receives latitude/longitude coordinates for climate lookups (zone, frost dates, growing season, and shipping-risk checks). The plugin sends the saved API key in an `x-api-key` request header to authenticate climate lookups and retrieve live usage and plan details. The initial service plan is free and includes 100 API calls per month; upgrades are available only when a site needs a higher monthly service limit. Account creation, key management, and plan changes open the external WhatsMy.Zone account dashboard. Plan-selection links include the selected plan and billing cycle. The settings screen may also request a WhatsMy.Zone language-pack manifest, and installing a language pack downloads the selected JSON translation pack from WhatsMy.Zone. Service policies: https://whatsmy.zone/policies.html
* Open-Meteo: receives latitude/longitude coordinates to return weather forecast data used for shipping-date forecast checks. Terms and privacy: https://open-meteo.com/en/terms
* Nominatim / OpenStreetMap: receives either a location search query entered by the user, or shipping address fields needed for geocoding (street, city, state/region, postal code, country). Reverse-geocoding requests send latitude/longitude coordinates. Nominatim usage policy: https://operations.osmfoundation.org/policies/nominatim/ OpenStreetMap Foundation terms: https://osmfoundation.org/wiki/Terms_of_Use OpenStreetMap Foundation privacy policy: https://osmfoundation.org/wiki/Privacy_Policy

These services are external to the WordPress site and are contacted only when the related lookup, forecast, geocoding, account-dashboard, language-pack, or plan-selection action is requested.

== Frequently Asked Questions ==

= Does this require any special server software? =
No. The plugin works on any standard PHP hosting without additional dependencies.

= Does this plugin require WooCommerce? =
WooCommerce is required only for the checkout freeze-shipping features. The climate lookup shortcodes can be used on regular WordPress pages without WooCommerce.

= What external services does this use? =
See the external services section above for the complete list of services, transmitted data, and policy links.

= Does this plugin send data to external services? =
Yes. This plugin sends only the data needed for climate, forecast, geocoding, account-dashboard, language-pack, and plan-selection requests. See the external services section above for full details.

= What data is transmitted to each service? =
Freeze Alert sends only the data needed for the requested lookup:
* WhatsMy.Zone: coordinates for hardiness zone, frost date, growing-season, and shipping-risk lookups; API key in an `x-api-key` request header for lookup authentication and usage/plan checks; selected upgrade tier and billing cycle in account-dashboard links; language-pack manifest requests and selected JSON language-pack downloads.
* Open-Meteo: coordinates only.
* Nominatim / OpenStreetMap: location search text, shipping address components for geocoding, or coordinates for reverse geocoding.

= How does Freeze Alert protect stored credentials and diagnostic data? =
The stored WhatsMy.Zone API key is no longer rendered back into the settings page after saving, is sent to WhatsMy.Zone in an `x-api-key` request header instead of URL parameters, public lookup endpoints are rate-limited, and internal debug details are only returned to authorized WooCommerce managers when Debug Mode is enabled.

= Does this require a WhatsMy.Zone API key? =
Yes, for authenticated WhatsMy.Zone climate lookups. Create or access an account at https://whatsmy.zone/account.html, copy an API key, paste it into the plugin settings, and save. The free service plan includes 100 API calls per month. The API key identifies this site when Freeze Alert requests hardiness zone, frost date, growing-season, and shipping-risk data, and when the settings screen retrieves usage and plan details. Free and paid WhatsMy.Zone plans affect service call limits only.

= Are any plugin features hidden behind a premium plugin version? =
No. The WordPress plugin code shipped in this plugin is the same for all users. Paid WhatsMy.Zone plans change service-side API usage limits, not separate plugin code.

= Is this compatible with WooCommerce HPOS? =
Yes, full compatibility with both legacy and High-Performance Order Storage.

== Changelog ==

= 3.7.2 =
* Replace the retired self-service Unlimited service option with bounded Starter, Growth, and Business plans plus a negotiated Enterprise path.
* Keep existing saved WhatsMy.Zone API keys working while displaying the current service-side monthly quota accurately.

= 3.7.1 =
* Remove automatic WhatsMy.Zone account creation and reconnect requests from the plugin settings.
* Move API-key setup and plan management to the authenticated WhatsMy.Zone account dashboard.
* Send saved API keys in `x-api-key` request headers for climate lookups and live usage checks instead of URL query parameters.

= 3.7 =
* Keep Schedule Later Delivery available for long shipping windows by falling back to the next frost-safe season start when no full transit-length frost-free window exists.

= 3.6 =
* Stack the freeze-protection product action button below the product name in the checkout alert.

= 3.5 =
* Translate the new Freeze Alert functionality and checkout freeze-check admin headings across the external language packs.
* Keep saved default protected-shipping and risk-acceptance text localized when switching to another Freeze Alert language pack.
* Refresh default disclaimer translations with clearer horticultural and meteorological wording.

= 3.4 =
* Add a Settings shortcut to the plugin row on installed plugins screens.
* Clarify WhatsMy.Zone account connection, API-call usage, and the free 100-call monthly allowance in the settings screen and readme.
* Keep localized climate lookup cache entries separated by active language so frost-date month names do not carry over after switching language packs.
* Use the full Freeze Alert prefix for transient/cache keys and admin redirect parameters.
* Translate updated hardiness-zone shortcode labels and shortcode reference controls across the 3.4 language packs.
* Localize the frost-period month labels in shortcode widgets and cache-bust shortcode assets after file changes.

= 3.3 =
* Show the specific climate lookup failure reason in shortcode widgets, including account setup, API-key, rate-limit, and monthly-usage-limit messages returned by WhatsMy.Zone.
* Preserve upstream WhatsMy.Zone lookup errors in the plugin REST wrapper instead of replacing them with a generic no-data response.

= 3.2 =
* Fix shortcode frost-safe month bars for southern-hemisphere seasonal locations whose safe season crosses New Year.

= 3.1 =
* Load the Freeze Alert admin menu, settings screen, and shortcode reference on WordPress sites that do not have WooCommerce active.
* Keep WooCommerce-only checkout settings and order tools hidden unless WooCommerce is active.
* Remove the hard WooCommerce Select2 dependency from the admin script so shortcode admin tools work on non-WooCommerce sites.

= 3.0 =
* Rename the plugin to remove official-agency wording and use Global Hardiness Zones and Frost Data.
* Align package ownership metadata with the WhatsMy.Zone WordPress.org account.
* Add a dedicated external services section with transmitted data and policy links for WhatsMy.Zone, Open-Meteo, and Nominatim/OpenStreetMap.
* Update Tested up to to the WordPress.org major-version format.
* Add explicit settings sanitizers and move flagged inline admin CSS/JS into the enqueued admin assets.
* Clarify that public REST endpoints are intentionally public, read-only, and rate-limited.

= 2.7.6 =
* Fix first-time saving of week-based delayed-shipping discount thresholds so values like 4 weeks no longer become 28 weeks after saving
* Make week-based shipping timeframe sanitization safe during first-time option creation

= 2.7.5 =
* Harden public lookup and checkout AJAX endpoints with throttling and stricter request validation
* Stop exposing saved API keys, public lookup debug logs, and full checkout addresses in rendered pages, API responses, browser logs, and PHP debug logs
* Restrict language-pack downloads and checkout redirects to trusted HTTPS destinations
* Tighten cache cleanup SQL and reduce stored checkout/session identifiers to privacy-preserving hashes

= 2.7.4 =
* Treat Rare Occasional Seasonal Frosts as tropical/no-frost locations for shipping-risk behavior
* Treat Irregular Frosts as permafrost/all-risk locations with no reliable safe shipping date

= 2.7.3 =
* Add support for Irregular Frosts and Rare Occasional Seasonal Frosts from the WhatsMy.Zone frost taxonomy
* Avoid showing invalid frost dates or scheduled-delivery dates when a frost class has no reliable safe season

= 2.7.2 =
* Add a degree symbol to the forecast low in the historical frost warning and remove the year from the historical frost-season dates

= 2.7.1 =
* Fix the Swedish language pack so the new forecast-aware historical freeze warning messages display in Swedish instead of falling back to English

= 2.7.0 =
* Use the actual short-term forecast low in the historical frost warning copy, rounded to whole degrees and shown in Fahrenheit for US stores or Celsius elsewhere
* Show month names in the historical frost-window dates and update the forecast-safe protection recommendation wording
* Extend the forecast-aware historical freeze warning messages into the external language packs

= 2.2.26 =
* Remove the accidental bundled `langpacks` plugin-folder fallback and return language-pack sourcing to the external development directory plus remotely installed packs
* Keep the runtime mojibake repair in the language-pack loader so previously broken stored or remote pack text can still recover cleanly

= 2.2.25 =
* Repair mojibake at language-pack load time so existing stored or remote packs recover cleanly even if they were previously saved with broken UTF-8 text

= 2.2.24 =
* Rebuild the bundled language-pack package with restored UTF-8 metadata and translations so installed admin language packs no longer show mojibake

= 2.2.23 =
* Repair mojibake in bundled language-pack labels and translations caused by a bad encoding rewrite during the previous version bump

= 2.2.22 =
* Preserve scheduled delivery selections after checkout refreshes even when the currently selected shipping method already matches the protected-shipping recommendation
* Allow delayed-shipping discounts to be applied and validated for scheduled deliveries instead of silently suppressing them when protected shipping is also selected

= 2.2.21 =
* Keep Schedule Later Delivery open until the customer confirms a delivery date instead of collapsing on the initial selection refresh
* Refresh delayed-shipping totals through the correct classic or block checkout path so qualifying discounts can appear in the order summary

= 2.2.20 =
* Prefer bundled or local authoritative language packs over hosted copies when local source files are present
* Refresh checkout warning translations in external language packs and bump pack metadata for reinstalling updated locales

= 2.2.19 =
* Add Hungarian and Czech external language packs

= 2.2.18 =
* Add Bulgarian, Greek, and Croatian external language packs

= 2.2.17 =
* Add Danish, Polish, and Romanian external language packs

= 2.2.16 =
* Add Norwegian, Dutch, and Ukrainian external language packs

= 2.2.15 =
* Translate the settings-page Save Changes button through the language manager more directly
* Add Swedish and Finnish external language packs

= 2.2.14 =
* Preserve the active Freeze Alert language when the main settings form is saved
* Translate the settings-page Save Changes button through the external Freeze Alert language packs

= 2.2.13 =
* Add Korean and Vietnamese external language packs
* Add a settings-page note with the Freeze Alert email address for additional language requests

= 2.2.12 =
* Translate the Discover shipping options button and helper text across all external Freeze Alert language packs

= 2.2.11 =
* Refresh language-setting caches aggressively after install/activate/remove actions so newly installed packs can be activated reliably

= 2.2.10 =
* Hardened language-pack activation so the selected locale persists reliably after clicking Activate
* Added a post-activation verification step that shows a clear error notice if a pack cannot be marked active

= 2.2.9 =
* Expanded shipping-option discovery to probe multiple destination countries, including non-default shipping countries such as the US

= 2.2.8 =
* Improved shipping-option discovery to calculate package rates through WooCommerce and try multiple sample products/quantities
* Remove stale admin-discovered fallback labels before saving a fresh discovery run

= 2.2.7 =
* Added a Discover shipping options button to the settings page so the recommended-shipping selector can be populated on demand
* Improved admin asset cache-busting so new settings-page JavaScript loads immediately after updates

= 2.2.6 =
* Prefill the complimentary-protection and protected-shipping disclaimer fields with polished default copy
* Translate the new default protection/disclaimer text across all supported plugin languages

= 2.2.5 =
* Add Italian, Portuguese, and Turkish external language packs
* Order settings-page language cards more clearly, with installed packs ahead of uninstalled ones

= 2.2.4 =
* Fix leaked placeholder tokens in the Japanese checkout and admin language-pack strings

= 2.2.3 =
* Replace the language dropdown with direct Activate actions on compact language cards
* Add Japanese and Simplified Chinese external language packs alongside Spanish, French, and German

= 2.2.2 =
* Add French and German external language packs alongside Spanish
* Shorten the checkout panel title to "Freeze Alert" while keeping the longer plugin name elsewhere

= 2.2.1 =
* Add downloadable external language-pack support for Freeze Alert settings, frontend copy, shortcodes, and admin screens
* Move Spanish language-pack hosting and deployment outside the plugin bundle

= 2.1.36 =
* Show the connected WhatsMy.Zone account email on the shortcode-page hosted widget card when the account identity has synced
* Sync and store the connected WhatsMy.Zone account email alongside the API key identity data

= 2.1.35 =
* Move the optional WhatsMy.Zone hosted map widget reference into a more visible shortcode-page card after the built-in shortcode docs
* Clarify that the hosted widget uses the same connected WhatsMy.Zone account and API key as Freeze Alert

= 2.1.34 =
* Add placeholder WhatsMy.Zone privacy and terms links to the admin shortcode notice and service FAQ disclosure

= 2.1.33 =
* Add an admin-only note on the Shortcodes screen pointing users to the optional separate WhatsMy.Zone hosted map widget builder
* Clarify there that the external widget service is optional and not required for Freeze Alert functionality

= 2.1.32 =
* Remove the interactive map shortcode and its admin references from the plugin
* Keep the shortcode feature set focused on zone, frost-date, and growing-season widgets

= 2.1.31 =
* Switch the map shortcode to locally served basemap tiles from the WhatsMy.Zone tile package instead of loading CARTO tiles in visitors' browsers
* Require the installed map tile package to include the new basemap layers used for OpenStreetMap/OpenMapTiles attribution-compliant rendering

= 2.1.30 =
* Bundle Leaflet locally inside the plugin instead of loading it from a third-party CDN
* Update the readme data-source wording to reflect the bundled local map library

= 2.1.29 =
* Update the plugin description and readme to match the current WhatsMy.Zone-backed service architecture
* Clarify that paid WhatsMy.Zone plans affect service usage limits rather than shipping a separate premium plugin build
* Refresh installation and shortcode documentation to match the current admin screens

= 2.1.28 =
* Stop Reconnect Account from silently replacing a valid WhatsMyZone key with a newly created or lower-tier account
* Surface WhatsMyZone reconnect conflict errors clearly and explain when reconnect should actually be used

= 2.1.27 =
* Stop the WhatsMyZone settings page from auto-reconnecting to a different site-linked account when it renders
* Keep live plan and usage synced from the configured API key while leaving account replacement as an explicit reconnect action

= 2.1.26 =
* Re-sync the locally stored WhatsMy.Zone API key, user ID, and tier from the authoritative site account before rendering account settings
* Ensure WhatsMy.Zone upgrade actions target the refreshed connected account instead of a stale stored user ID

= 2.1.25 =
* Stop blank or edited route rows from preserving old hidden geocode data when settings are saved
* Clear route point hidden coordinates immediately when the visible route address is changed or emptied in admin

= 2.1.24 =
* Show when a route exposure point, not just the destination, is the source driving the latest safe shipping date at checkout
* Make the checkout warning and safe-date hint name the specific route point when it is setting the recommendation

= 2.1.23 =
* Base the recommended safe shipping date only on checkout points that are actually at freeze risk in the current delivery window
* Prevent non-risky route exposure points from lingering as a later safe date on destination-based checkout alerts

= 2.1.22 =
* Prefer the active checkout address fields instead of stale hidden shipping fields so Freeze Alert follows the destination the customer is actually editing
* Align checkout validation and saved order freeze data with the same active-address logic

= 2.1.21 =
* Recheck freeze risk immediately when checkout address details change so stale safe dates do not linger from a previous lookup
* Clear plugin lookup caches on upgrade so updated climate and geocode results are used right away

= 2.1.20 =
* Rebalance the WhatsMyZone upgrade panel styling so it feels more at home in WordPress admin while keeping the same tier cards and billing toggle

= 2.1.19 =
* Replace the basic WhatsMyZone upgrade selector on the settings page with account-style subscription cards and a monthly/yearly billing toggle
* Keep plan upgrades wired to the existing WhatsMyZone Stripe checkout flow while showing the current plan and live usage more clearly

= 2.1.18 =
* Make the order metabox forecast check target the riskiest saved point in the shipment path instead of always using the destination
* Save and display whether the customer accepted an even later weather-based shipping date for scheduled deliveries

= 2.1.17 =
* Preserve Freeze Alert order records from checkout session data when order creation cannot re-run the full address assessment
* Keep scheduled-delivery selections and saved ship dates on orders even when the order-save step must fall back to session assessment data

= 2.1.16 =
* Let Route Exposure Points trigger checkout assessment even when the destination address cannot be geocoded
* Improve checkout messaging for route-only assessment results

= 2.1.15 =
* Make Route Exposure Points participate in checkout freeze-risk assessment instead of only being stored in settings
* Show route-specific checkout messaging when a configured transit point is the source of freeze risk

= 2.1.14 =
* Move Debug Mode to the bottom of the settings page just above Save Changes
* Disable the assessed-countries selector when Freeze Alert is set to assess all shipping countries

= 2.1.13 =
* Show "Ship now" on the Freeze Alert orders page when an assessed order does not have a delayed shipping date

= 2.1.12 =
* Show accepted-risk selections again on the Freeze Alert orders page while keeping the accepted-risk stats tied to confirmed acceptance
* Add a warning note on the Freeze Alert orders page when checkout assessment is disabled in settings

= 2.1.11 =
* Preserve accepted-risk orders on the admin metabox by inferring the saved customer choice from a confirmed risk-acceptance checkbox when needed
* Show accepted-risk selections on the order metabox even when the saved choice value is missing but the acceptance state is present

= 2.1.10 =
* Count accepted-risk orders only when the customer actually checked the freeze-risk acceptance box
* Require the freeze-risk acceptance checkbox before checkout can complete with "Ship Now Anyway"

= 2.1.9 =
* Tighten the Freeze Alert orders dashboard stat cards so more of them fit on one row on wide screens
* Make Freeze-Sensitive Categories include products assigned through selected subcategories, not only direct category matches
* Add settings to assess all shipping countries, only selected countries, or all except selected countries

= 2.1.8 =
* Let the Freeze Alert orders stats cards size to their content so more cards fit on one row on wide screens
* Remove the temporary dashboard note beneath the orders-page intro

= 2.1.7 =
* Add richer Freeze Alert orders dashboard cards for assessed carts, risked orders, and checkout option usage
* Start tracking checkout assessments so abandoned carts can contribute to the dashboard stats going forward, and simplify the orders-page pagination links

= 2.1.6 =
* Make every column on the Freeze Alert orders admin page sortable and keep sort state while paging
* Add admin search for Freeze Alert orders by order number, customer name, and shipping address

= 2.1.5 =
* Ensure saved scheduled and admin shipping dates always render on Freeze Alert admin order summaries even when the site's WordPress date format setting is blank
* Keep the WooCommerce order metabox and the Freeze Alert orders page aligned on hold and shipping date display

= 2.1.4 =
* Make the Freeze Alert orders admin page query assessed orders correctly on both legacy order storage and HPOS, with safer assessment badges and improved date handling
* Clean up the Freeze Alert orders page layout by removing the unused placed-date column and fixing horizontal pagination

= 2.1.3 =
* Add a dedicated admin toggle for showing a checkout reason when protection products are not offered for the shipment
* Make the checkout protection-unavailable note work independently from the complimentary-protection toggle

= 2.1.2 =
* Remove the extra complimentary-protection shipping-timeframe rule and rely on the store's main shipping window setting instead
* Simplify the default complimentary-protection unavailable message

= 2.1.1 =
* Show the complimentary-protection unavailable reason on checkout even when no protection products are currently configured

= 2.1.0 =
* Add merchant controls for complimentary freeze protection, including automatic free inclusion and customer-facing included/unavailable notices

= 2.0.31 =
* Reconcile recommended-shipping visibility against the live checkout DOM so the alert behaves correctly for both single-option and multi-option shipping layouts

= 2.0.30 =
* Use visible checkout shipping methods as recommendation candidates so the recommended-shipping card still appears when the option is on the page but server-side available-rate matching falls short

= 2.0.29 =
* Detect recommended shipping from shipment-summary rows like "Shipment 1" and hide the recommendation card when no recommended shipping option is actually available

= 2.0.28 =
* Capture shipping labels from checkout summary rows when no shipping radios/selects are rendered, so single recommended methods are recognized as already selected

= 2.0.27 =
* Improve recommended-shipping matching so a single available recommended option is treated as already selected even with plugin-added prefixes like "Shipment 1"

= 2.0.26 =
* Replace broken customer-facing icon and checkmark text with clean UTF-safe checkout labels

= 2.0.25 =
* Remove UTF-8 BOM from PHP files touched in the previous update so checkout AJAX responses remain valid JSON

= 2.0.24 =
* Clarify checkout freeze-risk wording so it explicitly refers to the customer's delivery location

= 2.0.23 =
* Polish the later-delivery consent text to more natural English
* Update the readme to reflect the current hybrid data sources, protected shipping recommendations, delayed-shipping discounts, and real cart-based protection items
= 2.0.22 =
* Make the freeze-protection option wording more general and merchant-friendly, and update the later-delivery consent text
= 2.0.21 =
* Add stronger guidance in the freeze-protection option when two or more protection choices are available, recommending at least one or a combination of several
= 2.0.20 =
* Refresh the freeze alert when cart items are removed so stale protection coverage is cleared promptly
* Keep the protection session aligned with real WooCommerce cart contents when protection items are removed outside the alert
= 2.0.19 =
* Allow manually typing recommended shipping labels when no observed checkout labels are available yet
* Preserve observed checkout shipping labels across uninstall/reinstall so the selector can repopulate after future reinstalls
= 2.0.18 =
* Mirror protection cart removals back into the freeze alert by refreshing protection state from the real cart after checkout updates
= 2.0.17 =
* Persist protection cart-item changes before checkout redraw and trigger a WooCommerce fragment refresh so protection items appear immediately
= 2.0.16 =
* Treat a single visible protected shipping option on checkout as already covered even when WooCommerce has not marked it selected yet
= 2.0.15 =
* Treat the only available protected shipping method as already covered instead of asking the customer to select it again
* Switched freeze protection products from fee-style checkout add-ons to real WooCommerce cart items, with synced add/remove behavior
= 2.0.14 =
* Further reduced vertical spacing inside the schedule option to remove remaining dead space between lines and helper text
= 2.0.13 =
* Tightened vertical spacing in the recommended shipping and schedule option content
* Renamed the risk option to "Ship Now Anyway" and hide it when protected shipping or freeze protection is already in use
* Count protection products already selected in session or already present in cart so they are no longer re-offered
= 2.0.12 =
* Tightened line spacing for the recommended shipping and schedule option copy
* Kept Schedule Later Delivery open when the flexible-date checkbox is toggled by saving without forcing a totals refresh
* Synced protection product state from the WooCommerce session so already-selected protection items are not offered again after checkout refreshes
= 2.0.11 =
* Hide the recommended shipping option card when the currently selected shipping method already matches the protected label
* Keep Schedule Later Delivery open on first selection instead of immediately refreshing checkout
* Stop offering freeze protection products that are already present in the cart
= 2.0.10 =
* Reworded the protected-shipping confirmation to be more reassuring for recommended frost-season shipping
* Kept Schedule Later Delivery open on first selection by delaying checkout refresh until a ship date is chosen
* Added a green completed state to freeze options that are already in use
= 2.0.9 =
* Removed the non-functional Recommended badge from the protected shipping option card
* Switched protected-shipping matching to use the currently selected checkout shipping label as well as the rate ID, so the note updates more reliably
= 2.0.8 =
* Simplified protected-shipping checkout guidance to update the note based on whether the recommended shipping option is already selected
* Removed the one-click shipping switch from the freeze alert panel to keep the behavior reliable across third-party shipping UIs
= 2.0.7 =
* Improved one-click protected shipping selection by clicking the actual checkout shipping control and forcing a WooCommerce refresh afterward
* Added stronger fallback event dispatching for third-party shipping method UIs
= 2.0.6 =
* Added an optional protected-shipping disclaimer for admins and surfaced it on checkout when the customer selects a matching shipping option
* Compared the currently selected shipping label against recommended protected labels and added one-click switching to matching protected rates when needed
= 2.0.5 =
* Reduced recommended shipping selector choices to unique short labels such as carrier names only
* Normalized older saved shipping recommendation labels to the same short format without auto-selecting new defaults
= 2.0.4 =
* Replaced the single recommended shipping text field with a searchable multi-select based on observed live checkout labels
* Added support for recommending multiple shipping option labels at checkout and in saved order notes
= 2.0.3 =
* Shortened observed checkout rate labels to prefer cleaner customer-facing shipping names in debug output
* Trimmed trailing price and plugin marker details from captured shipping labels when possible
= 2.0.2 =
* Stopped forcing a full checkout refresh for freeze-option selections that do not affect totals, so the chosen option stays open more reliably
* Re-applied the saved panel state after WooCommerce finishes rebuilding checkout markup
= 2.0.1 =
* Preserve the selected checkout freeze option when WooCommerce refreshes checkout totals
* Simplified the freeze alert to keep the dates in the main sentence only, with bold date emphasis
= 2.0.0 =
* Added a visible delayed-shipping discount message to the checkout alert when the discount setting is active
* Improved checkout wording for the delivery window, safer shipping date, and recommended ship date display
= 1.9.0 =
* Simplified merchant-facing wording for the recommended shipping option
* Hid observed checkout rate diagnostics behind a new Debug Mode setting
= 1.8.0 =
* Switched protected shipping recommendation to a simple admin-entered option name instead of fragile shipping rate ID matching
* Continued showing observed live checkout rates only as a debug/reference list for choosing a customer-facing label
= 1.7.0 =
* Improved checkout DOM scraping for third-party shipping option labels
* Added an admin debug view showing the raw observed checkout shipping rates captured from live checkout
= 1.6.0 =
* Preserve observed live checkout shipping labels in the admin protected shipping selector instead of letting fallback WooCommerce zone labels overwrite them
= 1.5.0 =
* Capture actual checkout-visible shipping options through a dedicated sync so third-party rates appear in the protected shipping selector more reliably
* Refresh observed shipping rates when checkout shipping methods render or change, even before the freeze warning panel is used
= 1.4.0 =
* Added support for observed real checkout shipping rate labels alongside configured WooCommerce shipping methods
= 1.3.0 =
* Preserve WhatsMy.Zone account credentials across uninstall/reinstall on the same site
* Updated account connection UI to support reconnecting an existing site account
= 1.2.0 =
* Aligned plugin metadata and readme versioning for more reliable WordPress installs and upgrades
* Added protected shipping method support, including observed third-party checkout rates
* Added delayed-shipping discount settings and improved checkout protection flows
= 1.0.0 =
* Initial release
* WooCommerce checkout integration
* Shortcodes for zone, frost, season, and map
* Admin order weather forecast
* REST API endpoints

== Screenshots ==

1. Global hardiness zone search: [freeze_alert_zone] shortcode
2. Frost-free season length: [freeze_alert_season] shortcode
3. Frost dates for any location: [freeze_alert_frost] shortcode
4. Enable checkout checks and set the shipping window.
5. Select freeze-sensitive products and protection options.
6. Recommend better shipping options.
7. Schedule later, accept now, or evaluate route points.
8. Frontend checkout alert.
9. Action panel for risky orders.

== Upgrade Notice ==

= 3.7.2 =
Updates the WhatsMy.Zone service-plan display to bounded monthly tiers and a negotiated Enterprise path. Existing saved API keys continue to work.

= 3.7.1 =
Hardens WhatsMy.Zone authentication transport. Existing saved API keys keep working. New or replacement keys are copied from the WhatsMy.Zone account dashboard and pasted into plugin settings.

= 3.7 =
Keeps Schedule Later Delivery available for long shipping windows when the climate has a safe season but no full transit-length frost-free stretch.

= 3.6 =
Improves the checkout freeze-protection product layout by placing the Add to Order button below the product name.

= 3.5 =
Improves admin language-pack coverage and keeps saved default frost-risk disclaimer text localized when switching languages.

= 3.4 =
Adds a plugin-row Settings link and clearer WhatsMy.Zone account/API usage documentation, including the free 100-call monthly allowance.

= 3.3 =
Shortcode widgets now display the real WhatsMy.Zone lookup failure reason when account setup, API-key, rate-limit, or monthly usage issues block location data.

= 3.2 =
Fixes southern-hemisphere frost-safe month bars in shortcode widgets.

= 3.1 =
Admin menu and shortcode-reference support for WordPress sites without WooCommerce.
