/**
 * GC Home Carousel.
 * Prefix: .gc-hcar-*  /  --gc-hcar-*
 *
 * A dual section hero slider. Two colour bands meet at a seam; the photo panel is
 * centred on that seam; the copy is anchored to the opposite outer edge with its text
 * aligned to the same edge. Flipping mirrors the whole arrangement exactly.
 *
 * Three things are deliberately independent objects, because tying them together
 * meant moving one moved the others:
 *   1. The seam, which only positions the background split. It has its own position,
 *      its own gradient softness and its own rotation angle.
 *   2. The photo panel, with its own width, height and X/Y nudge. It is centred on the
 *      seam by default and it does NOT rotate with the seam: the angle is applied to
 *      the bands layer alone, so an angled split never skews the photo.
 *   3. The copy, anchored to the outer edge with its own max width.
 *
 * Nothing here uses grid for placement. An earlier grid version coupled the photo's
 * width to the seam, and a flipped photo sitting in column 2 while appearing first in
 * the DOM made auto-placement push the copy into an implicit second row, which stole
 * the row's height and collapsed the panel to 45px. Absolute placement has neither
 * problem and makes the mirror exact.
 *
 * The transition is staged rather than a crossfade: the outgoing photo fades and eases
 * away, the incoming pops up from a slight scale, then the copy lines slide in from
 * above on a stagger. Direction flips the Y sign, so prev reads as going back. The
 * bands nudge in opposite directions for the length of the change.
 *
 * This owns the `.gc-hcar-*` prefix outright. The older `.hero-carousel` rules in
 * components.css and their block in main.js are left in place untouched, because
 * hand-authored Elementor HTML snippets may still use those class names.
 */

