/*!
 * SaaS Experience Bridge — Khung popup kết quả: thanh tiến độ, đầu, thân, chân
 *
 * 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.
 */

/* --------------------------------------------------------------------------
 * Popup kết quả
 *
 * Bảng so sánh cần bề ngang mà cột nội dung của theme không có. Popup lấy đúng
 * khoảng rộng nó cần, và nền mờ cắt hẳn mọi thứ phía sau ra khỏi tầm chú ý.
 * ----------------------------------------------------------------------- */

/*
 * Neo lên MÉP TRÊN, không căn giữa.
 *
 * Căn giữa nghĩa là mỗi lần nội dung cao thêm (giá về, panel thay khung xương)
 * thì cả hộp trượt lên vài chục pixel — người dùng đang đọc dòng nào thì dòng
 * đó chạy khỏi mắt. Neo trên thì phần đã đọc đứng yên, chỉ có phần dưới dài ra.
 */
.spe-modal {
	align-items: flex-start;
	display: flex;
	inset: 0;
	justify-content: center;
	/* Chừa 50px với mép màn hình; khổ hẹp thì không còn 50px nào để chừa. */
	padding: 50px;
	position: fixed;
	/* Trên mọi thứ của theme, nhưng vẫn dưới thanh admin của WordPress. */
	z-index: 99990;
}



@media (max-width: 700px) {
	.spe-modal {
		padding: 10px;
	}
}

/*
 * Nền mờ phía sau popup — KHÔNG dùng `backdrop-filter`.
 *
 * `backdrop-filter: blur()` bắt trình duyệt đọc lại toàn bộ pixel của trang nằm
 * dưới lớp phủ rồi làm mờ lại, ở kích thước cả màn hình. Nó cũng kéo cả cây
 * popup ra khỏi đường composite nhanh, nên mỗi lần cuộn trong bảng giá là một
 * lần cả lớp phủ phải dựng lại — đúng triệu chứng cuộn giật, và giật nặng hơn
 * hẳn trên laptop không rời GPU.
 *
 * Việc của lớp này là làm trang phía sau LÙI ra sau, và một lớp tối đặc hơn một
 * chút làm đúng việc đó với chi phí bằng không. Chỗ mất đi là vệt nhoè của chữ
 * nền — thứ không ai nhìn khi popup đang mở.
 */
.spe-modal__backdrop {
	background: rgba(15, 17, 21, 0.66);
	inset: 0;
	position: absolute;
}

.spe-modal[data-spe-scheme="dark"] .spe-modal__backdrop {
	background: rgba(0, 0, 0, 0.74);
}

/*
 * Khung popup CỐ ĐỊNH, không co giãn theo lượng dữ liệu đã về.
 *
 * Kết quả về nhỏ giọt trong hai phút. Nếu khung cao theo nội dung thì mỗi lượt
 * poll là một lần cả popup đổi kích thước dưới con trỏ — và vì nó nằm giữa màn
 * hình, đổi chiều cao là mọi thứ bên trong trượt theo. Cố định khung một lần
 * lúc mở: dữ liệu dài ra thì cuộn bên trong `.spe-modal__body`, còn bốn góc
 * popup đứng nguyên từ lúc mở tới lúc xong.
 */
.spe-modal__dialog {
	animation: spe-modal-in 0.22s cubic-bezier(0.22, 0.61, 0.36, 1);
	background: var(--spe-surface);
	border: 1px solid var(--spe-border);
	border-radius: var(--spe-radius);
	box-shadow: 0 24px 70px -20px rgba(15, 17, 21, 0.5);
	container-type: inline-size;
	display: flex;
	flex-direction: column;
	max-height: 100%;
	/* Không giới hạn bề ngang: bảng so sánh là lý do popup tồn tại. */
	max-width: none;
	overflow: hidden;
	position: relative;
	width: 100%;
}

/*
 * Chỉ view kết quả mới lấy hết chiều cao. Màn hình lỗi hay "không tìm thấy" chỉ
 * có một dòng chữ và một nút — kéo nó cao bằng màn hình thì 90% popup là khoảng
 * trắng, đọc ra như giao diện vẽ dở.
 */
.spe-modal__dialog:has( [data-spe-view="SUCCESS"]:not( [hidden] ) ) {
	block-size: 100%;
}

.spe-modal__dialog:focus-visible {
	outline: none;
}

@keyframes spe-modal-in {
	from {
		opacity: 0;
		transform: translateY(12px) scale(0.99);
	}
}

/*
 * Thanh chạy ở mép trên. Cùng ngôn ngữ với thanh trong thẻ đang tải, nhưng ở
 * đây nó là dấu hiệu DUY NHẤT rằng có việc đang chạy — kết quả không được biến
 * đi đâu cả.
 */
.spe-modal__bar {
	background: var(--spe-border);
	display: none;
	height: 3px;
	inset-block-start: 0;
	inset-inline: 0;
	overflow: hidden;
	position: absolute;
	z-index: 1;
}

/* Hiện khi đang thu, đang gửi, và trong nửa giây "chạy nốt" sau khi xong. */
.spe-modal[data-spe-sending="1"] .spe-modal__bar,
.spe-modal[data-spe-busy="1"] .spe-modal__bar,
.spe-modal[data-spe-finishing] .spe-modal__bar {
	display: block;
}

/* Quãng kết thúc: đầy tới 100% rồi mờ dần, không tắt phụt. */
.spe-modal[data-spe-finishing] .spe-modal__bar {
	animation: spe-bar-out 0.7s ease forwards;
}

@keyframes spe-bar-out {
	0%,
	55% {
		opacity: 1;
	}

	100% {
		opacity: 0;
	}
}

