== Changelog ==

This file contains the full release history of BrikPanel. The latest releases are kept in readme.txt; older versions are archived here.

= 3.3.1 (2026-09-10) =
* New: **The abandoned cart popup can now be written separately for each of your languages.** Its wording lived in one set of boxes, so a store selling in Estonian and Finnish showed the same text on both. On a store running Polylang, WPML, TranslatePress or Weglot a "Popup text per language" card now appears under WooCommerce → Settings → BrikPanel → Abandoned Carts, with a tab for each language; anything you leave empty falls back to the wording above it. The wording the popup writes on its own is included as well (the discount code heading, the Copy button, the "OFF" badge, the error messages), so a language BrikPanel ships no translation for no longer ends up half in English. A store with one language sees no change.
* Fix: **Add-to-cart figures are no longer inflated by scripted traffic.** The "one visitor, one product, once a day" rule was kept in the WooCommerce session, so a script that dropped its cookies between rounds arrived with a blank memory and was counted again every round; one store recorded 13,053 add-to-carts in a month where the real level was four to seven a day. The rule is now held on the server too, where a visitor cannot clear it, and it covers all three figures: per product, store-wide and on the checkout page. Signed-in customers are unaffected. Two guests sharing one connection and the same browser make-up who add the same product on the same day are now counted once.
* New: **BrikControl can put right add-to-cart history that was already inflated.** A new "Add-to-Cart History" check lists days that cannot be real (more add-to-carts than the store had visitors) and days far above that product's own normal, and "Correct these days" lowers them to an honest ceiling. Nothing is deleted, your products, orders and customers are untouched, and "Undo last correction" puts the earlier figures back exactly.
* New: **BrikControl now reports abandoned cart entries that look automated.** A new "Abandoned Cart Entries" check looks for four shapes a shopper's browser does not produce: an entry carrying a browser id BrikPanel never issued, one browser id typing many addresses within minutes, one address arriving from many browser ids, and dozens of empty signups inside a single minute. It only reports. Nothing is deleted and there is no button, because a shared computer or a busy promotion can look much the same.
* Fix: **The abandoned cart signup endpoint is far harder to flood.** It accepted any browser id the caller sent and tied its two-second limit to that same id, so a script that changed its cookie on every request wrote a row every time. An id BrikPanel did not issue is now refused and replaced, and the limit follows the connection as well as the cookie: a cookie-swapping script drops from a row per request to one in five, while real shoppers, and several people behind one connection, carry on as before.

= 3.3.0 (2026-09-07) =
* New: **BrikMentor is out.** BrikMentor is our separate paid add-on that acts on the figures BrikPanel shows you: it chases abandoned carts, wins lapsed customers back and sends campaigns to your customer segments, by email, from inside WooCommerce. Now that it is available, the "coming soon" wording is gone and BrikPanel points at the real thing: a card on the dashboard, a row under WooCommerce > Settings > BrikPanel, a button on Customer Analytics and Abandoned Carts that explains what BrikMentor would do with the screen you are looking at, and a single one-time note announcing the launch. The first month is $1. Nothing is ever installed from inside your admin: the buttons open BrikMentor's own page, where you buy it and download it yourself. Every one of these is dismissible, none of them appear if BrikMentor is already installed here, and a brand new store is left alone for its first three days.
* New: **The BrikMentor waiting list is now a plain newsletter.** It used to offer a place in a private beta, which no longer exists now that BrikMentor is out. It offers what it always really was: an occasional short email about new features, WooCommerce tips and ideas for growing your store. The sign-up box no longer opens by itself when your store passes 100 or 200 orders; it opens only when you press Subscribe, on the dashboard or under WooCommerce > Settings > BrikPanel. It is two steps instead of three, since it no longer asks which email tool you use, and the cards it used to place on Customer Analytics and Abandoned Carts are gone. If you are already on the list you stay on it and need do nothing.
* Fix: **The X on the Store Health warning now closes it for good.** It was written as a seven-day snooze, so the warning you had dismissed came back by itself a week later. Dismissing now sticks for the problems it was showing you, and the banner only speaks up again if a different check turns critical. Two things that made this worse are fixed with it: the X did nothing at all while the top bar was switched on, and a dismissal the server refused still cleared the banner from the screen without being saved anywhere, so it returned on the next page load. If saving fails you are now told. On a multisite network, dismissing on one store no longer silences the warning on all the others.
* Fix: **No more repeated deprecation lines in the error log on WooCommerce 11.1.** Drawing the notifications bell asked WooCommerce whether its Analytics feature was switched on, in a way WooCommerce retired in 11.1, and that wrote a line to the log on every admin page load. The question is now asked the way 11.1 expects. The "New customers today" entry still opens the right screen, with Analytics on or off.

= 3.2.99 (2026-09-07) =
* Fix: **Exported CSV files can no longer run anything when you open them.** Spreadsheet programs treat a cell starting with `=`, `+`, `-` or `@` as a formula rather than as text, so wording a customer typed at checkout could be run by Excel or Google Sheets the moment you opened an export. Placing a guest order was enough to plant it, and it ran on your computer, not the store's. Only the phone column was protected, and only in two of the exports. Every column of every CSV export is now protected: orders and customers under Segments, the lifetime value, RFM and cohort files under Customer Analytics, abandoned carts, selected products, and operational expenses. Plain numbers are left alone, so a negative stock level or a refund still reads as a number and still sorts. Excel downloads were never affected and are unchanged.
* Fix: **An expense whose title contains a comma no longer breaks the exported file.** In the operational expenses export the date, title and amount were written without quoting, so a single comma in a title pushed every following column one place to the right for that row. The file also carries the same marker as the other exports now, so Turkish characters open correctly in Excel instead of as symbols.

= 3.2.98 (2026-09-06) =
* Fix: **Yoast's SEO analysis works in the product editor again, instead of waiting forever.** On a store running Yoast WooCommerce SEO the Yoast panel showed up but nothing in it moved: the score badge never changed and the "Analysis results" list stayed empty. Yoast WooCommerce looks for the product type dropdown of the standard WooCommerce screen, and the editor prints a hidden stand-in for it, but only when Yoast arrives through the SEO card. If you had placed Yoast yourself from "Visible editor sections" the stand-in was missing, and Yoast's analysis stopped with an error before it had read a word of the page. Both routes print it now, so the score, the readability checks and the keyword checks update as you type and are saved with the product, on simple and variable products alike.
* Fix: **Screen readers can read the Yoast score again.** Hidden wording that other plugins' panels put in for screen readers was being taken off the page entirely rather than just hidden from view. In Yoast that wording is the only text form of the coloured score dot ("OK", "Needs improvement"), so the score could not be read out at all. It is now hidden the way WordPress hides its own.
* Fix: **Red error messages no longer disappear from the screen.** Submitting the Add User form with an email that is already registered looked like nothing had happened: WordPress printed its red error box, BrikPanel's notice tidying hid it, and because it was an error nothing moved it into the notifications bell either, so the message was gone with no trace. The same went for every error a screen prints itself, including WooCommerce's own error box on its settings pages and in the product and order editors, and WordPress's errors on Users, Plugins, Menus, Comments and the file editors. Red errors now stay on screen, on those screens as they already did elsewhere. Nothing changes if you have turned on "Also hide error notices" under WooCommerce, Settings, BrikPanel: those errors still go to the bell, and now the ones that used to vanish arrive there too.

= 3.2.97 (2026-09-05) =
* New: **The WhatsApp button on the abandoned cart list now tells you how many times you have opened that shopper's draft, and when you last did.** Until now the button left no trace at all, so the one channel most stores actually chase carts on was the one you had no record of. A small number sits on the corner of the icon and the button's tooltip spells it out ("opened 3 times, last ..."). It says opened, never sent: the draft is yours to edit or discard, and only you know whether it went. The counting itself is done by BrikMentor; on a store without it the button looks and behaves exactly as it did before, with no badge and no "0".
* Fix: **"Merge orders" no longer shows up for staff whose BrikPanel interface is switched off.** The bulk action skipped the check every other BrikPanel addition to the orders list makes, so an account moved back to the plain WooCommerce screens still saw it in the dropdown. It is now hidden for those accounts, and opening the merge page by its address is refused with the reason.
* Fix: **The merge confirmation can no longer be sent twice.** Going back and re-submitting the same confirmation, or a double click that got through, could run the merge a second time. The confirmation is now spent once and repeats are turned away. A confirmation that fails its checks is left untouched, so you can go back, fix the problem and carry on.
* Fix: **A failure while adding up the merged order no longer leaves a blank page.** The items had already moved and the old orders had already been cancelled by that point, so an error there gave you a white screen with no idea what had happened. You now get the merged order with a note asking you to press Recalculate.
* Fix: **BrikPanel's own merge bookkeeping is out of the field pickers.** Two internal entries appeared in the "Order custom fields" picker and in the Google Sheets order field list, where picking them would only ever produce blank cells. The two fields worth having, the order the goods went into and the numbers they came from, are still there to pick.

= 3.2.96 (2026-09-04) =
* New: **Merge orders.** When the same customer orders twice in a day you had two orders to pick, pack and post separately. Tick two or more orders in the list and a "Merge orders" button appears; it opens a preview screen where you choose which order stays, decide whether the customer is charged shipping once or for every order, and see the merged total before anything is written. On confirming, the products, fees and shipping move onto the order you picked, and the others are cancelled with a note linking to it. Nothing is deleted, so an old order number a customer quotes still opens and points at where their goods went. Stock is never counted twice, tax is carried across exactly as each order recorded it rather than being recalculated at today's rates, and coupon usage counts stay correct. Orders with a refund on them, orders in different currencies, and orders that disagree about whether prices include tax are refused with the reason shown. Switch the whole thing off under WooCommerce, Settings, BrikPanel, Orders List.

= 3.2.95 (2026-09-03) =
* Fix: **"Use the full screen width" now really uses the width, and arranges the page the way the WordPress editor does: a main column with a narrow side column beside it.** It used to widen only the variations table and the two description editors, leaving every other card in a narrow centre strip, and it stopped growing at a fixed 1500 pixels, so on a large monitor the editor still sat marooned in the middle with a wide empty margin on each side. It now scales with the screen, and the short setting cards (price, cost, stock, category, brand, tags, shipping, linked products) move into the side column, so a card holding one price box no longer takes a whole line to itself. The product name, the permalink under it, the images, the variations table, both description editors, the SEO card and panels added by other plugins keep the main column, since their content is what asked for the width in the first place. Each column flows on its own, so a short card never leaves an empty gap beside it, and your own section order is kept within each column: the list is split, never reordered. The side column grows with the screen and then stops, so the variations table still fits without a scrollbar on a wide monitor and the main column is never narrower than it is with the setting switched off. Nothing changes while the setting is off, or on screens narrower than about 1360 pixels, where the side column simply stacks underneath.
* Fix: **The "+ Add new category" and "+ Add new brand" forms fit the side column.** Their name box, parent picker and button sat on a single line that needs about 500 pixels, which pushed the parent picker out of a column half that wide. They now stack, and the fields in the side column fill it rather than keeping the narrower width they are given inside a wide card.

= 3.2.94 (2026-09-02) =
* Fix: **Turning a variable product into a simple one now asks first, and no longer throws the variations away when the save fails.** Switching a product to simple deletes every variation for good — they do not go to the trash and cannot be brought back — and it was the only place in the editor that did that without asking, even though clearing the variation list and deleting a single row both ask. It now confirms first and tells you how many variations are at stake. The deletion also waits until the product has actually been saved: if the save is stopped by a missing product name, or by another plugin raising an error, the product keeps its variations and its type instead of losing them behind a message saying nothing was saved.
* New: **The Permalink (URL slug) field is far easier to find, and lands right under the product name.** It has been in the editor since 3.1.46 but sat in the middle of the section list, so merchants reported there was no way to change a product's web address at all. It is still off out of the box; switching it on now places it directly under the product name, where the WordPress editor puts it. Turn it on under WooCommerce → Settings → BrikPanel → Products → "Visible editor sections".
* Fix: **Your SEO plugin's panel now appears in the editor on stores that use the block editor for products.** Some themes and plugins switch the block editor on for products. SEO plugins notice that and offer their settings as a block-editor sidebar instead of a panel, so BrikPanel's SEO card came up empty with a message blaming a plugin setting that was not the cause — SEOPress was the clearest case, but any plugin that works this way was affected. The BrikPanel editor now identifies itself correctly as a classic editing screen, so the SEO panel is registered and drawn where you would expect it. Nothing about the standard WooCommerce product screen changes.
* Fix: **The SEO "Canonical URL" box is no longer half the size of the field beside it.** It was the only web-address field in the editor and had been left out of the styling rule the other fields share, so it kept the browser's default width and sat noticeably short next to "Focus keyword".

= 3.2.93 (2026-08-30) =
* New: **Categories and tags can now be assigned in bulk from the selection bar itself.** Ticking a few products used to offer nothing but Export, Publish, Set as draft and the delete actions; the taxonomy actions existed, but behind the "Bulk update" button and on a tab that did not follow your selection. "Categories" and "Tags" buttons now sit in that bar and open the panel on "Selected products" with the matching action already chosen.
* New: **A category or tag can be removed from the selected products.** Until now the only way to take one off in bulk was "Set" with nothing ticked, which cleared every category the products had. Removing the last category leaves the product on your default one instead of none at all, unless the default is what you asked to remove.
* New: **New tags can be typed into the bulk panel, separated by commas,** as in WordPress' own bulk edit. Categories stay pick-only, since a new category needs a parent, and the box is only shown to users allowed to create terms.
* New: **An attribute's values can be dragged into the order shoppers should see them in.** A merchant reported a "Pack Size" dropdown listing 100, 12, 24, 50, 6: WooCommerce orders those values from a setting BrikPanel never wrote, so they all tied and fell back to alphabetical order. Values are now reorderable in the editor and that order is saved with the attribute, for variation attributes and plain ones alike. If the attribute is set to sort itself, the editor says so, because the order will not reach the product page.
* New: **The Cart share screen now has a home in the menu.** It was only reachable from "Create" in the top bar, and now also appears under "More", where it can be renamed, moved or hidden from Settings → Navigation like any other item.

= 3.2.92 (2026-08-30) =
* Fix: **The SEOPress panel now fits the product editor instead of being squeezed into a column too narrow for it.** With SEOPress Pro the panel gains five more tabs, and its own layout sizes the tab list as a share of the window rather than of the card it sits in, so every tab label broke onto two or three lines and the Google preview lost its web address off the right edge. The tab list now keeps a comfortable width, and the Google preview moves below the fields when there is not enough room beside them. If you use the Widescreen setting, the SEO card now takes the full width and shows the same roomy layout as the standard WooCommerce product page.
* Fix: **A product's barcode / GTIN is no longer emptied when you save.** SEOPress Pro adds those two fields to WooCommerce's Inventory section and rewrites them on every save even when they are not on the screen, so hiding the "Additional product data" card silently wiped them each time you saved a product. The fields are now left alone when they are not shown, and still save normally when they are.

= 3.2.91 (2026-08-30) =
* New: **SEOPress now draws its own SEO panel inside the product editor, so everything it offers is there, including its AI buttons.** The editor used to replace SEOPress with five plain fields of its own. Your meta title and description were saved correctly, but everything else SEOPress puts in that panel was missing: the "generate with AI" buttons, the Social tab for the Facebook and X preview, per-product redirections and the content analysis. The real panel is now shown, exactly as on the standard WooCommerce product page, and it saves from its own Save button as well as from the editor's.
* Fix: **Saving a variable product no longer copies the parent's SEO settings onto its variations.** Reordering variations, or switching one on or off, could write the product's meta title, description, canonical and redirection settings onto every variation as well.
* Fix: **A duplicate Google preview and a duplicate "Primary category" selector are gone when SEOPress is in charge.** The editor's own preview could also show a leftover template from a different SEO plugin.
* Fix: Opening the product editor with SEOPress active no longer logs a script error in the browser, and SEOPress's editor code is no longer loaded at all on a product where the SEO section is switched off.

= 3.2.90 (2026-08-28) =
* Fix: **Saving a product no longer loses the colour and size chosen for each variation.** On a product whose attributes had been rewritten by an import, a stock sync or an ERP feed, WooCommerce stops showing the variations' choices and every row reads "Any Colour, Any Size" even though the choices are still stored. The editor believed that emptiness and wrote it back on the next save, which deleted the choices for good. It now reads what is actually stored, and a value it was never shown is left exactly as it was instead of being erased.
* Fix: **A variable product can no longer be turned into a simple one, and its variations deleted, without anybody asking for it.** When the same kind of import left the product's attributes unusable, the editor opened with an empty variation list and took that to mean the product was no longer variable — so saving it removed every variation permanently. The editor now loads the variations regardless, and the save refuses to change the product type or remove variations unless the merchant actually made that choice.
* Fix: **An attribute whose options were emptied by an import is repaired instead of removed.** Where the product's list of colours or sizes had been wiped but the variations still held theirs, saving used to drop the attribute from the product as well, leaving a variable product with variations and no options at all. The list is now rebuilt from the variations themselves, which restores the product in one save. Clearing an attribute's options yourself still removes it, as before.

= 3.2.84 (2026-08-27) =
* Fix: **Payment fees are now read from more payment plugins, not just the official Stripe and PayPal ones.** The "Payment fees" expense line only looked at the fields written by official Stripe, older PayPal Standard and WooPayments, so a store taking cards through FunnelKit Stripe or the Payment Plugins PayPal gateway had the setting switched on and still saw nothing: the total came out at zero, and a zero line was hidden, which reads as a broken feature rather than as no data. Both gateways are now read. The currency of a fee is also taken from the field belonging to the gateway that wrote it instead of one shared field, so a fee charged in another currency is converted rather than quietly treated as being in the order's currency. When the setting is on and the total is still zero, the Expenses card now says so instead of hiding the line.
* Fix: **A one-day range on the dashboard chart no longer draws two days.** The chart grouped orders by the UTC calendar day while the range itself was your local day, so on every store outside UTC a single-day selection produced two points, the first labelled with yesterday's date. Days are now folded to your store's timezone, correctly on whole-hour, half-hour and quarter-hour offsets and across daylight saving changes. The totals in the cards above the chart were always right; only the chart was wrong.
* Fix: **"Last 7 Days" now covers 7 days rather than 8.** The 7, 30 and 90 day ranges each reached back one day too far, and because the previous period they were compared against was the correct length, the percentage change shown beside each figure was off as well. Your numbers will move slightly as a result: they are now the numbers the label promises.
* Fix: **The advertising card no longer counts a day's sales as pure profit.** Its own cost-of-goods lookup compared local dates against a date stored in UTC, which on a single-day range narrowed the window to about an hour and found nothing, so product cost was left out of that card's profit entirely.
* Fix: **A Google Sheets order sync can no longer repeat the same orders forever without writing anything.** After exporting a batch, the sync marks each order as sent. That mark was written straight to the database, and if it landed in one table while the part that looks for unsent orders reads another, which is what happens on a store part-way through WooCommerce's move to its own order tables, the database reported a perfect success and the mark never appeared. The same orders were picked up again on the next run, and every run after that, each one writing no rows at all. The mark is now read back from the table the sync actually reads, and any order missing it is recorded again through WooCommerce itself.
* Fix: **A brief outage of BrikPanel's Google session service no longer looks like a lost connection.** When the service that renews your Google session could not be reached, the sync reported that your connection had been disconnected, which sent store owners hunting for a fault on their own hosting. It now says the interruption is temporary and that the sync will carry on by itself.
* Developer: `brikpanel_payment_fee_meta_keys` covers the two new gateway fields, and the new `brikpanel_payment_fee_currency_meta_keys` filter maps each fee field to the field that holds its currency.

= 3.2.83 (2026-08-26) =
* Fix: **The Products screen and the product editor no longer break on hosts without the Multibyte String PHP library.** A store owner reported a Products page that never finished loading, and a critical error under the Category box on Add product, whether or not the store had any products. Both came from the same place: BrikPanel used a text function that this optional PHP library provides, without first checking the library was there. WordPress and WooCommerce both run happily without it, so the store looked fine everywhere else, which is what made it so hard to place. Because every store has at least one product category, the two screens failed on every single load. On the product editor the page stopped right after the "Category" heading, so the error was at least visible; on the Products screen it stopped inside the hidden Quick Edit panel, so nothing was shown at all and the loading circle simply turned forever. Every place BrikPanel handles text this way now falls back to a plain-text equivalent when the library is missing, including a lowercase conversion that keeps Turkish, Central European and accented category names searchable rather than leaving them out.
* Fix: **The products list now tells you when something went wrong instead of spinning forever.** If the server answered with something the list could not read at all, or a column added by another plugin failed while the table was being drawn, the loading circle stayed on screen with no message and no way forward but a page reload. Those cases now clear the circle and show "An error occurred. Please try again." A request that never comes back at all gives up after two minutes and does the same, rather than leaving the screen loading indefinitely.
* Fix: **Category and Brand boxes draw quickly on large catalogues, and say so when they are empty.** Building the category tree re-read the whole list of categories once for every category in it, which is unnoticeable on a small store and can exhaust the server's memory or time limit on one with thousands, producing a critical error on both the product editor and the products list. The tree is now built in a single pass. An empty Category or Brand box also says "No categories found." / "No brands found." instead of showing an empty white area that reads as broken.

= 3.2.82 (2026-08-26) =
* Fix: **BrikPanel no longer takes a store offline on older WooCommerce versions.** On WooCommerce 4.0 through 5.8 the plugin called a scheduling function that those versions do not have, and because the call ran on every page load the result was not a broken feature but a broken site: the storefront, the login page and the whole admin area returned a critical error, and the plugin could not be switched off from the admin or from WP-CLI to undo it. BrikPanel now asks the same question in a way every supported WooCommerce understands, so background jobs are still scheduled exactly once on those versions rather than the plugin simply going quiet. Stores on WooCommerce 5.9 and later were never affected.
* Fix: **A background job that cannot start no longer breaks the page it started from.** While WooCommerce is moving its scheduled-jobs storage to its newer tables, which happens by itself shortly after a fresh install, it can refuse to accept new jobs. That refusal used to travel up and return a critical error on every page of a brand new store. The job is now simply left for the next page load, which is where it gets picked up.
* Fix: **The Scheduled Tasks screen no longer breaks after a job has been cancelled.** On WooCommerce 4.0 the list could not draw a cancelled job and the whole screen failed to load, which happened the first time anyone switched a Google Sheets sync off. Rows that cannot be drawn are now left out instead.
* Developer: `Brikpanel_Cron::has_any_scheduled( $hook )` answers whether any job is queued for a hook regardless of its arguments. `Brikpanel_Cron::REQUIRED_FUNCTIONS` lists every Action Scheduler function the class depends on, and `is_available()` now checks all of them.

= 3.2.81 (2026-08-25) =
* Fix: **The "Follow-ups" column on the abandoned carts list is no longer drawn when nothing can fill it.** With BrikMentor installed but unable to answer, the column appeared on every row and stayed empty, which reads as broken rather than as no data. That covered three real situations: an older BrikMentor that predates the feature, one held back by its own dependency check, and one stopped because WooCommerce is inactive. The column now appears only when something is actually listening. The phone and WhatsApp column is unaffected and keeps working, because BrikPanel builds it from its own data.

= 3.2.80 (2026-08-24) =
* New: **A "Clear all" button empties a product's variation list in one click.** Starting a variation matrix over meant deleting every row by hand, one trash icon at a time, which is a long job on a product with fifty variations. The button sits beside "Generate variations", asks you to confirm, and then removes them straight away rather than waiting for a save. The product stays a variable product and keeps its attributes, so the next click can be "Generate variations" to build a fresh matrix. Variations that a third-party plugin had hidden as drafts are removed too, so nothing is left behind to reappear later. Large matrices are cleared in batches, so a product with thousands of variations finishes instead of timing out. This also fixes a related problem: saving a product whose variation list had been emptied used to turn it into a simple product and drop its variation attributes.

= 3.2.79 (2026-08-24) =
* New: **Payment processing fees are counted as an expense, using the real amount your provider charged.** Stripe, PayPal and WooPayments already record what they deducted from each order, but that figure was never read, so the only way to account for card commission was to guess it with a percentage-of-revenue cost. The real per-order amount is now taken straight from the order and shown as its own "Payment fees" line in the expenses breakdown, so foreign-card surcharges, currency spreads and refund adjustments are all included instead of averaged away. It also appears in the Excel export and the Google Sheets Profit tab, and you can file your own costs under it. Orders paid another way, such as bank transfer or cash on delivery, simply have no fee. Where fees were found on only some orders, or in a currency with no exchange rate set, the Expenses card says so rather than presenting a partial figure as complete. Switch it on or off at the top of the Operational Expenses screen; it starts on. If you already keep a percentage-based cost for card commission, that screen now warns you it may be counting the same money twice.

