/* =============================================================================
 * X-IRIS — CHẾ ĐỘ TỐI "HUD ĐIỀU HÀNH"
 *
 * File PHỦ. Không sửa một dòng nào của style.css (980 KB, dùng chung cả site) —
 * mọi thứ ở đây đều nằm dưới html[data-xtheme="dark"], không bật thì file này vô hại.
 *
 * BẢNG MÀU đã KIỂM BẰNG MÁY, không chọn bằng mắt:
 *   - Nền trang #040910 / thẻ #152740 -> 1.33:1. (Thử #070d16/#0e1826 trước: chỉ 1.09:1,
 *     mắt không thấy thẻ nổi lên — đúng lỗi "không phân vùng" đang phải sửa, nên bỏ.)
 *   - Chữ trên thẻ: ink 13.2:1 · muted 7.1:1 · faint 4.3:1 — đều đạt.
 *   - Chuỗi số liệu #12a594 / #d9722a: qua đủ 4 phép của validate_palette.js trên nền tối
 *     (dải sáng L 0.48–0.67, sàn bão hoà, tách mù màu ΔE 54, tương phản nền).
 *     KHÔNG bê nguyên #0f9d92/#e87511 của bản sáng: cam #e87511 L=0.684, vượt dải.
 *
 * Chuẩn dataviz: bản tối phải CHỌN LẠI bậc màu theo nền tối, không phải lật ngược bản sáng.
 * ============================================================================= */

/* BẢN 2 — bám theo xiris.vn (đo thẳng từ trang thật, không phỏng đoán).
 *
 * BẢN 1 SAI Ở ĐÂU: thẻ tô MÀU ĐẶC #152740, viền màu TỐI #24405e, nền trang PHẲNG.
 * Viền tối trên nền tối thì không thành cạnh -> mọi thứ dính vào nhau ("chìm hết").
 * Cách của xiris.vn ngược lại, và đó mới là chỗ ra chiều sâu:
 *   1. Nền trang = gradient NHIỀU LỚP + 2 quầng sáng -> tự nó đã có chiều sâu.
 *   2. Thẻ = LỚP TRẮNG MỜ rgba(255,255,255,.04), KHÔNG phải màu đặc -> thẻ ăn theo gradient
 *      bên dưới, thẻ gần quầng sáng khác thẻ ở xa -> mắt đọc ra không gian.
 *   3. Viền = rgba(122,219,255,.16) — XANH SÁNG mờ, không phải màu tối. Chính viền tạo cạnh.
 *   4. Quầng sáng BÊN TRONG thẻ: inset 0 0 20px rgba(112,236,255,.043).
 *   5. Nhấn = cyan #70ecff + mint #40f7b1 (không phải teal #2dd4bf nhạt nhoà).
 */
html[data-xtheme="dark"] {
  --x-page:  #04111d;   /* màu nền nền tảng — gradient thật đặt ở body */
  --x-cyan:  #70ecff;   /* nhấn chính (đo từ xiris.vn) */
  --x-mint:  #40f7b1;   /* nhấn phụ */
  --x-teal:  #70ecff;   /* giữ tên cũ cho các quy tắc bên dưới khỏi phải sửa hàng loạt */
  /* Bề mặt: LỚP PHỦ TRẮNG MỜ, không phải màu đặc.
     ⚠️ ALPHA .04 CỦA xiris.vn KHÔNG DÙNG ĐƯỢC Ở ĐÂY — đã đo: thẻ chỉ nổi hơn nền **1.09:1**,
     ĐÚNG con số của BẢN 1 mà chủ dự án đã bác ("nhìn nó chìm hết ko thấy gì cả"). Bê nguyên
     công thức của họ tức là đi ngược lại chính kết luận đó — và đã mắc thật, user phải báo lại
     lần hai ("nhìn nó chìm quá vậy").
     Vì sao .04 chạy được bên xiris.vn mà không chạy ở đây: trang họ là trang GIỚI THIỆU, thẻ
     nằm THƯA trên vùng gradient mạnh nên mỗi thẻ ăn một mức quầng sáng khác nhau -> mắt đọc ra
     không gian. Bảng điều hành này thẻ nằm SÁT NHAU trên vùng gradient gần phẳng -> mất hết
     manh mối đó, chỉ còn đúng 1.09:1 = chìm.
     .10 cho **1.28:1** (mắt đọc ra "đây là một thẻ") mà chữ --x-ink vẫn **14.2:1**.
     Hover .16 để tách khỏi trạng thái thường 1.22:1. */
  --x-card:  rgba(255,255,255,.10);
  --x-card2: rgba(255,255,255,.16);
  --x-zone:  rgba(255,255,255,.05);
  /* Viền: XANH SÁNG mờ — thứ tạo ra cạnh trên nền tối */
  --x-line:  rgba(122,219,255,.16);
  --x-line2: rgba(112,236,255,.34);
  --x-inset: inset 0 0 20px rgba(112,236,255,.05);   /* quầng sáng trong thẻ */
  --x-ink:   #f5fbff;   /* chữ chính (đo từ xiris.vn) */
  --x-mut:   #cfdae8;   /* chữ phụ */
  --x-faint: #a9b9c8;   /* chữ mờ */
  --x-blue:  #8ec5ff;
  --x-red:   #ff7a7a;
  --x-amber: #ffc94d;
  --x-green: #40f7b1;
  --x-glow:  rgba(112,236,255,.30);
}

/* ---------- 0. MÀU LINK — chỗ này KHÔNG BỎ QUA ĐƯỢC ----------
 * style.css:1892 có `a, a:link, a:active, a:visited { color: #1a3f5e }`.
 * `a:link` mang độ ưu tiên (0,1,1) nên **THẮNG cả `.unit{color:inherit}` (0,1,0)** —
 * tức là MỌI thẻ <a> viết `color:inherit` để ăn theo màu cha đều bị kéo về navy #1a3f5e.
 * Trên nền TRẮNG nó là 9.8:1 nên chẳng ai để ý; trên nền tối là **1.37:1 — tàng hình**
 * (đo thật: tên cụm trong "Sức khỏe theo cụm"). Phải đè lại, và đè bằng selector có
 * :link/:visited/:active thì mới đủ ưu tiên. */
html[data-xtheme="dark"] a,
html[data-xtheme="dark"] a:link,
html[data-xtheme="dark"] a:visited,
html[data-xtheme="dark"] a:active { color: var(--x-cyan); }
/* Thẻ/ô bấm được: phải ăn theo màu chữ của vùng chứ không phải màu link. Đây đều là những
   chỗ tác giả đã viết `color:inherit` mà bị a:link cướp mất. */
html[data-xtheme="dark"] a.unit,    html[data-xtheme="dark"] a.unit:link,
html[data-xtheme="dark"] a.tqlead,  html[data-xtheme="dark"] a.tqlead:link,
html[data-xtheme="dark"] a.tqm,     html[data-xtheme="dark"] a.tqm:link,
html[data-xtheme="dark"] a.tqnav-i, html[data-xtheme="dark"] a.tqnav-i:link,
html[data-xtheme="dark"] a.kpi,     html[data-xtheme="dark"] a.kpi:link,
html[data-xtheme="dark"] a.sc,      html[data-xtheme="dark"] a.sc:link,
html[data-xtheme="dark"] a.al,      html[data-xtheme="dark"] a.al:link,
html[data-xtheme="dark"] a.al:visited,
html[data-xtheme="dark"] a.tqm:visited, html[data-xtheme="dark"] a.tqlead:visited,
html[data-xtheme="dark"] a.unit:visited, html[data-xtheme="dark"] a.tqnav-i:visited { color: var(--x-ink); }

/* ---------- 1. KHUNG: trang, menu trái, thanh tiêu đề ---------- */
/* Nền GRADIENT NHIỀU LỚP — công thức lấy đúng từ xiris.vn. Đây là thứ làm nền "có chiều sâu"
   thay vì một mảng đen phẳng; và vì thẻ chỉ là lớp trắng mờ nên chúng ăn theo gradient này,
   thẻ ở gần quầng sáng trông khác thẻ ở xa -> mắt tự đọc ra không gian.
   Gắn ở body và dán cố định (không cuộn theo) để quầng sáng luôn nằm đúng chỗ. */
html[data-xtheme="dark"] body#body {
  color: var(--x-ink);
  background:
    radial-gradient(circle at 18% -10%, rgba(66,126,205,.16), rgba(0,0,0,0) 34%),
    radial-gradient(circle at 82% 4%,  rgba(64,247,177,.08), rgba(0,0,0,0) 30%),
    linear-gradient(#010613 0%, #092533 38%, #04111d 68%, #01030a 100%);
  background-attachment: fixed;
}
/* Các lớp bọc phải TRONG SUỐT để gradient của body xuyên qua — tô màu đặc ở đây là mất sạch. */
html[data-xtheme="dark"] .wrap_all_site,
html[data-xtheme="dark"] .content_main,
html[data-xtheme="dark"] .content_chinh { background: transparent; }

/* Lưới mờ — chất "phòng điều hành". position:fixed + pointer-events:none để không cuộn theo
   và không chắn chuột. */
html[data-xtheme="dark"] body#body::before {
  content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(112,236,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(112,236,255,.05) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(ellipse 90% 65% at 50% 0%, #000 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 90% 65% at 50% 0%, #000 30%, transparent 75%);
}
html[data-xtheme="dark"] .wrap_all_site { position: relative; z-index: 1; }
/* MOBILE: #cover (backdrop, z-index:100) là ANH EM NẰM NGOÀI .wrap_all_site. z-index:1 ở trên biến
   .wrap_all_site thành stacking context, nhốt .menu_mobile (fixed, z-index:1000) BÊN TRONG tầng 1
   -> #cover (100>1) phủ đè cả menu, menu mờ tịt không đọc/bấm được. Bỏ z-index ở khổ mobile (giữ
   position:relative) để menu về tầng gốc, đè lên backdrop. Lưới nền vẫn nằm dưới nội dung vì
   body::before đứng trước .wrap_all_site theo thứ tự cây (cả hai cùng tầng 0). */
@media (max-width: 991.98px) {
  html[data-xtheme="dark"] .wrap_all_site { z-index: auto; }
  /* Drawer chế độ tối: khối nội dung block (div.noiDung…SubHome…) giữ NỀN TRẮNG cứng mà dark KHÔNG
     đè -> chữ sáng (cyan/nhạt) trên nền trắng, gần như không đọc được. Cho trong suốt để lộ nền
     tối của .menu_mb. Chỉ hại ở drawer mobile (desktop .box_menu_trai không có phần tử nền trắng). */
  html[data-xtheme="dark"] .menu_mb #SubFileLibraryHome > div,
  html[data-xtheme="dark"] .menu_mb [class*="SubHome"] { background: transparent !important; }
  /* Chuông thông báo MOBILE (cả 2 chế độ): dropdown #dropdown_khung_thong_bao rộng 340px, container
     .dropdown_chuong_thong_bao KHÔNG có hậu tố 2/3 nên luật responsive 95/99vw không với tới -> panel
     lệch trái ~66px ra NGOÀI màn (bị cắt). Ghim cố định dưới header, vừa khổ máy, cuộn trong panel. */
  #dropdown_khung_thong_bao { position: fixed !important; left: 8px !important; right: 8px !important;
    top: 56px !important; width: auto !important; max-width: none !important;
    max-height: calc(100vh - 72px) !important; overflow: auto; }
}

html[data-xtheme="dark"] .box_menu_trai,
html[data-xtheme="dark"] .rong_mo_trai { background: rgba(3,10,20,.72); }
html[data-xtheme="dark"] .box_menu_trai { border-right: 1px solid var(--x-line); }
html[data-xtheme="dark"] .title_menu_trai { background: transparent; border-bottom: 1px solid var(--x-line); }
html[data-xtheme="dark"] .title_menu_trai * { color: var(--x-ink) !important; }
/* LOGO TỐI TRÊN NỀN TỐI. File logo (chatgpt-image-08_31_42-20-thg-9-2025.webp) vẽ chữ "X" màu
   NAVY ĐẬM cho nền trắng — trên menu tối nó chìm mất, chỉ còn chữ "IRIS" nhạt đọc được.
   Chủ dự án báo: "nền đen thui che mất cái logo". Không phải bị che, mà là logo tối trên nền tối.
   Chưa có file logo bản sáng nên xử bằng bộ lọc, không đụng file ảnh.
   `brightness(0) invert(1)` = ĐỔ TRẮNG TOÀN BỘ thành bóng chữ trắng. Cố ý: mất màu thương hiệu
   nhưng ĐỌC ĐƯỢC CHẮC CHẮN, và đúng lối mẫu GREENWORLD (logo trắng trên thanh bên tối).
   KHÔNG dùng `invert(1)` một mình — nó lật navy thành vàng cam, sai nhận diện hơn cả không sửa.
   → Muốn giữ màu thương hiệu thì phải có file logo bản nền tối; nhờ chủ dự án cấp sau. */
