== Changelog ==

= 2.1.0 =
* **Admin UI modernization** — Comprehensive redesign of the form editor and settings pages for a more coherent design language, aligned with native WordPress admin patterns.
* **Form editor**: Flat single-level tab bar replacing the previous nested two-level tab system. Six tabs: Fields, Appearance & General, Messages, Data Retention, Google Ads, Tokens.
* **Form editor**: CSS Grid-based layout for the field editor and live preview, replacing the old float-based 50/50 split.
* **Form editor**: Native WordPress title markup (`#titlewrap`) for the form title input.
* **Settings page**: Tab navigation with ARIA-compliant accessible tabs — Default Messages, Integrations, Privacy, Layout & Styling, Theme Helper, Danger Zone, Tokens.
* **Postbox structure**: All settings sections now use native WordPress `.postbox` + `.postbox-header` + `.inside` markup instead of custom wrappers.
* **Messages tab**: All four message postboxes displayed in a 2×2 grid layout. Radio buttons wrapped in `<fieldset>` with clickable `<label>` elements for better accessibility.
* **Messages tab**: TinyMCE editors now include a font family selector with 10 email-safe fonts (Arial, Arial Black, Comic Sans MS, Courier New, Georgia, Lucida Sans, Tahoma, Times New Roman, Trebuchet MS, Verdana). Link/unlink buttons added to the toolbar.
* **Default messages**: Default font changed from Lucida Sans to Arial for new forms. Removed overstylized wrappers (padding, background, border) from success and error message templates. Removed grey background from admin notification email template.
* **Default message preview**: Faithful rendering of email content — no longer strips inline styles.
* **CSS consolidation**: Merged `dashboard.css` into `admin.css`. Removed dead CSS selectors and legacy rules.
* **Bugfix**: Fixed broken CSS selectors caused by `accuaTabs` component renaming panel IDs — replaced `#accua_tab_*` selectors with `[data-tab="*"]` attribute selectors.
* **Bugfix**: Fixed Messages, Data Retention, and Tokens panels not properly contained within the tab system on the form editor page (unclosed `<div>` tags).

= 2.0.0-rc.3 =
* **Improvement**: Danger Zone moved to right column on Settings page, visible to administrators only
* **Improvement**: Bulk anonymize now shows a per-form preview with submission counts before confirming
* **Translation**: Complete Italian and Spanish translations (98% coverage)

= 2.0.0-rc.2 =
* **Bugfix**: Upgrade migration from 1.9.x — added data migration in `$old_db_version < 14` block: renames form `name` key to `title`, converts `fields` from CSV string to array, removes legacy `fieldnum` key.
* **Bugfix**: Submissions page — removed column header now uses translatable `%s (removed)` format instead of concatenated slug (e.g. "Email (removed)" instead of "emailrimosso").
* **Translation**: Updated Italian translations for removed column label.

= 2.0.0-rc.1 =
* Release candidate. See readme.txt for the full 2.0 feature summary.
* **PCP Compliance**: Fixed stable tag mismatch, added translators comments, replaced rmdir() with WP_Filesystem, added phpcs:ignore for shortcode output escaping.
* **Improvement**: Deactivation modal — anonymize now asks for confirmation before proceeding, "Just deactivate" button visually prominent.
* **Removed**: test-gdpr-deep.php from distribution.

= 2.0.0-beta.73 =
* **Bugfix**: Textdomain loading timing — moved `load_plugin_textdomain()` to `init` hook (was `plugins_loaded`), removed redundant call from `accua_form_init()` and `accua_forms_install()`. Fixes WordPress 6.7+ `_load_textdomain_just_in_time` notice.
* **Bugfix**: dbDelta `TEXT DEFAULT` warnings — removed `DEFAULT ''` from TEXT columns in CREATE TABLE statements. MySQL strict mode forbids default values on TEXT/BLOB columns.
* **Bugfix**: Deactivation "Delete all data" now properly cleans up — added `accua_forms_lastid` and `accua_form_api_keys` to deletion list, added transient guard to prevent `accua_forms_check_db_version_and_update()` from re-creating data during the deactivation redirect.
* **Bugfix**: Prevented double `accua_forms_install()` execution on activation (once from `plugins_loaded` version check + once from activation hook) via static guard.
* **Translation**: Added Italian translations for all Danger Zone and deactivation modal strings (25 new strings). Updated custom validation message strings.

= 2.0.0-beta.72 =
* **Bugfix**: File upload field — added `accept` attribute on the native `<input type="file">` so the browser file picker filters by allowed extensions (was only set on the JS wrapper via `data-accept`)
* **Bugfix**: File upload field — server-side extension validation is now case-insensitive (e.g. uploading `FILE.PDF` matches allowed extension `pdf`)
* **Improvement**: Extension override input now normalizes entries: strips leading dots and lowercases (`.PDF` → `pdf`)

= 2.0.0-beta.71 =
* **Improvement**: Data Retention tab in form editor — moved global default info to a description line below the override checkbox for clarity
* **Bugfix**: Danger Zone — fixed vertical alignment of the period dropdown (select) with adjacent input and button

= 2.0.0-beta.70 =
* **Feature**: Deactivation data cleanup modal on the Plugins page
  - Intercepts the "Deactivate" click and shows a modal with three options:
    - **Just deactivate** — keep all data, can reactivate later
    - **Anonymize all submissions** — replace personal data with placeholders, set IPs to 0.0.0.0
    - **Delete all data** — permanently remove forms, submissions, settings, and uploaded files (with extra confirmation)
  - Cancel button and overlay click to dismiss
