﻿/* WVEP.Web/wwwroot/css/wvep-thanh-phan.css */

/*
   THƯ VIỆN PHẦN TỬ DÙNG CHUNG CỦA WVEP.

   Mười bảy họ phần tử mà tám mươi màn nghiệp vụ dùng đi dùng lại: biểu tượng, nút,
   thẻ, bảng, ô nhập, nhãn trạng thái, thông báo, hộp thoại, bước tiến trình, đường
   dẫn phân cấp, phân trang, ô tìm kiếm, trạng thái rỗng, khung chờ tải, đầu màn,
   thanh công cụ và vòng chờ mang logo.

   VÌ SAO TÁCH RIÊNG MỘT TỆP. wvep.css giữ bảng nhận diện và kiểu dáng riêng của từng
   màn; wvep-cong.css giữ cái vỏ; tệp này giữ những mảnh nằm giữa hai thứ đó, tức là
   mọi mảnh không thuộc về màn nào cả mà thuộc về cả tám mươi màn. Nhập chúng vào một
   trong hai tệp kia thì không ai còn phân biệt được đâu là kiểu dáng chung phải giữ
   nguyên, đâu là kiểu dáng của một màn có thể sửa thoải mái.

   Tệp này nạp SAU wvep.css nên nó nâng cấp được những lớp đã có ở đó mà không phải đi
   sửa từng dòng trong hai nghìn dòng cũ. Tên lớp giữ nguyên hết, không đổi một cái
   nào, nên tám mươi màn không phải chỉnh gì.

   Xem toàn bộ thư viện chạy thật ở màn Hệ thống, mục Thư viện giao diện.

   MỌI MÀU Ở ĐÂY ĐỀU GỌI BIẾN. Không một mã màu nào viết thẳng, để đổi nhận diện lần
   sau chỉ phải sửa khối :root của wvep.css.
*/

/* ==================================================================
   1. Biểu tượng
   ================================================================== */

/*
   Bề dày nét, đầu nét và góc nối khai một lần ở đây chứ không lặp trong từng hình,
   nên sáu mươi hai hình nhẹ đi đáng kể và sửa độ mảnh của cả bộ chỉ mất một dòng.
   Màu lấy theo currentColor, tức là biểu tượng luôn cùng màu với chữ đứng cạnh nó.
*/
.wv-bt {
    display: inline-block;
    flex: 0 0 auto;
    width: var(--wv-bt);
    height: var(--wv-bt);
    vertical-align: -.18em;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    color: inherit;
    overflow: visible;
}

.wv-bt-nho {
    width: .875rem;
    height: .875rem;
    stroke-width: 1.8;
}

.wv-bt-lon {
    width: 1.5rem;
    height: 1.5rem;
    stroke-width: 1.5;
}

.wv-bt-rat-lon {
    width: 2.5rem;
    height: 2.5rem;
    stroke-width: 1.3;
}

/* Bốn màu vai trò dùng cho biểu tượng đứng riêng, ví dụ trong hộp thông báo. */
.wv-bt-chinh { color: var(--wv-chinh); }
.wv-bt-tot   { color: var(--wv-tot); }
.wv-bt-nhac  { color: var(--wv-nhac); }
.wv-bt-xau   { color: var(--wv-xau); }
.wv-bt-tin   { color: var(--wv-tin); }

/* ==================================================================
   2. Nút
   ================================================================== */

.wv-nut {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--wv-k2);
    padding: .5rem var(--wv-k4);
    min-height: 2.25rem;
    border: 1px solid var(--wv-chinh);
    border-radius: var(--wv-bo-2);
    background: var(--wv-chinh);
    color: #ffffff;
    font-family: inherit;
    font-size: var(--wv-cd-14);
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease;
}

.wv-nut:hover {
    background: var(--wv-chinh-dam);
    border-color: var(--wv-chinh-dam);
    color: #ffffff;
    text-decoration: none;
}

.wv-nut:active {
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, .18);
}

/* Nút đã khóa vẫn phải ĐỌC ĐƯỢC. Chữ trắng trên nền xám nhạt chỉ đạt tương phản
   1,6 lần, tức là người dùng không biết cái nút xám kia tên gì và vì sao mình không
   bấm được. Chữ xám đậm trên nền xám nhạt đạt 4,7 lần: vẫn nhìn ra ngay là đang khóa,
   mà chữ thì đọc được. */
.wv-nut:disabled,
.wv-nut[aria-disabled="true"] {
    background: var(--wv-xam-100);
    border-color: var(--wv-xam-200);
    color: var(--wv-xam-500);
    cursor: not-allowed;
    box-shadow: none;
}

.wv-nut .wv-bt {
    width: 1rem;
    height: 1rem;
}

/* Nút phụ: cùng hình dáng, nhưng viền chứ không tô nền, nên hai nút đứng cạnh nhau
   thì mắt biết ngay cái nào là việc chính. */
.wv-nut-phu {
    background: var(--wv-tam);
    border-color: var(--wv-vien);
    color: var(--wv-chinh);
}

.wv-nut-phu:hover {
    background: var(--wv-chinh-nen);
    border-color: var(--wv-chinh-vien);
    color: var(--wv-chinh-dam);
}

/* Nút nguy hiểm: xóa, hủy đơn, thu hồi duyệt. Đỏ để người bấm nhìn thấy trước khi bấm. */
.wv-nut-canh-bao {
    background: var(--wv-xau-chu);
    border-color: var(--wv-xau-chu);
    color: #ffffff;
}

.wv-nut-canh-bao:hover {
    background: var(--wv-xau-dam);
    border-color: var(--wv-xau-dam);
}

/* Nút nhấn: dùng cho một thao tác nổi bật không phải là việc chính, ví dụ Xuất bảng
   tính trên màn báo cáo. Chữ tối trên nền cam vàng, vì chữ trắng trên #ffab0b chỉ đạt
   tương phản 1,9 lần. */
.wv-nut-nhan {
    background: var(--wv-nhan);
    border-color: var(--wv-nhan);
    color: var(--wv-cam-800);
}

.wv-nut-nhan:hover {
    background: var(--wv-nhan-dam);
    border-color: var(--wv-nhan-dam);
    color: var(--wv-cam-800);
}

/* Nút mờ: thao tác thứ yếu, không viền, chỉ hiện nền khi rê chuột. */
.wv-nut-mo {
    background: transparent;
    border-color: transparent;
    color: var(--wv-chu-mo);
    font-weight: 500;
}

.wv-nut-mo:hover {
    background: var(--wv-xam-100);
    border-color: transparent;
    color: var(--wv-chinh-dam);
}

.wv-nut-nho {
    min-height: 1.875rem;
    padding: .25rem var(--wv-k3);
    font-size: var(--wv-cd-13);
}

.wv-nut-to {
    min-height: 2.625rem;
    padding: .625rem var(--wv-k5);
    font-size: var(--wv-cd-15);
}

.wv-nut-rong {
    width: 100%;
}

/*
   Biểu mẫu bọc MỘT nút chữ nằm trong ô thao tác của bảng.

   Trước đây mấy chỗ này mượn lớp wv-nut-rong, mà lớp ấy khai rộng trọn trăm phần trăm.
   Một thẻ form rộng trọn hàng thì nút Xóa bị đẩy xuống dòng dưới nút Sửa, nên ô thao tác
   cao gấp đôi và hai nút so le nhau ở mọi dòng của bảng.

   Thẻ form ở đây chỉ là cái vỏ để gửi lượt xóa kèm phiếu chống giả, nó không phải một
   khối bố cục, nên phải nằm gọn trong dòng như chính cái nút bên trong nó.
*/
.wv-nut-trong-o {
    display: inline;
}

/*
   Nút chỉ có biểu tượng. Cạnh vuông đúng cỡ chạm được, và BẮT BUỘC có lời đọc: một
   cái nút không chữ mà cũng không lời đọc thì với người dùng máy đọc màn hình nó chỉ
   là một ô trống không rõ bấm vào sẽ ra chuyện gì.
*/
.wv-nut-hinh {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    width: 2rem;
    height: 2rem;
    min-height: 0;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--wv-bo-2);
    background: transparent;
    color: var(--wv-chu-mo);
    cursor: pointer;
}

.wv-nut-hinh:hover {
    background: var(--wv-chinh-nen);
    border-color: var(--wv-chinh-vien);
    color: var(--wv-chinh-dam);
    text-decoration: none;
}

.wv-nut-hinh .wv-bt {
    width: 1.0625rem;
    height: 1.0625rem;
}

.wv-nut-hinh.wv-nut-canh-bao {
    background: transparent;
    border-color: transparent;
    color: var(--wv-xau);
}

.wv-nut-hinh.wv-nut-canh-bao:hover {
    background: var(--wv-xau-nen);
    border-color: var(--wv-xau-vien);
    color: var(--wv-xau-chu);
}

/* Một hàng nút thao tác trong ô cuối của bảng danh sách. */
.wv-hang-hinh {
    display: inline-flex;
    align-items: center;
    gap: var(--wv-k1);
}

/* ==================================================================
   3. Thẻ
   ================================================================== */

.wv-the {
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-1);
    margin-bottom: var(--wv-k5);
}

.wv-the-dau {
    display: flex;
    align-items: center;
    gap: var(--wv-k2);
    padding: var(--wv-k3) var(--wv-k5);
    border-bottom: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3) var(--wv-bo-3) 0 0;
    background: var(--wv-tam-mo);
    font-weight: 600;
    font-size: var(--wv-cd-14);
    color: var(--wv-xam-800);
}

.wv-the-dau .wv-bt {
    color: var(--wv-chinh);
}

.wv-the-than {
    padding: var(--wv-k5);
}

.wv-the-chan {
    display: flex;
    align-items: center;
    gap: var(--wv-k2);
    padding: var(--wv-k3) var(--wv-k5);
    border-top: 1px solid var(--wv-vien);
    border-radius: 0 0 var(--wv-bo-3) var(--wv-bo-3);
    background: var(--wv-tam-mo);
}

.wv-the-dau-phu {
    margin-left: auto;
    font-weight: 400;
    font-size: var(--wv-cd-12);
    color: var(--wv-chu-mo);
}

/* Ô tóm tắt một con số, xếp thành lưới ở đầu các màn báo cáo. */
.wv-o-tom-tat {
    border-left: 4px solid var(--wv-chinh);
    position: relative;
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-1);
    padding: var(--wv-k4) var(--wv-k5);
    overflow: hidden;
}

/* Vạch màu nằm dọc mép trái. Dùng phần tử giả chứ không dùng border-left, để bo góc
   của thẻ không bị vạch cắt vuông một bên. */
.wv-o-tom-tat::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 3px;
    background: var(--wv-chinh);
}

.wv-o-tom-tat.wv-nhan-cam::before { background: var(--wv-nhan); }
.wv-o-tom-tat.wv-nhan-tot::before { background: var(--wv-tot); }
.wv-o-tom-tat.wv-nhan-xau::before { background: var(--wv-xau); }

.wv-o-tom-tat .wv-nhan {
    display: block;
    font-size: var(--wv-cd-11);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--wv-chu-nhat);
    margin-bottom: var(--wv-k1);
}

.wv-o-tom-tat .wv-gia-tri {
    font-size: var(--wv-cd-20);
    font-weight: 700;
    color: var(--wv-xam-900);
}

/* ==================================================================
   4. Bảng
   ================================================================== */

.wv-bang {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--wv-cd-13);
}

.wv-bang th,
.wv-bang td {
    padding: .5rem var(--wv-k3);
    border-bottom: 1px solid var(--wv-vien-nhat);
    text-align: left;
    vertical-align: top;
}

/*
   NĂM LỚP CĂN LỀ PHẢI LẤY LẠI QUYỀN CỦA CHÍNH CHÚNG BÊN TRONG BẢNG.

   Luật ngay trên kia nặng hai mảnh, .wv-bang cộng td, còn .wv-phai chỉ nặng một mảnh, nên
   trong một bảng thì căn trái luôn thắng và mọi cột tiền của cả hệ thống bị căn TRÁI. Đo
   tận nơi ngày 25 tháng 8 năm 2026 trên bốn màn sổ quỹ, sổ cái, báo cáo công nợ và công
   nợ khách hàng: td.wv-phai đều cho ra text-align left.

   Đó không phải chuyện thẩm mỹ. Quy tắc thiết kế số 15 chốt rằng bảng SỐ của sổ sách vẫn
   cuộn ngang chứ không xếp chồng, và lý do duy nhất để nó chịu cuộn là để các con số
   THẲNG CỘT mà so với nhau. Căn trái thì 1.795.000 và 538.500.000 lệch nhau ba chữ số, và
   mắt chạy dọc một cột tiền không còn so được gì.

   Chữa bằng bộ chọn GHÉP chứ không bằng cách đổi thứ tự tệp, đúng cách mà quy tắc số 11
   đã chốt: viết hai mảnh liền nhau thì kết quả không còn phụ thuộc thứ tự nạp nữa.

   Lớp .wv-so thêm vào danh sách này ngày 26 tháng 8 năm 2026. Nó là lớp ô tiền của nhóm
   màn điều hành, trước đó chỉ được căn phải bởi một luật riêng có phạm vi .wv-doi-chieu, nên
   ba bảng của màn dòng tiền một đoàn không mang lớp ấy bị thua luật căn trái ngay trên. Đo
   được: quét 162 ô tiền trên 25 màn thì 159 ô căn phải, 3 ô căn trái, cả ba trên màn ấy.
   Khai ở đây, tức ở đúng chỗ bốn lớp kia đang đứng, thì không còn bảng nào phụ thuộc
   vào việc nó có nằm trong một khung mang lớp cụ thể hay không.
*/
.wv-bang th.wv-phai,
.wv-bang td.wv-phai,
.wv-bang th.wv-cong,
.wv-bang td.wv-cong,
.wv-bang th.wv-o-so,
.wv-bang td.wv-o-so,
.wv-bang th.wv-so,
.wv-bang td.wv-so,
.wv-bang th.wv-so-tinh,
.wv-bang td.wv-so-tinh {
    text-align: right;
}

.wv-bang th.wv-giua,
.wv-bang td.wv-giua {
    text-align: center;
}

.wv-bang thead th {
    background: var(--wv-xam-100);
    border-bottom: 1px solid var(--wv-vien);
    font-size: var(--wv-cd-11);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--wv-xam-700);
    vertical-align: bottom;
}

.wv-bang tbody tr:hover {
    background: var(--wv-chinh-nen);
}

.wv-bang tbody tr:last-child td {
    border-bottom: 0;
}

.wv-bang tfoot td {
    border-top: 2px solid var(--wv-vien);
    background: var(--wv-tam-mo);
    font-weight: 700;
}

/* Bảng có sọc, dùng cho bảng dài toàn số. */
.wv-bang-soc tbody tr:nth-child(even) {
    background: var(--wv-xam-50);
}

.wv-bang-soc tbody tr:nth-child(even):hover {
    background: var(--wv-chinh-nen);
}

/* Bảng gọn, dùng khi một màn phải bày hai mươi cột. */
.wv-bang-gon th,
.wv-bang-gon td {
    padding: .3125rem var(--wv-k2);
    font-size: var(--wv-cd-12);
}

.wv-ma {
    font-family: var(--wv-phong-ma);
    font-size: var(--wv-cd-12);
    color: var(--wv-chinh-dam);
}

/* ==================================================================
   5. Ô nhập
   ================================================================== */

