/**
 * GSSMG Elementor Extension — frontend styles.
 */

/* Container link ------------------------------------------------------- */
.gssmg-ee-linked {
	cursor: pointer;
}

.gssmg-ee-linked:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

/* Numbered pagination -------------------------------------------------- */
.gssmg-ee-num-pagination .swiper-pagination-bullet.gssmg-ee-numbered-bullet {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: auto;
	min-width: 1.6em;
	height: auto;
	padding: 0.15em 0.5em;
	border-radius: 999px;
	line-height: 1;
	font-size: 0.85em;
	background: transparent;
	color: inherit;
}

.gssmg-ee-num-pagination .swiper-pagination-bullet.gssmg-ee-numbered-bullet.swiper-pagination-bullet-active {
	background: currentColor;
	color: #fff;
}

/* Accordion columns ---------------------------------------------------- *
 * The layout is gated on .gssmg-ee-has-cols, which the script adds only once
 * the column wrappers exist. Two reasons: the column count is now per
 * breakpoint, so the same accordion may legitimately be single-column at some
 * widths, and until the wrappers are built the items are direct children -
 * turning on `display:flex` before that would lay them out in a row.
 * There is deliberately no max-width rule here: which breakpoint gets how many
 * columns is the author's call in the panel, resolved server-side.
 */
.gssmg-ee-accordion-columns .e-n-accordion.gssmg-ee-has-cols {
	display: flex;
	align-items: flex-start;
	gap: var( --n-accordion-gap, 20px );
}

.gssmg-ee-accordion-columns .e-n-accordion.gssmg-ee-has-cols > .gssmg-ee-accordion-col {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	gap: var( --n-accordion-gap, 20px );
	min-inline-size: 0;
}

/* Accordion title icon ------------------------------------------------- */
.e-n-accordion-item-title-text .gssmg-ee-title-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-right: 0.5em;
	flex: 0 0 auto;
	line-height: 1;
}

.e-n-accordion-item-title-text .gssmg-ee-title-icon svg,
.e-n-accordion-item-title-text .gssmg-ee-title-icon img {
	width: 1em;
	height: 1em;
	fill: currentColor;
}

/* Accordion category filter -------------------------------------------- *
 * The panel is built by frontend.js from the categories typed on the items
 * and inserted next to `.e-n-accordion`, above or below it. Everything here
 * is a plain default meant to be overwritten from the Style tab of the
 * widget; the only rules that carry weight are the two that have to beat the
 * widget's own: `hidden` against its `display: flex` on items, and the gap
 * under the last item still on screen.
 */
.gssmg-ee-accordion-filter-host .e-n-accordion-item[hidden] {
	display: none;
}

.gssmg-ee-accordion-filter-host .e-n-accordion .e-n-accordion-item.gssmg-ee-is-last {
	margin-block-end: 0;
}

.gssmg-ee-accordion-filter {
	--gssmg-ee-filter-space: 20px;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-block-end: var( --gssmg-ee-filter-space );
}

.e-n-accordion + .gssmg-ee-accordion-filter {
	margin-block: var( --gssmg-ee-filter-space ) 0;
}

.gssmg-ee-accordion-filter-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.5em 1em;
	border: 1px solid currentColor;
	border-radius: 999px;
	background-color: transparent;
	color: inherit;
	font: inherit;
	line-height: 1.2;
	cursor: pointer;
	transition:
		background-color 150ms ease,
		border-color 150ms ease,
		color 150ms ease;
}

.gssmg-ee-accordion-filter-btn:hover {
	background-color: rgba( 0, 0, 0, 0.05 );
}

.gssmg-ee-accordion-filter-btn.gssmg-ee-is-active {
	background-color: rgba( 0, 0, 0, 0.1 );
}

.gssmg-ee-accordion-filter-btn:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.gssmg-ee-accordion-filter-count {
	font-size: 0.85em;
	opacity: 0.7;
}

