=== SubtleForms changelog ===

This file keeps the full release history. readme.txt lists only the latest versions.

== Changelog ==

= 2.7.4 - 2026-11-04 =
* New: The SubtleForms menu and its Submissions item show the number of unread entries in a bubble, like the Comments menu, with counts above 9 shown as 9+.
* Change: SubtleForms has a new logo: the admin menu icon, the header mark and the block icon now use it.
* Change: Notices from WordPress and other plugins now appear under the SubtleForms header instead of above it.
* Change: SubtleForms screens have a footer with the version, documentation and support links and the list pagination, while the page content scrolls between the header and the footer.

= 2.7.3 - 2026-10-29 =
* New: Custom styling now has grouped, resettable controls that start from your theme colours and fonts, a compact or comfortable density, contrast warnings, and the builder preview shows the theme exactly as your site does.
* New: The Phone and Country fields have a new "Show country flags" setting that draws a small flag next to each country, loading the flag image only for forms that use it.
* Change: Removed freeform Custom CSS from the form builder for WordPress.org compliance. Structured appearance settings still work.
* Security: Classic form result storage, admin action nonces and every REST nonce check now sanitize request input before use, and public REST route detection normalizes REQUEST_URI before parsing.
* Security: The onboarding test email and the onboarding, tour and card dismiss routes now require the manage_options capability, the same as every SubtleForms screen.

= 2.7.2 - 2026-10-24 =
* Change: SubtleForms Pro builds older than 2.8.0 are not started by this version, to avoid errors. Update SubtleForms Pro to 2.8.0 or later.
* Change: Payment, pricing and coupon features are provided only by the add-on. This plugin no longer includes the order engine, and an entry's order is shown by the add-on.
* Change: A form that has a field no active plugin provides shows "This form is not available right now." and keeps its saved fields. Forms with only a leftover payments setting and no payment field keep working.
* New: On an empty site, SubtleForms offers to import forms from Contact Form 7, Gravity Forms, Fluent Forms and other detected form plugins.
* Change: Forms load without a loading flash, file uploads use a drop zone with a select button, repeater groups are labelled Entry N, and form settings let you choose the required-field mark and turn the validation summary on or off. Forms that have required fields show a short legend for the mark. Forms no longer paint a background by default, and inherit-from-theme keeps SubtleForms chrome for calendars and similar fields while using theme colours.
* Fix: The Preview tab uses one scrollbar for the canvas and styling controls.
* Change: Appearance presets no longer set form width; Layout / Form width stays a separate control so columns flex at full content width.
* Fix: The date picker trigger matches other fields, and the calendar panel is easier to read.
* Fix: The first-load route spinner uses the brand colour on the white stage, matching the admin shell.

= 2.7.1 - 2026-10-23 =
* Change: Forms with payment fields show a not available message instead of taking orders.
* Change: Forms that inherit the theme load no SubtleForms stylesheet, and the stylesheet has an RTL version.
* Change: Choice groups use a fieldset with a legend, and error and success boxes use theme-neutral colours.
* Fix: The keep-data uninstall setting is now saved and honoured.
* Fix: The per-user entry limit works.
* Security: Form schemas need the manage_options capability, reCAPTCHA v3 checks the score and action, and time tokens expire after two hours and work once.
* Security: The client IP honours trusted proxies, and queued mail and webhook details stay out of the cron option.