.wv-o-nhap {
    width: 100%;
    min-height: 2.25rem;
    padding: .4375rem var(--wv-k3);
    border: 1px solid var(--wv-xam-300);
    border-radius: var(--wv-bo-2);
    background: var(--wv-tam);
    color: var(--wv-chu);
    font-family: inherit;
    font-size: var(--wv-cd-14);
    line-height: 1.35;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.wv-o-nhap::placeholder {
    color: var(--wv-xam-400);
}

.wv-o-nhap:hover:not(:disabled):not([readonly]) {
    border-color: var(--wv-xam-400);
}

.wv-o-nhap:focus {
    outline: none;
    border-color: var(--wv-chinh);
    box-shadow: 0 0 0 3px rgba(0, 71, 117, .16);
}

/*
   TRẢ LẠI VÒNG TIÊU ĐIỂM CAM CHO NGƯỜI DÙNG BÀN PHÍM.

   Luật ngay trên đặt outline: none cho mọi ô nhập đang được chọn. Luật đó nặng 0-2-0,
   còn vòng tiêu điểm dùng chung khai ở wvep.css bọc trong :where nên chỉ nặng 0-1-0.
   Nặng hơn thì thắng, nên ô nhập là chỗ DUY NHẤT trong cả hệ thống mất vòng cam, chỉ
   còn lại quầng xanh mờ 16 phần trăm. Quầng ấy đủ thấy khi bấm chuột, nhưng người đi
   bằng phím Tab cần một dấu hiệu rõ ngang với mọi phần tử khác, và cần nó GIỐNG NHAU
   ở khắp nơi thì mắt mới bám theo được.

   Nên tách hai trường hợp: bấm chuột vào ô thì vẫn chỉ quầng xanh cho êm mắt, còn đi
   tới ô bằng bàn phím thì hiện đúng vòng cam như nút, như liên kết, như thẻ chọn.
   Giữ luôn quầng xanh ở đây để ô nhập không bị mất viền đậm khi đang gõ.
*/
.wv-o-nhap:focus-visible {
    outline: 2px solid var(--wv-nhan);
    outline-offset: 2px;
}

.wv-o-nhap:disabled,
.wv-o-nhap[readonly] {
    background: var(--wv-xam-50);
    color: var(--wv-chu-mo);
    cursor: not-allowed;
}

/* Ô nhập đang có lỗi. Viền đỏ ĐI KÈM câu giải thích ở dưới chứ không đứng một mình:
   riêng màu viền thì người mù màu đỏ lục không thấy gì cả. */
.wv-o-nhap.wv-o-loi,
.wv-o-nhap[aria-invalid="true"] {
    border-color: var(--wv-xau);
    background: var(--wv-xau-nen);
}

.wv-o-nhap.wv-o-loi:focus,
.wv-o-nhap[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 3px rgba(179, 38, 30, .16);
}

/* Ô chọn: vẽ mũi tên bằng chính hình nền dạng SVG nhúng thẳng, không tải tệp nào. */
select.wv-o-nhap {
    appearance: none;
    padding-right: var(--wv-k8);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c6873' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.4 9.4l5.6 5.6 5.6-5.6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--wv-k3) center;
    background-size: 1rem 1rem;
}

.wv-hang label {
    display: block;
    margin-bottom: var(--wv-k1);
    font-weight: 600;
    font-size: var(--wv-cd-13);
    color: var(--wv-xam-700);
}

/* Nhãn của một Ô TÍCH thì KHÔNG lấy luật nhãn hàng ngay trên.

   Nhãn hàng đứng TRÊN ô nhập nên đậm, tách dòng và chừa khoảng dưới. Nhãn ô tích đứng
   NGAY CẠNH ô tích nên phải chữ thường và không chừa khoảng nào, đúng như .wv-chon đã
   khai ở wvep.css.

   Vì sao .wv-chon một mình thua: nó nặng đúng MỘT lớp còn .wv-hang label nặng một lớp
   một thẻ, nên luật trên thắng bất kể thứ tự nạp. Đo được ngày 26 tháng 8 năm 2026 trên
   màn thêm nhà cung cấp: nhãn ô tích ra display block, font-weight 600, margin-bottom
   4px, trong khi .wv-chon khai display flex, font-weight 400, margin 0.

   Ba chỗ đã từng viết class="mb-0 fw-normal" đúng ý này, nhưng đó là hai lớp của
   Bootstrap mà cả hệ thống không nạp Bootstrap ở đâu, nên chúng chưa từng có tác dụng
   một lần nào. Bộ chọn ghép ở đây nặng hai lớp nên nó thắng, và thắng không phụ thuộc
   thứ tự nạp, đúng quy tắc 11. */
.wv-hang label.wv-chon,
.wv-hang .wv-nho label {
    display: flex;
    align-items: center;
    margin-bottom: 0;
    font-weight: 400;
}

.wv-goi-y {
    display: block;
    margin-top: var(--wv-k1);
    font-size: var(--wv-cd-12);
    color: var(--wv-chu-nhat);
}

.wv-loi-o {
    display: block;
    margin-top: var(--wv-k1);
    font-size: var(--wv-cd-12);
    color: var(--wv-xau);
}

/* Câu báo phía trình duyệt đặt ngay sau ô không có chỗ báo riêng (wv-kiem-bieu-mau.js). Thư viện
   bật tắt nhãn bằng thuộc tính style nội dòng (inline khi hiện lại) và để nhãn rỗng khi ô đã sửa
   đúng, nên hai luật phải thắng style nội dòng: có chữ là một khối dưới ô, rỗng là ẩn. */
.wv-loi-o-noi {
    display: block !important;
}

.wv-loi-o-noi:empty {
    display: none !important;
}

/* Thẻ thứ trong tuần của bảng giá là khung chữ đậm: câu báo đặt bên trong giữ nét thường. */
.wv-o-thu .wv-loi-o {
    font-weight: 400;
}

/* Ô nhập có biểu tượng dán bên trái, dùng cho ô tìm kiếm và ô tiền. */
.wv-o-co-hinh {
    position: relative;
    display: block;
}

.wv-o-co-hinh > .wv-bt {
    position: absolute;
    top: 50%;
    left: var(--wv-k3);
    transform: translateY(-50%);
    color: var(--wv-xam-400);
    pointer-events: none;
}

.wv-o-co-hinh > .wv-o-nhap {
    padding-left: var(--wv-k8);
}

.wv-o-co-hinh:focus-within > .wv-bt {
    color: var(--wv-chinh);
}

/* ==================================================================
   6. Nhãn trạng thái
   ================================================================== */

.wv-trang-thai {
    display: inline-flex;
    align-items: center;
    gap: var(--wv-k1);
    padding: .125rem var(--wv-k2);
    border: 1px solid transparent;
    border-radius: var(--wv-bo-tron);
    background: var(--wv-xam-100);
    color: var(--wv-xam-700);
    font-size: var(--wv-cd-12);
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.wv-tt-tot  { background: var(--wv-tot-nen);  border-color: var(--wv-tot-vien);  color: var(--wv-tot-chu); }
.wv-tt-nhac { background: var(--wv-nhac-nen); border-color: var(--wv-nhac-vien); color: var(--wv-nhac-chu); }
.wv-tt-xau  { background: var(--wv-xau-nen);  border-color: var(--wv-xau-vien);  color: var(--wv-xau-chu); }
.wv-tt-tin  { background: var(--wv-tin-nen);  border-color: var(--wv-tin-vien);  color: var(--wv-tin-chu); }
.wv-tt-chinh{ background: var(--wv-chinh-nen);border-color: var(--wv-chinh-vien);color: var(--wv-chinh-dam); }

/* Chấm tròn đứng trước chữ, cho mắt bắt trạng thái nhanh hơn là đọc chữ. */
.wv-trang-thai .wv-cham {
    width: .4375rem;
    height: .4375rem;
    border-radius: var(--wv-bo-tron);
    background: currentColor;
    flex: 0 0 auto;
}

.wv-the-module {
    display: inline-block;
    padding: .125rem var(--wv-k2);
    border: 1px solid var(--wv-chinh-vien);
    border-radius: var(--wv-bo-tron);
    background: var(--wv-chinh-nen-dam);
    color: var(--wv-chinh-dam);
    font-size: var(--wv-cd-12);
}

.wv-the-vai {
    display: inline-block;
    padding: .125rem var(--wv-k2);
    margin-right: var(--wv-k1);
    border: 1px solid var(--wv-nhac-vien);
    border-radius: var(--wv-bo-tron);
    background: var(--wv-nhac-nen);
    color: var(--wv-nhac-chu);
    font-size: var(--wv-cd-12);
}

/* ==================================================================
   7. Thông báo
   ================================================================== */

.wv-bao,
.wv-loi,
.wv-canh-bao {
    display: flex;
    align-items: flex-start;
    gap: var(--wv-k3);
    padding: var(--wv-k3) var(--wv-k4);
    margin-bottom: var(--wv-k4);
    border: 1px solid var(--wv-tin-vien);
    border-left: 3px solid var(--wv-tin);
    border-radius: var(--wv-bo-2);
    background: var(--wv-tin-nen);
    color: var(--wv-tin-chu);
    font-size: var(--wv-cd-13);
}

.wv-bao .wv-bt,
.wv-loi .wv-bt,
.wv-canh-bao .wv-bt {
    flex: 0 0 auto;
    margin-top: .0625rem;
}

.wv-loi {
    border-color: var(--wv-xau-vien);
    border-left-color: var(--wv-xau);
    background: var(--wv-xau-nen);
    color: var(--wv-xau-chu);
}

.wv-canh-bao {
    border-color: var(--wv-nhac-vien);
    border-left-color: var(--wv-nhac);
    background: var(--wv-nhac-nen);
    color: var(--wv-nhac-chu);
}

.wv-canh-bao a {
    color: var(--wv-nhac-chu);
    font-weight: 600;
}

/*
   Dải báo TỜ CHIẾT TÍNH ĐÃ HỦY, thêm ngày 18 tháng 9 năm 2026.

   Đậm hơn dải nhắc thường, vì đây không phải một lời nhắc mà là một sự thật về cả tờ:
   lượt hủy không hạ mốc, nên dãy mốc ngay dưới vẫn bày một tờ đi hết luồng duyệt.

   VIẾT HAI LỚP LIỀN NHAU cho độ nặng thành hai, đúng quy tắc 11: .wv-canh-bao khai ở
   chính tệp này nên một lớp trơn đặt sau vẫn thắng, nhưng thứ tự ấy là thứ dễ đổi nhất
   khi có người dọn lại tệp.
*/
.wv-canh-bao.wv-to-da-huy {
    border-color: var(--wv-xau-vien);
    border-left-color: var(--wv-xau);
    background: var(--wv-xau-nen);
    color: var(--wv-xau-chu);
}

.wv-canh-bao.wv-to-da-huy span {
    margin-left: var(--wv-k1);
}

.wv-bao-tot {
    border-color: var(--wv-tot-vien);
    border-left-color: var(--wv-tot);
    background: var(--wv-tot-nen);
    color: var(--wv-tot-chu);
}

.wv-bao-noi-dung {
    min-width: 0;
    flex: 1 1 auto;
}

.wv-bao-noi-dung strong {
    display: block;
    margin-bottom: .0625rem;
}

/*
   Ô tóm tắt lỗi của biểu mẫu KHÔNG được hiện khi chưa có lỗi nào.

   ASP.NET luôn dựng sẵn cái thẻ ấy ở mọi biểu mẫu, kể cả lúc biểu mẫu sạch: khi sạch
   thì nó gắn lớp validation-summary-valid và bên trong chỉ có một danh sách rỗng. Có
   lề và có màu nền nên nó hiện ra thành một dải đỏ trống ngay đầu mọi màn thêm mới,
   người dùng nhìn vào tưởng vừa làm sai cái gì đó mà không đọc được là sai chỗ nào.
   ĐÃ NHÌN THẤY ở màn Thêm tour: một dải đỏ cao 42 chấm, không một chữ nào trong đó.

   Bắt luôn cả trường hợp thẻ rỗng hoàn toàn, cho những chỗ tự dựng ô báo lỗi bằng tay.
*/
.wv-loi.validation-summary-valid,
.wv-loi:empty,
.wv-bao:empty,
.wv-canh-bao:empty {
    display: none;
}

/*
   Hộp báo này dựng bằng flex, mà flex khai ở tấm kiểu của mình thì đè luôn cả luật ẩn
   sẵn của trình duyệt. Không khai lại thì đặt thuộc tính hidden lên nó chẳng có tác dụng
   gì, và lời nhắc mốc đổi thuế nằm chình ình ngay cả khi không có mốc nào vắt qua.
*/
.wv-canh-bao[hidden] {
    display: none;
}

/*
   DẤU CẢNH BÁO NẰM TRONG MỘT Ô CỦA BẢNG.

   VÌ SAO PHẢI CÓ LỚP RIÊNG chứ không dùng lại .wv-canh-bao ngay trên. Ba hộp báo kia dựng
   cho một dải chạy hết bề ngang trang: chúng có nền tô, có viền bốn cạnh, có bo góc, có
   đệm trong mười hai trên mười sáu điểm ảnh và có lề dưới. Bấy nhiêu thứ đặt vào một ô
   bảng rộng chừng một trăm hai lăm điểm ảnh thì ra một tấm thẻ nhỏ có nền và có viền, cao
   sáu dòng, mép phải chỉ còn cách vạch cột đúng mười hai điểm ảnh. Đã nhìn tận mắt trên
   ảnh chụp khổ 1440 của màn Bàn giao việc: nó đọc ra như một mẩu giấy dán đè lên bảng chứ
   không đọc ra như một dòng ghi chú của ô, và người dùng kể lại đúng là nó đè sang cột bên
   cạnh. Nó cũng thổi chiều cao cả dòng lên một trăm bảy lăm điểm ảnh, tức gần gấp bốn
   những dòng không có cảnh báo.

   Lớp này giữ nguyên MÀU của bộ nhắc nhở, vì màu mới là thứ mắt bắt được khi lướt bảng
   tìm tờ quá hạn, nhưng bỏ hết phần dựng hộp: không nền, không viền bốn cạnh, không bo
   góc, không lề dưới. Còn lại đúng một vạch màu bên trái, và một vạch thì không bao giờ
   trông giống một tấm thẻ dán đè.

   display block cộng bề rộng tự động: khối bám đúng bề rộng ô chứa nó, chữ dài thì xuống
   dòng bên trong ô. Đây là chỗ khác hẳn ba hộp kia, vốn dựng bằng flex.

   Không đặt bề rộng tối thiểu, không đặt white-space: hai thứ ấy là hai lối duy nhất làm
   một khối chữ đòi rộng hơn ô của nó.
*/
.wv-dau-tre {
    display: block;
    margin-top: .25rem;
    padding-left: var(--wv-k2);
    border-left: 3px solid var(--wv-nhac);
    color: var(--wv-nhac-chu);
    font-size: var(--wv-cd-12);
    font-weight: 600;
    line-height: 1.35;
}

/* ==================================================================
   8. Hộp thoại
   ================================================================== */

/*
   Dựng bằng thẻ dialog của chính HTML. Trình duyệt lo sẵn ba việc khó: giam tiêu điểm
   bàn phím trong hộp, phím Esc đóng hộp, và tấm che phía sau. Tự viết ba việc ấy bằng
   tay là ba chỗ dễ sai mà không ai thử.
*/
.wv-hop-thoai {
    width: min(34rem, calc(100vw - 2rem));
    padding: 0;
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-4);
    background: var(--wv-tam);
    color: var(--wv-chu);
    box-shadow: var(--wv-bong-4);
}

/*
   TRẦN CHIỀU CAO VÀ PHẦN THÂN TỰ CUỘN, khai ở trạng thái ĐANG MỞ.

   Vì sao không khai display ở luật trên: tấm kiểu dáng của trình duyệt giấu một thẻ dialog
   chưa mở bằng đúng thuộc tính display, mà luật của mình thì bao giờ cũng thắng luật của
   trình duyệt. Đặt display lên .wv-hop-thoai là mọi hộp thoại của cả hệ thống nằm phơi ra
   giữa trang từ lúc mở màn, kể cả hộp chưa ai bấm tới.

   Không có trần này thì một quyển lịch sử dài đẩy nút đóng ra ngoài màn hình, và thẻ dialog
   không cuộn theo trang nên người dùng bị giam trong một cái hộp không có lối ra nào ngoài
   phím Esc. Đo được: một dòng chiết tính sửa hai mươi lượt đã đủ dài hơn màn 1280.

   Dòng dvh viết sau dòng vh, cố ý: trình duyệt hiểu dvh thì lấy dòng sau, không hiểu thì
   bỏ qua dòng ấy và giữ dòng vh. Trên điện thoại, 100vh tính cả phần thanh địa chỉ đang
   che, nên chỉ có dvh mới ra đúng chỗ thật sự nhìn thấy được.
*/
.wv-hop-thoai[open] {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 3rem);
    max-height: calc(100dvh - 3rem);
}

/*
   Hộp RỘNG, cho những hộp bày nguyên một khối nhiều cột.

   Bề rộng mặc định 34rem đủ cho một câu hỏi xác nhận, và hụt hẳn với quyển lịch sử thay
   đổi: lượt tra CẢ TỜ gom vết của tờ, của mọi dòng thu, mọi dòng chi và mọi mức giá khách,
   nên hàng đầu mỗi mục mang tới bốn mảnh (loại việc, tên bảng kèm số hiệu, người, thời
   điểm). Ở 34rem thì bốn mảnh ấy gãy thành bốn dòng và cả quyển sổ dài gấp đôi.
*/
.wv-hop-thoai-rong {
    width: min(52rem, calc(100vw - 2rem));
}

.wv-hop-thoai::backdrop {
    background: rgba(0, 26, 43, .48);
}

.wv-hop-thoai-dau {
    display: flex;
    align-items: center;
    gap: var(--wv-k3);
    padding: var(--wv-k4) var(--wv-k5);
    border-bottom: 1px solid var(--wv-vien);
}

.wv-hop-thoai-dau h2 {
    margin: 0;
    font-size: var(--wv-cd-16);
    font-weight: 700;
}

.wv-hop-thoai-dau .wv-nut-hinh {
    margin-left: auto;
}

/*
   Phần thân là chỗ DUY NHẤT được cuộn, nên phần đầu mang tiêu đề với nút đóng và phần chân
   mang dãy nút luôn nằm trong tầm mắt dù quyển sổ dài bao nhiêu.

   min-height: 0 là điều kiện bắt buộc chứ không phải một dòng thừa: một ô con của khối dàn
   hàng mặc định không chịu co nhỏ hơn nội dung của nó, nên thiếu dòng này thì overflow
   không bao giờ có dịp chạy và cả hộp cứ dài ra mãi.
*/
.wv-hop-thoai-than {
    min-height: 0;
    overflow-y: auto;
    padding: var(--wv-k5);
    font-size: var(--wv-cd-14);
}

.wv-hop-thoai-chan {
    display: flex;
    justify-content: flex-end;
    gap: var(--wv-k2);
    padding: var(--wv-k4) var(--wv-k5);
    border-top: 1px solid var(--wv-vien);
    background: var(--wv-tam-mo);
}

/* ==================================================================
   9. Bước tiến trình
   ================================================================== */

/*
   Năm mốc duyệt của một bảng chiết tính, bảy mốc của một báo giá. Mỗi bước là một ô
   riêng có số thứ tự, để người dùng biết mình đang ở bước mấy trên tổng mấy bước.
   Ba trạng thái: đã qua, đang đứng, chưa tới.
*/
.wv-moc-duyet {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k2);
    margin: 0 0 var(--wv-k4);
    padding: 0;
    list-style: none;
    counter-reset: moc;
}

/* Câu nói bảng đang nằm trên bàn của ai, đặt trên dãy mốc.

   Có mặt vì tên mốc chỉ nói việc VỪA XONG, còn thứ người mở bảng cần biết ngay là việc
   đang chờ mình hay chờ người khác. Suy ra từ tên mốc thì ai cũng suy được, nhưng mỗi
   người suy mất một nhịp, mà màn này người ta mở mấy chục lần một ngày. */
.wv-dang-cho {
    margin: 0 0 var(--wv-k3);
    font-weight: 600;
    color: var(--wv-chu);
}