/*
 * Hai chế độ. Chưa đo được thì một vệt chạy qua lại; đo được rồi thì thanh đầy
 * dần từ trái. Chuyển giữa hai chế độ chỉ là đổi thuộc tính data — không dựng
 * lại DOM, nên không có cú giật nào ở khoảnh khắc chuyển.
 */
.spe-modal__fill {
	background: var(--spe-accent-strong);
	display: block;
	height: 100%;
	position: absolute;
}

.spe-modal__bar[data-spe-mode="indeterminate"] .spe-modal__fill {
	animation: spe-indeterminate 1.5s cubic-bezier(0.65, 0.05, 0.36, 1) infinite;
	inline-size: 40%;
}

/*
 * Chế độ đo được: đầy dần và LUÔN chuyển động.
 *
 * `transition` dài (0.7s, ease-out) là cố ý: giá về theo từng đợt, nên nếu nhảy
 * tức thì thì thanh đứng im mấy giây rồi giật một cái. Trượt chậm khiến quãng
 * chờ có cảm giác liên tục — và đó là toàn bộ việc của một thanh tiến độ.
 */
.spe-modal__bar[data-spe-mode="determinate"] .spe-modal__fill {
	inline-size: 0;
	inset-inline-start: 0;
	transition: width 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Vệt sáng chạy trên phần đã đầy: nói "vẫn đang chạy" ngay cả khi số đứng yên. */
.spe-modal__bar[data-spe-mode="determinate"] .spe-modal__fill::after {
	animation: spe-sheen 1.6s ease-in-out infinite;
	background: linear-gradient(
		90deg,
		transparent,
		color-mix(in oklab, var(--spe-surface) 65%, transparent),
		transparent
	);
	content: "";
	inset: 0;
	position: absolute;
}

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

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

/* Phần trăm trong viên nhãn "đang quét", đậm như số của bản mẫu. */
.spe-scan__pct {
	color: var(--spe-ink);
	font-variant-numeric: tabular-nums;
}

/*
 * Nút đóng nổi lên trên nội dung chứ không đứng thành một dải riêng.
 *
 * Dải riêng chỉ chứa đúng một nút 32px nhưng ăn 40px chiều cao ở NGAY chỗ đắt
 * nhất của popup — mép trên, nơi mắt nhìn vào đầu tiên. Nổi lên trên thì hàng
 * tiêu đề kết quả lên sát mép, và ô mà nút che vốn là chỗ trống.
 *
 * Đổi lại phải chừa chỗ cho nó: xem `padding-inline-end` của `.spe-head` —
 * viên nhãn "đang quét" nằm đúng góc đó.
 */
.spe-modal__head {
	display: flex;
	inset-block-start: 0;
	inset-inline-end: 0;
	justify-content: flex-end;
	padding: 10px 12px;
	position: absolute;
	z-index: 3;
}

.spe-modal__close {
	appearance: none;
	background: var(--spe-surface-2);
	border: 1px solid var(--spe-border);
	border-radius: var(--spe-radius-pill);
	color: var(--spe-ink-2);
	cursor: pointer;
	display: inline-flex;
	flex: none;
	height: 32px;
	padding: 0;
	place-items: center;
	place-content: center;
	transition: background-color 0.15s ease, color 0.15s ease;
	width: 32px;
}

.spe-modal__close:hover {
	background: var(--spe-surface-3);
	color: var(--spe-ink);
}

.spe-modal__close:focus-visible {
	box-shadow: var(--spe-ring);
	outline: none;
}

.spe-modal__close svg {
	height: 14px;
	width: 14px;
}

/*
 * Nền xám nhạt, panel trắng — đây là thứ làm cả bản mẫu "ra hình": mỗi khối
 * nổi lên như một thẻ riêng. Popup trắng trên panel trắng thì viền 1px phải
 * gánh hết việc phân tách, và nhìn thành một mảng phẳng.
 */
.spe-modal__body {
	background: var(--spe-surface-2);
	flex: 1 1 auto;
	overflow: auto;
	overscroll-behavior: contain;
	padding: 12px 18px 16px;
}

/*
 * Chân popup chỉ tồn tại khi thật sự có nút: một thanh trống dưới kết quả trông
 * như giao diện vẽ dở.
 */
/*
 * Chân popup dính đáy, nên mỗi dòng ở đây là một dòng bị lấy đi khỏi vùng đọc
 * kết quả. Nút và ba gạch đầu dòng gỡ rủi ro xếp CÙNG một hàng; câu giải thích
 * việc theo dõi tự động chuyển xuống khối mời dưới bảng, nơi nó có chỗ để đọc.
 */
.spe-modal__foot {
	align-items: center;
	background: var(--spe-surface);
	border-top: 1px solid var(--spe-border-strong);
	display: flex;
	flex-wrap: wrap;
	gap: 8px 16px;
	justify-content: center;
	padding: 10px 18px;
}

/* Câu chữ bên trái nút, như thanh CTA của bản mẫu. */
.spe-cta__copy {
	display: grid;
	flex: 1;
	gap: 1px;
	min-width: 220px;
}

.spe-cta__title {
	color: var(--spe-ink);
	font-size: 12.5px;
	font-weight: 700;
	text-wrap: pretty;
}

.spe-cta__sub {
	color: var(--spe-ink-2);
	font-size: 11.5px;
	text-wrap: pretty;
}

@container (max-width: 700px) {
	.spe-cta__copy {
		flex: 1 1 100%;
		text-align: center;
	}
}

.spe-modal__foot:not(:has(.spe-actions:not([hidden]))) {
	display: none;
}

.spe-modal__foot .spe-actions {
	flex: none;
	margin-top: 0;
}

.spe-modal__foot .spe-btn {
	border-radius: 6px;
	font-size: 13px;
	font-weight: 700;
	padding: 9px 18px;
}

