=== MevvLegal ===
Contributors: mevvsoft
Tags: gdpr, cookie consent, cookie banner, privacy policy, kvkk
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.10.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Cookie consent and legal page generation — in one product. The banner and the cookie policy are fed from the same category list.

== Description ==

MevvLegal does two jobs in one place, because the two are really a single job: legal compliance.

A cookie banner has to link to a cookie policy, and the categories in the
banner have to be the same as the ones written in the policy. Splitting these
two jobs between two plugins that know nothing about each other is the reason
a banner that says "we use analytics cookies" ends up standing next to a
policy that never mentions them.

**Cookie consent**

* Four categories: necessary (cannot be switched off), preferences, statistics, marketing.
* "Reject" and "Accept" are equally visible — a design that makes rejection
  harder invalidates consent under KVKK (Turkey's Personal Data Protection
  Law) just as it does under GDPR.
* Scripts belonging to a category DO NOT RUN before consent is given. Scripts
  are held with `type="text/plain" data-mevv-kategori="…"`, and when consent
  arrives the node is rebuilt and released. A version that only shows a banner
  and loads everything is compliance theatre.
* The consent record stays in the visitor's browser; no record identifying
  anyone is created on the server.
* When the policy text or the category list changes, consent is asked again.
* Compatible with full-page caching: the server prints the same HTML to every
  visitor, and the browser makes the decision.

**Front-end audit — you do not have to write rules**

* Your home page is fetched as a logged-out visitor would fetch it, and which
  scripts are being held right now and which run without consent are counted.
  Three numbers are kept apart: held, released but first party, and released
  and THIRD PARTY. The last one is the real risk; the promise of the product
  is that this number is zero.
* "Half-finished" tags — the address has been moved but no category is left —
  are shown as a separate warning. Such a tag looks as if it is being held,
  but the browser runs it — a silent loss of compliance.
* For recognised trackers (Google, Meta, Hotjar, Clarity, TikTok, LinkedIn,
  Yandex, Intercom, Crisp and others) a hold rule is SUGGESTED.
  No suggestion activates by itself: holding a script that has been recognised
  wrongly breaks the site silently, and the decision is yours. Removing a rule
  is open under all circumstances and requires no license.
* The cookie and storage names that really appear in the visitor's browser are
  measured by low-rate sampling and listed as an inventory suggestion.
  **Only the NAME is collected; the cookie value is not read, not sent, not stored.**
  The cookies that are found enter the inventory only when you approve them.

**Service library — 121 third-party services**

* Every record carries the provider, the recognition pattern (address fragment
  and/or cookie name prefix), known cookie names, cookie LIFETIMES, the privacy
  policy address and, where there is one, the Google Consent Mode signal.
  Scope: analytics, ad networks, live support, email marketing, embedded
  content, bot protection, WordPress's and WooCommerce's own cookies.
* **Tools specific to the Turkish market are in the list:** iyzico, PayTR,
  Param, Sipay, Craftgate, Shopier, Papara, BKM Express, Masterpass; Insider,
  Related Digital (Euromessage), Netmera, Segmentify, D·engage, Desk360.
* **An unknown field is not made up.** If we do not know a cookie's lifetime, a
  provider's legal entity or its privacy policy address, the field stays empty
  and the screen marks that record "verify these fields". A wrong cookie
  lifetime is a wrong declaration in a compliance document; a missing
  declaration is a gap, a wrong declaration is a claim.
* **Payment providers and bot protections are recognised by name but are NOT HELD.**
  They are in the necessary category; because the library recognises them they
  leave the "unknown third party" box, but no hold rule is suggested — holding
  a payment script silently stops the checkout.
* Seeing the library and writing the rows by hand is free; writing the cookies
  it knows into the inventory with one click is Pro (the `envanter-duzenle` gate).
* The library sits in a data file (`includes/veri/servisler.php`) and can be
  extended with the `mevvlegal_servisler` filter without waiting for a release.

**Google Consent Mode v2 — an option, not the default**

* The default behaviour has not changed: no third-party script, Google tags
  included, runs until consent arrives, and not a single request goes to
  Google. Consent Mode is an OPTION that changes this, and it ships switched off.
* When you switch it on, `gtag('consent','default',…)` is printed with all four
  signals **denied**, BEFORE every gtag tag on the page; when the visitor
  decides, `gtag('consent','update',…)` is sent. The signals: `ad_storage`,
  `analytics_storage`, `ad_user_data`, `ad_personalization`.
* Mapping: statistics → `analytics_storage`; marketing → `ad_storage`,
  `ad_user_data`, `ad_personalization`. The preferences and necessary
  categories have no counterpart.