.wv-moc-duyet li {
    position: relative;
    display: flex;
    flex: 1 1 11rem;
    flex-direction: column;
    gap: .0625rem;
    padding: var(--wv-k3) var(--wv-k3) var(--wv-k3) 2.5rem;
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-2);
    background: var(--wv-tam);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
}

/* Số thứ tự nằm trong một vòng tròn ở mép trái, thay cho dòng chữ Mốc một Mốc hai
   chiếm mất một dòng của mỗi ô. */
.wv-moc-duyet li::before {
    counter-increment: moc;
    content: counter(moc);
    position: absolute;
    top: var(--wv-k3);
    left: var(--wv-k3);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.375rem;
    height: 1.375rem;
    border: 1px solid var(--wv-xam-300);
    border-radius: var(--wv-bo-tron);
    background: var(--wv-xam-50);
    font-size: var(--wv-cd-11);
    font-weight: 700;
    color: var(--wv-chu-mo);
}

.wv-moc-duyet li.wv-moc-da-qua {
    border-color: var(--wv-tot-vien);
    background: var(--wv-tot-nen);
    color: var(--wv-tot-chu);
}

.wv-moc-duyet li.wv-moc-da-qua::before {
    border-color: var(--wv-tot);
    background: var(--wv-tot);
    color: #ffffff;
}

/* Viền trái dày là dấu hiệu thứ hai của mốc đang đứng, đứng cạnh vòng sáng quanh ô.
   Có hai dấu chứ không một, vì vòng sáng chỉ khác ô bên cạnh ở màu, mà trong năm ô xếp
   liền nhau thì một khác biệt về màu không đủ để mắt bắt ngay chỗ cần nhìn. */
.wv-moc-duyet li.wv-moc-dang-o {
    border-color: var(--wv-chinh);
    border-left-width: 4px;
    box-shadow: 0 0 0 1px var(--wv-chinh);
    background: var(--wv-chinh-nen);
    color: var(--wv-chinh-dam);
}

.wv-moc-duyet li.wv-moc-dang-o::before {
    border-color: var(--wv-chinh);
    background: var(--wv-chinh);
    color: #ffffff;
}

.wv-moc-ten {
    font-weight: 600;
}

/* Biểu mẫu trả bảng về, kèm ô lý do bắt buộc.

   Xếp dọc chứ không xếp ngang cạnh nút: ô lý do là ô nhập nhiều dòng, đặt cạnh một nút
   thì ở khổ điện thoại nó teo lại còn vài chục điểm ảnh và người dùng gõ vào một khe. */
.wv-tra-ve {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--wv-k1);
    margin-top: var(--wv-k3);
}

.wv-tra-ve textarea {
    width: 100%;
    max-width: 40rem;
    margin-bottom: var(--wv-k2);
}

/* Sổ lý do trả về: mỗi lần bị bác một dòng, mới nhất lên trước. */
.wv-so-tra-ve {
    display: flex;
    flex-direction: column;
    gap: var(--wv-k3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.wv-so-tra-ve li {
    padding: var(--wv-k3);
    border: 1px solid var(--wv-vien);
    border-left: 3px solid var(--wv-nhac);
    border-radius: var(--wv-bo-2);
    background: var(--wv-tam);
}

.wv-so-tra-ve-dau {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2);
}

/* Lý do là chữ người dùng gõ nên có thể là một chuỗi dài không dấu cách. Không có
   overflow-wrap thì nó chòi thẳng ra ngoài khung ở khổ điện thoại. */
.wv-so-tra-ve-ly-do {
    margin: var(--wv-k2) 0 0;
    overflow-wrap: anywhere;
}

/* ==================================================================
   10. Đường dẫn phân cấp
   ================================================================== */

.wv-duong-dan {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k1);
    margin: 0 0 var(--wv-k2);
    padding: 0;
    list-style: none;
    font-size: var(--wv-cd-12);
    color: var(--wv-chu-nhat);
}

.wv-duong-dan li {
    display: flex;
    align-items: center;
    gap: var(--wv-k1);
}

.wv-duong-dan a {
    color: var(--wv-chu-mo);
}

.wv-duong-dan a:hover {
    color: var(--wv-chinh);
}

.wv-duong-dan .wv-bt {
    width: .75rem;
    height: .75rem;
    color: var(--wv-xam-400);
}

.wv-duong-dan [aria-current="page"] {
    color: var(--wv-xam-800);
    font-weight: 600;
}

/* ==================================================================
   11. Phân trang
   ================================================================== */

.wv-phan-trang {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k1);
    margin-top: var(--wv-k4);
}

/* Chỉ con TRỰC TIẾP, và chừa hẳn dòng chữ đếm.

   Luật cũ viết `.wv-phan-trang a, .wv-phan-trang span` nên nó tô viên thuốc con nhộng cho
   MỌI thẻ span nằm trong khối, kể cả `.wv-phan-trang-tin`. Lớp ấy chỉ đặt lại màu, cỡ chữ
   và lề trái chứ không gỡ viền cũng không gỡ khung, nên cả câu "526 bản ghi, mỗi trang 30
   dòng" hiện ra trong một cái khung cao 2rem. Hôm nay chỉ thấy được ở màn xem thử vì 31
   màn thật chưa dùng lớp ấy; bộ phân trang dùng chung thì dùng, nên phải chữa trước.

   Thu hẹp thành con trực tiếp cũng chặn luôn việc cụm chọn số dòng bị đóng khung hai lần:
   cụm ấy là một thẻ div nên nó tự rơi ra khỏi luật này, còn ba nút bên trong thì nhận kiểu
   qua nhánh `.wv-so-dong` viết ngay dưới đây. */
/* BỌC TRONG :where() ĐỂ LUẬT NỀN NHẸ ĐI, ngày 29 tháng 8 năm 2026.

   Viết `.wv-phan-trang > span:not(.wv-phan-trang-tin)` thì dấu :not() CÓ tính độ nặng, nên
   bộ chọn ấy nặng hai lớp một thẻ. Bốn luật trạng thái viết ngay dưới đây chỉ nặng hai lớp,
   nên với THẺ SPAN chúng thua và chết lặng. Đo trên bản Debug ở /NhaCungCap trang 125: ô
   trang đang đứng ra nền #ffffff chữ #1d2630 thay vì nền #004775 chữ trắng, hai ô dấu ba
   chấm ra nền trắng viền đủ trông y hệt một nút bấm được, nút Trước lúc bị tắt giống hệt
   lúc bấm được, và mức số dòng đang chọn mất nền #e9f2f8. Chỉ còn chữ đậm phân biệt.

   Trước lượt phân trang, luật nền viết `.wv-phan-trang a, .wv-phan-trang span`, nặng một
   lớp một thẻ, nên bốn luật kia thắng đủ. Lượt thu hẹp thành con trực tiếp đã vô tình đảo
   cán cân mà không có ca kiểm nào đo màu nên không có gì đỏ lên.

   :where() không góp độ nặng, nên luật nền về đúng một lớp và bốn luật trạng thái thắng
   lại, không phụ thuộc thứ tự khai. Đây là quy tắc 11 áp cho đúng chỗ: chỗ phải đè thì
   phải NẶNG HƠN, không phải chỉ đứng sau. */
.wv-phan-trang > :where(a, span:not(.wv-phan-trang-tin)),
.wv-so-dong > :where(a, span:not(.wv-so-dong-nhan)) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 var(--wv-k2);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-2);
    background: var(--wv-tam);
    color: var(--wv-chu);
    font-size: var(--wv-cd-13);
    text-align: center;
}

.wv-phan-trang > a:hover,
.wv-so-dong > a:hover {
    border-color: var(--wv-chinh-vien);
    background: var(--wv-chinh-nen);
    color: var(--wv-chinh-dam);
    text-decoration: none;
}

/* Số trang của màn xem thử: trông y như một số trang bấm được, nhưng không dẫn đi đâu
   vì ở màn ấy không có trang thứ hai để dẫn tới. */
.wv-phan-trang .wv-trang-le {
    color: var(--wv-chinh);
}

.wv-phan-trang .wv-trang-dang-o {
    background: var(--wv-chinh);
    border-color: var(--wv-chinh);
    color: #ffffff;
    font-weight: 700;
}

.wv-phan-trang .wv-trang-cach {
    border-color: transparent;
    background: transparent;
    color: var(--wv-xam-400);
}

/* Nút Trước ở trang một và nút Sau ở trang cuối.

   Dựng ra chứ không bỏ đi, để dãy không nhảy ngang mỗi lần sang trang: một nút bấm được ở
   trang này mà biến mất ở trang kia là hàng nút tự xê dịch dưới ngón tay người dùng. */
.wv-phan-trang .wv-trang-tat {
    color: var(--wv-xam-400);
    background: var(--wv-xam-50);
    cursor: default;
}

/* Cụm chọn số dòng mỗi trang: 20, 50, 100.

   Đẩy sang cạnh phải cùng bên với dòng chữ đếm, vì nó là tùy chọn NHÌN chứ không phải một
   bước đi trong danh sách. Là thẻ div nên nó không dính luật viên thuốc ở trên. */
.wv-so-dong {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k1);
    margin-left: auto;
}

.wv-so-dong-nhan {
    color: var(--wv-chu-nhat);
    font-size: var(--wv-cd-12);
}

.wv-phan-trang .wv-so-dong-chon {
    background: var(--wv-chinh-nen);
    border-color: var(--wv-chinh-vien);
    color: var(--wv-chinh-dam);
    font-weight: 700;
}

/* Dòng chữ đếm xuống hàng riêng khi cụm chọn số dòng đã chiếm cạnh phải. */
.wv-phan-trang-tin {
    flex: 1 0 100%;
    margin-top: var(--wv-k1);
    color: var(--wv-chu-nhat);
    font-size: var(--wv-cd-12);
}

/* ==================================================================
   12. Ô tìm kiếm và khối lọc
   ================================================================== */

.wv-o-tim {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 18rem;
    min-width: 0;
}

.wv-o-tim > .wv-bt {
    position: absolute;
    left: var(--wv-k3);
    color: var(--wv-xam-400);
    pointer-events: none;
}

.wv-o-tim > .wv-o-nhap {
    padding-left: var(--wv-k8);
    border-radius: var(--wv-bo-tron);
}

.wv-o-tim:focus-within > .wv-bt {
    color: var(--wv-chinh);
}

.wv-loc {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--wv-k3);
    padding: var(--wv-k4) var(--wv-k5);
    margin-bottom: var(--wv-k4);
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-1);
}

.wv-loc-o label {
    display: block;
    margin-bottom: var(--wv-k1);
    font-weight: 600;
    font-size: var(--wv-cd-12);
    color: var(--wv-xam-700);
}

.wv-loc-nut {
    display: flex;
    gap: var(--wv-k2);
}

/*
   HÀNG LỌC CANH THEO Ô NHẬP, không canh theo mép trên cũng không canh theo mép dưới.

   Vì sao phải đổi: mấy ô lọc cao thấp khác nhau. Ô có dòng gợi ý bên dưới thì cao hơn, ô
   có nhãn xuống hai dòng cũng cao hơn, ô Lọc thêm chứa hai dấu tích xếp dọc thì cao hơn
   hẳn. Canh theo mép dưới thì mấy cái ô NHẬP tán loạn theo, đo được lệch tới bảy mươi sáu
   điểm ảnh trên tám trên mười màn danh sách.

   ĐÃ THỬ LƯỚI CON RỒI BỎ. Cho cả hàng thành một lưới ba dòng nghe thì đúng, nhưng hàng
   lọc có khi tới sáu ô nên nó xuống dòng, mà ô xuống dòng thì rơi sang ba dòng lưới ngầm
   khác chứ không dùng chung ba dòng cũ. Đo lại sau khi đổi: lệch tăng từ bảy sáu lên một
   trăm hai mốt điểm ảnh, tức là tệ hơn hẳn.

   Cách chữa thật, đơn giản hơn nhiều: canh theo mép TRÊN, rồi chừa sẵn cho khối nhãn đúng
   hai dòng chữ. Nhãn một dòng hay hai dòng thì ô nhập vẫn bắt đầu ở cùng một chỗ, còn
   dòng gợi ý nằm dưới ô nhập nên không đẩy được gì nữa. Đổi lại mất thêm chút chiều cao
   khi mọi nhãn đều một dòng, và đó là cái giá rẻ hơn nhiều so với một hàng lọc so le.
*/
.wv-loc {
    align-items: flex-start;
}

.wv-loc-o label,
.wv-loc-rong label {
    display: flex;
    align-items: flex-end;
    line-height: 1.35;
    min-height: 2.7em;
}

/*
   Ô đánh dấu và ô chọn tròn trong hàng lọc phải chiếm đúng chiều cao của một ô nhập.

   Bản thân cái dấu tích chỉ cao chừng một phần ba ô nhập, nên nếu để nó tự do thì nó nằm
   lửng ở giữa khoảng trống và mắt đọc ra là nó tụt xuống so với mấy ô bên cạnh. Đo được
   lệch mười hai điểm ảnh ở màn đơn hàng.

   Chừa đúng chiều cao ô nhập rồi dồn dấu tích lên đầu khoảng ấy, thế là hàng ngang của
   mọi thứ bấm được nằm thẳng nhau.
*/
/*
   Kèm theo, hai dòng font-weight và font-size ở đây là để LẤY LẠI đúng điều .wv-chon đã
   khai, chứ không phải một lựa chọn mới.

   .wv-loc-o label ngay trên kia nặng hai mảnh (một lớp cộng một thẻ) và khai 600 cộng
   12px, đó là kiểu của cái NHÃN đứng trên một ô nhập. .wv-chon chỉ nặng một mảnh và khai
   400 cộng 13px, đó là kiểu của dòng chữ đi kèm một dấu tích. Nhãn nặng hơn nên thắng, và
   mọi dấu tích trên hàng lọc đọc ra 600 cộng 12px, tức là trông như một cái nhãn chứ không
   như một lựa chọn. Đo được ngày 26 tháng 8 năm 2026: 29 lượt trên 17 màn, ví dụ ô "Chỉ
   khách còn nợ" của màn công nợ.

   Đây đúng sinh đôi của lỗi .wv-hang label đã chữa cùng ngày ở phần dưới tệp này, chỉ khác
   chỗ đứng. Chữa cùng một lối: bộ chọn ghép hai mảnh nên kết quả không phụ thuộc thứ tự nạp.
*/
/*
   Khung bọc dấu tích đứng TRONG một hàng lọc thì bỏ khoảng đệm trên dưới của chính nó.

   Luật ngay trên đã chừa đúng chiều cao một ô nhập cho mỗi nhãn có dấu tích, nên tâm của
   dấu tích thẳng với tâm ô ngày bên cạnh. Nhưng khi dãy dấu tích được bọc thêm một lớp
   .wv-o-chon, khoảng đệm mười điểm ảnh cộng viền của khung bọc đẩy cả dãy tụt xuống, và
   luật kia không với tới được vì nó chỉ nói về cái nhãn chứ không nói về cái khung.

   Đo được ngày 26 tháng 8 năm 2026, so theo TÂM đúng quy tắc 19: màn chuyến mở bán lệch
   10 điểm ảnh ở khổ 1440 và 11 ở khổ 768, màn giữ chỗ lệch 11, màn đại lý lệch 10. Mười
   bốn màn danh sách của các lượt trước đo ra 0 vì chúng không bọc thêm lớp nào.

   Chỉ bỏ khoảng đệm TRÊN DƯỚI, giữ nguyên khoảng đệm hai bên và viền, nên khung bọc vẫn
   là một cái hộp nhìn thấy được như ở biểu mẫu.
*/
.wv-loc-o > .wv-o-chon,
.wv-loc-rong > .wv-o-chon {
    padding-block: 0;
    align-content: center;
}

.wv-loc-o .wv-chon,
.wv-loc-rong .wv-chon,
.wv-loc-o .wv-nho,
.wv-loc-rong .wv-nho {
    display: flex;
    align-items: center;
    min-height: 2.25rem;
    margin: 0;
    font-weight: 400;
    font-size: var(--wv-cd-13);
}

/* Hai dấu tích xếp dọc trong cùng một ô thì chỉ ô đầu chừa chiều cao, ô sau bám sát. */
.wv-loc-o .wv-chon + .wv-chon,
.wv-loc-rong .wv-chon + .wv-chon,
.wv-loc-o .wv-nho + .wv-nho,
.wv-loc-rong .wv-nho + .wv-nho {
    min-height: 0;
}

/*
   Nhãn dài quá hai dòng thì cắt ở dòng thứ hai. Để nó xuống ba dòng là đúng cái so le vừa
   chữa xong, mà một cái nhãn dài tới ba dòng thì bản thân nó đã là dấu hiệu phải viết lại
   cho ngắn, chỗ giải thích dài là dòng gợi ý bên dưới chứ không phải cái nhãn.
*/
.wv-loc-o label > span,
.wv-loc-rong label > span,
.wv-loc-o label,
.wv-loc-rong label {
    overflow: hidden;
}

/* Cụm nút nằm đúng dòng của ô nhập, không trôi lên trên hàng nhãn. */
.wv-loc-nut {
    margin-top: calc(var(--wv-cd-12) * 2.7 + var(--wv-k1));
}

@media (max-width: 760px) {
    /* Màn hẹp mỗi ô một hàng nên không còn gì để canh, trả nhãn về chiều cao tự nhiên. */
    .wv-loc-o label,
    .wv-loc-rong label {
        min-height: 0;
    }

    .wv-loc-nut {
        margin-top: 0;
    }
}

/* ==================================================================
   13. Trạng thái rỗng
   ================================================================== */

