/* ==========================================================================
   VNS Dashboard — hệ thiết kế dùng chung cho /tv và /
   Mọi kích thước tính theo `vw` để tự co giãn từ 1080p lên 4K mà không cần
   media query. Trên TV 85" ở 1920x1080, 1vw = 19,2px.
   ========================================================================== */

:root {
  /* Nền đen thuần: trên TV 85" nền càng tối thì con số càng nổi, và tấm nền
     OLED/LED không bị hắt sáng xanh vào phòng điều hành. */
  --nen:            #000000;
  --nen-the:        #0a0a0c;
  --nen-the-2:      #0e0e11;
  --vien:           #1f2430;
  --chu:            #ffffff;
  --chu-mo:         #8b93a5;
  --chu-rat-mo:     #5a6172;

  --xanh:           #38bdf8;
  --xanh-dam:       #0ea5e9;
  --luc:            #22d97f;
  --luc-dam:        #16a34a;
  --vang:           #fbbf24;
  --cam:            #fb923c;
  --do:             #f43f5e;
  --tim:            #a78bfa;
  --hong:           #f472b6;

  --bk: 0.6vw;   /* bo góc  */
  --gap: 0.75vw; /* khoảng cách lưới */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: var(--nen);
  color: var(--chu);
  font-family: "Inter", "Segoe UI", "Roboto", system-ui, -apple-system, sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

body.tv {
  overflow: hidden;               /* TV không bao giờ được có thanh cuộn */
  user-select: none;
  /* KHÔNG đặt `cursor: none`: người vận hành vẫn cần trỏ chuột để thao tác
     trên máy NUC (mở menu, chuyển tab, thoát kiosk). */
}

/* Ánh sáng nền nhẹ cho đỡ phẳng, vẫn giữ nền tối để TV không chói */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(60vw 40vw at 12% -8%,  rgba(56,189,248,.035), transparent 60%),
    radial-gradient(50vw 36vw at 88% 108%, rgba(167,139,250,.03), transparent 60%);
}

/* ------------------------------------------------------------------ khối ---- */

.the {
  position: relative; z-index: 1;
  background: var(--nen-the);
  border: 1px solid var(--vien);
  border-radius: var(--bk);
  padding: 0.85vw 1.05vw;
  display: flex; flex-direction: column;
  min-height: 0; min-width: 0;
  overflow: hidden;
}

/* Dải màu mảnh bên trái thẻ KPI — mã màu cho biết đang xem chỉ số nhóm nào,
   nhìn lướt từ xa vẫn phân biệt được mà không phải đọc nhãn. */
.the.kpi::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 0.2vw; background: var(--vach, transparent);
}
.the.kpi { padding-left: 1.15vw; }

.the-tieu-de {
  display: flex; align-items: center; gap: 0.5vw;
  font-size: 0.82vw; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--chu-mo);
  margin-bottom: 0.5vw; flex: 0 0 auto;
}
.the-tieu-de .chip {
  margin-left: auto; font-size: 0.72vw; letter-spacing: 0;
  text-transform: none; color: var(--chu-rat-mo);
  background: rgba(255,255,255,.05); border: 1px solid var(--vien);
  border-radius: 999px; padding: 0.1vw 0.5vw;
}

/* ------------------------------------------------------------------ KPI ----- */

.kpi { justify-content: space-between; }

/* Con số là thứ phải đọc được từ 5–10 m — cho nó chiếm hết chiều cao còn lại
   của thẻ và căn đáy, để mọi KPI trên cùng hàng thẳng chân số với nhau dù
   nhãn dài ngắn khác nhau. */
.kpi-so {
  font-size: 2.75vw; font-weight: 800; line-height: 1.0;
  letter-spacing: -0.035em;
  font-feature-settings: "tnum";
  color: #fff;
}
.kpi-so.nho { font-size: 2.4vw; }
/* Số nguyên đầy đủ (405.699.166) dài hơn bản rút gọn nhiều. Không chia bậc theo
   số ký tự ở đây — `vuaKhung()` trong tv.js ĐO bề rộng thật rồi co lại, vì bậc
   cố định luôn sai ở một độ phân giải nào đó. */
