/* ==========================================================================
   Finewerk — Liquid Glass  (.finewerk-liquid-glass)
   --------------------------------------------------------------------------
   Apple-inspired "Liquid Glass" material for ANY Elementor element: add the
   CSS class `finewerk-liquid-glass` (Elementor → Advanced → CSS Classes).
   No special markup is required; the material is painted entirely with the
   element's ::before / ::after pseudo-elements.

   Variations
   ---------------------------------------------------------------------------
   `finewerk-liquid-glass__dynamic` — the SAME material (identical blur,
       refraction, rim, highlights, pseudo-elements), with one addition: the
       plate tint reacts to how dark the page is underneath the element's TOP
       EDGE. Every rule below therefore lists both class names; the variation
       adds no second copy of the material, only the tint plumbing near the
       bottom of this file. Standalone (`finewerk-liquid-glass__dynamic` on its
       own) and combined with the base class both work.

   Progressive-enhancement tiers
   ---------------------------------------------------------------------------
   Tier 1 — SVG backdrop refraction (Chromium):
       JS (finewerk-liquid-glass.js) builds ONE unique SVG displacement filter
       per element (feImage map + feDisplacementMap) and exposes it through the
       per-element custom property `--fw-glass-filter`. Activated only when
       <html> carries `.fw-glass-svg` AND the element carries
       `data-fw-glass-ready` — i.e. only after JS verified real support and
       attached the filter. The backdrop is genuinely displaced (edge lensing).
   Tier 2 — CSS blur fallback (Safari / Firefox / no-JS on modern browsers):
       Pure CSS via @supports — blur + saturation + tint + simulated edge
       refraction (inner rim glow). Works with JavaScript disabled.
   Tier 3 — no-blur fallback (no backdrop-filter at all):
       The base styles below: translucent plate (~30% tint), border, radius,
       highlights, shadows. Content always stays readable.

   Tunables (set on the element, a wrapper, or in Elementor custom CSS):
       --fw-glass-opacity              plate tint alpha (Tier 1/2; Tier 3 ×2.5)
       --fw-glass-tint                 plate tint as "R, G, B" triplet
       --fw-glass-blur                 backdrop blur radius
       --fw-glass-saturation           backdrop saturation boost
       --fw-glass-radius               default corner radius (Elementor's own
                                       border-radius overrides it — pseudos
                                       inherit whatever radius the element has)
       --fw-glass-border-opacity       rim / edge-highlight strength
       --fw-glass-refraction-strength  Tier-1 displacement, px (unitless number)
       --fw-glass-highlight-x/y        specular highlight position (%)
       --fw-glass-highlight-opacity    specular highlight strength (0–1)

   Tunables for the __dynamic variation only:
       --fw-glass-dyn-level            0–1 backdrop darkness (WRITTEN BY JS)
       --fw-glass-dyn-tint             tint the plate moves toward when dark
       --fw-glass-dyn-opacity-min      plate alpha over a light backdrop
       --fw-glass-dyn-opacity-max      plate alpha over a very dark backdrop

   Layering / interaction safety:
       - position:relative + z-index:0 are applied with :where() (zero
         specificity) so any Elementor positioning/z-index wins.
       - ::before (plate) sits at z-index:-1, ::after (rim + specular) at
         z-index:2; both are pointer-events:none, so links, buttons, focus and
         Elementor editing are never blocked. No `overflow` is forced.
       - Pseudo selectors are doubled (.finewerk-liquid-glass.finewerk-…) so
         they reliably beat Elementor's own single-class ::before rules
         (e.g. the .e-con background-overlay) regardless of stylesheet order.

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

.finewerk-liquid-glass,
.finewerk-liquid-glass__dynamic {
	/* Tunables — sensible defaults; adding the class alone is enough. */
	--fw-glass-opacity: 0.12;
	--fw-glass-tint: 255, 255, 255;
	--fw-glass-blur: 16px;
	--fw-glass-saturation: 1.5;
	--fw-glass-radius: 24px;
	--fw-glass-border-opacity: 0.5;
	--fw-glass-refraction-strength: 45;
	--fw-glass-highlight-x: 28%;
	--fw-glass-highlight-y: 18%;
	--fw-glass-highlight-opacity: 0.55;
	/* RADIUS of the circular pointer highlight. The JS refines it per element
	   (~0.75 × the smaller box dimension, clamped 40–190px) so pills get a
	   small light and large cards a proportionate one; this is the static
	   fallback when JS hasn't run. */
	--fw-glass-highlight-size: 110px;

	/* Internal (not part of the public API) */
	--fw-glass-shadow-rgb: 15, 21, 38;        /* outer/inner shadow colour     */
	--fw-glass-inner-shadow-opacity: 0.16;    /* bottom inner shade            */
	--fw-glass-lens-glow: inset 0 0 0 0 rgba(255, 255, 255, 0); /* Tier-2 only */
}