/*
   Một cái bảng không có hàng nào mà cũng không có lời nào thì người dùng không phân
   biệt được ba chuyện khác hẳn nhau: chưa có dữ liệu, bộ lọc quá chặt, hay trang bị
   hỏng. Nên trạng thái rỗng luôn gồm ba phần: một hình, một câu nói rõ vì sao trống,
   và một lối đi tiếp.
*/
.wv-trong-ruong {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--wv-k2);
    padding: var(--wv-k10) var(--wv-k5);
    text-align: center;
    color: var(--wv-chu-mo);
}

.wv-trong-ruong .wv-bt {
    width: 2.75rem;
    height: 2.75rem;
    stroke-width: 1.2;
    color: var(--wv-xam-300);
    margin-bottom: var(--wv-k1);
}

.wv-trong-ruong h3 {
    margin: 0;
    font-family: var(--wv-phong);
    font-size: var(--wv-cd-15);
    font-weight: 600;
    color: var(--wv-xam-800);
}

.wv-trong-ruong p {
    margin: 0;
    max-width: 26rem;
    font-size: var(--wv-cd-13);
}

.wv-trong-ruong .wv-nut {
    margin-top: var(--wv-k2);
}

/* ==================================================================
   14. Khung chờ tải
   ================================================================== */

/*
   Vệt sáng chạy ngang trên nền xám. Dùng khi trang đã dựng xong bố cục nhưng số liệu
   chưa về, để bố cục không nhảy một cái khi số liệu về tới. Người tắt hiệu ứng chuyển
   động trong hệ điều hành thì chỉ thấy nền xám đứng yên, luật ấy nằm ở wvep-cogian.css.
*/
.wv-cho-tai {
    display: block;
    height: .875rem;
    border-radius: var(--wv-bo-1);
    background: linear-gradient(90deg,
        var(--wv-xam-100) 25%,
        var(--wv-xam-50) 37%,
        var(--wv-xam-100) 63%);
    background-size: 400% 100%;
    animation: wv-chay-cho 1.4s ease infinite;
}

.wv-cho-tai + .wv-cho-tai {
    margin-top: var(--wv-k2);
}

.wv-cho-tai-ngan { width: 40%; }
.wv-cho-tai-vua  { width: 70%; }
.wv-cho-tai-cao  { height: 2rem; }

@keyframes wv-chay-cho {
    0%   { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* ==================================================================
   15. Đầu màn và thanh công cụ
   ================================================================== */

.wv-dau-trang {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--wv-k4);
    margin-bottom: var(--wv-k4);
}

.wv-dau-nut {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k2);
}

.wv-tieu-de {
    margin: 0 0 var(--wv-k1);
    font-family: var(--wv-phong-tieu-de);
    font-size: var(--wv-cd-24);
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--wv-xam-900);
}

.wv-mo-ta {
    margin: 0;
    max-width: 52rem;
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
}

/* Thẻ chuyển khối trên biểu mẫu nhiều phần */

.wv-the-tab {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k1);
    margin-bottom: var(--wv-k4);
    border-bottom: 1px solid var(--wv-vien);
}

.wv-tab {
    border-radius: 4px 4px 0 0;
    display: inline-flex;
    align-items: center;
    gap: var(--wv-k2);
    padding: var(--wv-k2) var(--wv-k4);
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    color: var(--wv-chu-mo);
    font-family: inherit;
    font-size: var(--wv-cd-14);
    font-weight: 600;
    cursor: pointer;
    margin-bottom: -1px;
}

/* text-decoration ở đây là cho bản THẺ DẠNG ĐƯỜNG DẪN của màn địa lý: luật a:hover
   chung gạch chân mọi đường dẫn, mà một cái thẻ thì không gạch chân bao giờ. Bản thẻ
   dạng nút không đụng gì tới luật này. */
.wv-tab:hover {
    color: var(--wv-chinh-dam);
    text-decoration: none;
}

.wv-tab-dang-o {
    border-color: var(--wv-vien);
    margin-bottom: -1px;
    border-bottom-color: var(--wv-nhan);
    color: var(--wv-chinh-dam);
    background: transparent;
    padding-bottom: var(--wv-k2);
}

/* NỬA GIẤU của chính bộ thẻ ngay trên: khối nào không thuộc thẻ đang mở thì đeo lớp này.
   tour.js gắn và gỡ nó trên các khối .wv-khoi-tab của biểu mẫu tour.

   ĐÂY LÀ MỘT LỚP TIỆN ÍCH ĐỂ GIẤU, KHÔNG PHẢI MỘT KHUNG BỌC. Tên đọc ra là "khối ẩn",
   mà họ lớp wv-khoi-* bên cạnh nó thì toàn khung bọc thật, tức .wv-khoi-thuoc-tinh với
   .wv-khoi-dong, nên nó rất dễ bị đọc nhầm thành "một cái khối". Đã bị đọc nhầm thật:
   ngày 26 tháng 8 năm 2026 tìm ra năm chỗ trên bốn màn quản trị lấy nó làm khung bọc
   danh sách, và cả năm chỗ ấy trắng trơn. Không tích được vai trò cho một tài khoản mới,
   không phân quyền được cho một vai, không gán được chi nhánh phụ.

   Nó nằm ở ĐÂY, ngay dưới ba lớp của bộ thẻ, chứ không còn nằm rời một mình ở wvep.css.
   Đó chính là cách nó mất ngữ cảnh lần trước: đợt dọn trùng lớp dời .wv-tab với
   .wv-tab-dang-o sang tệp này mà bỏ nó lại, không một dòng chú thích nào, kẹt giữa hai
   mục không liên quan. Muốn dời tiếp thì dời cả cụm. */
.wv-khoi-an {
    display: none;
}

/* Khung cuộn ngang của bảng nhiều cột */

.wv-bang-cuon {
    overflow-x: auto;
    max-width: 100%;
    margin-bottom: var(--wv-k3);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    background: var(--wv-tam);
}

.wv-bang-cuon > .wv-bang {
    margin-bottom: 0;
}

/*
   Thanh cuộn của khung bảng để LỘ RA chứ không giấu đi. Đây là dấu hiệu duy nhất báo
   cho người dùng biết bên phải còn cột nữa; giấu nó đi thì người ta tưởng bảng hết ở
   đó và đi tìm cột Thao tác mãi không thấy.
*/
.wv-bang-cuon {
    scrollbar-width: thin;
    scrollbar-color: var(--wv-xam-300) var(--wv-xam-50);
}

.wv-bang-cuon::-webkit-scrollbar {
    height: 10px;
}

.wv-bang-cuon::-webkit-scrollbar-track {
    background: var(--wv-xam-50);
    border-top: 1px solid var(--wv-vien-nhat);
}

.wv-bang-cuon::-webkit-scrollbar-thumb {
    background: var(--wv-xam-300);
    border: 2px solid var(--wv-xam-50);
    border-radius: var(--wv-bo-tron);
}

.wv-bang-cuon::-webkit-scrollbar-thumb:hover {
    background: var(--wv-xam-400);
}

/* Thẻ đã bọc bảng rồi thì khung cuộn bên trong không cần viền và bo góc thêm lần nữa. */
.wv-the .wv-bang-cuon,
.wv-the-than .wv-bang-cuon {
    border: 0;
    border-radius: 0;
    margin-bottom: 0;
}

/* ==================================================================
   16. Vụn vặt dùng chung
   ================================================================== */

/*
   NHÃN CỦA MỘT Ô CHỈ ĐỌC, tức dòng chữ nhỏ in hoa đứng TRÊN một giá trị.

   Lớp này trước nằm ở wvep-giao-dien.css, và đó là một tấm CHỈ được nạp ở đúng một màn:
   Pages/HeThong/GiaoDien.cshtml, tức Thư viện giao diện. Mà thư viện giao diện đúng là
   chỗ người sau vào chép mẫu đem đi nơi khác, nên tên lớp đi khắp nơi còn tấm kiểu thì ở
   lại.

   Đo được ngày 26 tháng 8 năm 2026: 135 lượt viết .wv-nhan-o trên 17 tệp giao diện, trong
   đó chỉ 3 lượt nằm trong chính GiaoDien.cshtml. 132 lượt còn lại trên 16 tệp của nhóm
   điều hành và màn xác nhận dịch vụ chạy TRẦN, không một dòng kiểu dáng nào. Hậu quả không
   phải chuyện xấu đẹp: nhãn "Mã phiếu" đọc ra 14px, 400, màu chữ chính, còn giá trị ngay
   cạnh nó cũng 14px, 400, cùng màu chữ chính. Nhãn và giá trị không phân biệt được bằng
   mắt, tức là cái lớp mất sạch việc nó sinh ra để làm.

   Vì sao dời tấm khai chứ không đổi 132 chỗ dùng: đây là một lớp thành phần dùng chung
   thật, không phải một lớp riêng của trang thư viện. Chỗ đúng của nó là tấm thành phần
   được mọi màn nạp. Vẫn khai ở đúng MỘT tệp, quy tắc 11 giữ nguyên.

   Máy canh đi kèm nằm ở SoatLopKieuDangTests: phép soát nay hỏi thêm một câu mà trước đó
   nó không hỏi, là TRANG ẤY có nạp tấm khai lớp này không, chứ không chỉ hỏi có tấm nào
   khai không.
*/
.wv-nhan-o {
    display: block;
    margin-bottom: var(--wv-k1);
    font-size: var(--wv-cd-11);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--wv-chu-nhat);
}

.wv-luoi {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k5);
}

/*
   Nút dạng CHỮ, không có hộp: dùng cho mấy việc phụ nằm trong ô bảng, ví dụ Sửa hay
   Người dùng, chỗ mà năm cái nút có nền đặt cạnh nhau sẽ nặng mắt hơn chính dòng dữ liệu.

   PHẢI TỰ HỦY LUÔN CẢ TRẠNG THÁI RÊ CHUỘT của lớp nút nền.

   Thẻ mang cả hai lớp wv-nut và wv-nut-chu. Luật .wv-nut:hover là một lớp cộng một trạng
   thái nên nặng ký hơn .wv-nut trơn, vì vậy nó thắng dòng background none ở đây. Kết quả
   là rê chuột vào thì ô hiện ra một mảng xanh đậm, mà chữ vẫn giữ màu xanh đậm của
   .wv-nut-chu:hover, thành ra hai màu trùng nhau và chữ biến mất.

   Nên khối hover dưới đây phải khai lại đủ nền, viền và bóng, chứ không chỉ khai màu chữ.
*/
.wv-nut-chu {
    min-height: 0;
    padding: 0;
    border: none;
    background: none;
    box-shadow: none;
    color: var(--wv-chinh);
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
}

.wv-nut-chu:hover,
.wv-nut-chu:focus-visible,
.wv-nut-chu:active {
    background: none;
    border-color: transparent;
    box-shadow: none;
    color: var(--wv-chinh-dam);
    text-decoration: underline;
}

/*
   SỐ BẤM MỘT LẦN LÀ BÔI ĐEN TRỌN: mã số thuế, số tài khoản. Kế toán chép sang ủy nhiệm chi, chép thiếu một số
   là lệnh chuyển bị trả về (FIX PPM, 08/10/2026).
*/
.wv-chon-het {
    user-select: all;
    font-variant-numeric: tabular-nums;
}

.wv-phu {
    font-size: var(--wv-cd-12);
    color: var(--wv-chu-nhat);
}

.wv-cach {
    margin: 0 var(--wv-k1);
    color: var(--wv-xam-300);
}

.wv-hang-ngang {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--wv-k2);
    margin-bottom: var(--wv-k2);
}

.wv-cuoi-form {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k2);
    margin: var(--wv-k5) 0 var(--wv-k8);
}

/*
   CỤM MỘT Ô NHẬP CỘNG ĐÚNG MỘT NÚT QUYẾT, hai thứ phải đọc ra là đi với nhau.

   Chỗ dùng đầu tiên là ô Lý do từ chối cộng nút Từ chối đơn ở khối Xét duyệt của đơn nghỉ
   phép. Ràng buộc nghiệp vụ là lý do BẮT BUỘC, tầng dịch vụ chặn khi thiếu, nên cái nút
   không được đứng như một nút rời: người dùng phải nhìn ra là bấm nó tức là gửi đúng dòng
   chữ vừa gõ bên cạnh, chứ không phải từ chối trơn.

   VÌ SAO KHÔNG DÙNG ĐƯỢC .wv-luoi-nhap cho việc này. Lưới nhập chia ba cột đều nhau, nên
   ô lý do đeo .wv-rong-doi ăn hai cột còn cái nút rơi vào cột thứ ba, và nó hỏng KHÁC NHAU
   theo bề rộng. Ở khổ rộng, ô lưới của nút cao bằng cả hàng còn nút bắt đầu từ MÉP TRÊN,
   nên nút thẳng với cái NHÃN chứ không thẳng với ô nhập. Ở khổ vừa và khổ hẹp lưới rút còn
   hai cột rồi một cột, ô lý do chiếm trọn một hàng lưới và nút rơi hẳn xuống hàng lưới sau,
   cách ô nhập một khoảng bằng chiều cao nút cộng khoảng chừa dưới của .wv-hang.

   Đo được ngày 31 tháng 8 năm 2026, trên một trang thử nạp đúng bảy tấm kiểu dáng của
   _KhungDinh rồi ép bề rộng bằng Emulation.setDeviceMetricsOverride, so đáy nút với đáy ô
   nhập. Lối cũ: khổ 1440 nút nằm CAO HƠN đáy ô nhập 23 điểm ảnh; khổ 768 và khổ 390 nút
   không còn chung hàng với ô nhập nữa và đáy nút cách đáy ô 50 điểm ảnh. Lối mới: khổ 1440
   và khổ 768 chung hàng, lệch đáy 0, nút cách mép phải ô nhập đúng 8 điểm ảnh; khổ 390 nút
   xuống dòng nằm ngay dưới ô nhập, cách 8 điểm ảnh, cùng mép trái.

   Cụm này canh theo ĐÁY chứ không theo mép trên, đúng quy tắc 19 nói phép canh phải canh
   đúng cái mắt người thật sự nhìn: đáy ô nhập thẳng đáy nút thì hai thứ đọc ra là một dòng.
   Ô nhập co giãn ăn hết phần còn lại, nút giữ đúng bề rộng chữ của nó và đứng ngay sát ô,
   nên không còn khoảng trống nào chen vào giữa.

   Khổ hẹp thì ô nhập chiếm trọn một hàng và nút tụt xuống ngay dưới nó. Vẫn là một cụm,
   vì hai thứ vẫn nằm trong đúng một thẻ form và không có gì xen vào giữa.

   Không cần một dòng JavaScript nào: đây thuần là luật xếp chỗ, tắt JavaScript thì cụm
   vẫn xếp đúng và biểu mẫu vẫn gửi được theo lối cũ.
*/
.wv-cum-quyet {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--wv-k2);
    margin-bottom: var(--wv-k4);
}

/*
   Hàng nhập trong cụm bỏ khoảng chừa dưới của chính nó, không thì đáy hàng nằm thấp hơn
   đáy ô nhập đúng chừng ấy và phép canh theo đáy đẩy cái nút tụt xuống theo.

   Bề rộng nền 18rem là chỗ ngoặt: còn đủ chỗ thì ô nhập nằm cùng hàng với nút, hẹp hơn
   thì nó lấy trọn một hàng và nút xuống hàng dưới, chứ không bóp ô nhập lại thành một khe
   chỉ đọc được vài chữ.
*/
.wv-cum-quyet > .wv-hang {
    flex: 1 1 min(18rem, 100%);
    min-width: 0;
    margin-bottom: 0;
}

/* Chỉ máy đọc màn hình đọc được, mắt không thấy. Dùng cho lời đọc của những chỗ mà
   trên màn hình đã rõ nghĩa nhờ vị trí hoặc hình vẽ. */
.wv-chi-doc {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}


/* ==================================================================
   Chữ chỉ dành cho bộ đọc màn hình.

   Nút chỉ có biểu tượng thì người nhìn thấy hiểu ngay, còn người dùng bộ đọc màn hình
   nghe được đúng một chữ nut. Nên mỗi nút biểu tượng kèm một nhãn chữ mang lớp này:
   mắt không thấy, bộ đọc vẫn đọc. KHÔNG dùng display none hay visibility hidden, vì hai
   thứ đó giấu luôn khỏi bộ đọc.

   TUYỆT ĐỐI KHÔNG DÙNG position absolute Ở ĐÂY, dù đó là lối viết quen thuộc nhất cho
   lớp này. Đã đo trên máy thật: nhãn nằm trong bảng chiết tính, mà bảng ấy nằm trong một
   khối cuộn ngang. Một hộp absolute không có tổ tiên nào được định vị thì khối chứa nó
   là khung nhìn chứ không phải khối cuộn, nên nó THOÁT ra khỏi khối cuộn và đẩy cả trang
   trôi ngang 127 điểm ảnh ở bề rộng 1440. Đúng lỗi trang trôi ngang đã bị chê.

   Cách ở đây giữ nhãn NẰM TRONG dòng chảy, chiếm đúng một điểm ảnh và bị cắt sạch, nên
   nó không bao giờ thoát khỏi khối cuộn nào.
   ================================================================== */

.wv-an-chu {
    display: inline-block;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    border: 0;
    clip-path: inset(50%);
    white-space: nowrap;
    vertical-align: middle;
}

/* ------------------------------------------------------------------
   Ô chọn ngày giờ

   Trình duyệt đối xử với ô ngày khác hẳn ô chữ, nên dùng chung một lớp là chưa đủ.
   Hai chuyện phải chữa:

   Một, ô ngày tự đặt cho mình một chiều rộng tối thiểu tính theo chuỗi ngày dài nhất
   mà nó dựng được. Chiều rộng ấy thắng cả width 100 phần trăm, nên trong khung hẹp
   thì ô đội ra ngoài và đè lên mép thẻ. Đặt min-width về 0 để nó chịu co lại.

   Hai, phần hiển thị giá trị bên trong ô bị căn giữa, nên ngày nằm lửng lơ ở giữa ô
   trong khi mọi ô nhập khác đều căn trái. Kéo nó về căn trái cho thẳng hàng.

   Luật đặt theo KIỂU Ô chứ không theo lớp, để mọi ô ngày trong hệ thống đều nhận,
   kể cả ô nào sau này ai đó thêm mà quên gắn lớp dùng chung.
   ------------------------------------------------------------------ */