.gssmg-ee-accordion-filter-count::before {
	content: "(";
}

.gssmg-ee-accordion-filter-count::after {
	content: ")";
}

/* The filter transition ------------------------------------------------ *
 * frontend.js puts `gssmg-ee-anim` and the chosen effect on the widget, and
 * `--gssmg-ee-filter-duration` holds one half of the change: the items on
 * their way out (`gssmg-ee-is-hiding`) and the ones not arrived yet
 * (`gssmg-ee-is-showing`) share one starting state, and the list is rebuilt
 * in between, while neither is on screen.
 */
.gssmg-ee-accordion-filter-host.gssmg-ee-anim .e-n-accordion-item {
	transition:
		opacity var( --gssmg-ee-filter-duration, 150ms ) ease,
		transform var( --gssmg-ee-filter-duration, 150ms ) ease;
}

.gssmg-ee-accordion-filter-host.gssmg-ee-anim .e-n-accordion-item.gssmg-ee-is-hiding,
.gssmg-ee-accordion-filter-host.gssmg-ee-anim .e-n-accordion-item.gssmg-ee-is-showing {
	opacity: 0;
	pointer-events: none;
}

.gssmg-ee-accordion-filter-host.gssmg-ee-anim-slide-up .e-n-accordion-item.gssmg-ee-is-hiding,
.gssmg-ee-accordion-filter-host.gssmg-ee-anim-slide-up .e-n-accordion-item.gssmg-ee-is-showing {
	transform: translateY( var( --gssmg-ee-filter-shift, 16px ) );
}

.gssmg-ee-accordion-filter-host.gssmg-ee-anim-slide-down .e-n-accordion-item.gssmg-ee-is-hiding,
.gssmg-ee-accordion-filter-host.gssmg-ee-anim-slide-down .e-n-accordion-item.gssmg-ee-is-showing {
	transform: translateY( calc( var( --gssmg-ee-filter-shift, 16px ) * -1 ) );
}

.gssmg-ee-accordion-filter-host.gssmg-ee-anim-zoom .e-n-accordion-item.gssmg-ee-is-hiding,
.gssmg-ee-accordion-filter-host.gssmg-ee-anim-zoom .e-n-accordion-item.gssmg-ee-is-showing {
	transform: scale( var( --gssmg-ee-filter-scale, 0.94 ) );
}

/* The script skips the transition for a visitor who asks for reduced motion;
 * this covers the setting being changed after the page has loaded. */
@media ( prefers-reduced-motion: reduce ) {
	.gssmg-ee-accordion-filter-host.gssmg-ee-anim .e-n-accordion-item {
		transition-duration: 1ms;
	}

	.gssmg-ee-accordion-filter-btn {
		transition-duration: 1ms;
	}
}

/* Reveal on scroll ----------------------------------------------------- *
 * The contract is data attributes, not classes, so the same rules serve both
 * editors: the classic panel emits them from its controls, and on V4 (atomic)
 * elements the author types them into Elementor Pro's Attributes field.
 *
 *   data-gssmg-reveal-threshold  px scrolled before the element appears (required)
 *   data-gssmg-reveal-effect     fade | slide-up | slide-down | zoom | none
 *   data-gssmg-reveal-duration   ms       (V4; the classic panel sets the variable)
 *   data-gssmg-reveal-distance   px or length (V4; same)
 *   data-gssmg-reveal-once       any value but 0/no/false
 *
 * frontend.js adds .gssmg-ee-is-revealed past the threshold and swaps it for
 * .gssmg-ee-is-concealed when the page goes back up. Hidden means
 * `visibility: hidden`: the element keeps its box, drops out of the tab order
 * and the accessibility tree, and ignores clicks.
 *
 * Effects are keyframe animations, not transitions. A transition would have to
 * overwrite the element's `transition` list, and Elementor puts its own hover
 * transitions there on containers. Movement uses the individual `translate` and
 * `scale` properties, which compose with - rather than replace - any transform
 * set in the panel.
 *
 * Two keyframes with the start and end swapped, rather than one played in
 * reverse: a browser does not restart an animation whose name did not change.
 * `visibility` is animated too, so an element fading out stays visible until
 * the end of the animation.
 */
