/*!
 * SaaS Experience Bridge — Khung xương, chấm chờ, spinner, nhánh reduced-motion
 *
 * Một phần của giao diện Experience. Thứ tự nạp do public/ui/manifest.php quy
 * định và là RÀNG BUỘC: nhiều quy tắc dựa vào việc file sau ghi đè file trước
 * ở cùng độ đặc hiệu. Đảo thứ tự là đổi giao diện.
 */

/* --------------------------------------------------------------------------
 * Hoạt ảnh chờ — ba chấm nảy so le
 *
 * Thay cho câu chữ trong lúc thu dữ liệu. Nhịp chậm (1.3s) là cố ý: nhanh và
 * giật khiến việc chờ có cảm giác gấp gáp, còn nhịp thở đều nói "vẫn đang chạy,
 * cứ bình tĩnh".
 * ----------------------------------------------------------------------- */

.spe-working {
	align-items: center;
	display: inline-flex;
	gap: 6px;
}

.spe-working__dot {
	animation: spe-working 1.3s ease-in-out infinite;
	animation-delay: calc(var(--spe-d, 0) * 0.16s);
	background: var(--spe-accent-strong);
	block-size: 7px;
	border-radius: 50%;
	display: block;
	inline-size: 7px;
}

.spe-working--lg {
	gap: 9px;
}

.spe-working--lg .spe-working__dot {
	block-size: 10px;
	inline-size: 10px;
}

@keyframes spe-working {
	0%,
	72%,
	100% {
		opacity: 0.28;
		transform: scale(0.7);
	}

	36% {
		opacity: 1;
		transform: scale(1);
	}
}

/* Vùng chờ dưới thẻ khung xương. */
.spe-waiting {
	display: flex;
	justify-content: center;
	padding-block: 1.5rem 0.5rem;
}

/*
 * Dải tiến trình trong kết quả: chỉ còn hoạt ảnh, câu chữ đi đường trình đọc.
 *
 * Không khung, không nền, canh giữa ngay dưới dòng cuối — đọc ra đúng nghĩa
 * "còn dòng nữa đang tới". Một hộp màu chạy hết chiều ngang mà bên trong chỉ có
 * ba cái chấm thì trông như giao diện vẽ dở.
 */
.spe-insight--working {
	background: none;
	border: 0;
	display: flex;
	justify-content: center;
	padding: 0.9rem 0 0.4rem;
}

/*
 * Tắt hoạt ảnh: chấm phải đứng lại ở trạng thái ĐỌC ĐƯỢC, không phải ở khung
 * hình đầu tiên (mờ 28% và co lại) — nếu không thì với người tắt chuyển động,
 * dấu hiệu duy nhất của việc chờ gần như biến mất.
 */
@media (prefers-reduced-motion: reduce) {
	.spe-working__dot {
		opacity: 0.75;
		transform: none;
	}
}

/* --------------------------------------------------------------------------
 * Skeleton & spinner
 * ----------------------------------------------------------------------- */

.spe-card__body {
	display: grid;
	gap: 0.6rem;
	margin-top: 1.25rem;
}

/*
 * Sóng chờ chạy bằng `transform`, KHÔNG bằng `background-position`.
 *
 * Hai cách nhìn ra như nhau, nhưng `background-position` là một thuộc tính phải
 * TÔ LẠI: mỗi khung hình, mỗi khối chờ được vẽ lại từ đầu. Một bảng khung xương
 * mười mấy dòng là vài chục khối cùng tô lại 60 lần/giây, ngay lúc trang còn
 * đang dựng và đang chờ mạng — chính là lúc không còn gì để phí.
 *
 * `transform` thì chạy thẳng ở khâu ghép ảnh: không đo lại, không tô lại. Sóng
 * nằm ở lớp giả và trượt ngang qua ô, còn ô thì đứng yên.
 */
.spe-skel {
	background: var(--spe-surface-2);
	border-radius: 6px;
	display: block;
	height: 0.85rem;
	overflow: hidden;
	position: relative;
	width: 100%;
}

