=== MevvBlocks ===
Contributors: mevvsoft
Tags: blocks, gutenberg, page builder, responsive, layout
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.27.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A page builder inside the block editor: from header to footer, with per-device values.

== Description ==

WordPress's block editor is fast and native — but it has one gap: **you
cannot give a style value a separate answer for desktop, tablet and
mobile.** If you want a section to have wide spacing on desktop and narrow
spacing on mobile, core cannot express it. This is the most common reason
people turn to page builder plugins.

MevvBlocks fills exactly that gap. It gives you container, heading, text,
button, image, separator and testimonial blocks; every measurement value can
have a desktop, tablet and mobile counterpart.

= Why this is not a separate page builder =

You do not need to learn a new editor. These are ordinary blocks: the same
editor, the same shortcuts, the same patterns. Your data sits in
`post_content` as standard block markup — not in a custom table. Even if you
remove the plugin, your content stays readable and portable.

= Coming from Elementor =

[MevvBridge](https://mevvsoft.com/mevvbridge) converts your pages into these
blocks. The measured result: after conversion the home page of a real
WooCommerce store rendered with 99.8% visual similarity on desktop and 99.9%
on mobile, and the page height stayed pixel for pixel the same.

= What happens if the license expires =

Your site keeps working. This is not a promise but an architectural rule: no
file on the render path asks about license status, and a test checks this on
every release. What you lose when the license expires is the Pro panels in
the editor; your published pages keep rendering exactly as they were, along
with their saved tablet/mobile values.

= In the free version =

* 87 blocks — 110 together with 23 store blocks when WooCommerce is installed
* Content catalog: toggle, nested tabs, pie chart, playlist (audio/video with subtitles and posters), hand-picked social feed, tooltip, newsletter form, SVG animation with a still frame for reduced motion
* Block styles: gradient overlay, grayscale/blur until hover, circle and rounded masks, lift/zoom/tilt on hover — all off under reduced motion
* Dynamic text from a custom field, read through Advanced Custom Fields when it is active
* Theme templates: header, footer, single, archive, search, 404
* Login and registration forms (they work with JavaScript turned off too)
* Conditional visibility: a session, role, device, date and page condition on every block
* Mini cart — can be embedded in the header template (WooCommerce)
* Post/product grid and loop builder (draw the card with your own blocks)
* Form engine: sixteen field types, server-side validation, submission storage
* Navigation menu, search form, popups
* Ready-made template library: 56 sections and 11 full pages — 64 sections, 12 pages with the product showcase templates when WooCommerce is installed; plus block presets
* Accessibility auditor (an audit, not an overlay)
* Content and structure editing
* Flex/grid layout, direction, column count, minimum height
* Rendering of every saved responsive value

= In Pro =

* Editing values with desktop / tablet / mobile tabs
* Per-block custom CSS
* Presets and template library
* Content switcher (monthly/yearly panels with any blocks inside)
* Portfolio with a taxonomy filter (filtered in the browser, no outside request)
* Lottie embed from LottieFiles — an outside service, so it asks for consent first and shows a still image until then and under reduced motion; the player library is not bundled

== Installation ==

1. Install and activate the plugin.
2. Add the "Container" block in the block editor.
3. Place the blocks you want inside it.

== External services ==

MevvBlocks makes no request of its own. It has no telemetry and no licence
check in the free edition. One optional feature, and only that feature, talks
to an outside service — with a key you supply yourself.

**AI text assistant (Anthropic or OpenAI, your choice)** — the "write",
"rewrite", "shorten", "image alt text" and "translate" helpers in the block
editor. Nothing is sent until you have entered an API key on the MevvBlocks
settings screen and pressed one of those buttons in the editor. Without a key
the feature is not shown at all, and no request is ever made.
Data sent: the text you selected in the editor (or, for alt text, the image's
file name and the surrounding block text), plus the model name and your API
key in the request header. Your site address, your admin email, your other
content, your visitor data and any statistics are NOT sent.
Where: `https://api.anthropic.com/v1/messages` or
`https://api.openai.com/v1/chat/completions`, whichever provider you selected.
The request goes from your server, not from the browser, so the key never
reaches the page.
When: only on your explicit click in the editor. Never on a visitor request,
never on a schedule.
Anthropic — Terms: https://www.anthropic.com/legal/consumer-terms ·
Privacy: https://www.anthropic.com/legal/privacy
OpenAI — Terms: https://openai.com/policies/terms-of-use ·
Privacy: https://openai.com/policies/privacy-policy

== Frequently Asked Questions ==

= The core core/group block already exists, what is the difference? =

`core/group` is a very good block, but its style attributes have no concept
of screen size. You give a single padding value and it is applied on all
three devices. MevvBlocks keeps three values for every measurement.

= Does my content get locked into the plugin? =

No. The blocks are standard WordPress block markup inside `post_content`.
If you remove the plugin, the block contents remain as plain HTML.

= Does it work together with Elementor? =

Yes, there is no conflict. But there is no reason to use both on the same page.

== Screenshots ==

1. The container block in the block editor. On the right the Layout panel (free)
   and the device tabs panel (Pro): separate values for desktop, tablet and mobile.

== Changelog ==

= 1.27.1 =
* Nested tabs and the content switcher now find their panels through ownership, so a page builder wrapping each panel no longer leaves every panel open.

= 1.27.0 =
* New blocks: Toggle (nestable `<details>` with inner blocks), Nested Tabs with Tab Panels (any blocks inside, keyboard and ARIA tab pattern, unique ids when nested), Pie Chart (values also listed as text, no animation), Playlist (audio/video, subtitles, posters, each track a link without JavaScript), Social Feed (hand-picked posts as cards, no API key), Tooltip (hover, focus and tap; Escape closes), Newsletter (HMAC-signed plain POST, honeypot, rate limit, stored with form submissions, `mevvblocks_newsletter_subscribe` action), SVG Animation (shown as an image; `<picture>` swaps in a still frame under reduced motion).
* Block styles registered through the core Styles panel: gradient overlay, grayscale and blur until hover, circle and rounded masks, lift, zoom and tilt on hover. Hover transforms are disabled under reduced motion.
* Animated Heading: heading tag selectable (h1–h6, p, div, span) and a typing effect; both stop under reduced motion and the first word is always printed.
* Warning block: optional dismiss button; focus moves to the next element when dismissed. Type and title are now editable.
* Timeline: horizontal layout that turns vertical on narrow screens without changing the reading order.
* Table: header cells carry `scope="col"`; empty cells show a dash with a screen-reader label.
* Flip Box: tap, Enter/Space and Escape toggle the back face on touch and keyboard.
* Buttons and action links have a 44 px minimum target size.
* Dynamic custom field: read through `get_field()` when Advanced Custom Fields is active, raw meta otherwise.
* Icon set: 44 more stroked icons (94 in total), still no icon font.
* `docs/BLOK-AYARLARI.md`: generated map of every block's setting keys and the server file that reads them.

= 1.26.5 =
* MevvCore 1.0.5 is embedded: the licence check and the update client are now
  one shared copy instead of one per plugin, and the admin screens live under
  the shared "Mevv" menu as a single MevvBlocks row — every
  `admin.php?page=mevvblocks-*` address is unchanged and every screen is still
  one click away on the section strip.

= 1.26.4 =
* Navigation menu: when the block has no label of its own, the `<nav>` is named
  after the WordPress menu it shows, so three footer menus no longer all announce
  as "Navigation" (axe landmark-unique).

= 1.26.3 =
* Products block: the default (date) order and the content grid's date/title/menu
  orders also carry the ID as a secondary key — imported catalogues share
  publish times to the second, so the same page listed different products after
  every cache rebuild.
* Icon list: an icon-only link now gets an `aria-label` from the icon name (or
  the target host), so screen readers no longer announce an empty link.

= 1.26.2 =
* Products block: the "best selling", "price" and "rating" orders now carry the
  product ID as a secondary sort key. Rows with equal meta values (every product
  with zero sales, for instance) used to fall back to the database's physical
  order, which changes whenever the product query cache is rebuilt, so two
  installs with identical data printed different "best sellers". The primary
  order is unchanged; `tests/siralama.test.php` pins the query shape.

= 1.26.1 =
* wordpress.org packaging: `tools/package.sh --wporg` produces a package that
  does not contain the updater at all — a plugin hosted there is updated by
  WordPress itself. The package proves the absence from inside the zip, and a
  test (`tests/wporg-paket.test.php`) runs the packager and checks it.
* readme.txt rewritten in English (the project's source language; the Turkish
  lives in `languages/` like every other locale) and an "External services"
  section added for the optional AI assistant.
* Plugin Check findings fixed: `wp_strip_all_tags()`, `wp_parse_url()`,
  `wp_delete_file()`, `wp_delete_file_from_directory()` and `WP_Filesystem`
  instead of the raw PHP calls; missing `translators:` comments added;
  escaping in five admin screens.
* `assets/editor-giris.js` renamed to `assets/editor-giris-formu.js`. The
  wordpress.org file check matches core library names as bare substrings and
  read the `iris.js` inside `g-iris.js` as core's `iris.js`.

= 1.26.0 =
* **theme.json bridge.** On an installation using a block theme a double palette appeared: the theme's `theme.json` palette on one side, our `--e-global-color-*` set on the other, and the same color had to be changed in two places. The active theme's palette and font families are now offered to the global style as a SOURCE. The bridge is one-way (nothing is written into the theme's file), **off by default** and it fills only the slots left EMPTY — a manually entered value always wins. Which set of which theme goes to which of our variables is shown as a table on the Global Style screen; the ones that do not match are named too. The variable names were kept EXACTLY as they were: the color references of pages migrated with MevvBridge are not broken. On a theme with no theme.json the feature does not appear at all.
* **Mega panel option for the navigation menu.** The submenu of a top-level item can open as a wide 2–4 column panel instead of a narrow list. It is not a new block but a setting of the existing `mevvsoft/menu` block: the markup, the buttons, the `aria-expanded`/`aria-controls` relationships and the keyboard path stayed exactly the same — mega is only a layout. Below the hamburger breakpoint the panel turns into an accordion (on a phone three columns meant about 100 pixels per column), and in vertical layout it is not shown at all. The accessibility auditor gives a new info finding: it tells you when the panel is on but there is no top-level item with a submenu.
* **Page draft with AI.** The bring your own key principle is the same; the model DOES NOT WRITE MARKUP, it only picks from and orders the 56-section template inventory. The library renders the markup, so the generated page consists by definition only of registered blocks. If the model returns a name that is not in the list, that line is dropped and the user is told which names were dropped. The page is **always saved as a draft**; a publishing path exists neither as a parameter nor as a filter.
* Tests: two new files (`tema-json.test.php`, `ai-sayfa.test.php`) and 19 new assertions on the menu contract.

= 1.25.0 =
* The template library grew: 56 sections and 11 full pages instead of 16 sections and 4 pages; with WooCommerce installed, 64 sections and 12 pages including 8 product/category sections and a store landing page. The new sections spread across the hero, feature, testimonial, FAQ, pricing, call to action, contact, about, pre-footer band and statistics families; the pages add three home page variants, FAQ, campaign, story and thank you pages.
* The product showcase templates are in a separate file and register only when WooCommerce is active — on a store-less installation there is no template left that renders "unrecognized block" in the inserter. The products come from a query (new, featured, on sale, best selling); no category id is written into the template, because the same id in another store matches either nothing or the wrong category.
* The template tests now derive the allow list from the registration code: every module that adds a type to the `mevvblocks_turler` filter is loaded and every block name in the templates is tested against that union. A hand-maintained list went silently stale when a block was renamed. The two cases, with and without WooCommerce, are in two separate test files; in both the accessibility auditor passes with zero findings.
* The template texts were translated into the source language (English) — applying the source language decision of 1.24.0 to the template content. Section names and descriptions are already translatable; body texts stay in the source language because the moment they are inserted they are content the user edits.
* The block count in the readme was matched with the actual registration: it said "thirty two blocks", the count from the registration code is 78 general blocks + 23 WooCommerce blocks = 101. The number was verified not by hand but from the union of the type tables in the block registration chain.

= 1.24.1 =
* A store update mechanism was added to the free version. The plugin was not on WordPress.org and could not learn from anywhere that a new version existed; the response is signed with Ed25519 and pinned to mevvsoft.com.

= 1.24.0 =
* The source language became English; Turkish is now a maintained translation file (`languages/mevvblocks-tr_TR.po`). The reason was measured: gettext falls back to the source string in a locale that has no translation, and with Turkish msgids 194 of 195 locales were seeing a Turkish interface. The Turkish user still sees 100% Turkish.
* `Orta` was a single msgid but was used in two meanings — "center" in alignment, "medium" in image size. It was split apart.
* Eight strings had remained in the source language in the `_n()` plural forms; when the number was not 1 the interface rendered the wrong language. Thirteen singular/plural pairs were fixed.

= 1.23.1 =
* The measurement table on the Web Vitals screen did not fill the card; the scrolling was moved from the table itself to the wrapper.

= 1.23.0 =
* Core Web Vitals screen: LCP, CLS and INP are measured from real visitors' browsers and the 75th percentile is shown over a 28-day window — not a lab run, but the kind of field data Search Console looks at.
* The measurement is library-free (about 1 KB) and the sampling is done in the browser; had the server decided, two different HTML outputs would come out for the same address and the full page cache would break.
* No IP, cookie or identity is taken from the visitor. With an insufficient sample no number is shown.

= 1.22.0 =
* The ready-made templates look right on a fresh installation too: on a site where the palette is not set up the global color variables stayed undefined and icons came out white on a white background. The four system colors are now filled with the source plugin's own defaults.
* `min-width: 0` was added to the container (the source plugin's own rule, missing in ours): while three-column sections dropped to a single column on mobile the column width remained and the page scrolled horizontally.
* The page templates appear in WordPress's own "start with a pattern" screen. We do not open our own modal — a layer that comes up in front of you on every new page is an obstacle.
* Visual auditor: 20 pattern pages, desktop + mobile, 0 findings.

= 1.21.0 =
* The editor canvas layout is no longer APPROXIMATE: padding, margin, direction, gap, alignment, background, corner, shadow, transform and position appear with the front-end values. The CSS is produced by the single style engine on the server — there is no second copy in the editor.
* Measured: the old canvas had 24 layout differences, now 0 differences across 64 properties (tools/onizleme-esitlik.js).

= 1.20.0 =
* A different image per device: another frame can be shown on mobile. The small size of the same image was already automatic; this is a different image. The WebP/AVIF counterparts are given to the mobile source too.
* The admin bar also finds the theme header/footer templates on sites that came over from Elementor.

= 1.19.0 =
* Positioning: absolute and fixed position, horizontal/vertical direction,
  offset and stacking order (z-index) — separate per device.
* z-index can also be given independently of positioning.

= 1.18.0 =
* A MevvBlocks menu in the admin bar on the front end: editing the template
  that renders the page's header and footer, the site palette and refreshing
  the block cache of the page being viewed.
* There is DELIBERATELY no "Edit with MevvBlocks" button: our editor is
  WordPress's own block editor, WordPress already puts "Edit page" there and
  a second copy would be confusing. The menu gives what WordPress does not
  give.

= 1.17.1 =
* The button text was not visible: the background and the text took the same
  color and the button came out as a plain rectangle. The colors are now
  separate and come from variables.
* The back face of the flip box overflowed the box.
* The Images and Custom Code screens were added to the top bar; they were in
  the menu but not in the bar.

= 1.17.0 =
* AI in the editor: writing text, rewriting, shortening, image alt text and
  translation. It works WITH YOUR OWN API KEY — the request goes from your
  site directly to the provider, your text does not reach us, the quota and
  the bill stay with you. Anthropic and OpenAI are supported.
* The key never reaches the browser: the request goes from the server. It
  does not come back from any endpoint either; not even the admin form
  renders the value back.
* The result is not written into the block directly, it comes as a suggestion and you apply it.

= 1.16.0 =
* Editor notes: leaving a note on every block, marking it resolved and
  deleting it. Notes are visible only in the editor; they are not rendered
  anywhere on the page.
* A duplicated block now gets a new id. So the copy does not inherit notes
  and gets its own CSS scope — previously two copies shared the same scope
  and the render layer papered over this on every request.

= 1.15.0 =
* Twenty two new interaction and transform blocks: flip box, call to
  action, animated heading, slides, hotspot, reading progress,
  side panel, contact buttons, price list, logo strip,
  before/after, announcement bar, back to top, reading time, text on a
  path, banner, number box, testimonial carousel, comparison,
  steps, checked list, data bar.
  The block count went from 79 to 101 (78 if WooCommerce is not installed).
* The script of seven blocks is in a SINGLE file and loads only if one of
  those blocks is on the page.
* With reduced motion on, the flip and the marquee stop, and both faces stay
  readable.
* There is DELIBERATELY no Lottie block: it requires an external library of
  over 250 KB and would contradict our reason for rejecting Prism in the code block.

= 1.14.0 =
* Twenty new WooCommerce blocks: product title, images, price,
  add to cart, rating, stock, meta, short description, description, tabs,
  additional information, related products, upsell, cross-sell, cart, checkout,
  my account, order tracking, sorting and result count.
  The block count went from 59 to 79.
* None of them draws its own markup: WooCommerce's own template functions
  and shortcodes are called. The theme overrides those templates and
  plugins hook into those hooks; our own drawing would silently drop
  additions such as shipping, installment and stock notification.
* Cart, checkout, my account and order tracking are visitor-specific: the
  full page cache is turned off and they are never put into the element cache.
* If WooCommerce is not active these blocks register neither on the server nor in the editor.

= 1.13.0 =
* Twelve new content and media blocks: Video, Audio, Gallery, Quote, Notice,
  Spacer, Anchor, Code, Table, FAQ, Timeline, Badge.
  The block count went from 47 to 59.
* Video embeds use the SAME consent path as the map block: if MevvLegal is
  installed it holds the frame back, otherwise the block asks for its own
  consent, and the site owner can turn it off if they want. No second
  consent mechanism was written.
  `youtube-nocookie.com` is used for YouTube.
* The code block does not load an external syntax highlighting library;
  it renders the `language-*` class, whoever wants color can attach their own tool.
* The FAQ uses `<details>`: it opens and closes with JavaScript turned off
  too.

= 1.12.0 =
* Twelve new site and theme blocks: Site Logo, Site Title, Site Tagline,
  Page Title, Archive Title, Archive Description, Breadcrumb, Post
  Info, Previous/Next, Author Box, Comments, Sitemap.
  The block count went from 35 to 47.
* A site block with no value no longer renders its wrapper either: an empty
  widget container left an invisible gap the size of the container's spacing
  and the reason could not be found without looking at the source.
* The breadcrumb builds its own chain; it does not call the theme's or the
  SEO plugin's function (calling a function that does not exist means a fatal error)
  and it does not render JSON-LD (SEO plugins already do).

= 1.11.1 =
* The session condition was not applied in custom code: a code with "logged
  in users only" selected was visible to guests too. The admin setting wrote
  under the name `giris`, the condition engine read under the name `kosul_giris`.

= 1.11.0 =
* Site-wide custom code: HTML, CSS and JavaScript in the header, at the
  start of the body and at the end of the body. For verification tags,
  measurement codes and small style fixes. Position, priority and session condition can be set.
* IT DOES NOT RUN PHP. Putting a PHP runner inside a page builder would turn
  the permission given to the designer into permission to run code on the
  server.
* The capability is `unfiltered_html`: someone who cannot put a raw script in
  a post cannot put one site-wide at all.
* If MevvLegal is installed, the tracker scripts coming out of here are also
  held back until cookie consent is given.

= 1.10.1 =
* Wrapping an image twice in `<picture>` was fixed. WordPress filters every
  `<img>` tag in the content separately, without looking at the `<picture>`
  it sits inside; the protection now relies on a marker that stays on the
  img itself.
* If a plugin that lazy loads with JavaScript is active, the `<picture>`
  wrapping does not kick in. The reason was measured: those plugins change
  the src of the `<img>` and do not touch `<source srcset>`, and because
  `<source>` comes first lazy loading was effectively disabled. File
  generation continues.

= 1.10.0 =
* Transform: translate, scale, rotate (Z and 3D X/Y),
  skew, horizontal/vertical mirroring, transform origin and transform on
  hover — all of them separately for desktop, tablet and mobile.
* Mask: circle, triangle, hexagon, blob, flower, freeform and your own
  image; with size, position and repeat controls.
* The shapes are not a separate file but embedded in the CSS: so that the
  mask does not silently disappear if the path is wrong.

= 1.9.0 =
* Image optimization: a WebP (optionally AVIF) copy of every uploaded image
  is written NEXT TO the original — the original file is not touched.
  On the page the image is served inside a `<picture>`; the address of each
  format sits in the HTML and the browser makes the choice.
* The method of returning a different file on the server according to the
  `Accept` header was DELIBERATELY not used: the same address changing per
  visitor means every cache in between gives the wrong file to the wrong
  person.
* A file that does not shrink is not kept. Small PNGs with few colors most
  of the time grow as WebP; if the gain is below 5% and below 1 KB the
  generated file is deleted and that size is not tried again.
* Batch conversion for the media library, in chunks and resuming where it
  left off; deleting the generated files with one click.
* If a plugin that does the same job (LiteSpeed, ShortPixel, Imagify, Smush,
  EWWW, Optimole, Converter for Media) is active, MevvBlocks steps aside on
  its own and states the reason.

= 1.8.0 =
* Element cache: block output is stored, not regenerated on every request.
  Blocks that vary by visitor, query or parent
  (form, login, registration, mini cart, product grid, loop, search)
  are never stored under any condition — if the timestamped signature of
  the form block froze in the cache, submissions would be silently rejected after a while.
* A "Speed" card in the admin panel: turning the cache on/off and clearing it.
  Saving a post, switching themes and a plugin update refresh the cache on
  their own.

= 1.7.0 =
* Conditional visibility: a session status, user role, device, date range
  and page context condition on every block.
* Login form and registration form: server-side validation, rate limit, honeypot,
  validated redirect. They work with JavaScript turned off too.
* Mini cart (WooCommerce): can be embedded in the header template, the cart
  count is refreshed with WooCommerce's own fragment API.
* Cache honesty: a page carrying a condition that varies by visitor or an
  account form is NOT put into the full page cache. If it were, the HTML
  generated for the first visitor would be served to everyone and hidden
  content would be visible to the wrong person. A date condition does not
  disable the cache, it shortens its lifetime up to the next boundary.

= 1.6.0 =
* Phase 3: price table, countdown, map (OpenStreetMap embed, asking for
  consent), counter, progress bar, team member, star rating,
  social share, table of contents, testimonial carousel pattern.
* A bar across the admin screens — four Mevvsoft products, the same layout.

= 1.4.0 =
* Loop builder: draw the grid's card with your own blocks.

= 1.3.0 =
* Post/product grid and search form.

= 1.2.0 =
* Navigation menu, image box, social icons, copyright block.
* The copyright year is now dynamic: correct on its own on 1 January.

= 1.1.0 =
* Motion effects (entrance animation, sticky position, parallax).
* Template library: fifteen sections, four pages, block presets.

= 1.0.0 =
* First release.
* Seven blocks, server-side render.
* Style generation per device (desktop, tablet, mobile).
* Output parity test with MevvBridge.