= 3.2.78 (2026-08-21) =
* New: **A "Variation SKUs" column shows the codes of a product's variations without opening it.** The SKU column shows a variable product's own code, so the only way to see what its variations are called was to open the product. The new column, switched on from the "Columns" button on the products list, puts them on the product row: one code prints as itself, several collapse into a small count you hover to read the full list. It reads the code each variation actually has, so a variation that simply inherits the parent's code is not counted as one of its own. The column is off until you turn it on, and adds no extra database work whether it is on or off. Searching already matched variation codes, so you can now find a product by one of its variation SKUs and see that SKU in the list as well.

= 3.2.77 (2026-08-21) =
* New: **The products list tells you how many variations a variable product has.** The "Variable" tag next to the product name now carries the count, so you can see at a glance which products have five variations and which have fifty. Until now the only way to find out was to click into the price or stock cell and open the variation popup. Nothing extra is loaded to work this out, so the list is no slower.
* New: **Admin Columns now works with the BrikPanel products list.** Columns you set up in the Admin Columns plugin never appeared here, because BrikPanel draws its own products list and Admin Columns only attaches itself to the standard WordPress one. Your configured columns are now listed under "Plugin columns" in the Columns menu, with the labels, widths and order you gave them, and appear in the table once you tick them on. They start switched off, like every other plugin column, so the table never widens itself. Columns that Admin Columns only re-lists from WooCommerce or another plugin are left out, since those already reach this list on their own.
* Fix: **Editing a cell no longer blanks the plugin columns on that row.** After changing a SKU, price or stock quantity straight in the list, the cells contributed by other plugins on that row emptied out, along with GTIN, Product Code, shipping class, author and the featured star. They stayed empty until the page was reloaded, because the row was redrawn from the smaller set of data the edit sends back. The edit now updates the row instead of replacing it.
* Developer: `brikpanel_products_columns` now does what it has always documented. A column definition with a `render` callback is drawn for real, with a header and a cell on every row, and its `width` is honoured; the callback receives the product and its ID, and for a variable product it receives the parent, so it can aggregate across variations. Cell output is sanitised the way third-party column cells are, a callback that echoes rather than returns also works, and a callback that throws leaves an empty cell instead of breaking the list. New columns are visible by default unless the definition sets `'default' => false`.

= 3.2.76 (2026-08-21) =
* Fix: **A deleted product can no longer keep its SKU reserved.** WooCommerce keeps a fast SKU index next to your products, and a product removed from the database could leave an entry behind in it. The WordPress admin still reported that SKU as free, but the REST API refused to create a product with it, so an ERP, marketplace connector or import tool got "already present in the lookup table" for a product that no longer existed and could never send it again. BrikPanel now clears those leftovers at the end of the request that caused them, whatever removed the product.
* Fix: **Fast delete now clears the cached copy of every product it removes.** In fast mode BrikPanel deletes rows straight from the database for speed, but the copies WordPress and WooCommerce keep in memory were left behind. On a store with an object cache such as Redis or Memcached, a deleted product could still be read for a while afterwards, which is what let the SKU index entry above come back. Each batch now clears exactly what it deleted, and the site-wide cache flush that used to run at the end of the job, slowing down every visitor, is gone.
* Fix: **Cancelling a fast delete no longer leaves category counts wrong.** Stopping the job halfway skipped the tidy-up that runs when it finishes, so the product counts next to your categories stayed at their old numbers. Cancelling now finishes what the completed batches started.
* New: **Store Health reports on your product SKU index, and can clean it up.** A new "Product SKU Index" check counts entries pointing at products that no longer exist, shows you which SKUs are blocked, and clears them with one click. Nothing in your catalogue is touched: only rows whose product is already gone.
* Developer: `brikpanel_sku_lookup_guard_cleaned` fires after leftover lookup rows are removed. `brikpanel_brikcontrol_lookup_warn_orphans` sets the warning threshold and `brikpanel_brikcontrol_lookup_scan_attributes` can skip the attribute-table scan on very large catalogues. Store Health checks can now offer a repair action by overriding `supports_fix()` and `run_fix()`.

= 3.2.75 (2026-08-19) =
* New: **Shipping can now be counted as a cost, so it stops inflating your Net profit.** What a customer pays for delivery was added to your revenue with nothing deducted against it, so every store that charges for shipping read a higher profit than it actually made. A new "Subtract shipping cost from Net profit" setting under WooCommerce, Settings, BrikPanel, Analytics turns the deduction on. WooCommerce never records what you paid the courier, only what the customer was charged, so that charge is what gets deducted, and where you know the real figure the new "Shipping cost" box on the order screen holds it for that one order. That box is also the only way to account for an order you shipped free of charge, where nothing was charged and so nothing would otherwise be deducted. The setting is off by default, so your figures do not move on update, and switching it on or off takes effect on every date range at once. Shipping gets its own line in the profit breakdown and its own column in a Google Sheets profit report.
* New: **An expense can now be filed under another expense.** Adding a cost offers a "Part of" picker listing the top-level expenses you already have, so Cleaning and Coffee can sit under Office and the profit breakdown draws them indented beneath it instead of as one long flat list. Nesting is presentation only: nothing is merged or subtotalled, every line keeps its own amount and its own share of revenue, and a percentage cost can be a parent or a child like any other. Renaming an expense carries whatever is filed under it, and removing one asks first, because it takes them with it. The same picker is on the dashboard's quick add, and "Part of" is a writable column in the expenses tab of a Google Sheets sync.
* Developer: `brikpanel_profit_shipping_cost` filters the shipping figure deducted from Net profit for a window, which is where a label-printing plugin or a 3PL feed can supply the real carrier charge instead of the estimate.

= 3.2.74 (2026-08-19) =
* Fix: **An abandoned cart is no longer wiped when the shopper comes back with an empty basket.** BrikPanel keeps a copy of what was in the cart so you can see it and follow it up. That copy was refreshed on every visit, including visits where the browser arrived with nothing in the cart at all - an expired session, a basket cleared somewhere else, an order placed under a different address. On a cart that had already been marked abandoned that was final: the contents were gone, the row dropped out of the Abandoned list for good, and it started reading as "Email only", as though the shopper had left an address and never had a cart. A cart that has been marked abandoned now keeps what was in it. Carts that were never marked abandoned still update as before.
* Fix: **Carts already damaged that way are put back where they belong.** A one-time correction moves them out of "Email only" and back into "Abandoned". Their contents cannot be recovered - nothing else held a copy - but the list stops contradicting itself.
* New: **A shopper who abandons a second, different cart is announced again.** Until now a cart row was announced to follow-up tools once in its life, so a customer who came back weeks later, filled a completely different basket and left again was never chased for it. It is announced again when the basket really is a different one and at least a day has passed since the last announcement. Both conditions matter: without the first, every reviving cart would be announced over and over; without the second, a shopper adjusting quantities would start a new sequence every day. The `brikpanel_cartab_reannounce_hours` filter sets the wait, or returns 0 for the old behaviour.
* New: **The Follow-ups column says why a cart was not chased.** With BrikMentor installed but its cart flow switched off, its licence inactive or its sending domain not yet connected, the cell reads "Not chased: ..." instead of sitting empty. An empty cell reads as a fault; this names the setting.

= 3.2.73 (2026-08-18) =
* Fix: **Bundles, composites and other add-on product types keep their contents when you save them in the BrikPanel editor.** The protection added in 3.2.60 works by asking your plugins which product sections they add, so BrikPanel can tell when a product type has settings this editor does not show and leave that plugin's data alone. It asked every plugin in one go, and a single plugin that failed to answer took the whole answer down with it, so the protection quietly never switched on. WooCommerce Composite Products fails to answer on any store, which meant the protection was off wherever it was installed and a bundle could still come back empty after a save. Each plugin is now asked on its own, so one bad answer costs only that plugin's sections. A plugin that cannot answer at all is now also kept away from the save, which protects composite products themselves for the first time. Everything else on the page continues to save as before, on every product type.
* Fix: **The list of extra product sections in settings is complete again.** Under WooCommerce, Settings, BrikPanel, the same failure emptied that list, so sections belonging to perfectly healthy plugins were missing and could not be added to the editor. Reported by devksec on the support forum, along with the two items above.
* Fix: **"Open in WooCommerce" now opens the WooCommerce editor.** The note shown on product types BrikPanel cannot fully display offered a link that led straight back to the BrikPanel editor, so on a store where everyone works in the BrikPanel interface there was no way to reach those settings at all. The link now opens the WooCommerce editor for that one product, and saving there leaves you on that screen. The next product you open still opens in BrikPanel.
* Developer: `brikpanel_pe_unrepresented_owner_paths` filters the plugins BrikPanel holds back from `woocommerce_admin_process_product_object` for a product type it cannot represent, alongside the existing `brikpanel_pe_unrendered_type_panels`. Adding `&brikpanel=0` to a product edit URL skips the redirect into the BrikPanel editor for that one request.

= 3.2.72 (2026-08-17) =
* Fix: **Prices no longer come out back to front in Arabic, Hebrew and Persian messages.** A store in Egypt sent a WhatsApp message quoting a total of 15.402,50 EGP and the customer read "EGP 50,15.402". The digits were right when they left the store; they were rearranged as the message was drawn on screen. Written inside a right-to-left sentence, the decimal mark can be read as an ordinary piece of punctuation rather than as part of the number, and the two halves of the amount are then laid out in the opposite order. WooCommerce protects prices from this on your shop pages, and that protection was being lost on the way into a plain-text message. It is now restored around every amount, date, phone number and order number in a WhatsApp draft and in a status-change email. Nothing changes for a store writing in a left-to-right language.
* Fix: **A status-change email subject that quotes the order total now shows the amount, not its markup.** A subject or heading written as "Your order {order_total} is on its way" arrived reading "&#36;1,299.00" instead of "$1,299.00".
* New: **The abandoned-cart WhatsApp draft understands {cart_total}.** The shopper's cart total, formatted in the currency the cart was captured in, so a message can quote the amount waiting to be paid. Your saved message is untouched; the placeholder is simply available now, listed with the others under WooCommerce, Settings, BrikPanel, Cart abandonment.
* Fix: **Variation names no longer show stray markup in the abandoned-cart list.** Where WooCommerce or another plugin puts markup between a variation's name and its attributes, a product recorded as "Hoodie<span> - </span>M" appeared exactly like that in the cart column, in the WhatsApp draft and in an exported CSV. Names are now reduced to plain text as they are read, so carts recorded before this release are corrected as well.
* Fix: **A price is no longer split across two lines in a WhatsApp message.** The no-break space WooCommerce places between the amount and the currency symbol was being turned into an ordinary space, leaving the symbol free to wrap onto the next line on a narrow phone screen.
* Developer: `brikpanel_money_text()`, `brikpanel_money_text_from_html()`, `brikpanel_bidi_isolate_ltr()`, `brikpanel_bidi_isolate_numbers()` and `brikpanel_plain_text_from_html()` are available for anything that renders a price, a date or a phone number as plain text. Defining `BRIKPANEL_NO_BIDI_ISOLATION` in wp-config.php turns the isolation off.

= 3.2.71 (2026-08-17) =
* Fix: **A shopper still typing their email address no longer leaves a second cart behind.** The checkout captures an address as it is typed, and it cannot tell a pause from a finished address: someone who had reached "name@gmail.co" and typed the rest three seconds later ended up with two carts, one of them at an address nobody reads. That row counted as an abandoned cart and would have been sent follow-up mail that bounces. On one live store six shoppers had such a row, and all six had in fact completed their order. A further address from the same browser, with the same wording before the "@" and within fifteen minutes, is now read as the same shopper still correcting the same address, so it updates the row already open instead of opening a new one. Two genuinely different addresses, or the same address from two different browsers, still keep their own rows as before. Popup signups are left alone, because a coupon may already have been issued against that address.
* Fix: **Customers who really did buy are no longer moved back to "Abandoned".** The repair that reopens carts credited to an order that failed asked one question only: did this address ever buy anything? For the half-typed rows above the answer was no, because the order was placed under the corrected address, so the rows of people who had genuinely bought were reopened and put back on the follow-up list. Two further signs are now accepted: the browser recorded on the order itself, and another row for the same shopper closed at the same moment, which also covers orders placed before that record existed.
* Fix: **An old abandoned cart no longer gets today's date, or a second round of follow-up.** A reopened cart was stamped with the time of the repair rather than its own, so about an hour later it was marked abandoned all over again with today's date, and everything listening for an abandoned cart, including follow-up mail, started afresh on carts that had been left behind weeks earlier. On the reporting store 26 of 27 rows were re-announced this way. Reopened carts now keep their own dates, and a cart is announced as abandoned once and once only, whatever happens to it afterwards.
* Fix: **Rows already on your list are tidied once on update.** Where the same shopper has several rows from one bout of typing, they are merged into the one that carries the real address, keeping the row that became an order, and dates that had been pulled forward are put back. Carts from the same address that are simply duplicates, and rows outside the fifteen-minute window, are left as they were. The repair now works its way through in small batches, so a store with tens of thousands of carts can no longer run out of memory on the first admin page after updating.
* New: **A short note about BrikMentor now appears on Customer Analytics and Abandoned Carts.** BrikMentor is the AI assistant and email marketing engine being built for WooCommerce, and the card explains what it will do with the figures on the screen you are looking at, with a button to join the private beta list. Dismissing it anywhere hides it everywhere, including the one on the dashboard, and it disappears for good once BrikMentor is out.
* Fix: **Spanish stores now get the right wording where a count can be zero.** The Spanish translation file carried a French heading and France's rule for choosing between singular and plural, and the two disagree at zero, so a line such as "0 products" could come through in the wrong form. The heading and the rule are corrected.
* Tweak: The new waitlist wording is translated in all nine languages BrikPanel ships with: German, Spanish, French, Italian, Dutch, Polish, Brazilian Portuguese, Russian and Turkish.
* Developer: `brikpanel_cartab_email_captured` fires again, with the same row, when an address is corrected, so a mailing tool always ends up with the address the shopper actually uses. The fifteen-minute window can be changed with the new `brikpanel_cartab_typo_window` filter.

= 3.2.70 (2026-08-16) =
* Fix: **BrikPanel no longer costs a database lookup per setting on every page load.** Settings were read one at a time, in the shop front as well as the admin, and settings belonging to a section you had never opened were never saved at all, which costs just as much to ask for as one that is there. All of them are now fetched together in one go. Measured on a store with every section saved: fifteen lookups on each shop page and forty-nine on each admin page, down to none. Measured again on a store that had never opened those sections, where between eleven and thirty-one lookups per admin page survived the first pass: also down to none. Reported by a store owner.
* Fix: **The command palette no longer rewrites its menu index on every admin page.** To let Ctrl+K find any admin page, BrikPanel keeps a copy of your menu. That copy, around 30 KB on a plugin-heavy store, was written back to the database every time you opened any admin page even when nothing about the menu had changed, and on the reporting store that single write took 1.2 seconds per page. It is now written only when the menu actually changes, so opening admin pages costs nothing at all. Reported by a store owner.
* Fix: **That menu copy is now kept only for people who can use the palette, and is removed with the account.** It was saved for every user who opened any admin screen, including those without permission to open the palette at all, and it was still saved with the palette's navigation search switched off. Because the copy no longer expires on its own, it also had to be cleared when an account is deleted, and that only happened for deletions made through the admin screens: deleting a user with WP-CLI, through the REST API or from another plugin left the copy behind for good.
* Fix: **The palette now notices when a plugin moves one of its own pages.** A plugin that changes the address of a menu entry while keeping the same name used to go undetected, so Ctrl+K kept offering the old address and there was nothing left to correct it. Every index is rebuilt once on update.
* Fix: **The store health scan no longer floods the scheduled-jobs queue.** Turning plugins on or off queued a fresh scan for each plugin rather than one for the operation, so switching off twenty plugins queued twenty scans at once, and a plugin that disables itself on each page load could keep the queue permanently full. High CPU and a sluggish admin followed. One plugin change now queues one scan, it waits for the operation to finish before measuring, and there is a floor on how often it can run. A further plugin change inside that window moves the waiting scan rather than being ignored, so what finally runs sees the plugins you ended up with. Stores already carrying a backlog have the duplicates cleared once on update, leaving the normal daily scan untouched. Reported by a store owner.
* Fix: **Notices are no longer hidden behind the header on the order screen.** The space kept clear under the fixed bar at the top of an order was measured against the wrong part of the page, so the "Order updated" message and any warning sat partly underneath it, and the problem got worse rather than better whenever a notice was actually on screen. The space is now measured against the top of the content column at every window size, with the top bar on or off, and on phones, so it stays right even when another plugin adds a banner of its own above the page or changes the height of the WordPress toolbar. Reported by a store owner.

= 3.2.69 (2026-08-15) =
* Fix: **A payment that fails no longer leaves the cart marked "Recovered".** A cart was counted as won back the moment WooCommerce created the order, which is before the payment gateway has even run. A card that was then declined left the cart reading "Recovered" for good, so the Recovered count and its value included money the store never took, and your follow-up emails stopped going to exactly the shopper who still needed them. A cart is now recovered only once its order reaches a status that means a real sale, which covers bank transfer, cash on delivery and any custom order status your store uses, and the row re-opens by itself if that order is later declined, cancelled or deleted. Reported by a store owner.
* Fix: **Retrying a failed payment no longer splits one cart into two rows.** Because the first attempt had already closed the cart, the shopper's next try opened a fresh row for the same cart, which became another abandoned cart an hour later. One shopper could end up with an active cart and several recovered ones side by side. One cart now stays one row however many times payment is attempted.
* Fix: **Figures already recorded are corrected once on update.** Carts credited to an order that failed, was cancelled or has since been deleted go back to Abandoned or Active, and duplicate rows left behind for the same cart are merged into one. Carts that really were bought are left untouched.
* Fix: **A cart abandoned at the payment page no longer disappears from the list.** With gateways that send the shopper to the bank's own site, the cart is emptied on the way out, and a shopper who gave up there had their saved cart contents overwritten with an empty one, which took the row out of the abandoned list altogether. The saved cart is now kept while payment is in flight, so the shoppers most worth chasing stay visible.
* Fix: **Saving a product can no longer clear its images.** When the image gallery had not finished loading, a save said nothing about images at all and the server read that as "the merchant removed them", so the product's featured image and gallery were quietly emptied. Because the editor also saves by itself every minute, this could happen without anyone pressing Save. The editor now stays silent about images until it knows what they are, and removing every image by hand still works exactly as before, on simple and variable products alike.
* Developer: A new `brikpanel_cart_recovery_reverted` action fires when a recovery is undone, so an email tool that cancelled its follow-up series can queue it again. Documented, with the rest, under WooCommerce → Settings → BrikPanel → Developers.

= 3.2.68 (2026-08-15) =
* Fix: **"Active carts" now counts carts, not empty email signups.** An email captured with nothing in the cart was counted as an active cart, which is why the card could read "Active carts 6" next to "Value in cart $0.00". Those rows also never aged out, because only carts holding items are moved to abandoned, so the number could only grow. Emails captured without a cart still count under "Emails collected" and are listed as "Email only". Reported by a store owner.
* Fix: **"Recovered" now means a cart that really was abandoned and then bought.** Any order matching the shopper marked their cart as recovered, including one placed moments after the email was captured, without the cart ever having been left behind. Those are ordinary sales, and counting them made the card and its "Recovered value" read far higher than the carts you actually won back. They are now listed separately as "Converted", and Recovered counts only carts that were abandoned first.
* Fix: **One order no longer counts as several recoveries.** A shopper captured more than once (a popup signup and a checkout entry, say) had every one of those rows credited with the same single order, so both the Recovered count and the recovered value were inflated by carts that never separately sold. One order now credits one cart. Figures already recorded are corrected once on update, so existing stores will see Recovered fall to its true value.
* New: **You can set how long a cart stays eligible to be counted as recovered.** WooCommerce → Settings → BrikPanel → Cart abandonment has a new "Count as recovered within" setting, seven days by default. A customer returning long after they left a cart behind is a new sale rather than a recovery, and previously a cart from a month earlier was still credited to that order.
* Fix: **Changing an order's status in the admin no longer credits the wrong cart.** Recovery matched the browser making the request as well as the billing email. On the order screen that browser is yours, not the shopper's, so a store admin with their own captured cart could have it credited to whichever order they were editing. Browser matching now applies only where it belongs, at the checkout itself.

= 3.2.67 (2026-08-15) =
* New: **You can now decide, per attribute, whether it shows on the product page.** Every attribute row in the product editor has a "Show on product page" switch, matching the checkbox WooCommerce offers on its own product screen. Switch it off and the attribute disappears from the Additional information table on the storefront while everything else about it stays the same. On a variable product you can hide an attribute from that table and still keep it as an option buyers choose, exactly as WooCommerce allows. Reported by a store owner.
* Fix: **Attributes you had hidden no longer come back on the next save.** The editor did not read WooCommerce's "Visible on the product page" setting and switched it back on every time a product was saved, so an attribute hidden from the WooCommerce product screen reappeared on the storefront as soon as the product was saved in BrikPanel. Your setting is now read, shown and kept, on both simple and variable products.

= 3.2.66 (2026-08-15) =
* New: **Abandoned Carts lets you choose which columns you see, and in what order.** A "Columns" button above the table switches any column off, and you can drag the entries to put the columns in the order you prefer, or move them with Alt and the arrow keys. Your choice is remembered for you alone, so it does not change what anyone else on the store sees. Two columns you could not see before are now available: "Cart total" on its own, and "Created", the date the cart was first started.
* New: **You can sort abandoned carts by cart value or by age.** A "Sort by" picker above the table offers highest and lowest cart value, and oldest and newest cart, alongside the usual last activity. Sorting by highest value makes the big carts worth chasing easy to find, and oldest first surfaces the ones that have been sitting the longest. Exports follow whatever sort you have chosen, so the file matches the screen. Requested by a store owner.
* New: **Pick a date range in one click instead of typing two dates.** The two empty date boxes above the abandoned carts list are gone, replaced by a single picker with Today, Last 7 days, Last 30 days and Last 90 days. Two specific dates are still available under "Custom range", which reveals the date boxes only when you ask for them. The list opens on "All time" as before, so nothing changes until you choose a range.
* Fix: **Date filtering now follows your store's timezone.** Filtering the abandoned carts list by date compared your dates against UTC rather than your store's own clock, so on a store several hours ahead of UTC a day's filter was shifted by that many hours: carts from the early hours were missing and some from the previous evening appeared instead. Dates are now read in your store's timezone.
* Tweak: **The filters above the abandoned carts list are now a single tidy row that applies itself.** Search, status, source, date range and sorting sit on one line with their labels inside them, searching happens as you type, and every other control applies the moment you change it, so the "Apply" button is gone. A "Clear" link appears whenever a filter is active.

= 3.2.65 (2026-08-15) =
* Fix: **Store Health no longer stops part-way through scanning your products.** On stores with more than 200 products the scan ran its first batch and then stopped, so the page sat on "Scanning 200 / 667 products…" forever and the image check never produced a result. Each batch queues the next one, and that hand-off was being refused because the batch already running counted as a duplicate of itself. Scans now run to the end whatever the size of your catalogue. Reported by a store owner.
* Fix: **A scan that stops halfway no longer leaves "Scan now" greyed out with no way back.** While a scan was believed to be running the button was disabled, so a store left on a frozen progress bar could not start a new scan at all and had to wait an hour for the state to expire. Store Health now checks whether anything is actually still queued, and picks the scan up from where it stopped instead of leaving it hanging. This also repairs stores that were left frozen by the previous version: opening the page is enough.

