/**
 * Bốc Số VTG — style cho dashboard frontend.
 *
 * MOBILE-FIRST: mọi style mặc định (không media query) là giao diện mobile;
 * @media (min-width: ...) chỉ MỞ RỘNG thêm cho tablet/desktop.
 * Xem chuẩn: docs/DASHBOARD_STANDARDS.md §5.
 *
 * ── Hệ mốc kích thước MÀN HÌNH (breakpoint) — CHUẨN CHUNG toàn dự án ────
 * Lấy đúng số của Tailwind CSS (framework phổ biến nhất hiện dùng số này) để
 * không tự chế số tuỳ hứng. Dùng cho MỌI @media (min-width: ...) mới thêm
 * sau này — không tạo mốc lạ (VD 900px, 1440px...) trừ khi có lý do rất cụ
 * thể ghi rõ trong comment tại chỗ đó.
 *
 *   640px  (sm) — điện thoại lớn/phablet nằm ngang, ít dùng trong dashboard.
 *   768px  (md) — tablet dọc / cửa sổ trình duyệt chia đôi — mốc CHÍNH, mở
 *                 bố cục 2 cột (.bsv-grid--2, .bsv-grid--2-1...).
 *   1024px (lg) — tablet ngang / laptop nhỏ — mốc cho bố cục nhiều cột hơn
 *                 hoặc tỉ lệ cột lệch cần nhiều chỗ (.bsv-grid--reception).
 *   1280px (xl) — desktop thật — KHÔNG mở thêm cột, chỉ là mốc tham chiếu;
 *                 nội dung form/chi tiết dùng .bsv-content--sm/md/lg/xl
 *                 (max-width cố định, xem bên dưới) để tự dừng lại ở đây dù
 *                 màn hình FHD/2K/4K/8K rộng tới đâu — KHÔNG thêm mốc riêng
 *                 cho từng độ phân giải (không ai làm vậy, xem nghiên cứu
 *                 Tailwind/Bootstrap: cả 2 đều dừng breakpoint quanh
 *                 1280-1536px, còn lại xử lý bằng max-width của container).
 *
 * KHÔNG khai báo font-family — kế thừa Inter Tight từ Flatsome (CLAUDE.md §1).
 * Mọi class có tiền tố .bsv- nên không đụng độ theme.
 */

/* ── Full-width: trang plugin chiếm 100% bề rộng trên desktop ─────────
   Router thêm class bsv-page vào <body> ở mọi trang chứa shortcode plugin;
   ghi đè max-width container của Flatsome chỉ trong phạm vi các trang đó. */
body.bsv-page .container,
body.bsv-page .row.row-main {
	max-width: 100% !important;
}

/* Giảm khoảng trắng đầu trang trước tabs danh mục tin tức (xem
   components/news-tabs.php) — Flatsome mặc định có padding-top khá lớn cho
   #content (canh giữa "Page Title" ẩn), áp dụng cho cả trang bài viết (đơn
   post, nơi JS dời tabs lên đầu .article-inner) lẫn trang shortcode plugin. */
body.single-post #content,
body.bsv-page #content {
	padding-top: 0 !important;
}

/* ── Header theo vai trò thay cho header Flatsome trên TOÀN BỘ trang ──────
   Router::bodyClass() gắn class bsv-no-theme-header cho mọi trang front-end;
   header plugin được in ngay sau <body> (wp_body_open, xem
   Router::renderGlobalHeader()/render()) rồi ẩn header theme ở đây.
   Liệt kê nhiều selector Flatsome hay dùng — nếu site vẫn còn sót 1 header
   theme nào đó, F12 kiểm tra ID/class thật rồi bổ sung thêm vào đây. */
body.bsv-no-theme-header #header,
body.bsv-no-theme-header .header-wrapper,
body.bsv-no-theme-header #wrapper-navigation,
body.bsv-no-theme-header .top-bar-wrapper,
body.bsv-no-theme-header .stuck-nav-helper {
	display: none !important;
}

/* Chừa khoảng cách nhỏ quanh header plugin — CHỈ ở trang header được chèn
   trực tiếp sau <body> (bài viết, trang tĩnh...), không phải trang dashboard/
   shortcode (đã nằm sẵn trong khung nội dung có lề đúng, thêm margin ở đây
   sẽ làm header bị lệch/thụt vào so với nội dung bên dưới). Chỉ set
   margin-top/trái/phải riêng lẻ — không dùng shorthand để không đè mất
   margin-bottom mặc định của .bsv-header (16px, xem trên). */
body.bsv-header-injected .bsv-header {
	margin-left: 10px;
	margin-right: 10px;
	margin-top: 10px;
}

.bsv {
	/* Xanh y tế (teal) — đổi thương hiệu chỉ cần sửa 2 biến này. */
	--bsv-primary: #0d9488;
	--bsv-primary-dark: #0f766e;
	--bsv-bg: #f6f8fb;
	--bsv-surface: #fff;
	--bsv-border: #e2e8f0;
	--bsv-text: #1e293b;
	--bsv-muted: #64748b;
	--bsv-success: #16a34a;
	--bsv-warning: #d97706;
	--bsv-danger: #dc2626;
	--bsv-radius: 10px;

	color: var(--bsv-text);
	font-size: 15px;
	line-height: 1.55;
}

.bsv *,
.bsv *::before,
.bsv *::after {
	box-sizing: border-box;
}

/* ── Header chung mọi trang plugin ──────────────────────────────────── */
.bsv-header {
	align-items: center;
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	display: flex;
	justify-content: space-between;
	margin-bottom: 8px;
	padding: 6px;
}

@media (min-width: 768px) {
	.bsv-header { margin-bottom: 16px; padding: 8px 14px; }
}

.bsv-header__logo { color: var(--bsv-text); display: flex; align-items: center; text-decoration: none; }
.bsv-header__logo img { display: block; height: 36px !important; max-width: 160px; object-fit: contain; width: auto !important; }

.bsv-header__nav { display: flex; gap: 4px; }

.bsv-header__link {
	/* appearance:none — nút "Thêm vào Màn hình chính" là <button>, các mục
	   còn lại là <a>. Thiếu dòng này, Safari/Chrome tự vẽ THÊM khung nút hệ
	   điều hành (-webkit-appearance mặc định của button) chồng lên box đã
	   canh giữa bằng flex, đẩy icon lệch lên trên dù CSS flex đã đúng. Đây
	   mới là nguyên nhân thật, không phải do font/line-height hay path SVG. */
	appearance: none;
	-webkit-appearance: none;
	align-items: center;
	background: none;
	border: 0;
	border-radius: 8px;
	color: var(--bsv-text);
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	font-size: 14px;
	font-weight: 600;
	gap: 6px;
	line-height: 1;
	margin: 0;
	min-height: 40px;
	padding: 6px 10px;
	text-decoration: none;
}

.bsv-header__link:hover { background: var(--bsv-bg); color: var(--bsv-primary); }

/*
 * display:flex (không phải inline mặc định) để trung hoà `vertical-align:
 * -3px` khai báo chung cho .bsv-icon (dùng để canh icon với CHỮ đứng cạnh ở
 * nơi khác) — vertical-align chỉ có tác dụng trong ngữ cảnh inline, còn
 * trong flex container thì bị bỏ qua nên icon luôn nằm giữa tuyệt đối, không
 * còn bị đẩy xuống tạo khoảng trống thừa phía dưới như trước.
 */
.bsv-header__icon {
	align-items: center;
	display: inline-flex;
	font-size: 18px;
	justify-content: center;
	line-height: 1;
	position: relative;
}

.bsv-header__avatar {
	border-radius: 50%;
	display: block;
	height: 24px !important;
	object-fit: cover;
	width: 24px !important;
}

/* Chấm đỏ số thông báo chưa đọc. */
.bsv-header__badge {
	background: var(--bsv-danger);
	border-radius: 999px;
	color: #fff;
	font-size: 10px;
	font-weight: 700;
	line-height: 1;
	padding: 2px 5px;
	position: absolute;
	right: -8px;
	top: -6px;
}

/*
 * Nút nổi quét QR đặt lịch / check-in — chỉ bệnh nhân/khách chưa đăng ký mới
 * thấy (xem $show_qr_checkin trong header.php). Cố định góc dưới-trái màn
 * hình, hiện mọi kích thước màn hình (không riêng mobile) vì đây là nút nổi
 * độc lập, không còn tranh chỗ với logo trong header nữa.
 */
.bsv-qr-fab {
	/* !important trên các thuộc tính hộp: đây là thẻ <button> thật, Flatsome/
	   UX Builder thường có CSS toàn cục cho mọi button (border-radius, padding
	   riêng của theme) có thể đè specificity thường — khoá cứng để chắc chắn
	   ra đúng hình tròn bất kể theme can thiệp gì. overflow: hidden để icon/nội
	   dung bên trong không kéo hộp phình ra khỏi hình tròn. Lớp đệm mờ dần dùng
	   nhiều box-shadow lồng nhau (KHÔNG dùng pseudo-element ::before) vì
	   pseudo-element cùng stacking context với chính nút rất dễ bị nền chính
	   che mất — box-shadow luôn vẽ ra ngoài viền, chắc chắn hiển thị. */
	appearance: none !important;
	-webkit-appearance: none !important;
	-moz-appearance: none !important;
	align-items: center;
	background: var(--bsv-primary) !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 50% !important;
	bottom: 16px;
	box-shadow:
		0 2px 10px rgba(0, 0, 0, 0.25),
		0 0 0 8px rgba(13, 148, 136, 0.18),
		0 0 0 16px rgba(13, 148, 136, 0.08) !important;
	box-sizing: border-box !important;
	color: #fff;
	cursor: pointer;
	display: inline-flex;
	flex-shrink: 0;
	height: 52px !important;
	justify-content: center;
	left: 16px;
	line-height: 1 !important;
	margin: 0 !important;
	min-height: 0 !important;
	min-width: 0 !important;
	overflow: hidden !important;
	padding: 0 !important;
	position: fixed;
	width: 52px !important;
	z-index: 999;

	/* Rung nhẹ định kỳ để thu hút chú ý — nghỉ dài giữa các lần rung (không
	   rung liên tục gây khó chịu/phân tâm), animation-fill-mode mặc định nên
	   nút đứng yên ở phần còn lại của chu kỳ. */
	animation: bsv-qr-shake 4s ease-in-out infinite;
}

