=== Secure SMTP ===
Contributors: technologiallc, zainsaeed
Tags: smtp, wp_mail, email delivery, forms, dkim, spam protection
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 1.21.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Reliable SMTP relay + drop-in forms for WordPress. DKIM-aligned mail delivery, bounce + complaint tracking, and built-in spam protection — powered by the SecureSMTP cloud (by Technologia FZE).

== Description ==

Secure SMTP is a wp_mail relay + drop-in form solution for WordPress sites that need **deliverable email** and **invisible spam protection** without setting up reCAPTCHA, Akismet, or an SMTP plugin.

You build the form inside WordPress (or in the SecureSMTP dashboard) and embed it on any page with a shortcode. When a visitor submits, the plugin forwards the data to the SecureSMTP API, which runs a multi-layer spam check, sends the notification email from authenticated infrastructure, and stores the submission in your SecureSMTP dashboard for review and AI-assisted triage.

= Highlights =

* **13 ready-to-use templates** — Contact, Quote Request, Newsletter, Support Ticket, Lead Magnet, Booking, Feedback, Event RSVP, Job Application, Demo Request, Real Estate, Wedding, Restaurant Reservation. Pick one and customise.
* **Drag-and-drop field editor** — text, email, phone, number, textarea, dropdown, checkbox, radio, checkbox group, section heading, HTML block, file upload, date, time, URL. Reorder fields by dragging the handle. Each field supports per-field style overrides (colour, label size, width — half / third / full for automatic multi-column rows), optional conditional visibility rules ("show only when …"), and per-field validation rules (regex, min/max length, min/max value, custom error message).
* **Invisible spam protection** — randomised honeypot, time-to-submit check, signed render-time nonce, and an optional Cloudflare Turnstile challenge. Zero visitor friction.
* **Reliable email delivery** — emails are sent from SecureSMTP infrastructure on `securessmtp.com` via Resend, with SPF/DKIM/DMARC set up correctly so messages actually reach the inbox. Reply-To is set to the visitor so you reply straight to the lead.
* **Per-form design** — pick brand colour, corner radius, field background tone, button alignment, and an optional card wrapper. Live preview while editing.
* **Hosted forms** — design a form once in the SecureSMTP dashboard and embed it on any number of sites via `[qcs_form slug="contact"]`. Edits propagate to every embedding site.
* **Mail Log** — every `wp_mail()` call from the site (your form, password resets, WooCommerce, other plugins) is logged so you can verify what's actually being sent.
* **Submissions dashboard** — every submission appears in your SecureSMTP dashboard with full payload, spam score, AI classification, and the email-delivery status.

= Why this plugin needs a SecureSMTP account =

Email deliverability and spam classification both depend on cloud services that simply cannot be run from a typical WordPress host. The plugin needs to call the SecureSMTP API (`https://securessmtp.com/api/v1/forms/submit`) on every submission. A **free SecureSMTP account** at https://securessmtp.com/signup gives you everything you need to use the plugin — there is no trial period, no time-limit, and no nag screen. Paid plans exist for higher submission volumes, advanced AI features, and analytics, but the free tier is fully functional and never expires.

= External services this plugin uses =

This plugin relies on the following external services. Their use is essential to the plugin's function. See the **Privacy & Data Handling** section below for details on what data is sent and when.

* **SecureSMTP API (Technologia FZE)** — `https://securessmtp.com/api/v1/*` — the destination for form submissions, the source of form definitions for hosted forms, the API key validator, the optional Email Delivery routing endpoint (when *Settings → Email Delivery* is enabled, every `wp_mail()` call this site makes is sent through this API for authenticated delivery), and the read-only custom-domain (DKIM) status lookup that drives the in-admin verification panel. Terms: https://securessmtp.com/terms — Privacy policy: https://securessmtp.com/privacy
* **SecureSMTP media (Technologia FZE)** — `https://securessmtp.com/media/*` — onboarding walkthrough GIF embedded on the plugin's WordPress admin landing page (visible only until you connect your API key). Same domain as the API; loaded only inside `wp-admin`, never to public visitors. Privacy policy: https://securessmtp.com/privacy
* **Cloudflare Turnstile** — `https://challenges.cloudflare.com/*` — invisible bot-detection challenge loaded on the form page when Turnstile is enabled in your SecureSMTP account. Terms: https://www.cloudflare.com/website-terms — Privacy policy: https://www.cloudflare.com/privacypolicy/

The plugin does **not** connect to any third-party advertising, analytics, or tracking service. No data is shared with any party other than the services listed above.