* **Refactor**: Extracted `_accua_forms_delete_all_plugin_data()` helper to share deletion logic between Danger Zone and deactivation modal

= 2.0.0-beta.69 =
* **Feature**: Danger Zone section on settings page
  - Bulk anonymize submissions older than a configurable period (days/months/years) across all forms
  - Delete all Contact Forms data (settings, forms, submissions, uploaded files) with domain-name confirmation prompt
  - Both operations use AJAX with clear success/error feedback

= 2.0.0-beta.68 =
* **Bugfix**: Simplified IP anonymization — writes `0.0.0.0` directly instead of read-then-anonymize, eliminating an unnecessary DB query

= 2.0.0-beta.67 =
* **Feature**: All columns in the form list table are now sortable (From Email, From Name, Admin Email, BCC Email, Data Retention, Shortcode, PHP Code)
  - Retention column sorts by underlying seconds value for correct numeric ordering
  - Shortcode and PHP Code columns sort by form ID (since values are ID-derived)
  - Invalid orderby parameters safely fall back to ID sort

= 2.0.0-beta.66 =
* **Feature**: Per-form data retention tab in form editor — new "Data Retention" tab after Fields / Messages
  - Shows current global default summary
  - "Override default data retention" checkbox to enable per-form settings
  - Retention period (days/months/years) and mode (anonymize/delete) controls
* **Feature**: Data Retention column in form list — shows effective retention for each form
  - Displays per-form override or global default with human-readable format
* **Bugfix**: Fixed mixed-language dropdown in retention settings ("days, mesi, years" → properly translated)
* **Translations**: Italian translations for all data retention and GDPR privacy strings

= 2.0.0-beta.65 =
* **Bugfix**: Anonymized notes now show `[Anonymized]` instead of WordPress's generic `[deleted]` — consistent with field value anonymization

= 2.0.0-beta.64 =
* **Feature**: Submissions list table upgraded to full WP_List_Table native features
  - All columns sortable (SQL-level sorting with clickable headers)
  - Custom field columns sort via LEFT JOIN, with NULLs pushed to end regardless of direction
  - Row actions on ID column: View, Move to Trash / Restore, Permanently Delete (with confirmation dialog)
  - Per-page screen option: users can set items per page (default 100, saved per-user)
  - Removed fields separated into collapsible "Removed Fields" section in Screen Options
  - Primary column set to ID for WordPress responsive table support
  - Empty state message: "No submissions found."
* **Improvement**: Anonymized field values now show `[Anonymized]` instead of WordPress's generic `[deleted]` — clearer intent, properly translatable per-plugin
* **Translations**: Italian translations updated for all new strings

= 2.0.0-beta.63 =
* **Feature**: GDPR data anonymization and retention system
  - WordPress Privacy API integration: personal data exporter and eraser
  - Configurable data retention: global + per-form override (days/months/years), mode (anonymize or delete)
  - WP-Cron automated cleanup of expired submissions
  - Manual anonymization: single submission button (AJAX) + bulk action on submissions list
  - Privacy policy suggestion text via `wp_add_privacy_policy_content()`
  - Uses WordPress standard `wp_privacy_anonymize_data()` per field type
* **Architecture**: Anonymization stored as independent boolean (`afs_anonymized` column), orthogonal to trash status — anonymized submissions stay in active views and dashboard statistics
* **UI**: Single submission page redesigned to WordPress admin standards with 4-state action matrix (Anonymize/Trash/Restore depending on state)
* **CSS Version**: 148
* **DB Version**: 14

= 2.0.0-beta.62 =
* **Bugfix**: Fixed PHP 8.x "Undefined array key" warnings on the Submissions list page — added missing `isset` check for field `name` key in column headers, and added array bounds guard when parsing `_wp_http_referer` parameters

= 2.0.0-beta.61 =
* **Bugfix**: Sidebyside layout (labels on left) converted from flexbox to float-based layout for backward compatibility — custom JS using `.css('display', 'block')` to show hidden fields no longer breaks the label/field alignment
* **Bugfix**: Single checkboxes in sidebyside forms now left-aligned instead of indented at 25% margin — elements without a label div (`.pfbc-fieldwrap:first-child`) skip the label column offset
* **Bugfix**: Checkbox inputs (`.accuaform-fieldtype-checkbox`) now have consistent minimum size (`1rem`) and no left margin across all browsers and layouts
* **CSS Version**: 147

= 2.0.0-beta.60 =
* **Bugfix**: Fixed client-side validation treating "-" as empty in all field types — now only select dropdowns treat "-" and "Select..." as unselected; text inputs, textareas, and other fields accept "-" as a valid value
* **JS Version**: 93

= 2.0.0-beta.59 =
* **Updated Chart.js** from v3.5.0 to v4.5.1 — dashboard charts now use the latest Chart.js release
* **JS Version**: 92

= 2.0.0-beta.58 =
* **Custom validation messages**: Override default required and format validation messages at field definition and per-form level
  - Field-level overrides on the Fields page: set custom required message and custom format message for each field definition — applies everywhere that field is used
  - Per-form overrides in form editor: checkbox + text input to override at the individual form level (highest priority)
  - Priority chain: per-form instance → field definition → default i18n translation
  - Supports `%s` placeholder for the field name in custom messages
  - Custom messages bypass i18n translations — used as-is regardless of site language
  - Works on both client-side (inline errors, submit and blur) and server-side (AJAX) validation
  - Follows the draft system: per-form changes saved to draft until global Save button is clicked