/* Structural defaults — :where() keeps specificity at zero so Elementor's own
   position / z-index / border-radius settings always win. */
:where(.finewerk-liquid-glass, .finewerk-liquid-glass__dynamic) {
	position: relative;
	z-index: 0; /* own stacking context: keeps ::before behind content only   */
	border-radius: var(--fw-glass-radius);
}

/* Smooth pointer-highlight glide (the JS registers the highlight custom
   properties with CSS.registerProperty where available, which makes them
   transitionable). :where() so an Elementor transition setting wins. */
@media (prefers-reduced-motion: no-preference) {
	:where(.finewerk-liquid-glass, .finewerk-liquid-glass__dynamic) {
		transition:
			--fw-glass-highlight-x 0.45s cubic-bezier(0.25, 0.6, 0.3, 1),
			--fw-glass-highlight-y 0.45s cubic-bezier(0.25, 0.6, 0.3, 1);
	}
}

/* --------------------------------------------------------------------------
   Shared pseudo-element geometry
   -------------------------------------------------------------------------- */
.finewerk-liquid-glass.finewerk-liquid-glass::before,
.finewerk-liquid-glass.finewerk-liquid-glass::after,
.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::before,
.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	border-radius: inherit;   /* follows the element's ACTUAL radius          */
	pointer-events: none;     /* never intercept clicks / editing             */
}

/* --------------------------------------------------------------------------
   ::before — the glass plate (tint + depth; Tier 3 baseline)
   Tier 3: no backdrop support → a slightly stronger translucent tint (~30%
   with the default --fw-glass-opacity) keeps the panel visible and readable.
   -------------------------------------------------------------------------- */
.finewerk-liquid-glass.finewerk-liquid-glass::before,
.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::before {
	z-index: -1;
	background: rgba(var(--fw-glass-tint), calc(var(--fw-glass-opacity) * 2.5));
	/* Natural depth below the plate PLUS the bright rim / internal shadows.
	   The rim lives here (not on ::after) so the highlight layer stays a
	   single-purpose gradient that can never disturb the crisp edge ring. */
	box-shadow:
		0 24px 48px -16px rgba(var(--fw-glass-shadow-rgb), 0.30),
		0 6px 14px -6px  rgba(var(--fw-glass-shadow-rgb), 0.16),
		/* 1px translucent rim ring ("glass edge")                            */
		inset 0 0 0 1px rgba(255, 255, 255, calc(var(--fw-glass-border-opacity) * 0.5)),
		/* bright top rim + subtler bottom rim (light bending around edges)   */
		inset 0  1.5px 0.5px -1px rgba(255, 255, 255, calc(var(--fw-glass-border-opacity) * 1.2)),
		inset 0 -1.5px 0.5px -1px rgba(255, 255, 255, calc(var(--fw-glass-border-opacity) * 0.7)),
		/* soft internal sheen (top) and internal shadow (bottom) → curvature */
		inset 0  18px 30px -20px rgba(255, 255, 255, 0.40),
		inset 0 -16px 30px -22px rgba(var(--fw-glass-shadow-rgb), var(--fw-glass-inner-shadow-opacity)),
		/* Tier-2 simulated lens glow (transparent everywhere else)           */
		var(--fw-glass-lens-glow);
}

/* --------------------------------------------------------------------------
   ::after — the moving specular highlight ONLY
   A circle with an explicit radius, so the light reads as a round reflection
   on every aspect ratio. (Percentage radii would stretch with the box — on a
   wide nav bar the old 130%×100% ellipse degenerated into a horizontal
   stripe.) Clipped by border-radius: inherit; centre stays translucent.
   -------------------------------------------------------------------------- */
