=== WFY24 Weather Widget ===
Contributors: wfy24
Tags: weather, widget, forecast, embed, temperature
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 2.5.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Free, lightweight, embeddable weather widget for your WordPress site. One-click activation, 51 languages, auto location, light/dark theme.

== Description ==

WFY24 Weather Widget lets you embed a free, fully-featured weather widget on any WordPress site — in any post, page, or sidebar — with a single shortcode, Gutenberg block, or built-in sidebar widget.

= Zero-friction setup =

Activating the plugin opens **Settings → WFY24 Weather**, one screen with everything on it:

1. **Activate now (free)** — check the pre-filled admin email and your defaults (city, language, theme, units) and click once. The plugin registers your site with wfy24.com and the widget is live. No external signup, no copy/paste.
2. **Connect an existing WFY24 widget** — already have a key from an earlier install, from the wfy24.com widget builder, or from the main site of your Multisite? Paste it instead.
3. **Quick actions** on the dashboard — publish a "Weather" page with the widget ready to go, or add a compact widget to your first sidebar, each with one click.

= Features =

* **Free version** with a small wfy24.com attribution link under each widget — stated on the activation screen before you click Activate. No credit card, no hidden fees, no ads. A Pro plan that removes the link is in preparation ([Pro is coming — notify me](https://www.wfy24.com/en/widgets/pro))
* **Lightweight** — one small script, loaded asynchronously in the footer; nothing blocks your page
* **Real-time data** — temperature, conditions, wind, humidity, 5-day forecast
* **51 languages** — the widget defaults to your site language; pick any of the 51 per site or per widget
* **Admin interface in 15 locales** — the settings screen and activation form are translated into Bulgarian, Czech, Dutch, French, German (de_DE / de_AT / de_CH), Greek, Hungarian, Italian, Polish, Portuguese (pt_PT / pt_BR), Spanish and Swedish (strings added in 2.5.0 read in English until the catalogues are refreshed), and the activation link opens wfy24.com in your own language
* **Auto location** — pin a city, or leave it empty for the visitor's approximate location (IP-based, no prompt); precise location with the visitor's permission is an opt-in toggle
* **Light / Dark / Auto theme** — matches your site automatically
* **7 layouts** — Classic, Compact, Minimal, Badge, Forecast, Air Quality, Air Quality + Weather (wide)
* **Shadow DOM isolation** — zero CSS conflicts with your theme
* **Zero dependencies** — no jQuery, no React, no bloat
* **Multi-source data** — ICON-D2/EU/Global NWP with GFS fallback, blended with station observations

= Usage =

Shortcode:

`[wfy24_weather]`

Override per instance:

`[wfy24_weather city="paris-fr2988507" theme="dark" variant="forecast" lang="fr"]`

Or use the **WFY24 Weather Widget** block in the Gutenberg editor for a visual interface.

= Attribution =

The free version of this plugin displays a small attribution link — its visible text is `wfy24.com` — under each rendered widget. The activation screen says so above the "Activate now (free)" button: "By activating you agree to display a small attribution link (wfy24.com) under each widget"; clicking that button is your explicit permission to enable the link. A Pro plan that removes the attribution is in preparation; until it launches the plugin shows "Pro is coming — notify me" ([wfy24.com/en/widgets/pro](https://www.wfy24.com/en/widgets/pro)). Existing Pro subscriptions keep hiding the link.

= External service =

This plugin connects to the WFY24 weather service at `https://www.wfy24.com`:

* **Plugin activation**: POSTs to `/api/widget/register-from-plugin` with the email you confirmed in the activation form (pre-filled from Settings → General; editable inline before activation), site name, site domain, WordPress version, plugin version and site locale, in order to automatically provision your free API key. No activation happens without your explicit click on the "Activate now (free)" button. If wfy24.com already holds a widget for that email and domain, it answers with the first characters of the existing key and a replacement-key link; the plugin then shows the "Connect an existing WFY24 widget" form instead of creating a duplicate. Pasting a key into that form sends nothing.
* **City search** (admin only, when typing in the Default City field): the plugin's REST endpoint `/wp-json/wfy24/v1/cities` proxies your search query (e.g. "athens") to `/api/places/search` server-side. Your search query is sent along with a User-Agent identifying the plugin. Results (slug + label + country flag) are cached for 5 minutes per query. The admin's IP is never exposed cross-origin because the request is server-to-server.
* **Widget rendering** (client-side on visitor browsers): loads `widget.js` and queries `/api/widget/data`. The widget sends the API key, the city slug when one is set, and the language/units/theme preferences. Location: with a default city set, that city is shown and no visitor location is used. With no default city and the "Auto-detect visitor location" toggle off (the default), the widget shows the weather for the visitor's approximate location derived from the IP address of the request — no browser prompt, no coordinates. With the toggle on, the browser asks the visitor for permission; if granted, the visitor's latitude/longitude is sent, otherwise the IP-based location is used. No personal data is stored beyond standard anonymized request logs for rate limiting.
* **Pro status** (admin pages only): once an hour, on an admin page load, the plugin GETs `/api/widget/pro/status` with the first characters of the key to learn whether the key is on the Pro plan (this is what hides the attribution link for Pro sites). After a failed request it waits an hour before trying again.
* **Pro checkout / billing portal** (only if the admin clicks "Upgrade now" or "Manage subscription", and only while Pro is available): POSTs to `/api/widget/pro/checkout` and `/api/widget/pro/portal` — the portal request carries the site's full key — to open a Stripe Checkout or Stripe Billing Portal session. While Pro is parked (the default in this version) the upgrade button is not shown and the checkout handler refuses to run; site owners who want the checkout can define `WFY24_PRO_ENABLED` as `true` in `wp-config.php`.

Links:

* WFY24 Terms of Service: [https://www.wfy24.com/en/terms](https://www.wfy24.com/en/terms)
* WFY24 Privacy Policy: [https://www.wfy24.com/en/privacy-policy](https://www.wfy24.com/en/privacy-policy)

== Installation ==

1. Upload the plugin to `/wp-content/plugins/wfy24-weather-widget/`, or install via Plugins → Add New.
2. Activate the plugin via the Plugins menu.
3. **Settings → WFY24 Weather** opens automatically. Check the pre-filled email and your defaults, click **Activate now (free)**. Done — then use the quick actions (Create Weather page, Add to sidebar) or add `[wfy24_weather]` anywhere.

If you already have a key (an earlier install of this plugin, the [wfy24.com widget builder](https://www.wfy24.com/en/widgets), or the main site of a sub-directory Multisite):

1. Go to **Settings → WFY24 Weather**.
2. Open **Connect an existing WFY24 widget** and paste the key (it looks like `wfy24_` followed by 32 letters and digits). A value of any other shape is rejected and nothing is changed.
3. Add `[wfy24_weather]` to any post, page, or widget area.

== Multisite Support ==

The plugin is multisite-compatible. All settings (API key, defaults, page) are stored per-subsite using `get_option()`/`add_option()`, so each subsite operates independently.

* **Network Activation does not contact wfy24.com.** It only loads the plugin code on every subsite. No `admin_email` is sent, no API key is created, no automatic phone-home occurs.
* **Each subsite admin activates individually.** When the admin opens Settings → WFY24 Weather on a subsite and clicks "Activate now (free)", the plugin sends *that subsite's* domain and `Settings → General → Email Address` to wfy24.com to obtain a domain-bound API key. The admin is shown a dynamic disclosure of the exact values that will be transmitted before clicking — no consent is collected on behalf of admins of other subsites.
* **New subsites added later remain inactive** until their admin activates them. The widget will not render on a subsite that has not been activated or connected; no data leaves WordPress until an admin explicitly clicks Activate on that subsite.
* **No centralized network admin panel** exists in this version — each subsite has its own settings page. A network-level overview is on the roadmap.
* **API keys are domain-bound.** A key issued for `site-a.example.com` will not function on `site-b.example.com`, which means subdomain and domain-mapped multisite installs work correctly out of the box (each subsite gets its own key for its own domain).
* **Sub-directory installs share one host.** On `example.com/site-a`, `example.com/site-b` … every subsite reports the same domain, `example.com`, so wfy24.com sees one site. Activate the main site normally; on each further subsite open **Connect an existing WFY24 widget** and paste the main site's key (the main site shows it under Settings → WFY24 Weather → Advanced). A second "Activate" with the same email on the same host is answered with "already registered" and the connect form, not a second key.

== Frequently Asked Questions ==

= Is it really free? =

Yes. No credit card, no trial, no ads in the widget. Fair-use rate limits apply (plenty for normal sites).

= Do I need to create an account manually? =

No. The plugin registers your site automatically on activation using your WordPress admin email. If you already have a key — from an earlier install, from the wfy24.com widget builder, or from another subsite — paste it into **Connect an existing WFY24 widget** on the same screen.

= Can I revoke / change my key later? =

Yes — visit [wfy24.com/en/widgets](https://www.wfy24.com/en/widgets) to manage keys (the "Lost it? request a replacement" link on the activation screen takes you to the same place). A replacement key issued there must be pasted into **Connect an existing WFY24 widget** in this plugin; the old key stops working within about 30 minutes.

= What data is sent to wfy24.com? =

Minimal. See the "External service" section above. The plugin only contacts wfy24.com on actions you explicitly trigger (activation click, widget rendering on visitor pages, Pro upgrade click). There is no background telemetry, no scheduled cron, and no analytics.

= Can I customize the look? =

The widget uses Shadow DOM for style isolation, so it won't clash with your theme. Choose from 7 layouts (Classic, Compact, Minimal, Badge, Forecast, Air Quality, Air Quality + Weather wide) and 3 themes (Auto, Light, Dark).

= What languages are supported? =

51 languages. The site default follows your WordPress site language (choose another in Settings → WFY24 Weather); set the `lang` attribute on a shortcode or block to override it per widget with any of the 51 ISO 2-letter codes.

= How do I find a city slug? =

Go to [wfy24.com](https://www.wfy24.com), search for your city, and copy the slug from the URL (e.g. `paris-fr2988507`).

= Does it work with caching plugins? =

Yes. The widget loads client-side, so full-page cache has no impact on weather freshness.

= Does it work with Gutenberg / block editor? =

Yes — we ship a "WFY24 Weather Widget" block under the Widgets category.

= What data sources does WFY24 use? =

WFY24 combines multiple NWP models (DWD ICON-D2, ICON-EU, ICON-Global, GFS fallback) with real observations from 19,000+ weather stations (METAR, SYNOP, CWOP, DWD, etc.). Air quality comes from the Copernicus Atmosphere Monitoring Service (CAMS).

= Is there an attribution / "powered by" link? =

Yes. The free version of this plugin displays a small link with the text `wfy24.com` under each rendered widget. This is stated explicitly on the activation screen, above the "Activate now (free)" button; clicking "Activate" is your explicit consent. The link is how we keep the service free for everyone.

= Can I remove the wfy24.com link? =

Not yet. A Pro plan that removes it is in preparation — the plugin shows "Pro is coming — notify me" ([wfy24.com/en/widgets/pro](https://www.wfy24.com/en/widgets/pro)) until it launches. Sites that already have a Pro subscription keep it, and their widgets keep rendering without the link.

== Screenshots ==

1. The welcome screen after activation — live widget preview and the activation status
2. The welcome screen on first open — "Activate now (free)" or enter a key manually
3. Classic widget layout rendered on a live WordPress page

== Changelog ==

= 2.5.0 =
* **Connect an existing WFY24 widget.** The activation screen gains a second form: paste a key you already have (from an earlier install of this plugin, from the wfy24.com widget builder, or from the main site of a sub-directory Multisite) and the dashboard opens at once. The key's shape is checked in the browser and again before saving; a malformed value is rejected and nothing changes. "I have a key — enter manually" now opens this form instead of leaving the site.
* **Re-activation no longer dead-ends.** When wfy24.com already has a widget for this site and email, the plugin says so, shows the first characters of that key, opens the connect form and links to the replacement-key page — instead of printing "Could not activate".
* **Widget language follows your site.** New installs and the activation form default to the WordPress site language (a German site gets a German widget) instead of English. Saved settings are untouched.
* **Armenian.** The language list now matches the 51 languages the widget speaks.
* **No more "Enable location" box on a fresh install.** With no default city and visitor geolocation off, the widget shows the weather for the visitor's approximate (IP-based) location, without a browser prompt. Turn on "Auto-detect visitor location" only if you want the browser's precise location with the visitor's permission; set a default city to pin one place.
* **Structured data names the place.** The JSON-LD `name` and `description` use the resolved place name ("Weather forecast for Paris"), never the city slug.
* **Attribution stated on the activation screen again** (it had dropped out of the unified screen in 2.0.0): the free widget shows a small wfy24.com link, and the screen says so above the Activate button.
* **Pro is parked until launch.** The upgrade button, price and feature list are hidden; a "Pro is coming — notify me" link takes their place (site owners can define `WFY24_PRO_ENABLED` as `true` in wp-config.php to show the checkout). Existing Pro subscriptions keep working. Checkout and portal failures are now shown as admin notices instead of failing silently, the hourly status check backs off for an hour after a failed request instead of retrying on every admin page load, and the billing-portal request identifies the site with its full key.
* **Activation is stricter about what it stores.** An activation answer without a valid key is reported as an error and is never saved as an empty key.
* Readme: the descriptions of the removed 1.x wizard, the "6.6 KB" size figure and the "ML post-processing" claim are gone; screenshot captions match the images; sub-directory Multisite is documented.

= 2.4.0 =
* **Admin interface in 15 locales.** Adds Bulgarian, Czech, Dutch, French, Greek, Hungarian, Italian, Polish, Portuguese (European and Brazilian), Spanish and Swedish to the German set. Each one uses its own WordPress core admin vocabulary rather than a literal translation — Apparence → Widgets, Vzhled → Widgety, Външен вид → Джаджи — because that is what the person reading the screen already knows.
* Separate European and Brazilian Portuguese, for the same reason the German set is split three ways: WordPress does not fall back between regional variants, and definições/configurações, guardar/salvar and ecrã/tela are different words in exactly the vocabulary an admin screen uses.
* Tested up to WordPress 7.1.

= 2.3.0 =
* **German admin interface** — settings screen, setup wizard and all notices translated, with separate files for Germany (de_DE), Austria (de_AT) and Switzerland (de_CH). WordPress does not fall back from de_AT or de_CH to de_DE, so a site set to "Deutsch (Österreich)" or "Deutsch (Schweiz)" would otherwise have stayed in English; de_CH uses ss for the eszett throughout.
* **Activation link now opens in your own language.** The "activate" and "manage keys" buttons pointed at the English page for every site in every language; they now follow your WordPress admin language to the matching wfy24.com page, falling back to English for languages the widget does not speak.
* Translation template rebuilt from source: it covered 44 strings, 22 of which no longer existed in the plugin, against 98 strings actually in the code. Anyone translating from the old template was working from a file that was 22% complete and partly fictional.

= 2.2.0 =
* Completely redesigned widget: crisp SVG icons (no more emoji), condition-tinted accents, temperature range bars in the 5-day forecast, stat meters, and a refreshed light/dark look.
* Country names now localized in all 50 languages (was: always Greek).
* 5-day forecast (was 3), correct day/night icons worldwide, per-place local noon for daily icons.
* Full right-to-left layout for Arabic, Hebrew, Farsi and Urdu.
* Accessibility: reduced-motion support, screen-reader labels, WCAG AA contrast throughout.
* Imperial mode now converts precipitation (in/h) as well.
* Faster and lighter on the host page: no more page-wide DOM observers, refreshes pause in background tabs, geolocation resolved once per page view.
* Block editor: width control now cache-busts correctly; admin live preview reflects width and Pro attribution.

= 2.1.1 =
* **Fixed: aqi-wide live preview crushed in the 360px sticky sidebar.** When the saved/selected variant is `aqi-wide`, the settings-page preview now breaks out of the right-hand sidebar and renders in a full-width row above the form, so the horizontal weather + AQI bar has room to show its actual layout. On the published page nothing changes — the variant has always rendered correctly when given content-width room.

= 2.1.0 =
* **NEW: Wide AQI variant (weather + air quality side-by-side).** A new `variant="aqi-wide"` style places the location, current weather (icon, temperature, conditions, feels-like, daily high/low) on the left and a horizontal European-AQI bar (0–100+) with category label on the right. Designed for embeds that span the full content width, where the compact AQI card looks too narrow.
* **NEW: User-controlled width.** All variants now accept a `width` attribute — `[wfy24_weather variant="aqi-wide" width="800px"]` or `width="100%"`. Accepts `400`, `400px`, `80%`, `100%`; invalid values are dropped silently. Set a site-wide default in *Settings → WFY24 Weather Widget → Default width* or override per shortcode / Gutenberg block. Empty value keeps each variant's built-in default.
* Tested up to WordPress 7.0.

= 2.0.2 =
* **Fixed: Badge variant truncated text mid-word.** The badge layout has `overflow:hidden` and `white-space:nowrap`, but the segments inside didn't carry `data-fit-priority` hints — so when the embed sat in a narrow column (e.g. the admin's live-preview sidebar) the fit observer didn't know which parts to hide and the "Powered by WFY24" link was clipped mid-letter. Now the powered-by link, the description, the "Feels like" segment, and their dividers each have priorities; the observer hides them cleanly in priority order until everything fits.
* **Fixed: "Add to sidebar" quick action shown for block-based themes.** On themes like Twenty Twenty-Three that register no classic sidebars, the action would always end in "Could not auto-add to sidebar — please add the widget manually from Appearance → Widgets". The button is now hidden on block-theme installs and replaced with a short note pointing to the Site Editor and the shortcode option.
* **Requires PHP 8.1 (was 7.4).** PHP 7.4 reached end-of-life in November 2022 and is no longer receiving security patches. 8.1 is the lowest version Plugin Check / WordPress.org still recommends.

= 2.0.1 =
* **Fixed: AQI variant chips unreadable in dark theme.** The pollutant chips (PM2.5, PM10, O₃, NO₂) were using a translucent overlay that resolved to near-invisible against the dark theme's navy backdrop, leaving the value text floating on what looked like the bare widget bg. The chip background, text, and border now use solid theme-aware colors (slate-700 on navy in dark, white on pale-blue in light), and the chip text reads from a dedicated set of CSS variables that stay legible regardless of the cascade.
* Version bump also serves as a Cloudflare-cache buster — the `?ver=2.0.0` query had been cached on the CDN with the original 2.0.0 bundle, so even after the widget.js fix landed on the origin, sites embedding the script kept loading the stale copy. `?ver=2.0.1` is a fresh cache key.

= 2.0.0 =
* **NEW: Air Quality (AQI) widget variant.** A new `variant="aqi"` style renders European-AQI air quality for the configured city — the big AQI index number, category band (good through hazardous, color-coded per the EEA scale), and the four headline pollutants (PM2.5, PM10, O₃, NO₂). Data comes from the Copernicus Atmosphere Monitoring Service (CAMS) via wfy24.com. Pick it from the "Style variant" dropdown in settings, or set it inline with `[wfy24_weather variant="aqi"]`.
* **Premium admin redesign.** The plugin's two separate admin screens — the onboarding wizard and the settings page — have been merged into a single unified screen at *Settings → WFY24 Weather Widget*. New 2-column layout with a sticky live preview on the right plus inline quick actions (create Weather page, add to sidebar) so you never need to leave the page to set up an embed. The old `wfy24-welcome` URL still works — it now redirects to the unified screen.
* **Re-organized settings.** Essentials (city, language, theme, units, style) are upfront; visitor location, SEO JSON-LD, and the API key sit in a collapsible Advanced panel.
* **Embed snippet card** with one-click copy-to-clipboard.
* **Removed: multi-city (`cities="..."`).** The v1.7.x multi-city feature is removed in this major release — the implementation needed a dedicated admin picker UI to be discoverable, and the new unified layout focuses on the most common single-city flow. If you had multi-city enabled, your shortcodes without `cities=` now fall back to your Default City; explicit `[wfy24_weather cities="..."]` shortcodes will only render the first city. The `wfy24_default_cities` option is preserved on update so no data is lost in case the feature returns later.
* `widget.js` is unchanged, so every existing shortcode and Gutenberg block in published posts continues to render exactly as before.

= 1.6.0 =
* **NEW: Schema.org JSON-LD output.** Each widget instance now emits a server-rendered `WebPageElement` block describing the city (as `Place`), language, units, and provider. Helps search engines and AI agents understand that the page contains a weather forecast for a specific location — useful for semantic search, AI overviews, and future rich-result eligibility. Toggle from the settings screen (on by default).
* **Canonical URLs + localized names.** The JSON-LD resolves each shortcode's city against the wfy24.com search API on the server side, so the emitted `url` is the real canonical (e.g. `https://www.wfy24.com/el/weather/thessaloniki-gr57554537`) and the `Place.name` uses the language-correct form pulled from the translations table (`İstanbul` for `tr`, `Θεσσαλονίκη` for `el`, etc.). Cached in a WP transient for 24h on hit, 5min on miss — first page load makes one upstream call, all subsequent renders are cache hits.
* Filter hooks for third-party customization: `wfy24_jsonld_enabled` (per-widget on/off) and `wfy24_jsonld_data` (modify the payload before emission).
* No change to the visual widget — `widget.js` is unchanged. Existing shortcodes and blocks render exactly as before with the new JSON-LD appended.

= 1.5.6 =
* **Language combobox: clicking the field now shows all 50 languages, not just the saved selection.** Previously, focusing the field with "English" already saved would self-match the filter and the dropdown would only show the single English entry — useless for switching language. Now the picker detects when the input value equals an existing language's native or English name (i.e. the saved selection) and shows the full list so you can browse.
* Both city and language inputs now select-all on focus, so typing immediately replaces the saved value instead of appending to it.
* Removed the 12-item / 20-item slicing on the language list — the dropdown is scrollable, all 50 are now reachable.

= 1.5.5 =
* **Fixed: city and language suggestion dropdowns never opened.** The combobox stylesheet sets `display: none` as the default state for the suggestion list; the JavaScript was clearing the inline override (`element.style.display = ''`) which fell back to that CSS default — so the dropdown was always hidden, even though the REST proxy was returning matches and no console errors were thrown. Now sets `display: block` explicitly. Affects both the Default City picker and the Language combobox on the settings and onboarding screens.

= 1.5.4 =
* **City picker UX matches the public wfy24.com search.** The Default City dropdown now renders each result as a two-line item — country flag, bold place name, and a grey secondary line with region + country (e.g. "Athens" / "Attica, Greece") — instead of a single concatenated label. The picker also forwards the admin's locale to the upstream search so localized place names are returned.
* **Keyboard navigation in the city picker.** ↑ / ↓ to move through results, Enter to select, Escape to close — same shortcuts as the public site's search dialog. Hovered and keyboard-active items share a single highlight state.
* Internal: `/wp-json/wfy24/v1/cities` now returns structured fields (`slug`, `name`, `country_code`, `country_name`, `flag`, `region`) instead of a single pre-formatted `label`. Cache key includes the locale so per-language responses don't collide.

= 1.5.3 =
* **Onboarding overhaul.** Step 1 is now a complete configuration form — admin email (editable inline; no need to leave the wizard for Settings → General), default city (autocomplete search backed by wfy24.com places API), language (searchable combobox with all 50 supported languages shown in their native script and English name), theme, units, and a visitor-geolocation toggle — all set in one place before activation. Click Activate and the widget is live with your exact configuration.
* **Visitor geolocation is now off by default.** Previously the widget would call `navigator.geolocation` whenever no default city was set, which triggered a browser permission prompt on every visitor and silently broke when declined. Auto-detect is now an explicit opt-in checkbox; the default is to honour the admin-set city, which matches what 95%+ of sites actually want (e.g. a tourism site for Crete shouldn't show a Swedish visitor's local weather).
* **City picker.** Type a city name and pick from results (slug + flag + country) instead of needing to know the wfy24.com slug format. Powered by a server-side proxy (`/wp-json/wfy24/v1/cities`) so the admin's IP is never exposed cross-origin.
* **Language combobox.** All 50 supported languages now appear in a searchable dropdown with native + English names; type-ahead filters by either. The free-text 2-letter code input is gone.
* **Stronger Pro pitch.** The free-version notice now lists the full Pro feature set inline (no attribution, higher rate limits, priority support, custom CSS via theme tokens, historical data + analytics) instead of just "removes the link."
* **Sticky settings access.** A "Open plugin settings" button is now pinned on the onboarding screen, and a "Skip onboarding" link routes admins straight to Settings if they prefer to configure manually.
* **CORP header on widget.js + /api/widget/.** The hosted bundle now ships `Cross-Origin-Resource-Policy: cross-origin`, which makes the widget work in cross-origin-isolated environments (e.g. playground.wordpress.net) that ship `Cross-Origin-Embedder-Policy: require-corp`.

= 1.5.2 =
* **Activation transparency.** The onboarding wizard now displays an explicit, dynamic disclosure listing exactly what is sent to wfy24.com on click — the site domain, the administrator email currently configured in Settings → General (rendered live so the admin sees their own email before consenting), the site name, the WordPress version, the plugin version, and the locale. No visitor data is collected. Admins who want to register with a different email are pointed to Settings → General and asked to change it before clicking Activate.
* Documented multisite behaviour explicitly: per-subsite onboarding, no automatic phone-home on Network Activation, domain-bound API key per subsite. See the new "Multisite Support" section.

= 1.5.1 =
* Plugin Check compliance — replaced two `wp_redirect()` calls in the Pro flow (Stripe Checkout and Billing Portal) with `wp_safe_redirect()` plus a scoped `allowed_redirect_hosts` filter that whitelists `checkout.stripe.com`, `billing.stripe.com`, and `pay.stripe.com`. The redirect helper validates the target host against this list before issuing the redirect, falling back to a safe admin URL on mismatch.
* Tightened the readme upgrade notice for 1.5.0 to fit the 300-character limit.
* Cleaned up readme: the "External service" section and FAQ no longer reference the daily telemetry ping (removed in 1.4.0) — the plugin makes no scheduled outbound calls.

= 1.5.0 =
* **WP.org compliance: replaced inline `<script>` tags with `wp_enqueue_script`.** All three call sites — the `[wfy24_weather]` shortcode, the admin-settings live preview, and the onboarding wizard preview — now register the widget bundle through WordPress's enqueue API and emit a `<div data-wfy24-widget …>` placeholder where the widget should render.
* The hosted widget bundle (widget.js) gained a third mount mode: it scans the DOM for `[data-wfy24-widget]` elements and renders inside the placeholder you mark, so WordPress hosts can keep the script in the page footer (per directory guidelines) without breaking in-place rendering. The legacy inline-`<script>` pattern still works unchanged for non-WordPress integrations.
* Added the WordPress 6.3 `strategy => 'async'` enqueue option.

= 1.4.0 =
* **Removed the opt-in telemetry ping** in line with the WordPress.org Plugin Directory guidelines on phoning home. The plugin no longer schedules a daily WP-Cron event and no longer sends domain / WordPress version / plugin version to wfy24.com. The `Telemetry` checkbox has been removed from the Settings page. Existing scheduled events are cleared on upgrade and on deactivation.
* The Settings page no longer shows monthly request counts on the connection card (these were populated by the removed telemetry response). The card still shows the API key prefix.
* No change to the widget itself or to the Pro flow. All remaining external HTTP calls (one-shot site registration, Pro status, Stripe checkout/portal) are part of the service the plugin exposes and only run in response to an explicit user action.

= 1.2.0 =
* **Pro tier.** Added a Pro section to the plugin Settings page. One-click upgrade opens a Stripe Checkout session (€9/month); on successful payment the plugin is notified via webhook and the widget suppresses the "Weather by WFY24" attribution link. Existing Pro users see their renewal date and a "Manage subscription" button that opens the Stripe Billing Portal (update card, cancel, download invoices). Secure checkout via Stripe, cancel anytime.
* The shortcode now reads the Pro status from a plugin option (refreshed hourly via /api/widget/pro/status) and passes `data-attribution="0"` or `"1"` to widget.js accordingly.
* Added "Upgrade to Pro" actions on the Settings page. No behavior change for free-tier users — the attribution remains required on free.

= 1.1.2 =
* Attribution compliance: the free version now displays an explicit disclosure notice in the onboarding wizard before activation explaining that the "Weather by WFY24" link will appear under each widget. User consent is captured via the "Activate now (free)" button click. Added FAQ entries explaining the attribution, the Pro upgrade path, and external service behavior. The widget script now respects a `data-attribution` attribute (hardcoded to "1" in the free plugin; Pro version sends "0" to suppress the link).

= 1.1.1 =
* Plugin Check compliance: added translators comments, ordered placeholders (%1$s/%2$s), escaped block wrapper attributes, prefixed globals with wfy24_, removed load_plugin_textdomain (auto-loaded since WP 4.6), added nonce / enqueue justifications where required by the widget's embed pattern.

= 1.1.0 =
* **Zero-friction onboarding** — welcome wizard auto-registers your site with wfy24.com on activation (no copy/paste)
* **One-click Weather page creation** — publish a "Weather" page with the widget ready to go
* **One-click sidebar integration** — inject a compact widget into your first sidebar widget area
* **Connection status** — Settings page now shows key status and monthly request count
* **Opt-in telemetry** — daily anonymous ping so your wfy24.com dashboard shows active installs
* Improved readme disclosure for external services

= 1.0.0 =
* Initial release
* Shortcode `[wfy24_weather]` with city, theme, lang, units, variant attributes
* Gutenberg block under Widgets category
* Settings page for defaults (API key, city, theme, units, language, variant)
* Support for 50 languages and 5 layouts

== Upgrade Notice ==

= 2.5.0 =
Paste-your-key form and a clear message when the site is already registered; widget language defaults to your site language; Armenian added (51); fresh installs show IP-based local weather instead of an error box; Pro upgrade parked until launch. Existing settings unchanged.

= 2.4.0 =
The admin interface is now translated into 15 locales and the plugin is tested against WordPress 7.1. No settings changes needed.

= 2.3.0 =
German admin interface (de_DE / de_AT / de_CH) and the activation link now opens wfy24.com in your own language. No settings changes needed.

= 2.2.0 =
Major visual redesign, localized country names in all 50 languages, RTL support, 5-day forecast and accessibility fixes. No settings changes needed.

= 2.1.0 =
Adds a new wide AQI variant (weather + air quality side-by-side) and a `width` attribute on every shortcode/block. Existing embeds keep their previous look — opt in via `variant="aqi-wide"` and/or `width="800px"`. Confirmed compatible with WordPress 7.0.

= 1.5.3 =
Onboarding now configures everything in one form (email, city autocomplete, language combobox, theme, units, geolocation). Visitor-geolocation is off by default — no more surprise browser permission prompts. Stronger Pro feature list. Existing installs keep their settings.

= 1.5.2 =
Onboarding wizard now shows a dynamic disclosure of exactly what is sent to wfy24.com on activation, including the live admin email value, so admins can review and change it in Settings → General before consenting. Multisite behaviour documented explicitly. No behaviour change for existing installs.

= 1.5.1 =
Plugin Check fixes — wp_redirect to Stripe replaced with wp_safe_redirect plus a Stripe-host allowlist; readme upgrade notice tightened. No behaviour change.

= 1.5.0 =
Replaces inline script tags with wp_enqueue_script in the shortcode, admin preview, and onboarding wizard, per WordPress.org Plugin Directory guidelines. The hosted widget bundle gained a placeholder-element mount mode so rendering stays in-place. Existing shortcodes keep working.

= 1.4.0 =
Removes the opt-in daily telemetry ping in line with WordPress.org guidelines. No external calls happen on a schedule any more. Cleans up the previously scheduled WP-Cron event automatically.

= 1.2.0 =
Adds one-click Pro upgrade (€9/mo via Stripe). Pro subscribers' widgets no longer show the attribution link.

= 1.1.2 =
Adds explicit attribution disclosure in the activation wizard (WP.org guideline compliance). No behavior change for existing installs — the "Weather by WFY24" link was already part of the widget.

= 1.1.1 =
Code-quality and compliance pass for WP.org Plugin Check (translators comments, escaping, prefixing, ordered placeholders). No user-visible changes.

= 1.1.0 =
Zero-click activation, onboarding wizard, auto-create Weather page, auto-add to sidebar, connection status. Highly recommended.

= 1.0.0 =
First public release.
