/* GC Solari Board — split-flap product tiles. Scope: .gc-solari
   The card face is the shop archive card, so this file only owns the board and
   the leaf that folds on the card's middle.

   One leaf does the whole fold, exactly as a real Solari unit does. It is a
   half height panel hinged on the card's middle line, and it sweeps in a single
   uninterrupted turn from -180deg, where it lies over the top half, to 0deg,
   where it lies over the bottom half. Its two faces carry the two halves it
   needs, so nothing is swapped in flight and no script runs while it moves.

   Three layers: base is the outgoing card, cover is the incoming card's top half
   waiting underneath the leaf, and the leaf turns over on top of both.

     leaf back  : outgoing top half, the face you see at -180deg
     cover      : incoming top half, uncovered as the leaf sweeps away
     leaf front : incoming bottom half, the face you see at 0deg
     base       : outgoing card, covered by the leaf when it lands */

.gc-solari, .gc-solari *, .gc-solari *::before, .gc-solari *::after { box-sizing: border-box; }

.gc-solari {
	--gc-solari-cols: 5;
	--gc-solari-gap: 30px;
	--gc-solari-fold: 400ms;
	--gc-solari-tile-max: 280px;
	--gc-solari-depth: 1100px;
	--gc-solari-lap: 2px;
	--gc-solari-ease: cubic-bezier(.36, .02, .38, 1);
	width: 100%;
	font-family: var(--gc-font-body, "Inter", system-ui, sans-serif);
}