[data-gssmg-reveal-threshold]:not(.gssmg-ee-is-revealed) {
	visibility: hidden;
	opacity: 0;
}

[data-gssmg-reveal-threshold].gssmg-ee-is-revealed {
	animation: gssmg-ee-reveal-in var( --gssmg-ee-reveal-duration, 300ms ) ease-out backwards;
}

[data-gssmg-reveal-threshold].gssmg-ee-is-concealed {
	animation: gssmg-ee-reveal-out var( --gssmg-ee-reveal-duration, 300ms ) ease-in forwards;
}

[data-gssmg-reveal-threshold][data-gssmg-reveal-effect="none"] {
	animation: none;
}

[data-gssmg-reveal-effect="slide-up"] {
	--gssmg-ee-reveal-from-translate: 0 var( --gssmg-ee-reveal-distance, 20px );
}

[data-gssmg-reveal-effect="slide-down"] {
	--gssmg-ee-reveal-from-translate: 0 calc( -1 * var( --gssmg-ee-reveal-distance, 20px ) );
}

[data-gssmg-reveal-effect="zoom"] {
	--gssmg-ee-reveal-from-scale: 0.9;
}

@keyframes gssmg-ee-reveal-in {
	from {
		visibility: hidden;
		opacity: 0;
		translate: var( --gssmg-ee-reveal-from-translate, none );
		scale: var( --gssmg-ee-reveal-from-scale, none );
	}

	to {
		visibility: visible;
		opacity: 1;
		translate: none;
		scale: none;
	}
}

@keyframes gssmg-ee-reveal-out {
	from {
		visibility: visible;
		opacity: 1;
		translate: none;
		scale: none;
	}

	to {
		visibility: hidden;
		opacity: 0;
		translate: var( --gssmg-ee-reveal-from-translate, none );
		scale: var( --gssmg-ee-reveal-from-scale, none );
	}
}

/* Keep the fade, drop the movement. */
@media ( prefers-reduced-motion: reduce ) {
	[data-gssmg-reveal-effect="slide-up"],
	[data-gssmg-reveal-effect="slide-down"],
	[data-gssmg-reveal-effect="zoom"] {
		--gssmg-ee-reveal-from-translate: none;
		--gssmg-ee-reveal-from-scale: none;
	}
}

/* Editor preview: always visible, or the element could not be selected. */
body.elementor-editor-active [data-gssmg-reveal-threshold],
.elementor-edit-mode [data-gssmg-reveal-threshold] {
	visibility: visible;
	opacity: 1;
	animation: none;
}

/* WordPress Menu: show all items --------------------------------------- *
 * Scoped to the main menu only; the mobile dropdown is a separate <nav> and
 * keeps its stock behavior unless the widget's Mobile Menu control is set to
 * Show all items - those rules are the next block down.
 *
 * SmartMenus shows and hides nested lists with an inline `display`, and on a
 * hide it animates height/overflow inline too. `!important` is the only thing
 * that outranks inline styles, so those properties carry it. `position:
 * static` is what makes SmartMenus treat the menu as collapsible: it then
 * ignores hover, and a click on a parent item with a visible submenu follows
 * the link.
 */
.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--main .elementor-nav-menu ul {
	display: block !important;
	position: static !important;
	width: auto;
	height: auto !important;
	overflow: visible !important;
}

/* The widget's Submenu Indicator stays visible (empty it in the panel to drop
 * it), but it must not act as a toggle: SmartMenus treats a click on
 * `.sub-arrow` as "collapse this submenu" and cancels the link. Letting the
 * click pass through to the parent <a> keeps the whole item a plain link. */