= 3.2.64 (2026-08-15) =
* New: **You can put variations in the order you want.** Grab a row by the handle on its left and drag it where it belongs, or use the arrow keys once the handle has focus. There is also a "Sort variations" picker above the table for A to Z, Z to A, and the order your attribute values are already in. The order is saved with the product and is the order you see everywhere else, including WooCommerce's own product screen. Until now there was no way to sort variations at all: the list always came back in the order the variations happened to be created. Reported by a store owner.
* Fix: **"Generate variations" no longer rearranges the variations you already have.** It used to rebuild the whole list from scratch, so an order you had arranged by hand was lost every time you pressed it, and a newly created variation could jump to the top. Existing variations now stay exactly where they are and only genuinely new combinations are added, at the end of the list. Reported by a store owner.
* Fix: **Regenerating no longer silently deletes variations.** A variation whose combination is no longer in your attribute values, and a row you added by hand with "Any", both used to vanish when you pressed "Generate variations", and the next save removed them for good. They are now kept and marked "Not in your attributes" so you can decide whether to delete them. A variation you had just deleted can also no longer come back from a later "Generate".
* Fix: **Fields added by other plugins now stay with the right variation.** If another plugin adds its own field to each variation, deleting a variation used to shift every one of those values onto the variation below it, and the last one was lost. The same applied when reordering. Each value now stays with the variation it belongs to, and anything you type into such a field is no longer wiped when the table redraws.
* Fix: **Saving a variable product with the variations section switched off no longer destroys it.** If "Variations" was turned off in WooCommerce → Settings → BrikPanel → Products, saving a variable product from the editor turned it into a simple product and permanently deleted every one of its variations, because the hidden switch reported "not a variable product". The editor now leaves the product type alone when it has no variations section to ask about.

= 3.2.63 (2026-08-14) =
* Fix: **A phone number that already carries its country code no longer gets a second one in front of it.** A shopper who typed "90 545 728 83 42" at a store based in the United States was linked to "+1 90 545 728 83 42", a number belonging to nobody. When BrikPanel has no country on file for a shopper it used to fall back to your store's own country and put that code in front regardless; now, if the number already begins with a country code, the number is trusted and left alone. When the shopper's real country is known nothing changes. Reported by a store owner.
* New: **Abandoned carts remember which country the phone was typed in.** Checkout now records the billing country alongside the phone, so the WhatsApp link no longer has to guess one afterwards. Where a guess is still the only option, the button's tooltip says so, and shows the exact number it will dial before you click it. Carts saved before this update keep working and simply fall back to the smarter detection above.
* Fix: **The Orders and Abandoned Carts screens now build WhatsApp links the same way.** The two screens each had their own copy of the number logic and could disagree: a Caribbean number gained a duplicated area code on one screen but not the other, a number already written with its country code was doubled on one screen, and one screen would happily build a link from a number too long to be real. Both now share one routine, so the same customer always gets the same link. Numbers written with "+", with "00" or with the North American "011" dial-out prefix are all understood, and a single national leading zero is dropped without eating the rest of the number.

= 3.2.62 (2026-08-14) =
* New: **Attributes you type in the product editor can become real WooCommerce attributes, in any language.** Colour and size swatches, layered navigation and attribute filters all read what WooCommerce calls global attributes, the ones listed under Products → Attributes. The editor used to convert one for you only if you happened to name it Color, Colour, Renk, Size or Beden, so a Dutch shop typing "Kleur" ended up with a product-only attribute its theme could not use, while an English shop typing "Color" got a site-wide one it never asked for. There is now one switch, "Create global attributes automatically" in WooCommerce → Settings → BrikPanel → Products, on by default and no longer tied to a list of words. An attribute that already exists is reused instead of duplicated, whatever capitalisation you type. Nothing is created while the product is still a draft, and a name WooCommerce will not accept, too long, reserved or just a number, quietly stays product-only rather than failing the save. Switching it off later leaves attributes that already exist alone; remove those in Products → Attributes. Reported by a store owner.
* Fix: **A variation's default choice no longer disappears when you save twice without reloading.** When an attribute became a global one during a save, the editor kept referring to it by its old name, so the "Default Form Values" dropdown came back empty and the next save cleared the default you had picked. The editor now picks up the new attribute, its proper label and its values straight from the save, so a second save keeps everything and a variation row you add by hand offers the right options.
* Fix: **The item list in an abandoned-cart WhatsApp message now puts each product on its own line.** Products were strung together on one line separated by semicolons, so a cart of four or five items arrived as a crowded paragraph that was hard to read on a phone. `{items}` now writes one product per line, variations included. Downloading the list as CSV or Excel is unchanged, where the whole cart still belongs in a single cell. Reported by a store owner.
* New: **The WhatsApp button on your orders now opens with the message already written.** Clicking the WhatsApp icon on the Orders list, or the button on an order's page, used to open an empty conversation and leave you to type everything yourself. It now opens with a draft ready to send, which you can still edit or delete before sending; nothing is ever sent on its own. Write your own in WooCommerce → Settings → BrikPanel → Orders, with `{customer_first_name}`, `{order_number}`, `{order_status}`, `{order_total}`, `{order_items}` and more. Clear the box to go back to opening an empty conversation.
* New: **A different WhatsApp message for each order status.** Say one thing while an order is being prepared and another while it is still awaiting payment. Every order status your store has is listed, including your own custom ones and any a shipping plugin adds; switch one on and write its message, and every status you leave off keeps using the general message. Simple and variable products both list correctly, with each variation's options shown once.

= 3.2.61 (2026-08-14) =
* New: **A button another plugin adds to the top bar now follows you everywhere.** BrikPanel's own top bar steps aside on a few screens, the post and page editor, the site editor, and for staff accounts without WooCommerce permissions, and WordPress shows its own toolbar there instead. Until now a button registered for the BrikPanel bar simply disappeared on those screens. It is now placed in the WordPress toolbar automatically, so the plugin author writes one registration and the button is there on every screen. The store owner keeps the same on/off switch and per-role visibility rules over it either way. Requested by arcanetech.

= 3.2.60 (2026-08-13) =
* Fix: **The Rank Math SEO score is correct again in the product editor.** A product scoring 100/100 in the product list showed 0/100 on the BrikPanel editing screen. Rank Math loads its Advanced Custom Fields bridge on any product screen, and with the ACF section switched off that bridge threw an error which cancelled the entire analysis before a single test had run, so the score fell back to zero. The bridge is now left out when no ACF field is on screen, an add-on that fails while Rank Math gathers the content can no longer take the whole score down with it, and the product's first image is handed over as the featured image so the image tests pass exactly as they do in the WordPress editor. Both screens now report the same number, on simple and on variable products.
* New: **Write your own WhatsApp message for abandoned carts, in your own language.** The message opened from the Abandoned Carts list was fixed text. WooCommerce → Settings → BrikPanel → Cart abandonment now has a "WhatsApp message" box with `{customer_name}`, `{store_name}`, `{items}`, `{cart_url}` and `{recovery_url}` placeholders. `{recovery_url}` rebuilds that exact cart in a single tap, with the right variations selected. Leave the box untouched and the message stays as it was, in your store's language.
* Fix: Text in Arabic, Turkish or any other non-Latin alphabet is no longer cut in the middle of a character when a message or popup field reaches its length limit.
* New: **Live Visitors shows what each visitor is browsing on.** Mobile, tablet or desktop now appears as a small icon at the start of every row, worked out with the same detector as the Devices breakdown, so the two can never disagree. No raw browser information is stored and nothing extra is sent from the visitor's browser.
* Security: **A customer can no longer inject code into your dashboard through their own billing details.** Details a customer types in themselves, such as a phone number, were placed in the Live Visitors row tooltip without escaping the double quote character, so a crafted phone number could run its own script the moment the store owner hovered over that row. Every row tooltip, label and link now uses attribute-safe escaping.
* Fix: **Saving a variable product no longer stops after the first variation.** BrikPanel asks other plugins to save their own variation fields after each variation. A plugin that ends the request outright instead of returning an error, which Woo Product Variation Gallery does when it does not recognise the form it is given, left every variation after the first one unsaved and showed no error at all. Such a plugin now loses only its own field write, your variation data is saved, and every other plugin carries on as normal. The same protection covers the plugins that run when the product itself is saved.
* Fix: **Admin-only wording no longer turns up in translation plugins.** Text that only ever appears on BrikPanel's own admin screens was being prepared on every storefront page view and every background request, so front-end translation plugins such as TranslatePress collected it as store text: 112 such rows on a test store, now none. It is prepared only where it is actually shown, which also takes a slice of needless work out of every page load.

= 3.2.52 (2026-08-13) =
* Fix: **Saving a bundle, composite or booking product no longer wipes its own data.** After a save, BrikPanel told other plugins to process the product, which is how their fields get saved. For a product type whose own WooCommerce panel the simplified editor cannot show, those plugins received a form that never contained their fields and read that as "the merchant cleared everything": a WooCommerce Product Bundles product lost every bundled item and had its layout and cart settings reset. When BrikPanel saves a product type it cannot fully represent, it now holds back only the plugin that owns the missing panel, so that plugin's data is left exactly as it was while every other plugin still saves normally, and the editor says where those settings can be changed. Reported on the support forum.
* Fix: A product whose type is added by another plugin (bundle, composite, booking, subscription) keeps that type when saved from the editor with the product type selector switched off, instead of being turned into a simple product.
* Fix: One plugin failing while WooCommerce draws its product data panels no longer hides every other plugin's panel from the "Additional product data sections" list, or from the editor itself.

= 3.2.51 (2026-08-13) =
* New: **Find a product by your own supplier or manufacturer code.** The product list search already matched the title, the description and the WooCommerce SKU, including a variation SKU, but a warehouse that scans a supplier code kept in its own custom field got nothing back. Stores can now tell BrikPanel which extra fields to search with the new `brikpanel_product_search_meta_keys` filter, and a code found on a variation returns its parent product, so simple and variable products both work. Nothing changes unless you use the filter: out of the box BrikPanel still searches exactly the WooCommerce SKU field. Requested on the support forum.
* Fix: **A SKU containing an apostrophe is now findable.** Searching the product list for a code such as OB'RIEN-9933 returned nothing, because the apostrophe was still escaped when the SKU was matched. Searching by product name was unaffected.
* Fix: A product search no longer leaves its extra search rule switched on for the rest of the page load when another plugin throws an error while the product list is being built, which could quietly widen unrelated searches on the same request.
* Fix: While a product search is running, BrikPanel's extra search rule is no longer applied to searches another plugin happens to run at the same moment, which could quietly widen someone else's results.

= 3.2.50 (2026-08-13) =
* Fix: **Cookie consent now works with the banners people actually use.** The consent gate added in 3.2.48 was tested against the eleven most-installed consent banners, and two problems turned up. Banners that report a decision without declaring which privacy law applies, which includes CookieYes and GDPR Cookie Compliance by Moove, left BrikPanel waiting forever after the visitor had already clicked Accept. And banners that announce "everything denied" on the very first page load, CookieYes among them, made BrikPanel send a pointless clean-up request on every page view before the visitor had touched anything. Both are fixed: a decision from your banner is honoured whichever way it is reported, and a refusal with nothing to clean up is now the no-op it should be.
* Tweak: The consent documentation now lists which banners work with no setup at all (Complianz, CookieYes, GDPR Cookie Compliance, WPConsent, Cookiebot, iubenda, Beautiful Cookie Consent Banner), which one needs its own Compliance mode connected (Cookie Notice), and gives a tested copy-paste bridge for the ones that do not use the WordPress Consent API at all (CookieAdmin, Real Cookie Banner, Termly).

= 3.2.49 (2026-08-13) =
* New: **Remove an expense straight from the dashboard.** The Profit section's Expenses breakdown was read-only: you could add a cost with the "+" button but there was no way to take one back out without leaving the page. Every line that comes from your own expenses now has a small remove control. Because a line is a grouped total rather than a single entry, the confirmation tells you exactly what it covers: one entry is named with its date and amount, several are summed and counted.
* New: **Repeating expenses ask what you meant.** Removing a line that belongs to a repeating expense offers a choice between clearing only the period you are looking at and removing the repeating expense altogether. The first entry of a series is the date the whole series is generated from, so it is kept out of the "only this period" option and the dialog says so rather than quietly deleting future occurrences.
* Fix: **Deleting one occurrence of a repeating expense now sticks.** Removing a single generated occurrence, from either the Operational Expenses page or the dashboard, looked like it worked but the entry came straight back the next time the figures were read: the engine that fills in a repeating expense saw a period with no entry and created it again. Removed occurrences are now remembered, so they stay removed, while the rest of the series keeps running. Editing the expense's amount no longer brings them back either, and changing its start date or frequency correctly forgets removals that no longer apply.
* Fix: A repeating expense set to a percentage of revenue can no longer be expanded into dated money entries, which would have multiplied the rate as if it were an amount.

= 3.2.48 (2026-08-13) =
* New: **Visitor tracking can now wait for cookie consent.** Until now the only way to stop BrikPanel writing a visitor cookie before a consent banner had been answered was to switch tracking off entirely, which also emptied the Visitors, Live Visitors and conversion funnel cards. A new **Wait for cookie consent** switch under WooCommerce → Settings → BrikPanel → Analytics keeps the statistics and holds everything back until the visitor allows analytics: no cookie, no browser storage, no request. Consent takes effect immediately without a page reload, and withdrawing it stops tracking and deletes BrikPanel's own cookies and browser storage for that visitor. Off by default, so nothing changes unless you turn it on. Reported by silaghichris.
* New: **Works with the WordPress Consent API out of the box.** With the consent switch on, BrikPanel reads the `statistics` category, follows live consent changes from your banner, and declares every cookie and browser storage key it uses so a consent platform can list them in your cookie policy automatically.
* Developer: Consent can also be driven from any cookie banner through the `brikpanel_frontend_tracking_allowed` PHP filter or the `brikpanel_start_tracking()` / `brikpanel_stop_tracking()` JavaScript methods. Both are documented under WooCommerce → Settings → BrikPanel → Developers.

= 3.2.47 (2026-08-13) =
* Fix: **Pasting a comma-separated list of attribute values now works.** The attribute value box only split on the pipe character WooCommerce itself uses, so pasting "Red, Blue, Green" landed as one long value. Commas now split too. A pipe still wins when the text contains one, so a WooCommerce list whose values contain commas ("Lime, Basil and Mandarin | Vanilla") is still read correctly.
* Fix: **A failed save now tells you what actually went wrong.** "An error occurred" was all you got when saving a product failed, which is no help to anyone. The message now names the server's reply — the status code and, when another plugin's PHP error killed the request, the error and the file it came from. The full reply is also written to the browser console so it can be copied into a support message.

= 3.2.46 (2026-08-13) =
* New: **Other plugins can add their own buttons to the top bar.** BrikPanel hides the WordPress toolbar, so a plugin that added a button there had nowhere to put it and the only option was the single manual shortcut in the settings. A plugin can now register a real top bar item: a live counter, a menu, a status badge, or just a label and a link. It can sit on the left or the right, next to whichever built-in control it belongs beside. Every registered item shows up in WooCommerce → Settings → BrikPanel → Dashboard with the same on/off switch and per-role visibility rules as the built-in controls, so the store owner stays in charge of it. Requested by arcanetech.

= 3.2.45 (2026-08-13) =
* Fix: **The sidebar lines up for staff accounts, not just administrators.** Menu items supplied by other plugins carried a slightly wider icon than BrikPanel's own, so their labels sat a fraction further right and their rows a pixel taller, leaving a ragged left edge. Administrators barely noticed it because most of their menu is BrikPanel's own items; a staff account, whose menu is mostly other plugins, saw it on nearly every row. Every row now reserves the same icon slot and stands the same height, in both left-to-right and right-to-left stores. Reported by slamadeyinka.
* Fix: **The stray "WooCommerce" row in a staff account's menu is gone.** BrikPanel lists Orders and Customers as menu items of their own and hides the "WooCommerce" heading above them. A role that cannot open either one was left with just the heading, which sat out of line with everything else and led to a "Cannot load woocommerce." error page when clicked, because it is a heading rather than a real screen. It is now left out when there is nothing under it, and styled like any other item on the rare setup where it does open a page.
* Fix: Menu icons that come from another plugin as a Dashicon are no longer drawn larger than the icons beside them, and a menu item the current account cannot open no longer leaves an empty element behind in the sidebar.

= 3.2.44 (2026-08-10) =
* Fix: **Unsaved variation edits are no longer thrown away.** Filling in costs, prices, stock or SKUs across the variation table and then pressing "Generate variations" wiped every one of them and restored the table to how it looked when the page loaded, because regenerating rebuilt each row from the last saved copy rather than from what was on screen. Everything you have typed is now carried into the rebuilt table. The same protection covers a save that is still running: on a big product a save takes a few seconds, and anything typed while it was in flight used to be reverted the moment the reply came back, then quietly saved as empty on the next save. Reported by connororgan94 for variation costs in particular.
* New: **Add a single variation instead of generating every combination.** An "Add manually" button sits next to "Generate variations". It adds one row and lets you pick the combination yourself from a dropdown per attribute, including WooCommerce's "Any" option, so a product with nine bundles and two inserts no longer forces all eighteen rows on you when you only sell three of them. Picking a combination another variation already uses is flagged straight away.
* New: **Paste a whole list of attribute values or tags at once.** The attribute value box now accepts a pipe-separated list, the same format WooCommerce's own attribute box uses, so you can copy a list of values straight across or out of a spreadsheet and get one value per entry. Product tags do the same with a comma-separated list. A comma inside a value is left alone, so "Lime, Basil and Mandarin" stays one value.
* New: **"Select all" for a global attribute.** An attribute backed by a global attribute now shows a button that adds every one of its values in one click, and turns into "Clear all" once they are all on the product. Typing a value the attribute does not have yet offers to add it, so a new value can be created from the product itself instead of going to the attributes screen first.
* Fix: **Deleting an attribute no longer leaves it stuck to the variations.** Removing an attribute row and saving left every variation still carrying the deleted attribute in the database. It was invisible and harmless day to day, but it came back to life the moment an attribute of the same name was added again, silently pinning variations to a value nobody chose. A variation now only keeps the attributes the product actually has.
* New: **Optional wide layout for big monitors.** A new "Use the full screen width" setting under WooCommerce ▸ Settings ▸ BrikPanel ▸ Products lets the variations table and the two description editors spread across a wide screen instead of staying in the centre column; the short-field cards keep their normal width so the page still reads as one page. The variations table then stops needing a horizontal scrollbar on most stores, so cost, SKU and image are visible without scrolling sideways. Off by default, and it has no effect below roughly 1360 pixels. Requested by connororgan94.

= 3.2.42 (2026-08-09) =
* Tweak: The Google Ads and Meta Ads integration is out of beta, so its "Beta" labels have been removed from the dashboard button, the Ad Platforms page, the WooCommerce menu item and the settings screen.

= 3.2.41 (2026-08-09) =
* Fix: **"Most Added to Cart" counted far more adds than really happened.** Three things were being counted that no shopper did. Link preloading, the feature in browsers and speed plugins that quietly loads a page before you click it, follows the "Add to cart" links on your shop and category pages, and WooCommerce fills the cart for real when it does, so a single preloader sweeping one page produced one add for every product on it. On top of that the same person adding the same product again, and carts filled by scripts or from the admin area, all counted every single time. Adds are now counted the same way the "Add to cart" figure above them always has been, one per shopper per product per day, and preloaded requests are ignored everywhere in the analytics. Expect the numbers on this card to drop sharply and to finally line up with the rest of the dashboard.
* Fix: **"Most Viewed Pages" credited category and search traffic to a random product.** Views were recorded against whichever product the page happened to finish listing, so a busy category page inflated one arbitrary product and never appeared under its own name. Category, tag and shop pages are now listed as themselves, the cart and account pages are counted properly instead of being dropped, and a search results page is left out rather than pinned on a product.
* Fix: **Both cards could show fewer than five rows.** If one of the top entries pointed at a product or page that had since been deleted, the row was quietly removed and the card looked like there was less data than there was. The list now fills up to five with whatever still exists.

= 3.2.40 (2026-08-09) =
* New: **The dashboard remembers the date range you picked.** Choosing Last 7 Days, Last 30 Days or a custom range used to last only until you refreshed or left the screen, and the dashboard snapped back to Today every time you came back. Your choice now stays, including a custom range with its exact dates. It is remembered per account, so every member of staff keeps their own view, and per store on a network install.
* Fix: **A date that does not exist on the calendar no longer drags in your whole order history.** A custom range like the 45th of month 13, which only a hand-edited link or a corrupted saved range could produce, slipped past the date check and was read as the beginning of time, so the dashboard and the Excel export both went off and measured every order the store has ever taken. Impossible dates are now rejected on every route in and fall back to today.

= 3.2.39 (2026-08-09) =
* Fix: **A saved product editor layout could be discarded on some stores.** When the stored section layout had been written by a settings import it was ignored entirely and rebuilt from scratch, which dropped any third-party plugin panels the store had added to the editor.

= 3.2.38 (2026-08-09) =
* Fix: **The top bar icons could go blank on a single screen.** On stores running a plugin that styles SVG icons across the whole page, the notification bell, the hidden-notices bell and the other top bar icons were repainted invisible on whichever screen that plugin loads its stylesheet on, most often the Orders list. The buttons still worked and still opened their panels, they just looked empty. The top bar now draws its own icons on its own terms, so no other plugin's styling can wipe them, on any screen and in both left-to-right and right-to-left layouts. Thanks to iesayi for the report.
* Fix: **A dead search box sat in the toolbar for staff who could not use it.** The "Search BrikPanel" box was added to the admin bar for every account, but the scripts behind it only loaded for accounts that could manage WooCommerce, so those staff saw an unstyled box that did nothing when clicked. It is now shown only to the accounts that can actually use it.
* Fix: **The WordPress menu is no longer reordered for accounts that keep it.** Anyone left on the standard WordPress sidebar now also keeps its original ordering, instead of having WooCommerce quietly moved to the top by a panel they are not using.

= 3.2.37 (2026-08-08) =
* Fix: **Staff accounts saw two menus stacked on top of each other.** On any account that was not an administrator, the BrikPanel sidebar could be drawn without the stylesheet that hides the WordPress menu underneath it, leaving an unstyled list of links sitting above the normal WordPress and WooCommerce menu. The sidebar and its stylesheet now always travel together, so this can no longer happen for anyone.
* Fix: **BrikPanel now reaches the staff roles it was always meant to.** The panel only recognised accounts holding WooCommerce's "manage WooCommerce" permission, but WooCommerce itself shows its own menus to roles that hold order, report or product permissions instead. Custom staff roles built with a role editor were caught in that gap. Anyone WooCommerce treats as store staff, plus editors and authors, now gets the BrikPanel interface; customers and subscribers keep the standard WordPress screens as before.
* Developer: new `brikpanel_interface_capabilities` and `brikpanel_user_can_use_interface` filters to widen or narrow which accounts receive the BrikPanel interface.

= 3.2.36 (2026-08-06) =
* New: **Product categories are now a folder tree.** WordPress lists categories flat and marks nesting with dashes, which becomes unreadable once a store has a real hierarchy. Each parent now has an arrow you click to open or close it, sub-categories are indented under the parent they belong to, and a badge shows how many children each one has. Expand all and Collapse all sit above the list, and whatever you leave open is remembered for your next visit.
* New: **A category branch is no longer cut in half by pagination.** Up to 300 categories the whole hierarchy is shown on one page, so a parent and its children always stay together instead of a parent ending page one and its children starting page two. A larger catalogue keeps the old paging, and still gets the tree, because rendering every row at once would cost more than it saves.
* New: **The category search box filters as you type.** Matching categories appear instantly along with the parents they sit under, with no page reload.
* New: **Drag a category onto another to nest it, or onto the strip above the list to lift it back to the top level.** Dropping a category onto its own sub-category is refused, and hovering a closed parent while dragging opens it so you can drop deeper in one motion.
* New: **Add subcategory and Move to top level in the row actions.** Add subcategory picks the parent in the add form for you, so a child category takes one click instead of hunting through the parent dropdown.
* Fix: **Adding a category told you nothing.** "Category added." was being swallowed by BrikPanel's own notice cleanup on that screen, so the form gave no confirmation at all. The confirmation is back, restyled to match the panel, and a rejected name (a duplicate, for example) says so in the same place.
* Fix: **Bulk actions can no longer reach a category you cannot see.** Selecting rows and then collapsing a branch, or filtering the list, used to leave hidden rows ticked, so a bulk delete could hit categories that were never on screen. Hidden rows are unticked automatically.

