/* Card. Cả card bấm được nhờ <a> thật ở tiêu đề phủ kín card (stretched link):
   Ctrl/Cmd+click, chuột phải vẫn ra menu link kể cả khi bấm vào ảnh.

   <article class="vo-card">
     <div class="vo-card__media"><img src="..." alt="..." width="800" height="600" loading="lazy"></div>
     <div class="vo-card__body">
       <h3 class="vo-card__title"><a class="vo-card__link" href="/ninh-binh/trang-an/">Trang An</a></h3>
       <p class="vo-card__text">Mô tả ngắn...</p>
       <div class="vo-card__meta"><svg class="vo-icon">..</svg> 3 hours</div>
     </div>
     <a class="vo-badge vo-badge--on-image vo-card__tag" href="/ninh-binh/">Ninh Binh</a>  (tuỳ chọn)
     <button class="vo-heart" data-vo-heart="/ninh-binh/trang-an/">...</button>          (PHP vo_heart())
   </article>

   Biến thể:
   .vo-card--boxed    có khung viền + nền trắng (card Where to stay, affiliate)
   .vo-card--overlay  chữ nằm trên ảnh, nền mờ dần (card điểm đến)
   .vo-card--row      ảnh nhỏ bên trái, chữ bên phải (sidebar, danh sách bài)
*/

.vo-card {
	/* Chỉnh ở đây */
	--vo-card-ratio: 4 / 3;                         /* Tỉ lệ ảnh */
	--vo-card-radius: var(--vo-radius-card);          /* Bo góc ảnh */
	--vo-card-gap:var(--vo-space-3);                            /* Khoảng ảnh -> chữ */
	--vo-card-zoom: 1.05;                           /* Zoom ảnh khi hover (1 = tắt) */
	--vo-card-title-fs: var(--vo-nav-top-fs);       /* Cỡ tiêu đề (= chữ menu header) */
	--vo-card-title-fw: var(--vo-nav-fw);           /* Độ đậm tiêu đề */
	--vo-card-title-lines: 2;                       /* Số dòng tối đa tiêu đề */
	--vo-card-text-lines: 2;                        /* Số dòng tối đa mô tả */

	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--vo-card-gap);
	min-width: 0;
	color: var(--vo-ink);
	border-radius: var(--vo-card-radius);
}

.vo-card__media {
	position: relative;
	aspect-ratio: var(--vo-card-ratio);
	overflow: hidden;
	border-radius: var(--vo-card-radius);
	background: var(--vo-skeleton);                 /* nền chờ ảnh tải */
}
/* Khung chờ ảnh khi mạng chậm: bóng sáng quét từ trái sang phải trên nền xám. Quét bằng transform (chạy ở GPU, không vẽ lại); ảnh về là phủ lên nên
   bóng tự biến mất, không cần JS. Chỉ quét 8 lượt (~12s) rồi dừng để ô ảnh chưa bao giờ tải không chạy hoạt ảnh vô tận. ::before chỉ khi có ảnh: ô rỗng dùng tranh thay thế bên dưới. */
.vo-card__media:has(img) { isolation: isolate; }
.vo-card__media:has(img)::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--vo-skeleton-sweep);
	transform: translateX(-100%);
	animation: vo-skeleton-sweep 1.5s ease-in-out 8;
	pointer-events: none;
}
@keyframes vo-skeleton-sweep { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
	.vo-card__media:has(img)::before, .vo-hero__cell::before { animation: none; }
}
.vo-card__media:empty::before,                  /* không có ảnh: tranh thay thế (--vo-ph-img, tokens.css) thay vì ô trống */
.vo-search__thumb:empty::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--vo-ph-img) center bottom / cover no-repeat;
}
.vo-card__media--attraction { --vo-ph-img: var(--vo-ph-attraction); }   /* điểm tham quan chưa có ảnh: tranh núi đá vôi thay vì đồi chung */
.vo-card__media picture { display: contents; }   /* <picture> của card đổi tỉ lệ theo màn (vo_card_img): img vẫn phủ kín khung như không có nó */
.vo-card__media img {
	position: relative;                             /* trên bóng sáng khung chờ */
	z-index: 1;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--vo-dur) var(--vo-ease);
}
@media (hover: hover) and (pointer: fine) {   /* layer riêng: hết khựng cuối hiệu ứng zoom khi rê chuột. Chỉ máy tính: điện thoại không có hover, 30 ảnh card thành 30 lớp làm tab iPhone hết bộ nhớ khi chụm zoom */
	.vo-card__media img { will-change: transform; backface-visibility: hidden; }
}