.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--main .sub-arrow {
	pointer-events: none;
}

/* Pro turns the indicator of nested parents sideways, where their dropdown
 * flies out. Expanded submenus always open below, so point it the same way
 * as on the top level. */
.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow i,
.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg {
	transform: none;
}

/* Horizontal layout: a top-level item is a flex row. Wrap it so the submenu
 * drops onto its own line below the link, while an enabled divider (the
 * item's ::after) stays on the link's line. */
.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--layout-horizontal .elementor-nav-menu > li {
	flex-wrap: wrap;
	align-content: flex-start;
}

.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--layout-horizontal .elementor-nav-menu > li::after {
	order: 1;
}

.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--layout-horizontal .elementor-nav-menu > li > ul {
	flex-basis: 100%;
	order: 2;
}

/* Line the submenu up with its parent link, which is inset by the widget's
 * Space Between setting. */
.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--layout-horizontal .elementor-nav-menu > li:not(:first-child) > ul {
	margin-inline-start: var( --e-nav-menu-horizontal-menu-item-margin );
}

.gssmg-ee-nav-submenus-expanded .elementor-nav-menu--layout-horizontal .elementor-nav-menu > li:not(:last-child) > ul {
	margin-inline-end: var( --e-nav-menu-horizontal-menu-item-margin );
}

/* WordPress Menu: all items inside the mobile dropdown ------------------- *
 * The widget's Mobile Menu choice keeps the hamburger; the rules below only
 * expand the nested lists once the dropdown <nav> is opened. No media query
 * is needed: Pro only shows that nav below the widget's dropdown breakpoint,
 * so the same inline-display-beating trick as the desktop mode applies as-is.
 */
.gssmg-ee-nav-mobile-expanded .elementor-nav-menu__container.elementor-nav-menu--dropdown .elementor-nav-menu ul {
	display: block !important;
	position: static !important;
	width: auto;
	height: auto !important;
	overflow: visible !important;
}

/* Same contract as the desktop mode: the indicator stays visible but a tap
 * on it must reach the parent link, not toggle the submenu. */
.gssmg-ee-nav-mobile-expanded .elementor-nav-menu__container.elementor-nav-menu--dropdown .sub-arrow {
	pointer-events: none;
}

/* Container carousel --------------------------------------------------- *
 * The contract is the `data-gssmg-carousel` JSON attribute on the container.
 * frontend.js wraps the container's children into .gssmg-ee-carousel-track
 * only while the carousel is on for the current width, and adds
 * .gssmg-ee-carousel-active to the element that holds them: the container
 * itself, or its .e-con-inner when the container is boxed. Every layout rule
 * below is gated on that class, so on a disabled breakpoint the stock
 * Elementor flexbox or grid applies untouched.
 *
 * Custom properties (set on the container by the panel, or inline by
 * frontend.js for V4 elements):
 *
 *   --gssmg-ee-carousel-per-view          slides per view (fractions allowed)
 *   --gssmg-ee-carousel-slide-width       slide width in "Fixed slide width" mode
 *   --gssmg-ee-carousel-bleed             room above/below for shadows
 *   --gssmg-ee-carousel-nav-gap           arrows distance from the slides
 *   --gssmg-ee-carousel-nav-justify       arrows alignment below/above
 *   --gssmg-ee-carousel-arrows-gap        space between the two arrows
 *   --gssmg-ee-carousel-arrow-size        button size
 *   --gssmg-ee-carousel-arrow-padding     room around the icon
 *   --gssmg-ee-carousel-arrow-radius      button radius
 *   --gssmg-ee-carousel-arrow-color(-hover), --gssmg-ee-carousel-arrow-bg(-hover)
 *   --gssmg-ee-carousel-arrow-nudge       hover shift in the arrow direction
 *   --gssmg-ee-carousel-arrow-disabled-opacity
 *
 * The slide gap is the container's own column gap: the track inherits it, and
 * frontend.js mirrors it into --gssmg-ee-carousel-gap for the per-view math.
 *
 * Root selectors carry the attribute inside :is() to outrank the V4 class
 * styles (.elementor .e-xxx) and the container's own display rules.
 */