.gc-hcar {
	/* Band colours. JS mirrors the active slide's pair onto these, so the whole stage
	   recolours as the slides move. */
	--gc-hcar-band-a: var(--gc-ink);
	--gc-hcar-band-b: var(--gc-blue-dark);

	/* Optional per-band images, layered over the band colour so a transparent
	   pattern still shows the colour behind it. PHP builds these values because the
	   zoom maths needs each image's natural size. */
	--gc-hcar-band-a-img: none;
	--gc-hcar-band-a-size: auto;
	--gc-hcar-band-a-repeat: no-repeat;
	--gc-hcar-band-b-img: none;
	--gc-hcar-band-b-size: auto;
	--gc-hcar-band-b-repeat: no-repeat;

	/* The seam: its own position, softness and angle. */
	--gc-hcar-seam: 42%;
	--gc-hcar-seam-soft: 12%;
	--gc-hcar-seam-angle: 0deg;

	/* The photo panel: its own size and nudge, centred on the seam. */
	--gc-hcar-media-w: 44%;
	--gc-hcar-media-h: 72%;
	--gc-hcar-media-x: 0px;
	--gc-hcar-media-y: 0px;
	--gc-hcar-media-fit: cover;
	--gc-hcar-media-pos: center center;
	--gc-hcar-media-bg: transparent;
	--gc-hcar-radius: var(--gc-radius-md);
	/* No shadow by default. A large soft shadow over a coloured band reads as a
	   translucent glass sheet on the photo rather than as depth. */
	--gc-hcar-media-shadow: none;

	--gc-hcar-height: 640px;
	--gc-hcar-gutter: clamp(20px, 5vw, 64px);
	--gc-hcar-pad-top: 50px;
	--gc-hcar-pad-bottom: 25px;
	/* Pushes the photo and the copy down from the vertical centre together. The stage
	   sits under a sticky header, so dead centre puts the top of the content too close
	   to it. Applied as a translate rather than as padding because both parts are
	   absolutely centred, and padding on the slide would only move the centre by half. */
	--gc-hcar-content-top: 50px;
	--gc-hcar-copy-max: 560px;
	/* Only used by the stacked layout: the desktop stage places the photo and the copy
	   independently, so there is no gap between them to set. */
	--gc-hcar-gap: 28px;

	--gc-hcar-ink: var(--gc-white);
	--gc-hcar-sub: rgba(255, 255, 255, .78);

	--gc-hcar-badge-color: var(--gc-hcar-ink);
	--gc-hcar-badge-bg: rgba(255, 255, 255, .12);
	--gc-hcar-badge-border: rgba(255, 255, 255, .4);

	--gc-hcar-arrow-color: var(--gc-hcar-ink);
	--gc-hcar-arrow-bg: rgba(255, 255, 255, .12);
	--gc-hcar-arrow-border: rgba(255, 255, 255, .28);
	--gc-hcar-dot-color: var(--gc-hcar-ink);

	--gc-hcar-card-w: 320px;
	--gc-hcar-card-h: 420px;
	--gc-hcar-card-body-h: 33.333%;
	--gc-hcar-card-min-h: 320px;
	--gc-hcar-card-bg: var(--gc-white, #FFFFFF);
	--gc-hcar-card-media-bg: var(--gc-blue-light, #EAF3FA);
	--gc-hcar-card-title: var(--gc-ink, #14212B);
	--gc-hcar-card-price: var(--gc-blue-dark, #3D82B3);
	--gc-hcar-card-btn-start: var(--gc-cta-start, #5BA7DB);
	--gc-hcar-card-btn-end: var(--gc-cta-end, #3D82B3);
	--gc-hcar-card-btn-text: #FFFFFF;
	--gc-hcar-card-fit: var(--gc-hcar-media-fit);
	--gc-hcar-card-pos: var(--gc-hcar-media-pos);
	--gc-hcar-card-zoom: 100;
	--gc-hcar-card-pad: 0px;

	--gc-hcar-grid-gap: 10px;
	--gc-hcar-grid-max: 372px;
	--gc-hcar-grid-radius: 12px;
	--gc-hcar-grid-cols: 3;
	--gc-hcar-grid-ratio: 1;
	--gc-hcar-grid-fit: cover;
	--gc-hcar-grid-tile-bg: rgba(255, 255, 255, .1);
	--gc-hcar-grid-tile-border: rgba(255, 255, 255, .22);
	--gc-hcar-grid-active: var(--gc-hcar-ink);

	--gc-hcar-fade-color: #F4F8FB;
	--gc-hcar-fade-h: 25%;
	--gc-hcar-fade-top-h: 25%;

	/* Live drag offset in px, written by JS while a pointer is down. */
	--gc-hcar-drag: 0px;

	/* Autoplay period, mirrored from the data attribute so the dot progress ring runs
	   on exactly the same clock as the timer. */
	--gc-hcar-auto: 6000ms;

	position: relative;
	width: 100%;
	min-height: var(--gc-hcar-height);
	box-sizing: border-box;
	overflow: hidden;
	isolation: isolate;
}

.gc-hcar--full {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
}

.gc-hcar-fade,
.gc-hcar-topfade {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 3;
	pointer-events: none;
}
.gc-hcar-fade {
	bottom: 0;
	height: var(--gc-hcar-fade-h);
	background-image: linear-gradient(0deg, var(--gc-hcar-fade-color) 0%, transparent 100%);
}
.gc-hcar-topfade {
	top: 0;
	height: var(--gc-hcar-fade-top-h);
	background-image: linear-gradient(180deg, var(--gc-hcar-fade-color) 0%, transparent 100%);
}
.gc-hcar--fade { margin-bottom: -1px; }
.gc-hcar--fade-top { margin-top: -1px; }

/* ---- The two bands ----
   The seam is a cut, not a rotation. Both bands fill the stage and each is clipped to
   its side of the seam line, so the angle lives in the edge between them and nothing
   ever turns the photos: whatever the seam is doing, a band image stays level.

   The lean is how far the seam's end wanders from its midpoint, worked out from the
   angle and the stage height so the edge reads as that many degrees. The bands run a
   little past the top and bottom to give the slide-change nudge somewhere to go. */

.gc-hcar-bands {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	overflow: hidden;
	/* where the seam crosses the middle of the stage, and which way it leans */
	--gc-hcar-seam-x: var(--gc-hcar-seam);
	--gc-hcar-lean: calc(tan(var(--gc-hcar-seam-angle)) * var(--gc-hcar-height) * 0.62);
}

.gc-hcar-band {
	position: absolute;
	top: -12%;
	bottom: -12%;
	left: 0;
	right: 0;
	overflow: hidden;
	transition: background-color .85s ease, transform .85s cubic-bezier(.22, 1, .36, 1);
	will-change: transform;
}

.gc-hcar-band::before {
	content: "";
	position: absolute;
	inset: 0;
	background-position: center;
}

/* The two halves of the cut. Left of the line, then right of it. The lower band runs a
   pixel past the line and the upper one lands exactly on it, so the join cannot show a
   hairline of whatever sits behind them. */
.gc-hcar-band--a {
	background-color: var(--gc-hcar-band-a);
	clip-path: polygon(
		0 0,
		calc(var(--gc-hcar-seam-x) + var(--gc-hcar-lean) + 1px) 0,
		calc(var(--gc-hcar-seam-x) - var(--gc-hcar-lean) + 1px) 100%,
		0 100%);
}
.gc-hcar-band--a::before {
	background-image: var(--gc-hcar-band-a-img);
	background-size: var(--gc-hcar-band-a-size);
	background-repeat: var(--gc-hcar-band-a-repeat);
}

.gc-hcar-band--b {
	background-color: var(--gc-hcar-band-b);
	clip-path: polygon(
		calc(var(--gc-hcar-seam-x) + var(--gc-hcar-lean)) 0,
		100% 0,
		100% 100%,
		calc(var(--gc-hcar-seam-x) - var(--gc-hcar-lean)) 100%);
}
.gc-hcar-band--b::before {
	background-image: var(--gc-hcar-band-b-img);
	background-size: var(--gc-hcar-band-b-size);
	background-repeat: var(--gc-hcar-band-b-repeat);
}

/* Soft gradient where the two colours meet. Softness 0 gives a hard edge. This strip is
   the one thing that does turn with the angle, and it is a gradient, not a picture. */
.gc-hcar-bands::after {
	content: "";
	position: absolute;
	top: -60%;
	bottom: -60%;
	left: var(--gc-hcar-seam-x);
	width: var(--gc-hcar-seam-soft);
	transform: translateX(-50%) rotate(var(--gc-hcar-seam-angle));
	background: linear-gradient(90deg, transparent, rgba(0, 0, 0, .16) 50%, transparent);
	opacity: .7;
}

/* Opposing nudge for the length of a slide change. Reversed when going back. */
.gc-hcar.is-changing .gc-hcar-band--a { transform: translateY(-2.2%); }
.gc-hcar.is-changing .gc-hcar-band--b { transform: translateY(2.2%); }
.gc-hcar.is-changing[data-dir="prev"] .gc-hcar-band--a { transform: translateY(2.2%); }
.gc-hcar.is-changing[data-dir="prev"] .gc-hcar-band--b { transform: translateY(-2.2%); }

/* ---- Flipped: exact mirror ----
   The seam measures from the right, the photo centres on the mirrored seam line, the
   copy anchors to the left edge, and the angle inverts so the split leans the same way
   relative to the photo. Every value is the complement of the default. */

/* The line crosses at the mirrored position and leans the other way, and the two bands
   swap sides. Everything else is inherited, so there is one seam, described once. */
.gc-hcar--img-right .gc-hcar-bands {
	--gc-hcar-seam-x: calc(100% - var(--gc-hcar-seam));
	--gc-hcar-lean: calc(tan(var(--gc-hcar-seam-angle)) * var(--gc-hcar-height) * -0.62);
}

.gc-hcar--img-right .gc-hcar-band--a {
	clip-path: polygon(
		calc(var(--gc-hcar-seam-x) + var(--gc-hcar-lean) - 1px) 0,
		100% 0,
		100% 100%,
		calc(var(--gc-hcar-seam-x) - var(--gc-hcar-lean) - 1px) 100%);
}

.gc-hcar--img-right .gc-hcar-band--b {
	clip-path: polygon(
		0 0,
		calc(var(--gc-hcar-seam-x) + var(--gc-hcar-lean)) 0,
		calc(var(--gc-hcar-seam-x) - var(--gc-hcar-lean)) 100%,
		0 100%);
}

.gc-hcar--img-right .gc-hcar-bands::after {
	transform: translateX(-50%) rotate(calc(var(--gc-hcar-seam-angle) * -1));
}

/* ---- Slides ---- */

.gc-hcar-viewport {
	position: relative;
	z-index: 1;
	min-height: var(--gc-hcar-height);
	touch-action: pan-y;
	cursor: grab;
}

.gc-hcar-viewport.is-dragging {
	cursor: grabbing;
}

.gc-hcar-slide {
	position: absolute;
	inset: 0;
	padding: var(--gc-hcar-pad-top) var(--gc-hcar-gutter) var(--gc-hcar-pad-bottom);
	box-sizing: border-box;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity .5s ease, visibility 0s linear .5s;
}

.gc-hcar-slide.is-active {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: opacity .5s ease;
	z-index: 2;
}

/* ---- The photo panel: centred on the seam, upright at any seam angle ---- */

.gc-hcar-media {
	position: absolute;
	z-index: 1;
	top: 50%;
	left: var(--gc-hcar-seam);
	width: var(--gc-hcar-media-w);
	height: var(--gc-hcar-media-h);
	/* Centred on the seam, then offset by the X/Y nudge and the live drag. */
	transform: translate(
		calc(-50% + var(--gc-hcar-media-x) + var(--gc-hcar-drag)),
		calc(-50% + var(--gc-hcar-media-y) + var(--gc-hcar-content-top))
	);
	border-radius: var(--gc-hcar-radius);
	overflow: hidden;
	background: var(--gc-hcar-media-bg);
	box-shadow: var(--gc-hcar-media-shadow);
}

/* Mirrored, so a positive X nudge still moves the panel the same way relative to its
   own side of the stage. */
.gc-hcar--img-right .gc-hcar-media {
	left: calc(100% - var(--gc-hcar-seam));
	transform: translate(
		calc(-50% - var(--gc-hcar-media-x) + var(--gc-hcar-drag)),
		calc(-50% + var(--gc-hcar-media-y) + var(--gc-hcar-content-top))
	);
}

.gc-hcar-media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: var(--gc-hcar-media-fit);
	object-position: var(--gc-hcar-media-pos);
}

/* Product panel: the card fills the same panel a photo would, so every panel
   control (size, nudge, radius, shadow, seam anchoring) keeps working. */
.gc-hcar-media--product {
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	box-shadow: none;
	overflow: visible;
}
.gc-hcar-card {
	position: relative;
	display: flex;
	flex-direction: column;
	width: min(100%, var(--gc-hcar-card-w));
	height: min(100%, var(--gc-hcar-card-h));
	background: var(--gc-hcar-card-bg);
	border-radius: inherit;
	box-shadow: var(--gc-hcar-media-shadow);
}
/* Fixed image shape. The image leads and the card takes whatever height that plus the
   info panel needs, so the shot keeps its ratio however tall the panel around it is.
   The panel still follows the grid, so the card simply centres in it. */
.gc-hcar--card-shape .gc-hcar-card,
.gc-hcar--card-shape.gc-hcar--grid-match-h .gc-hcar-card {
	height: auto;
}
.gc-hcar--card-shape .gc-hcar-card-media {
	flex: 0 0 auto;
	width: 100%;
	aspect-ratio: var(--gc-hcar-card-ratio, 1);
}
.gc-hcar--card-shape .gc-hcar-card-body {
	flex: 0 0 auto;
	min-height: 0;
}

.gc-hcar-card-media {
	position: relative;
	display: block;
	flex: 1 1 auto;
	min-height: 0;
	overflow: hidden;
	border-radius: var(--gc-hcar-radius) var(--gc-hcar-radius) 0 0;
	background: var(--gc-hcar-card-media-bg);
	padding: var(--gc-hcar-card-pad);
	box-sizing: border-box;
}
.gc-hcar-card-media img {
	width: 100%;
	height: 100%;
	object-fit: var(--gc-hcar-card-fit);
	object-position: var(--gc-hcar-card-pos);
	transform: scale(calc(var(--gc-hcar-card-zoom) / 100));
	transform-origin: var(--gc-hcar-card-pos);
}
/* A hard share of the card, never more, so the image above it always keeps the rest.
   Everything inside is sized to fit that share at the smallest card the panel allows,
   which is what the tight padding, the small gap and the clamped name are for. */
.gc-hcar-card-body {
	flex: 0 0 var(--gc-hcar-card-body-h);
	min-height: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 5px;
	padding: 8px 16px;
	text-align: center;
	box-sizing: border-box;
	overflow: hidden;
}
.gc-hcar-card-title {
	/* One line, so a long product name can never push the button out of its share. */
	display: -webkit-box;
	-webkit-line-clamp: 1;
	line-clamp: 1;
	-webkit-box-orient: vertical;
	overflow: hidden;
	width: 100%;
	font-family: var(--gc-font-heading, "Manrope", sans-serif);
	font-weight: 700;
	font-size: 16px;
	line-height: 1.3;
	color: var(--gc-hcar-card-title);
	text-decoration: none;
}
.gc-hcar-card-title:hover { color: var(--gc-hcar-card-price); }
.gc-hcar-card-price { font-weight: 700; font-size: 15px; line-height: 1.2; color: var(--gc-hcar-card-price); }
.gc-hcar-card-price del { opacity: .55; font-weight: 500; margin-right: 6px; }
.gc-hcar-card-price ins { text-decoration: none; }
.gc-hcar-card-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-top: 2px;
	padding: 8px 20px;
	border-radius: var(--gc-radius-pill, 999px);
	background: linear-gradient(135deg, var(--gc-hcar-card-btn-start), var(--gc-hcar-card-btn-end));
	color: var(--gc-hcar-card-btn-text);
	font-family: var(--gc-font-heading, "Manrope", sans-serif);
	font-weight: 600;
	font-size: 14px;
	text-decoration: none;
	box-shadow: var(--gc-shadow-button, 0 6px 16px -2px rgba(91, 167, 219, .3));
	transition: transform .15s ease, filter .15s ease;
}
.gc-hcar-card-btn:hover { transform: translateY(-1px); filter: brightness(1.05); color: var(--gc-hcar-card-btn-text); }
/* Outgoing photo fades and eases away; incoming pops up from a slight scale a beat
   after the change starts, which is what reads as new content arriving. */
.gc-hcar-slide .gc-hcar-media img {
	opacity: 0;
	transform: scale(1.06) translateY(3%);
	transition: opacity .55s ease, transform .8s cubic-bezier(.22, 1, .36, 1);
}

.gc-hcar-slide.is-active .gc-hcar-media img {
	opacity: 1;
	transform: none;
	transition-delay: .12s;
}

.gc-hcar[data-dir="prev"] .gc-hcar-slide .gc-hcar-media img {
	transform: scale(1.06) translateY(-3%);
}

/* The panel scales its image on slide change; a card holds its own zoom instead, so
   the product shot never stretches with the change. */
.gc-hcar-slide .gc-hcar-media--product img,
.gc-hcar-slide.is-active .gc-hcar-media--product img,
.gc-hcar[data-dir="prev"] .gc-hcar-slide .gc-hcar-media--product img {
	transform: scale(calc(var(--gc-hcar-card-zoom) / 100));
}

/* ---- Copy: anchored to the outer edge, text aligned to the same edge ---- */

.gc-hcar-copy {
	position: absolute;
	z-index: 2;
	top: 50%;
	right: var(--gc-hcar-gutter);
	/* Capped so it can never reach across the seam into the photo. */
	width: min(var(--gc-hcar-copy-max), calc(100% - var(--gc-hcar-seam) - var(--gc-hcar-gutter) * 2));
	text-align: right;
	transform: translate(calc(var(--gc-hcar-drag) * .4), calc(-50% + var(--gc-hcar-content-top)));
}

.gc-hcar-copy .gc-hcar-sub {
	margin-left: auto;
	margin-right: 0;
}

.gc-hcar-copy .gc-hcar-actions {
	justify-content: flex-end;
}

.gc-hcar--img-right .gc-hcar-copy {
	right: auto;
	left: var(--gc-hcar-gutter);
	text-align: left;
}

.gc-hcar--img-right .gc-hcar-copy .gc-hcar-sub {
	margin-left: 0;
	margin-right: auto;
}

.gc-hcar--img-right .gc-hcar-copy .gc-hcar-actions {
	justify-content: flex-start;
}

/* Every copy line enters from above on its own step. --i is set per line in the
   markup, so one rule staggers the whole block. */
.gc-hcar-line {
	opacity: 0;
	transform: translateY(-24px);
	transition: opacity .5s ease, transform .7s cubic-bezier(.22, 1, .36, 1);
}

.gc-hcar-slide.is-active .gc-hcar-line {
	opacity: 1;
	transform: none;
	transition-delay: calc(260ms + var(--i, 0) * 80ms);
}

/* Backwards: the lines come up from below instead, so direction is legible. */
.gc-hcar[data-dir="prev"] .gc-hcar-line {
	transform: translateY(24px);
}

.gc-hcar-badge {
	display: flex;
	align-items: center;
	gap: 12px;
	font-family: var(--gc-font-body);
	font-size: .7rem;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--gc-hcar-badge-color);
	margin-bottom: 18px;
}
.gc-hcar-badge::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: var(--gc-hcar-badge-border);
	opacity: .7;
}

.gc-hcar-heading {
	font-family: var(--gc-font-heading);
	font-weight: 700;
	font-size: clamp(2rem, 1.3rem + 2.6vw, 3.4rem);
	line-height: 1.08;
	letter-spacing: -.02em;
	color: var(--gc-hcar-ink);
	margin: 0 0 .5em;
	text-wrap: balance;
}

.gc-hcar-sub {
	font-family: var(--gc-font-body);
	font-size: 1.02rem;
	font-weight: 300;
	line-height: 1.7;
	color: var(--gc-hcar-sub);
	margin: 0 0 2rem;
	max-width: 46ch;
}

.gc-hcar-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
}

.gc-hcar-actions .btn {
	padding: 14px 28px;
	font-size: 15px;
}

/* ---- Product grid: anchored to the outer edge of the photo side ----
   A sibling of the viewport rather than part of a slide, so it stays put while the
   slides change. The width cap is the real distance from the gutter to the panel's
   leading edge, derived from the seam, the panel width and the panel nudge, so the
   grid can never reach the card however those are tuned. That same expression holds
   on both sides, because flipping mirrors all three. */

.gc-hcar-grid {
	position: absolute;
	z-index: 3;
	top: 50%;
	left: var(--gc-hcar-gutter);
	width: min(
		var(--gc-hcar-grid-max),
		calc(var(--gc-hcar-seam) - var(--gc-hcar-media-w) / 2 + var(--gc-hcar-media-x) - var(--gc-hcar-gutter) - 16px)
	);
	transform: translate(calc(var(--gc-hcar-drag) * .4), calc(-50% + var(--gc-hcar-content-top)));
	display: grid;
	grid-template-columns: repeat(var(--gc-hcar-grid-cols), 1fr);
	gap: var(--gc-hcar-grid-gap);
}

.gc-hcar--img-right .gc-hcar-grid {
	left: auto;
	right: var(--gc-hcar-gutter);
}

/* Height matching. The row count follows the responsive column count, so the grid's
   height cannot be derived in CSS; JS measures the grid and writes --gc-hcar-grid-h.
   The fallback keeps the panel at its own height until that first measurement.

   The card height is the floor. A short grid, say a single row of two tiles, would
   otherwise hand the panel a height smaller than the card's own copy needs, and the
   image area, being the only flexible part, would collapse to nothing. */
.gc-hcar--grid-match-h .gc-hcar-media--product {
	height: max(var(--gc-hcar-grid-h, var(--gc-hcar-media-h)), var(--gc-hcar-card-h), var(--gc-hcar-card-min-h));
}

.gc-hcar--grid-match-h .gc-hcar-card {
	height: 100%;
}

.gc-hcar-tile {
	position: relative;
	aspect-ratio: var(--gc-hcar-grid-ratio);
	padding: 0;
	margin: 0;
	border: 1px solid var(--gc-hcar-grid-tile-border);
	border-radius: var(--gc-hcar-grid-radius);
	background: var(--gc-hcar-grid-tile-bg);
	overflow: hidden;
	cursor: pointer;
	appearance: none;
	transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease;
}

.gc-hcar-tile img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: var(--gc-hcar-grid-fit);
	object-position: center;
}

