@charset "UTF-8";
/* =============================================================
 * Lớp phủ Design System - áp token Figma "Design System 1.1 [VPTWĐ]"
 * lên theme legacy (main.css / site.min.css / bootstrap-extend).
 *
 * Xử lý các lỗi audit UI/UX vòng 1 (21/07/2026) - xem
 * agents/airtable/records/list-fail-l1.json. Mã lỗi ghi ở từng khối.
 *
 * THỨ TỰ NẠP: sau toàn bộ CSS theme, TRƯỚC dark-mode.css.
 * File này chỉ dùng var(--...) của tokens.css nên dark-mode.css
 * (ánh xạ lại token trong html[data-theme="dark"]) tự động áp dụng.
 *
 * Vì theme cũ dùng !important rất nhiều nên nhiều khai báo ở đây
 * buộc phải dùng theo. Chỉ đụng vào màu / chữ / bo góc / khoảng cách,
 * KHÔNG đổi display - position - width để tránh vỡ layout.
 * ============================================================= */

/* -------------------------------------------------------------
 * 0. Token còn thiếu & hai chỗ tokens.css lệch spec
 *
 * Nguồn: agents/rules_figma/R05, R06 - đọc từ bản export Figma.
 * KHÔNG sửa tokens.css vì đầu file đó ghi "SINH TỰ ĐỘNG - đừng sửa tay"
 * (và nguồn sinh ra nó, agents/figma-design-system/*.json, đã không còn
 * trong repo nên cũng không tái sinh được). Đè ở đây, tokens.css nạp
 * trước nên các khai báo dưới thắng.
 * ------------------------------------------------------------- */
:root {
    /* --- Quầng focus. Figma đặt tên "Focus ring <trạng thái>". ---
       Quy luật: trung tính 3px, trạng thái cần chú ý 4px.
       #FDD7D7 KHÔNG có trong thang tokens.css - nó kẹp giữa
       primary/100 (#FEE2E2) và primary/200 (#FECACA). */
    --focus-ring-brand: 0 0 0 3px #FDD7D7;
    --focus-ring-gray: 0 0 0 3px #E5E7EB;
    --focus-ring-success: 0 0 0 4px #86EFAC;
    --focus-ring-warning: 0 0 0 3px #FEF3C7;
    --focus-ring-error: 0 0 0 4px #FECACA;

    /* --- Shadow. Gốc rgba(18,26,43) - navy đậm, KHÔNG phải đen thuần.
       Đen thuần trên nền sáng trông xỉn hơn. --- */
    --shadow-xs: 0 1px 4px rgba(18, 26, 43, .05);
    --shadow-sm: 0 0 4px rgba(18, 26, 43, .1), 0 1px 2px -1px rgba(18, 26, 43, .06);
    --shadow-md: 0 0 9px -2px rgba(18, 26, 43, .1), 0 2px 4px -2px rgba(18, 26, 43, .06);
    --shadow-lg: 0 4px 15px -4px rgba(18, 26, 43, .1), 0 4px 6px -4px rgba(18, 26, 43, .05);
    --shadow-xl: 0 3px 25px -4px rgba(18, 26, 43, .1), 0 8px 8px -6px rgba(18, 26, 43, .04);
    --shadow-xxl: 0 10px 45px -12px rgba(18, 26, 43, .2);

    /* --- Sửa lệch so với Figma --- */

    /* tokens.css khai --color-border-brand: var(--brand-primary) = primary/600.
       Figma "border-brand" = primary/500. Lệch đúng một bậc. */
    --color-border-brand: var(--color-primary-500);

    /* Figma "Body large" 18/24, tokens.css ghi 18/26.
       Figma "Caption small" 12/18, tokens.css ghi 12/16. */
    --font-line-h4: 24px;
    --font-line-caption: 18px;
}

/* -------------------------------------------------------------
 * 1. Nền chữ & phân cấp màu             [UI_04.2] [UI_07.1]
 * Chữ chính neutral-900 trên nền trắng = 16.1:1, chữ phụ
 * neutral-600 = 7.6:1, đều vượt ngưỡng AA 4.5:1 cho cỡ 14px.
 * Trước đây chữ phụ dùng #a4b7c1 (2.0:1) - trượt AA.
 * ------------------------------------------------------------- */
body,
.page,
.panel,
.panel-body {
    color: var(--color-text-primary);
}

/* .main_bg bị viết cứng background-color:#fff trong thẻ <style> của 5 trang
   (userProfile, index, notice/index, searchLoginHistory, loginHistoryIndex).
   Style trong trang nằm sau file này nên phải dùng !important mới thắng.

   Ở chế độ tối, dark-mode.css đổi màu chữ sang sáng nhưng nền trắng này
   không ai đè -> chữ sáng trên nền trắng, đo được 1.04:1, gần như không
   đọc nổi. Lỗi có sẵn từ trước, không phải do lớp phủ này.
   Chế độ sáng không đổi gì vì --color-bg-surface cũng là #FFFFFF. [UI_04.2] */
.main_bg {
    background-color: var(--color-bg-surface) !important;
}

/* Các lớp chữ mờ của theme cũ đều nhạt hơn ngưỡng AA */
.text-muted,
.help-block,
.form-text,
small.text-muted {
    color: var(--color-text-secondary) !important;
}

/* -------------------------------------------------------------
 * 2. Cỡ chữ tối thiểu 14px                        [UI_05.3]
 * Theme cũ rải rất nhiều cỡ 10-13px (nhãn phụ, chú thích định dạng
 * ngày, ô bảng trên mobile). Đặt sàn 14px cho chữ nội dung.
 * ------------------------------------------------------------- */
body,
.panel-body,
.form-control,
.table>tbody>tr>td,
.table>thead>tr>th,
label,
p,
td,
th,
.text-muted,
.help-block,
.form-text {
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
}

/* Chú thích định dạng ngày. renew/css/style.css có đặt 14px nhưng file đó
   chỉ được renew/layout.jsp nạp; các màn dùng adminLayout thì không có rule
   nào -> thẻ <small> rơi về mặc định 80% của cha, đo được 9.6px.
   Khai báo lại ở đây để cả hai layout cùng đúng.            [UI_05.3] */
.date-format-hint,
small.date-format-hint {
    display: block;
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
    color: var(--color-text-secondary);
    margin-top: var(--space-1);
}

/* Phân trang của displaytag: thẻ <a> trần bên trong span.pagelinks bị
   theme cũ ép 12px.                                        [UI_05.3] */
.pagelinks,
.pagelinks a,
.pagelinks strong,
.pagelinks span {
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
}

/* Không dùng màu đỏ toàn cục của thẻ <a> cho phân trang: mặc định là đen,
   chỉ trang hiện tại/hover mới nổi bật màu đỏ.             [UI_07.1] */
.pagelinks a {
    color: var(--color-text-primary);
    border-radius: var(--radius-sm, 4px);
}

/* displaytag render Đầu/Trước (hoặc Sau/Cuối) không có href khi không còn
   trang trước/sau (xem paging.banner.first/last trong displaytag*.properties)
   - vẫn là thẻ <a> nên phải chặn bằng [href], nếu không link "không bấm
   được" vẫn ăn hover như link thật, gây hiểu lầm là click được.
   pointer-events: none chặn hẳn :hover/:focus lẫn click phát sinh từ
   chuột (cùng kỹ thuật bootstrap.css dùng cho .page-item.disabled .page-link
   bên dưới) - chỉ đổi màu/cursor thôi thì rule a:hover toàn cục ở mục 10
   vẫn chen được text-decoration: underline vào lúc rê chuột. */
.pagelinks a:not([href]) {
    color: var(--color-text-muted);
    cursor: default;
    pointer-events: none;
}

.pagelinks a[href]:hover,
.pagelinks a[href]:focus {
    color: var(--brand-primary);
    background-color: var(--color-primary-50);
    text-decoration: none;
}

/* Trang hiện tại phải nổi hơn các trang khác             [UI_07.1] */
.pagelinks strong {
    color: #fff;
    background-color: var(--brand-primary);
    border-radius: var(--radius-sm, 4px);
    font-weight: 600;
}

/* Dòng "Tìm thấy X, hiển thị từ Y đến Z" (managerGroupsListResult.jsp,
   searchLoginHistory.jsp, managerDepartmentIndex.jsp...) dùng class Bootstrap
   cũ .callout.callout-info: main.css gán border-left-width .25rem cho .callout,
   layout.css/style.css tô màu xanh #109bdc qua .callout-info -> thừa một vạch
   xanh không thuộc bảng màu design system. Bỏ khung, giữ nguyên chữ đậm/padding
   đã có ở .pagepanner.callout.                                    [UI_01.1] */
/* Bảng kết quả: bootstrap.css/main.css/style.min.css đều đặt .table
   { margin-bottom: 1rem } (= 14px) - hơi rộng so với thanh phân trang ngay bên
   dưới. Thu về 9px; độ đặc hiệu (0,4,0) thắng .table (0,1,0) nên không cần
   !important và cũng không đụng các bảng khác không đủ 4 lớp này. */
.table.table-striped.table-bordered.table-hover {
    margin-bottom: 9px;
}

.callout.pagepanner {
    border: none;
    padding: 0;
    /* .callout (main.css) còn margin dọc mặc định - triệt để bằng 0 để dòng chữ
       thẳng hàng đúng tâm với cụm nút trong .sso-pager-bar. */
    margin: 0;
}

/* sso-pager.js bọc div.pagepanner (chữ) + span.pagelinks (nút) - vốn là 2 khối
   anh em rời trong .panel-body - vào .sso-pager-bar để xếp thành thanh:
   chữ "Hiển thị X - Y ..." bên trái, cụm nút « ‹ Trang X/Y › » bên phải. */
.sso-pager-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* layout.css/style.css gán padding: 2px 4px cho span.pagelinks - bỏ theo yêu cầu. */
span.pagelinks {
    padding: 0;
}

/* ---- Phân trang kiểu design-system (displaytag_vi.properties) --------------
   Trái: #pagebannerId "Hiển thị {từ} - {đến} trong tổng số {tổng} kết quả".
   Phải: span.pagelinks = 4 nút pill « ‹ › » + .pg-pages ("Trang X / Y" do
   sso-pager.js ghi sau mỗi lần render, thay cho dãy số trang cũ). */
#pagebannerId {
    margin: 0;
    color: var(--color-text-secondary);
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
}

span.pagelinks {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pagelinks .pg-nav {
    min-width: 32px;
    height: 32px;
    padding: 0 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--color-neutral-200);
    border-radius: var(--radius-sm, 4px);
    background: #fff;
    color: var(--color-text-primary);
    font-size: var(--font-size-body);
    line-height: 1;
    text-decoration: none;
}

.pagelinks .pg-nav[href]:hover,
.pagelinks .pg-nav[href]:focus {
    border-color: var(--brand-primary);
    background-color: var(--color-primary-50);
    color: var(--brand-primary);
    text-decoration: none;
}

/* Đầu/Cuối vô hiệu: displaytag render <a> không có href ở trang đầu/cuối. */
.pagelinks .pg-nav:not([href]) {
    color: var(--color-text-muted);
    background: var(--color-neutral-100);
    border-color: var(--color-neutral-200);
    cursor: default;
    pointer-events: none;
}

.pagelinks .pg-pages {
    padding: 0 10px;
    color: var(--color-text-primary);
    font-size: var(--font-size-body);
    white-space: nowrap;
}

/* Trước khi sso-pager.js chạy, {0} còn là dãy <a>/<strong> số trang - trung hòa
   để không loé ra kiểu cũ (JS sẽ ghi đè innerHTML thành "Trang X / Y"). */
.pagelinks .pg-pages a,
.pagelinks .pg-pages strong {
    all: unset;
}

/* Phân trang popup chọn đơn vị/nhóm (#groups_pagination, dựng bằng JS trong
   managerUserForm.jsp / managerDepartmentForm.jsp) nay render đúng cấu trúc
   span.pagelinks > .pg-nav / .pg-pages như displaytag nên dùng chung toàn bộ
   style ở trên - đã bỏ nhóm rule #groups_pagination .page-link (ul.pagination
   Bootstrap không còn được dựng nữa). */

/* Cây đơn vị (jsTree) mặc định 12px - dùng ở màn quản lý người dùng và
   quản lý đơn vị, là danh sách đọc nhiều nên phải đạt sàn 14px. [UI_05.3] */