* **Bugfix**: Phone field blur validation now uses custom format messages — previously only submit and server-side validation respected custom messages, blur showed the default translated message
* **Bugfix**: Phone field required error not shown after clearing a previously invalid value — error state was left inconsistent between phone format cleanup and required blur handler
* **JS Version**: 91

= 2.0.0-beta.57 =
* **Block editor support**: Added a native Gutenberg block for inserting contact forms
  - Search for "Contact Form" in the block inserter or type `/contact`
  - Select a form from the dropdown — live preview renders in the editor
  - Sidebar panel with form selector in "Form Settings"
  - No build tools required — works with plain JavaScript
  - Fully translatable — Italian translations included
* **Bugfix**: Fixed PHP warning "Undefined array key description" on the Fields admin page for fields without a description

= 2.0.0-beta.56 =
* **Insert Contact Form modal overhaul**: Rebuilt the classic editor "Insert Contact Form" TinyMCE button with a WordPress-native modal
  - Searchable form list with keyboard navigation, matching WP's own link dialog pattern
  - CSS/JS only loads on post editor screens (not every admin page)
  - All UI strings translatable via WPML/gettext — Italian translations included
  - Fixed Cancel/Insert button alignment with flexbox
  - Removed legacy iframe popup code and unused AJAX handler

= 2.0.0-beta.55 =
* **Dashboard: New "Monthly submissions by page" chart**: Added a second chart to the dashboard showing submissions and unique pages per month, with independent period control
* **Dashboard: Post type filtering**: Added content type filter to narrow dashboard statistics by post type (page, post, custom post types)
* **Dashboard: Improved content filter**: Page/content filter now shows post type labels, groups options by type, and dynamically filters based on selected content type
  - Moved page filter from the first chart area to the new second chart section
  - Post type and content dropdowns are linked: selecting a content type filters the content dropdown options

= 2.0.0-beta.54 =
* **Fix: File Download Rendered as Raw Text Instead of Downloading (improved)**: Improved the file download fix from beta.53 which was not fully effective on all server configurations
  - Added `header_remove()` to clear all pre-set HTTP headers (including `Content-Type: text/html` set by `admin-ajax.php`) before sending download headers
  - Added `nocache_headers()` to prevent browser/proxy caching of the download response
  - Changed `die('')` to `exit` to avoid extra bytes in the output stream

= 2.0.0-beta.53 =
* **Fix: File Download Rendered as Raw Text Instead of Downloading**: On servers with caching plugins, file attachments displayed raw binary in the browser instead of downloading — fixed by clearing output buffers before sending headers and using `FILEINFO_MIME_TYPE` instead of `FILEINFO_MIME` for clean MIME types
* **Improvement: Mask Password Values in Submissions List**: Password fields now show `••••` in the list table instead of the stored value

= 2.0.0-beta.52 =
* **Fix: AJAX Form Submission Stuck on "Sending" When Server Returns `submitted: false`**: The form permanently froze in loading state when the server did not recognize the submission (e.g. expired nonce from a cached page)
  - Added `else` branch for `response.submitted === false` in the AJAX response handler — shows error message, re-enables submit button, unlocks fields, and triggers fallback to direct POST after 3 failures
  - Fixed `postMessage` handler to accept responses where `buildID` is `null` (server rejection) as long as `jsuuid` matches, so error displays immediately instead of waiting for the polling timeout
  - Root cause on production: server-side page caching served stale WordPress nonces to non-logged-in visitors
* **Fix: Password-and-Confirm Field Ignored Label Override**: Used hardcoded "Password" label instead of user-configured custom label
* **Fix: Required Multiselect Validation Bypass**: Required `<select multiple>` fields were not flagged as invalid when empty — `[]` was incorrectly treated as truthy
* **JS Version**: 85

= 2.0.0-beta.51 =
* **Fix: Custom CSS Class/ID Not Rendered for Radio, Checkbox, Multicheckbox, Turnstile, and Captcha**: These field types were missing `$field_properties` in their constructor calls, causing custom CSS class and ID to be silently ignored
  - `accua-forms.php`: Added `$field_properties` to constructor calls for single checkbox, radio, multicheckbox/post-multicheckbox, turnstile, and captcha (v2)
* **Per-Option Custom ID and Class for Radio and Checkbox Fields**: Each individual radio/checkbox option now gets a unique ID and class derived from the field's custom CSS ID/class
  - Format: `{css_id}-option-N` / `{css_class}-option-N` (1-based)
  - `classes/Element/Radio.php`, `classes/Element/Checkbox.php`: Applied per-option ID and class to option wrapper divs

= 2.0.0-beta.50 =
* **Fix: Custom HTML Field CSS Class and ID Not Rendered**: Custom CSS class and ID set on Custom HTML fields were saved but never applied to the frontend HTML output
  - `Element/HTML.php`: Extended constructor to accept an optional `$properties` parameter for wrapper CSS class/ID
  - `accua-forms.php`: Pass `$field_properties` to `Element_HTML` constructor (same pattern as fieldset fix in beta.49)
* **Refresh Preview for Custom HTML Fields**: Added "Refresh Preview" link below the Custom HTML textarea in the form editor
  - Saves the field to draft and refreshes the preview iframe, allowing content changes to be previewed before publishing