.gc-hcar-tile:hover {
	transform: translateY(-2px);
	border-color: var(--gc-hcar-grid-active);
}

/* Pointer over a tile shades the artwork and names the product. The name sits
   in the middle of the tile, so the shade is even rather than weighted to the
   foot, with a little more depth at the edges to hold the type. */
.gc-hcar-tile::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	opacity: 0;
	pointer-events: none;
	background: radial-gradient(120% 120% at 50% 50%, rgba(6, 16, 26, .62), rgba(6, 16, 26, .86));
	transition: opacity .22s ease;
}
.gc-hcar-tile__name {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 8px 9px;
	font-family: var(--gc-font-body, "Inter", system-ui, sans-serif);
	/* Scales with the tile, so widening the grid does not leave the name small
	   in the middle of it. */
	font-size: clamp(11px, calc(var(--gc-hcar-grid-max, 372px) / 30), 14px);
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: -.005em;
	text-align: center;
	text-wrap: balance;
	color: #fff;
	overflow: hidden;
	opacity: 0;
	transform: translateY(5px);
	pointer-events: none;
	transition: opacity .22s ease, transform .22s ease;
}
.gc-hcar-tile:hover::after,
.gc-hcar-tile:focus-visible::after { opacity: 1; }
.gc-hcar-tile:hover .gc-hcar-tile__name,
.gc-hcar-tile:focus-visible .gc-hcar-tile__name { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	.gc-hcar-tile__name { transition: opacity .22s ease; transform: none; }
}

