/* ==========================================================================
   UGS Announce Tab — a small, classic "sticky" tab docked to the left/right
   edge of the browser and fixed to the screen at all times (it does NOT
   scroll with the page — an earlier round of this widget briefly tried
   that, per a misreading of feedback, and it was explicitly reverted), that
   periodically "peeks" (a brief nudge/bounce) to catch the eye. Clicking it
   opens a popup holding whatever Elementor template was picked for it.

   Every class here is namespaced ugs-an-* — see this widget's PHP file
   header for why that separation from the plugin's other widgets matters.
   ========================================================================== */

.ugs-an-empty-placeholder {
	max-width: 460px;
	margin: 0 auto;
	border: 1px dashed rgba(0,0,0,0.25);
	border-radius: 10px;
	padding: 16px;
	font-size: 13px;
	opacity: 0.7;
	line-height: 1.5;
}

/* ---------- The tab itself ---------- */

.ugs-an-tab {
	--ugs-an-accent: #F04927;
	--ugs-an-tab-size: 68px;
	/* How much of the tab shows at rest, in actual pixels. A slider control
	   ("Peek Amount") writes this. */
	--ugs-an-peek-exposure: 16px;
	/* How far (in px) the tab additionally travels, on top of the peek
	   amount, when it's fully revealed (hover/focus/peeking) — a slider
	   control ("Pop Out Distance") writes this, independently of Tab Size.
	   Deliberately a flat, author-controlled px distance rather than
	   anything computed from the tab's own rendered size (see the
	   .ugs-an-side-left/-right rule below for why). Defaults generously
	   high so, out of the box, it still reaches a full reveal. */
	--ugs-an-pop-out: 300px;
	/* The periodic peek's target position — halfway between resting and
	   fully-popped, clamped the same way the hover/focus rule below is so
	   it can never overshoot past flush with the edge. Derived, not
	   author-set directly. */
	--ugs-an-peek-swing: min(0px, calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure) + var(--ugs-an-pop-out) / 2));
	/* How far the tab tilts — at the MIDPOINT of its periodic peek (see the
	   ugs-an-peek-left/-right keyframes below), AND for as long as it's
	   fully revealed on hover/focus (see the :hover/:focus-within rule
	   further down) — a plain signed degree value, 0 by default, written by
	   the "Peek Rotation" NUMBER control. Purely cosmetic on top of the
	   left/right position changes in both cases. */
	--ugs-an-peek-rotate: 0deg;
	/* Written by the "Reveal Animation" SELECT control's selectors_dictionary
	   as a ready-to-use transition value (this fallback matches the "Smooth"
	   preset below — always overridden in practice, since render() always
	   adds one of the ugs-an-anim-* classes); the class also switched on the
	   wrapper (ugs-an-anim-*) is what varies the PERIODIC peek swing's
	   timing, since that's a keyframe animation rather than a transition. */
	--ugs-an-reveal-transition: left 0.25s ease, right 0.25s ease, transform 0.25s ease;

	/* No background, no glass, no border/box-shadow — this tab is meant to
	   read as just its image/GIF or text floating at the edge, completely
	   transparent otherwise (per feedback: the popup content already gets
	   the frosted-glass treatment, the tab itself shouldn't). An optional
	   drop-shadow (the "Tab Shadow" control) can still be layered on
	   independently of that, since a transparent shape can disappear
	   entirely against a similarly-colored page background. filter:
	   drop-shadow (not box-shadow) so it hugs the actual image/text shape
	   rather than drawing a rectangle behind it. */
	position: fixed;
	top: 0;
	/* This used to be 99997 — high by ordinary page-content standards, but
	   third-party overlays that a real site almost always also has running
	   (cookie-consent banners, live-chat bubbles, exit-intent / scroll-
	   triggered email popups) routinely hardcode something far higher —
	   999999 and 2147483647 (the max signed 32-bit int) are both extremely
	   common conventions for "must always be on top," specifically BECAUSE
	   those scripts assume they're the only thing doing it. Whichever one
	   loads or triggers later simply wins the z-index comparison and paints
	   over everything below it, including this tab — no clipping or
	   removal involved, it's just genuinely covered.
	   This fits the newest report much better than the earlier
	   overflow/containing-block bugs: those third-party scripts commonly
	   inject themselves well after DOMContentLoaded (matching "once the
	   page fully loads, it's getting pushed to the back"), some consent/
	   popup tools specifically trigger on scroll depth (matching Safari
	   only losing the tab once scrolled to the bottom), and whether a given
	   test run's popup/banner fires at all is often itself conditional
	   (already dismissed this session, A/B-tested, only-once-per-visitor,
	   a delay timer) — matching "not guaranteed to fail every time."
	   Pushed right up near the top of the legal range so this can only
	   lose that comparison to something even more extreme than the
	   convention above. */
	z-index: 2147483001;
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: var(--ugs-an-tab-size);
	min-height: var(--ugs-an-tab-size);
	padding: 8px;
	color: #F2EFE8;
	background: none;
	border: none;
	box-shadow: none;
	filter: none;
	box-sizing: border-box;
	/* FIXED — deliberately, and this is the actual intended behavior, not a
	   workaround: per explicit direction, this tab is a classic "sticky"
	   corner tab, fixed to the screen and always visible no matter how far
	   the visitor scrolls or which element on the page actually does the
	   scrolling. `top` (below) is a plain, static value straight from the
	   "Vertical Offset" control (applied as an inline style / a small
	   #id-scoped <style> block by class-ugs-ml-announce-widget.php's
	   render() — see that file), not something JS recalculates — a fixed
	   position needs no scroll-tracking at all, which is the whole appeal
	   of this over the page-anchored version an earlier round of this
	   widget briefly used.

	   What the peek/hover/retract states all move — kept on the tab itself
	   (not a child) so the dismiss button rides along with it.

	   IMPORTANT: this animates the `left`/`right` OFFSET, not a transform
	   percentage. An earlier version used `transform: translateX(-100%)`
	   etc., which is relative to the element's OWN rendered box — since
	   increasing Tab Size grows that box (and the image inside it) at the
	   same time, the percentage-based shift grew right along with it,
	   compounding into the image visibly sliding further past the edge
	   the bigger the tab got, and (being percentage-of-self, recalculated
	   at paint time) it also read as janky/inconsistent on hover. Plain
	   px math against explicit custom properties has neither problem. */
	transition: var(--ugs-an-reveal-transition);
}