.bsv-qr-fab:hover { opacity: 0.9; animation-play-state: paused; }

@keyframes bsv-qr-shake {
	0%, 8%, 100% { transform: translateX(0) rotate(0); }
	1% { transform: translateX(-3px) rotate(-8deg); }
	2% { transform: translateX(3px) rotate(8deg); }
	3% { transform: translateX(-3px) rotate(-6deg); }
	4% { transform: translateX(3px) rotate(6deg); }
	5% { transform: translateX(-2px) rotate(-3deg); }
	6% { transform: translateX(2px) rotate(3deg); }
	7% { transform: translateX(0) rotate(0); }
}

/* Modal quét/xác nhận check-in QR — JS thuần (assets/js/qr-checkin.js), dựng
   DOM trực tiếp vì header hiện ở cả trang chưa nạp Alpine. */
.bsv-qr-modal {
	align-items: flex-end;
	background: rgba(0, 0, 0, 0.5);
	bottom: 0;
	display: flex;
	justify-content: center;
	left: 0;
	/* transform ép Safari vẽ lớp này trên GPU compositing layer riêng —
	   không có dòng này, Safari đôi khi vẽ lệch ngang phần tử fixed đúng lúc
	   thanh địa chỉ thu/giãn khi cuộn (lỗi hiển thị đặc trưng của Safari). */
	overscroll-behavior: contain;
	position: fixed;
	right: 0;
	top: 0;
	transform: translateZ(0);
	z-index: 9999;
}

.bsv-qr-modal__box {
	background: var(--bsv-surface);
	border-radius: var(--bsv-radius) var(--bsv-radius) 0 0;
	max-height: 90vh;
	max-height: 90dvh;
	overflow-y: auto;
	padding: 16px;
	width: 100%;
}

@media (min-width: 768px) {
	.bsv-qr-modal { align-items: center; justify-content: center; }
	.bsv-qr-modal__box { border-radius: var(--bsv-radius); max-width: 420px; }
}