input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="time"] {
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
    text-align: left;
}

input[type="date"]::-webkit-date-and-time-value,
input[type="datetime-local"]::-webkit-date-and-time-value,
input[type="month"]::-webkit-date-and-time-value,
input[type="week"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value {
    text-align: left;
}

/* Khối sửa giá trị bên trong cũng phải chịu co, nếu không nó lại đẩy ô rộng ra. */
input[type="date"]::-webkit-datetime-edit,
input[type="datetime-local"]::-webkit-datetime-edit {
    padding: 0;
    min-width: 0;
}

/* Nút lịch nằm sát mép phải, không chiếm chỗ của chữ. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
    margin-left: auto;
    padding-left: var(--wv-k2);
    cursor: pointer;
}

/*
   CHỐT ĐỘ NẶNG cho nút dạng chữ, để kết quả không phụ thuộc thứ tự nạp tệp.

   Lớp .wv-nut và lớp .wv-nut-chu cùng nặng một lớp, nên cái nào khai SAU thì thắng. Mà cả
   hai đang được khai ở CẢ HAI tệp wvep.css và wvep-thanh-phan.css, nên chỉ cần đảo thứ tự
   hai thẻ nạp, hoặc trình duyệt giữ lại một tệp cũ một tệp mới, là nút chữ biến thành một
   khối đặc màu xanh đậm mang chữ cũng màu xanh đậm, tức là một mảng tối không đọc được.

   Viết hai lớp liền nhau thì độ nặng thành hai, luôn thắng .wv-nut một lớp, bất kể thứ tự.
   Đây là cái nêm chặn tạm cho tới khi dọn xong chuyện một lớp khai ở hai tệp.
*/
.wv-nut.wv-nut-chu {
    min-height: 0;
    padding: 0;
    border: none;
    background: none;
    box-shadow: none;
    color: var(--wv-chinh);
}

/*
   Hai nút chữ đứng cạnh nhau phải có khoảng thở.

   Bỏ hết phần đệm của nút nền xong thì hai chữ dính sát nhau, đọc ra thành một cụm
   "Người dùngSửa". Trước đây phần đệm của nút nền che mất chuyện này, nên nó chỉ lộ ra
   sau khi phần đệm bị gỡ.

   Dùng khoảng cách bên trái chứ không dùng khoảng cách hai bên, để nút đầu tiên vẫn
   thẳng hàng với mép ô bảng.
*/
.wv-nut.wv-nut-chu + .wv-nut.wv-nut-chu,
.wv-nut.wv-nut-chu + form,
form + .wv-nut.wv-nut-chu {
    margin-left: var(--wv-k3);
}

.wv-nut.wv-nut-chu:hover,
.wv-nut.wv-nut-chu:focus-visible,
.wv-nut.wv-nut-chu:active {
    background: none;
    border-color: transparent;
    box-shadow: none;
    color: var(--wv-chinh-dam);
    text-decoration: underline;
}


/* ==================================================================
   17. Vòng chờ mang logo và vùng tải ngầm
   ================================================================== */

/*
   VÒNG CHỜ CỦA WVEP: logo công ty đứng yên ở giữa, một cung tròn màu nhấn chạy quanh.

   Hình logo lấy thẳng tệp đã có trong wwwroot/img, không vẽ lại bằng SVG và không tải
   phông biểu tượng nào từ mạng. Đổi nhận diện lần sau chỉ phải thay đúng tệp ảnh ấy.

   HAI CỠ, và chúng khác nhau về VIỆC chứ không chỉ về số đo:
     cỡ nhỏ  nằm đè lên bảng khi người dùng chỉ lọc lại, phần khung quanh bảng giữ nguyên
     cỡ lớn  phủ cả vùng nội dung khi cả màn đang được thay, người dùng mất chỗ bám mắt

   Chọn nhầm cỡ thì người dùng hiểu nhầm phạm vi thứ đang đổi: cỡ lớn cho một lượt lọc
   làm người ta tưởng cả màn đang dựng lại và ngồi chờ lâu hơn thực tế.
*/

.wv-vong-cho {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--wv-k2);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
    text-align: center;
}

.wv-vong-cho-hinh {
    position: relative;
    display: block;
    width: 2.75rem;
    height: 2.75rem;
}

.wv-vong-cho-vong {
    display: block;
    width: 100%;
    height: 100%;
    animation: wv-quay-vong 1.1s linear infinite;
}

.wv-vong-cho-vong circle {
    fill: none;
    stroke-width: 3.2;
}

.wv-vong-cho-day {
    stroke: var(--wv-chinh-vien);
}

/*
   Cung chạy dài đúng một phần tư vòng. Chu vi của đường tròn bán kính 21 là 131,9 nên
   nét 33 và quãng trống 99 chia ra vừa khít; đổi bán kính trong tệp giao diện mà quên
   đổi hai số này thì cung bị đứt quãng.
*/
.wv-vong-cho-cung {
    stroke: var(--wv-nhan);
    stroke-linecap: round;
    stroke-dasharray: 33 99;
}

.wv-vong-cho-logo {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 56%;
    height: 56%;
    transform: translate(-50%, -50%);
    object-fit: contain;
}

.wv-vong-cho-loi {
    max-width: 18rem;
}

.wv-vong-cho.wv-vong-cho-lon {
    gap: var(--wv-k3);
    font-size: var(--wv-cd-15);
}

.wv-vong-cho.wv-vong-cho-lon .wv-vong-cho-hinh {
    width: 5.5rem;
    height: 5.5rem;
}

@keyframes wv-quay-vong {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/*
   Người đã đặt máy giảm chuyển động thì KHÔNG quay nữa, đổi sang nhịp mờ tỏ. Vòng quay
   liên tục là đúng loại chuyển động gây chóng mặt cho người nhạy cảm với tiền đình, mà
   dấu hiệu cần truyền đạt chỉ là "máy đang làm", nhịp mờ tỏ nói được đúng chừng ấy.
*/
@media (prefers-reduced-motion: reduce) {
    .wv-vong-cho-vong {
        animation: wv-tho-vong 1.6s ease-in-out infinite;
    }
}

@keyframes wv-tho-vong {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
}

/*
   VÙNG TẢI NGẦM: khối mà máy chủ thay ruột, phần còn lại của màn đứng yên.

   Phải có position relative vì tấm phủ vòng chờ neo vào chính nó. Thiếu dòng này thì
   tấm phủ leo lên khối cha gần nhất có neo, thường là cả thân trang, và vòng chờ hiện
   ra giữa màn hình thay vì nằm trên bảng.
*/
.wv-vung-ngam {
    position: relative;
}

.wv-lop-cho {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: var(--wv-k8) var(--wv-k4);

    /* Đủ đục để chữ của vòng chờ đọc được, đủ trong để người dùng vẫn thấy mình đang
       đứng ở bảng nào. Đã đo ở khổ điện thoại: dưới mức này thì tiêu đề cột hiện xuyên
       qua đúng chỗ đặt câu chữ và hai lớp chữ chồng lên nhau. */
    background: rgba(255, 255, 255, .88);
}

/*
   Bảng dài hơn một màn hình thì tấm phủ cũng dài theo, và vòng chờ neo ở đỉnh tấm phủ
   sẽ nằm ngoài tầm mắt của người đang cuộn ở giữa bảng. Dán dính vào đỉnh khung nhìn
   thì cuộn tới đâu vòng chờ theo tới đó, vẫn nằm trong phạm vi vùng đang tải.
*/
.wv-lop-cho .wv-vong-cho {
    position: sticky;
    top: var(--wv-k8);
}

.wv-lop-cho.wv-lop-cho-lon {
    align-items: center;
    padding: var(--wv-k4);
}

.wv-lop-cho.wv-lop-cho-lon .wv-vong-cho {
    position: static;
}

/*
   Máy chủ trả lỗi hay mạng đứt thì nói ra ngay tại chỗ bảng, kèm nút thử lại. Bảng cũ
   được GIỮ NGUYÊN bên dưới chứ không xóa đi: xóa đi là người dùng mất luôn số liệu họ
   đang đọc dở, mà lần hỏi hỏng không hề chứng minh số liệu cũ đã sai.
*/
.wv-loi-tai {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k3);
    padding: var(--wv-k3) var(--wv-k4);
    border: 1px solid var(--wv-xau-vien);
    border-radius: var(--wv-bo-2);
    background: var(--wv-xau-nen);
    color: var(--wv-xau-chu);
}

.wv-loi-tai-loi {
    flex: 1 1 16rem;
    margin: 0;
}

/*
   ==========================================================================
   18. Ô CHỌN GÕ ĐƯỢC
   ==========================================================================

   Toàn bộ phần này do wv-o-chon-go.js dựng ra chứ không có trong tệp giao diện nào, nên
   máy không chạy được JavaScript thì luật dưới đây không áp lên phần tử nào cả và ô chọn
   hiện nguyên như thường.

   MỘT Ô CHỨ KHÔNG PHẢI HAI. Bản trước có thêm một ô gõ riêng đứng trên ô chọn, người dùng
   phải gõ ở ô này rồi bấm sang ô kia. Nay gõ và chọn cùng một chỗ.
*/

.wv-chon-go {
    position: relative;
    min-width: 0;
}

/*
   Thẻ select thật vẫn nằm trong trang và vẫn mang dữ liệu đi, chỉ là không còn phải nhìn
   thấy. Ẩn bằng cách thu về một điểm ảnh chứ KHÔNG dùng display none: mã của nhiều màn
   đọc select[name] để nhân bản dòng, và một thẻ đã bị gỡ khỏi luồng dựng hình vẫn phải
   trả lời được những câu hỏi ấy.
*/
/*
   Khai kèm tên thẻ để nặng hơn .wv-o-nhap. Thiếu chữ select ở đầu thì hai luật cùng một
   lớp và thứ tự nạp quyết định ai thắng: đo ngày 15 tháng 9 năm 2026, thẻ select ẩn vẫn
   rộng 43 điểm ảnh và thò ra ngoài mép phải ở khổ 390, kéo cả trang trôi ngang.

   Ghim vào góc trên trái của ô bọc, và chặn bề rộng ở cả hai đầu: clip-path chỉ cắt phần
   VẼ ra, nó không hề làm phần tử chiếm ít chỗ đi.
*/
select.wv-chon-go-an {
    position: absolute;
    left: 0;
    top: 0;
    width: 1px;
    min-width: 0;
    max-width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

.wv-chon-go-nhap {
    width: 100%;
    min-width: 0;
}

/*
   Danh sách bung ra GẮN THẲNG VÀO THÂN TRANG, neo theo toạ độ màn hình. Nằm trong ô thì
   nó bị khối cuộn của bảng cắt mất nửa dưới, mà bảng chiết tính thì khối nào cũng cuộn.
*/
.wv-chon-go-ds {
    position: fixed;
    z-index: 900;
    margin: 0;
    padding: var(--wv-k1) 0;
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-2);
    box-shadow: var(--wv-bong-2);
    list-style: none;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.wv-chon-go-muc {
    padding: var(--wv-k2) var(--wv-k3);
    color: var(--wv-chu);
    font-size: var(--wv-cd-14);
    cursor: pointer;
    overflow-wrap: anywhere;
}

.wv-chon-go-muc:hover {
    background: var(--wv-xam-100);
}

/*
   Mục đang được bàn phím trỏ tới. Tô bằng nền chính nhạt chứ không bằng viền, vì viền làm
   dòng nhích đi một điểm ảnh mỗi lần mũi tên chạy qua và cả danh sách trông như rung.
*/
.wv-chon-go-sang {
    background: var(--wv-chinh-nen);
    color: var(--wv-chinh-dam);
    font-weight: 600;
}

.wv-chon-go-trong {
    padding: var(--wv-k2) var(--wv-k3);
    color: var(--wv-chu-nhat);
    font-size: var(--wv-cd-13);
    font-style: italic;
}

/*
   MÃ ĐI KÈM TÊN, cho ô khai data-wv-go-ma (ô Đối tác của bảng chi eTour, 9 tháng 10 năm 2026).

   Mã của mục đang chọn nằm dưới ô, cùng cỡ chữ và màu mờ với ô Loại phí nằm dưới ô Tên chiết
   tính, để hai ô đứng cạnh nhau đọc thành một hàng. Dòng bảng chi vốn đã cao hai tầng vì ô Tên
   kèm ô Loại phí, nên dòng mã nằm gọn trong chiều cao sẵn có: không thêm cột, không nới cột.

   Không khai display ở đây: dòng mã rỗng được giấu bằng thuộc tính hidden, và một luật display
   của tệp này sẽ đè mất nó.
*/
.wv-chon-go-ma-chon {
    margin-top: var(--wv-k1);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    user-select: all;
}

/*
   Mã BẤM ĐƯỢC của ô khai data-wv-go-ma-xem (13 tháng 10 năm 2026): nút mở thẻ thông tin nhà cung cấp,
   trông như một đường dẫn. Gỡ khung, nền và lề của nút; màu đường dẫn và gạch chân chấm cho mắt biết
   bấm được. Bỏ user-select: all của dòng mã, kẻo cú bấm thành cú bôi đen.
*/
.wv-chon-go-ma-xem {
    max-width: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--wv-chinh);
    font: inherit;
    letter-spacing: inherit;
    text-decoration: underline dotted;
    text-underline-offset: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
    user-select: text;
}

.wv-chon-go-ma-xem:hover {
    color: var(--wv-chinh-dam);
    text-decoration-style: solid;
}

.wv-chon-go-co-ma {
    display: flex;
    align-items: baseline;
    gap: var(--wv-k2);
}

.wv-chon-go-ten {
    flex: 1 1 auto;
    min-width: 0;
}

.wv-chon-go-ma {
    flex: none;
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Dòng đang sáng đổi màu chữ, mã đi theo cho khỏi lạc màu trên nền chính nhạt. */
.wv-chon-go-sang .wv-chon-go-ma {
    color: inherit;
    opacity: .75;
}

/* ==================================================================
   ẢNH ĐẠI DIỆN
   ==================================================================

   Ba chỗ dùng: khối tự đổi ảnh, danh sách tài khoản, và vòng tròn trên thanh ngang.
   Vòng tròn trên thanh ngang khai riêng ở wvep-cong.css vì nó thuộc khung cửa, nên ở
   đây chỉ thêm đúng một luật cho trường hợp vòng tròn ấy MANG ẢNH thay vì mang chữ.

   Mọi lớp dưới đây khai đúng một lần, ở đúng tệp này. Khai lại ở tệp khác là hai bên
   cùng độ nặng và kết quả tùy thứ tự nạp, đúng lỗi quy tắc 11 và 30 nói tới.
*/

.wv-anh-khoi {
    display: flex;
    align-items: flex-start;
    gap: var(--wv-k4);
    flex-wrap: wrap;
}

.wv-anh-xem {
    flex: 0 0 auto;
}

/* Phần việc co được, phần ảnh thì không: ảnh co lại là mất luôn cái nó dùng để nói. */
.wv-anh-viec {
    flex: 1 1 18rem;
    min-width: 0;
}

/* Ảnh tròn. Khai cả bề ngang lẫn chiều cao rồi cắt theo phần giữa, nên ảnh nào cũng ra
   đúng một hình tròn dù người dùng đưa lên tấm dọc hay tấm ngang. */
.wv-anh-tron {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 6rem;
    height: 6rem;
    border-radius: 50%;
    object-fit: cover;
    background: var(--wv-xam-100);
    border: 1px solid var(--wv-vien);
}

.wv-anh-tron-nho {
    width: 2.5rem;
    height: 2.5rem;
}

/* Chưa có ảnh thì vòng tròn mang chữ cái đầu của tên. Không để trống, vì một ô trống
   giữa bảng làm cả hàng so le và trông như trang đang hỏng. */
.wv-anh-tron-trong {
    background: var(--wv-chinh);
    color: #ffffff;
    font-weight: 700;
    letter-spacing: .02em;
    border-color: transparent;
}

.wv-anh-tron-nho.wv-anh-tron-trong {
    font-size: var(--wv-cd-12);
}

/* Cột ảnh trong danh sách tài khoản. Trên điện thoại bảng đổi sang lối xếp chồng, lúc
   ấy ô ảnh không cần nhãn dẫn ở mép trái nên bỏ khoảng đệm đi cho gọn. */
.nd-c-anh {
    width: 4rem;
    text-align: center;
}

/* Vòng tròn tài khoản trên thanh ngang khi nó mang ẢNH. Nền và màu chữ của bản mang chữ
   cái đầu phải bỏ đi, kẻo nền xanh hằn thành một vành quanh tấm ảnh. */
.wv-anh-nguoi-co {
    padding: 0;
    background: transparent;
    object-fit: cover;
}

/* Hai thẻ đứng cạnh nhau, dời từ wvep-giao-dien.css sang ở lượt 9.
   Đặt ở tấm này vì đây là tấm MỌI màn đều nạp: tấm cũ chỉ nạp ở hai màn Thư viện giao diện,
   nên bốn màn khác viết lớp này đang chạy không có một dòng kiểu dáng nào. */

.wv-luoi-doi {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--wv-k5);
    align-items: start;
}

.wv-luoi-doi > .wv-the {
    margin-bottom: 0;
}