.jstree-anchor,
.jstree-node,
.jstree-default .jstree-anchor {
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
}

/* -------------------------------------------------------------
 * 3. Phân cấp tiêu đề                    [UI_07.2] [UI_05.1]
 * Trước đây H2/H3 gần bằng nhau và hay viết hoa toàn bộ. Áp thang
 * font-scale của Design System, bỏ viết hoa.
 * ------------------------------------------------------------- */
h1,
.h1 {
    font-size: var(--font-size-h1);
    line-height: var(--font-line-h1);
}

h2,
.h2 {
    font-size: var(--font-size-h2);
    line-height: var(--font-line-h2);
}

h3,
.h3 {
    font-size: var(--font-size-h3);
    line-height: var(--font-line-h3);
}

h4,
.h4 {
    font-size: var(--font-size-h4);
    line-height: var(--font-line-h4);
}

h5,
.h5 {
    font-size: var(--font-size-h5);
    line-height: var(--font-line-h5);
}

h1,
h2,
h3,
h4,
h5,
.h1,
.h2,
.h3,
.h4,
.h5,
.title_form,
.panel-title {
    font-family: var(--font-family-base);
    font-weight: 600;
    color: var(--color-text-primary);
    text-transform: none;
    letter-spacing: 0;
}

/* Tiêu đề vùng trong trang hồ sơ / biểu mẫu.               [UI_01.1]
   Bản gốc (renew/css/style.css) là pill gradient xanh-lá
   #287cec -> #4dc28c, position:absolute, padding-left:50px.

   Bỏ gradient thì phải bỏ luôn absolute và trả lại padding ngang:
   thẻ nằm trong .row (margin-left:-15px) nên mép trái của nó thò ra
   ngoài vùng cắt overflow:hidden của mCustomScrollbar 15px - padding
   50px cũ vốn đang che khuyết điểm đó. Để padding 0 thì ký tự đầu
   của tiêu đề bị cắt mất. 15px = đúng gutter của .col-*.

   flex: 0 0 100% để tiêu đề chiếm trọn một hàng, vì .row là flex
   container - nếu không nó thành flex item nằm cạnh các cột. */
.title_form {
    position: static;
    left: auto;
    top: auto;
    width: 100%;
    flex: 0 0 100%;
    background: none;
    padding: 0 15px;
    margin: var(--space-6) 0 var(--space-3);
    font-size: var(--font-size-h4);
    line-height: var(--font-line-h4);
    color: var(--color-text-primary);
    border-radius: 0;
}

/* Hệ quả trực tiếp của việc đưa .title_form về static ở trên.  [UI_03.4]

   renew/css/style.css khai .main_bg .row { padding: 60px } - 60px trên đó vốn
   để chừa chỗ cho pill tiêu đề position:absolute nằm đè lên đầu hàng. Tiêu đề
   nay là phần tử tĩnh chiếm chỗ thật, nên 60px kia thành khoảng trắng chết
   nguyên vẹn ở đầu MỌI hàng.

   Đo trên màn Hồ sơ cá nhân: 4 hàng x 60px, chiều cao trang giảm từ 1478px
   xuống 1187px sau khi bỏ. Ảnh hưởng cả 5 trang dùng .main_bg (userProfile,
   index, notice/index, searchLoginHistory, loginHistoryIndex).

   Chỉ bỏ padding trên; giữ nguyên trái/phải/dưới vì chúng vốn đã là 0. */
.main_bg .row {
    padding-top: 0;
}

/* .heading-radius: pill gradient #287cec -> #80c85f của theme cũ.  [UI_01.1]
   Giữ lại selector phòng khi còn màn dùng, nhưng đưa về màu thương hiệu. */
.heading-radius {
    background: var(--color-bg-subtle) !important;
    color: var(--color-text-primary) !important;
    border-left: 3px solid var(--brand-primary);
    border-radius: var(--radius-sm);
    justify-content: flex-start;
    padding: 0 var(--space-4);
    width: auto;
    height: auto;
    min-height: 40px;
    font-weight: 600;
}

/* -------------------------------------------------------------
 * 4. Thanh tiêu đề panel               [UI_05.1] [UI_08.2]
 * Audit: "Header không in hoa, bỏ icon". Icon fa-th chỉ trang trí,
 * không mô tả được nội dung -> ẩn bằng CSS thay vì sửa 23 file JSP.
 * ------------------------------------------------------------- */
.panel-heading>strong>.fa-th,
.panel-heading>strong>.fa-th-list,
.sso-search-heading>strong>.fa-th {
    display: none;
}

.panel-heading>strong,
.panel-heading>strong>span {
    font-size: var(--font-size-h5);
    line-height: var(--font-line-h5);
    font-weight: 600;
    text-transform: none;
    color: var(--color-text-primary);
}

.panel-heading {
    background: var(--color-bg-surface);
    border-bottom: 1px solid var(--color-border-subtle);
}

/* -------------------------------------------------------------
 * 5. Nhãn biểu mẫu                                [UI_05.1]
 * Audit: "in hoa in đậm cho các label không cần thiết >> input viết
 * regular". Bỏ bold, giữ 500 để vẫn tách khỏi giá trị.
 * ------------------------------------------------------------- */
label,
.control-label,
.form-horizontal .control-label {
    font-weight: 500;
    text-transform: none;
    color: var(--color-text-primary);
}

/* Bảng dạng "nhãn - giá trị" (hồ sơ cá nhân) dùng <strong> làm nhãn */
.table-common td>strong {
    font-weight: 500;
    color: var(--color-text-secondary);
}

/* Dấu bắt buộc.                                            [UI_04.4]
   KHÔNG tô đỏ cả thẻ mang class .required: ở các form vai trò / người dùng
   thì chính thẻ <label> mang class này, tô đỏ là đỏ nguyên cụm nhãn
   ("Mã vai trò", "Tên vai trò") - đúng lỗi "dùng màu đỏ cho text bình thường".
   Markup đã có sẵn <font color="red">*</font> nên chỉ cần giữ nhãn màu chữ
   thường, dấu sao tự đỏ. */
label.required,
.form-control-label.required {
    color: var(--color-text-primary);
}

.text-required {
    color: var(--color-danger-600);
}

/* Dấu sao viết bằng thẻ <font color="red"> (#FF0000) - trên nền trắng chỉ đạt
   4.00:1, dưới ngưỡng AA 4.5:1, lại còn thừa hưởng cỡ 13px. Thuộc tính color
   của <font> chỉ là gợi ý trình bày nên CSS đè được.           [UI_04.2] */
label font,
.form-control-label font {
    color: var(--color-danger-600);
    font-size: var(--font-size-body);
}

/* bootstrap-extend.min.css có
   @media (min-width:768px){.form-horizontal .form-control-label{text-align:right}}
   - quy ước form-horizontal gốc của Bootstrap, căn nhãn về phía ô nhập bên cạnh.
   Đổi toàn cục sang trái: nhãn đọc thuận mắt hơn khi nằm sát lề trái của cột,
   nhất là nhãn 2 dòng (ví dụ "Yêu cầu đổi mật khẩu trong lần đăng nhập đầu
   tiên"). File này nạp sau bootstrap-extend.min.css ở mọi trang trong layout
   (common/renew/layout.jsp, common/adminLayout.jsp) nên đủ thắng mà không cần
   !important. */
.form-horizontal .form-control-label {
    text-align: left;
    /* layout.css đã cho padding-left: 8px, nhưng cộng cả padding-left của cột
       Bootstrap (.col-xl-*) thì chữ nhãn vẫn gần như thẳng hàng với chữ tiêu đề
       card phía trên (panel-heading, padding-left riêng 12px) - nhìn như label
       không thụt vào so với heading. Cộng thêm để nhãn lùi vào phải rõ rệt hơn,
       tách bạch khỏi mép chữ tiêu đề.
       24px (không phải 16px trước đây): các hàng 2 cột (label-input-label-input)
       chỉ cách nhau 8px giữa mép ô nhập cột trái và mép nhãn cột phải - nhãn cột
       phải trông như dính sát vào ô nhập cột trái. Padding lớn hơn nới thêm
       khoảng cách này (áp dụng cho mọi nhãn, cả hai cột, vì cùng một rule). */
    padding-left: 24px;
}

/* Nhãn cột trái trong MỌI form tìm kiếm: 20px riêng cho form search (khác 24px
   dùng chung ở mọi form khác - .form-horizontal .form-control-label phía trên)
   theo yêu cầu chuẩn hoá form search: cột trái 20px, cột phải 56px.
   Rule sau (:last-of-type:not(:only-of-type), 56px) đặc hiệu hơn selector này
   (thêm 2 pseudo-class) nên vẫn thắng cho nhãn cột phải - viết TRƯỚC nó trong
   file cũng không sao vì độ đặc hiệu mới là thứ quyết định, không phải thứ tự. */
[id^="searchPanelBody"] .form-group.row > label.form-control-label {
    padding-left: 20px;
}

/* Riêng nhãn cột phải (nhãn thứ 2 trong mỗi .form-group.row - "Kiểu backup",
   "Trạng thái", "Đích lưu trữ"...) trong MỌI form tìm kiếm: 24px là đủ để tách
   khỏi chữ tiêu đề card, nhưng khoảng cách tới mép ô nhập cột trái vẫn quá sát
   (theo phản ánh trên backupPolicySearchForm.jsp). Chọn theo id container thay
   vì .form-horizontal vì mọi khối #searchPanelBody* (searchPanelHeading.jsp
   sinh ra, theo đúng tên tham số "target" mỗi màn truyền vào) đều là khối tìm
   kiếm - không đụng tới các form khác (form thêm/sửa/xem chi tiết) vốn đã có
   nhịp cột riêng.
   :last-of-type (không phải :nth-of-type(2)) vì một vài hàng có nhãn ẩn xen giữa
   (display: none, vd #selectGroupsText ở managerUserSearchForm.jsp) - nhãn ẩn đó
   vẫn tính vào thứ tự DOM nên nth-of-type(2) có thể trúng nhãn ẩn thay vì nhãn
   cột phải thật sự. last-of-type luôn đúng nhãn cuối cùng - cột phải - bất kể có
   nhãn ẩn xen giữa hay không.
   :not(:only-of-type) để loại các hàng chỉ có 1 nhãn (field full-width kiểu
   Service ID, Client IP) - hàng đó không có "cột phải" nào để tách khỏi, nhãn
   duy nhất của nó vẫn là last-of-type nên nếu thiếu điều kiện này sẽ bị đẩy
   lùi nhầm. */
[id^="searchPanelBody"] .form-group.row > label.form-control-label:last-of-type:not(:only-of-type) {
    padding-left: 56px;
}

/* -------------------------------------------------------------
 * 6. Nút bấm             [UI_01.1] [UI_02.1] [UI_02.4] [UI_06.1]
 * Bo góc 8px theo Figma, cùng chiều cao, có hover/focus/active.
 * ------------------------------------------------------------- */
.btn {
    font-family: var(--font-family-base);
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
    font-weight: 500;
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-4);
    /* Audit UI_02.2: "Chiều cao hơi lớn tốn diện tích >> 40/44. Kích thước chữ
       hơi lớn >> 14-15pt". Đo bản trước được 37px - thấp hơn chuẩn. Ép 40px,
       giữ chữ 14px.                                               [UI_02.2] */
    min-height: var(--space-10);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    text-transform: none;
    transition: background-color .15s ease-in-out,
        border-color .15s ease-in-out,
        color .15s ease-in-out,
        box-shadow .15s ease-in-out;
}

/* Bàn phím phải thấy được điểm dừng - viền focus 3px alpha thương hiệu.
   .form-control:not(:disabled):not([readonly]): disabled vốn đã bị loại khỏi
   tab order nên không cần chặn, nhưng readonly (như userName lúc update) vẫn
   Tab tới được - không có rule này thì ô đó vẫn nổi viền đỏ dù đã tắt hết hiệu
   ứng :focus/:hover khác cho readonly ở trên. */
.btn:focus-visible,
.form-control:focus-visible:not(:disabled):not([readonly]),
a:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
    box-shadow: none;
}

.btn-primary,
.btn-search,
.btn-submit,
.btn-save {
    background-color: var(--brand-primary) !important;
    border-color: var(--brand-primary) !important;
    color: var(--color-text-on-primary) !important;
}