* **Auto-Preview on Field Changes**: The form preview now updates automatically when any field option is changed in the editor
  - Checkboxes and selects trigger immediate preview refresh
  - Text inputs and textareas use an 800ms debounce delay to avoid excessive updates during typing
  - Uses silent save (saves to draft without replacing widget HTML) to preserve user's in-progress edits
* **JS Version**: 83

= 2.0.0-beta.49 =
* **Fix: Fieldset Custom CSS Class and ID Not Rendered**: Custom CSS class and ID set on fieldset (group) fields were saved but never applied to the HTML output
  - `accua-forms.php`: Pass `$field_properties` to `AccuaForm_Element_FieldsetBegin` constructor so `wrapperCssClass` and `wrapperCssId` are set on the element
  - `FieldsetBegin.php`: Merge wrapper CSS class into the `class` attribute and override `id` with wrapper CSS ID before rendering, so they appear directly on the `<fieldset>` tag

= 2.0.0-beta.48 =
* **Fix: Duplicate Validation Errors**: Fixed PFBC Element validation accumulating errors across calls instead of resetting them
  - `Element::isValid()` now clears the errors array before running validators, preventing duplicate messages
  - Removed redundant `Validation_Email` that was added both in the Email element constructor and in the form builder switch case
* **Extension Hooks for External Field Types**: Added five hooks for external plugins to register custom field types without modifying Contact Forms core
  - `accua_forms_field_types` (filter): Register custom field types in the editor dropdown
  - `accua_forms_render_field_element` (filter): Return custom Element objects for rendering
  - `accua_forms_field_settings` (action): Render extra settings HTML in field editor
  - `accua_forms_save_field_data` (filter): Modify field instance data on save
  - `accua_forms_enqueue_scripts` (action): Enqueue frontend JS/CSS when a form is rendered

= 2.0.0-beta.47 =
* **Fix: Prefix-Only Telephone Values Treated as Empty**: Values containing only a country prefix (e.g. "+39") are now consistently treated as empty across all validation layers
  - Required telephone fields with only a prefix now correctly show the "required field" error instead of silently submitting
  - Optional telephone fields with only a prefix submit without errors (treated as blank)
  - Client-side: Added `isTelephonePrefixOnly()` helper in `AccuaForm.php` used by both submit and blur required checks
  - Server-side: `Telephone.php` overrides `isValid()` to normalize prefix-only values to empty before PFBC validators run, so `Required` correctly rejects them
  - Prefix-only threshold: ≤4 digits starting with `+` (covers all international dialing codes)
* **JS Version**: 81

= 2.0.0-beta.46 =
* **Fix: Blurry text on Chromium browsers**: Removed unnecessary `will-change` CSS property from inline error messages that caused GPU-based text rendering, losing subpixel antialiasing. No visual or accessibility regressions — animation and content-flash prevention are handled by the keyframes themselves.
* **CSS Version**: 143

= 2.0.0-beta.45 =
* **Custom CSS Class & ID for Field Wrappers**: Added per-field CSS Class and CSS ID settings in the form editor
  - Each field now has "CSS Class" and "CSS ID" inputs in its settings panel
  - CSS Class supports multiple space-separated classes
  - CSS ID adds a unique HTML `id` attribute to the field wrapper `div.pfbc-element`
  - Available for all field types (except fieldset-end)
  - Works across all three form layouts: standard, side-by-side, and inline-label
  - Values are sanitized with `sanitize_html_class()` and escaped with `esc_attr()` on output
  - Follows the draft system: values are saved to draft until the global Save button is clicked
  - Fully translatable labels and help text (Italian translation included)
* **JS Version**: 78

= 2.0.0-beta.44 =
* **Removed all unnecessary `!important` from frontend CSS**: Improves theme compatibility and prevents forced styling conflicts (e.g., transparent backgrounds on select dropdowns overriding theme styles)
  - Removed 35 `!important` declarations; only 10 remain (visually-hidden file input, required for accessibility)
  - Fixed PHP inline styles: changed `background` shorthand to `background-color` to avoid resetting SVG caret on select elements
  - Removed forced `transparent` default for field backgrounds when no color is configured
  - All form inputs now use `background-color: inherit` for consistent appearance across any theme background
  - Increased CSS selector specificity for color picker fields instead of relying on `!important`
  - Removed PFBC jQuery `outerWidth()` calls that injected inline `style="width: Xpx"` on textboxes and textareas, conflicting with CSS `width: 100%`
* **CSS Version**: 142

= 2.0.0-beta.43 =
* **Restored URL Hash on Form Submission**: URL now updates with `#formSubmitSuccess-{formID}`, `#formSubmitInvalid-{formID}`, or `#formSubmitError-{formID}` after form submission (feature originally from v1.4.10, lost during v2.0.0 rewrite)
  - Uses `history.replaceState()` for clean URL update without page jump or browser history pollution
  - Works with smooth scrolling introduced in v2.0.0-beta.18 (no regression)
  - Covers all submission paths: client-side validation failure, AJAX success, AJAX server-side invalid, AJAX error
  - Non-AJAX fallback: inline script scrolls to result anchor and sets hash on page load
  - GA/gtag tracking unaffected (event-based, does not read URL fragments)
  - Bonus: GA4 now automatically captures `page_location` with hash in all subsequent events, enabling URL-based goal/funnel tracking
* **JS Version**: 77