== Installation ==

1. Upload the `qcs-form` folder to `/wp-content/plugins/` (or install the zip via **Plugins → Add New → Upload Plugin**).
2. Activate the plugin via **Plugins → Installed Plugins**.
3. Create a free SecureSMTP account at https://securessmtp.com/signup (if you don't have one).
4. Add your site at https://securessmtp.com/app/forms/sites — this gives you a per-site API key.
5. In WordPress, open **SecureSMTP → Settings**, paste the API key, and click **Save and test connection**. You should see a green "Connected" status.
6. Open **SecureSMTP → Add New**, pick a template, customise the fields, save, and copy the shortcode (`[qcs_form id="123"]`) into any page or post.

That's it. Submit a test message — the email lands in the address you configured, and the submission shows up in your SecureSMTP dashboard.

== Frequently Asked Questions ==

= Is the plugin free? Do I need a paid SecureSMTP plan to use it? =

The plugin itself is free and GPL-licensed. A **free SecureSMTP account** is required for the API the plugin calls — that account has no time limit and is fully functional for typical small-site usage. Paid SecureSMTP plans exist for sites with very high submission volumes or that want extras like AI-assisted reply drafting, but they are not required to use this plugin.

= Why does the plugin need an external service? Can it work fully on-site? =

No — and this is intentional. Two things make a contact form actually work in 2026: (1) email that doesn't go to spam, which requires sending from authenticated infrastructure that a self-hosted WordPress site usually cannot provide, and (2) reliable bot/spam classification, which requires constantly updated heuristics. Both are operated as the SecureSMTP cloud the plugin calls. You can self-host an SMTP server and set up SPF/DKIM/DMARC manually if you prefer, but Secure SMTP is built specifically for site owners who'd rather not.

= Where do form submissions go? =

