/*
 * Buytena loading states
 * ---------------------
 * Two visuals, both pure CSS so they paint on the first frame:
 *
 *   .bl-art--ring   rotating conic arc — page overlay, full-page waits
 *   .bl-art--dots   three pulsing dots  — inline, inside buttons
 *
 * Why not Lottie by default: a loader has to appear within a frame or two,
 * and lottie-web means ~250KB of player plus a JSON round-trip before anything
 * is drawn. The CSS art is instant, themeable from the --ml-* tokens the rest
 * of the site already uses, and animates on the compositor.
 *
 * Lottie is still supported (js/loader.js) for the case where a real
 * designed animation is wanted: BuytenaLoader.playLottie(host, '/x.json').
 *
 * Size comes from --loader-size, set inline per usage. Stroke weight scales
 * with it so a 20px inline spinner and a 140px overlay ring read as the same
 * family.
 */

.bl-art {
	--loader-size: 40px;
	--loader-accent: var(--ml-orange, #f97316);
	--loader-thickness: max(2px, calc(var(--loader-size) * 0.075));

	display: block;
	flex: none;
	width: var(--loader-size);
	height: var(--loader-size);
}

/* An author display rule beats the UA stylesheet's [hidden], and the busy
   markup toggles the hidden attribute, so honour it here. */
.bl-art[hidden] {
	display: none;
}

/* ── ring ─────────────────────────────────────────────────────── */

.bl-art--ring {
	border-radius: 50%;
	background: conic-gradient(
		from 0turn,
		transparent 0%,
		transparent 20%,
		var(--loader-accent) 100%
	);
	-webkit-mask: radial-gradient(
		farthest-side,
		transparent calc(100% - var(--loader-thickness)),
		#000 calc(100% - var(--loader-thickness))
	);
	mask: radial-gradient(
		farthest-side,
		transparent calc(100% - var(--loader-thickness)),
		#000 calc(100% - var(--loader-thickness))
	);
	animation: bl-ring-spin 760ms linear infinite;
}

@keyframes bl-ring-spin {
	to {
		transform: rotate(1turn);
	}
}

/* ── dots ─────────────────────────────────────────────────────── */
/* Three children are written by js/loader.js; nth-child drives the
   stagger so the markup stays free of per-instance timing. */

.bl-art--dots {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: calc(var(--loader-size) * 0.22);
}

.bl-art--dots > i {
	display: block;
	width: var(--loader-thickness);
	height: var(--loader-thickness);
	border-radius: 50%;
	background: var(--loader-accent);
	animation: bl-dot 1.05s ease-in-out infinite;
}

.bl-art--dots > i:nth-child(2) {
	animation-delay: 140ms;
}

.bl-art--dots > i:nth-child(3) {
	animation-delay: 280ms;
}

@keyframes bl-dot {
	0%,
	70%,
	100% {
		opacity: 0.25;
		transform: scale(0.8);
	}
	35% {
		opacity: 1;
		transform: scale(1);
	}
}

/* ── overlay ──────────────────────────────────────────────────── */

.buytena-loader-overlay {
	position: fixed;
	z-index: 9999;
	inset: 0;
	display: grid;
	place-items: center;
	padding: 1.5rem;
	background: rgb(6 21 43 / 0.55);
	backdrop-filter: blur(6px);
	animation: bl-fade-in 160ms ease-out both;
}

.buytena-loader-overlay__panel {
	display: grid;
	justify-items: center;
	gap: 1.1rem;
	width: min(20rem, 100%);
	padding: 2rem 2.25rem 1.75rem;
	border: 1px solid var(--ml-line, #e2e8f0);
	border-radius: 14px;
	background: var(--ml-surface, #fff);
	box-shadow: 0 30px 70px -30px rgb(6 21 43 / 0.55);
	text-align: center;
}

.buytena-loader-overlay__text {
	margin: 0;
	color: var(--ml-ink, #06152b);
	font-size: 0.95rem;
	font-weight: 600;
	letter-spacing: -0.01em;
}

/* Indeterminate sweep — shows work continuing without inventing a percentage. */
.buytena-loader-overlay__bar {
	overflow: hidden;
	width: 100%;
	height: 3px;
	border-radius: 999px;
	background: rgb(6 21 43 / 0.08);
}

.buytena-loader-overlay__bar > i {
	display: block;
	width: 40%;
	height: 100%;
	border-radius: 999px;
	background: linear-gradient(
		90deg,
		transparent,
		var(--ml-orange, #f97316),
		transparent
	);
	animation: bl-sweep 1.25s ease-in-out infinite;
}

@keyframes bl-sweep {
	0% {
		transform: translateX(-105%);
	}
	100% {
		transform: translateX(350%);
	}
}

@keyframes bl-fade-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

/* Stops the page behind the overlay from scrolling away underneath it. */
.buytena-loader-open,
.buytena-loader-open body {
	overflow: hidden;
}

/* ── legacy alias ─────────────────────────────────────────────── */
/* .loading-spinner was the original class name; kept so existing markup and
   any inline styles in the admin theme keep working. */

.loading-spinner {
	--loader-size: 1.15em;
	display: inline-block;
	flex: none;
	width: var(--loader-size);
	height: var(--loader-size);
	border-radius: 50%;
	background: conic-gradient(
		from 0turn,
		transparent 0%,
		transparent 20%,
		currentColor 100%
	);
	-webkit-mask: radial-gradient(
		farthest-side,
		transparent calc(100% - 2px),
		#000 calc(100% - 2px)
	);
	mask: radial-gradient(
		farthest-side,
		transparent calc(100% - 2px),
		#000 calc(100% - 2px)
	);
	animation: bl-ring-spin 760ms linear infinite;
	vertical-align: -0.2em;
}

/* ── reduced motion ───────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	/* Rotation is the cue that triggers vestibular symptoms, so the ring
	   slows to a long opacity breathe rather than dropping the feedback. */
	.bl-art--ring,
	.loading-spinner {
		animation: bl-ring-breathe 1.8s ease-in-out infinite;
	}

	.bl-art--dots > i {
		animation-duration: 1.8s;
	}

	.buytena-loader-overlay {
		animation: none;
	}

	.buytena-loader-overlay__bar > i {
		width: 100%;
		animation: none;
		opacity: 0.45;
	}
}

@keyframes bl-ring-breathe {
	0%,
	100% {
		opacity: 0.4;
	}
	50% {
		opacity: 1;
	}
}
