/**
 * GEEKS Loop Grid.
 *
 * Almost everything here is written by the controls rather than by this file:
 * the flow, the tracks, the gaps and the height all come from the panel, per
 * breakpoint. What is left is the resting state the controls write over, and
 * the two things a control cannot say.
 */

.geeks-lg {
	display: grid;
	/* The resting arrangement, which is also what the editor shows before the
	   author has touched anything and what a page whose CSS never arrived is
	   left with: three columns, downwards. */
	grid-auto-flow: row;
	grid-template-columns: repeat( var( --geeks-lg-cols, 3 ), minmax( 0, 1fr ) );
}

/* A GRID ITEM THAT CANNOT PUSH THE GRID WIDER.
 *
 * A grid track is sized by its contents unless it is told otherwise, and a long
 * unbroken word or a wide picture inside a loop item is enough to widen a
 * column past its share. `minmax(0, 1fr)` above says that for the explicit
 * tracks; this says it for the items themselves, which is the other half of the
 * same promise and the reason a `1fr` column stays a `1fr` column. */
.geeks-lg > .e-loop-item {
	min-width: 0;
	min-height: 0;
}

/* Sideways, the row is as long as its items and the box is the window onto it.
 *
 * The scrollbar is deliberately a real one: it is the only thing on the page
 * that says there is more to the right, and a reader who cannot see it cannot
 * know to drag. Inside a GEEKS horizontal scroll it would be a second way to
 * move the same content, so the handler takes it off there — see `is-carried`. */
.geeks-lg {
	scrollbar-gutter: stable;
}

/* Carried by something else: the GEEKS horizontal scroll translates the row
   itself, so the grid must not also scroll — two scrollers over one row fight
   each other, and the inner one swallows the wheel.
   
   `!important` because the direction control writes `overflow-x` from the panel,
   through Elementor's own stylesheet, at a specificity this file cannot reach:
   the rule there is keyed on the element's own id class. The alternative is to
   ask the author to remember that a carried grid wants different settings from a
   free one, which is not a thing anyone should have to remember. */
.geeks-lg.is-carried {
	overflow-x: visible !important;
	scrollbar-gutter: auto;
}

/* THE SCATTER.
 *
 * A transform, not a margin: the item is drawn somewhere else and the grid's own
 * geometry is untouched, so nothing reflows, no track is resized and the travel
 * of a horizontal scroll is exactly what it was. The axis is the one the grid
 * does NOT run along, which is why the class says which it is — the handler
 * reads the resolved direction from the element rather than guessing it from a
 * setting that may belong to another breakpoint.
 *
 * The transition is for the editor, where a nudge changes as the author drags
 * the slider; on the page the number is written once and never moves. */
.geeks-lg-shift-y > .e-loop-item {
	transform: translateY( var( --geeks-lg-shift, 0px ) );
}

.geeks-lg-shift-x > .e-loop-item {
	transform: translateX( var( --geeks-lg-shift, 0px ) );
}

@media ( prefers-reduced-motion: no-preference ) {
	body.elementor-editor-active .geeks-lg > .e-loop-item {
		transition: transform 0.2s ease;
	}
}

/* THE PAGINATION FURNITURE.
 *
 * Base renders the Load more button, a spinner and an end-of-list message,
 * because the pagination section is Elementor's and this widget kept it. What it
 * does not bring is the styling: every rule in Elementor's own `widget-loop-grid`
 * stylesheet is keyed on `.elementor-widget-loop-grid`, and this widget is called
 * something else — so enqueuing that file would change nothing at all.
 *
 * Left alone, the spinner is a Font Awesome icon with no size, which renders at
 * the SVG's own dimensions: a ring of eight black circles several hundred pixels
 * across, sitting in the middle of the grid. It looks like a fault in the widget
 * and is really a missing rule.
 *
 * So the handful that matter are written here, against our class. The names are
 * Elementor's — the markup is theirs, and the handler sets the same classes it
 * would have. */
.elementor-widget-geeks-loop-grid .e-load-more-spinner {
	display: flex;
	margin-top: var( --load-more—spacing, 30px );
}

.elementor-widget-geeks-loop-grid .e-load-more-spinner svg,
.elementor-widget-geeks-loop-grid .e-load-more-spinner i {
	/* Hidden until a batch is actually on its way; one line height, not the
	   icon's own idea of its size. */
	display: none;
	margin: 0 auto;
	width: 1em;
	height: 1em;
	fill: var( --load-more-spinner-color, currentColor );
	color: var( --load-more-spinner-color, currentColor );
}

.elementor-widget-geeks-loop-grid.e-load-more-pagination-loading .e-load-more-spinner svg,
.elementor-widget-geeks-loop-grid.e-load-more-pagination-loading .e-load-more-spinner i {
	display: flex;
}

/* While a batch is loading the button keeps its size — so the row below does not
   jump — and gives its place to the spinner. */
.elementor-widget-geeks-loop-grid.e-load-more-pagination-loading .elementor-button-content-wrapper {
	visibility: hidden;
}

.elementor-widget-geeks-loop-grid .e-loop__load-more {
	margin-top: var( --load-more—spacing, 30px );
	text-align: var( --load-more-button-align, center );
}

