/* Global Custom Fields — frontend button styling */

.octgf-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	text-decoration: none;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.2s ease, opacity 0.2s ease;
}
.octgf-btn:hover {
	opacity: 0.95;
}
.octgf-btn .octgf-btn-icon {
	display: inline-flex;
	align-items: center;
}
.octgf-btn .octgf-btn-icon svg {
	width: 1em;
	height: 1em;
	fill: currentColor;
}

/* Sensible defaults if the widget is used without style tweaks */
.octgf-call-btn {
	background: #2563eb;
	color: #fff;
	padding: 12px 24px;
	border-radius: 6px;
}
.octgf-whatsapp-btn {
	background: #25d366;
	color: #062e17;
	padding: 12px 24px;
	border-radius: 6px;
}

/* Inline text links from shortcodes */
.octgf-phone-link,
.octgf-whatsapp-link {
	text-decoration: none;
}

/* Widget looping animations (opt-in per device via the widget's Animation control).
   animation-name/duration/iteration are applied by Elementor; these define the frames. */
@keyframes octgf-pulse {
	0%, 100% { transform: scale( 1 ); }
	50%      { transform: scale( 1.06 ); }
}
@keyframes octgf-bounce {
	0%, 100%   { transform: translateY( 0 ); }
	50%        { transform: translateY( -6px ); }
}
@keyframes octgf-float {
	0%, 100% { transform: translateY( 0 ); }
	50%      { transform: translateY( -4px ); }
}
@keyframes octgf-grow {
	0%   { transform: scale( 1 ); }
	50%  { transform: scale( 1.04 ); }
	100% { transform: scale( 1 ); }
}
@media ( prefers-reduced-motion: reduce ) {
	.octgf-btn,
	.octgf-sb-btn { animation: none !important; }
}

/* Safety net: never leave our contact buttons stuck hidden. Elementor adds
   `elementor-invisible` (visibility:hidden; opacity:0) whenever a setting named
   `animation` is present and waits for its own entrance-animation JS to reveal
   the element. Our looping/hover animation controls are now `octgf_`-prefixed to
   avoid that collision, but this guarantees any legacy `animation` value lingering
   in saved element data can never hide the button on the front end. */
.elementor-widget-octgf-call-button.elementor-invisible,
.elementor-widget-octgf-whatsapp-button.elementor-invisible {
	visibility: visible !important;
	opacity: 1 !important;
	animation: none !important;
}

/* =========================================================================
   Sticky Buttons — vertical bar stuck to the middle of the screen edge
   ========================================================================= */
.octgf-sb {
	position: fixed;
	top: 50%;
	transform: translateY( calc( -50% + var( --octgf-sb-offset, 0px ) ) );
	z-index: 99990;
	display: flex;
	flex-direction: column;
	gap: var( --octgf-sb-gap, 10px );
}
.octgf-sb-left {
	left: 0;
	align-items: flex-start;
}
.octgf-sb-right {
	right: 0;
	align-items: flex-end;
}