.finewerk-liquid-glass.finewerk-liquid-glass::after,
.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::after {
	z-index: 2;
	background: radial-gradient(
		circle var(--fw-glass-highlight-size) at var(--fw-glass-highlight-x) var(--fw-glass-highlight-y),
		rgba(255, 255, 255, calc(0.30 * var(--fw-glass-highlight-opacity))) 0%,
		rgba(255, 255, 255, calc(0.15 * var(--fw-glass-highlight-opacity))) 30%,
		rgba(255, 255, 255, calc(0.05 * var(--fw-glass-highlight-opacity))) 55%,
		rgba(255, 255, 255, 0) 72%
	);
	transition: opacity 0.35s ease;
}

/* --------------------------------------------------------------------------
   Tier 2 — CSS blur fallback (pure CSS, no JS required)
   -------------------------------------------------------------------------- */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
	.finewerk-liquid-glass.finewerk-liquid-glass::before,
	.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::before {
		background: rgba(var(--fw-glass-tint), var(--fw-glass-opacity));
		-webkit-backdrop-filter: blur(var(--fw-glass-blur)) saturate(var(--fw-glass-saturation));
		backdrop-filter: blur(var(--fw-glass-blur)) saturate(var(--fw-glass-saturation));
	}

	/* Simulated edge refraction: a soft inner rim glow (appended to the
	   ::before shadow stack via this variable) suggests the lensing Tier 1
	   renders for real. (A visual simulation only — CSS cannot displace
	   backdrop pixels without SVG filter support.) */
	.finewerk-liquid-glass,
	.finewerk-liquid-glass__dynamic {
		--fw-glass-lens-glow: inset 0 0 18px -8px rgba(255, 255, 255, calc(var(--fw-glass-border-opacity) * 0.55));
	}
}

/* --------------------------------------------------------------------------
   Tier 1 — genuine SVG backdrop displacement (Chromium)
   `html.fw-glass-svg` + `data-fw-glass-ready` are both set by the JS only
   after (a) feature-verifying SVG-in-backdrop-filter support and (b) building
   this element's unique filter and storing `url(#…)` in --fw-glass-filter.
   Order matters: blur/saturate FIRST, displacement LAST, so the lensing at
   the edges stays crisp instead of being smeared by the blur.
   -------------------------------------------------------------------------- */
html.fw-glass-svg .finewerk-liquid-glass[data-fw-glass-ready]::before,
html.fw-glass-svg .finewerk-liquid-glass__dynamic[data-fw-glass-ready]::before {
	-webkit-backdrop-filter:
		blur(calc(var(--fw-glass-blur) * 0.55))
		saturate(var(--fw-glass-saturation))
		var(--fw-glass-filter);
	backdrop-filter:
		blur(calc(var(--fw-glass-blur) * 0.55))
		saturate(var(--fw-glass-saturation))
		var(--fw-glass-filter);
}

/* With real refraction active, the simulated rim glow is redundant. */
html.fw-glass-svg .finewerk-liquid-glass[data-fw-glass-ready],
html.fw-glass-svg .finewerk-liquid-glass__dynamic[data-fw-glass-ready] {
	--fw-glass-lens-glow: inset 0 0 0 0 rgba(255, 255, 255, 0);
}

/* NOTE: the highlight layer (::after) deliberately carries NO filter. A CSS
   filter's output is not clipped to the pseudo-element's border box (the
   filter region extends beyond it), so displacing the highlight leaked
   gradient pixels outside the glass and cut a visible band where the
   pre-clipped rounded edge was warped. The gradient is clipped naturally by
   border-radius: inherit instead; the refraction below it (::before backdrop)
   provides the material's distortion. */

/* --------------------------------------------------------------------------
   Dark variant — for glass sitting on light content but wanting a dark smoke
   tint (add BOTH classes: "finewerk-liquid-glass finewerk-liquid-glass--dark")
   -------------------------------------------------------------------------- */
