/**
 * Khối bài viết — bốn layout dùng chung một bộ phần tử.
 *
 * Không mã màu, không px cho khoảng cách (CLAUDE.md §1.2, §1.3), để khối đi theo
 * tông của từng khách. Ngoại lệ duy nhất là lớp phủ tối và chữ trắng của layout
 * mosaic: scrim là bóng đổ lên ảnh, không mang màu thương hiệu (§1.8).
 *
 * HAI HỌ LAYOUT, và khác nhau ở đúng một điều:
 *
 *   nd-loop--overlay   chữ ĐÈ lên ảnh   → mosaic
 *   (không overlay)    chữ DƯỚI/BÊN ảnh → grid, list, feature
 *
 * Chữ đè lên ảnh chỉ hợp khi ô đủ lớn để tấm ảnh làm nền được. Ba ô đều nhau
 * trong `grid` thì không ô nào là điểm nhấn, và chữ trắng trên ảnh ở cỡ ấy là
 * một bài kiểm tra thị lực.
 */

/* ── Khung chung ─────────────────────────────────────────────────────────── */

.nd-loop__item {
	display: flex;
	flex-direction: column;
	min-inline-size: 0;
}

.nd-loop__media {
	background: var( --wp--preset--color--surface, transparent );
	border-radius: var( --wp--custom--radius--sm, 0.25rem );
	overflow: hidden;
	position: relative;
}

/*
 * `object-fit` đi kèm mọi chỗ ảnh bị ép khung — CLAUDE.md nói rõ, và DEBT-011
 * đã phải sửa 17 chỗ vì thiếu nó. Không có dòng này thì ảnh 16:9 nhét vào ô cao
 * là một người bị kéo dài ra.
 */
.nd-loop__image {
	block-size: 100%;
	display: block;
	inline-size: 100%;
	inset: 0;
	object-fit: cover;
	position: absolute;
}