= 3.2.35 (2026-08-04) =
* New: **A Profit column on the product list.** Switch it on from the Columns menu next to Cost and every row shows what it earns, price minus cost of goods, with the margin measured against cost. Variable products show the range across their variations, a product selling below cost is flagged in red, and a small marker appears when some variations have no cost or price on file yet so a partial figure never passes for a complete one. The number updates the moment you change a price or a cost in Quick Edit.
* Fix: **SEO columns added by your SEO plugin now show real data.** With Rank Math's "SEO Details" column switched on, every row read "N/A" and "Keyword: Not Set" no matter what the product actually had, because BrikPanel never told the plugin which products were on screen. Scores and focus keywords now appear correctly, styled to match the rest of the panel, and the inline edit links that could never work on this screen are no longer shown. The fix is generic, so other plugins that add list columns benefit too. Thanks to ehabeljoker for the report.
* Fix: **Picking your SEO plugin's own panel in the editor settings now works.** If you placed the Rank Math, Yoast, All in One SEO or SEOPress panel yourself under Visible editor sections, the product editor showed BrikPanel's generic SEO fields instead and the panel you picked appeared nowhere at all. Your pick is now honoured: the plugin's own panel renders where you placed it, with its scripts loaded, and it is the only SEO area on the page.
* Fix: **The search preview in the editor no longer shows the wrong plugin's data.** On a store that had switched SEO plugins, or that runs two of them side by side, the Google preview above the SEO panel could show a leftover title and description from the old plugin while the panel below showed the current ones. Whichever plugin is actually installed is now read first, so the preview and the panel always agree.
* Fix: **Your Rank Math score stays current after saving from BrikPanel.** Saving a product through the BrikPanel editor left the score frozen at whatever the last save from the WordPress editor had produced, which then showed up stale in the product list. It is now carried over on every save, and a session where the analysis never ran can no longer overwrite a good score with a zero.

= 3.2.34 (2026-08-03) =
* New: **Costs you keep in a cost-of-goods plugin now show up in BrikPanel.** If your product costs live in Cost of Goods for WooCommerce or WooCommerce Cost of Goods, BrikPanel could not see them: the Cost column stayed empty and the dashboard treated your whole catalogue as free to buy, which quietly made Net profit look better than it is. Those costs are now read everywhere, on the product list, in the editor, in Quick Edit, in the Google Sheets export and in the profit figures, for simple and variable products alike. Nothing changes for stores that do not use one of those plugins, and a store keeping its cost anywhere else can point BrikPanel at that field with the `brikpanel_cogs_meta_keys` filter.
* Fix: **A cost typed into the product editor no longer disappears after saving.** With a cost-of-goods plugin installed, that plugin also adds its own cost box inside the WooCommerce product data panels, and on save it wrote its own (usually empty) box over the figure you had just typed, on the product and on every one of its variations. Both boxes now always show the same number, whichever one you type into, and what you save is what you get back after a reload. Editing the cost in BrikPanel also keeps your cost plugin's own screens and profit figures up to date, and clearing a cost now clears it everywhere instead of reappearing on the next page load.
* Fix: **Editing a cost in a Google Sheet now really changes it.** On a store running a cost-of-goods plugin, a cost typed into the sheet looked like it saved but left the product untouched. It is written to every cost field in use now, and no longer fills the error log with a warning on each synced row.

= 3.2.33 (2026-08-02) =
* Fix: **Right-to-left sites can use their lists again.** On Arabic, Hebrew, Persian and other right-to-left sites, an invisible layer stretched over the whole Orders list and every other admin list. Clicking an order, a product, a link or a button did nothing except tick every checkbox on the page, so nothing could be opened. The layer is gone and every list behaves normally again, with "select all" back to working only from its own checkbox. Thanks to iesayi for reporting it and pinpointing the cause.

= 3.2.32 (2026-08-02) =
* Fix: **Variation names no longer disappear when you save a variable product.** After changing anything in the variations table and clicking Update, the Variation column emptied out on every row and only came back after reloading the page. The names are now redrawn together with the freshly saved rows, so the table stays readable through any number of saves.
* Tweak: **A variation that matches every value of an attribute is now labelled "Any Size"** instead of showing a blank slot in its name.

= 3.2.31 (2026-08-02) =
* New: **Assign a coupon to your customers by name instead of by email.** The coupon editor's customer field is now a searchable picker: start typing a name, username or email address and pick one or several registered customers from the list, each shown with their username so you can tell two people with the same name apart. You no longer have to remember and retype the address an account was registered with. A picked customer is matched by their account email, so the coupon works for them even if they check out with a different billing address. You can still type any address by hand, including guests who have no account and wildcards such as *@example.com.
* Tweak: **The setting is easier to find.** WooCommerce → Settings → BrikPanel → Coupons now calls it "Assign to specific customers" instead of "Allowed email addresses", so it reads like what it does.

= 3.2.30 (2026-07-30) =
* New: **Manage your expenses from a Google Sheet.** Google Sheets gains an Expenses tab that keeps your operational costs in a spreadsheet, so you can paste in a month of invoices instead of adding them one at a time. Turn on two-way sync and any row you type becomes a real expense in BrikPanel, counted in your net profit: leave the Expense ID cell empty and BrikPanel adds the entry and fills the ID in for you, change a cell on an existing row and that expense is updated. One-off costs, repeating costs and percentage costs such as card commission all work, and the sheet is rebuilt from BrikPanel after every change so the two never drift apart.
* Fix: **Crawlers no longer inflate your visitor and add-to-cart figures.** Google's Merchant Center store crawler and many other bots walk a store's "add to cart" links to check prices and stock, and each visit was being recorded as a real shopper adding a real product. On a heavily crawled store that turned into thousands of add-to-carts, an inflated visitor count and crawler entries sitting in the Live visitors panel. BrikPanel now recognises a far wider range of automated traffic, including Google Storebot, Google-InspectionTool, GoogleOther, Google Shopping, the AI crawlers, uptime and SEO tools, headless browsers and command-line tools, and leaves all of it out of every figure: visitors, page views, product views, add-to-carts, checkout visits, Live visitors and abandoned carts.
* New: **Your own exclusion lists.** WooCommerce → Settings → BrikPanel → Analytics has two new fields: "Excluded user agents" for anything else you want left out, and "Excluded IP addresses" for a single address or a whole range, so you can also leave out your own office traffic or a crawler that disguises itself as a normal browser.
* Fix: **A crawler that pretends to be a normal browser can no longer run the numbers up.** Visits that keep no cookies are now counted at most once a day, the same limit a real shopper already had, so an unrecognised crawler can no longer add thousands of events. Real shoppers are unaffected, on simple and variable products.

= 3.2.29 (2026-07-28) =
* Fix: **Paragraph breaks in product descriptions.** Descriptions written before BrikPanel (in the classic WordPress editor, or brought in by an importer) opened in the product editor with every paragraph run together on one line, and pressing Enter to separate them again produced markup the storefront rendered with no spacing between paragraphs. Existing descriptions now open with their paragraphs intact, and a new paragraph created with Enter is a real paragraph everywhere: in the editor, in the HTML view and on the product page. Applies to both the description and the short description, on simple and variable products.
* Fix: **Descriptions were emptied when their section was switched off.** If the "Product description" or "Short description" section was turned off in the product editor's section settings, saving a product cleared the stored description and short description. Both are now left untouched when their section is not shown.
* Fix: **A description you did not edit is no longer rewritten.** Opening a product and saving it (or letting the editor auto-save) rewrote the stored description even when it had not been touched. It is now saved back exactly as it was, and only reformatted once you actually edit it.
* Fix: **A deliberate empty line inside a description now shows on the product page** instead of being dropped, and the first line of a description is saved as a proper paragraph like the rest.
* Fix: **Upsells and cross-sells were not saved.** On stores that show the "Additional product data" card in the product editor, WooCommerce's own product-data handler ran too early in the save and reset every field it could not find under its native name, so linked products were cleared again the moment they were saved. The same reset also emptied the product image gallery. Both now survive the save, on simple and variable products.
* Fix: **Product search in the Upsells and Cross-sells fields now matches WooCommerce.** The picker searched product titles and descriptions only, so a search for a SKU or GTIN found nothing and variations never appeared. It now uses WooCommerce's own product search, returning the same results as the native Linked Products fields.

= 3.2.28 (2026-07-26) =
* Change: **The CSV import on the Abandoned Carts screen has been removed.** The "Import CSV" button that brought an existing email list into the Abandoned Carts list is gone. Everything else on the screen is unchanged: emails are still captured automatically from checkout, the signup popup and logged-in add-to-cart, and search, filters, per-row cart details, CSV and Excel export and the statistics cards all work exactly as before. Entries that were added by the old importer stay in your list and are still shown and exported as "Imported".

= 3.2.27 (2026-07-23) =
* New: **Fields other plugins add to the product screen now work inside the BrikPanel editor.** When another plugin adds its own fields to WooCommerce's native "Product data" tabs or to the variation rows (internal product codes, subscription and booking options, per-currency prices, condition/used-item fields, and other custom fields), BrikPanel can now show them in its product editor and save them correctly through each plugin's own save routine, for both simple and variable products. Previously many such fields either did not show, or showed but silently failed to save. Turn on the new "Auto-show fields other plugins add" switch (WooCommerce → Settings → BrikPanel → Products) to surface them all at once, or leave it off (the default) and pick individual sections in the "Additional product data sections" list, where each option now lists the fields it contains so you can find a plugin's field by name (for example "Inventory (Product Code)"). Per-variation fields from other plugins are always kept and saved, so editing a product never wipes them.

= 3.2.26 (2026-07-23) =
* New: **Cart share links.** Build a cart of products in the admin and hand a customer one link that fills their cart, then sends them straight to checkout. Made for stores that take orders over Instagram, WhatsApp or Facebook: open Create → Cart share link, search the items the customer asked for, set quantities, pick the right variation for variable products, then copy the link or share it on WhatsApp. Customers can share too: a "Share cart" button on the store cart page copies a link that reproduces their current cart. Works with both simple and variable products; find the on/off switches under BrikPanel → Settings → Cart share.

= 3.2.25 (2026-07-23) =
* New: **The "Product Code for WooCommerce" plugin now works inside BrikPanel.** If you use that plugin to give products an internal code (an alternative to the barcode/GTIN), you can now enter and edit that code directly in the BrikPanel product editor, for both simple and variable products (a field per variation), and its optional second code field is supported too. A new "Product Code" column is also available on the products overview: turn it on from the Columns button. For variable products the column shows the code when they all share one, or a compact "N codes" badge listing each variation's code. Everything appears automatically only when the Product Code plugin is active, and honours the titles you set for the fields there.

= 3.2.24 (2026-07-23) =
* Fix: **Saving a product no longer fails silently when another plugin errors during the save.** If a third-party plugin (for example a media offload plugin such as Media Cloud, or an SEO plugin) raised an error while a product was being saved, the save request would end with a server error and the editor would appear to do nothing, leaving no explanation. The editor now catches that situation, keeps working, and shows a clear message pointing to the plugin that needs attention, instead of a blank failure. A leftover coding error in the editor that could hide the real message when a save failed has also been fixed.

= 3.2.23 (2026-07-22) =
* New: **Every user can now switch the BrikPanel interface on or off for their own account, without affecting anyone else.** Until now the on/off (power) switch turned BrikPanel off for the whole store, so one administrator turning it off took it away from every administrator and shop manager at once, and there was no way to keep one administrator on the native admin while another kept BrikPanel. A new "Let each user choose (per-user control)" option (WooCommerce → Settings → BrikPanel → Access) makes the power switch, and a matching checkbox on each user's own profile page, control that user's preference only. A companion "Roles that start with BrikPanel off" setting decides what each role begins with (for example start administrators on the native admin while shop managers keep BrikPanel), and every user is still free to opt their own account back in. Store-wide rules an administrator sets (disabling BrikPanel for specific users or roles) always take priority over a personal choice, and a new `brikpanel_access_user_disabled` filter lets developers write their own per-user rule in code. With per-user control left off, the switch behaves exactly as before.
* New: **The WhatsApp order shortcut can now be switched off, and hidden from selected roles.** The one-click WhatsApp shortcut (the icon on the orders list and the "Message on WhatsApp" button on the order edit screen) previously appeared for everyone who can manage WooCommerce orders, with no way to remove it. A new "WhatsApp order shortcut" switch (WooCommerce → Settings → BrikPanel → Orders) turns it off everywhere, and a "Hide WhatsApp shortcut from roles" setting removes it for the roles you pick while everyone else keeps it. A user hidden by their role can switch it back on for their own account from their WordPress profile page. Defaults are unchanged: the shortcut stays on and visible to everyone who can manage orders.
* Tweak: **The BrikMentor early-access installer has been replaced with a direct sign-up link.** The launch buttons for BrikMentor now open its sign-up page on brksoft.com instead of downloading and installing the plugin from inside the admin, so BrikPanel no longer installs software that is not hosted on WordPress.org. After signing up you download and install BrikMentor yourself in the usual way (Plugins → Add New → Upload).

= 3.2.22 (2026-07-21) =
* New: **Product videos added with Blocksy Pro can now be managed from the BrikPanel product editor.** Blocksy lets you attach a video (YouTube, Vimeo or a self-hosted file) to a product image, but that option only appeared in WordPress's own media dialog, never in BrikPanel's gallery. Every image in the editor gallery now has a video button that opens a compact panel to set the source, the playback trigger (on click, autoplay or on hover), looping and whether to hide the player controls; an image that already carries a video shows a filled button. Videos set either way stay in step, and BrikPanel only ever touches the video settings, leaving your other Blocksy image options untouched. Works on both simple and variable products, and appears only when Blocksy is your active theme.
* New: **You can now see and edit a product's publish date from the streamlined product editor.** The date field previously showed only for scheduled (future) products, so there was no way to back-date a published product or correct its publish date. A compact calendar control at the left of the editor header now shows the publish date for every product and lets you change it. Giving a published product a future date schedules it (when scheduling is enabled) rather than silently unpublishing it, and a brand-new product simply reads "Immediately". Works on both simple and variable products.
* Fix: **A missing plugin file no longer takes the whole site down.** If a BrikPanel file went missing (an interrupted update, or a security scanner quarantining a single file), the site and the WordPress admin would both show a blank white screen with a fatal error, locking the owner out completely. BrikPanel now loads each of its parts defensively: a missing part is skipped, the rest keep working, and a clear notice in the admin explains that some files are missing and the plugin should be reinstalled. Your settings and data are never touched.

= 3.2.21 (2026-07-20) =
* New: **The order export now shows how many orders your shipping filter will actually include, before you sync.** Ticking every shipping method box does not mean "export everything": it means "only orders that use one of these methods", so stores whose orders carry no shipping line (local sales, digital goods) could end up with far fewer rows than expected, with nothing on screen to explain it. A live scope hint under the shipping boxes now reads, for example, "9 of 2,153 orders match this shipping filter", updates as you tick boxes, and states plainly that orders without a shipping method are excluded. With no filter set it simply confirms that all orders will be exported.
* Fix: **Sheets to WooCommerce order-status sync is now visible in the interface.** The two-way sync already worked, but the order status column was not flagged as writable, so the "two-way" badge, the two-way information box and the sync marker in the sheet header never appeared and the feature looked one-way. The information box also now tells you when two-way sync is switched off for that flow, instead of claiming your edits are written back to the store. Existing sheets keep their current header row; the marker appears there after a "Reset & re-push everything".
* Fix: **An order-status edit made on any row of a multi-line order is now applied.** An order with several items spans several rows, and only the first one was read; changing the status on the second or third row did nothing and was silently overwritten by the next sync. All of the order's rows are now checked, and if two rows disagree the edit is reported as a conflict rather than guessed at.
* Fix: **A status change that fails to save is no longer recorded as done.** If another plugin blocked the save, BrikPanel still marked the order as up to date and never retried it. The order is now re-read from the database after saving, and the sync only moves on once the status really changed; otherwise it is logged and retried on the next run.
* Fix: **A refund id or a trashed order in the order id column no longer stops the whole sync.** Either could abort the run partway through, leaving every following order in the sheet unprocessed, and a stale row could even pull a trashed order back out of the trash. Both are now skipped safely.
* Fix: **Order ids are no longer misread when the sheet formats numbers.** With a thousands separator applied to the id column, an id such as 32053 was read as 32, so a status change could land on a completely different order. Ids are now read as raw numbers, and only whole numbers are accepted.
* Fix: **Status matching now works with non-Latin and custom status names.** Turkish, Cyrillic and other non-Latin status labels were never recognised and were rejected as unknown, and a custom status whose label matched a built-in status name could redirect the order to the wrong status. Matching is now accent- and case-correct for every language, with built-in status keys always taking precedence.
* Fix: **Editing any cell of a variation row no longer corrupts its cost.** BrikPanel writes a variation's effective cost to the sheet (including a cost inherited from the parent product, and WooCommerce's "add to parent cost" mode) but compared it back against the variation's own raw cost, so an unrelated edit on that row (changing stock, for example) made the sync think the cost had been edited and wrote the wrong figure back to WooCommerce, silently skewing profit reports. Comparison and write-back now use the same basis, an inherited cost keeps following its parent, and a value that is impossible in additive mode is rejected and logged instead of stored.
* Fix: **Sorting your sheet or inserting rows no longer makes an update overwrite the wrong order.** Row positions were remembered as absolute numbers and never re-checked, so any row shift sent one order's data onto another order's row. BrikPanel now reads the sheet's own id column, repairs its row map when it has drifted, and re-adds an order whose row is gone rather than writing over its neighbour. The same protection was added to the product sync.
* Fix: **Changing the sync interval now really changes it.** Picking a different interval (15 minutes to 2 minutes, say) updated the setting but left the background job running on the old schedule. The job is now rescheduled whenever the interval changes.
* Fix: **Turning the Google Sheets module off now cancels its background jobs.** They previously stayed scheduled indefinitely and came back on the old interval when the module was switched on again.
* Fix: **Switching to a different spreadsheet now resets the product sync too.** Only the order state was cleared, so products kept writing to row positions from the old spreadsheet and could overwrite existing content in the new one.
* Fix: **A failed product write is no longer counted as synced**, which previously left the sheet permanently out of step with WooCommerce and produced false conflicts. Failed rows are retried on the next sync and logged.
* Improvement: **The sync log no longer floods.** A repeating error is now collapsed into a single line with a "repeated N times" count, so the entry explaining why syncing stopped (an expired Google connection, for instance) is no longer pushed out of the log within minutes.
* Fix: **The "Out of stock" notification in the top bar now opens the filtered product list directly**, matching the order notifications, instead of the full unfiltered catalog. The stock and status filters are now carried through, so the list shows exactly the products the bell counted, including for variable products. WooCommerce's own and third-party "out of stock" links land on the filtered list as well. The product count in the page heading also now reflects the current filter instead of the whole catalog.
* Tweak: The Google Sheets integration is out of beta, so its "Beta" labels have been removed.

= 3.2.20 (2026-07-19) =
* Performance: **Storefront tracking now uses a single combined request per page view instead of up to four separate ones.** The page-view counter, live-visitor ping, daily visitor/traffic-source count and product-view count are all carried by one request, and the extra "visitor left" call that used to fire on every page navigation was removed entirely (the Live view now simply expires idle visitors on its own, within about a minute). On stores with heavy traffic this cuts BrikPanel's tracking requests by roughly two thirds. Background browser tabs also stop pinging while hidden. Tracking can still be disabled completely, or the live refresh interval stretched up to 300 seconds, under WooCommerce → Settings → BrikPanel → Analytics.

= 3.2.18 (2026-07-19) =
* New: **Front-end tracking can now be switched off entirely** (WooCommerce → Settings → BrikPanel → Analytics → "Visitor tracking"). When off, BrikPanel adds zero scripts and zero requests to your storefront — ideal for stores that already run a dedicated analytics tool. The live-visitor refresh interval is also configurable (10–300 seconds, default 30) to reduce load on busy stores.
* New: **"Customer details in Live view" privacy switch** — keep live tracking on but stop caching logged-in customers' name, email and phone entirely, for a fully anonymous Live view. Live visitor data was already only kept in a short-lived cache (about two minutes) and never written to the database.
* New: **WooCommerce's native Cost of Goods Sold field is now the source of truth for all cost reads** (dashboard profit, product list, Quick Edit, Google Sheets, purchase orders). Costs written by other plugins or import pipelines directly to WooCommerce's cost field — even via direct database updates — are picked up automatically; older BrikPanel-only costs are migrated over once, automatically. WooCommerce's additive-variation cost flag is now honoured too (variation cost added on top of the parent's). Existing stores see identical numbers, the two cost stores simply can no longer drift apart.
* New: **`brikpanel_product_cogs` filter** for integrators who keep product cost in a custom field — point BrikPanel's per-product cost reads at any source from one hook.
* New: **WCML (WooCommerce Multilingual & Multicurrency) support** — foreign-currency orders are converted to your base currency using WCML's rate, snapshotted onto the order at purchase time so the day-of-sale rate is captured going forward. Saving WCML's settings also re-converts your existing foreign-currency orders in the background, so historical figures catch up too. The `brikpanel_order_base_factor` filter is now documented for bridging any other multi-currency stack.
* New: **Per-site activation on multisite** — BrikPanel can now be activated on individual subsites instead of forcing network-wide activation. Existing network-activated installs are unaffected; the network access-rules page only shows while network-activated (it only applies in that mode).
* Fix: **Visitor IP hashing upgraded to a salted SHA-256 (HMAC) with a per-site secret**, matching what the readme always claimed. The previous truncated-MD5 hash was theoretically reversible for IPv4 by brute force; the raw IP was never stored or exposed either way.
* Fix: **Cost of Goods backfill now runs on fresh installs** — on stores where WooCommerce's native cost field was already populated before BrikPanel was installed, the dashboard showed Cost of Goods 0.00 because the one-time import only ran on version upgrades, never on a first install. It now runs at activation and self-heals on existing installs with the update.
* Tweak: The live visitor cache no longer stores the customer's user id (it was never displayed).

= 3.2.17 (2026-07-17) =
* Fix: **Variable products no longer flip to "out of stock" after a sale (POS or storefront) when their variations still have stock**. Some variable products carry a leftover parent-level "manage stock" flag with no quantity (from an import or a simple-to-variable conversion); the first completed order made WooCommerce derive out-of-stock from the empty parent quantity, hiding the whole product. BrikPanel's self-repair routine now also clears this dormant leftover before it can do damage, and re-runs automatically once after updating. Deliberate parent-level stock setups are left untouched.

= 3.2.14 (2026-07-14) =
* New: **You can now turn individual product variations on or off directly from the BrikPanel product editor**. Each variation row has an "Active" switch (next to its name), matching WooCommerce's own Enabled control, plus a bulk "Set active / Set inactive" option under "Apply to all variations". Inactive variations are hidden from your store; new variations are Active by default. This fixes cases where variations added through the dashboard could end up inactive with no way to re-enable them without leaving BrikPanel. Works on both simple and variable products.

= 3.2.13 (2026-07-14) =
* Fix: **You can now add numeric attribute values (like shoe sizes 38, 40, 42) to variations again**. When an attribute's values were purely numbers, clicking a suggested value from the dropdown silently did nothing after the first one was added, so variable products with size-number attributes could not be built. Selecting values from the suggestion list now works for numeric and text values alike, on both simple and variable products. The same fix applies to numeric product tags.

= 3.2.12 (2026-07-14) =
* Fix: **The "Additional product data" card no longer breaks its layout on stores where WooCommerce's tab styling applies**. After the previous compatibility fix, WooCommerce's own stylesheet could float the third-party sections into a narrow column, scattering the group titles around them (most visible on RTL languages such as Persian or Arabic). The sections now always stack full-width inside the card, on both LTR and RTL admins.
* Improvement: **Broader compatibility for buttons inside third-party "Additional product data" sections**. The card now recreates the native product editor's full container chain, so plugins that attach their add/remove/sort buttons to any of the standard WooCommerce containers work inside the streamlined editor as well. Works on both simple and variable products.

= 3.2.11 (2026-07-10) =
* Fix: **Buttons inside third-party "Additional product data" sections now work again**. When another plugin adds its own section to the product data (for example a "Box Contents" repeater with an "+ Add Item" button, product insurance or warranty fields), those buttons rely on the WooCommerce product-data container that the streamlined editor did not recreate, so clicking them did nothing and the changes could not be saved. The container is now provided, so add/remove/sort buttons and their fields work and save exactly as they do on the standard WooCommerce editor. Works on both simple and variable products.
* Fix: **A duplicate SKU or GTIN is no longer dropped silently when saving a product**. If you entered a SKU (or GTIN) already used by another product, WooCommerce rejected it as not unique, but the editor still showed "Product saved!" and left the field blank, so it looked like the SKU could not be set. The product now still saves, and a clear message tells you the SKU/GTIN was skipped because it must be unique. Works on both simple and variable products.
* New: **Rename the "Site management" heading in the sidebar**. A new "Section heading label" field under WooCommerce > Settings > BrikPanel > Navigation lets you replace the "Site management" label above the lower group of menu items with your own wording. Leave it blank to keep the default label, which stays fully translatable.
* Fix: **The WooCommerce > Settings > BrikPanel screen no longer crashes when WooCommerce Composite Products is active**. To detect which extra tabs your product editor offers, BrikPanel briefly runs WooCommerce's product-data-tabs hook; Composite Products' handler expected a real product in that moment and hit a fatal error, which took down the whole settings page. That hook is now run safely, so a tab from any plugin that misbehaves is ignored and the page loads normally. Other plugins' tabs are still detected as before.
* Fix: **The product Categories, Tags, Brands and Attributes screens no longer leave a large empty area on the right**. With the modern sidebar hidden, these screens pinned their content to the left and left the rest of the page blank on some themes. The layout now centres correctly whether the modern sidebar is shown or hidden.