/* ==================================================================
   KHỐI BẤM RỒI MỚI HIỆN CHỖ NHẬP

   VÌ SAO CẦN LỚP MỚI. Cột Thao tác của hàng đợi duyệt nghỉ phép bày SẴN một ô nhập lý
   do cho mọi dòng đang chờ duyệt. Một trang hai mươi đơn là hai mươi ô nhập mở cùng
   lúc, trong khi người dùng chỉ từ chối đúng một đơn: cột phình ra, mấy nút thật thì
   lẫn giữa một rừng ô trống, và mắt không nhặt được cái nào là cái cần bấm.

   VÌ SAO DỰNG BẰNG THẺ details CHỨ KHÔNG GIẤU BẰNG MÃ CHẠY TRÊN TRÌNH DUYỆT. Nền phải
   chạy được khi tắt JavaScript, đó là luật xuyên suốt dự án. Giấu bằng mã thì tắt
   JavaScript đi là ô hiện sẵn nguyên như cũ, tức chỉ gọn cho một nửa người dùng, mà
   nửa còn lại không hề biết mình đang xem một bản khác. Thẻ details là của chính HTML,
   trình duyệt tự đóng mở, không phụ thuộc một dòng mã nào.

   Lớp này viết chung chứ không gắn riêng cho màn nghỉ phép, vì hình dạng "một nút thao
   tác đòi thêm một dòng chữ mới bấm được" còn ở nhiều chỗ khác của hệ thống.
   ================================================================== */

/*
   Bỏ hình tam giác mặc định của thẻ tóm tắt. Mỗi trình duyệt vẽ một kiểu và không kiểu
   nào ăn nhập với mấy nút chữ đứng cạnh nó trong cùng một ô bảng. Chữ trên nút đã nói
   đủ việc nó làm, nên bỏ hẳn hình vẽ thay vì đi chỉnh cho ba trình duyệt giống nhau.

   Khai cả hai lối: list-style cho trình duyệt đời mới, và bộ chọn giả riêng của WebKit
   cho Safari đời cũ, chỗ mà thẻ tóm tắt chưa nhận list-style.
*/
.wv-mo-nhap > summary {
    list-style: none;
}

.wv-mo-nhap > summary::-webkit-details-marker {
    display: none;
}

/*
   Chỗ nhập chỉ có mặt khi khối đã mở, nên nó được phép chiếm trọn bề ngang của ô.

   Ô nhập đứng riêng một hàng và nút gửi rơi xuống hàng dưới: cột Thao tác của bảng chỉ
   rộng chừng hai trăm sáu mươi điểm ảnh, nhét ô nhập cùng nút vào một hàng thì ô nhập
   co lại còn đủ đọc vài chữ, mà lý do từ chối là câu người xin nghỉ sẽ đọc để biết phải
   sửa gì.

   Khai margin đủ bốn phía chứ không chỉ khai phía trên: thẻ form mang sẵn một khoảng
   đệm chân của tấm kiểu trình duyệt, để nguyên là mỗi lượt mở lại đội thêm một khoảng
   trắng thừa dưới nút gửi.
*/
.wv-mo-nhap > form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2);
    margin: var(--wv-k2) 0 0;
}

.wv-mo-nhap > form > .wv-o-nhap {
    flex: 1 1 100%;
    min-width: 0;
}


/* ==================================================================
   BỐN LỚP DÙNG CHUNG, thêm ngày 7 tháng 9 năm 2026 cùng màn Tuyến và địa danh.

   Khai ở tấm THÀNH PHẦN chứ không ở tấm riêng của màn, vì cả bốn đều là thứ mọi màn danh
   mục sẽ cần: một tiêu đề cấp ba, một khoảng cách trên, một dòng đang chọn, và một khối
   nhập mở ra khi bấm Thêm. Để ở tấm riêng thì màn thứ hai cần tới lại phải chép.
   ================================================================== */

/* Tiêu đề cấp ba, nhỏ hơn tiêu đề thẻ. Dùng để chia nhóm bên trong một thẻ, ví dụ tên từng
   điểm đến trong danh sách địa danh của một tuyến. */
.wv-tieu-de-nho {
    margin: var(--wv-k3) 0 var(--wv-k1);
    font-size: 1rem;
    font-weight: 600;
    color: var(--wv-chinh-dam);
}

.wv-tieu-de-nho:first-child {
    margin-top: 0;
}

/* Khoảng cách trên, dùng cho hàng nút đứng sau một khối nhập. */
.wv-cach-tren {
    margin-top: var(--wv-k2);
}

/* Dòng đang được chọn trong một bảng nhiều cấp. Nền nhạt chứ không đổi màu chữ: bảng này có
   cột số, mà đổi màu chữ số thì người đọc tưởng con số ấy mang nghĩa khác. */
.wv-dong-dang-chon > td {
    background: var(--wv-chinh-nen);
}

/* Khối nhập mở ra khi bấm nút Thêm. Có vạch trên để tách khỏi phần danh sách bên trên, vì
   hai phần ấy nằm chung một thẻ. */
.wv-khoi-them {
    margin-top: var(--wv-k3);
    padding-top: var(--wv-k3);
    border-top: 1px solid var(--wv-vien-nhat);
}


/* ---------- Khối chỉ số đầu màn, 11 tháng 9 năm 2026 ---------- */

/*
   Mấy con số tóm tắt đặt ngay trên bộ lọc, để người mở màn biết tình hình trước khi phải
   gõ gì. Khai ở TẤM THÀNH PHẦN DÙNG CHUNG chứ không ở tấm riêng của một cụm màn, vì đây
   là hình dạng mọi màn danh sách sẽ dùng lại.

   Ô BẤM ĐƯỢC và ô chỉ để đọc trông GIỐNG NHAU, cố ý: thứ phân biệt chúng là con trỏ chuột
   và vòng sáng lúc nhận bàn phím, chứ không phải màu chữ. Tô màu khác cho ô bấm được thì
   màu ấy tranh chỗ với hai màu THẬT SỰ mang tin là màu nhắc và màu xấu bên dưới.
*/
.wv-chi-so {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k4);
}

.wv-chi-so-o {
    display: flex;
    flex: 1 1 10rem;
    flex-direction: column;
    gap: var(--wv-k1);
    padding: var(--wv-k3);
    border: 1px solid var(--wv-vien-nhat);
    border-radius: var(--wv-bo-2);
    background: var(--wv-nen);
    color: inherit;
    text-decoration: none;
}

a.wv-chi-so-o:hover,
a.wv-chi-so-o:focus-visible {
    border-color: var(--wv-chinh-vien);
}

.wv-chi-so-nhan {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
}

.wv-chi-so-gia-tri {
    font-size: var(--wv-cd-24);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    line-height: 1.1;
}

/* Ô NHẮC là việc còn phải làm, ô XẤU là việc đã trễ. Hai màu khác nhau vì hai mức khẩn
   khác nhau, và chỉ tô khi con số KHÁC KHÔNG: một ô số không mà vẫn đỏ thì người đọc học
   được rằng màu ở đây không mang tin gì. */
.wv-chi-so-nhac {
    border-color: var(--wv-nhac-vien);
    background: var(--wv-nhac-nen);
}

.wv-chi-so-nhac .wv-chi-so-gia-tri {
    color: var(--wv-nhac-chu);
}

.wv-chi-so-xau {
    border-color: var(--wv-xau-vien);
    background: var(--wv-xau-nen);
}

.wv-chi-so-xau .wv-chi-so-gia-tri {
    color: var(--wv-xau-chu);
}


/* ---------- Hai lớp chữ dùng chung, 11 tháng 9 năm 2026 ---------- */

/*
   Giữ nguyên chỗ xuống dòng người dùng đã gõ. Một ô nội dung dài gõ thành mấy đoạn mà bày
   ra dính liền một khối thì người đọc mất hết cấu trúc mà người viết đã đặt vào.
*/
.wv-giu-dong {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Chữ mang tin XẤU: hạn đã trôi qua, số tiền vượt dự trù. Chỉ là màu chữ, không đổi nền,
   để nó dùng được ngay trong một ô bảng mà không phá nhịp của cả hàng. */
.wv-chu-xau {
    color: var(--wv-xau-chu);
}


/* ---------- Thẻ nhân sự và trang hồ sơ một người, 11 tháng 9 năm 2026 ---------- */

/*
   Lưới thẻ tự xếp theo bề rộng còn lại. Sàn 12rem là chỗ vừa đủ cho một họ tên đầy đủ
   tiếng Việt xuống tối đa hai dòng; hẹp hơn thì tên ba bốn chữ vỡ thành ba dòng và cả
   hàng thẻ so le nhau.
*/
.ns-luoi-the {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
    gap: var(--wv-k3);
}

.ns-the-mot {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--wv-k1);
    padding: var(--wv-k3);
    border: 1px solid var(--wv-vien-nhat);
    border-radius: var(--wv-bo-2);
    background: var(--wv-nen);
    color: inherit;
    text-align: center;
    text-decoration: none;
}

.ns-the-mot:hover,
.ns-the-mot:focus-visible {
    border-color: var(--wv-chinh-vien);
}

/* Người đã nghỉ mờ đi chứ KHÔNG ẩn: hồ sơ của họ vẫn phải tra ra được cho bảng lương và
   hợp đồng của các kỳ cũ. Mờ là đủ để mắt bỏ qua khi lướt tìm người đang làm. */
.ns-the-nghi {
    opacity: 0.65;
}

.ns-the-anh,
.ns-anh-lon,
.ns-anh-xem {
    display: block;
    border-radius: 50%;
    object-fit: cover;
    background: var(--wv-nen-mo);
}

.ns-the-anh {
    width: 5.5rem;
    height: 5.5rem;
}

/* Ô thay ảnh khi chưa có ảnh: chữ cái đầu của họ tên. Để trống thì hàng thẻ so le nhau vì
   mỗi ô cao một kiểu, mà so le thì mắt phải dò lại từ đầu mỗi hàng. */
.ns-the-anh-trong,
.ns-anh-lon-trong,
.ns-anh-xem-trong {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--wv-chu-mo);
    font-weight: 600;
}

.ns-the-anh-trong {
    font-size: var(--wv-cd-24);
}

.ns-the-ten {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.ns-the-ma {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    font-variant-numeric: tabular-nums;
}

.ns-the-dong {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
}

.ns-the-hd {
    color: var(--wv-chu);
}

/* Thiếu hợp đồng nói bằng màu NHẮC chứ không màu lỗi: đó là việc còn phải làm của phòng
   nhân sự, không phải một lỗi của phần mềm. */
.ns-the-thieu {
    color: var(--wv-nhac-chu);
}

.ns-the-moc {
    margin-top: var(--wv-k1);
    padding: 0 var(--wv-k2);
    border-radius: var(--wv-bo-1);
    font-size: var(--wv-cd-11);
    line-height: 1.6;
}

.ns-the-moc-lam {
    background: var(--wv-tot-nen);
    color: var(--wv-tot-chu);
}

.ns-the-moc-nghi {
    background: var(--wv-nen-mo);
    color: var(--wv-chu-mo);
}

/* ----- Trang hồ sơ một người ----- */

/*
   Ảnh bên trái, thông tin bên phải. Dưới 900 thì xếp chồng, vì hai cột trên màn điện thoại
   làm cột thông tin hẹp tới mức mỗi nhãn xuống hai dòng.
*/
.ns-ho-so {
    display: grid;
    grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
    gap: var(--wv-k3);
    align-items: start;
}

@media (max-width: 899.98px) {
    .ns-ho-so {
        grid-template-columns: minmax(0, 1fr);
    }
}

.ns-ho-so-phai {
    display: flex;
    flex-direction: column;
    gap: var(--wv-k3);
    min-width: 0;
}

.ns-the-anh-lon .wv-the-than {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--wv-k1);
    text-align: center;
}

.ns-anh-lon {
    width: 11rem;
    height: 11rem;
}

.ns-anh-lon-trong {
    font-size: 3.5rem;
}

.ns-anh-ten {
    margin: var(--wv-k2) 0 0;
    font-weight: 600;
}

.ns-anh-phu {
    margin: 0;
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
}

/* Khối tải ảnh trên biểu mẫu: ảnh đang dùng đứng cạnh ô chọn tệp, để người sửa thấy ngay
   mình đang thay tấm nào. */
.ns-anh-sua {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k3);
}

.ns-anh-xem {
    width: 7rem;
    height: 7rem;
    font-size: var(--wv-cd-24);
}

.ns-anh-sua .wv-hang {
    flex: 1 1 18rem;
    min-width: 0;
}

/* ------------------------------------------------------------------
   Trình soạn thư trực quan, cụm gửi thư GT-01.

   Ba lớp, và chỉ ba: thanh nút, ô gõ, khung xem trước. Cả ba dùng lại
   biến màu và biến khoảng cách đã có, không đẻ thêm bảng màu riêng.
   ------------------------------------------------------------------ */

.wv-thanh-soan {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
    margin-bottom: 0.5rem;
}

/* Ô gõ contenteditable. Cao tối thiểu chứ không cố định: lá thư ngắn thì
   ô ngắn theo, lá thư dài thì ô giãn ra và không đẻ thanh cuộn thứ hai. */
.wv-o-soan {
    min-height: 16rem;
    max-height: 32rem;
    overflow-y: auto;
    padding: 0.75rem 0.85rem;
    line-height: 1.6;
    text-align: left;
    cursor: text;
}