.btn-primary:hover,
.btn-search:hover,
.btn-submit:hover,
.btn-save:hover {
    background-color: var(--brand-primary-hover) !important;
    border-color: var(--brand-primary-hover) !important;
}

.btn-primary:active,
.btn-primary.active,
.btn-search:active,
.btn-submit:active,
.btn-save:active {
    background-color: var(--brand-primary-active) !important;
    border-color: var(--brand-primary-active) !important;
}

/* Figma: bg-button-primary-disabled = neutral/100, fg = neutral/400.
   Trước đây dùng --brand-primary-disabled (primary/300) - đỏ nhạt, trông
   như nút vẫn bấm được.                          [R05] [UI_06.1] */
.btn-primary:disabled,
.btn-primary.disabled,
.btn-search:disabled,
.btn-submit:disabled,
.btn-save:disabled {
    background-color: var(--color-neutral-100) !important;
    border-color: var(--color-neutral-100) !important;
    color: var(--color-neutral-400) !important;
    cursor: not-allowed;
}

/* Nút phụ: nền trắng viền xám, KHÔNG dùng đỏ để không tranh cấp
   với hành động chính.                                  [UI_07.1] */
.btn-white,
.btn-default,
.btn-cancel {
    background-color: var(--color-bg-surface) !important;
    border: 1px solid var(--color-border-primary) !important;
    color: var(--color-text-primary) !important;
}

.btn-white:hover,
.btn-default:hover,
.btn-cancel:hover {
    background-color: var(--color-bg-subtle) !important;
    border-color: var(--color-border-primary) !important;
}

.btn-outline-vt {
    background-color: transparent !important;
    border: 1px solid var(--brand-primary) !important;
    color: var(--brand-primary) !important;
}

.btn-outline-vt:hover {
    background-color: var(--color-primary-50) !important;
}

.btn-danger {
    background-color: var(--color-danger-600) !important;
    border-color: var(--color-danger-600) !important;
    color: var(--color-text-on-primary) !important;
}