/* Resting position: mostly off-screen, showing only --ugs-an-peek-exposure
   worth of the tab. Still has to reference --ugs-an-tab-size to know how
   far off-screen "mostly hidden" is — there's no way around that — but
   nothing here is a percentage of the box's own fluctuating render size,
   so it can't compound with Tab Size the way the old transform did. */
.ugs-an-side-left {
	left: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure));
	/* Hinge the peek's rotation (below) at the edge the tab is docked to,
	   rather than its own center, so a nonzero Peek Rotation reads as the
	   tab swinging out on a hinge fixed to the screen edge, not spinning
	   in place. */
	transform-origin: left center;
}

.ugs-an-side-right {
	right: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure));
	transform-origin: right center;
}

/* Fully revealed: rest position plus the "Pop Out Distance" control, capped
   with min()/max() so no matter how large that control is set, it can
   never overshoot past sitting flush with the edge (left:0 / right:0) —
   i.e. the slider's practical range is "barely past peek" up to "fully
   revealed", with no way to push it too far and create a gap.

   Scoped to devices with a real mouse-like hover/pointer on purpose. On a
   touchscreen, tapping the tab both focuses AND (per a well-known mobile
   Chrome/Safari quirk) can leave :hover "stuck" matching indefinitely,
   with no corresponding "unhover" gesture to clear it — so this rule
   would keep winning the cascade over the periodic peek animation the
   instant each bounce finished, reading as "bounces smoothly, then
   suddenly snaps to the fully popped-out position, then cycles back into
   the bounce" (reported worse on phone than on an actual mouse-driven
   browser, which is exactly this distinction). On a touch device the
   bounce animation is the only reveal — tapping goes straight to opening
   the popup (or the link), never lingering in a half-triggered hover
   state to fight with it. */