* `wait_for_update` 500 ms, `ads_data_redaction` on, `url_passthrough`
  OFF — carrying a rejected click identifier into the site's own addresses
  would be getting around the rejection by a technical route.
* **Honest limit:** while this option is on, the Google tag DOES RUN on the
  page. Even if the visitor says "reject all", a request goes to Google; no
  cookie is written, but the IP address and the page address do go. This is a
  step back from the "no requests at all" position, and the screen says exactly
  this so that you take the decision knowingly. The exemption is granted only
  to Google's carrier tags (gtag.js, gtm.js); Meta Pixel, TikTok and the others
  continue to be held.

**Consent analytics**

* Acceptance rate (full acceptance / partial / full rejection), category
  breakdown, comparison of policy versions and a day-by-day trend. The charts
  are CSS; no external library is loaded.
* The denominator for each category is the number of declarations in which that
  category was really OFFERED; a category opened later is not counted as
  "rejected" in the declarations made before it was opened.
* **Honest limit:** the counters are not unique per person and can be inflated
  by a malicious request. This is not a visitor counter but a record of how
  many consent declarations were taken with which text — the screen writes this
  next to the percentages.

**Banner appearance — six controls**

* Background, text colour, button colour, button text colour, corner radius and
  width. The values are written into a CSS custom property; you do not have to
  edit the theme's stylesheet.
* **The button colour is a SINGLE setting** and is applied to both the "Reject
  all" and the "Accept all" buttons. If the two could be given separate
  colours, the dark pattern that fades out rejection could be produced with one
  click. The real job of this screen is not decoration but closing the hole
  that writing CSS by hand opens.
* The text/background and button/button-text contrast is calculated with the
  WCAG ratio, and a warning is printed if it is below 4.5:1. The warning does
  not block saving.

**Geo rule — the decision is taken in the browser**

* A different consent model depending on the visitor's region: the EU/EEA, the
  United Kingdom and Turkey are always opt-in consent (cannot be changed);
  opt-out for the USA; the option of not showing the banner at all for other
  countries.
* **The region is read from the time zone reported by the visitor's browser.**
  The IP address is not sent anywhere, no geolocation service is asked, and
  nothing is written to the device.
* The server DOES NOT BRANCH by country: the same HTML is printed to every
  visitor and the browser decides which one is shown. A page that branches by
  country on the server would, under full-page caching, be served to everyone
  with the first visitor's country.
* A time zone is not a location: VPNs and travel drop people into the wrong
  bucket. That is why every case that cannot be read and is not recognised
  falls into the MOST PROTECTIVE bucket (opt-in consent).
* **Honest limit:** while the rule is on, third-party scripts run without
  consent being asked for the visitors in the opt-out and free buckets; the
  "third-party scripts running without consent: 0" measurement on the Front-End
  Audit screen is now true only for the EU/Turkey bucket. The screen says so.
  Switching it on is Pro, switching it off is free under all circumstances.

**Multilingual site**

* The banner title, banner text and category labels are registered with WPML's
  and Polylang's string translation; `wpml-config.xml` is in the package.
* The language comes from the ADDRESS. The browser's `Accept-Language` header
  is not looked at — a page that branches on a request header would be served
  to everyone from cache with the first visitor's language.
* The policy version is independent of the language: a visitor who gives
  consent on the Turkish page is not asked again when they move to the English
  page. A consent asked over and over for the same content turns into a consent
  asked until "accept" is pressed.

**Data subject request form (DSAR)**

* The `[mevvlegal_veri_talebi]` shortcode: the visitor can ask for a copy of
  their data or request its deletion (KVKK Art. 11, GDPR Arts. 15–22).
* The export and the deletion are done by **WordPress core** (Tools → Export /
  Erase Personal Data). We did not write our own deletion mechanism: core's
  flow asks every record, including WooCommerce orders, comments and other
  plugins' data.
* The request does nothing until the email verification has been done.
* The answer is the same under all circumstances — an answer that gave away
  whether the address is registered would turn the form into an account
  verification tool.

**Setup wizard**

* Five steps: organisation details → categories and banner text → front-end
  scan → script hold suggestions → legal pages. Every step can be skipped.
* The wizard adds no new capability; it asks for the existing ones in the right
  order and at every step calls the very same method the relevant screen calls.
* It DOES NOT OVERWRITE an existing page and does not say "you are compliant"
  at the end: compliance depends on all the plugins on your site and on your
  business's real data flow. The place to verify is the Front-End Audit screen.

**Legal pages**

* Privacy Policy / KVKK Disclosure Notice
* Cookie Policy (generated from the cookie categories)
* Terms of Use
* Distance Sales Agreement
* Return and Exchange Terms (Right of Withdrawal)
* Delivery and Shipping Terms