= 3.2.6 (2026-07-09) =
* Fix: **The Appearance > Menus screen no longer crashes on some sites**. On stores where another plugin left an unexpected entry in WordPress's admin menu, opening Appearance > Menus (and a few related admin screens) could hit a fatal error. BrikPanel's sidebar now safely skips any such entry, so those pages load normally again.
* Improvement: **Every value of a large product attribute is now reachable while editing a product**. When adding values from a global attribute that has many terms (for example a "Color" attribute with 40 colours), the suggestion list only showed the first ten and hid the rest, even after you typed to filter it. It now offers up to fifty matching values in a scrollable list, so you can pick any of them. Works on both simple and variable products.

= 3.2.5 (2026-07-09) =
* Fix: **The dashboard catalog summary (products, variations, sellable items) now updates the moment your catalog changes**. It could previously keep showing the earlier totals for a few minutes after you added or removed variations, or trashed a product, because the figures were cached too aggressively. They now refresh immediately whenever a product or variation is added, published, trashed, restored or deleted. The "sellable items" total is also now exact for variable products that have no purchasable variations yet (they no longer inflate the count). (This was never related to legacy vs High-Performance Order Storage: product counts always read from the same place.)
* New: **Control who sees each embedded WordPress dashboard widget**. The dashboard widgets you pull into the BrikPanel dashboard (under WooCommerce > Settings > BrikPanel > Dashboard) can now each be limited to Everyone, Admins only, or hidden from specific roles, just like the top bar controls. This is handy for keeping the "Site Health Status" widget, which exposes server and security details, away from staff. Administrators always see every widget so you can never lock yourself out.
* Fix: **The "More" sidebar menu no longer lands on a 404**. When the "More" group's first item was a custom link, clicking the "More" label itself opened a "page not found" error instead of the link's real address. The "More" header now points at a valid destination, and an empty "More" group (with nothing left inside it) is hidden entirely rather than shown as a broken link.
* Improvement: **The generic WordPress "Help" tab is now hidden across the whole admin**. That top-right "Help" button only ever showed generic, non-store help, so it no longer appears on any screen: the orders list, the product and order editors, settings, and every core WordPress screen. "Screen Options" is left untouched, so you can still choose which columns a list shows.

= 3.2.4 (2026-07-08) =
* New: **Schedule a product to go live later**. The status menu in the product editor gains a **Scheduled** option that WooCommerce's own editor does not offer: pick it, choose a future date and time, and the product is held back and published automatically the moment it arrives. It is on by default and can be switched off under WooCommerce > Settings > BrikPanel > Products. Scheduled products also appear in the BrikPanel products list with their own **Scheduled** tab, a blue badge and their go-live date, and can be scheduled or unscheduled from Quick Edit too. Works on both simple and variable products
* New: **See your catalog size at a glance on the dashboard**. A small line under the Low Stock heading now shows how many **products** and **variations** your store holds, plus the number of **sellable items**, the real count of purchasable units once each variable product is counted by its variations rather than as a single line. This makes the true size of your store clear even when many products use variations. Works with simple and variable products alike
* Improvement: **Remove a variation image in one click**. Hover a variation that has an image and a small X appears in the corner of the thumbnail; click it to clear the image without opening the media library. The change now sticks after saving and reloading, and a variation with no image of its own no longer falls back to showing the parent product's featured image

= 3.2.3 (2026-07-07) =
* Fix: **The WooCommerce > Settings > BrikPanel screen could crash when the modern sidebar was switched off**. With the modern navigation turned off, opening BrikPanel's settings (and a few other admin screens) could hit a fatal error. This is fixed, and verified with the modern sidebar both on and off.
* Fix: **Custom sidebar links no longer land on a 404 on some managed hosts**. A custom link added in the navigation editor renders with the correct address everywhere, but on hosts that draw their own admin menu from the raw menu slug (such as WordPress.com / Atomic) clicking it could reach a "404 / not allowed" page. Those links now resolve to their real destination, whether that is an external URL or another admin page.

= 3.2.2 (2026-07-07) =
* New: **Message a customer on WhatsApp straight from an order**. Orders with a phone number now show a green WhatsApp icon in the orders list, just before the order number (and hideable from Screen Options), and a "Message on WhatsApp" button under the billing address on the order screen. Clicking it opens WhatsApp Web on desktop or the app on mobile, with the number formatted for the customer's billing country. Works on classic and High-Performance Order Storage, and on simple and variable product orders
* New: **Show or hide each top bar item by role**. Every top bar control (the live counter, search, quick-create, notifications, "View store" and the rest) can now be set to Everyone, Admins only, or specific roles. This lets you keep administrative notifications and alerts away from your clients while managing many sites. Administrators (and network super admins) always keep access, so you cannot lock yourself out
* New: **Hide new menu items by default**. A new option under WooCommerce > Settings > BrikPanel > Navigation keeps any menu item added by a newly installed plugin hidden from the sidebar until you have reviewed it. New items show in the navigation editor with a "New" badge, ready to switch on when you are happy with them. It is off by default, so nothing changes unless you turn it on
* Fix: **Importing order statuses from another plugin no longer looks like it failed**. After clicking "Import selected", the browser could show a "Leave site? Changes may not be saved" warning; if you chose to stay, the page did not refresh and the imported status did not appear, even though it had already been saved. That warning is now suppressed for the intentional refresh, so the imported status shows straight away
* Fix: **Administrator-only areas stay closed to a store manager who was granted "manage options"**. If a shop manager's role had been given the "manage options" permission with a role editor, several administrator-only areas (the settings lock, the top bar settings link, hiding Screen Options from non-administrators, and the welcome tour) opened up to them. Access to these is now decided by role, so only real administrators (and network super admins) get in

= 3.2.1 (2026-07-06) =
* Docs: expanded the readme with the new **cart abandonment / cart recovery** feature and clearer **WooCommerce sales report** wording, and refreshed the screenshots (added the Abandoned Carts screen). No functional or code changes in this release.

= 3.2.0 (2026-07-06) =
* New: **Recover lost sales with the Cart Abandonment module**. BrikPanel now captures the email of shoppers who start checkout but do not finish, and collects them on a new "Abandoned Carts" screen so no lead slips away. Emails are picked up from the checkout email field (classic shortcode and the newer block checkout, including custom pages), and from logged-in customers as soon as they add to cart. Every entry keeps a full snapshot of the cart, including the exact variation chosen (for example "Colour: Red"), quantity and total, and each cart moves through Active, then Abandoned, then Recovered once the shopper places the order, even if they check out with a different email. The screen has search, status, source and date filters, per-row product details, CSV and Excel export, and statistics cards
* New: **An optional discount popup that hands out a personal coupon**. Switch on the email popup and BrikPanel shows a clean, on-brand sign-up offer to your visitors. Anyone who subscribes is issued their own single-use percentage coupon (10% by default, and you set the rate), restricted to their email and valid for 30 days, shown right there with a one-click Copy button. Close the popup and it folds into a small floating tab so it is never in the way but is one click from reopening. You control the heading, message, button and success text, the delay before it appears, and the cooldown after it is dismissed
* New: **Pick how the offer is revealed**. The coupon in the popup can be revealed with one of six animated styles, choose the one that fits your store under WooCommerce > Settings > BrikPanel > Cart abandonment: Sealed envelope, Pocket card, Scratch card, Slot machine, Magnetic assembly or the Classic ticket. All of them respect the visitor's reduced-motion preference
* New: **Import an email list into Abandoned Carts**. Already have a list of leads? The new "Import CSV" button on the Abandoned Carts screen reads a CSV of emails (with optional first name, last name and phone), auto-detects comma or semicolon separators, matches your column headings, skips duplicates and invalid rows, and reports exactly what was imported
* New: **Spacers and spacing controls for the sidebar**. The navigation editor can now add blank spacers and divider lines between menu items to group them how you like, and a new "Item spacing" setting (Compact, Comfortable or Spacious) sets how much breathing room each row gets
* New: **Choose your sidebar icon style**. A new "Sidebar icon style" setting under Appearance lets you switch the sidebar icons between Solid (the original filled look) and Line (a lighter outline style). Solid stays the default, so nothing changes unless you want it to
* Fix: **"Copy all" on the store summary no longer times out on large stores**. On stores with tens of thousands of orders and customers, the store summary could fail with a timeout while working out new versus returning customers. The query behind it has been rebuilt to use the right database indexes, so it now returns quickly while showing exactly the same figures

