/* FlowKit – motion infrastructure */

/*
 * Anti-flicker. Hide animatable FlowKit elements until JS has set their start
 * state and marked them .fk-ready. Gated three ways so content is NEVER stuck:
 *   - html.fk-js          : only when JS booted (added by an inline <head> script)
 *   - :not(.fk-fallback)  : a 2s failsafe in that script force-reveals everything
 *   - reduced-motion      : the inline script skips adding fk-js entirely
 * visibility:hidden (not display:none) reserves layout, so there is no shift.
 */
html.fk-js:not(.fk-fallback) [data-flowkit="true"]:not(.fk-ready) {
	visibility: hidden !important;
}

/*
 * Whole-page auto mode: top-level rows get data-flowkit from JS only after load,
 * so pre-hide them here (matching the units core.js tags) to avoid a flash.
 */
html.fk-js:not(.fk-fallback) body.fk-page-auto [data-elementor-type] > .elementor-section:not(.fk-ready),
html.fk-js:not(.fk-fallback) body.fk-page-auto [data-elementor-type] > .e-con:not(.fk-ready) {
	visibility: hidden;
}

/*
 * Layout safety. Contain horizontal overflow from animated transforms so an
 * effect can never add a horizontal scrollbar or shift the layout width.
 * overflow-x:clip (not hidden) avoids creating a scroll container; vertical
 * motion stays fully visible.
 */
[data-flowkit] {
	overflow-x: clip;
}

/* Guarantee image/icon clip containers actually clip. */
[data-flowkit] .elementor-widget-image .elementor-image,
[data-flowkit] .elementor-image {
	overflow: hidden;
}

[data-flowkit] .elementor-widget-icon-box .elementor-icon-box-icon,
[data-flowkit] .elementor-widget-icon .elementor-icon {
	overflow: hidden;
}

/* ----------------------------------------------------------------------- *
 * Text styles. Static CSS, applied via data-fk-style + CSS vars on the
 * wrapper. They combine with any animation; the .fk-* selectors keep the
 * style working after SplitText fragments the text.
 * ----------------------------------------------------------------------- */

/*
 * Text Style: Gradient. Applied to the whole heading. When combined with a
 * split text effect, each fragment is painted with the same gradient by JS
 * (paintSplitStyle), so the gradient stays continuous.
 *
 * Static = a plain 2-stop gradient with positions.
 * Animated (data-fk-grad="animated") = the static gradient plus a soft light
 * sheen that sweeps across once per cycle (the fk-grad-sheen rule below).
 */