.octgf-sb-btn {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-width: var( --octgf-sb-size, 52px );
	height: var( --octgf-sb-size, 52px );
	padding: 0;
	background: var( --octgf-sb-bg, #2563eb );
	color: var( --octgf-sb-color, #fff );
	text-decoration: none;
	font-size: calc( var( --octgf-sb-size, 52px ) * 0.42 );
	line-height: 1;
	box-shadow: 0 4px 14px rgba( 0, 0, 0, 0.22 );
	transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
}
.octgf-sb-btn:hover {
	color: var( --octgf-sb-color, #fff );
	filter: brightness( 1.08 );
	box-shadow: 0 8px 20px rgba( 0, 0, 0, 0.28 );
}

.octgf-sb-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 1em;
	height: 1em;
}
.octgf-sb-icon svg {
	display: block;
	width: 1em;
	height: 1em;
	fill: currentColor;
}
.octgf-sb-icon img {
	display: block;
	width: 1em;
	height: 1em;
	object-fit: contain;
}
.octgf-sb-icon .dashicons {
	width: 1em;
	height: 1em;
	font-size: 1em;
}
.octgf-sb-label {
	font-size: 14px;
	font-weight: 600;
	white-space: nowrap;
}

/* Explicit color on the inner elements: theme link rules (a, a:visited,
   #page a …) can outrank .octgf-sb-btn and repaint it, but they only reach
   the icon/label through inheritance — a direct declaration here wins. */
.octgf-sb-btn .octgf-sb-icon,
.octgf-sb-btn .octgf-sb-label {
	color: var( --octgf-sb-color, #fff );
}

/* --- Shapes ------------------------------------------------------------ */
/* Bar shapes (tab / square): stretch every button to the width of the widest
   one so mixed label lengths still form one clean, even column. Circles keep
   their natural size (stretching would distort them). */
.octgf-sb-shape-tab,
.octgf-sb-shape-square {
	align-items: stretch;
}
.octgf-sb-shape-tab .octgf-sb-btn,
.octgf-sb-shape-square .octgf-sb-btn {
	width: auto;
}
.octgf-sb-shape-circle .octgf-sb-btn {
	border-radius: 50%;
}
.octgf-sb-shape-circle.octgf-sb-left .octgf-sb-btn   { margin-left: 12px; }
.octgf-sb-shape-circle.octgf-sb-right .octgf-sb-btn  { margin-right: 12px; }
.octgf-sb-shape-square .octgf-sb-btn {
	border-radius: 10px;
}
.octgf-sb-shape-square.octgf-sb-left .octgf-sb-btn   { margin-left: 12px; }
.octgf-sb-shape-square.octgf-sb-right .octgf-sb-btn  { margin-right: 12px; }
/* Edge tab: flush to the screen edge, rounded on the inner side only. */
.octgf-sb-right.octgf-sb-shape-tab .octgf-sb-btn { border-radius: 10px 0 0 10px; }
.octgf-sb-left.octgf-sb-shape-tab .octgf-sb-btn  { border-radius: 0 10px 10px 0; }

/* --- Display modes ------------------------------------------------------
   Desktop and mobile modes live in mutually exclusive media queries so they
   can never fight each other across the breakpoint. */
@media ( min-width: 783px ) {
	/* Icon only: the label becomes a slide-out hover tooltip (absolute →
	   never shifts siblings; pure CSS). */
	.octgf-sb-desk-icon .octgf-sb-label {
		position: absolute;
		top: 50%;
		background: var( --octgf-sb-bg, #2563eb );
		color: var( --octgf-sb-color, #fff );
		padding: 9px 14px;
		border-radius: 8px;
		box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.2 );
		opacity: 0;
		pointer-events: none;
		transition: opacity 0.2s ease, transform 0.2s ease;
	}
	.octgf-sb-right.octgf-sb-desk-icon .octgf-sb-label {
		right: calc( 100% + 10px );
		transform: translateY( -50% ) translateX( 8px );
	}
	.octgf-sb-right.octgf-sb-desk-icon .octgf-sb-btn:hover .octgf-sb-label {
		opacity: 1;
		transform: translateY( -50% ) translateX( 0 );
	}
	.octgf-sb-left.octgf-sb-desk-icon .octgf-sb-label {
		left: calc( 100% + 10px );
		transform: translateY( -50% ) translateX( -8px );
	}
	.octgf-sb-left.octgf-sb-desk-icon .octgf-sb-btn:hover .octgf-sb-label {
		opacity: 1;
		transform: translateY( -50% ) translateX( 0 );
	}
	/* Text only. */
	.octgf-sb-desk-text .octgf-sb-icon {
		display: none;
	}
	.octgf-sb-desk-text .octgf-sb-btn {
		width: auto;
		padding: 0 16px;
	}
	/* Icon + text. */
	.octgf-sb-desk-both .octgf-sb-btn {
		width: auto;
		padding: 0 16px 0 12px;
	}
}

/* --- Icon position relative to the label (Icon + Text mode) -------------
   Physical left/right regardless of site direction; harmless in icon-only /
   text-only modes because only one of the two elements renders. */
.octgf-sb-icon-right .octgf-sb-btn { flex-direction: row-reverse; }
[dir="rtl"] .octgf-sb-icon-left .octgf-sb-btn,
.rtl .octgf-sb-icon-left .octgf-sb-btn { flex-direction: row-reverse; }
[dir="rtl"] .octgf-sb-icon-right .octgf-sb-btn,
.rtl .octgf-sb-icon-right .octgf-sb-btn { flex-direction: row; }
.octgf-sb-icon-top .octgf-sb-btn { flex-direction: column; }
.octgf-sb-icon-bottom .octgf-sb-btn { flex-direction: column-reverse; }

/* Stacked (above/below) needs room to grow past the fixed button height. */
@media ( min-width: 783px ) {
	.octgf-sb-icon-top.octgf-sb-desk-both .octgf-sb-btn,
	.octgf-sb-icon-bottom.octgf-sb-desk-both .octgf-sb-btn {
		height: auto;
		min-height: var( --octgf-sb-size, 52px );
		padding: 10px 14px;
		gap: 6px;
	}
}
/* --- Animations (reuse the shared keyframes above) ---------------------- */
.octgf-sb-anim-pulse .octgf-sb-btn  { animation: octgf-pulse 2s ease-in-out infinite; }
.octgf-sb-anim-bounce .octgf-sb-btn { animation: octgf-bounce 1.6s ease-in-out infinite; }
.octgf-sb-anim-float .octgf-sb-btn  { animation: octgf-float 2.4s ease-in-out infinite; }
.octgf-sb-anim-grow .octgf-sb-btn   { animation: octgf-grow 2s ease-in-out infinite; }
.octgf-sb-anim-hover .octgf-sb-btn:hover { transform: scale( 1.08 ); }

/* RTL sites: keep label text direction correct. */
.rtl .octgf-sb-label,
[dir="rtl"] .octgf-sb-label {
	direction: rtl;
}

/* --- Mobile overrides (WP admin breakpoint, matches admin.css) ----------
   Each mobile mode explicitly resets what the desktop modes set; these rules
   sit later in the file with matching-or-higher specificity, so they win. */
@media ( max-width: 782px ) {
	/* Icon only. */
	.octgf-sb.octgf-sb-mob-icon .octgf-sb-icon {
		display: flex;
	}
	.octgf-sb.octgf-sb-mob-icon .octgf-sb-btn {
		width: var( --octgf-sb-size, 52px );
		min-width: var( --octgf-sb-size, 52px );
		padding: 0;
	}
	.octgf-sb.octgf-sb-mob-icon .octgf-sb-label {
		position: absolute;
		top: 50%;
		background: var( --octgf-sb-bg, #2563eb );
		color: var( --octgf-sb-color, #fff );
		font-size: 13px;
		padding: 8px 12px;
		border-radius: 8px;
		box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.2 );
		opacity: 0;
		pointer-events: none;
		transition: opacity 0.2s ease, transform 0.2s ease;
	}
	.octgf-sb-right.octgf-sb-mob-icon .octgf-sb-label {
		right: calc( 100% + 10px );
		left: auto;
		transform: translateY( -50% ) translateX( 8px );
	}
	.octgf-sb-right.octgf-sb-mob-icon .octgf-sb-btn:hover .octgf-sb-label,
	.octgf-sb-right.octgf-sb-mob-icon .octgf-sb-btn:focus .octgf-sb-label {
		opacity: 1;
		transform: translateY( -50% ) translateX( 0 );
	}
	.octgf-sb-left.octgf-sb-mob-icon .octgf-sb-label {
		left: calc( 100% + 10px );
		right: auto;
		transform: translateY( -50% ) translateX( -8px );
	}
	.octgf-sb-left.octgf-sb-mob-icon .octgf-sb-btn:hover .octgf-sb-label,
	.octgf-sb-left.octgf-sb-mob-icon .octgf-sb-btn:focus .octgf-sb-label {
		opacity: 1;
		transform: translateY( -50% ) translateX( 0 );
	}

	/* Text only. */
	.octgf-sb.octgf-sb-mob-text .octgf-sb-icon {
		display: none;
	}
	.octgf-sb.octgf-sb-mob-text .octgf-sb-btn {
		width: auto;
		padding: 0 14px;
	}
	.octgf-sb.octgf-sb-mob-text .octgf-sb-label,
	.octgf-sb.octgf-sb-mob-both .octgf-sb-label {
		position: static;
		background: transparent;
		color: inherit;
		font-size: 13px;
		padding: 0;
		border-radius: 0;
		box-shadow: none;
		opacity: 1;
		pointer-events: auto;
		transform: none;
		transition: none;
	}

	/* Icon + text. */
	.octgf-sb.octgf-sb-mob-both .octgf-sb-icon {
		display: flex;
	}
	.octgf-sb.octgf-sb-mob-both .octgf-sb-btn {
		width: auto;
		padding: 0 14px 0 10px;
	}
	/* Stacked icon (above/below) needs room to grow past the fixed height. */
	.octgf-sb-icon-top.octgf-sb-mob-both .octgf-sb-btn,
	.octgf-sb-icon-bottom.octgf-sb-mob-both .octgf-sb-btn {
		height: auto;
		min-height: var( --octgf-sb-size, 52px );
		padding: 8px 12px;
		gap: 5px;
	}
}

/* --- Per-device visibility (keep last so it always wins) ---------------- */
@media ( min-width: 783px ) {
	.octgf-sb-hide-desktop { display: none !important; }
}
@media ( max-width: 782px ) {
	.octgf-sb-hide-mobile { display: none !important; }
}

/* =========================================================================
   Sticky Buttons — minimize / restore
   The × above the bar tucks the whole bar off-screen, leaving a slim edge
   handle (the same button, restyled) that brings it back. The bar keeps its
   vertical centering transform; minimizing only adds a translateX.
   ========================================================================= */
.octgf-sb-collapsible {
	transition: transform 0.28s ease;
}

.octgf-sb-noanim {
	transition: none !important;
}

/* Hardened against theme `button` styles: every box property is explicit and
   the selector is scoped to out-rank `button[type=button]` theme rules. */
.octgf-sb .octgf-sb-min {
	position: absolute;
	top: -34px;
	appearance: none;
	-webkit-appearance: none;
	box-sizing: border-box;
	width: 26px;
	height: 26px;
	min-width: 0;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	outline: none;
	border-radius: 50%;
	background: #fff !important;
	color: #50575e !important;
	box-shadow: 0 2px 10px rgba( 0, 0, 0, 0.28 );
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: inherit;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	z-index: 1;
	transition: background 0.15s ease, transform 0.15s ease, color 0.15s ease;
}
/* Every interactive state pinned with !important — themes style
   button:hover/:focus/:active (often via #id selectors) and would otherwise
   repaint the control dark until it loses focus. */
.octgf-sb .octgf-sb-min:hover,
.octgf-sb .octgf-sb-min:focus,
.octgf-sb .octgf-sb-min:active {
	background: #fff !important;
	color: #1d2327 !important;
	outline: none;
}
.octgf-sb .octgf-sb-min:hover {
	transform: scale( 1.1 );
}
.octgf-sb-right .octgf-sb-min { right: 0; }
.octgf-sb-left .octgf-sb-min  { left: 0; }
/* Circle / square shapes keep a 12px edge margin on their buttons — align. */
.octgf-sb-shape-circle.octgf-sb-right .octgf-sb-min,
.octgf-sb-shape-square.octgf-sb-right .octgf-sb-min { right: 12px; }
.octgf-sb-shape-circle.octgf-sb-left .octgf-sb-min,
.octgf-sb-shape-square.octgf-sb-left .octgf-sb-min  { left: 12px; }

/* The × is drawn with two centered bars (a text glyph never sits perfectly
   centered — its baseline offset depends on the theme's font). */
.octgf-sb .octgf-sb-min-x {
	position: relative;
	display: block;
	width: 12px;
	height: 12px;
	font-size: 0;
	color: transparent;
}
.octgf-sb .octgf-sb-min-x::before,
.octgf-sb .octgf-sb-min-x::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 12px;
	height: 2px;
	border-radius: 1px;
	background: #50575e;
	transform: translate( -50%, -50% ) rotate( 45deg );
}
.octgf-sb .octgf-sb-min-x::after {
	transform: translate( -50%, -50% ) rotate( -45deg );
}
.octgf-sb .octgf-sb-min:hover .octgf-sb-min-x::before,
.octgf-sb .octgf-sb-min:hover .octgf-sb-min-x::after {
	background: #1d2327;
}

/* Chevron (pure CSS): points away from the edge, i.e. "pull the bar back". */
.octgf-sb-min-chev {
	display: none;
	width: 7px;
	height: 7px;
	border-left: 2px solid #fff;
	border-bottom: 2px solid #fff;
	transform: rotate( 45deg );
	margin-inline-start: 3px;
}

/* --- Minimized: slide the bar out, keep a slim handle at the edge -------- */
.octgf-sb-minimized.octgf-sb-right {
	transform: translateY( calc( -50% + var( --octgf-sb-offset, 0px ) ) ) translateX( calc( 100% + 16px ) );
}
.octgf-sb-minimized.octgf-sb-left {
	transform: translateY( calc( -50% + var( --octgf-sb-offset, 0px ) ) ) translateX( calc( -100% - 16px ) );
}

.octgf-sb-minimized .octgf-sb-btn {
	pointer-events: none;
}

.octgf-sb-minimized .octgf-sb-min {
	top: 0;
	bottom: 0;
	width: 22px;
	height: auto;
	border-radius: 0;
	background: #2563eb !important;
	color: #fff !important;
	box-shadow: 0 4px 14px rgba( 0, 0, 0, 0.22 );
}
.octgf-sb-minimized .octgf-sb-min:hover,
.octgf-sb-minimized .octgf-sb-min:focus,
.octgf-sb-minimized .octgf-sb-min:active {
	background: #1d4ed8 !important;
	color: #fff !important;
	transform: none;
}
/* The bar is translated 100% + 16px off-screen, so the container's near edge
   sits 16px past the viewport; -38px (= 22px handle + that 16px) parks the
   handle exactly flush with the screen edge, fully visible. */
.octgf-sb-minimized.octgf-sb-right .octgf-sb-min {
	right: auto;
	left: -38px;
	border-radius: 11px 0 0 11px;
}
.octgf-sb-minimized.octgf-sb-left .octgf-sb-min {
	left: auto;
	right: -38px;
	border-radius: 0 11px 11px 0;
}

.octgf-sb-minimized .octgf-sb-min-x {
	display: none;
}
.octgf-sb-minimized .octgf-sb-min-chev {
	display: block;
}
/* Left-side bar: the handle chevron points right (toward the content). */
.octgf-sb-minimized.octgf-sb-left .octgf-sb-min-chev {
	transform: rotate( 225deg );
	margin-inline-start: 0;
	margin-inline-end: 3px;
}

/* =========================================================================
   Sticky Buttons — bottom-corner position (merged from Contact Bubbles)
   In bottom mode --octgf-sb-offset is the distance from the bottom edge and
   --octgf-sb-offset-x the distance from the side edge.
   ========================================================================= */
.octgf-sb-vpos-bottom {
	top: auto;
	bottom: var( --octgf-sb-offset, 20px );
	transform: none;
}
.octgf-sb-vpos-bottom.octgf-sb-right { right: var( --octgf-sb-offset-x, 20px ); }
.octgf-sb-vpos-bottom.octgf-sb-left  { left: var( --octgf-sb-offset-x, 20px ); }

/* Bottom corner sits away from the edge, so shape margins are unnecessary. */
.octgf-sb-vpos-bottom.octgf-sb-shape-circle .octgf-sb-btn,
.octgf-sb-vpos-bottom.octgf-sb-shape-square .octgf-sb-btn {
	margin-left: 0;
	margin-right: 0;
}

/* Minimized in bottom mode: slide sideways only (no vertical centering term);
   the extra offset-x keeps the handle flush with the screen edge. */
.octgf-sb-minimized.octgf-sb-vpos-bottom.octgf-sb-right {
	transform: translateX( calc( 100% + 16px + var( --octgf-sb-offset-x, 20px ) ) );
}
.octgf-sb-minimized.octgf-sb-vpos-bottom.octgf-sb-left {
	transform: translateX( calc( -100% - 16px - var( --octgf-sb-offset-x, 20px ) ) );
}

/* =========================================================================
   Sticky Buttons — circle "FAB" styling
   Circles read like a classic floating chat button: a big solid glyph on a
   flat colored disc with a soft drop shadow, and the label as a
   speech bubble in the button colors with a small arrow pointing at the circle.
   In Icon + Text mode the bubble is always visible; in Icon-only mode it is
   the hover tooltip. The bubble opens toward the screen center.
   ========================================================================= */
/* Declared on the button (not the bar) because --octgf-sb-bg / --octgf-sb-color
   are set inline on each .octgf-sb-btn; on the bar they would resolve to the
   fallback blue. */
.octgf-sb-shape-circle .octgf-sb-btn {
	--octgf-sb-bubble-bg: var( --octgf-sb-bg, #2563eb );
	--octgf-sb-bubble-color: var( --octgf-sb-color, #fff );
}
.octgf-sb-shape-circle .octgf-sb-btn {
	font-size: calc( var( --octgf-sb-size, 52px ) * 0.62 );
	box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.28 );
}
.octgf-sb-shape-circle .octgf-sb-btn:hover {
	filter: none;
	box-shadow: 0 10px 24px rgba( 0, 0, 0, 0.34 );
}

/* Shared bubble arrow (icon-only tooltip and always-on Icon + Text bubble). */
.octgf-sb-shape-circle .octgf-sb-label::after {
	content: "";
	position: absolute;
	top: 50%;
	width: 0;
	height: 0;
	border: 7px solid transparent;
	transform: translateY( -50% );
}
.octgf-sb-shape-circle.octgf-sb-right .octgf-sb-label::after {
	left: 100%;
	border-left-color: var( --octgf-sb-bubble-bg );
}
.octgf-sb-shape-circle.octgf-sb-left .octgf-sb-label::after {
	right: 100%;
	border-right-color: var( --octgf-sb-bubble-bg );
}

/* Bubble skin shared by every floating-label mode on circles. Repeated per
   mode below so it outranks the generic mode rules (same specificity, later). */
@media ( min-width: 783px ) {
	.octgf-sb-shape-circle.octgf-sb-desk-icon .octgf-sb-label,
	.octgf-sb-shape-circle.octgf-sb-desk-both .octgf-sb-label {
		background: var( --octgf-sb-bubble-bg );
		color: var( --octgf-sb-bubble-color );
		border-radius: 10px;
		padding: 9px 14px;
		font-size: 14px;
		box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.22 );
	}
	.octgf-sb-shape-circle.octgf-sb-desk-icon .octgf-sb-btn .octgf-sb-label,
	.octgf-sb-shape-circle.octgf-sb-desk-both .octgf-sb-btn .octgf-sb-label {
		color: var( --octgf-sb-bubble-color );
	}
	/* Icon + Text on a circle: keep the circle, float the label as a bubble.
	   Overrides the pill padding / flex-direction of the generic both-mode. */
	.octgf-sb-shape-circle.octgf-sb-desk-both .octgf-sb-btn {
		width: var( --octgf-sb-size, 52px );
		min-width: var( --octgf-sb-size, 52px );
		height: var( --octgf-sb-size, 52px );
		min-height: 0;
		padding: 0;
		flex-direction: row;
	}
	.octgf-sb-shape-circle.octgf-sb-desk-both .octgf-sb-label {
		position: absolute;
		top: 50%;
		pointer-events: none;
	}
	.octgf-sb-shape-circle.octgf-sb-right.octgf-sb-desk-both .octgf-sb-label {
		right: calc( 100% + 12px );
		transform: translateY( -50% );
	}
	.octgf-sb-shape-circle.octgf-sb-left.octgf-sb-desk-both .octgf-sb-label {
		left: calc( 100% + 12px );
		transform: translateY( -50% );
	}
	/* Hover tooltip: sit a little further out to leave room for the arrow. */
	.octgf-sb-shape-circle.octgf-sb-right.octgf-sb-desk-icon .octgf-sb-label { right: calc( 100% + 12px ); }
	.octgf-sb-shape-circle.octgf-sb-left.octgf-sb-desk-icon .octgf-sb-label  { left: calc( 100% + 12px ); }
	/* Text-only renders the label inline inside the button: no arrow. */
	.octgf-sb-shape-circle.octgf-sb-desk-text .octgf-sb-label::after { display: none; }
}
@media ( max-width: 782px ) {
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-icon .octgf-sb-label,
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-both .octgf-sb-label {
		background: var( --octgf-sb-bubble-bg );
		color: var( --octgf-sb-bubble-color );
		border-radius: 10px;
		padding: 8px 12px;
		font-size: 13px;
		box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.22 );
	}
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-icon .octgf-sb-btn .octgf-sb-label,
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-both .octgf-sb-btn .octgf-sb-label {
		color: var( --octgf-sb-bubble-color );
	}
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-both .octgf-sb-btn {
		width: var( --octgf-sb-size, 52px );
		min-width: var( --octgf-sb-size, 52px );
		height: var( --octgf-sb-size, 52px );
		min-height: 0;
		padding: 0;
		flex-direction: row;
	}
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-both .octgf-sb-label {
		position: absolute;
		top: 50%;
		pointer-events: none;
		opacity: 1;
		transition: none;
	}
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-right.octgf-sb-mob-both .octgf-sb-label {
		right: calc( 100% + 12px );
		left: auto;
		transform: translateY( -50% );
	}
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-left.octgf-sb-mob-both .octgf-sb-label {
		left: calc( 100% + 12px );
		right: auto;
		transform: translateY( -50% );
	}
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-right.octgf-sb-mob-icon .octgf-sb-label { right: calc( 100% + 12px ); }
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-left.octgf-sb-mob-icon .octgf-sb-label  { left: calc( 100% + 12px ); }
	.octgf-sb.octgf-sb-shape-circle.octgf-sb-mob-text .octgf-sb-label::after { display: none; }
}

/* Full-disc brand SVGs (WhatsApp): on circles the artwork IS the button, so
   stretch it edge to edge; the disc inside the SVG carries --octgf-sb-bg. */
.octgf-sb-shape-circle .octgf-sb-icon svg.octgf-svg-full {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border-radius: 50%;
}

/* ---------- Listing Grid (v3.12) ---------- */

/*
 * Live filter (v3.17). The scope is a plain block that wraps everything the
 * widget prints, so a filter can replace the grid, the slider, the pagination
 * and the empty message in one go. It is printed only when a Filter ID is set,
 * and every style below it is written on descendants, so it changes nothing
 * about the layout.
 */
.octgf-listing-scope {
	display: block;
}

.octgf-listing-scope.is-filtering {
	opacity: 0.55;
	transition: opacity 0.15s ease;
}

/* Nothing inside is clickable while the new page is on its way. */
.octgf-listing-scope.is-filtering a,
.octgf-listing-scope.is-filtering button {
	pointer-events: none;
}

.octgf-listing {
	display: grid;
	grid-template-columns: repeat(var(--octgf-cols, 3), minmax(0, 1fr));
	column-gap: var(--octgf-gap-x, var(--octgf-gap, 24px));
	row-gap: var(--octgf-gap-y, var(--octgf-gap, 24px));
	margin: 0;
	padding: 0;
	list-style: none;
}
.octgf-listing__item {
	min-width: 0;
}
.octgf-listing-equal-yes .octgf-listing__item > .elementor {
	height: 100%;
}
/*
 * "Make the whole item a link" (v3.20.1): an empty overlay stretched over the
 * item, printed as its last child. It used to be a wrapper <a> around the item
 * markup, which is invalid the moment the template holds a link of its own and
 * made browsers re-parse — and visually break — the card.
 */
.octgf-listing__item--linked {
	position: relative;
}
.octgf-listing__item--linked > .octgf-listing__link {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1;
	display: block;
	font-size: 0;
	color: inherit;
	text-decoration: none;
	/*
	 * The overlay takes no pointer events, so hover effects inside the card
	 * and the links the template prints keep working exactly as they did.
	 * listing.js follows the overlay for a click anywhere else in the item;
	 * keyboard focus and Enter are unaffected by pointer-events.
	 */
	pointer-events: none;
}
.octgf-listing__item--linked {
	cursor: pointer;
}
.octgf-listing__item--linked :where(a, button, input, select, textarea, label) {
	cursor: auto;
}
.octgf-listing__item--linked :where(a, button) {
	cursor: pointer;
}
/* Visible keyboard focus, since the overlay itself shows nothing. */
.octgf-listing__link:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}
.octgf-listing-empty {
	margin: 0;
	opacity: 0.7;
}
.octgf-listing-pagination {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: 24px;
}
.octgf-listing-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 36px;
	height: 36px;
	padding: 0 10px;
	border: 1px solid currentColor;
	border-radius: 6px;
	text-decoration: none;
	color: inherit;
	line-height: 1;
}
.octgf-listing-pagination .page-numbers.current {
	background: currentColor;
}
.octgf-listing-pagination .page-numbers.current::after {
	content: none;
}
.octgf-listing-pagination a.page-numbers:hover {
	opacity: 0.75;
}
.octgf-listing-pagination .page-numbers.current {
	color: #fff;
	background: #1d2939;
	border-color: #1d2939;
}

/* ---------- Listing Grid: masonry, slider, load more (v3.14) ---------- */

/* Masonry: CSS columns — items keep their height, reading order goes down
   each column (same trade-off as any CSS-only masonry). */
.octgf-listing--masonry {
	display: block;
	column-count: var(--octgf-cols, 3);
	column-gap: var(--octgf-gap-x, 24px);
}
.octgf-listing--masonry .octgf-listing__item {
	break-inside: avoid;
	margin-bottom: var(--octgf-gap-y, 24px);
}

/* "Correct first/last row gap": trim the outer vertical space. */
.octgf-listing-edge-yes .octgf-listing {
	margin-block: calc(var(--octgf-gap-y, 24px) / -2);
}
.octgf-listing-edge-yes .octgf-listing__item {
	padding-block: calc(var(--octgf-gap-y, 24px) / 2);
}
.octgf-listing-edge-yes .octgf-listing {
	row-gap: 0;
}

/* Slider */
.octgf-listing-slider {
	position: relative;
}
.octgf-listing-slider__track {
	position: relative;
}
.octgf-listing-slider .octgf-listing.swiper {
	display: block;
	column-gap: 0;
	row-gap: 0;
}

/* Until the slider starts (or if its library never arrives), lay the slides
   out as the grid the Columns Number control asks for, instead of letting
   Swiper's own CSS give each slide the full width. */
.octgf-listing-slider:not(.octgf-slider-ready) .swiper-wrapper {
	display: grid;
	grid-template-columns: repeat(var(--octgf-cols, 3), minmax(0, 1fr));
	align-items: stretch;
}

/* The gap between slides is slide padding, not Swiper's spaceBetween, so the
   Horizontal Gap control applies live while editing. */
.octgf-listing-slider .octgf-listing__item {
	box-sizing: border-box;
	padding-inline-end: var(--octgf-gap-x, 24px);
}
.octgf-listing-slider .swiper-wrapper {
	align-items: stretch;
}
.octgf-listing-slider .octgf-listing__item {
	height: auto;
}
/* Arrows. Specific enough to beat a theme's generic button rules, and the
   built-in SVG always points LEFT — the rules below turn it the right way
   round for each button in each text direction. */
.octgf-listing-slider__track .octgf-listing-arrow,
.octgf-listing-slider__track button.octgf-listing-arrow {
	position: absolute;
	inset-block-start: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 44px;
	height: 44px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: #fff;
	color: #1d2939;
	box-shadow: 0 2px 10px rgba(16, 24, 40, .14);
	line-height: 1;
	font-size: 18px;
	cursor: pointer;
	transform: translateY(-50%);
	transition: color .15s ease, background-color .15s ease;
}
.octgf-listing-slider__track .octgf-listing-arrow--prev {
	inset-inline-start: 0;
}
.octgf-listing-slider__track .octgf-listing-arrow--next {
	inset-inline-end: 0;
}
.octgf-listing-slider__track .octgf-listing-arrow > * {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.octgf-listing-slider__track .octgf-listing-arrow svg {
	width: 18px;
	height: 18px;
	display: block;
}
.octgf-listing-slider__track .octgf-listing-arrow i {
	font-size: inherit;
	line-height: 1;
}

/* Built-in arrow direction: LTR → prev points left, next points right.
   RTL → the other way round. A custom icon is never mirrored. */
.octgf-listing-arrow--next .octgf-listing-arrow__svg {
	transform: scaleX(-1);
}
.rtl .octgf-listing-arrow--next .octgf-listing-arrow__svg {
	transform: none;
}
.rtl .octgf-listing-arrow--prev .octgf-listing-arrow__svg {
	transform: scaleX(-1);
}

.octgf-listing-slider__track .octgf-listing-arrow.swiper-button-disabled {
	opacity: .4;
	cursor: default;
}
.octgf-listing-dots {
	position: static;
	display: flex;
	justify-content: center;
	gap: 8px;
	margin-top: 16px;
}
.octgf-listing-dots .swiper-pagination-bullet {
	width: 10px;
	height: 10px;
	margin: 0;
	background: #d0d5dd;
	opacity: 1;
}
.octgf-listing-dots .swiper-pagination-bullet-active {
	background: #1d2939;
}

/* Load more */
.octgf-listing-more {
	display: flex;
	justify-content: center;
	margin-top: 24px;
}
.octgf-listing-more__btn {
	padding: 12px 28px;
	border: 1px solid currentColor;
	border-radius: 6px;
	background: none;
	color: inherit;
	font: inherit;
	cursor: pointer;
	transition: opacity .15s ease;
}
.octgf-listing-more__btn:hover {
	opacity: .75;
}
.octgf-listing-more__btn.is-loading,
.octgf-listing-more__btn[disabled] {
	opacity: .5;
	cursor: default;
}