.btn-table {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    min-height: 32px;
    padding: var(--space-1);
    border-radius: var(--radius-sm);
    background: transparent;
    border: none;
    color: var(--color-text-secondary);
    transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

/* Loại trừ .active/.noactive: đây không phải nút bấm mà là ô vuông chỉ trạng thái
   Hoạt động/Khóa ở cột Trạng thái (managerUserList.jsp, adInformationUserList.jsp).
   Dùng :not() thay vì viết rule đè, để màu riêng của từng biến thể (.btn-table.active,
   .btn-table.noactive trong layout.css) giữ nguyên mà không phải chép lại mã màu.

   KHÔNG đổi background-color: icon thao tác trong bảng (xem/sửa/xoá...) chỉ
   cần phản hồi bằng mờ đi (layout.css: .btn-table:hover { opacity: .7 }),
   không cần thêm khối nền xám sau icon - yêu cầu bỏ hẳn hiệu ứng đổi nền khi
   hover, giữ nguyên màu icon riêng của từng biến thể (.edit/.refresh/.delete...). */
.btn-table:not(.active):not(.noactive):hover {
    background-color: transparent;
}

/* Nút thao tác Form: đệm padding 20px thưa thoáng, nền trong suốt không bị lồi viền hay thừa đường kẻ */
.form-actions-sticky,
.form-actions {
    position: relative !important;
    background-color: transparent !important;
    border: none !important;
    border-top: none !important;
    border-bottom: none !important;
    box-shadow: none !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    /* padding-top: 20px !important; */
    padding-bottom: 20px !important;
    /* margin-top: 16px !important; */
    margin-bottom: 0 !important;
}

.form-actions-sticky .form-group,
.form-actions .form-group {
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
}

.form-actions-sticky,
.form-actions-sticky .form-group,
.form-actions-sticky .vt-align-center,
.form-actions,
.form-actions .form-group,
.form-actions .vt-align-center,
.panel-footer,
.modal-footer {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 12px !important;
    flex-wrap: wrap !important;
}

.form-actions-sticky .btn,
.form-actions .btn,
.panel-footer .btn,
.modal-footer .btn {
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* -------------------------------------------------------------
 * 7. Ô nhập liệu             [UI_02.1] [UI_02.3] [UI_06.1]
 * Theme cũ: góc vuông, viền 1px xám đậm, không có trạng thái focus
 * rõ ràng. Đưa về bo 8px + viền token + vòng focus thương hiệu + chiều cao 40px chuẩn.
 * ------------------------------------------------------------- */
.form-control,
.custom-input,
select,
select.form-control,
.select2-container .select2-selection--single,
.vt-form-control,
.datePickerInput,
.vt-dtp-input,
.bootstrap-select .dropdown-toggle,
.bootstrap-tagsinput,
.org-selector-input,
.form-select-custom,
.select2Menu,
.select2Action {
    font-family: var(--font-family-base);
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
    /* Không có class nào ở đây tự khai font-weight nên mỗi loại control lại
       ăn theo UA stylesheet của chính nó (input/select thường 400, nhưng
       .select2-selection__rendered là <span> nằm trong text bình thường của
       trang nên có thể thừa hưởng weight khác nếu ancestor đổi). Khai cứng
       400 để input thường và ô ngày (readonly, xem rule riêng bên dưới)
       chắc chắn cùng một weight, không lệ thuộc ngữ cảnh render. */
    font-weight: 400;
    color: var(--color-text-primary);
    background-color: var(--color-bg-field, var(--color-bg-surface));
    border: 1px solid var(--color-border-primary);
    border-radius: var(--radius-md) !important;
    padding: var(--space-2) var(--space-3);
    height: 40px !important;
    min-height: 40px !important;
    max-height: 40px !important;
    box-sizing: border-box !important;
    box-shadow: none;
    transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

textarea.form-control {
    height: auto !important;
    min-height: 80px !important;
    max-height: none !important;
}

/* Hover: viền đen đậm hơn + quầng xám nhạt, đồng bộ với trạng thái focus. */
.form-control:hover:not(:disabled):not([readonly]) {
    border-color: var(--color-neutral-900);
    box-shadow: var(--focus-ring-gray);
}

/* readonly khác disabled: input vẫn submit được giá trị (cần cho userName lúc
   update - đổi sang disabled thì mất giá trị khi submit form), nhưng vẫn cho
   click/focus bằng chuột dù không gõ được, gây cảm giác "bấm được mà không
   làm gì". Chặn hẳn click bằng pointer-events, giữ nguyên attribute readonly
   để form vẫn gửi value như cũ.
   KHÔNG áp dụng chung cho mọi .form-control[readonly]: bộ chọn ngày/giờ dùng
   chính readonly + click để MỞ panel (dpReadonly - xem datePicker.jsp,
   "chỉ cho chọn bằng panel, không gõ tay"), chặn pointer-events ở đó sẽ làm
   panel hết mở được. Scope riêng theo #userName. */
#userName[readonly]:not(:disabled) {
    pointer-events: none;
    cursor: not-allowed;
}

/* pointer-events: none làm input KHÔNG BAO GIỜ là mục tiêu hit-test của chuột
   nữa, nên cursor khai trên chính nó (dòng trên) không được trình duyệt vẽ ra -
   khi rê chuột, trình duyệt "xuyên qua" input và tính cursor theo phần tử NẰM
   DƯỚI nó, tức là div bọc ngoài. Phải khai not-allowed lần nữa ở đúng phần tử
   thực sự nhận hit-test đó thì con trỏ mới hiện đúng. */
.wrap-input100:has(> #userName[readonly]:not(:disabled)) {
    cursor: not-allowed;
}

/* readonly/disabled: các rule :focus/:focus-visible bên dưới đều loại trừ hai
   trạng thái này để không còn viền/quầng nào - nhưng "không set gì" lại để lộ
   outline xanh mặc định của trình duyệt (Chrome/Edge) khi click hoặc Tab vào ô
   readonly (readonly vẫn nhận focus được, khác disabled). Tắt hẳn outline
   riêng ở đây, tách khỏi rule :focus phía dưới. */
.form-control:focus:disabled,
.form-control:focus[readonly] {
    outline: none;
}

/* Focus: đồng bộ với hover - viền đen đậm + quầng xám thay vì đỏ thương hiệu,
   tránh nhầm với trạng thái lỗi (cũng dùng tông đỏ).           [R06]
   :not([readonly]) vì readonly (khác disabled) vẫn nhận được focus bằng click/
   tab - ô như userName lúc update (readonly, không cho gõ) không nên nổi viền
   ring như đang cho phép sửa. */
.form-control:focus:not(:disabled):not([readonly]),
.select2-container--focus .select2-selection--single {
    border-color: var(--color-neutral-900);
    box-shadow: var(--focus-ring-gray);
    outline: none;
}

/* Trạng thái lỗi.                              [R02] [R06] [UI_04.2]
   Figma cho viền báo lỗi (error/600 = #DC2626) TRÙNG đúng màu viền
   thương hiệu (primary/500 = #DC2626) - không phân biệt được bằng màu.
   Nó dồn việc phân biệt sang quầng: focus 3px #FDD7D7, lỗi 4px #FECACA.
   Trước đây ta mới làm một nửa - focus có quầng, lỗi không có gì.

   .wrap-input100.alert-validate là khuôn validate của các form JSP;
   .has-error là của Bootstrap. Gom cả hai cho nhất quán. */
.form-control.is-invalid,
.has-error .form-control,
.wrap-input100.alert-validate .form-control {
    border-color: var(--color-danger-600);
}

/* :not([readonly]) cùng lý do với .form-control:focus ở trên: ô readonly (như
   userName lúc update) vẫn có thể mang class alert-validate/is-invalid từ lúc
   trước đó, nhưng không cho gõ thì không nên nổi viền+quầng đỏ khi bấm vào. */
.form-control.is-invalid:focus:not(:disabled):not([readonly]),
.has-error .form-control:focus:not(:disabled):not([readonly]),
.wrap-input100.alert-validate .form-control:focus:not(:disabled):not([readonly]) {
    border-color: var(--color-danger-600);
    box-shadow: var(--focus-ring-error);
    outline: none;
}

.form-control::placeholder {
    color: var(--color-text-muted);
    opacity: 1;
}

/* select2 vẽ placeholder bằng <span> chứ không dùng thuộc tính placeholder,
   nên rule ::placeholder ở trên không với tới. Mặc định #999 = 2.85:1 trên
   nền trắng, dưới ngưỡng AA. neutral-500 cho 4.83:1.          [UI_04.2]

   Cùng một cái bẫy ở mục 4.5 của HANDOVER, lần trước sót chỗ này:
   select2.min.css khai
     .select2-container--default .select2-selection--single .select2-selection__placeholder
   với độ đặc hiệu 0,3,0 và nạp ở chỉ số 45, SAU file này (36). Rule cũ ở đây
   chỉ 0,1,0 nên thua cả về đặc hiệu lẫn thứ tự - đo trên màn Sao lưu dự phòng
   vẫn ra #999 (2.85:1). Nâng đặc hiệu bằng nhau và thêm !important. */
.select2-container .select2-selection--single .select2-selection__placeholder,
.select2-container--default .select2-selection--single .select2-selection__placeholder {
    color: var(--color-text-muted) !important;
}

.form-control:disabled,
.form-control[readonly] {
    background-color: var(--color-bg-subtle);
    color: var(--color-text-secondary);
    cursor: not-allowed;
}

/* select2 thay <select> gốc bằng div .select2-selection riêng để hiển thị, nên
   select gốc bị disabled (managerUserForm.jsp ở chế độ Xem chi tiết, và bất kỳ
   form nào khác dùng select2 cho ô chỉ đọc) không tự kéo theo nền xám như input
   text/textarea - select2 tự thêm class "select2-container--disabled" lên
   container khi gốc bị disabled, dùng lại đúng token màu của rule trên.
   Cần !important + gộp cả 2 class "select2-container" và "select2-container--disabled"
   trên cùng phần tử (độ đặc hiệu 0,3,0): mục 18 "Dropdown select2 khi mở" ở dưới
   (dòng ~1742) đặt background-color !important cho .select2-container
   .select2-selection--single với độ đặc hiệu chỉ 0,2,0 nhưng nằm SAU trong file nên
   vẫn thắng nếu rule này chỉ ngang bằng độ đặc hiệu. */
.select2-container.select2-container--disabled .select2-selection {
    background-color: var(--color-bg-subtle) !important;
    cursor: not-allowed;
}

/* Ô ngày/giờ (.vt-dtp-input) dùng readonly + click để MỞ panel, không phải
   readonly "khoá không cho sửa" như #userName - về bản chất nó vẫn là một ô
   đang cho phép nhập (qua panel) nên không nên nhuốm màu/nền/cursor mờ của
   rule readonly chung ở trên, khiến nó trông xám/khác trọng số so với các ô
   nhập liệu còn lại trong cùng form (vd: backupPolicyForm - Thời điểm sao
   lưu). Đặc hiệu 0,0,3,0 - cao hơn .form-control[readonly] (0,0,2,0) nên
   thắng bất kể thứ tự nạp. */
.form-control.vt-dtp-input[readonly] {
    background-color: var(--color-bg-field, var(--color-bg-surface));
    color: var(--color-text-primary);
    cursor: pointer;
}

/* Checkbox tuỳ biến (.checkbox-custom, vd managerUserSearchForm.jsp - "Tài
   khoản voffice"): site.min.css khai cứng `.checkbox-custom label { cursor:
   pointer }` cho label vẽ ô vuông, không loại trừ trường hợp input bên trong
   bị disabled - hover vào vẫn hiện tay bấm được y hệt lúc enable dù click
   không có tác dụng gì. */
.checkbox-custom:has(input:disabled) label,
.radio-custom:has(input:disabled) label {
    cursor: not-allowed !important;
}

/* Nhãn text đứng ngoài (vd label[for="createUser"] "Tài khoản voffice") gắn
   for để bấm chữ cũng toggle được checkbox - cùng lý do trên, khi input đích
   bị disabled thì nhãn này cũng phải thôi hiện cursor:pointer. :has() dò theo
   toàn bộ hàng .form-group.row vì nhãn và input không phải anh em trực tiếp. */
.form-group.row:has(#createUser:disabled) label[for="createUser"] {
    cursor: not-allowed !important;
}

/* --- select2: căn giữa theo chiều dọc trong ô cao 40px ---  [UI_03.1]
   select2 dựng sẵn cho ô cao 36px: .select2-selection__rendered mang
   line-height 36px, còn .select2-selection__arrow neo cứng top:1px;height:26px.
   Khi khối .select2-selection--single nhận padding 8px + min-height 40px của
   rule .form-control ở trên thì:
     - chữ "--Chọn--" bị đẩy xuống, tâm lệch +6.7px so với tâm ô
     - mũi tên và dấu × dính lên trên, tâm lệch -3.5px
   Bỏ padding của khối bao, giao padding ngang cho phần tử con, và cho
   mũi tên cao 100% để tự căn giữa. Sau khi sửa cả ba lệch <= 0.3px.

   Bắt buộc !important cho arrow/clear vì hai lý do:
     - layout.css khai .select2-selection__arrow { height: 31px !important }
     - select2.min.css nạp SAU file này, cùng độ đặc hiệu 0,3,0 nên thắng
       theo thứ tự với top:1px.
   Riêng __rendered thì không cần, để nguyên không !important. */
.select2-container,
.bootstrap-select {
    width: 100% !important;
}

.select2-container .select2-selection--single {
    height: 40px !important;
    min-height: 40px !important;
    box-sizing: border-box !important;
    padding: 0;
}

.select2-container .select2-selection--single .select2-selection__rendered {
    height: 38px !important;
    line-height: 38px !important;
    display: flex !important;
    align-items: center !important;
    padding: 0 46px 0 var(--space-3);
}

/* select2.min.css khai .select2-selection__rendered { color: #444 } - đặc hiệu
   thấp hơn nhưng vẫn đè được vì khối .select2-selection--single ở trên chỉ set
   color cho container ngoài, span text bên trong bị vendor ghi đè, không kế
   thừa. Text giá trị đã chọn (không phải placeholder, đã xử lý riêng ở dưới)
   vẫn ra #444 xám thay vì token. dark-mode.css đã vá cho chế độ tối
   (html[data-theme="dark"] ...__rendered), thiếu bản chế độ sáng ở đây. [UI_04.2] */
.select2-container .select2-selection--single .select2-selection__rendered {
    color: var(--color-text-primary) !important;
}

.select2-container .select2-selection--single .select2-selection__placeholder,
.select2-container--default .select2-selection--single .select2-selection__placeholder {
    display: flex !important;
    align-items: center !important;
    height: 38px !important;
    line-height: 38px !important;
    margin: 0 !important;
}

.select2-container .select2-selection--multiple,
.select2-container--default .select2-selection--multiple {
    min-height: 40px !important;
    box-sizing: border-box !important;
    display: flex !important;
    align-items: center !important;
    padding: 2px 8px !important;
}

.select2-container .select2-selection--multiple .select2-search--inline,
.select2-container--default .select2-selection--multiple .select2-search--inline {
    display: flex !important;
    align-items: center !important;
    height: 32px !important;
    margin: 0 !important;
    padding: 0 !important;
}

.select2-container .select2-selection--multiple .select2-search__field,
.select2-container--default .select2-selection--multiple .select2-search__field {
    height: 32px !important;
    line-height: 32px !important;
    margin: 0 !important;
    padding: 0 !important;
    font-size: 14px !important;
}

.select2-container .select2-selection--single .select2-selection__arrow {
    top: 0 !important;
    height: 100% !important;
    right: var(--space-2) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Nút × xóa lựa chọn (allowClear). Không đặt màu thì dấu × thừa hưởng màu chữ của
   .select2-selection__rendered nên đen ngang giá trị đã chọn, trông như một phần
   nội dung chứ không phải nút phụ trợ -> để màu ghi, hover mới đậm lên. */
.select2-container .select2-selection--single .select2-selection__clear {
    position: absolute !important;
    top: 0 !important;
    right: 28px !important;
    height: 38px !important;
    line-height: 38px !important;
    margin: 0 !important;
    padding: 0 !important;
    color: var(--color-text-muted, #6B7280) !important;
    transition: color .15s ease-in-out;
}

.select2-container .select2-selection--single .select2-selection__clear:hover,
.select2-container .select2-selection--single .select2-selection__clear:focus {
    /* color: var(--color-text-primary, #111827) !important; */
    outline: none;
}

/* Nhóm ô ngày tháng: nút lịch phải liền khối với ô nhập  [UI_02.1] */


/* Nút icon lịch.                                     [UI_02.3] [UI_07.1]
   UI_07.1: "Icon datepicker BỎ NỀN, mũi tên thay icon nhạt hơn"
   UI_02.3: "Icon thiếu tối giản >> tham khảo design system"

   Spec Figma (agents/figma_clone/Datepicker.css):
     Input              padding 10px 12px · border 1px #C3C8D0 · radius 8px · gap 8px
     Button icon tablet 38x38 · padding 9px · background #FFFFFF · radius 8px
   -> nút icon KHÔNG có viền riêng, là ô vuông 38px bo 8px tách khỏi ô nhập
   một khoảng 8px, chứ không dính liền thành một khối như bản cũ.

   Bản trước tôi làm ngược hẳn: thêm nền xám VÀ dính liền bằng border-left:none.
   Nay bỏ cả hai. */
.input-group .input-group-addon,
.input-group .input-group-btn>.btn {
    border: none;
    border-radius: var(--radius-md);
    background-color: transparent;
    color: var(--color-text-muted);
    width: 38px;
    min-width: 38px;
    height: 38px;
    min-height: 38px;
    padding: 9px;
    margin-left: var(--space-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Ô ngày lấy lại bo góc đủ bốn phía - bản cũ vuông mép phải để dính vào nút.
   Selector phải khớp đúng dạng của Bootstrap: nó khai
   `.input-group > .form-control:not(:last-child) { border-radius: 0 }` với đặc
   hiệu 0,3,0, thắng `.input-group .form-control` (0,2,0). Dùng cùng đặc hiệu thì
   file này nạp sau (36 so với 7) nên thắng theo thứ tự. */
.input-group>.form-control,
.input-group>.form-control:not(:last-child) {
    border-radius: var(--radius-md);
}

/* Mũi tên select2 nhạt hơn - cùng yêu cầu UI_07.1. select2.min.css nạp SAU
   file này nên bắt buộc !important (xem HANDOVER 4.5).            [UI_07.1] */
.select2-container--default .select2-selection--single .select2-selection__arrow b {
    border-top-color: var(--color-text-muted) !important;
}

/* -------------------------------------------------------------
 * 8. Bảng dữ liệu                       [UI_02.3] [UI_03.1]
 * Bỏ bớt đường kẻ (audit: "nhiều khung viền lớp kiểu cũ"), giữ kẻ
 * ngang phân dòng. Đầu bảng nền xám nhạt thay vì viền đậm.
 * ------------------------------------------------------------- */
.table>thead>tr>th {
    background-color: var(--color-bg-subtle);
    color: var(--color-text-primary);
    font-weight: 600;
    text-transform: none;
    border-bottom: 1px solid var(--color-border-primary);
    border-top: none;
    padding: var(--space-3);
    vertical-align: middle;
}

.table>tbody>tr>td {
    border-top: 1px solid var(--color-border-subtle);
    padding: var(--space-3);
    color: var(--color-text-primary);
    vertical-align: middle;
}

/* Khung ngoài bo góc 4px, bên trong chỉ còn kẻ ngang phân dòng.
   Khung dùng --color-border-primary (đậm hơn kẻ phân dòng đang là
   --color-border-subtle) để đọc ra là khung bao chứ không lẫn vào đường kẻ.

   border-collapse: separate là BẮT BUỘC để bo được góc - ở chế độ collapse
   (main.css:249 đặt cho mọi <table>) trình duyệt vẽ viền hợp nhất theo đường
   thẳng và bỏ qua hoàn toàn border-radius.

   Đổi sang separate thì viền các ô không hợp nhất nữa, nên mỗi đường kẻ ngang
   phải có đúng MỘT chủ. Nếu không, `.table-bordered td, .table-bordered th
   { border: 1px }` của style.min.css/main.css sẽ vẽ chồng lên kẻ phân dòng
   thành 2px ở mọi hàng, và cạnh trái/phải của từng ô sẽ hiện lại thành lưới
   dọc. Vì vậy phải liệt kê tường minh từng cạnh dưới đây. */
.table-bordered {
    border: 1px solid var(--color-border-primary);
    border-radius: var(--radius-sm);
    border-collapse: separate;
    border-spacing: 0;
}

/* Đầu bảng giữ kẻ dưới */
.table-bordered>thead>tr>th {
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--color-border-primary);
}

/* Thân bảng giữ kẻ trên (khai ở .table>tbody>tr>td phía trên) làm kẻ phân dòng;
   cạnh dưới của hàng cuối đã là viền dưới của bảng. */
.table-bordered>tbody>tr>td {
    border-left: none;
    border-right: none;
    border-bottom: none;
}

/* Hàng đầu tiên không cần kẻ trên: đã có kẻ dưới của đầu bảng, hoặc viền trên
   của bảng khi không có <thead>. */
.table-bordered>tbody>tr:first-child>td {
    border-top: none;
}

/* Cột "Thao tác" ghim phải (.sticky-col-r0, layout.css) mất viền phải: mọi ô
   .table-bordered đã bị bỏ border-left/right ở 2 rule phía trên, cả bảng chỉ
   còn dựa vào viền NGOÀI của chính thẻ <table> để khép mép phải. Nhưng cột ghim
   là position: sticky, nền trắng đặc + z-index: 3 (layout.css) nên vẽ đè lên
   đúng đường viền ngoài đó suốt chiều cao cột - nhìn như bị mất viền. Trả lại
   viền phải riêng cho chính cột ghim để nó luôn tự khép mép, không phụ thuộc
   viền ngoài bảng đang bị nó che khuất. */
.table-bordered .sticky-col-r0 {
    border-right: 1px solid var(--color-border-primary);
}

/* Nền của ô (đầu bảng xám, sọc .table-striped) là hình chữ nhật đặc và không tự
   theo bo góc của bảng - phải bo riêng 4 ô ở góc, không thì nền thò ra ngoài
   đường viền cong. Dự án không dùng <tfoot> nên tbody:last-child là hàng cuối. */
.table-bordered>thead>tr:first-child>th:first-child {
    border-top-left-radius: var(--radius-sm);
}

.table-bordered>thead>tr:first-child>th:last-child {
    border-top-right-radius: var(--radius-sm);
}

.table-bordered>tbody>tr:last-child>td:first-child {
    border-bottom-left-radius: var(--radius-sm);
}

.table-bordered>tbody>tr:last-child>td:last-child {
    border-bottom-right-radius: var(--radius-sm);
}

.table-hover>tbody>tr:hover {
    background-color: var(--color-bg-subtle);
}

/* -------------------------------------------------------------
 * 9. Trạng thái rỗng                              [UI_04.4]
 * Audit: "Sử dụng màu đỏ cho text nội dung bình thường >> dùng màu
 * text bình thường và nhạt". Không tìm thấy bản ghi KHÔNG phải lỗi.
 * Dùng chung cho markup tĩnh và chuỗi HTML sinh trong JS.
 * ------------------------------------------------------------- */
.sso-empty-state {
    /* Đổi từ text-secondary sang text-primary (#111827) theo yêu cầu ngày
       07/08/2026: dòng "Không tồn tại bản ghi." phải là chữ đen như nội dung
       thường. Vẫn dùng token nên chế độ tối tự lấy #E7EAEE. */
    color: var(--color-text-primary);
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
    text-align: center;
    padding: var(--space-4) 0;
}

/* Bỏ icon cảnh báo đi kèm - trạng thái rỗng không phải cảnh báo */
.sso-empty-state .glyphicons,
.sso-empty-state .fa-warning,
.sso-empty-state .fa-exclamation-triangle {
    display: none;
}

/* layout.css (legacy) đặt .fa { font-weight: 800 }. FontAwesome 4 chỉ có 1 nét
   (normal) nên trình duyệt phải "faux-bold" - làm mọi glyph dày lên bất thường,
   lộ rõ nhất ở icon mũi tên (nút "Quay lại"). Trả riêng nhóm mũi tên về đúng nét
   gốc; .fa.fa-* có độ đặc hiệu cao hơn .fa của layout.css. */
.fa.fa-arrow-left,
.fa.fa-arrow-right,
.fa.fa-arrow-up,
.fa.fa-arrow-down,
.fa.fa-long-arrow-left,
.fa.fa-long-arrow-right,
.fa.fa-long-arrow-up,
.fa.fa-long-arrow-down {
    font-weight: 400;
}

/* -------------------------------------------------------------
 * 10. Liên kết                          [UI_01.1] [UI_04.4]
 * Theme cũ dùng #295d9f / #0ea6c8 / #31c0be - không thuộc bảng màu
 * thương hiệu. Đưa về đỏ Viettel, gạch chân khi hover.
 * ------------------------------------------------------------- */
a {
    /* color: var(--brand-primary); */
    transition: color .15s ease-in-out;
}

a:hover,
a:focus {
    color: var(--brand-primary-hover);
    text-decoration: underline;
}

/* Liên kết trong bảng hồ sơ vốn bị ép #295d9f !important */
.cover-content a {
    color: var(--brand-primary) !important;
}

/* -------------------------------------------------------------
 * 11. Khoảng cách theo bội số 4                   [UI_03.4]
 * Audit: "sử dụng bội số của 4 tham khảo Google M3".
 * ------------------------------------------------------------- */
.form-group {
    margin-bottom: var(--space-4);
}

.panel {
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border-subtle);
    box-shadow: none;
    margin-bottom: var(--space-2);
}

/* Audit L2 25/08/2026: margin-bottom ở trên chỉ có ý nghĩa khi còn .panel khác
   xếp ngay dưới (vd panel tìm kiếm rồi tới panel danh sách) - khi .panel là
   phần tử cuối cùng trong khối cha (không còn gì bên dưới để tạo khoảng cách,
   như panel form "Thêm mới người dùng") thì margin-bottom chỉ tạo khoảng trắng
   thừa cuối trang. Bỏ riêng cho trường hợp cuối, giữ nguyên khoảng cách giữa
   các .panel xếp chồng ở những màn khác. */
.panel:last-child {
    margin-bottom: 0;
}

/* Audit L2 20/08/2026 [UI_03.4]: 20px (--space-5) bị chê "quá lớn" so với
   nội dung - hạ xuống mốc kế tiếp của thang bội-4 là 16px (--space-4). */
.panel-body {
    padding: var(--space-4);
}

/* site.min.css có .page-content { padding: 30px } (theme cũ, không sửa trực
   tiếp file minify) - cùng lỗi "padding quá lớn" như .panel-body ở trên,
   đây là lớp bọc NGOÀI CÙNG mọi trang (đồng cấp, đứng trước .panel-body
   trong cây DOM), nên đổi theo cùng mốc 16px cho nhất quán.       [UI_03.4] */
.page-content {
    padding: var(--space-4);
}

/* site.min.css có .panel-heading + .panel-body { padding-top: 0 } với độ đặc
   hiệu 0,2,0, thắng .panel-body ở trên. Khi thanh tiêu đề chưa có đường kẻ
   thì không ai để ý, nhưng từ lúc thêm border-bottom cho .panel-heading thì
   viền trên của ô nhập đầu tiên nằm chồng đúng lên đường kẻ đó.
   Khai báo lại cùng độ đặc hiệu, file này nạp sau nên thắng.     [UI_03.4] */
.panel-heading+.panel-body {
    padding-top: var(--space-4);
}

/* Audit L2 25/08/2026: bảng "Danh sách người dùng" (managerUserList.jsp) lệch phải,
   không nằm giữa khối panel. #searchResult .panel-body có inline
   overflow-x:auto; padding-right:0 - cố ý bỏ padding phải để cột dính bên phải
   (.sticky-col-r*) canh đúng "right: 0" theo mép vùng cuộn, không lệch 16px như
   padding-left. Không bỏ padding-right:0 đó (sẽ làm lệch vị trí cột dính), mà bù
   khoảng trống 16px ra phần tử BỌC NGOÀI (.table-scroll-wrap, không cuộn, không
   ảnh hưởng "right: 0" bên trong) để bảng lại đối xứng trái/phải trong panel.

   padding-left cùng mốc 16px: bảng rộng hơn panel (min-width: 900px, table-scroll-
   wrap luôn hẹp hơn) nên mặc định bị cuộn ngang, ẩn bớt vài cột đầu (STT, Tên
   nhóm...) - khi đó mép trái bảng cũng cần đúng 16px đệm với nền panel như mép
   phải, không được để bảng chạm sát viền trái khi cuộn hết cỡ. */
.table-scroll-wrap {
    padding-left: var(--space-4);
    padding-right: var(--space-4);
}

/* .table-scroll-wrap::before (layout.css) là dải bóng mờ báo còn cột bị khuất
   bên trái khi cuộn, left: 0 mặc định tính theo mép padding-box của chính
   .table-scroll-wrap. Từ khi khối này có padding-left ở trên, mép đó không còn
   trùng mép trái thật của bảng nữa (lùi ra ngoài đúng bằng padding-left) - phải
   dịch vào lại cùng mốc 16px để bóng mờ bám đúng theo bảng, không dính vào mép
   khối cha bên ngoài. */
.table-scroll-wrap::before {
    left: var(--space-4);
}

.panel-heading {
    padding: var(--space-3) var(--space-3);
    /* Đo trên DOM ra ~48.67px thay vì đúng 48 (cùng dạng lệch số lẻ 0.67px đã gặp
       ở .sso-breadcrumb-bar/.sso-search-heading/.panel-heading-toolbar) - riêng
       khối có thêm border-top (vd. heading thứ 2 trở đi trong
       backupPolicyDetail.jsp) còn cộng thêm 0.67px nữa từ chính viền đó. Ép
       height cứng + box-sizing: border-box để border/padding/nội dung luôn gói
       gọn trong đúng 48px bất kể có thêm viền hay không. */
    height: 48px;
    box-sizing: border-box;
}

/* Dải tiêu đề có nút hành động phải cao bằng dải chỉ có chữ: 48px.
   .panel-heading không đặt chiều cao, nó bằng padding trên/dưới cộng nội dung
   cao nhất. Dải chỉ có chữ: 12 + 24 (--font-line-h5) + 12 = 48px.
   Dải có nút: nút giữ đúng chuẩn 40px [UI_02.2], nên padding dọc phải hạ xuống
   4px để ra 4 + 40 + 4 = 48px. Đệm 4px là mức tối đa mà trần 48px cho phép khi
   không thu nhỏ nút. Padding ngang giữ 12px để mép chữ thẳng với các dải khác.
   Không đặt trên .panel-heading chung: dải chỉ có chữ vẫn cần 12px mới đủ 48. */
.panel-heading.panel-heading-toolbar {
    padding: var(--space-1) var(--space-3);
    /* Đo trên DOM ra ~48.67px thay vì đúng 48 - cùng dạng lệch số lẻ 0.67px đã gặp
       ở .sso-breadcrumb-bar/.sso-search-heading (phép cộng padding+nội dung+viền
       không khớp trên thực tế). Dùng min-height (KHÔNG phải height cứng) để vẫn
       chốt đúng chuẩn 48px khi toolbar nằm gọn 1 hàng, nhưng cho dải cao thêm khi
       .panel-heading-actions bị đẩy xuống dòng ở màn hẹp (flex-wrap: wrap khai ở
       layout.css). height: 48px cứng trước đây khiến hàng nút thứ 2 tràn ra ngoài
       header, đè lên bảng bên dưới và cắt nút cuối ở mép phải panel. */
    min-height: 48px;
    height: auto;
    box-sizing: border-box;
}

/* -------------------------------------------------------------
 * 12. Lịch chọn ngày (jQuery UI)        [UI_02.1] [UI_01.1]
 * Ảnh lỗi UI_02.1: nhiều lớp khung viền, góc vuông, ô "hôm nay"
 * màu cam không thuộc bảng màu.
 *
 * Spec lấy từ agents/figma_clone/Datecell.css và Datepicker.css:
     Khung lịch  nền #FFFFFF · Shadow lg
     Ô ngày      39x40 · padding 10px 16px · radius 8px
                 chữ Inter 400 14px #374151
     hover       nền #F6F7F9
     ngoài tháng chữ #C3C8D0
     đang chọn   nền #B9000E · chữ #FFFFFF
     hôm nay     nền #FEF2F2 · chữ #DC2626

   Bản trước mới đúng phần khung và màu trạng thái; lưới ngày vẫn giữ kích
   thước mặc định của jQuery UI và bo 4px, nên nhìn vẫn là lịch kiểu cũ. */
/* Phải viết `.ui-datepicker.ui-widget` (0,2,0) chứ không phải `.ui-datepicker`
   (0,1,0): custom-widget.css khai đúng dạng hai class đó với
   `box-shadow: rgba(0,0,0,.5) 0 5px 15px -5px` và `padding: 2px 8px 8px 0`,
   nên bản trước bị đè hoàn toàn - khung lịch vẫn bóng đen kiểu cũ. */
.ui-datepicker,
.ui-datepicker.ui-widget {
    /* Viền neutral-100 (#F0F2F4), KHÔNG phải neutral-200 - Figma ghi rõ. */
    border: 1px solid var(--color-neutral-100);
    /* Thống nhất độ cong theo chuẩn radius-md (8px) cho input / datepicker */
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    background: var(--color-bg-surface);
    padding: 20px 24px;
    font-family: var(--font-family-base);
    font-size: var(--font-size-body);
    width: 321px;
    box-sizing: border-box;
}

/* Thanh điều khiển tháng/năm. Spec Figma "Month and year controls":
     hàng ngang · space-between · căn giữa · rộng 273
     nút chevron  "Button icon tablet" 38x38 · padding 9px · nền #FFFFFF · bo 8px
     cụm tháng+năm  hàng ngang · gap 12px
     chữ tháng/năm  "Body small/Semibold" = Inter 600 16px/22 · màu #374151

   Bản trước chỉ bỏ nền và viền của header, chưa đụng nút mũi tên lẫn ô chọn
   tháng/năm - nên phần trên của lịch vẫn nguyên kiểu jQuery UI mặc định. */
.ui-datepicker .ui-datepicker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: transparent;
    border: none;
    color: var(--color-neutral-700);
    padding: 0 0 var(--space-3);
    margin: 0;
}

/* Hai nút mũi tên: vuông 38px bo 8px, nền trắng, không viền - cùng khuôn với
   nút icon lịch ở ô nhập. jQuery UI mặc định định vị absolute và gắn nền
   gradient, phải huỷ cả hai. */
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next,
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
    position: static;
    top: auto;
    left: auto;
    right: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 9px;
    margin: 0;
    border: none;
    border-radius: var(--radius-md);
    background: var(--color-bg-surface);
    color: var(--color-neutral-700);
    cursor: pointer;
}

.ui-datepicker .ui-datepicker-prev:hover,
.ui-datepicker .ui-datepicker-next:hover {
    background: #F6F7F9;
}

/* Cụm "Tháng 6" + "2026" */
.ui-datepicker .ui-datepicker-title {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    margin: 0;
    line-height: 22px;
}

/* Ô chọn tháng và năm. jQuery UI dựng <select> khi bật changeMonth/changeYear.
   Bỏ khung select mặc định, giữ đúng kiểu chữ Body small/Semibold. */
.ui-datepicker .ui-datepicker-title select,
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
    width: auto;
    min-height: 0;
    margin: 0;
    padding: var(--space-1) var(--space-2);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    font-family: var(--font-family-base);
    font-size: var(--font-size-h5);
    line-height: 22px;
    font-weight: 600;
    color: var(--color-neutral-700);
    cursor: pointer;
}

.ui-datepicker .ui-datepicker-title select:hover {
    background: #F6F7F9;
}

.ui-datepicker .ui-datepicker-title select:focus {
    border-color: var(--color-border-brand);
    box-shadow: var(--focus-ring-brand);
    outline: none;
}

/* Lưới ngày rộng đúng 273px theo Figma (321 trừ padding ngang 24x2), chia đều
   7 cột -> mỗi ô 39px. Không đặt width thì bảng co lại theo nội dung, đo được
   chỉ 31.3px mỗi ô. */
.ui-datepicker table {
    margin: 0;
    width: 100%;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
}

/* Nhãn thứ: Figma dùng textStyle "Caption large/Medium" = Inter 500 14px/20,
   màu #374151 (neutral-700) - cùng màu với số ngày, không nhạt hơn. */
.ui-datepicker th {
    padding: 0;
    height: 40px;
    font-size: var(--font-size-body);
    line-height: 20px;
    font-weight: 500;
    color: var(--color-neutral-700);
    border: none;
    text-align: center;
}

.ui-datepicker td {
    padding: 0;
    border: none;
}

/* Ô ngày theo đúng spec: 39x40, bo 8px, canh giữa bằng flex thay vì
   text-align + line-height của theme cũ.

   Kèm biến thể .ui-state-default vì custom-widget.css khai
   `.ui-datepicker .ui-state-default { color: #333 }` với đặc hiệu 0,2,0,
   thắng `.ui-datepicker td a` (0,1,1) của bản trước. */
.ui-datepicker td a,
.ui-datepicker td span,
.ui-datepicker td a.ui-state-default,
.ui-datepicker td span.ui-state-default {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--font-size-body);
    line-height: 20px;
    font-weight: 400;
    color: var(--color-neutral-700);
    background: transparent;
    text-align: center;
    box-sizing: border-box;
}

