/* =============================================================================
   PlcRemote — giao diện

   Bố cục ba phần: cột điều hướng bên trái, thanh tiêu đề trên, vùng nội dung.
   Cột trái tông đậm là khung cố định; vùng nội dung sáng mới là chỗ mắt dừng lại.

   Bootstrap vẫn được nạp trước file này vì các trang Account (Identity) và vài
   trang cũ còn dùng. Những lớp trùng tên với Bootstrap (card, btn) ở đây đổi
   thành .the và .nut để hai bộ không đè nhau.
   ============================================================================= */

:root {
  --nen:        #f2f4f8;
  --the:        #ffffff;
  --vien:       #dfe3ea;
  --vien-nhat:  #eef1f6;

  --chu:        #1c2433;
  --chu-2:      #64708a;
  --chu-3:      #8e99b0;

  --chinh:      #1e4b8f;
  --chinh-dam:  #163a70;
  --chinh-nhat: #e8eefa;

  --tot:        #1a7f4b;
  --tot-nen:    #e6f5ed;
  --canh:       #a5670a;
  --canh-nen:   #fdf3e0;
  --xau:        #b32020;
  --xau-nen:    #fdeaea;

  --canh-trai:  #16233c;
  --canh-chu:   #aab6cc;
  --canh-hoat:  #ffffff;

  --bo-goc: 10px;
  --do-bong: 0 1px 2px rgba(20, 32, 60, .06), 0 4px 12px rgba(20, 32, 60, .05);
  --rong-canh: 232px;

  /* Sắc phụ: viền và chữ đậm trên nền trạng thái, nền phụ của bảng/ô nhập.
     Chữ cảnh báo là --canh-dam, KHÔNG phải --canh-chu: --canh-chu là chữ cột trái, và
     khai trùng tên trong cùng :root thì cái khai sau thắng — menu từng ra màu nâu vì vậy. */
  --tot-vien:   #bfe6d0;  --tot-chu:  #145c37;
  --canh-vien:  #f0dcb4;  --canh-dam: #7d4e07;
  --xau-vien:   #f2c4c4;  --xau-chu:  #8c1919;
  --nen-dau-bang: #f7f9fc;
  --dong-hover:   #f8fafd;
  --xau-nen-dam:  #fbdede;
  --canh-nen-dam: #fbecd2;
  --nen-tat:      #f5f7fa;
  --vong-chinh:   rgba(30, 75, 143, .12);
  --den-tat:      #cdd3de;
  --den-vien:     #b8c0cf;
  --den-bat:      #2ecc71;
  --man-che:      rgba(12, 20, 36, .5);
  --bong-hop:     0 20px 60px rgba(10, 18, 32, .35);
  --mui-ten:      url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' stroke='%2364708a' stroke-width='1.8' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  --bong-noi:     0 12px 34px rgba(10, 18, 32, .22);
  --chu-dao:      #ffffff;  /* chữ trên nền --chinh, giống nhau ở cả hai giao diện */
  --lich-hinh:    url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' fill='none' stroke='%2364708a' stroke-width='1.4'%3E%3Crect x='1.4' y='2.6' width='12.2' height='11' rx='1.8'/%3E%3Cpath d='M1.4 6h12.2M4.6 1.2v2.6M10.4 1.2v2.6' stroke-linecap='round'/%3E%3C/svg%3E");

  color-scheme: light;
}

/* Giao diện tối. Thuộc tính data-theme do wwwroot/giao-dien.js đặt trước khi vẽ
   (theo lựa chọn đã lưu, hoặc theo hệ điều hành), nên CSS chỉ cần một bộ giá trị. */
:root[data-theme="dark"] {
  --nen:        #0f1520;
  --the:        #182033;
  --vien:       #2a3550;
  --vien-nhat:  #212b42;

  --chu:        #e6eaf2;
  --chu-2:      #9aa7c0;
  --chu-3:      #6f7c96;

  --chinh:      #4f86dc;
  --chinh-dam:  #6d9be6;
  --chinh-nhat: #1b2a45;

  --tot:        #3ccf7a;
  --tot-nen:    rgba(46, 204, 113, .14);
  --canh:       #e0a430;
  --canh-nen:   rgba(224, 164, 48, .14);
  --xau:        #ef5a5a;
  --xau-nen:    rgba(239, 90, 90, .14);

  --canh-trai:  #0b111c;
  --canh-chu:   #9aa7c0;
  --canh-hoat:  #ffffff;

  --do-bong: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .3);

  --tot-vien:   rgba(46, 204, 113, .3);   --tot-chu:  #8fe3b2;
  --canh-vien:  rgba(224, 164, 48, .3);   --canh-dam: #f0c974;
  --xau-vien:   rgba(239, 90, 90, .3);    --xau-chu:  #f5a3a3;
  --nen-dau-bang: #1c2538;
  --dong-hover:   #1f2a40;
  --xau-nen-dam:  rgba(239, 90, 90, .26);
  --canh-nen-dam: rgba(224, 164, 48, .26);
  --nen-tat:      #141b2b;
  --vong-chinh:   rgba(79, 134, 220, .3);
  --den-tat:      #2a3550;
  --den-vien:     #3a4762;
  --den-bat:      #2ecc71;
  --man-che:      rgba(0, 0, 0, .6);
  --bong-hop:     0 20px 60px rgba(0, 0, 0, .6);
  --mui-ten:      url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' stroke='%239aa7c0' stroke-width='1.8' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  --bong-noi:     0 12px 34px rgba(0, 0, 0, .5);
  --lich-hinh:    url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' fill='none' stroke='%239aa7c0' stroke-width='1.4'%3E%3Crect x='1.4' y='2.6' width='12.2' height='11' rx='1.8'/%3E%3Cpath d='M1.4 6h12.2M4.6 1.2v2.6M10.4 1.2v2.6' stroke-linecap='round'/%3E%3C/svg%3E");

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--nen);
  color: var(--chu);
  font: 14px/1.55 "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--chinh); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Vòng focus chung cho mọi thứ bấm được bằng bàn phím. Chỉ hiện khi đi bằng Tab
   (:focus-visible), không hiện khi bấm chuột. Không đè lên control Bootstrap ở trang Account.
   Bỏ qua h1: FocusOnNavigate (Routes.razor) đặt focus vào tiêu đề mỗi lần chuyển trang để
   trình đọc màn hình đọc tên trang; trình duyệt mobile coi focus đó là "visible" và vẽ khung. */
