.ugs-ml-card {
	/* standard widget width — shared across the whole plugin family via
	   assets/css/base.css, never hardcoded per-widget */
	max-width: var(--ugs-widget-max-width, 420px);
	margin: 0 auto;
	padding: 28px 20px 32px;
	border-radius: 18px;
	font-family: inherit;
	text-align: center;
	box-sizing: border-box;

	/* Card background: alpha-driven solid/glass formula, same shape as the
	   popup's own Solid/Glass toggle below. --ugs-ml-card-bg-alpha is set
	   by the "Background Style" control (Solid → 1, Glass/Frosted → 0.45);
	   --ugs-ml-card-bg by the "Background Color" control. At alpha 1 this
	   is a flat opaque color with no blur (the previous default look); at
	   0.45 it's a frosted, ~11px-blurred glass pane over whatever's behind
	   the widget on the page. */
	--ugs-ml-card-bg: #0C0C0B;
	--ugs-ml-card-bg-alpha: 0.45;
	background-color: color-mix(in srgb, var(--ugs-ml-card-bg) calc(var(--ugs-ml-card-bg-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: overlay;
	backdrop-filter: blur(calc((1 - var(--ugs-ml-card-bg-alpha)) * 20px));
	-webkit-backdrop-filter: blur(calc((1 - var(--ugs-ml-card-bg-alpha)) * 20px));
	box-shadow: var(--ugs-glass-bevel);
	border: var(--ugs-glass-rim);
}

.ugs-ml-card * {
	box-sizing: border-box;
}

.ugs-ml-empty-placeholder {
	border: 1px dashed rgba(255,255,255,0.25);
	border-radius: 10px;
	padding: 24px 18px;
	font-size: 13px;
	opacity: 0.7;
	line-height: 1.5;
}

/* ---------- Album art + vinyl hover animation ---------- */

.ugs-ml-art-wrap {
	position: relative;
	width: 100%;
	max-width: 280px;
	aspect-ratio: 1 / 1;
	margin: 0 auto 20px;
	cursor: pointer;
}

/* The peek wrapper only handles sliding the record out from behind the
   cover — it never rotates itself, so its transform never fights with the
   disc's own continuous spin animation underneath it. */
.ugs-ml-vinyl-peek {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 92%;
	height: 92%;
	transform: translate(-62%, -50%);
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
	z-index: 1;
	pointer-events: none;
}

.ugs-ml-art-wrap:hover .ugs-ml-vinyl-peek {
	transform: translate(-94%, -50%);
}

/* The disc itself: grooves + a strong glassy gloss sweep, reading as an
   actual pressed record rather than a flat gradient circle. The center
   label (album art) and spindle hole are separate child elements so the
   art can sit on top, unclipped by the groove pattern beneath it. */
.ugs-ml-vinyl-disc {
	--ugs-ml-vinyl-label: #F04927;
	position: absolute;
	inset: 0;
	z-index: 0;
	border-radius: 50%;
	background:
		/* fine concentric grooves across the whole disc */
		repeating-radial-gradient(circle at center, #262626 0px, #262626 1px, #050505 1.6px, #050505 3px),
		/* base disc color underneath the grooves */
		radial-gradient(circle at 42% 38%, #1c1c1c 0%, #060606 70%);
	box-shadow:
		0 0 0 1px rgba(255,255,255,0.05) inset,
		0 10px 26px rgba(0,0,0,0.55);
	overflow: hidden;
}

/* The bundled vinyl texture (assets/img/vinyl-record.png, if present)
   replaces only the generated grooves background (higher-specificity
   compound selector beats the base rule above) — the label and spindle
   below are unchanged and still layer on top the same as the
   fully-generated version. */
.ugs-ml-vinyl-disc.ugs-ml-vinyl-disc-custom {
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

/* Glass highlight, like light catching the record's lacquer coating — a
   sibling of the disc rather than its ::after, and deliberately never
   spun: a real reflection comes from a fixed light source, not the
   record's own rotation, so keeping it stationary while the disc spins
   underneath is what actually reads as glossy vinyl instead of a
   painted-on shine. Sized down and dimmed (~30% less opaque than an
   earlier pass) to sit correctly over the photographed texture instead
   of overpowering it. Stacked above the disc (z-index 0) but below the
   label/spindle (1/2), same relative order as before. */
.ugs-ml-vinyl-gloss {
	position: absolute;
	/* 5% inset on each side = ~90% of the disc's diameter. A previous pass
	   scaled this up to 94.5% per a "bump it up 5%" request, but that read
	   as bigger than the vinyl image again once judged against the real
	   photo (vs. our synthetic test texture) — reverting to the size that
	   measured and looked correctly contained within the record's edge. */
	inset: 5%;
	z-index: 1;
	border-radius: 50%;
	background:
		radial-gradient(ellipse 38% 28% at 28% 22%, rgba(255,255,255,0.39) 0%, rgba(255,255,255,0.13) 35%, transparent 70%),
		linear-gradient(115deg,
			rgba(255,255,255,0.15) 0%,
			rgba(255,255,255,0.03) 26%,
			transparent 48%,
			transparent 64%,
			rgba(255,255,255,0.07) 100%
		);
	mix-blend-mode: screen;
	pointer-events: none;
}

/* Center label — the album art itself, printed onto the vinyl: dimmed and
   slightly desaturated so it reads as ink on a record rather than a
   pasted photo, with a thin accent-colored ring like a real label edge.
   Now a sibling of the disc and gloss (not nested inside the disc) so it
   can sit above the stationary gloss layer in one flat stacking order —
   a matte paper label wouldn't carry the same glassy reflection as the
   lacquered disc surface around it. Positions identically either way
   since the disc fills its parent's box exactly (inset: 0). */
.ugs-ml-vinyl-label {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 40%;
	height: 40%;
	transform: translate(-50%, -50%);
	border-radius: 50%;
	background-size: cover;
	background-position: center;
	filter: brightness(0.6) saturate(0.75) contrast(1.05);
	box-shadow:
		0 0 0 2px var(--ugs-ml-vinyl-label, #F04927),
		0 0 0 3px rgba(0,0,0,0.6),
		inset 0 0 12px rgba(0,0,0,0.5);
	z-index: 2;
}

.ugs-ml-vinyl-spindle {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 3%;
	height: 3%;
	transform: translate(-50%, -50%);
	border-radius: 50%;
	background: #050505;
	box-shadow: 0 0 0 1px rgba(255,255,255,0.15);
	z-index: 3;
}

.ugs-ml-art-wrap:hover .ugs-ml-vinyl-disc {
	animation: ugs-ml-spin 2.4s linear infinite;
}

/* The label and spindle spin along with the disc (realistic — a real
   label turns with the record), but as separate siblings now (see the
   gloss layer notes above) each needs its own centering translate kept
   alive through the animation, which a plain rotate() would otherwise
   replace. The gloss is deliberately excluded from both keyframes. */
.ugs-ml-art-wrap:hover .ugs-ml-vinyl-label,
.ugs-ml-art-wrap:hover .ugs-ml-vinyl-spindle {
	animation: ugs-ml-spin-centered 2.4s linear infinite;
}

@keyframes ugs-ml-spin {
	from { transform: rotate(0deg); }
	to   { transform: rotate(360deg); }
}

@keyframes ugs-ml-spin-centered {
	from { transform: translate(-50%, -50%) rotate(0deg); }
	to   { transform: translate(-50%, -50%) rotate(360deg); }
}

.ugs-ml-art {
	position: relative;
	z-index: 2;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 8px;
	box-shadow: 0 10px 30px rgba(0,0,0,0.45);
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
	display: block;
}

.ugs-ml-art-wrap:not(.ugs-ml-art-wrap-tilt):hover .ugs-ml-art {
	transform: translateX(6%) rotate(2deg);
}

@media (prefers-reduced-motion: reduce) {
	.ugs-ml-art-wrap:hover .ugs-ml-vinyl-disc,
	.ugs-ml-art-wrap:hover .ugs-ml-vinyl-label,
	.ugs-ml-art-wrap:hover .ugs-ml-vinyl-spindle {
		animation: none;
	}
}

/* ---------- 3D Tilt (mouse parallax) cover interaction ----------
   Alternative to the vinyl hover-peek above (selected per-widget via
   "Cover Interaction"): the album art itself tilts in 3D toward the
   cursor, with a soft glare following the pointer. JS sets the
   --tilt-x/--tilt-y/--tilt-rx/--tilt-ry custom properties on mousemove;
   this stays pure CSS otherwise. */

.ugs-ml-art-wrap-tilt {
	/* A tighter perspective distance (relative to the card's ~280px max
	   width) reads as real depth/foreshortening at large rotation angles
	   instead of a flat skew — the closer the "viewer" is, the more a
	   turned plane looks like it's actually turning in space. */
	perspective: 550px;
}

.ugs-ml-tilt-stage {
	position: relative;
	width: 100%;
	height: 100%;
	border-radius: 8px;
	overflow: hidden;
	transform-style: preserve-3d;
	backface-visibility: hidden;
	transform: rotateX(var(--tilt-rx, 0deg)) rotateY(var(--tilt-ry, 0deg)) translateZ(0);
	box-shadow: 0 14px 32px rgba(0,0,0,0.4);
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease;
	will-change: transform;
}

.ugs-ml-art-wrap-tilt:hover .ugs-ml-tilt-stage {
	transition: transform 0.08s linear, box-shadow 0.3s ease;
	box-shadow: 0 26px 46px rgba(0,0,0,0.55);
}

.ugs-ml-tilt-stage .ugs-ml-art {
	position: relative;
	z-index: 1;
	transform: none;
	transition: none;
}

.ugs-ml-tilt-glare {
	position: absolute;
	inset: 0;
	z-index: 2;
	border-radius: 8px;
	/* Alpha dropped ~60% from an earlier 0.4 — it was reading as too much. */
	background: radial-gradient(circle at var(--tilt-x, 50%) var(--tilt-y, 50%), rgba(255,255,255,0.16), transparent 60%);
	opacity: 0;
	transition: opacity 0.3s ease;
	pointer-events: none;
}

.ugs-ml-art-wrap-tilt:hover .ugs-ml-tilt-glare {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.ugs-ml-tilt-stage {
		transition: none;
		transform: none !important;
	}
}

/* ---------- Title / subtitle ---------- */

.ugs-ml-title {
	font-size: 18px;
	font-weight: 700;
	margin: 0 0 4px;
	line-height: 1.3;
}

.ugs-ml-subtitle {
	font-size: 14px;
	opacity: 0.7;
	margin: 0 0 20px;
}

/* ---------- "Listen Now" CTA button ---------- */

.ugs-ml-open-popup-btn {
	display: inline-block;
	margin: 0 0 4px;
	padding: 12px 32px;
	border-radius: 999px;
	border: 1.5px solid rgba(255,255,255,0.25);
	background: rgba(255,255,255,0.06);
	color: inherit;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.02em;
	cursor: pointer;
	transition: transform 0.15s ease, border-color 0.2s ease, background 0.2s ease;
}

.ugs-ml-open-popup-btn:hover {
	transform: translateY(-1px);
	background: rgba(255,255,255,0.12);
}

.ugs-ml-icon-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 8px;
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	flex-shrink: 0;
	overflow: hidden;
}

/* A user-uploaded icon carries its own artwork/background, so it gets no
   forced color chip behind it — just sized and clipped to match the badge. */
.ugs-ml-icon-badge-custom {
	background: none;
}

.ugs-ml-icon-badge-custom img,
.ugs-ml-icon-badge-custom svg {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* Most uploaded/Icon-Library SVGs (e.g. Font Awesome's own downloadable
   brand icons) ship with NO fill attribute at all on their <path> — they're
   meant to inherit color from context. Without this rule the SVG spec's
   fill initial value (black) wins, which is why "Icon Glyph Color
   (override)" looked like it had no effect on an uploaded icon: the color
   was being set on .ugs-ml-icon-badge, but nothing translated that into the
   SVG's `fill`. This only affects paths that don't already set their own
   fill, so a genuinely multi-color uploaded logo (explicit fill="..." per
   path) still keeps its own colors. */
.ugs-ml-icon-badge-custom svg {
	fill: currentColor;
}

/* A Font Awesome icon-library pick renders as an <i> font glyph rather than
   an image, so it needs its own sizing instead of the width:100% above. */
.ugs-ml-icon-badge-custom i {
	font-size: 18px;
	line-height: 1;
	color: inherit;
}

/* ---------- Popup ---------- */

/* The overlay stays in the DOM (display never toggles) so opacity/transform
   can transition smoothly; visibility + pointer-events keep it inert and
   unclickable while closed. */
.ugs-ml-popup {
	position: fixed;
	inset: 0;
	background: rgba(0,0,0,0);
	/* display:none until JS opens it (see widget.js openPopup/closePopup).
	   This element being position:fixed/inset:0 means whatever ancestor
	   ends up as its containing block (see neutralizeFixedContainingAncestors
	   in widget.js — Elementor sections routinely have a transform, filter
	   or backdrop-filter that makes them one instead of the true viewport)
	   still generates real box geometry for it even while merely
	   visibility:hidden/opacity:0 — browsers count that geometry toward
	   the PAGE's own scrollable overflow, so a mismatch between this
	   popup and a narrower/offset ancestor box was creating a persistent
	   horizontal scrollbar on some pages even with the popup fully closed
	   and never interacted with. display:none removes it from layout
	   entirely, which visibility alone does not. */
	display: none;
	align-items: center;
	justify-content: center;
	z-index: 99999;
	/* Asymmetric padding shifts the vertically-centered popup off dead
	   center. Top padding pushes it down, bottom padding pushes it up —
	   currently netting ~30px BELOW center (120 top vs 60 bottom), i.e.
	   ~50px lower than the previous 20/60 split. This only affects the
	   align-items:center desktop/tablet layout — mobile resets all four
	   padding sides itself in the media query below and is unaffected. */
	padding: 120px 20px 60px;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.32s ease, background-color 0.32s ease, visibility 0s linear 0.32s;
}

.ugs-ml-popup.ugs-ml-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-ml-popup-inner {
	--ugs-ml-popup-bg: #111111;
	--ugs-ml-popup-alpha: 1;
	position: relative;
	background-color: color-mix(in srgb, var(--ugs-ml-popup-bg) calc(var(--ugs-ml-popup-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: overlay;
	backdrop-filter: blur(calc((1 - var(--ugs-ml-popup-alpha)) * 20px));
	-webkit-backdrop-filter: blur(calc((1 - var(--ugs-ml-popup-alpha)) * 20px));
	border: var(--ugs-glass-rim);
	color: #fff;
	/* Fluid width: 380px on phones/small tablets, growing gently with the
	   viewport on larger screens rather than jumping between a couple of
	   fixed breakpoints, capped at 480px so it never gets desktop-huge.
	   Wrapped in min(92vw, …): the bare clamp() has a 380px FLOOR, and on
	   a device wide enough to skip the portrait media query below but not
	   actually 380px+92% comfortable (e.g. some Android tablets/foldables
	   in a mid-size landscape width) that floor could exceed the real
	   available width. min(92vw, …) guarantees this can never be wider
	   than the viewport itself — belt-and-suspenders alongside the
	   ancestor-containing-block fix elsewhere, so a wide popup can't be
	   the cause of a horizontal scrollbar/side-bar on Android Chrome. */
	max-width: min(92vw, clamp(380px, 40vw, 480px));
	width: 100%;
	max-height: 85vh;
	overflow-y: auto;
	overflow-x: hidden;
	border-radius: 16px;
	padding: 24px 20px 20px;
	text-align: center;
	box-shadow: 0 24px 60px rgba(0,0,0,0.45), var(--ugs-glass-bevel);
	/* the "smooth vertical expanding" open: scales/slides up from slightly
	   below and settles into place, reversing on close. */
	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-ml-popup.ugs-ml-popup-open .ugs-ml-popup-inner {
	transform: translateY(0) scale(1);
	opacity: 1;
}

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

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

/* ---------- Popup faces (Listen list <-> Share panel) ---------- */

.ugs-ml-popup-face {
	display: none;
}

.ugs-ml-popup-face.ugs-ml-popup-face-active {
	display: block;
	animation: ugs-ml-face-in 0.28s ease;
}

@keyframes ugs-ml-face-in {
	from { opacity: 0; transform: translateY(6px); }
	to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	.ugs-ml-popup-face.ugs-ml-popup-face-active {
		animation: none;
	}
}

.ugs-ml-popup-art {
	width: 200px;
	height: 200px;
	object-fit: cover;
	border-radius: 8px;
	margin: 0 auto 14px;
	display: block;
}

/* Qualified with the parent + element selector (not just the bare class)
   and !important on the font properties specifically: a theme's own
   `h1..h6` element-selector rules were still winning the cascade over a
   plain single-class selector on some sites, which is why the size/weight
   change didn't visibly take effect before. */
.ugs-ml-popup-inner h4.ugs-ml-popup-title {
	margin: 0 0 2px;
	font-family: inherit !important;
	font-weight: 900 !important;
	font-size: 20px !important;
	line-height: 1.15 !important;
}

.ugs-ml-popup-subtitle {
	margin: 0 0 16px;
	font-size: 13px;
	opacity: 0.7;
}

.ugs-ml-popup-listen-on {
	text-align: left;
	font-size: 12px;
	opacity: 0.55;
	margin: 0 0 10px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-weight: 700;
}

.ugs-ml-popup-list {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin-bottom: 14px;
}

.ugs-ml-popup-row {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 14px;
	border-radius: 10px;
	border: var(--ugs-glass-rim);
	background-color: color-mix(in srgb, color-mix(in srgb, var(--ugs-ml-popup-bg) 80%, white 20%) calc(var(--ugs-ml-popup-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: overlay;
	box-shadow: var(--ugs-glass-bevel);
	text-decoration: none;
	color: inherit;
	transition: border-color 0.2s ease, transform 0.15s ease;
}

.ugs-ml-popup-row:hover {
	transform: translateY(-1px);
}

.ugs-ml-popup-row.ugs-ml-hidden-extra {
	display: none;
}

.ugs-ml-popup-row.ugs-ml-show-extra {
	display: flex;
}

.ugs-ml-platform-label {
	flex: 1;
	text-align: left;
	font-weight: 600;
	font-size: 14px;
}

.ugs-ml-platform-arrow {
	opacity: 0.4;
	font-size: 14px;
}

.ugs-ml-popup-see-more {
	display: block;
	margin: 0 auto 16px;
	background: none;
	border: none;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	padding: 6px 10px;
}

.ugs-ml-popup-share {
	background: none;
	border: 1px solid rgba(255,255,255,0.2);
	color: inherit;
	padding: 8px 16px;
	border-radius: 20px;
	font-size: 13px;
	cursor: pointer;
}

/* ---------- Share panel (own "page" inside the popup) ---------- */

.ugs-ml-share-header {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 16px;
}

.ugs-ml-share-back {
	background-color: color-mix(in srgb, color-mix(in srgb, var(--ugs-ml-popup-bg) 80%, white 20%) calc(var(--ugs-ml-popup-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: overlay;
	border: var(--ugs-glass-rim);
	box-shadow: var(--ugs-glass-bevel);
	color: inherit;
	/* 50% bigger than the original 30px / 15px */
	width: 45px;
	height: 45px;
	border-radius: 50%;
	font-size: 22.5px;
	line-height: 1;
	cursor: pointer;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.ugs-ml-share-title {
	font-size: 16px;
	font-weight: 700;
	margin: 0;
	text-align: left;
	flex: 1;
}

.ugs-ml-share-preview {
	display: flex;
	align-items: center;
	gap: 12px;
	background-color: color-mix(in srgb, color-mix(in srgb, var(--ugs-ml-popup-bg) 80%, white 20%) calc(var(--ugs-ml-popup-alpha) * 100%), transparent);
	background-image: var(--ugs-glass-noise);
	background-blend-mode: overlay;
	border: var(--ugs-glass-rim);
	box-shadow: var(--ugs-glass-bevel);
	border-radius: 12px;
	padding: 12px;
	margin-bottom: 18px;
	text-align: left;
}

.ugs-ml-share-preview-art {
	width: 56px;
	height: 56px;
	border-radius: 8px;
	object-fit: cover;
	flex-shrink: 0;
	display: block;
}

.ugs-ml-share-preview-text {
	min-width: 0;
}

.ugs-ml-share-preview-title {
	font-weight: 700;
	font-size: 13px;
	line-height: 1.3;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.ugs-ml-share-preview-url {
	font-size: 11px;
	opacity: 0.6;
	margin-top: 3px;
}

.ugs-ml-share-grid {
	display: grid;
	/* minmax(0, 1fr) instead of a bare 1fr: grid items default to
	   min-width:auto, so a column is never allowed to shrink below its
	   content's natural width. A nowrap label wider than its fair share
	   was forcing the whole grid (and the popup) wider than the viewport
	   on narrow Android screens, producing a horizontal scrollbar. */
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16px 6px;
}

.ugs-ml-share-opt {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	min-width: 0;
	background: none;
	border: none;
	color: inherit;
	font-size: 11px;
	font-family: inherit;
	cursor: pointer;
	padding: 4px 2px;
}

.ugs-ml-share-icon {
	width: 44px;
	height: 44px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	overflow: hidden;
	color: #fff;
	transition: transform 0.15s ease;
}

/* A user-uploaded/library icon carries its own artwork, so it gets no
   forced color chip behind it — sized to fill or fit the same circle. */
.ugs-ml-share-icon-custom {
	background: none;
}

.ugs-ml-share-icon-custom img,
.ugs-ml-share-icon-custom svg {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* See the matching comment on .ugs-ml-icon-badge-custom svg above — same
   fix, same reasoning, for the Share Screen icons. */
.ugs-ml-share-icon-custom svg {
	fill: currentColor;
}

.ugs-ml-share-icon-custom i {
	font-size: 20px;
	line-height: 1;
	color: inherit;
}

.ugs-ml-share-opt:hover .ugs-ml-share-icon {
	transform: translateY(-2px);
}

.ugs-ml-share-label {
	opacity: 0.85;
	/* Allowed to wrap (rather than nowrap) so a long label can shrink with
	   its column instead of forcing the grid wider than the viewport. */
	white-space: normal;
	word-break: break-word;
	text-align: center;
	max-width: 100%;
}

/* Portrait phones/small-to-mid tablets get the more compact "bottom sheet"
   treatment below, keyed off actual orientation rather than width alone —
   a landscape phone is often wider than 480px anyway and already falls
   through to the roomier desktop-style clamp() above, but a portrait
   device up to 600px wide (larger phones, small tablets held upright)
   should still get the extra shrink-to-fit flexibility here rather than
   being treated like a desktop popup. */
@media (max-width: 480px), (orientation: portrait) and (max-width: 600px) {
	.ugs-ml-card {
		padding: 20px 14px 24px;
	}

	.ugs-ml-open-popup-btn {
		width: 100%;
		padding: 13px 20px;
	}

	.ugs-ml-popup {
		padding: 12px;
		align-items: flex-end;
		/* Bottom-sheet on mobile: extra bottom padding lifts the sheet up
		   off the very bottom edge. Reduced from 112px to move the main
		   listen screen ~50px further down per request — the share screen
		   (below) is untouched and still sits noticeably higher, toggled
		   via a JS-added class when that face is active. */
		padding-bottom: 62px;
	}

	.ugs-ml-popup.ugs-ml-popup-share-active {
		padding-bottom: 212px;
	}

	.ugs-ml-popup-inner {
		/* Was a flat 100% (edge-to-edge against the popup's own 12px
		   padding) — min(90vw, 440px) keeps it just as comfortable on a
		   narrow phone while never being sized wider than 90% of the true
		   viewport, so it can't itself be the thing pushing the page into
		   a horizontal scrollbar even if something upstream ever miscounts
		   the containing block again. */
		max-width: min(90vw, 440px);
		width: 100%;
		max-height: 90vh;
		border-radius: 20px 20px 12px 12px;
		padding: 22px 16px 18px;
	}

	.ugs-ml-popup-art {
		width: 150px;
		height: 150px;
	}

	.ugs-ml-popup-row {
		padding: 12px 14px;
	}

	.ugs-ml-share-grid {
		gap: 14px 4px;
	}

	.ugs-ml-share-icon {
		width: 40px;
		height: 40px;
	}
}

/* ---------- Attention grabber (optional, per-widget) ----------
   A looping motion cue for drawing attention to a specific widget
   instance — e.g. the one release you want people to notice on a page
   with several. Each one is a short burst followed by a ~3s pause
   before it repeats, rather than moving nonstop. Applied to the outer
   card so it works whether or not the widget has album art. */

.ugs-ml-card {
	position: relative;
}

/* Burst happens in the last quarter of a 4s loop (~1s of motion, ~3s
   of rest), then repeats. */
@keyframes ugs-ml-fx-pulse {
	0%, 75%, 100% { transform: scale(1); box-shadow: 0 0 0 rgba(255,255,255,0); }
	87.5%         { transform: scale(1.035); box-shadow: 0 0 26px rgba(255,255,255,0.35); }
}

.ugs-ml-fx-pulse {
	animation: ugs-ml-fx-pulse 4s ease-in-out infinite;
}

@keyframes ugs-ml-fx-wiggle {
	0%, 75%, 100% { transform: rotate(0deg); }
	80%           { transform: rotate(-3deg); }
	85%           { transform: rotate(3deg); }
	90%           { transform: rotate(-2deg); }
	95%           { transform: rotate(2deg); }
	98%           { transform: rotate(0deg); }
}

.ugs-ml-fx-wiggle {
	animation: ugs-ml-fx-wiggle 4s ease-in-out infinite;
	transform-origin: 50% 50%;
}

@keyframes ugs-ml-fx-shake {
	0%, 75%, 100% { transform: translateX(0); }
	78%           { transform: translateX(-5px); }
	81%           { transform: translateX(5px); }
	84%           { transform: translateX(-4px); }
	87%           { transform: translateX(4px); }
	90%           { transform: translateX(-2px); }
	93%           { transform: translateX(2px); }
	96%           { transform: translateX(0); }
}

.ugs-ml-fx-shake {
	animation: ugs-ml-fx-shake 4s ease-in-out infinite;
}

/* Gleam/shine: a soft diagonal highlight sweeps across the card. This
   animates a background-image's position rather than translating a
   physically wider element clipped by `overflow: hidden` — the earlier
   approach required hiding overflow on the card, which also clipped the
   vinyl record's hover "peek" past the album art. A background is
   always confined to its own element's box with no clipping needed, so
   the record can still extend past the card normally. Opacity of the
   highlight is intentionally low (0.26, down from an earlier 0.4). */
.ugs-ml-fx-glow {
	background-image: linear-gradient(115deg, transparent 42%, rgba(255,255,255,0.26) 50%, transparent 58%);
	background-repeat: no-repeat;
	background-size: 260% 260%;
	background-position: -60% -60%;
	animation: ugs-ml-fx-glow-sweep 2.6s linear infinite;
}

@keyframes ugs-ml-fx-glow-sweep {
	0%   { background-position: -60% -60%; }
	100% { background-position: 160% 160%; }
}

@media (prefers-reduced-motion: reduce) {
	.ugs-ml-fx-pulse,
	.ugs-ml-fx-wiggle,
	.ugs-ml-fx-shake,
	.ugs-ml-fx-glow {
		animation: none !important;
	}
}