.wv-o-soan:focus {
    outline: 2px solid var(--wv-chinh, #1d6fb8);
    outline-offset: 1px;
}

.wv-o-soan h2 {
    margin: 0.6rem 0 0.35rem;
    font-size: 1.15rem;
}

.wv-o-soan p {
    margin: 0 0 0.6rem;
}

.wv-o-soan img {
    max-width: 100%;
    height: auto;
}

/* Khung xem trước. Viền và nền riêng để người dùng thấy rõ đây là thứ
   khách sẽ thấy, không phải một ô nữa để gõ vào. */
.wv-khung-xem-thu {
    display: block;
    width: 100%;
    min-height: 26rem;
    border: 1px solid var(--wv-vien, #d5dae0);
    border-radius: 0.4rem;
    background: #fff;
}

/* Hai cột trên màn rộng, một cột khi hẹp. Ngưỡng 1100 chứ không 768:
   soạn thư cạnh khung xem trước cần bề ngang thật, dưới ngưỡng ấy thì
   hai cột đều hẹp tới mức không cột nào dùng được. */
.wv-luoi-soan {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

@media (min-width: 1100px) {
    .wv-luoi-soan {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

/* Khối hẹn giờ gửi, đứng ngay dưới nút gửi ngay. Xếp ngang trên màn
   rộng để nhãn, ô ngày giờ và nút nằm cùng một hàng; xuống dòng khi
   hẹp, vì ô datetime-local không co lại dưới chừng mười lăm rem mà
   vẫn đọc được. */
.gt-hen-gio {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.9rem;
}

.gt-hen-gio .wv-o-nhap {
    width: auto;
    min-width: 15rem;
}

/* Gửi thử: nhãn, ô, nút trên một hàng. Để trong .wv-luoi-nhap thì nút
   thành một ô lưới và bị kéo giãn bằng cả cột. */
.gt-gui-thu {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
}

.gt-gui-thu .wv-o-nhap {
    flex: 0 1 26rem;
    min-width: 15rem;
}

/* Bảng kiểm trước khi gửi. Mỗi mục một chấm màu vẽ bằng CSS chứ không
   dùng ký tự biểu tượng: đạt xanh, chặn gửi đỏ, chỉ nhắc vàng. Chữ vẫn
   nói đủ nghĩa nên người không phân biệt được màu vẫn đọc ra. */
.gt-bang-kiem {
    list-style: none;
    margin: 0 0 0.9rem;
    padding: 0;
    display: grid;
    gap: 0.35rem;
}

.gt-bang-kiem li {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.gt-bang-kiem li::before {
    content: "";
    flex: none;
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
}

.gt-kiem-dat::before { background: var(--wv-xanh, #1f8a5b); }
.gt-kiem-chan { color: var(--wv-do, #b42318); font-weight: 600; }
.gt-kiem-chan::before { background: var(--wv-do, #b42318); }
.gt-kiem-nhac::before { background: var(--wv-vang, #c98a04); }

/* Dấu tự lưu nháp do JavaScript dựng ra, nên nó không có mặt trong
   tệp cshtml nào. Khai ở đây chứ không để trần: một dòng chữ không
   kiểu dáng nằm sát nút Lưu trông như một lời báo lỗi. */
.gt-dau-tu-luu {
    margin-left: auto;
    white-space: nowrap;
}

/* XÓA NGÀY 18 THÁNG 9 NĂM 2026: lớp wv-o-ma-thu. Khối gõ mã tự viết
   đã thay bằng nút xem mã của trình soạn thảo, nên không thẻ nào còn
   mang lớp ấy. Quy tắc 11 bắt đối chiếu trước khi xóa: lớp này khai ở
   ĐÚNG MỘT tệp và không tệp nào dùng, nên không có thuộc tính nào của
   nó đang có hiệu lực ở chỗ khác. Đã quét cả css, cshtml và js.

   ------------------------------------------------------------------
   Hai lớp cho chữ dài trong cụm gửi thư GT-01.

   ĐỊA CHỈ THƯ VÀ DÒNG TIÊU ĐỀ là hai chỗ chữ dài mà không có dấu cách
   để ngắt: một địa chỉ thư dài bốn mươi ký tự liền mạch sẽ đẩy cả
   trang trôi ngang ở khổ điện thoại. Đo ngày 15 tháng 9 năm 2026: màn
   chi tiết đợt gửi rộng 487 điểm ảnh trên khổ 390, và thủ phạm là khối
   bản chữ thuần dùng thẻ pre.
   ------------------------------------------------------------------ */

.wv-ngat-duoc {
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* Bản chữ thuần của lá thư. Giữ đúng lần xuống dòng người soạn đã gõ,
   nhưng dòng quá dài thì vẫn ngắt chứ không đẩy trang trôi ngang. */
.wv-khoi-chu-thu {
    margin: 0;
    padding: 0.6rem 0.75rem;
    max-height: 18rem;
    overflow-y: auto;
    background: var(--wv-nen-phu, #f5f6f8);
    border: 1px solid var(--wv-vien, #d5dae0);
    border-radius: 0.35rem;
    font-family: inherit;
    font-size: 0.92rem;
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* XÓA NGÀY 18 THÁNG 9 NĂM 2026: ba luật của lớp wv-khoi-ma-thu, cùng
   lý do với wv-o-ma-thu ở trên. */


/* =====================================================================
   CỔNG GỬI THƯ: soạn thư, ngăn thư, hoạt động, người nhận, danh bạ
   ===================================================================== */

/* ----- Nút Soạn thư ở đầu thanh bên ----- */
.wv-muc.gt-nut-soan {
    width: auto;
    margin: var(--wv-k2) var(--wv-k3) var(--wv-k3);
    padding: .6rem var(--wv-k4);
    background: var(--wv-nhan);
    color: var(--wv-xanh-950);
    border-left: 0;
    border-radius: var(--wv-bo-3);
    font-weight: 600;
    box-shadow: var(--wv-bong-2);
}

.wv-muc.gt-nut-soan .wv-bt {
    opacity: 1;
}

.wv-muc.gt-nut-soan:hover,
.wv-muc.gt-nut-soan.wv-dang-o {
    background: var(--wv-cam-300);
    color: var(--wv-xanh-950);
}

.wv-muc.gt-nut-soan.wv-dang-o .wv-bt {
    color: var(--wv-xanh-950);
}

html.wv-canh-gon .wv-muc.gt-nut-soan {
    margin: var(--wv-k2) auto var(--wv-k3);
    padding: .6rem;
    justify-content: center;
}

/* ----- Màn soạn ----- */
.gt-soan {
    display: block;
    padding-bottom: var(--wv-k2);
}

/* Biểu mẫu lọc của cổng thư: ô tìm hẹp hơn một chút để ô trạng thái lên cùng hàng, nút
   đứng liền sau các ô, "Thêm bộ lọc" nằm cạnh nút và chỉ trải hết hàng khi mở. */
.gt-loc .wv-loc-rong {
    flex-basis: min(14rem, 100%);
}

.gt-loc > .wv-loc-nut {
    order: 1;
}

/* Khối lập nhóm và khối thêm tay vào sổ thôi nhận: một hàng ô, nút ở cuối. */
.gt-lap-nhom {
    margin-bottom: var(--wv-k4);
}

.gt-soan-khung {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--wv-k4);
    align-items: start;
}

@media (min-width: 1280px) {
    .gt-soan-khung {
        grid-template-columns: minmax(0, 1fr) minmax(320px, 400px);
    }

    .gt-soan-xem {
        position: sticky;
        top: var(--wv-k4);
    }
}

.gt-soan-chinh {
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-1);
    padding: var(--wv-k2) var(--wv-k4) var(--wv-k4);
    min-width: 0;
}

.gt-soan-xem {
    display: grid;
    gap: var(--wv-k2);
}

.gt-soan-xem .wv-khung-xem-thu {
    min-height: 32rem;
}

.gt-dong {
    display: grid;
    grid-template-columns: 5.5rem minmax(0, 1fr);
    gap: var(--wv-k3);
    align-items: start;
    padding: var(--wv-k3) 0;
    border-bottom: 1px solid var(--wv-vien-nhat);
}

.gt-dong-nhan {
    padding-top: .55rem;
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
    font-weight: 600;
}

.gt-dong-o {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2);
    min-width: 0;
}

.gt-dong-o > .wv-o-nhap {
    flex: 1 1 16rem;
    width: auto;
}

.gt-dong-toi .gt-dong-o {
    display: block;
}

@media (max-width: 640px) {
    .gt-dong {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--wv-k1);
    }

    .gt-dong-nhan {
        padding-top: 0;
    }
}

.gt-chon-hop {
    flex: 1 1 22rem;
    width: auto;
}

.gt-nguoi-gui-tay {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k2);
    flex: 1 1 100%;
}

.gt-nguoi-gui-tay[hidden] {
    display: none;
}

.gt-nguoi-gui-tay .wv-o-nhap {
    flex: 1 1 14rem;
    width: auto;
}

.gt-lien-phu {
    font-size: var(--wv-cd-13);
    white-space: nowrap;
}

.gt-o-tieu-de {
    font-size: var(--wv-cd-16);
    font-weight: 600;
}

.gt-kieu {
    gap: var(--wv-k4);
    padding-top: .35rem;
}

.gt-chon-kieu {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-weight: 600;
    cursor: pointer;
}

.gt-chon-kieu input {
    accent-color: var(--wv-chinh);
}

.gt-kieu [hidden] {
    display: none;
}

.gt-mau select {
    flex: 0 1 18rem;
    width: auto;
}

.gt-soan-than {
    padding-top: var(--wv-k3);
}

.gt-ds-tep {
    list-style: none;
    margin: 0 0 var(--wv-k2);
    padding: 0;
    display: grid;
    gap: var(--wv-k1);
    width: 100%;
}

.gt-ds-tep li {
    display: flex;
    align-items: center;
    gap: var(--wv-k2);
    flex-wrap: wrap;
}

.gt-dong-tep .gt-dong-o {
    display: grid;
    gap: var(--wv-k1);
}

.gt-tuy-chon {
    margin-top: var(--wv-k3);
}

.gt-tuy-chon > summary {
    cursor: pointer;
    color: var(--wv-chinh);
    font-weight: 600;
    font-size: var(--wv-cd-13);
    padding: var(--wv-k2) 0;
}

.gt-tuy-chon[open] > summary {
    margin-bottom: var(--wv-k2);
}

/* ----- Ô "Gửi tới" dạng thẻ ----- */
.gt-o-the {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    min-height: 2.75rem;
    padding: .35rem .5rem;
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-2);
    cursor: text;
}

.gt-o-the:focus-within {
    border-color: var(--wv-chinh-sang);
    box-shadow: 0 0 0 3px var(--wv-chinh-nen-dam);
}

.gt-o-go {
    flex: 1 1 12rem;
    min-width: 8rem;
    border: 0;
    outline: 0;
    background: transparent;
    font: inherit;
    font-size: var(--wv-cd-14);
    color: var(--wv-chu);
    padding: .25rem .15rem;
}

.gt-the {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    max-width: 100%;
    padding: .15rem .2rem .15rem .6rem;
    background: var(--wv-chinh-nen);
    border: 1px solid var(--wv-chinh-vien);
    border-radius: var(--wv-bo-tron);
    font-size: var(--wv-cd-13);
    line-height: 1.4;
}

.gt-the-ten {
    font-weight: 600;
    color: var(--wv-chu);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 16rem;
}

.gt-the-phu {
    color: var(--wv-chu-mo);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 14rem;
}

.gt-the-nhom {
    background: var(--wv-nhan-nen);
    border-color: var(--wv-nhan-vien);
}

.gt-the-loc {
    background: var(--wv-tin-nen);
    border-color: var(--wv-tin-vien);
}

.gt-the-giu {
    background: var(--wv-xam-100);
    border-color: var(--wv-xam-200);
}

.gt-the-tep {
    background: var(--wv-tot-nen);
    border-color: var(--wv-tot-vien);
}

.gt-the-hong {
    background: var(--wv-xau-nen);
    border-color: var(--wv-xau-vien);
}

.gt-the-hong .gt-the-ten {
    color: var(--wv-xau-chu);
}

.gt-the-thoi .gt-the-ten {
    text-decoration: line-through;
    color: var(--wv-chu-nhat);
}

/* Nút bỏ thẻ: dấu nhân vẽ bằng hai vạch CSS, không dùng ký tự. */
.gt-the-bo {
    position: relative;
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
}

.gt-the-bo::before,
.gt-the-bo::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: .65rem;
    height: 1.5px;
    background: var(--wv-chu-mo);
    transform: translate(-50%, -50%) rotate(45deg);
}

.gt-the-bo::after {
    transform: translate(-50%, -50%) rotate(-45deg);
}

.gt-the-bo:hover {
    background: rgba(0, 33, 56, .08);
}

.gt-them-the {
    border: 0;
    background: none;
    color: var(--wv-chinh);
    font: inherit;
    font-size: var(--wv-cd-13);
    font-weight: 600;
    cursor: pointer;
    padding: .15rem .35rem;
}

.gt-goi-y {
    position: absolute;
    z-index: 1200;
    max-height: 22rem;
    overflow-y: auto;
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-3);
    padding: .25rem 0;
}

.gt-goi-y-dong {
    display: grid;
    gap: .1rem;
    padding: .45rem .75rem;
    cursor: pointer;
}

.gt-goi-y-dong:hover,
.gt-goi-y-dong.gt-dang-chon {
    background: var(--wv-chinh-nen);
}

.gt-goi-y-tren {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--wv-k2);
}

.gt-goi-y-ten {
    font-weight: 600;
    font-size: var(--wv-cd-14);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gt-goi-y-loai {
    flex: 0 0 auto;
    padding: 0 .45rem;
    border-radius: var(--wv-bo-tron);
    background: var(--wv-xam-100);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-11);
    letter-spacing: .02em;
}

.gt-goi-y-loai.gt-loai-nhom {
    background: var(--wv-nhan-nen);
    color: var(--wv-nhan-chu);
}

.gt-goi-y-phu {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gt-goi-y-thoi {
    color: var(--wv-xau-chu);
    font-size: var(--wv-cd-12);
    font-weight: 600;
}

.gt-dong-phu {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k3);
    margin-top: var(--wv-k2);
}

.gt-dem {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
    font-variant-numeric: tabular-nums;
}

.gt-dem-xau {
    color: var(--wv-xau-chu);
}

/* Thả tệp vào ô Gửi tới: viền nét đứt báo đúng chỗ thả. */
.gt-o-the.gt-keo-tha {
    border-style: dashed;
    border-color: var(--wv-chinh-sang);
    background: var(--wv-chinh-nen-dam);
}

/* Khung kể lại một lượt nhập tệp: mỗi tệp một mục, lấy bao nhiêu người, ở cột nào, bỏ gì. */
.gt-bao-tep {
    display: grid;
    gap: var(--wv-k3);
    margin-top: var(--wv-k3);
    padding: var(--wv-k3) var(--wv-k4);
    background: var(--wv-tam-mo);
    border: 1px solid var(--wv-tot-vien);
    border-radius: var(--wv-bo-3);
    font-size: var(--wv-cd-13);
}

.gt-bao-tep[hidden] {
    display: none;
}

.gt-bao-tep-muc {
    display: grid;
    gap: var(--wv-k2);
}

.gt-bao-tep-muc + .gt-bao-tep-muc {
    padding-top: var(--wv-k3);
    border-top: 1px dashed var(--wv-vien);
}

.gt-bao-tep-xau {
    color: var(--wv-xau-chu);
}

.gt-bao-tep-chinh,
.gt-bao-tep-mau {
    margin: 0;
}

.gt-bao-tep-phu {
    margin: 0;
    padding-left: 1.1rem;
    color: var(--wv-chu-mo);
}

.gt-bao-tep-mau {
    color: var(--wv-chu-mo);
    overflow-wrap: anywhere;
}

.gt-bao-tep-an {
    justify-self: start;
}

.gt-khoi-loc {
    display: grid;
    gap: var(--wv-k3);
    margin-top: var(--wv-k3);
    padding: var(--wv-k3) var(--wv-k4);
    background: var(--wv-tam-mo);
    border: 1px dashed var(--wv-vien);
    border-radius: var(--wv-bo-3);
}

.gt-khoi-loc[hidden] {
    display: none;
}

.gt-khoi-loc-nguon {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2) var(--wv-k4);
}

.gt-khoi-loc-o {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: var(--wv-k3);
}

.gt-khoi-loc-o > label {
    display: grid;
    gap: .25rem;
}

.gt-khoi-loc-dai-ly {
    align-self: end;
}

.gt-khoi-loc-nut {
    display: flex;
    align-items: center;
    gap: var(--wv-k3);
}

/* ----- Thanh gửi dính đáy màn soạn ----- */
.gt-thanh-gui {
    position: sticky;
    bottom: 0;
    z-index: 20;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2);
    margin-top: var(--wv-k4);
    padding: var(--wv-k3) var(--wv-k4);
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-3);
}

.gt-nut-gui {
    min-width: 8rem;
    font-weight: 600;
}

.gt-hen {
    position: relative;
}

.gt-khoi-hen {
    position: absolute;
    bottom: calc(100% + .5rem);
    left: 0;
    z-index: 30;
    display: grid;
    gap: .35rem;
    min-width: 17rem;
    padding: var(--wv-k3);
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-3);
}

.gt-khoi-hen[hidden] {
    display: none;
}

.gt-hen-nhanh {
    padding: .45rem .6rem;
    border: 0;
    border-radius: var(--wv-bo-2);
    background: transparent;
    color: var(--wv-chu);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.gt-hen-nhanh:hover {
    background: var(--wv-chinh-nen);
}

.gt-hen-tu-chon {
    display: grid;
    gap: .25rem;
    padding-top: var(--wv-k2);
    border-top: 1px solid var(--wv-vien-nhat);
}

.gt-thanh-thu {
    margin-left: auto;
    flex-wrap: nowrap;
}

.gt-thanh-thu .wv-o-nhap {
    flex: 0 1 15rem;
    min-width: 11rem;
}

@media (max-width: 720px) {
    .gt-thanh-thu {
        margin-left: 0;
        width: 100%;
    }
}

/* ----- Ngăn thư ----- */
.gt-ngan {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--wv-k1) var(--wv-k4);
    margin-bottom: var(--wv-k4);
    border-bottom: 1px solid var(--wv-vien);
}

.gt-ngan-muc {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .55rem .25rem;
    margin-bottom: -1px;
    color: var(--wv-chu-mo);
    font-weight: 600;
    border-bottom: 2px solid transparent;
}

.gt-ngan-muc:hover {
    color: var(--wv-chinh-dam);
    text-decoration: none;
}

.gt-ngan-dang-o {
    color: var(--wv-chinh-dam);
    border-bottom-color: var(--wv-nhan);
}

.gt-ngan-so {
    min-width: 1.5rem;
    padding: 0 .4rem;
    border-radius: var(--wv-bo-tron);
    background: var(--wv-xam-100);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.gt-ngan-dang-o .gt-ngan-so {
    background: var(--wv-chinh-nen-dam);
    color: var(--wv-chinh-dam);
}

.gt-ngan-ghi {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-left: auto;
    padding-bottom: .55rem;
    color: var(--wv-tin-chu);
    font-size: var(--wv-cd-13);
}

.gt-cham-song {
    width: .5rem;
    height: .5rem;
    border-radius: 50%;
    background: var(--wv-tin);
    animation: gt-nhip 1.6s ease-in-out infinite;
}

@keyframes gt-nhip {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
    .gt-cham-song {
        animation: none;
    }
}

.gt-loc-them {
    order: 2;
    flex: 0 0 auto;
    align-self: flex-end;
    margin-bottom: .45rem;
}

.gt-loc-them[open] {
    flex-basis: 100%;
}

.gt-loc-them > summary {
    cursor: pointer;
    color: var(--wv-chinh);
    font-weight: 600;
    font-size: var(--wv-cd-13);
    padding: .25rem 0;
}

.gt-loc-them-o {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k3);
    padding-top: var(--wv-k2);
}

.gt-tom-tat {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k2);
    align-items: baseline;
    margin: 0 0 var(--wv-k2);
    color: var(--wv-chu-mo);
}

.gt-tom-tat strong {
    color: var(--wv-chu);
}

.gt-trong {
    display: grid;
    justify-items: center;
    gap: var(--wv-k3);
    padding: var(--wv-k8) var(--wv-k4);
    background: var(--wv-tam);
    border: 1px dashed var(--wv-vien);
    border-radius: var(--wv-bo-3);
    color: var(--wv-chu-mo);
    text-align: center;
}

.gt-trong p {
    margin: 0;
}

.gt-bang-thu td {
    vertical-align: top;
}

.gt-thu-tieu-de {
    font-weight: 600;
    color: var(--wv-chu);
}

.gt-ty-le {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.gt-o-nut {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--wv-k1) var(--wv-k2);
}

.gt-tien-do {
    height: 6px;
    min-width: 4rem;
    margin: .2rem 0;
    background: var(--wv-xam-100);
    border-radius: var(--wv-bo-tron);
    overflow: hidden;
}

.gt-tien-do > span {
    display: block;
    height: 100%;
    background: var(--wv-chinh-sang);
    border-radius: inherit;
}

.gt-tien-do-mo > span {
    background: var(--wv-tot);
}

.gt-tien-do-bam > span {
    background: var(--wv-nhan-dam);
}

.gt-tien-do-lon {
    flex: 1 1 12rem;
    height: 10px;
}

.gt-dang-gui {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k4);
    padding: var(--wv-k3) var(--wv-k4);
    background: var(--wv-tin-nen);
    border: 1px solid var(--wv-tin-vien);
    border-radius: var(--wv-bo-3);
    color: var(--wv-tin-chu);
    font-variant-numeric: tabular-nums;
}

.gt-xem-noi-dung {
    min-height: 30rem;
}

/* ----- Hoạt động ----- */
.gt-sk-mo { --gt-mau: var(--wv-tot); }
.gt-sk-bam { --gt-mau: var(--wv-nhan-dam); }
.gt-sk-thoi { --gt-mau: var(--wv-xau); }
.gt-sk-hong { --gt-mau: var(--wv-xam-500); }

.gt-dem-sk {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k4);
}

.gt-dem-sk-o {
    display: grid;
    gap: .1rem;
    padding: var(--wv-k3) var(--wv-k4);
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-left: 4px solid var(--gt-mau);
    border-radius: var(--wv-bo-3);
    color: var(--wv-chu);
}

.gt-dem-sk-o:hover {
    text-decoration: none;
    box-shadow: var(--wv-bong-2);
}

.gt-dem-sk-so {
    font-size: 1.5rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.gt-dem-sk-nhan {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
}

.gt-dong-thoi-gian {
    list-style: none;
    margin: 0;
    padding: 0;
}

.gt-dtg-ngay {
    margin: var(--wv-k4) 0 var(--wv-k1);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.gt-dtg-ngay:first-child {
    margin-top: 0;
}

.gt-dtg-muc {
    display: grid;
    grid-template-columns: 3.25rem .75rem minmax(0, 1fr);
    gap: var(--wv-k2);
    align-items: start;
    padding: .45rem 0;
    border-bottom: 1px solid var(--wv-vien-nhat);
}

.gt-dtg-gon .gt-dtg-muc {
    grid-template-columns: 5.5rem .75rem minmax(0, 1fr);
}

.gt-dtg-gio {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
    font-variant-numeric: tabular-nums;
    text-align: right;
    padding-top: .05rem;
}

.gt-dtg-cham {
    width: .625rem;
    height: .625rem;
    margin-top: .35rem;
    border-radius: 50%;
    background: var(--gt-mau);
}

.gt-dtg-than {
    display: grid;
    gap: .1rem;
    min-width: 0;
}

.gt-dtg-than .wv-phu span + span::before {
    content: ", ";
}

.gt-dtg-nguoi {
    font-weight: 600;
}

.gt-dtg-lien-ket {
    color: var(--wv-tin-chu);
    font-family: var(--wv-phong-ma);
    font-size: var(--wv-cd-12);
}

/* ----- Bố cục hai cột và danh sách gọn ----- */
.gt-hai-cot {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--wv-k4);
    align-items: start;
}

@media (min-width: 1100px) {
    .gt-hai-cot {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }

    .gt-hai-cot.gt-hai-cot-deu {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

.gt-ds-gon {
    list-style: none;
    margin: 0;
    padding: 0;
}

.gt-ds-gon > li {
    padding: var(--wv-k2) 0;
    border-bottom: 1px solid var(--wv-vien-nhat);
}

.gt-ds-gon > li:last-child {
    border-bottom: 0;
}

.gt-ds-so > li {
    display: flex;
    justify-content: space-between;
    gap: var(--wv-k3);
    font-variant-numeric: tabular-nums;
}

.gt-ds-xep-hang {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--wv-k3);
}

.gt-ds-xep-hang > li {
    display: grid;
    gap: .2rem;
}

.gt-xh-dau {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--wv-k3);
    min-width: 0;
}

.gt-xh-dau > a {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gt-xh-dau > strong {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
}

.gt-khoi-doc {
    display: grid;
    gap: var(--wv-k2);
}

.gt-lap-nhom-o {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--wv-k3);
}

.gt-lap-nhom-o > .wv-hang {
    flex: 1 1 16rem;
    margin: 0;
}

.gt-thanh-chon {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--wv-k3);
    margin-bottom: var(--wv-k2);
}

.gt-ds-hop {
    list-style: none;
    margin: 0;
    padding: 0;
}

.gt-ds-hop > li {
    display: grid;
    gap: .2rem;
    padding: var(--wv-k3) 0;
    border-bottom: 1px solid var(--wv-vien-nhat);
}

.gt-ds-hop > li:last-child {
    border-bottom: 0;
}

.gt-ds-hop .gt-o-nut {
    justify-content: flex-start;
}

.gt-hop-dau {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2);
}

.gt-hop-tat {
    opacity: .6;
}

/* ----- Biểu đồ tổng quan ----- */
.gt-bieu-do svg {
    display: block;
    width: 100%;
    height: auto;
}

.gt-bd-luoi {
    stroke: var(--wv-vien-nhat);
    stroke-width: 1;
}

.gt-bd-chu {
    fill: var(--wv-chu-nhat);
    font-size: 11px;
    font-family: var(--wv-phong-so);
}

.gt-bd-gui {
    fill: var(--wv-chinh-nen-dam);
}

.gt-bd-mo {
    fill: var(--wv-tot);
}

.gt-bd-bam {
    fill: var(--wv-nhan-dam);
    stroke: var(--wv-tam);
    stroke-width: 1.5;
}

.gt-chu-giai {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--wv-k3);
    font-size: var(--wv-cd-12);
    color: var(--wv-chu-mo);
    font-weight: 400;
}