.vo-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--vo-space-1);
	min-width: 0;
}
.vo-card__title {
	margin: 0;
	font-size: var(--vo-card-title-fs);
	font-weight: var(--vo-card-title-fw);
	line-height: 1.3;
	letter-spacing: normal;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--vo-card-title-lines);
	line-clamp: var(--vo-card-title-lines);
	overflow: hidden;
}
.vo-card__link {
	color: inherit;
	text-decoration: none;
	transition: color var(--vo-dur-fast) ease;
}
/* Link phủ kín cả card */
.vo-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	border-radius: inherit;
}
.vo-card__text {
	margin: 0;
	color: var(--vo-muted);
	font-size: var(--vo-fs-sm);
	line-height: 1.5;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--vo-card-text-lines);
	line-clamp: var(--vo-card-text-lines);
	overflow: hidden;
}
.vo-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vo-space-1) var(--vo-space-3);
	color: var(--vo-muted);
	font-size: var(--vo-fs-xs);
	line-height: 1.4;
	font-weight: 450;                               /* giữa 400 và 500 (Inter biến thiên) */
}
.vo-card__meta > * { display: inline-flex; align-items: flex-start; gap: var(--vo-space-1); }   /* chữ nhiều dòng: icon ở dòng đầu */
.vo-card__meta { --vo-meta-icon-nudge: -1px; }             /* nâng icon cho cân chữ hoa (thấp: -2px, cao: 0) */
.vo-card__meta .vo-icon { flex: none; display: block; height: 1.4em; position: relative; top: var(--vo-meta-icon-nudge); }   /* 1.4em = line-height của .vo-card__meta */
.vo-card__body > .vo-badge,
.vo-card__body > .vo-badges { align-self: flex-start; }   /* badge ôm chữ, không kéo hết card */

/* Nổi trên ảnh: badge trái, tim / nút phải */
.vo-card .vo-card__tag {
	position: absolute;
	top: var(--vo-space-3);
	left: var(--vo-space-3);
	z-index: var(--vo-z-card);
	max-width: calc(100% - 72px);                   /* chừa chỗ cho nút tim bên phải */
}
.vo-card > .vo-heart,
.vo-card__corner {
	position: absolute;
	top: var(--vo-space-3);
	right: var(--vo-space-3);
	z-index: var(--vo-z-card);
}

@media (hover: hover) {
	.vo-card:hover .vo-card__media img { transform: scale(var(--vo-card-zoom)); }
	/* Card chữ dưới ảnh: hover đổi màu tiêu đề thay vì gạch chân */
	.vo-card:not(.vo-card--overlay):not(.vo-card--region):hover .vo-card__link { color: var(--vo-primary-hover); }
}
/* Focus bàn phím: viền quanh cả card */
.vo-card__link:focus-visible { outline: 0; }
.vo-card:has(.vo-card__link:focus-visible) {
	outline: 2px solid var(--vo-primary);
	outline-offset: 4px;
}

/* Boxed: có khung */
.vo-card--boxed {
	--vo-card-gap: 0px;
	overflow: hidden;
	border: 1px solid var(--vo-divider);
	border-radius: var(--vo-radius-card);
	background: var(--vo-surface);
	transition: box-shadow var(--vo-dur) var(--vo-ease);
}
.vo-card--boxed .vo-card__media { border-radius: 0; }
.vo-card--boxed .vo-card__body { flex: 1; padding: var(--vo-space-4) var(--vo-space-4) var(--vo-space-4); }
.vo-card--boxed .vo-card__foot { margin-top: auto; padding-top: var(--vo-space-2); }   /* nút / giá dính đáy card */
@media (hover: hover) {
	.vo-card--boxed:hover { box-shadow: var(--vo-shadow-card); }
}

/* Overlay: chữ trên ảnh */
.vo-card--overlay {
	--vo-card-ratio: 1 / 1;                         /* Vuông */
	--vo-card-radius: var(--vo-radius-card);
	--vo-card-gap: 0px;
	color: var(--vo-on-image);
}
.vo-card--overlay .vo-card__media::after {     /* nền tối cho chữ trắng đọc được */
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;                                     /* trên ảnh (z-index 1, khung chờ ở trên) */
	background: var(--vo-shade);
	pointer-events: none;
}
/* Ảnh + chữ chồng bằng grid; phần chữ phủ kín card nên link phủ (::after) vẫn trọn card */
.vo-card--overlay { display: grid; }
.vo-card--overlay .vo-card__media,
.vo-card--overlay .vo-card__body { grid-area: 1 / 1; }
.vo-card--overlay .vo-card__body {
	position: relative;
	z-index: 1;                                     /* nằm trên ảnh */
	justify-content: flex-end;
	padding: var(--vo-space-4);
}
.vo-card--overlay .vo-card__title { font-size: var(--vo-fs-lg); font-weight: var(--vo-overlay-title-fw); color: var(--vo-on-image); }
.vo-card--overlay .vo-card__text,
.vo-card--overlay .vo-card__meta { color: var(--vo-on-image); font-weight: var(--vo-overlay-sub-fw); }   /* chữ phụ trên ảnh */
/* Card attraction: ảnh vuông sạch (tag + tim nằm trên ảnh), chữ dưới ảnh. Điểm đến · thời gian · giá vé nằm 1 dòng đậm, không icon. */
.vo-card--attraction .vo-card__meta { color: var(--vo-ink); font-size: var(--vo-fs-xs); font-weight: 600; }
.vo-card--attraction .vo-card__meta > span { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }   /* luôn 1 dòng: dư thì "…" */