.gssmg-ee-carousel-active:is( [data-gssmg-carousel], [data-gssmg-carousel] > .e-con-inner ) {
	display: grid;
	grid-template-columns: minmax( 0, 1fr );
	grid-template-rows: none;
	grid-auto-flow: row;
	grid-auto-rows: auto;
	align-content: start;
	align-items: stretch;
	justify-items: stretch;
	row-gap: var( --gssmg-ee-carousel-nav-gap, 16px );
	max-inline-size: 100%;
}

/* A scroll container clips both axes (overflow-x: auto forces overflow-y too).
 * The vertical padding gives protruding content room inside the clip area and
 * the negative margin cancels it, so the slides keep their position. */
.gssmg-ee-carousel-active > .gssmg-ee-carousel-track {
	display: grid;
	grid-auto-flow: column;
	grid-template-columns: none;
	grid-template-rows: none;
	grid-auto-columns: calc( ( 100% - ( var( --gssmg-ee-carousel-per-view, 3 ) - 1 ) * var( --gssmg-ee-carousel-gap, 0px ) ) / var( --gssmg-ee-carousel-per-view, 3 ) );
	column-gap: inherit;
	row-gap: 0;
	align-items: stretch;
	/* `safe` is what keeps a centred row scrollable: plain `center` pushes the
	 * start of an overflowing row out of reach, cutting the first slide off
	 * with no way back to it. */
	justify-content: var( --gssmg-ee-carousel-justify, start );
	padding-block: var( --gssmg-ee-carousel-bleed, 0px );
	margin-block: calc( var( --gssmg-ee-carousel-bleed, 0px ) * -1 );
	overflow-x: auto;
	overflow-y: hidden;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.gssmg-ee-carousel-active > .gssmg-ee-carousel-track::-webkit-scrollbar {
	display: none;
}

.gssmg-ee-carousel-active > .gssmg-ee-carousel-track:focus-visible {
	outline: 2px solid var( --gssmg-ee-carousel-arrow-color, currentColor );
	outline-offset: calc( var( --gssmg-ee-carousel-bleed, 0px ) * -1 + 2px );
}

.gssmg-ee-carousel-size-width.gssmg-ee-carousel-active > .gssmg-ee-carousel-track {
	grid-auto-columns: var( --gssmg-ee-carousel-slide-width, 280px );
}

.gssmg-ee-carousel-size-auto.gssmg-ee-carousel-active > .gssmg-ee-carousel-track {
	grid-auto-columns: max-content;
}

.gssmg-ee-carousel-no-snap.gssmg-ee-carousel-active > .gssmg-ee-carousel-track {
	scroll-snap-type: none;
}

.gssmg-ee-carousel-active > .gssmg-ee-carousel-track > * {
	min-inline-size: 0;
	margin-inline: 0;
	scroll-snap-align: start;
}

/* A slide fills its column; its own width setting would otherwise overflow or
 * underfill it. Content-width slides keep their widths on purpose. */
.gssmg-ee-carousel-active:not(.gssmg-ee-carousel-size-auto) > .gssmg-ee-carousel-track > * {
	inline-size: auto;
	max-inline-size: none;
}

.gssmg-ee-carousel-center.gssmg-ee-carousel-active > .gssmg-ee-carousel-track > * {
	scroll-snap-align: center;
}

/* Arrows. `position: relative` keeps them above the track's bleed area, which
 * the negative margin lays over them. */
.gssmg-ee-carousel-active > .gssmg-ee-carousel-nav {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: var( --gssmg-ee-carousel-nav-justify, center );
	gap: var( --gssmg-ee-carousel-arrows-gap, 12px );
}

/* Everything fits: no arrows. */
.gssmg-ee-carousel-active:not(.gssmg-ee-carousel-overflow) > .gssmg-ee-carousel-nav {
	display: none;
}

/* On the sides: the track and the arrows share one grid cell. */
.gssmg-ee-carousel-nav-sides.gssmg-ee-carousel-active > .gssmg-ee-carousel-track,
.gssmg-ee-carousel-nav-sides.gssmg-ee-carousel-active > .gssmg-ee-carousel-nav {
	grid-area: 1 / 1;
}

.gssmg-ee-carousel-nav-sides.gssmg-ee-carousel-active > .gssmg-ee-carousel-nav {
	align-self: center;
	justify-content: space-between;
	margin-inline: var( --gssmg-ee-carousel-nav-gap, 8px );
	pointer-events: none;
}

/* Arrows from the [gssmg_ee_carousel_nav] shortcode. Hidden while the
 * carousel is off or everything fits, unless hide_inactive="no"; always drawn
 * in the editor so the author can see where they go. */
.gssmg-ee-carousel-external-nav {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var( --gssmg-ee-carousel-arrows-gap, 12px );
}

/* frontend.js adds -shown while the arrows have something to do, or always
 * when the carousel asks to keep them in place. */
.gssmg-ee-carousel-external-nav:not(.gssmg-ee-carousel-external-nav-shown):not(.gssmg-ee-carousel-external-nav-preview) {
	display: none;
}

.gssmg-ee-carousel-external-nav-start {
	justify-content: flex-start;
}

.gssmg-ee-carousel-external-nav-center {
	justify-content: center;
}

.gssmg-ee-carousel-external-nav-end {
	justify-content: flex-end;
}

.gssmg-ee-carousel-external-nav-between {
	justify-content: space-between;
}

/* Specificity is intentionally high to beat theme button resets (Hello
 * Elementor sets border, background and color on button:hover / :focus). */
:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-nav, .gssmg-ee-carousel-external-nav.gssmg-ee-carousel-external-nav ) > .gssmg-ee-carousel-btn {
	display: grid;
	place-items: center;
	box-sizing: border-box;
	inline-size: var( --gssmg-ee-carousel-arrow-size, 44px );
	block-size: var( --gssmg-ee-carousel-arrow-size, 44px );
	min-inline-size: 0;
	margin: 0;
	padding: var( --gssmg-ee-carousel-arrow-padding, 8px );
	border: 0;
	border-radius: var( --gssmg-ee-carousel-arrow-radius, 0 );
	background: var( --gssmg-ee-carousel-arrow-bg, transparent );
	color: var( --gssmg-ee-carousel-arrow-color, currentColor );
	/* Font icons size themselves by font-size; this gives them the same box
	 * an inline SVG gets. */
	font-size: calc( var( --gssmg-ee-carousel-arrow-size, 44px ) - 2 * var( --gssmg-ee-carousel-arrow-padding, 8px ) );
	line-height: 0;
	cursor: pointer;
	pointer-events: auto;
	transition: opacity 0.2s, color 0.2s, background-color 0.2s;
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-nav, .gssmg-ee-carousel-external-nav.gssmg-ee-carousel-external-nav ) > .gssmg-ee-carousel-btn:hover:not(:disabled),
:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-nav, .gssmg-ee-carousel-external-nav.gssmg-ee-carousel-external-nav ) > .gssmg-ee-carousel-btn:focus-visible {
	background: var( --gssmg-ee-carousel-arrow-bg-hover, var( --gssmg-ee-carousel-arrow-bg, transparent ) );
	color: var( --gssmg-ee-carousel-arrow-color-hover, var( --gssmg-ee-carousel-arrow-color, currentColor ) );
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-nav, .gssmg-ee-carousel-external-nav.gssmg-ee-carousel-external-nav ) > .gssmg-ee-carousel-btn:focus {
	background: var( --gssmg-ee-carousel-arrow-bg, transparent );
	color: var( --gssmg-ee-carousel-arrow-color, currentColor );
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-nav, .gssmg-ee-carousel-external-nav.gssmg-ee-carousel-external-nav ) > .gssmg-ee-carousel-btn:focus-visible {
	outline: 2px solid var( --gssmg-ee-carousel-arrow-color, currentColor );
	outline-offset: 2px;
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-nav, .gssmg-ee-carousel-external-nav.gssmg-ee-carousel-external-nav ) > .gssmg-ee-carousel-btn:disabled {
	opacity: var( --gssmg-ee-carousel-arrow-disabled-opacity, 0.3 );
	cursor: default;
}