The templates are written according to Law No. 6698 (KVKK), Law No. 6502 on
Consumer Protection, the Distance Contracts Regulation and Law No. 6563;
optional GDPR sections are added as well.

**English templates — not a translation, separate texts**

Five of the templates have an English version, and these are NOT a translation
of the Turkish text. They rest on directly applicable EU legislation: GDPR
(2016/679), the ePrivacy Directive (2002/58/EC) and the Consumer Rights
Directive (2011/83/EU). Translating the Turkish text would mean citing the
article numbers of Turkish legislation to a visitor reading in English.

**The English version of the Distance Sales Agreement is deliberately not
produced.** The Turkish text is a specific contract document required by the
Distance Contracts Regulation; there is no such mandatory document on the EU
side. The corresponding pre-contractual information obligation is met in the
order flow and in the other English templates.

In the English texts, the places where we cannot know the right answer are left
EMPTY and appear marked in square brackets on the page: applicable law,
competent court, EU representative (GDPR Art. 27), data protection officer,
recipient countries, retention periods, who bears the cost of return shipping,
the countries delivered to and the dispute resolution body. A clause filled in
by guesswork is worse than a clause left empty.

Organisation details (trade name, address, MERSIS, tax office, telephone,
email) are filled in from one place and printed into all the templates.

The generated page is a normal WordPress page: it can be edited afterwards and
stays in place even if the plugin is removed. No lock is produced.

**Text change notice.** Which template version a page was generated with is
recorded. When a plugin update changes the template text, the admin panel tells
you the page is standing with the old text and suggests regenerating it. Your
texts are not updated by themselves: you may have edited the page by hand, and
deleting those edits without warning would be worse than printing a warning.
The same warning is printed when the cookie policy has drifted from the
category list. The warning can be dismissed but comes back when the shape of
the problem changes.

**Accessibility statement.** The seventh template: a statement of the site's
accessibility status. In the EU it is mandatory for public sector bodies under
Article 7 of Directive (EU) 2016/2102, and voluntary in the private sector.
**We DO NOT FILL IN the conformity level:** the level, the evaluation method,
the inaccessible content and the body to apply to are left empty in square
brackets and appear marked on the page. Conformity is the result of a
measurement; writing "this site is accessible" on the page of an organisation
that has never measured anything would be letting a disabled user into the site
trusting that sentence.

**Cookie settings link in the footer — by itself**

* After the visitor has closed the banner once, they must be able to change
  their decision: withdrawing consent has to be as easy as giving it (GDPR
  Art. 7(3)), and a consent that cannot be withdrawn is invalid at the moment
  it is given as well.
* The link is added to the footer by itself. If you have already placed the
  `[mevvlegal_cerez_ayarlari]` shortcode on a page, in a widget or in a menu, a
  second button is not printed; if there is an opener you wrote into your theme
  by hand, the one added by itself is removed.
* It can be switched off. When you switch it off, the screen writes what is lost.
* The Front-End Audit also MEASURES it: is there really a cookie settings link
  on your home page. It is not enough for the setting to say "on" — your theme
  may not be calling `wp_footer`.
* Legal pages that have been generated but cannot be reached from any menu,
  setting or link are also reported. A privacy policy that cannot be reached
  from anywhere is the same thing as a policy that does not exist.

**Records: processing inventory and data breach record**

* **Personal data processing inventory** (KVKK Art. 16 / GDPR Art. 30). It is
  not shown to the visitor, it is asked for in an audit; it is the basis of your
  VERBIS registration. Nine fields: activity, data subject group, data
  categories, purpose, legal basis, retention period, recipients, transfer
  abroad, technical and administrative measures.
* **The legal basis and the retention period are not filled in.** The right
  answer depends on your activity; if we wrote a default basis, a guess of ours
  would go into the audit as your declaration. A field you leave empty stays
  empty and the screen lists the gaps line by line. The screen never says "your
  inventory is complete": the only thing it can measure is whether a field is
  empty or not.
* **Draft** rows are derived from your cookie settings (category name, category
  summary and the cookie names in the inventory). None of them is added by
  itself, and when one is added the legal basis, retention, recipients and
  measures come in empty.
* **Data breach record** (GDPR Art. 33(5); KVKK Art. 12(5)). The record covers
  breaches that were not notified as well — the real thing asked in an audit is
  most often the reason for not notifying.
* **We do not calculate the notification obligation.** The screen shows the time
  elapsed since the breach became known and the 72-hour threshold; it does not
  say "you must notify" or "there is no need". Whether the obligation has arisen
  depends on whether the breach creates a risk to people's rights and freedoms,
  a legal assessment, and the data a plugin has is not enough for it.