.gc-hcar-tile.is-active {
	border-color: var(--gc-hcar-grid-active);
	box-shadow: 0 0 0 2px var(--gc-hcar-grid-active);
}

.gc-hcar-tile:focus-visible {
	outline: 2px solid var(--gc-hcar-grid-active);
	outline-offset: 3px;
}

/* ---- Navigation cluster: one centred group, arrows above the dots ---- */

.gc-hcar-nav {
	position: absolute;
	bottom: clamp(20px, 3vw, 36px);
	left: 50%;
	transform: translateX(-50%);
	z-index: 4;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
}

.gc-hcar-nav-arrows {
	display: flex;
	align-items: center;
	gap: 12px;
}

.gc-hcar-arrow {
	position: relative;
	width: 46px;
	height: 46px;
	display: grid;
	place-items: center;
	border: 1px solid var(--gc-hcar-arrow-border);
	border-radius: 50%;
	background: var(--gc-hcar-arrow-bg);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	color: var(--gc-hcar-arrow-color);
	cursor: pointer;
	transition: background .2s ease, transform .2s ease, border-color .2s ease;
}

.gc-hcar-arrow:hover,
.gc-hcar-arrow:focus-visible {
	background: rgba(255, 255, 255, .26);
	border-color: rgba(255, 255, 255, .5);
	transform: scale(1.06);
}