.gssmg-ee-carousel-btn svg {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	transition: translate 0.2s ease;
}

/* Each direction has its own icon, so only a right-to-left page flips them. */
.gssmg-ee-carousel-btn:dir(rtl) svg {
	scale: -1 1;
}

/* An icon from the panel: a font glyph sized to the button, or an image. */
.gssmg-ee-carousel-btn i,
.gssmg-ee-carousel-btn svg,
.gssmg-ee-carousel-btn img {
	font-size: inherit;
	line-height: 1;
}

.gssmg-ee-carousel-btn img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

.gssmg-ee-carousel-next:hover:not(:disabled) svg,
.gssmg-ee-carousel-prev:dir(rtl):hover:not(:disabled) svg {
	translate: var( --gssmg-ee-carousel-arrow-nudge, 4px ) 0;
}

.gssmg-ee-carousel-prev:hover:not(:disabled) svg,
.gssmg-ee-carousel-next:dir(rtl):hover:not(:disabled) svg {
	translate: calc( var( --gssmg-ee-carousel-arrow-nudge, 4px ) * -1 ) 0;
}

@media ( prefers-reduced-motion: reduce ) {
	.gssmg-ee-carousel-btn svg {
		transition: none;
	}
}

/* Carousel dots --------------------------------------------------------- *
 * One dot per slide, either as a row of its own above or below the slides,
 * between the two arrow buttons when they share an edge, or anywhere on the
 * page through the [gssmg_ee_carousel_dots] shortcode. Custom properties:
 *
 *   --gssmg-ee-carousel-dot-size          dot diameter
 *   --gssmg-ee-carousel-dot-gap           space between the dots
 *   --gssmg-ee-carousel-dots-justify      row alignment in its own row
 *   --gssmg-ee-carousel-dot-radius        dot corners (50% keeps them round)
 *   --gssmg-ee-carousel-dot-color(-hover) inactive and hover color
 *   --gssmg-ee-carousel-dot-color-active  color of the slide in view
 *   --gssmg-ee-carousel-dot-opacity       how faded the other dots are
 */