* No person's identity is kept in the records: the number of people affected and
  the data types are written, not who they are.

== Installation ==

1. Install and activate the plugin. The cookie banner works from the first
   moment; third-party scripts without consent are held even before you
   configure anything.
2. Open **MevvLegal → Setup Wizard** in the admin panel. Five steps:
   organisation details, cookie categories and banner text, front-end scan,
   hold suggestions for recognised trackers, generation of the legal pages.
3. Scan your home page from the **MevvLegal → Front-End Audit** screen. The
   promise of the product is that the "third-party scripts running without
   consent: 0" line is zero; the measurement is made here.
4. Generate the legal pages and **review them against your own activity before
   publishing.** The templates are not legal advice.

For third-party code you have pasted into the theme by hand:

    <script type="text/plain" data-mevv-kategori="istatistik"> … </script>

Server requirement: WordPress 6.0+, PHP 8.1+. No external library is loaded, no
request is sent to an external server.

== External services ==

MevvLegal does not send your content, your visitors' data or any identifier to
a third-party service. It has no telemetry and no licence check in the free
edition.

**Your own site** — the Front-End Audit screen fetches your own home page so
it can count what a logged-out visitor actually receives: which scripts are
being held, which are running without consent, and which of those are
third-party. This is the only network request the plugin makes.
Data sent: the public URL of your own home page, with a `mevv-tarama`
cache-busting parameter. No cookies are sent, no logged-in session is used,
no site identifier and no visitor data leaves your server.
When: only when you press "Scan" on the Front-End Audit screen, or, if you
have turned scheduled scanning on, when that scheduled run fires. Never on a
visitor request.

The third-party service library shipped in `includes/veri/servisler.php` is
DATA, not a connection: it lists address patterns and privacy policy links so
the plugin can RECOGNISE third-party scripts on your own pages. Nothing is
fetched from those addresses.

== Frequently Asked Questions ==

= If my license expires, does the banner stop? =

No. The cookie banner, script holding, the consent log, consent analytics,
cookie deletion, the footer link and the statutory records you keep all keep
working exactly as before. Only NEW configuration is restricted (generating the
e-commerce templates, editing the cookie inventory, script-to-category mapping,
export). A compliance tool going silent over a payment problem would leave you
legally exposed — under KVKK the administrative fine is imposed on the data
controller, not on the plugin vendor.

= What happens to my data if I delete the plugin? =

Your settings are deleted. **The consent log, the policy text archive, the
processing inventory and the data breach record are KEPT by default:** all four
are documents that the legislation requires to be kept and whose only copy is
here. If you want all of them deleted, you have to choose it explicitly from the
"If the plugin is deleted" card on the Cookie Consent screen; that choice cannot
be undone.

Your generated legal pages stay in place under all circumstances. They are
normal WordPress pages; your privacy policy disappearing when the plugin is
removed would put you in breach of the legislation.

= Does it work with full-page caching? =

Yes. The server prints the same HTML to every visitor; there is no branching on
the server by consent state, country or language, and the browser takes the
decision. No extra settings are needed with LiteSpeed, WP Rocket and similar
caching plugins.

= Do you keep records about the visitor on the server? =

No. The consent record stays in the visitor's own browser. Only a counter that
cannot be connected to anyone is kept on the server: on which day, with which
policy version, how many times which combination of categories was approved. The
IP address, cookie identifier and user information are not recorded.

= How does a visitor withdraw their consent? =

From the "Cookie settings" link in the footer. The link is added by itself by
default; you can also put it wherever you want with the
`[mevvlegal_cerez_ayarlari]` shortcode. The Front-End Audit screen measures
whether the link is really printed on your home page.

= Do the templates replace a lawyer? =

No. No template can know your business's field of activity, your data flows, the
third-party tools you use and your contractual relationships. The texts are a
starting draft; review them before publishing.

= Should you not be filling in the accessibility statement yourselves? =

No, and deliberately. The conformity level is the result of a measurement; a
plugin that does not measure it filling it in would mean publishing an unmeasured
claim as your declaration. A wrong accessibility statement is worse than no
statement at all: a disabled user enters the site trusting that sentence.

= Do you tell me whether I have to notify a data breach? =

No. The screen shows the time elapsed since the breach became known and the
72-hour threshold. Whether the notification obligation has arisen is a legal
assessment and the decision is yours. A screen that said "there is no need" could
leave a breach that should have been notified unnotified, and the fine would be
imposed on you.

== Legal disclaimer ==