.kpi-donvi {
  font-size: 1.1vw; font-weight: 700; color: var(--chu-rat-mo);
  margin-left: 0.25vw;
}

/* Dòng số + đơn vị: đẩy xuống đáy để chân số thẳng hàng ngang toàn dải KPI */
.kpi > .kpi-hang {
  display: flex; align-items: baseline;
  margin-top: auto; min-width: 0;
  white-space: nowrap;
}
/* Lưới an toàn: dù cỡ chữ có tính sai thì cũng co lại chứ không đẩy tràn thẻ */
.kpi > .kpi-hang > .kpi-so { min-width: 0; overflow: hidden; text-overflow: clip; }
.kpi > .kpi-hang > .kpi-donvi { flex: 0 0 auto; }

/* Nhãn KPI luôn 1 dòng — xuống 2 dòng thì chân số các thẻ lệch nhau */
.kpi > .the-tieu-de {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;
}

.kpi-phu {
  display: flex; align-items: baseline; gap: 0.55vw;
  margin-top: 0.4vw; font-size: 0.86vw; color: var(--chu-mo);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Dòng so sánh cùng kỳ hôm qua — màu do tv.js gán theo tăng/giảm */
.kpi-ss {
  margin-top: 0.15vw; font-size: 0.78vw; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kpi-phu b { color: var(--chu); font-weight: 700; }

/* ---- Lớp màu THEO NGỮ NGHĨA (ưu tiên dùng nhóm này) --------------------
   Quy tắc thống nhất toàn dashboard, đừng chọn màu theo cảm tính:
     thông tin   -> trắng      nghiêm trọng -> tím
     tăng        -> xanh lá    trung tính   -> xanh lam
     giảm        -> đỏ
   Nhìn lướt từ 5-10 m, người trực phải đoán được ý nghĩa chỉ qua màu. */
.mau-thong-tin   { color: var(--chu); }
.mau-tang        { color: var(--luc); }
.mau-giam        { color: var(--do); }
.mau-nghiem-trong{ color: var(--tim); }
.mau-trung-tinh  { color: var(--xanh); }

/* ---- Lớp màu theo TÊN MÀU (giữ cho code cũ, tránh dùng cho cái mới) ---- */
.mau-xanh { color: var(--xanh); }
.mau-luc  { color: var(--luc); }
.mau-vang { color: var(--vang); }
.mau-cam  { color: var(--cam); }
.mau-do   { color: var(--do); }
.mau-tim  { color: var(--tim); }
.mau-hong { color: var(--hong); }
.mau-mo   { color: var(--chu-mo); }

/* thanh tiến trình mảnh dưới KPI */
.thanh { height: 0.35vw; border-radius: 999px; background: rgba(255,255,255,.07); overflow: hidden; margin-top: 0.5vw; }
.thanh > i { display: block; height: 100%; border-radius: 999px; transition: width .6s ease; }

/* ------------------------------------------------------------------ bảng ---- */

.bang { width: 100%; border-collapse: collapse; font-size: 1.02vw; }
.bang th {
  text-align: left; font-size: 0.72vw; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--chu-rat-mo);
  padding: 0 0.4vw 0.4vw; border-bottom: 1px solid var(--vien);
}
.bang td { padding: 0.4vw 0.4vw; border-bottom: 1px solid rgba(255,255,255,.05); }
.bang tr:last-child td { border-bottom: none; }
/* Cột số đậm hơn cột chữ — mắt bắt được con số trước khi đọc nhãn */
.bang .p { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.bang tbody td:first-child { font-weight: 600; color: var(--chu); }
.bang .nhan {
  display: inline-block; font-size: 0.68vw; font-weight: 700; letter-spacing: .04em;
  padding: 0.08vw 0.4vw; border-radius: 0.25vw;
  background: rgba(255,255,255,.07); color: var(--chu-mo);
}
.bang .nhan.ung  { background: rgba(56,189,248,.15);  color: var(--xanh); }
.bang .nhan.hoan { background: rgba(167,139,250,.15); color: var(--tim); }
.bang .nhan.loi  { background: rgba(244,63,94,.15);   color: var(--do); }

.cuon { flex: 1 1 auto; min-height: 0; overflow: hidden; }

/* ------------------------------------------------------------------ chart --- */

.boc-chart { flex: 1 1 auto; min-height: 0; position: relative; }
.boc-chart canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
/* Thông báo chồng lên biểu đồ khi chưa đủ dữ liệu — biểu đồ trống trơn khiến
   người xem tưởng hỏng, nói rõ lý do thì không. */
.boc-chart .chua-du {
  position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; text-align: center;
  padding: 0 2vw; font-size: 0.95vw; color: var(--chu-rat-mo);
  background: rgba(10,10,12,.72); border-radius: var(--bk);
}

/* ------------------------------------------------------------------ trạng thái */

.den { width: 0.65vw; height: 0.65vw; border-radius: 50%; background: var(--chu-rat-mo); flex: 0 0 auto; }
.den.song { background: var(--luc); box-shadow: 0 0 0 0 rgba(34,217,127,.7); animation: dap 2s infinite; }
.den.cu   { background: var(--vang); }
.den.chet { background: var(--do); animation: nhay 1s steps(2) infinite; }

@keyframes dap {
  70%  { box-shadow: 0 0 0 0.6vw rgba(34,217,127,0); }
  100% { box-shadow: 0 0 0 0    rgba(34,217,127,0); }
}
@keyframes nhay { 50% { opacity: .25; } }

/* hiệu ứng số nhảy khi có dữ liệu mới */
.nhap { animation: sang .8s ease; }
@keyframes sang {
  0%   { color: var(--luc); text-shadow: 0 0 1.4vw rgba(34,217,127,.6); }
  100% { color: inherit;    text-shadow: none; }
}

/* ------------------------------------------------------------------ ticker -- */

.chay {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 0.8vw;
  background: var(--nen-the); border: 1px solid var(--vien);
  border-radius: var(--bk); overflow: hidden; padding-left: 0.9vw;
}
.chay-nhan {
  flex: 0 0 auto; font-size: 0.78vw; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--do);
  display: flex; align-items: center; gap: 0.4vw;
}
.chay-khung { flex: 1 1 auto; overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 2%, #000 96%, transparent); }
.chay-noi-dung {
  display: inline-flex; gap: 2.2vw; white-space: nowrap;
  font-size: 0.88vw; color: var(--chu-mo);
  animation: truot 60s linear infinite;
}
.chay-noi-dung span b { color: var(--chu); font-weight: 600; }
.chay-noi-dung span i { color: var(--do); font-style: normal; font-weight: 700; }
@keyframes truot { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ------------------------------------------------------------------ báo lỗi -- */

#loi-ket-noi {
  position: fixed; z-index: 50; inset: auto 0 0 0;
  background: var(--do); color: #fff;
  font-size: 1vw; font-weight: 700; text-align: center;
  padding: 0.6vw; transform: translateY(101%); transition: transform .4s ease;
}
#loi-ket-noi.hien { transform: translateY(0); }

/* Cảnh báo dữ liệu cũ — ĐẨY nội dung xuống chứ không đè lên header, vì header
   chứa đồng hồ và đèn trạng thái, che mất đúng lúc đang có sự cố là phản tác
   dụng. Màu vàng: chưa mất kết nối, nhưng số liệu đã đứng yên quá lâu. */
#canh-bao-cu {
  display: none;
  background: var(--vang); color: #1a1200;
  font-size: 1vw; font-weight: 800; text-align: center;
  padding: 0.5vw; flex: 0 0 auto;
}
#canh-bao-cu.hien { display: block; }
/* Khi có cảnh báo, lưới co lại đúng phần banner chiếm.
   Dùng flex thay vì calc() ước lượng: chiều cao banner đổi theo cỡ chữ và
   số dòng, trừ bằng hằng số sẽ sai và làm nội dung tràn/thừa. */
body.tv { display: flex; flex-direction: column; }
body.tv > .man { flex: 1 1 auto; height: auto; min-height: 0; }