html[data-xtheme="dark"] .title_menu_trai img { filter: brightness(0) invert(1); opacity: .92; }
html[data-xtheme="dark"] .box_profile { background: rgba(255,255,255,.035); border-bottom: 1px solid var(--x-line); }
html[data-xtheme="dark"] .box_profile * { color: var(--x-ink); }
html[data-xtheme="dark"] .big_item_menu { border-color: var(--x-line); }
html[data-xtheme="dark"] .big_item_menu a { color: #bfe9f5; }
html[data-xtheme="dark"] .big_item_menu a:hover { color: var(--x-cyan); background: rgba(112,236,255,.08); }

/* ---- THU MENU = THANH ICON DỌC 72px — phần riêng BẢN TỐI (2026-07-17) ----
   Phần dùng chung + bản sáng nằm ở themes/theme_xiris/modules/menu/global.dac_biet.tpl.
   <style> của .tpl đó nằm trong <body> nên đứng SAU file này -> luật CÙNG hạng thì nó
   thắng. Mọi luật dưới đây có thêm `html[...]` (một phần tử) nên hơn đúng 1 bậc
   ((0,n,1) > (0,n,0)) -> thắng ngược lại. Đổi selector bên .tpl thì phải chép y sang đây.

   BỌC @media (min-width:992px) cho khớp bên .tpl: dưới 992px cột trái ẩn hẳn (hidden-sm hidden-xs).

   TƯƠNG PHẢN (tự tính, nền gộp rgba(3,10,20,.72) CHỒNG 2 LỚP — .rong_mo_trai và
   .box_menu_trai đều tô, xem dòng 118-119 — lên nền trang #04111d => ~rgb(3,11,21)):
     · nhãn 10px #bfe9f5 trên nền thanh ......... 15.3:1  (cần 4.5:1) ✔
     · nhãn 10px #70ecff trên nền mục đang xem ... 11.3:1  (cần 4.5:1) ✔
     · icon nút » #70ecff trên nền nút ........... 11.4:1  (cần 3:1) ✔ */
@media (min-width: 992px) {
  /* Vạch nhấn mép trái mục đang xem: cyan thay cho #016a70 của bản sáng (teal đậm
     trên nền tối thì không thành vạch). Bản mở đang là `inset 2px`, thu lại dày 3px cho rõ. */
  html[data-xtheme="dark"] .dong_menu .workplace h3.active > a { box-shadow: inset 3px 0 0 var(--x-cyan); }

  /* Nút » : bản sáng là nền #f1f5f9 + viền #e2e8f0 — hai màu SÁNG, để nguyên là
     lòi mảng trắng trên nền tối (đúng lỗi `.workplace h3{background:#fff}` đã phải sửa). */
  html[data-xtheme="dark"] .dong_menu .xm-expand {
    background: var(--x-card);
    border: 1px solid var(--x-line);
    color: var(--x-cyan);
  }
  html[data-xtheme="dark"] .dong_menu .xm-expand:hover {
    background: var(--x-card2);
    border-color: var(--x-line2);
  }
}

/* Thanh tiêu đề: nền teal đặc -> chuyển sang thanh tối có gạch sáng dưới chân */
html[data-xtheme="dark"] .dong_mo_menu {
  background: linear-gradient(180deg, rgba(9,37,51,.85), rgba(4,17,29,.85));
  border-bottom: 1px solid var(--x-line2);
  box-shadow: 0 1px 0 rgba(112,236,255,.18), 0 8px 26px -14px rgba(112,236,255,.5);
  backdrop-filter: blur(6px);
}
html[data-xtheme="dark"] .dong_mo_menu,
html[data-xtheme="dark"] .dong_mo_menu * { color: var(--x-ink); }

/* ---------- 2. MÀN CÓ BIẾN CSS: chỉ cần đảo biến, cả màn tự theo ----------
   Đây là lý do bản tối làm được gọn. Màn nào khai biến trên wrapper thì ở đây ghi đè đúng
   danh sách biến CỦA NÓ (tên biến mỗi màn một khác: --muted / --mut / --faint...). */

/* -- Tổng quan (.tqd-wrap: 14 biến) -- */
html[data-xtheme="dark"] .tqd-wrap {
  --ink: var(--x-ink); --muted: var(--x-mut); --faint: var(--x-faint);
  --line: var(--x-line);
  /* --bg KHÔNG phải nền trang: bản sáng đặt #f5f7fa và dùng nó làm MẶT NỀN MỀM cho
     .mt (3 ô Quá hạn/Sắp tới/An toàn) và cho .al:hover / .unit:hover. Để transparent
     là 3 ô mất hộp còn trơ số, và hover chết ở 2 danh sách dày nhất màn. */
  --bg: rgba(255,255,255,.10); --soft: rgba(255,255,255,.13);
  --blue: var(--x-blue); --blue2: #4d86e0; --teal: var(--x-teal);
  --red: var(--x-red); --amber: var(--x-amber); --green: var(--x-green);
  --navy1: #061424; --navy2: #0b2a44;
}
html[data-xtheme="dark"] .tqhero {
  background:
    radial-gradient(circle at 88% -30%, rgba(112,236,255,.16), rgba(0,0,0,0) 46%),
    linear-gradient(125deg, #061726 0%, #0a2a3e 55%, #0d3550 100%);
  border: 1px solid var(--x-line2);
  box-shadow: var(--x-inset), 0 0 30px -10px var(--x-glow);
}
/* Thanh chuyển hệ DÁN DÍNH. Bản sáng là `background:#fff` ĐẶC (tong_quan.tpl:108) nên không rò.
   Bản tối trước đây tôi đặt `linear-gradient(#04111d 72%, rgba(4,17,29,0))` cho mềm mép — SAI:
   28% dưới (~20px của 71px) TRONG SUỐT, nội dung cuộn qua LÒI LÊN đọc được, đè lên 2 thẻ. Chính
   tôi gây ra lỗi này, bản sáng không có.
   Không quay lại màu đặc được: nền trang là gradient nhiều lớp, đắp một khối #04111d phẳng lên
   sẽ thành hình chữ nhật lộ rõ. Cách đúng cho nền gradient: gần đặc + LÀM MỜ NỀN SAU —
   chữ cuộn qua nhoè hẳn, không đọc được, mà thanh vẫn ăn theo gradient bên dưới. */
html[data-xtheme="dark"] .tqnav {
  background: rgba(4,17,29,.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
/* Trình duyệt không hỗ trợ backdrop-filter (Firefox cũ) thì phải đặc, thà lộ mép còn hơn rò chữ */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html[data-xtheme="dark"] .tqnav { background: #04111d; }
}
html[data-xtheme="dark"] .tqnav-i,
html[data-xtheme="dark"] .tqlead,
html[data-xtheme="dark"] .tqm,
html[data-xtheme="dark"] .card,
html[data-xtheme="dark"] .tk-k, html[data-xtheme="dark"] .tk-card, html[data-xtheme="dark"] .tk-f {
  background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .tqnav-i:hover,
html[data-xtheme="dark"] .tqlead:hover,
html[data-xtheme="dark"] .tqm:hover {
  background: var(--x-card2); border-color: var(--x-line2);
  box-shadow: var(--x-inset), 0 0 22px -6px var(--x-glow);
}
html[data-xtheme="dark"] .tqnav-i.on { border-color: var(--x-cyan); box-shadow: inset 0 0 0 1px rgba(112,236,255,.55), 0 0 26px -6px var(--x-glow); }
html[data-xtheme="dark"] .tqnav.stuck { box-shadow: 0 8px 16px -10px #000; }
html[data-xtheme="dark"] #tqSecNM { background: rgba(112,180,255,.035); border-color: rgba(122,180,255,.14); }
html[data-xtheme="dark"] #tqSecML { background: rgba(64,247,177,.035); border-color: rgba(64,247,177,.14); }
html[data-xtheme="dark"] .tqsec-ico { background: rgba(255,255,255,.07); border: 1px solid var(--x-line); }
html[data-xtheme="dark"] .tqz-go a { background: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-mut); }
html[data-xtheme="dark"] .tqz-go a:hover { border-color: var(--x-cyan); color: var(--x-cyan); background: rgba(112,236,255,.1); }
html[data-xtheme="dark"] .card-h { background: rgba(255,255,255,.03); border-color: var(--x-line); }
html[data-xtheme="dark"] .tqsec-none { background: rgba(255,255,255,.03); border-color: var(--x-line); }
/* Viên tình trạng: bộ gốc là màu nhạt vẽ cho nền navy; nền tối cần bộ RIÊNG (đậm nền, sáng chữ) */
html[data-xtheme="dark"] .tqsec-h .sp-critical,
html[data-xtheme="dark"] .tqnav-i .st.sp-critical { background: #3a1418; color: #ff8f8f; border-color: #6b2028; }
html[data-xtheme="dark"] .tqsec-h .sp-warning,
html[data-xtheme="dark"] .tqnav-i .st.sp-warning { background: #3a2a0d; color: #fcd34d; border-color: #6b4c14; }
html[data-xtheme="dark"] .tqsec-h .sp-normal,
html[data-xtheme="dark"] .tqnav-i .st.sp-normal { background: #0b312c; color: #5eead4; border-color: #17564d; }
html[data-xtheme="dark"] .tqsec-h .sp-unknown,
html[data-xtheme="dark"] .tqnav-i .st.sp-unknown { background: #16283c; color: var(--x-mut); border-color: var(--x-line); }
/* Bảng top tuyến + thanh tỷ trọng */
html[data-xtheme="dark"] .tqml-t td { border-color: rgba(122,219,255,.09); }
html[data-xtheme="dark"] .tqml-t th { border-color: var(--x-line); }
html[data-xtheme="dark"] .tqml-bar { background: rgba(255,255,255,.08); }

/* -- Thống kê (.tkw) -- */
html[data-xtheme="dark"] .tkw {
  --ink: var(--x-ink); --mid: var(--x-mut); --mut: var(--x-faint);
  /* bản sáng --bg:#fff = mặt nền của .tk-k/.tk-card (không phải nền trang) */
  --line: var(--x-line); --bg: var(--x-card); --soft: rgba(255,255,255,.04);
  --brand: var(--x-teal);
  --s1: #12a594;   /* đã kiểm trên nền tối — KHÔNG dùng lại #0f9d92 của bản sáng */
  --s2: #d9722a;   /* cam bản sáng #e87511 vượt dải sáng của nền tối */
  --grid: rgba(122,219,255,.10); --axis: rgba(122,219,255,.3);
}
html[data-xtheme="dark"] .tk-ch { background: rgba(255,255,255,.03); border-color: var(--x-line); }
html[data-xtheme="dark"] .tk-chip { background: #0b312c; color: #5eead4; }
html[data-xtheme="dark"] .tk-chip2 { background: #16283c; color: var(--x-mut); border-color: var(--x-line); }
html[data-xtheme="dark"] .tk-go {
  background: linear-gradient(135deg, rgba(112,236,255,.94), rgba(64,247,177,.94)); color: #03111a;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.08), 0 10px 24px -12px rgba(64,247,177,.5);
}
html[data-xtheme="dark"] .tk-go:hover { background: linear-gradient(135deg, #70ecff, #40f7b1); color: #03111a; }
html[data-xtheme="dark"] .tk-t td { border-color: rgba(122,219,255,.09); }
html[data-xtheme="dark"] .tk-pb { background: rgba(255,255,255,.08); }
html[data-xtheme="dark"] .tk-ll a { background: #3a2a0d; color: #fcd34d; border-color: #6b4c14; }
html[data-xtheme="dark"] .tk-ll a:hover { background: #4a360f; color: #fde68a; }
html[data-xtheme="dark"] .tk-warn { background: #3a2a0d; border-color: #6b4c14; color: #fcd34d; }
html[data-xtheme="dark"] .tk-warn.tk-ok { background: #0b312c; border-color: #17564d; color: #5eead4; }
html[data-xtheme="dark"] .tk-tip { background: rgba(6,22,36,.96); border: 1px solid var(--x-line2); backdrop-filter: blur(4px); }
html[data-xtheme="dark"] .tk-ph img, html[data-xtheme="dark"] .tk-pp img { border-color: var(--x-line2); }

/* -- Dự báo & Cảnh báo AI (.aiop-wrap: 11 biến) -- */
html[data-xtheme="dark"] .aiop-wrap {
  --ink: var(--x-ink); --muted: var(--x-mut); --faint: var(--x-faint);
  /* bản sáng --bg:#f7f8fa = nền hover (.todo/.alarm) + nền chip (.a-trend/.det-chip).
     Để transparent là hover chết và chip mất hình. */
  --line: var(--x-line); --bg: rgba(255,255,255,.10); --soft: rgba(255,255,255,.13);
  --blue: var(--x-blue); --amber: var(--x-amber); --red: var(--x-red);
  --purple: #a78bfa; --green: var(--x-green);
}

/* ---------- 3. Ô nhập / bảng / hộp thoại dùng chung (bootstrap) ---------- */
html[data-xtheme="dark"] .form-control,
html[data-xtheme="dark"] select, html[data-xtheme="dark"] input[type="text"],
html[data-xtheme="dark"] input[type="number"], html[data-xtheme="dark"] input[type="password"],
html[data-xtheme="dark"] textarea {
  background: #0d1c2e; border-color: var(--x-line); color: var(--x-ink);
}
html[data-xtheme="dark"] .form-control::placeholder,
html[data-xtheme="dark"] input::placeholder { color: var(--x-faint); }
html[data-xtheme="dark"] .form-control:focus { border-color: var(--x-teal); box-shadow: 0 0 0 2px var(--x-glow); }
html[data-xtheme="dark"] .table, html[data-xtheme="dark"] .table td, html[data-xtheme="dark"] .table th {
  color: var(--x-ink); border-color: var(--x-line);
}
html[data-xtheme="dark"] .table-striped > tbody > tr:nth-of-type(odd) { background: rgba(255,255,255,.035); }
html[data-xtheme="dark"] .table-hover > tbody > tr:hover { background: rgba(255,255,255,.075); }
/* Modal PHẢI tô màu ĐẶC: nó nổi trên .modal-backdrop chứ không nằm trên gradient của body,
   nên var(--x-card) = rgba(255,255,255,.04) sẽ trong suốt 96% -> đọc xuyên thấy trang dưới.
   Đây là phủ SAI chứ không phải phủ thiếu. */
html[data-xtheme="dark"] .modal-content {
  background: #0d1c2e; color: var(--x-ink);
  border: 1px solid var(--x-line2); box-shadow: 0 18px 60px -12px #000;
}
html[data-xtheme="dark"] .modal-header, html[data-xtheme="dark"] .modal-footer {
  border-color: var(--x-line); background: rgba(255,255,255,.03);
}
html[data-xtheme="dark"] .modal-title { color: var(--x-ink); }
html[data-xtheme="dark"] .close { color: var(--x-mut); text-shadow: none; opacity: .8; }
html[data-xtheme="dark"] .close:hover { color: var(--x-ink); opacity: 1; }
/* Nút bootstrap: xiris_dark.css trước đây không có một dòng nào -> .btn-default trắng nguyên */
html[data-xtheme="dark"] .btn-default {
  background: rgba(255,255,255,.06); border-color: var(--x-line); color: var(--x-ink);
}
html[data-xtheme="dark"] .btn-default:hover, html[data-xtheme="dark"] .btn-default:focus {
  background: rgba(255,255,255,.12); border-color: var(--x-line2); color: var(--x-ink);
}
html[data-xtheme="dark"] .alert-warning { background: #3a2a0d; border-color: #6b4c14; color: #fcd34d; }
html[data-xtheme="dark"] .alert-danger { background: #3a1418; border-color: #6b2028; color: #ff8f8f; }
/* Select2 (bộ chọn dự án) tự dựng DOM riêng, không ăn theo .form-control */
html[data-xtheme="dark"] .select2-container--default .select2-selection--single,
html[data-xtheme="dark"] .select2-dropdown {
  background: #0d1c2e; border-color: var(--x-line);
}
html[data-xtheme="dark"] .select2-container--default .select2-selection--single .select2-selection__rendered { color: var(--x-ink); }
html[data-xtheme="dark"] .select2-container--default .select2-results__option[aria-selected=true],
html[data-xtheme="dark"] .select2-container--default .select2-results__option--highlighted[aria-selected] { background: #1b3050; }
html[data-xtheme="dark"] .select2-search--dropdown .select2-search__field { background: #0d1c2e; color: var(--x-ink); border-color: var(--x-line); }

/* ---------- 4. Nút chuyển chế độ (xiris_switcher.js chèn vào .dong_mo_menu) ---------- */
/* Nút này khai màu cho CẢ HAI chế độ (không có tiền tố data-xtheme) — bản dưới là bản SÁNG.
   Trước đây nó là chữ trắng trên viền trắng mờ, vì thanh header khi đó tô teal #017e84.
   Thanh giờ TRẮNG (xiris_switcher.js dựng theo mẫu GREENWORLD) -> chữ trắng thành tàng hình. */
#xiris-theme {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px solid #e2e8f0; background: #f8fafc;
  color: #334155; border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600;
  white-space: nowrap; user-select: none;
}
#xiris-theme:hover { background: #eef2f6; border-color: #cbd5e1; }
html[data-xtheme="dark"] #xiris-theme {
  border-color: var(--x-line2); background: #0d1c2e; color: var(--x-teal);
  box-shadow: 0 0 12px -3px var(--x-glow);
}
html[data-xtheme="dark"] #xiris-theme:hover { background: #16283c; }

/* ---------- Dự báo & Cảnh báo AI (.aiop-wrap) — PHỦ THIẾU, tìm ra khi user báo "chìm quá" ----------
   BÀI HỌC: trước đây tưởng màn này XONG vì nó khai 11 biến CSS, cứ đảo biến là cả màn theo.
   SAI. Nó dùng biến MỘT PHẦN — 33 chỗ vẫn ghim mã màu cứng. Hậu quả tệ nhất: .det-col:first-child
   (:102) ghim background:#fff, mà CSS tối lại đổi màu CHỮ sang --x-ink -> **chữ trắng #f5fbff trên
   nền trắng #fff = 1.04:1, TÀNG HÌNH HOÀN TOÀN**. Đó chính là hộp "KHUYẾN NGHỊ XỬ LÝ" 849x568.
   Đổi màu chữ mà quên đổi màu hộp còn tệ hơn không đổi gì cả. */

/* Hộp khuyến nghị — mảng trắng to nhất màn (849x568) */
html[data-xtheme="dark"] .det-col:first-child { background: var(--x-card); }
html[data-xtheme="dark"] .det-col + .det-col { background: rgba(255,255,255,.03); border-left-color: var(--x-line); }
/* .det-act:107 viền #d7e2ef sáng */
html[data-xtheme="dark"] .det-act { border-color: var(--x-line); border-left-color: var(--x-blue); }
/* .det-safe:120-121 — khối "An toàn", nền kem #fdf6ee chữ nâu #8a4b12 (2.1:1 trên nền tối sau khi phủ) */
html[data-xtheme="dark"] .det-safe {
  background: rgba(255,201,77,.08); border-color: rgba(255,201,77,.28); color: #ffd98a;   /* 11.7:1 */
}
html[data-xtheme="dark"] .det-safe b { color: var(--x-amber); }                            /* 11.4:1 */

/* Thẻ số + KPI :48, :58 — 8 mảng trắng */
html[data-xtheme="dark"] .perf-card,
html[data-xtheme="dark"] .kpi { background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset); }

/* .btn.ghost:14 nền #fff. Và .btn:13 — nút CHÍNH nền var(--blue)=#8ec5ff (màu SÁNG của bản tối)
   với chữ trắng -> 1.81:1. Bản sáng --blue là #1266d6 nên chữ trắng đúng; bản tối đảo --blue
   thành màu sáng thì chữ PHẢI đổi sang tối, không thì nút tự tàng hình. */
html[data-xtheme="dark"] .aiop-ctl .btn { background: rgba(142,197,255,.16); color: var(--x-blue); }
html[data-xtheme="dark"] .aiop-ctl .btn.on,
html[data-xtheme="dark"] .aiop-ctl .btn.active { background: var(--x-blue); color: #03111a; }   /* 9.3:1 */
html[data-xtheme="dark"] .aiop-ctl .btn.ghost { background: rgba(255,255,255,.06); color: var(--x-mut); border-color: var(--x-line); }

/* Viên mức cảnh báo :79 và :96 — 18 viên, đều là nền nhạt + chữ đậm vẽ cho nền trắng.
   Nền tối đảo cực: nền = màu nhấn pha loãng, chữ = màu nhấn ở bậc sáng. */
/* Viên phải tô nền ĐẶC, KHÔNG dùng alpha. Lý do: viên nằm LỒNG trong thẻ (cũng alpha) trong
   hàng (cũng alpha) -> các lớp CỘNG DỒN, nền thật sáng hơn tính toán. Đã mắc: dự tính
   rgba(255,122,122,.14) + #ff7a7a cho 4.73:1, ĐO THẬT chỉ 3.25:1 vì thiếu 1 tầng trong phép tính.
   Nền đặc thì kết quả TẤT ĐỊNH, không phụ thuộc nó bị lồng sâu bao nhiêu.
   Dùng lại đúng bộ màu của .tqnav-i .st.sp-* bên dưới — đã chạy tốt, giữ cho toàn site nhất quán. */
html[data-xtheme="dark"] .alarm-sev.crit, html[data-xtheme="dark"] .accb.w { background: #3a1418; color: #ff8f8f; }    /* 6.5:1 */
html[data-xtheme="dark"] .alarm-sev.warn, html[data-xtheme="dark"] .accb.f { background: #3a2a0d; color: #fcd34d; }    /* 9.6:1 */
html[data-xtheme="dark"] .alarm-sev.fault { background: #1b2a45; color: var(--x-blue); }                               /* 7.6:1 */
html[data-xtheme="dark"] .accb.g { background: #0b312c; color: #5eead4; }                                              /* 8.9:1 */
/* .alarm-sev.ok (:79) — SÓT ở lượt trước: đã phủ crit/warn/fault mà quên .ok. Đo ra 2 viên còn trắng. */
html[data-xtheme="dark"] .alarm-sev.ok { background: #0b312c; color: #5eead4; }                                        /* 8.9:1 */
/* .det-verify (:122) ghim #2f5c8c — navy vẽ cho nền trắng, trên nền tối chỉ 2,28:1. Đây là dòng
   "kiểm tra lại sau ~15'" ở cuối mỗi khuyến nghị, tức chữ NGƯỜI VẬN HÀNH PHẢI ĐỌC. */
html[data-xtheme="dark"] .det-verify { color: var(--x-blue); }                                                                            /* 7.9:1 */

/* Bảng "Nhắc việc" (block wework, nút tròn góc dưới trái) — dùng chung MỌI màn nên phủ ở đây.
   duan.css:3363 + style.css:8368 cùng khai .wework-task-item. */
html[data-xtheme="dark"] .wework-reminder-panel { background: #0d1c2e; border-color: var(--x-line2); color: var(--x-ink); }
html[data-xtheme="dark"] .wework-task-item { background: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-ink); }
html[data-xtheme="dark"] .wework-task-item:hover { background: rgba(255,255,255,.09); }
html[data-xtheme="dark"] .wework-task-item a,
html[data-xtheme="dark"] .wework-task-item a:link,
html[data-xtheme="dark"] .wework-task-item a:visited { color: var(--x-ink); }
/* .wework-task-title tự khai color:#333 nên KHÔNG ăn theo màu của .wework-task-item -> 1.19:1,
   gần như tàng hình. Đặt màu ở thẻ cha là chưa đủ khi con tự khai màu riêng. */
html[data-xtheme="dark"] .wework-task-title { color: var(--x-ink); }                       /* 14.5:1 */
html[data-xtheme="dark"] .wework-task-meta,
html[data-xtheme="dark"] .wework-task-sub { color: var(--x-mut); }
/* .wework-section-title ghim #d80027 (đỏ thẫm vẽ cho nền trắng) -> 3.23:1 trên nền tối */
html[data-xtheme="dark"] .wework-section-title { color: #ff9b9b; }                          /* 8.5:1 */
html[data-xtheme="dark"] .wework-badge { background: #b42318; color: #fff; }
html[data-xtheme="dark"] .wework-reminder-panel .wework-empty { color: var(--x-faint); }

/* ---------- MODULE NHANSU (Quản lý nhân viên) — màn NGOÀI module duan ----------
   BÀI HỌC LẶP LẠI: phạm vi ban đầu chốt là "7 màn dự án + menu + header", nên mọi màn của
   module KHÁC (nhansu, noti, users...) không ai phủ. Nhưng chúng NẰM TRONG MENU, chủ dự án bấm
   vào là thấy ngay — và đã thấy: "màn hình này cũng lỗi đen thui nè".
   Gốc: style.css:5344 ghim `.item_menu{color:#000}` -> 13 ô chữ ĐEN TUYỀN trên nền tối = 1.1:1. */
html[data-xtheme="dark"] .item_menu {
  background: var(--x-card); border-color: var(--x-line); color: var(--x-ink);   /* 14.2:1 */
  box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .item_menu a,
html[data-xtheme="dark"] .item_menu a:link,
html[data-xtheme="dark"] .item_menu a:visited { color: var(--x-ink); }
/* :5354 hover nền vàng #FFD161 + chữ #000 — trên nền tối vẫn đọc được (chữ tối trên vàng sáng),
   nhưng vàng đặc chói và lạc bảng màu HUD. Đổi sang cyan mờ cho khớp phần còn lại. */
html[data-xtheme="dark"] .item_menu:hover { background: rgba(112,236,255,.14); border-color: var(--x-line2); }
html[data-xtheme="dark"] .item_menu:hover,
html[data-xtheme="dark"] .item_menu:hover a { color: var(--x-cyan); }             /* 11.1:1 */
html[data-xtheme="dark"] .workplace-grid .item a { color: var(--x-ink); }
/* .sidebar-footer — hộp trắng 180x63 ở góc dưới trái ("Phát triển bởi XIRIS"), hiện trên màn
   nhansu. Logo trong đó cũng là bản tối nên phải đổ trắng như logo menu. */
html[data-xtheme="dark"] .sidebar-footer {
  background: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-mut);
}
html[data-xtheme="dark"] .sidebar-footer img { filter: brightness(0) invert(1); opacity: .85; }

/* Chuông thông báo (block `noti`, xiris_switcher.js kéo vào cụm phải).
   .dropdown-menu NỔI trên trang chứ không nằm trên gradient của body -> phải tô MÀU ĐẶC,
   cho var(--x-card) = rgba(255,255,255,.04) là trong suốt 96%, đọc xuyên thấy nội dung dưới. */
html[data-xtheme="dark"] #xiris-hdr-right .btn_noti { color: var(--x-ink); }
html[data-xtheme="dark"] #xiris-hdr-right .btn_noti:hover { background: rgba(112,236,255,.12); }
html[data-xtheme="dark"] .dropdown-menu {
  background: #0d1c2e; border: 1px solid var(--x-line2); box-shadow: 0 18px 60px -12px #000;
}
html[data-xtheme="dark"] .dropdown-menu > li > a { color: var(--x-mut); }
html[data-xtheme="dark"] .dropdown-menu > li > a:hover,
html[data-xtheme="dark"] .dropdown-menu > li > a:focus { background: rgba(255,255,255,.07); color: var(--x-ink); }
html[data-xtheme="dark"] .dropdown-menu .divider { background-color: var(--x-line); }
html[data-xtheme="dark"] #box_nhan_thong_bao,
html[data-xtheme="dark"] #box_nhan_thong_bao * { color: var(--x-ink); }

/* ---------- PANEL THÔNG BÁO — kích thước + trạng thái RỖNG (áp CẢ HAI chế độ) ----------
   `noti.tpl:21` `#box_nhan_thong_bao` KHÔNG in gì khi 0 thông báo — không có cả dòng
   "chưa có thông báo". Nhưng CSS vẫn cấp cho `.dropdown-menu` nguyên 683x825 ⇒ bung ra là
   một tấm RỖNG phủ gần kín màn hình. Trước đây chuông không bấm được nên chẳng ai thấy;
   vá cho chuông bấm được xong thì lỗi này lộ ngay.
   Cố ý KHÔNG bọc trong html[data-xtheme="dark"]: lỗi này có ở CẢ hai chế độ. */
#xiris-hdr-right #dropdown_khung_thong_bao {
  width: 340px; min-width: 340px; max-width: 92vw;
  max-height: 420px; overflow-y: auto; padding: 6px;
}
#xiris-hdr-right #box_nhan_thong_bao { min-height: 0; }
/* :empty KHÔNG khớp phần tử chỉ chứa khoảng trắng, mà khoảng trắng chính là thứ nó in ra.
   Nên dùng ::after luôn có, rồi ẩn đi khi CÓ thông báo bằng luật kế tiếp. */
#xiris-hdr-right #box_nhan_thong_bao::after {
  content: 'Chưa có thông báo nào';
  display: block; padding: 26px 12px; text-align: center;
  font-size: 12.5px; color: #5b6b7b;                      /* 5,9:1 trên nền trắng */
}
html[data-xtheme="dark"] #box_nhan_thong_bao a,
html[data-xtheme="dark"] #box_nhan_thong_bao a:link,
html[data-xtheme="dark"] #box_nhan_thong_bao a:visited { color: var(--x-ink); }

/* Chip người dùng ở cụm phải của header (xiris_switcher.js dựng).
   Selector phải mang :link/:visited mới đủ ưu tiên chống a:link của style.css:1892 — xem mục 0. */
html[data-xtheme="dark"] #xiris-user,
html[data-xtheme="dark"] #xiris-user:link,
html[data-xtheme="dark"] #xiris-user:visited { color: var(--x-ink); }
html[data-xtheme="dark"] #xiris-user:hover { background: rgba(112,236,255,.12); }
html[data-xtheme="dark"] #xiris-user img { border-color: var(--x-line2); }
html[data-xtheme="dark"] #xiris-user .xu-ph { background: rgba(112,236,255,.14); color: var(--x-cyan); }
html[data-xtheme="dark"] #xiris-user .xu-tx i { color: var(--x-cyan); opacity: .9; }

/* ---------- 5. Những mảng SÁNG còn sót — tìm ra bằng cách quét DOM thật ----------
   Cách quét: duyệt mọi phần tử, đọc getComputedStyle().backgroundColor, lọc r,g,b > 225
   và alpha > .5, bỏ phần tử nhỏ hơn 4px. Đây là các chỗ nó chỉ ra. */

/* Thanh cuộn: style.css:7192 và :7208 ghim track màu #fff. .box_menu_trai cao 100vh nên
   LUÔN có thanh cuộn -> vạch trắng dọc suốt mép menu. */
html[data-xtheme="dark"] #body::-webkit-scrollbar-track,
html[data-xtheme="dark"] .box_menu_trai::-webkit-scrollbar-track,
html[data-xtheme="dark"] .content_main::-webkit-scrollbar-track { background-color: transparent; }
html[data-xtheme="dark"] #body::-webkit-scrollbar-thumb,
html[data-xtheme="dark"] .content_main::-webkit-scrollbar-thumb {
  background-color: rgba(122,219,255,.22); border-radius: 999px;
}
html[data-xtheme="dark"] #body::-webkit-scrollbar-thumb:hover,
html[data-xtheme="dark"] .content_main::-webkit-scrollbar-thumb:hover { background-color: rgba(122,219,255,.4); }
html[data-xtheme="dark"] * { scrollbar-color: rgba(122,219,255,.28) transparent; }

/* Thanh tỷ trọng: tong_quan.tpl:93 .unit-bar và :106 .acc .abar đều ghim #eef1f4.
   9 thanh gần trắng nằm ngay giữa "Sức khỏe theo cụm" — mảng sáng to nhất còn lại của màn. */
/* Thanh cân bằng nước: chọn LẠI bậc màu cho nền tối (không lật ngược bản sáng).
   Chữ vẫn tối - đã kiểm 6.22:1 và 5.82:1 trên 2 màu này. */
html[data-xtheme="dark"] .tqml-bal .u { background: #12a594; }
html[data-xtheme="dark"] .tqml-bal .l { background: #d9722a; }
html[data-xtheme="dark"] .tqml-bar { background: rgba(255,255,255,.09); }

html[data-xtheme="dark"] .unit-bar,
html[data-xtheme="dark"] .acc .abar { background: rgba(255,255,255,.09); }

/* Ô icon 30x30 ở thanh chuyển hệ: .tqnav-i .ic không đặt background nên ăn .bg-teal
   (#e2f6f4) của bảng màu chung, mà icon lại là --teal=#70ecff -> 1.5:1, gần như tàng hình.
   Phải đè cả nền lẫn chữ, không chỉ nền. */
html[data-xtheme="dark"] .tqnav-i .ic.bg-teal,
html[data-xtheme="dark"] .tqsec-t .ic.bg-teal { background: rgba(112,236,255,.14); color: var(--x-cyan); }
html[data-xtheme="dark"] .tqnav-i .ic.bg-blue,
html[data-xtheme="dark"] .tqsec-t .ic.bg-blue { background: rgba(142,197,255,.14); color: var(--x-blue); }

/* Nút tròn xanh lá góc dưới trái (style.css:8290, wework.css:3287) — màu #43b047 không
   thuộc bảng màu nào, chói trên nền tối. */
html[data-xtheme="dark"] .wework-floating-btn {
  background-color: rgba(64,247,177,.16); border: 1px solid var(--x-line2); color: var(--x-mint);
  box-shadow: 0 0 14px -4px var(--x-glow);
}

/* ===========================================================================
 * 4 MÀN CÒN LẠI — bieu_do / giam_sat_bao_tri / mang_luoi / scada
 * Bốn màn này KHÔNG khai biến CSS nào nên không có đường tắt "đảo biến" như 3 màn trước —
 * phải phủ từng quy tắc. Selector đều CHÉP NGUYÊN từ .tpl rồi thêm tiền tố
 * html[data-xtheme="dark"]: <style> nội tuyến của .tpl đứng SAU <link> này nên hoà độ ưu
 * tiên là .tpl thắng; tiền tố cộng 1 thuộc tính + 1 phần tử mới đủ thắng.
 * Khối scada và mang_luoi là BẢN ĐÃ VÁ sau phản biện chéo 3 lăng kính.
 * =========================================================================== */

/* ---------- MÀN BIEU_DO (bieu_do.tpl) ---------- */
/* VÌ SAO mọi selector đều có tiền tố html[data-xtheme="dark"] .chart-page :
 * <style> nội tuyến của bieu_do.tpl (dòng 10-109) nằm SAU <link> xiris_dark.css trong <head>.
 * Cùng độ ưu tiên thì .tpl thắng. Tiền tố cộng 1 thuộc tính + 1 lớp + 1 phần tử nên luôn vượt
 * bản gốc, đồng thời .chart-page (dòng 111) khoá phạm vi để không rò sang màn khác.
 *
 * MẶT NỀN đã GỘP CHỒNG lên #04111d (getComputedStyle chỉ trả về lớp rgba, không phải màu mắt thấy):
 *   --x-zone .022            -> #0a1622      --x-card .04             -> #0e1b26
 *   thẻ trong vùng (.04/.022)-> #141f2b      .bd-row:hover (.06/.04)  -> #1c2933
 * Mọi con số :1 trong file này tính trên các màu đó. 66/66 cặp chữ-nền đạt ngưỡng.
 *
 * CHIP thì tô ĐẶC và DÙNG LẠI đúng bộ chip đã có ở mục 2 của file này, không chế màu mới:
 *   đỏ #3a1418/#ff8f8f/#6b2028 · hổ phách #3a2a0d/#fcd34d/#6b4c14
 *   ngọc #0b312c/#5eead4/#17564d · trung tính #16283c/--x-mut/--x-line
 *   (thêm 1 họ XANH DƯƠNG #12283f/--x-blue/#1f4166 vì màn này có 3 chỗ cần: .tank-delay,
 *    .kpi-min, .bd-val .tr.down — bộ cũ không có tông này.)
 */

/* -- 1. THANH LỌC trên cùng (dòng 115) --
 * Cái div này KHÔNG CÓ CLASS, nền #f8f9fa viết thẳng vào style="". Inline thắng mọi stylesheet
 * nên bắt buộc !important — thêm class vào .tpl cũng không cứu được, inline vẫn thắng.
 * Bám chuỗi [style*=] là cách duy nhất túm được nó mà không phải sửa .tpl. */
html[data-xtheme="dark"] .chart-page .card-header-flex > div[style*="#f8f9fa"] {
  background: var(--x-zone) !important;
  border-color: var(--x-line) !important;
}
/* 4 nhãn "Chọn dự án / bể / Skid / thiết bị" (117, 124, 139, 148) — cùng một chuỗi inline
 * color:#475569. Trên nền tối chỉ 2.51:1 => gần như đọc không ra. --x-mut/vùng = 12.90:1. */
html[data-xtheme="dark"] .chart-page .card-header-flex label[style*="#475569"] {
  color: var(--x-mut) !important;
}

/* -- 2. TABS Lịch sử / Live (47-50) --
 * Chú ý dòng 49 có `border-bottom: ... !important` => phải !important lại mới đè được, độ ưu
 * tiên cao hơn cũng vô ích. Và vì đây là thẻ <a>, phải viết kèm :link/:visited: luật chung
 * `html[data-xtheme="dark"] a:link` ở mục 0 chỉ kém đúng 1 phần tử — không kèm là cưỡi lằn ranh. */
html[data-xtheme="dark"] .chart-page .custom-tabs { border-bottom-color: var(--x-line); }
html[data-xtheme="dark"] .chart-page .custom-tabs > li > a,
html[data-xtheme="dark"] .chart-page .custom-tabs > li > a:link,
html[data-xtheme="dark"] .chart-page .custom-tabs > li > a:visited { color: var(--x-mut); }   /* 13.46:1 */
html[data-xtheme="dark"] .chart-page .custom-tabs > li.active > a,
html[data-xtheme="dark"] .chart-page .custom-tabs > li.active > a:link,
html[data-xtheme="dark"] .chart-page .custom-tabs > li.active > a:visited,
html[data-xtheme="dark"] .chart-page .custom-tabs > li.active > a:hover,
html[data-xtheme="dark"] .chart-page .custom-tabs > li.active > a:focus {
  border-bottom: 3px solid var(--x-cyan) !important;                                          /* 13.72:1 */
  color: var(--x-cyan);
  background: transparent;
}
/* :focus phải có mặt: bootstrap `.nav > li > a:focus{background-color:#eee}` vẫn sống,
 * dòng 50 của .tpl chỉ chặn :hover => bấm xong tab loé mảng trắng. */
html[data-xtheme="dark"] .chart-page .custom-tabs > li > a:hover,
html[data-xtheme="dark"] .chart-page .custom-tabs > li > a:focus {
  background: rgba(112,236,255,.08);
  color: var(--x-ink);                                                                        /* 15.50:1 */
}

/* -- 3. Bảng điều khiển thời gian (52, 54) + dải Live (202-205) -- */
html[data-xtheme="dark"] .chart-page .control-panel {
  background: var(--x-card); border-color: var(--x-line);
  box-shadow: var(--x-inset);   /* bóng gốc rgba(0,0,0,.05) là bóng ĐEN — trên nền tối = vô hình */
}
html[data-xtheme="dark"] .chart-page .time-input-group label { color: var(--x-mut); }          /* 12.34:1 */
/* #live-controls (202): nền #f0fdfa + viền #a7f3d0 nằm INLINE nên đè cả .control-panel.
 * KHÔNG đụng tới display: JS bật/tắt bằng .css('display','flex') / .hide(). */
html[data-xtheme="dark"] .chart-page #live-controls {
  background: rgba(64,247,177,.06) !important;
  border-color: rgba(64,247,177,.28) !important;
}
html[data-xtheme="dark"] .chart-page #live-controls > div[style*="#047857"] {
  color: var(--x-mint) !important;                                                            /* 12.28:1 */
}
html[data-xtheme="dark"] .chart-page #countdown {
  color: var(--x-red) !important;   /* #dc2626 chỉ 3.94:1, chữ 16px đậm cần 4.5 -> trượt. Nay 6.74:1 */
}

/* -- 4. Dòng chảy các bể (19-25) -- */
html[data-xtheme="dark"] .chart-page .tank-flow-container {
  background: var(--x-zone); border-color: var(--x-line);
}
html[data-xtheme="dark"] .chart-page .tank-box {
  background: var(--x-card); border-color: var(--x-line2); box-shadow: var(--x-inset);
}
/* Viên số bể nằm VẮT qua mép hộp (top:-12px) — nửa trên đè lên vùng, nửa dưới đè lên thẻ.
 * Lớp trắng mờ sẽ đổi màu giữa chừng, nên viên này phải tô ĐẶC. */
html[data-xtheme="dark"] .chart-page .tank-box .tank-index {
  background: #0b3a55; color: var(--x-cyan);                                                  /* 8.64:1 */
  box-shadow: 0 0 12px -3px var(--x-glow);
}
html[data-xtheme="dark"] .chart-page .tank-box b { color: var(--x-ink); }                     /* 15.96:1 */
/* .tank-delay: luật này chỉ sống tới lần fetchData đầu tiên — sau đó JS gán inline đè (js_changes #7) */
html[data-xtheme="dark"] .chart-page .tank-delay {
  background: #12283f; color: var(--x-blue); border-color: #1f4166;                           /* 8.27:1 */
}
html[data-xtheme="dark"] .chart-page .flow-arrow { color: rgba(112,236,255,.55); }            /* 4.75:1 */

/* -- 5. Nút đồng bộ T0 (28-29) --
 * Cũng chỉ sống tới lần trigger('change') đầu tiên; sau đó JS gán inline (js_changes #8). */
html[data-xtheme="dark"] .chart-page .toggle-sync-btn {
  background: rgba(112,236,255,.10); border-color: var(--x-line2); color: var(--x-cyan);      /* 11.12:1 */
  box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .chart-page .toggle-sync-btn:hover { background: rgba(112,236,255,.18); }
/* Ô tick là control gốc của trình duyệt — CSS thường không với tới ruột nó, phải khai color-scheme */
html[data-xtheme="dark"] .chart-page #toggle-time-shift { color-scheme: dark; accent-color: var(--x-cyan); }

/* -- 6. Nút gạt Tổng quan / Kỹ thuật (58-61) -- */
html[data-xtheme="dark"] .chart-page .bd-toggle { border-color: var(--x-line); }
html[data-xtheme="dark"] .chart-page .bd-toggle button {
  background: rgba(255,255,255,.04); color: var(--x-mut);                                     /* 12.34:1 */
}
/* Đoạn đang chọn phải tô ĐẶC như .tk-go: nền mờ + chữ cyan thì hai đoạn nhìn gần giống nhau,
 * mất luôn ý nghĩa "đang ở chế độ nào". */
html[data-xtheme="dark"] .chart-page .bd-toggle button.active {
  background: var(--x-cyan); color: #03111a;                                                  /* 13.77:1 */
}
html[data-xtheme="dark"] .chart-page .bd-toggle button:not(.active):hover { background: rgba(255,255,255,.09); }

/* -- 7. HERO kết luận kỳ truy vấn (63-75) -- */
html[data-xtheme="dark"] .chart-page .bd-envbar {
  background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .chart-page .bd-vic.ok   { background: #0b312c; color: var(--x-mint); }   /* 10.17:1 */
html[data-xtheme="dark"] .chart-page .bd-vic.warn { background: #3a2a0d; color: var(--x-amber); }  /*  9.04:1 */
html[data-xtheme="dark"] .chart-page .bd-vic.bad  { background: #3a1418; color: var(--x-red); }    /*  6.43:1 */
html[data-xtheme="dark"] .chart-page .bd-cap { color: var(--x-mut); }   /* 10px w800 cần 4.5; --x-faint chỉ 8.69 vẫn đạt nhưng chữ 10px thì lấy mut cho chắc: 12.34:1 */
/* Ba màu này của bản sáng đều là bậc TỐI (#15803d/#b45309/#b91c1c) — đặt lên nền tối là tàng hình.
 * Chọn lại bậc theo nền tối, không lật ngược bản sáng. Chữ 16.5px < 18.66px nên ngưỡng vẫn là 4.5. */
html[data-xtheme="dark"] .chart-page .bd-verdict-t.ok   { color: var(--x-mint); }             /* 12.59:1 */
html[data-xtheme="dark"] .chart-page .bd-verdict-t.warn { color: var(--x-amber); }            /* 11.40:1 */
html[data-xtheme="dark"] .chart-page .bd-verdict-t.bad  { color: var(--x-red); }              /*  6.91:1 */
html[data-xtheme="dark"] .chart-page .bd-range { color: var(--x-mut); }                       /* 12.34:1 */
html[data-xtheme="dark"] .chart-page .bd-envstat { border-left-color: var(--x-line); }
html[data-xtheme="dark"] .chart-page .bd-envstat span { color: var(--x-mut); }                /* 12.34:1 */
/* Số 24px => ngưỡng 3.0. #0f172a của .t b là gần đen — chỗ chết người nhất của hero. */
html[data-xtheme="dark"] .chart-page .bd-envstat.d b { color: var(--x-red); }                 /*  6.91:1 */
html[data-xtheme="dark"] .chart-page .bd-envstat.w b { color: var(--x-amber); }               /* 11.40:1 */
html[data-xtheme="dark"] .chart-page .bd-envstat.s b { color: var(--x-mint); }                /* 12.59:1 */
html[data-xtheme="dark"] .chart-page .bd-envstat.t b { color: var(--x-ink); }                 /* 16.72:1 */

/* -- 8. Nhóm mức độ (78-83) -- */
html[data-xtheme="dark"] .chart-page .bd-sec-h { color: var(--x-mut); }                       /* 13.46:1 */
/* Quầng quanh chấm gốc là pastel gần trắng (#fee2e2/#dcfce7/#f1f5f9) — trên nền tối thành 3 đốm
 * loé. Đổi sang quầng cùng tông với chính chấm đó. */
html[data-xtheme="dark"] .chart-page .bd-sec-h.d .dot { background: var(--x-red);   box-shadow: 0 0 0 3px rgba(255,122,122,.22); }
html[data-xtheme="dark"] .chart-page .bd-sec-h.s .dot { background: var(--x-mint);  box-shadow: 0 0 0 3px rgba(64,247,177,.22); }
html[data-xtheme="dark"] .chart-page .bd-sec-h.n .dot { background: var(--x-faint); box-shadow: 0 0 0 3px rgba(169,185,200,.18); }
html[data-xtheme="dark"] .chart-page .bd-sec-h .cnt { background: #16283c; color: var(--x-mut); }  /* 10.58:1 */
html[data-xtheme="dark"] .chart-page .bd-sec-b {
  background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset);
}
/* Bóng đỏ gốc rgba(220,38,38,.08) không thấy gì trên nền tối; viền đỏ mới là thứ cần đọc ra. */
html[data-xtheme="dark"] .chart-page .bd-sec.d .bd-sec-b {
  border-color: rgba(255,122,122,.34);
  box-shadow: var(--x-inset), 0 0 26px -12px rgba(255,122,122,.55);
}

/* -- 9. Hàng thông số (85-107) -- */
html[data-xtheme="dark"] .chart-page .bd-row { border-bottom-color: rgba(122,219,255,.09); }  /* cùng token với .tk-t td / .tqml-t td */
html[data-xtheme="dark"] .chart-page .bd-row:hover { background: rgba(255,255,255,.06); }
html[data-xtheme="dark"] .chart-page .bd-row.danger  .rail { background: var(--x-red); }       /*  6.91:1 */
html[data-xtheme="dark"] .chart-page .bd-row.warn    .rail { background: var(--x-amber); }     /* 11.40:1 */
html[data-xtheme="dark"] .chart-page .bd-row.safe    .rail { background: var(--x-mint); }      /* 12.59:1 */
html[data-xtheme="dark"] .chart-page .bd-row.neutral .rail { background: var(--x-faint); }     /*  8.69:1 */
/* .bd-row.neutral .bd-ic khai HAI LẦN (dòng 90 và 92) cùng độ ưu tiên — dòng 92 mới là bản
 * đang chạy. Luật dưới đây cao hơn cả hai nên không cần quan tâm bản nào thắng. */
html[data-xtheme="dark"] .chart-page .bd-row.danger  .bd-ic { background: #3a1418; color: var(--x-red); }
html[data-xtheme="dark"] .chart-page .bd-row.warn    .bd-ic { background: #3a2a0d; color: var(--x-amber); }
html[data-xtheme="dark"] .chart-page .bd-row.safe    .bd-ic { background: #0b312c; color: var(--x-mint); }
html[data-xtheme="dark"] .chart-page .bd-row.neutral .bd-ic { background: #16283c; color: var(--x-mut); }
html[data-xtheme="dark"] .chart-page .bd-name b { color: var(--x-ink); }   /* #0f172a gần đen: 1.5:1. Nay 16.72:1 (14.23:1 khi hover) */
html[data-xtheme="dark"] .chart-page .bd-chip2 {
  background: #16283c; color: var(--x-mut); border-color: var(--x-line);                      /* 10.58:1 */
}
html[data-xtheme="dark"] .chart-page .bd-chip2.cfg {   /* chip "ngưỡng cấu hình" -> họ ngọc */
  background: #0b312c; color: #5eead4; border-color: #17564d;                                 /*  9.53:1 */
}
html[data-xtheme="dark"] .chart-page .bd-chip2.ref {   /* chip "tham chiếu" -> họ hổ phách */
  background: #3a2a0d; color: #fcd34d; border-color: #6b4c14;                                 /*  9.60:1 */
}
html[data-xtheme="dark"] .chart-page .bd-val .u { color: var(--x-faint); }                    /*  8.69:1 */
html[data-xtheme="dark"] .chart-page .bd-val .tr.up   { background: #3a2a0d; color: #fcd34d; }  /* 9.60:1 */
html[data-xtheme="dark"] .chart-page .bd-val .tr.down { background: #12283f; color: var(--x-blue); } /* 8.27:1 */
html[data-xtheme="dark"] .chart-page .bd-val .tr.flat { background: #16283c; color: var(--x-mut); }  /* 10.58:1 */
html[data-xtheme="dark"] .chart-page .bd-sent small { color: var(--x-faint); }                /*  8.69:1 */
html[data-xtheme="dark"] .chart-page .bd-na { color: var(--x-faint); }                        /*  8.69:1 */
html[data-xtheme="dark"] .chart-page .bd-spark2 {
  background: rgba(255,255,255,.03); border-color: var(--x-line);
}

/* -- 10. Bảng KPI (33-43) -- */
html[data-xtheme="dark"] .chart-page .kpi-widget {
  background: var(--x-card);
  border-color: var(--x-line);
  border-top-color: var(--x-cyan);   /* phải đứng SAU border-color, nếu không bị nuốt mất */
  box-shadow: var(--x-inset);
}
/* Hover gốc chỉ đổi bóng ĐEN đậm hơn => trên nền tối bấm vào không thấy gì phản hồi. */
html[data-xtheme="dark"] .chart-page .kpi-widget:hover {
  box-shadow: var(--x-inset), 0 0 22px -6px var(--x-glow);
  border-color: var(--x-line2);
  border-top-color: var(--x-cyan);
}
html[data-xtheme="dark"] .chart-page .kpi-title { color: var(--x-ink); border-bottom-color: var(--x-line); }
html[data-xtheme="dark"] .chart-page .kpi-skid { background: #16283c; color: var(--x-mut); }  /* 10.58:1 */
html[data-xtheme="dark"] .chart-page .kpi-label { color: var(--x-faint); }                    /*  8.69:1 */
/* MAX/AVG/MIN: 3 màu bản sáng #dc2626/#059669/#2563eb đều là bậc tối, chọn cho nền trắng. */
html[data-xtheme="dark"] .chart-page .kpi-max .kpi-value { color: var(--x-red); }             /*  6.91:1 */
html[data-xtheme="dark"] .chart-page .kpi-avg .kpi-value { color: var(--x-mint); }            /* 12.59:1 */
html[data-xtheme="dark"] .chart-page .kpi-min .kpi-value { color: var(--x-blue); }            /*  9.62:1 */

/* -- 11. Hộp biểu đồ do JS sinh (dòng 665 VÀ 854 — mã trùng ở 2 chỗ) --
 * background:#fff nằm INLINE => !important. Dùng CSS chứ không sửa JS vì một luật này bịt
 * được CẢ HAI chỗ sinh; sửa JS thì phải nhớ sửa đủ 2 dòng. */
html[data-xtheme="dark"] .chart-page .chart-group-box {
  background: var(--x-card) !important;
  border-color: var(--x-line) !important;
  box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .chart-page .chart-group-box > h4 {
  color: var(--x-ink) !important;   /* inline color:#333 = 1.51:1, tên nhóm thiết bị coi như biến mất */
}

/* -- 12. HIGHCHARTS (SVG, không phải canvas nên CSS vẫn với tới) --
 * fill/stroke Highcharts ghi ra là THUỘC TÍNH TRÌNH BÀY => CSS thắng, KHÔNG cần !important.
 * Riêng cái gì khai qua options.style thì Highcharts gọi .css() => thành INLINE => phải !important.
 * Tooltip (743-744, 934-935, 1345) ĐÃ SẴN TỐI rgba(15,23,42,.95)+#fff = 14.6:1 — kiểm rồi, không đụng. */
html[data-xtheme="dark"] .chart-page .highcharts-background { fill: transparent; }  /* để mặt .chart-group-box lộ qua */
html[data-xtheme="dark"] .chart-page .highcharts-grid-line { stroke: rgba(122,219,255,.10); }  /* = --grid của .tkw */
html[data-xtheme="dark"] .chart-page .highcharts-xaxis .highcharts-axis-line { stroke: rgba(122,219,255,.30); }  /* = --axis. CHỈ trục x: lineColor trục y là màu series, phải giữ */
html[data-xtheme="dark"] .chart-page .highcharts-axis-labels text {
  fill: var(--x-mut) !important;    /* labels.style.color:'#666' -> Highcharts .css() -> inline */
}
html[data-xtheme="dark"] .chart-page .highcharts-xaxis .highcharts-axis-title {
  fill: var(--x-faint) !important;  /* '#64748b' (714/905). Không đụng title trục y — nó mang màu series */
}
/* zoomType:'x' đang bật => kéo chuột xong hiện nút "Reset zoom" nền #f7f7f7 chữ #333. */
html[data-xtheme="dark"] .chart-page .highcharts-button-box { fill: rgba(255,255,255,.06); stroke: var(--x-line2); }
html[data-xtheme="dark"] .chart-page .highcharts-button text { fill: var(--x-ink) !important; }

/* -- 13. Modal chi tiết 1 cảm biến (249-257) --
 * .modal-content đã phủ ở mục 3 (#0d1c2e đặc). Nhưng .modal-header có style="background:#1e293b"
 * INLINE nên đè luôn luật .modal-header của mục 3 => đầu modal là slate-800, thân là navy #0d1c2e:
 * hai màu tối khác họ dán cạnh nhau, nhìn ra ngay là lỗi. Đây là lỗi THẨM MỸ chứ không phải
 * tương phản (#fff trên #1e293b = 14.63:1, vẫn đạt). */
html[data-xtheme="dark"] .chart-page #bdDetailModal .modal-header {
  background: rgba(255,255,255,.03) !important;
  border-bottom: 1px solid var(--x-line);
}

/* -- 14. Ô giờ gốc của trình duyệt (179, 186) --
 * input[type=time] không nằm trong danh sách ô nhập ở mục 3, nhưng nó mang class .form-control
 * nên nền/chữ đã đúng. Cái CSS không với tới là ĐỒNG HỒ + bảng chọn giờ do trình duyệt vẽ. */
html[data-xtheme="dark"] .chart-page input[type="time"] { color-scheme: dark; }

/* -- 15. GAP: select2 chế độ CHỌN NHIỀU --
 * KHÔNG phải phủ lại: mục 3 của file này chỉ phủ .select2-selection--single. Màn này có 3 ô
 * multiple (be_id 126, kid_id 140, thong_so 149) => 3 khung trắng bự nhất màn.
 * Không khoá được vào .chart-page: select2 tự dựng DOM và gắn vào <body>. */
html[data-xtheme="dark"] .select2-container--default .select2-selection--multiple {
  background-color: #0d1c2e; border-color: var(--x-line);
}
html[data-xtheme="dark"] .select2-container--default.select2-container--focus .select2-selection--multiple {
  border-color: var(--x-cyan);   /* gốc là `border: solid black 1px` — đen trên đen = không thấy đang focus */
}
html[data-xtheme="dark"] .select2-container--default .select2-selection--multiple .select2-selection__choice {
  background-color: #16283c; border-color: var(--x-line2); color: var(--x-ink);               /* 14.35:1 */
}
html[data-xtheme="dark"] .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
  color: var(--x-faint); border-right-color: var(--x-line2);
}
html[data-xtheme="dark"] .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
  color: var(--x-red); background-color: transparent;
}
/* Ô gõ tìm nằm trong khung: type="search" nên KHÔNG lọt vào luật input[type=text] ở mục 3. */
html[data-xtheme="dark"] .select2-search--inline .select2-search__field { color: var(--x-ink); }

/* -- 16. GAP: lịch jQuery UI (nạp ở dòng 2-4, gọi ở 345 cho #tu_ngay/#den_ngay) --
 * Cũng chưa hề được phủ. jquery-ui.min.css cho `.ui-widget-content{background:#fff;color:#333}`
 * => bấm vào ô ngày là loé một tấm lịch TRẮNG giữa màn tối.
 * Lịch NỔI trên trang chứ không nằm trên gradient của body => phải tô ĐẶC (bẫy modal). */
html[data-xtheme="dark"] .ui-datepicker {
  background: #0d1c2e; border: 1px solid var(--x-line2); color: var(--x-ink);
  box-shadow: 0 18px 50px -12px #000;
}
html[data-xtheme="dark"] .ui-datepicker .ui-datepicker-header {
  background: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-ink);
}
html[data-xtheme="dark"] .ui-datepicker th { color: var(--x-mut); }                           /* 12.14:1 */
/* Ô ngày là <a class="ui-state-default"> => dính bẫy a:link. Luật chung ở mục 0 đang kéo nó về
 * cyan (cả tháng toàn số cyan, đọc rất mệt); kèm :link/:visited ở đây để giành lại --x-ink. */
html[data-xtheme="dark"] .ui-datepicker .ui-state-default,
html[data-xtheme="dark"] .ui-datepicker .ui-state-default:link,
html[data-xtheme="dark"] .ui-datepicker .ui-state-default:visited {
  background: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-ink);        /* 16.46:1 */
}
html[data-xtheme="dark"] .ui-datepicker .ui-state-hover,
html[data-xtheme="dark"] .ui-datepicker .ui-state-default:hover {
  background: rgba(112,236,255,.14); border-color: var(--x-line2); color: var(--x-cyan);
}
html[data-xtheme="dark"] .ui-datepicker .ui-state-active,
html[data-xtheme="dark"] .ui-datepicker .ui-state-active:link,
html[data-xtheme="dark"] .ui-datepicker .ui-state-active:visited {
  background: var(--x-cyan); border-color: var(--x-cyan); color: #03111a;                     /* 13.77:1 */
}
html[data-xtheme="dark"] .ui-datepicker .ui-state-highlight { background: #3a2a0d; border-color: #6b4c14; color: #fcd34d; }
/* 2 mũi tên tháng trước/sau là ẢNH SPRITE nét sẫm — CSS không sửa được ruột ảnh, chỉ lật màu được. */
html[data-xtheme="dark"] .ui-datepicker .ui-icon { filter: invert(1) brightness(1.35); }
/* (changeMonth/changeYear:true sinh 2 <select> trần — mục 3 đã phủ rồi, không lặp lại.) */

/* ---------- MÀN GIAM_SAT_BAO_TRI (giam_sat_bao_tri.tpl) ---------- */
/* KHÔNG CÓ BIẾN CSS NÀO ĐỂ ĐẢO — gợi ý "2 biến" là nhầm.
   Đã grep `var\(--` và `^\s*--[a-z]` trên toàn file: 0 kết quả. Thứ trông giống biến chỉ là
   `.select2-selection--single::after` (dòng 48-49) lọt regex. Màn này ghim hex THẲNG vào 49
   quy tắc trong <style> nội tuyến (dòng 4-75) + 3 chỗ style="" trong markup, nên không có
   đường tắt: phải phủ từng quy tắc. (xiris_font.css:310 có nhắc .gs-page nhưng chỉ đặt
   font-family, không đụng màu -> không liên quan.)

   MỌI selector dưới đây = CHÉP NGUYÊN selector của .tpl + tiền tố html[data-xtheme="dark"].
   Không rút gọn: <style> của .tpl nằm SAU <link> nên cùng độ ưu tiên là .tpl thắng.

   KHÔNG BỌC `.gs-page` — đây là chỗ dễ hỏng nhất của màn này. 2 modal (dòng 135, 158) nằm
   NGOÀI div.gs-page (đóng ở dòng 132), mà JS dòng 371 lại dựng bảng lịch sử bằng chính class
   .gs-tb, và dòng 365/369 dùng .gs-loading. Scope theo .gs-page = bảng trong modal Lịch sử
   giữ nguyên th trắng #f8fafc. Chép nguyên selector thì hai nơi ăn chung một luật.

   Bẫy a:link KHÔNG áp dụng ở màn này: soát toàn markup có 0 thẻ <a>; .btn-link-filter
   (dòng 67) gắn lên <button> (dòng 187-189). Không canvas / Highcharts / Cytoscape / three.js
   -> không có gì phải đẩy sang js_changes vì lý do vẽ.

   TƯƠNG PHẢN: tính bằng cách GỘP CHỒNG lớp trong suốt lên nền đáy #04111d (L=0.00515).
   Mặt thẻ --x-card rgba(255,255,255,.04) chồng lên đáy -> L=0.00996 (mốc dùng lại bên dưới).
   Nền modal đặc #0d1c2e -> L=0.01114. */

/* --- 1. Gốc màn: chữ + 4 mặt thẻ trắng (dòng 5, 6, 10, 14, 51) ---
   Bản sáng ghim #fff cho hero/kpi/unit/filter. Không tô màu đặc thay thế: --x-card là lớp
   trắng mờ để gradient của body xuyên qua, thẻ gần quầng sáng khác thẻ ở xa. Viền lấy
   --x-line (xanh sáng mờ) vì chính nó tạo cạnh trên nền tối, viền tối thì không thành cạnh. */
html[data-xtheme="dark"] .gs-page { color: var(--x-ink); }            /* #f5fbff / thẻ L.00996 = 16.79:1 */
html[data-xtheme="dark"] .gs-hero,
html[data-xtheme="dark"] .gs-kpi,
html[data-xtheme="dark"] .gs-unit,
html[data-xtheme="dark"] .gs-filter {
  background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .gs-hero h2 { color: var(--x-ink); }         /* 16.79:1 */

/* Viên vai trò (dòng 8): bản sáng #e0f2fe/#075985 là cặp vẽ cho nền trắng, lật sang nền tối
   là nhoè. Chọn lại bậc màu theo nền tối, theo đúng lối .tqnav-i .ic.bg-teal đã có. */
html[data-xtheme="dark"] .gs-hero .gs-role {
  background: rgba(112,236,255,.14); color: var(--x-cyan);            /* cyan / viên L.03479 = 8.92:1 */
}

/* --- 2. KPI (dòng 12, 13) ---
   3 màu số #dc2626/#d97706/#16a34a là bậc chọn cho nền TRẮNG; trên nền tối chúng tụt xuống
   dưới ngưỡng. Không lật ngược — lấy thẳng bộ đã kiểm của theme. */
html[data-xtheme="dark"] .gs-kpi span { color: var(--x-faint); }      /* #a9b9c8 / thẻ = 8.72:1 (11.5px cần 4.5) */
html[data-xtheme="dark"] .gs-kpi.overdue b { color: var(--x-red); }   /* #ff7a7a / thẻ = 6.94:1 */
html[data-xtheme="dark"] .gs-kpi.due b     { color: var(--x-amber); } /* #ffc94d / thẻ = 11.44:1 */
html[data-xtheme="dark"] .gs-kpi.safe b    { color: var(--x-green); } /* #40f7b1 / thẻ = 12.64:1 */
/* .gs-kpi b (dòng 11) không đặt color -> tự ăn --x-ink của .gs-page. Không cần luật. */

/* --- 3. Khối Unit / Thiết bị (dòng 15, 16, 19, 20) ---
   .gs-unit-head chồng thêm 1 lớp .05 LÊN TRÊN mặt .gs-unit (.04) -> L=0.01824, vẫn nổi lên
   khỏi thân thẻ mà không phá tính trong suốt. */
html[data-xtheme="dark"] .gs-unit-head {
  background: rgba(255,255,255,.05); color: var(--x-ink);             /* 14.75:1 */
  border-bottom: 1px solid var(--x-line);
}
html[data-xtheme="dark"] .gs-dev { border-top-color: var(--x-line); }
html[data-xtheme="dark"] .gs-dev-head .cd { color: var(--x-faint); }  /* 8.72:1 (12px cần 4.5) */
html[data-xtheme="dark"] .gs-rt {
  background: rgba(142,197,255,.14); border-color: rgba(142,197,255,.28);
  color: var(--x-blue);                                              /* #8ec5ff / chip L.03043 = 7.20:1 */
}

/* --- 4. BẢNG (dòng 22, 23, 37) — dùng ở CẢ .gs-page LẪN trong modal Lịch sử (JS dòng 371).
   Vì th chỉ là lớp trắng mờ nên nó tự đúng ở hai nơi: trên thẻ -> L=0.01824, trên modal đặc
   -> L=0.01972. Chữ --x-mut đạt cả hai (10.88:1 và 10.65:1). Một luật, hai chỗ. */
html[data-xtheme="dark"] .gs-tb th,
html[data-xtheme="dark"] .gs-tb td { border-color: var(--x-line); }
html[data-xtheme="dark"] .gs-tb th {
  background: rgba(255,255,255,.05); color: var(--x-mut);             /* 10.88:1 trên thẻ · 10.65:1 trong modal */
}
html[data-xtheme="dark"] .gs-tb tr:hover td { background: rgba(255,255,255,.075); } /* ink 13.68:1 */

/* --- 5. VIÊN TRẠNG THÁI (dòng 25, 26, 27) — 5 viên, status_key sinh ở JS dòng 274,
   danh sách khoá lấy từ dòng 120-124: overdue/due/ok/no-cycle/off.
   Bản sáng là "nền nhạt + chữ đậm". Nền tối cần bộ NGƯỢC LẠI: nền đậm + chữ sáng. Tô MÀU ĐẶC
   (không rgba) để viên không đổi sắc theo việc nằm trên thẻ hay trong modal. */
html[data-xtheme="dark"] .gs-badge.overdue  { background: #3a1418; color: #ff8f8f; }        /* 7.41:1 */
html[data-xtheme="dark"] .gs-badge.due      { background: #3a2a0d; color: #fcd34d; }        /* 9.60:1 */
html[data-xtheme="dark"] .gs-badge.ok       { background: #0b312c; color: #5eead4; }        /* 9.53:1 */
html[data-xtheme="dark"] .gs-badge.off      { background: #16283c; color: var(--x-mut); }   /* 10.58:1 */
html[data-xtheme="dark"] .gs-badge.no-cycle { background: #0b2c3a; color: var(--x-cyan); }  /* 10.54:1 */

/* --- 6. NÚT THAO TÁC (dòng 29, 35, 36) ---
   .gs-btn.done: #16a34a + #fff chỉ được 3.30:1 — TRƯỢT 4.5:1 (chữ 12px đậm < 18.66px).
   Đây là lỗi có thật chứ không phải chuyện gu màu. Lật sang lối CTA của theme (.tk-go dòng
   202): nền sáng + chữ tối.
   .gs-btn.hist: #334155 nằm sát mặt thẻ -> nút/thẻ chỉ 1.69:1, nút icon 32px gần như tan vào
   thẻ. Cho lớp sáng hơn + vòng viền. Dùng inset box-shadow chứ KHÔNG dùng border, vì .gs-btn
   đang border:0 và height:28px — thêm border thật sẽ đội nút lên 2px, lệch hàng. */
html[data-xtheme="dark"] .gs-btn.done { background: var(--x-mint); color: #03111a; }  /* 13.79:1 */
html[data-xtheme="dark"] .gs-btn.done:hover { background: #79ffc9; color: #03111a; }  /* 15.43:1 */
html[data-xtheme="dark"] .gs-btn.hist {
  background: rgba(255,255,255,.10); color: var(--x-mut);             /* 9.32:1 */
  box-shadow: inset 0 0 0 1px var(--x-line2);                        /* vòng/thẻ = 2.58:1 — xem rui_ro */
}
html[data-xtheme="dark"] .gs-btn.hist:hover {
  background: rgba(255,255,255,.16); color: var(--x-ink);
  box-shadow: inset 0 0 0 1px var(--x-cyan);
}

/* --- 7. Dòng chờ (dòng 30) — xuất hiện cả trên trang lẫn trong modal Lịch sử (JS dòng 365, 369) */
html[data-xtheme="dark"] .gs-loading { color: var(--x-faint); }       /* 9.48:1 trên trang · 8.55:1 trong modal */

/* --- 8. SELECT2 chọn dự án (dòng 39, 40, 43, 45, 46, 48, 49) ---
   Dòng 45-46 dùng !important (tác giả tự ghi chú là để đè duan.css). Độ ưu tiên của tiền tố
   KHÔNG cứu được ở đây — !important thắng bất kể specificity — nên bắt buộc !important lại.
   Một luật này phủ luôn dòng 39-40 (cùng thuộc tính, ưu tiên thấp hơn). */
html[data-xtheme="dark"] .gs-hero .select2-selection--single {
  background: #0d1c2e !important; border-color: var(--x-line) !important;
}
html[data-xtheme="dark"] .gs-hero .select2-selection__rendered {
  color: var(--x-ink) !important;                                     /* ink / #0d1c2e = 16.46:1 */
}
/* Trạng thái MỞ phải viết riêng: luật trên có !important nên nó sẽ giết luôn viền nhấn của
   dòng 43 -> mở dropdown mà không thấy phản hồi. Phải trả lại bằng !important cùng cấp. */
html[data-xtheme="dark"] .gs-hero .select2-container--open .select2-selection--single {
  border-color: var(--x-cyan) !important; box-shadow: 0 0 0 3px var(--x-glow);
}
/* Mũi tên tự vẽ (dòng 48). Dòng 42 tô .select2-selection__arrow b màu #475569 nhưng dòng 47
   đã display:none !important cả arrow -> bỏ qua, phủ nó là phủ vào chỗ không hiển thị. */
html[data-xtheme="dark"] .gs-hero .select2-selection--single::after {
  border-top-color: var(--x-faint);
}
/* BẪY: luật ngay trên là (0,3,1), còn dòng 49 của .tpl xoá mũi tên xuống bằng
   border-top-color:transparent chỉ ở (0,3,0) -> luật của ta THẮNG và khi mở sẽ hiện CẢ hai
   mũi tên chồng nhau. Phải khẳng định lại transparent ở (0,4,1). */
html[data-xtheme="dark"] .gs-hero .select2-container--open .select2-selection--single::after {
  border-top-color: transparent; border-bottom-color: var(--x-cyan);
}
/* Nhãn "Dự án" (dòng 84) ghim style="color:#475569" NGAY TRONG THẺ -> inline thắng mọi
   stylesheet, chỉ !important mới gỡ được. Xem js_changes để bỏ hẳn inline rồi rút !important. */
html[data-xtheme="dark"] .gs-hero label[style] { color: var(--x-mut) !important; }  /* 12.38:1 */

/* --- 9. BỘ LỌC (dòng 53, 56, 57) ---
   Dòng 54 (.gs-filter select) KHÔNG phủ lại: xiris_dark.css:228 `html[data-xtheme="dark"] select`
   là (0,1,2), đã thắng sẵn (0,1,1) của .tpl -> nền/viền/chữ của #f_status đã đúng rồi. */
html[data-xtheme="dark"] .gs-filter label { color: var(--x-mut); }    /* 12.38:1 */
html[data-xtheme="dark"] .dropdown-check-list .anchor {
  background: rgba(255,255,255,.06); border-color: var(--x-line);      /* ink / L.02027 = 14.32:1 */
}
html[data-xtheme="dark"] .dropdown-check-list .anchor:after { border-top-color: var(--x-faint); }

/* --- 10. DROPDOWN LỌC (dòng 58, 60, 61, 64, 65) ---
   ul.items là position:absolute + z-index:999, NỔI TRÊN nội dung trang -> bắt buộc MÀU ĐẶC.
   Cho nó --x-card (rgba .04) là trong suốt 96%, đọc xuyên thấy KPI/bảng bên dưới.
   Bóng cũ rgba(15,23,42,.12) là bóng vẽ cho nền sáng, trên nền tối coi như không có. */
html[data-xtheme="dark"] .dropdown-check-list ul.items {
  background: #0d1c2e; border-color: var(--x-line2);
  box-shadow: 0 18px 40px -10px #000;
}
html[data-xtheme="dark"] .dropdown-check-list ul.items li.filter-action-line { border-bottom-color: var(--x-line); }
html[data-xtheme="dark"] .dropdown-check-list ul.items li label { color: var(--x-mut); }  /* 12.14:1 */
/* Ô tìm (dòng 64): xiris_dark.css:228 đã cho nền #0d1c2e — nhưng dropdown CŨNG là #0d1c2e,
   thành ra ô nhập tàng hình trong hộp. Selector .tpl ở đây là (0,3,3), thắng (0,1,2) của
   luật chung, nên phải tự đặt lại cả nền lẫn viền tại (0,4,4). */
html[data-xtheme="dark"] .dropdown-check-list ul.items li.filter-search input {
  background: rgba(255,255,255,.06); border-color: var(--x-line); color: var(--x-ink);  /* 14.02:1 */
}
html[data-xtheme="dark"] .dropdown-check-list ul.items li.filter-search input:focus {
  border-color: var(--x-cyan); box-shadow: 0 0 0 2px var(--x-glow);
}
/* Ô tích (JS dòng 193, 198, 200): trình duyệt vẽ ô checked bằng xanh mặc định, lạc khỏi bảng
   màu. accent-color đổi được mà không đụng ô chưa tích — ô trắng chưa tích trên nền tối vẫn
   là dấu hiệu tốt, không cần sửa. */
html[data-xtheme="dark"] .chk-flt { accent-color: var(--x-cyan); }

/* --- 11. Nút chữ trong dropdown (dòng 67, 68) — là <button>, không phải <a>, nên bẫy a:link
   không dính. #0284c7 trên #0d1c2e quá tối, phải nâng bậc. */
html[data-xtheme="dark"] .btn-link-filter { color: var(--x-cyan); }        /* 12.37:1 */
html[data-xtheme="dark"] .btn-link-filter:hover { color: var(--x-ink); }   /* 16.46:1 */

/* --- 12. Nút Xoá lọc (dòng 70, 71) --- */
html[data-xtheme="dark"] .gs-btn-ghost {
  background: rgba(255,255,255,.06); border-color: var(--x-line); color: var(--x-mut);  /* 10.57:1 */
}
html[data-xtheme="dark"] .gs-btn-ghost:hover {
  background: rgba(255,255,255,.12); border-color: var(--x-line2); color: var(--x-ink); /* 11.82:1 */
}

/* --- 13. Đầu modal Ghi nhận (dòng 137) ---
   style="background:#16a34a;color:#fff" là INLINE -> thắng cả xiris_dark.css:248, nên hiện
   giờ dải xanh lá vẫn nguyên trong chế độ tối. Và nó TRƯỢT thật: #fff trên #16a34a = 3.30:1,
   chữ <b> ~14px cần 4.5:1. Chỉ !important mới gỡ được inline.
   Modal Lịch sử (dòng 160, #334155/#fff = 10.35:1) ĐẠT -> để nguyên, không đụng. */
html[data-xtheme="dark"] #gsLogModal .modal-header {
  background: rgba(64,247,177,.10) !important; color: var(--x-mint) !important;  /* 9.82:1 */
  border-bottom: 1px solid var(--x-line);
}

/* ---------- MÀN MANG_LUOI (mang_luoi.tpl) ---------- */
/* Màn này KHÔNG có một wrapper duy nhất — nó có HAI, và phải đối xử khác nhau:
     .ml-bar  (tpl:162) — thanh công cụ, nằm TRÊN gradient của body  -> nền đáy #04111d
     .w3d-app (tpl:170) — khung 3D ĐỤC, bên trong là WebGL canvas    -> nền đáy là CẢNH 3D
   Mọi chú giải/bảng/hộp bên trong .w3d-app nổi trên canvas chứ KHÔNG nổi trên gradient của
   body. Đó là lý do cả khối này không dùng var(--x-card): rgba(255,255,255,.04) trên canvas
   là trong suốt 96%, chữ sẽ nằm đè lên ống nước và không đọc được. Các lớp nổi tô ĐẶC #0d1c2e
   (đúng cách modal đang làm), chỉ chú giải/gợi ý giữ .93/.92 như bản sáng để còn thấy cảnh.

   ĐỘ ƯU TIÊN: hai khối <style> nằm NGAY TRONG .tpl -> đứng SAU <link xiris_dark.css> trong
   head. Vì vậy mọi selector dưới đây được CHÉP NGUYÊN của .tpl rồi thêm tiền tố, không rút gọn.

   TƯƠNG PHẢN: số trong chú thích là tính thật, gộp chồng lớp trong suốt lên đúng nền của nó
   (#04111d cho .ml-bar, #0d1c2e cho các lớp nổi trong .w3d-app), không phải ước lượng.

   VIỀN: chỗ nào tpl ĐÃ có border thì chỉ đổi border-color (.w3d-app, .ml-ro, .w3d-ef input);
   chỗ nào tpl KHÔNG có border thì vẽ vòng viền bằng box-shadow inset (.w3d-if, .ml-meta,
   .w3d-ih) — thêm border vào là đội thêm 1-2px, mà phủ là TÔ LẠI chứ không bày lại. */

/* ===== A. Thanh công cụ .ml-bar — vùng DUY NHẤT của màn nằm trên gradient body ===== */
/* tpl:147 #0f172a chữ tiêu đề trên nền tối = 1.10:1 — tàng hình, đây là chỗ hỏng thật.
   tpl:148 #017e84 = 3.92:1 (KHÔNG phải ~2.2:1): phần tử này là <i class="fa fa-sitemap">
   (tpl:163), tức GLYPH biểu tượng nên ngưỡng là 3.0 (WCAG 1.4.11 non-text) -> ĐẠT. Đổi sang
   cyan là để ĐỒNG BỘ MÀU NHẤN, không phải để vá tương phản. */
html[data-xtheme="dark"] .ml-bar h3 { color: var(--x-ink); }        /* 18.24:1 */
html[data-xtheme="dark"] .ml-bar h3 i { color: var(--x-cyan); }     /* 13.72:1 */
/* tpl:150 — viên "N phần tử · N đường ống": nền #e6f4f4 là mảng sáng to nhất của thanh.
   Đổi sang lớp cyan mờ để nó ăn theo gradient bên dưới thay vì trổ một ô trắng.
   tpl:150 KHÔNG đặt border -> vẽ vòng viền bằng inset, không thêm border (xem ghi chú VIỀN
   ở đầu khối). Bản sáng .ml-meta vốn đã thấp hơn .ml-ro 2px vì .ml-ro có border; giữ nguyên
   chênh lệch đó thay vì "sửa" nó ở riêng bản tối. */
html[data-xtheme="dark"] .ml-meta {
  background: rgba(112,236,255,.12); color: var(--x-cyan);          /* 10.58:1 */
  box-shadow: inset 0 0 0 1px var(--x-line);
}
/* tpl:151 — viên "Chỉ xem": cùng lý do, nhưng đây là trạng thái trung tính nên giữ xám.
   tpl:151 CÓ sẵn border:1px -> chỉ đổi màu, không đổi hình. */
html[data-xtheme="dark"] .ml-ro {
  background: rgba(255,255,255,.05); color: var(--x-mut);           /* 12.08:1 */
  border-color: var(--x-line);
}
/* tpl:158 — viền lúc đang chọn dự án. Nền/chữ/viền-thường của Select2 đã có sẵn ở mục 3 của
   file này, RIÊNG trạng thái focus/open thì chưa; #017e84 trên nền tối coi như không thấy
   -> mở hộp ra mà không biết nó đang mở. Tiền tố cho (0,4,1), thắng cả tpl (0,3,0) lẫn luật
   Select2 chung (0,3,1). */
html[data-xtheme="dark"] .ml-bar .select2-container--focus .select2-selection--single,
html[data-xtheme="dark"] .ml-bar .select2-container--open .select2-selection--single {
  border-color: var(--x-cyan); box-shadow: 0 0 0 2px var(--x-glow);
}

/* ===== B. Khung 3D và các lớp nổi trên canvas ===== */
/* tpl:3 — #c9d6e6 là màu trời của cảnh ban ngày; nó lộ ra ở mép bo góc và loé lên trong lúc
   chờ dựng cảnh -> một mảng xanh nhạt nhấp nháy giữa trang tối. Viền đổi sang cyan mờ chứ
   không đổi sang một màu tối hơn: trên nền tối chỉ viền SÁNG mới vẽ ra được cạnh.
   Nhận: viền này 2.55:1 so với nền trang, dưới 3:1 — chấp nhận có ý thức, vì nó chỉ là khung
   trang trí quanh một khung nhìn 3D vốn đã tự có cạnh, không phải nút bấm. */
html[data-xtheme="dark"] .w3d-app {
  background: var(--x-page); border-color: var(--x-line2);
  box-shadow: 0 0 34px -12px var(--x-glow);
}
/* tpl:20 — màn chờ "Đang dựng cảnh 3D…". */
html[data-xtheme="dark"] .w3d-loading {
  background: var(--x-page); color: var(--x-mut);                   /* 13.46:1 */
}
/* tpl:8 — 12 thẻ <a> công cụ (tpl:175, 178-188; tpl:184 mang sẵn .act).
   ĐÂY LÀ BẪY 2, NẰM NGAY TRONG FILE NÀY — không bỏ qua được:
   `.w3d-top a{color:#fff}` chỉ (0,1,1), THUA mục 0 (dòng 60-63) `html[data-xtheme="dark"]
   a:link` (0,2,2) -> cả thanh công cụ hoá cyan. Trên nền trắng nó sống được vì style.css:1892
   `a:link` cũng (0,1,1) -> HOÀ -> <style> của tpl đứng sau nên thắng; sang bản tối thì
   (0,2,2) > (0,1,1), thắng bất kể thứ tự. Chỉ tpl:109 `.w3d-top a.act`, tpl:21 `.w3d-sync`,
   tpl:23 `#w3dRec.rec` sống sót vì có !important -> nút "Hiệu ứng" (tpl:184) trắng khi BẬT,
   cyan khi TẮT: nhấp nháy đổi màu mỗi lần bấm.

   NỀN THẬT sau nút là TRỜI của cảnh 3D, KHÔNG phải gradient của body. skyMat
   (sodo3d_view.js:130) đặt bot=#eef4fb (chân trời, gần TRẮNG) / top=#6ea8e8, và fragment
   shader (js:131) cho t=pow(smoothstep(-0.1,0.75,h),0.75) -> ở độ cao thanh công cụ h≈0
   nên t≈0.09, tức trời ở đó gần như #eef4fb. Đo gộp chồng thật (trời -> gradient tpl:6 ->
   nền nút rgba(255,255,255,.16)), quét cả 2 đầu trời × 4 mức gradient:
       HIỆN TẠI:  cyan 1.01-2.97:1  ·  #fff 1.09-4.13:1   -> TRƯỢT 4.5 ở MỌI điểm.
   Nên trả #fff lại là CẦN nhưng CHƯA ĐỦ — phải hạ nền nút xuống kính tối. Dùng đúng thành ngữ
   đã có sẵn trong chính tpl này: .w3d-nav button (tpl:133) = rgba(15,23,42,.44) + #fff + viền
   mờ. Không chế kiểu mới, và chỉ đổi MÀU (border-color), không đổi hình.
   Sau vá: #fff 5.19-11.87:1 (xấu nhất 5.19 ở chân trời + gradient tắt) — ĐẠT ở mọi điểm, và
   vẫn đạt nếu người dùng bật "Ban đêm" (trời tối đi thì càng tăng).
   Tiền lệ: .w3d-ih bên dưới cũng là chỗ bản sáng hỏng sẵn và đã CHỌN LẠI bậc màu cho nền tối
   thay vì bê nguyên — làm giống vậy ở đây.

   ĐỘ ƯU TIÊN: nhánh có :link/:visited = (0,3,2), THẮNG mục 0 (0,2,2) dứt điểm. Nhánh trần chỉ
   (0,2,2) -> HOÀ với mục 0, thắng được là nhờ khối này nằm cuối file; giữ nhánh trần cho <a>
   không href, nhưng CHỖ DỰA THẬT là 2 nhánh pseudo-class. (href="#" trỏ về chính trang đang
   mở nên có thể ăn :visited -> bắt buộc phải có cả :visited, không chỉ :link.)
   KHÔNG đặt color vào :hover — tpl:109 .act đã có color:#fff !important, và sau vá này .act
   ăn khớp màu chữ với 11 nút còn lại đúng như bản sáng, chỉ khác nền (nền .act cũng !important
   nên vẫn là xanh dương -> trạng thái "đang bật" nay còn NỔI HƠN vì 11 nút kia đã tối đi). */
html[data-xtheme="dark"] .w3d-top a,
html[data-xtheme="dark"] .w3d-top a:link,
html[data-xtheme="dark"] .w3d-top a:visited {
  color: #fff;                        /* 5.19:1 (trời sáng nhất) — 11.87:1 (đỉnh trời + gradient) */
  background: rgba(13,28,46,.62); border-color: var(--x-line2);
}
html[data-xtheme="dark"] .w3d-top a:hover { background: rgba(13,28,46,.78); }  /* tpl:9 — (0,3,2) */
/* tpl:12 — BẪY THẬT: mục 3 (xiris_dark.css:228) đặt `html[data-xtheme="dark"] select
   {background:#0d1c2e}` ở (0,1,2) — 1 thuộc tính + 2 phần tử, KHÔNG phải (0,2,2) — vẫn thắng
   `.w3d-scale select` (0,1,1) của tpl:11 -> hộp thả xuống thành NỀN TỐI, trong khi tpl:12 vẫn
   ghim option màu #0f172a. Kết quả: chữ tối trên nền tối = 1.04:1, danh sách tỉ lệ và danh
   sách kỳ trống trơn. Phải sửa ở option, không phải ở select.
   Bản vá (0,2,3) > tpl:12 (0,1,2) -> thắng. */
html[data-xtheme="dark"] .w3d-scale select option {
  color: var(--x-ink); background: #0d1c2e;                         /* 16.46:1 */
}
/* tpl:15 — chú giải góc dưới trái. Giữ .93 như bản sáng để còn thấy cảnh chạy phía sau; đã
   tính CẢ HAI đầu: nền cảnh sáng nhất (trời ban ngày #eef4fb lọt qua 7%) lẫn nền cảnh tối.
   Bóng đổ #15 rgba(15,23,42,.15) trên nền tối là vô hình -> đổi sang bóng đen sâu + viền sáng. */
html[data-xtheme="dark"] .w3d-legend {
  background: rgba(13,28,46,.93); border-color: var(--x-line2);
  color: var(--x-ink);                    /* 13.74:1 (cảnh sáng nhất) — 16.46:1 (cảnh tối) */
  box-shadow: 0 10px 30px -8px #000, var(--x-inset);
}
html[data-xtheme="dark"] .w3d-legend b { color: var(--x-faint); }   /* 7.14:1 — 8.56:1 */
/* tpl:19 — gợi ý thao tác góc dưới phải. Cùng cách. */
html[data-xtheme="dark"] .w3d-hint {
  background: rgba(13,28,46,.92); border-color: var(--x-line);
  color: var(--x-mut);                    /* 9.84:1 (cảnh sáng nhất) — 12.14:1 (cảnh tối) */
  box-shadow: 0 10px 30px -8px #000;
}

/* ===== C. Bảng thông tin vật thể (.w3d-inspect) ===== */
/* tpl:25 — rgba(255,255,255,.97). Đây là bảng có ô nhập và bảng số, TÔ ĐẶC chứ không để mờ:
   nó nổi trên canvas, mờ 3% cũng đủ làm ống nước chạy qua sau chữ số. */
html[data-xtheme="dark"] .w3d-inspect {
  background: #0d1c2e; border-color: var(--x-line2);
  box-shadow: 0 18px 60px -12px #000;
}
/* tpl:27 — gradient #0ea5e9→#2563eb với chữ #fff mới chỉ 2.77:1 ở đầu sáng: bản sáng đã hỏng
   sẵn, nên KHÔNG lật ngược nó mà chọn lại bậc màu cho nền tối.
   Bản sáng không có vạch ngăn (gradient đậm tự tách đầu bảng khỏi thân trắng); bản tối gradient
   rất nhạt nên CẦN vạch ngăn — nhưng tpl:27 không đặt border, nên vẽ bằng inset để khỏi đội
   thêm 1px (xem ghi chú VIỀN ở đầu khối). */
html[data-xtheme="dark"] .w3d-ih {
  background: linear-gradient(135deg, rgba(112,236,255,.16), rgba(142,197,255,.08));
  color: var(--x-ink);                                              /* 10.94:1 */
  box-shadow: inset 0 -1px 0 var(--x-line);
}
/* tpl:34/36/37/38 — từng hàng "nhãn | giá trị". #64748b và #0f172a đều là bậc của nền trắng. */
html[data-xtheme="dark"] .w3d-r { border-bottom-color: var(--x-line); }
html[data-xtheme="dark"] .w3d-r span { color: var(--x-faint); }     /* 8.56:1 */
html[data-xtheme="dark"] .w3d-r b { color: var(--x-ink); }          /* 16.46:1 */
html[data-xtheme="dark"] .w3d-r b.hl { color: var(--x-cyan); }      /* 12.38:1 */
/* tpl:39 — hộp chú thích chân bảng. Nền #f1f5f9 đổi thành lớp trắng mờ thì gần như không thấy
   hộp nữa, nên phải thêm một vòng viền. Dùng box-shadow inset chứ KHÔNG dùng border: tpl
   không đặt border cho .w3d-if, mà nó nằm trong bảng chật (margin:8px 13px 12px) nên thêm
   2px là lệch mạch dòng. */
html[data-xtheme="dark"] .w3d-if {
  background: rgba(255,255,255,.05); color: var(--x-mut);           /* 10.65:1 */
  box-shadow: inset 0 0 0 1px var(--x-line);
}

/* ===== D. Các nút trong bảng (.w3d-ba và họ hàng) =====
   Thứ tự ở đây BẮT BUỘC giống thứ tự trong tpl: .w3d-ba2/.ba3/.bad đều là class thứ hai đứng
   cùng .w3d-ba (đã kiểm DOM thật: sodo3d_view.js:662/663/1249/1252 sinh "w3d-ba w3d-ba2",
   "w3d-ba w3d-ba3b", "w3d-ba w3d-ba3", "w3d-ba w3d-bad"), mọi luật đều (0,2,1) nên chỉ có
   source order phân thắng bại — hệt như tpl đang dựa vào. Và `.w3d-ba:hover` (0,3,1) cao hơn
   `.w3d-ba2` (0,2,1), nên :hover CHỈ được đặt background, đặt color vào đó là nuốt mất màu
   chữ của mọi nút biến thể. */
/* tpl:40 — nút chính "Bay tới xem". #fff trên #0ea5e9 = 2.77:1 (bản sáng vốn đã hỏng).
   Dùng lại đúng công thức của .tk-go: gradient sáng + chữ tối. */
html[data-xtheme="dark"] .w3d-ba {
  background: linear-gradient(135deg, rgba(112,236,255,.94), rgba(64,247,177,.94));
  color: #03111a;            /* nghỉ (alpha .94 gộp 6% #0d1c2e): 12.30:1 cyan · 12.31:1 mint */
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.08), 0 10px 24px -12px rgba(64,247,177,.5);
}
/* hover tô ĐẶC nên cao hơn lúc nghỉ: 13.77:1 cyan · 13.79:1 mint */
html[data-xtheme="dark"] .w3d-ba:hover { background: linear-gradient(135deg, #70ecff, #40f7b1); }
/* tpl:42 — "Xem lịch sử các kỳ": nút phụ, giữ đúng hệ màu tác giả gán (teal) nhưng chuyển sang
   dạng nền mờ + chữ sáng để không tranh chỗ với nút chính. */
html[data-xtheme="dark"] .w3d-ba2 {
  background: rgba(64,247,177,.14); color: var(--x-mint);           /* 8.79:1 — hover 6.55:1 */
  box-shadow: inset 0 0 0 1px rgba(64,247,177,.32);
}
html[data-xtheme="dark"] .w3d-ba2:hover { background: rgba(64,247,177,.24); }
/* tpl:64/66 — "Nhập số liệu kỳ mới" / "Lưu số liệu kỳ này": #b45309 là nâu, trên nền tối nó
   đục và chết; giữ nghĩa "hổ phách" của tác giả bằng --x-amber. */
html[data-xtheme="dark"] .w3d-ba3b,
html[data-xtheme="dark"] .w3d-ba3 {
  background: rgba(255,201,77,.14); color: var(--x-amber);          /* 8.25:1 — hover 6.28:1 */
  box-shadow: inset 0 0 0 1px rgba(255,201,77,.32);
}
html[data-xtheme="dark"] .w3d-ba3b:hover,
html[data-xtheme="dark"] .w3d-ba3:hover { background: rgba(255,201,77,.24); }
/* tpl:100 — "Xoá hẳn kỳ này" (sodo3d_view.js:1252). Đây là nút PHÁ HUỶ, cố ý để đỏ đậm hơn hai
   cái trên. --x-red là màu nhấn TỐI NHẤT của bảng màu (nghỉ 5.55:1 so với 8.79/8.25 của
   mint/amber) nên nó KHÔNG còn dư địa như .ba2/.ba3: hover nâng alpha làm nền sáng lại gần màu
   chữ -> ngưỡng vỡ ở đúng .26 (.24=4.60 · .25=4.51 · .26=4.41). tpl:40 cho .w3d-ba
   font-size:12.5px/weight:600 nên ngưỡng là 4.5, KHÔNG phải 3.0. Không được để nút phá huỷ tụt
   xuống dưới ngưỡng đúng lúc con trỏ chỉ vào để bấm -> hover dừng ở .22 (4.78:1, còn biên,
   không sát mép như .24/.25). */
html[data-xtheme="dark"] .w3d-bad {
  background: rgba(255,122,122,.14); color: var(--x-red);           /* 5.55:1 */
  box-shadow: inset 0 0 0 1px rgba(255,122,122,.34);
}
html[data-xtheme="dark"] .w3d-bad:hover { background: rgba(255,122,122,.22); }  /* 4.78:1 */

/* ===== E. Lịch sử các kỳ ===== */
html[data-xtheme="dark"] .w3d-hist { border-top-color: var(--x-line); }   /* tpl:45 */
html[data-xtheme="dark"] .w3d-hh { color: var(--x-faint); }               /* tpl:47 — 8.56:1 */
html[data-xtheme="dark"] .w3d-hb:hover { background: rgba(255,255,255,.07); } /* tpl:50 */
/* tpl:51/52 — ĐẢO NGƯỢC có chủ đích. Bản sáng: cột thường #7dd3fc (nhạt), cột ĐANG CHỌN
   #0284c7 (đậm) — trên nền trắng thì "đậm hơn = đang chọn". Bê nguyên sang nền tối thì cột
   đang chọn hoá ra TỐI HƠN cả cột thường, tức nó biến mất đúng lúc cần nổi nhất. Nền tối phải
   đọc ngược: đang chọn = SÁNG hơn.
   Đây là hình khối chứ không phải chữ -> ngưỡng 3:1. Alpha của cột thường kéo HAI CẶP NGƯỢC
   CHIỀU NHAU: hạ alpha thì cột thường chìm vào mặt bảng (.45 = 2.97:1, TRƯỢT 3.0) nhưng tách
   khỏi cyan tốt lên (4.17:1); nâng alpha thì ngược lại. .5 là điểm cả hai cùng qua:
   cột thường/mặt bảng 3.36:1, cyan/cột thường 3.69:1.
   (Đừng đọc nhầm thành "muốn tách rõ hơn thì nâng alpha" — đúng ngược chiều.) */
html[data-xtheme="dark"] .w3d-hb i { background: rgba(142,197,255,.5); }
html[data-xtheme="dark"] .w3d-hb.on i { background: var(--x-cyan); box-shadow: 0 0 8px -1px var(--x-glow); }
html[data-xtheme="dark"] .w3d-hb span { color: var(--x-faint); }          /* tpl:53 — 8.56:1 */
html[data-xtheme="dark"] .w3d-hb.on span { color: var(--x-cyan); }        /* tpl:54 — 12.38:1 */
/* tpl:56/58/59 — bảng số liệu các kỳ. */
html[data-xtheme="dark"] .w3d-ht th {
  background: rgba(255,255,255,.06); color: var(--x-faint);               /* 7.28:1 */
}
html[data-xtheme="dark"] .w3d-ht td { border-bottom-color: var(--x-line); color: var(--x-mut); } /* 12.14:1 */
html[data-xtheme="dark"] .w3d-ht td:first-child { color: var(--x-faint); }  /* 8.56:1 */
/* tpl:60/61 — hàng của kỳ đang xem: bản sáng dùng #eff6ff (xanh nhạt hơn nền trắng). Nền tối
   thì "nhạt hơn" không tồn tại, phải làm ngược: sáng hơn mặt bảng. */
html[data-xtheme="dark"] .w3d-ht tr.on td {
  background: rgba(112,236,255,.10); color: var(--x-ink);                 /* 12.96:1 */
}
html[data-xtheme="dark"] .w3d-ht tr.on td:first-child { color: var(--x-cyan); } /* 9.74:1 */
/* tpl:62 — dòng tổng kết. #0f766e trên #0d1c2e chỉ 3.14:1, dưới 4.5 của chữ 11.5px. */
html[data-xtheme="dark"] .w3d-hf {
  background: rgba(64,247,177,.09); border-color: rgba(64,247,177,.3);
  color: var(--x-mint);                                                  /* 10.08:1 */
}

/* ===== F. Nhập số liệu kỳ mới + ảnh công tơ ===== */
html[data-xtheme="dark"] .w3d-edit { border-top-color: var(--x-line); }  /* tpl:68 */
html[data-xtheme="dark"] .w3d-ef label { color: var(--x-faint); }        /* tpl:71 — 8.56:1 */
/* tpl:72 — thêm .w3d-inspect vào chuỗi KHÔNG phải cho đẹp: mục 3 (xiris_dark.css:228) có
   `html[data-xtheme="dark"] input[type="text"]{background:#0d1c2e}` ở (0,2,2), và MỌI ô nhập ở
   đây đều đúng là type="text" (sodo3d_view.js:1233, 1235-1239) nên nó đụng thật — chứ không
   phải input nói chung. Mà "html[data-xtheme=dark] .w3d-ef input" cũng đúng (0,2,2) -> HOÀ,
   chỉ hơn nhau vì khối này nằm cuối file. Mượn tổ tiên .w3d-inspect (có thật: sodo3d_view.js:
   659-664 dựng cả form vào .w3d-ib bên trong inspectEl = #w3dInspect = .w3d-inspect, tpl:192)
   để lên (0,3,2), thắng dứt điểm.
   Vì mặt bảng cũng là #0d1c2e nên nếu để ô nhập ăn #0d1c2e của mục 3 thì ô nhập tan vào bảng,
   không thấy có ô nào để gõ. tpl:72 CÓ sẵn border:1px -> chỉ đổi màu. */
html[data-xtheme="dark"] .w3d-inspect .w3d-ef input {
  background: rgba(255,255,255,.06); border-color: var(--x-line);
  color: var(--x-ink);                                                   /* 14.01:1 */
}
html[data-xtheme="dark"] .w3d-inspect .w3d-ef input:focus {              /* tpl:73 */
  border-color: var(--x-cyan); box-shadow: 0 0 0 2px var(--x-glow);
}
html[data-xtheme="dark"] .w3d-em.ok { color: var(--x-mint); }            /* tpl:75 — 12.40:1 */
/* tpl:76 — #b91c1c trên #0d1c2e chỉ 2.65:1: báo lỗi mà không đọc được là hỏng nặng nhất trong
   nhóm này, vì nó chỉ hiện đúng lúc người dùng nhập sai. */
html[data-xtheme="dark"] .w3d-em.err { color: var(--x-red); }            /* 6.80:1 */
html[data-xtheme="dark"] .w3d-pb {                                       /* tpl:81 */
  background: rgba(255,255,255,.05); border-color: var(--x-line2);
  color: var(--x-mut);                                                   /* 10.65:1 */
}
html[data-xtheme="dark"] .w3d-pb:hover {                                 /* tpl:82 */
  background: rgba(112,236,255,.1); border-color: var(--x-cyan);
  color: var(--x-cyan);                                                  /* 9.74:1 */
}
/* tpl:85 và tpl:93 — viền ảnh: #cbd5e1 sáng hơn ảnh lẫn nền, thành ra vẽ một khung trắng
   quanh ảnh; cyan mờ vừa đủ tách ảnh khỏi mặt bảng. */
html[data-xtheme="dark"] .w3d-pp img,
html[data-xtheme="dark"] .w3d-ph img { border-color: var(--x-line2); }
html[data-xtheme="dark"] .w3d-pu { color: var(--x-amber); }              /* tpl:87 — 11.22:1 */
html[data-xtheme="dark"] .w3d-pok { color: var(--x-mint); }              /* tpl:88 — 12.40:1 */
html[data-xtheme="dark"] .w3d-px { color: var(--x-red); }                /* tpl:89 — 6.80:1 */
/* tpl:99 — hộp cảnh báo trước khi ghi đè kỳ đã có (sodo3d_view.js:1234). */
html[data-xtheme="dark"] .w3d-warn {
  background: rgba(255,201,77,.10); border-color: rgba(255,201,77,.34);
  color: var(--x-amber);                                                 /* 9.12:1 */
}

/* ---------- MÀN SCADA (scada.tpl) ---------- */
/*
 * VÌ SAO SELECTOR DÀI: <style> của scada.tpl (dòng 2-146) nằm trong thân trang, tức đứng SAU
 * thẻ <link> nạp file này. Luật CÙNG hạng thì .tpl thắng. Nên mọi selector dưới đây được chép
 * NGUYÊN từ .tpl rồi thêm tiền tố html[data-xtheme="dark"] — cộng 1 thuộc tính + 1 phần tử là
 * luôn hơn bản gốc. Rút gọn selector ở đây là thua.
 *
 * VÌ SAO ALPHA THẤP: panel phải của màn này lồng SÂU NHẤT site — 8 lớp chồng nhau:
 *   trang #04111d -> .sc-card .04 -> .xp-skid-grp .02 -> .xp-skid-body .018 -> .xp-type .02
 *   -> .xp-type .xp-devices .015 -> .xp-devcard .02 -> .xp-row .03
 * Mỗi lớp là rgba trắng nên chúng CỘNG DỒN. Chọn alpha cao cho đẹp từng lớp thì tới tầng 8
 * nền đã xám bệch. Với chuỗi trên, tầng đáy .xp-row gộp lại vẫn chỉ ra rgb(42,53,63) L=0.0343
 * nên chữ --x-ink còn 11.9:1. Mọi số tương phản trong file này là GỘP CHỒNG lên #04111d, không
 * phải getComputedStyle (nó chỉ trả về đúng lớp rgba, không phải màu mắt nhìn thấy).
 */

/* ===== 1. Khung + đầu màn ===== */
/* .sc-wrap:3 ghim color:#0f172a cho cả màn. Đây là gốc rễ: mọi phần tử con không tự khai màu
   (.xp-title:33, .sc-kpi b:17, .xp-row .xp-val:43, .sc-al-u:118, .sc-legend div) đều thừa kế
   nó — đổi một dòng này là phủ được cả nhóm. --x-ink trên nền trang: 16.7:1. */
/* --faint:#5d708c mới khai trên .sc-wrap (scada.tpl:12) để CỨU BẢN SÁNG — #94a3b8 cũ chỉ 2,56:1.
   Giá trị sáng đó trên nền tối chỉ còn 3,77:1 nên PHẢI đảo ở đây, nếu không là chữ mờ chìm hẳn.
   Đảo biến chứ không viết luật cho từng selector vì 3 chỗ dùng nó là style NỘI TUYẾN
   (scada.tpl:221 ô chú giải Bypass, :229, :444 do JS sinh) — nội tuyến (1,0,0,0) thắng mọi
   stylesheet, selector thường KHÔNG với tới, chỉ còn !important hoặc biến. Biến sạch hơn.
   Các luật html[data-xtheme="dark"] cho .xp-... và .sc-loading bên dưới vẫn giữ nguyên và vẫn
   thắng (chúng đặt color THẲNG, không qua biến) — nay chỉ là lớp dự phòng, không xung đột.
   --x-faint #a9b9c8 trên thẻ tối: 8.7:1. */
html[data-xtheme="dark"] .sc-wrap { color: var(--x-ink); --faint: var(--x-faint); }
html[data-xtheme="dark"] .sc-head h3 i { color: var(--x-cyan); }           /* 13.7:1 */
/* .sc-kpi.w b bản sáng đổi #f59e0b -> #c47e08 (3,31:1 @22px đậm). Trên nền tối #c47e08 chỉ
   3,0:1 — qua ngưỡng 3,0 của chữ lớn nhưng sát mép; luật :1372 dưới đây đã đưa về --x-amber
   (11,4:1) nên bản tối KHÔNG bị ảnh hưởng bởi thay đổi bên .tpl. */

/* .sc-tabs:7-10. BẪY a:link: .sc-tabs a{color:#475569} là (0,1,1) — NGANG a:link của
   style.css:1892, thắng được chỉ nhờ đứng sau. Sang bản tối, bản chép-nguyên
   html[data-xtheme="dark"] .sc-tabs a là (0,2,2) — HOÀ ĐÚNG BẰNG html[data-xtheme="dark"] a:link
   (0,2,2) ở dòng 61 file này, và chỉ thắng nhờ khối scada đứng SAU nó. Thêm :link/:visited để
   lên (0,3,2) thì thắng bằng ĐỘ ƯU TIÊN, khỏi phụ thuộc vị trí khối trong file. */
html[data-xtheme="dark"] .sc-tabs { border-color: var(--x-line); }
html[data-xtheme="dark"] .sc-tabs a,
html[data-xtheme="dark"] .sc-tabs a:link,
html[data-xtheme="dark"] .sc-tabs a:visited { color: var(--x-mut); border-right-color: var(--x-line); }  /* 13.5:1 */
/* Tab đang chọn: bản sáng tô teal đặc #017e84. Nền tối không cần khối đặc — viền cyan + nền
   cyan mờ đã đủ tách, lại ăn theo gradient bên dưới. */
html[data-xtheme="dark"] .sc-tabs a.active,
html[data-xtheme="dark"] .sc-tabs a.active:link,
html[data-xtheme="dark"] .sc-tabs a.active:visited {
  background: rgba(112,236,255,.16); color: var(--x-cyan);                 /* 9.5:1 */
  box-shadow: inset 0 0 0 1px rgba(112,236,255,.3);
}

/* Viên vai trò :11-12 — 4 bộ nền nhạt/chữ đậm vẽ cho nền trắng. Nền tối phải đảo cực:
   nền = màu nhấn pha loãng, chữ = chính màu nhấn ở bậc sáng. */
html[data-xtheme="dark"] .sc-role { background: rgba(112,236,255,.10); color: var(--x-cyan); }        /* 11.1:1 */
html[data-xtheme="dark"] .sc-role-van_hanh { background: rgba(142,197,255,.14); color: var(--x-blue); } /* 8.1:1 */
html[data-xtheme="dark"] .sc-role-quan_ly  { background: rgba(167,139,250,.14); color: #c4b5fd; }       /* 8.5:1 */
html[data-xtheme="dark"] .sc-role-giam_sat { background: rgba(64,247,177,.12);  color: var(--x-mint); } /* 10.6:1 */

/* .sc-error:14 — nền #fef2f2 là mảng hồng nhạt to nhất khi có lỗi. */
html[data-xtheme="dark"] .sc-error {
  background: rgba(255,122,122,.10); border-color: rgba(255,122,122,.32); color: var(--x-red);  /* 6.7:1 */
}

/* ===== 2. Dải KPI + thanh công cụ ===== */
/* .sc-kpi:16 nền #fff — 5 thẻ trắng đặc, mảng sáng to nhất đầu màn. box-shadow gốc là
   rgba(15,23,42,.04): bóng tối trên nền tối = không tồn tại, đổi sang quầng sáng trong thẻ. */
html[data-xtheme="dark"] .sc-kpi {
  background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .sc-kpi span { color: var(--x-faint); }           /* 8.7:1 @11px */
/* :18 — bậc màu bản sáng. #16a34a/#dc2626 tính trên nền tối chỉ 5.3:1 và 4.0:1; số KPI là
   22px đậm nên qua ngưỡng 3:1, nhưng vẫn chọn LẠI theo bảng HUD cho khớp đèn + cảnh báo. */
html[data-xtheme="dark"] .sc-kpi.n b { color: var(--x-mint); }             /* 12.6:1 */
html[data-xtheme="dark"] .sc-kpi.w b { color: var(--x-amber); }            /* 11.4:1 */
html[data-xtheme="dark"] .sc-kpi.c b { color: var(--x-red); }              /* 6.9:1  */

/* .sc-btn:20 nền #fff. BẪY a:link lần 2, và lần này bản SÁNG đang thua sẵn: .sc-btn{color:#334155}
   là (0,1,0) < a:link (0,1,1) nên chữ nút thật ra đang là navy #1a3f5e chứ không phải xám.
   Phải viết :link/:visited -> (0,3,1) mới hơn html[data-xtheme="dark"] a:link (0,2,2). */
html[data-xtheme="dark"] .sc-btn,
html[data-xtheme="dark"] .sc-btn:link,
html[data-xtheme="dark"] .sc-btn:visited {
  background: rgba(255,255,255,.06); border-color: var(--x-line); color: var(--x-ink);  /* 16.0:1 */
}
/* .sc-btn.primary:21 teal đặc -> dải cyan->mint, chữ tối. Dùng lại đúng công thức .tk-go
   (file này:202) cho nút chính toàn site giống nhau. Chữ #03111a trên dải: 12.2:1. */
html[data-xtheme="dark"] .sc-btn.primary,
html[data-xtheme="dark"] .sc-btn.primary:link,
html[data-xtheme="dark"] .sc-btn.primary:visited {
  background: linear-gradient(135deg, rgba(112,236,255,.94), rgba(64,247,177,.94));
  color: #03111a; border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.08), 0 10px 24px -12px rgba(64,247,177,.5);
}
html[data-xtheme="dark"] .sc-tag-ro { background: rgba(255,255,255,.05); color: var(--x-mut); border-color: var(--x-line); }  /* 12.1:1 */
html[data-xtheme="dark"] .sc-tag-op { background: rgba(112,236,255,.10); color: var(--x-cyan); border-color: var(--x-line2); } /* 11.1:1 */

/* ===== 3. Sân đồ thị + chú giải ===== */
/* .sc-cy-box:25 nền #fff — mảng trắng 560px, thứ chói nhất màn. Cytoscape KHÔNG tự tô nền
   canvas nên nền hộp này chính là nền đồ thị: CSS sửa được, và đây là chỗ DUY NHẤT của đồ thị
   mà CSS với tới. Giữ trong suốt để gradient body xuyên qua làm nền sân. */
html[data-xtheme="dark"] .sc-cy-box {
  background: rgba(255,255,255,.03); border-color: var(--x-line); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .sc-loading { color: var(--x-faint); }            /* 8.9:1 */
/* .sc-legend:27 — BẪY MODAL/POPUP: nó position:absolute NỔI TRÊN canvas, node và cạnh được vẽ
   ngay dưới nó. Cho --x-card (trắng .04) là trong suốt 96% -> đọc xuyên thấy đồ thị. PHẢI tô
   ĐẶC. Chữ thừa kế --x-ink từ .sc-wrap: 16.5:1 @11px. */
html[data-xtheme="dark"] .sc-legend {
  background: #0d1c2e; border-color: var(--x-line2); box-shadow: 0 8px 24px -10px #000;
}
/* 4 ô màu chú giải: border-color nằm ở INLINE STYLE (tpl:200-203) nên thắng mọi stylesheet —
   chỉ !important mới gỡ được. Bộ màu này BẮT BUỘC khớp hàm edgeColor() đã sửa trong js_changes,
   không thì chú giải nói một đằng đồ thị vẽ một nẻo. */
html[data-xtheme="dark"] .sc-legend div:nth-child(1) b { border-color: var(--x-cyan)  !important; } /* Dòng chảy */
html[data-xtheme="dark"] .sc-legend div:nth-child(2) b { border-color: var(--x-amber) !important; } /* Điều khiển */
html[data-xtheme="dark"] .sc-legend div:nth-child(3) b { border-color: #a78bfa        !important; } /* Phụ thuộc */
html[data-xtheme="dark"] .sc-legend div:nth-child(4) b { border-color: var(--x-faint) !important; } /* Bypass */

/* ===== 4. Panel phải — 3 tầng lồng (Bể -> Loại -> Thiết bị) ===== */
html[data-xtheme="dark"] .sc-card {
  background: var(--x-card); border-color: var(--x-line); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .xp-hint,
html[data-xtheme="dark"] .xp-empty { color: var(--x-faint); }              /* 8.7:1 */

/* Viên đếm :36 — dùng ĐÚNG bộ viên đã kiểm ở mục 2 file này (.sp-critical/.sp-warning/
   .sp-normal, dòng 176-181), không chế bộ mới, để chấm màu toàn site đọc như nhau. */
html[data-xtheme="dark"] .xp-n { background: #0b312c; color: #5eead4; }    /* 9.5:1 */
html[data-xtheme="dark"] .xp-w { background: #3a2a0d; color: #fcd34d; }    /* 9.6:1 */
html[data-xtheme="dark"] .xp-c { background: #3a1418; color: #ff8f8f; }    /* 7.4:1 */

/* --- Tầng 1: BỂ/SKID :87-96. Bản sáng đánh dấu cấp cao nhất bằng teal ĐẶC #017e84 (chỗ đậm
   nhất panel). Nền tối làm ngược: khối đặc sẽ chặn gradient, nên dùng cyan pha loãng đậm dần
   theo cấp — cấp 1 .13, cấp 2 .07, cấp 3 .03 — vẫn ra thứ bậc mà lớp nào cũng trong. */
html[data-xtheme="dark"] .xp-skid-grp {
  background: rgba(255,255,255,.02); border-color: var(--x-line2); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .xp-skid-grp > summary { background: rgba(112,236,255,.13); color: var(--x-ink); }  /* 11.4:1 @13.5px đậm */
html[data-xtheme="dark"] .xp-skid-grp[open] > summary { background: rgba(112,236,255,.20); }                 /* 9.3:1 */
html[data-xtheme="dark"] .xp-skid-body { background: rgba(255,255,255,.018); }
/* Caret :90 #bfe9ea · icon :93 #cfeaea · số đếm :95 #cdeaea — teal nhạt vẽ cho header teal ĐẶC
   #017e84 của bản sáng. KHÔNG hụt tương phản trên nền mới (nền summary gộp ra rgb(31,58,70),
   #cdeaea đo được 9.3:1) nên đây là ĐỒNG BỘ BẢNG MÀU, không phải vá lỗi đọc: 3 màu này thuộc
   bảng teal cũ, để nguyên thì caret+icon+số đếm của tầng CAO NHẤT lệch tông so với tầng
   .xp-type ngay dưới nó (đã sang --x-cyan). Độ ưu tiên đã kiểm: (0,2,3) > :90 (0,1,2);
   (0,3,2) > :93 (0,2,1); (0,2,1) > :95 (0,1,0) — thắng cả ba, không cần !important. */
html[data-xtheme="dark"] .xp-skid-grp > summary:before,
html[data-xtheme="dark"] .xp-skid-grp > summary .fa { color: var(--x-cyan); }   /* 8.7:1 đóng · 7.1:1 mở */
html[data-xtheme="dark"] .xp-skid-cnt { color: var(--x-mut); }                  /* 8.5:1 @11.5px */

/* --- Tầng 2: LOẠI THIẾT BỊ :99-110 */
html[data-xtheme="dark"] .xp-type { background: rgba(255,255,255,.02); border-color: var(--x-line); }
html[data-xtheme="dark"] .xp-type > summary { background: rgba(112,236,255,.07); color: var(--x-cyan); }     /* 9.1:1 */
html[data-xtheme="dark"] .xp-type[open] > summary { background: rgba(112,236,255,.11); }                     /* 8.1:1 */
html[data-xtheme="dark"] .xp-type > summary:before,
html[data-xtheme="dark"] .xp-type > summary .fa { color: var(--x-cyan); }
html[data-xtheme="dark"] .xp-type-cnt { color: var(--x-faint); }           /* 6.3:1 */
html[data-xtheme="dark"] .xp-run { background: #0b312c; color: #5eead4; }  /* 9.5:1 */
html[data-xtheme="dark"] .xp-type .xp-devices { background: rgba(255,255,255,.015); }

/* --- Tầng 3: THIẾT BỊ :74-84. .xp-type .xp-devcard:110 (0,2,0) đè .xp-devcard:74 (0,1,0) ở
   bản sáng, nhưng tiền tố html[data-xtheme="dark"] đưa luật dưới đây lên (0,2,1) — bằng ở cột
   lớp (2=2), hơn ở cột phần tử (1>0) — nên nó ĐÃ thắng cả hai. Không cần phủ thêm bản dài. */
html[data-xtheme="dark"] .xp-devcard { background: rgba(255,255,255,.02); border-color: var(--x-line); }
html[data-xtheme="dark"] .xp-devcard > summary.xp-dev { background: rgba(255,255,255,.03); color: var(--x-ink); }   /* 12.0:1 */
html[data-xtheme="dark"] .xp-devcard > summary.xp-dev .xp-dev-name { color: var(--x-ink); }
html[data-xtheme="dark"] .xp-devcard > summary.xp-dev:before { color: var(--x-faint); }
html[data-xtheme="dark"] .xp-devcard[open] > summary.xp-dev { background: rgba(112,236,255,.08); border-bottom-color: var(--x-line); } /* 10.7:1 */
html[data-xtheme="dark"] .xp-devcard[open] > summary.xp-dev:before { color: var(--x-cyan); }
html[data-xtheme="dark"] .xp-devcard > summary.xp-dev:hover { background: rgba(255,255,255,.07); }
/* .xp-dev:57 hiện KHÔNG bao giờ hiện độc lập: JS (tpl:317) luôn sinh <summary class="xp-dev">
   bên trong <details class="xp-devcard">, mà .xp-devcard>summary.xp-dev:75 (0,2,1) HOÀ đúng
   bằng luật này (0,2,1) rồi thắng nhờ đứng sau — kể cả viền trái (nó đặt border-left:0, không
   còn cạnh nào để tô). Giữ làm dự phòng nếu sau này .xp-dev dùng riêng. */
html[data-xtheme="dark"] .xp-dev { background: rgba(112,236,255,.08); color: var(--x-cyan); border-left-color: var(--x-line2); }
/* NHƯNG .xp-dev .fa thì SỐNG và đang phá. Đây là selector HẬU DUỆ, và .fa DUY NHẤT nằm trong
   .xp-dev chính là icon nút Chạy/Dừng: tpl:317 -> <span class="xp-ops-wrap"> -> tpl:268-269
   ctrlButtons() sinh <button class="xp-op xp-op-on on"><i class="fa fa-play">. Luật (0,3,1)
   khớp THẲNG thẻ <i> nên thắng màu THỪA KẾ từ .xp-op-on.on (0,3,1) vốn chỉ khớp <button>.
   Hậu quả đo GỘP CHỒNG: cyan #70ecff trên nền --x-mint = 1.0017:1 (icon Chạy TÀNG HÌNH đúng
   lúc nút đang hoạt) và trên --x-red = 1.82:1 — cả hai dưới ngưỡng 3:1 của chỉ báo phi-văn-bản.
   Trả icon về ăn theo màu chữ của nút bằng chuỗi 3 lớp (0,4,1): thắng bằng ĐỘ ƯU TIÊN nên
   không vỡ nếu ai đó sắp xếp lại file. <i> không phải <a> nên bẫy a:link không đụng tới. */
html[data-xtheme="dark"] .xp-dev .fa { color: var(--x-cyan); }
html[data-xtheme="dark"] .xp-dev .xp-op .fa { color: inherit; }  /* .on: 13.8:1 / 7.6:1 · thường: 9.5:1 / 7.4:1 */
html[data-xtheme="dark"] .xp-dev span.xp-dev-cnt,
html[data-xtheme="dark"] .xp-dev-cnt { color: var(--x-faint); }

/* --- Dòng thông số :38-51 */
html[data-xtheme="dark"] .xp-row { background: rgba(255,255,255,.03); border-left-color: var(--x-line2); }
html[data-xtheme="dark"] .xp-name { color: var(--x-ink); }                 /* 11.9:1 */
html[data-xtheme="dark"] .xp-sub { color: var(--x-faint); }                /* 6.2:1 @10px */
html[data-xtheme="dark"] .xp-sub em { background: rgba(112,236,255,.14); color: var(--x-cyan); }  /* 6.3:1 @10px */
html[data-xtheme="dark"] .xp-row .xp-val small { color: var(--x-faint); }
html[data-xtheme="dark"] .xp-val-nodata {
  background: rgba(255,255,255,.05); color: var(--x-faint); border-color: var(--x-line);
}
html[data-xtheme="dark"] .xp-row.xp-nodata { background: rgba(255,255,255,.02); }
html[data-xtheme="dark"] .xp-row.xp-nodata .xp-name { color: var(--x-faint); }
html[data-xtheme="dark"] .xp-normal   { border-left-color: var(--x-mint); }
html[data-xtheme="dark"] .xp-warning  { border-left-color: var(--x-amber); background: rgba(255,201,77,.08); }  /* ink 10.9:1 */
html[data-xtheme="dark"] .xp-critical { border-left-color: var(--x-red);   background: rgba(255,122,122,.09); } /* ink 11.4:1 */
html[data-xtheme="dark"] .xp-sec { color: var(--x-faint); }

/* Đèn LED :50-51. Chỉ báo phi-văn-bản: ngưỡng 3:1 so với nền dòng, không phải 4.5.
   #cbd5e1 của bản sáng gộp lên nền dòng rgb(42,53,63) được 8.4:1 — ĐẠT, KHÔNG hụt.
   Đổi sang --x-faint là để chấm/đèn toàn site cùng một bảng màu, KHÔNG phải cứu tương phản;
   đổi xong tương phản GIẢM 8.4 -> 6.2, vẫn thừa ngưỡng 3:1 nên chấp nhận được. Ai ưu tiên
   tương phản hơn đồng bộ bảng màu thì bỏ hẳn dòng này — #cbd5e1 gốc đọc tốt hơn. */
html[data-xtheme="dark"] .xp-led { background: var(--x-faint); }           /* 6.2:1 */
html[data-xtheme="dark"] .xp-led-normal   { background: var(--x-mint); }   /* 9.0:1 */
html[data-xtheme="dark"] .xp-led-warning  { background: var(--x-amber); }  /* 8.2:1 */
html[data-xtheme="dark"] .xp-led-critical { background: var(--x-red); }    /* 5.0:1 */

html[data-xtheme="dark"] .xp-det { border-top-color: var(--x-line); }
html[data-xtheme="dark"] .xp-det > summary { color: var(--x-faint); }      /* 6.8:1 */
html[data-xtheme="dark"] .xp-det > summary:before { color: var(--x-cyan); }

/* Nút Chạy/Dừng :64-69. Chữ 11px đậm -> vẫn cần 4.5:1. Đã thử giữ --x-red trên nền đỏ pha
   loãng: chỉ 4.08:1 vì nút nằm trên summary (đã là lớp thứ 7) — HỤT. Nên dùng bộ viên đặc
   #3a1418/#ff8f8f và #0b312c/#5eead4 đã kiểm ở mục 2: nút nhỏ tô đặc không hại chiều sâu. */
html[data-xtheme="dark"] .xp-op-on  { background: #0b312c; color: #5eead4; border-color: #17564d; }  /* 9.5:1 */
html[data-xtheme="dark"] .xp-op-on:hover { background: #11463f; }                                    /* 7.2:1 */
html[data-xtheme="dark"] .xp-op-on.on {
  background: var(--x-mint); color: #03111a; border-color: var(--x-mint);                            /* 13.8:1 */
  box-shadow: 0 0 0 3px rgba(64,247,177,.22);
}
html[data-xtheme="dark"] .xp-op-off { background: #3a1418; color: #ff8f8f; border-color: #6b2028; }  /* 7.4:1 */
html[data-xtheme="dark"] .xp-op-off:hover { background: #4d1a1f; }                                   /* 6.5:1 */
html[data-xtheme="dark"] .xp-op-off.on {
  background: var(--x-red); color: #03111a; border-color: var(--x-red);                              /* 7.6:1 */
  box-shadow: 0 0 0 3px rgba(255,122,122,.22);
}

html[data-xtheme="dark"] .xp-ctrl {
  background: rgba(112,236,255,.07); border-color: var(--x-line2); color: var(--x-mut);  /* 10.5:1 */
}
/* :71-72 — khai trong <style> nhưng JS hiện KHÔNG sinh class này (xem rủi ro #2). Phủ cho đủ. */
html[data-xtheme="dark"] .xp-ctrl-row { background: rgba(255,255,255,.03); border-color: var(--x-line); }
html[data-xtheme="dark"] .xp-ctrl-name { color: var(--x-ink); }

/* Toast :112-114 — BẪY MODAL/POPUP lần 2. position:fixed góc dưới-phải nên nó nổi trên ĐÁY
   gradient body (file này:87 chốt #01030a ở 100%, background-attachment:fixed nên đáy gradient
   luôn nằm ở đáy khung nhìn). Nền #0f172a của bản sáng dựng nên HÌNH KHỐI nhờ 18.9:1 trên
   trang trắng; trên nền tối chỉ còn 1.16:1 — hộp tan biến, chỉ còn chữ trắng trôi nổi. Cộng
   thêm box-shadow rgba(15,23,42,.28) là bóng TỐI trên nền tối = không tồn tại (đúng cái bẫy đã
   bắt được ở .sc-kpi). Dùng #0d1c2e cho khớp .sc-legend/.modal-content (các phần tử NỔI khác
   của bản tối) + viền cyan làm cạnh: viền gộp lên nền hộp ra rgb(47,99,117), so với đáy trang
   3.09:1 — vừa đủ ngưỡng 3:1. Chữ #fff sẵn có trên #0d1c2e: 17.2:1.
   BẮT BUỘC viết đủ CẢ 3 luật: html[data-xtheme="dark"] #sc-toast là (1,1,1) — LỚN HƠN
   #sc-toast.run:114 (1,1,0) — nên `border` viết tắt sẽ GIẾT LUÔN vạch 4px xanh/đỏ phân biệt
   Chạy/Dừng. Hai luật .run/.stop là (1,2,1) nên giành lại được. */
html[data-xtheme="dark"] #sc-toast {
  background: #0d1c2e; border: 1px solid var(--x-line2);
  box-shadow: 0 12px 32px -8px #000, 0 0 18px -6px var(--x-glow);
}
html[data-xtheme="dark"] #sc-toast.run  { border-left: 4px solid var(--x-mint); }
html[data-xtheme="dark"] #sc-toast.stop { border-left: 4px solid var(--x-red); }

/* ===== 5. Cảnh báo AI :116-145 ===== */
/* 6 biến thể nền pastel (#fffbeb/#fef2f2/#eff6ff/#f5f3ff) -> nền = màu nhấn pha loãng .08-.09.
   Chữ .sc-al-u .c/.w của bản sáng là chỗ HỤT THẬT: #dc2626 = 3.97:1 và #b45309 = 3.81:1 trên
   nền tối, dưới ngưỡng 4.5 cho chữ thường. Không phải chuyện thẩm mỹ. */
html[data-xtheme="dark"] .sc-al { background: rgba(255,201,77,.08); border-left-color: var(--x-amber); }
html[data-xtheme="dark"] .sc-al.crit { background: rgba(255,122,122,.09); border-left-color: var(--x-red); }
html[data-xtheme="dark"] .sc-al.ai-critical { background: rgba(255,122,122,.09); border-left-color: var(--x-red); }
html[data-xtheme="dark"] .sc-al.ai-warning  { background: rgba(255,201,77,.08);  border-left-color: var(--x-amber); }
html[data-xtheme="dark"] .sc-al.ai-early    { background: rgba(142,197,255,.08); border-left-color: var(--x-blue); }
html[data-xtheme="dark"] .sc-al.ai-fault    { background: rgba(167,139,250,.08); border-left-color: #a78bfa; }
html[data-xtheme="dark"] .sc-al-u .c { color: var(--x-red); }              /* 5.9:1 — bản sáng 3.97:1 */
html[data-xtheme="dark"] .sc-al-u .w { color: var(--x-amber); }            /* 9.7:1 — bản sáng 3.81:1 */
html[data-xtheme="dark"] .sc-al-s { color: var(--x-faint); }               /* 7.4:1 @11.5px */
html[data-xtheme="dark"] .sc-al-reco { color: var(--x-mut); border-top-color: var(--x-line); }  /* 10.5:1 */
html[data-xtheme="dark"] .sc-al-more { color: var(--x-faint); }            /* 8.7:1 */
html[data-xtheme="dark"] .sc-noal { color: var(--x-mint); }                /* 12.6:1 */
/* Chấm loại cảnh báo :138-139 — #2563eb và #7c3aed là bậc xanh/tím vẽ cho nền trắng. */
html[data-xtheme="dark"] .dot-critical { background: var(--x-red); }
html[data-xtheme="dark"] .dot-warning  { background: var(--x-amber); }
html[data-xtheme="dark"] .dot-early    { background: var(--x-blue); }
html[data-xtheme="dark"] .dot-fault    { background: #a78bfa; }

/* ===== 6. Chỉ báo realtime :127-136 ===== */
/* .sc-live:128 chữ #0f8a5f = 4.40:1 và .sc-live-cd:130 #64748b = 4.02:1 — cả hai HỤT ngưỡng
   4.5 cho chữ 11px. Đây là hai chỗ hụt thật của màn, không phải làm cho đồng bộ. */
html[data-xtheme="dark"] .sc-live {
  color: var(--x-mint); background: rgba(64,247,177,.09); border-color: rgba(64,247,177,.28);  /* 11.5:1 */
}
html[data-xtheme="dark"] .sc-live-cd { color: var(--x-faint); }            /* 7.9:1 */
html[data-xtheme="dark"] .sc-live.soon {
  color: var(--x-amber); background: rgba(255,201,77,.10); border-color: rgba(255,201,77,.30); /* 10.4:1 */
}
html[data-xtheme="dark"] .sc-live.soon .sc-live-dot { background: var(--x-amber); }
/* scPulse:123 bơm quầng ĐỎ rgba(220,38,38,.55). Đúng cho đèn nguy cấp, nhưng .sc-live-dot:127
   là chấm XANH cũng xài chung nó -> chấm xanh nhấp nháy đỏ. Nền trắng chẳng ai để ý; nền tối
   quầng nổi rõ và đọc thành "đang báo lỗi". Đổi sang quầng mint. */
html[data-xtheme="dark"] .sc-live-dot { background: var(--x-mint); animation: scPulseMint 1.5s infinite; }
/* @keyframes KHÔNG lồng được dưới html[data-xtheme="dark"] — nó là at-rule toàn cục, tra theo
   TÊN. Mà định nghĩa đè cùng tên cũng thua: scFlash của .tpl:125 đứng sau file này. Nên đặt
   TÊN MỚI rồi trỏ animation lại ở luật đã có tiền tố. scFlash nháy nền #fff3bf — vàng gần
   trắng, trên nền tối là chớp loá mỗi lần một giá trị đổi (mỗi 5s, nhiều ô cùng lúc). */
html[data-xtheme="dark"] .sc-al-flash { animation: scFlashDark 1s ease-out; }
html[data-xtheme="dark"] .xp-val.vflash { animation: scFlashDark .9s ease-out; border-radius: 5px; }
html[data-xtheme="dark"] .sc-live.reload { animation: scLiveFlashDark .7s ease-out; }
/* 3 khối dưới nằm ngoài tiền tố vì buộc phải vậy; chúng vô hại khi tắt chế độ tối vì KHÔNG
   luật nào của bản sáng gọi tới tên này. */
@keyframes scFlashDark { 0% { background: rgba(112,236,255,.30); } 100% { background: transparent; } }
@keyframes scLiveFlashDark { 0% { background: rgba(64,247,177,.30); } 100% { background: rgba(64,247,177,.09); } }
@keyframes scPulseMint { 0%,100% { box-shadow: 0 0 0 0 rgba(64,247,177,.55); } 50% { box-shadow: 0 0 0 6px rgba(64,247,177,0); } }

/* ---------- MÀN NGOÀI MODULE DUAN ---------- */
/* Phạm vi ban đầu chốt là "7 màn duan + menu + header", nên nhansu/noti/users/phanquyen/wework
 * chưa ai phủ. Lần trước vá lẻ `.item_menu` khi chủ dự án báo "màn hình này cũng lỗi đen thui";
 * khối này quét TĨNH nốt phần còn lại để không phải vá lẻ lần ba.
 *
 * BẪY ĐỘ ƯU TIÊN của chính file này, phải nhớ khi đọc bên dưới:
 * mục 0 có `html[data-xtheme="dark"] a:link` = (0,2,2). Nó CAO HƠN
 * `html[data-xtheme="dark"] .theme-red` = (0,2,1). Mà `.theme-*`, `.config-item`,
 * `.list-group-item` đều được gắn lên thẻ <a>. Nên mọi chỗ tô màu chữ cho <a> ở dưới
 * BẮT BUỘC phải viết kèm :link/:visited, không thì cyan của mục 0 nuốt hết.
 */

/* ===== A. BẢNG DANH SÁCH .table-scroll — LỖI NẶNG NHẤT, 20+ màn =====
 * Đây là bộ khung dùng chung của 13 màn nhansu + phanquyen + wework/danh_gia_kpi.
 * style.css:8983 `.table-scroll tbody td{background:#fff}` tô TRẮNG ĐẶC từng ô, mà mục 3 của
 * file này lại đã đổi màu chữ bảng sang --x-ink -> **chữ trắng #f5fbff trên nền trắng #fff =
 * 1,04:1, TÀNG HÌNH HOÀN TOÀN**. Đúng lại vết xe của .det-col:first-child ghi ở trên:
 * đổi màu chữ mà quên đổi màu hộp còn tệ hơn không đổi gì.
 * Ô để trong suốt (không phải tô card) để .table-striped/.table-hover ở mục 3 lộ ra được. */
html[data-xtheme="dark"] .table-scroll tbody td { background: transparent; }

/* :8952 khung ngoài bảng nền #fff + viền #e5e7eb — mảng trắng to bằng cả màn */
html[data-xtheme="dark"] .table-scroll {
  background: var(--x-card); border-color: var(--x-line);   /* chữ --x-ink trên nền này 14,2:1 */
  box-shadow: var(--x-inset);
}
/* :8963 `.table-scroll table{color:#333}` — 1,19:1. Thẻ <table> tự khai màu nên các ô con
   không có màu riêng sẽ thừa kế nó, không ăn theo mục 3. */
html[data-xtheme="dark"] .table-scroll table { color: var(--x-ink); }

/* VIỀN BẢNG — chỗ này KHÔNG dùng luật thường được.
 * Có HAI luật !important cùng vẽ viền sáng cho nền trắng:
 *   bootstrap.min.css  `.table-bordered th,.table-bordered td{border:1px solid #ddd!important}`
 *   style.css:8609/8613 `.table-scroll td/th{border:1px solid #D5D8DC!important}`
 * !important thắng mọi luật thường bất kể thứ tự nạp, nên `.table td{border-color}` ở mục 3
 * KHÔNG hề có tác dụng trên các bảng này — lưới kẻ vẫn sáng nguyên trên nền tối.
 * Phải đánh lại bằng !important + độ ưu tiên cao hơn. */
html[data-xtheme="dark"] .table-scroll td,
html[data-xtheme="dark"] .table-scroll th,
html[data-xtheme="dark"] .table-bordered > thead > tr > th,
html[data-xtheme="dark"] .table-bordered > tbody > tr > td,
html[data-xtheme="dark"] .table-bordered > tbody > tr > th,
html[data-xtheme="dark"] .table-bordered > tfoot > tr > td { border-color: var(--x-line) !important; }
/* :9026 luật viền riêng của .table-scroll (#e5e7eb, không !important) */
html[data-xtheme="dark"] .table-scroll .table-bordered > thead > tr > th,
html[data-xtheme="dark"] .table-scroll .table-bordered > tbody > tr > td { border-color: var(--x-line); }

/* :6376 track thanh cuộn của bảng ghim #fff + viền #fff. .table-scroll cao 80vh nên bảng nào
   cũng có thanh cuộn -> vạch trắng chạy dọc mép mọi bảng. Cùng bệnh với thanh cuộn menu đã vá
   ở mục 5, chỉ khác là hồi đó quét DOM chưa đụng tới màn nhansu nên bỏ sót. */
html[data-xtheme="dark"] .table-scroll::-webkit-scrollbar,
html[data-xtheme="dark"] .table-scroll::-webkit-scrollbar-track {
  background-color: transparent; border-color: transparent;
}
html[data-xtheme="dark"] .table-scroll::-webkit-scrollbar-thumb { background: rgba(122,219,255,.22); }
html[data-xtheme="dark"] .table-scroll::-webkit-scrollbar-thumb:hover { background: rgba(122,219,255,.4); }

/* ===== B. HÀNG PHÂN CẤP .tr_cap_1..4 (phanquyen + wework/danh_gia_kpi_thang) =====
 * :8575-8605. Bốn tầng này ENCODE CẤU TRÚC CÂY (cha -> giai đoạn -> dòng chính -> chi tiết),
 * mất tầng là mất nghĩa chứ không chỉ xấu. Bản sáng đo được:
 *   cấp 1 #78C6FC -> chữ --x-ink 1,78:1 | cấp 2 #e2f0f9 -> 1,11:1
 *   cấp 3 #FAF7F7 -> 1,02:1             | cấp 4 #fff    -> 1,04:1   (cả 4 tầng tàng hình)
 * TÁCH TẦNG BẰNG MÀU SẮC, KHÔNG BẰNG ĐỘ SÁNG — đây là chỗ tôi phải chọn lại cách làm:
 * ở dải tối, tương phản độ sáng bị nén, thử thang #13304a/#16283c/#0b2436 chỉ ra 1,06-1,10:1
 * giữa hai tầng liền kề = dính vào nhau. Đổi sang tách theo GÓC MÀU thì tách thật:
 * 208° / 39° / 172° / 209°, bão hoà 63% — và #3a2a0d, #0b312c là bộ đã dùng cho .sp-* ở trên,
 * không chế màu mới. Nền ĐẶC vì hàng nằm lồng trong .table-scroll (đã alpha) -> các lớp cộng dồn. */
html[data-xtheme="dark"] .table-scroll .tr_cap_1 td {
  background: #1a4a73; color: var(--x-ink);                 /* 8,86:1 — nền nổi hơn trang 2,06:1 */
  border-top-color: var(--x-line2);
}
html[data-xtheme="dark"] .table-scroll .tr_cap_2 td { background: #3a2a0d; color: #fcd34d; }  /* 9,60:1 */
html[data-xtheme="dark"] .table-scroll .tr_cap_3 td { background: #0b312c; color: #5eead4; }  /* 9,53:1 */
/* Cấp 4 bản sáng là #fff = ĐÚNG BẰNG nền ô thường, tức tầng này vốn không có nền riêng,
   chỉ khác ở chữ nâu #78281F. Giữ đúng nết đó: nền trong suốt, chữ đỏ nhạt. */
html[data-xtheme="dark"] .table-scroll .tr_cap_4 td { background: transparent; color: #ff9b9b; }  /* 7,34:1 */

/* ===== C. .well — hộp tìm kiếm đầu 28 màn =====
 * bootstrap `.well{background-color:#f5f5f5;border:1px solid #e3e3e3}` -> chữ --x-ink 1,04:1.
 * Không nằm trong style.css nên các lượt quét trước (chỉ soi style.css) không thấy. */
html[data-xtheme="dark"] .well {
  background: var(--x-card); border-color: var(--x-line);   /* 14,2:1 */
  box-shadow: var(--x-inset);
}

/* ===== D. .panel — 46 màn =====
 * bootstrap `.panel{background-color:#fff}` -> 1,04:1. Đây là hộp bọc phổ biến nhất của cả cụm
 * nhansu/users/wework, sót nó là sót gần hết. */
html[data-xtheme="dark"] .panel {
  background-color: var(--x-card); border-color: var(--x-line);   /* 14,2:1 */
  box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .panel-default { border-color: var(--x-line); }
/* `.panel-default>.panel-heading` (0,2,1) nên phải đè bằng (0,3,2), không rút gọn thành .panel-heading */
html[data-xtheme="dark"] .panel-default > .panel-heading,
html[data-xtheme="dark"] .panel > .panel-heading {
  background-color: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-ink);   /* 16,4:1 */
}
html[data-xtheme="dark"] .panel-footer {
  background-color: rgba(255,255,255,.05); border-top-color: var(--x-line); color: var(--x-mut);
}
/* :4863 `.panel-title{color:#007378}` — teal thẫm vẽ cho nền trắng, trên thẻ tối còn 2,63:1.
   Đây là TIÊU ĐỀ hộp, chữ to nhất trong panel mà lại mờ nhất. */
html[data-xtheme="dark"] .panel-title { color: var(--x-cyan); }                                /* 10,7:1 */
html[data-xtheme="dark"] .panel-title a,
html[data-xtheme="dark"] .panel-title a:link,
html[data-xtheme="dark"] .panel-title a:visited { color: var(--x-cyan); }

/* ===== E. PHÂN TRANG — mọi màn danh sách =====
 * Không tìm được bằng cách grep class trong .tpl vì {NV_GENERATE_PAGE} dựng HTML từ PHP.
 * config.ini của theme đặt ul_class='pagination', li_class='' -> ra đúng DOM bootstrap 3,
 * ăn `.pagination>li>a{background-color:#fff;border:1px solid #ddd;color:#428bca}` = mảng trắng. */
html[data-xtheme="dark"] .pagination > li > a,
html[data-xtheme="dark"] .pagination > li > span {
  background-color: rgba(255,255,255,.05); border-color: var(--x-line); color: var(--x-cyan);  /* 12,3:1 */
}
html[data-xtheme="dark"] .pagination > li > a:hover,
html[data-xtheme="dark"] .pagination > li > a:focus,
html[data-xtheme="dark"] .pagination > li > span:hover {
  background-color: rgba(112,236,255,.14); border-color: var(--x-line2); color: var(--x-cyan);
}
/* Trang đang xem: bản sáng là nền xanh đặc + chữ trắng. Giữ nguyên lối đó nhưng đảo cực —
   nền cyan sáng thì chữ PHẢI tối, để trắng là tự tàng hình (đúng lỗi .aiop-ctl .btn đã sửa ở trên). */
html[data-xtheme="dark"] .pagination > .active > a,
html[data-xtheme="dark"] .pagination > .active > span,
html[data-xtheme="dark"] .pagination > .active > a:hover,
html[data-xtheme="dark"] .pagination > .active > span:hover,
html[data-xtheme="dark"] .pagination > .active > a:focus,
html[data-xtheme="dark"] .pagination > .active > span:focus {
  background-color: var(--x-cyan); border-color: var(--x-cyan); color: #03111a;               /* 13,8:1 */
}
html[data-xtheme="dark"] .pagination > .disabled > span,
html[data-xtheme="dark"] .pagination > .disabled > a {
  background-color: rgba(255,255,255,.03); border-color: var(--x-line); color: var(--x-faint); /* 8,5:1 */
}

/* ===== F. NÚT .theme-* — 21+ màn =====
 * :8729-8830 khai lần 1 (nền nhạt + chữ đậm), :9159-9190 khai LẠI cùng tên class cho "màu icon"
 * -> nền/chữ thực tế lấy bản sau, viền còn lại của bản trước. Cả hai đều là nền sáng.
 * Nền ĐẶC chứ không alpha: nút nằm lồng trong .well/.panel (đều alpha) -> cộng dồn, đúng bài
 * học của viên .alarm-sev (tính 4,73:1 mà đo thật 3,25:1).
 * Bộ nền #1b2a45/#0b312c/#3a2a0d/#3a1418 là bộ .sp-* đã dùng ở trên, giữ nhất quán toàn site.
 * :link/:visited BẮT BUỘC — các nút này là thẻ <a> (vd `<a class="theme-btn theme-red">Thêm mới</a>`),
 * mà mục 0 có a:link (0,2,2) > .theme-red (0,2,1) nên không có :link là bị cyan nuốt. */
html[data-xtheme="dark"] .theme-btn { box-shadow: none; }
html[data-xtheme="dark"] .theme-blue,   html[data-xtheme="dark"] a.theme-blue:link,   html[data-xtheme="dark"] a.theme-blue:visited   { background: #1b2a45; border-color: rgba(142,197,255,.32); color: var(--x-blue); }  /* 7,9:1 */
html[data-xtheme="dark"] .theme-green,  html[data-xtheme="dark"] a.theme-green:link,  html[data-xtheme="dark"] a.theme-green:visited  { background: #0b312c; border-color: rgba(94,234,212,.32);  color: #5eead4; }        /* 9,5:1 */
html[data-xtheme="dark"] .theme-yellow, html[data-xtheme="dark"] a.theme-yellow:link, html[data-xtheme="dark"] a.theme-yellow:visited { background: #3a2a0d; border-color: rgba(252,211,77,.32);  color: #fcd34d; }        /* 9,6:1 */
html[data-xtheme="dark"] .theme-red,    html[data-xtheme="dark"] a.theme-red:link,    html[data-xtheme="dark"] a.theme-red:visited    { background: #3a1418; border-color: rgba(255,143,143,.32); color: #ff8f8f; }        /* 7,4:1 */
html[data-xtheme="dark"] .theme-purple, html[data-xtheme="dark"] a.theme-purple:link, html[data-xtheme="dark"] a.theme-purple:visited { background: #241b3d; border-color: rgba(196,181,253,.32); color: #c4b5fd; }        /* 8,8:1 */
html[data-xtheme="dark"] .theme-orange, html[data-xtheme="dark"] a.theme-orange:link, html[data-xtheme="dark"] a.theme-orange:visited { background: #3a2410; border-color: rgba(255,184,119,.32); color: #ffb877; }        /* 8,6:1 */
html[data-xtheme="dark"] .theme-pink,   html[data-xtheme="dark"] a.theme-pink:link,   html[data-xtheme="dark"] a.theme-pink:visited   { background: #3a142c; border-color: rgba(255,158,196,.32); color: #ff9ec4; }        /* 8,3:1 */
/* Icon trong nút tự khai màu riêng (`.theme-green i{color:#1e8449}`...) nên không ăn màu nút */
html[data-xtheme="dark"] .theme-blue i   { color: var(--x-blue); }
html[data-xtheme="dark"] .theme-green i  { color: #5eead4; }
html[data-xtheme="dark"] .theme-yellow i { color: #fcd34d; }
html[data-xtheme="dark"] .theme-red i    { color: #ff8f8f; }
html[data-xtheme="dark"] .theme-purple i { color: #c4b5fd; }
html[data-xtheme="dark"] .theme-orange i { color: #ffb877; }
html[data-xtheme="dark"] .theme-pink i   { color: #ff9ec4; }
/* Hover bản sáng đổi chữ sang #fff (và .theme-red/.theme-orange đổi cả nền sang màu chói).
   Trên nền tối để nguyên là chữ trắng trên nền đậm — vẫn đọc được nhưng mất hẳn cảm giác "bấm được".
   Sáng nền lên 1 bậc, giữ chữ, đúng lối .item_menu:hover đã làm. */
html[data-xtheme="dark"] .theme-blue:hover   { background: #24395e; color: var(--x-blue); }
html[data-xtheme="dark"] .theme-green:hover  { background: #0f463e; color: #5eead4; }
html[data-xtheme="dark"] .theme-yellow:hover { background: #4a360f; color: #fcd34d; }
html[data-xtheme="dark"] .theme-red:hover    { background: #4f1b20; color: #ff8f8f; }
html[data-xtheme="dark"] .theme-purple:hover { background: #322553; color: #c4b5fd; }
html[data-xtheme="dark"] .theme-orange:hover { background: #4f3116; color: #ffb877; }
html[data-xtheme="dark"] .theme-pink:hover   { background: #4f1b3c; color: #ff9ec4; }

/* ===== G. .page — bọc CẢ màn hồ sơ users/info =====
 * :4734 `.page{background:#fff}`. users/info.tpl:5 là `<div class="page">` ôm trọn trang ->
 * cả màn trắng, chữ 1,04:1. Vào được từ chip người dùng ở header nên rất dễ gặp. */
html[data-xtheme="dark"] .page { background: var(--x-card); }                                  /* 14,2:1 */

/* ===== H. .nv-info — hộp thông báo của NukeViet, 10 màn users =====
 * :1516/:1531/:1536. Hai biến .error/.success dùng !important nên phải đánh lại bằng !important. */
html[data-xtheme="dark"] .nv-info {
  background-color: #16283c; border-color: var(--x-line); color: var(--x-mut);                 /* 10,6:1 */
}
html[data-xtheme="dark"] .nv-info.info {
  background-color: #1b2a45; border-color: rgba(142,197,255,.32); color: var(--x-blue);        /* 7,9:1 */
}
html[data-xtheme="dark"] .nv-info.info:before { color: var(--x-blue); }
html[data-xtheme="dark"] .nv-info.success {
  background-color: #0b312c !important; border-color: rgba(94,234,212,.32) !important; color: #5eead4;  /* 9,5:1 */
}
html[data-xtheme="dark"] .nv-info.success:before { color: #5eead4; }
html[data-xtheme="dark"] .nv-info.error {
  background-color: #3a1418 !important; border-color: rgba(255,143,143,.32) !important; color: #ff8f8f; /* 7,4:1 */
}
html[data-xtheme="dark"] .nv-info.error:before { color: #ff8f8f; }

/* ===== I. CHUÔNG THÔNG BÁO — hover =====
 * :7860 `.item_thong_bao:hover{background:#F5F8F9}`. Khối dropdown đã phủ ở trên (chữ ép --x-ink),
 * nên hover vào một thông báo là chữ trắng trên nền gần trắng = 1,02:1: BẤM VÀO LÀ MẤT CHỮ.
 * Phủ thiếu ngay trong vùng đã phủ, không phải màn mới.
 * wework/noti2.tpl:41 chép y hệt sang tên .item_thong_bao2 nên dính cùng lỗi. */
html[data-xtheme="dark"] .item_thong_bao:hover,
html[data-xtheme="dark"] .item_thong_bao2:hover { background: rgba(255,255,255,.07); }          /* chữ 13,6:1 */

/* ===== J. MÀN CHÍNH WEWORK (wework/main.tpl — "Công việc" trong menu) ===== */
/* :7616 `.tab_config-content{background:white}` — cái này là TẤM NỀN của cả màn, mảng trắng to nhất */
html[data-xtheme="dark"] .tab_config-content {
  background: var(--x-card); border: 1px solid var(--x-line); box-shadow: var(--x-inset);       /* 14,2:1 */
}
/* wework.css:2813 `.tab_config-tabs_ww{background:#fff}` — thanh tab của 13 màn wework */
html[data-xtheme="dark"] .tab_config-tabs_ww,
html[data-xtheme="dark"] .tab_config-tabs { background: transparent; }
/* :7642 thẻ `.config-item{background:#f9fafa;border:1px solid #d0d0d0}` */
html[data-xtheme="dark"] .config-item,
html[data-xtheme="dark"] a.config-item:link,
html[data-xtheme="dark"] a.config-item:visited {
  background: var(--x-card); border-color: var(--x-line); color: var(--x-ink); box-shadow: var(--x-inset);
}
html[data-xtheme="dark"] .config-item:hover { background: var(--x-card2); border-color: var(--x-line2); }
/* :7668 `.config-item h3{color:#34495e}` — chữ tối, và h3 tự khai màu nên không ăn màu thẻ cha */
html[data-xtheme="dark"] .config-item h3 { color: var(--x-ink); }                               /* 14,2:1 */
/* :7661 `.config-item i{color:#017e84}` — teal thẫm còn 3,05:1 trên thẻ tối */
html[data-xtheme="dark"] .config-item i { color: var(--x-cyan); }                               /* 10,7:1 */

/* ===== K. ICON MENU CẤP 2 (menu/global.dac_biet.tpl) =====
 * <style> nội tuyến của template menu khai `.icon{background-color:#eef3ff;color:#3366ff}` và
 * 7 biến thể `.icon.blue/.green/...` — đều nền nhạt vẽ cho menu trắng, giờ menu đã tối.
 * CHỈ hiện sau khi bấm nút "+" xổ nhóm con nên trước giờ chưa ai báo.
 * Bó trong .workplace-grid: class `.icon` quá chung, duan/projects.tpl cũng dùng — mà duan
 * ngoài phạm vi, không được đụng tới. */
html[data-xtheme="dark"] .workplace-grid .icon {
  background-color: rgba(112,236,255,.14); color: var(--x-cyan);                                /* 10,0:1 */
}
html[data-xtheme="dark"] .workplace-grid .item:hover .icon { background-color: rgba(112,236,255,.24); }
/* 7 biến thể tự khai nền+chữ riêng (`.icon.blue{background:#e6f4f1;color:#016a70}` — 2,33:1),
   (0,2,0) nên luật .workplace-grid .icon (0,3,1) ở trên đã đè được cả nền lẫn chữ.
   Giữ lại phân biệt nhóm bằng SẮC ĐỘ chữ, nền để chung một mức cho khỏi loang lổ. */
html[data-xtheme="dark"] .workplace-grid .icon.green      { color: var(--x-mint); }
html[data-xtheme="dark"] .workplace-grid .icon.yellow     { color: var(--x-amber); }
html[data-xtheme="dark"] .workplace-grid .icon.red        { color: var(--x-red); }
html[data-xtheme="dark"] .workplace-grid .icon.purple     { color: #c4b5fd; }
html[data-xtheme="dark"] .workplace-grid .icon.orange     { color: #ffb877; }
html[data-xtheme="dark"] .workplace-grid .icon.light-blue,
html[data-xtheme="dark"] .workplace-grid .icon.blue       { color: var(--x-blue); }

/* :1479/:1483 hai lớp tiện ích tô nền `.bg-gainsboro{#dcdcdc}` / `.bg-lavender{#eee}`.
 * Dùng dày ở users (login, hồ sơ, danh sách thành viên) — luôn đi kèm .page/.panel dạng
 * `class="page panel panel-default bg-lavender"`. Bản sáng chúng làm hộp XÁM HƠN nền trắng, tức
 * là "hộp có tô nhấn". Đặt SAU .page/.panel để trên cùng một thẻ chúng vẫn thắng (cùng (0,2,1),
 * luật sau thắng) -> giữ đúng quan hệ "tô nhấn thì lệch một bậc so với hộp thường". */
html[data-xtheme="dark"] .bg-lavender  { background-color: rgba(255,255,255,.05); }   /* 16,4:1 */
html[data-xtheme="dark"] .bg-gainsboro { background-color: rgba(255,255,255,.09); }   /* 14,4:1 */

/* ===== L. LINH TINH BOOTSTRAP còn sót ===== */
/* `.input-group-addon{background-color:#eee;border:1px solid #ccc;color:#555}` — 8 màn */
html[data-xtheme="dark"] .input-group-addon {
  background-color: rgba(255,255,255,.07); border-color: var(--x-line); color: var(--x-mut);    /* 10,5:1 */
}
/* `.list-group-item{background-color:#fff;border:1px solid #ddd}` */
html[data-xtheme="dark"] .list-group-item,
html[data-xtheme="dark"] a.list-group-item:link,
html[data-xtheme="dark"] a.list-group-item:visited {
  background-color: var(--x-card); border-color: var(--x-line); color: var(--x-ink);            /* 14,2:1 */
}
html[data-xtheme="dark"] a.list-group-item:hover { background-color: var(--x-card2); color: var(--x-ink); }
/* `.nav-tabs>li.active>a{color:#555;background-color:#fff;border:1px solid #ddd}` — tab đang mở màu trắng */
html[data-xtheme="dark"] .nav-tabs { border-bottom-color: var(--x-line); }
html[data-xtheme="dark"] .nav-tabs > li > a { color: var(--x-mut); }
html[data-xtheme="dark"] .nav-tabs > li > a:hover { background-color: rgba(255,255,255,.06); border-color: var(--x-line); }
html[data-xtheme="dark"] .nav-tabs > li.active > a,
html[data-xtheme="dark"] .nav-tabs > li.active > a:hover,
html[data-xtheme="dark"] .nav-tabs > li.active > a:focus {
  background-color: var(--x-card); border-color: var(--x-line); border-bottom-color: transparent; color: var(--x-cyan);  /* 10,7:1 */
}
/* Ô nhập bị khoá: mục 3 đã kéo MỌI .form-control về #0d1c2e — kể cả ô khoá, vì
   `html[data-xtheme="dark"] .form-control` (0,2,1) > `.form-control[disabled]` (0,2,0).
   Tức là bản tối vô tình XOÁ dấu hiệu "ô này không sửa được" mà bản sáng có (nền #eee).
   Không phải lỗi tương phản nhưng là chức năng bị mất, và do chính file này gây ra.
   Nền phải tô ĐẶC và phải đo với Ô THƯỜNG chứ không phải với nền trang: thử rgba(255,255,255,.04)
   trước, ra ĐÚNG 1,02:1 so với #0d1c2e — tức vẫn không thấy gì, vá như không vá. */
html[data-xtheme="dark"] .form-control[disabled],
html[data-xtheme="dark"] .form-control[readonly] {
  background: #203044; color: var(--x-faint);        /* chữ 6,7:1 — nền tách khỏi ô thường 1,28:1 */
}

/* ===== M. <style> NỘI TUYẾN CỦA TỪNG MÀN =====
 * Selector CHÉP NGUYÊN từ .tpl rồi thêm tiền tố: <style> của .tpl nằm SAU <link> file này. */
/* nhansu/thong_tin_nhan_vien.tpl:54 — nền panel hồ sơ nhân viên */
html[data-xtheme="dark"] .nen_panel_nv { background: rgba(255,255,255,.05); }                   /* 16,4:1 */
/* nhansu/hop_dong.tpl:16, nhan_vien_add.tpl:19, thong_tin_nhan_vien.tpl:74 — cùng một luật chép 3 nơi */
html[data-xtheme="dark"] .wrap_item_file_view { border-bottom-color: var(--x-line); }
/* wework/list_du_an.tpl:20, tasks.tpl:36, tasks_room.tpl:35 — cột tên dự án dán dính, nền trắng đặc.
   Nền ĐẶC (không alpha): cột này dán dính đè lên nội dung cuộn qua, alpha là rò chữ — đúng lỗi
   .tqnav đã mắc và đã sửa ở mục 2. */
html[data-xtheme="dark"] .projname2 {
  background: #0d1c2e;                                                                          /* 16,5:1 */
  border-left-color: var(--x-line); border-right-color: var(--x-line);
}
/* wework/tasks_add.tpl:87 — ô tìm người nhận việc */
html[data-xtheme="dark"] #search_box_assign { background-color: rgba(255,255,255,.05); }
/* wework/tasks_import.tpl:15 — hộp hướng dẫn nhập Excel */
html[data-xtheme="dark"] .info-box { background-color: #0b312c; border-color: rgba(94,234,212,.32); color: #5eead4; }  /* 9,5:1 */


/* ===== DAI DONG CHAY (.fx-*) — man Bieu do =====
   Nen thuc te: --x-card (10% trang) tren --x-page #04111d = #1d2934; chip dung --x-zone = #111d28.
   Tuong phan da tinh tren nen COMPOSITE do, khong phai tren #04111d. */
html[data-xtheme="dark"] .chart-page .fx-lane-tt { color: var(--x-faint); }                 /* 7,37:1 */
html[data-xtheme="dark"] .chart-page .fx-stage { background: var(--x-card); border-color: var(--x-line);
    border-left-color: var(--x-cyan); }
html[data-xtheme="dark"] .chart-page .fx-nm { color: var(--x-ink); }                        /* 14,18:1 */
html[data-xtheme="dark"] .chart-page .fx-hrt { color: var(--x-cyan); }                      /* 10,66:1 */
html[data-xtheme="dark"] .chart-page .fx-src { color: var(--x-mut); }                       /* 10,46:1 */
html[data-xtheme="dark"] .chart-page .fx-stage.fx-unit_manual { border-left-color: var(--x-amber); }
html[data-xtheme="dark"] .chart-page .fx-stage.fx-unit_manual .fx-src { color: var(--x-amber); }  /* 9,66:1 */
html[data-xtheme="dark"] .chart-page .fx-stage.fx-unknown { border-left-color: var(--x-faint);
    background: repeating-linear-gradient(45deg, rgba(255,255,255,.10), rgba(255,255,255,.10) 6px,
                rgba(255,255,255,.05) 6px, rgba(255,255,255,.05) 12px); }
html[data-xtheme="dark"] .chart-page .fx-stage.fx-unknown .fx-hrt { color: var(--x-faint); }
html[data-xtheme="dark"] .chart-page .fx-stage.fx-side { border-left-color: var(--x-faint); }
html[data-xtheme="dark"] .chart-page .fx-tag { color: var(--x-faint); }
html[data-xtheme="dark"] .chart-page .fx-tank { background: var(--x-zone); color: var(--x-mut); }  /* 12,07:1 */
html[data-xtheme="dark"] .chart-page .fx-ns { color: var(--x-cyan); }                       /* 12,30:1 */
html[data-xtheme="dark"] .chart-page .fx-arrow { color: var(--x-faint); }                   /* 9,48:1 */
html[data-xtheme="dark"] .chart-page .fx-empty { color: var(--x-amber); background: rgba(255,201,77,.10);
    border-color: rgba(255,201,77,.34); }
html[data-xtheme="dark"] .chart-page .fx-sum { color: var(--x-mut); background: var(--x-zone);
    border-color: var(--x-line); }


/* ==========================================================================
   BỔ SUNG TRƯỚC KHI LẤY TỐI LÀM MẶC ĐỊNH
   Rà soát 2026-07-20 tìm ra 54 chỗ còn ghim màu sáng mà không có cặp ghi đè.
   Khi tối chỉ là tuỳ chọn thì các chỗ này ít người thấy; lấy tối làm MẶC ĐỊNH thì
   người vào lần đầu gặp ngay -> phải phủ hết rồi mới lật.
   Nguyên tắc: chỉ dùng biến --x-* đã có, không đẻ màu mới.
   ========================================================================== */

/* --- 1. Ô TÌM KIẾM (nền ghim inline nên bắt buộc !important) -------------
   Nặng nhất trong cả đợt: nền sáng + chữ thừa hưởng màu sáng -> GÕ KHÔNG THẤY CHỮ.
   Có ở projects, list_du_an, projects_view, form_tasks_add. */
html[data-xtheme="dark"] input#q,
html[data-xtheme="dark"] input#search_box,
html[data-xtheme="dark"] input[name="q"],
html[data-xtheme="dark"] input[name="search_box"] {
  background: var(--x-card) !important;
  color: var(--x-ink) !important;
  border: 1px solid var(--x-line) !important;
}
html[data-xtheme="dark"] input#q::placeholder,
html[data-xtheme="dark"] input#search_box::placeholder,
html[data-xtheme="dark"] input[name="q"]::placeholder,
html[data-xtheme="dark"] input[name="search_box"]::placeholder { color: var(--x-faint) !important; }

/* --- 2. Dải .overview và modal-header ghim inline ------------------------- */
html[data-xtheme="dark"] .overview {
  background: var(--x-card) !important;
  border-bottom-color: var(--x-line) !important;
}
html[data-xtheme="dark"] .modal-header[style] {
  background-color: transparent !important;
  border-bottom: 1px solid var(--x-line) !important;
}

/* --- 3. Khung chat: chữ trắng trên nền #f9f9f9 = MẤT SẠCH tin nhắn -------- */
html[data-xtheme="dark"] #chat-box {
  background: var(--x-zone) !important;
  border-color: var(--x-line) !important;
  color: var(--x-ink);
}

/* --- 4. Hai hộp hướng dẫn nhập Excel (nền ghim inline, không đặt màu chữ) - */
html[data-xtheme="dark"] div[style*="#DBE6FF"],
html[data-xtheme="dark"] div[style*="#EEEEEE"] {
  background: var(--x-card) !important;
  color: var(--x-ink) !important;
}

/* --- 5. Nút Gửi ở màn Hỏi đáp AI ----------------------------------------
   Bản tối đảo --blue thành #8ec5ff (SÁNG) nên chữ trắng chỉ còn ~1,4:1.
   Nền đã sáng thì chữ phải sẫm lại, không phải làm nền tối đi. */
html[data-xtheme="dark"] .ha-send { color: #04111d !important; }

/* --- 6. Hộp thả xuống chọn dự án (select2) -------------------------------
   Bản phủ cũ chỉ đổi NỀN dropdown mà quên màu chữ -> chữ gần đen trên nền
   #0d1c2e (~1,2:1): hộp trông rỗng, tên dự án chỉ hiện khi rê chuột. */
html[data-xtheme="dark"] .select2-container--default .select2-results__option { color: var(--x-ink) !important; }

/* --- 7. Màn Phân quyền theo chức năng (trước đây CHƯA phủ dòng nào) ------- */
html[data-xtheme="dark"] .qf-wrap,
html[data-xtheme="dark"] .qf-cn-name { color: var(--x-ink); }
html[data-xtheme="dark"] .qf-panel {
  background: var(--x-card); border-color: var(--x-line); box-shadow: none;
}
html[data-xtheme="dark"] .qf-gtitle { background: var(--x-zone); color: var(--x-cyan); }
html[data-xtheme="dark"] .qf-table thead th { background: transparent; color: var(--x-mut); }
html[data-xtheme="dark"] .qf-table th,
html[data-xtheme="dark"] .qf-table td { border-color: var(--x-line); }
html[data-xtheme="dark"] .qf-hint,
html[data-xtheme="dark"] .qf-cn-desc { color: var(--x-faint); }

/* --- 8. Màn Cấu hình sơ đồ SCADA (trước đây CHƯA phủ dòng nào) ------------ */
html[data-xtheme="dark"] .cf { color: var(--x-ink); }
html[data-xtheme="dark"] .cf-kpi,
html[data-xtheme="dark"] .cf-stage,
html[data-xtheme="dark"] .cf-skid,
html[data-xtheme="dark"] .cf-unit { background: var(--x-card); border-color: var(--x-line); }
html[data-xtheme="dark"] .cf-kpi b,
html[data-xtheme="dark"] .cf-titl .sub b { color: var(--x-ink); }

/* --- 9. Giám sát bảo trì: menu 3 chấm + thẻ phiếu chờ duyệt ---------------
   Hai khối này do JS chèn vào sau nên bản phủ cũ (viết theo .tpl đời trước) không với tới. */
html[data-xtheme="dark"] .gs-kebab-menu {
  background: #0d1c2e; border-color: var(--x-line); box-shadow: 0 10px 24px rgba(0, 0, 0, .55);
}
html[data-xtheme="dark"] .gs-kebab-menu * { color: var(--x-ink); }
html[data-xtheme="dark"] .gs-pcard { background: var(--x-card); border-color: var(--x-line); }
html[data-xtheme="dark"] .gs-pcard h4 { color: var(--x-ink); }
html[data-xtheme="dark"] .gs-pm { color: var(--x-mut); }

/* --- 10. Hộp mã QR trên màn Mạng lưới ------------------------------------
   CHỈ đổi khung. Ảnh QR (.w3d-qrimg) PHẢI giữ nền trắng — đảo màu là máy không quét được. */
html[data-xtheme="dark"] .w3d-qrbox { background: var(--x-card); border-color: var(--x-line); }

/* --- 11. Thanh công cụ mô hình 3D ---------------------------------------
   Khung cảnh 3D (.pv3-stage) CỐ Ý sáng = bầu trời ban ngày, đã có nút "Ban đêm" -> không đụng.
   Chỉ thanh công cụ nằm NGOÀI khung cảnh mới cần theo chế độ tối. */
html[data-xtheme="dark"] .pv3-bar { background: var(--x-card); border-color: var(--x-line); color: var(--x-ink); }
html[data-xtheme="dark"] .pv3-bar label,
html[data-xtheme="dark"] .pv3-cnt { color: var(--x-mut); }
html[data-xtheme="dark"] .pv3-btn { background: var(--x-card2); border-color: var(--x-line); color: var(--x-ink); }
html[data-xtheme="dark"] .pv3-btn:hover { background: var(--x-line2); }
html[data-xtheme="dark"] .pv3-bar select { background: var(--x-card2); color: var(--x-ink); border-color: var(--x-line); }

/* --- 12. Thống kê: mũi tên tăng/giảm và số cảnh báo ----------------------- */
html[data-xtheme="dark"] .tk-up { color: var(--x-amber); }
html[data-xtheme="dark"] .tk-dn { color: var(--x-green); }
html[data-xtheme="dark"] .tk-warn b[style] { color: var(--x-amber) !important; }

/* --- 13. Màn Xem báo cáo dự án ------------------------------------------- */
html[data-xtheme="dark"] .stat-box,
html[data-xtheme="dark"] .chart-container,
html[data-xtheme="dark"] .table-container {
  background: var(--x-card) !important; border-color: var(--x-line) !important;
}

/* --- 14. Biểu đồ dự báo AI (SVG tự sinh, màu ghim trong JS) ---------------
   KHÔNG sửa JS: `stroke`/`fill` viết trong SVG chỉ là THUỘC TÍNH TRÌNH BÀY, CSS luôn thắng.
   Chọn theo đúng giá trị hex mà JS sinh ra -> đổi màu mà không đụng một dòng mã nào.
   Nếu sau này JS đổi hex thì luật ở đây ngừng ăn (không vỡ, chỉ hết tác dụng). */
html[data-xtheme="dark"] .chart-svg line[stroke="#eef2f7"] { stroke: rgba(255, 255, 255, .12); }
html[data-xtheme="dark"] .chart-svg line[stroke="#e2e8f0"] { stroke: var(--x-line2); }
html[data-xtheme="dark"] .chart-svg path[stroke="#2563eb"] { stroke: var(--x-blue); }
html[data-xtheme="dark"] .chart-svg [stroke="#d97706"] { stroke: var(--x-amber); }
html[data-xtheme="dark"] .chart-svg [fill="#d97706"] { fill: var(--x-amber); }
html[data-xtheme="dark"] .chart-svg [stroke="#dc2626"] { stroke: var(--x-red); }
html[data-xtheme="dark"] .chart-svg [fill="#dc2626"] { fill: var(--x-red); }
html[data-xtheme="dark"] .chart-svg [stroke="#64748b"] { stroke: var(--x-faint); }
html[data-xtheme="dark"] .chart-svg [fill="#64748b"] { fill: var(--x-faint); }
/* vạch ngưỡng còn bị nhân opacity .5 nên trên nền tối gần như tàng hình */
html[data-xtheme="dark"] .chart-svg [opacity="0.5"] { opacity: .85; }

/* --- 15. IN ẤN: luôn in ra NỀN SÁNG -------------------------------------
   Tối là mặc định nghĩa là báo cáo dự án / phiếu bảo trì / trang QR sẽ in ra nền đen,
   tốn mực và nhiều máy in ra đen sì. Khi in thì ép về sáng, bất kể đang xem chế độ nào. */
@media print {
  html[data-xtheme="dark"],
  html[data-xtheme="dark"] body,
  html[data-xtheme="dark"] body#body {
    background: #fff !important;
    background-image: none !important;
    color: #000 !important;
  }
  html[data-xtheme="dark"] * {
    background-image: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }
}