The template texts are not legal advice. No template can know your business's
field of activity, your data flows and your contractual relationships. Review
them against your own activity before publishing.

== License ==

The cookie banner and script holding are independent of the license: they keep
working when the license expires. Only new configuration is restricted
(generating the e-commerce templates, editing the cookie inventory,
script-to-category mapping). A compliance tool going silent over a payment
problem leaves the customer legally exposed.

The front-end audit, cookie observation and approving hold rules for recognised
trackers are open in the free version as well. The reason: the audit is where
the "script holding" promise, given for free, is verified — giving the promise
for free and charging for its verification makes the promise unverifiable.
Stopping a third-party script that runs without consent is that promise itself;
detecting the problem and asking for payment to solve it is the worst thing a
compliance tool can sell. What depends on Pro is writing the cookies that are
found into the inventory — inventory editing is already Pro, and that is where
the policy TEXT presented to the visitor is changed. In the free version the
findings are still visible: you always learn what has not been declared.

Consent analytics is free as well: the counters have been collected in the free
version since the first day, and the reason they are collected is to prove
consent. Collecting them and not showing them would make the promise given
unverifiable. Pro's counterpart in this area is the CSV export that turns the
counters and the text archive into a single file that can be carried outside the
organisation.

The banner appearance, multilingual support, the data request form and the setup
wizard are free. The reasons, in order: appearance settings are a guard rail that
closes a compliance hole (the button colour is a single setting and is applied to
both buttons); a banner shown in a language that cannot be read does not meet the
informing side of informed consent at all; the request form is the surface on
which THE VISITOR exercises their statutory right and cannot be tied to the site
owner's subscription status; and the wizard configures capabilities the free
version already has — an unconfigured cookie banner is the very failure this
product exists to prevent.

Switching the geo rule ON is Pro; switching it OFF is free under all
circumstances. The reason is the same as for Consent Mode: the rule adds no
compliance, for some visitors it takes a step back from compliance. A customer
without the option is not left unprotected, on the contrary they are left more
protected.