.gc-hcar-arrow svg {
	width: 20px;
	height: 20px;
}

/* ---- Dots, each with an autoplay progress ring ---- */

.gc-hcar-dots {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
}

.gc-hcar-dot {
	position: relative;
	width: 26px;
	height: 26px;
	display: grid;
	place-items: center;
	padding: 0;
	border: none;
	background: none;
	cursor: pointer;
	border-radius: 50%;
}

.gc-hcar-dot::before {
	content: "";
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .45);
	transition: background .25s ease, transform .25s ease;
}

.gc-hcar-dot:hover::before { background: rgba(255, 255, 255, .8); }
.gc-hcar-dot.is-active::before { background: var(--gc-hcar-dot-color); transform: scale(1.15); }

.gc-hcar-dot:focus-visible {
	outline: 2px solid var(--gc-hcar-ink);
	outline-offset: 2px;
}

/* Only the active dot's ring animates, and it restarts each time a slide becomes
   active because JS re-adds the class. */
.gc-hcar-ring {
	position: absolute;
	inset: 0;
	transform: rotate(-90deg);
	pointer-events: none;
}

.gc-hcar-ring circle {
	fill: none;
	stroke: var(--gc-hcar-dot-color);
	stroke-width: 1.5;
	stroke-linecap: round;
	/* r = 11 on a 26 box, so the path length is 2 * pi * 11. */
	stroke-dasharray: 69.1;
	stroke-dashoffset: 69.1;
}