.elementor-widget-geeks-loop-grid .e-loop__load-more .elementor-button {
	position: relative;
	cursor: pointer;
	width: var( --load-more-button-width );
}

.elementor-widget-geeks-loop-grid .e-loop__load-more .e-load-more-spinner {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	margin: 0;
	transform: translate( -50%, -50% );
}

/* Nothing left to fetch: the button goes, the message arrives. */
.elementor-widget-geeks-loop-grid.e-load-more-pagination-end .e-loop__load-more {
	display: none;
}

.elementor-widget-geeks-loop-grid .e-load-more-message {
	display: none;
	margin-top: var( --load-more—spacing, 30px );
	color: var( --load-more-message-color );
	text-align: var( --load-more-message-alignment, center );
}

.elementor-widget-geeks-loop-grid.e-load-more-pagination-end .e-load-more-message {
	display: block;
}

.elementor-widget-geeks-loop-grid .e-loop-nothing-found-message {
	padding-block: var( --e-loop-nothing-found-message-space-from-top, 30px ) var( --e-loop-nothing-found-message-space-from-bottom, 30px );
	color: var( --e-loop-nothing-found-message-color, #1f2124 );
	text-align: var( --e-loop-nothing-found-message-align, center );
}

/* AND IT HAS TO TURN.
 *
 * Elementor's handler spins its spinner by adding `eicon-animation-spin`, a class
 * whose animation lives in their icon stylesheet — another thing that arrives with
 * the markup and not with the widget. Rather than depend on a class we do not set
 * and a file we do not load, the turn is defined here: a still spinner says
 * nothing, which is the one thing a spinner exists not to do. */
@keyframes geeks-lg-spin {
	to { transform: rotate( 360deg ); }
}

.elementor-widget-geeks-loop-grid.e-load-more-pagination-loading .e-load-more-spinner svg,
.elementor-widget-geeks-loop-grid.e-load-more-pagination-loading .e-load-more-spinner i {
	animation: geeks-lg-spin 0.9s linear infinite;
}

/* THE WAY BACK OUT OF A TEMPLATE, ON A SIDEWAYS GRID.
 *
 * Pro hangs its "Save & Back" bar on the item being edited and lifts it clear
 * with `translateY(-100%)` — about thirty pixels ABOVE the item. A sideways grid
 * declares `overflow-x: auto` so the row can be scrolled, and CSS will not give
 * one axis a scrollbar and leave the other visible: `overflow-y` becomes auto
 * with it, and the box clips. Measured in the editor: the bar painted at 622
 * against a grid starting at 650, with the grid itself the first clipping
 * ancestor. The author was inside the template with the way out cropped off —
 * and only ever sideways, since a vertical grid never asks for the scrollbar.
 *
 * So while a template is open in place the row stops clipping. `overflow-x:
 * clip` keeps the horizontal edge without making a scroll container, which is
 * what lets the vertical stay visible; scrolling the row is no loss here,
 * because the item being worked on is the one on screen. The class is the one
 * the handler puts on the widget when the switch into the template happens.
 *
 * `!important` for the same reason `is-carried` needs it: the direction control
 * writes `overflow-x` through Elementor's own stylesheet, at a specificity this
 * file cannot reach. */
.elementor-widget-geeks-loop-grid.elementor-in-place-template-editable .elementor-loop-container {
	overflow: visible !important;
	overflow-x: clip !important;
}

/* THE WAY BACK GOES INSIDE THE ITEM.
 *
 * Elementor hangs Save & Back in the 30px strip over the edited item's top
 * edge — outside the item, where anything that clips can swallow it. The row
 * above stops clipping while a template is open, but a grid whose items fill
 * their row inside a GEEKS horizontal scroll sits flush against the scroller's
 * own `overflow: hidden`: the author's container, and the one doing the
 * scrolling, so lifting that clip is not on offer.
 *
 * The handler sets this class whenever a template is open in place — not only
 * where the strip would be cut, which is how it started out. One place on every
 * grid is easier to use than a handle that moves with whatever the section
 * around it happens to clip. It sits 30px in from the item's top-left corner.
 *
 * Not centred, and not nudged sideways by a percentage of itself: Elementor's
 * own furniture — the container's toolbar, the drag dots, the element handles —
 * all hangs on the top edge, and a tab inset from the corner is clear of every
 * one of them at once. A percentage offset would have been measured in the
 * handle's own width, which is the width of a TRANSLATED string: "Save & Back"
 * is Pro's, and every locale sizes it differently.
 *
 * The tails go with the move. They are what makes a tab look fixed to an edge,
 * and this one is not on an edge any more.
 *
 * Four classes beat Pro's three, so no `!important` is needed. */
.elementor-widget-geeks-loop-grid.geeks-lg-handle-inside .elementor-document-save-back-handle .elementor-document-handle__inner {
	top: 30px;
	left: 30px;
	transform: none;
	border-radius: 5px;
}

.elementor-widget-geeks-loop-grid.geeks-lg-handle-inside .elementor-document-save-back-handle .elementor-document-handle__inner::before,
.elementor-widget-geeks-loop-grid.geeks-lg-handle-inside .elementor-document-save-back-handle .elementor-document-handle__inner::after {
	display: none;
}

.elementor-widget-geeks-loop-grid .e-loop-item:has( > .elementor-document-save-back-handle ) {
	position: relative;
}