Switching scheduled scanning ON is Pro; scanning by hand and switching scanning
OFF are free under all circumstances. Scheduled scanning adds no compliance, nor
does it make you take a step back from compliance: it puts a measurement that can
be done by hand onto a calendar. The promise of the free version ("what is being
held right now" can be measured at any moment) stands as it is; what Pro sells is
not the measurement but standing watch over the measurement. The cron run never
asks about the license — a scan that is switched on does not stop silently even
if your license expires.

Switching Google Consent Mode v2 ON is Pro; switching it OFF is free under all
circumstances. The reason: this option adds no compliance, it takes a step back
from compliance — a customer without the option is not left unprotected, on the
contrary they are left more protected. It is a commercial configuration that
compensates the advertising customer's loss of measurement. Its exit, though, can
under no circumstances be tied to payment: after switching it on once it is
always possible to say "this does not suit me, let the request going to Google
stop", and the setting keeps working as it is even if your license expires.

== Developer notes ==

To hold hand-written third-party code:

    <script type="text/plain" data-mevv-kategori="istatistik"> … </script>
    <iframe data-mevv-src="https://…" data-mevv-kategori="pazarlama"></iframe>

To map enqueued scripts from code:

    add_filter( 'mevvlegal_betik_kategorileri', function ( $harita ) {
        $harita['google-analytics'] = 'istatistik';
        return $harita;
    } );

To extend the recognised tracker table (local tools will not be in this list,
and you should not have to wait for a release):

    add_filter( 'mevvlegal_desenler', function ( $desenler ) {
        $desenler['olcum.example/izle.js'] = [ 'Yerel Ölçüm', 'istatistik' ];
        return $desenler;
    } );

To change the Consent Mode carrier list and the category mapping:

    add_filter( 'mevvlegal_consent_mode_tasiyicilari', function ( $liste ) {
        $liste[] = 'googletagmanager.com/gtag/destination';
        return $liste;
    } );

    add_filter( 'mevvlegal_consent_mode_esleme', function ( $esleme ) {
        return $esleme; // category => [ signal, … ]
    } );

Front-end surface:

    window.mevvOnay.izin( 'istatistik' );   // true/false
    window.mevvOnay.ac();                    // open the settings panel
    window.mevvOnay.dinle( function ( onay ) { … } );
    document.addEventListener( 'mevv-onay', function ( e ) { … } );

Cookie settings link in the footer: `[mevvlegal_cerez_ayarlari]`
(It can also be added by itself from the Cookie Consent screen; if you have put
the shortcode somewhere, a second button is not printed.)

Data subject request form: `[mevvlegal_veri_talebi]` (takes an optional
`baslik` attribute)

To add your own tool to the Records screen:

    add_action( 'mevvlegal_kayit_araclari', function () { … } );

The counterpart for the Consent Analytics screen is `mevvlegal_gunluk_araclari`.
Both hooks are empty in the free version; Pro attaches its export buttons there.

The geo rule can be read on the browser side through `window.mevvLegalBolge`:

    window.mevvLegalBolge.bolge;   // 'ab' | 'abd' | 'diger'
    window.mevvLegalBolge.karar(); // 'optin' | 'optout' | 'serbest'

== Changelog ==

= 1.10.1 =
* **The banner's own title and body text are now translatable.** They were
  the default values of a setting and were written into the code as fixed
  Turkish strings, so on an English (or German, or Japanese) site the frame
  around the banner was translated while the banner itself spoke Turkish.
  Source language is English now and the Turkish is a maintained translation
  like every other locale; the same applies to the provider, lifetime and
  purpose columns of the default cookie inventory. All eighteen locales were
  filled in. The legal wording is a literal rendering — no claim was
  strengthened or weakened. A text you have already saved is untouched.
* The cookie inventory is now sanitised ON INPUT, once, instead of relying on
  each of the three places that print it.
* wordpress.org packaging: `tools/package.sh --wporg` produces a package that
  does not contain the updater at all, and proves it from inside the zip.
  There, WordPress performs the update itself. The mevvsoft.com package is
  unchanged.
* Escaping, `wp_parse_url()`, `wp_delete_file()` and translator-comment
  placement fixes reported by Plugin Check; `Tested up to` raised to 7.1.
* readme.txt rewritten in English and an "External services" section added.

= 1.10.0 =
* **Service library: 121 third-party services are recognised** (the previous table had 39 address patterns). Every record now carries not just "name + category"; it carries the provider, the recognition pattern (address fragment and/or cookie name prefix), known cookie names, cookie LIFETIMES, the privacy policy address and, where there is one, the Google Consent Mode signal. Scope: analytics, ad networks, live support, email marketing, embedded content, bot protection, WordPress's/WooCommerce's own cookies and **payment, engagement and personalisation tools specific to the Turkish market** (iyzico, PayTR, Param, Sipay, Craftgate, Shopier, Papara, BKM Express, Insider, Related Digital, Netmera, Segmentify, D·engage, Desk360).
* **An unknown field is NOT MADE UP, it is marked.** If we do not know a cookie's lifetime, a provider's legal entity or its privacy policy address, the field stays empty and the screen shows that record as "verify these fields". A wrong cookie lifetime is a wrong declaration in a compliance document; a missing declaration is a gap, a wrong declaration is a claim. 33 of the 121 records are complete, 88 of them have at least one field to be verified, and this is written on the screen.
* **Payment providers and bot protections are now recognised BY NAME but are NOT HELD.** They stand in the "necessary" category; because the library recognises them they left the "unknown third party" box in the Front-End Audit, but no hold rule is suggested — holding a payment script stops the checkout SILENTLY: the page opens, the button does not work.
* **The cookies the library knows can be written into the cookie inventory with one click** (Pro — today's `envanter-duzenle` gate; no new gate was opened). Recognising the service, seeing its details and writing the rows by hand are free.
* The inventory is now in a data file (`includes/veri/servisler.php`), not embedded in the code; it is updated from a single file and can be extended with the `mevvlegal_servisler` filter without waiting for a release.
* New integrity test (`tests/servisler.test.php`, 74 assertions): required fields, valid category, plain-text patterns, conflicting patterns, matching ORDER (specific pattern before general), the "missing information" declaration matching reality exactly, and the locked category not leaking into the hold table.

= 1.9.0 =
* Scheduled scanning (Pro): the scan on the Front-End Audit screen can now be put on a weekly or daily calendar. The same engine runs (there is no second scanner), the result is compared with the previous scan and ONLY new findings are reported: a script/frame running without consent that was not in the previous one, or a cookie name newly seen outside the inventory. A notice in the admin panel and, if wanted, an email summary to the site administrator (addresses, cookie names and numbers only — no visitor data, it is not collected anyway). The first run is the baseline and deliberately reports nothing. The last 10 runs are listed on the screen. Switching it on is Pro; switching it off and scanning by hand are free under all circumstances. The screen states plainly that WP-Cron runs on traffic and that on a site without traffic the scan may be delayed.

= 1.8.1 =
* A store update mechanism was added to the free version. The plugin was not on WordPress.org and had no way of learning that a new version existed; the response is signed with Ed25519 and pinned to mevvsoft.com.

= 1.8.0 =
* The interface was translated into ten languages: Turkish, English, Spanish, German, French, Portuguese, Italian, Dutch, Japanese, Russian, Polish — plus eight country variants (es_MX, pt_PT, de_CH…).
* The source language became English. The reason was measured: in a locale with no gettext translation it falls back to the source string, and with Turkish msgids 194 of 195 locales were seeing a Turkish interface. Turkish did not disappear; it became a maintained translation file.
* Legal terms were written in every language with the wording of the official GDPR text; KVKK and GDPR article numbers were kept exactly as they were.
* Nine strings in `_n()` plural forms had stayed in the source language; when the number was not 1 the interface printed the wrong language. Fixed.
= 1.6.1 =

* **The plugin's source language became English.** All interface strings
  (`msgid`) are now written in English; the Turkish text was moved into the
  `languages/mevvlegal-tr_TR.po` file and continues to appear as it did when the
  site language is Turkish. This is not a behaviour change: no screen, no option
  key, no shortcode and no class name changed. The reason is the layout
  WordPress.org expects — source language English, other languages translation
  files — and opening the translation path to languages other than Turkish.
* `languages/mevvlegal.pot` was regenerated with the new English strings;
  `mevvlegal-tr_TR.po` / `.mo` were added to the package.

= 1.6.0 =

* **The cookie settings link is added to the footer by itself.** Until now, on a
  site that had not placed the `[mevvlegal_cerez_ayarlari]` shortcode by hand,
  a visitor who closed the banner had no way left of changing their decision.
  This was not a missing convenience but a compliance gap: withdrawing consent
  has to be as easy as giving it (GDPR Art. 7(3)) and a consent that cannot be
  withdrawn is invalid at the moment it is given as well. If you have already
  placed the shortcode, a second button is not printed; if there is a
  hand-written opener, the one added by itself is removed. It can be switched
  off, and when it is switched off the screen writes what is lost.
* **The Front-End Audit now MEASURES the link as well.** It is not enough for
  the setting to say "on": the theme may not be calling `wp_footer`. The scan
  reports whether it really found a cookie settings opener on your home page.
* **Unlinked legal page warning.** A policy page that has been generated but
  cannot be reached from any menu, from the WordPress privacy setting, from the
  banner or from the footer is now reported. KVKK Art. 10 does not ask for the
  text to exist but for it to be presented to the data subject.
* **Accessibility statement template** (Turkish and English). WE do not fill in
  the conformity level, the evaluation method, the inaccessible content and the
  body to apply to; they are left empty in square brackets and appear marked on
  the page. Conformity is the result of a measurement, and a wrong accessibility
  statement is worse than no statement at all.
* **Records screen: the personal data processing inventory** (KVKK Art. 16 /
  GDPR Art. 30) **and the data breach record** (GDPR Art. 33(5)). Both are
  internal documents that are not shown to the visitor and are asked for in an
  audit. The legal basis and the retention period are not filled in — a field
  left empty stays empty and the screen lists the gaps. The rows derived from
  the cookie settings are drafts; they do not enter the inventory without your
  approval. The notification obligation is NOT CALCULATED: how much is left of
  the 72-hour threshold is shown, the decision is yours.
* **`uninstall.php`: settings are deleted, statutory records are KEPT.** The
  consent log, the policy text archive, the processing inventory and the breach
  record are preserved by default; all of them are deleted only if that is
  chosen explicitly from the Cookie Consent screen. Generated legal pages and
  template stamps are never deleted under any circumstances. On multisite
  installations the sites are walked one by one.
* **Translation infrastructure:** `languages/mevvlegal.pot` is in the package,
  the translation is loaded on `init`. A static check guarantees that no `__()`
  call is left with a missing or misspelled text domain — such a call runs,
  returns the right text, and simply is not translated.
* All the new items are FREE. The reason is the list's own rule: what ADDS
  compliance is free, what makes you take a step back from compliance (Consent
  Mode, the geo rule) is Pro to switch on. In this release there is not a single
  item that takes a step back. Pro's counterpart is the CSV export that turns
  the records into a single file that can be carried outside the organisation.

= 1.5.0 =

* Admin bar: single-line navigation between all of MevvLegal's screens.
  Identical to the MevvBlocks panel; a check guarantees that the panels of the
  two products do not drift apart.
* Measuring the four items added in 1.4.0 (cookie deletion, WP Consent API
  bridge, GPC, text diff) in production, and their fixes.

= 1.4.0 =

* **When consent is withdrawn, cookies are deleted.** Until now, withdrawal
  held the scripts again but the cookies written on the device stayed; a
  cookie that stays is still read, and withdrawing consent means the
  processing based on that consent stops. The names to be deleted are fed
  from the cookie inventory — a second list is not kept.
* **We say what cannot be deleted.** Cookies marked HttpOnly are by
  definition invisible to JavaScript; cookies written to another domain
  cannot be deleted through your site either. We do not say "we deleted
  them all": the screen writes this limit, and the front end reports what
  cannot be deleted as a separate list. The real solution for third-party
  cookies is still holding them.
* **Your own consent record is not deleted** (`mevv-onay`) — deleting it
  would also delete the "I withdrew" decision. The WP Consent API's records
  are preserved as well.
* **WP Consent API bridge.** If WordPress's official consent API is
  installed, the banner's decision is reported to that API; that way plugins
  we do not recognise also wait until consent arrives. If the API plugin is
  not installed nothing is loaded — we are not writing our own copy.
* **GPC (Global Privacy Control) is listened to.** A visitor with GPC on in
  their browser gets the opt-in consent model whatever the geo rule says.
  The signal never releases a script under any circumstances and is not
  turned into a consent record: a browser setting is not informed consent,
  and the banner continues to be shown — the visitor may also accept. Do Not
  Track is deliberately not listened to — in some browsers it was sent
  without the user choosing it.
* **Legal text currency: we now show the difference.** When the template
  version moved forward, saying "your text is out of date" was not enough;
  "Show the difference" on the Legal Pages screen compares the published
  text with the text that would be regenerated, line by line.
* **A page you edited by hand is protected.** When the page is generated a
  fingerprint of its body is recorded; if you changed it by hand afterwards
  the screen and the warning say so separately and show what regenerating
  would take away. No page is regenerated by itself, and a revision is left
  before overwriting.
* All four of the new items are FREE, and cookie deletion and GPC have no
  setting: both only add compliance and never make you take a step back.

= 1.3.0 =
* Banner appearance: six controls for background, text colour, button colour,
  button text, corner radius and width. The values are written into a CSS
  custom property. The button colour is a SINGLE setting and is applied to both
  buttons; the contrast is calculated with the WCAG ratio and warned about
  below 4.5:1.
* Text change notice: the cookie policy drifting from the category list and the
  template text being updated are reported everywhere in the admin panel. The
  templates now carry a version stamp; which version a page was generated with
  is recorded. "Unknown" and "out of date" are kept apart.
* Banner multilingual: the banner text and the category labels are registered
  with WPML/Polylang string translation, `wpml-config.xml` is in the package.
  The language comes from the address; the browser header is not looked at. The
  policy version is independent of the language.
* Geo rule: EU/EEA/UK/Turkey opt-in consent (cannot be changed), opt-out for
  the USA, the option of not showing the banner at all for other countries. The
  region is read from the browser's time zone; the IP is not sent anywhere and
  the server does not branch by country. Every unknown case falls into the most
  protective bucket. Switching it on is Pro, switching it off is unconditionally
  free.
* Data subject request form: `[mevvlegal_veri_talebi]`. It hands the job over to
  WordPress core's privacy flow; no deletion mechanism of our own was written.
  The answer is the same under all circumstances.
* English legal templates (privacy, cookie, terms of use, right of withdrawal,
  delivery). Not a translation, separate texts resting on EU legislation. The
  English version of the Distance Sales Agreement is deliberately not produced.
  The sections that cannot be known for certain are left empty and appear marked
  on the page.
* Setup wizard: five steps, each one calling the method the existing screen
  calls. It does not overwrite an existing page and does not say "you are
  compliant".

= 1.2.0 =
* Google Consent Mode v2 — as an OPTION, off by default. When it is on, all
  four `default` signals are printed in the denied state before every gtag
  tag on the page; when consent arrives `update` is sent. The exemption is
  granted only to Google's carrier tags. When it is on, the Google tag runs
  on the page and a request goes to Google for a rejecting visitor too; this
  is written on the admin screen without being softened. Switching it on is
  Pro, switching it off is unconditionally free.
* Consent Analytics screen: acceptance rate, category breakdown, policy version
  comparison and a day-by-day trend. The charts are CSS; no external library.
  That the counters are not unique per person is written on the screen.

= 1.1.0 =
* Front-End Audit screen: the home page is fetched and which scripts are being
  held right now is counted. Held, first-party and third-party are counted
  separately; "half-finished" tags are shown as a warning.
* Hold rule suggestion for recognised third-party trackers. The suggestion does
  not activate by itself; removing a rule is open under all circumstances.
* Cookie observation: the cookie and storage NAMES that appear in the visitor's
  browser are measured by low-rate sampling and listed as an inventory
  suggestion. The cookie value is not read, not sent, not stored.

= 1.0.0 =
* First release.