.gssmg-ee-carousel-active > .gssmg-ee-carousel-dots,
.gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots,
.gssmg-ee-carousel-external-dots {
	display: flex;
	align-items: center;
	justify-content: var( --gssmg-ee-carousel-dots-justify, center );
	gap: var( --gssmg-ee-carousel-dot-gap, 10px );
}

/* Same overlay fix as the arrows: the track's negative bleed margin would
 * otherwise lay over a row of its own. */
.gssmg-ee-carousel-active > .gssmg-ee-carousel-dots {
	position: relative;
	z-index: 1;
}

/* Everything fits: no dots. Merged into the arrows row they share its hide. */
.gssmg-ee-carousel-active:not(.gssmg-ee-carousel-overflow) > .gssmg-ee-carousel-dots {
	display: none;
}

/* Dots from the [gssmg_ee_carousel_dots] shortcode. Hidden while the
 * carousel is off or everything fits, unless hide_inactive="no"; always
 * drawn in the editor so the author can see where they go. */
.gssmg-ee-carousel-external-dots {
	flex-wrap: wrap;
	justify-content: center;
}

.gssmg-ee-carousel-external-dots:not(.gssmg-ee-carousel-external-dots-shown):not(.gssmg-ee-carousel-external-dots-preview) {
	display: none;
}