.gc-solari__head { max-width: 640px; margin: 0 auto 28px; text-align: center; }
.gc-solari__eyebrow {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-bottom: 12px;
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--gc-blue-dark, #3D82B3);
}
.gc-solari__eyebrow::before,
.gc-solari__eyebrow::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: currentColor;
	opacity: .28;
}
.gc-solari__title {
	margin: 0;
	font-family: var(--gc-font-heading, "Manrope", system-ui, sans-serif);
	font-weight: 700;
	font-size: clamp(1.5rem, 1.3rem + .9vw, 2.1rem);
	line-height: 1.14;
	letter-spacing: -.022em;
	text-wrap: balance;
	color: var(--gc-ink, #14212B);
}
.gc-solari__lead { margin: 10px 0 0; font-size: 15px; line-height: 1.55; color: var(--gc-muted, #5A6B75); }

.gc-solari__board {
	display: grid;
	grid-template-columns: repeat(var(--gc-solari-cols), minmax(0, 1fr));
	gap: var(--gc-solari-gap);
	max-width: calc(
		var(--gc-solari-cols) * var(--gc-solari-tile-max)
		+ (var(--gc-solari-cols) - 1) * var(--gc-solari-gap)
	);
	margin-inline: auto;
	perspective: var(--gc-solari-depth);
	perspective-origin: 50% 44%;
}

/* The tile is held at the whole pixel height the script measured, and every one
   of its four layers is cut from that same number. Left to stretch with the grid
   row it lands on a fractional height, the halves are cut from a rounded one,
   and the card the leaf sets down sits a fraction of a pixel off the card the
   base holds: that is the nudge at the end of a fold. A locked tile also means a
   card swapping in cannot relevel the row and shift the tiles beside it. */
.gc-solari__tile { position: relative; height: var(--gc-solari-h, auto); contain: layout; }
.gc-solari__base { position: relative; z-index: 0; height: 100%; }
.gc-solari__base > .gc-shop__card { height: 100%; }

/* Two lines of name on every card, so a one line product does not make its row
   shorter than the rest of the board. */
.gc-solari .gc-shop__name { min-height: 2.6em; }

/* The card is a flex column at a fixed height, and the square image is the one
   part of it that would rather resize than let the body take the slack. Pinned,
   so a spare pixel is spent on the body and the artwork stays the same size in
   all four copies of the card. */
.gc-solari .gc-shop__media { flex: 0 0 auto; }

/* No hover lift anywhere on the board. A tile is three stacked copies of a
   card and only one of them can be hovered, so a lift on that one slides it out
   of register with the other two, and anything hanging off the card edge (the
   badges) tears away from the artwork. */
.gc-solari .gc-shop__card,
.gc-solari .gc-shop__card:hover {
	transform: none;
	transition: none;
}
.gc-solari .gc-shop__card:hover .gc-shop__media img { transform: none; }

/* Badges and the review chip hang past the card edge, so they cannot ride a
   half height window. They fade out as the leaf leaves the top half and fade
   back in on the card that landed, once the leaf is out of the way.

   Landing needs a state of its own. The card that lands is the node the leaf was
   carrying, moved into the base, and moving a node cancels whatever it was
   transitioning: it would arrive at full opacity in one frame however long the
   fade is set to. So it lands under is-landing, which holds it transparent with
   no transition, and dropping that class a frame later is what the fade runs
   from. */
.gc-solari .gc-badges,
.gc-solari .gc-review-peek {
	transition: opacity 300ms ease 60ms;
}
.gc-solari__tile.is-flip .gc-badges,
.gc-solari__tile.is-flip .gc-review-peek {
	opacity: 0;
	transition: opacity 150ms ease;
}
.gc-solari__tile.is-landing .gc-badges,
.gc-solari__tile.is-landing .gc-review-peek {
	opacity: 0;
	transition: none;
}

/* Both halves are half height windows onto a whole card. Aligning the card to
   the top or the bottom of its window picks the half, so there is no clipping
   maths and no clip-path to re-rasterise on every frame. */
/* The fold layers only exist while a tile is turning. Left on show at rest, the
   leaf is a 3D transformed layer rasterised separately from the card beneath
   it, and the two disagree by a fraction of a pixel along the hinge: that is
   the line across the middle of every card. At rest only the base paints. */
.gc-solari__cover,
.gc-solari__leaf { visibility: hidden; }
.gc-solari__tile.is-flip .gc-solari__cover,
.gc-solari__tile.is-flip .gc-solari__leaf { visibility: visible; }

.gc-solari__cover,
.gc-solari__face {
	overflow: hidden;
	display: flex;
	pointer-events: none;
}
/* The card must keep its whole height inside a half height window and overflow
   it, so the window shows one half. The shop card sets height:100%, which in a
   half height box would squash the entire card into it and make both faces show
   the same thing. */
.gc-solari__cover > .gc-shop__card,
.gc-solari__face > .gc-shop__card {
	width: 100%;
	height: var(--gc-solari-h, auto);
	flex: 0 0 auto;
	transition: none;
	transform: none;
	box-shadow: none;
}
.gc-solari__cover > .gc-shop__card img,
.gc-solari__face > .gc-shop__card img { transition: none; }

.gc-solari__cover {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 1;
	height: calc(var(--gc-solari-h, 100%) / 2 + var(--gc-solari-lap));
	align-items: flex-start;
}

/* Hinged on the card's middle, which the overlap puts a pixel below the leaf's
   own top edge. At rest the leaf sits at -180deg carrying the card already on
   screen, so it is an exact overlay of the top half and never has to be shown
   or hidden. That also means its layer is already rastered when a fold starts. */
.gc-solari__leaf {
	position: absolute;
	left: 0;
	right: 0;
	top: calc(var(--gc-solari-h, 100%) / 2 - var(--gc-solari-lap));
	z-index: 2;
	height: calc(var(--gc-solari-h, 100%) / 2 + var(--gc-solari-lap));
	transform-origin: 50% var(--gc-solari-lap);
	transform: rotateX(-180deg);
	transform-style: preserve-3d;
	pointer-events: none;
}
.gc-solari__face {
	position: absolute;
	inset: 0;
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
}
.gc-solari__face--front { align-items: flex-end; }
.gc-solari__face--back { align-items: flex-start; transform: rotateX(180deg); }

/* Handed to the compositor for the length of the turn. Half a dozen leaves are
   in flight at any moment during a wave, and each one is a 3D layer carrying a
   product image: without the hint they are rasterised as the turn starts, which
   is the stutter at the front of a fold. */
.gc-solari__tile.is-flip .gc-solari__leaf {
	animation: gc-solari-fold var(--gc-solari-fold) var(--gc-solari-ease) forwards;
	will-change: transform;
}
@keyframes gc-solari-fold {
	from { transform: rotateX(-180deg); }
	to { transform: rotateX(0deg); }
}

/* Reduced motion: the card crosses over instead of folding. */
.gc-solari__base { transition: opacity 240ms ease; }
.gc-solari__tile.is-fade .gc-solari__base { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
	.gc-solari__tile.is-flip .gc-solari__leaf { animation: none; }
}

/* How many tiles the board holds is decided server side, so a five across board
   becomes five rows deep on a phone. The columns control drops to three then two
   with the breakpoints, and these keep the board two rows at each of them by
   dropping the tiles that would fall past the second row. The script leaves a
   tile it cannot measure out of the wave, so a dropped tile costs nothing. */
/* Elementor's own breakpoints, because the columns control is what changes on
   them: three across from 1024 down, two from 767 down.

   The count is set here as well as on the control. A board printed by the theme
   rather than placed in Elementor is an ad hoc element, and Elementor only
   generates control CSS for elements saved on a page, so for the shop board
   every selector driven control is inert and the stylesheet is all there is: it
   was holding five columns on a phone. A board placed in Elementor overrides
   this from its own responsive values, which are the same three and two. */
@media (max-width: 1024px) {
	.gc-solari { --gc-solari-cols: 3; }
	.gc-solari__head { margin-bottom: 20px; }
	.gc-solari__board { gap: 16px; }
	.gc-solari__tile:nth-child(n+7) { display: none; }
}

@media (max-width: 767px) {
	.gc-solari { --gc-solari-cols: 2; }
	.gc-solari__board { gap: 12px; }
	.gc-solari__tile:nth-child(n+5) { display: none; }
	.gc-solari .gc-shop__body { padding: .8rem .85rem 1rem; }
	.gc-solari .gc-shop__cat { font-size: .6rem; letter-spacing: .1em; margin-bottom: .3rem; }
	.gc-solari .gc-shop__name { font-size: .88rem; min-height: 2.4em; }
	.gc-solari .gc-shop__price { font-size: .95rem; margin-top: .45rem; }
	.gc-solari .gc-shop__price del { font-size: .8rem; }
	.gc-solari .gc-shop__cta { font-size: .78rem; padding-top: .7rem; }
	.gc-solari .gc-shop__cta svg { width: 13px; height: 13px; }
}