.spe-skel::after,
.spe-offer__price-wait::after {
	animation: spe-shimmer 1.4s ease-in-out infinite;
	background: linear-gradient(
		90deg,
		transparent,
		var(--spe-surface-3),
		transparent
	);
	content: "";
	inset: 0;
	position: absolute;
}

@keyframes spe-shimmer {
	from {
		transform: translateX(-100%);
	}

	to {
		transform: translateX(100%);
	}
}

/*
 * Khung xương chỉ còn dùng cho bảng nơi bán: một khối vuông thay favicon, hai
 * vạch thay tên shop và tên miền, ô giá dùng chính khối chờ của bản thật. Các
 * khối khoá không có khung xương — chúng không đang được tải, xem teasersReady().
 */
.spe-skel--icon {
	block-size: 24px;
	border-radius: 6px;
	inline-size: 24px;
}

@keyframes spe-indeterminate {
	from {
		transform: translateX(-100%);
	}

	to {
		transform: translateX(350%);
	}
}

/* Kết quả hiện lên theo bậc, mỗi section trễ hơn một nhịp. */
.spe-view[data-spe-view="SUCCESS"]:not([hidden]) .spe-card {
	animation: spe-fade 0.3s ease backwards;
}

.spe-section {
	animation: spe-rise 0.42s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
	animation-delay: calc(var(--spe-i, 0) * 70ms + 60ms);
}

@keyframes spe-fade {
	from {
		opacity: 0;
	}
}

@keyframes spe-rise {
	from {
		opacity: 0;
		transform: translateY(10px);
	}
}

.spe-spinner {
	animation: spe-spin 0.7s linear infinite;
	border: 2px solid currentColor;
	border-radius: 50%;
	border-top-color: transparent;
	display: inline-block;
	flex: none;
	height: 0.95em;
	opacity: 0.9;
	width: 0.95em;
}

.spe-spinner--lg {
	border-width: 3px;
	color: var(--spe-accent-strong);
	height: 28px;
	width: 28px;
}

@keyframes spe-spin {
	to {
		transform: rotate(360deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.spe-entry *,
	.spe-entry *::before,
	.spe-entry *::after,
	.spe-modal,
	.spe-modal *,
	.spe-modal *::before,
	.spe-modal *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}

	.spe-skel,
	.spe-offer__price-wait {
		opacity: 0.7;
	}
}

/* Entry thừa bị runtime gỡ khỏi luồng. */
.spe-entry[data-spe-duplicate] {
	display: none !important;
}

/* --------------------------------------------------------------------------
 * Hẹp: nút xuống dòng, bỏ pill để không bóp chữ
 * ----------------------------------------------------------------------- */

@container (max-width: 540px) {
	.spe-search {
		border-radius: var(--spe-radius);
		flex-wrap: wrap;
		padding: 0.75rem;
	}

	.spe-search__input {
		flex-basis: 60%;
	}

	.spe-search__submit {
		flex: 1 1 100%;
	}

	.spe-kpi {
		border-radius: var(--spe-radius-sm) !important;
	}

	.spe-card__trace {
		flex-basis: 100%;
		margin-left: 0;
	}

	.spe-search-halo {
		border-radius: calc(var(--spe-radius) + 9px);
	}

	/* Thanh đã xuống dòng nên bộ chọn không còn cần vạch ngăn bên trái. */
	.spe-scope__toggle {
		border-inline-start: 0;
		padding-inline: 0.25rem;
	}

	.spe-scope__panel {
		inline-size: min(320px, calc(100cqi - 1.5rem));
		inset-inline-end: 0;
		inset-inline-start: auto;
	}
}

/* Thông báo cấu hình, chỉ admin thấy. */
.spe-notice--admin {
	background: rgba(250, 178, 25, 0.14);
	border-left: 4px solid #fab219;
	border-radius: 6px;
	padding: 0.75rem 1rem;
}