= 2.7.0 - 2026-10-23 =
* New: Web addresses and links written as [text](https://example.com) in a form's confirmation message are now clickable; only http, https and site-relative links are allowed and anything else stays plain text.
* New: Add-ons can register their own panel in the form builder under Integrations.
* New: Extension points for add-ons: field type overrides, logic evaluators, Reports panel slots, form mount hooks and a form-deleted action, with placeholders in the builder and Reports.
* Change: Removed two settings that were saved but never used: the WooCommerce product and currency fields.

= 2.6.1 - 2026-10-23 =
* Fix: A visitor who starts a form and leaves is counted in the form funnel again; the leave report is sent as form data so WordPress can read it.
* Change: A form on your site now appears sooner and without a gap: its fields and labels are printed in the page and drawn from there instead of being fetched after the page loads, and a plain outline of the form is shown until the form is ready.
* Fix: The SubtleForms block now keeps the form's own styling (colours, theme and layout) both on your site and in the editor preview, the preview is marked and cannot be used, and a theme chosen in the block still overrides it.
* Fix: The "Rows per page" label in the list footers now sits on one line with its select instead of above it.

= 2.6.0 - 2026-10-22 =
* New: A form funnel on the Reports screen shows how many people saw, started and sent each form and the last field people touched before leaving without sending it, with a plain suggestion for each field; it keeps only daily totals per form, sets no cookies, stores no answers or IP addresses, skips robots and people who manage SubtleForms, and follows the Count form views switch. Form views are no longer counted for people who manage SubtleForms either, so Seen and Started count the same visitors.
* New: Settings, Tools, Migrate finds the forms you made with Contact Form 7, Gravity Forms or Fluent Forms on this site and imports the ones you tick as drafts, with their fields, required rules, choices, email notifications and thank-you message, and a report of anything that could not be copied; entries and payment settings are not imported and the original forms are not changed. Email notifications have a Reply-To setting that takes one address or a field tag such as {field:email}, and imported forms keep their Reply-To.
* New: New forms now stop spam robots quietly without a CAPTCHA, because the hidden trap field and the too-fast check are on by default for every form you create, the dashboard shows how many spam messages were blocked in the last 30 days and why, each form shows its own count under Spam protection, and sites that update get a one-time offer to turn both on for all their forms with Undo.
* Change: Forms load faster: every page with a form now downloads 22 percent less SubtleForms code (46 KB instead of 59 KB compressed), the date picker, phone and country lists, uploads, payments and the conversational layout are only downloaded by forms that use them, pages without a form still load nothing, and on a slow mobile connection a form is ready about a quarter of a second sooner.
* Change: The SubtleForms screens no longer pin the WordPress admin menu in its own scrolling column on short windows; the menu behaves as in WordPress.
* Change: The Submissions screen no longer has a New tab, because All already lists unread entries; an old link to the New tab opens All.
* Change: Tools is now a tab in Settings, with an MCP tab right after it that explains MCP. The old Tools address opens the Tools tab.
* Change: Report panels no longer scroll inside their own boxes: long lists in Form funnel and Each form show the top rows with a Show all button, and every panel fits from phone to wide screens.
* Fix: The Submissions footer (result count, previous and next, rows per page) stays at the bottom edge of the list pane with no entries, a few or many.
* Fix: Submissions lists past the first 100 entries when 50 or 100 rows per page are chosen, and an empty page after the last row was removed keeps its real page count so Previous works.
* Fix: Choosing 50 or 100 rows per page on the Submissions screen lists the entries instead of showing "Entries could not be loaded".

= 2.5.0 - 2026-10-21 =
* Change: The Branding tab is gone from Settings.
* Fix: The date, time and date and time pickers work from the keyboard. Focus moves into the dialog when it opens, the hour and minute columns take the arrow keys, Home, End and Enter, and Escape returns focus to the field.
* Fix: The Country and phone country search is announced as a combobox with the active country, Escape returns focus to the field instead of the page, and required dropdown, country, date and time fields are marked required for screen readers.
* Fix: The small grey text in the Columns layout headers, prefix and suffix text and country codes is darker so it reaches the 4.5 to 1 contrast WCAG asks for.
* Fix: On the builder canvas, Radio and Checkboxes fields show their default choices selected, like Dropdown and Toggle already did.
* Fix: A logic rule on a Country field matches whether the field stores the country code or the country name, in the browser and on submit.
* Fix: Entries sent from the builder Preview are left out of the dashboard totals, today, week and trend, reports, the unread count, the Inbox and a form's entry limit. They show as Preview and can be listed with the Result filter.
* Change: The create form dialog, the quick start wizard and Form settings use the same wording and help for the form name, description and form types.
* Change: In Form settings, Notifications, the Send email and Send to webhook buttons are one group with a gap, above the list and again below it once there is a notification. The webhook is called "Webhook" everywhere.
* New: A webhook sends only the data you tick: form, entry details, each answer and, on payment forms, the amount, currency and status. A live example shows the exact JSON, and "View as JSON" edits the same body with merge tags. Webhooks saved before keep sending the same body.
* Fix: Custom headers of a webhook are name and value rows you can type into, with a JSON view. Before, the field put the old text back on every keystroke. Headers that SubtleForms sets itself, such as Host and the signature, are refused with a reason.
* Change: The webhook test in a form sends the ticked data built from the form's own fields.
* Fix: The question text of a Checkbox grid is no longer a label that points at a control which does not exist, so screen readers name the group once.
* Fix: The Submissions list no longer scrolls sideways in a narrow pane, shows each entry on two lines with a sticky footer and a slim icon bulk bar, shows a count on every tab that updates at once after each action, marks starred entries with a flat amber star only, and gives each row action its own tooltip.

= 2.4.1 - 2026-10-20 =
* Fix: Choosing 50 or 100 rows per page on the Forms screen shows the forms instead of "Forms could not be loaded".
* Fix: Clearing a saved setting, such as an API key or a sender name, saves it empty instead of keeping the old value.
* Fix: A form has no padding of its own, so it lines up with the text around it.
* Fix: No line or border above the submit button.
* Change: "Inherit from theme" adds no styling of its own. The theme styles the fields, labels and buttons, and the buttons use the theme's button style. Custom controls such as the dropdown and date pickers, the signature pad and the rich text editor keep their look so they stay usable.
* Change: A form on "Inherit from theme" whose colours, type or field and button style were changed keeps the SubtleForms styling, starting from the theme. The appearance panel says which applies.
* Fix: On a theme form whose theme has no primary colour, the submit button is no longer white on white.
* Change: Fields on the builder canvas use flat colours instead of gradients.
* Fix: A webhook address typed without https:// gets it, and an address WordPress refuses (a local or private host, or a port other than 80, 443 and 8080) is listed in the entry's activity log with the reason instead of failing silently.
* Fix: Webhooks no longer send the form's spam check token, the honeypot or CAPTCHA tokens with the answers.
* Change: The default webhook body is the one the Webhooks settings describe: the event, form and entry IDs, a link to the entry, the answers keyed by field under "fields", and every answer with its label under "answers". Receivers that read answers at the top level of the body should read them from "fields".
* Fix: The webhook test in Settings is ready as soon as an address is typed, uses the same address check, body and signing as real deliveries, and says why an address is refused.
* New: Each webhook action in Form settings has a Send test request button that sends the action's own method, headers, signing and custom body.
* Change: A field ID can use hyphens and up to 64 characters. Saving a form refuses an ID used by two fields anywhere in the form (inside steps, columns and containers too) or a name SubtleForms reserves for its own values.
* Change: Gravity Forms and Fluent Forms imports keep each field's name from the other plugin (Fluent's field name, Gravity's parameter name) as its field ID when it is valid, so data and integrations that use those names keep matching.
* New: Change a field's ID in the field settings. Click the pencil next to the ID, type the new one, press Enter. The ID is checked as you type, and merge tags, formulas, conditional logic, emails, webhooks, confirmations, integrations and payment settings that use it are updated. Undo puts it back, and earlier entries keep their answers under the old ID.
* Fix: Forms imported in Tools, migrated from Gravity Forms or Fluent Forms, or created with a schema get the same save steps as a builder save, so add-ons can finish them (a signed webhook gets its secret, logic rules for missing fields are removed).
* Fix: The live form sends the page's language with its requests when a translation add-on gives one, so translated labels and confirmations are used.
* New: An action, subtleforms/submission/deleted, fires when an entry is deleted for good, so add-ons can remove what they keep about it.
* Fix: An integration's status dot in Settings turns green as soon as it is switched on and set up, without a reload.
* Fix: Entry ages read 1 hour ago, 1 minute ago and 1 day ago instead of using the plural for one.
* Fix: Deleting a coupon, discarding changes, deleting forms or steps, resetting settings and export errors use the SubtleForms dialog instead of the browser's confirm and alert boxes.
* Change: In the builder the field inspector's first tab is called Field and its Appearance section is called Display, so they are not confused with the Settings view and the Style tab.
* Fix: On a window shorter than the WordPress menu, SubtleForms screens fill the window instead of showing a dark band under the page, and the lower menu items stay reachable.
* Fix: On a phone the form builder says it needs a wider screen instead of showing a clipped toolbar, with a button back to the forms and an option to open it anyway.
* Fix: With the reading pane on the right, a narrow window shows the open entry over the list at full width, and its actions wrap onto a second line instead of overlapping or being cut off.
* Fix: On a phone the forms and submissions lists show each row as a card instead of a table that scrolls sideways, checkboxes keep their normal size, the tabs stay on one line and the search box gets its own line.
* Fix: The Quick Start Wizard fits the window on every step with its buttons always in view, and the Help & tour menu closes when you pick Start Tour or View Documentation.
* Fix: The builder tour describes the real header buttons, shows the toolbar and settings of a selected field, and no longer scrolls the page.
* Fix: Pages with a form no longer jump when the form appears: the space for the form is kept from the start.

= 2.4.0 - 2026-10-20 =
* New: A payment form has its own currency setting under Settings, Payments. It follows the site currency until you pick one.
* New: More currencies for payments, including JPY, KRW, INR, PKR, AED, SAR, SGD, HKD, CHF, NZD, SEK, NOK, DKK, PLN, MXN, BRL and ZAR.
* Fix: Saving a form's Payments settings no longer fixes the form to US dollars, so the site currency applies.
* Fix: The Custom amount field shows the form's currency symbol on the live form and in the builder.
* Fix: Yen and other currencies without cents are rounded to whole units in prices, the summary, the charge and the entry.
* Fix: Product and priced option answers in entries, emails and exports show whole units for every currency without cents, such as KRW, not only for JPY.
* Fix: Entries, CSV exports and resent emails show prices in the currency the entry was charged in, so changing the site or form currency later does not relabel older entries.
* Fix: A coupon typed in a Coupon field, or with spaces in it, gives the same total at payment and on submit.
* Fix: A coupon with an unreadable date, or an expiry before its start, is refused with a message.
* Fix: Order quotes, coupon checks and payment intents answer not found for a draft form, like submitting does.
* Fix: Product name, price and quantity settings are under General in the builder.
* Fix: Priced options show no choice as selected on the builder canvas unless one is set as the default.
* Fix: Entries whose payment failed show Payment failed in the entries list and on the dashboard.
* Fix: Admins are asked to connect Stripe when no payment gateway is connected.
* Fix: Payment validation messages can be translated.
* Fix: An order below the smallest card charge for its currency gets a clear message before and at payment.
* Fix: Submissions exported and imported in Tools keep their order, coupon, totals, payment status, gateway and transaction ID, and a failed payment stays failed.
* Fix: Priced options shown as a dropdown use the same picker as other dropdowns, with a name and required state.
* Change: An entry refers to the form version it was sent with instead of storing a full copy of the form, about 1 KB, in its meta. Entry lists no longer carry a form copy. A background job removes the copies older entries hold, a few hundred entries at a time. An older entry whose form version cannot be found keeps its copy, so it stays readable.
* Fix: One formatter turns answers into text for the entry view, emails, CSV exports, PDF data and integrations, so they all read the same.
* Fix: Dropdown, radio, checkbox, picture and priced option answers show their labels. Single checkbox, consent and toggle answers read Yes or No everywhere, including the PDF.
* Fix: Matrix answers name each row and its chosen columns, for example "Speed: Good; Price: OK" and "Mon: AM, PM".
* Fix: Date, time and date and time answers follow the field's display format in the entry view, emails, CSV exports and PDFs.
* Fix: Dependent dropdown answers show the label chosen at each level in emails, PDFs, CRM notes and webhooks, including the full payload of a Webhook action, and in mapped integration fields when the add-on passes the form.
* Fix: Product answers read as order lines with a quantity and price, and priced options show their label and price.
* Fix: CSV exports list uploaded files by name with an admin download link instead of the stored file record.
* Fix: A field with a very long label and no admin label is named by its label shortened to 60 characters in emails, CSV headers, entries, PDFs and the required message.
* Fix: The submissions list names the sender by a name or email answer, or shows Anonymous. A product quantity or a choice is never shown as the sender.
* Fix: The server checks every answer the way the form does. A choice must be one the field offers; dates, times, ratings, scores, sliders, matrix answers, colours and signatures must be real values; a field that takes one value refuses a list; and a read-only field keeps its value.
* Fix: Server error messages use the same words as the form and can be translated.
* Fix: An email field that allows several addresses accepts them separated by commas and stores each one. With RFC validation off, an address such as user@localhost is accepted.
* Fix: A website can be typed without https://, which is added. Only http and https addresses are accepted, in the form and on the server.
* Fix: Pasting an international phone number picks its country, the leading 0 of a national number is dropped, and the server checks the calling code and the length. A +1 number with a Canadian area code shows Canada.
* Fix: A Custom amount outside its minimum or maximum, a Product quantity above its maximum and a Priced option that is not offered are refused, instead of being charged a different amount. A pick-one Priced options field charges one option.
* Fix: A required Rich text field with no text in it is refused.
* Fix: A Repeater with fewer entries than its minimum shows one message, such as "Add at least 2 entries.", instead of errors for fields that were never shown.
* Fix: Hidden field values, including {date}, {user_email} and {user_name}, are worked out on the server, so they are stored when a form is sent without JavaScript.
* Fix: Values sent for an Order summary or Fixed fee field are not stored, so they no longer appear as columns in CSV exports.
* Fix: A builder save that fails names the field as well as the setting, a numeric label, placeholder or default value saves, and long labels wrap on the canvas.
* Fix: A column stored as an object with a fields or children list renders its fields on the live form, includes them in the live total, validates them and gives them defaults, so a product in that column is shown as well as charged.
* Fix: Deleting a field inside a step, container or column shows the Field deleted notice with Undo, and deleting a step counts every field in it.
* Fix: When the forms list fails to load after a change of tab, search, sort or page size, the previous rows are cleared, so Published forms are not shown or actionable under Trash. A failed retry of the same view keeps its rows.
* Fix: When the entries list fails to load after a change of tab, search, date range, form or sort, the previous entries are cleared, so Inbox entries are not shown or actionable under Trash. A failed retry of the same view keeps its entries.
* Fix: In the builder Preview, a desktop form wider than the canvas is scaled into a stage of the scaled size, centred in the canvas, so the whole form stays visible beside the styling panel with no sideways scroll.
* Fix: The Payment Form template's product is set as a fixed product: no quantity box in the builder or on the live form, and the quote, the payment intent and the entry charge it once without a submitted value.
* Fix: The Donation Form template's Custom Amount is required and has a minimum of 1, in the browser and on the server, so an empty or zero amount cannot complete a donation form. A donation template from an add-on gets the same rule unless it sets a higher minimum.
* Fix: Templates from add-ons lose only raw card inputs, found by an id or key such as card_number, expiry or cvv. A field or container whose label or id only mentions a card, such as a Gift card message or a Scorecard, is kept, and so is the Card Payment field.
* Fix: A payment template from an add-on that already prices the order with Priced options, a Custom Amount or a Fixed fee no longer gets a 10.00 fixed product added and charged on top. In a multi-step template, a missing product goes in the first step and a missing Order summary and note go in the last step, instead of beside the steps.
* Fix: The server checks conditional logic against the answers as typed, before a website gets https:// and before email lists and phone numbers are tidied, as the browser does. A rule such as Website equals example.com keeps the fields, priced fields, conditional emails and confirmations it controls. The stored answers are still tidied.
* Fix: The live form refuses a Product quantity that is not a whole number, is below the minimum (including the starting 1 when the minimum is higher) or is above the maximum, with the server's messages, before any card payment is started.
* Fix: A color field saves the color it shows, including its default.
* Fix: Each CAPTCHA field uses its own provider and keys, and the form says when a check is not set up.
* Fix: A form has one CAPTCHA field per provider. Publishing a second reCAPTCHA, hCaptcha or Turnstile field is refused with a message, and the visitor's token is checked once.
* Fix: When publishing is refused because of a field, the builder shows the reason instead of [object Object].
* Fix: Password fields can show a strength meter and ask for the password again.
* Fix: A US phone number is grouped as it is typed, and a short number is rejected.
* Fix: Dropdown, radio and multiple choice start with choices, and the canvas shows the default choice.
* Fix: Choice groups are not tied to a missing control, prefix and suffix text is named for screen readers, and a consent link uses the words already in the sentence.
* Fix: A section heading and custom HTML each take a full row, and column layouts use a real column count.
* Fix: Hidden and color fields no longer repeat the admin label or the default value.
* Fix: Net Promoter Score has a low and a high label, and a Calculation field has a prefix and a suffix.
* Fix: An Action Hook field runs when the form is shown and when it is submitted.
* Fix: Logic for a checkbox, toggle or country offers the real values, and an off toggle counts as empty.
* Fix: The second dependent dropdown lists only the choices that belong to the first answer, and the first dropdown keeps its label.
* Fix: Replacing dependent dropdowns from a file asks first, and a semicolon file imports as separate columns.
* Fix: Dropdown, country, phone and date fields work from the keyboard. The calendar can jump to a month and year, and country buttons show a letter code.
* Fix: The first invalid dropdown, country, date or phone control receives focus.
* Fix: The admin and confirmation email switches apply to every form, and the saved sender is used when an email has no From address.
* Fix: Submitting the form preview does not send email or webhooks, does not count toward the entry limit, and is only available to an administrator.
* Fix: A form block that is not using AJAX submits with a normal page load.
* Fix: A form block that is not using AJAX shows the errors and keeps the answers when a submission is refused, shows the confirmation message once it is accepted, and follows a redirect confirmation only after a successful submission.
* Fix: A form block that is not using AJAX follows a confirmation redirect to another site, as the AJAX form does, instead of sending visitors to the home page.
* Fix: Confirmation messages and redirects fill merge tags.
* Fix: A custom webhook body fills merge tags.
* Fix: Resend says when the email was not queued, and sending it again still sends.
* Fix: Removing a flag or spam label restores the entry status, including a payment status.
* Fix: Delete follows the Trash or Hard setting for forms and entries.
* Fix: The New count follows the form you are viewing, and opening an entry marks it read in the list.
* Fix: Dashboard counts refresh when an entry is saved.
* Fix: Dashboard and reports count from midnight in the site timezone.
* Fix: Autosave uses the interval in Settings, and turning it off stops it.
* Fix: A link to an entry loads that entry even when it is past the first page. The list keeps its tab and search, and Back returns to the list.
* Fix: Confirmation rows use the same spacing as the rest of the builder.
* Fix: A form in a block is the same width as the same form in a shortcode.
* Fix: A theme-styled form uses the theme button, the theme font and the width of the content column, and the builder preview loads the theme fonts.
* Fix: Publishing a form no longer looks unpublished when the only difference is the order of appearance settings.
* Fix: Gravity Forms and Fluent Forms imports keep pages, hidden fields, names and conditional logic, and leave payment, quiz and post fields out.
* Fix: On Tools, choosing a file is one keyboard stop, notices clear when you change section, and forms with the same title show their number and status.
* Fix: Importing entries warns when a file is from another form and skips entries that are already there. The transfer screen says notes, the IP address, the browser, files, logs and unpublished drafts are not in the file.
* Fix: Importing the same entries file again skips entries that were flagged, marked as spam, restored, read or starred since, and two different entries with the same answers at the same time are both imported.
* Fix: A webhook that is still waiting says Queued.

= 2.3.9 - 2026-10-19 =
* Change: Reports show real numbers only.
* Change: Global functions and transients use the subtleforms_ prefix.
* Fix: Webhook retries and the default signing secret follow Settings, Integrations, Webhooks.
* Fix: Visitors can send a form from a page served by a page cache. The spam time check uses a token signed by the server, so a wrong device clock no longer blocks a person, and a bot cannot skip it.
* Fix: Form views from visitors are counted for Reports, and a trashed or draft form refuses entries with a not found answer.
* Fix: The entry view shows the label of the chosen option, as emails do, and Yes or No for consent, single checkbox and toggle answers.
* Fix: The Preview tab keeps the form centred and fully visible beside the styling panel on laptop screens.
* Fix: An HTML block's markup in its settings goes through the WordPress post content filter on save, and every HTML block is filtered again when the live form loads.
* Fix: Answers the server refuses are not stored as failed entries, and the spam fields are never part of an entry.
* Fix: Deleting a form deletes its entries, uploaded files, activity logs, schema versions and view totals. The retention purge removes logs too.
* Fix: The personal data export and erase tools match the exact email address and show the form name.
* Fix: Imported forms and entries are cleaned like a builder save. A form export never leaves forms out without saying so.
* Fix: The API log skips unknown routes and visitor traffic, and is capped. The submit route has its own rate limit.
* Fix: A numeric HubSpot Portal ID no longer blocks saving Settings.
* Fix: Uploads use the WordPress upload and filesystem functions, and new sites store files in a folder with a random name.
* Fix: Name and Address part settings are kept, drawn and checked the same way in the browser and on the server.
* Fix: Notice, Section heading and Page break settings show in the builder, and a step shows its description.
* Fix: Files uploaded inside a Repeater are kept with the entry and linked in the entry and email.
* Fix: Dependent dropdown values come from their labels, a new choice never reuses an old value, the Columns layout does not pre-fill an answer, and every level of a required dependent field is required.
* Fix: Priced fields hidden by conditional logic are not charged, and a hidden Fixed fee is not charged or listed.
* Fix: For card payments, emails and integrations run only after the payment goes through. A failed payment emails the site owner instead.
* Fix: The builder notes when a priced form has no Card Payment field and will save entries as Payment pending.
* Fix: Every template emails the site owner instead of posting to an example address. The Payment form has a product and an order summary, without card number fields, and the Donation form has a custom amount.
* Fix: The builder header, preview, conversational choices, coupon field and presets fit and stay readable. Failed loads and saves show Retry. The builder shows a placeholder while loading. Deleting a field can be undone. Quick Start creates the form. Last 7 days matches on the dashboard and Reports.
* Fix: Charts have a text summary, Rows per page has a name, muted text is readable, and a hidden field toolbar is out of the tab order.
* Fix: The AI assistant settings tab is removed. It reported a successful connection for any key and blocked saving other settings.
* Change: SubtleForms requires WordPress 6.6.
* Fix: Deleting the plugin removes its tables, options, transients, uploads and scheduled tasks on every site in a network.
* Fix: Text in the admin and on the public form can be translated with a language pack.

= 2.3.8 - 2026-10-19 =
* New: Dependent dropdowns open in a column editor. Each column is one dropdown, and choosing an item shows only what belongs to it.
* New: On the form, a chained field can be dropdowns, buttons, or columns. Columns show every list at once. The first choice is selected, and a list with nothing for that choice stays empty.
* New: Chained choices can be typed in, or replaced from a CSV file. An example file is there to download, and the current lists can be downloaded too.

= 2.3.7 - 2026-10-18 =
* New: The submissions list can open an entry beside or below the inbox. Previous and Next follow the current tab, search and filters, and the address keeps the open entry.
* New: List density can be comfortable, default or compact. The gear on Submissions saves that choice for the current admin. Settings → General sets the default for everyone else.
* New: Hidden is in the field library. Visitors never see it. The value is stored with the entry and sent to notifications and integrations, and it can use {user_email}, {user_name}, {date} and {get:param}.
* New: Repeater, Group and Columns use the same field toolbar as other fields: move up or down, move into a container, width, duplicate and delete.
* Fix: A field label can be a short paragraph. A consent line longer than 255 characters now saves. The limit is 2,000 characters, and a save error names the field label when it is too long.

= 2.3.6 - 2026-10-18 =
* New: Tools exports and imports SubtleForms forms and submissions as JSON, and imports Gravity Forms and Fluent Forms exports as drafts. Payments, quizzes and add-ons are skipped and listed.
* New: Tools shows activity logs, webhook calls and a 30-day log of SubtleForms REST calls. Request and response bodies are not stored in the API log.
* New: Reports shows how many forms, submissions and unread entries you have, and submissions for the last 7 days.

= 2.3.5 - 2026-10-18 =
* New: Appearance can inherit the active theme. The preset and the custom controls use the theme's type, colours and content width, and a custom value still overrides the theme.
* Change: Preview names Desktop, Tablet and Mobile, with the same icons as the fields. Widths come from the theme when it sets them, otherwise 1280, 768 and 390, and each size stays distinct.
* Fix: Inline layout wraps fields instead of crushing them onto one row. A single email and button still sit on one row on a wide screen and stack on a phone.

= 2.3.4 - 2026-10-17 =
* Change: Form settings use vertical tabs across the full width, with each area on its own panel. Notifications is its own tab.
* New: Country, dropdown, date, time and date-time fields use a custom picker. Stored dates and times stay in the same format, and an optional choice can be cleared.
* Fix: The phone field keeps the country a visitor picks, including before any digits are entered and when two countries share a dial code such as +1. Turning flags off is saved with the form.
* Fix: A new chained choice skips values already used on that dropdown, so removing one and adding another does not reuse an identifier.
* Fix: The builder canvas shows dropdown choices and the country list. Undo still restores a form after the last page break is removed, and the WordPress menu reads SubtleForms.

= 2.3.3 - 2026-10-14 =
* Fix: A drawn signature shows as the signature image in the entry details and in a Repeater table instead of a long line of code. HTML notification emails show the signature as an embedded image that mail apps display, plain text emails say "Signed", and CSV exports write "Signed" instead of the image code. The PDF already showed the image and is unchanged.
* Fix: One submit stores one entry. Pressing Enter on the focused Submit button of a conversational form, or double clicking Submit, could send the form twice and store the entry twice.
* Fix: The entries list no longer shows an entry twice or puts back a change you just made, such as a star or a move to the Trash, when a background refresh or an earlier request finishes late.
* Fix: With no AI provider saved yet, the AI settings show the OpenAI help and model choices that match the OpenAI provider shown in the menu, not the custom endpoint help.
* Fix: Conversational forms submit again. The live form sent its answers to a wrong address and nothing was saved.
* Fix: Form shadows are removed on the live form, the preview and the builder canvas, and the canvas background is white.
* Fix: The preview device buttons show the selected size again. The preview stage is full width and the form inside is 960px, 768px or 380px wide. Submitting the preview saves an entry, runs the form's actions like a live submission and works for draft forms when you are signed in as an administrator.
* Fix: Matrix rows and columns stay in place after leaving Preview.
* Fix: Date limits, the number step, the phone format, the slider default and required matrix rows are checked in the browser and on the server.
* Change: Field settings are ordered General (label and help text), Appearance, then Advanced.
* Fix: Name and address no longer use a legend. Country, Dropdown and Chained Select show their configured options. Toggle has an enabled or disabled default and starts disabled.
* Fix: Saving settings keeps a valid autosave interval and names the setting when a value is out of range. Sender and admin email addresses may be left empty.
* Fix: A charged calculation that cannot be worked out is refused instead of becoming a free order.
* Fix: Coupon percentages above 100 and negative usage limits are refused in the editor and on the server.
* Fix: An empty Trash has its own message, and the dashboard form selector lists every form instead of the 10 most recently updated.

= 2.3.2 - 2026-10-13 =
* Fix: Creating a form from some templates opened an empty form, for example Volunteer Signup, Event Registration and Vendor Application. Those templates used a single checkbox with a list of options, which the server refused, and the refusal was not reported. Such a checkbox is now saved as a Checkboxes (Multiple choice) field, every template creates its full form with its fields, settings, notifications and type, and a form that cannot be created shows the reason and leaves no empty form behind.
* Fix: The form type follows the form. Adding the first Page Break to a Standard form makes it Multi-step, and removing the last one makes it Standard again with every field kept. The builder badge, the Settings tab, All Forms, the dashboard, the entry details and the live form all show the same type, and a message with Undo tells you when the type changes. Forms saved by older versions are corrected when the plugin updates.
* New: A Form type setting on the Settings tab. Changing a Standard form to Multi-step puts every field in a first step. Changing a Multi-step form to Standard or Conversational removes the steps and keeps every field in order, after you confirm.
* Fix: A new conversational form now starts with "Add your first question" instead of a block that could not be edited or removed. Every question, a welcome screen too, can be edited, replaced with another field, moved earlier or later, duplicated and deleted. Clicking a field in the panel fills an empty question, and otherwise adds a new question right after the one you are on. Add question makes an empty question where you are.
* Fix: The live conversational form asks the same questions in the same order as the builder shows, says "Question 2 of 5", treats a Group or Repeater as one question and checks each question with the same rules and messages as other forms.
* Fix: The label and help text of a Repeater, Group and Columns can now be edited in their settings. They are saved and show in the builder and on the live form, with the container's own settings such as the Repeater button label and limits.
* New: Every field has a Field label visibility setting. Visible shows the label above the field. Hidden hides it from view but keeps it for screen readers, so the field still has a name. This replaces the Hide label option of the Style tab, and fields that used it keep their hidden label.
* New: Every field with help text has a Help text placement setting, below or above the input, on the builder canvas and on the live form.
* New: Every input field has a Custom validation message, shown when an answer is filled in but not valid, for example a wrong email address, a number out of range or text that does not match the pattern. It replaces the pattern message of text fields. Every input field also has the message for when it is left empty, and the server uses both messages too.
* New: Field defaults on the Settings tab set the label visibility, help text placement and both messages for every field that does not set its own.
* Fix: The Admin label of a field is now used everywhere it should be: entries, notification emails ({all_fields}), CSV export, the PDF and data sent to integrations, webhooks and Zapier. Hidden fields and Repeaters have an Admin label too.
* Fix: Group and Columns fields, which are no longer in the field library, showed no settings in the builder. Their settings are back.
* Fix: Custom HTML fields show their content on the builder canvas instead of a placeholder.
* Developer: New helpers SchemaRepair::checkboxListsToMultipleChoice(), SchemaRepair::syncType() and FieldMapper::adminLabel(). FieldMapper::fields() rows carry the admin label as "label" and the public label as "public_label". Form metadata accepts labelVisibility, descriptionPlacement, requiredMessage and validationMessage.
* Database: When the plugin updates, the type stored with each form is set from its structure (Multi-step when it has a Page Break, Standard when it has none). Conversational forms are not changed. No tables or columns are added.

= 2.3.1 - 2026-10-12 =
* Fix: Adding a Page Break to a form hid every existing field behind a new empty step. A Page Break now splits the form where it is placed: the fields above it become step 1 and the fields below it the next step. Added at the very top, the existing fields stay in step 1 and the break starts an empty step 2 after them. Undo and Redo reverse the whole change in one step.
* Fix: Forms saved by older versions with fields outside every step are repaired when they are opened in the builder and when the live form loads. Those fields move into the first step with their order, keys, settings and conditions kept, and the builder says so until you save.
* New: Every field of a multi-step form has a Step setting in its General settings. Choosing another step moves the field to the end of that step, keeps its key, settings, conditions and payment links, switches the canvas to that step and keeps the field selected. You can also drag a field onto a step tab.
* Fix: Repeaters now work for visitors. Add and Remove buttons use your button label and respect the minimum and maximum number of groups. Each group has its own inputs, names (for example companies[0][ticker]), required checks, errors and conditions, focus moves to the new group or the next one after a removal, and the buttons have clear names for screen readers. This works on the live form, in the builder Preview and in the block editor preview, and on phones.
* Fix: The server checks every Repeater group on its own and stores the answer as a list of groups. Entries show the groups as a table, emails list them under {all_fields} (a table in HTML emails), and the PDF data includes each group.
* Change: CSV export gives a Repeater one column per child field, named "Repeater label: Child label". Each group is one line inside the cell, in the same order in every column of that Repeater, so line 2 of every column belongs to group 2. Exports that mix several forms write each group as a numbered line such as "1. ticker: AAPL; shares: 8".
* Fix: Fields could not be dragged into a Repeater, Group or columns because pressing anywhere on the container started dragging the container. Containers now accept drops into their drop zone, only the container handle drags the container, the zone that will take the drop is highlighted (also inside nested containers), and fields can be dragged in and out of containers and from the field library. The new Move to menu on each field toolbar does the same from the keyboard.
* Fix: Clicking a field inside a Repeater, Group or columns, or pressing Enter on it, opened the container's settings. It now opens the field's own Settings, Validation, Logic and Style, and the container is still selected from its header.
* Fix: The Trash tab of All Forms showed trashed forms as Draft with the normal actions. They now show as Trashed with only Restore and Delete permanently (which asks first), in the row menu and as bulk actions. Restore returns a form to the status it had before, and tab counts refresh. A trashed form does not show or accept entries.
* Fix: Duplicating a form failed for multi-step forms with an empty step. Duplicate now runs on the server in one request for any form, including multi-step, Repeater and payment forms. The copy gets a new ID, Draft status and the title with " (copy)", no entries are copied, and a failure shows the actual reason and leaves no half-made copy.
* Fix: A new blank form starts with a working admin notification sent to {admin_email} with the subject "New entry: {form_title}". An email action without a recipient or subject shows "Needs setup", its warnings only show while it is switched on, and it never blocks saving.
* Fix: A payment form priced by Product or Priced option fields failed every autosave with "Unsaved changes" and "Retry autosave", because saving required a fixed amount or an amount field and dropped the checkout settings. Such forms now save, and a failed save names the setting at fault.
* Fix: Save and validation notices of a form are cleared when you leave the form, and no longer follow you to other screens.
* New: Entries Trash. Deleting an entry, alone or in bulk, moves it to a new Trash tab where it can be restored to its previous status or deleted permanently. The Trash is emptied automatically after 30 days by the daily cleanup; change the number of days under Settings > Advanced. Entries in the Trash are left out of counts, limits, exports, analytics and the dashboard, and cannot be resent.
* Change: The Number, Slider and Payment Amount fields call their increment setting "Step size", so it is not confused with form steps.
* Developer: New REST routes POST /forms/{id}/duplicate and POST /submissions/{id}/restore. DELETE /submissions/{id} moves the entry to the Trash unless force=1 is passed. New actions subtleforms/form/duplicated, subtleforms/submission/trashed, subtleforms/submission/untrashed and subtleforms/schema/repaired_orphans. FieldMapper::answers() rows for a Repeater carry a "groups" list for renderers that draw a table.
* Database: Adds a trashed_from column to the forms table and trashed_from and trashed_at columns to the entries table. They are added automatically when the plugin updates; no data is changed.

= 2.3.0 - 2026-10-11 =
* New: An integration log with Retry on each entry, a webhook delivery log and "Send test contact" in the form integrations.
* New: Email merge tags. An "Insert tag" menu in the email settings adds {all_fields}, {field:key}, {form_title}, {entry_id}, {site_name}, {admin_email} and {date} at the cursor. Single and double braces both work, so {{all_fields}} and forms made before 2.3 keep working. The help menu explains every tag.
* New: Emails can be sent as HTML, with line breaks kept and {all_fields} drawn as a table. An empty message now sends every answer instead of raw data.
* New: Newsletter template with one email field and the button on the same row, an inline field layout for any form, and a Dark surface appearance preset for footers and hero sections. Previews show dark-surface forms on a dark background.
* New: Entries can be starred, with a Starred tab. Bulk actions for read, unread, star, spam, flag, delete and export selected use one request, and bulk delete asks first.
* New: Private notes on each entry, with author and date.
* New: Resend notifications from an entry, using the answers as they were saved.
* Performance: The signature pad and rich text editor are downloaded only on pages whose form has those fields. Pages without a form load nothing from SubtleForms.
* Accessibility: Every field type passes automated axe checks (WCAG 2.1 AA) before and after a failed submit, on desktop and phone widths. Rating stars, matrix rows and choice groups now have proper names, step navigation no longer claims to be a tab list, and dates no longer suggest a birthday autofill.
* Fix: Label colour, input text colour, focus ring, button text colour and button radius from the Appearance panel were dropped on save. They are now kept.
* Fix: Button text colour now applies to every button style.
* Fix: A form whose only fields were, for example, a Signature or Rich text field could not be published. Any field that takes an answer now counts, including fields inside columns.
* Fix: Template descriptions and some admin text used long dashes; they read as plain sentences now.
* Developer: New REST routes POST /submissions/bulk, POST and DELETE /submissions/{id}/notes and POST /submissions/{id}/resend. Export accepts a list of entry IDs.
* Developer: A Tests workflow runs PHPUnit, Jest and the Playwright and axe browser tests against WordPress (wp-env) on every push.

= 2.2.1 - 2026-10-11 =
* Fix: If a card payment was authorised but the entry could not be saved (database error, spam check, CAPTCHA or validation), the hold on the card is now released.
* Fix: Card declines are shown next to the card field and every other answer stays in the form.
* New: Coupons can be limited per customer, and the Order Summary shows how many uses are left and when the coupon expires.
* Fix: Setting a field's width no longer drops its required setting, options, placeholder or help text on the live form. Width only changes the layout.
* Fix: Errors found by the server are shown on each field, which is marked invalid, linked to its message and focused. The message above the form now reads "Please fix the 4 highlighted fields."
* Fix: The Country field lists every country again. It and the Address field share one country list.
* Fix: Paragraph answers keep their line breaks in entries and in emails. HTML emails show them as line breaks.
* Fix: Rich text answers keep paragraphs, line breaks, bold, italic, lists and links.
* Fix: Passwords are never stored as typed. Entries show "Password provided", a field can opt in to storing a one-way hash, and passwords are left out of emails and CSV exports.
* Fix: A single checkbox saved with a list of options shows those options. The builder turns it into a Multiple choice field and explains why, and such a checkbox can no longer be published.
* Fix: New Matrix fields start with two rows and three columns. An empty matrix shows a hint in the builder and is hidden on the live form.
* Fix: A Calculation field without a formula shows a hint in the builder and is hidden on the live form.
* Fix: An empty Disclaimer is hidden on the live form and shows a hint in the builder.
* Fix: Every input has a name, so forms work with browser autofill and password managers.
* Fix: The builder shows "Published", "Published, changes not live" or "Draft" correctly, and asks "Push your changes live?" before updating a live form.
* Fix: The field width button has a label for screen readers that follows the chosen width.
* Fix: Toggle, Opinion scale, Picture choice, Signature and Calculation answers were not sent with the entry. They are now saved.
* Fix: The spam trap field has a random name and no visible label text, so autofill does not fill it.
* Fix: Email subjects stay on one line.
* Readme: Describes what the free plugin does in 2.2.

= 2.2.0 - 2026-10-11 =
* New: File and image uploads work end to end: files upload as soon as they are picked, are checked for type and size, stored under random names in a protected folder, downloaded by admins through a secure link, and deleted with the entry or by data retention
* New: Conditional logic rebuilt with one rule engine shared by the browser and the server. Hidden fields are no longer validated or stored
* New: Form analytics: views, submissions and conversion rate per form
* Fix: Conditional logic rules saved in the builder were not applied on the live form
* Fix: Visitors who were not logged in did not get a form's custom confirmation
* Fix: Integration settings never loaded because extensions booted too late
* Fix: CSV export used the newest entry's columns only, broke nested values and accented characters, and could carry spreadsheet formulas; all fixed
* Developer: `subtleforms/submission/completed`, `subtleforms/submit/response`, `subtleforms/public_schema`, `subtleforms/payments/external`, `subtleforms/payments/line_items`, `subtleforms/email/attachments` and `window.SubtleFormsExtend` for add-on field types

= 2.1.0 - 2026-10-11 =
* New: Payments that add up on the server. Product (price and quantity), Priced Options (radio, cards, dropdown or checkboxes with a price per option), Custom Amount and Fixed Fee fields feed one live order
* New: Order Summary lists every item with subtotal, discount, tax and total as visitors fill the form, with a coupon box right under the total
* New: Coupons. SubtleForms › Payments manages percentage or fixed discounts with minimum order, usage limits, start and end dates and per-form rules. Codes are checked when applied and again on submit, and a use is counted only when the order goes through
* New: Card Payment field for gateways (Stripe). Entries keep the full order and payment status, shown in an Order panel on the entry
* New: Calculation fields can be charged ("Charge this amount")
* New: Payments screen with gateway status, setup guide and the coupon manager
* New: The builder canvas is now what you see is what you get: form and field styling (colours, radius, input style, label position, spacing) shows on the canvas as you change it
* New: Field widths (Full, 3/4, 2/3, 1/2, 1/3, 1/4) from the field toolbar place fields side by side, replacing column containers in the field library. Forms that already use columns keep working
* Developer: `subtleforms/payments/quote`, `subtleforms/payments/validate_coupon`, `subtleforms/payment/verify`, `subtleforms/payment/capture`, `subtleforms/payment/void`, `subtleforms/payments/gateways` and `subtleforms/frontend/enqueued`
* Fix: Plugin Check findings (escaped exception message, sanitising kept field settings with wp_kses_post, annotated counts query)

= 2.0.0 - 2026-10-11 =
* Redesign: New admin built on the WordPress 7.1 admin look: dark frame, white stage, top navigation, admin colour scheme accent and WordPress components throughout
* Redesign: Dashboard with KPI strip, 14-day submissions chart, quick actions and system status
* Redesign: Forms and Submissions lists rebuilt as data views with tabs, column picker, filters and row actions; submissions lead with the sender, not an ID
* Redesign: Submission detail as a reading pane with answers, activity tabs, previous/next, read/unread, flag and delete
* Redesign: New form screen is now a template library with wireframe previews and a one-step naming dialog
* Redesign: Settings use grouped navigation, setting cards and a floating save bar (Ctrl/Cmd+S saves)
* Redesign: Extensions page is now grouped by job, with clear off, needs-setup and active states
* Builder: Gutenberg-style three-panel editor with field library, canvas and tabbed inspector (Settings, Validation, Logic, Style)
* Builder: Choices editor with drag to reorder, default selection, value column, bulk edit and image options
* Builder: Form settings gain After submit (message with merge tags or redirect, submit button text) and Availability (logged-in only, open and close dates, entry limit)
* Fields: New Toggle and Opinion Scale fields.
* Fields: New settings on existing fields: help text, default value tokens, prefix and suffix, min and max length, pattern, choice limits, option layouts, custom required message, admin label, read-only and CSS class
* Fields: Field library reorganised and renamed; rarely used and duplicate field types hidden from the library (existing forms keep working)
* Fix: Field settings not declared in the validator (conditions, min/max, formulas and more) were dropped on save; they are now kept and sanitised
* Fix: Publishing could replace the latest changes with an older autosave draft
* Fix: Unread counts used a status value that submissions never have; counts now use the read flag
* Fix: Marking a submission unread overwrote its processing status
* Appearance: Nine style presets drawn as live mini previews, plus a Custom mode for every colour, font, field, button and layout setting
* Appearance: New tokens for label colour, input text, focus ring, button text and button radius
* Appearance: Field Style tab with a live sample, visual width picker and colour chips that show the inherited value
* Fix: The builder preview did not update when appearance or fields changed
* Fix: Admin hover colours leaked into the WordPress menu and button labels
* Fix: Modal titles were invisible when the computer used dark mode
* Fix: Dates are stored in UTC so relative times are correct in every timezone

= 1.9.2 - 2026-09-29 =
* Design: Adopted the WordPress Design System: accent now follows the site's admin colour scheme via --wp-admin-theme-color
* Design: Switched to the WordPress system font stack; removed DM Sans, Satoshi and JetBrains Mono webfont enqueues
* Design: Neutrals retinted to the WordPress admin grey ramp; flatter radii (4px) and minimal shadows
* Design: Borders, text and surfaces aligned to native WordPress admin values

= 1.9.1 - 2026-09-29 =
* Block: New inspector options: show title/description toggles, Form Theme dropdown with live preview, Reset to defaults, Advanced (AJAX, Tab Index, Field Values)
* Block: Editor preview now matches the frontend (removed divergent editor-only styling; frontend stylesheet drives both)
* Block: Theme, title/description, AJAX, tab index and prefilled field values now flow through to the frontend render
* Fix: "Last updated" on the forms list showed ~5h off because naive UTC datetimes were parsed as local time
* Fix: Search and other admin inputs no longer render in JetBrains Mono (regression from 1.9.0)
* Fix: Loading spinner re-skinned to the indigo brand and uses the sans font
* Builder: Appearance sidebar in the Preview tab now uses native Gutenberg PanelBody panels
* Field: New dedicated Disclaimer field (info/warning/success/neutral variants) with its own icon

= 1.9.0 - 2026-09-29 =
* UI: New indigo design system (#4F46E5 brand, #A5B4FC accent, #1E1B4B text)
* UI: DM Sans for headings, Satoshi for body text, JetBrains Mono for code areas
* UI: Enqueued webfonts (Google Fonts + Fontshare) the WordPress-standard way
* UI: Re-skinned primary buttons, toggles, focus rings, and card hovers to indigo
* UX: Every field type now has a unique icon: no repeated icons across fields
* Compliance: Aligned Stable tag with plugin version (1.9.0)

= 1.8.1 =
Releases between 1.6.10 and 1.8.1 were not tagged individually, so the changes
below are recorded as one entry rather than split across versions that cannot
now be reconstructed accurately.

* Submissions: unread badges, spam and flagged statuses, column visibility, relative timestamps, per-field filtering and date-range export
* Submissions: chunked prefetch pagination for large lists
* Submission detail: two-column layout, actions timeline, and pipeline logs enriched with action data
* Builder: structured group fields as container nodes, with a hierarchy system for nested fields
* Builder: configurable composite fields, field identity icons, and a rebuilt field picker with search
* Builder: live preview mode
* Templates: free templates expanded from 2 to 11 across 5 categories.
* Settings: tab routing via URL hash
* Database: is_read migration for the submissions table
* Accessibility and onboarding persistence fixes throughout

= 1.6.10 - 2026-01-16 =
* Security: Added REST API nonce verification for CSRF protection
* Security: Implemented rate limiting on public submit endpoint (10 req/min per IP)
* Compliance: Registered privacy policy content for data collection disclosure
* Fix: Added missing validation rules for spam and privacy settings

= 1.6.9 - 2026-01-15 =
* UX: Improved country field preview rendering with sample countries
* Fix: Extended CAPTCHA HTML injection for all provider field types (recaptcha, hcaptcha, turnstile)
* Fix: Frontend CAPTCHA renderer now supports all provider types

= 1.6.8 - 2026-01-15 =
* UX: Added CAPTCHA preview placeholder in form builder and preview modal
* UI: Shows "CAPTCHA will appear here" message instead of empty field

= 1.6.7 - 2026-01-14 =
* Chore: Stable architecture freeze point
* Admin: UI and styling baseline established

= 1.6.6 =
* Feature: Added country field with full ISO-3166 country list
* Feature: CAPTCHA system with support for reCAPTCHA, hCaptcha, and Turnstile
* Enhancement: Improved spam protection with honeypot and time validation

= 1.6.5 =
* Enhancement: Improved form builder responsiveness
* Fix: Field validation errors now display correctly
* Fix: Submission export CSV format improvements

= 1.6.0 =
* Feature: Multi-step form support
* Feature: Conversational form type
* Feature: Sectioned form layout
* Enhancement: Redesigned form builder interface

= 1.5.0 =
* Initial public release
* Feature: Visual form builder
* Feature: Submissions management
* Feature: REST API endpoints
* Feature: Basic spam protection