@media (hover: hover) and (pointer: fine) {
	.ugs-an-side-left:hover,
	.ugs-an-side-left:focus-within {
		left: min(0px, calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure) + var(--ugs-an-pop-out)));
		/* Same tilt as the periodic peek's midpoint (see "Peek Rotation" and
		   the ugs-an-peek-left/-right keyframes below) — 0deg by default, so
		   this is a no-op unless that control is set. transform-origin is
		   set on this same element above (left/right center), and the
		   transform half of --ugs-an-reveal-transition (set per animation
		   preset further down) is what makes this animate smoothly rather
		   than snapping. */
		transform: rotate(var(--ugs-an-peek-rotate));
	}

	.ugs-an-side-right:hover,
	.ugs-an-side-right:focus-within {
		right: min(0px, calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure) + var(--ugs-an-pop-out)));
		transform: rotate(var(--ugs-an-peek-rotate));
	}

	/* Hover wins over a peek already in flight. A running keyframe
	   animation overrides ordinary declarations — including the
	   :hover left/right/transform values above — so if the pointer landed
	   mid-peek, the animation and the hover transition fought over the
	   same properties and some browsers made the tab jump around. Dropping
	   the animation while hovered/focused lets the normal transition take
	   over from wherever the tab currently is (transitions start from the
	   animated value), and announce-widget.js removes the .ugs-an-peeking
	   class on mouseenter so the peek doesn't restart from 0% the moment
	   the pointer leaves. !important so it beats the animation-name rules
	   below regardless of source order. */
	.ugs-an-tab.ugs-an-peeking:hover,
	.ugs-an-tab.ugs-an-peeking:focus-within {
		animation: none !important;
	}
}

/* While the popup is open, force the tab back to its partially-exposed
   resting position regardless of hover/focus — otherwise a tab clicked
   open (which leaves its trigger button focused, and on desktop often
   still hovered) would stay popped out behind/next to its own popup.
   announce-widget.js toggles this class on open/close. The !important
   is required to win over the :hover/:focus-within rules above without
   depending on source order. */
.ugs-an-side-left.ugs-an-popup-active {
	left: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure)) !important;
	/* Force flat too — otherwise a nonzero Peek Rotation would leave the
	   tab visibly tilted while its own popup sits open right next to it,
	   since :hover/:focus-within can still be matching underneath this
	   rule (only the position, not the pseudo-class match, is overridden
	   above). */
	transform: rotate(0deg) !important;
}

.ugs-an-side-right.ugs-an-popup-active {
	right: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure)) !important;
	transform: rotate(0deg) !important;
}

/* ---------- Reveal animation presets ---------- */
/* "Reveal Animation" control picks one of these classes. Applied directly
   to .ugs-an-tab itself (as a compound class, not a descendant selector)
   because announce-widget.js moves the tab out to be a direct child of
   <body> — see the JS for why — so it can no longer rely on an ancestor
   wrapper class to carry this. Each pairs a hover-transition feel with a
   matching periodic-peek feel, rather than exposing every timing knob
   separately. Smooth is a plain ease; Snappy is a fast ease-out; Bouncy
   uses an overshoot cubic-bezier, which — since the peek keyframes below
   swing to a real 0%/50%/100% set of stops rather than just two — actually
   overshoots past fully-open and past the resting spot before settling. */
/* `transform` rides along in the same transition list as `left`/`right` —
   same duration and easing per preset — so the hover-reveal's rotation
   (see the :hover/:focus-within rule above) animates in step with the
   slide instead of snapping or lagging behind it. */
.ugs-an-tab.ugs-an-anim-smooth {
	--ugs-an-reveal-transition: left 0.25s ease, right 0.25s ease, transform 0.25s ease;
}

.ugs-an-tab.ugs-an-anim-snappy {
	--ugs-an-reveal-transition: left 0.18s cubic-bezier(0.16, 1, 0.3, 1), right 0.18s cubic-bezier(0.16, 1, 0.3, 1), transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}