.finewerk-liquid-glass--dark {
	--fw-glass-tint: 18, 22, 30;
	/* A dark tint needs more body than the default 0.12 or light text on it
	   becomes unreadable over bright backdrops. */
	--fw-glass-opacity: 0.4;
	--fw-glass-border-opacity: 0.28;
	--fw-glass-highlight-opacity: 0.35;
	--fw-glass-inner-shadow-opacity: 0.35;
}

/* --------------------------------------------------------------------------
   Dynamic variation — `.finewerk-liquid-glass__dynamic`
   --------------------------------------------------------------------------
   Same material as above (all of it comes from the shared rules); the ONLY
   difference is that the plate tint follows the page underneath the element's
   TOP EDGE. The JS (finewerk-liquid-glass.js) samples several points spread
   across that edge, converts the composited backdrop to perceptual lightness
   (CIE L*) and writes a single continuous number into

       --fw-glass-dyn-level      0 = light backdrop … 1 = very dark backdrop

   which this rule turns into a plate alpha. Because it is one continuous
   interpolation — not a set of states — the glass moves through every shade in
   between: default grey → slightly lighter → medium → bright → near-white.
   The easing between two readings is done in JS (frame-rate independent, ~70ms
   time constant) so it also works in engines without CSS.registerProperty.

   Without JavaScript the level stays 0 and the element renders exactly like a
   plain `.finewerk-liquid-glass`.

   Tune with --fw-glass-dyn-opacity-min / -max (NOT --fw-glass-opacity, which
   this rule computes). The selector is doubled to match the specificity of the
   pseudo-element rules above, so a `.some-parent .some-child` tint override
   cannot silently disable the reaction.
   -------------------------------------------------------------------------- */
.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic {
	/* Written by the JS on every meaningful change (0–1). */
	--fw-glass-dyn-level: 0;
	/* The colour the plate moves toward as the backdrop darkens. */
	--fw-glass-dyn-tint: 255, 255, 255;
	/* Plate alpha at level 0 — matches the base material's default. */
	--fw-glass-dyn-opacity-min: 0.12;
	/* Plate alpha at level 1 — the brightest, most translucent-white state. */
	--fw-glass-dyn-opacity-max: 0.4;

	--fw-glass-tint: var(--fw-glass-dyn-tint);
	--fw-glass-opacity: calc(
		var(--fw-glass-dyn-opacity-min) +
		(var(--fw-glass-dyn-opacity-max) - var(--fw-glass-dyn-opacity-min)) * var(--fw-glass-dyn-level)
	);
}

/* --------------------------------------------------------------------------
   Accessibility preferences
   -------------------------------------------------------------------------- */

/* Higher contrast: near-solid plate, no see-through blur, strong rim.
   !important intentionally outranks the tier selectors above — a user
   preference must beat every tier. */
@media (prefers-contrast: more) {
	.finewerk-liquid-glass.finewerk-liquid-glass::before,
	.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::before {
		background: rgba(var(--fw-glass-tint), 0.92) !important;
		-webkit-backdrop-filter: none !important;
		backdrop-filter: none !important;
		box-shadow: inset 0 0 0 1px rgba(var(--fw-glass-shadow-rgb), 0.8) !important;
	}
	.finewerk-liquid-glass.finewerk-liquid-glass::after,
	.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::after {
		background: none !important;
	}
}

/* Reduced transparency: mostly opaque plate, light blur only. */
@media (prefers-reduced-transparency: reduce) {
	.finewerk-liquid-glass.finewerk-liquid-glass::before,
	.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::before {
		background: rgba(var(--fw-glass-tint), 0.88) !important;
		-webkit-backdrop-filter: blur(6px) !important;
		backdrop-filter: blur(6px) !important;
	}
}

/* Reduced motion: the material stays, the glide/transition goes.
   (JS separately skips pointer tracking under this preference, and snaps the
   dynamic tint to its target instead of easing toward it.) */
@media (prefers-reduced-motion: reduce) {
	.finewerk-liquid-glass.finewerk-liquid-glass,
	.finewerk-liquid-glass.finewerk-liquid-glass::after,
	.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic,
	.finewerk-liquid-glass__dynamic.finewerk-liquid-glass__dynamic::after {
		transition: none !important;
	}
}