/* #F6F7F9 là giá trị Figma, không có trong thang tokens.css - nó nằm giữa
   neutral-50 (#F9FAFB) và neutral-100 (#F0F2F4). Giữ nguyên số của Figma. */
.ui-datepicker td a:hover {
    background: #F6F7F9;
}

/* Ngày ngoài tháng hiện tại và ngày bị khoá: chữ nhạt neutral-300 */
.ui-datepicker td.ui-datepicker-other-month a,
.ui-datepicker td.ui-datepicker-unselectable span,
.ui-datepicker td.ui-state-disabled span {
    color: var(--color-neutral-300);
}

/* Ngày đang chọn dùng đỏ thương hiệu thay cho cam mặc định */
.ui-datepicker td a.ui-state-active,
.ui-datepicker td .ui-state-active {
    background: var(--brand-primary) !important;
    color: var(--color-text-on-primary) !important;
    border: none !important;
}

/* Hôm nay: nền hồng nhạt, chữ primary/500 - KHÔNG phải primary/600 như bản
   trước, Figma ghi rõ #DC2626 cho chữ trên nền #FEF2F2. */
.ui-datepicker td a.ui-state-highlight,
.ui-datepicker td .ui-state-highlight {
    background: var(--color-primary-50) !important;
    color: var(--color-primary-500) !important;
    border: none !important;
}