.gt-chu-giai > span::before {
    content: "";
    display: inline-block;
    width: .65rem;
    height: .65rem;
    margin-right: .3rem;
    border-radius: 2px;
    vertical-align: -1px;
}

.gt-chu-giai-gui::before { background: var(--wv-chinh-nen-dam); }
.gt-chu-giai-mo::before { background: var(--wv-tot); }
.gt-chu-giai-bam::before { background: var(--wv-nhan-dam); border-radius: 50%; }

/* ----- Tự gửi nhắc trên màn soạn ----- */
.gt-nhac .wv-goi-y {
    margin: 0 0 var(--wv-k2);
}

.gt-buoc-nhac {
    display: grid;
    gap: var(--wv-k2);
    padding: var(--wv-k3);
    margin-bottom: var(--wv-k2);
    background: var(--wv-tam-mo);
    border: 1px solid var(--wv-vien-nhat);
    border-radius: var(--wv-bo-3);
}

.gt-buoc-nhac[hidden] {
    display: none;
}

.gt-buoc-dau {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wv-k2);
}

.gt-buoc-dau label {
    display: inline-flex;
    align-items: center;
    gap: var(--wv-k2);
}

.gt-buoc-dau select {
    width: auto;
}

.gt-buoc-so {
    min-width: 3.5rem;
    font-weight: 700;
    color: var(--wv-chinh-dam);
}

.gt-o-ngay {
    width: 5rem;
}

/* Nhãn nhỏ cạnh mã thư: lá nhắc, số lần nhắc còn chờ. */
.gt-nhan-nho {
    display: inline-block;
    margin-left: .35rem;
    padding: 0 .45rem;
    border-radius: var(--wv-bo-tron);
    background: var(--wv-nhan-nen);
    color: var(--wv-nhan-chu);
    font-size: var(--wv-cd-11);
    font-weight: 600;
}

/* ----- Báo nhanh khi khách mở thư ----- */
.gt-bao-nhanh {
    position: fixed;
    right: var(--wv-k4);
    bottom: var(--wv-k4);
    z-index: 2000;
    display: grid;
    gap: var(--wv-k2);
    width: min(22rem, calc(100vw - 2rem));
}

.gt-bao-the {
    position: relative;
    display: grid;
    gap: .15rem;
    padding: var(--wv-k3) 2.25rem var(--wv-k3) var(--wv-k4);
    background: var(--wv-tam);
    border: 1px solid var(--wv-vien);
    border-left: 4px solid var(--wv-tot);
    border-radius: var(--wv-bo-3);
    box-shadow: var(--wv-bong-3);
    color: var(--wv-chu);
    transition: opacity .5s ease, transform .5s ease;
}

.gt-bao-the:hover {
    text-decoration: none;
}

.gt-bao-bam {
    border-left-color: var(--wv-nhan-dam);
}

.gt-bao-tat {
    opacity: 0;
    transform: translateY(.5rem);
}

.gt-bao-dau {
    font-weight: 600;
}

.gt-bao-phu {
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-13);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gt-bao-dong {
    position: absolute;
    top: .5rem;
    right: .5rem;
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}

.gt-bao-dong::before,
.gt-bao-dong::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: .65rem;
    height: 1.5px;
    background: var(--wv-chu-mo);
    transform: translate(-50%, -50%) rotate(45deg);
}

.gt-bao-dong::after {
    transform: translate(-50%, -50%) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
    .gt-bao-the {
        transition: none;
    }
}


/* ---------- Tài liệu đính kèm của hồ sơ, 14 tháng 10 năm 2026 ---------- */

/*
   Khuôn _TaiLieuSua và _TaiLieuXem của hồ sơ nhà cung cấp và hồ sơ tour, cộng danh sách tệp của hồ sơ
   nhân sự và văn bản. Dời từ bộ lớp ncc-tep-* (10/09/2026) vốn khai ở tấm của hồ sơ đối tác mà ba cụm
   màn kia mượn dùng; thêm ghi chú từng tệp: "đây là hợp đồng gì".

   Danh sách tệp, KHÔNG phải bảng. Mỗi dòng chỉ có tên, ghi chú và một câu phụ, mà một bảng nhiều cột
   bắt mắt người đọc đi ngang trong lúc thứ họ tìm nằm dọc.
*/
.wv-tep-ds {
    display: flex;
    flex-direction: column;
    gap: var(--wv-k2);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Danh sách ô ghi chú của tệp vừa chọn chờ wv-ghi-chu-tep.js dựng, nằm ẩn khi chưa chọn tệp nào.
   Luật display ngay trên đè thuộc tính hidden, nên phải khai lại. */
.wv-tep-ds[hidden] {
    display: none;
}

.wv-tep-mot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--wv-k3);
    padding: var(--wv-k2) var(--wv-k3);
    border: 1px solid var(--wv-vien-nhat);
    border-radius: var(--wv-bo-2);
    background: var(--wv-nen-mo);
}

/* Tên tệp được phép DÀI. Cắt nó bằng dấu ba chấm là bắt người đọc bấm thử để biết mình đang tải cái
   gì, mà tên tệp thật thường mang cả tên khách sạn lẫn năm. */
.wv-tep-ten {
    min-width: 0;
    flex: 1 1 16rem;
    overflow-wrap: anywhere;
}

.wv-tep-co {
    display: block;
    margin-top: var(--wv-k1);
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
    font-variant-numeric: tabular-nums;
}

/* Ghi chú ở màn xem: chữ thường màu chữ chính, đứng ngay dưới tên tệp, trên dòng dung lượng. Đây là
   câu trả lời cho "tệp này là gì", nên không được mờ như dòng phụ. */
.wv-tep-ghi-chu {
    display: block;
    margin-top: var(--wv-k1);
    color: var(--wv-chu);
}

/* Câu báo tổng dung lượng tệp vượt mức một lượt lưu, do wv-ghi-chu-tep.js bật tắt. Khối báo chung
   đặt display: flex nên đè mất thuộc tính hidden, phải khai lại. */
.wv-tep-tran[hidden] {
    display: none;
}

/* Ô ghi chú ở biểu mẫu: rộng hơn phần tên, xuống hàng riêng khi dòng hẹp. */
.wv-tep-ghi-chu-o {
    flex: 2 1 18rem;
    min-width: 0;
}


/* ---------- Đơn nghỉ ba bước và lưới chấm công tháng, 14 tháng 10 năm 2026 ---------- */

/*
   Khối duyệt của màn một đơn nghỉ: ba bước đúng ba chữ ký trên mẫu NS-10-BM01. Bước xong viền xanh,
   bước bị từ chối viền đỏ, bước chưa tới viền nhạt.
*/
.np-buoc {
    display: flex;
    flex-direction: column;
    gap: var(--wv-k2);
    margin: 0 0 var(--wv-k4);
    padding: 0;
    list-style: none;
}

.np-buoc-mot {
    display: flex;
    flex-direction: column;
    gap: var(--wv-k1);
    padding: var(--wv-k2) var(--wv-k3);
    border-left: 3px solid var(--wv-vien);
    border-radius: var(--wv-bo-2);
    background: var(--wv-tam-mo);
}

.np-buoc-xong {
    border-left-color: var(--wv-tot);
}

.np-buoc-hong {
    border-left-color: var(--wv-xau);
}

.np-buoc-ten {
    font-weight: 600;
}

.np-y-kien {
    color: var(--wv-chu-mo);
}

.np-quyet {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--wv-k2);
    max-width: 40rem;
    margin-bottom: var(--wv-k4);
}

.np-quyet .wv-hang {
    width: 100%;
}

/*
   Lưới chấm công tháng của màn chấm công: mỗi người một hàng, mỗi ngày một ô ký hiệu. Cột họ tên dính
   mép trái khi cuộn ngang, vì ba mươi mốt cột ngày luôn rộng hơn khung. Màu ô theo nhóm chữ: P xanh,
   K và N đỏ, CT xanh dương, O và các loại khác vàng nhạt; thứ bảy, chủ nhật tô nền.
*/
.cc-luoi {
    border-collapse: collapse;
    font-size: var(--wv-cd-12);
    font-variant-numeric: tabular-nums;
}

.cc-luoi th,
.cc-luoi td {
    min-width: 2.1rem;
    padding: 2px 3px;
    border: 1px solid var(--wv-vien-nhat);
    text-align: center;
    white-space: nowrap;
}

.cc-luoi thead th {
    background: var(--wv-tam-mo);
    font-weight: 600;
}

.cc-cot-stt {
    min-width: 2rem;
}

.cc-cot-so {
    min-width: 3rem;
    font-weight: 600;
}

.cc-cot-ten {
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 11rem;
    text-align: left !important;
    background: var(--wv-tam);
}

.cc-ma {
    display: block;
    color: var(--wv-chu-mo);
    font-size: .7rem;
}

.cc-thu {
    font-weight: 400 !important;
    color: var(--wv-chu-mo);
}

.cc-luoi .cc-nghi-tuan {
    background: var(--wv-nhan-nen);
}

.cc-o {
    font-weight: 600;
}

.cc-x {
    color: var(--wv-chu);
    font-weight: 400;
}

.cc-off {
    color: var(--wv-chu-mo);
    font-weight: 400;
}

.cc-luoi .cc-p {
    background: var(--wv-tot-nen);
    color: var(--wv-tot-chu);
}

.cc-luoi .cc-k {
    background: var(--wv-xau-nen);
    color: var(--wv-xau-chu);
}

.cc-luoi .cc-ct {
    background: var(--wv-tin-nen);
    color: var(--wv-tin-chu);
}

.cc-luoi .cc-khac {
    background: var(--wv-nhac-nen);
    color: var(--wv-nhac-chu);
}

.cc-ngoai {
    color: var(--wv-chu-mo);
}

.cc-quy-uoc {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k2) var(--wv-k4);
    margin: var(--wv-k3) 0 0;
    padding: 0;
    list-style: none;
    color: var(--wv-chu-mo);
    font-size: var(--wv-cd-12);
}

.cc-quy-uoc b {
    color: var(--wv-chu);
}

/* =====================================================================
   CỬA CRM, ĐỢT 1, NGÀY 24 THÁNG 10 NĂM 2026: danh sách khách, biểu mẫu,
   hồ sơ khách 360. Tiền tố crm-, khai ở tấm thành phần như cụm gửi thư,
   vì bộ soát lớp chỉ biết bảy tấm mà khuôn nạp cho mọi màn.
   ===================================================================== */

/* ----- Hộp nhỏ Đổi người phụ trách trên đầu hồ sơ khách -----

   Dãy nút đầu hồ sơ làm mốc neo, không phải chính thẻ details: nút Đổi người
   phụ trách đứng giữa dãy, neo vào nó thì ở bề rộng vừa vừa khung nhập tràn
   khỏi mép trái màn. Hẹp từ 760 trở xuống thì khung nằm ngay dưới nút. */
.crm-dau-nut {
    position: relative;
}

@media (min-width: 761px) {
    .crm-hop-doi > form {
        position: absolute;
        top: calc(100% + var(--wv-k1));
        right: 0;
        z-index: 40;
        width: min(22rem, calc(100vw - 2rem));
        padding: var(--wv-k3);
        background: var(--wv-tam);
        border: 1px solid var(--wv-vien);
        border-radius: var(--wv-bo-3);
        box-shadow: var(--wv-bong-3);
    }
}

/* ----- Nút Gọi và Zalo đứng sau mỗi số điện thoại ----- */
.crm-goi {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wv-k1);
    margin-top: var(--wv-k1);
}

/* ----- Chấm của dòng thời gian lịch sử phụ trách ----- */
.crm-sk-phu-trach { --gt-mau: var(--wv-chinh); }

/* ----- Danh sách khách trùng trên biểu mẫu thêm khách ----- */
.crm-ds-trung {
    margin: var(--wv-k2) 0;
    padding-left: 1.25rem;
}

.crm-ds-trung > li + li {
    margin-top: var(--wv-k1);
}

/* ----- Ô thứ hai đứng dưới ô thứ nhất trong một ô của bảng người liên hệ trên biểu mẫu khách -----

   Vá sau soát CRM đợt 1, ngày 24 tháng 10 năm 2026: ô chọn Vai trò đứng dưới ô Chức danh, ô Nhận
   tin đứng dưới ô Sinh nhật, để bảng còn bảy cột và vừa khung ở khổ 1280. */
.crm-o-duoi {
    margin-top: var(--wv-k1);
}

/* ----- Lưới hai cột của hồ sơ khách 360 -----

   Vá sau soát CRM đợt 1, ngày 24 tháng 10 năm 2026. Lưới gt-hai-cot của cụm gửi thư chia hai cột
   từ 1100 điểm ảnh, mà cột trái của hồ sơ chở bảng người liên hệ và bảng báo giá. Đo bằng Chrome
   trên đúng bảy tệp kiểu dáng: ở khổ 1280 cột trái chỉ còn khung 554 điểm ảnh, khổ 1440 còn 652,
   trong khi bảng người liên hệ đòi 714 và bảng báo giá đòi 733, nên cột Nhận tin và cột Trạng thái
   báo giá phải kéo ngang mới thấy (quy tắc 28).

   Hồ sơ giữ MỘT cột, rộng như trước CRM đợt 1, cho tới khổ 1600. Từ đó cột trái còn khung 740
   (trần thân trang giữ nó ở 746 trên màn rộng hơn), còn hai bảng, khi ô ngày mang wv-o-ngay, đòi
   676 và 657. */
@media (min-width: 1100px) {
    .gt-hai-cot.crm-ho-so {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (min-width: 1600px) {
    .gt-hai-cot.crm-ho-so {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }
}
