﻿/**
 * Filter Carousel widget.
 *
 * Everything visual is expressed through the --fc-* tokens declared on the
 * root, so a palette swap is a class swap and every Elementor colour control
 * overrides one variable rather than a scattered set of properties.
 *
 * Motion is GSAP's job whenever GSAP is on the page (see the JS). The rules
 * here cover three cases GSAP cannot: the pre-JS paint, the no-GSAP fallback,
 * and hover/focus states that belong in CSS anyway. The deck is laid out with
 * plain flex until Swiper initialises (.is-ready), so the cards are never a
 * stacked column in the moment before JS runs â€” or at all, if Swiper is
 * missing.
 */

/* ------------------------------------------------------------------ tokens */

.goxom-fc {
	/* Motion â€” the Elementor duration/stagger controls write these, and the JS
	   reads them back so the panel stays the single source of truth. */
	--goxom-fc-anim-dur: 700ms;
	--goxom-fc-anim-stagger: 90ms;
	--goxom-fc-ease: cubic-bezier(.22, 1, .36, 1);

	/* Type. Overridden to `inherit` by --font-theme for sites that would rather
	   keep their own family. */
	--fc-font-display: 'Sora', 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
	--fc-font-body: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

	/* Shape */
	--fc-radius-card: 24px;
	--fc-radius-media: 20px;
	--fc-radius-pill: 999px;
	--fc-radius-btn: 999px;

	--fc-shadow-card: 0 1px 2px rgba(16, 12, 8, .04), 0 12px 28px -14px rgba(16, 12, 8, .18);
	--fc-shadow-card-h: 0 2px 4px rgba(16, 12, 8, .05), 0 30px 60px -22px rgba(16, 12, 8, .32);
	--fc-shadow-rail: inset 0 0 0 1px var(--fc-line);

	/* Width of the content column. Kept as a token because the bleeding deck
	   has to line its first card up with the heading, which means knowing where
	   that column starts. The Content Width control writes both. */
	--fc-content: 1320px;

	position: relative;
	isolation: isolate;
	overflow: hidden;
	padding: 110px 0;
	color: var(--fc-ink);
	background-color: var(--fc-bg);
	font-family: var(--fc-font-body);
	-webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- palettes */

/* Sunset â€” warm sand ground, ember accent, near-black ink. The default. */
.goxom-fc--pal-sunset {
	--fc-bg: #FBF7F3;
	--fc-surface: #FFFFFF;
	--fc-ink: #171412;
	--fc-ink-2: #6E645B;
	--fc-line: rgba(23, 20, 18, .10);
	--fc-accent: #EF5B2B;
	--fc-accent-soft: rgba(239, 91, 43, .10);
	--fc-accent-2: #0F8F7E;
	--fc-grad: linear-gradient(115deg, #FF8347 0%, #EF5B2B 55%, #E0431E 100%);
	--fc-on-accent: #FFFFFF;
	--fc-glow-1: rgba(255, 131, 71, .28);
	--fc-glow-2: rgba(15, 143, 126, .18);
	--fc-glass: rgba(255, 255, 255, .82);
	--fc-glass-ink: #171412;
}

/* Midnight â€” dark ground, violetâ†’cyan accent. */
.goxom-fc--pal-midnight {
	--fc-bg: #0A0D1A;
	--fc-surface: #141A2E;
	--fc-ink: #F4F6FB;
	--fc-ink-2: #99A3BD;
	--fc-line: rgba(255, 255, 255, .12);
	--fc-accent: #7C6BFF;
	--fc-accent-soft: rgba(124, 107, 255, .16);
	--fc-accent-2: #3BC9F5;
	--fc-grad: linear-gradient(115deg, #7C6BFF 0%, #5B8CFF 50%, #3BC9F5 100%);
	--fc-on-accent: #0A0D1A;
	--fc-glow-1: rgba(124, 107, 255, .34);
	--fc-glow-2: rgba(59, 201, 245, .24);
	--fc-glass: rgba(20, 26, 46, .72);
	--fc-glass-ink: #F4F6FB;

	--fc-shadow-card: 0 1px 2px rgba(0, 0, 0, .5), 0 16px 34px -18px rgba(0, 0, 0, .9);
	--fc-shadow-card-h: 0 2px 6px rgba(0, 0, 0, .55), 0 34px 64px -24px rgba(0, 0, 0, 1);
}

/* Emerald â€” mint ground, deep green ink. */
.goxom-fc--pal-emerald {
	--fc-bg: #F0F6FC;
	--fc-surface: #FFFFFF;
	--fc-ink: #0C2338;
	--fc-ink-2: #5A7387;
	--fc-line: rgba(12, 35, 56, .10);
	--fc-accent: #1273C4;
	--fc-accent-soft: rgba(14, 159, 110, .10);
	--fc-accent-2: #F0A93B;
	--fc-grad: linear-gradient(115deg, #3E9BE8 0%, #1273C4 60%, #0B5596 100%);
	--fc-on-accent: #FFFFFF;
	--fc-glow-1: rgba(34, 197, 139, .24);
	--fc-glow-2: rgba(242, 163, 60, .18);
	--fc-glass: rgba(255, 255, 255, .82);
	--fc-glass-ink: #0C2338;
}

/* Legacy â€” the widget's original cyan/navy, kept so pages built against it can
   opt back in rather than being restyled underneath. */
.goxom-fc--pal-legacy {
	--fc-bg: #F4F8FF;
	--fc-surface: #FFFFFF;
	--fc-ink: #16155C;
	--fc-ink-2: #6B7394;
	--fc-line: rgba(22, 21, 92, .14);
	--fc-accent: #1273C4;
	--fc-accent-soft: rgba(22, 164, 200, .10);
	--fc-accent-2: #F2653D;
	--fc-grad: linear-gradient(115deg, #1FC0E4 0%, #1273C4 100%);
	--fc-on-accent: #FFFFFF;
	--fc-glow-1: rgba(22, 164, 200, .22);
	--fc-glow-2: rgba(242, 101, 61, .14);
	--fc-glass: rgba(255, 255, 255, .82);
	--fc-glass-ink: #16155C;
}

/* Type opt-out: fall back to whatever the theme sets. */
.goxom-fc--font-theme {
	--fc-font-display: inherit;
	--fc-font-body: inherit;
}

/* ------------------------------------------------------------------ ground */

/* Two soft colour fields behind everything. Purely decorative, pointer-inert,
   and cheap: two radial gradients on one element rather than blurred boxes. */
.goxom-fc__glow {
	position: absolute;
	inset: -20% -10%;
	z-index: -1;
	pointer-events: none;
	background:
		radial-gradient(42% 46% at 12% 8%, var(--fc-glow-1) 0%, transparent 70%),
		radial-gradient(38% 44% at 88% 82%, var(--fc-glow-2) 0%, transparent 72%);
}

.goxom-fc--no-glow .goxom-fc__glow {
	display: none;
}

/* Stated rather than inherited: the max-width has to include the gutters
   whatever box-sizing the theme happens to set. */
.goxom-fc__inner {
	position: relative;
	box-sizing: border-box;
	max-width: 1320px;
	margin-inline: auto;
	padding-inline: 20px;
}

/* ----------------------------------------------------------------- heading */

/* Text and top-right nav share a row on desktop; the nav drops out of the flow
   entirely when the editor puts the arrows under the deck instead. */
.goxom-fc__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 28px;
	margin-bottom: 38px;
}

/* Takes the whole row by default. A fixed measure here left a dead column on
   the right of every wide screen and pushed a title that would otherwise fit
   onto two lines; the arrows, when present, reserve their own space through
   flex instead. Set a deliberate measure with the Title Max Width control. */
.goxom-fc__head-text {
	flex: 1 1 auto;
	min-width: 0;
}

/* Centre alignment only makes sense with the text on its own line. */
.goxom-fc--head-center .goxom-fc__head {
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.goxom-fc--head-center .goxom-fc__head-text {
	margin-inline: auto;
}

.goxom-fc__subtitle {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	margin-bottom: 16px;
	padding: 7px 16px 7px 12px;
	border-radius: var(--fc-radius-pill);
	font-family: var(--fc-font-body);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--fc-accent);
	background-color: var(--fc-accent-soft);
	box-shadow: inset 0 0 0 1px var(--fc-line);
}

/* The eyebrow's leading dot. Pulses only when the JS says motion is welcome. */
.goxom-fc__spark {
	flex: none;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background-image: var(--fc-grad);
}

.goxom-fc__title {
	margin: 0;
	font-family: var(--fc-font-display);
	font-size: clamp(30px, 4.2vw, 54px);
	line-height: 1.08;
	font-weight: 700;
	letter-spacing: -.03em;
	text-wrap: balance;
	color: var(--fc-ink);
}

/* SplitText's per-character wrapper. */
.goxom-fc__title .goxom-fc__char,
.goxom-fc__title .goxom-fc__word {
	display: inline-block;
	will-change: transform, opacity;
}

/* ------------------------------------------------------------------- pills */

/* A scroll rail rather than a wrapping block: a taxonomy with a dozen terms
   scrolls sideways instead of stacking three rows deep.

   The whole point of the outer element is the overflow affordance. A row that
   simply ran off the edge read as broken text rather than as "there is more
   this way", so the fades and the chevrons are gated on classes the JS sets
   from the actual scroll position â€” they appear only on the side that has
   somewhere to go, and not at all when everything already fits. */
/* A flex box, not a plain block, so the container can never grow taller than
   the pill row it wraps. The fades and chevrons are pinned to this element's
   full height (top:0; bottom:0 / top:50%); left as a block, any stray height
   from a parent or theme rule stretched it, and the right-hand fade dropped
   into a tall white slab hanging below the row. As a flex box its cross size
   is its content's â€” the scroll row â€” and nothing downstream can inflate it. */
.goxom-fc__filters-outer {
	position: relative;
	display: flex;
	margin-bottom: 48px;
}

.goxom-fc__filters-wrap {
	position: relative;
	/* The only flex child: take the full width, and â€” crucially â€” be allowed to
	   shrink below the pill row's natural width, or overflow-x never engages and
	   the row would push the container wide instead of scrolling inside it. */
	flex: 1 1 auto;
	min-width: 0;
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	/* Belongs to the rail, not the page: a scroll here must never drag the
	   section sideways once the row hits its end. */
	overscroll-behavior-x: contain;
}

.goxom-fc__filters-wrap::-webkit-scrollbar {
	display: none;
}

/* Fades to the rail's own surface, since at the point they are visible the
   rail is what is underneath them. */
.goxom-fc__filters-outer::before,
.goxom-fc__filters-outer::after {
	content: "";
	position: absolute;
	/* Only ever as tall as the pill row. The container hugs that height now, so
	   top/bottom:0 would be equivalent â€” but pinning to the top and capping the
	   height means the fade stays a row-height strip even if some later rule
	   gives the container extra height, rather than smearing down the section. */
	top: 0;
	height: 100%;
	max-height: 60px;
	z-index: 2;
	width: 72px;
	opacity: 0;
	pointer-events: none;
	transition: opacity .3s ease;
}

.goxom-fc__filters-outer::before {
	left: 0;
	border-radius: var(--fc-radius-pill) 0 0 var(--fc-radius-pill);
	background: linear-gradient(90deg, var(--fc-surface) 34%, rgba(255, 255, 255, 0) 100%);
}

.goxom-fc__filters-outer::after {
	right: 0;
	border-radius: 0 var(--fc-radius-pill) var(--fc-radius-pill) 0;
	background: linear-gradient(270deg, var(--fc-surface) 34%, rgba(255, 255, 255, 0) 100%);
}

.goxom-fc__filters-outer.can-prev::before,
.goxom-fc__filters-outer.can-next::after {
	opacity: 1;
}

.goxom-fc__rail-btn {
	position: absolute;
	top: 50%;
	z-index: 3;
	display: none;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	margin-top: -17px;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	color: var(--fc-ink);
	background-color: var(--fc-surface);
	box-shadow: 0 2px 10px -2px rgba(0, 0, 0, .22), inset 0 0 0 1px var(--fc-line);
	transition: color .3s var(--goxom-fc-ease), background-color .3s var(--goxom-fc-ease),
	            box-shadow .3s var(--goxom-fc-ease), transform .3s var(--goxom-fc-ease);
}

/* A gradient cannot be transitioned, so the fill is painted on a pseudo that
   fades instead â€” the same trick the carousel arrows use, and the reason those
   ease in while this one used to snap. */
.goxom-fc__rail-btn::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background-image: var(--fc-grad);
	opacity: 0;
	transition: opacity .3s var(--goxom-fc-ease);
}

/* Above the pseudo fill, or the chevron would be painted over by it. */
.goxom-fc__rail-btn svg {
	position: relative;
	width: 15px;
	height: 15px;
	transition: transform .3s var(--goxom-fc-ease);
}

.goxom-fc__rail-btn:hover {
	color: var(--fc-on-accent);
	transform: scale(1.08);
	box-shadow: 0 6px 16px -4px rgba(0, 0, 0, .28), inset 0 0 0 1px transparent;
}

.goxom-fc__rail-btn:hover::before {
	opacity: 1;
}

.goxom-fc__rail-btn:active {
	transform: scale(.96);
}

.goxom-fc__rail-btn:hover svg {
	transform: scale(1.1);
}

.goxom-fc__rail-btn:focus-visible {
	outline: 2px solid var(--fc-accent);
	outline-offset: 2px;
}

.goxom-fc__rail-btn--prev { left: 5px; }
.goxom-fc__rail-btn--next { right: 5px; }

.goxom-fc__filters-outer.can-prev .goxom-fc__rail-btn--prev,
.goxom-fc__filters-outer.can-next .goxom-fc__rail-btn--next {
	display: inline-flex;
}

/* Touch devices swipe the row; a button they would have to reach for is just
   something else covering a pill. */
@media (hover: none) {
	.goxom-fc__rail-btn {
		display: none !important;
	}
}

.goxom-fc--head-center .goxom-fc__filters-wrap {
	text-align: center;
}

.goxom-fc__filters {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px;
	border-radius: var(--fc-radius-pill);
	background-color: var(--fc-surface);
	box-shadow: var(--fc-shadow-rail);
	white-space: nowrap;
}

/* The travelling highlight. JS measures the active pill and drives x/width;
   until it does, it stays invisible and the active pill paints its own fill. */
.goxom-fc__pill-ind {
	position: absolute;
	top: 6px;
	left: 0;
	z-index: 0;
	height: calc(100% - 12px);
	width: 0;
	border-radius: var(--fc-radius-pill);
	background-image: var(--fc-grad);
	opacity: 0;
	pointer-events: none;
	transform-origin: left center;
	will-change: transform, width;
}

/* Fallback easing for the highlight when GSAP is not driving it. */
.goxom-fc:not(.is-gsap) .goxom-fc__pill-ind {
	transition: transform .45s var(--goxom-fc-ease), width .45s var(--goxom-fc-ease), opacity .3s ease;
}

.goxom-fc__filters.is-ready .goxom-fc__pill-ind {
	opacity: 1;
}

.goxom-fc__pill {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 11px 20px;
	border: 0;
	border-radius: var(--fc-radius-pill);
	font-family: var(--fc-font-body);
	font-size: 15px;
	font-weight: 600;
	line-height: 1.2;
	cursor: pointer;
	color: var(--fc-ink-2);
	background-color: transparent;
	transition: color .35s ease;
}

.goxom-fc__pill:hover {
	color: var(--fc-ink);
}

.goxom-fc__pill.is-active {
	color: var(--fc-on-accent);
}

/* No JS, no travelling highlight â€” the active pill fills itself instead. */
.goxom-fc__filters:not(.is-ready) .goxom-fc__pill.is-active {
	background-image: var(--fc-grad);
}

.goxom-fc__pill:focus-visible {
	outline: 2px solid var(--fc-accent);
	outline-offset: 3px;
}

.goxom-fc__pill-count {
	padding: 2px 7px;
	border-radius: var(--fc-radius-pill);
	font-size: 11px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: currentColor;
	/* Tints itself from whatever colour the pill currently is, so it reads on
	   both the rail and the active highlight. The flat fallback comes first for
	   browsers without color-mix(). */
	background-color: rgba(128, 128, 128, .16);
	background-color: color-mix(in srgb, currentColor 15%, transparent);
}

/* CSS-only pill entrance, staggered off the --goxom-fc-pill-i the template
   stamps on each button. This is the no-GSAP path: the JS toggles .is-revealed
   only when it is handling the reveal itself without GSAP, so the two never
   animate the same element twice. */
.goxom-fc--pill-anim .goxom-fc__filters.is-pending .goxom-fc__pill {
	opacity: 0;
}

.goxom-fc--pill-anim .goxom-fc__filters.is-revealed .goxom-fc__pill {
	animation: goxom-fc-pill-in var(--goxom-fc-anim-dur) var(--goxom-fc-ease) both;
	animation-delay: calc(var(--goxom-fc-pill-i, 0) * 70ms);
}

@keyframes goxom-fc-pill-in {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ slider */

.goxom-fc__slider-wrap {
	position: relative;
}

/* The reference design runs the slides past the content column to the screen
   edges. 100vw includes the scrollbar, hence the section's overflow: hidden. */
.goxom-fc--bleed .goxom-fc__slider-wrap {
	width: 100vw;
	margin-left: calc(50% - 50vw);
}

.goxom-fc:not(.goxom-fc--bleed) .goxom-fc__slider-wrap {
	max-width: 1320px;
	margin-inline: auto;
	padding-inline: 20px;
}

/* Room for the hover lift and its shadow, which would otherwise be clipped by
   Swiper's own overflow. */
.goxom-fc__slider {
	box-sizing: border-box;
	overflow: hidden;
	padding-block: 14px 20px;
}

/* A bleeding deck still starts where the heading does â€” running off only the
   right edge reads as "there is more this way", where running off both edges
   just looks unaligned. Slides moving left show through the gutter, which is
   the peek of the previous card the design wants anyway. */
.goxom-fc--bleed .goxom-fc__slider {
	padding-left: max(20px, calc(50vw - (var(--fc-content) / 2) + 20px));
}

/* Pre-init layout, and the permanent layout when Swiper is unavailable: a
   scrollable flex row rather than a stacked column. Swiper takes over the
   wrapper the moment it initialises and .is-ready lands. */
.goxom-fc__slider:not(.is-ready) {
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}

.goxom-fc__slider:not(.is-ready)::-webkit-scrollbar {
	display: none;
}

.goxom-fc__slider:not(.is-ready) .swiper-wrapper {
	display: flex;
	gap: 24px;
	padding-inline: 20px;
}

.goxom-fc__slider:not(.is-ready) .goxom-fc__slide {
	flex: 0 0 clamp(240px, 23%, 340px);
	scroll-snap-align: start;
}

.goxom-fc__slide {
	height: auto;
}

/* Hidden by the filter rather than removed, so Swiper keeps one stable deck. */
.goxom-fc__slide[hidden] {
	display: none;
}

/* ------------------------------------------------------- filter motion (CSS) */

/* With GSAP driving, the tweened inline transforms must not be double-animated
   by a CSS transition on the very same properties. */
.goxom-fc.is-gsap .goxom-fc__slide {
	transition: none !important;
}

/* The no-GSAP path for the deck's entrance and exit. With GSAP present the JS
   never adds these classes and drives transforms directly instead.

   `will-change` is deliberately absent: these transitions run once per filter
   click, and pinning a layer on every slide for the life of the page costs
   more than it saves. */
.goxom-fc[data-filter-anim]:not([data-filter-anim=""]) .goxom-fc__slide {
	transition: opacity var(--goxom-fc-anim-dur) var(--goxom-fc-ease),
	            transform var(--goxom-fc-anim-dur) var(--goxom-fc-ease);
}

/* Leaving is uniform and quicker than arriving â€” a staggered exit reads as
   hesitation, and the incoming stagger is what the eye follows. */
.goxom-fc[data-filter-anim]:not([data-filter-anim=""]) .goxom-fc__slide.is-anim-out {
	transition-duration: calc(var(--goxom-fc-anim-dur) * .5);
	transition-delay: 0ms !important;
	pointer-events: none;
}

.goxom-fc[data-filter-anim="fade"] .goxom-fc__slide.is-anim-in,
.goxom-fc[data-filter-anim="fade"] .goxom-fc__slide.is-anim-out {
	opacity: 0;
}

.goxom-fc[data-filter-anim="rise"] .goxom-fc__slide.is-anim-in {
	opacity: 0;
	transform: translateY(46px);
}

.goxom-fc[data-filter-anim="rise"] .goxom-fc__slide.is-anim-out {
	opacity: 0;
	transform: translateY(-26px);
}

.goxom-fc[data-filter-anim="scale"] .goxom-fc__slide.is-anim-in {
	opacity: 0;
	transform: scale(.84);
}

.goxom-fc[data-filter-anim="scale"] .goxom-fc__slide.is-anim-out {
	opacity: 0;
	transform: scale(.94);
}

/* Perspective has to sit on an ancestor of the rotating element. Swiper
   translates this same wrapper, which does not disturb the perspective it
   establishes for its children. */
.goxom-fc[data-filter-anim="flip"] .swiper-wrapper,
.goxom-fc[data-filter-anim="deck"] .swiper-wrapper {
	perspective: 1400px;
}

.goxom-fc[data-filter-anim="flip"] .goxom-fc__slide {
	transform-origin: center bottom;
}

.goxom-fc[data-filter-anim="flip"] .goxom-fc__slide.is-anim-in {
	opacity: 0;
	transform: rotateX(-42deg);
}

.goxom-fc[data-filter-anim="flip"] .goxom-fc__slide.is-anim-out {
	opacity: 0;
	transform: rotateX(24deg);
}

.goxom-fc[data-filter-anim="skew"] .goxom-fc__slide.is-anim-in {
	opacity: 0;
	transform: translateX(56px) skewX(-8deg);
}

.goxom-fc[data-filter-anim="skew"] .goxom-fc__slide.is-anim-out {
	opacity: 0;
	transform: translateX(-32px) skewX(5deg);
}

/* "deck" is a GSAP-only routine (3D shuffle); without GSAP it reads as a rise,
   which is the closest thing plain CSS can honestly do. */
.goxom-fc[data-filter-anim="deck"] .goxom-fc__slide.is-anim-in {
	opacity: 0;
	transform: translateY(40px) scale(.9);
}

.goxom-fc[data-filter-anim="deck"] .goxom-fc__slide.is-anim-out {
	opacity: 0;
	transform: translateY(-20px) scale(.95);
}

/* -------------------------------------------------------------------- card */

.goxom-fc__card {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 14px 14px 6px;
	border-radius: var(--fc-radius-card);
	background-color: var(--fc-surface);
	box-shadow: var(--fc-shadow-card);
	transition: box-shadow .45s var(--goxom-fc-ease), transform .45s var(--goxom-fc-ease);
}

/* GSAP owns the lift when it is available (it adds .is-gsap to the root), so
   the CSS hover transform is scoped to the fallback path to keep the two from
   fighting over the same transform. */
.goxom-fc__card:hover {
	box-shadow: var(--fc-shadow-card-h);
}

.goxom-fc:not(.is-gsap) .goxom-fc__slide:hover .goxom-fc__card {
	transform: translateY(-8px);
}

/* The flat variant drops the surface entirely â€” image, then text on the
   section ground, as the original design had it. */
.goxom-fc--flat .goxom-fc__card {
	padding: 0;
	background-color: transparent;
	box-shadow: none;
}

.goxom-fc__media {
	position: relative;
	overflow: hidden;
	height: 300px;
	border-radius: var(--fc-radius-media);
	background-color: var(--fc-accent-soft);
}

.goxom-fc__media-link {
	display: block;
	width: 100%;
	height: 100%;
}

.goxom-fc__media img,
.goxom-fc__media-empty {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .8s var(--goxom-fc-ease);
}

.goxom-fc:not(.is-gsap).goxom-fc--zoom .goxom-fc__card:hover .goxom-fc__media img {
	transform: scale(1.08);
}

/* Keeps the glass chips legible over a bright photo. */
.goxom-fc__shade {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient(to top, rgba(0, 0, 0, .38) 0%, rgba(0, 0, 0, .06) 34%, transparent 62%);
}

.goxom-fc__badge {
	position: absolute;
	top: 14px;
	left: 14px;
	z-index: 2;
	padding: 7px 14px;
	border-radius: var(--fc-radius-pill);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .04em;
	color: var(--fc-on-accent);
	background-image: var(--fc-grad);
	box-shadow: 0 6px 18px -8px rgba(0, 0, 0, .55);
}

/* Duration / star rating, read as a frosted chip on the image rather than a
   line of grey text under it. */
.goxom-fc__meta {
	position: absolute;
	left: 14px;
	bottom: 14px;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 7px;
	max-width: calc(100% - 28px);
	padding: 8px 14px;
	border-radius: var(--fc-radius-pill);
	font-size: 13px;
	font-weight: 600;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	color: var(--fc-glass-ink);
	background-color: var(--fc-glass);
	-webkit-backdrop-filter: blur(10px) saturate(140%);
	        backdrop-filter: blur(10px) saturate(140%);
}

.goxom-fc__meta-icon {
	flex: none;
	width: 16px;
	height: 16px;
	color: var(--fc-accent);
}

.goxom-fc__body {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 18px 8px 14px;
}

.goxom-fc--flat .goxom-fc__body {
	padding-inline: 0;
}

.goxom-fc__name {
	margin: 0;
	min-width: 0;
	font-family: var(--fc-font-display);
	font-size: 21px;
	font-weight: 600;
	line-height: 1.25;
	letter-spacing: -.01em;
	color: var(--fc-ink);
}

.goxom-fc__name a {
	color: inherit;
	text-decoration: none;
	background-image: linear-gradient(var(--fc-accent), var(--fc-accent));
	background-repeat: no-repeat;
	background-size: 0 2px;
	background-position: 0 100%;
	transition: color .3s ease, background-size .45s var(--goxom-fc-ease);
}

.goxom-fc__name a:hover {
	color: var(--fc-accent);
	background-size: 100% 2px;
}

.goxom-fc__row--foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: auto;
	padding-block: 14px 0;
	border-top: 1px solid var(--fc-line);
}

.goxom-fc--flat .goxom-fc__row--foot {
	border-top-color: transparent;
	padding-top: 4px;
}

.goxom-fc__price {
	margin: 0;
	flex: none;
	font-family: var(--fc-font-display);
	font-size: 22px;
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -.02em;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
	color: var(--fc-ink);
}

.goxom-fc__price-old {
	margin-right: 5px;
	font-size: .72em;
	font-weight: 500;
	text-decoration: line-through;
	color: var(--fc-ink-2);
}

.goxom-fc__price-affix {
	font-size: .62em;
	font-weight: 600;
	letter-spacing: .02em;
	color: var(--fc-ink-2);
}

.goxom-fc__btn {
	position: relative;
	/* Keeps the -1 fill pseudo inside the button rather than letting it drop
	   behind the card surface. */
	isolation: isolate;
	overflow: hidden;
	flex: none;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 11px 20px;
	border: 1px solid var(--fc-line);
	border-radius: var(--fc-radius-btn);
	font-family: var(--fc-font-body);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	color: var(--fc-ink);
	background-color: transparent;
	transition: color .35s var(--goxom-fc-ease), border-color .35s ease;
}

/* The fill wipes up from the bottom instead of switching background-color, so
   the hover has a direction. */
.goxom-fc__btn::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
	background-image: var(--fc-grad);
	transform: translateY(101%);
	transition: transform .45s var(--goxom-fc-ease);
}

.goxom-fc__btn > * {
	position: relative;
	z-index: 1;
}

.goxom-fc__btn:hover,
.goxom-fc__btn:focus-visible {
	color: var(--fc-on-accent);
	border-color: transparent;
}

.goxom-fc__btn:hover::before,
.goxom-fc__btn:focus-visible::before {
	transform: translateY(0);
}

.goxom-fc__btn-icon {
	width: 15px;
	height: 15px;
	transition: transform .45s var(--goxom-fc-ease);
}

.goxom-fc__btn:hover .goxom-fc__btn-icon {
	transform: translateX(4px);
}

/* --------------------------------------------------------- nav, dots, meter */

.goxom-fc__foot {
	display: flex;
	align-items: center;
	gap: 28px;
	margin-top: 44px;
}

.goxom-fc__nav {
	display: flex;
	align-items: center;
	gap: 12px;
	flex: none;
}

/* The row owns the spacing above it; the buttons carry none of their own.
   Vertical margin on a flex item is centred along with the item â€” a 48px top
   margin here does not push the arrows down 48px, it pushes them 24px below
   the meter they are supposed to sit level with.

   `!important` rather than a specificity war, and this is the case that earns
   it: Elementor's {{WRAPPER}} is already three classes, so the rule it
   generates for a control targeting .goxom-fc__nav lands at (0,4,0) â€” nothing
   written by hand in this file can outrank it. Its CSS is also cached per
   post, so a page saved while Spacing Above still targeted the nav keeps
   serving that rule until the page is re-saved. The control now writes to
   .goxom-fc__foot instead, so there is nothing legitimate left for a vertical
   margin on the nav to carry. */
.goxom-fc__foot .goxom-fc__nav,
.goxom-fc__head .goxom-fc__nav {
	margin-top: 0 !important;
}

.goxom-fc__foot .goxom-fc__nav {
	margin-bottom: 0 !important;
	align-self: center;
}

/* Top-right nav sits in the heading row and hides itself on mobile, where the
   deck is swiped rather than clicked. */
.goxom-fc__nav--top {
	margin-bottom: 6px;
}

.goxom-fc__arrow {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 54px;
	height: 54px;
	padding: 0;
	border: 1px solid var(--fc-line);
	border-radius: 50%;
	cursor: pointer;
	color: var(--fc-ink);
	background-color: var(--fc-surface);
	transition: color .35s ease, border-color .35s ease, box-shadow .35s ease;
}

.goxom-fc__arrow::before {
	content: "";
	position: absolute;
	inset: -1px;
	border-radius: 50%;
	background-image: var(--fc-grad);
	opacity: 0;
	transition: opacity .35s ease;
}

.goxom-fc__arrow svg {
	position: relative;
	width: 20px;
	height: 20px;
}

.goxom-fc__arrow:hover,
.goxom-fc__arrow:focus-visible {
	color: var(--fc-on-accent);
	border-color: transparent;
	box-shadow: 0 14px 30px -14px var(--fc-accent);
}

.goxom-fc__arrow:hover::before,
.goxom-fc__arrow:focus-visible::before {
	opacity: 1;
}

.goxom-fc__arrow:focus-visible {
	outline: 2px solid var(--fc-accent);
	outline-offset: 3px;
}

/* Swiper marks the ends when looping is off â€” say so rather than leaving a
   button that silently does nothing. */
.goxom-fc__arrow[disabled],
.goxom-fc__arrow--disabled {
	opacity: .35;
	cursor: default;
	pointer-events: none;
}

/* A thin position meter reads better under a bleeding deck than a row of dots,
   and gives GSAP something continuous to drive. */
.goxom-fc__progress {
	position: relative;
	flex: 1 1 auto;
	height: 3px;
	border-radius: 999px;
	overflow: hidden;
	background-color: var(--fc-line);
}

.goxom-fc__progress-bar {
	position: absolute;
	inset: 0;
	transform-origin: left center;
	transform: scaleX(0);
	border-radius: inherit;
	background-image: var(--fc-grad);
}

/* GSAP tweens this transform when it is present; the transition is the
   fallback path's easing, scoped so the two never both run. */
.goxom-fc:not(.is-gsap) .goxom-fc__progress-bar {
	transition: transform .5s var(--goxom-fc-ease);
}

.goxom-fc__dots {
	position: static;
	flex: 1 1 auto;
	text-align: center;
}

.goxom-fc__dots .swiper-pagination-bullet {
	background-color: var(--fc-ink-2);
	transition: width .35s var(--goxom-fc-ease), background-color .35s ease;
}

.goxom-fc__dots .swiper-pagination-bullet-active {
	width: 26px;
	border-radius: 999px;
	background-color: var(--fc-accent);
}

/* --------------------------------------------------------------- notices */

.goxom-fc__notice,
.goxom-fc__empty {
	padding: 26px;
	margin-inline: 20px;
	border: 1px dashed var(--fc-line);
	border-radius: var(--fc-radius-media);
	text-align: center;
	font-weight: 500;
	color: var(--fc-ink);
	background-color: var(--fc-accent-soft);
}

/* ------------------------------------------------------------ breakpoints */

@media (max-width: 1024px) {
	.goxom-fc__nav--top {
		display: none;
	}
}

@media (max-width: 767px) {
	.goxom-fc {
		padding: 70px 0;
	}

	.goxom-fc__inner {
		padding-inline: 16px;
	}

	.goxom-fc__head {
		flex-direction: column;
		align-items: flex-start;
		margin-bottom: 28px;
	}

	.goxom-fc__filters-outer {
		margin-bottom: 32px;
	}

	.goxom-fc__foot {
		flex-direction: column-reverse;
		gap: 22px;
		margin-top: 30px;
	}

	.goxom-fc__progress,
	.goxom-fc__dots {
		width: 100%;
	}

	.goxom-fc__media {
		height: 260px;
	}

	.goxom-fc__name {
		font-size: 19px;
	}

	.goxom-fc__price {
		font-size: 20px;
	}

	.goxom-fc__arrow {
		width: 48px;
		height: 48px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.goxom-fc *,
	.goxom-fc *::before {
		transition: none !important;
		animation: none !important;
	}

	.goxom-fc--zoom .goxom-fc__card:hover .goxom-fc__media img,
	.goxom-fc__rail-btn:hover,
	.goxom-fc__rail-btn:active,
	.goxom-fc__rail-btn:hover svg {
		transform: none;
	}

	/* The JS skips the filter animation here too, but a slide must never be
	   left stranded at opacity 0 if it is mid-swap when the setting changes. */
	.goxom-fc--pill-anim .goxom-fc__pill,
	.goxom-fc__slide.is-anim-in,
	.goxom-fc__slide.is-anim-out {
		opacity: 1 !important;
		transform: none !important;
	}

	.goxom-fc__progress-bar {
		transform: scaleX(1);
	}
}