/* -------------------------------------------------------------
 * 13. Thống nhất một bộ font Inter                [UI_01.3]
 * Còn sót tahoma/arial ở tooltip báo lỗi (validationEngine),
 * cây đơn vị (dynatree) và context menu.
 * ------------------------------------------------------------- */
.formError,
.formError .formErrorContent,
table.table-striped div.formError .formErrorContent,
ul.dynatree-container,
ul.dynatree-container a,
.context-menu-item,
.context-menu-list {
    font-family: var(--font-family-base) !important;
}

/* Icon glyphicons trong trang hồ sơ đang dùng #295d9f - xanh ngoài
   bảng màu thương hiệu.                                 [UI_01.1] */
body .main_bg .glyphicons {
    color: var(--color-text-secondary);
}

/* -------------------------------------------------------------
 * 14. Form dài nhiều mục: mỗi mục là một thẻ riêng
 *                            [UI_03.1] [UI_06.1] [UI_07.2]
 * Màn Cấu hình hệ thống lặp khuôn: .panel-heading -> .panel-body -> <hr>,
 * năm lần, tất cả nằm trong MỘT .panel. Kết quả là mỗi mục có hai đường kẻ
 * cùng độ dày 1px (gạch chân tiêu đề + <hr> cuối mục) cộng viền card ngoài,
 * không phân biệt được đường nào mở mục, đường nào đóng mục.
 *
 * Đóng khung từng mục: tiêu đề là dải nền bo góc trên, thân là hộp trắng bo
 * góc dưới, <hr> ẩn đi vì đã có khoảng cách giữa các thẻ.
 *
 * Khoanh vùng bằng :has(> form > hr) để CHỈ trúng panel có nhiều mục.
 * Đã kiểm: màn danh sách (Quản lý người dùng) có 2 panel, 0 panel bị ảnh
 * hưởng. Chrome 105+ mới có :has(), nhưng cả file đã phụ thuộc CSS variable
 * nên trình duyệt cũ vốn không dùng được lớp phủ này.
 * ------------------------------------------------------------- */
:root {
    /* Nền dải tiêu đề mục. Không dùng --color-bg-subtle (neutral-100) vì nó
       chỉ chênh nền trang 1.07:1 - nhìn như trùng màu. neutral-200 cho 1.19
       so với nền trang và 1.24 so với thân thẻ, chữ vẫn đạt 14.3:1. */
    --color-bg-section-header: var(--color-neutral-200);
}

html[data-theme="dark"] {
    /* Sáng hơn cả nền trang (#0A0F15) lẫn mặt thẻ (#161E27): 1.49 và 1.31 */
    --color-bg-section-header: #27333F;
}

/* Thẻ bao ngoài lui về làm nền, tránh lồng hai lớp khung */
.panel:has(> form > .panel-heading + .panel-body + hr) {
    background: transparent;
    border: none;
    border-radius: 0;
}

.panel:has(> form > hr)>form>.panel-heading {
    margin-top: var(--space-6);
    background: var(--color-bg-section-header);
    border: 1px solid var(--color-border-subtle);
    border-bottom: none;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.panel:has(> form > hr)>form>.panel-heading:first-child {
    margin-top: 0;
}

.panel:has(> form > hr)>form>.panel-heading+.panel-body {
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-top: none;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}

.panel:has(> form > hr)>form>hr {
    display: none;
}

/* -------------------------------------------------------------
 * 15. Chữ mồ côi cuối dòng                        [UI_05.4]
 * Nhãn hai chữ bị ngắt xuống dòng lẻ ("đầu tiên", "khóa").
 * ------------------------------------------------------------- */
label,
.control-label,
.table>thead>tr>th,
.table>tbody>tr>td,
.checkbox label,
.radio label,
.title_form,
dt,
dd {
    text-wrap: pretty;
}

/* -------------------------------------------------------------
 * 17. Header — căn giữa logo theo chiều dọc          [UI_01.2]
 *
 * Đo trên trang thật: header cao 71px, logo 72x45 nhưng cách mép trên
 * 10.5px, cách mép dưới 15.5px — lệch 5px. Icon menu ngay cạnh lại căn
 * giữa hoàn hảo (29.5/29.5), nên đây là lỗi riêng của khối logo.
 *
 * Thủ phạm: bootstrap-extend.min.css khai
 *     .navbar-brand-logo { margin-top: -.357rem }
 * Gốc font của file đó là 14px nên -.357rem = đúng -5px.
 *
 * KHÔNG chỉ đơn giản bỏ margin đó: bỏ xong logo lệch xuống 5px theo chiều
 * ngược lại (trên 15.5, dưới 10.5). Nghĩa là bản thân hộp chứa vốn đã không
 * căn giữa, margin âm chỉ đang bù trừ quá tay. Cách đúng là để flex tự căn,
 * rồi trả margin về 0.
 * ------------------------------------------------------------- */
/* App có HAI header khác nhau, phải phủ cả hai:
     - common/renew/header.jsp  -> <header id="mainHeader">
     - common/header.jsp        -> <nav class="site-navbar">, KHÔNG có id
   Bản sửa đầu tiên khoá vào #mainHeader nên chỉ với tới một cái; màn Chính sách
   lưu trữ vẫn lệch nguyên. Vì vậy phần căn dọc để KHÔNG có phạm vi id.

   Bỏ id cũng an toàn hơn: các quy tắc ẩn/hiện của sidebar
   (.box-logo .navbar-brand, .active-sidebar .box-logo .navbar-brand) có độ đặc
   hiệu 0,2,0 và 0,3,0 - nay chúng vẫn thắng .navbar-brand (0,1,0) như thiết kế
   ban đầu, thay vì bị #mainHeader (1,1,0) đè mất. */
.site-navbar,
#mainHeader {
    display: flex !important;
    align-items: center !important;
    height: 71px !important;
    padding-left: 0 !important;
}

/* Nav đè lên div.page ~5px: site.min.css có body{padding-top:66.01px} - chừa
   chỗ đúng bằng chiều cao GỐC của .site-navbar (fixed, lấy ra khỏi luồng).
   Khối ngay trên đã nâng nav lên 71px nhưng không ai cập nhật lại phần chừa
   chỗ này (nó nằm trong file minify không sửa tay được) -> 71 - 66.01 ≈ 5px
   bị nav che mất. Chỉ khoanh vào body.animsition (layout dùng .site-navbar +
   div.page, tức adminLayout.jsp): colorLayout.jsp không nạp file này nên
   không bị ảnh hưởng; renew/layout.jsp dùng body.fixbug-body, header/cấu
   trúc trang khác hẳn, cũng không khớp selector.                 [UI_01.2] */
body.animsition {
    padding-top: 71px;
}

.site-navbar .navbar-brand,
#mainHeader .navbar-brand {
    display: flex !important;
    align-items: center !important;
    height: 71px !important;
    position: static !important;
    float: none !important;
    transform: none !important;
    margin-left: 0 !important;
}

/* Thẻ <a> giữ nguyên chiều cao và vị trí, chỉ bỏ padding dọc rồi để flex căn
   giữa. Cách này đúng cho cả hai header dù padding của chúng khác nhau
   (renew: 0; header cũ: 10px 15px). */
.navbar-brand>.logo-container,
.navbar-brand>a {
    display: flex;
    align-items: center;
    padding-top: 0;
    padding-bottom: 0;
}

.navbar-brand-logo {
    display: block;
    margin-top: 0;
}

/* gap CHỈ cho #mainHeader, và là bắt buộc chứ không phải trang trí: ở header đó
   .navbar-brand vốn không phải flex, nên chuyển sang flex làm mất khoảng cách
   inline giữa logo và chữ (đo được tụt 33px -> 8px). Khai lại tường minh 32px.

   Header còn lại vốn ĐÃ là flex và khoảng cách 33px do padding ngang của thẻ
   <a> tạo ra - không đụng vào, vì sửa padding ngang sẽ kéo logo dịch trái và
   phá luôn khoảng cách 25px tới icon menu. */