.nd-loop__badge {
	background: var( --wp--preset--color--brand, #000 );
	color: var( --wp--preset--color--fg-on-brand, #fff );
	font-size: var( --wp--preset--font-size--xs, 0.75rem );
	inset-block-end: 0;
	inset-inline-start: 0;
	letter-spacing: 0.04em;
	padding-block: var( --wp--preset--spacing--3-xs, 0.25rem );
	padding-inline: var( --wp--preset--spacing--2-xs, 0.5rem );
	position: absolute;
	text-transform: uppercase;
	z-index: 1;
}

.nd-loop__title {
	margin: 0;
}

.nd-loop__title a {
	color: inherit;
	text-decoration: none;
}

.nd-loop__title a:hover,
.nd-loop__title a:focus-visible {
	text-decoration: underline;
}

.nd-loop__meta {
	color: var( --wp--preset--color--fg-muted, currentColor );
	font-size: var( --wp--preset--font-size--sm, 0.875rem );
	margin-block: var( --wp--preset--spacing--2-xs, 0.5rem ) 0;
}

.nd-loop__author {
	font-weight: 700;
}

.nd-loop__sep {
	opacity: 0.7;
	padding-inline: var( --wp--preset--spacing--3-xs, 0.25rem );
}

.nd-loop__excerpt {
	color: var( --wp--preset--color--fg-muted, currentColor );
	margin-block: var( --wp--preset--spacing--2-xs, 0.5rem ) 0;
}

/* Tiêu đề mục, kiểu nhãn đặc trên một đường kẻ. */
.nd-loop__head {
	border-block-end: 2px solid var( --wp--preset--color--fg, currentColor );
	margin-block-end: var( --wp--preset--spacing--sm, 1rem );
}

.nd-loop__head-label {
	background: var( --wp--preset--color--fg, #000 );
	color: var( --wp--preset--color--canvas, #fff );
	display: inline-block;
	font-size: var( --wp--preset--font-size--sm, 0.875rem );
	font-weight: 700;
	letter-spacing: 0.06em;
	padding-block: var( --wp--preset--spacing--2-xs, 0.5rem );
	padding-inline: var( --wp--preset--spacing--sm, 1rem );
	text-transform: uppercase;
}

.nd-loop__notice {
	border: 1px dashed var( --wp--preset--color--line, currentColor );
	color: var( --wp--preset--color--fg-muted, currentColor );
	padding: var( --wp--preset--spacing--sm, 1rem );
}

/* ── Họ overlay: chữ đè lên ảnh ──────────────────────────────────────────── */

.nd-loop--overlay .nd-loop__item {
	border-radius: var( --wp--custom--radius--sm, 0.25rem );
	isolation: isolate;
	min-block-size: 0;
	overflow: hidden;
	position: relative;
}

.nd-loop--overlay .nd-loop__media {
	border-radius: 0;
	inset: 0;
	position: absolute;
}

.nd-loop--overlay .nd-loop__badge {
	inset-block-end: auto;
	inset-block-start: auto;
	position: static;
}

/*
 * NỀN TỐI ĐI THEO KHỐI CHỮ, KHÔNG ĐI THEO Ô.
 *
 * Một lớp phủ trải đều cả ô thì độ tối ở chỗ có chữ phụ thuộc CHIỀU CAO Ô: ô lớn
 * cao gấp đôi ô nhỏ, nên cùng một gradient cho ra hai độ tối khác hẳn nhau, và ô
 * nhỏ nào rơi vào một tấm ảnh sáng là chữ trắng biến mất. Đã thấy đúng như vậy
 * lúc chụp thử.
 *
 * Đặt gradient lên chính khối chữ thì chữ luôn nằm trên ít nhất 0,62 alpha, bất
 * kể ô cao bao nhiêu và ảnh sáng tối thế nào.
 */
.nd-loop--overlay .nd-loop__body {
	background: linear-gradient( to top, var( --nd-scrim-end ) 0%, var( --nd-scrim-mid ) 55%, transparent 100% );
	color: #fff;
	margin-block-start: auto;
	padding: var( --wp--preset--spacing--sm, 1rem );
	padding-block-start: var( --wp--preset--spacing--xl, 3rem );
	position: relative;
}

.nd-loop--overlay .nd-loop__badge {
	display: inline-block;
	margin-block-end: var( --wp--preset--spacing--2-xs, 0.5rem );
}

/*
 * CHỮ TRÊN ẢNH PHẢI KHAI MÀU TƯỜNG MINH, KHÔNG ĐƯỢC THỪA KẾ.
 *
 * Đây là một lỗi đã ra tới site khách. Bản đầu chỉ đặt `color: #fff` lên
 * `.nd-loop__body` rồi để tiêu đề thừa kế xuống. Chạy đúng trên nd-base, và
 * SAI trên site của khách — vì preset của khách khai:
 *
 *     styles.elements.heading.color.text
 *
 * WordPress dịch dòng đó thành `:root :where(h1,h2,h3…){color:…}`, tức một màu
 * TƯỜNG MINH trên thẻ tiêu đề. Thừa kế chỉ chạy khi KHÔNG có luật nào khớp —
 * có một luật rồi thì màu trắng của khối cha không bao giờ xuống tới nơi. Tiêu
 * đề thành chữ đậm trên nền ảnh tối, gần như không đọc được.
 *
 * Bài học chung: một lớp phủ chữ-trên-ảnh không được phụ thuộc vào thừa kế,
 * vì mọi preset đều có quyền tô màu thẻ tiêu đề và mỗi khách một preset.
 */
.nd-loop--overlay .nd-loop__title,
.nd-loop--overlay .nd-loop__title a,
.nd-loop--overlay .nd-loop__meta,
.nd-loop--overlay .nd-loop__excerpt {
	color: var( --nd-overlay-text );
}

/*
 * BA MỨC LỚP PHỦ VÀ HAI MÀU CHỮ — vì khoá cứng chữ trắng là sửa một lỗi bằng
 * cách tạo một cái cũi khác.
 *
 * Ảnh tối thì chữ trắng đọc tốt và lớp phủ nhạt là đủ. Ảnh sáng — ảnh sản phẩm
 * nền trắng, ảnh chụp ngoài trời — thì chữ trắng biến mất dù phủ đậm tới đâu,
 * và lối ra đúng là đảo lại: nền phủ sáng, chữ đậm.
 *
 * Trắng và đen ở lớp phủ là màu tuyệt đối, đúng ngoại lệ §1.8 cho phép: lớp phủ
 * là bóng đổ lên ảnh, không mang màu thương hiệu. Nhưng CHỮ đậm thì lấy từ vai
 * trò `fg` của khách — nó là chữ, không phải bóng.
 */
.nd-loop--overlay {
	--nd-overlay-text: #fff;
	--nd-scrim-end: rgba( 0, 0, 0, 0.88 );
	--nd-scrim-mid: rgba( 0, 0, 0, 0.62 );
}

.nd-loop--scrim-soft {
	--nd-scrim-end: rgba( 0, 0, 0, 0.7 );
	--nd-scrim-mid: rgba( 0, 0, 0, 0.4 );
}

.nd-loop--scrim-strong {
	--nd-scrim-end: rgba( 0, 0, 0, 0.96 );
	--nd-scrim-mid: rgba( 0, 0, 0, 0.8 );
}

.nd-loop--text-dark {
	--nd-overlay-text: var( --wp--preset--color--fg, #101828 );
	--nd-scrim-end: rgba( 255, 255, 255, 0.94 );
	--nd-scrim-mid: rgba( 255, 255, 255, 0.72 );
}

.nd-loop--text-dark.nd-loop--scrim-soft {
	--nd-scrim-end: rgba( 255, 255, 255, 0.8 );
	--nd-scrim-mid: rgba( 255, 255, 255, 0.52 );
}

.nd-loop--text-dark.nd-loop--scrim-strong {
	--nd-scrim-end: rgba( 255, 255, 255, 0.98 );
	--nd-scrim-mid: rgba( 255, 255, 255, 0.88 );
}

/* ── Layout mosaic ───────────────────────────────────────────────────────── */

/*
 *   ┌───────────────┬───────────────┐
 *   │               │     wide      │
 *   │     lead      ├───────┬───────┤
 *   │               │ small │ small │
 *   └───────────────┴───────┴───────┘
 *
 * Bốn cột hai hàng, KHÔNG phải "hai cột rồi chia đôi": chia lồng nhau thì hai ô
 * nhỏ dưới phải không bao giờ thẳng hàng với ô vừa ở trên, vì mỗi tầng chia lại
 * mang một `gap` riêng.
 */
.nd-loop--mosaic {
	display: grid;
	gap: var( --wp--preset--spacing--2-xs, 0.5rem );
	grid-template-columns: repeat( 4, 1fr );
	grid-template-rows: repeat( 2, minmax( 0, 1fr ) );
}

.nd-loop--mosaic .nd-loop__item--lead {
	grid-column: 1 / 3;
	grid-row: 1 / 3;

	/* Không có sàn này thì ô lớn co theo cột phải và ảnh bị bẹp. */
	min-block-size: 24rem;
}

.nd-loop--mosaic .nd-loop__item--wide {
	grid-column: 3 / 5;
	grid-row: 1 / 2;
}

.nd-loop--mosaic .nd-loop__item--small {
	grid-row: 2 / 3;
}

.nd-loop--mosaic .nd-loop__item--small:nth-of-type( 3 ) {
	grid-column: 3 / 4;
}

.nd-loop--mosaic .nd-loop__item--small:nth-of-type( 4 ) {
	grid-column: 4 / 5;
}

.nd-loop--mosaic .nd-loop__item--lead .nd-loop__title {
	font-size: var( --wp--preset--font-size--xl, 1.75rem );
}

.nd-loop--mosaic .nd-loop__item--wide .nd-loop__title {
	font-size: var( --wp--preset--font-size--lg, 1.25rem );
}

.nd-loop--mosaic .nd-loop__item--small .nd-loop__title {
	font-size: var( --wp--preset--font-size--sm, 0.875rem );
}

/* ── Layout grid ─────────────────────────────────────────────────────────── */

.nd-loop--grid .nd-loop__cols {
	display: grid;
	gap: var( --wp--preset--spacing--md, 1.5rem );
	grid-template-columns: repeat( 3, 1fr );
}

.nd-loop--grid .nd-loop__media {
	aspect-ratio: 4 / 3;
}

.nd-loop--grid .nd-loop__body {
	padding-block-start: var( --wp--preset--spacing--xs, 0.75rem );
}

.nd-loop--grid .nd-loop__title {
	font-size: var( --wp--preset--font-size--md, 1.125rem );
}

/* ── Layout list ─────────────────────────────────────────────────────────── */

.nd-loop--list .nd-loop__item {
	display: grid;
	gap: var( --wp--preset--spacing--sm, 1rem );
	grid-template-columns: minmax( 0, 14rem ) minmax( 0, 1fr );
	margin-block-end: var( --wp--preset--spacing--md, 1.5rem );
}

.nd-loop--list .nd-loop__item:last-child {
	margin-block-end: 0;
}

.nd-loop--list .nd-loop__media {
	aspect-ratio: 3 / 2;
}

.nd-loop--list .nd-loop__title {
	font-size: var( --wp--preset--font-size--lg, 1.25rem );
}

/* ── Layout feature ──────────────────────────────────────────────────────── */

.nd-loop--feature .nd-loop__split {
	display: grid;
	gap: var( --wp--preset--spacing--md, 1.5rem );
	grid-template-columns: minmax( 0, 3fr ) minmax( 0, 2fr );
}

.nd-loop--feature .nd-loop__main .nd-loop__media {
	aspect-ratio: 16 / 10;
}

.nd-loop--feature .nd-loop__main .nd-loop__title {
	font-size: var( --wp--preset--font-size--xl, 1.75rem );
}

.nd-loop--feature .nd-loop__main .nd-loop__body {
	padding-block-start: var( --wp--preset--spacing--xs, 0.75rem );
}

.nd-loop--feature .nd-loop__rail .nd-loop__item {
	border-block-end: 1px solid var( --wp--preset--color--line, currentColor );
	display: grid;
	gap: var( --wp--preset--spacing--xs, 0.75rem );
	grid-template-columns: minmax( 0, 7rem ) minmax( 0, 1fr );
	padding-block-end: var( --wp--preset--spacing--xs, 0.75rem );
}

.nd-loop--feature .nd-loop__rail .nd-loop__item:last-child {
	border-block-end: 0;
	padding-block-end: 0;
}

.nd-loop--feature .nd-loop__rail .nd-loop__media {
	aspect-ratio: 4 / 3;
}

.nd-loop--feature .nd-loop__rail .nd-loop__title {
	font-size: var( --wp--preset--font-size--sm, 0.875rem );
}

/* ── Điện thoại ──────────────────────────────────────────────────────────── */

/*
 * Dưới 782px mọi lưới thành một cột. Giữ mosaic trên điện thoại là bốn ô cao
 * bằng một phần tư màn hình, và ô nào cũng không đọc được.
 */
@media ( max-width: 781px ) {

	.nd-loop--mosaic {
		grid-template-columns: 1fr;
		grid-template-rows: none;
	}

	.nd-loop--mosaic .nd-loop__item--lead,
	.nd-loop--mosaic .nd-loop__item--wide,
	.nd-loop--mosaic .nd-loop__item--small:nth-of-type( 3 ),
	.nd-loop--mosaic .nd-loop__item--small:nth-of-type( 4 ) {
		grid-column: auto;
		grid-row: auto;
	}

	.nd-loop--mosaic .nd-loop__item {
		min-block-size: 14rem;
	}

	.nd-loop--mosaic .nd-loop__item--lead {
		min-block-size: 18rem;
	}

	.nd-loop--grid .nd-loop__cols,
	.nd-loop--feature .nd-loop__split {
		grid-template-columns: 1fr;
	}

	.nd-loop--list .nd-loop__item,
	.nd-loop--feature .nd-loop__rail .nd-loop__item {
		grid-template-columns: minmax( 0, 8rem ) minmax( 0, 1fr );
	}
}