= 3.1.51 (2026-07-05) =
* New: **Send an automatic email when an order reaches a custom status**. Each custom order status now has its own email settings under WooCommerce > Settings > BrikPanel > Order statuses. Switch it on and, whenever an order moves into that status, BrikPanel sends a message you have written, to the customer, your store admin, and any extra addresses you add. You choose the subject, heading and body, and can drop in placeholders such as the order number, total, items, customer name and a link to view the order. The emails are wrapped in WooCommerce's own header and footer, so they carry your store's email branding. Works the same on simple and variable product orders
* New: **Import order statuses from another plugin**. Moving to BrikPanel from another custom-order-status plugin? A new "Import from another plugin" card on the Order statuses screen finds statuses that other plugins have registered, and any "orphan" statuses left on your orders after a plugin was removed (which otherwise show as a raw code and drop out of filters and reports). Import the ones you want in a click and they become editable BrikPanel statuses, keeping their existing colour where it can be detected
* Improvement: **Apply a custom order status to many orders at once**. Your custom statuses now appear in the orders list "Bulk actions" menu (and in BrikPanel's own bulk buttons), so you can select several orders and change them all to a custom status in one go, instead of opening each order. Works on both simple and variable product orders, on classic and High-Performance Order Storage
* Fix: **The on/off switch can no longer be hidden from you by a store manager**. The top bar's BrikPanel power switch used to appear for anyone with the "manage options" permission, so a shop manager granted that permission could turn BrikPanel off for the whole store. Its visibility is now decided by role: administrators (and network super admins) always see it, and you can grant it to other roles from a new "Show the on/off switch to roles" setting under Access control

= 3.1.47 (2026-07-02) =
* New: **Filter the Products list by brand**. A brand drop-down now sits next to the category filter, so you can narrow the list to a single brand in one click. It appears only when your store has a brand taxonomy (WooCommerce's own product brands or a third-party one), and your choice is kept in the page URL
* New: **A "Date" column for the Products list**. You can now show each product's publish date and time in the list, in your site's own date format and time zone. It is off by default; switch it on from the "Columns" button. Handy if you re-date products to refresh them at the top of a category
* Improvement: **Category cells in the Products list are now clickable**. Click a product's category and the list filters to that category straight away, just like the native WooCommerce list. Works on both simple and variable products
* New: **More formatting in the description editors**. The rich-text toolbar (long and short description, on simple and variable products) gains Heading 1, Heading 5 and Quote block styles, left/centre/right text alignment, and a text colour picker with an on-brand palette. Useful when your theme does not turn the product title into an H1 and you want one in the description for SEO
* Fix: **The visible-sections checkboxes no longer flicker**. The checkboxes under WooCommerce > Settings > BrikPanel > Products (which sections show in the editor) had a small visual jump when ticked; they now use a clean, static BrikPanel checkbox

= 3.1.46 (2026-06-30) =
* New: **Traffic Sources in the dashboard**. The "Visitors by Device" panel has a new "Sources" tab that breaks your visitors down into Direct, Organic Search, Social, Referral, Paid and Email, with a "Top Referrers" list showing which sites send you the most traffic. A lightweight tracker records each visitor's referrer and landing page, one record per visitor per day, so the picture builds up over time
* New: **Edit a product's URL slug (permalink) from the editor**. A new "Permalink (URL slug)" section in the product editor lets you set a custom URL for a product, with the storefront URL prefix shown for reference. Leave it blank and WooCommerce builds the slug from the title as before. It is off by default; switch it on under WooCommerce > Settings > BrikPanel > Products. Works on both simple and variable products
* New: **Edit the sale price and cost straight from the Products list**. Clicking the price of a simple product now opens a small popover with both the Regular and Sale price, and the Cost (COGS) column is editable inline too, so a quick change no longer means opening the editor. Variable products keep using the per-variation popup, where regular, sale and cost are already editable one by one
* New: **Edit the legacy "Return Draft" and "Change" order statuses**. These two built-in statuses used to be fixed and could not be removed; they now appear in your list under WooCommerce > Settings > BrikPanel > Order statuses, so you can rename or delete them like any other custom status. New installs start without them
* New: **Search by GTIN in the command palette**. The CMD+K search already matched product name and SKU; it now also matches a product's GTIN, UPC, EAN or ISBN, on both products and variations, and shows the code in the result
* New: **Network Admin link for multisite**. On a multisite network, BrikPanel hides the WordPress toolbar, which was the only way back to the Network Admin. Network administrators now have a "Network Admin" item in the top bar's user menu
* Fix: **The "More" menu no longer breaks links to Coupons and custom order-status pages**. Clicking Coupons, or a third-party page such as a custom order-status plugin, from the sidebar's "More" group could land on a WordPress error page. Those links now point to the right place
* Fix: **The "New customers today" notification now matches the dashboard**. The top bar's new-customer count only counted registered accounts and missed guest checkouts, so it could read zero while the dashboard's Customer Types showed new customers. It now uses exactly the same source as the dashboard
* Fix: **"Order updated." and "Post updated." confirmations are back**. BrikPanel's hiding of third-party admin notices was also swallowing WordPress and WooCommerce's own confirmation bar after you saved an order or a post. The first-party message is now left alone
* Fix: **The "Screen Options" and "Help" buttons now show on the classic (non-HPOS) order screen too**, where WooCommerce's own styles had hidden them. On the orders list they are back to WordPress's standard buttons in their usual top-right place
* Fix: **Your site name is no longer cut off in the top bar on wide screens**. A long store name was being trimmed even when there was plenty of room; it can now grow with the window before it ever shortens

= 3.1.45 (2026-06-27) =
* Fix: **The "Screen Options" and "Help" buttons are no longer hidden on the orders screens**. WordPress tucks those toggles into the very top-right corner, exactly where BrikPanel's bars sit, so they ended up hidden behind them. On the single order screen they now live inside the sticky header next to the status and Save button; on the orders list they sit next to the "Add order" button. Either way they open the same panel as before, fully visible. On tablets and phones they shrink to compact icons so they stay reachable without crowding the bar. Works on both simple and variable product orders

= 3.1.40 (2026-06-27) =
* Improvement: **Marketplace sales now count in Revenue and Net profit**. On stores that use BrikMarket, the headline Revenue, Total Sales, Cost of goods and Net profit now include your marketplace turnover (Trendyol, Hepsiburada and the rest) together with your website orders, so the dashboard reflects the whole business instead of showing your revenue as zero while the marketplace cards held all the sales
* Fix: **The Profit section no longer shows a permanent loss after you add product costs**. Cost of goods was counting your marketplace orders' costs while Revenue did not count their sales, so the moment you filled in a product cost the store looked like it was losing money. Revenue and Cost of goods now cover exactly the same orders, on both simple and variable products, so profit and margin are correct. The Google Sheets profit report uses the same basis
* Improvement: **Conversion rate and visitor stats stay website-only**. Orders, average order value, conversion rate and visitors keep counting only on-site activity (marketplace orders have no website visit), so your conversion rate stays accurate even though the money figures now include the marketplace. A separate fix means marketplace orders are now reliably recognised for this split on High-Performance Order Storage stores
* Fix: **Marketplace revenue is converted to your store currency**. The per-marketplace sales totals are now converted to your base currency before being added up, matching the rest of the dashboard, so a store selling in more than one currency no longer mixes raw amounts together

= 3.1.39 (2026-06-26) =
* New: **Add images to the product description**. The description editors (both the long description and the short description, on simple and variable products) now have an "Insert image" button that opens your media library. You can set the image's alt text, its alignment (None, Left, Centre or Right) and its size (Small, Medium, Large or Full, that is roughly a quarter, half, three-quarters or the image's natural width). Click an image you have already inserted to change its alignment, size or alt text, or to swap it for another. No more closing BrikPanel to add a picture with the classic editor
* New: **Open description images in a lightbox**. While inserting or editing an image, tick "Open in a lightbox when clicked" and that image opens in a clean full-screen overlay on the product page when a shopper clicks it (click to enlarge, then close with the backdrop, the X button or the Esc key). The small lightbox script only loads on product pages that actually use it, so storefront performance is unaffected
* Improvement: **Keep typing straight after inserting an image**. The cursor is now placed right after a newly inserted image, so you can carry on writing without having to click back into the editor

= 3.1.38 (2026-06-25) =
* Fix: **Google Sheets product sync no longer creates duplicate rows for variations (or any product)**. When a stock or price change was pushed but the plugin had lost track of which sheet row a product lived on, for example after a network hiccup dropped Google's reply or an earlier full sync was interrupted, the next push could add a second row for the same item. The push now reconciles against the Product ID already in the sheet and updates that existing row instead of appending a duplicate. Variations and their parent product are protected the same way. Run "Sync now" once to clear any duplicate rows a previous version left behind

= 3.1.36 (2026-06-22) =
* New: **The product editor's attributes and variations section was redesigned**. The card now has a clean header (the "Variable product" title, a short description and the toggle) above a tidy body, matching the rest of the editor, instead of the previous stacked grey text. The plain attribute drop-down is replaced with a modern, searchable picker: click the field, type to filter your global attributes, and press Enter to add the match. The free-text "add a value" box and its Add button are now one joined input, and the "Size and Color" shortcut moved into a clear "Quick add" chip. Every action behaves exactly as before, on both simple and variable products
* New: **Drag to reorder attribute rows**. Each attribute row now has a drag handle, so you can reorder your attributes the way WooCommerce does. Because the order decides how variation names are built, reordering marks any already-generated variations as needing a refresh and prompts you to regenerate them
* Fix: **WooCommerce's "Customer history" and "Order attribution" boxes are back on the modern order screen**. Both boxes carry useful native data and were being hidden by mistake; they now show with BrikPanel's card styling. Only the raw "Custom Fields" box (already replaced by BrikPanel's "Additional details" card) and the download-permissions box stay hidden
* Fix: **The "Order actions" box no longer looks broken with the CURCY multi-currency plugin**. CURCY adds a currency selector and a note to that box; the selector now sits on its own full-width row with the note as small helper text underneath, and the Trash and Update buttons line up correctly. Stores without CURCY are unchanged
* Improvement: **Security and reliability hardening of the attributes and variations editor**. The data the editor embeds in the page is now safely encoded so attribute or term names imported from elsewhere can never break out of the script, saving and the variation preview now run a per-product permission check, and creating a new term or global attribute is limited to users allowed to do so. Removing a taxonomy attribute from a product now cleans up its old term links, a sensible upper limit guards against a runaway number of variations, and several smaller fixes make the variation preview race-safe and stop duplicate attribute rows. Works on both simple and variable products

= 3.1.32 (2026-06-21) =
* New: **Third-party plugin meta boxes now live in the "Visible editor sections" list**. The separate "Third-party plugin meta boxes" picker is gone. Every meta box BrikPanel finds (SEO plugins, Germanized, WPCode, custom boxes and so on) now appears as a row in the same section list, marked "Plugin" and hidden by default, so you can switch it on and drag it to any position with the native sections. The editor then renders that box in the exact spot you placed it, for example between Price and Cost of goods. Your earlier selections are migrated across automatically. Works on both simple and variable products
* New: **Set cost (COGS) from the Products bulk update**. The bulk update action now has a Cost option that writes the cost of goods to many products at once, mirrored to WooCommerce's native COGS field where available. Like price, it applies directly on simple products and to every variation on variable products, and can be narrowed to matching variations with the attribute filter. Leaving the value empty clears the cost
* New: **"Fix store visibility (after import)" bulk action**. After a CSV or Excel stock import, products that are in stock could stay hidden on the storefront because the importer wrote the stock value without updating WooCommerce's visibility data. A new Maintenance action in the Products bulk update scans the whole catalogue and realigns each product's "out of stock" visibility flag and lookup data with its real stock status, re-syncing variable products from their variations first. No more toggling a product off and on to make it reappear
* New: **Paste tables into the product description**. Pasting content that contains a table into the description editor now keeps the table, including merged cells, instead of flattening it to plain text. The table also renders with clean borders in the editor and saves intact. Works on both simple and variable products
* Improvement: **Third-party "Additional product data" sections now match the BrikPanel design**. Extra product-data sections added by other plugins are forced onto BrikPanel's clean style: the red accent bar that the CURCY currency switcher drew beside its price fields is gone, and add-on builders that paint their own brand colours (such as the AcoWebs product add-ons) are normalised to BrikPanel's neutral palette, headers and inputs
* Improvement: **A much better experience on phones and tablets**. The dashboard no longer scrolls sideways on a phone, and its help tooltips and Profit cards stay tidy and readable. The top bar no longer overlaps its own logo and search button. The classic (re-skinned WordPress) menu now opens cleanly in the mobile drawer, with no icons sitting on top of the text and submenus that expand in full. The whole menu is now reachable on tablet-width windows (between 783 and 960 pixels wide), where it previously could not be opened at all. The BrikPanel settings page no longer overflows sideways on a narrow screen
* Fix: **"Additional product data" no longer shows unrelated fields**. With a multi-currency plugin in fixed-price mode, surfacing the per-currency price fields was accidentally running other plugins' field hooks too, so unrelated fields could leak into the card even when nothing was selected. The multi-currency prices now appear in their own small section and nothing else is pulled in. Works on both simple and variable products
* Fix: **WPML: the Products list is no longer empty when your admin language has no translated products**. On a WPML store whose catalogue is in one language while your admin language is set to another, the modern Products list could show nothing while the tab counts still showed the full total. The list is a store-management screen, not a translation workflow, so it now shows your whole catalogue regardless of the selected admin language, matching the counts. Product saving is untouched, so each product keeps its own language
* Fix: **Your custom brand logo now applies as soon as you set it**. Choosing a logo under Appearance previously also required ticking a separate checkbox, which was easy to miss, so the logo was silently ignored. The logo now turns on automatically when you set it and off when you remove it, and the extra checkbox is gone. A duplicate "ghost" logo that could appear at the very top of the modern login page is fixed at the same time
* Fix: **The dashboard "With Marketplace" label no longer pushes the filters onto a second line**. When the marketplace add-on is active, that label is now shown as a small line under the title instead of widening the heading, so the date and export controls stay on the same row

= 3.1.31 (2026-06-17) =
* Fix: A selected third-party plugin meta box (the "Additional fields" card in the product editor) could render with no background, border or shadow on some sites. The card now keeps its styling even when another plugin moves or restyles the meta box area

= 3.1.29 (2026-06-16) =
* New: **Percentage-based expenses**. Add a cost as a percentage of revenue (for example a 2.9% credit-card or marketplace commission) and it is calculated against your sales for every period automatically, shown on its own line in the Expenses breakdown
* Improvement: **The expense "Category" field is now "Title"** — clearer for naming a one-off cost
* Improvement: **Operational Expenses sits under the "More" menu** in the BrikPanel sidebar when the Suppliers module is off, instead of taking its own top-level slot
* New: **Add an expense straight from the dashboard**. The Profit section's Expenses card now has a quick "+" button that opens a small form (amount, category, date, repeat, note), so you can log a cost without leaving the dashboard. It saves to the same place as the Operational Expenses page
* New: **Recurring expenses now repeat automatically**. Mark an expense as Monthly, Weekly or Yearly and it is counted in every period from its start date onward, all on its own. No more adding rent or payroll by hand each month. Existing entries are left exactly as they were
* Improvement: **The Operational Expenses page is now always reachable**. Previously it only appeared while the Suppliers module was enabled, even though the expenses you logged still affect the dashboard's Net Profit. It now stands on its own as an "Expenses" item in the BrikPanel sidebar when Suppliers is off, and stays grouped under Suppliers when that module is on. Same page, same data, just no longer hidden
* Improvement: **The Expenses breakdown now itemises your real expense categories**. Instead of lumping everything into a single "Other" line, the breakdown lists each category you logged (for example Salaries, Rent, Shipping carriers, Packaging) alongside ad spend, tax and supplier/stock costs, so you can see exactly where the money went
* Fix: **Storefront Revenue and Total Sales no longer read as $0 on stores using the marketplace add-on**. An order-exclusion query could, in some setups, drop every order and zero out the figures; this is now computed correctly
* New: **Returns and Coupons in the dashboard Profit section**. Revenue is now shown net of customer refunds for the period, so your margin reflects money you actually kept, and a new expandable breakdown on the Revenue card spells it out: Gross sales, Returns, Net revenue, plus how much you gave away in coupon discounts. Net profit updates accordingly. Works on both simple and variable products
* New: **Clearer Profit tooltips**. Revenue, Cost of Goods, Expenses and Net Profit each have a help icon explaining exactly how the figure is calculated, including that taxes are part of Expenses and that administrator test orders are left out
* New: **Choose which Profit fields to show**. Under WooCommerce > Settings > BrikPanel you can hide Cost of Goods, Expenses, Returns or Coupons if your store does not use them. Revenue and Net Profit are always shown. Hiding a field only removes it from view; it is still factored into Net Profit where it is a real cost, so the number stays accurate

= 3.1.28 (2026-06-15) =
* New: **Early access to BrikMentor**. Once your store passes 100 completed orders (and again at 200 if you dismissed the first one), BrikPanel invites you to join the private beta list for BrikMentor, a separate AI assistant and email marketing platform for your store that is in the works. There is also a small, dismissible "BrikMentor is coming" card at the bottom of the dashboard, and a permanent "BrikMentor early access" option at the bottom of WooCommerce > Settings > BrikPanel, so you can join at any time, even before that milestone. Joining is entirely optional: you type your email and tick a consent box, and you can answer one optional question about which marketing tool you use. Nothing is sent unless you fill in the form and consent, the invite never appears again once you join or after the final milestone, and you can unsubscribe at any time. Your submitted email is stored locally and delivered reliably with automatic retries, so it is never lost; if your host blocks the connection entirely, a WhatsApp button appears so you can still request access directly. See "What data does BrikPanel send outside my site?" in the FAQ
* Improvement: **The review request is now shown less often**. The earlier 14-day review prompt was removed; BrikPanel now asks for a review only after 50 completed orders, a much stronger sign the plugin is actually helping your store

= 3.1.27 (2026-06-15) =
* Improvement: **Per-currency prices from CURCY now appear automatically in the product editor**. When the CURCY (Currency Switcher for WooCommerce) plugin is set to "Fixed Price" mode, it adds a price box for each extra currency. Those boxes are attached to WooCommerce's native price fields, which the BrikPanel editor only shows for sections you pick by hand, so they were easy to miss. BrikPanel now detects CURCY's fixed-price mode and surfaces those per-currency price fields on its own: on simple products (in the product-data section) and on every variation row (open the variation's "more fields" arrow). Type a price per currency, save, and it is written straight to CURCY's own data, so the storefront shows exactly what you entered. If you prefer CURCY's automatic exchange-rate mode instead, there is nothing to enter and the dashboard still converts every order to your store currency. Works on both simple and variable products. Reported by a user on wordpress.org

= 3.1.26 (2026-06-15) =
* Improvement: **Product fields from more third-party plugins now appear in the BrikPanel editor with their proper name**. Plugins that add a "Product data" tab the older way (such as Estimated Delivery Date Per Product For WooCommerce) were already detected, but their section showed an unfriendly internal name. BrikPanel now reads the plugin's real tab title, so the section reads correctly (for example "Product Est Date"). As before, pick which of these extra sections to show under WooCommerce > Settings > BrikPanel > Products. Works on both simple and variable products, including per-variation fields. Reported by a user

= 3.1.25 (2026-06-15) =
* Improvement: **Multi-currency conversion now also covers the Segments and Orders screens**. Version 3.1.22 converted the main dashboard to your store currency; this release extends the same day-of-sale conversion to the Segments screen (the Orders tab's Total Revenue and Average Order Value, and the Customers tab's per-customer spend) and to the revenue summary above the Orders list. As before, each order is converted using the exact rate from a multi-currency plugin such as CURCY (Currency Switcher for WooCommerce) on the day of sale, falling back to the manual rate under WooCommerce > Settings > BrikPanel > Currency. Individual order rows still display in the currency the order was placed in. Requested by a user on wordpress.org
* Fix: **Variable products can now have descriptive (non-variation) attributes in the editor**. The "Product attributes" card, used for tag/spec attributes such as "Occasion" or "Material" that appear on the product page but do not create variations, was hidden whenever a product was variable, so those attributes could only be managed for simple products. The card now shows for variable products too, right alongside the Variations section: variation attributes (Size, Color) are still managed by the variations wizard, while descriptive attributes are added in the card. Both are saved together, and existing variations are untouched. Requested by a user on wordpress.org

= 3.1.24 (2026-06-14) =
* Improvement: **The modern Products screen loads faster on large catalogs**. The screen reads each product's categories, tags and other taxonomies as it builds the list, and it was doing so with a function that ignores the data WooCommerce had already loaded for the page, firing a fresh database query for every product and every taxonomy (roughly seven extra queries per row). It now reads from the data already in memory, cutting about 140 database queries off a single page of 20 products with no change to what you see. Works on both simple and variable products
* Fix: **No more off-brand focus box around the selected item in the classic menu**. When the modern navigation is turned off and the classic (re-skinned) WordPress menu is used, the selected or clicked menu item could show a harsh coloured outline (red on some systems) around its text, drawn by the browser or operating system. The classic menu now suppresses that native outline and, for keyboard users, draws the same clean on-brand rounded focus ring the modern menu uses, so clicking with the mouse stays clean while keyboard navigation still shows a clear, accessible highlight
* Improvement: **Welcome tour polish and Ad Platforms stays idle until connected**. The feature slides in the welcome tour were simplified from a two-column card grid to a clean single-column checklist, and the "Open your dashboard" button no longer turns blue on hover. The Ad Platforms daily sync job is now only scheduled while at least one platform (Google or Meta) is connected, and any leftover scheduled job is cleared when the module is off or disconnected, so nothing runs in the background until you actually connect an ad account. Google Sheets sync is unaffected and keeps running as before

= 3.1.23 (2026-06-13) =
* New: **Full SmartCrawl (WPMU DEV SEO) support in the product editor**. If you use SmartCrawl as your SEO plugin, the product editor's SEO card now reads and writes SmartCrawl's own fields (SEO title, meta description, focus keyword, canonical URL and "hide from search engines"), and shows a live SmartCrawl SEO analysis right inside the card: a score out of 100 plus a checklist of page and content checks that updates as you type, the same way SmartCrawl's own editor does. SmartCrawl's editor panel is built to only appear on the standard WordPress edit screen, so it could not be shown inside BrikPanel before; BrikPanel now runs SmartCrawl's own analyzer behind the scenes and presents the result in BrikPanel's design. Works on both simple and variable products. Requested by a user on wordpress.org
* Fix: **Products screen could fail to load with some SEO and column plugins active**. If a third-party plugin (for example SmartCrawl Pro) added a column or row action to the Products list and its code raised an error when run outside the standard WordPress products screen, that error could break the whole BrikPanel Products list so it showed a "page could not load" message instead of your products. BrikPanel now isolates every third-party column, cell and filter-bar contribution: if one misbehaves it is quietly skipped and the rest of the screen keeps working. Reported by a user on wordpress.org

= 3.1.22 (2026-06-13) =
* New: **Multi-currency stores now report in a single currency**. If your store takes orders in more than one currency, the dashboard used to add every order's raw total together regardless of its currency, so a 100 TRY order and a 100 USD order were summed as "200" and shown in your store currency. BrikPanel now converts every order to your store currency before adding it up, so Revenue, Average Order Value, the sales-over-time chart and the per-country sales on the globe are all reported in one comparable currency. When you use a multi-currency plugin such as CURCY (Currency Switcher for WooCommerce), the exact exchange rate from the day of each sale is read automatically from the order, so historical figures use the rate that actually applied at the time, not today's rate. For currencies that arrive without a saved rate, you can enter a flat fallback rate under WooCommerce > Settings > BrikPanel > Currency. Requested by a user on wordpress.org
* New: **Recent Orders shows each order in its real currency**. The dashboard's Recent Orders list used to print every total with your store currency symbol even when the order was placed in another currency. Each order now shows its own currency, with a small converted figure in your store currency underneath when the two differ
* New: **Editable "Sort order" column on the Products list**. The modern Products screen can now show a Sort order column (toggle it from the "Columns" menu, off by default). Type a number directly into the cell to set a product's position on the storefront when "Custom ordering" is active, the same value WooCommerce uses for menu order. Works on both simple and variable products
* Note: A product attribute that is NOT used for variations (for example an "Occasion" attribute used only as a descriptive tag) is already supported, in the product editor's "Product attributes" card, separately from the Variations section, on both simple and variable products

= 3.1.21 (2026-06-12) =
* New: **Two-way Google Sheets sync now covers price, cost and status**. Until now only Stock and Stock status could be edited in the sheet and written back to your store; the reverse sync now also writes back Regular price, Sale price, Cost (COGS) and Status. Edit those cells in your sheet, and the next sync applies them to the matching product. Every value is validated (prices and cost must be a number, status must be one of publish/draft/pending/private), an empty cell means "leave unchanged", and a built-in conflict guard keeps the store version if the same product was changed in WooCommerce after the last sync, so a sheet edit never silently overwrites a newer store change. Works on both simple products and variations, with each variation carrying its own price, cost and status. Requested by a user on serel.bg
* New: **It is now obvious which columns sync back**. Columns that write to your store are marked with a two-way glyph in the sheet header and a "two-way" badge in the settings column picker, and the Products tab shows a clear note listing exactly which columns are two-way and warning that every other column is display-only and will be overwritten on the next sync. The Status column also gets a helpful drop-down in the sheet
* New: **Short description and Description columns for the product sync**. You can now add the product short description and full description as columns in the Google Sheets product export. Both are off by default and can be switched on from the column picker; HTML is flattened to clean readable text, and a variation with no description of its own falls back to its parent's, so the column is never needlessly blank

= 3.1.20 (2026-06-12) =
* Fix: **JavaScript error when opening WooCommerce > Settings > BrikPanel**. The Custom CSS field's code editor was being started on every settings section even though that field only renders on the Appearance section, which threw an uncaught "Cannot read properties of undefined" error against a textarea that was not on the page. On some sites that error could interrupt other scripts and leave the settings screen looking visibly broken. The code editor now loads only on the Appearance section (also saving its assets everywhere else) and guards against a missing field. Reported by a user on serel.bg

= 3.1.19 (2026-06-11) =
* New: **Customer phone numbers in Segments and Customer Analytics**. The phone number now appears alongside the email everywhere you view or download a list of customers or orders: the Segments screen (both the Orders and Customers tabs) gains a Phone column, and the Customer Analytics screen shows the phone under the email in the Lifetime Value and RFM analysis customer lists. Every CSV export from those screens now includes a Phone column too, so you can use the data for SMS or WhatsApp marketing the same way you already use email. Phone is read from the order's billing details and falls back to the customer's saved billing phone, covering guests and registered customers alike, on both simple and variable products
* New: **Shipping class and Author columns on the product list**. The modern Products screen can now show a Shipping class column and an Author column, both toggled from the "Columns" menu and off by default, with your choice saved per user. The Author column is handy on multi-vendor setups such as Dokan, where it shows the product's seller. Works on both simple and variable products
* Improvement: **The master interface switch now lands you on the matching native screen**. Turning BrikPanel off from inside a panel screen no longer always drops you on the WordPress dashboard: it now takes you to the closest stock WordPress / WooCommerce equivalent of the screen you were on (the products list to the native product table, the product editor to that product's classic editor, coupons to the coupon list, customer analytics to WC Analytics customers, and so on). Screens with no native counterpart still fall back to the dashboard, and screens that are only skinned in place reload where they are. Developers can extend the mapping with the `brikpanel_master_off_landing_map` filter
* Improvement: **Top bar visual polish**. The 10px gap that appeared between the top bar and the "Screen Options / Help" row on WooCommerce list screens (orders, products, ...) was removed, the notification bell and "visit site" icon buttons were brought down to the same height as the Create button, and the user profile button was resized and given the same corner radius as the rest of the bar, so every control in the right-hand cluster now lines up in one consistent height and shape
* Fix: **Selecting a large global attribute no longer freezes the product editor**. Picking an existing global attribute that has thousands of terms (for example an `author` attribute with several thousand values) used to stamp every single term into the row as a selected tag, flooding the page with DOM nodes and locking the browser. The row now opens empty and you add only the terms you want through the existing type-ahead search, on both the Product attributes card and the variation wizard's Custom template. The full term list that was also being embedded into each option as JSON has been dropped (it was already sent in the save payload), trimming roughly 250kb off the editor page on stores with large taxonomies. Deliberate defaults (the Size + Color template's preset sizes, a product's already-saved values) are preserved. Works on both simple and variable products
* Fix: **Exported phone numbers are protected against spreadsheet formula injection**. A phone number that starts with "+" is written safely so spreadsheet apps treat it as text, not a formula

= 3.1.17 (2026-06-09) =
* New: **The orders overview is now a set of trend cards with a date-range filter**. The strip above the orders list has been reworked into separate cards for Total orders, Completed, Refunded and Revenue, each with its own mini sparkline showing the shape of the period, and a date picker (Today, Last 24 hours, Last 7 days, Last 30 days) that updates every card and the marketplace panel at once. Hourly detail is used for the day views and daily detail for the week and month views, all in your store's time zone. Your chosen range is remembered between visits, and the role-based "Hide orders analytics" control still applies. Counts use the same valid-sale and refund statuses as the rest of BrikPanel, on both simple and variable products
* New: **Export your custom checkout fields to Google Sheets**. Any extra checkout or order fields on your store (added through WooCommerce's own checkout fields, a checkout-field plugin, or a code snippet) are now detected automatically and offered in the Orders "Columns to export" picker, alongside the built-in columns. Pick the ones you want and their values are written to your sheet on every sync. Works for both simple and variable products
* New: **Filter the Google Sheets order export by shipping method**. A "Shipping methods to export" picker on the Orders tab lets you push only the orders that used the methods you choose (for example only Local pickup, or only Flat rate). Leave every box unchecked to export every order as before
* New: **Cost of Goods (COGS) in the Google Sheets export**. Three new optional columns are available: "Order COGS total" (the whole order's cost of goods) and "Line COGS (cost × qty)" on the Orders tab, and "Cost (COGS)" on the Products tab. Costs use the same per-unit values as BrikPanel's Profit reports, with variations falling back to their parent's cost when they have none of their own. They are off by default; add them from the relevant "Columns to export" picker
* Fix: **Two-way product sync no longer re-pushes rows that did not change** when the rightmost exported column is blank for some products (for example a "Cost (COGS)" column with no cost set). Google Sheets drops trailing empty cells when read back, which made those rows look different from what was pushed and triggered a needless re-push on every poll. Rows are now compared at their full width, so only genuine edits flow back. Two-way status sync for orders and stock sync for products are both verified working, including when the new optional columns shift the position of the Order status or Stock column

= 3.1.15 (2026-06-09) =
* Fix: **Costs entered in WooCommerce's own Cost of Goods Sold field now show up in BrikPanel**. If you set a product's cost from WooCommerce's native Cost of Goods Sold field (rather than BrikPanel's editor), that cost was previously invisible to BrikPanel: the dashboard Profit/COGS read as empty and the Cost column and Quick Edit on the product list showed nothing, even though the value was clearly saved on the product. BrikPanel now reads WooCommerce's native cost everywhere and keeps it in step automatically, so the figure appears at once. Existing products are caught up in a one-time pass on update; works for both simple products and variations

= 3.1.15 (2026-06-08) =
* New: **SEO fields for SureRank right inside the product editor**. SureRank's SEO title, meta description, canonical URL and focus keyword now appear inline in the BrikPanel product editor, with a live SEO-analysis panel that scores the current, unsaved values as you type. SureRank's own editor is a React popup that cannot draw inside a custom screen, so the fields are surfaced through BrikPanel's unified SEO card instead. Everything is written back into SureRank's own `surerank_settings_general` meta (plus the per-post noindex flag), so the storefront output and SureRank's own dashboard stay perfectly in sync. Works on both simple and variable products
* New: **Limit the Google Sheets product sync to selected categories**. A category picker on the Products tab lets you push only the products in the categories you choose (sub-categories included) instead of the whole catalogue. Off by default (all products). "Sync now" fully clears and rebuilds the Products tab, so narrowing the filter never leaves stale rows behind for products that no longer match. Covers simple products and their variations
* New: **Hide the orders analytics summary from chosen roles**. A new "Hide orders analytics from roles" setting under WooCommerce -> Settings -> BrikPanel -> Access control hides the 30-day revenue and order-count strip above the orders list from any roles you pick, while those users keep the full orders screen. Ideal for multi-branch stores where branch staff process orders without seeing the whole store's totals. What you select is exactly what is hidden, and a defence-in-depth check on the data endpoint stops a hidden role from fetching those figures directly. Note: this hides the store-wide numbers, it does not recalculate them per branch
* New: **Choose which order statuses feed your dashboard order stats** (WooCommerce -> Settings -> BrikPanel -> Analytics). You can now decide exactly which order statuses count as valid sales and which count as refunds, so stores using shipment-tracking or returns plugins with custom statuses ("Partially shipped", "Delivered", "Partially refunded", ...) stop having those orders quietly left out of the figures. The choice drives every dashboard number alike: Revenue, Orders, Average Order Value, Profit and Customer Lifetime Value
* Improvement: **Compatibility with PixelYourSite Product Catalog Pro** — its product-data fields now render and save correctly inside the BrikPanel product editor, on both simple and variable products
* Fix: **A store with no products no longer triggers an uncaught error**. On an empty catalogue the dashboard store-summary inventory query (an INNER JOIN onto stock data) returned no row, and the code then read totals straight off that missing row. It is now guarded, so a brand-new store with no products reports zero units and zero value instead of crashing the page
* Fix: **Resolved a conflict with the Admin and Site Enhancements (ASE) plugin** so ASE's tweaks and BrikPanel's interface no longer clash on the same admin screens
* Fix: **Navigation scrolling glitch** — fixed unwanted scrolling reported while moving around the dashboard

= 3.1.13 (2026-06-06) =
* New: **Exclude staff or point-of-sale accounts from customer analytics**. If you also ring up in-person sales through one or two staff or POS logins, those accounts can rack up hundreds of orders and quietly distort every per-customer number: they inflate the average lifetime value, dominate the RFM segments, and skew cohort retention, so the figures stop describing your real customers. A new "Exclude customers" button on the Customer Analytics page opens a simple picker where you can search and choose specific accounts and/or whole roles to leave out. Excluded accounts still count fully toward your shop totals (revenue, order counts, the dashboard sales figures and the Segments "Orders" tab are all unchanged), they are only removed from the customer-level views: lifetime value, RFM segments, cohort retention, the Customer Analytics tables and the Segments "Customers" tab. Saving recomputes the metrics immediately so the page reflects the change at once, and a small badge on the button shows how many accounts are currently excluded. Works the same on stores with simple and variable products
* Fix: **Stale customer rows are now pruned reliably after a recompute**. The nightly customer-metrics rebuild marks the run with a timestamp and then deletes any customer row it did not touch (for example someone whose orders were all refunded out, or who is now excluded). On servers whose database session time zone is not UTC, that marker was taken from PHP in UTC while the rows were stamped in the database's local time, so the cleanup compared two different clocks and left stale rows behind for up to the time-zone offset. The run marker is now read from the database itself, so the comparison always uses one clock and stale rows are removed on the first recompute

= 3.1.12 (2026-06-01) =
* Fix: **Variable products no longer stay "out of stock" once their variations are back in stock**. If a variable product had ever been switched to manage stock at the *parent* level with a quantity of 0 (so the parent was pinned to "out of stock"), turning the variations back on and raising their stock left the whole product reading out of stock, because WooCommerce trusts a parent that manages its own stock and never looks at the children. BrikPanel never manages stock at the parent level for variable products (each variation owns its own stock), so the editor now clears that leftover parent-level stock flag on every save and lets the stock status be derived from the variations: when any variation is in stock, the product is in stock. A one-time, self-healing migration runs in the background on upgrade and repairs already-saved products in the same situation (parent managing stock, marked out of stock, but with at least one in-stock variation), in safe batches so large catalogs are never slowed; products that are genuinely out of stock are left untouched. Applies to both simple and variable products

= 3.1.7 (2026-06-01) =
* New: **Desktop Mode compatibility**. BrikPanel now plays cleanly inside the "Desktop Mode" plugin, which turns /wp-admin into a desktop-style workspace where each screen opens in its own draggable window. Whenever a page renders under the Desktop Mode shell (either inside a window or on the shell host), BrikPanel stands down its own global chrome, the top bar and the custom navigation sidebar, so it does not duplicate the window title bar, paint a redundant strip over the desktop, or leave an orphaned content margin where the sidebar used to be. Desktop Mode's dock takes over navigation and its Cmd/Ctrl + K palette covers search, while every BrikPanel screen (dashboard, orders, the product editor, ...) fills its window edge to edge with all of its styling intact, on both simple and variable products. The integration is fully scoped: a page detached to a classic tab keeps the complete BrikPanel chrome, and when Desktop Mode is not installed nothing changes at all
* Fix: **Custom fields added through the `brikpanel_product_editor_boxes` hook are saved again**. Inputs a developer renders inside their own editor card (including ACF fields via `acf_render_fields()`) were drawn on the page but never reached the save request, so they silently dropped on every save. The product editor's save collector now also gathers every named input inside `.brikpanel-pe-ext-card` (alongside the metabox, WooCommerce-field and per-variation collectors) and forwards it to the server, where the save handler fires `save_post` / `save_post_product` so the owning plugin's own listener persists the value. ACF's hidden `#acf-form-data` nonce block is emitted once per page and travels with the payload so ACF can verify its nonce and run `acf_save_post()`. Works on both simple and variable products
* Improvement: **Silent auto-save no longer runs on a product that has not been published yet**. The editor's 60-second background auto-save used to fire on any dirty form, which could quietly write a brand-new or draft product to the database before the user was ready. It is now gated on a live flag (`#bpe-product-id[data-live]`, set server-side only for `publish` / `private` products) so a work-in-progress draft or an auto-draft is never persisted behind the user's back, auto-save only protects an already-live product from losing edits. The flag flips on the moment you publish from the editor and reverts if you move the product back to draft, on both simple and variable products

= 3.1.6 (2026-05-30) =
* New: **Master on/off switch for the whole BrikPanel interface**. A single store-wide toggle (WooCommerce -> Settings -> BrikPanel -> Access control, "BrikPanel interface", on by default) flips every back-office user between BrikPanel and the stock WordPress / WooCommerce admin in one click. You can also flip it from the on/off switch in the BrikPanel top bar, or from the native WordPress admin bar while BrikPanel is off, so you can always get back in. Only administrators see and control it, the control is nonce-checked and `manage_options`-gated, and its styling is inlined so it survives even when all BrikPanel assets are swept off. This is the global, all-users axis that sits above the existing per-user / per-role Access control
* New: **Reworked mobile and tablet layouts across the interface**. The dashboard, product list, product editor, orders and top bar were all given proper responsive breakpoints (960 / 782 / 600 / 480 / 380px). KPI and profit cards reflow from four to three to two columns as the screen narrows, the product editor's sticky header folds into two rows with the status menu re-anchored as a near-full-width sheet that stays on screen, the product list table and filter bar compress for phones, and the top bar collapses to icon-only on the smallest screens. Pure CSS, no markup or query changes, and it covers both simple and variable product screens
* New: **Bulk editor now covers categories, brands, weight, dimensions and tags**. The product list bulk update gained shipping fields (Set weight / length / width / height, shown in your store's configured weight and dimension units) and per-taxonomy actions that are generated for every product taxonomy on the store: Set / Add to Categories, Tags, Brands (any registered brand taxonomy is auto-detected) and any custom product taxonomy. "Set" replaces the terms, "Add to" appends them, with a searchable hierarchical term picker. Each taxonomy is capability-gated, runs in safe batches via the existing job runner (prepare / process / cancel AJAX), and works on both simple and variable products

= 3.1.5 (2026-05-29) =
* New: **Google Ads is now live for everyone**. Google approved the `adwords` sensitive-scope verification for our OAuth project, so the "Coming soon" skin on the Google Ads card is off by default and the full flow works out of the box: **Connect Google Ads**, account picker, Manager (MCC) account support, **Sync now**, and Disconnect. Daily spend, impressions and clicks flow into the dashboard for real ROAS and Net Profit, exactly like Meta. The skin is kept only as an operator escape hatch (a single `wp-config.php` constant or option) in case Google ever revokes the verification, so it can be re-hidden without a code change. Meta Ads stays in its own pending-review state, unchanged
* New: **"Imported spend data" panel on the Ad Platforms page**. A month-by-month breakdown plus an all-time summary for each connected platform, so you can see exactly what BrikPanel has pulled behind the dashboard figures: total spend, impressions, clicks, average CTR / CPC / CPM, the number of days with data, and the full date span. Rows are grouped by currency so a rare mid-life account-currency switch stays visible instead of being silently summed, and a Refresh button re-reads the latest. Backed by two new read-only store queries (`account_summary()` / `monthly_breakdown()`) and a nonce-checked, `manage_woocommerce`-gated `brikpanel_ads_spend_breakdown` AJAX endpoint
* New: **Restrict BrikPanel settings to administrators**. A new "Restrict settings to administrators" toggle under WooCommerce -> Settings -> BrikPanel -> Access control keeps the settings tab administrator-only and is **on by default**. Shop managers and other roles that can manage WooCommerce keep the full BrikPanel interface but are kept out of the settings tab itself, even by direct link: the tab is removed from the WooCommerce settings nav, a direct hit on `?tab=brikpanel` lands silently on WC General (no PHP notice), and defense-in-depth 403 guards sit on the render and save paths. This is a separate, narrower axis from the existing interface Access control, so a shop manager can keep BrikPanel while only administrators touch its configuration. Turn it off to hand the settings page back to every `manage_woocommerce` user. Super admins on multisite always pass
* Fix: **Loading accounts for a Google Ads manager (MCC) user no longer floods the "Recent errors" log**. Manager-only sub-accounts routinely return a 403 on the customer-info enrichment call (the account is visible in the list but only reachable through the manager), which is an expected outcome, not a failure. That specific 403 is now silenced from the error log while genuinely unexpected errors (for example a 500) are still recorded
* Tweak: The Ad Platforms dashboard ROAS labels are now fully translatable, and a number of user-facing strings across the Ad Platforms screens were reworded for clarity

= 3.1.1 (2026-05-24) =
* New: **Google Sheets two-way sync — Sheets edits now flow back into WooCommerce**. The Sheets integration is no longer push-only. Two new flows ship alongside the existing one-way pushes: (1) **Orders pull** — the Orders tab is polled every 2 / 5 / 15 minutes (your pick), and any change to the **Order status** column is applied to the matching `WC_Order` via `update_status()` with a "Status changed via Google Sheets sync." order note; status text is normalised so "Processing", "wc-processing" and the localised label all map back to the right WC key. (2) **Products pull** — a new dedicated **Products** tab pushes every simple product and every variation (variations get their own row, parent_id column points to the parent) with id / SKU / name / price / **stock** / status; the Stock column is the only writable cell and changes flow back into WooCommerce on the next poll. Last-write-wins conflict resolution compares each cell against a sha256 snapshot stored on product/order meta AND against `_date_modified`, so a stale poll cannot clobber a fresh Woo edit (a 10s grace window absorbs same-second push/save races); divergence detected mid-poll is logged and the row is re-pushed instead. Push side is event-driven (`woocommerce_product_set_stock`, `woocommerce_variation_set_stock_status`, `woocommerce_new_product`, etc.) with a 5-second debounce so bulk inventory updates coalesce into one Sheets API call; a "Pull now" button next to "Sync now" runs the reverse direction synchronously and a structured toast reports `checked / applied / conflicts`. Tabs are dropdown-validated with the real WC status set on first push so merchants pick from a list instead of free-typing a status that would be silently skipped. Off by default per flow (the toggles say "Two-way sync: apply status / stock edits from Sheets") — the existing one-way push behaviour is unchanged for stores that don't opt in. Works identically on simple and variable stores
* New: **ACF (Advanced Custom Fields) field groups now auto-render in the BrikPanel product editor** — reported by a user who created ACF fields targeting `product` and never saw them appear. Root cause: BrikPanel relied on the merchant to hand-pick every metabox via the "Third-party plugin metaboxes" multiselect, but the multiselect was built from `add_meta_boxes` snapshots that fire only on `load-post.php` / `load-post-new.php`, neither of which runs on the BrikPanel editor page, so ACF's per-group metaboxes were never even registered to be picked. The editor now bootstraps ACF metaboxes directly (`ACF_Form_Post::add_meta_boxes()`) when rendering, AND auto-resolves every ACF field group whose Location Rules match the current product via `acf_get_field_groups( [ 'post_type' => 'product', 'post_id' => $id ] )` so the matching groups appear without the merchant touching the multiselect. A new **"Auto-include ACF field groups"** toggle (default on) lives directly above the metaboxes multiselect under WooCommerce → Settings → BrikPanel → Products; a `brikpanel_pe_auto_include_acf` filter lets developers gate it programmatically per product. Save round-trips already work because the editor emits ACF's hidden `_acf_nonce` / `_acf_post_id` / `_acf_screen` / `_acf_changed` block. Applies to both simple and variable products
* New: **Eight popular-language translations bundled in the plugin** — fully translated UI for German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Italian (`it_IT`), Dutch (`nl_NL`), Polish (`pl_PL`), Brazilian Portuguese (`pt_BR`) and Russian (`ru_RU`), shipped alongside the existing Turkish (`tr_TR`) and refreshed to cover every string introduced in this release (Two-way sync UI, ACF auto-include toggle, Pull now / Poll interval controls, conflict toasts, etc.). PO + MO + WP 6.5+ `.l10n.php` files are all included so stores using any of these locales get a localised admin out of the box, no manual `wp i18n` step required

= 3.0.9 (2026-05-22) =
* Fix: **Foreign-plugin icons rendered as empty squares when a non-default Interface font was selected** — the Appearance feature applied the chosen typeface with `[class*="brikpanel-"] *`, and the topbar feature tags both `<body>` and `<html>` with `brikpanel-has-topbar` so its layout offsets can apply. Together those two facts made the broad selector match every descendant of `<body>` on every admin page that rendered the topbar, including third-party plugin screens. Icon-font glyphs (Font Awesome, Material Icons, etc.) lost their `font-family` to the Interface font and rendered as tofu boxes. The selector now excludes `body` and `html` so real BrikPanel wrappers like `.brikpanel-dashboard` and `.brikpanel-topbar-*` still receive the font while foreign plugin UIs are no longer touched. Reported on a WP Mobile Bottom Menu (WP BNav) icon picker; the same root cause affected any third-party admin screen using icon fonts. No change at the default "System default" font setting

= 3.0.9 (2026-05-19) =
* New: **Site-wide Cmd/Ctrl + K command palette**. The palette no longer scans only orders; it now searches four sources in one place: **Orders** (customer name, email, phone, order ID, or a product SKU inside the order), **Products** (simple and variable, by name or SKU, variations included), **Customers** (registered users by name, email, or username), and **Navigation** (jump to any admin page, including screens added by third-party plugins). Every source has its own on/off toggle under a new WooCommerce → Settings → BrikPanel → "Search" section, so the palette can stay orders-only or open up to a full admin-wide search, and a `brikpanel_search_sources` filter lets developers add, remove, or reorder sources. The admin menu is indexed per user on real page loads (admin-ajax never builds the menu, so it is read back from a per-user transient during the search request), every source is independently capability-checked, and the placeholder stays "Search orders" while orders is the only active source so existing users see no change. Resolves the report that Cmd/Ctrl + K only found orders and could not reach the rest of the site or third-party plugin pages

= 3.0.5 (2026-05-19) =
* New: **GTIN column on the products list** — the BrikPanel product list can now show a **GTIN** column reading WooCommerce's native `_global_unique_id` field (`WC_Product::get_global_unique_id()`). Off by default; flip it on per-user from the **Columns** popover (persisted in user meta, like every other column). Variable products show the parent GTIN, or the aggregated variation GTINs when the parent has none — so it works for both simple and variable products
* New: **Search products by SKU** — the product list live-search box now matches on SKU as well as title. A `posts_search` filter rewrites the query so a search term hits a product's own `_sku` **and** surfaces a parent product whenever one of its variation SKUs matches, with `$wpdb->esc_like()` escaping throughout. Resolves the user report that SKU search did not work on the product list
* New: **Yoast SEO for WooCommerce compatibility** — the WooCommerce-specific Yoast addon (detected via `WPSEO_WOO_VERSION`) ran its identifier/GTIN analysis against `#product-type` and `#_sku` DOM nodes that the simplified BrikPanel editor never rendered, so it errored out. The editor now emits hidden shim nodes mirroring the real product type and SKU and keeps the hidden `#product-type` in sync when the BrikPanel type selector changes, so the Yoast Woo SEO analysis and score panel run correctly inside the BrikPanel product editor for both simple and variable products
* New: **Dashboard export button** — a new export button next to the dashboard date-range presets downloads the full dashboard as a multi-sheet Excel workbook (Summary, conversion funnel, order status, devices, customer segments, top products, most-viewed, most added-to-cart, sales-over-time, countries, cities, low stock, subscriptions and full order records) for the active date range. Built from the exact payload the dashboard renders so the file can never drift from the screen; streamed via `admin-post.php` (`brikpanel_dashboard_export`, nonce-checked, `manage_woocommerce`-gated) with real numeric cells so the spreadsheet can sum and sort
* New: **Shipping class in the product editor** — WooCommerce's `product_shipping_class` taxonomy is now selectable in the simplified product editor as an opt-in **Shipping class** section (enable it from WooCommerce → Settings → BrikPanel via the editor section list; hidden by default). Simple products get one selector; variable products additionally get a per-variation shipping class column with a "Same as parent" inherit option, so every variation can override individually. Closes the migration gap reported by users who relied on WooCommerce shipping classes
* Fix: **Bullet points now render in the product editor and on the storefront** — bulleted and numbered lists created in the editor were being wrapped in an invalid `<p> > <ul>` structure so they did not display as a list. After an insert-list command the editor now unwraps the list from its surrounding paragraph, and explicit `list-style` / `display:list-item` CSS for nested `ul`/`ol`/`li` (disc → circle → square) makes lists render correctly in both the editor and the front-end product description
* Improvement: **Richer product description editor** — the description and short-description editors gained a block-format dropdown (Paragraph, Heading 2, Heading 3, Heading 4) that reflects and applies the current selection's block, plus heading CSS so the formatting is visible while editing. Combined with the existing visual ⇄ HTML source toggle, content pasted from a website (which keeps its markup) can now be retagged with proper headings from the toolbar instead of only being fixable in the code editor
* Fix: **Google Sheets "Choose existing spreadsheet" 403 right after connecting**: Google's consent screen presents the Drive permission as an optional checkbox, so a user could complete OAuth with a perfectly valid token while the `drive.file` scope was never actually granted. The connection then showed a green "Connected", but the Picker, "Create new spreadsheet" and every sync failed with a raw Google 403 until the user disconnected and reconnected. BrikPanel now verifies the granted scope after consent and refuses a connection that is missing Drive access with a clear, actionable message; surfaces a prominent warning on an already broken connection; and blocks the Picker and create-sheet actions with a fix-it prompt instead of leaking a scope-less token to a raw Google 403. Behaves identically on simple and variable stores

= 3.0.4 (2026-05-18) =
* New: **Access control** — a new WooCommerce → Settings → BrikPanel → "Access control" section lets you keep the BrikPanel interface for some users while leaving others on the stock WordPress / WooCommerce admin. Disable for **administrators** with one toggle (the common agency setup: clients who are shop managers get BrikPanel, the agency's own administrator account stays vanilla), and/or for any **roles** or hand-picked **individual users**. Disabled users get the native admin menu, dashboard, product/order/coupon screens and zero BrikPanel styling; everyone else is unaffected. Enforced in two layers — every interface toggle is short-circuited to "off" so each module renders the native screen, and all always-on BrikPanel assets, the extra order-list columns and the font/accent/brand-logo theming are swept — so the result is pixel-for-pixel the default experience. BrikPanel analytics, tracking and background jobs keep running for the store regardless. The BrikPanel settings tab is always reachable (with the real toggle states) even for an excluded administrator, so you can never lock yourself out

= 3.0.2 (2026-05-16) =
* Security: **Signed proxy responses** — every reply from the brksoft.com proxy (Google Ads, Meta Ads and Google Sheets OAuth) is now HMAC-SHA256 signed with a freshness timestamp. The plugin verifies the signature on every successful response and refuses to act on any unsigned, tampered, replayed or stale body instead of trusting it — closing cache-poisoning / transport-tampering / log-only attack paths
* Security: **Remote kill-switch** — a signed `revoke` directive lets the proxy operator make all installs immediately wipe their stored Google / Meta / Sheets tokens and stop calling the proxy until the user reconnects, so a suspected proxy compromise can be contained without a plugin update
* Security: **Google Ads query allow-list** on the proxy — only the exact daily-spend query is accepted; any attempt to pull search terms, PII or other resources through a connected account is rejected
* Security: **Hostile `raw_data` handling** — ad-spend API payloads are depth-, size- and charset-capped before they are stored, so a malicious response cannot bloat the table or smuggle content to later consumers
* Security: Proxy global off-switch, `no-store` / `noindex` response headers, and operational hardening notes for the brksoft.com proxy
* Tweak: Version bump to 3.0.2; no functional changes to the dashboard, sync or UI

= 3.0.0 (2026-05-15) =
* New: **Google Ads & Meta Ads integration** — BrikPanel now pulls daily ad spend from Google Ads and Meta (Facebook / Instagram) Ads into a local table so the dashboard can show **real ROAS and Net Profit** next to store revenue. Three new KPI cards render under the existing dashboard metrics: **Ad Spend** (summed across every connected platform for the active date range), **ROAS** (store revenue ÷ ad spend), and **Net Profit** (revenue − COGS − ad spend − manual expenses). The cards are multi-currency aware — when an ad account reports in a different currency than the store, spend is shown split as "₺X + $Y" and ROAS / Net Profit are intentionally omitted (UI shows "—") instead of printing a misleading converted number. COGS is read from WooCommerce's native order COGS meta through a dedicated HPOS-compatible query; manual expenses come from the existing BrikPanel expenses table. The cards only appear once the first sync has written real data
* New: One-click OAuth connect per platform through the same brksoft.com proxy pattern as Google Sheets — PKCE-protected handoff, and the Google **developer token** / Meta **app secret** / OAuth client secret never ship inside the plugin (the proxy injects them server-side). Tokens are kept in a single encrypted multi-platform vault (`sodium_crypto_secretbox`, AES-256-GCM fallback, key HKDF-derived from the site's WP salts) with platform-aware refresh: Google uses the standard `refresh_token` grant, Meta uses the `fb_exchange_token` long-lived-token swap. A revoked / `invalid_grant` connection auto-clears so the UI shows a clean "reconnect" state instead of looping on errors
* New: Per-platform **primary account picker** — Google enumerates accounts via `listAccessibleCustomers` with manager-account (MCC) `login-customer-id` support; Meta lists `/me/adaccounts` including accounts under a Business Manager. On first account selection BrikPanel backfills **3 years of history**, split into 90-day Action Scheduler chunks scheduled most-recent-first so today's spend appears on the dashboard within minutes while the full history fills in behind it. A daily sync re-pulls the trailing 7 days to absorb the late revisions ad platforms apply to recent-day numbers; every write is an idempotent UPSERT so re-syncing or overlapping windows never duplicate a day
* New: Dedicated **Ad Platforms** page under the WooCommerce menu (Beta badge), a "Connect ad accounts" call-to-action on the dashboard, a per-platform manual **Sync now** button, backfill progress, and a token-redacted error log viewer. A master toggle under WooCommerce → Settings → BrikPanel → **Ad Platforms** (default on) makes the whole module dormant when off — no admin page, no scheduled sync, no dashboard cards — while saved connections are kept. Google Ads stays locked behind a switch until its Google-approved developer token is live so users never hit a dead "Connect" button; Meta is unaffected. A new `wp_brikpanel_ad_spend` table is created on activation alongside the other BrikPanel tables, and the raw API payload is retained per row for the planned BrikMentor analysis
* Developer: New proxy-tunnelled **Google Ads API** and **Meta Marketing API** clients (`Brikpanel_Ads_Google_Client`, `Brikpanel_Ads_Meta_Client`) built on `wp_remote_*` with one-shot 401 refresh-and-retry, infrastructure-only backoff (HTTP 429 / 502 / 503 / 504 plus Meta rate-limit codes 4 / 17 / 32 / 613) and no retry on application-level 500s so a misconfigured proxy fails fast instead of hanging the settings UI — no Composer dependency added, reusing the foundation laid by the 2.9.0 Sheets client

= 2.9.5 (2026-05-13) =
* New: Multisite network access rules — when BrikPanel is network-activated, every subsite admin used to inherit full visibility of the WooCommerce → BrikPanel settings tab; a new "BrikPanel Access" page under Network Admin → Settings now lets the Super Admin enforce a role allowlist (`brikpanel_network_access` site-option). When enforcement is on, only users whose role is in the allowlist see the settings tab, the BrikPanel sidebar menus, and can hit any `brikpanel_*` AJAX endpoint — gated centrally through `brikpanel_user_can_access()` so a single check applies across surfaces and the `administrator` role can never be removed from the allowlist (defense-in-depth)
* New: **Delete individual variations** from inside the BrikPanel product editor — every row in the variation table now has a per-row trash button with an in-place confirmation, and the deletion is finalized when the parent product is saved. Combined with the existing **Generate variations** button this closes the last gap users hit when migrating away from the default WooCommerce variations tab. Works on both brand-new variable products and existing ones with attribute combinations already generated
* New: Unsaved-changes guard on the product editor — clicking the top-left "Back to Products" arrow (or closing the tab / reloading) while any field is dirty now triggers the browser's native `beforeunload` confirmation instead of silently discarding edits. Dirty state is tracked on every input / textarea / select / contenteditable inside the editor body
* New: Quick-edit drawer **featured product star** — the slide-in quick edit panel from the products list now exposes the same featured-product star that lives in the row and the full product editor, so a product can be flipped in/out of WooCommerce's featured pool without opening either screen. Backed by the same `brikpanel_toggle_featured` AJAX endpoint as the row icon; row + drawer star sync via a shared `applyQeFeaturedState()` so toggling either surface updates the other instantly. Works for both simple and variable products
* New: Optional advanced coupon restriction fields — the slide-over coupon editor stays minimal by default, but six WC-native restriction fields can now be enabled individually under WooCommerce → Settings → BrikPanel → Coupons: **Products**, **Exclude products**, **Product categories**, **Exclude categories**, **Allowed billing emails** and **Limit usage to X items**. Each toggle is checked both on the editor render side AND inside the AJAX save handler so a hostile payload cannot write to a field that an admin has not enabled. Closes the migration gap reported by users moving from heavy WC coupon workflows
* New: Drag-free **dashboard section ordering** — the existing "Visible dashboard sections" multiselect is now an ordered list with per-row visibility checkbox and up/down arrow buttons (same pattern as the product editor section ordering), so dashboard cards can be both hidden and reordered without touching the drag-and-drop API. Order persists as `brikpanel_dashboard_section_order` JSON, and the dashboard renderer resolves the final order through a `brikpanel_dashboard_section_order` filter so developers can override programmatically
* New: "Copy everything" help tooltip — the previously-cryptic dashboard "Copy everything" button now ships with a question-mark icon next to it whose hover/focus tooltip explains exactly what it does: bundles every dashboard metric (KPIs, top products, recent orders, customers, settings) into a single Markdown report and copies it to the clipboard, ready to paste into ChatGPT / Claude for instant store analysis. CSS-only popover, repositions right-aligned on screens under 900px
* New: **Google Sheets** integration ships with a "Beta" badge on its menu item and page header, and can now be fully disabled from WooCommerce → Settings → BrikPanel → "Google Sheets integration" with a single checkbox (`brikpanel_gs_module_enabled`, default on). When disabled, no admin page, no sync classes, no OAuth handlers and no `woocommerce_new_order` listener are registered — zero overhead on stores that do not use the connector
* Fix: Third-party **brand / taxonomy columns** in the products list now render as comma-separated, locale-aware brand labels instead of dumping the raw array (`Array` or `["Brand1","Brand2"]`). The ASE bridge routes any column whose source is a taxonomy through `get_the_terms()` + `sanitize_term_field()` + `wp_get_list_item_separator()` before output, with per-term escaping — fixes brand columns added by WooCommerce Brands, Perfect WooCommerce Brands, YITH Brands and any plugin that registers a taxonomy column on the products list
* Fix: Variable products created through the BrikPanel editor sometimes lost their variation selector on the storefront (notably reported on stores running the Blocksy Pro theme). Root cause: an in-flight `save_post` hook reloaded the parent product through WC's poisoned factory cache and silently flipped the `product_type` term back to "simple". `save_variations()` now reasserts the `variable` term with `wp_set_object_terms()`, clears WC's per-product `_type_` cache via `WC_Cache_Helper::get_cache_prefix()`, calls `clean_post_cache()`, and finally calls `WC_Product_Variable::sync()` on a freshly-instantiated parent so the frontend always recognizes the product as variable

= 2.9.1 (2026-05-12) =
* Critical fix: Google Sheets sync handlers were registered only inside the `is_admin()` gate, so Action Scheduler workers (WP-Cron / CLI) and the front-end `woocommerce_new_order` hook never saw them — real-time sync silently dropped new orders and bulk export failed with "no callbacks registered". Bootstrap now loads outside the admin gate (same pattern as BrikControl); admin menu / AJAX endpoints still self-gate to admin context
* Critical fix: "Sync now" was queueing an Action Scheduler job and returning immediately, leaving the user with no progress, no row count, and no completion signal. Now runs inline with a spinner, sticky "Syncing…" toast, and a final success toast reporting actual rows + duration. Bulk export still paginates in the background via Action Scheduler when more rows remain
* New: "Reset & re-push everything" button on the Orders tab — clears the `_brikpanel_gs_synced_at` flag from every order so the next Sync re-pushes the full history to the currently configured tab. Useful when renaming the target tab so the old history appears in the new tab
* New: switching the target spreadsheet now automatically resets sync state — every order is re-pushed to the new sheet on the next sync (was: silently kept the old "synced" flags so new sheet stayed empty)
* Improvement: Sync now feedback is data-driven — when nothing new was synced, the toast explains "every order is already marked synced" and points to the Reset button instead of returning silent zero
* Improvement: Reports / Customers / Orders sync handlers return structured stats (`rows`, `orders`, `more`) so manual sync can report exact numbers and the JS UI can refresh the "Last successful sync" stamp inline without a page reload
* Improvement: `ensure_tab` now detects pre-seeded empty tabs (created via the "Create new spreadsheet" flow) and writes their header on first sync instead of leaving them headerless. Existing tabs with non-empty headers are never overwritten
* Improvement: Reports analytics helpers (`brikpanel_get_total_revenue`, `brikpanel_get_visitor_count`, etc.) are now explicitly loaded by the reports-sync handler, so Sales Summary / Daily KPIs / Top Products / Funnel tabs work when running inside Action Scheduler workers (previously silently emitted zero rows)
* Improvement: Token refresh stays robust when `expires_at` has already lapsed — the lazy refresh path runs synchronously through the brksoft.com proxy and surfaces auth errors clearly

= 2.9.0 (2026-05-12) =
* New: **Google Sheets integration** — a fully native, one-click connector that streams BrikPanel data into a Google Sheet of your choice. Four flows ship in V1: (1) **Real-time order sync** — every new WooCommerce order is appended to a dedicated tab within seconds, with one row per line item so variations get their own row and attribute columns; status changes update the existing row in place via stored row indices kept in order meta. (2) **Scheduled bulk export** — Action Scheduler-backed hourly/4h/daily job that catches up historical orders matching a configurable date range and status set; same idempotency guarantee, so manually re-running "Sync now" never duplicates rows. (3) **Analytics report snapshots** — four overwrite-mode tabs (Sales Summary, Daily KPIs, Top Products, Funnel) are refreshed on an interval, exposing total-sales, conversion, AOV, refund/conversion rates and the visitor → checkout funnel directly in Sheets for formulas and pivots. (4) **Customer + RFM snapshot** — chained to the nightly RFM recompute so the segments tab refreshes the moment the metrics table does. Authentication uses an OAuth proxy that BrikPanel hosts on brksoft.com (PKCE-protected handoff token, never sends the auth code through the browser URL); the plugin stores only encrypted access/refresh tokens locally (sodium_crypto_secretbox keyed off AUTH_KEY + SECURE_AUTH_KEY) and requests minimum scopes — `spreadsheets` + `drive.file` (NOT full Drive). HPOS-compatible queries throughout, custom error log with bearer/token redaction, exponential backoff on 429/5xx, and full re-pin into the modern sidebar. Top-level menu page (Google Sheets) under WooCommerce → BrikPanel
* Developer: New WP-CLI-compatible Sheets API client (`Brikpanel_Sheets_Client`) using `wp_remote_*` with built-in 401-refresh, 429 exponential backoff, and 403 rateLimitExceeded handling — no Composer dependency added. Reusable foundation for the planned Google Ads integration in 3.0

= 2.8.6 (2026-05-11) =
* New: Featured product star — a new opt-in setting adds a clickable star next to the status dropdown in the simplified product editor and at the start of every row in the products list, so any product can be flipped in or out of WooCommerce's featured pool without opening the full editor. Backed by WC's native `featured` term on the `product_visibility` taxonomy (single source of truth shared with storefront shortcodes and "featured" widgets), with optimistic UI and a dedicated `brikpanel_toggle_featured` AJAX endpoint. Off by default so existing installs are unchanged
* New: Brand logo for the BrikPanel topbar and the modern login page — a new opt-in toggle under WooCommerce → Settings → BrikPanel → Appearance lets store owners pick a single brand image from the media library that replaces both the BrikPanel mark in the admin top bar AND the centered logo on the modern login screen. One picker drives both surfaces so the brand stays consistent. Off by default; wide non-square logos stretch horizontally up to 160px in the top bar instead of being letterboxed
* New: Settings import / export — a new "Import / Export" section under WooCommerce → Settings → BrikPanel downloads every BrikPanel option as a single portable JSON file (toggles, layout, accent color, sidebar order, dashboard order, product-editor section order, notification preferences). The import endpoint validates the format header, refuses files over 1 MB, and sanitises every value against its declared WC field type before writing — so a hostile upload can never inject raw values into `wp_options`. The brand logo attachment id is intentionally skipped because it cannot transfer across sites. New `brikpanel_exportable_option_keys` filter for developers
* New: Drag-free section ordering in the simplified product editor — the previously-flat "Visible editor sections" multiselect under Settings → Products is now a sortable list with per-row up/down buttons and a visibility checkbox, so store owners can both hide and reorder every editor section (Images, Pricing, Inventory, Category, Tags, Digital, Description, Variations, SEO, Attributes, …) without touching code. Order is persisted as JSON and merged forward on plugin update so newly-introduced sections never silently disappear; hidden sections keep their slot so they slide back into place when re-enabled
* New: Backorder "Notify customer" sub-option — opt-in setting that surfaces WooCommerce's third backorder value (`notify`) in the simplified product editor. When "On backorder" is selected as the stock status, a CSS-Grid collapse reveals two radios (*Allow without notification* / *Allow and notify customer*); WC then writes a customer-visible note onto backordered line items at checkout. Works on both simple and variable products (variation rows expose the same control), and off by default so existing installs keep their two-value behaviour
* New: Quick-edit drawer now respects custom product taxonomies — a new opt-in setting surfaces any third-party product taxonomy (Brands from WooCommerce / Perfect WooCommerce Brands / YITH Brands, plus any custom `register_taxonomy` for the product post type) inside the slide-in quick-edit panel alongside Categories and Tags. Hierarchical taxonomies render as a checkbox tree, flat ones as a flat list, and capability checks (`assign_terms`) ensure editors without rights never see fields they can't save. Off by default; built-in cat/tag and attribute (`pa_*`) taxonomies are excluded since they already have dedicated UI
* Improvement: Virtual flag is now driven by the Downloadable toggle in the product editor — toggling "Digital (downloadable)" on automatically locks Virtual on and disables it, so the user can never end up in an inconsistent "downloadable but ships physically" state. Variations inherit the parent's Virtual + Downloadable flags so the lock applies uniformly across variable products

= 2.8.5 (2026-05-07) =
* New: BrikControl — Store Health module. A new "Store Health" surface (shield icon in the BrikPanel topbar + dashboard alert banner + dedicated `admin.php?page=brikpanel-brikcontrol` report page) audits every published and private product (and variation) and scores the store on two e-commerce-critical axes: oversized product images (>1 MB) and modern format coverage (WebP / AVIF). Each finding ships a clear recommendation — BrikPanel does NOT bundle its own image converter (that would needlessly bloat the plugin); instead it detects already-active optimizers (Smush, ShortPixel, Imagify, EWWW, Optimole, reSmush.it, LiteSpeed, WebP Express, Converter for Media, ShortPixel Adaptive Images, Jetpack Boost…) and, when none is found, surfaces a critical flag with a curated install list. Scans run in the background through Action Scheduler (200 products per batch, idle when not needed) and the topbar updates without leaving the page
* New: Vendor management settings under WooCommerce → Settings → BrikPanel → Vendors. New dedicated section pill exposes a master toggle for the Vendors / Stock Orders feature, a "Show vendor field in product editor" toggle (adds a Sourcing card with vendor + per-product vendor SKU; variations inherit the parent vendor unless overridden), a "Show vendor column on products list" toggle, the Stock Orders module toggle with a configurable PO reference prefix, and granular automations for the moment a purchase order is received (auto-increase WC stock, auto-update product cost / COGS with last-cost OR weighted-average method, auto-create matching expense entry under a configurable category). A "Settings" row is also injected into the top-level Vendors menu that links straight to the section
* New: Full WordPress Multisite compatibility — BrikPanel can now be network-activated to deploy a separate, fully-isolated dashboard on every subsite. Each subsite gets its own products, orders, vendors, stock orders, expenses, customer analytics tables, settings and Action Scheduler queue, with zero cross-site leakage. Network activation provisions every existing subsite immediately, and a `wp_initialize_site` hook back-fills tables / defaults the moment a new subsite is created on a network where BrikPanel is already active. Per-site activation continues to work unchanged on single-site WordPress
* Improvement: New products now default to the **Published** status in the BrikPanel product editor instead of "Draft". Auto-draft posts are surfaced as "publish" in the status dropdown so the very first save publishes the product without a second click — matching what most store owners expect. Existing drafts keep their current status untouched
* Improvement: Brand-new products now show a **Publish** button (instead of "Save") and clicking it actually publishes the product. The moment the first save succeeds, the action bar auto-injects the **View product**, **Duplicate** and **Add new** buttons next to the status dropdown — no page reload required. Previously these only appeared after a manual page refresh
* Improvement: Toggling **"Does this product have sizes/colors?"** on now hides the standalone **Product attributes** card while the variations wizard is open, so users no longer get confused between variation attributes (Size / Color) and spec attributes (Brand / Material). Switching the toggle back off restores the card immediately. Works on both simple→variable transitions and existing variable products
* Fix: The product list **Sort** dropdown now correctly re-orders products when a specific category is selected. Previously, filtering by category and changing the sort order in the same session left the table on the previous ordering because rapid filter+sort changes raced each other; in-flight requests are now aborted when a newer one is fired, so the visible ordering always matches the dropdown — for both simple and variable products

= 2.7.2 (2026-05-04) =
* New: Sidebar navigation customizer "More menu" section — top-level WordPress admin menu items (and custom links) can now be promoted into the BrikPanel "More" dropdown alongside the native WooCommerce submenus, instead of only living in the top "Store" or "Site management" groups. Drag any row from WooCommerce → Settings → BrikPanel → Navigation into the new third section and it renders as a child of "More" on the sidebar, with the existing WC submenu structure (Reports, Status, Extensions, …) preserved
* New: Per-submenu visibility toggles in the customizer — every system row now expands into a collapsible panel that lists its individual WordPress submenu children (e.g. Users → All Users, Add User, Profile) with a small toggle next to each one. Hidden children disappear from the BrikPanel sidebar hover/expand menu without removing the parent
* New: Custom icon override for system items — every system row now has a "Change icon" button that opens the icon picker dialog and replaces the default WordPress dashicon with one of the curated BrikPanel SVG icons (25+ options); a "Use original" button restores the dashicon. Previously only user-added custom links could pick from this icon set
* Improvement: Customizer config schema is forward-compatible — existing saved configs continue to work without `submenus` / `icon_override` fields, and the snapshot now collects all submenu children (with WC promotion/skip filters applied) so newly-installed plugins surface their child items automatically

= 2.7.0 (2026-05-04) =
* New: Sidebar navigation customizer — every item in the BrikPanel left menu (both the top "Store" group and the "Site management" group below the heading) can now be reordered via drag-and-drop, hidden, or extended with custom internal/external links from WooCommerce → Settings → BrikPanel → Navigation. Configuration is stored as JSON in a single option and newly-installed plugins auto-append at the end so they always remain visible after an update
* New: Dashboard section visibility — the "Dashboard" settings section now exposes a multiselect that lets store owners pick exactly which cards render on the BrikPanel dashboard (KPI cards, sales chart + live visitors, conversion funnel + order rates, locations globe, top products + recent orders, most viewed pages + add-to-cart, devices + customer types, RFM segments, low stock + LTV, subscriptions, marketplace analytics, WordPress widgets). Empty selection means "show everything", so existing installs keep their full dashboard
* New: Storefront product ordering from the BrikPanel product list — a new "Sort" toggle in the toolbar enables drag-and-drop reordering of products with a handle column, and a "Custom order" entry has been added to the sort dropdown so the saved order is also browseable inside the panel. Reordering writes directly to `wp_posts.menu_order` so the new sequence applies on the storefront immediately, with collisions tie-broken by title
* New: Admin interface appearance customization — a new "Appearance" section in BrikPanel settings lets you change the UI font (System default + nine curated Google Fonts: Inter, Poppins, Roboto, Manrope, DM Sans, Plus Jakarta Sans, Nunito, Work Sans) and the primary/accent color used across the dashboard, top bar, sidebar, products, orders, coupons, segments, expenses, customer analytics, product editor and the modern login page. Google fonts are loaded with `display: swap` and a `preconnect` hint, and skipped entirely when "System default" is selected so no outbound request is ever made by default
* New: Full RTL support — a dedicated `assets/css/brikpanel-rtl.css` override stylesheet (~860 lines, all rules scoped under `body.rtl`) is enqueued at priority 999 only when WordPress reports an RTL locale (Arabic, Hebrew, Persian, Urdu, …), so the entire BrikPanel UI flips direction cleanly — dashboard, products list, product editor, orders, coupons, segments, expenses, customer analytics, top bar, sidebar nav, login page, modals and toast notifications
* Improvement: BrikPanel settings page reorganized into a Shopify-style sub-navigation — the previously single long page is now split into focused sections (General, Navigation, Dashboard, Products, Orders, Coupons, Login page, Notifications, Developers) so admins land on one topic at a time. Each section's title + description + form-table block is wrapped into a single visual card; third-party fields injected via the public `brikpanel_settings_fields` filter are still respected
* Fix: Cmd/Ctrl + K order search no longer leaves a phantom empty WordPress Command Palette open behind the BrikPanel overlay. The keydown listener is now registered in the capture phase with `stopImmediatePropagation()` so WordPress core's `commands-command-menu` (which binds the same shortcut) never fires, and closing the BrikPanel search via Escape no longer reveals an empty WP search modal underneath
* Fix: The "X" close button on the bulk-update modal in the products page now closes the modal correctly — the click handler had only been bound to the bottom "Cancel" button, leaving the top-right close icon inert. Both controls are now wired to the same `closeBulkModal` handler

= 2.6.1 (2026-04-28) =
* New: Live store summary — BrikPanel now generates a continuously updated `brikpanel-store-summary.md` file that captures every metric the panel collects (sales, orders, AOV, conversion rate, top products, top countries, customer LTV / RFM / cohort highlights, inventory health and more) in a compact, human-readable format. Designed for two flows: paste it into any AI chat for instant store interpretation, or hand it to a data analyst, accountant or investor as a one-page snapshot of the whole shop
* New: Cache plugin integration on the BrikPanel top admin bar — when WP Rocket, LiteSpeed Cache, W3 Total Cache, WP Super Cache, WP Fastest Cache, Cache Enabler, Hummingbird, Comet Cache, Breeze, Autoptimize, SG Optimizer, Swift Performance or Nginx Helper is active, a "Clear cache" button appears in the top bar and purges the detected provider in one click
* New: Quick edit "Downloadable" toggle for virtual / digital products in the product list — when a product is digital, the slide-in quick edit now exposes the downloadable switch so digital products can be flipped without opening the full product editor (works for both simple and variable products)
* New: Gutenberg compatibility — the simplified product editor and the BrikPanel order screens now coexist cleanly with the block editor, including stores that have Gutenberg forced on for `product` post type
* Improvement: Digital product settings (Virtual / Downloadable / Files / Download limits) are now positioned above the description and short description fields in the product editor — the most relevant toggles for digital sellers are visible without scrolling
* Fix: "Top Countries by Orders" and "Top Countries by Customers" dashboard cards now show accurate values — the previous query joined the wrong address table on HPOS stores and double-counted shipping/billing entries on legacy stores. Both code paths have been rewritten and the totals now match `wc_get_orders` and the customer table exactly
* Fix: "Visitors by Device" dashboard widget data source corrected — device classification is now derived from the stored User-Agent on the `wp_brikpanel_visitors` table (not from a stale transient), so desktop / mobile / tablet shares match the visitor log row-for-row

= 2.5.3 (2026-04-25) =
* New: Full SEO plugin compatibility — Yoast SEO, Rank Math, All in One SEO and SEOPress metaboxes (including the SEO score panel) now render and save inside the BrikPanel product editor, with all of their features available from the simplified screen
* New: Custom BrikPanel-styled top admin bar that replaces the default WordPress toolbar across the entire admin (not only the dashboard) with a larger, e-commerce-focused notification bell and quick links — enabled by default and toggleable from settings
* New: Sold downloadable products column on the order edit page — see how many times each download has been redeemed by the customer, like the legacy panel used to show
* New: BrikMarket marketplace analytics block on the dashboard — when BrikMarket is active, marketplace orders are excluded from the storefront conversion rate and a dedicated section shows orders per marketplace, share by marketplace, and top categories from marketplace orders
* New: Compatibility with major subscription / membership plugins — WooCommerce Subscriptions, Subscriptions for WooCommerce (WP Swings), MemberPress, Paid Memberships Pro, WooCommerce Memberships, YITH WooCommerce Subscription, SUMO Subscriptions, WebToffee Subscriptions for WooCommerce and Restrict Content Pro
* New: Advanced filtering and segmentation for customers and orders — combine spend range, product, location, date and more to build saved segments
* New: Customer analytics suite — Cohort retention, Customer Lifetime Value (LTV) and RFM segmentation, all calculated from your store data and visualized in the dashboard
* New: Developer hooks & filters system — `brikpanel_after_product_save` action, `brikpanel_product_editor_boxes` filter and many more, with a built-in developer documentation popup in settings (one-click copy buttons for every snippet)
* New: Brand field in the refactored product editor — the WooCommerce `product_brand` taxonomy is now first-class alongside categories and tags
* New: Admin and Site Enhancements (ASE) custom columns are now respected in the BrikPanel product, order and customer lists
* New: Per-user toggles for any third-party / SEO column in the products list — extra columns added by Yoast, Rank Math, ASE and other plugins can now be hidden from the existing "Columns" dropdown
* Improvement: Hardened performance for low-resource WooCommerce hosting — heavy queries are batched, cached and run through Action Scheduler so the dashboard, customer analytics and bulk editor stay responsive on shared hosting
* Improvement: All JavaScript and jQuery strings audited for translation — every customer-facing message in the JS layer now goes through `wp_localize_script` so translators no longer miss strings hidden in scripts
* Fix: Sidebar menu no longer flickers / disappears on upward scroll — the sticky positioning CSS that fought with the new top bar has been corrected
* Fix: Variation tab no longer loses unsaved state when navigating back — the editor now restores the in-progress variation form without needing to close and reopen the product
* Fix: PHP notice raised when the refactored product editor module was disabled in settings is now resolved
* Fix: "Top Marketplace Products" and "Top Categories from Marketplaces" cards now correctly render data for the selected date range (last 30 days and custom ranges)
* Fix: Removed the redundant "Storefront metrics shown below exclude marketplace orders…" helper notice now that marketplace data has its own dedicated section

= 2.2.1 (2026-04-24) =
* Improvement: "Force native login submission" is now enabled by default so custom authentication plugins (2FA, SSO, or captcha layers) keep working on a fresh install without extra configuration. Existing sites keep their current setting
* Fix: Newly created categories in the simplified product editor now reflect instantly in the checklist and parent dropdown with correct hierarchy, depth indentation, and alphabetical ordering — previously the new entry was appended flat at the end and missed the depth class, and the first category on a product with none at all was silently dropped

= 2.2.0 (2026-04-20) =
* Improvement: New "Force native login submission" toggle under WooCommerce → Settings → BrikPanel → Login Page for custom authentication plugins that aren't auto-detected, plus a `brikpanel_disable_ajax_login` filter hook for developers. When any of these conditions trigger, the AJAX login endpoint is no longer registered at all, reducing the attack surface

= 2.1.6 (2026-04-20) =
* New: "Private" status filter on the product list — quickly isolate products that are published privately alongside the existing All / Published / Draft / Trash tabs
* New: Hover popover for the Category column in the product list — the main category stays inline and a "+N" badge reveals every remaining category on hover, so products assigned to multiple categories no longer hide their taxonomy
* New: Visual / HTML toggle on both the short description and full description editors in the simplified product editor — paste raw HTML without losing formatting, switch back to the rich-text view at any time
* Improvement: ACF (Advanced Custom Fields) and other third-party metabox compatibility hardened — ACF field groups targeting the `product` post type now bootstrap, render, and save correctly on the BrikPanel product editor (file, image, gallery, repeater, true/false and text fields all tested). The `_acf_nonce` / `_acf_post_id` payload is emitted so save round-trips validate. Applies to both simple and variable products
* Improvement: "Additional fields" / third-party metabox card redesigned — inputs no longer overflow the right edge of the card, JavaScript-driven fields (ACF, custom pickers) receive their init payload, and text/number inputs are now fully editable across every registered metabox
* Improvement: Category list rows on the categories page are now more compact — reduced vertical padding and tighter line-height so more categories fit on screen without scrolling
* Improvement: Downloadable product file URLs are now editable in place — the file input accepts direct edits and the media library browse button replaces the existing file instead of requiring a delete-and-reupload cycle
* Improvement: Custom login page is now fully compatible with 2FA and SSO plugins — when Wordfence Login Security, Two Factor, WP 2FA, miniOrange, Solid Security, Duo, Rublon, or Google Authenticator is active, BrikPanel keeps its modern styling but hands the form submit to the native `wp-login.php` flow so multi-step authentication works exactly as the plugin author intended. Closes a silent 2FA bypass where AJAX login could skip a redirect-based challenge page

= 2.1.5 (2026-04-17) =
* New: Inline stock-status toggle in the product list — flip "In stock / Out of stock" directly from the row without opening a popup, for both simple and variable products
* New: "Columns" dropdown above the product list — hide the columns you don't need (SKU, Price, Stock, Category, Status, Image) and the preference is remembered per user
* New: WordPress widgets position setting for the dashboard — display the embedded WP widgets section above or below BrikPanel analytics (handy for shop managers who rely on widget shortcuts)
* New: `brikpanel_dashboard_section_order` filter hook — developers can reorder any dashboard section via a snippet
* New: `brikpanel_products_columns` filter hook — register custom columns in the product list
* Improvement: Login page AJAX falls back to the native WordPress submit flow when the AJAX endpoint is blocked (e.g. WP Hide / security plugins renaming `admin-ajax.php`), so users are no longer stuck on a generic "An error occurred" message
* Improvement: Login page toast notifications are now centered at the top of the screen for better visibility
* Improvement: Admin notice suppression now also runs on the BrikPanel settings tab — third-party marketing notices no longer leak onto the settings page
* Improvement: WooCommerce's generic "Your settings have been saved" banner is replaced with a branded BrikPanel confirmation on the settings tab
* Improvement: Variable-product stock-status changes now propagate to every variation and the WooCommerce meta lookup table, so flipping a variable product off actually makes it unavailable on the storefront

= 2.1.0 (2026-04-16) =
* New: Admin notice suppression — hides third-party plugin notices on BrikPanel pages for a cleaner, distraction-free admin experience (toggleable from settings)
* New: Product tags support in the simplified product editor with autocomplete suggestions
* New: Cost of Goods Sold (COGS) field support when enabled in WooCommerce settings
* Improvement: Enhanced SEO plugin compatibility — Yoast SEO, Rank Math, AIOSEO, and SEOPress metaboxes now load correctly on the BrikPanel product editor
* Improvement: Better admin body class handling for modern product edit and classic navigation modes

= 2.0.7 (2026-04-12) =
* Comprehensive settings have been added to the product editing page.

= 2.0.4 (2026-04-09) =
* Add Digital product support

= 2.0.1 (2026-04-08) =
* Bug fix: The "Live Visitors" section was scrolling to the right

= 2.0.0 (2026-04-08) =
* New: Modern WooCommerce dashboard rebuilt from scratch with real-time sales analytics, conversion funnel, order status donut, and 3D geographic globe
* New: WooCommerce live visitors widget with cart status and current page
* New: Cmd/Ctrl + K lightning-fast order search across ID, name, email, phone, and SKU
* New: Modern WooCommerce order management page with 30-day overview bar and inline status change
* New: WooCommerce product list plugin with AJAX pagination, live search, and one-click publish toggle
* New: Quick edit sidebar for inline product editing without leaving the list
* New: WooCommerce bulk editor with full variation support — bulk edit variation prices, bulk update variation stock, percentage and fixed-amount updates, by category or selected products
* New: WooCommerce variation price editor modal with attribute filtering
* New: Simplified WooCommerce product editor with drag-and-drop image upload, searchable category picker, live SEO preview, and auto-generated variations
* New: WooCommerce variation gallery — separate image gallery per variation
* New: WooCommerce categories page with drag-and-drop parent/child nesting
* New: Best-in-class free WooCommerce coupon manager with slide-over panel and one-click duplicate
* New: Custom WP login page (WordPress login customizer) with AJAX submission
* New: Sound notifications and confetti celebrations on new completed orders
* New: Welcome / onboarding modal for first-run experience
* New: WooCommerce sales by country and city with interactive 3D globe
* New: WooCommerce conversion tracking with full visitor → cart → checkout → order funnel
* New: Two custom order statuses — Return Draft and Change
* New: Optional simplified admin mode that hides the full WordPress menu for non-technical clients
* Improvement: Full HPOS (High-Performance Order Storage) compatibility with dual code paths on every order query
* Improvement: All AJAX endpoints hardened with nonce + capability checks
* Improvement: IP addresses now SHA-256 hashed before storage for privacy
* Improvement: Admin users excluded from all analytics to keep numbers clean
* Improvement: Tested up to WordPress 6.9 and WooCommerce 9.x

= 1.5.0 (2026-03-01) =
* Improvement: Simplified licensing — all features now completely free

= 1.4.1 (2026-02-15) =
* Bug fix: Yesterday date range calculation corrected in dashboard widgets

= 1.3.5 (2026-01-20) =
* Bug fix: Order conversion rate calculation accuracy improved

= 1.3.4 (2026-01-10) =
* New feature: Added new dashboard widgets for enhanced store insights

= 1.3.3 (2025-12-15) =
* Bug fix: Order count display corrected for filtered views

= 1.3.2 (2025-12-01) =
* Bug fix: Resolved Slider Revolution CSS color conflict

= 1.2.9 (2025-11-15) =
* Bug fix: Resolved compatibility issues on stores without HPOS enabled

= 1.2.6 (2025-11-01) =
* Bug fix: Product category addition issue resolved

= 1.2.3 (2025-10-15) =
* Improvement: Full translation support added with .pot file

= 1.2.2 (2025-10-01) =
* Bug fix: Admin Menu Editor compatibility restored

= 1.2.0 (2025-09-15) =
* Improvement: WooCommerce 9.4 compatibility
* Improvement: Redesigned UI with enhanced navigation
* Bug fix: Various minor fixes