/* Audit UI_01.2 nguyên văn: "Khoảng cách 2 logo khác nhau >> GẦN LẠI như bên trên".
   Ảnh chồng hai header từ hai màn để chỉ ra chúng lệch nhau. Bản trước tôi đo được
   32px (#mainHeader) và 33px (nav.site-navbar) rồi CỐ Ý để lệch - đúng thứ tiêu chí
   này cấm. Nay ép cả hai về 24px, và chọn giá trị nhỏ hơn theo chữ "gần lại".

   Ở nav.site-navbar khoảng cách do padding ngang của thẻ <a class="nav-link">
   (15px) tạo ra, nên phải zero padding-right. KHÔNG đụng padding-left - nó giữ
   logo đúng vị trí so với icon menu.

   KHÔNG dùng `gap`: đo được computed ra "24px 8px" - có quy tắc khác của theme
   ép riêng column-gap: 8px, nên gap của mình chỉ ăn phần row. Cộng thêm
   .navbar-brand-logo có sẵn margin-right: 10px, tổng ra 18px chứ không phải 24.

   Cách chắc ăn: triệt column-gap, rồi đặt khoảng cách bằng margin-right của
   chính logo - một nguồn duy nhất, không phụ thuộc quy tắc nào khác. [UI_01.2] */
.navbar-brand {
    column-gap: 0 !important;
}

.site-navbar .navbar-brand>.logo-container,
#mainHeader .navbar-brand>.logo-container,
.site-navbar .navbar-brand>a,
#mainHeader .navbar-brand>a {
    display: flex !important;
    align-items: center !important;
    padding: 0 !important;
    margin: 0 !important;
}

.site-navbar .navbar-brand a img.navbar-brand-logo,
#mainHeader .navbar-brand a img.navbar-brand-logo,
.navbar-brand-logo {
    display: block !important;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    margin-left: 0 !important;
    margin-right: 16px !important;
}

/* -------------------------------------------------------------
 * 16. Hộp thoại xác nhận (SweetAlert2)
 *                  [UI_01.1] [UI_04.2] [UI_07.1] [UI_06.1]
 *
 * Màu nút được truyền bằng THAM SỐ JAVASCRIPT chứ không phải CSS:
 *   confirmButtonColor: "#06ccc2"   (20 chỗ)
 *   cancelButtonColor:  "#e0635c"   (17 chỗ)
 *   cancelButtonColor:  "#b0b5ae"   (3 chỗ)
 * rải trên 40 dòng thuộc 9 file JSP. SweetAlert2 gán chúng thành
 * style.backgroundColor inline trên nút, nên lớp phủ chỉ với tới được
 * bằng !important.
 *
 * Sửa ở đây thay vì sửa 40 dòng vì: một chỗ duy nhất, và trùm luôn cả
 * những hộp thoại chưa được rà tới.
 *
 * Xanh ngọc #06CCC2 và đỏ hồng #E0635C đều nằm ngoài bảng màu thương hiệu.
 * Nặng hơn: đo chữ trắng trên hai nền đó được 2.01:1 và 3.44:1 - TRƯỢT AA
 * cả hai. Đỏ Viettel #B9000E cho 6.84:1.
 *
 * Nút hủy theo đúng quy tắc phân cấp của khối 6: nền trắng viền xám, không
 * dùng màu để khỏi tranh cấp với hành động chính.
 * ------------------------------------------------------------- */
.swal2-popup {
    font-family: var(--font-family-base);
    border-radius: var(--radius-md);
}

.swal2-popup .swal2-title,
.swal2-popup .swal2-html-container,
.swal2-popup .swal2-content {
    color: var(--color-text-primary);
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
}

.swal2-styled {
    font-family: var(--font-family-base);
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
    font-weight: 500;
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-4);
    min-height: 40px;
    transition: background-color .15s ease-in-out, border-color .15s ease-in-out;
}

.swal2-styled.swal2-confirm {
    background-color: var(--brand-primary) !important;
    border: 1px solid var(--brand-primary) !important;
    color: var(--color-text-on-primary) !important;
}

.swal2-styled.swal2-confirm:hover {
    background-color: var(--brand-primary-hover) !important;
    border-color: var(--brand-primary-hover) !important;
}

.swal2-styled.swal2-cancel {
    background-color: var(--color-bg-surface) !important;
    border: 1px solid var(--color-border-primary) !important;
    color: var(--color-text-primary) !important;
}

.swal2-styled.swal2-cancel:hover {
    background-color: var(--color-bg-subtle) !important;
}

.swal2-styled:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
    box-shadow: none;
}

/* -------------------------------------------------------------
 * 18. Dropdown select2 khi mở                        [UI_02.1]
 *
 * Audit nguyên văn: "thiết kế ô search sử dụng góc vuông >> có boder radius
 * tầm 6-8 xem theo design system". Ảnh trỏ vào ô search BÊN TRONG dropdown
 * lúc select2 đang bung, không phải hộp select lúc đóng.
 *
 * Bản trước chỉ sửa .select2-selection--single (hộp đóng) nên đúng chỗ audit
 * chụp lại vẫn nguyên góc vuông.
 *
 * select2.min.css nạp ở chỉ số 45, SAU file này (36), nên phần lớn cần
 * !important - cùng lý do đã ghi ở HANDOVER mục 4.5.
 * ------------------------------------------------------------- */
.select2-container--default .select2-selection--single,
.select2-container .select2-selection--single {
    border: 1px solid var(--color-border-primary) !important;
    border-radius: var(--radius-md) !important;
    background-color: var(--color-bg-field, var(--color-bg-surface)) !important;
    height: 40px !important;
    min-height: 40px !important;
    box-sizing: border-box !important;
}

.select2-container--default .select2-selection--multiple,
.select2-container .select2-selection--multiple {
    border: 1px solid var(--color-border-primary) !important;
    border-radius: var(--radius-md) !important;
    background-color: var(--color-bg-field, var(--color-bg-surface)) !important;
    min-height: 40px !important;
    box-sizing: border-box !important;
}

/* Hover/focus đồng bộ với input .form-control: viền đen đậm + quầng xám
   thay vì đỏ thương hiệu, tránh nhầm với trạng thái lỗi. */
.select2-container .select2-selection--single:hover {
    border-color: var(--color-neutral-900) !important;
    box-shadow: var(--focus-ring-gray) !important;
}

.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--focus .select2-selection--single {
    border-color: var(--color-neutral-900) !important;
    box-shadow: var(--focus-ring-gray) !important;
}

.select2-container--default .select2-dropdown,
.select2-dropdown {
    border: 1px solid var(--color-border-primary) !important;
    border-radius: var(--radius-md) !important;
    box-shadow: var(--shadow-md);
    overflow: hidden;
}

.select2-container--default .select2-search--dropdown .select2-search__field,
.select2-search--dropdown .select2-search__field {
    border: 1px solid var(--color-border-primary) !important;
    border-radius: var(--radius-md) !important;
    padding: var(--space-2) var(--space-3) !important;
    font-family: var(--font-family-base);
    font-size: var(--font-size-body);
    color: var(--color-text-primary);
}

.select2-container--default .select2-search--dropdown .select2-search__field:focus {
    border-color: var(--color-neutral-900) !important;
    box-shadow: var(--focus-ring-gray);
    outline: none;
}

/* Panel dán sát hộp select. Select2 đặt top của panel bằng JS nên margin ở đây
   chỉ dịch panel đi đúng khoảng đó, không ảnh hưởng phép tính lật trên/dưới. */
.select2-container--open .select2-dropdown--below {
    margin-top: var(--space-1);
}

.select2-container--open .select2-dropdown--above {
    margin-top: calc(-1 * var(--space-1));
}

/* Ô search bị bọc trong khung padding 4px, dính vào mép panel và không có
   đường ngăn với danh sách bên dưới. */
.select2-container--default .select2-search--dropdown {
    padding: var(--space-2);
    border-bottom: 1px solid var(--color-border-primary);
}

.select2-container--default .select2-results > .select2-results__options {
    padding: var(--space-1);
}

/* Option của select2 chỉ có padding 6px cả bốn phía - chật, và vệt nền hover
   chạy hết chiều ngang panel nên trông như một mảng đặc. Cho padding 8/12px
   theo nhịp ô nhập liệu, bo 4px để vệt nền thụt vào trong panel.
   .select2-container--default nâng đặc hiệu lên 0,2,0, thắng
   .select2-results__option (0,1,0) của select2.min.css mà không cần
   !important. */
.select2-container--default .select2-results__option {
    font-size: var(--font-size-body);
    line-height: var(--font-line-body);
    color: var(--color-text-primary);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
}

/* Hover và "đang chọn" phải bắt theo CLASS, không theo [aria-selected].
   Bản 4.1.0-beta.1 đánh dấu trạng thái bằng --highlighted / --selected /
   --disabled, còn aria-selected chỉ là thuộc tính trợ năng và JS gán
   aria-selected="true" cho cả ô ĐANG RÊ CHUỘT (results:focus). Hệ quả của bản
   cũ bắt theo [aria-selected="true"]: rê tới đâu ô đó hiện màu "đang chọn"
   (nền hồng, chữ đỏ) - không phân biệt được hover với lựa chọn thật; đồng thời
   ô đang chọn bị gỡ aria-selected khi rê sang ô khác nên mất dấu.

   Vẫn cần !important: select2.min.css nạp SAU file này (HANDOVER 4.5) và khai
   .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable
   nền xanh #5897fb ở cùng đặc hiệu 0,3,0. */
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
    background-color: var(--color-bg-subtle) !important;
    color: var(--color-text-primary) !important;
}

.select2-container--default .select2-results__option--selected {
    background-color: var(--color-bg-subtle) !important;
    color: var(--color-text-primary) !important;
    font-weight: 500;
}

/* Rê chuột lên chính ô đang chọn thì giữ nguyên màu "đang chọn". Cùng đặc hiệu
   0,3,0 với rule hover ở trên nên phải đặt sau mới thắng. */
.select2-container--default .select2-results__option--selected.select2-results__option--highlighted {
    background-color: var(--color-bg-subtle) !important;
    color: var(--color-text-primary) !important;
}

.select2-container--default .select2-results__option--disabled {
    color: var(--color-text-muted) !important;
    cursor: default;
}

/* Dòng "Không tìm thấy kết quả phù hợp" không phải một lựa chọn. */
.select2-container--default .select2-results__message {
    color: var(--color-text-muted);
    cursor: default;
}

/* Popup chọn đơn vị (#applicationTable1 - managerGroupsListResult.jsp): khi
   chỉ cho chọn 1 đơn vị, JS render cột chọn bằng <input type="radio"> thay vì
   checkbox (xem managerUserForm.jsp - "sửa để user chỉ được chọn 1 đơn vị").
   Radio mặc định của trình duyệt chấm xanh, đổi sang đỏ thương hiệu. */
#applicationTable1 input[type="radio"] {
    accent-color: var(--brand-primary);
}

/* Cả dòng cũng chọn được radio (xử lý click ở managerUserForm.jsp), nên cần
   con trỏ tay để báo dòng có thể bấm, không chỉ riêng ô tròn radio. */
#applicationTable1 tbody tr:has(input[type="radio"]) {
    cursor: pointer;
}

/* -------------------------------------------------------------
 * 19. Thẻ chức năng trang chủ              [UI_02.4] [UI_08.3]
 *
 * Hai audit cùng trỏ vào bốn thẻ ở trang chủ (Xác thực 2 bước, Đổi mật khẩu,
 * Quản lý ứng dụng, Quản lý phân quyền):
 *
 *   UI_02.4: "Khi hover chỉ thay đổi mỗi icon thành phần >> nên thay đổi nền
 *             bên dưới của cả icon và text (nền card nổi lên hoặc xám nhạt...)"
 *   UI_08.3: "Thiết kế phần minh hoạ thiếu quen thuộc >> icon trên nền"
 *
 * Markup (index.jsp): <a> > .content-wrapper > div(svg) + .intro-container.
 * Các thẻ này KHÔNG phải .btn nên mọi hover thêm ở khối 6 không với tới.
 *
 * Icon là <svg fill="#5D636F"> nội tuyến - thuộc tính trình bày của SVG không
 * nhận var(), nên chỉ bọc nền quanh icon chứ không đổi màu icon.
 * ------------------------------------------------------------- */