.gssmg-ee-carousel-external-dots-start {
	justify-content: flex-start;
}

.gssmg-ee-carousel-external-dots-center {
	justify-content: center;
}

.gssmg-ee-carousel-external-dots-end {
	justify-content: flex-end;
}

/* Specificity is intentionally high to beat theme button resets, same as the
 * arrows above. */
:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-external-dots.gssmg-ee-carousel-external-dots ) > .gssmg-ee-carousel-dot {
	box-sizing: border-box;
	flex: 0 0 auto;
	inline-size: var( --gssmg-ee-carousel-dot-size, 10px );
	block-size: var( --gssmg-ee-carousel-dot-size, 10px );
	min-inline-size: 0;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: var( --gssmg-ee-carousel-dot-radius, 50% );
	background: var( --gssmg-ee-carousel-dot-color, currentColor );
	color: inherit;
	font-size: 0;
	line-height: 0;
	opacity: var( --gssmg-ee-carousel-dot-opacity, 0.35 );
	cursor: pointer;
	transition: opacity 0.2s, background-color 0.2s;
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-external-dots.gssmg-ee-carousel-external-dots ) > .gssmg-ee-carousel-dot:hover:not(:disabled),
:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-external-dots.gssmg-ee-carousel-external-dots ) > .gssmg-ee-carousel-dot:focus-visible {
	background: var( --gssmg-ee-carousel-dot-color-hover, var( --gssmg-ee-carousel-dot-color, currentColor ) );
	opacity: 1;
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-external-dots.gssmg-ee-carousel-external-dots ) > .gssmg-ee-carousel-dot:focus-visible {
	outline: 2px solid var( --gssmg-ee-carousel-dot-color-active, var( --gssmg-ee-carousel-dot-color, currentColor ) );
	outline-offset: 2px;
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-external-dots.gssmg-ee-carousel-external-dots ) > .gssmg-ee-carousel-dot.gssmg-ee-carousel-dot-current {
	background: var( --gssmg-ee-carousel-dot-color-active, var( --gssmg-ee-carousel-dot-color, currentColor ) );
	opacity: 1;
}

:is( .gssmg-ee-carousel-active > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-nav > .gssmg-ee-carousel-dots, .gssmg-ee-carousel-external-dots.gssmg-ee-carousel-external-dots ) > .gssmg-ee-carousel-dot:disabled {
	cursor: default;
}

@media ( prefers-reduced-motion: reduce ) {
	.gssmg-ee-carousel-dot {
		transition: none;
	}
}


/* ------------------------------------------------------------------ *
 * Tabs menu shortcode ([gssmg_ee_tabs_menu])
 *
 * The shell around a moved V4 (e-tabs) menu exists only as an Alpine
 * x-data scope - display: contents keeps it out of the box tree so the
 * moved role="tablist" renders exactly where it would have in the
 * original element.
 * ------------------------------------------------------------------ */

.gssmg-ee-atomic-tabs {
	display: contents;
}

/* "Place menu via shortcode" on: the built-in menu hides wherever it still
 * sits inside its element. A menu moved into a placeholder carries
 * .gssmg-ee-tabs-menu-moved, so this never hides the relocated copy - not
 * even when the placeholder lives inside the widget itself. */
[data-gssmg-tabs-menu-source] .elementor-tabs-wrapper:not(.gssmg-ee-tabs-menu-moved),
[data-gssmg-tabs-menu-source] .e-n-tabs-heading:not(.gssmg-ee-tabs-menu-moved),
[data-gssmg-tabs-menu-source] [data-element_type="e-tabs-menu"]:not(.gssmg-ee-tabs-menu-moved) {
	display: none !important;
}
