/**
 * GEEKS Button.
 *
 * THE LINK IS THE OUTER BOX and the FACE inside it is the visual button. That
 * shape is shared by every preset, for two reasons: the icon then sits inside
 * the tag, part of the same click target with one focus ring around it; and a
 * preset that moves the button needs something to move that is not the element
 * its own siblings live in — a child cannot stay behind while its parent slides
 * away.
 *
 * Resting values (padding, radius, speed) live HERE rather than as Elementor
 * control defaults. A value kept only in PHP is filled in when the CSS is
 * rendered but is missing from the editor's model, so the panel shows an empty
 * field beside a button that plainly has padding — and typing the 0 the field
 * already claims changes nothing. Keeping it in one place, below the panel,
 * makes an empty field mean "the resting look" and any typed value, 0 included,
 * a real change.
 *
 * Presets add their own `.is-<name>` rules beside the shared ones.
 */

/* Every background here is a linear gradient — a flat colour is simply the same
   colour at both stops. That is the whole point: `background-image` cannot be
   transitioned, but these ARE registered properties, and a registered `<color>`
   interpolates. One mechanism paints and animates flat colours and gradients
   alike, with no second layer to fade in and nothing hiding behind it. */
@property --geeks-btn-c1 { syntax: "<color>"; inherits: false; initial-value: transparent; }
@property --geeks-btn-c2 { syntax: "<color>"; inherits: false; initial-value: transparent; }
@property --geeks-btn-s1 { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
@property --geeks-btn-s2 { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
@property --geeks-btn-ang { syntax: "<angle>"; inherits: false; initial-value: 180deg; }

.geeks-btn-box {
	display: flex;
	flex-direction: column;
}

/* The link: no look of its own, just the box everything sits in. */
.geeks-btn {
	--geeks-btn-speed: 0.25s;

	position: relative;
	display: inline-flex;
	/* NOT `stretch`. The face must take its height from its own padding and
	   type; if it stretched to the link, and the link were sized by the square,
	   and the square by --geeks-btn-sq which comes from the face, the height
	   would be a closed loop — it freezes at its first value and stops
	   following the padding. */
	align-items: center;
	max-width: 100%;
	cursor: pointer;
}

/* A button with no link renders as <button>, and Hello Elementor's reset.css
   styles every raw <button> on the site in its own pink: `#c36` border and
   text, and `background-color: #c36` with white text on hover and focus. Its
   `[type=button]:hover` outscores a lone `.geeks-btn`, so the wrapper is named
   here to outrank it — the states are listed because that is where it strikes,
   and `transition` is reset because the parent theme animates `all .3s` on
   buttons, which would drag our margin and colours along at its own pace.

   None of this is cosmetic defence: the link must carry NO look of its own, or
   the parent theme's paints show around a face that no longer covers the whole
   element. */
.geeks-btn-box .geeks-btn,
.geeks-btn-box .geeks-btn:hover,
.geeks-btn-box .geeks-btn:focus,
.geeks-btn-box .geeks-btn:active {
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-align: inherit;
	text-decoration: none;
	white-space: normal;
	transition: none;
}

/* The face: everything the Style tab paints. */
.geeks-btn-face {
	position: relative;
	z-index: 1;
	flex: 1 1 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.6em;
	padding: 16px 34px;
	border-radius: 6px;
	line-height: 1.2;
	text-align: center;
	/* Every var carries a fallback, and not for tidiness: where `@property` is
	   unsupported the stops are plain unset properties, an unset `var()` is
	   invalid, and one invalid `var()` takes the WHOLE declaration with it — the
	   button would lose its background rather than just its animation. Elementor
	   only writes the stops and angle for a gradient, so a flat colour is
	   exactly the case that would break. */
	background-image: linear-gradient(
		var( --geeks-btn-ang, 180deg ),
		var( --geeks-btn-c1, transparent ) var( --geeks-btn-s1, 0% ),
		var( --geeks-btn-c2, transparent ) var( --geeks-btn-s2, 100% )
	);
	transition:
		margin-left var( --geeks-btn-speed ) ease,
		border-radius var( --geeks-btn-speed ) ease,
		border-color var( --geeks-btn-speed ) ease,
		color var( --geeks-btn-speed ) ease,
		--geeks-btn-c1 var( --geeks-btn-speed ) ease,
		--geeks-btn-c2 var( --geeks-btn-speed ) ease,
		--geeks-btn-s1 var( --geeks-btn-speed ) ease,
		--geeks-btn-s2 var( --geeks-btn-speed ) ease,
		--geeks-btn-ang var( --geeks-btn-speed ) ease;
}

/* The label sits above the background. */
.geeks-btn-label {
	position: relative;
	z-index: 1;
}

/* The icon's resting look. `em` throughout, so it tracks the label whenever the
   typography changes; `order: -1` puts it before the label until the Which side
   control says otherwise. */
.geeks-btn-icon {
	position: relative;
	z-index: 1;
	order: -1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 1em;
	line-height: 0;
	transition: color var( --geeks-btn-speed ) ease;
}

/* An uploaded SVG has no font size to inherit, so it is sized from the wrapper
   and painted with `currentColor` — which is what lets the Colour control, and
   an empty one falling back to the label's colour, work for both icon kinds. */
.geeks-btn-icon svg {
	display: block;
	width: 1em;
	height: 1em;
	fill: currentColor;
}

.geeks-btn-icon i,
.geeks-btn-icon i::before {
	font-size: inherit;
	line-height: 1;
}

/* Keyboard focus shows what hover shows, and is never removed without a
   replacement: a button nobody can see themselves reach is a broken button.
   One ring around the pair, because the pair is one link. */
.geeks-btn-box .geeks-btn:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 3px;
	border-radius: 6px;
}

/* ---------------------------------------------------------------------------
   Slide and reveal
   --------------------------------------------------------------------------- */

.geeks-btn.is-slide {
	/* ZERO until the observer has measured, and that is the whole trick.
	   The real value is the face's height, which only JavaScript can read — and
	   any guess here is visible: the square is laid out at this size, so a guess
	   taller than the face makes the LINK taller than the button, and the button
	   visibly snaps when the true value lands a frame later.
	   At zero there is nothing to snap. The square is 0×0 and the face's
	   negative margin is 0, so the widget renders exactly as the Solid preset
	   does — right width, right height — and when the measurement arrives the
	   square grows to the face's height while the margin pulls back by the same
	   amount, which changes no dimension of the box at all. The cost is that a
	   hover in the first frame or two has nothing to reveal yet. */
	--geeks-btn-sq: 0px;
}

/* While the first measurement is being written, nothing animates: the widget
   has to arrive at its size rather than travel to it. geeks-button.js takes
   this off again a frame later, so every later change still slides. */
.geeks-btn.is-slide.is-sizing .geeks-btn-face,
.geeks-btn.is-slide.is-sizing .geeks-btn-panel {
	transition: none;
}

/* MARGIN, not transform. A transform paints the face somewhere else and leaves
   the layout alone; a margin IS layout, so the link genuinely grows by the
   square's width and anything to its right is pushed along. At rest the
   negative margin pulls the face back over the square, making the box exactly
   as wide as the face alone. */
.geeks-btn.is-slide .geeks-btn-face {
	margin-left: calc( -1 * var( --geeks-btn-sq ) );
}

.geeks-btn.is-slide:hover .geeks-btn-face,
.geeks-btn.is-slide:focus-visible .geeks-btn-face {
	margin-left: 0;
}

.geeks-btn-panel {
	position: relative;
	z-index: 0;
	flex: 0 0 auto;
	align-self: center;
	/* Square by construction, not by aspect-ratio: --geeks-btn-sq IS the face's
	   height, so writing it into both axes makes the box exactly as tall as the
	   face and exactly as wide as it is tall. `aspect-ratio` would be ignored
	   here anyway — it only decides a dimension nothing else has determined. */
	width: var( --geeks-btn-sq );
	height: var( --geeks-btn-sq );
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 6px;
	/* A switch, not a fade. Going in, the square is already there before the
	   face has moved a pixel; coming back, the zero-duration change is DELAYED
	   by the whole slide, so it blinks off only once the face is home and
	   covering it. */
	opacity: 0;
	/* Every var carries a fallback, and not for tidiness: where `@property` is
	   unsupported the stops are plain unset properties, an unset `var()` is
	   invalid, and one invalid `var()` takes the WHOLE declaration with it — the
	   button would lose its background rather than just its animation. Elementor
	   only writes the stops and angle for a gradient, so a flat colour is
	   exactly the case that would break. */
	background-image: linear-gradient(
		var( --geeks-btn-ang, 180deg ),
		var( --geeks-btn-c1, transparent ) var( --geeks-btn-s1, 0% ),
		var( --geeks-btn-c2, transparent ) var( --geeks-btn-s2, 100% )
	);
	transition:
		opacity 0s ease var( --geeks-btn-speed ),
		border-radius var( --geeks-btn-speed ) ease,
		--geeks-btn-c1 var( --geeks-btn-speed ) ease,
		--geeks-btn-c2 var( --geeks-btn-speed ) ease,
		--geeks-btn-s1 var( --geeks-btn-speed ) ease,
		--geeks-btn-s2 var( --geeks-btn-speed ) ease,
		--geeks-btn-ang var( --geeks-btn-speed ) ease;
}

.geeks-btn.is-slide:hover .geeks-btn-panel,
.geeks-btn.is-slide:focus-visible .geeks-btn-panel {
	opacity: 1;
	transition:
		opacity 0s ease 0s,
		border-radius var( --geeks-btn-speed ) ease,
		--geeks-btn-c1 var( --geeks-btn-speed ) ease,
		--geeks-btn-c2 var( --geeks-btn-speed ) ease,
		--geeks-btn-s1 var( --geeks-btn-speed ) ease,
		--geeks-btn-s2 var( --geeks-btn-speed ) ease,
		--geeks-btn-ang var( --geeks-btn-speed ) ease;
}

/* Where the two boxes meet, both go square.

   `!important` earns its place here, and only here. The Border radius control
   writes `border-radius` through Elementor's per-element selector — three
   classes deep — which no rule in a theme stylesheet can outrank. Without it a
   button whose radius was set in the panel simply never flattens: the corners
   stay round and the two boxes read as two boxes. This is a state overriding a
   value, not a style fighting a style, so the blunt instrument is the honest
   one. */
.geeks-btn.is-slide:hover .geeks-btn-face,
.geeks-btn.is-slide:focus-visible .geeks-btn-face {
	border-top-left-radius: 0 !important;
	border-bottom-left-radius: 0 !important;
}

.geeks-btn.is-slide:hover .geeks-btn-panel,
.geeks-btn.is-slide:focus-visible .geeks-btn-panel {
	border-top-right-radius: 0 !important;
	border-bottom-right-radius: 0 !important;
}

/* The square is only ever revealed by motion, so with motion refused there is
   nothing to reveal — it stays put and shows from the start. */
@media ( prefers-reduced-motion: reduce ) {
	.geeks-btn-face,
	.geeks-btn-panel,
	.geeks-btn-icon {
		transition: none;
	}

	.geeks-btn.is-slide .geeks-btn-face { margin-left: 0; }
	.geeks-btn-panel { opacity: 1; }
}
