/* FluxCore Background Effects — pure CSS, no JS involved.
   Applied per-element from inside Elementor's Style tab ("FluxCore
   Background Effect") on any Container, Section, Column, or Div Block —
   see class-fluxcore-elementor.php. Every color/speed/opacity value below
   is a CSS custom property Elementor writes per-element via its own
   `selectors` mechanism, exactly like Elementor's own style controls;
   this file only defines what those variables drive. */

/* ---- Gradient Shift ---- */
.fx-bg-effect-yes.fx-bg-type-gradient {
	background: linear-gradient(
		120deg,
		var( --fx-bg-color-1, #87e64b ),
		var( --fx-bg-color-2, #000000 ),
		var( --fx-bg-color-1, #87e64b )
	) !important;
	background-size: 200% 200% !important;
	animation: fxBgShift var( --fx-bg-speed, 20s ) ease infinite;
}

@keyframes fxBgShift {
	0% {
		background-position: 0% 50%;
	}
	50% {
		background-position: 100% 50%;
	}
	100% {
		background-position: 0% 50%;
	}
}

/* ---- Aurora Blobs ----
   Two blurred, oversized pseudo-elements (::before and ::after), each
   painting two radial-gradient blobs, layered behind the element's real
   content and blended with `mix-blend-mode: screen` so overlapping colors
   glow together instead of just sitting side by side. Each layer's blobs
   travel through four widely-spaced waypoints in one continuous forward
   loop (not a back-and-forth wobble around one spot), combined with a
   slight scale pulse, so the motion reads clearly as blobs migrating
   across the area rather than a gentle in-place glow — see the reference
   recording this was built from. */
.fx-bg-effect-yes.fx-bg-type-aurora {
	position: relative;
	overflow: hidden;
	background-color: var( --fx-aurora-base, #0b0f19 ) !important;
}

.fx-bg-effect-yes.fx-bg-type-aurora::before,
.fx-bg-effect-yes.fx-bg-type-aurora::after {
	content: "";
	position: absolute;
	inset: -35%;
	z-index: 0;
	pointer-events: none;
	filter: blur( 80px );
	mix-blend-mode: screen;
	opacity: var( --fx-aurora-opacity, 0.6 );
	background-repeat: no-repeat;
	background-size: 160% 160%;
	transform-origin: center;
	animation-timing-function: ease-in-out;
	animation-iteration-count: infinite;
}

.fx-bg-effect-yes.fx-bg-type-aurora::before {
	background-image: radial-gradient( circle at 25% 30%, var( --fx-aurora-c1, #87e64b ) 0%, transparent 55% ),
		radial-gradient( circle at 75% 70%, var( --fx-aurora-c3, #ec4899 ) 0%, transparent 55% );
	animation-name: fxAuroraDriftA;
	animation-duration: var( --fx-aurora-speed, 14s );
}

.fx-bg-effect-yes.fx-bg-type-aurora::after {
	background-image: radial-gradient( circle at 75% 25%, var( --fx-aurora-c2, #6366f1 ) 0%, transparent 55% ),
		radial-gradient( circle at 25% 75%, var( --fx-aurora-c4, #f59e0b ) 0%, transparent 55% );
	animation-name: fxAuroraDriftB;
	animation-duration: var( --fx-aurora-speed, 14s );
}

@keyframes fxAuroraDriftA {
	0% {
		background-position: 15% 20%, 85% 80%;
		transform: scale( 1 );
	}
	25% {
		background-position: 65% 10%, 35% 90%;
		transform: scale( 1.12 );
	}
	50% {
		background-position: 90% 65%, 10% 35%;
		transform: scale( 1 );
	}
	75% {
		background-position: 35% 90%, 65% 10%;
		transform: scale( 1.12 );
	}
	100% {
		background-position: 15% 20%, 85% 80%;
		transform: scale( 1 );
	}
}

@keyframes fxAuroraDriftB {
	0% {
		background-position: 90% 15%, 10% 85%;
		transform: scale( 1.08 );
	}
	25% {
		background-position: 40% 55%, 60% 45%;
		transform: scale( 1 );
	}
	50% {
		background-position: 10% 90%, 90% 10%;
		transform: scale( 1.15 );
	}
	75% {
		background-position: 60% 40%, 40% 60%;
		transform: scale( 1 );
	}
	100% {
		background-position: 90% 15%, 10% 85%;
		transform: scale( 1.08 );
	}
}

/* Keeps the element's real content painting above the blurred blob
   layers. If content unexpectedly disappears behind the effect on a
   heavily custom layout, give that inner element `position: relative`
   directly. */
.fx-bg-effect-yes.fx-bg-type-aurora > * {
	position: relative;
	z-index: 1;
}

/* ---- Fluted Glass ----
   Two layers: a blurred, cursor-following colored "bloom" (::before),
   and a repeating diagonal stripe pattern standing in for fluted-glass
   ribs (::after), blended over it with `mix-blend-mode: overlay` so the
   ribs locally lighten/darken the bloom wherever they cross it — the
   same visual idea as light bending through ribbed glass, without an
   actual WebGPU shader. public/js/background-effects-glass.js updates
   --fx-glass-x/--fx-glass-y to the cursor position on hover-capable
   devices; touch devices get a slow automatic drift instead (see the
   fallback keyframes below), since there's no cursor to follow. The
   @property declarations are what let the position variables — and
   therefore the bloom's movement — actually transition smoothly instead
   of jumping between values. */
@property --fx-glass-x {
	syntax: "<percentage>";
	inherits: true;
	initial-value: 50%;
}
@property --fx-glass-y {
	syntax: "<percentage>";
	inherits: true;
	initial-value: 40%;
}

.fx-bg-effect-yes.fx-bg-type-glass {
	position: relative;
	overflow: hidden;
	background-color: var( --fx-glass-base, #f5f5f4 ) !important;
	--fx-glass-x: 50%;
	--fx-glass-y: 40%;
}

.fx-bg-effect-yes.fx-bg-type-glass::before {
	content: "";
	position: absolute;
	inset: -20%;
	z-index: 0;
	pointer-events: none;
	background: radial-gradient(
		circle at var( --fx-glass-x ) var( --fx-glass-y ),
		var( --fx-glass-bloom, rgba( 99, 102, 241, 0.55 ) ) 0%,
		transparent var( --fx-glass-bloom-size, 45% )
	);
	filter: blur( var( --fx-glass-blur, 70px ) );
	transition: --fx-glass-x 300ms ease, --fx-glass-y 300ms ease;
}

.fx-bg-effect-yes.fx-bg-type-glass::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	opacity: var( --fx-glass-rib-opacity, 0.8 );
	mix-blend-mode: overlay;
}

/* Pattern: Diagonal Ribs (fluted glass) — the default. Alternating
   highlight/shadow lines at an angle, mimicking corrugated glass. */
.fx-bg-effect-yes.fx-bg-type-glass.fx-glass-pattern-ribs::after {
	background-image: repeating-linear-gradient(
		var( --fx-glass-rib-angle, 100deg ),
		rgba( 255, 255, 255, 0.45 ) 0px,
		rgba( 255, 255, 255, 0.45 ) calc( var( --fx-glass-rib-width, 5px ) * 0.25 ),
		transparent calc( var( --fx-glass-rib-width, 5px ) * 0.25 ),
		transparent calc( var( --fx-glass-rib-width, 5px ) * 0.75 ),
		rgba( 0, 0, 0, 0.12 ) calc( var( --fx-glass-rib-width, 5px ) * 0.75 ),
		rgba( 0, 0, 0, 0.12 ) var( --fx-glass-rib-width, 5px ),
		transparent var( --fx-glass-rib-width, 5px ),
		transparent calc( var( --fx-glass-rib-width, 5px ) * 1.5 )
	);
}

/* Pattern: Grid — thin horizontal + vertical lines forming a grid, sized
   by --fx-glass-pattern-size (the spacing between lines). */
.fx-bg-effect-yes.fx-bg-type-glass.fx-glass-pattern-grid::after {
	background-image: linear-gradient( rgba( 255, 255, 255, 0.35 ) 1px, transparent 1px ),
		linear-gradient( 90deg, rgba( 255, 255, 255, 0.35 ) 1px, transparent 1px );
	background-size: var( --fx-glass-pattern-size, 50px ) var( --fx-glass-pattern-size, 50px );
}

/* Pattern: Dots — a repeating dot grid, sized by --fx-glass-pattern-size. */
.fx-bg-effect-yes.fx-bg-type-glass.fx-glass-pattern-dots::after {
	background-image: radial-gradient( circle, rgba( 255, 255, 255, 0.45 ) 1.5px, transparent 1.5px );
	background-size: var( --fx-glass-pattern-size, 50px ) var( --fx-glass-pattern-size, 50px );
}

/* Pattern: Crosshatch — the same diagonal lines as Ribs, plus a second
   set at 90° to them, so they cross like woven glass. */
.fx-bg-effect-yes.fx-bg-type-glass.fx-glass-pattern-crosshatch::after {
	background-image: repeating-linear-gradient(
			var( --fx-glass-rib-angle, 100deg ),
			rgba( 255, 255, 255, 0.35 ) 0px,
			rgba( 255, 255, 255, 0.35 ) 1px,
			transparent 1px,
			transparent var( --fx-glass-rib-width, 5px )
		),
		repeating-linear-gradient(
			calc( var( --fx-glass-rib-angle, 100deg ) + 90deg ),
			rgba( 255, 255, 255, 0.35 ) 0px,
			rgba( 255, 255, 255, 0.35 ) 1px,
			transparent 1px,
			transparent var( --fx-glass-rib-width, 5px )
		);
}

.fx-bg-effect-yes.fx-bg-type-glass > * {
	position: relative;
	z-index: 2;
}

/* Touch devices have no cursor to follow, so the bloom drifts on its own
   instead of sitting frozen in one spot. */
@media ( hover: none ) {
	.fx-bg-effect-yes.fx-bg-type-glass::before {
		animation: fxGlassDrift 16s ease-in-out infinite;
	}
}

@keyframes fxGlassDrift {
	0% {
		--fx-glass-x: 20%;
		--fx-glass-y: 30%;
	}
	50% {
		--fx-glass-x: 80%;
		--fx-glass-y: 60%;
	}
	100% {
		--fx-glass-x: 20%;
		--fx-glass-y: 30%;
	}
}

/* ---- Perlin Noise Flow Field ----
   Only the base color and stacking context are set here — the flow
   itself is drawn frame by frame onto a <canvas> that
   public/js/background-effects-noiseflow.js injects into the element,
   since genuine procedural noise motion isn't something CSS alone can
   produce (unlike every other effect in this file). If that script
   hasn't run yet (or JS is disabled), the base color alone still shows,
   so there's no broken/empty state either way. */
.fx-bg-effect-yes.fx-bg-type-noiseflow {
	position: relative;
	overflow: hidden;
	background-color: var( --fx-noise-base, #0b0f19 ) !important;
}

.fx-bg-effect-yes.fx-bg-type-noiseflow canvas.fx-noise-canvas {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	width: 100%;
	height: 100%;
	display: block;
}

.fx-bg-effect-yes.fx-bg-type-noiseflow > *:not( canvas.fx-noise-canvas ) {
	position: relative;
	z-index: 1;
}

@media ( prefers-reduced-motion: reduce ) {
	.fx-bg-effect-yes.fx-bg-type-gradient {
		animation: none;
		background-position: 0% 50%;
	}
	.fx-bg-effect-yes.fx-bg-type-aurora::before,
	.fx-bg-effect-yes.fx-bg-type-aurora::after {
		animation: none;
	}
	.fx-bg-effect-yes.fx-bg-type-aurora::before {
		background-position: 15% 20%, 85% 80%;
		transform: scale( 1 );
	}
	.fx-bg-effect-yes.fx-bg-type-aurora::after {
		background-position: 90% 15%, 10% 85%;
		transform: scale( 1 );
	}
	.fx-bg-effect-yes.fx-bg-type-glass::before {
		transition: none;
		animation: none;
	}
}