.bsv-qr-modal video { background: #000; border-radius: 8px; width: 100%; }


/* Mobile-first: chỉ icon; từ 768px hiện thêm chữ. */
.bsv-header__text { display: none; }

@media (min-width: 768px) {
	.bsv-header__text { display: inline; }

	/* Tên người dùng có thể dài — cắt gọn thay vì đẩy vỡ layout header. */
	.bsv-header__link .bsv-header__text {
		display: inline-block;
		max-width: 140px;
		overflow: hidden;
		text-overflow: ellipsis;
		vertical-align: middle;
		white-space: nowrap;
	}
}

/* ── Bố cục: 1 cột trên mobile, nở ra từ 768px ──────────────────────── */
.bsv-grid {
	display: grid;
	gap: 12px;
	grid-template-columns: 1fr;
}

/* Cho phép 1 vài lưới thẻ chỉ số ngắn gọn (chỉ 1 số) chia 2/3 cột ngay ở
   mobile thay vì mỗi thẻ chiếm hẳn 1 hàng — dùng cho thẻ nội dung ngắn, KHÔNG
   dùng cho thẻ có nhiều dòng dài (VD: "Phòng khám mới") vì sẽ bị chật. */
.bsv-grid--2-xs { grid-template-columns: repeat(2, 1fr); }
.bsv-grid--3-xs { gap: 8px; grid-template-columns: repeat(3, 1fr); }

@media (min-width: 768px) {
	.bsv-grid { gap: 16px; }
	.bsv-grid--2 { grid-template-columns: repeat(2, 1fr); }
	.bsv-grid--3 { grid-template-columns: repeat(3, 1fr); }
	.bsv-grid--4 { grid-template-columns: repeat(4, 1fr); }
	.bsv-grid--6 { grid-template-columns: repeat(6, 1fr); }
	.bsv-grid--span-2 { grid-column: span 2; }
	/* Tỉ lệ 2:1 — VD trang Tài khoản: Thông tin cá nhân (rộng) : Đổi mật khẩu (hẹp). */
	.bsv-grid--2-1 { grid-template-columns: 2fr 1fr; }
	/* Tỉ lệ 1:2 — VD trang Hoá đơn: Danh sách (hẹp) : Chi tiết (rộng, có
	   bảng chọn dịch vụ + form riêng bên trong nên cần nhiều chỗ hơn). */
	.bsv-grid--1-2 { grid-template-columns: 1fr 2fr; }
	/* 2 cột ở tablet đứng (768px) → 3 cột ở tablet ngang/iPad landscape
	   (1024px) → 4 cột từ desktop rộng (1280px) — dùng cho lưới thẻ nhiều nội
	   dung (ảnh + tên + phụ đề + nút) mà .bsv-grid--4 thường (nhảy thẳng 4 cột
	   ngay từ 768px) làm thẻ quá chật ở iPad. Xem templates/home.php,
	   clinic-directory.php, doctor-directory.php, news.php. */
	.bsv-grid--2-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
	.bsv-grid--2-4 { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1280px) {
	.bsv-grid--2-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Tỉ lệ 3:5:2 (Quầy tiếp nhận: Đang khám/Hàng đợi/Check-in) dời sang mốc lg
   (1024px) thay vì md (768px) — ở đúng 768px, cột "Check-in" chỉ còn ~154px
   (768 × 2/10), quá chật để thao tác; từ 1024px mới đủ rộng dùng được (mỗi
   cột ~205-512px). Dưới 1024px xếp DỌC (grid 1 cột mặc định) thay vì ép 3
   cột chật — xem reception-desk.php. */
@media (min-width: 1024px) {
	.bsv-grid--reception { grid-template-columns: 3fr 5fr 2fr; }
}

/* ── Khung nội dung giới hạn bề rộng (form/chi tiết dạng "trang trong
   trang") — KHÔNG kéo hết bề rộng trang full-width dù màn hình rộng tới
   đâu (FHD/2K/3K/4K/8K đều dừng ở đúng 1 mức, phần dư thành khoảng trắng 2
   bên) — đúng cách Tailwind/Bootstrap xử lý container, xem comment mốc
   kích thước ở đầu file. KHÔNG cần @media: max-width vô hại trên mobile
   (màn hình mobile luôn hẹp hơn các số này). 4 mức tương ứng độ phức tạp
   nội dung — số lấy theo container Bootstrap (đã kiểm chứng thực tế qua
   nhiều dự án, không phải số tự chọn). KHÔNG canh giữa (không margin:auto)
   — nội dung dashboard luôn bắt đầu từ lề trái, khớp với toolbar/menu phía
   trên, canh giữa sẽ trông lệch. */
.bsv-content--sm { max-width: 720px; } /* Form 1 cột đơn giản — VD Hồ sơ phòng khám. */
.bsv-content--md { max-width: 960px; } /* Form/nội dung vừa — VD Ví tín dụng. */
.bsv-content--lg { max-width: 1140px; } /* Form + danh sách 2 cột — VD Lịch làm việc. */
.bsv-content--xl { max-width: 1320px; } /* 2 cột đầy đủ (danh sách + chi tiết) — VD Hoá đơn. */

/* ── Trang profile thương hiệu công khai (bác sĩ / phòng khám) ───────── */
/* Khác với .bsv-content--* (dashboard, luôn lề trái): đây là trang ĐỌC công
   khai (khách/bệnh nhân xem qua link chia sẻ) — canh giữa như trang nội
   dung thông thường, tránh dòng chữ kéo dài hết màn hình rộng (FHD/2K...). */
.bsv-profile-page {
	margin: 0 auto;
	max-width: 1100px;
}

/* ── Trang đăng nhập/đăng ký công khai ────────────────────────────────── */
/* Trang khách truy cập ĐẦU TIÊN, chủ yếu từ điện thoại — mặc định (mobile):
   đệm dọc vừa đủ để thẻ không dính sát mép trên/dưới màn hình, thẻ gần full
   width. ≥768px: đệm dọc lớn hơn, thẻ co lại 1 kích thước vừa canh giữa —
   đúng cảm giác "trang đăng nhập" thay vì kéo full-width như dashboard. */
.bsv-auth-page__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 24px 0 40px;
}

.bsv-auth-page__logo {
	display: block;
	height: 40px;
	margin-bottom: 20px;
	object-fit: contain;
	width: auto;
}

.bsv-auth-page__card {
	width: 100%;
	max-width: 440px;
}

.bsv-auth-page__title {
	font-size: 20px;
	margin: 0 0 16px;
	text-align: center;
}

.bsv-auth-page__links {
	margin-top: 12px;
	text-align: center;
}

/* Ô mã OTP + nút "Gửi mã" cùng hàng — 2 cột cố định an toàn ở mọi bề rộng
   (input ngắn 6 số + nút ngắn, không phải danh sách nhiều cột dễ vỡ trên
   mobile hẹp như đã từng gặp ở nơi khác, xem docs/DASHBOARD_STANDARDS.md). */
.bsv-auth-page__otp-row {
	display: grid;
	gap: 8px;
	grid-template-columns: 1fr 1fr;
}

@media (min-width: 768px) {
	.bsv-auth-page__inner { padding: 48px 0 64px; }
	.bsv-auth-page__logo { height: 48px; margin-bottom: 24px; }
}

.bsv-profile__cover {
	border-radius: var(--bsv-radius);
	margin-bottom: 14px;
	overflow: hidden;
}

.bsv-profile__cover img {
	display: block;
	height: 160px !important;
	object-fit: cover;
	width: 100% !important;
}

@media (min-width: 768px) {
	.bsv-profile__cover img { height: 260px !important; }
}

.bsv-profile__head {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
}

.bsv-profile__avatar {
	border: 1px solid var(--bsv-border);
	border-radius: 50%;
	display: block;
	height: 96px !important;
	object-fit: cover;
	width: 96px !important;
}

.bsv-profile__name {
	font-size: 20px;
	font-weight: 700;
	margin: 0 0 4px;
}

.bsv-profile__links {
	display: grid;
	gap: 10px;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Icon trước mỗi dòng liên hệ (phone/mail/shield/zalo/website...) — nhạt hơn
   chữ 1 chút để không lấn át nội dung, thẳng hàng dù text 1 hay nhiều dòng. */
.bsv-profile__links li,
.bsv-profile__links li a {
	align-items: center;
	color: inherit;
	display: flex;
	gap: 8px;
}

.bsv-profile__links .bsv-icon {
	color: var(--bsv-muted);
	flex-shrink: 0;
}

.bsv-card {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	padding: 14px;
	/* Ô lưới (grid item) mặc định KHÔNG co nhỏ hơn nội dung bên trong (min-width:
	   auto ngầm định của grid/flex) — khối nào bên trong có hàng cuộn ngang
	   (VD .bsv-kanban-row ở Quầy tiếp nhận) sẽ đẩy TRÀN cả khung cha ra ngoài
	   màn hình thay vì tự cuộn gọn bên trong. min-width:0 buộc ô lưới co đúng
	   theo cột được cấp, phần cuộn ngang xử lý ở bên trong nó. */
	min-width: 0;
}

@media (min-width: 768px) {
	.bsv-card { padding: 16px; }
}

.bsv-card__title {
	font-size: 15px;
	font-weight: 600;
	margin: 0 0 12px;
}

.bsv-toolbar {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 8px;
}

/* Bọc riêng Menu (nếu có, xem $before ở toolbar.php) + tiêu đề — LUÔN cùng 1
   hàng dù màn hình hẹp cỡ nào, không rớt xuống dòng dưới như $actions. */
.bsv-toolbar__heading {
	align-items: center;
	display: flex;
	flex: 1 1 auto;
	flex-wrap: nowrap;
	gap: 10px;
	min-width: 0;
}

/* Giãn hết chỗ trống trong .bsv-toolbar__heading → nút hành động ($actions)
   luôn CÙNG HÀNG bên phải trên màn đủ rộng. Cỡ chữ giảm dần theo màn hình
   (16px mobile → 22px desktop) — mobile giờ có thêm nút "Tải lại trang" cạnh
   Menu nên càng chật chỗ, tiêu đề phải nhỏ hơn nữa mới đủ chỗ không rớt dòng. */
.bsv-toolbar__title {
	flex: 1 1 auto;
	font-size: 16px;
	margin: 0;
	min-width: 0;
}

@media (min-width: 768px) {
	.bsv-toolbar { margin-bottom: 10px; }
	.bsv-toolbar__title { font-size: 18px; }
}

.bsv-toolbar__spacer { flex: 1 1 auto; }

/* Toolbar có nút hành động ngắn (VD: "Xem tất cả" ở box Tin tức trang chủ) —
   ép luôn cùng hàng bên phải, tiêu đề tự cắt gọn nếu chật thay vì rớt dòng. */
.bsv-toolbar--tight .bsv-toolbar { flex-wrap: nowrap; margin-bottom: 14px; }
.bsv-toolbar--tight .bsv-toolbar__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Thẻ chỉ số ─────────────────────────────────────────────────────── */
.bsv-stat {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	padding: 12px 14px;
}

.bsv-stat__label {
	color: var(--bsv-muted);
	font-size: 13px;
}

.bsv-stat__value {
	font-size: 24px;
	font-weight: 700;
	line-height: 1.2;
}

@media (min-width: 768px) {
	.bsv-stat { padding: 14px 16px; }
	.bsv-stat__value { font-size: 26px; }
}

/* Box "Tra cứu" (Quầy tiếp nhận): 2 nhóm thống kê "Lượt khám thành công" (4
   ô) + "Lịch hẹn sắp tới" (3 ô) — tỉ lệ cột 4:3 đúng bằng số ô mỗi bên nên
   TỪNG Ô ở cả 2 nhóm rộng bằng nhau, gộp thành 1 hàng 7 ô đều trên desktop.
   Mobile: xếp chồng từng nhóm (mỗi nhóm lại co về 1 cột nhờ .bsv-grid). */
.bsv-lookup-stats { display: grid; gap: 14px; margin-bottom: 14px; }
@media (min-width: 768px) {
	.bsv-lookup-stats { grid-template-columns: 4fr 3fr; }
}

/* Nhãn thời gian ("hôm nay"/"tuần này"...) đứng cạnh số trong .bsv-stat__value
   — chữ nhỏ như .bsv-stat__label, số vẫn giữ nguyên cỡ to. */
.bsv-stat__unit {
	color: var(--bsv-muted);
	font-size: 13px;
	font-weight: 400;
}

/* Biến thể màu cho thẻ chỉ số: tô viền + số cho dễ phân biệt. */
.bsv-stat--info { border-color: #3b82f6; }
.bsv-stat--info .bsv-stat__value { color: #2563eb; }

.bsv-stat--primary { border-color: var(--bsv-primary); }
.bsv-stat--primary .bsv-stat__value { color: var(--bsv-primary); }

.bsv-stat--warning { border-color: var(--bsv-warning); }
.bsv-stat--warning .bsv-stat__value { color: var(--bsv-warning); }

.bsv-stat--danger { border-color: var(--bsv-danger); }
.bsv-stat--danger .bsv-stat__value { color: var(--bsv-danger); }

/* ── Biểu đồ cột đơn giản (xu hướng doanh thu/lịch hẹn theo ngày) ─────
   Dựng bằng div + chiều cao %, KHÔNG dùng SVG/canvas hay thư viện ngoài —
   nhẹ, không phụ thuộc CDN, đủ dùng cho báo cáo (xem
   components/clinic-full-report.php + bsvClinicOwner.barHeight()). */
.bsv-barchart {
	align-items: flex-end;
	display: flex;
	gap: 4px;
	height: 140px;
	overflow-x: auto;
	padding-bottom: 4px;
}

.bsv-barchart__col {
	align-items: center;
	display: flex;
	flex: 1 0 20px;
	flex-direction: column;
	height: 100%;
	justify-content: flex-end;
	min-width: 20px;
}

.bsv-barchart__bar {
	background: var(--bsv-primary);
	border-radius: 3px 3px 0 0;
	min-height: 3px;
	width: 100%;
}

.bsv-barchart__label {
	color: var(--bsv-muted);
	font-size: 10px;
	margin-top: 4px;
	white-space: nowrap;
}

@media (min-width: 768px) {
	.bsv-barchart { height: 180px; }
}

/* Phân bố số sao đánh giá (1-5) — cột ngang, dễ đọc hơn cột dọc khi chỉ có 5 mục. */
.bsv-ratingbar {
	align-items: center;
	display: flex;
	gap: 8px;
	margin-bottom: 6px;
}

.bsv-ratingbar__label { flex-shrink: 0; font-size: 13px; width: 34px; }

.bsv-ratingbar__track {
	background: var(--bsv-bg);
	border-radius: 4px;
	flex: 1 1 auto;
	height: 10px;
	overflow: hidden;
}

.bsv-ratingbar__fill { background: var(--bsv-warning); height: 100%; }

.bsv-ratingbar__count { color: var(--bsv-muted); flex-shrink: 0; font-size: 12px; width: 28px; text-align: right; }

/* Số bốc đang gọi — to, rõ, nhìn được từ xa (màn hình chờ / điện thoại lễ tân). */
.bsv-now-serving {
	background: #fff;
	border: 2px solid var(--bsv-primary);
	border-radius: var(--bsv-radius);
	color: var(--bsv-text);
	padding: 18px;
	text-align: center;
}

.bsv-now-serving__number {
	font-size: 48px;
	font-weight: 800;
	line-height: 1;
}

@media (min-width: 768px) {
	.bsv-now-serving { padding: 20px; }
	.bsv-now-serving__number { font-size: 56px; }
}

/* ── Bảng dữ liệu: MẶC ĐỊNH là danh sách thẻ (mobile) ────────────────
   Mỗi <td> cần data-label để hiện nhãn cột. Từ 640px chuyển thành bảng. */
.bsv-table-wrap {
	-webkit-overflow-scrolling: touch;
	overflow-x: auto;
}

.bsv-table {
	border-collapse: collapse;
	width: 100%;
}

.bsv-table,
.bsv-table tbody,
.bsv-table tr,
.bsv-table td {
	display: block;
	width: 100%;
}

.bsv-table thead { display: none; }

.bsv-table tr {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	margin-bottom: 10px;
	padding: 6px 4px;
}

.bsv-table td {
	display: flex;
	gap: 12px;
	justify-content: space-between;
	padding: 7px 12px;
}

.bsv-table td::before {
	color: var(--bsv-muted);
	content: attr(data-label);
	flex-shrink: 0;
	font-size: 13px;
	font-weight: 600;
}

.bsv-table td:empty { display: none; }

.bsv-table__queue {
	font-size: 18px;
	font-weight: 700;
}

/* Bảng dày dữ liệu, nhiều dòng/trang (VD Danh bạ thuốc) — khoảng cách dòng
   hẹp hơn để đỡ cuộn dài, KHÔNG sửa .bsv-table gốc vì dùng chung cho mọi
   bảng khác (hoá đơn, sổ cái...), đổi trực tiếp sẽ ảnh hưởng hết. Truyền
   qua $table_class của components/data-table.php. */
.bsv-table--compact tr { margin-bottom: 4px; padding: 2px 4px; }
.bsv-table--compact td { padding: 3px 12px; }

@media (min-width: 640px) {
	.bsv-table { display: table; min-width: 640px; }
	.bsv-table thead { display: table-header-group; }
	.bsv-table tbody { display: table-row-group; }

	.bsv-table tr {
		background: none;
		border: 0;
		border-radius: 0;
		display: table-row;
		margin: 0;
		padding: 0;
	}

	.bsv-table td,
	.bsv-table th {
		border-bottom: 1px solid var(--bsv-border);
		display: table-cell;
		padding: 10px 12px;
		text-align: left;
		vertical-align: middle;
		width: auto;
	}

	.bsv-table--compact td,
	.bsv-table--compact th { padding: 4px 12px; }

	.bsv-table td::before { content: none; }
	.bsv-table td:empty { display: table-cell; }

	.bsv-table th {
		background: var(--bsv-bg);
		color: var(--bsv-muted);
		font-size: 13px;
		font-weight: 600;
		white-space: nowrap;
	}

	.bsv-table tbody tr:nth-child(even) { background: var(--bsv-bg); }
	.bsv-table tbody tr:hover { background: var(--bsv-border); }

	.bsv-table td code,
	.bsv-table th code {
		background: var(--bsv-bg);
		border-radius: 4px;
		font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
		font-size: 12px;
		padding: 2px 6px;
	}

	.bsv-table tbody tr:nth-child(even) td code { background: var(--bsv-surface); }

	.bsv-table__queue {
		text-align: center;
		width: 64px;
	}
}

/* ── Thẻ danh sách: grid 3 cột cố định [ảnh | nội dung | icon hành động] ── */
.bsv .bsv-item {
	align-items: center;
	display: grid;
	gap: 12px;
	grid-template-columns: 48px 1fr auto;
}

/* Danh sách không có ảnh/placeholder đầu dòng (VD Bảng giá dịch vụ) — chỉ 2
   ô [nội dung | hành động], không thì ô nội dung bị ép vào đúng cột 48px
   đầu tiên của grid 3 cột mặc định, làm tên dịch vụ vỡ dòng xấu. */
.bsv .bsv-item--compact { grid-template-columns: 1fr auto; }

/* !important để thắng mọi rule img của theme (Flatsome hay ép ảnh 100%). */
.bsv .bsv-item__img,
.bsv .bsv-item__placeholder {
	border: 1px solid var(--bsv-border);
	border-radius: 10px;
	display: block;
	height: 48px !important;
	max-width: none;
	object-fit: cover;
	width: 48px !important;
}

/* Chưa có ảnh: ô chữ cái đầu thay thế. */
.bsv .bsv-item__placeholder {
	align-items: center;
	background: var(--bsv-bg);
	color: var(--bsv-muted);
	display: flex;
	font-size: 18px;
	font-weight: 700;
	justify-content: center;
}

/* Biến thể ảnh tròn (bác sĩ). */
.bsv-item--round .bsv-item__img,
.bsv-item--round .bsv-item__placeholder { border-radius: 50%; }

.bsv-item__body { min-width: 0; }

/* Biến thể .bsv-item dùng làm link (trỏ về trang profile bác sĩ/phòng khám) —
   .bsv-item vốn là <div>, khi render bằng <a> phải reset màu/underline mặc định. */
.bsv-item--link {
	color: inherit;
	text-decoration: none;
}

.bsv-item--link:hover .bsv-item__title { color: var(--bsv-primary); }

.bsv-item__title { font-weight: 600; }

.bsv-item__sub {
	color: var(--bsv-muted);
	font-size: 13px;
	margin-top: 2px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.bsv-item__count {
	background: var(--bsv-bg);
	border: 1px solid var(--bsv-border);
	border-radius: 999px;
	color: var(--bsv-muted);
	font-size: 12px;
	font-weight: 600;
	margin-left: 6px;
	padding: 1px 8px;
	white-space: nowrap;
}

/* ── Danh sách checkbox trong form (chuyên khoa, bác sĩ...) ─────────── */
.bsv-checklist {
	border: 1px solid var(--bsv-border);
	border-radius: 8px;
	max-height: 170px;
	overflow-y: auto;
	padding: 6px 12px;
}

/* Luôn 2 cột cho gọn (nhãn danh mục ngắn nên mobile vẫn vừa). */
.bsv-checklist--2 {
	column-gap: 16px;
	display: grid;
	grid-template-columns: 1fr 1fr;
}

.bsv-checklist--3 {
	column-gap: 16px;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
}

/* Biến thể responsive cho thanh lọc "Khu vực"/"Chuyên khoa": dưới 768px 2
   cột, từ 768px trở lên 3 cột — TỐI ĐA 3 cột ở mọi kích thước màn hình
   (nhãn dài, chia nhiều cột hơn dễ vỡ dòng/xếp lệch). */
.bsv-checklist--2-3 {
	column-gap: 16px;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
}

.bsv-checklist--3-4 {
	column-gap: 16px;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
}

/* Thanh lọc trên danh sách phòng khám/bác sĩ:
   mobile xếp dọc trên-dưới; desktop 2 box theo tỷ lệ 3:4. */
.bsv-filterbar {
	display: grid;
	gap: 12px;
	grid-template-columns: 1fr;
	margin-bottom: 14px;
}

@media (min-width: 768px) {
	.bsv-filterbar { grid-template-columns: 3fr 4fr; }
	.bsv-checklist--2-3 { grid-template-columns: repeat(3, 1fr); }
	.bsv-checklist--3-4 { grid-template-columns: repeat(3, 1fr); }
}

.bsv .bsv-checklist label {
	align-items: center;
	cursor: pointer;
	display: flex;
	font-size: 14px;
	gap: 8px;
	line-height: 1.3;
	margin: 0;
	padding: 4px 0;
}

.bsv .bsv-checklist input[type="checkbox"] {
	flex-shrink: 0;
	height: 16px;
	margin: 0;
	width: 16px;
}

/* Nút icon trần: không viền, không nền, chỉ đổi màu nền nhẹ khi hover. */
.bsv .bsv-icon-btn {
	align-items: center;
	background: none;
	border: 0;
	border-radius: 6px;
	box-shadow: none;
	color: var(--bsv-muted);
	cursor: pointer;
	display: inline-flex;
	font-size: 16px;
	height: 32px;
	justify-content: center;
	line-height: 1;
	margin: 0;
	padding: 0;
	width: 32px;
}

.bsv .bsv-icon-btn:hover { background: var(--bsv-bg); color: var(--bsv-text); }
.bsv .bsv-icon-btn--danger:hover { background: #fee2e2; color: var(--bsv-danger); }

/* Biến thể có màu SẴN (không chỉ lúc hover) — dùng cho hành động quan trọng
   ngay trên thẻ số bốc (Gọi khám/Vắng), cần nhận ra ngay không cần rê chuột. */
.bsv .bsv-icon-btn--success { color: var(--bsv-success); }
.bsv .bsv-icon-btn--success:hover { background: #dcfce7; }
.bsv .bsv-icon-btn--danger { color: var(--bsv-danger); }

/* ── Nhãn trạng thái ────────────────────────────────────────────────── */
.bsv-badge {
	border-radius: 999px;
	display: inline-block;
	font-size: 12px;
	font-weight: 600;
	padding: 3px 10px;
	white-space: nowrap;
}

.bsv-badge--pending { background: #fef3c7; color: #92400e; }
.bsv-badge--confirmed { background: #ccfbf1; color: #115e59; }
.bsv-badge--danger { background: #fee2e2; color: #991b1b; }
.bsv-badge--checked_in { background: #e0e7ff; color: #3730a3; }
.bsv-badge--in_progress { background: #cffafe; color: #155e75; }
.bsv-badge--completed { background: #dcfce7; color: #166534; }
.bsv-badge--no_show { background: #fee2e2; color: #991b1b; }
.bsv-badge--cancelled { background: #f1f5f9; color: #475569; }

/* Box bác sĩ được tài trợ (trang chủ, box quảng cáo) — bố cục GIỐNG HỆT thẻ
   bác sĩ thường, chỉ khác viền xanh lá + nhãn "Được tài trợ" xám nhạt nhỏ ở
   góc trên để phân biệt, không lấn át nội dung chính của thẻ. */
.bsv-item--sponsored { border: 2px solid var(--bsv-success); position: relative; }
/* Neo góc trên-phải của thẻ (thẻ đã position:relative ở trên) — cùng hàng
   với tên bác sĩ/phòng khám thay vì chiếm hẳn 1 hàng riêng phía trên. */
.bsv-item--sponsored__label {
	display: inline-block;
	background: var(--bsv-border);
	color: var(--bsv-muted);
	font-size: 11px;
	position: absolute;
	top: 14px;
	right: 14px;
}
.bsv-badge--active { background: #dcfce7; color: #166534; }
.bsv-badge--inactive { background: #f1f5f9; color: #475569; }

/* ── Danh bạ thuốc: chip list nhanh/kết quả tìm khi kê đơn ────────────── */
.bsv-med-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.bsv-med-chip {
	align-items: center;
	background: var(--bsv-bg);
	border: 1px solid var(--bsv-border);
	border-radius: 999px;
	cursor: grab;
	display: inline-flex;
	font-size: 13px;
	gap: 4px;
	min-height: 40px;
	padding: 6px 8px 6px 12px;
}

@media (min-width: 768px) {
	.bsv-med-chip { min-height: 30px; padding: 4px 6px 4px 10px; }
}

.bsv-med-chip:hover { background: var(--bsv-surface); border-color: var(--bsv-primary); }

.bsv-med-chip__move,
.bsv-med-chip__remove {
	appearance: none;
	background: none;
	border: 0;
	border-radius: 50%;
	color: var(--bsv-muted);
	cursor: pointer;
	font-size: 12px;
	line-height: 1;
	min-height: 28px;
	min-width: 28px;
	padding: 0;
}

@media (min-width: 768px) {
	.bsv-med-chip__move,
	.bsv-med-chip__remove { min-height: 20px; min-width: 20px; }
}

.bsv-med-chip__remove:hover { background: #fee2e2; color: var(--bsv-danger); }
.bsv-med-chip__move:hover { background: var(--bsv-border); color: var(--bsv-text); }

/* ── Form & nút — vùng chạm >= 44px trên mobile ─────────────────────── */
.bsv-field { margin-bottom: 10px; }

.bsv-label {
	display: block;
	font-size: 13px;
	font-weight: 600;
	margin-bottom: 4px;
}

/* Selector kép .bsv .bsv-input để THẮNG style form của Flatsome
   (input[type="text"] có specificity ngang class — thiếu prefix là bị
   theme đè, ô nhập lệch chiều cao so với nút như lỗi ở form OTP). */
.bsv .bsv-input,
.bsv .bsv-select,
.bsv .bsv-textarea {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: 8px;
	box-shadow: none;
	font-size: 15px; /* >=15px để iOS Safari không tự zoom khi focus */
	/* height:auto + line-height ghi đè height cố định của Flatsome cho
	   select — thiếu 2 dòng này chữ trong dropdown bị cắt chân. */
	height: auto;
	line-height: 1.4;
	margin: 0;
	min-height: 40px;
	padding: 8px 12px;
	width: 100%;
}

.bsv .bsv-input:focus,
.bsv .bsv-select:focus,
.bsv .bsv-textarea:focus {
	border-color: var(--bsv-primary);
	box-shadow: none;
	outline: 2px solid rgba(13, 148, 136, 0.15);
}

.bsv .bsv-textarea { min-height: 90px; resize: vertical; }

/* Ô tìm kiếm bác sĩ/phòng khám/SĐT ở box "Bốc số khám" trang chủ — viền cam
   nổi bật hơn input thường. Khai báo SAU khối .bsv-input ở trên — 2 rule cùng
   specificity (.bsv .class) thì rule đứng SAU mới thắng theo thứ tự cascade. */
.bsv .bsv-input--doctor-search,
.bsv .bsv-input--doctor-search:focus {
	border-color: var(--bsv-warning);
}

.bsv .bsv-input:disabled,
.bsv .bsv-select:disabled,
.bsv .bsv-textarea:disabled {
	background: var(--bsv-bg);
	color: var(--bsv-muted);
	cursor: not-allowed;
	opacity: 0.7;
}

.bsv-btn {
	/* appearance/box-shadow/text-transform/letter-spacing: ghi đè skin nút
	   mặc định của Flatsome/UX Builder (theme áp text-transform:uppercase +
	   box-shadow cho MỌI <button>/.button trên site) — thiếu các dòng này,
	   nút plugin bị "ăn" theo giao diện theme thay vì đúng thiết kế đã làm. */
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	align-items: center;
	background: var(--bsv-primary);
	border: 1px solid transparent;
	border-radius: 8px;
	box-shadow: none;
	color: #fff;
	cursor: pointer;
	display: inline-flex;
	font-size: 14px;
	font-weight: 600;
	gap: 6px;
	justify-content: center;
	letter-spacing: normal;
	/* line-height + margin ghi đè style button của Flatsome — thiếu là nút
	   cao hơn ô nhập (lỗi lệch hàng ở ô OTP). */
	line-height: 1.4;
	margin: 0;
	min-height: 40px;
	padding: 8px 14px;
	text-decoration: none;
	text-transform: none;
	white-space: nowrap;
}

.bsv-btn:hover { background: var(--bsv-primary-dark); color: #fff; }
.bsv-btn:disabled { cursor: not-allowed; opacity: 0.55; }

/* Desktop có chuột: gọn hơn nữa; mobile giữ 40px cho vùng chạm. */
@media (min-width: 768px) {
	.bsv-btn { min-height: 36px; padding: 6px 14px; }
	.bsv-btn--sm { min-height: 30px; padding: 4px 10px; }
	.bsv .bsv-input,
	.bsv .bsv-select { min-height: 36px; padding: 6px 12px; }
}

.bsv-btn--ghost {
	background: transparent;
	border-color: var(--bsv-border);
	color: var(--bsv-text);
}

.bsv-btn--ghost:hover { background: var(--bsv-bg); color: var(--bsv-text); }
.bsv-btn--danger { background: var(--bsv-danger); }
.bsv-btn--success { background: var(--bsv-success); }
.bsv-btn--sm { font-size: 13px; min-height: 36px; padding: 5px 11px; }
.bsv-btn--block { width: 100%; }

/* Cụm nút thao tác trong bảng/thẻ. */
.bsv-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

/* Kanban — mỗi bác sĩ 1 cột riêng (xem components/reception-desk.php). Số cột
   tự co giãn theo số bác sĩ (kanbanColumnStyle() trong app.js đặt
   grid-template-columns qua :style): 1 bác sĩ tràn 100%, 2 chia đôi, 3 chia
   3, từ 4 trở lên LUÔN tối đa 3 cột/hàng — dư ra tự xuống hàng tiếp theo
   đúng cơ chế grid (không cần thêm code, chỉ cần cấp cố định 3 cột). */
.bsv-kanban-row {
	display: grid;
	gap: 12px;
}

/* Mobile-first: ép về 1 cột trên điện thoại BẤT KỂ số bác sĩ — chia 2/3 cột
   theo :style JS chỉ hợp lý từ tablet/desktop trở lên, chia sẵn trên màn
   375px sẽ ra cột quá hẹp không đọc được. !important để thắng style inline
   (kanbanColumnStyle() luôn đặt trực tiếp trên phần tử, specificity cao hơn
   class thường). */
@media (max-width: 767.98px) {
	.bsv-kanban-row { grid-template-columns: 1fr !important; }
}

.bsv-kanban-col {
	background: var(--bsv-bg);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	min-width: 0;
	padding: 10px;
}

.bsv-kanban-col__head {
	align-items: center;
	display: flex;
	gap: 6px;
	justify-content: space-between;
}

.bsv-kanban-col__name { font-size: 14px; font-weight: 600; }

/* Hàng đợi dạng thẻ kéo/thả — đổi thứ tự khám (VD: khách bận việc đúng lúc tới lượt). */
.bsv-queue-cards {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* 3 hàng riêng biệt: (1) số + nút hành động, (2) tên bệnh nhân, (3) thông tin
   còn lại — tránh dồn hết vào 1 hàng ngang gây vỡ chữ khi cột kanban hẹp
   (xem .bsv-kanban-col, 240px). */
.bsv-queue-card {
	display: flex;
	flex-direction: column;
	gap: 6px;
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: 10px;
	padding: 10px 12px;
	cursor: grab;
	/* Chặn trình duyệt tự cuộn trang khi bắt đầu kéo trên di động — nếu không,
	   ngón tay vừa chạm vào thẻ đã bị hiểu thành cử chỉ cuộn, không kích hoạt
	   được pointermove cho kanbanMove() (xem bsvClinic.kanbanStart() trong app.js). */
	touch-action: none;
	/* QUAN TRỌNG: thiếu 2 dòng này, mousedown+kéo trên vùng chữ (tên bệnh nhân,
	   SĐT...) bị trình duyệt hiểu thành BÔI ĐEN VĂN BẢN hoặc tự khởi động kéo
	   ảnh/text gốc của trình duyệt — "cướp" mất thao tác kéo trước khi
	   pointermove kịp chạy, khiến kéo/thả tự chế trông như "không phản ứng". */
	-webkit-user-drag: none;
	user-select: none;
	/* Giữ tay lâu trên di động (đặc biệt iOS Safari) mà chưa kịp di chuyển —
	   trình duyệt hiểu thành cử chỉ NHẤN GIỮ GỐC, bật menu ngữ cảnh/kính lúp
	   chọn văn bản, "cướp" luôn thao tác kéo đang định làm; người dùng phải tự
	   tắt menu đó rồi thử lại, tạo cảm giác "phải chờ rất lâu mới ăn". Tắt hẳn
	   callout này để giữ lâu trên thẻ luôn hiểu là bắt đầu kéo, không phải cử
	   chỉ gốc của hệ điều hành. */
	-webkit-touch-callout: none;
}

/* Kéo/thả kiểu kanban bằng Pointer Events (xem bsvClinic.kanbanStart() trong
   app.js) — thay hẳn HTML5 draggable/dragstart/dragover/drop vì cơ chế gốc
   của trình duyệt không hoạt động trên di động và dễ bị huỷ ngang khi danh
   sách render lại qua Alpine x-for. */
.bsv-queue-card.is-dragging-source { opacity: 0.35; }

.bsv-queue-card--ghost {
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
	opacity: 0.92;
	pointer-events: none;
	position: fixed;
	transform: rotate(2deg);
	z-index: 999;
}

/* Cột/nhóm bác sĩ (hàng đợi) hoặc box "Đang khám" đang được kéo thẻ qua —
   viền xanh báo hiệu đây là chỗ sẽ thả vào nếu buông tay ngay lúc này. */
[data-doctor-group].is-drop-target,
[data-serving-doctor].is-drop-target {
	background: var(--bsv-bg);
	border-radius: var(--bsv-radius);
	outline: 2px dashed var(--bsv-primary);
	outline-offset: 2px;
}

/* Vùng thả khi nhóm bác sĩ chưa có bệnh nhân nào — viền đứt để báo hiệu rõ
   đây là chỗ thả được (xem components/reception-desk.php), cao gần bằng 1
   thẻ thật để dễ nhắm khi kéo/thả, không còn chỉ là 1 dòng chữ mờ nhỏ xíu. */
.bsv-queue-card--empty {
	border-style: dashed;
	color: var(--bsv-muted);
	font-size: 13px;
	justify-content: center;
	min-height: 44px;
	text-align: center;
}

/* Hàng 1: số bốc bên trái, nút hành động (Gọi khám/Vắng) dồn bên phải. */
.bsv-queue-card__row {
	align-items: center;
	display: flex;
	justify-content: space-between;
	gap: 8px;
}

.bsv-queue-card__number {
	flex-shrink: 0;
	min-width: 40px;
	height: 40px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--bsv-primary);
	color: #fff;
	border-radius: 8px;
	font-weight: 700;
	font-size: 16px;
}

.bsv-queue-card__name {
	font-weight: 600;
}

@media (min-width: 768px) {
	.bsv-queue-card { padding: 8px 12px; }
	.bsv-queue-card__number { min-width: 36px; height: 36px; font-size: 14px; }
}

/* Ảnh QR khổ lớn để in treo tại quầy (kiểu QR chuyển khoản ngân hàng). */
.bsv-qr-poster {
	background: #fff;
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	padding: 24px;
	text-align: center;
}

.bsv-qr-poster img { border-radius: 8px; height: auto; margin: 14px auto; max-width: 100%; }

.bsv-qr-poster__name { font-size: 20px; font-weight: 700; }
.bsv-qr-poster__hint { color: var(--bsv-text); font-weight: 600; margin-bottom: 10px; }
.bsv-qr-poster__contact { color: var(--bsv-muted); font-size: 14px; }

/* In: phiếu số/đơn thuốc/hồ sơ bệnh án/poster QR đều in bằng 1 IFRAME ẨN
   tách biệt hoàn toàn khỏi trang gốc (bsv.printByLayout() và
   bsv.printElementIsolated() ở app.js — clone outerHTML của đúng khu vực
   cần in, không đụng gì tới phần còn lại của trang). KHÔNG dùng kiểu "ẩn
   visibility:hidden phần còn lại của trang" (từng thử, đã bỏ) — cách đó vẫn
   giữ nguyên chiều cao layout của toàn bộ nội dung trang phía sau, sinh
   nhiều trang trắng thừa khi trang có nhiều nội dung. */

/* Lưới chọn khung giờ. */
.bsv-slots {
	display: grid;
	gap: 8px;
	grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
}

/* Box nhúng "Nhúng Bốc số khám" (iframe cao cố định) — khung giờ nhỏ/sát
   nhau hơn để hiện được nhiều hàng hơn trong cùng chiều cao, xem
   templates/components/booking-form.php ($locked). Vùng chạm 40px vẫn giữ
   đủ chuẩn mobile tối thiểu, chỉ nhỏ hơn 44px mặc định 1 chút. */
.bsv-slots--compact {
	gap: 6px;
	grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
}
.bsv-slots--compact .bsv-slot {
	min-height: 40px;
	padding: 6px 4px;
}

.bsv-slot {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: 8px;
	cursor: pointer;
	font-weight: 600;
	min-height: 44px;
	padding: 10px 4px;
	text-align: center;
}

.bsv-slot:disabled {
	background: var(--bsv-bg);
	color: var(--bsv-muted);
	cursor: not-allowed;
	text-decoration: line-through;
}

.bsv-slot.is-active {
	background: var(--bsv-primary);
	border-color: var(--bsv-primary);
	color: #fff;
}

/* ── Tabs ───────────────────────────────────────────────────────────── */
.bsv-tabs {
	-webkit-overflow-scrolling: touch;
	display: flex;
	gap: 18px;
	margin-bottom: 10px;
	overflow-x: auto;
	scroll-behavior: smooth;
	scrollbar-width: thin;
}

.bsv-tabs::-webkit-scrollbar { height: 4px; }
.bsv-tabs::-webkit-scrollbar-thumb { background: var(--bsv-border); border-radius: 2px; }
.bsv-tabs::-webkit-scrollbar-track { background: transparent; }

.bsv-tab {
	/* !important trên border/text-decoration: khi tabs nằm trong bài viết
	   (.entry-content), CSS link mặc định của theme (border-bottom/underline
	   riêng cho thẻ <a>) có specificity đủ đè mất kiểu gạch chân bo tròn của
	   tab, khiến 2 nơi hiện khác nhau dù dùng chung 1 class — khoá cứng để
	   luôn ra đúng 1 kiểu bất kể ngữ cảnh. */
	background: none !important;
	border: 0 !important;
	border-bottom: 2px solid transparent !important;
	border-radius: 0 0 3px 3px !important;
	color: var(--bsv-muted);
	cursor: pointer;
	display: inline-block;
	flex-shrink: 0;
	font-size: 14px;
	font-weight: 600;
	min-height: 36px;
	padding: 6px 4px;
	text-decoration: none !important;
	white-space: nowrap;
}

.bsv-tab.is-active {
	border-bottom-color: var(--bsv-primary) !important;
	color: var(--bsv-primary);
}

/* Tabs chèn trước tiêu đề bài viết (xem components/news-tabs.php) — JS dời
   thành con trực tiếp của .article-inner (Flatsome), cùng cấp và cùng độ
   rộng với entry-header/entry-content nên không cần tự đặt max-width/padding
   riêng, kế thừa đúng khung .large-10.col có sẵn của theme. KHÔNG tự thêm
   margin riêng cho #bsv-news-tabs — để margin-bottom của .bsv-tabs bên trong
   quyết định khoảng cách, giống hệt trang Tin tức (news.php), tránh cộng dồn
   margin khiến 2 nơi lệch khoảng cách nhau. */

@media (min-width: 640px) {
	.bsv-tabs { gap: 4px; }
	.bsv-tab { padding: 6px 14px; }
}

/* ── Menu dropdown (xem components/menu-dropdown.php) — thay cho hàng tab/
   toolbar ngang dài: bấm hoặc rê chuột vào nút "Menu" bung ra danh sách dọc.
   position:relative trên khối bọc ngoài để .bsv-menu-dropdown__panel định vị
   tuyệt đối ngay bên dưới, không đẩy layout xung quanh. ───────────────── */
.bsv-menu-dropdown {
	display: inline-block;
	/* isolation:isolate ép trình duyệt tạo hẳn 1 stacking context RIÊNG cho
	   khối Menu (nút + panel) — z-index của .bsv-menu-dropdown__panel lúc này
	   chỉ so sánh TRONG PHẠM VI NÀY, không còn "thoát" ra ngoài để so với các
	   khối khác cùng cấp trên trang nữa. Vì vậy bản thân khối bọc ngoài NÀY
	   cũng phải có z-index riêng (bằng đúng z-index panel bên trong) thì mới
	   thắng được các khối SAU nó trong DOM (VD cột "Đang khám" ở Quầy tiếp
	   nhận nhiều bác sĩ) — thiếu dòng z-index này, khối Menu bị coi ngang
	   hàng z-index:auto với các khối đó và thua vì đứng TRƯỚC trong DOM. */
	isolation: isolate;
	position: relative;
	z-index: 9000;
}

.bsv-menu-trigger {
	/* Ghi đè skin nút mặc định của Flatsome/UX Builder — xem comment tương tự
	   ở .bsv-btn phía trên (đây là <button> RIÊNG, không kế thừa .bsv-btn nên
	   phải tự khai báo lại). */
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	box-shadow: none;
	letter-spacing: normal;
	line-height: 1.4;
	margin: 0;
	text-transform: none;
	align-items: center;
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	color: var(--bsv-text);
	cursor: pointer;
	display: inline-flex;
	font-size: 15px;
	font-weight: 700;
	gap: 6px;
	/* Tối thiểu 40px cao trên mobile theo chuẩn vùng chạm (xem CLAUDE.md). */
	min-height: 40px;
	padding: 5px 12px;
}

.bsv-menu-trigger:hover { border-color: var(--bsv-primary); color: var(--bsv-primary); }

.bsv-menu-dropdown__panel {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
	display: flex;
	flex-direction: column;
	/* Khoảng cách GIỮA 2 nút — tách riêng khỏi padding trên/dưới của từng
	   nút (padding lo phần "vùng chạm" bên trong 1 nút, gap lo khoảng trống
	   GIỮA các nút với nhau). */
	gap: 3px;
	/* Bung xuống ngay dưới nút "Menu" ("từ chữ Menu đó") — không phải toàn màn
	   hình. KHÔNG đặt width/min-width cố định — để trình duyệt tự co giãn
	   theo đúng độ rộng nội dung bên trong (item dài nhất), tránh chữ bị dồn
	   xuống 2 dòng chật chội khi panel hẹp hơn nội dung thật sự cần. */
	left: 0;
	/* KHÔNG để margin-top > 0: panel dùng position:absolute nên không tính
	   vào chiều cao của .bsv-menu-dropdown (khối cha nghe mouseenter/
	   mouseleave) — hở dù chỉ vài px cũng tạo ra 1 vùng "chết" giữa nút Menu
	   và panel, chuột đi qua đó bị coi là rời khỏi Menu, tự đóng panel ngay
	   dù chưa kịp chạm vào panel. Panel chạm sát nút Menu (margin-top:0) thì
	   không còn vùng chết này nữa. */
	margin-top: 0;
	max-height: 70vh;
	/* Chỉ chặn tràn màn hình mobile — KHÔNG đặt trần px cố định (320px trước
	   đây hẹp hơn cả text dài nhất, khiến tự hiện thanh cuộn ngang do
	   overflow-y:auto kéo theo overflow-x:auto). 90vw đủ rộng cho mọi mục,
	   overflow-x:hidden chặn hẳn thanh cuộn ngang dù có xảy ra lệch nhỏ. */
	max-width: 90vw;
	overflow-x: hidden;
	overflow-y: auto;
	padding: 6px;
	position: absolute;
	top: 100%;
	/* Đứng trên mọi nội dung khác của trang, kể cả card/toolbar khác — 60
	   từng bị 1 số khối khác (badge kéo thả z-index:999, FAB QR z-index:999...)
	   che đè lúc mở, nhất là bàn làm việc bác sĩ solo (Menu ở đầu trang, ngay
	   trên tiêu đề "Quầy tiếp nhận"). Nâng hẳn lên gần mức modal (9999) để
	   chắc chắn luôn nổi trên mọi thành phần khác, nhưng vẫn thấp hơn modal
	   thật (nếu 1 modal đang mở đồng thời thì modal vẫn phải ở trên cùng). */
	z-index: 9000;
}

.bsv-menu-dropdown__item {
	/* Ghi đè skin nút mặc định của Flatsome/UX Builder — xem comment tương tự
	   ở .bsv-btn/.bsv-menu-trigger phía trên. */
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	box-shadow: none;
	letter-spacing: normal;
	line-height: 1.4;
	margin: 0;
	text-transform: none;
	background: none;
	border: 0;
	border-radius: 6px;
	color: var(--bsv-text);
	cursor: pointer;
	font-size: 15px;
	font-weight: 700;
	/* min-height 40px (chuẩn vùng chạm) trước đây ÉP chiều cao tối thiểu,
	   khiến giảm padding không có tác dụng thấy được; hạ xuống 32px để
	   padding thật sự chi phối độ cao, vẫn đủ rộng để bấm trên mobile.
	   Khoảng cách GIỮA các nút nay tách riêng qua gap ở .bsv-menu-dropdown__panel. */
	min-height: 32px;
	padding: 5px 12px;
	text-align: left;
	/* nowrap: panel tự co giãn RỘNG THEO ĐÚNG item dài nhất (thay vì luôn
	   khoá ở min-width cũ rồi bẻ chữ xuống dòng) — panel có max-width chặn
	   tràn màn hình, item nào thật sự quá dài mới cần bẻ dòng thì override
	   riêng, còn lại 1 dòng cho gọn. */
	white-space: nowrap;
	width: 100%;
}

.bsv-menu-dropdown__item:hover { background: var(--bsv-bg); }

.bsv-menu-dropdown__item.is-active {
	background: var(--bsv-bg);
	color: var(--bsv-primary);
	font-weight: 700;
}

@media (min-width: 768px) {
	.bsv-menu-trigger { min-height: 36px; }
	.bsv-menu-dropdown__item { min-height: 36px; }
}

/* ── Modal: toàn màn hình trên mobile, hộp giữa màn hình từ 640px ─────
   height dùng cả vh (fallback) lẫn dvh (viewport thực đang hiển thị) —
   trình duyệt mobile (Safari/Chrome) tính "100vh" theo viewport LỚN NHẤT
   (kể cả phần bị thanh địa chỉ che), khiến mép trên modal (tiêu đề + nút
   đóng) bị khuất sau thanh địa chỉ khi nó đang xoè ra. dvh tính đúng phần
   đang thấy được nên không còn bị che. */
.bsv-modal {
	align-items: flex-end;
	background: rgba(15, 23, 42, 0.5);
	display: flex;
	height: 100vh;
	height: 100dvh;
	inset: 0;
	justify-content: center;
	padding-top: env(safe-area-inset-top);
	position: fixed;
	z-index: 9999;
}

.bsv-modal__box {
	background: var(--bsv-surface);
	border-radius: 14px 14px 0 0;
	max-height: 92vh;
	max-height: 92dvh;
	overflow-y: auto;
	padding: 18px 16px;
	width: 100%;
}

@media (min-width: 640px) {
	.bsv-modal { align-items: center; padding: 16px; }

	.bsv-modal__box {
		border-radius: 12px;
		max-height: 90vh;
		max-height: 90dvh;
		max-width: 560px;
		padding: 20px;
	}

	/* Form nhiều trường (hồ sơ thương hiệu bác sĩ/phòng khám, lịch làm việc...)
	   — ép đúng 90% chiều rộng màn hình, không chỉ giới hạn tối đa. */
	.bsv-modal__box--wide { max-width: 90vw; width: 90vw; }
}

.bsv-modal__head {
	align-items: center;
	display: flex;
	justify-content: space-between;
	margin-bottom: 14px;
}

/* ── Trạng thái & thông báo ─────────────────────────────────────────── */
.bsv-empty,
.bsv-loading {
	color: var(--bsv-muted);
	padding: 28px 12px;
	text-align: center;
}

/* Danh sách trường còn thiếu (VD form đặt lịch) — chỉ tô đỏ DẤU chấm đầu
   dòng cho dễ quan sát/cảnh báo, chữ vẫn giữ màu mờ bình thường (::marker
   không kế thừa color của phần tử cha, phải khai riêng). */
.bsv-list--warn li::marker {
	color: var(--bsv-danger);
}

.bsv-alert {
	border-radius: 8px;
	font-size: 14px;
	margin-bottom: 14px;
	padding: 10px 14px;
}

.bsv-alert--error { background: #fee2e2; color: #991b1b; }
.bsv-alert--info { background: #ccfbf1; color: #115e59; }
.bsv-alert--warning { background: #fef3c7; color: #92400e; }

.bsv-toast {
	background: #1e293b;
	border-radius: 8px;
	bottom: 20px;
	color: #fff;
	font-size: 14px;
	left: 50%;
	max-width: calc(100vw - 32px);
	opacity: 1;
	padding: 11px 18px;
	position: fixed;
	transform: translateX(-50%);
	transition: opacity 0.4s;
	z-index: 10000;
}

.bsv-toast--success { background: var(--bsv-success); }
.bsv-toast--error { background: var(--bsv-danger); }
.bsv-toast.is-out { opacity: 0; }

/* ── Thông báo hiện NGAY TRONG popup/trang (dưới nút bấm) — thay cho toast
   nổi góc màn hình khi đang ở trong .bsv-modal__box/.bsv-inline-page (xem
   bsv.toast()), tránh bị che khuất/lệch ra ngoài vùng cuộn riêng của popup.
   Màu CHỮ đổi theo ngữ cảnh, nền nhạt thay vì khối màu đặc — hợp với việc
   nằm lẫn trong nội dung thay vì nổi hẳn lên trên. */
.bsv-inline-toast {
	background: var(--bsv-bg);
	border-radius: 8px;
	font-size: 13px;
	font-weight: 600;
	margin-top: 12px;
	opacity: 1;
	padding: 10px 14px;
	text-align: center;
	transition: opacity 0.4s;
}

.bsv-inline-toast--info { color: var(--bsv-primary); }
.bsv-inline-toast--success { color: var(--bsv-success); }
.bsv-inline-toast--error { background: rgba(220, 38, 38, 0.08); color: var(--bsv-danger); }
.bsv-inline-toast.is-out { opacity: 0; }

/* ── Thông báo "Đến lượt vào khám" — TO, giữa màn hình ────────────────
   Trên cả toast (z-index 10000) vì đây là thông báo quan trọng nhất với
   bệnh nhân, không được để lẫn/bỏ lỡ như toast thường. */
.bsv-call-alert {
	align-items: center;
	background: var(--bsv-primary);
	display: flex;
	inset: 0;
	justify-content: center;
	padding: 24px;
	padding-top: calc(24px + env(safe-area-inset-top));
	position: fixed;
	z-index: 10001;
}

.bsv-call-alert__box {
	max-width: 420px;
	text-align: center;
}

.bsv-call-alert__text {
	color: #fff;
	font-size: 28px;
	font-weight: 800;
	line-height: 1.35;
	margin: 0;
}

/* Ghi đè .bsv-btn mặc định (cũng nền --bsv-primary — trùng màu nền overlay,
   sẽ "biến mất" nếu không đổi riêng) — nền trắng/chữ xanh để nổi bật. */
.bsv-call-alert .bsv-btn {
	background: #fff;
	color: var(--bsv-primary);
}

@media (min-width: 768px) {
	.bsv-call-alert__text { font-size: 34px; }
}

/* ── Máy quét QR ────────────────────────────────────────────────────── */
/* Vùng bốc số trên trang chủ khi CHƯA đăng nhập: mờ đi, bấm vào để được
   nhắc đăng nhập (lockGuard xử lý click). */
.bsv .bsv-locked {
	cursor: pointer;
	filter: grayscale(0.4);
	opacity: 0.45;
	user-select: none;
}

/* Mọi phần tử BÊN TRONG vùng khoá không nhận chuột — click luôn rơi vào
   chính wrapper (nơi gắn lockGuard), không cách nào bấm trúng nút bên trong. */
.bsv .bsv-locked > * { pointer-events: none; }

/* ── Card tin tức (trang chủ, trang Tin tức, box nhúng) ───────────────
   Ảnh phủ toàn card; chân card (34% chiều cao) nền xanh y tế đè lên đáy
   ảnh, viền card cùng màu — dùng chung cho mọi nơi hiển thị bài viết.
   10% chiều cao đầu chân (~30% chiều cao chân) là dải gradient mờ dần
   từ ảnh sang nền xanh; phần còn lại đặc màu để chữ nằm hẳn trong nền. */
.bsv .bsv-news {
	aspect-ratio: 16 / 11;
	background: var(--bsv-bg);
	border: 1px solid var(--bsv-primary);
	border-radius: var(--bsv-radius);
	display: block;
	overflow: hidden;
	position: relative;
	text-decoration: none;
}

.bsv .bsv-news__media {
	inset: 0;
	position: absolute;
}

.bsv .bsv-news__img {
	display: block;
	height: 100% !important;
	object-fit: cover;
	width: 100% !important;
}

.bsv .bsv-news__body {
	background: linear-gradient(to bottom, transparent 0%, var(--bsv-primary) 30%, var(--bsv-primary) 100%);
	bottom: 0;
	color: #fff;
	display: flex;
	flex-direction: column;
	height: 34%;
	justify-content: flex-end;
	left: 0;
	padding: 10px 14px;
	position: absolute;
	right: 0;
}

.bsv .bsv-news__title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.35;
	margin-bottom: 8px;
	overflow: hidden;
}

.bsv .bsv-news:hover .bsv-news__title { text-decoration: underline; }

.bsv .bsv-news__meta {
	align-items: center;
	color: rgba(255, 255, 255, 0.85);
	display: flex;
	flex-wrap: wrap;
	font-size: 12px;
	gap: 6px 8px;
}

.bsv .bsv-news__cat {
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

/* Chấm phân cách chuyên mục/ngày — chỉ hiện khi có cả hai. */
.bsv .bsv-news__cat:not(:empty) + .bsv-news__date::before {
	content: '•';
	margin-right: 8px;
}

/* ── Box tin tức trên MOBILE: dạng dòng kiểu bảng tin (ảnh đại diện tròn +
   tiêu đề + nhãn "Mới" + thời gian tương đối + trích đoạn), giữ NGUYÊN thẻ
   ảnh phủ .bsv-news ở trên cho DESKTOP — mặc định (mobile) hiện .bsv-news-feed,
   ẩn .bsv-news-grid; từ 768px trở lên đảo ngược lại (đúng chuẩn mobile-first,
   xem CLAUDE.md). Dùng ở news-latest.php (box "Tin tức" trang chủ). ──────── */
.bsv-news-grid { display: none; }

.bsv-news-feed { display: block; }

.bsv .bsv-news-feed__item {
	align-items: flex-start;
	border: 1px solid var(--bsv-border);
	border-radius: 10px;
	color: inherit;
	display: flex;
	gap: 12px;
	margin-bottom: 10px;
	padding: 12px;
	text-decoration: none;
}

.bsv .bsv-news-feed__item:last-child { margin-bottom: 0; }

.bsv .bsv-news-feed__avatar {
	border-radius: 50%;
	flex-shrink: 0;
	height: 64px !important;
	object-fit: cover;
	width: 64px !important;
}

.bsv .bsv-news-feed__body { min-width: 0; }

.bsv .bsv-news-feed__head {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.bsv .bsv-news-feed__title {
	font-size: 16px;
	font-weight: 600;
}

.bsv .bsv-news-feed__item:hover .bsv-news-feed__title { text-decoration: underline; }

.bsv .bsv-news-feed__badge {
	background: var(--bsv-success);
	border-radius: 999px;
	color: #fff;
	font-size: 12px;
	font-weight: 700;
	padding: 2px 10px;
}

/* Hàng 2 (dưới tiêu đề): danh mục + thời gian. */
.bsv .bsv-news-feed__meta {
	align-items: center;
	color: var(--bsv-muted);
	display: flex;
	flex-wrap: wrap;
	font-size: 13px;
	gap: 6px 8px;
	margin-top: 2px;
}

.bsv .bsv-news-feed__cat {
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.bsv .bsv-news-feed__time { white-space: nowrap; }

/* Chấm phân cách danh mục/thời gian — chỉ hiện khi có cả hai. */
.bsv .bsv-news-feed__cat:not(:empty) + .bsv-news-feed__time::before {
	content: '•';
	margin-right: 8px;
}

.bsv .bsv-news-feed__excerpt {
	color: var(--bsv-muted);
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	font-size: 14px;
	margin: 0;
	overflow: hidden;
}

@media (min-width: 768px) {
	.bsv-news-grid { display: grid; }
	.bsv-news-feed { display: none; }
}

.bsv-icon { display: inline-block; flex-shrink: 0; vertical-align: -3px; }

.bsv-muted { color: var(--bsv-muted); font-size: 13px; }
.bsv-mb-0 { margin-bottom: 0; margin-top: 0; }

/* Màu chữ chỉ báo % thay đổi (tăng/giảm) trong báo cáo — xem
   components/clinic-full-report.php + bsvClinicOwner.changeClass(). */
.bsv-text--success { color: var(--bsv-success); }
.bsv-text--danger { color: var(--bsv-danger); }
[x-cloak] { display: none !important; }

/* Ô tìm tài khoản theo SĐT/tên (autocomplete) — xem components/account-picker.php. */
.bsv-account-picker {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: var(--bsv-radius);
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
	left: 0;
	margin-top: 4px;
	max-height: 240px;
	overflow-y: auto;
	position: absolute;
	right: 0;
	top: 100%;
	z-index: 20;
}

.bsv-account-picker__item {
	background: none;
	border: 0;
	border-bottom: 1px solid var(--bsv-border);
	cursor: pointer;
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	padding: 8px 10px;
	text-align: left;
	width: 100%;
}

.bsv-account-picker__item:last-child { border-bottom: 0; }
.bsv-account-picker__item:hover { background: var(--bsv-bg); }

/* ── Lưới thumbnail ảnh/tài liệu đính kèm — LUÔN 5 cột vuông cả mobile lẫn
   desktop (khác .bsv-grid thường co về 1 cột trên mobile), vì đây chỉ là
   thumbnail nhỏ để chọn, xem đủ nội dung ở popup slider (bsv.openAttachmentViewer())
   khi bấm vào. Dùng chung: sửa lịch hẹn (patient.php), box "Đang khám"
   (reception-desk.php). ────────────────────────────────────────────────── */
.bsv-attach-grid {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: 6px;
}
.bsv-attach-grid__item {
	position: relative;
	aspect-ratio: 1 / 1;
	border-radius: 6px;
	overflow: hidden;
	border: 1px solid var(--bsv-border);
	cursor: pointer;
	background: var(--bsv-bg);
}
.bsv-attach-grid__item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.bsv-attach-grid__item--pdf {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 4px;
	font-size: 10px;
	line-height: 1.3;
	color: var(--bsv-muted);
	text-align: center;
	word-break: break-all;
	overflow: hidden;
}

/* Popup slider xem ảnh/pdf — tạo bằng JS thuần (bsv.openAttachmentViewer()),
   không qua Alpine, nên cần class .bsv ở gốc để ăn đúng biến CSS. */
.bsv-attachment-viewer {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.85);
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
}
.bsv-attachment-viewer__body { max-width: 90vw; max-height: 85vh; }
.bsv-attachment-viewer__body img {
	max-width: 90vw;
	max-height: 85vh;
	object-fit: contain;
	display: block;
	border-radius: 6px;
}
.bsv-attachment-viewer__body iframe {
	width: 90vw;
	height: 85vh;
	border: none;
	border-radius: 6px;
	background: #fff;
}
.bsv-attachment-viewer__close,
.bsv-attachment-viewer__nav {
	position: absolute;
	background: rgba(255, 255, 255, 0.15);
	border: none;
	color: #fff;
	cursor: pointer;
	border-radius: 50%;
}
.bsv-attachment-viewer__close {
	top: 16px;
	right: 16px;
	width: 40px;
	height: 40px;
	font-size: 26px;
	line-height: 1;
}
.bsv-attachment-viewer__nav {
	top: 50%;
	transform: translateY(-50%);
	width: 48px;
	height: 48px;
	font-size: 28px;
}
.bsv-attachment-viewer__nav--prev { left: 16px; }
.bsv-attachment-viewer__nav--next { right: 16px; }

/* ── Modal "Tuỳ chỉnh nội dung in" (tab Mẫu in) — khay field kéo-thả ─────── */
.bsv-layout-dropzone {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-height: 120px;
	padding: 8px;
	border: 1px dashed var(--bsv-border);
	border-radius: 8px;
	background: var(--bsv-bg);
}
.bsv-layout-chip {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 6px 10px;
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: 6px;
	font-size: 13px;
	cursor: grab;
}
/* Chip đã đặt vào 1 khu vực: hàng trên = tên field + nút xoá, hàng dưới =
   4 ô chỉnh style (cỡ chữ/đậm/canh lề/màu/font) — khác chip trong khay
   "Trường có sẵn" (chỉ có tên, chưa cấu hình được gì). */
.bsv-layout-chip--placed { flex-direction: column; align-items: stretch; gap: 4px; }
.bsv-layout-chip__head { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.bsv-layout-chip__head span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.bsv-layout-chip__head button {
	background: none;
	border: none;
	color: var(--bsv-danger);
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
	padding: 0 2px;
}
.bsv-layout-chip__style {
	display: grid;
	grid-template-columns: 44px 26px 1fr 26px 1fr;
	gap: 4px;
	cursor: default;
}
/* .bsv-layout-chip__style .bsv-input/.bsv-select: ĐỦ specificity thắng
   .bsv .bsv-input/.bsv-select mặc định (min-height 40px) — cần nhỏ gọn vì
   nằm trong 1 chip hẹp, không phải form thường. */
.bsv-layout-chip__style.bsv-layout-chip__style .bsv-input,
.bsv-layout-chip__style.bsv-layout-chip__style .bsv-select { padding: 2px 4px; font-size: 12px; min-height: 26px; }
.bsv-layout-chip__bold {
	background: var(--bsv-surface);
	border: 1px solid var(--bsv-border);
	border-radius: 4px;
	font-weight: 700;
	cursor: pointer;
}
.bsv-layout-chip__bold.is-active { background: var(--bsv-primary); color: #fff; border-color: var(--bsv-primary); }

/* ── "Quản lý Bốc số" — khối nổi bật cho lượt check-in ĐẦU TIÊN ở bàn làm
   việc bệnh nhân (xem templates/dashboard/patient.php). Mobile-first: mặc
   định đã đủ rộng/dễ chạm cho điện thoại, không cần mở rộng thêm ở tablet/
   desktop ngoài giới hạn max-width để không quá khổ trên màn hình lớn. */
.bsv-queue-hero {
	position: relative;
	background: var(--bsv-surface);
	border: 1px solid #86efac;
	border-radius: 16px;
	box-shadow: 0 4px 16px rgba(15, 23, 42, .06);
	padding: 18px 16px 20px;
	margin-bottom: 20px;
	max-width: 480px;
	margin-left: auto;
	margin-right: auto;
	text-align: center;
}
.bsv-queue-hero__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	font-size: 15px;
}
.bsv-queue-hero__cancel {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	background: #f1f5f9;
	border: 1px solid var(--bsv-border);
	border-radius: 8px;
	color: var(--bsv-danger);
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	padding: 4px 10px;
	min-height: 32px;
}
.bsv-queue-hero__serving-label {
	display: inline-flex;
	align-items: center;
	background: color-mix(in srgb, var(--bsv-success) 12%, transparent);
	border: 1px solid color-mix(in srgb, var(--bsv-success) 35%, transparent);
	border-radius: 8px;
	color: var(--bsv-success);
	font-size: 13px;
	font-weight: 700;
	padding: 4px 10px;
	min-height: 32px;
}
.bsv-queue-hero__number {
	/* clamp thay vì cố định 100px — số bốc có thể dài hơn "B-24" (VD "B-124"),
	   clamp co lại tự nhiên trên màn hình hẹp thay vì tràn/vỡ layout. */
	font-size: clamp(60px, 20vw, 100px);
	font-weight: 800;
	line-height: 1.1;
	color: var(--bsv-primary);
	margin: 2px 0 14px;
}
.bsv-queue-hero__stats {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 8px;
	margin-bottom: 18px;
}
.bsv-queue-hero__stat {
	background: color-mix(in srgb, var(--bsv-primary) 8%, transparent);
	border-radius: 10px;
	padding: 8px 4px;
}
.bsv-queue-hero__stat-label {
	font-size: 13px;
	color: var(--bsv-muted, #64748b);
	margin-bottom: 4px;
	line-height: 1.3;
}
.bsv-queue-hero__stat-value {
	font-size: 16px;
	font-weight: 700;
}
.bsv-queue-hero__progress {
	display: flex;
	align-items: flex-start;
	justify-content: center;
	gap: 4px;
}
.bsv-queue-hero__step {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	font-size: 11px;
	color: var(--bsv-muted, #64748b);
	width: 64px;
}
.bsv-queue-hero__step-icon {
	width: 48px;
	height: 48px;
	border-radius: 999px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 22px;
	background: var(--bsv-border);
	color: #fff;
}
.bsv-queue-hero__step--done .bsv-queue-hero__step-icon { background: var(--bsv-success); }
.bsv-queue-hero__step--done { color: var(--bsv-success); font-weight: 600; }
.bsv-queue-hero__step--active .bsv-queue-hero__step-icon {
	width: 72px;
	height: 72px;
	background: var(--bsv-primary);
	box-shadow: 0 0 0 4px color-mix(in srgb, var(--bsv-primary) 25%, transparent);
}
.bsv-queue-hero__step--active .bsv-queue-hero__step-icon .bsv-icon {
	width: 33px;
	height: 33px;
}
.bsv-queue-hero__step--active { color: var(--bsv-primary); font-weight: 700; }
.bsv-queue-hero__step--pending { opacity: .45; }
.bsv-queue-hero__step-line {
	flex: 0 0 auto;
	width: 24px;
	height: 2px;
	background: var(--bsv-border);
	margin-top: 23px;
}
.bsv-queue-hero__hint {
	margin: 14px 0 0;
	font-size: 13px;
	font-weight: 600;
	color: var(--bsv-primary);
}
.bsv-layout-chip__color { width: 26px; height: 26px; padding: 0; border: 1px solid var(--bsv-border); border-radius: 4px; cursor: pointer; }