= 2.0.0-beta.41 =
* **Preview Layout Fix**: Fixed form preview flashing wrong layout in form editor
  - Problem: Preview appeared correct for a moment, then switched to wrong layout (sidebyside) regardless of actual setting
  - Root Cause: `updatePreviewLayout()` ran after each iframe load and hardcoded `sidebyside` as fallback when dropdown was set to "default", ignoring the actual global default
  - Solution: Removed client-side layout class toggling from `updateFullPreview()` — the server already renders the correct layout; layout changes use `reloadPreviewWithLayout()` which rebuilds the iframe
  - Also fixed: Save handler now preserves layout in preview reload

= 2.0.0-beta.27 =
* **Critical Bug Fix**: AJAX form submission now correctly returns success/error messages
  - Problem: Messages were captured BEFORE email sending completed, resulting in empty response messages
  - Solution: Moved `getSubmittedMessages()` to AFTER `isValid()` and `wp_save()` calls
  - Impact: Error message "Oops! Something went wrong" now displays when `wp_mail()` fails; success message displays on success
* **Project Cleanup**: Moved documentation files to `docs/` subfolder
* **Git Hygiene**: Added `.gitignore` to exclude zip files and local-only tools

= 2.0.0-beta.25 =
* **Accessible Loading State**: Replaced hidden summary with visible loading state during AJAX submission
  - Shows spinner + text "Submitting your form, please wait..." during form submission
  - Uses `role="status"` with `aria-live="polite"` for screen reader announcement
  - `aria-busy="true"` indicates ongoing operation
  - Smooth CSS transitions (0.25s ease-out) between all states (loading → success/error)
  - Respects `prefers-reduced-motion` user preference (disables animations)
  - Removed old standalone throbbler spinner (now integrated in summary)
* **New CSS Class**: `.pfbc-validation-loading` with blue/neutral color scheme
* **CSS/JS Versions**: CSS 103, JS 45

= 2.0.0-beta.24 =
* **UX Fix**: Validation summary no longer shows premature "success" message during AJAX submission
  - Summary is hidden during server validation, only shows result after server response
  - Prevents confusing flash of "All fields correct" before server-side validation completes
* **JS Version**: 44