.ugs-an-tab.ugs-an-anim-bouncy {
	--ugs-an-reveal-transition: left 0.45s cubic-bezier(0.34, 1.56, 0.64, 1), right 0.45s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.ugs-an-trigger {
	display: flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: none;
	color: inherit;
	cursor: pointer;
	padding: 0;
	width: 100%;
	height: 100%;
	font-family: inherit;
}

.ugs-an-tab-image {
	display: block;
	width: calc(var(--ugs-an-tab-size) - 16px);
	height: calc(var(--ugs-an-tab-size) - 16px);
	object-fit: contain;
	border-radius: 8px;
}

.ugs-an-tab-text {
	font-size: 13px;
	font-weight: 700;
	line-height: 1.25;
	max-width: 120px;
	white-space: normal;
}

.ugs-an-dismiss {
	/* Simple, flat, always-visible circle — no longer tied to the tab's own
	   background (the tab has none now). Kept deliberately plain rather
	   than glass since it's a tiny utility control, not the tab's content. */
	position: absolute;
	top: -8px;
	background-color: rgba(12, 12, 11, 0.85);
	border: 1px solid rgba(255,255,255,0.22);
	box-shadow: 0 2px 6px rgba(0,0,0,0.35);
	color: #F2EFE8;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	font-size: 14px;
	line-height: 1;
	cursor: pointer;
	z-index: 1;
}

.ugs-an-side-left .ugs-an-dismiss {
	right: -8px;
}

.ugs-an-side-right .ugs-an-dismiss {
	left: -8px;
}

/* ---------- Peek animation ---------- */
/* A brief, punctuated nudge — added as a class by announce-widget.js on an
   interval and removed after it plays once, rather than a continuously
   looping CSS animation, so the timing is controllable per-widget via the
   "Peek Every" setting. */

/* The periodic peek is a smaller tease than a full hover-reveal — it swings
   out to roughly HALFWAY between the resting position and the fully-popped
   (hover) position, then back, rather than all the way out. --ugs-an-tab
   defines --ugs-an-peek-swing for this (rest + half of Pop Out Distance,
   same min(0px, …) clamp as the full-reveal position so it can never
   overshoot past flush either). It optionally also tilts at that same
   midpoint by --ugs-an-peek-rotate (the "Peek Rotation" control, 0 by
   default) before rotating back flat — see the keyframes below and the
   transform-origin on .ugs-an-side-left/-right above. */
@keyframes ugs-an-peek-left {
	0%   { left: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure)); box-shadow: none; transform: rotate(0deg); }
	50%  { left: var(--ugs-an-peek-swing); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ugs-an-accent) 60%, transparent); transform: rotate(var(--ugs-an-peek-rotate)); }
	100% { left: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure)); box-shadow: none; transform: rotate(0deg); }
}

@keyframes ugs-an-peek-right {
	0%   { right: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure)); box-shadow: none; transform: rotate(0deg); }
	50%  { right: var(--ugs-an-peek-swing); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ugs-an-accent) 60%, transparent); transform: rotate(var(--ugs-an-peek-rotate)); }
	100% { right: calc(-1 * var(--ugs-an-tab-size) + var(--ugs-an-peek-exposure)); box-shadow: none; transform: rotate(0deg); }
}

/* Swings about halfway out (see --ugs-an-peek-swing above) and back — same
   keyframe shape for every "Reveal Animation" preset, only the duration
   and timing-function change per preset, which is enough on its own to
   give Bouncy a real overshoot past both ends. Compound classes on the tab
   itself, same reasoning as the presets above — no ancestor wrapper to
   hang a descendant selector off of once the tab's been moved to <body>. */
.ugs-an-tab.ugs-an-side-left.ugs-an-peeking {
	animation-name: ugs-an-peek-left;
	animation-duration: 1.4s;
	animation-timing-function: ease-in-out;
}

.ugs-an-tab.ugs-an-side-right.ugs-an-peeking {
	animation-name: ugs-an-peek-right;
	animation-duration: 1.4s;
	animation-timing-function: ease-in-out;
}

