=== WP CSS Merge ===
Contributors: digitalapps
Tags: css, performance, optimization, cache
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.0.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Safely combines compatible local stylesheets into cached bundles while preserving WordPress dependency order and automatic fallbacks.

== Description ==

WP CSS Merge reduces compatible frontend stylesheet requests by combining local CSS files into cached bundles.

Version 2 uses a safety-first bundle engine:

* Uses WordPress's resolved print order, including late dependency changes and already printed styles.
* Creates different bundles for different style sets instead of sharing one global file.
* Keeps external, inline, conditional, RTL, unsupported, and excluded styles unchanged. Bypasses bundling when other plugins filter stylesheet tags or URLs, preserving integrity hashes, CDN rewrites, and per-file attributes.
* Rebases relative image and font URLs to their original public locations.
* Writes cache files atomically in the current site's uploads directory.
* Automatically serves the original stylesheets whenever bundling is unavailable or unsuccessful.
* Fingerprints the actual source contents, versions, settings, locale, URLs, and printed style combinations. Source changes are detected even when timestamps and file sizes are unchanged.
* Retains published bundles for cached pages across setting changes, updates, theme switches, and deactivation.
* Supports multisite with a separate cache location for each site.

The plugin never downloads remote CSS, contacts external services, or sends telemetry.

Because HTTP/2 and HTTP/3 reduce the cost of multiple requests, combining every stylesheet is not always faster. WP CSS Merge therefore combines only contiguous compatible styles. Source contents are read on each uncached PHP page request to verify freshness; existing bundles avoid repeated CSS transformation and writes.

== Installation ==

1. Install and activate WP CSS Merge.
2. Go to Settings > WP CSS Merge.
3. Enable CSS bundling and save the settings.
4. Visit the frontend to allow bundles to be generated for the style combinations in use.

New source contents and style combinations automatically select new bundle URLs. Published files are retained because page and CDN caches may still reference them. Purge those caches before using Clear generated CSS or uninstalling the plugin. Deactivation preserves generated files for existing cached pages.

== Frequently Asked Questions ==

= What happens on the first request? =

The plugin builds a bundle when its first stylesheet link is being printed. If generation fails, the original stylesheets load unchanged.

= Why are some stylesheets not combined? =

External stylesheets and styles with inline, conditional, RTL, unsupported at-rule, or different media behavior remain separate to protect rendering and cascade order. Handles listed in the exclusion setting also remain separate. If another plugin filters stylesheet links or URLs, bundling is bypassed for that request so every original filter and attribute is preserved.

= Can the cache grow indefinitely? =

New bundle writes have a default 100 MB storage budget per site. At the budget, uncached style combinations fall back to original files while existing bundles remain usable. Concurrent writes may briefly exceed the budget. The `wp_css_merge_max_cache_size` filter can change the budget in bytes. Purge page and CDN caches before manually clearing generated CSS to reclaim storage.

= Where are bundles stored? =

Bundles are stored in a `wp-css-merge` directory inside the current site's WordPress uploads directory. Multisite installations receive separate site-specific directories through the normal uploads API.

= Does the plugin collect or transmit data? =

No. WP CSS Merge performs local filesystem and stylesheet processing only. It does not use external services, telemetry, or tracking.

= How do I find a stylesheet handle to exclude? =

Stylesheet handles are the first argument passed to `wp_enqueue_style()`. A theme or plugin developer can provide the relevant handle when troubleshooting compatibility.

== Screenshots ==

1. Configure safe CSS bundling, conservative minification, handle exclusions, and generated cache controls.
2. The plugin active on the Plugins screen with its direct Settings action and release metadata.

== Upgrade Notice ==

= 2.0.2 =

Fixes filtered styles, late print order, cache retention, and same-timestamp CSS updates.

= 2.0.1 =

Keeps WordPress-inlineable styles separate so their dependent stylesheets always render correctly.

= 2.0.0 =

The aggregation engine and settings screen have been rebuilt. Existing activation choices are preserved, but old global cache files are no longer used.

== Changelog ==

= 2.0.2 =

* Built bundles from WordPress's actual print list only when their first link is emitted.
* Preserved third-party stylesheet filters, integrity hashes, CDN rewrites, and custom attributes.
* Fingerprinted the exact CSS source bytes to detect changes with unchanged timestamps and sizes.
* Retained published bundle URLs across automatic changes and deactivation, with a storage budget and explicit clearing.
* Added real WordPress loader and filesystem regressions and made HTTP tests preserve site options.
* Updated development dependencies and clarified cache management and compatibility.

= 2.0.1 =

* Kept styles with WordPress inline-path metadata outside generated bundles.
* Added a WordPress 7 wp-env regression test for inline-style boundaries and automatic fallback.

= 2.0.0 =

* Replaced the single global CSS file with context-specific, fingerprinted bundles.
* Added automatic fallback to original WordPress styles on every generation or validation failure.
* Preserved dependency order, media grouping, and unsupported style behavior.
* Added safe same-site path resolution and relative asset URL rebasing.
* Added atomic cache writes, stale cache cleanup, per-site multisite storage, and cache controls.
* Replaced the AJAX toggle and unrelated promotion with accessible native WordPress settings.
* Added exclusions, conservative minification, lifecycle cleanup, and current compatibility metadata.

= 1.0.5 =

* Improved path compatibility across operating systems.

= 1.0.0 =

* Initial release.
