/* ==========================================================================
   Finewerk — Background  (.fw-bg-gradient)
   --------------------------------------------------------------------------
   THE Finewerk background treatment, as one class. Add the CSS class
   `fw-bg-gradient` (Elementor → element → Advanced → CSS Classes, or straight
   in a component's markup) and the element gets BOTH halves of the design:

       1. the Finewerk green gradient, and
       2. the grain/noise texture over it.

   There is no separate grain class. `fw-bg-gradient` alone is the complete
   treatment — no companion class, no markup, no JavaScript.

   Visual stack:
       Finewerk gradient  →  grain texture  →  element content

   OWNERSHIP
   ---------------------------------------------------------------------------
   This file is the canonical implementation and the child theme owns it. It is
   enqueued on `wp_enqueue_scripts` (handle `softro-child-background`) and in
   the Elementor preview iframe, so it is a render-blocking <link> in <head> on
   every page and the treatment is correct on first paint. It must NOT be
   duplicated into Elementor Custom CSS, Customizer → Additional CSS, a
   snippet, or an individual widget stylesheet.

   The finewerk-custom-elements plugin ships a byte-equivalent copy of this
   file so its widgets still render outside this theme; it skips its copy when
   this handle is already enqueued, so the CSS never loads twice.

   SPECIFICITY CONTRACT — read before adding rules elsewhere
   ---------------------------------------------------------------------------
   The gradient below is a single class (0,1,0) so a component can still own
   its own surface by outranking it — deliberately, and by specificity rather
   than by load order:

       - `.finewerk-hero-banner.finewerk-hero-banner` keeps the banner's
         Elementor-configurable gradient (0,2,0 beats this file).
       - `.home3-banner-section .banner-wrapper` keeps the parent theme's
         banner photo (0,2,0 beats this file), and takes only the grain.

   Component stylesheets that merely paint a flat colour UNDER the gradient use
   the `background-color` longhand, never the `background` shorthand, so they
   can never wipe out the gradient image.

   WHY ::after AND NOT A FILTER
   ---------------------------------------------------------------------------
   The grain must never touch the element's children. A `filter:` / `backdrop-
   filter:` on the element itself would propagate to every descendant (text,
   images, buttons, nested containers all get noised). A pseudo-element is a
   sibling layer of the content instead: it is painted between the element's
   own background and its in-flow children, so children are never filtered,
   blended, faded or re-rasterised.

   STACKING — the part that must be exactly right on Elementor Containers
   ---------------------------------------------------------------------------
   Paint order inside one stacking context (CSS 2.1 Appendix E):
       1. the element's own background / borders
       2. descendants with NEGATIVE z-index      ← the grain lives here
       3. in-flow, non-positioned block children  ← .e-con-inner, widgets…
       4-7. floats, inline content, positioned descendants
   So `z-index: -1` is above the background and below ALL real content — but
   ONLY if the element actually forms a stacking context. Otherwise the
   negative layer escapes upward and paints BEHIND the element's background,
   i.e. invisible.

   Elementor's own container rule is:
       .e-con { --z-index: revert;  z-index: var(--z-index); … }
   which resolves to `z-index: auto` and, at specificity (0,1,0), beats any
   zero-specificity `:where()` rule. A Container therefore does NOT form a
   stacking context on its own, and a `z-index:-1` pseudo-element on it is
   invisible.

   The fix is `isolation: isolate`: it forms a stacking context unconditionally
   WITHOUT touching `position` or `z-index`, so Elementor's own Position and
   Z-Index controls keep working untouched. Elementor's stylesheet never uses
   `isolation` (verified: 0 occurrences in frontend.min.css), so nothing can
   collide with it. It additionally scopes `mix-blend-mode` to this element,
   so the grain blends with THIS element's background only and can never
   blend with the page behind a transparent container.

   VISIBILITY — why plain feTurbulence + overlay is invisible
   ---------------------------------------------------------------------------
   `feTurbulence` outputs random values in ALL FOUR channels, alpha included,
   so a raw turbulence tile is only ~50% opaque and washed out. Its luminance
   also clusters tightly around mid-grey — and `mix-blend-mode: overlay` with
   a mid-grey source is the IDENTITY function (overlay(b, 0.5) === b), so the
   majority of pixels produce no change at all. Both are corrected here:
       - feFuncA pins alpha to 1        → a fully opaque tile
       - feFunc{R,G,B} expand contrast  → values span the full 0…1 range, so
                                          overlay genuinely lightens/darkens
       - color-interpolation-filters="sRGB" keeps the contrast predictable
         (the linearRGB default dulls the noise)

   Tunables (set on the element, a wrapper, or in Elementor custom CSS):
       --fw-grain-opacity  grain strength (default 0.22)
       --fw-grain-size     tile size, e.g. "200px" (default 200px)
       --fw-grain-blend    blend mode against the background (default overlay)

   Safety:
       - pointer-events:none → never intercepts clicks, hover, focus or
         Elementor editing.
       - inset:0 → pinned to the element's box; cannot escape or create
         overflow, regardless of the element's `overflow` value.
       - border-radius: inherit → follows the element's ACTUAL radius, so
         rounded containers clip the grain to their own corners.
       - The grain selectors are doubled (.fw-bg-gradient.fw-bg-gradient) so
         they reliably beat Elementor's single-class rules regardless of
         stylesheet order. The gradient itself is deliberately NOT doubled —
         see the specificity contract above.
       - ::after (not ::before) — Elementor's container background overlay IS
         `.e-con::before` (`content: var(--background-overlay)`), so using
         ::after leaves that feature completely intact.
       - One small inlined SVG data-URI, tiled by `background-repeat`: no HTTP
         request, no raster asset, and cost stays flat no matter how large the
         element is or how many elements on the page use the class.

   Author: Chili-House
   ========================================================================== */