.gc-hcar-dot.is-active .gc-hcar-ring circle {
	animation: gc-hcar-ring var(--gc-hcar-auto) linear forwards;
}

/* Hover, focus or drag pauses autoplay, so the ring pauses with it rather than lying
   about when the next slide lands. */
.gc-hcar.is-paused .gc-hcar-dot.is-active .gc-hcar-ring circle {
	animation-play-state: paused;
}

/* Autoplay off entirely: no ring at all rather than one that never moves. */
.gc-hcar--no-auto .gc-hcar-ring {
	display: none;
}

@keyframes gc-hcar-ring {
	from { stroke-dashoffset: 69.1; }
	to { stroke-dashoffset: 0; }
}

/* ---- Responsive ----
   The seam only works with room either side of it. Below this the stage becomes a
   single stacked column: photo above, copy below, bands split top and bottom. */

@media (max-width: 900px) {
	.gc-hcar {
		--gc-hcar-height: auto;
		--gc-hcar-seam: 52%;
	}

	/* The angle is dropped: an angled seam across a narrow stacked column just clips
	   content. The split goes back to being pure geometry, so the cut is switched off
	   and the bands take a top half and a bottom half. */
	.gc-hcar-band,
	.gc-hcar--img-right .gc-hcar-band {
		clip-path: none;
		top: auto;
		bottom: auto;
		left: -2%;
		right: -2%;
		width: auto;
	}

	.gc-hcar-band--a,
	.gc-hcar--img-right .gc-hcar-band--a { top: -4%; height: calc(var(--gc-hcar-seam) + 4%); }

	.gc-hcar-band--b,
	.gc-hcar--img-right .gc-hcar-band--b { top: var(--gc-hcar-seam); bottom: -4%; height: auto; }

	.gc-hcar.is-changing .gc-hcar-band--a { transform: translateX(-2.2%); }
	.gc-hcar.is-changing .gc-hcar-band--b { transform: translateX(2.2%); }
	.gc-hcar.is-changing[data-dir="prev"] .gc-hcar-band--a { transform: translateX(2.2%); }
	.gc-hcar.is-changing[data-dir="prev"] .gc-hcar-band--b { transform: translateX(-2.2%); }

	.gc-hcar-bands::after,
	.gc-hcar--img-right .gc-hcar-bands::after {
		top: var(--gc-hcar-seam);
		bottom: auto;
		left: 0;
		right: 0;
		width: auto;
		height: var(--gc-hcar-seam-soft);
		/* level: the strip is the divider itself here, and there is no angle to follow */
		transform: translateY(-50%);
		background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .16) 50%, transparent);
	}

	.gc-hcar-viewport {
		min-height: 0;
	}

	/* Back into normal flow so the stage sizes to its tallest slide. */
	.gc-hcar-slide {
		position: relative;
		inset: auto;
		display: flex;
		flex-direction: column;
		gap: var(--gc-hcar-gap);
		padding: calc(var(--gc-hcar-pad-top) + var(--gc-hcar-content-top)) clamp(20px, 5vw, 40px) calc(var(--gc-hcar-pad-bottom) + 80px);
	}

	/* The bar is sticky, so as soon as the page moves it pins over the top of the hero. Every
	   stacked width keeps a bar's worth of clear air above the card, and a top padding and
	   content offset that already add up to more still win. Written as a concrete property,
	   not a variable: both of those are responsive controls, so their values for the device
	   are written on the element and would beat anything set here. */
	.gc-hcar-slide {
		padding-top: max(
			calc(var(--gc-hcar-pad-top) + var(--gc-hcar-content-top)),
			var(--gc-hcar-head-clear, 144px)
		);
	}

	.gc-hcar-slide:not(.is-active) {
		position: absolute;
		inset: 0;
	}

	/* Out of absolute placement: the nudge, the seam centring and the edge anchoring
	   all stop applying, and a ratio box replaces the percentage height. */
	.gc-hcar-media,
	.gc-hcar--img-right .gc-hcar-media {
		position: static;
		top: auto;
		left: auto;
		width: 100%;
		height: auto;
		aspect-ratio: 16 / 10;
		transform: none;
	}

	.gc-hcar-media--product,
	.gc-hcar--img-right .gc-hcar-media--product {
		aspect-ratio: auto;
		height: var(--gc-hcar-card-h);
	}

	/* Stacked, the card sets its own height, so the panel follows the card. */
	.gc-hcar--card-shape .gc-hcar-media--product,
	.gc-hcar--card-shape.gc-hcar--img-right .gc-hcar-media--product {
		height: auto;
	}

	.gc-hcar-copy,
	.gc-hcar--img-right .gc-hcar-copy {
		position: static;
		top: auto;
		left: auto;
		right: auto;
		width: 100%;
		text-align: left;
		transform: none;
	}

	.gc-hcar-copy .gc-hcar-sub,
	.gc-hcar--img-right .gc-hcar-copy .gc-hcar-sub {
		margin-left: 0;
		margin-right: auto;
	}

	.gc-hcar-copy .gc-hcar-actions,
	.gc-hcar--img-right .gc-hcar-copy .gc-hcar-actions {
		justify-content: flex-start;
	}

	.gc-hcar-nav {
		bottom: 26px;
	}

	/* Out of edge anchoring and into the flow below the stage. The slide gives up
	   the space it was reserving for the nav bar, and the grid reserves it instead,
	   since the grid is now the last thing above it. */
	.gc-hcar-grid,
	.gc-hcar--img-right .gc-hcar-grid {
		position: static;
		left: auto;
		right: auto;
		width: auto;
		transform: none;
		padding: 0 clamp(20px, 5vw, 40px) calc(var(--gc-hcar-pad-bottom) + 80px);
	}

	.gc-hcar--has-grid .gc-hcar-slide {
		padding-bottom: var(--gc-hcar-pad-bottom);
	}

	/* The grid runs the full width here, so its height is nothing the card should
	   follow. Back to the card's own height. */
	.gc-hcar--grid-match-h .gc-hcar-media--product,
	.gc-hcar--img-right.gc-hcar--grid-match-h .gc-hcar-media--product {
		height: var(--gc-hcar-card-h);
	}

	.gc-hcar--card-shape.gc-hcar--grid-match-h .gc-hcar-media--product,
	.gc-hcar--card-shape.gc-hcar--img-right.gc-hcar--grid-match-h .gc-hcar-media--product {
		height: auto;
	}
}