= 2.0.0-beta.23 =
* **Phone Validation E.164 Compliance**: Updated to follow ITU-T E.164 standard
  - Maximum 15 digits (E.164 compliant)
  - No minimum digit requirement (flexible for all countries)
  - Lenient formatting: spaces, dashes, dots, slashes, parentheses, plus sign
  - Rejects invalid characters (letters, special symbols like #, @, etc.)
* **Bug Fix**: Phone validation now correctly rejects text characters
  - Fixed: `+39 dasdsad` was incorrectly accepted as valid
  - Character validation now runs BEFORE digit count bypass
* **JS Version**: 43

= 2.0.0-beta.22 =
* **Phone Field A11y Improvement**: Placeholder-only approach (no prefilled default value)
  - Removed default value `+39 `, using placeholder only (better for screen readers)
* **Phone Validation Made More Lenient**: No minimum digit requirement
* **Frontend Performance Optimization**: Removed unused libphonenumber-min.js (171KB saved)
* **Simplified phone-validation.js**: Reduced from 166 lines to ~100 lines
* **JS Version**: 42

= 2.0.0-beta.21 =
* **Phone Validation Fix for Optional Fields**: Fixed validation failing when only country prefix entered
  - Treat values with ≤4 digits as "empty" (user hasn't entered actual number beyond prefix)
* **W3 Total Cache Compatibility**: Verified working with Page Cache, Minify, and Browser Cache
* **JS Version**: 41

= 2.0.0-beta.20 =
* **Critical Bug Fix**: Form no longer disappears after correcting validation errors
  - Fixed jsuuid transient caching issue in `AccuaForm.php`
* **Dead Code Cleanup**: Removed debug statements and commented-out legacy code

= 2.0.0-beta.19 =
* **i18n:** Fixed reCAPTCHA typo (was "reCATPCHA") in 5 validation files
* **i18n:** Fixed double space and "re-try" → "retry" in CAPTCHA error messages
* **i18n:** Replaced non-standard "identificative" with proper English "identifier" in form/field validation
* **i18n:** Fixed "it must contains" → "must contain" grammar error
* **i18n:** Improved "identificator" → "unique identifier" and "unchangeable" → "cannot be changed"
* **i18n:** Fixed "hyphen and underscores" → "hyphens, and underscores" (Oxford comma)
* **i18n:** Improved duplicate field error message clarity

= 2.0.0-beta.18 =
* **Fix:** Success messages now display correctly (was sometimes empty)
* **Fix:** Form submission no longer jumps around - smooth scrolling to messages
* **Fix:** Multiple forms on same page now handle messages independently
* **Fix:** Shows error message when email sending fails (wp_mail returns false)
* **UX:** Added CSS animation for success/error messages with reduced-motion support
* **Technical:** Changed static $submittedMessages to per-form array keyed by formId
* **Technical:** Added all three anchor elements (#formSubmitSuccess, #formSubmitInvalid, #formSubmitError)
* **Technical:** Updated CSS version 102, JS version 38

= 2.0.0-beta.17 =
* **Security:** Fixed null byte injection causing 500 server error on form submission
* **PHP 8:** Sanitize null bytes from user input to prevent mail() ValueError
* **Technical:** Added str_replace("\0", '', ...) sanitization during form value processing

= 2.0.0-beta.16 =
* **Debug:** Removed all debug statements (alert, console.log, error_log) for production release
* **Fix:** Server-side validation errors now properly update the validation summary area
* **UX:** Turnstile validation message changed to "Please verify you are not a robot."

= 2.0.0-beta.11 =
* **Accessibility:** Enhanced validation summary with clickable field links for easy navigation
* **UX:** Error summary now shows "Verifica i seguenti campi per continuare:" with list of invalid fields
* **UX:** Each field name in summary is a clickable link that scrolls to and focuses the field
* **UX:** Smooth scroll animation with focus after 500ms delay for better user experience
* **UX:** Green success state shows "Tutti i campi sono corretti. Pronto per l'invio!" when all fields valid
* **UX:** Summary only appears after first submit attempt (not on page load)
* **Typography:** Consistent font sizes - 0.9375rem header, 0.875rem list items
* **Translation:** Updated Italian and Spanish translations with new summary strings
* **Technical:** New JS functions: scrollToFieldAndFocus(), updateSummaryArea(), fieldErrorsList array
* **Technical:** New CSS classes: .pfbc-validation-summary, .pfbc-validation-error, .pfbc-validation-success
* **Technical:** Updated CSS version 95, JS version 36 for cache busting

= 2.0.0-beta.10 =
* **Feature:** Modern default file extensions for file upload fields
* **Feature:** Added docx, xlsx, pptx, odt, ods, odp, csv, gif, webp, svg, heic, rar, 7z, tar extensions
* **Removed:** Obsolete bz, bz2 archive formats from defaults

= 2.0.0-beta.9 =
* **UX:** Added prominent visible error message for unsupported file formats in drag & drop upload
* **UX:** Red error box with warning icon shows "⚠ filename: File type not allowed"
* **UX:** Dropzone border turns red on error, clears automatically when valid file uploaded
* **Design:** Neutral design update - removed border-radius from dropzone and file list items
* **Technical:** Updated CSS version 94, JS version 34 for cache busting

= 2.0.0-beta.8 =
* **NEW:** Accessible drag & drop file upload with modern UI
* **Accessibility:** Full WCAG 2.2 AA / European Accessibility Act compliance
* **Accessibility:** Keyboard navigation (Enter/Space to open file picker)
* **Accessibility:** ARIA attributes and screen reader announcements
* **UX:** Dashed border dropzone with folder emoji icon
* **UX:** File list with filename, size, and remove button
* **Technical:** Progressive enhancement with DataTransfer API

= 2.0.0-beta.7 =
* **UX:** Comprehensive CSS refinements for floating label form view
* **UX:** Balanced padding for proper vertical text centering
* **UX:** Custom SVG caret for dropdowns with cross-browser consistency
* **Accessibility:** Added font-family: inherit to date inputs

= 2.0.0-beta.6 =
* **Feature:** Added "Restore to Default" buttons for form messages 1-4 in Settings page
* **UX:** Restore buttons use native WordPress link styling for consistent admin UI
* **AJAX:** New `accua_forms_restore_default_message` endpoint for restoring default values
* **Technical:** Refactored default form data into reusable `accua_forms_get_default_form_data()` function
* **Technical:** Updated CSS version 73, JS version 30 for cache busting

= 2.0.0-beta.5 =
* **UX:** Save button now shows "Saving..." text during save operation instead of empty button
* **UX:** Removed redundant bottom "Salva le impostazioni" save button from form editor
* **PHP 8:** Fixed "Unsupported operand types: null + array" error when creating new forms
* **Translation:** Added "Saving..." string to translation files (.pot regenerated)
* **Technical:** Updated CSS version 69, JS version 25 for cache busting

= 2.0.0-beta.4 =
* **Accessibility:** Replaced jqColorPicker library with WordPress native wp-color-picker (Iris)
* **Accessibility:** Color picker now fully WCAG 2.2 AA compliant with keyboard navigation and screen reader support
* **Accessibility:** Full European Accessibility Act compliance for color selection fields
* **UX:** Fixed dropdown caret positioning - added proper right padding (2.5em) for visual clarity
* **UX:** WordPress color picker provides familiar interface for administrators and better mobile/touch support
* **Performance:** Removed external jqColorPicker dependency - uses WordPress core functionality
* **Technical:** Color picker callbacks ensure proper hex color format with # prefix
* **Technical:** Updated ColorPicker.php element class to use wpColorPicker() method
* **Technical:** Updated admin script enqueues to use wp-color-picker instead of jqColorPicker
* **Developer:** WordPress Iris color picker supports RTL languages and theme customization

= 2.0.0-beta.3 =
* **NEW:** Material Design "Inline Labels" layout option for forms
* **Accessibility:** Floating labels follow WCAG 2.2 Material Design guidelines
* **Accessibility:** Proper vertical centering and font sizing for readability
* **UX:** Consistent border styling across all field types (text inputs, textareas, dropdowns)
* **UX:** Firefox-compatible date field placeholder behavior (hides dd/mm/yyyy when empty)
* **UX:** Symmetric padding for better dropdown caret centering
* **Technical:** JavaScript date input value detection with .has-value class
* **Technical:** CSS fallbacks for cross-browser compatibility (WebKit + Firefox)
* **Translation:** Updated Italian and Spanish translation files
* Fixed: Border weight consistency - all fields now use 1px solid borders
* Fixed: Label vertical centering using CSS transform translateY(-50%)
* Fixed: Font size increased to 1rem for better readability

= 2.0.0-beta.2 =
* Fixed: Error message positioning on mandatory file upload fields
* Fixed: Error messages now appear after help text instead of overlapping it
* Improved: Correct visual order - Browse button → Help text → Error message
* Improved: Reduced excessive padding in file upload fields (1.2rem → 1rem)
* Technical: Updated client-side validation in AccuaForm.php (4 locations)
* Technical: Updated AJAX validation in Error/Standard.php (2 locations)

= 2.0.0-beta.1 =
* **NEW:** Cloudflare Turnstile Captcha field support (via Simple Cloudflare Turnstile plugin v1.35.0+)
* **MAJOR:** Complete file reorganization following WordPress plugin development best practices
* **MAJOR:** Comprehensive WCAG 2.2 and WAI-ARIA 1.2 accessibility improvements
* **Accessibility:** Added ARIA attributes (aria-required, aria-invalid, aria-describedby)
* **Accessibility:** Implemented real-time validation on blur/change events
* **Accessibility:** Auto-focus on first invalid field after form submission
* **Accessibility:** Inline error messages with role=alert and aria-live=polite
* **Accessibility:** Enhanced radio and checkbox field accessibility and error handling
* **Accessibility:** Added HTML5 required attributes for dual compliance
* **Accessibility:** Added accessible required indicators with aria-label
* **Accessibility:** Fixed duplicate id='dashboard_right_now' (13 instances removed)
* **UX:** Modernized error styling with clean compact design
* **UX:** Improved validation messages - clearer, more direct, field-specific
* **UX:** Removed unnecessary 'Attention:' and 'Error:' prefixes from messages
* **Translation:** Proper textdomain loading on plugins_loaded hook (WordPress best practice)
* **Translation:** Complete Italian translation with all new error messages
* **Translation:** Complete Spanish translation with all new error messages
* **Translation:** Removed incomplete German translation
* **Translation:** Generated new .pot template file
* **Files:** Moved all CSS files to `/assets/css/` with descriptive names (admin.css, dashboard.css, frontend.css)
* **Files:** Moved all JavaScript files to `/assets/js/admin/` and `/assets/js/frontend/`
* **Files:** Moved vendor libraries to `/assets/vendor/` (jqColorPicker, Chart.js, dragtable)
* **Files:** Moved all images to `/assets/img/`
* **Files:** Updated all asset references across 13 PHP files
* **Files:** Removed deprecated Flot charting library (27 files)
* **Files:** Added documentation (REORGANIZATION-2025.md, ASSET-LOCATION-REFERENCE.md)
* **Technical:** Updated asset version constants for cache busting (CSS v54, JS v15.0)
* **Technical:** Added PHP 7.4 minimum requirement
* **Technical:** CSS content fix to avoid charset declaration issues
* Fixed: Drag-and-drop functionality in form builder after reorganization
* Backward compatible with existing forms

= 1.9.14 =
* Added Cloudflare Turnstile field integration
* New field-based Turnstile implementation (drag-and-drop control)
* Works standalone or enhanced with Simple Cloudflare Turnstile plugin
* Backward compatible with existing forms

= 1.9.13 =
* Improved hostname detection for AJAX requests

= 1.9.12 =
* Removed "WordPress" from plugin name to comply with WordPress naming guidelines

= 1.9.11 =
* Improved dashboard widget access control for better security
* Enhanced permission checks and capability handling

= 1.9.10 =
* Tiny improvements for SEO and accessibility.

= 1.9.9 =
* Security improvements.
* Fixed several deprecation warnings when WP_DEBUG is enabled.

= 1.9.8 =
* Added support for Google Ads.
* To set a GADS conversion tracking code, go to Form Name > Appearance and General > fill the dedicated field with a GADS Conversion Code (es: AW-123456789/aaBBccDD)


= 1.9.7 =
* Enhance SQL query security following WordPress Best Practices
* Resolved path handling issues that prevented file uploads in Windows-based development environments like LocalWP
* Enhanced file upload security with proper MIME type validation
* Added download links for uploaded files on individual submission pages (previously, these links were only available on the list page)

= 1.9.6 =
* Fixed an issue that could cause PHP sessions to remain open, triggering WordPress Site Health warnings

= 1.9.5 =
* Minor fixes to previous version fix

= 1.9.4 =
* Fixed vulnerability - Missing Authorization to Unauthenticated Form Submission Download

= 1.9.3 =
* Matomo support for tracking field filled in and form submissions as events
* Fixed CSRF vulnerability

= 1.9.2 =
* Reverted an incorrect fix in the previous version

= 1.9.1 =
* Hardening for potential SQL injection vulnerabilities

= 1.9.0 =
* Checks for unfiltered_html capability and supports limited admin permissions in WordPress multisite configurations
* Filters the list of allowed upload file extensions according get_allowed_mime_types(), and check the maximum upload size with wp_max_upload_size()
* Default date fix
* Other minor fixes

= 1.8.0 =
* Using tinyColorPicker on frontend
* Fixed XSS vulnerability

= 1.7.0 =
* Lead status
* Minor fixes

= 1.6.1 =
* Fixed trashed form restore
* Fixed CSRF vulnerability

= 1.6.0 =
* IP masking option

= 1.5.10 =
* Fixed plugin icon

= 1.5.9 =
* Fixed adding more custom HTML fields and fieldsets

= 1.5.8 =
* Fixed CSRF vulnerabilities
* Fixed some JavaScript errors due to WordPress filters
* Fixed many minor bugs

= 1.5.7 =
* tested compatibility with WordPress 6.2.0

= 1.5.6 =
* Fixed CSRF vulnerability

= 1.5.5 =
* Fixed XSS vulnerabilities

= 1.5.4 =
* Graphical changes to default messages
* Fixed some minor bugs

= 1.5.3 =
* Removed unused code
* Fixed some minor issues

= 1.5.2 =
* Fixed critical error when trying to access the dashboard

= 1.5.1 =
* Renewed UI
* Fixing some minor bugs

= 1.4.14 =
* Lazy load reCAPTCHA

= 1.4.13 =
* added html attributes to improve SEO

= 1.4.12 =
* Tested compatibility with PHP up to 8.0 and WordPress up to 5.8.1
* reCAPTCHA loaded from recaptcha.net trying to improve accessibility from countries banning google.com domain
* Fixed minor XSS vulnerability reported on wpscan.com by Felipe Restrepo Rodriguez and Sebastian Cruz Cardona. Form title was not sanitized in every place it was used in the admin interface, however this is mitigated by the fact that only admin users with manage_options capability can edit it.

= 1.4.11 =
* avoid "headers already sent" warnings during WordPress cron

= 1.4.10 =
* Tested compatibility with PHP up to 7.4
* After submission, the fragment #formSubmitSuccess-formID is added to the URL, so the page is scrolled to the top of the message, and it's easier to track the submission with tools like Google Analytics
* fragments #formSubmitInvalid-formID and #formSubmitError-formID are added in case of invalid submission or error
* improved loading of reCAPTCHA
* removed unused resources from PFBC library
* colorPicker styles and javascripts now loads only if it's used
* other small bugfixes

= 1.4.9 =
* improved compatibility with Google Tag Manager to track field filled in and form submission

= 1.4.8 =
* fixed compatibility issues with php 7.2
* option to track field filled in and form submission as events on Google Analytics
* workaround to open/download attachments in submissions exported and opened with Microsoft Excel

= 1.4.7 =
* fixed compatibility issue with WordPress 4.8 that made show/hide buttons for field settings in the form editor invisible
* fixed compatibility issues with php 7.0 and 7.1
* fixed strict standards errors

= 1.4.6 =
* restored compatibility with PHP < 5.3
* fixed some strict standards errors

= 1.4.5 =
* Scaled reCAPTCHA 2 area for devices with less than 400px screen width
* More informations about senders and receivers of the form emails in the forms list page

= 1.4.4 =
* Changed text domain of translatable strings to match the plugin slug
* Bulk action to delete permanently trashed submissions

= 1.4.3 =
* Fixed table index length issue that prevented saving submission values of new user of Contact Forms with recent WordPress versions
* Added internationalization info

= 1.4.2 =
* Fixed table definition error that prevented saving submission of new users of Contact Forms 1.4.0

= 1.4.1 =
* Fixed undefined variable in accua-form-api.php on line 29

= 1.4.0 =
* Filter and export by year and month
* Added actions accua_forms_field_added, accua_forms_field_updated and accua_forms_field_deleted

= 1.3.9 =
* better support for reCAPTCHA allowing to enter site keys and use version 2
* fixed visualization bug of reCAPTCHA 1 with new WordPress themes
* fixed bug that prevented editing fields on the page after a form submission

= 1.3.8 =
* fixed incompatibility with WordPress 4.4 that prevented submissions export

= 1.3.7 =
* fixed incompatibility with WordPress 4.4 that caused a PHP error in every page that includes a form
* new token for select, checkbox and radio labels
* changed database table to allow referrers and urls longer than 255 characters 

= 1.3.6 =
* Replaced deprecated user level '10' with capability 'manage_options'

= 1.3.5 =
* fixed incompatibility of form editor with WordPress 4.3 and Chrome
* adding rules to robots.txt to allow /wp-admin/js/ and /wp-admin/css/ for styles and scripts included from that folders

= 1.3.4 =
* Password fields now saves the hash value of the password using wp_hash_password
* Field to set the emails "From:" name
* fixed CAPTCHA field incompatibility with CloudFlare RocketLoader and possibly other JavaScript optimizer
* fixed glitch in the "Form fields" area on the "Edit form" page with latest versions of WordPress

= 1.3.3 =
* improved checkboxes, select and radio definition to allow pre-selected options
* fixed PHP 5.5 incompatibility issue. Now the plugin works with PHP from version 5.2 to 5.5
* fixed default value for email, colorpicker and password fields
* allowed removal of elements by a filter after the form generation

= 1.3.2 =
* fixed visualization of color picker field
* workaround to have multiple forms with recaptcha on the same page

= 1.3.1 =
* fixed validation of required fields with multiple values
* show recipient of admin email in form list
* changes in submissions list generation and export to allow usage by other plugins

= 1.3 =
* Spanish translation by Maria Ramos of [WebHostingHub](http://www.webhostinghub.com/)
* Color picker field
* Possibility to insert raw tokens in html messages
* Disabled HTML5 validation of email fields, using JavaScript validation

= 1.2.1 =
* Fixed installation and upgrade process issues introduced in 1.2
* Users who installed 1.2 as their first version reported that submissions where not saved. Upgrading to this version will fix this issue

= 1.2 =
* Fieldsets
* Submissions trash and restore
* Fixed counting of active and deleted forms
* Fixed submission bug in Internet Explorer 8 and previous versions

= 1.1 =
* Added interface to set basic form styles (borders, colors, padding)
* Fixed captcha validation
* Added submission graph by form
* Screenshots removed from the package
* Other minor fixes