/* Row: ảnh nhỏ trái, chữ phải */
.vo-card--row {
	--vo-card-ratio: 1 / 1;
	--vo-card-radius: var(--vo-radius-card);
	--vo-card-thumb: 88px;                          /* Cỡ ảnh nhỏ */
	flex-direction: row;
	align-items: center;
	gap: var(--vo-space-4);
}
.vo-card--row .vo-card__media { flex: none; width: var(--vo-card-thumb); }
.vo-card--row .vo-card__body { flex: 1; }
.vo-card--row .vo-card__title { font-size: var(--vo-fs-sm); }
/* Tim ở góc ảnh nhỏ, không đè chữ */
.vo-card--row > .vo-heart { --vo-heart-size: 28px; --vo-heart-icon: 16px; }
.vo-card--row > .vo-heart,
.vo-card--row .vo-card__corner {
	top: 4px;
	right: auto;
	left: calc(var(--vo-card-thumb) - 32px);
}

/* Mobile: card nhỏ nên chữ gọn hơn */
@media (max-width: 599px) {
	.vo-card:not(.vo-card--overlay) { --vo-card-gap: var(--vo-space-2); }
	.vo-card__body { gap: 2px; }
	.vo-card__title { line-height: 1.25; }
	.vo-card__text { font-size: var(--vo-fs-xs); line-height: 1.4; }
	.vo-card--overlay .vo-card__body { padding: var(--vo-space-3); }
}

/* Lưới card tự chia cột: <div class="vo-grid" style="--vo-grid-min: 220px"> */
.vo-grid {
	--vo-grid-min: 260px;                           /* Card hẹp hơn số này thì xuống dòng */
	--vo-grid-gap:var(--vo-space-5) var(--vo-space-5);
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--vo-grid-min)), 1fr));
	gap: var(--vo-grid-gap);
}

/* Card attraction (overlay) */
.vo-card--attraction {
	--vo-card-ratio: 1 / 1;
	--vo-card-title-fs: var(--vo-fs-md);
	--vo-card-title-fw: 600;
	--vo-card-title-lines: 3;                       /* tên dài xuống dòng thay vì che ảnh */
}

/* Dòng đánh giá: điểm + 5 chấm vàng + (số lượt). Chấm nửa tô bằng gradient cứng, không cần ảnh / icon */
.vo-rating {
	--vo-rating-dot: 11px;                          /* Cỡ 1 chấm */
	display: flex;
	align-items: center;
	gap: var(--vo-space-1);
	color: var(--vo-muted);
	font-size: var(--vo-fs-xs);
	line-height: 1;
}
.vo-rating__score { color: var(--vo-ink); }
.vo-rating__dots { display: inline-flex; gap: 2px; margin-inline: var(--vo-space-1); }
.vo-rating__dot {
	box-sizing: border-box;
	width: var(--vo-rating-dot);
	height: var(--vo-rating-dot);
	border: 1.5px solid var(--vo-accent);           /* viền vàng giữ cho chấm rỗng vẫn thấy được */
	border-radius: 50%;
}
.vo-rating__dot--full { background: var(--vo-accent); }
.vo-rating__dot--half { background: linear-gradient(to right, var(--vo-accent) 50%, transparent 50%); }

/* Card region trang chủ (overlay) */
.vo-card--region { --vo-card-ratio: 1 / 1; }    /* Mobile: vuông */
@media (min-width: 600px) {
	.vo-card--region { --vo-card-ratio: 4 / 3; }  /* Tablet + desktop: ngang 4:3 */
}
/* Mobile: số card region hiện cùng lúc (1.5 = lộ card kế; tăng = card nhỏ hơn) */
.vo-regions .vo-scroller { --vo-regions-per-m: 1.5; }
@media (max-width: 599px) {
	.vo-regions .vo-scroller--3 { --_per: var(--vo-regions-per-m); }
}

/* Thời gian đọc dưới tên bài (block guides) */
.vo-card__read { color: var(--vo-muted); font-size: var(--vo-fs-2xs); letter-spacing: .03em; text-transform: uppercase; }   /* "N MIN READ" ở mọi card bài viết (hàng cuộn, sidebar, hộp thoại) */