/* ---- Gradient ------------------------------------------------------------ */
[data-fk-style="gradient"] .elementor-heading-title,
[data-fk-style="gradient"] .elementor-button .elementor-button-text {
	display: inline-block;
	background-image: var( --fk-bg, linear-gradient( 90deg, #6D5EFC, #F0468A ) ) !important;
	background-size: 100% 100%;
	-webkit-background-clip: text !important;
	background-clip: text !important;
	-webkit-text-fill-color: transparent !important;
	color: transparent !important;
}

[data-fk-style="gradient"][data-fk-grad="animated"] .elementor-heading-title,
[data-fk-style="gradient"][data-fk-grad="animated"] .elementor-button .elementor-button-text {
	background-size: 300% 100% !important;
	animation: fk-grad-breathe var( --fk-grad-speed, 4s ) ease-in-out infinite alternate !important;
}

@keyframes fk-grad-breathe {
	from { background-position: 0% 50%; }
	to   { background-position: 100% 50%; }
}

/*
 * Shimmer: a second background layer above the gradient — a narrow band of
 * light travelling across. Both layers are clipped to the text, so the sweep
 * lights the letters rather than a rectangle behind them.
 */
[data-fk-style="gradient"][data-fk-shimmer="yes"] .elementor-heading-title,
[data-fk-style="gradient"][data-fk-shimmer="yes"] .elementor-button .elementor-button-text {
	background-image:
		linear-gradient( 100deg, transparent 42%, var( --fk-shimmer, rgba(255,255,255,0.85) ) 50%, transparent 58% ),
		var( --fk-bg, linear-gradient( 90deg, #6D5EFC, #F0468A ) ) !important;
	background-repeat: no-repeat;
	background-size: 250% 100%, 100% 100% !important;
	animation: fk-grad-shimmer var( --fk-grad-speed, 4s ) linear infinite !important;
}

@keyframes fk-grad-shimmer {
	from { background-position: -150% 0, 0 0; }
	to   { background-position: 250% 0, 0 0; }
}

/* ---- Shine --------------------------------------------------------------- */
/* Text keeps its own color; a filter:brightness pulse creates a real light
   sweep that works on any background and any text color.                      */
[data-fk-style="shine"] .elementor-heading-title,
[data-fk-style="shine"] .elementor-button .elementor-button-text {
	color: var( --fk-shine-color, #a78bfa ) !important;
	-webkit-text-fill-color: var( --fk-shine-color, #a78bfa ) !important;
	animation: fk-shine-pulse var( --fk-shine-speed, 2.5s ) ease-in-out infinite !important;
}

@keyframes fk-shine-pulse {
	0%, 55%, 100% { filter: brightness( 1 ); }
	28%           { filter: brightness( var( --fk-shine-bright, 2 ) ); }
}

/* ---- Outline ------------------------------------------------------------- */
[data-fk-style="outline"] .elementor-heading-title,
[data-fk-style="outline"] .elementor-button .elementor-button-text {
	-webkit-text-stroke: var( --fk-stroke-width, 1px ) var( --fk-stroke-color, #6D5EFC ) !important;
	-webkit-text-fill-color: transparent !important;
	color: transparent !important;
}

/* ----------------------------------------------------------------------- *
 * Surface: Glass / Rim Light / Aurora                                     *
 * ----------------------------------------------------------------------- */

/* ---- Glass ----------------------------------------------------------------
   Real glassmorphism, not the "grey box + blur(8px)" the average addon sells:
   translucent tint, saturated backdrop blur, a specular sheen and a refracted
   top hairline, plus an optional elevation shadow so cards actually float.
   Works when the element sits over a rich background (image, video, gradient).
   From Active Theory / dope.security boarding pass panel aesthetic.          */
[data-fk-surface="glass"] {
	background-color:         var( --fk-glass-bg, rgba(255,255,255,0.06) ) !important;
	background-image:         var( --fk-glass-sheen, none ) !important;
	backdrop-filter:          blur( var( --fk-glass-blur, 20px ) ) saturate( var( --fk-glass-sat, 180% ) ) !important;
	-webkit-backdrop-filter:  blur( var( --fk-glass-blur, 20px ) ) saturate( var( --fk-glass-sat, 180% ) ) !important;
	border:                   1px solid var( --fk-glass-border, rgba(255,255,255,0.12) ) !important;
	box-shadow:               inset 0 1px 0 0 var( --fk-glass-hi, rgba(255,255,255,0) ),
	                          var( --fk-glass-shadow, 0 0 0 0 rgba(0,0,0,0) ) !important;
}

/* No backdrop-filter (old Firefox, ancient WebKit): without a fallback the
   panel turns into a 6%-opacity ghost and the text on it becomes unreadable.
   Fall back to a near-solid tint of the same colour — frosted, not invisible. */
@supports not ( (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) ) {
	[data-fk-surface="glass"] {
		background-color: var( --fk-glass-bg-fb, rgba(16,16,20,0.88) ) !important;
		background-image: none !important;
	}
}

/* ---- Glass, soft edges -----------------------------------------------------
   backdrop-filter clips at the element's box, so plain glass always ends in a
   razor edge — fine for a card, ugly for a floating header. Soft mode moves
   the whole frosting onto a ::before and fades it out with a gradient mask,
   so the blur dissolves instead of stopping. Border and specular hairline are
   hard edges by definition, so this mode removes them; the drop shadow stays.
   Content sits above the frosted layer and is never faded by the mask.       */
[data-fk-surface="glass"][data-fk-glass-soft]:not(.elementor-sticky) {
	position: relative !important;
}

[data-fk-surface="glass"][data-fk-glass-soft] {
	background-color:         transparent !important;
	background-image:         none !important;
	backdrop-filter:          none !important;
	-webkit-backdrop-filter:  none !important;
	border:                   none !important;
	box-shadow:               var( --fk-glass-shadow, 0 0 0 0 rgba(0,0,0,0) ) !important;
}

[data-fk-surface="glass"][data-fk-glass-soft]::before {
	content:                  "";
	position:                 absolute;
	inset:                    0;
	z-index:                  0;
	pointer-events:           none;
	border-radius:            inherit;
	background-color:         var( --fk-glass-bg, rgba(255,255,255,0.06) );
	background-image:         var( --fk-glass-sheen, none );
	backdrop-filter:          blur( var( --fk-glass-blur, 20px ) ) saturate( var( --fk-glass-sat, 180% ) );
	-webkit-backdrop-filter:  blur( var( --fk-glass-blur, 20px ) ) saturate( var( --fk-glass-sat, 180% ) );
	mask-image:               var( --fk-glass-mask );
	-webkit-mask-image:       var( --fk-glass-mask );
}

[data-fk-surface="glass"][data-fk-glass-soft="all"]::before {
	mask-composite:           intersect;
	-webkit-mask-composite:   source-in;
}

/* Content above the frosted layer. Inline position (absolute decorations,
   sticky headers) still wins over this rule. */
[data-fk-surface="glass"][data-fk-glass-soft] > * {
	position: relative;
}

@supports not ( (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) ) {
	[data-fk-surface="glass"][data-fk-glass-soft]::before {
		background-color: var( --fk-glass-bg-fb, rgba(16,16,20,0.88) );
		background-image: none;
	}
}

/* ---- Rim Light ------------------------------------------------------------
   Inset box-shadow that mimics a rim light catching a dark glass panel.
   From Reflect Notes — surfaces separated by subtle inset glow, not borders. */
[data-fk-surface="rimlight"] {
	box-shadow: 0 0 var( --fk-rim-size, 24px ) 0 var( --fk-rim-shadow, rgba(255,255,255,0.06) ) inset !important;
}

/* ---- Aurora Divider -------------------------------------------------------
   Gradient hairline border that fades at the edges — a luminous divider.
   From Reflect Notes aurora gradient system.                                */
[data-fk-aurora="bottom"] {
	border-bottom: 1px solid transparent !important;
	border-image:  linear-gradient( 90deg, transparent 0%, var( --fk-aurora-color, #9382ff ) 50%, transparent 100% ) 1 !important;
}

[data-fk-aurora="top"] {
	border-top:   1px solid transparent !important;
	border-image: linear-gradient( 90deg, transparent 0%, var( --fk-aurora-color, #9382ff ) 50%, transparent 100% ) 1 !important;
}

/* ----------------------------------------------------------------------- *
 * Gradient border.
 *
 * One ring, drawn as a ::before on a host element chosen per widget type.
 * PHP writes data-fk-btarget so the CSS knows where the ring belongs:
 *
 *   button → .elementor-button
 *   image  → whichever element directly wraps the <img>
 *   ring   → the .fk-ring element, for FlowKit's own widgets, which render
 *            their own host and so need no guessing
 *   self   → the widget's own box: its container div when Elementor renders
 *            one, otherwise the wrapper itself
 *
 * The ring is a gradient rectangle with its middle masked out. That is what
 * lets it sit on a transparent element, follow the host's own border-radius
 * and cost no layout. ::after carries the outer glow separately, because an
 * outer box-shadow on the ring itself would be eaten by the same mask.
 *
 * --fk-angle is animated by CSS alone, so a page whose only FlowKit feature
 * is a gradient border loads no JavaScript at all.
 * ----------------------------------------------------------------------- */

@property --fk-angle {
	syntax: '<angle>';
	initial-value: 0deg;
	inherits: false;
}

@property --fk-bc1 {
	syntax: '<color>';
	initial-value: #6d5efc;
	inherits: true;
}

@property --fk-bc2 {
	syntax: '<color>';
	initial-value: #ec4899;
	inherits: true;
}

@property --fk-bw {
	syntax: '<length>';
	initial-value: 2px;
	inherits: true;
}

@property --fk-bglw {
	syntax: '<length>';
	/* stylelint-disable-next-line length-zero-no-unit -- a <length> @property registration rejects the unitless 0 */
	initial-value: 0px;
	inherits: true;
}

/* PHP writes the normal (-n) and hover (-h) pairs; these two rules resolve
   them into the values the ring reads. Registering the four properties above
   is what lets the hover swap transition instead of snapping. */
[data-fk-border] {
	--fk-bc1:  var( --fk-bc1n,  #6d5efc );
	--fk-bc2:  var( --fk-bc2n,  #ec4899 );
	--fk-bw:   var( --fk-bwn,   2px );
	--fk-bglw: var( --fk-bglwn, 0px );
	transition: --fk-bc1 0.3s ease, --fk-bc2 0.3s ease, --fk-bw 0.3s ease, --fk-bglw 0.3s ease;
}

/* :has() keeps the hover area on the button itself rather than the whole
   widget row, which is what a bare :hover on the wrapper would give. */
[data-fk-btarget="button"]:has( .elementor-button:hover ),
[data-fk-btarget="image"]:has( img:hover ),
[data-fk-btarget="self"]:hover,
[data-fk-btarget="ring"]:has( .fk-ring:hover ) {
	--fk-bc1:  var( --fk-bc1h,  var( --fk-bc1n,  #6d5efc ) );
	--fk-bc2:  var( --fk-bc2h,  var( --fk-bc2n,  #ec4899 ) );
	--fk-bw:   var( --fk-bwh,   var( --fk-bwn,   2px ) );
	--fk-bglw: var( --fk-bglwh, var( --fk-bglwn, 0px ) );
	--fk-bop: 1;
}

/* ---- Modes ---------------------------------------------------------------
   Each mode is one declaration of --fk-bimg on the wrapper. The nested var()s
   resolve here, on the element that also carries the angle animation, so the
   gradient recomputes each frame and inherits down to the ring.            */
[data-fk-border="static"],
[data-fk-border="pulse"] {
	--fk-bimg: linear-gradient( var( --fk-bang, 90deg ), var( --fk-bc1 ), var( --fk-bc2 ) );
}

[data-fk-border="rotate"] {
	--fk-bimg: conic-gradient( from var( --fk-angle ), var( --fk-bc1 ), var( --fk-bc2 ), var( --fk-bc1 ) );
}

/* A short bright arc travelling an otherwise empty track. */
[data-fk-border="beam"] {
	--fk-bimg: conic-gradient(
		from var( --fk-angle ),
		transparent 0deg,
		transparent 288deg,
		var( --fk-bc1 ) 324deg,
		var( --fk-bc2 ) 352deg,
		transparent 360deg
	);
}

[data-fk-border="rotate"],
[data-fk-border="beam"] {
	animation: fk-b-spin var( --fk-bspd, 3s ) linear infinite;
}

[data-fk-border="pulse"] {
	--fk-banim: fk-b-breathe;
	--fk-bease: ease-in-out;
}

[data-fk-bhover="yes"] {
	--fk-bop: 0;
}

/* ---- The host ------------------------------------------------------------
   FlowKit's own widgets skip the data-fk-btarget guesswork: they render the
   host themselves and mark it .fk-ring.                                     */
[data-fk-btarget="button"] .elementor-button,
[data-fk-btarget="image"] :has( > img ),
[data-fk-btarget="self"] > .elementor-widget-container,
[data-fk-btarget="self"]:not( :has( > .elementor-widget-container ) ),
[data-fk-btarget="ring"] .fk-ring {
	position: relative;
}

/* An image sits in a full-width box, so shrink the host to the picture and
   drop the inline descender gap under it — otherwise the ring floats free. */
[data-fk-btarget="image"] :has( > img ) {
	display: inline-block;
	max-width: 100%;
	border-radius: var( --fk-br, 0 );
}

[data-fk-btarget="image"] img {
	display: block;
}

/* ---- The ring ------------------------------------------------------------ */
[data-fk-btarget="button"] .elementor-button::before,
[data-fk-btarget="image"] :has( > img )::before,
[data-fk-btarget="self"] > .elementor-widget-container::before,
[data-fk-btarget="self"]:not( :has( > .elementor-widget-container ) )::before,
[data-fk-btarget="ring"] .fk-ring::before {
	content: '';
	position: absolute;
	z-index: 1;
	inset: 0;
	padding: var( --fk-bw );
	border-radius: inherit;
	background-image: var( --fk-bimg );
	opacity: var( --fk-bop, 1 );
	pointer-events: none;
	transition: opacity 0.3s ease;
	animation: var( --fk-banim, none ) var( --fk-bspd, 3s ) var( --fk-bease, linear ) infinite;
	-webkit-mask: linear-gradient( #000 0 0 ) content-box, linear-gradient( #000 0 0 );
	mask: linear-gradient( #000 0 0 ) content-box, linear-gradient( #000 0 0 );
	-webkit-mask-composite: xor;
	mask-composite: exclude;
}

/* ---- The glow ------------------------------------------------------------
   An outer box-shadow paints only outside its own box, so it rings the
   element without tinting it and without touching the widget's own shadow. */
[data-fk-btarget="button"] .elementor-button::after,
[data-fk-btarget="image"] :has( > img )::after,
[data-fk-btarget="self"] > .elementor-widget-container::after,
[data-fk-btarget="self"]:not( :has( > .elementor-widget-container ) )::after,
[data-fk-btarget="ring"] .fk-ring::after {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: inherit;
	box-shadow: 0 0 var( --fk-bglw ) var( --fk-bc1 );
	opacity: var( --fk-bop, 1 );
	pointer-events: none;
	transition: opacity 0.3s ease;
	animation: var( --fk-banim, none ) var( --fk-bspd, 3s ) var( --fk-bease, linear ) infinite;
}

@keyframes fk-b-spin {
	to { --fk-angle: 360deg; }
}

@keyframes fk-b-breathe {
	0%, 100% { opacity: 1; }
	50%      { opacity: 0.4; }
}

.fk-marquee {
	display: inline-flex;
	flex-wrap: nowrap;
}

/* ----------------------------------------------------------------------- *
 * Scroll sections. The JavaScript in sections.js writes the sticky offsets
 * and the pinned track's position; these rules only make the container
 * capable of holding them.
 * ----------------------------------------------------------------------- */

/* A sticky child is positioned against the nearest scrollport, so nothing on
   the way up may clip — including the overflow-x rule [data-flowkit] sets. */
[data-fk-section="stack"] {
	overflow: visible !important;
}

[data-fk-section="horizontal"] {
	overflow: hidden;
}

/* The track has to be wider than the viewport before there is anything to
   slide, which a wrapping flex row would never be. */
[data-fk-section="horizontal"] > .e-con-inner,
[data-fk-section="horizontal"] > .elementor-container {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	width: max-content;
	max-width: none;
}

/*
 * Reduced-motion is handled entirely in JS (configurable via the
 * flowkit/reduced_motion_mode filter), so there is intentionally no CSS
 * override here — a CSS rule would fight the 'ignore'/'fade' modes.
 */