.fw-bg-gradient {
	/* Tunables — sensible defaults; adding the class alone is enough. */
	--fw-grain-opacity: 0.22;
	--fw-grain-size: 200px;
	--fw-grain-blend: overlay;

	/* The Finewerk green. The flat colour is the fallback for engines that
	   cannot parse the gradient; the gradient overrides it everywhere else. */
	background: #0F3D3A;
	background: linear-gradient(
		150deg,
		rgba(15, 61, 58, 1) 43%,
		rgba(65, 99, 46, 1) 100%
	);
}

/* Position fallback for elements that are `static` (Elementor Containers and
   widgets are already `position: relative`). :where() keeps specificity at
   zero so an Elementor Position setting (absolute/fixed/sticky) always wins —
   any of those is still a containing block for the pseudo-element. */
:where(.fw-bg-gradient) {
	position: relative;
}

/* Guarantee the stacking context that makes `z-index: -1` mean "above the
   background, below the content". Doubled class so it cannot be lost to
   Elementor's own single-class rules. Does NOT touch position or z-index. */
.fw-bg-gradient.fw-bg-gradient {
	isolation: isolate;
}

.fw-bg-gradient.fw-bg-gradient::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;             /* above the background, below every child      */
	border-radius: inherit;  /* follows the element's ACTUAL radius          */
	pointer-events: none;    /* never intercept clicks / editing            */

	/* Opaque, contrast-expanded, desaturated fractal noise. `stitchTiles`
	   makes the 200×200 tile seamless, so `repeat` covers any element size at
	   any viewport without media queries or per-breakpoint assets. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.2' intercept='-0.6'/%3E%3CfeFuncG type='linear' slope='2.2' intercept='-0.6'/%3E%3CfeFuncB type='linear' slope='2.2' intercept='-0.6'/%3E%3CfeFuncA type='linear' slope='0' intercept='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
	background-repeat: repeat;
	background-size: var(--fw-grain-size) var(--fw-grain-size);

	/* `overlay` lightens and darkens symmetrically, so one neutral tile reads
	   correctly over dark, light, saturated, gradient and photographic
	   backgrounds alike, without tinting them. */
	mix-blend-mode: var(--fw-grain-blend);
	opacity: var(--fw-grain-opacity);
}

/* Optional finer / coarser grain presets. */
.fw-bg-gradient--fine {
	--fw-grain-size: 130px;
}
.fw-bg-gradient--strong {
	--fw-grain-opacity: 0.35;
}

/* A user who prefers reduced transparency likely wants less visual noise
   competing with content — soften rather than remove. */
@media (prefers-reduced-transparency: reduce) {
	.fw-bg-gradient.fw-bg-gradient::after {
		opacity: calc(var(--fw-grain-opacity) * 0.5);
	}
}