Two places, in this order: (1) the email address you configured on the form (sent from SecureSMTP infrastructure for reliable delivery, with `Reply-To` set to the visitor's email), and (2) your SecureSMTP dashboard at `https://securessmtp.com/app/forms/submissions`, where you can review, search, and export the full payload.

= Do I need to set up reCAPTCHA, Akismet, or anything else? =

No. The plugin handles spam protection automatically — randomised honeypot fields, time-based bot detection, a signed nonce, and optional Cloudflare Turnstile. All invisible to real visitors; no checkboxes, no puzzles.

= Can I use this on multiple sites? =

Yes. Add each site at https://securessmtp.com/app/forms/sites to get a per-site API key, then paste that key into each site's plugin settings. Submissions, mail logs, and analytics are tracked per site.

= What data does the plugin send to securessmtp.com? =

Only what is required to deliver the form: the form field values the visitor entered, the page URL the form was on, the visitor's IP address and User-Agent (for spam classification), the HTTP referrer, and the API key that identifies your site. See the **Privacy & Data Handling** section below for the complete breakdown.

= Can I export or delete submissions for GDPR/CCPA requests? =

Yes — every submission can be viewed, exported, and deleted from the SecureSMTP dashboard. Deleting a submission in the dashboard removes the underlying record. If a visitor requests deletion, locate their submission by email and remove it; their email is no longer stored on the SecureSMTP side once deleted.

= Does the plugin make any AJAX or REST endpoints public on my site? =

Yes — one AJAX endpoint (`admin-ajax.php?action=qcs_form_submit`) and the public form-rendering shortcode. The AJAX endpoint validates a per-render nonce, a honeypot, and the time-to-submit before forwarding the request to SecureSMTP. No other endpoints are added.

= How do I uninstall cleanly? =

Deactivate the plugin in **Plugins → Installed Plugins**. To remove all plugin data (forms, settings, mail log), delete the plugin via WordPress; `uninstall.php` will clean up. Your SecureSMTP account, submissions, and forms saved on the SecureSMTP dashboard are not affected — manage those at https://securessmtp.com/app.

== Privacy & Data Handling ==

This plugin transmits data to an external service (the SecureSMTP API at `securessmtp.com`) because that is how spam classification and reliable email delivery are performed. Site administrators are responsible for disclosing this in their own privacy policy. Below is the complete data inventory.

= When a visitor submits a form =

The following is sent to `https://securessmtp.com/api/v1/forms/submit`:

* All form field values the visitor entered.
* The visitor's IP address (used for rate-limiting and spam classification).
* The visitor's User-Agent (used for spam classification).
* The HTTP Referer header (the page that contained the form).
* The URL of the page the form was submitted from.
* Your site's API key (identifies which SecureSMTP account the submission belongs to).
* A Cloudflare Turnstile token, if Turnstile is enabled on your SecureSMTP site.

= When a form is rendered =

Nothing is sent to SecureSMTP at render time. If Turnstile is enabled, the visitor's browser loads a JavaScript challenge from `https://challenges.cloudflare.com/turnstile/`. Cloudflare's data handling is described at https://www.cloudflare.com/privacypolicy/.

= When the WordPress admin opens the plugin's settings or editor =

The plugin calls `https://securessmtp.com/api/v1/sites/me` to validate the API key and fetch site configuration. No visitor data is involved.

= When Email Delivery is enabled =

If you turn on *Settings → Email Delivery → Route outgoing email through SecureSMTP*, the plugin forwards every WordPress `wp_mail()` call this site makes to `https://securessmtp.com/api/v1/mail/send` for authenticated delivery. The following fields of each email are transmitted:

* Recipient address(es) (`To`, `Cc`, `Bcc`).
* Subject line.
* Message body (HTML or plain text — exactly what your site asked WordPress to send).
* `From` address and display name.
* `Reply-To` address (if any).
* `List-Unsubscribe` / `List-Unsubscribe-Post` headers, and any custom `X-*` headers, when present.
* The sender mode you picked (`relay`, `domain`, or `auto`) and the name of the plugin/theme that originated the send (auto-detected, for diagnostics).
* Your site's API key (identifies which SecureSMTP account the message belongs to).

Attachments are **not** forwarded — if a `wp_mail()` call has attachments, the plugin returns control to WordPress's native mailer and the message is sent locally instead. If the SecureSMTP API is unavailable, rate-limited, over quota, or declines the message for any reason, the plugin again returns control to the native mailer — your mail is never silently dropped.

If Email Delivery is left off (the default), no email data is transmitted to SecureSMTP.

= When the admin checks custom-domain (DKIM) status =

When the *Send from my own domain* radio is selected, or when the admin clicks *Check domain status* on the settings screen, the plugin calls `https://securessmtp.com/api/v1/mail/domain-status` to read the verification state of the site's sending domain(s). This is a read-only call; no visitor data is transmitted. The cached response is stored in a WordPress transient for 10 minutes.

= Cookies =

The plugin sets no cookies on the visitor's browser. WordPress core may set its own cookies; those are unaffected.

= Local storage =

Forms, settings, a mail log of every `wp_mail()` call, and a local copy of every form submission are stored in the WordPress database (tables `qcs_form_mail_log` and `qcs_form_submissions`). The mail log is capped at 5,000 rows and excludes message bodies by default to keep storage bounded. The submissions table stores the same field data that was sent to securessmtp.com — site administrators with `manage_options` capability can browse, search, export, or delete entries from the *SecureSMTP → Submissions* admin page.

= SecureSMTP privacy policy =

The full privacy policy for the SecureSMTP service is at https://securessmtp.com/privacy. It describes data retention, the legal basis for processing, sub-processors, and how to make access/deletion/export requests.

== Screenshots ==

1. The drag-and-drop form editor inside WordPress — each field is a card you can reorder, collapse, or edit.
2. The form designer — pick brand colour, corner radius, and button alignment with a live preview.
3. The settings page — paste your API key and verify the connection.
4. The Mail Log — every `wp_mail()` call from the site, with source plugin auto-detected.
5. A rendered form on the front-end, with the modern styling and inline validation.
6. The SecureSMTP dashboard view of incoming submissions, with spam score and AI classification.

== Changelog ==

= 1.21.0 =
* **Rebrand:** visual identity, icons, banners, and copy updated to reflect the SecureSMTP brand.
* **Fix:** All inline `<style>` and `<script>` blocks now use the standard `wp_enqueue` / `wp_add_inline_style` pattern (WordPress.org plugin review fix).
* **Fix:** Text domain now matches the plugin slug `qcs-forms`.

= 1.19.0 =
* **New dedicated SMTP page** under SecureSMTP → SMTP. The Email Delivery controls (routing toggle, sender mode, live wp_mail() test button, competing-SMTP plugin warning) now live as their own top-level menu item instead of being buried inside Settings. Settings → Email Delivery still works for back-compat.
* **Cross-link to SecureSMTP dashboard email log**. Both the new SMTP page and the existing Mail Log point at https://securessmtp.com/app/forms/email — the platform-side log of every email routed through SecureSMTP across all your connected sites. Makes it obvious where to look when you want a centralised view across multiple WordPress installs.
* **Safer Settings save**. The API key field is now only updated when the field is actually present in the POST — prevents a regression in a multi-form setup from accidentally emptying the saved key.

= 1.18.0 =
* **Email Delivery now reliably catches third-party form plugins.** The mail-relay's WordPress filter priority moved from 9 → 1 so Secure SMTP beats other SMTP plugins to incoming `wp_mail()` calls. A new `phpmailer_init` hook also catches Gravity Forms notifications and similar plugins that bypass `wp_mail()` entirely.
* **Mail Log now shows the routing decision** for every `wp_mail()` attempt — "Routed via SecureSMTP", "Skipped: relay off", "Fell back: API error", "Claimed by another plugin", and several more. Makes it obvious whether your Contact Form / WPForms / Gravity Forms emails are actually going through SecureSMTP, or being intercepted by something else.
* **Competing SMTP plugin detection.** If WP Mail SMTP / Post SMTP / FluentSMTP / Easy WP SMTP / similar are active alongside Secure SMTP with Email Delivery enabled, Settings → Email Delivery now shows a clear warning explaining the conflict and which plugin to deactivate.
* **New "Send a real wp_mail() test" button** in Settings → Email Delivery. Distinct from the existing connection test — this fires a real `wp_mail()` through the full WordPress pipeline (honeypot, filters, every other plugin's hooks) and reports back whether the message was actually routed through SecureSMTP or fell back.
* **First-run prompt** when a fresh install has an API key but Email Delivery is still off — a dismissible admin notice points to where to enable it.

= 1.17.0 =
* **Field-level validation rules.** Every input field now has a collapsible "Validation" sub-panel — regex pattern (without the `/…/` delimiters), min / max length, min / max value (for numeric fields), and a custom error message shown when any rule fails. Rules are evaluated client-side on input/blur/submit and re-evaluated server-side before the submission is forwarded to the platform.
* **Per-form Custom CSS escape hatch.** The form Settings panel now has an "Advanced → Custom CSS" textarea. CSS you paste is automatically scoped to `.qcs-form[data-form-id="<id>"]` at render time so it can't leak onto the rest of the page. Live canvas preview deliberately does not apply Custom CSS — test on the front-end.
* **wp-color-picker for every per-field colour input.** The "Style overrides" panel's label, input-background, input-border, and input-text colour fields are now wp-color-picker swatches (the same picker the Design tab's brand colour already uses), not plain hex text boxes. Adding a new field instantly gets working pickers; saved colours load into the swatch on edit.
* **File upload field type.** New `file` field for accepting attachments. Per-field: accept (MIME / extensions), max file size in MB (hard-capped at 25 MB), max files (hard-capped at 5), and an "allow multiple" toggle. Files are stored under `wp-content/uploads/qcs-form-attachments/<form-id>/<yyyy-mm>/` with a unique per-file prefix, and the submission's payload to the platform carries a JSON-stringified list of `{filename,url,size,mime_type}` so notification emails contain clickable links. Strict server-side MIME allowlist (images, PDF, DOC/DOCX, XLS/XLSX, TXT, ZIP) — SVG, PHP, JS, HTML, EXE, and SH are all rejected. Oversize / wrong-type uploads bail with an inline error.
* No platform-side changes: per-field validation + file metadata stay on this site; the platform API still receives field values as strings. Existing 1.16.0 forms render unchanged.

= 1.16.0 =
* **New field types:** Radio buttons, Checkbox group, Section heading, and HTML block — addable from the field type dropdown alongside the existing inputs. Radio + checkbox group support inline or stacked layouts; headings render as a visual section divider; HTML blocks let you insert intro copy, links, or notes between fields. Headings + HTML blocks have no input and never appear in submission payloads.
* **Per-field style overrides.** Every field card has a collapsible "Style overrides" panel — label colour, label size (S/M/L), label weight (normal/bold), input background / border / text colour, and field width (Full / Half / Third). Leave any value empty to inherit the global Design tab default. Field width drives an automatic multi-column layout on the frontend: adjacent half-width fields pair up, adjacent third-width fields chunk into 3-up rows, and a full-width field always breaks to its own row.
* **Live clickable canvas.** The Form-builder screen now has a "Form preview" pane sitting beside the field list — it renders the actual configured fields with their per-field styles applied and re-paints on every edit. Click any field on the canvas to jump straight to its editor card (with a brief highlight pulse). Replaces the old static preview that used to live in the Design tab.
* **Conditional visibility.** Each field can declare a single rule — "show only when [field name] [equals | contains | is not empty] [value]". The frontend toggles the field via the `hidden` attribute on every input event in the watched source, and the server re-evaluates the rule server-side so a hidden field is treated as not-present (skipping its required-check and dropping its value from the submission payload).
* **Inline options editor.** Radio + checkbox group options are edited as a per-line list (each row has a remove button + "Add option") instead of the old line-break-delimited textarea, which makes reordering and editing one option at a time much less error-prone. Dropdowns keep accepting both forms.
* No platform-side changes: per-field metadata stays in the field array on each submission; existing forms unchanged in v1.15.0 render identically.

= 1.15.0 =
* **New: send notifications to up to 3 email addresses per form.** Each form's settings panel now has dedicated Recipient 1, Recipient 2, and Recipient 3 fields so multiple people on your team can be notified when a submission lands. Recipient 1 stays in sync with the legacy single-recipient field, so existing forms continue to work without any reconfiguration.
* **New: auto-responder confirmation email to the submitter** with variable placeholders ({name}, {email}, {form_name}, {site_name}). Optional per-form — toggle "Send a confirmation email to the form submitter", set the subject, write the body (HTML allowed), and choose a From name. The platform substitutes the placeholders against the submission's values and dispatches the confirmation via SecureSMTP's authenticated infrastructure. Confirmations are only sent when the form contains an email field.

= 1.14.2 =
* **Logged-in WordPress admins are no longer subject to the rate-limit block** — so site owners can freely test their forms during setup without locking themselves out. The plugin flags submissions made by users with the `manage_options` capability and the platform skips its per-IP rate-limit check on those.
* **Default rate limit relaxed for everyone** — was "1 submission per IP per 60 seconds" (which tripped admins doing 2-3 quick test submissions); now "3 submissions per IP per 60 seconds". Bot-burst protection still kicks in past 3 hits/minute.

= 1.14.1 =
* **New dedicated "Blocks" admin page** under *SecureSMTP → Blocks* — visible whether or not a block is active. Shows current site/IP blocks with the same unblock buttons as the v1.14.0 admin notice, plus an always-on "How blocks happen" explainer (rate-limit / abuse-disable / manual-admin) so site owners can self-serve answer "why was my IP blocked?". Includes a "Re-check now" link to force a fresh poll.

= 1.14.0 =
* **You'll know the moment SecureSMTP blocks you.** When SecureSMTP rate-limit-blocks a submitter IP, or auto-disables your whole site for an abuse spike, a loud red admin notice now appears on every wp-admin page explaining exactly what's blocked, who triggered it, and how to fix it.
* **One-click self-unblock for recoverable issues.** Rate-limit blocks (IP) and auto-disable spikes (whole site) are recoverable from inside wp-admin — the red notice has an **Unblock this IP** / **Reactivate my site** button that calls the SecureSMTP platform and clears the block. Non-recoverable cases (manual admin holds, sustained abuse) show a **Contact support** button instead.
* **Hourly background check.** A WP-cron task polls the new `/api/v1/blocks/status` endpoint once an hour and caches the result, so the notice surfaces without slowing any admin page. **Re-check now** link on the notice forces a fresh poll on demand.
* **Quick links from the notice** straight to *Submissions* (pre-filtered to the "skipped" relay status, so you can see what was blocked) and *Settings*.
* New platform-side dashboard page at securessmtp.com → **SecureSMTP → Blocks** lists every active block across your sites with the same self-unblock buttons.

= 1.12.1 =
* **Documentation:** expanded the External Services and Privacy & Data Handling sections to fully disclose the Email Delivery routing (added in 1.11.0) and the custom-domain (DKIM) status lookup (added in 1.12.0) — including the exact fields transmitted on each routed `wp_mail()` call.
* Hardened two admin-side output paths with explicit `esc_attr()` even though both emit only literal string constants — silences a `WordPress.Security.EscapeOutput.OutputNotEscaped` warning from static analysis tools. No behavioural change.

= 1.12.0 =
* **Live "Send from my own domain" status, right inside WordPress.** The Email Delivery settings now show whether your custom sending domain is verified yet — without leaving wp-admin. A green banner confirms when mail is going out as your own address (with the exact domain and From address); an amber banner lists any domains still pending DNS verification and confirms your mail is meanwhile sent via the SecureSMTP relay, never delayed.
* **Guided DKIM setup walkthrough.** A built-in step-by-step guide (open the Email Delivery dashboard → add your domain → copy the DKIM/SPF/DMARC records → verify → re-check) replaces the bare link-out, so you can complete domain verification with the instructions in front of you. The guide auto-expands when you pick "Send from my own domain" and the domain isn't verified yet.
* New **"Check domain status"** button re-queries the platform on demand and caches the result for 10 minutes.
* Degrades gracefully: if the status endpoint is ever unavailable, the walkthrough and dashboard link are still shown — the settings screen is never blocked.

= 1.11.0 =
* **Email Delivery.** Optionally route this site's outgoing email — WooCommerce receipts, password resets, admin notifications, every `wp_mail()` call — through the SecureSMTP platform for authenticated, reliable delivery. Enable it under *SecureSMTP → Settings → Email Delivery*.
* **Fail-safe by design.** If the platform is ever unavailable, over quota, or declines a message, WordPress automatically falls back to its normal mailer — your email is never silently dropped.
* **Choose your sender.** Send from the SecureSMTP verified domain with replies directed back to the original sender (zero setup, recommended), or verify your own domain via DKIM so mail goes out as your own address.
* **"Save and send test email"** button to confirm routing end-to-end from the settings screen.

= 1.10.0 =
* **Redesigned admin dashboard.** Connected users now see a permanent **Help & resources** section with 6 link cards (Setup guide, SecureSMTP dashboard, How it works, Pricing, Support, Privacy) plus a **Watch the 60-second tour** collapsible that reveals the walkthrough GIF on demand — no more bare dashboard once you finish onboarding.
* New header strip shows connection status (green "Connected" / amber "Not connected" pill) and the plugin version at a glance.
* New quick-action card grid with icons: New form · All forms (with count badge) · Mail Log · Settings.
* Footer strip with version, setup-guide link, settings link, and support link — visible from every visit.
* The onboarding panel from v1.9.0 still appears unchanged while disconnected and disappears after setup.

= 1.9.0 =
* **Welcome card on the SecureSMTP admin dashboard** — first-time users now land on an onboarding panel with a 60-second animated walkthrough of the entire connect → build → embed → review flow, plus a numbered 4-step quickstart. The panel auto-hides as soon as the API key is configured, so it never gets in the way of returning users.
* Onboarding GIF is loaded from `securessmtp.com/media/` (declared in External Services), keeping the plugin zip under 65 KB and letting us improve the walkthrough without users having to update the plugin.
* New CTA: "Read the full setup guide" links out to `securessmtp.com/forms/get-started` — a public docs page with the same walkthrough plus step-by-step screenshots and an FAQ.

= 1.8.0 =
* **Plugin Check compliance pass** — addressed every error and the great majority of warnings from the official WordPress.org `plugin-check` tool ahead of directory submission.
* Input sanitisation hardened across admin + frontend: every `$_POST` / `$_GET` / `$_SERVER` read is now `wp_unslash()`-ed before the appropriate `sanitize_*()` call (no functional change — the data was already safe in practice, this just makes the intent explicit to static analysis).
* All custom-table queries in `class-mail-log.php` re-routed through `$wpdb->prepare()`; documented suppressions added where direct DB calls are intentional (audit-log writes have no usable cache).
* Pagination output in the Mail Log view is now wrapped in `wp_kses_post()` for explicit safe-HTML escaping.
* Added missing `translators:` comments to all `__()` calls containing `printf` placeholders.
* Empty `languages/` folder shipped so the `Domain Path` header points at a real directory.
* `Tested up to:` bumped to `6.7`.

= 1.7.0 =
* **WordPress.org submission preparation** — plugin metadata cleaned up, full `readme.txt` rewritten to WP.org format with comprehensive Privacy & Data Handling section, External Services disclosure, FAQ expanded, and GPL header confirmed throughout.
* Plugin display name standardised to **Secure SMTP** (previously "QCS FORM" in the header).
* No functional changes to the runtime; this is a packaging release.

= 1.6.2 =
* **Drag-and-drop form builder** inside the WordPress form editor. Each field is now a collapsible card with a left-side drag handle — click and drag to reorder, click anywhere on the summary row to expand the field's settings. Uses jQuery UI Sortable (already shipped by WP core, no external dependencies).
* Each card's collapsed summary shows the field's type icon (text/email/dropdown/etc.), label, and a red "Required" pill if applicable — at-a-glance view of the form structure.
* New fields auto-expand on add and the cursor lands in the Label input so you can start typing immediately.
* Empty-state hint when a form has no fields yet.
* Field summary updates in real time as you type the label, change the type, or toggle Required — no page reload needed.

= 1.6.1 =
* **Removed third-party form-builder integrations** (Contact Form 7, Elementor, WPForms, Forminator). The hook-detection approach was unreliable across Pro versions and the added complexity wasn't justified. Use hosted forms (`[qcs_form slug="..."]` from the new dashboard builder) or WP-native Secure SMTP forms instead — both have first-class support.
* Removed: Integrations admin submenu, `qcs_form_integrations` option, `qcs-form/includes/integrations/` folder, the "Send test event" button.
* No data loss — submissions, sites, API keys, mail log, hosted forms all untouched.

= 1.6.0 =
* **Hosted forms.** Build forms in the SecureSMTP dashboard at `/app/forms/builder` (drag-drop field editor, live preview, design controls) and embed them on any WordPress site with the new shortcode: `[qcs_form slug="contact"]`.
* One form definition, many sites — edit once in the SecureSMTP dashboard, propagates to every embedding site within 5 minutes (transient cache TTL). Particularly useful for agencies running the same form across multiple client sites.
* The original `[qcs_form id="123"]` shortcode for WP-native forms keeps working unchanged. The two flows coexist; users can use either or both.
* Submissions from hosted forms are tagged `template: hosted:<slug>` in the dashboard so they're easy to filter / analyse separately.

= 1.5.8 =
* The "Send test event to SecureSMTP" result banner now surfaces the server's specific error string (e.g. `error=invalid_api_key`, `error=site_disabled`) when the test fails. Previously only the HTTP code was shown, which made it harder to diagnose 4xx failures.

= 1.5.7 =
* Fix: the "Send test event to SecureSMTP" button on the Integrations page was nested inside the outer settings `<form>` — HTML doesn't allow that, so browsers silently dropped the inner form. Clicking the button was actually submitting the settings form (and just saving toggles), not running the test. Replaced with AJAX so the result now renders inline below the button without any nested-form issue.

= 1.5.6 =
* Auto-enabled diagnostic mode whenever `WP_DEBUG_LOG` is true (no separate constant needed): logs the AJAX entry point hit, every `elementor_pro/*` action fired during the request, and a shutdown summary indicating whether our `on_event` was called at all.

= 1.5.5 =
* New diagnostic mode for the Elementor integration. Add `define('QCS_FORM_DEBUG_HOOKS', true);` to wp-config.php and submit a form — every `elementor_pro/*` action that fires during the request is logged to `/wp-content/debug.log`.

= 1.5.4 =
* **Elementor**: removed the `validation` hook from our listener list — it was firing too early and tripping the per-request guard. Now hooking `process` + `new_record` + `submission/processed`.

= 1.5.3 =
* **Elementor integration now listens on 4 different hook names**, not just one. Per-request guard prevents duplicate forwards.

= 1.5.2 =
* **"Send test event" button** on each integration card — fires a synthetic submission through that integration's `forward()` method so you can verify the SecureSMTP API round-trip works.
* **Debug logging** — when `WP_DEBUG_LOG` is on, every integration's hook entry/exit and forward result is written to `/wp-content/debug.log`.

= 1.5.1 =
* Fix: settings page link now points at the real API Keys / Sites pages (`/app/forms/api-keys`, `/app/forms/sites`) instead of the stale `/admin/forms` URL.
* Defensive fix: `wp_mail` filter no longer requires a strict `array` return type, so a misbehaving upstream filter can't trigger a TypeError.

= 1.5.0 =
* **Form Designer** — new Design meta box on every form's edit screen. Pick a brand colour, corner roundness, field background tone, submit-button alignment, and an optional card wrapper with shadow.
* Per-form CSS variables are injected on render, so each form can have its own look.
* **Mail Log** — new admin page at *SecureSMTP → Mail Log* records every `wp_mail()` call from the site.
* **Robust integration detection** — also detect via `is_plugin_active()` as a fallback.

= 1.4.0 =
* **Pre-built integrations for popular form builders** — Contact Form 7, Elementor Forms (Pro), WPForms (Lite + Pro), Forminator. (Subsequently removed in 1.6.1 — see that entry.)

= 1.3.0 =
* Redesigned frontend form UI — modern field styling, soft focus ring, inline per-field error messages, loading spinner inside submit button.
* New themable CSS — override `--qcs-brand`, `--qcs-radius`, `--qcs-bg-field`, etc. from your child theme.
* Automatic two-column layout for adjacent short fields on wider screens.
* Live error clearing as the user fixes the field.
* Dark-mode-friendly defaults via `prefers-color-scheme`.

= 1.2.0 =
* Cloudflare Turnstile (invisible mode) integration. Site key fetched dynamically from the SecureSMTP API.
* `cf_turnstile_token` forwarded with every submission for server-side verification.


= 1.1.0 =
* 8 new templates: Booking, Feedback, Event RSVP, Job Application, Demo Request, Real Estate, Wedding, Restaurant Reservation. Total now 13.
* Three new field types: Date, Time, URL — with server-side sanitisation per type.

= 1.0.0 =
* Initial release: CPT-backed forms, 5 templates, field editor, shortcode, honeypot + nonce + time-check, AJAX submit → central API.

== Upgrade Notice ==

= 1.19.0 =
Email Delivery / SMTP now has its own top-level menu item under SecureSMTP — easier to find for site owners who don't realize the relay can handle Contact Form 7 / Gravity Forms / WPForms / Forminator. Also makes the "where do I see relayed emails on the SecureSMTP dashboard" question explicit. Safe drop-in upgrade.

= 1.18.0 =
Email Delivery now catches third-party form plugins (Contact Form 7, Gravity Forms, WPForms, etc.) far more reliably — the filter priority moved to 1 and a PHPMailer hook now catches the plugins that bypass `wp_mail()`. Mail Log surfaces the routing decision so you can see exactly what happened. Detects competing SMTP plugins. Safe drop-in upgrade.

= 1.17.0 =
Adds field-level validation rules (regex, min/max length/value, custom error), per-form Custom CSS escape hatch, wp-color-picker swatches for the per-field colour controls, and a File upload field type backed by WordPress media storage. Existing 1.16.0 forms render identically. Safe drop-in upgrade.

= 1.16.0 =
Major form-builder upgrade: 4 new field types (radio, checkbox group, heading, HTML block), per-field style overrides (label colours / sizes / weights, input colours, field width), a live clickable canvas next to the fields editor that mirrors the rendered form, and conditional visibility rules. Existing forms render identically — every new feature is additive. Safe drop-in upgrade.

= 1.15.0 =
Send each form's submission to up to 3 recipient addresses and (optionally) send an auto-responder confirmation email back to the submitter with placeholder variables like {name} and {form_name}. Existing single-recipient forms keep working unchanged. Safe drop-in upgrade.

= 1.14.2 =
Site owners can now test their forms freely — admin-side submissions skip the per-IP rate limit, and the default rate limit is relaxed to 3/min for everyone. Safe drop-in upgrade.

= 1.14.1 =
Adds a permanent **Blocks** page under *SecureSMTP* so site owners can inspect their block status at any time, not just when the red admin notice fires. Safe drop-in upgrade.

= 1.14.0 =
You'll now see a red admin notice the moment SecureSMTP blocks your site or an IP, with a one-click "Unblock me" button for recoverable cases. Adds an hourly background WP-cron event and two new platform endpoints. Safe drop-in upgrade.

= 1.12.1 =
Documentation pass: the Email Delivery and DKIM disclosures in readme are now complete. No code or behavioural change beyond a defensive `esc_attr()` wrapper on two literal-string admin echoes. Safe drop-in upgrade.

= 1.12.0 =
Email Delivery now shows your custom-domain (DKIM) verification status inside WordPress, with a built-in step-by-step setup guide and an on-demand "Check domain status" button. Safe drop-in upgrade.

= 1.11.0 =
Adds optional Email Delivery — route this site's WordPress email through the SecureSMTP platform for authenticated delivery, with automatic fallback to your normal mailer if the platform is ever unavailable. Off by default; enable it under Settings → Email Delivery. Safe drop-in upgrade.

= 1.10.0 =
Adds a permanent **Help & resources** section to the SecureSMTP admin dashboard with a collapsible video tour and docs links. Also adds connection-status pill and a redesigned action grid. Safe drop-in upgrade.

= 1.9.0 =
Adds an onboarding walkthrough (60-second GIF + 4-step quickstart) to the SecureSMTP admin dashboard, visible only until you connect your API key. Safe drop-in upgrade.

= 1.8.0 =
Plugin Check compliance pass ahead of WordPress.org submission. Hardened input sanitisation, prepared SQL on all mail-log queries, wrapped pagination output. No behavioural changes — safe drop-in upgrade.

= 1.7.0 =
Packaging release for WordPress.org submission. Plugin name normalised to "Secure SMTP" and `readme.txt` now includes a complete Privacy & Data Handling section. No functional changes — safe drop-in upgrade.

= 1.6.2 =
Drag-and-drop field reordering in the WordPress form editor. Safe drop-in upgrade.

= 1.6.0 =
Adds hosted forms (`[qcs_form slug="..."]`) so one form definition can be embedded on many sites. Existing `[qcs_form id="123"]` shortcodes continue to work unchanged.