:focus-visible:not(h1):not(.form-control):not(.form-select):not(.form-check-input) {
  outline: 2px solid var(--chinh); outline-offset: 2px;
}
button, [role="button"], a.nut, .cong-tac { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

h1:focus { outline: none; }

/* ---------------------------------------------------------------- *
   Bố cục
 * ---------------------------------------------------------------- */

/* Khung khớp đúng chiều cao màn hình và KHÔNG tự cuộn — chỉ .noi-dung bên trong
   mới cuộn, để mỗi màn hình chỉ có đúng một thanh cuộn. */
.khung { display: flex; height: 100vh; height: 100dvh; overflow: hidden; }

.canh-trai {
  width: var(--rong-canh);
  flex: 0 0 var(--rong-canh);
  background: var(--canh-trai);
  color: var(--canh-chu);
  display: flex;
  flex-direction: column;
  height: 100%;
}

.canh-hieu {
  padding: 12px 14px 11px;
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  display: flex; align-items: center; gap: 9px;
}
.canh-hieu .dau-hieu {
  width: 30px; height: 30px; border-radius: 8px;
  background: linear-gradient(135deg, #3d7bd9, #1e4b8f);
  color: #fff; font-weight: 700; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 30px;
}
.canh-hieu .ten { color: #fff; font-weight: 600; font-size: 15px; letter-spacing: .2px; line-height: 1.2; }
.canh-hieu .phu { display: block; font-size: 11px; color: var(--chu-3); font-weight: 400; }

.canh-muc { padding: 6px 8px 10px; overflow-y: auto; flex: 1; }
.canh-nhom {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .8px;
  color: #66748f; padding: 9px 10px 3px; font-weight: 600;
}

.canh-muc a, .canh-muc button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 6px 11px; margin-bottom: 1px;
  border: 0; border-radius: 7px; background: none;
  color: var(--canh-chu); font: inherit; font-size: 13.5px; line-height: 1.45;
  text-align: left; text-decoration: none; cursor: pointer;
  transition: background .12s, color .12s;
}
.canh-muc a:hover, .canh-muc button:hover { background: rgba(255, 255, 255, .06); color: #fff; text-decoration: none; }
.canh-muc a.hoat { background: var(--chinh); color: var(--canh-hoat); font-weight: 600; }
.canh-muc .bieu-tuong {
  width: 18px; text-align: center; flex: 0 0 18px; opacity: .9; font-size: 15px;
}
/* Biểu tượng vẽ bằng SVG khi không có ký tự Unicode phù hợp (tài khoản). */
.canh-muc .bieu-tuong svg { display: block; width: 16px; height: 16px; margin: 0 auto; }
.canh-muc .dem {
  margin-left: auto; background: var(--xau); color: #fff;
  font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 9px;
}
.canh-muc a.hoat .dem { background: rgba(255, 255, 255, .25); }

.than { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; overflow: hidden; }

.thanh-tren {
  background: var(--the);
  border-bottom: 1px solid var(--vien);
  padding: 0 22px;
  height: 58px;
  flex: 0 0 58px;
  display: flex; align-items: center; gap: 14px;
  z-index: 20;
}
.thanh-tren h1 { font-size: 17px; margin: 0; font-weight: 600; }
.thanh-tren .phai { margin-left: auto; display: flex; align-items: center; gap: 12px; }

.nguoi-dung { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.nguoi-dung .anh {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--chinh-nhat); color: var(--chinh);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 12px;
}
.nguoi-dung .ten { font-weight: 600; }
.nguoi-dung .vai { display: block; font-size: 11px; color: var(--chu-2); font-weight: 400; }

/* Nút đổi sáng/tối: biểu tượng đổi theo giao diện đang dùng. */
.nut-giao-dien {
  width: 34px; height: 34px; border-radius: 8px;
  border: 1px solid var(--vien); background: var(--the); color: var(--chu-2);
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0;
}
.nut-giao-dien:hover { color: var(--chu); border-color: var(--chu-3); }
.nut-giao-dien::before { content: "\263E"; }              /* ☾ — bấm để sang tối */
:root[data-theme="dark"] .nut-giao-dien::before { content: "\2600"; } /* ☀ — bấm để sang sáng */

/* Chỗ cuộn DUY NHẤT của mỗi màn hình. min-height:0 là bắt buộc với flex item. */
.noi-dung { padding: 11px; flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }

.nut-menu {
  display: none; background: none; border: 0; cursor: pointer;
  font-size: 20px; color: var(--chu); padding: 4px 8px; border-radius: 6px; margin: 0;
}
.nut-menu:hover { background: var(--vien-nhat); }
/* Ô đánh dấu điều khiển menu: giấu khỏi mắt nhưng vẫn nhận focus, để bàn phím mở được menu. */
.nut-menu-bat {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.nut-menu-bat:focus-visible ~ .than .nut-menu { outline: 2px solid var(--chinh); outline-offset: 2px; }
.man-che { display: none; }

/* ---------------------------------------------------------------- *
   Thẻ
 * ---------------------------------------------------------------- */

.the {
  background: var(--the);
  border: 1px solid var(--vien);
  border-radius: var(--bo-goc);
  box-shadow: var(--do-bong);
  margin-bottom: 8px;
  overflow: hidden;
}
.the > h2 {
  margin: 0; padding: 13px 18px;
  font-size: 14px; font-weight: 600;
  border-bottom: 1px solid var(--vien-nhat);
  display: flex; align-items: center; gap: 10px;
}
.the > h2 .phai { margin-left: auto; font-weight: 400; font-size: 12px; color: var(--chu-2); }
.the > .body { padding: 18px; }

.hint { color: var(--chu-2); font-size: 12.5px; margin: 6px 0; }

/* ---------------------------------------------------------------- *
   Ô thống kê
 * ---------------------------------------------------------------- */

/* Hàng ô thống kê đầu trang. Cách khối dưới đúng bằng khoảng giữa hai .the.
   Mỗi ô: .qlk-nhan (nhãn) + .qlk-so-lon (số) + .hint tuỳ chọn, như ô tag ở Giám sát. */
.stats {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-bottom: 8px;
}
.stats .qlk-so-lon { overflow-wrap: anywhere; }

.stat {
  background: var(--the);
  border: 1px solid var(--vien);
  border-radius: var(--bo-goc);
  box-shadow: var(--do-bong);
  padding: 15px 17px;
  position: relative;
  min-width: 0;
}
.stat.bad  { border-left: 3px solid var(--xau); }
.stat.ok   { border-left: 3px solid var(--tot); }
.stat.warn { border-left: 3px solid var(--canh); }

.qlk-nhan {
  font-size: 11.5px; color: var(--chu-2);
  text-transform: uppercase; letter-spacing: .5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qlk-so-lon {
  font-size: 25px; font-weight: 700; color: var(--chu);
  letter-spacing: -.5px; margin-top: 5px; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.stat.bad .qlk-so-lon { color: var(--xau); }
.stat .hint { margin: 3px 0 0; font-size: 12px; }
.stat .hint.xau { color: var(--xau); }

/* Ô thống kê có biểu tượng (tổng quan Giám sát): ô vuông nền nhạt bên trái, màu theo
   trạng thái của ô; ô trung tính (không có gì bất thường) để xám. */
.stat.co-bieu-tuong { display: flex; align-items: center; gap: 13px; }
.stat.co-bieu-tuong > div { min-width: 0; }
.o-bieu-tuong {
  flex: 0 0 40px; height: 40px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--vien-nhat); color: var(--chu-2);
}
.o-bieu-tuong svg { width: 22px; height: 22px; }
.stat.ok   .o-bieu-tuong { background: var(--tot-nen);  color: var(--tot); }
.stat.warn .o-bieu-tuong { background: var(--canh-nen); color: var(--canh); }
.stat.bad  .o-bieu-tuong { background: var(--xau-nen);  color: var(--xau); }
.stat.co-bieu-tuong.ok   .qlk-so-lon { color: var(--tot); }
.stat.co-bieu-tuong.warn .qlk-so-lon { color: var(--canh); }
input[aria-invalid="true"] { border-color: var(--xau); }

/* ---------------------------------------------------------------- *
   Bố cục theo cấu hình tag (Group / Kind)

   Mỗi nhóm là một thẻ .the, thân là lưới .nhom-luoi. Ô số to chiếm hai cột,
   hàng đèn chiếm cả bề ngang, còn lại là ô .stat bình thường — mô phỏng cách
   màn HMI xếp: số chính thật to, đèn quạt xếp hàng, công tắc cạnh giá trị.
 * ---------------------------------------------------------------- */

.nhom-luoi {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  align-items: start;
}
.nhom-luoi .stat { box-shadow: none; }

/* Ô số to: số chính của màn hình, ví dụ NHIỆT ĐỘ PHÒNG trên kho lạnh. */
.stat.lon { grid-column: span 2; }
.stat.lon .qlk-so-lon { font-size: 46px; letter-spacing: -1px; margin-top: 8px; }
@media (max-width: 480px) { .stat.lon { grid-column: span 1; } .stat.lon .qlk-so-lon { font-size: 36px; } }

/* Hàng đèn: các tag Lamp khai liên tiếp trong cùng nhóm nằm chung một hàng. */
.hang-den {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 8px 6px;
  padding: 10px 12px;
  background: var(--nen); border: 1px solid var(--vien-nhat); border-radius: var(--bo-goc);
}
.den {
  display: inline-flex; flex-direction: column; align-items: center; gap: 5px;
  min-width: 64px; padding: 6px 4px;
  font-size: 11.5px; color: var(--chu-2); text-align: center; line-height: 1.2;
}
.den .cham {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--den-tat); border: 2px solid var(--den-vien);
  transition: background .15s, box-shadow .15s;
}
.den.bat .cham { background: var(--den-bat); border-color: var(--tot); box-shadow: 0 0 0 3px rgba(26, 127, 75, .18); }
.den.bat { color: var(--chu); }
.den.bad .cham { background: var(--xau-nen); border-color: var(--xau); }
.den.canh .cham { background: var(--canh-nen); border-color: var(--canh); }
.den .nhan { max-width: 96px; overflow: hidden; text-overflow: ellipsis; }
/* Đèn đa trạng thái (Kind State): dòng chữ trạng thái dưới tên, để không chỉ dựa vào màu. */
.den .tt { font-size: 11px; font-weight: 600; color: var(--chu-3); }
.den.bat .tt { color: var(--tot); }
.den.canh .tt { color: var(--canh); }
.den.bad .tt { color: var(--xau); }

/* Công tắc ON/OFF: nút bấm được tô như switch; trạng thái luôn theo giá trị đọc về. */
.cong-tac {
  position: relative; width: 52px; height: 28px; flex: 0 0 auto;
  border-radius: 14px; border: 1px solid var(--den-vien); background: var(--den-tat);
  cursor: pointer; padding: 0; transition: background .15s, border-color .15s;
}
.cong-tac .nu {
  position: absolute; top: 2px; left: 2px; width: 22px; height: 22px;
  border-radius: 50%; background: var(--the); box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: left .15s;
}
.cong-tac.bat { background: var(--den-bat); border-color: var(--tot); }
.cong-tac.bat .nu { left: 26px; }
.cong-tac:disabled { cursor: not-allowed; opacity: .55; }
.cong-tac:focus-visible { outline: 2px solid var(--chinh); outline-offset: 2px; }
.cong-tac-chu { font-size: 20px; font-weight: 700; color: var(--chu-3); }
.cong-tac-chu.bat { color: var(--tot); }

/* Nút nhấn kiểu CHẠY / DỪNG. */
.nut.lon { width: 100%; padding: 12px 16px; font-size: 15px; margin-top: 8px; }

/* ---------------------------------------------------------------- *
   Giám sát theo nhóm (Pages/Dashboard.razor + Components/GiamSat)

   Mỗi nhóm (một màn HMI) là một thẻ .the-nhom; tiêu đề thẻ cho biết nút điều khiển máy
   nào. Trong thẻ (.nhom-than) mỗi loại tag là một dòng trải hết bề ngang, thứ tự cố định:
   hàng đèn, lưới ô số, Cài đặt, Công tắc, Chạy/dừng (mỗi loại là lưới ô tự xuống dòng,
   không khung bọc phần điều khiển, không nhãn đầu mục).
   Không chia cột, nên loại nhiều tag không kéo dài một cột và bỏ trống cột kia. Chỉ
   .noi-dung cuộn.
   .loc-nhom lọc theo nhóm, dạng viên để khác hàng tab sơ đồ ngay phía trên.
 * ---------------------------------------------------------------- */

.loc-nhom { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.loc-nhom a {
  padding: 5px 12px; border: 1px solid var(--vien); border-radius: 20px;
  background: var(--the); color: var(--chu-2);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
.loc-nhom a:hover { color: var(--chu); background: var(--vien-nhat); text-decoration: none; }
.loc-nhom a[aria-current="page"] { background: var(--chinh-nhat); border-color: var(--chinh); color: var(--chinh); }

.the-nhom { margin-bottom: 12px; }
.nhom-than { display: grid; gap: 14px; padding: 18px; }

/* Chạy / dừng: một hàng nút cỡ cố định, không giãn hết bề ngang thẻ. */
.hang-nut { display: flex; flex-wrap: wrap; gap: 10px; }
.hang-nut .nut.lon { width: auto; min-width: 170px; margin-top: 0; }
.hang-nut .hint { flex-basis: 100%; margin: 0; }

/* Công tắc và Cài đặt: lưới ô tự xuống dòng, mỗi ô một tag có viền riêng. */
.ds-cong-tac, .ds-cai-dat { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.ds-cong-tac { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.ds-cai-dat { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px; }
.ds-cong-tac li, .ds-cai-dat li {
  background: var(--the); border: 1px solid var(--vien-nhat); border-radius: var(--bo-goc); min-width: 0;
}

/* Công tắc: tên · công tắc · BẬT/TẮT; cao ≥ 44px cho dễ chạm. */
.ds-cong-tac li { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 14px; }
.ds-cong-tac .ten { flex: 1; min-width: 0; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-cong-tac .cong-tac-chu { flex: 0 0 auto; min-width: 3.2em; font-size: 13.5px; white-space: nowrap; }
.cong-tac-chu.xau { color: var(--xau); }

/* Cài đặt: tầng trên tên + dải · giá trị hiện tại, tầng dưới ô nhập + Ghi trọn ô. */
.ds-cai-dat li { display: grid; gap: 8px; align-content: start; padding: 10px 14px; }
.ds-cai-dat .dong-dau { display: flex; align-items: flex-start; gap: 12px; }
.ds-cai-dat .ten { flex: 1; min-width: 0; font-size: 13.5px; overflow-wrap: anywhere; }
.ds-cai-dat .ten .hint { margin: 2px 0 0; font-size: 12px; }
.ds-cai-dat .hien-tai { flex: 0 0 auto; text-align: right; }
.ds-cai-dat .hien-tai .hint { display: block; margin: 0; font-size: 11.5px; }
.ds-cai-dat .hien-tai strong { font-size: 17px; }
.ds-cai-dat .hien-tai strong.xau { color: var(--xau); font-size: 13.5px; }
.ds-cai-dat .hint.xau { margin: 0; }

.hint.xau { color: var(--xau); }

@media (max-width: 560px) {
  .loc-nhom { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
  .nhom-than { padding: 14px; }
  .hang-nut .nut.lon { flex: 1 1 140px; min-width: 0; }
  .ds-cong-tac, .ds-cai-dat { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------- *
   Bảng
 * ---------------------------------------------------------------- */

.dt { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.dt thead th {
  background: var(--nen-dau-bang);
  text-align: left; font-weight: 600; font-size: 12px;
  color: var(--chu-2); text-transform: uppercase; letter-spacing: .4px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--vien);
  position: sticky; top: 0; z-index: 2;
  white-space: nowrap;
}
.dt tbody td { padding: 9px 12px; border-bottom: 1px solid var(--vien-nhat); vertical-align: middle; }
.dt tbody tr:last-child td { border-bottom: 0; }
.dt tbody tr:hover { background: var(--dong-hover); }

.dt tfoot td {
  padding: 10px 12px; font-weight: 700;
  background: var(--nen-dau-bang); border-top: 2px solid var(--vien);
}

.dt .r, td.r, th.r { text-align: right; }
.dt .c, td.c, th.c { text-align: center; }
.num { font-variant-numeric: tabular-nums; white-space: nowrap; }

tr.dong-am  { background: var(--xau-nen); }
tr.dong-am:hover { background: var(--xau-nen-dam); }
tr.dong-cho { background: var(--canh-nen); }
tr.dong-cho:hover { background: var(--canh-nen-dam); }
tr.dong-mo td { color: var(--chu-3); }
tr.dong-bam { cursor: pointer; }
tr.dong-bam:focus-visible { outline-offset: -2px; }

.scroll, .scroll-x { overflow-x: auto; max-width: 100%; }
/* Bảng dài (lịch sử): giới hạn chiều cao, cuộn bên trong thẻ để header dính. */
.cuon-doc { max-height: 60vh; overflow-y: auto; }

/* ---------------------------------------------------------------- *
   Nhãn, thông báo
 * ---------------------------------------------------------------- */

.tag {
  display: inline-block; padding: 2px 8px; border-radius: 20px;
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
  background: var(--vien-nhat); color: var(--chu-2);
}
.tag.ok   { background: var(--tot-nen);  color: var(--tot); }
.tag.warn { background: var(--canh-nen); color: var(--canh); }
.tag.bad  { background: var(--xau-nen);  color: var(--xau); }
.tag.mo   { background: var(--vien-nhat); color: var(--chu-2); }

/* Chấm nhấp nháy cạnh nhãn "đang nhận dữ liệu" — dấu hiệu sống của trang. */
.tag .cham {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; margin-right: 5px; vertical-align: 1px;
}
.tag.ok .cham { animation: cham-nhay 1.4s ease-in-out infinite; }
@keyframes cham-nhay { 50% { opacity: .25; } }

.msg {
  padding: 11px 14px; border-radius: 8px; margin: 0 0 14px;
  font-size: 13.5px; border: 1px solid transparent;
}
.msg:last-child { margin-bottom: 0; }
.msg.ok   { background: var(--tot-nen);  border-color: var(--tot-vien);  color: var(--tot-chu); }
.msg.warn { background: var(--canh-nen); border-color: var(--canh-vien); color: var(--canh-dam); }
.msg.bad  { background: var(--xau-nen);  border-color: var(--xau-vien);  color: var(--xau-chu); }
.msg.info { background: var(--chinh-nhat); border-color: var(--chinh-nhat); color: var(--chinh-dam); }
.msg ul { margin: 6px 0 0; padding-left: 20px; }
.msg li { margin: 2px 0; }

.bang-cho {
  background: var(--canh-nen); border: 1px solid var(--canh-vien);
  border-left: 3px solid var(--canh);
  color: var(--canh-dam); padding: 12px 15px; border-radius: 8px; margin-bottom: 16px;
  font-size: 13.5px;
}
.bang-cho.bad {
  background: var(--xau-nen); border-color: var(--xau-vien);
  border-left-color: var(--xau); color: var(--xau-chu);
}
.bang-cho ul { margin: 6px 0 0; padding-left: 20px; }

/* ---------------------------------------------------------------- *
   Nút, ô nhập
 * ---------------------------------------------------------------- */

.nut {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--chinh); color: #fff;
  border: 1px solid var(--chinh); border-radius: 7px;
  padding: 8px 16px; font-size: 13.5px; font-weight: 600;
  cursor: pointer; font-family: inherit; line-height: 1.3;
  text-decoration: none; white-space: nowrap;
  transition: background .12s;
}
.nut:hover:not(:disabled) { background: var(--chinh-dam); border-color: var(--chinh-dam); color: #fff; text-decoration: none; }
.nut:disabled { opacity: .5; cursor: not-allowed; }
.nut.ghost { background: var(--the); color: var(--chinh); }
.nut.ghost:hover:not(:disabled) { background: var(--chinh-nhat); color: var(--chinh); }
.nut.bad { background: var(--xau); border-color: var(--xau); }
.nut.bad:hover:not(:disabled) { background: var(--xau-chu); border-color: var(--xau-chu); }
.nut.ok { background: var(--tot); border-color: var(--tot); }
.nut.ok:hover:not(:disabled) { background: var(--tot-chu); border-color: var(--tot-chu); }
.nut.ghost.ok { background: var(--the); color: var(--tot); }
.nut.ghost.ok:hover:not(:disabled) { background: var(--tot-nen); color: var(--tot); }
.nut.ghost.bad { background: var(--the); color: var(--xau); }
.nut.ghost.bad:hover:not(:disabled) { background: var(--xau-nen); color: var(--xau); }
.nut.sm { padding: 5px 11px; font-size: 12.5px; }

.row-btn { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 15px; }

/* Tô theo lối LOẠI TRỪ: mọi ô nhập đều được tô, kể cả ô không khai type. */
input:not([type=checkbox]):not([type=radio]):not([type=file]):not(.form-control),
select:not(.form-select), textarea:not(.form-control) {
  border: 1px solid var(--vien); border-radius: 7px;
  padding: 7px 11px; font-size: 13.5px; font-family: inherit;
  background: var(--the); color: var(--chu); width: 100%;
  min-height: 35px;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--chinh);
  box-shadow: 0 0 0 3px var(--vong-chinh);
}
input:disabled, select:disabled { background: var(--nen-tat); color: var(--chu-3); }
input::placeholder { color: var(--chu-3); }

select:not(.form-select) {
  appearance: none; -webkit-appearance: none;
  padding-right: 30px; cursor: pointer;
  background-image: var(--mui-ten);
  background-repeat: no-repeat; background-position: right 11px center;
}
select.tu-rong { width: auto; }

input[type=checkbox] {
  width: 16px; height: 16px; margin: 0; accent-color: var(--chinh); cursor: pointer;
}

.fld {
  display: block; font-size: 12px; font-weight: 600;
  color: var(--chu-2); margin-bottom: 4px;
}

/* Ô nhập ghép với nút ở bên phải (ghi giá trị xuống PLC). */
.o-ghep { display: flex; gap: 6px; align-items: center; }
.o-ghep input { flex: 1; min-width: 90px; text-align: right; font-variant-numeric: tabular-nums; }
.o-ghep .nut { flex: 0 0 auto; }
.o-ghep .don-vi { flex: 0 0 auto; color: var(--chu-2); font-size: 12.5px; }

/* Thanh lọc / thao tác nằm ngang trên đầu màn hình. */
.qlk-thanh { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.qlk-thanh .phai { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.qlk-thanh .nut { height: 35px; }

/* Thanh lọc trạm → HMI → tag (Lịch sử, Nhật ký lệnh): mỗi ô có nhãn phía trên, nút canh đáy cho thẳng hàng với ô nhập. */
.loc-lich-su { align-items: flex-end; }
.loc-lich-su .o-tram { flex: 0 1 200px; min-width: 150px; }
.loc-lich-su .o-tag { flex: 1 1 260px; min-width: 0; }

/* ---------------------------------------------------------------- *
   Ô ngày (Components/Shared/ONgay.razor)

   Ô chữ dd/mm/yyyy tự vẽ thay cho <input type="date">, thứ hiện theo locale của MÁY
   chứ không theo trang — xem chú thích đầu ONgay.razor. Chép từ SmeKho, đổi .btn → .nut
   và màu → token. 150px vừa "31/12/2026" cộng nút lịch.
 * ---------------------------------------------------------------- */
.o-ngay { position: relative; display: inline-block; width: 150px; max-width: 100%; }
.o-ngay .o-ngay-chu { padding-right: 32px; font-variant-numeric: tabular-nums; }

/* Nút lịch nằm ĐÈ lên ô, thụt 1px để không phủ mất viền — viền mới là thứ đổi màu khi ô
   nhận con trỏ. tabindex=-1: người dùng bàn phím mở lịch bằng mũi tên xuống ngay trong ô. */
.o-ngay-nut {
  position: absolute; right: 1px; top: 1px; bottom: 1px; width: 30px;
  border: 0; padding: 0; border-radius: 0 6px 6px 0;
  background: transparent var(--lich-hinh) no-repeat center;
  cursor: pointer;
}
.o-ngay-nut:hover { background-color: var(--vien-nhat); }
.o-ngay-nut:disabled { cursor: default; opacity: .45; }

/* Lịch đang mở: cả ô ngày nổi lên trên mọi thứ (kể cả .hop-nen 200), và lớp .lich-nen
   trong suốt phủ kín màn hình NẰM DƯỚI ô chữ (z-index âm trong ngữ cảnh xếp lớp của
   .o-ngay) — bấm ra ngoài là đóng lịch, còn bấm vào ô chữ vẫn gõ được. */
.o-ngay.dang-mo { z-index: 300; }
.lich-nen { position: fixed; inset: 0; z-index: -1; }

.lich {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 1;
  width: 258px; padding: 10px;
  background: var(--the); border: 1px solid var(--vien); border-radius: 10px;
  box-shadow: var(--bong-noi);
  font-size: 13px;
}
.lich-dinh { display: flex; align-items: center; gap: 5px; margin-bottom: 8px; }
.lich-dinh select {
  min-height: 28px; padding: 3px 24px 3px 8px; font-size: 12.5px;
  background-position: right 7px center;
}
.lich-dinh .lich-thang { flex: 1 1 auto; }
.lich-dinh .lich-nam { flex: 0 0 74px; width: 74px; }
.lich-mui {
  flex: 0 0 auto; width: 26px; height: 26px; padding: 0;
  border: 1px solid var(--vien); border-radius: 6px; background: var(--the);
  color: var(--chu-2); font-size: 15px; line-height: 1; cursor: pointer;
}
.lich-mui:hover { background: var(--vien-nhat); color: var(--chu); }

.lich-luoi { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.lich-thu {
  padding: 3px 0 5px; text-align: center;
  font-size: 11px; font-weight: 600; color: var(--chu-3);
}
.lich-o {
  height: 30px; padding: 0; border: 0; border-radius: 6px; background: none;
  font-family: inherit; font-size: 12.5px; color: var(--chu);
  font-variant-numeric: tabular-nums; cursor: pointer;
}
.lich-o:hover { background: var(--chinh-nhat); }
.lich-o:focus-visible { outline: 2px solid var(--chinh); outline-offset: -2px; }
/* Ngày của tháng bên cạnh: mờ đi chứ không bỏ trống — bỏ trống thì tuần đầu/cuối trông
   như lỗi hiển thị, mà bấm sang tháng bên cạnh vẫn là thao tác hay dùng. */
.lich-o.mo { color: var(--chu-3); }
.lich-o.nay { box-shadow: inset 0 0 0 1px var(--chinh); font-weight: 600; }
.lich-o.chon { background: var(--chinh); color: var(--chu-dao); font-weight: 600; }
.lich-o.chon:hover { background: var(--chinh-dam); }

.lich-chan { display: flex; gap: 8px; margin-top: 9px; }
.lich-chan .nut { flex: 1; justify-content: center; text-align: center; }

/* Màn hẹp: lịch 258px đặt dưới ô thứ hai của hàng lọc sẽ tràn mép phải và bị .noi-dung
   cắt mất. Đưa ra giữa màn hình như một hộp thoại nhỏ. */
@media (max-width: 560px) {
  .lich { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); }
}

.grid { display: grid; gap: 16px; }
.grid.g2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.qlk-nap { padding: 40px; text-align: center; color: var(--chu-3); font-size: 14px; }

.hop-muc { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--chu); }
.hop-muc:not(:first-child) { margin-top: 22px; }

code {
  background: var(--vien-nhat); padding: 1px 5px; border-radius: 4px;
  font-size: 12px; font-family: Consolas, "Cascadia Mono", monospace; color: inherit;
}
pre { font-size: 12px; font-family: Consolas, "Cascadia Mono", monospace; }

/* ---------------------------------------------------------------- *
   Biểu đồ (Components/Shared/LineChart.razor)
   Toàn bộ tương tác là CSS :hover trên vùng bắt chuột của từng điểm.
 * ---------------------------------------------------------------- */

.bieu-do { overflow-x: auto; }
.bieu-do svg {
  display: block; width: 100%; min-width: 600px; max-width: 1100px; height: auto;
  font: 12px "Segoe UI", system-ui, sans-serif;
}
.bieu-do .luoi { stroke: var(--vien-nhat); stroke-width: 1; vector-effect: non-scaling-stroke; }
.bieu-do .truc { fill: var(--chu-2); font-variant-numeric: tabular-nums; }
.bieu-do .duong {
  fill: none; stroke: var(--chinh); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.bieu-do .loi { fill: var(--xau-nen); }

.bieu-do .diem .vung { fill: transparent; }
.bieu-do .diem .doc, .bieu-do .diem circle, .bieu-do .diem .chu-thich { display: none; }
.bieu-do .diem:hover .doc, .bieu-do .diem:hover circle, .bieu-do .diem:hover .chu-thich { display: block; }
.bieu-do .diem .doc { stroke: var(--chu-3); stroke-width: 1; vector-effect: non-scaling-stroke; }
.bieu-do .diem circle { fill: var(--chinh); stroke: var(--the); stroke-width: 2; }
.bieu-do .diem.loi circle { fill: var(--xau); }
.bieu-do .chu-thich rect { fill: var(--chu); }
.bieu-do .chu-thich text { fill: var(--the); font-variant-numeric: tabular-nums; }
.bieu-do .chu-thich .gia-tri { font-weight: 600; }

/* ---------------------------------------------------------------- *
   Sơ đồ HMI (Components/Shared/DiagramView.razor, Pages/DiagramAdmin.razor)

   Ảnh màn HMI do admin tải lên, trên đó là dấu tag .moc đặt theo phần trăm ảnh
   nên đúng chỗ ở mọi cỡ màn. Ảnh không phóng quá cỡ gốc (--rong-anh, đặt inline)
   để chữ trong sơ đồ không nhoè. .moc chỉ định vị, góc trên trái của dấu là điểm admin đã bấm
   (dấu to nhỏ khác nhau, canh theo góc dễ đặt hơn canh theo tâm).
   Số đo, cài đặt, công tắc, chạy/dừng là chính khối của lưới Thông số (.stat, .ds-cai-dat,
   .ds-cong-tac, .hang-nut — Components/GiamSat/DauSoDo.razor), ở đây chỉ thu gọn cho vừa
   ảnh nền; sửa mẫu gốc là sơ đồ đổi theo. Đèn .moc-den và cảnh báo .moc-canh-bao là dấu
   nhỏ không chữ. Mọi dấu có nền đặc và bóng để nổi trên mọi ảnh.
 * ---------------------------------------------------------------- */

/* Hàng chọn chế độ xem: Thông số | Trang chủ | Fan | … */
.so-do-tab {
  display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 10px;
  border-bottom: 1px solid var(--vien);
}
.so-do-tab a {
  padding: 7px 14px; margin-bottom: -1px;
  border: 1px solid transparent; border-radius: 7px 7px 0 0;
  color: var(--chu-2); font-weight: 600; font-size: 13.5px;
}
.so-do-tab a:hover { color: var(--chu); background: var(--vien-nhat); text-decoration: none; }
.so-do-tab a[aria-current="page"] {
  background: var(--the); color: var(--chinh);
  border-color: var(--vien); border-bottom-color: var(--the);
}

.so-do { background: var(--nen); }
.so-do-khung { position: relative; width: 100%; max-width: var(--rong-anh); }
.so-do-khung img { display: block; width: 100%; height: auto; }

.moc {
  position: absolute; z-index: 1;
  display: inline-flex; line-height: 1.2; white-space: nowrap;
}
.moc:hover, .moc:focus-within { z-index: 2; }
.moc a:hover { text-decoration: none; }
.moc a:focus-visible, .moc button:focus-visible { outline: 2px solid var(--chinh); outline-offset: 2px; }

/* Tag không còn: ô "?" nét đứt. */
.moc-so {
  display: inline-flex; align-items: center; padding: 3px 8px; border-radius: 6px;
  background: var(--the); border: 2px dashed var(--den-vien); box-shadow: var(--do-bong);
  color: var(--chu-3); font-size: 13px; font-weight: 700;
}

/* Khối lưới Thông số trên ảnh: một tag mỗi khối, bỏ lưới bao, thu nhỏ chữ và đệm.
   Chỉ giữ dòng phụ khi báo lỗi; dải cho phép và chữ "Hiện tại" bỏ đi cho gọn. */
.moc .nhom-luoi, .moc .ds-cai-dat, .moc .ds-cong-tac { display: block; }
.moc .stat, .moc .ds-cai-dat li, .moc .ds-cong-tac li {
  border-color: var(--vien); border-radius: 7px; box-shadow: var(--do-bong);
}
.moc .stat { padding: 4px 9px; }
.moc .qlk-nhan { max-width: 150px; font-size: 9.5px; letter-spacing: .3px; }
.moc .qlk-so-lon { margin-top: 1px; font-size: 16px; letter-spacing: 0; }
.moc .stat.lon .qlk-so-lon { margin-top: 1px; font-size: 24px; letter-spacing: -.5px; }
.moc .stat .hint { display: none; }
.moc .stat .hint.xau { display: block; margin: 1px 0 0; font-size: 10.5px; }

.moc .ds-cai-dat li { gap: 4px; padding: 5px 8px; }
.moc .ds-cai-dat .dong-dau { align-items: center; gap: 10px; }
.moc .ds-cai-dat .ten { font-size: 11.5px; }
.moc .ds-cai-dat .ten .hint, .moc .ds-cai-dat .hien-tai .hint { display: none; }
.moc .ds-cai-dat .hien-tai strong { font-size: 14px; }
.moc .ds-cai-dat .hint.xau { max-width: 230px; font-size: 10.5px; white-space: normal; }
.moc .o-ghep { gap: 4px; }
/* Bộ chọn dài vì quy tắc chung của <input> có bốn :not() (độ ưu tiên 0,4,1). */
.so-do-khung .moc .o-ghep input[type=number][inputmode] {
  flex: 0 0 76px; width: 76px; min-width: 0; min-height: 26px; padding: 2px 6px; font-size: 12.5px;
}
.moc .o-ghep .don-vi { font-size: 11px; }
.moc .o-ghep .nut.sm { padding: 3px 9px; font-size: 12px; }

.moc .ds-cong-tac li { gap: 8px; min-height: 0; padding: 4px 8px; }
.moc .ds-cong-tac .ten { flex: 0 1 auto; max-width: 130px; font-size: 11.5px; }
.moc .ds-cong-tac .cong-tac-chu { min-width: 2.6em; font-size: 11.5px; }
.moc .cong-tac { width: 38px; height: 20px; border-radius: 10px; }
.moc .cong-tac .nu { top: 1px; left: 1px; width: 16px; height: 16px; }
.moc .cong-tac.bat .nu { left: 19px; }

.moc .hang-nut { flex-direction: column; align-items: center; gap: 3px; }
.moc .hang-nut .nut.lon { flex: none; min-width: 0; padding: 5px 12px; font-size: 12.5px; box-shadow: var(--do-bong); }
.moc .hang-nut .hint {
  max-width: 220px; padding: 2px 5px; border-radius: 4px;
  background: var(--the); font-size: 10.5px; white-space: normal;
}

/* Đèn: chấm tròn như đèn trên HMI, chỉ màu (xám dừng, xanh chạy, vàng chuyển tiếp, đỏ lỗi) —
   kể cả đèn nhiều trạng thái. Chữ trạng thái nằm ở tooltip/aria-label và dòng trong bảng dưới ảnh.
   Không có chữ đi kèm nên vàng/đỏ tô đặc, không dùng nền nhạt như .den của lưới. */
.moc-den {
  display: inline-flex; align-items: center;
  padding: 3px; border-radius: 999px;
  background: var(--the); border: 1px solid var(--vien); box-shadow: var(--do-bong);
}
.moc-den .cham {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  background: var(--den-tat); border: 2px solid var(--den-vien);
}
.moc-den.bat .cham  { background: var(--den-bat); border-color: var(--tot); }
.moc-den.canh .cham { background: var(--canh); border-color: var(--canh); }
.moc-den.bad .cham  { background: var(--xau); border-color: var(--xau); }
.moc-den.mo .cham   { background: var(--the); border-style: dashed; }

/* Cảnh báo: tam giác mờ khi yên, nền đỏ khi bit đang bật. */
.moc-canh-bao {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--the); border: 2px solid var(--den-vien); box-shadow: var(--do-bong);
  color: var(--chu-3); font-size: 13px;
}
.moc-canh-bao.bad  { background: var(--xau); border-color: var(--xau); color: var(--chu-dao); }
.moc-canh-bao.canh { border-color: var(--canh); color: var(--canh); }

/* Khung soạn: ảnh đúng pixel gốc để toạ độ chuột là toạ độ ảnh; dấu không nhận chuột.
   Số thứ tự ở góc dấu khớp danh sách bên phải; dấu đang chọn có vòng màu chính. */
.so-do-soan { width: var(--rong-anh); max-width: none; cursor: crosshair; }
.so-do-soan .moc { pointer-events: none; }
.moc > .so {
  position: absolute; top: -10px; left: -10px; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px;
  background: var(--chu-2); color: var(--the); font-size: 10.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.moc.chon { z-index: 3; border-radius: 8px; outline: 2px solid var(--chinh); outline-offset: 3px; box-shadow: 0 0 0 7px var(--vong-chinh); }
.moc.chon > .so { background: var(--chinh); color: var(--chu-dao); }

.so-do-soan-thanh { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-end; margin-bottom: 14px; }
.so-do-soan-thanh .o-ghep { flex: 0 1 360px; }
.so-do-soan-thanh .o-ghep input { text-align: left; }
.so-do-soan-luoi { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; align-items: start; }
.so-do-cot { min-width: 0; }
.so-do-dang-chon {
  padding: 10px 12px; margin-bottom: 10px;
  background: var(--chinh-nhat); border-radius: 8px;
}
.so-do-xy { display: flex; gap: 10px; margin-top: 8px; }
.so-do-xy .fld { flex: 1; margin: 0; }
.so-do-ds { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; }
.so-do-muc {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 8px; border: 1px solid transparent; border-radius: 7px;
  background: none; color: var(--chu); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.so-do-muc:hover { background: var(--vien-nhat); }
.so-do-muc.chon { background: var(--chinh-nhat); border-color: var(--chinh); }
.so-do-muc .ten { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.so-do-them { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.so-do-them > div { flex: 1 1 240px; }
/* Chọn tệp: ô <input type=file> gốc (chữ "Choose file" theo ngôn ngữ trình duyệt) ẩn đi
   nhưng vẫn nhận Tab; <label for> mang dáng .nut mở hộp chọn tệp, không cần JS. */
.chon-tep { display: flex; align-items: center; gap: 10px; min-width: 0; }
.chon-tep input[type=file] {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.chon-tep input[type=file]:focus-visible + .nut { outline: 2px solid var(--chinh); outline-offset: 2px; }
.chon-tep input[type=file]:disabled + .nut { opacity: .5; cursor: not-allowed; pointer-events: none; }
.chon-tep .ten { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--chu-2); font-size: 12.5px; }
/* Dòng đang chọn: màn đang soạn, hoặc tín hiệu vừa nhảy tới từ dấu trên ảnh. */
tr.dong-chon, .dt tbody tr.dong-chon:hover { background: var(--chinh-nhat); }

@media (max-width: 900px) {
  .so-do-soan-luoi { grid-template-columns: minmax(0, 1fr); }
}

/* Màn hẹp: ảnh giữ bề rộng tối thiểu đủ đọc và cuộn ngang trong khung (trang thì không). */
@media (max-width: 700px) {
  .so-do-khung { min-width: min(720px, var(--rong-anh)); }
}

/* ---------------------------------------------------------------- *
   Hộp thoại
 * ---------------------------------------------------------------- */

.hop-nen {
  position: fixed; inset: 0; z-index: 200;
  background: var(--man-che);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px 20px; overflow-y: auto;
}
.hop {
  background: var(--the); border-radius: 12px; width: 100%; max-width: 520px;
  box-shadow: var(--bong-hop);
  display: flex; flex-direction: column; max-height: calc(100vh - 80px);
  animation: hop-hien .14s ease-out;
  overscroll-behavior: contain;
}
.hop.rong { max-width: 1080px; }
@keyframes hop-hien { from { opacity: 0; transform: translateY(-8px); } }
.hop:focus { outline: none; } /* focus đặt vào hộp chỉ để bắt phím Escape, không cần vòng viền */

.hop-dinh {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px; border-bottom: 1px solid var(--vien);
  flex: 0 0 auto;
}
.hop-dinh h2 { margin: 0; font-size: 15px; font-weight: 600; flex: 1; min-width: 0; }
.hop-dong {
  background: none; border: 0; font-size: 26px; line-height: 1;
  color: var(--chu-2); cursor: pointer; padding: 0 4px; border-radius: 6px;
}
.hop-dong:hover { background: var(--vien-nhat); color: var(--chu); }

.hop-than { padding: 20px; overflow-y: auto; flex: 1 1 auto; }
.hop-than > .the:last-child, .hop-than > .msg:last-child { margin-bottom: 0; }
.hop-than p { margin: 0 0 10px; }
.hop-than p:last-child { margin-bottom: 0; }
.hop-chan {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 12px 20px; border-top: 1px solid var(--vien); flex: 0 0 auto;
}

@media (max-width: 900px) {
  .hop-nen { padding: 0; }
  .hop { max-width: none; border-radius: 0; max-height: 100vh; height: 100vh; }
  .hop.rong { max-width: none; }
}

/* ---------------------------------------------------------------- *
   Đăng nhập
 * ---------------------------------------------------------------- */

.man-dang-nhap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #16233c 0%, #1e4b8f 100%);
  padding: 20px;
}
.hop-dang-nhap { width: 100%; max-width: 380px; }
.hop-dang-nhap .the { margin-bottom: 0; }
.hop-dang-nhap .dinh { text-align: center; margin-bottom: 22px; color: #fff; }
.hop-dang-nhap .dinh .dau-hieu {
  width: 52px; height: 52px; border-radius: 13px; margin: 0 auto 12px;
  background: rgba(255, 255, 255, .13); border: 1px solid rgba(255, 255, 255, .2);
  display: flex; align-items: center; justify-content: center;
  font-size: 21px; font-weight: 700;
}
.hop-dang-nhap .dinh h1 { margin: 0; font-size: 21px; font-weight: 600; }
.hop-dang-nhap .dinh p  { margin: 5px 0 0; font-size: 13px; opacity: .75; }
.hop-dang-nhap .nut { width: 100%; }
.hop-dang-nhap .row-btn { margin-top: 18px; }
.hop-dang-nhap .row-btn + .row-btn { margin-top: 8px; }
.hop-dang-nhap .validation-message { display: block; margin: 4px 0 0; color: var(--xau); }
.hop-dang-nhap .validation-message:empty { display: none; }
.dang-nhap-lien-ket {
  display: flex; flex-direction: column; gap: 6px; align-items: center;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--vien-nhat);
  font-size: 13px;
}

/* ---------------------------------------------------------------- *
   Tài khoản (Components/Account/Shared/ManageLayout.razor)
   Menu mục bên trái + nội dung; màn hẹp thì menu thành hàng trên.
 * ---------------------------------------------------------------- */

.tk-khung {
  display: grid; grid-template-columns: 200px minmax(0, 1fr);
  gap: 16px; align-items: start;
}
.tk-menu { display: flex; flex-direction: column; gap: 2px; }
.tk-menu a {
  padding: 8px 12px; border-radius: 7px;
  color: var(--chu-2); font-weight: 600; font-size: 13.5px;
}
.tk-menu a:hover { color: var(--chu); background: var(--vien-nhat); text-decoration: none; }
.tk-menu a.active { color: var(--chinh-dam); background: var(--chinh-nhat); }
.tk-form { max-width: 420px; }
.tk-noi-dung .validation-message { display: block; margin: 4px 0 0; font-size: 12.5px; }
.tk-noi-dung .validation-message:empty { display: none; }
.tk-noi-dung td form { display: inline-flex; gap: 6px; }
.tk-buoc { margin: 0; padding-left: 20px; font-size: 13.5px; }
.tk-buoc > li { margin-bottom: 18px; }
.tk-buoc > li:last-child { margin-bottom: 0; }
.tk-buoc .khoi-chep { margin-top: 8px; max-width: 420px; }
@media (max-width: 700px) {
  .tk-khung { grid-template-columns: 1fr; }
  .tk-menu { flex-direction: row; flex-wrap: wrap; }
}

/* Ô tích kèm câu giải thích — dùng cho các lựa chọn cần nói rõ hệ quả. */
.chk { display: flex; align-items: flex-start; gap: 8px; font-size: 13px;
  color: var(--chu-2); cursor: pointer; }
.chk input { margin-top: 3px; width: 15px; height: 15px; flex: none; }

/* Ô mật khẩu kèm nút con mắt (NutHienMatKhau) nằm bên phải trong ô.
   Bộ chọn dài để thắng quy tắc tô ô nhập chung ở trên (padding-right). */
.o-mat-khau { position: relative; display: block; }
.o-mat-khau input:not([type=checkbox]):not([type=radio]):not([type=file]):not(.form-control) { padding-right: 40px; }
.hien-mk {
  position: absolute; right: 3px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 29px; padding: 0; border: 0; border-radius: 6px;
  background: transparent; color: var(--chu-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.hien-mk:hover { color: var(--chu); background: var(--nen); }
.hien-mk svg { width: 18px; height: 18px; }
.hien-mk .mat-dong, .hien-mk[aria-pressed="true"] .mat-mo { display: none; }
.hien-mk[aria-pressed="true"] .mat-dong { display: block; }

/* Khối chữ đơn cách + nút chép ở góc phải (Components/Shared/KhoiChep.razor): token, header,
   URL cần dán sang máy khác. Chữ chừa lề phải để không chui dưới nút. */
.khoi-chep {
  position: relative; margin: 0 0 12px;
  background: var(--vien-nhat); border-radius: 6px;
}
.khoi-chep:last-child { margin-bottom: 0; }
.khoi-chep pre {
  margin: 0; padding: 12px 48px 12px 12px;
  white-space: pre-wrap; word-break: break-all;
}
.nut-chep {
  position: absolute; top: 6px; right: 6px;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid var(--vien); border-radius: 6px;
  background: var(--the); color: var(--chu-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.nut-chep:hover { color: var(--chu); border-color: var(--chu-3); }
.nut-chep svg { width: 16px; height: 16px; }
.nut-chep .bieu-da-chep, .nut-chep[data-ket-qua="da-chep"] .bieu-chep { display: none; }
.nut-chep[data-ket-qua="da-chep"] .bieu-da-chep { display: block; }
.nut-chep[data-ket-qua="da-chep"] { color: var(--tot); border-color: var(--tot); }
.nut-chep[data-ket-qua="loi"] { color: var(--xau); border-color: var(--xau); }

/* Danh sách ô tích có thể dài (chọn trạm cho tài khoản): cuộn trong khung thay vì kéo dài hộp thoại. */
.ds-chon {
  max-height: 220px; overflow-y: auto;
  border: 1px solid var(--vien); border-radius: var(--bo-goc);
  padding: 8px 12px; display: flex; flex-direction: column; gap: 6px;
}

/* Lưới quyền theo chức năng (hộp Sửa tài khoản): cột Xem / Sửa hẹp, ô tích canh giữa;
   dòng nhóm đậm có ô tích bật cả nhóm; chức năng thụt vào dưới nhóm. */
.bang-quyen {
  margin-top: 8px;
  border: 1px solid var(--vien); border-radius: var(--bo-goc);
}
.bang-quyen .o-quyen { width: 64px; text-align: center; }
.bang-quyen input[type=checkbox] { vertical-align: middle; }
.bang-quyen tr.nhom-quyen td { background: var(--nen-dau-bang); font-weight: 700; }
.bang-quyen td.thut { padding-left: 28px; }
.bang-quyen td.thut .hint { display: block; margin: 2px 0 0; }

/* ---------------------------------------------------------------- *
   Màn hình hẹp: cột trái trượt ra ngoài, chỉ hiện khi bấm nút ☰.
   Đóng mở bằng ô đánh dấu ẩn (#nutMenuBat) nên không cần JavaScript.
 * ---------------------------------------------------------------- */

@media (max-width: 900px) {
  .canh-trai {
    position: fixed; left: 0; top: 0; z-index: 100;
    height: 100vh; height: 100dvh;
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, .3);
  }
  .nut-menu-bat:checked ~ .canh-trai { transform: translateX(0); }
  .nut-menu-bat:checked ~ .man-che {
    display: block; position: fixed; inset: 0;
    background: rgba(10, 18, 32, .5); z-index: 99;
  }
  .nut-menu { display: block; }
  .noi-dung { padding: 10px; }
  .thanh-tren { padding: 0 15px; }
  .nguoi-dung .vai, .nguoi-dung .ten { display: none; }
  .nut.sm { min-height: 32px; }
}

/* Người dùng tắt hiệu ứng chuyển động ở hệ điều hành: bỏ mọi animation/transition. */
@media (prefers-reduced-motion: reduce) {
  .tag.ok .cham { animation: none; }
  .hop { animation: none; }
  .canh-trai, .den .cham, .cong-tac, .cong-tac .nu, .nut { transition: none; }
}

@media (max-width: 560px) {
  .stats { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .stat { padding: 12px 13px; }
  .qlk-so-lon { font-size: 21px; }
  .stat.co-bieu-tuong { gap: 10px; }
  .o-bieu-tuong { flex-basis: 32px; height: 32px; }
  .o-bieu-tuong svg { width: 18px; height: 18px; }
  .row-btn .nut { flex: 1; }
  .thanh-tren h1 { font-size: 15px; }
  /* Ô chọn trạm / HMI trên thanh lọc chiếm trọn một hàng; ô tìm + nút vẫn chung hàng. */
  .qlk-thanh > select.tu-rong,
  .qlk-thanh > div:has(> select),
  .loc-lich-su .o-tram { flex: 1 1 100%; width: 100%; min-width: 0; }
}

@media print {
  .canh-trai, .thanh-tren, .row-btn, .qlk-thanh { display: none !important; }
  .khung { height: auto; overflow: visible; }
  .noi-dung { padding: 0; overflow: visible; }
  .the, .stat { box-shadow: none; border-color: #ccc; break-inside: avoid; }
  body { background: #fff; }
}

/* ---------------------------------------------------------------- *
   Phần riêng của Blazor
 * ---------------------------------------------------------------- */

#blazor-error-ui {
  background: var(--canh-nen);
  color: var(--canh-dam);
  border-top: 1px solid var(--canh-vien);
  bottom: 0;
  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
  display: none;
  left: 0;
  padding: 0.6rem 1.25rem 0.7rem 1.25rem;
  position: fixed;
  width: 100%;
  z-index: 1000;
}
#blazor-error-ui .dismiss {
  cursor: pointer;
  position: absolute;
  right: 0.75rem;
  top: 0.5rem;
}

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--tot); }
.invalid { outline: 1px solid var(--xau); }
.validation-message { color: var(--xau); }

.blazor-error-boundary {
  background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
  padding: 1rem 1rem 1rem 3.7rem;
  color: white;
}
.blazor-error-boundary::after { content: "Đã xảy ra lỗi." }

.darker-border-checkbox.form-check-input { border-color: #929292; }

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}