@media (max-width: 640px) {
	/* Card width and height are responsive controls, so their mobile values are written on the
	   element and beat any variable set here. The phone card is sized by concrete properties
	   below instead: it fills the column and the shot leads. */
	.gc-hcar {
		--gc-hcar-gutter: 20px;
		--gc-hcar-pad-top: 36px;
		--gc-hcar-pad-bottom: 20px;
		--gc-hcar-content-top: 0px;
		--gc-hcar-gap: 18px;
	}

	.gc-hcar-slide {
		padding: calc(var(--gc-hcar-pad-top) + var(--gc-hcar-content-top)) var(--gc-hcar-gutter) calc(var(--gc-hcar-pad-bottom) + 44px);
	}

	/* restated because the shorthand above resets it */
	.gc-hcar-slide {
		padding-top: max(
			calc(var(--gc-hcar-pad-top) + var(--gc-hcar-content-top)),
			var(--gc-hcar-head-clear, 144px)
		);
	}

	.gc-hcar-media:not(.gc-hcar-media--product),
	.gc-hcar--img-right .gc-hcar-media:not(.gc-hcar-media--product) { aspect-ratio: 16 / 9; }

	/* The shot leads and the card takes whatever that plus the panel needs: a set height
	   cropped to a different shape on every phone. Width is capped rather than filling the
	   column, so the card stays a card and does not become the whole hero. */
	.gc-hcar-media--product,
	.gc-hcar--img-right .gc-hcar-media--product,
	.gc-hcar--grid-match-h .gc-hcar-media--product,
	.gc-hcar--img-right.gc-hcar--grid-match-h .gc-hcar-media--product { height: auto; }

	.gc-hcar-card { width: min(100%, 260px); height: auto; }

	/* 4:3 unless a shape is chosen: the .gc-hcar--card-shape rule above carries the chosen
	   ratio and outranks this, so the literal here is only ever the no-shape case */
	.gc-hcar-card-media {
		flex: 0 0 auto;
		width: 100%;
		aspect-ratio: 4 / 3;
	}

	.gc-hcar-card-body { flex: 0 0 auto; gap: 5px; padding: 12px 14px 14px; }

	.gc-hcar-nav-arrows { display: none; }
	.gc-hcar-nav { bottom: 16px; gap: 0; }

	.gc-hcar-badge {
		font-size: 10.5px;
		letter-spacing: .12em;
		gap: 10px;
		margin-bottom: 14px;
	}
	.gc-hcar-heading { font-size: clamp(1.45rem, 1.1rem + 2.2vw, 1.6rem); margin-bottom: .4em; }
	.gc-hcar-sub { font-size: 14.5px; line-height: 1.5; margin-bottom: 1.25rem; }
	/* stacked rather than wrapped, so two actions are one column of equal blocks instead of
	   a full width button beside a stray half-width one */
	.gc-hcar-actions { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 10px; }
	.gc-hcar-actions .btn { width: 100%; justify-content: center; min-height: 46px; padding: 12px 22px; }

	.gc-hcar-card-title { font-size: 15px; }
	.gc-hcar-card-price { font-size: 14.5px; }
	.gc-hcar-card-btn { padding: 9px 18px; font-size: 13.5px; }

	.gc-hcar-dot::after { content: ""; position: absolute; inset: -6px; }

	.gc-hcar--has-grid .gc-hcar-grid {
		padding: 0 var(--gc-hcar-gutter) calc(var(--gc-hcar-pad-bottom) + 44px);
	}

	.gc-hcar--grid-hide-mobile .gc-hcar-grid {
		display: none;
	}

	.gc-hcar--grid-hide-mobile.gc-hcar--has-grid .gc-hcar-slide {
		padding-bottom: calc(var(--gc-hcar-pad-bottom) + 44px);
	}
}