.ugs-an-tab.ugs-an-anim-snappy.ugs-an-side-left.ugs-an-peeking,
.ugs-an-tab.ugs-an-anim-snappy.ugs-an-side-right.ugs-an-peeking {
	animation-duration: 1s;
	animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}

.ugs-an-tab.ugs-an-anim-bouncy.ugs-an-side-left.ugs-an-peeking,
.ugs-an-tab.ugs-an-anim-bouncy.ugs-an-side-right.ugs-an-peeking {
	animation-duration: 1.7s;
	animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (prefers-reduced-motion: reduce) {
	.ugs-an-side-left.ugs-an-peeking,
	.ugs-an-side-right.ugs-an-peeking {
		animation: none !important;
	}
}

@media (max-width: 480px) {
	.ugs-an-tab {
		--ugs-an-tab-size: 56px;
	}

	.ugs-an-tab-text {
		font-size: 11px;
		max-width: 90px;
	}
}

/* ---------- Popup ---------- */
/* Same open/close mechanics as the rest of the plugin's popups. */

.ugs-an-popup {
	position: fixed;
	inset: 0;
	background: rgba(0,0,0,0);
	display: none;
	align-items: center;
	justify-content: center;
	/* Raised alongside .ugs-an-tab's own z-index for the same reason — the
	   popup is what the tab actually opens, so it needs to clear the same
	   third-party overlays, just always a hair above the tab itself. */
	z-index: 2147483002;
	padding: 20px;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.32s ease, background-color 0.32s ease, visibility 0s linear 0.32s;
}

.ugs-an-popup.ugs-an-popup-open {
	background: rgba(0,0,0,0.6);
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: opacity 0.32s ease, background-color 0.32s ease, visibility 0s linear 0s;
}

.ugs-an-popup-inner {
	--ugs-an-popup-bg: #111111;
	--ugs-an-popup-alpha: 1;
	position: relative;
	background-color: color-mix(in srgb, var(--ugs-an-popup-bg) calc(var(--ugs-an-popup-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: normal;
	backdrop-filter: blur(calc((1 - var(--ugs-an-popup-alpha)) * 20px));
	-webkit-backdrop-filter: blur(calc((1 - var(--ugs-an-popup-alpha)) * 20px));
	border: var(--ugs-glass-rim);
	color: #fff;
	max-width: var(--ugs-an-popup-max-width, min(92vw, clamp(380px, 40vw, 480px)));
	width: 100%;
	max-height: 85vh;
	overflow-y: auto;
	overflow-x: hidden;
	overscroll-behavior: contain;
	border-radius: 16px;
	padding: 24px 20px 20px;
	text-align: left;
	box-shadow: 0 24px 60px rgba(0,0,0,0.45), var(--ugs-glass-bevel);
	transform: translateY(28px) scale(0.94);
	opacity: 0;
	transition: transform 0.38s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.28s ease;
}

.ugs-an-popup.ugs-an-popup-open .ugs-an-popup-inner {
	transform: translateY(0) scale(1);
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.ugs-an-popup,
	.ugs-an-popup-inner {
		transition-duration: 0.01ms !important;
	}
}

.ugs-an-popup-close {
	position: absolute;
	top: 12px;
	right: 12px;
	background-color: color-mix(in srgb, color-mix(in srgb, var(--ugs-an-popup-bg) 80%, white 20%) calc(var(--ugs-an-popup-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: normal;
	border: var(--ugs-glass-rim);
	box-shadow: var(--ugs-glass-bevel);
	color: inherit;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	font-size: 27px;
	line-height: 1;
	cursor: pointer;
	z-index: 2;
}

.ugs-an-popup-content {
	width: 100%;
}

.ugs-an-popup-content > *:first-child {
	margin-top: 0;
}

.ugs-an-popup-content > *:last-child {
	margin-bottom: 0;
}

@media (max-width: 480px), (orientation: portrait) and (max-width: 600px) {
	.ugs-an-popup {
		padding: 12px;
	}

	.ugs-an-popup-inner {
		max-width: min(90vw, 440px);
		width: 100%;
		max-height: 90vh;
		border-radius: 20px;
	}
}