.content-wrapper {
    display: flex;
    align-items: flex-start;
    gap: var(--space-4);
    padding: var(--space-4);
    border-radius: var(--radius-md);
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    transition: background-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

.content-wrapper>div:first-child {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    background-color: transparent;
}

/* [UI_02.4] hover đổi nền CẢ THẺ, không chỉ icon. */
a:hover>.content-wrapper,
.content-wrapper:hover {
    background-color: var(--color-neutral-50);
    box-shadow: var(--shadow-sm);
}

a:hover>.content-wrapper>div:first-child {
    background-color: transparent;
}

.bd-sidebar a,
.bd-sidebar a:hover,
.bd-sidebar a:focus,
.bd-sidebar a:active,
.bd-sidebar a.active,
.bd-sidebar a span {
    text-decoration: none !important;
}

/* -------------------------------------------------------------
 * 19. Hiệu ứng Hover chuẩn theme cho icon mắt hiện/ẩn mật khẩu (.eye-icon)
 *
 * TRƯỚC đây khối này còn gồm cả .fa-eye/.fa-eye-slash (icon Font Awesome),
 * nhưng .fa-eye trong pro-vt-sso không dùng cho toggle mật khẩu nào cả (toggle
 * mật khẩu ở login.jsp/reset.jsp dùng <img class="eye-icon">, không phải FA) -
 * nó là icon "Xem chi tiết" (.btn-table.refresh) dùng chung ở 5 màn danh sách
 * (backupPolicyList, managerDepartmentList, managerUserList,
 * actionHistoryManagerList, actionHistoryManagerErrList). Rule hover đỏ +
 * scale ở đây (dùng !important, thắng cả .btn-table.refresh{color:...
 * !important} của layout.css) làm icon mắt xem chi tiết đổi màu đỏ + phóng to
 * khi hover, không đồng nhất với icon sửa/xoá cạnh nó (chỉ đổi nền, giữ
 * nguyên màu). Bỏ .fa-eye/.fa-eye-slash khỏi khối này để nó rơi về đúng hiệu
 * ứng hover chung của .btn-table (sso-design-system.css mục 6). */
.eye-icon,
img.eye-icon {
    cursor: pointer;
    transition: color .2s ease-in-out, transform .2s ease-in-out, filter .2s ease-in-out, opacity .2s ease-in-out;
}

.eye-icon:hover,
img.eye-icon:hover {
    transform: scale(1.18);
    opacity: 0.85;
    filter: drop-shadow(0 0 3px rgba(238, 0, 51, 0.45));
}

/* Audit L2 25/08/2026: tên đăng nhập (userInfo.userName) và tên đầy đủ
   (userInfo.fullName) cạnh ảnh đại diện góc trên phải (header.jsp) đang trắng
   trên nền đỏ - đổi cả 2 dòng thành cùng màu với các mục trong dropdown-menu
   bên dưới (.dropdown-item mặc định #212529 của Bootstrap) để đồng nhất.

   .nav-item.nav-link.dropdown-toggle (đủ cả 3 lớp, không chỉ 2) vì main.css có
   `.animsition.navbar-expand .navbar-nav .nav-link` độ đặc hiệu 4 lớp (0,4,0) -
   cao hơn bản trước chỉ 3 lớp (0,3,0) nên bị thua dù nạp sau. Viết đủ 4 lớp ở
   đây để hoà độ đặc hiệu, phần thắng nhờ thứ tự nạp sau. */
.info_user p,
.info_user .nav-item.nav-link.dropdown-toggle {
    color: #212529;
}

/* main.css có `.dropdown-item i { color: #c2cfd6 }` (0,1,1) - đặc hiệu cao hơn
   .glyphicons-dropdown-item một mình (0,1,0), nên khi 4 icon còn lại của
   dropdown (Hướng dẫn sử dụng, Câu hỏi thường gặp, Chế độ tối, Đăng xuất) đổi
   từ <span class="glyphicons"> sang <i class="fa">, chúng lọt vào rule xám
   nhạt đó (dành cho icon phụ ở nơi khác) làm cả dropdown nhìn nhạt màu. Viết
   lại với độ đặc hiệu cao hơn (0,2,0) để trả về đúng #4B5563 như cũ. */
.dropdown-item .glyphicons-dropdown-item {
    color: #4B5563;
}

/* main.css có `.dropdown-item i { display: inline-block; margin-left: -10px }`
   để kéo icon lùi lại 10px, bù cho padding-left 20px của .dropdown-item, canh
   icon thẳng hàng với các dropdown khác trong hệ thống. Rule đó chỉ khớp thẻ
   <i>, nên 2 icon SVG (Lịch sử đăng nhập, Hồ sơ cá nhân - dùng lại SVG của
   sidebar, xem header.jsp) không được bù, bị thụt sang phải 10px so với 4
   icon còn lại. Áp lại đúng phần bù đó cho riêng SVG trong dropdown-item. */
.dropdown-item svg.glyphicons-dropdown-item {
    display: inline-block;
    margin-left: -10px;
}

/* -------------------------------------------------------------
 * 20. Cây đơn vị (jsTree)
 *
 * Dựng theo ảnh spec agents/photo_2026-08-07_09-57-54.jpg: mỗi dòng chỉ còn
 * CHEVRON + tên đơn vị. Không icon thư mục, không icon tệp, không đường kẻ
 * chấm nối nhánh - cả ba thứ đó đều cắt ra từ một sprite duy nhất
 * (share/css/32px.png) của theme jstree-default, nên gỡ sprite là hết cùng lúc.
 *
 * Cây dùng ở 6 màn (quản lý đơn vị 4 file, quản lý người dùng 2 file) và đều
 * khởi tạo bằng $('#...').jstree(), nên sửa tập trung ở đây là đủ, không phải
 * đụng vào từng JSP.
 *
 * Ghi chú đặc hiệu: mọi khai báo của theme đều dạng `.jstree-default .X`
 * (0,2,0). File này nạp SAU jsTree.css (xem adminLayout.jsp) nên chỉ cần viết
 * đúng mức đặc hiệu đó là thắng, không cần !important.
 * ------------------------------------------------------------- */

/* Gỡ sprite khỏi mọi thành phần của cây: nút +/-, icon thư mục và cả dải kẻ
   chấm dọc (background repeat-y trên .jstree-node). */
.jstree-default .jstree-node,
.jstree-default .jstree-icon,
.jstree-default .jstree-last,
.jstree-default > .jstree-no-dots .jstree-node,
.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl {
    background-image: none;
    background-color: transparent;
}

/* Ảnh spec không có icon thư mục/tệp. Ẩn bằng CSS thay vì sửa `icon:` trong
   sáu file JSP - hành vi dữ liệu của cây giữ nguyên. */
.jstree-default .jstree-anchor > .jstree-themeicon {
    display: none;
}

/* Dòng cao 28 cho thoáng hơn mức 24 mặc định của theme, đúng nhịp của ảnh. */
.jstree-default .jstree-node {
    min-height: 28px;
    line-height: 28px;
}

.jstree-default .jstree-icon,
.jstree-default .jstree-icon:empty {
    width: 24px;
    height: 28px;
    line-height: 28px;
}

/* Audit L2 25/08/2026: tên đơn vị dài (jsTree mặc định white-space: nowrap,
   xem jsTree.css) tràn ngang ra ngoài khối "Cây đơn vị", phải cuộn ngang mới
   đọc hết. Ép xuống dòng + vỡ từ, height chuyển sang auto/min-height để dòng
   tự giãn cao theo số dòng thay vì cắt cứng ở 28px như trước.

   max-width: calc(100% - 24px) là phần BẮT BUỘC, không phải tuỳ chọn: .jstree-
   anchor là inline-block width:auto, đứng ngay sau icon .jstree-ocl (24px,
   cũng inline-block) trên cùng 1 dòng trong <li>. Trình duyệt tính "shrink-to-
   fit" cho inline-block auto-width dựa trên bề rộng còn lại của DÒNG mà KHÔNG
   trừ phần icon đứng trước nó cùng dòng - nên anchor tự tính rộng bằng cả
   100% <li> (đã đúng đắn hẹp dần theo độ sâu lồng), rồi cộng thêm 24px của
   icon phía trước => luôn tràn ra ngoài đúng 24px ở MỌI cấp độ sâu, bất kể
   text ngắn hay dài. Phải trừ tay 24px này, riêng width tự nhiên không tự
   trừ được. */
.jstree-default .jstree-anchor {
    height: auto;
    min-height: 28px;
    line-height: 28px;
    white-space: normal;
    word-break: break-word;
    max-width: calc(100% - 24px);
    padding: 0 8px 0 0;
    border-radius: var(--radius-md);
    color: var(--color-text-primary);
}

/* Chevron: một hình duy nhất, nhánh mở thì xoay 90 độ. Vẽ bằng mask +
   currentColor để chế độ tối tự đổi màu theo chữ, không cần bộ icon thứ hai. */
.jstree-default .jstree-ocl {
    color: var(--color-text-secondary);
}

.jstree-default .jstree-ocl::before {
    content: '';
    display: block;
    width: 16px;
    height: 16px;
    margin: 6px auto;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6L15 12L9 18'/%3E%3C/svg%3E") center / 16px 16px no-repeat;
    mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6L15 12L9 18'/%3E%3C/svg%3E") center / 16px 16px no-repeat;
    transition: transform .15s ease-in-out;
}

.jstree-default .jstree-open > .jstree-ocl::before {
    transform: rotate(90deg);
}

/* Nút lá và nút đang tải không có chevron, nhưng vẫn giữ nguyên ô trống 24px
   để nhãn của lá thẳng cột với nhãn của nhánh - đúng như ảnh spec. */
.jstree-default .jstree-leaf > .jstree-ocl::before,
.jstree-default .jstree-loading > .jstree-ocl::before {
    display: none;
}

.jstree-default .jstree-loading > .jstree-ocl {
    /* Đường dẫn tuyệt đối vì file này nằm ở share/renew/css còn ảnh ở share/css */
    background: url("/share/css/throbber.gif") center center no-repeat;
}

/* Nhánh chưa mở được gắn sẵn một nút giả (children: [{}] trong JSP) chỉ để cây
   biết là có con mà vẽ chevron; nút đó bị xoá sau khi AJAX trả về danh sách
   thật. Trước đây nó lộ ra thành một icon tệp lạc lõng, giờ bỏ icon thì thành
   một dòng trống - ẩn hẳn nhánh con trong lúc đang tải cho gọn. */
.jstree-default .jstree-loading > .jstree-children {
    display: none;
}

/* Rê chuột và dòng đang chọn: bỏ hai dải xanh #e7f4f9 / #beebff của theme,
   thay bằng xám nền và đỏ thương hiệu. Chế độ tối do dark-mode.css lo (nạp sau
   file này) nên ở đây chỉ cần bảng sáng. */
.jstree-default .jstree-hovered {
    background: #F6F7F9;
    border-radius: var(--radius-md);
    box-shadow: none;
}

.jstree-default .jstree-clicked {
    background: var(--color-primary-50);
    border-radius: var(--radius-md);
    box-shadow: none;
    color: var(--brand-primary);
    font-weight: 500;
}

/* ==========================================================================
   Nhãn trạng thái trong bảng danh sách
   Thay cho cách cũ "<i class="fa fa-square"> + chữ": ô vuông màu tách rời chữ
   nên phải đọc chú giải mới hiểu, còn nhãn viền bao trọn chữ thì tự nó đã nói
   hết. Dùng chung cho mọi cột trạng thái (người dùng, AD...) nên đặt ở đây
   thay vì lặp lại <style> trong từng JSP.
   ========================================================================== */
.status-tag {
    display: inline-block;
    padding: 2px 12px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: 13px;
    line-height: 20px;
    /* Nhãn phải nằm gọn một dòng, không bị bẻ giữa "Đang" và "hoạt động" khi cột hẹp */
    white-space: nowrap;
}

.status-tag.status-tag-active {
    color: var(--color-success-700);
    border-color: var(--color-success-300);
    background-color: var(--color-success-50);
}

.status-tag.status-tag-inactive {
    color: var(--color-danger-700);
    border-color: var(--color-danger-300);
    background-color: var(--color-danger-50);
}