@media (max-width: 480px) {
	.gc-hcar {
		--gc-hcar-gutter: 16px;
		--gc-hcar-pad-top: 28px;
	}
	.gc-hcar-heading { font-size: 1.45rem; }
	.gc-hcar-card { width: min(100%, 240px); }
}

@media (prefers-reduced-motion: reduce) {
	.gc-hcar-band,
	.gc-hcar-line,
	.gc-hcar-tile,
	.gc-hcar-slide .gc-hcar-media img {
		transition: none;
	}

	.gc-hcar-tile:hover {
		transform: none;
	}

	.gc-hcar.is-changing .gc-hcar-band--a,
	.gc-hcar.is-changing .gc-hcar-band--b,
	.gc-hcar.is-changing[data-dir="prev"] .gc-hcar-band--a,
	.gc-hcar.is-changing[data-dir="prev"] .gc-hcar-band--b {
		transform: none;
	}

	.gc-hcar-slide .gc-hcar-media:not(.gc-hcar-media--product) img,
	.gc-hcar-slide .gc-hcar-line {
		transform: none;
	}

	.gc-hcar-slide.is-active .gc-hcar-media img,
	.gc-hcar-slide.is-active .gc-hcar-line {
		opacity: 1;
	}

	.gc-hcar-slide:not(.is-active) .gc-hcar-media img,
	.gc-hcar-slide:not(.is-active) .gc-hcar-line {
		opacity: 0;
	}

	.gc-hcar-dot.is-active .gc-hcar-ring circle {
		animation: none;
	}
}

/* Eyebrow: one spec across every Gencore widget. Inter 11.5/600/.16em,
   uppercase, no trailing rule. */
.gc-hcar-badge {
	display: block;
	font-family: var(--gc-font-body, "Inter", system-ui, sans-serif);
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	line-height: 1.4;
	margin-bottom: 14px;
}

.gc-hcar-badge::before,
.gc-hcar-badge::after { display: none; }

@media (max-width: 640px) {
	.gc-hcar-badge { font-size: 10.5px; margin-bottom: 12px; }
}
