/* ============================================================
   KHUNG MÀN HÌNH QUẢN LÝ — sidebar + header + nội dung
   Dịch từ sample/Mockups/02·03·04·05·06·07·08.
   ============================================================ */

.app { display: flex; min-height: 100vh; }

/* ── Thanh bên ────────────────────────────────────────────────────────────── */
.side {
  width: var(--sidebar-w); flex: none; background: var(--sidebar); color: #fff;
  display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh;
}
.side-brand { padding: var(--sp-16) var(--sp-18) 15px; border-bottom: 1px solid rgba(255,255,255,.1); }
.side-brand b { font-size: 18px; font-weight: 800; letter-spacing: -.02em; display: block; }
.side-brand i { font-style: normal; font-size: 10px; font-weight: 700; letter-spacing: .24em; color: #8791A3; }

.nav { padding: var(--sp-10); flex: 1; overflow-y: auto; }
.nav-lb { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #5D6879; padding: var(--sp-12) var(--sp-10) var(--sp-6); }
.nav a {
  display: flex; align-items: center; gap: var(--sp-10);
  padding: 8px var(--sp-10); border-radius: var(--r-sm);
  color: #B9C2D0; font-size: 13px; font-weight: 500; text-decoration: none;
}
.nav a:hover { background: rgba(255,255,255,.06); color: #fff; }
.nav a.on { background: var(--bni-red); color: #fff; font-weight: 600; }
.nav a:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

.side-foot { padding: var(--sp-12) var(--sp-16); border-top: 1px solid rgba(255,255,255,.1); font-size: var(--fs-sm); color: #8791A3; }
.side-foot b { display: block; color: #DDE3EC; font-size: var(--fs-body); font-weight: 600; }
.side-foot button { margin-top: var(--sp-6); color: #8791A3; }
.side-foot button:hover { color: #DDE3EC; }

/* ── Vùng chính ───────────────────────────────────────────────────────────── */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; background: var(--surface); }

.head { background: var(--card); border-bottom: 1px solid var(--line); padding: 15px var(--sp-24); }
.head-flush { padding-bottom: 0; }
.head-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-20); flex-wrap: wrap; }
.head-sub { margin: var(--sp-3) 0 0; font-size: 12px; color: var(--muted); }
.head-act { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.body { padding: var(--sp-20) var(--sp-24); flex: 1; }
.foot { background: var(--card); border-top: 1px solid var(--line); padding: var(--sp-12) var(--sp-24); display: flex; justify-content: space-between; align-items: center; gap: var(--sp-12); }

/* ── Khối thống kê đầu trang ──────────────────────────────────────────────── */
.stats { display: flex; gap: 0; padding: var(--sp-16) 0 15px; flex-wrap: wrap; }
.st { padding-right: 26px; margin-right: 26px; border-right: 1px solid var(--line-2); }
.st:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
/* .st-k / .st-v đã chuyển sang shared.css: member-chapter.js dùng chúng mà
   trang /m/ không nạp admin.css → nhãn và số hiện không style. */
.st .dist { margin-top: var(--sp-7); width: 190px; }

.warnbox {
  display: flex; gap: var(--sp-9); align-items: flex-start;
  background: var(--warn-bg); border: 1px solid var(--warn-bd); border-radius: var(--r-sm);
  padding: var(--sp-9) var(--sp-11); max-width: 330px;
  font-size: var(--fs-sm); line-height: 1.5; color: var(--warn-tx);
}
.warnbox b { color: var(--warn-ink); }

/* Bốn số lớn — dùng ở bước 2 wizard và Tổng quan */
.big { display: flex; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); margin-bottom: var(--sp-16); flex-wrap: wrap; }
.big-i { flex: 1; min-width: 150px; padding: var(--sp-14) var(--sp-16); border-right: 1px solid var(--line-2); }
.big-i:last-child { border-right: 0; }
.big-k { font-size: var(--fs-sm); color: var(--muted); }
.big-v { font-size: 23px; font-weight: 700; letter-spacing: -.02em; margin-top: var(--sp-2); line-height: 1.1; }
.big-v small { font-size: 12px; color: var(--muted); font-weight: 500; }

/* ── Tab chế độ xem ───────────────────────────────────────────────────────── */
.modes { display: flex; gap: var(--sp-2); }
.mode {
  font-size: var(--fs-body); font-weight: 600; padding: var(--sp-9) 13px;
  border: 0; background: none; color: var(--muted); cursor: pointer;
  border-bottom: 2px solid transparent; font-family: inherit;
}
.mode.on { color: var(--bni-red); border-bottom-color: var(--bni-red); }

/* ── Thanh lọc ────────────────────────────────────────────────────────────── */
.filters {
  display: flex; align-items: center; gap: var(--sp-10);
  padding: var(--sp-12) var(--sp-22); background: var(--card);
  border-bottom: 1px solid var(--line); flex-wrap: wrap;
}
.fsp { flex: 1; }
.cnt { font-size: var(--fs-sm); color: var(--muted); }

/* ── Bảng cuộn ────────────────────────────────────────────────────────────── */
.tblwrap { overflow: auto; flex: 1; background: var(--card); }
.tblwrap thead th { position: sticky; top: 0; z-index: 3; }
.tblwrap thead .grp { text-align: center; border-left: 1px solid var(--line); color: var(--bni-navy); }

/* Chế độ "Chi tiết mốc điểm": 28 cột, hai cột đầu DÍNH khi cuộn ngang.
   Đây là điểm khó chịu nhất khi dùng file Excel hiện tại. */
.detail table { font-size: var(--fs-sm); min-width: 1500px; }
.detail .stt { position: sticky; left: 0; background: var(--card); z-index: 2; width: 32px; }
.detail .sticky2 { position: sticky; left: 32px; background: var(--card); z-index: 2; min-width: 180px; box-shadow: 1px 0 0 var(--line); }
.detail thead th:nth-child(1) { position: sticky; left: 0; z-index: 4; }
.detail thead th:nth-child(2) { position: sticky; left: 32px; z-index: 4; box-shadow: 1px 0 0 var(--line); }
.detail tbody tr:hover .stt, .detail tbody tr:hover .sticky2 { background: var(--hover); }

.gp { text-align: center; width: 52px; font-size: var(--fs-xs); border-left: 1px solid var(--line-2); }
.gp .ok { color: var(--lt-green); font-weight: 700; font-size: 13px; }
.gp .need { color: var(--bni-navy); font-weight: 700; background: #EDF3FC; padding: 2px var(--sp-5); border-radius: 4px; font-size: 10.5px; }
.gp .mut { color: var(--ghost); }
.pv { color: var(--muted); width: 52px; text-align: center; }
.tot { width: 52px; text-align: center; font-weight: 700; font-size: 13.5px; }
.tot.green { color: var(--lt-green); }
.tot.amber { color: var(--lt-amber-ink); }
.tot.red   { color: var(--lt-red); }
.sm { width: 48px; text-align: center; color: var(--ink-2); }

.tfoot {
  background: var(--card); border-top: 1px solid var(--line);
  padding: var(--sp-10) var(--sp-22); display: flex; justify-content: space-between;
  align-items: center; gap: var(--sp-12); font-size: var(--fs-sm); color: var(--muted); flex-wrap: wrap;
}
.legend { display: flex; gap: var(--sp-14); align-items: center; flex-wrap: wrap; }
.legend span { display: inline-flex; align-items: center; gap: var(--sp-5); }
.legend em { font-style: normal; width: 9px; height: 9px; border-radius: 2px; display: inline-block; }

/* ── Bố cục hai cột ───────────────────────────────────────────────────────── */
.two, .two-wide { display: grid; gap: var(--sp-16); align-items: start; }
.two { grid-template-columns: minmax(0, 1fr) 340px; }
/* Cột phải chứa biểu đồ xu hướng nên phải CO GIÃN theo màn hình, không khoá cứng:
   khoá 380px thì màn rộng bao nhiêu cột trái nuốt hết, biểu đồ vẫn chật y như cũ.
   Chặn trên 560px để màn siêu rộng không kéo nó dài ngoẵng. */
.two-wide { grid-template-columns: minmax(0, 1fr) clamp(380px, 34%, 560px); }
/* PHẢI giữ minmax(0, …): `1fr` là `minmax(auto, 1fr)` — khôi phục lại đúng cái
   tràn min-content mà hai dòng trên vừa chặn, ở đúng khổ màn cần chặn nhất. */
@media (max-width: 1100px) { .two, .two-wide { grid-template-columns: minmax(0, 1fr); } }

.kv { padding: var(--sp-12) var(--sp-14); }
.kv div { display: flex; justify-content: space-between; gap: var(--sp-10); font-size: var(--fs-body); padding: var(--sp-5) 0; border-bottom: 1px solid var(--line-2); }
.kv div:last-child { border-bottom: 0; }
.kv span { color: var(--muted); }
.kv b { font-weight: 600; text-align: right; }

.rowline { display: flex; align-items: center; gap: var(--sp-11); padding: var(--sp-9) var(--sp-14); border-bottom: 1px solid var(--line-2); font-size: var(--fs-body); }
.rowline:last-child { border-bottom: 0; }
.rowline .nm { flex: 1; font-weight: 500; min-width: 0; }
/* Khối tên + gợi ý xếp dọc — .nm là flex NGANG nên không lồng khối dọc vào đó được */
.rowline-stack { flex: 1; min-width: 0; }
.rowline-stack .who { display: flex; align-items: baseline; gap: var(--sp-6); flex-wrap: wrap; }
.rowline-stack .who b { font-size: 13px; font-weight: 600; }
.rowline-stack .who i { font-style: normal; font-size: var(--fs-xs); color: var(--muted); }
.rowline-stack .task { font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-3); line-height: 1.5; }
.rowline-stack .task b { color: var(--ink-2); font-weight: 600; }
.rowline code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); background: var(--surface); padding: 1px var(--sp-5); border-radius: 4px; }
.tagx { font-size: 10.5px; font-weight: 700; padding: 2px var(--sp-7); border-radius: var(--r-pill); background: var(--err-bg); color: #B3261E; }
.tago { font-size: 10.5px; font-weight: 700; padding: 2px var(--sp-7); border-radius: var(--r-pill); background: var(--ok-bg); color: var(--ok-tx); }

/* ── Biểu đồ cột thuần CSS (Tổng quan, Chi tiết thành viên) ───────────────── */
/* align-items: stretch + .bar cao 100% là BẮT BUỘC: cột được vẽ bằng chiều cao
   phần trăm, mà phần trăm chỉ ăn khi cha có chiều cao xác định. Để flex-end thì
   .bar co lại vừa nội dung và mọi cột dẹp thành một vạch. */

/* Thanh ngang cho "Chỉ số yếu nhất của chapter" */
.hbar { display: flex; align-items: center; gap: var(--sp-11); padding: var(--sp-9) var(--sp-14); border-bottom: 1px solid var(--line-2); }
.hbar:last-child { border-bottom: 0; }
.hbar-k { width: 108px; flex: none; font-size: var(--fs-body); font-weight: 600; }
.hbar-track { flex: 1; height: 9px; background: var(--line-2); border-radius: var(--r-pill); overflow: hidden; }
.hbar-fill { display: block; height: 100%; border-radius: var(--r-pill); }
.hbar-fill.green { background: var(--lt-green); }
.hbar-fill.amber { background: var(--lt-amber); }
.hbar-fill.red   { background: var(--lt-red); }
.hbar-v { width: 96px; flex: none; text-align: right; font-size: var(--fs-sm); color: var(--muted); }
.hbar-v b { color: var(--ink); font-weight: 700; }

/* ── Wizard nhập liệu (Màn 03) ────────────────────────────────────────────── */
.stepper { display: flex; margin-top: var(--sp-16); overflow-x: auto; }
.stp {
  display: flex; align-items: center; gap: var(--sp-9);
  padding: 0 var(--sp-20) var(--sp-12) 0; margin-right: var(--sp-20);
  position: relative; border-bottom: 2px solid transparent; flex: none;
}
.stp::after { content: ''; position: absolute; right: 0; top: 8px; width: 12px; height: 1px; background: var(--line); }
.stp:last-child::after { display: none; }
.stp-n { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: var(--fs-xs); font-weight: 700; background: #EDEFF3; color: var(--faint); flex: none; }
.stp-t { font-size: var(--fs-body); font-weight: 600; color: var(--faint); white-space: nowrap; }
.stp.done .stp-n { background: var(--lt-green); color: #fff; }
.stp.done .stp-t { color: var(--ink-2); }
.stp.on { border-bottom-color: var(--bni-red); }
.stp.on .stp-n { background: var(--bni-red); color: #fff; }
.stp.on .stp-t { color: var(--ink); font-weight: 700; }

.drops { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-14); }
@media (max-width: 980px) { .drops { grid-template-columns: 1fr; } }
.drop { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--sp-16); }
.drop.empty { border: 1.5px dashed #C7CDD6; background: #FAFBFC; text-align: center; padding: 26px var(--sp-16); display: block; }
.drop.empty b { display: block; font-size: 13px; color: var(--ink); font-weight: 700; }
.drop.empty p { margin: var(--sp-9) 0 0; font-size: 12px; color: var(--muted); line-height: 1.5; }
.drop.over { border-color: var(--bni-navy); background: #F2F6FC; border-style: solid; }
.drop.bad { border-color: var(--err-bd); background: var(--err-bg); border-style: solid; }
.drop-h { display: flex; align-items: flex-start; gap: var(--sp-9); }
.drop-ic { width: 32px; height: 32px; border-radius: var(--r-sm); background: #EAF3EC; color: var(--lt-green); display: grid; place-items: center; flex: none; }
.drop-ic.bad { background: var(--err-bg); color: var(--lt-red); }
.drop-t { font-size: 13px; font-weight: 700; line-height: 1.25; }
.drop-s { font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-2); }
.file { display: flex; align-items: center; gap: 8px; background: var(--thead); border: 1px solid var(--line-2); border-radius: var(--r-sm); padding: var(--sp-7) var(--sp-9); margin-top: var(--sp-12); font-size: var(--fs-sm); }
.file b { font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meta { margin-top: var(--sp-11); border-top: 1px solid var(--line-2); padding-top: var(--sp-10); }
.meta div { display: flex; justify-content: space-between; gap: var(--sp-10); font-size: var(--fs-sm); padding: 2.5px 0; }
.meta span { color: var(--muted); }
.meta b { font-weight: 600; text-align: right; }

/* Thẻ đối soát tên (bước 3) */
.mt { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); padding: 15px var(--sp-16); margin-bottom: var(--sp-12); }
.mt-h { display: flex; align-items: flex-start; gap: var(--sp-12); }
.mt-src { flex: 1; min-width: 0; }
.mt-lb { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.mt-nm { font-size: var(--fs-h2); font-weight: 700; margin-top: var(--sp-3); letter-spacing: -.01em; }
.mt-ctx { font-size: var(--fs-sm); color: var(--muted); margin-top: var(--sp-3); line-height: 1.5; }
.opts { display: flex; gap: 8px; margin-top: 13px; flex-wrap: wrap; }
.opt { border: 1.5px solid var(--line); background: var(--card); border-radius: var(--r-sm); padding: 8px var(--sp-12); cursor: pointer; font-family: inherit; text-align: left; }
.opt b { display: block; font-size: var(--fs-body); font-weight: 600; }
.opt i { font-style: normal; font-size: 10.5px; color: var(--muted); }
.opt.pick { border-color: var(--bni-navy); background: #F2F6FC; }
.opt.pick b { color: var(--bni-navy); }
.opt.skip { border-style: dashed; }
.pct { font-size: 10.5px; font-weight: 700; color: var(--lt-green); background: var(--ok-bg); padding: 1px var(--sp-6); border-radius: var(--r-pill); margin-left: var(--sp-6); }
.remember { display: flex; align-items: center; gap: 8px; margin-top: var(--sp-12); font-size: var(--fs-sm); color: var(--ink-2); cursor: pointer; }

/* Top thay đổi lớn nhất (bước 4) */
.mv { display: flex; align-items: center; gap: var(--sp-10); padding: 8px var(--sp-14); border-bottom: 1px solid var(--line-2); font-size: var(--fs-body); }
.mv:last-child { border-bottom: 0; }
.mv .nm { flex: 1; font-weight: 500; min-width: 0; }
.mv .sc { color: var(--muted); font-size: var(--fs-sm); width: auto; }
.mv .dd { font-weight: 700; font-size: 12px; min-width: 38px; text-align: right; }
.mv .up { color: var(--lt-green); }
.mv .dn { color: var(--lt-red); }

.confirm { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--sp-16); display: flex; gap: var(--sp-12); align-items: flex-start; margin-top: var(--sp-16); }
.confirm h4 { margin: 0 0 4px; font-size: 13.5px; font-weight: 700; }
.confirm p { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.55; }

/* ── Màn hình hẹp: sidebar xếp ngang ──────────────────────────────────────── */
@media (max-width: 860px) {
  .app { flex-direction: column; }
  .side { width: 100%; height: auto; position: static; flex-direction: row; align-items: center; gap: var(--sp-10); padding-right: var(--sp-12); }
  .side-brand { border-bottom: 0; border-right: 1px solid rgba(255,255,255,.1); }
  .nav { display: flex; gap: var(--sp-3); overflow-x: auto; padding: var(--sp-6); }
  .nav-lb { display: none; }
  .side-foot { display: none; }
  .body, .head, .filters, .tfoot, .foot { padding-left: var(--sp-14); padding-right: var(--sp-14); }
}

/* ── Màn Tự động: nhật ký chạy của bot ─────────────────────────────────── */

.runs { display: flex; flex-direction: column; }
.run {
  display: grid; grid-template-columns: 84px 1fr auto; gap: var(--sp-12);
  align-items: start; padding: var(--sp-12) var(--sp-14);
  border-top: 1px solid var(--line);
}
.run:first-child { border-top: 0; }
.run-st {
  font-size: var(--fs-xs); font-weight: 700; text-align: center;
  padding: var(--sp-3) var(--sp-6); border-radius: var(--r-pill);
  border: 1px solid var(--line); color: var(--muted); background: var(--ghost);
}
.run-st.published { background: var(--ok-bg); border-color: var(--ok-bd); color: var(--ok-tx); }
.run-st.draft     { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-tx); }
.run-st.failed    { background: var(--err-bg); border-color: var(--err-bd); color: var(--err-tx); }
.run-b b { display: block; font-size: var(--fs-sm); line-height: 1.45; }
.run-m { font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-3); }
.run-x { display: flex; flex-wrap: wrap; gap: var(--sp-5); margin-top: var(--sp-7); }
.run-x span {
  font-size: var(--fs-xs); padding: var(--sp-2) var(--sp-7);
  border-radius: var(--r-sm); background: var(--ghost); color: var(--ink-2);
  border: 1px solid var(--line);
}
.run-x span.bad { background: var(--err-bg); border-color: var(--err-bd); color: var(--err-tx); }
.run-x span.ok  { background: var(--ok-bg); border-color: var(--ok-bd); color: var(--ok-tx); }

/* Công tắc bật/tắt bot */
.sw-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-14); padding: var(--sp-14); }
.sw-row > div p { font-size: var(--fs-xs); color: var(--muted); margin: var(--sp-3) 0 0; }
.sw-box { position: relative; width: 46px; height: 26px; flex: none; }
.sw-box input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }
.sw-tr {
  position: absolute; inset: 0; border-radius: var(--r-pill);
  background: var(--line-2); transition: background .15s; pointer-events: none;
}
.sw-tr::after {
  content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  border-radius: 50%; background: #fff; box-shadow: var(--shadow-card); transition: transform .15s;
}
.sw-box input:checked + .sw-tr { background: var(--lt-green); }
.sw-box input:checked + .sw-tr::after { transform: translateX(20px); }
.sw-box input:focus-visible + .sw-tr { outline: 2px solid var(--bni-red); outline-offset: 2px; }

/* Dải giờ chạy trong ngày */
.hours { display: flex; flex-wrap: wrap; gap: var(--sp-5); }
.hour {
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  padding: var(--sp-5) var(--sp-9); border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--ghost); color: var(--ink-2); cursor: pointer;
}
.hour.on { background: var(--bni-navy); border-color: var(--bni-navy); color: #fff; }

/* ── Biểu đồ xu hướng điểm trung bình ──────────────────────────────────── */

.chart { padding: var(--sp-16) var(--sp-16) var(--sp-10); }

/* Ba hàng cùng gap → các cột thẳng nhau mà không cần bảng */
.chart-row { display: flex; gap: var(--sp-6); }
.chart-row .cell { flex: 1; min-width: 0; }

/* Hàng số trên đầu cột */
.chart-vals .cell { text-align: center; line-height: 1.25; margin-bottom: var(--sp-5); }
.chart-vals b { display: block; font-size: var(--fs-sm); font-weight: 700; }
.chart-vals i { font-size: 10px; font-style: normal; font-weight: 600; }
.chart-vals i.up { color: var(--lt-green); }
.chart-vals i.dn { color: var(--lt-red); }
.chart-vals i.fl { color: var(--faint); }

/* Khu vẽ — chiều cao cố định để vạch ngưỡng canh đúng theo % của cột */
.chart-plot { position: relative; height: 168px; }
.chart-cols { height: 100%; align-items: flex-end; }

.col-track { height: 100%; display: flex; align-items: flex-end; background: var(--ghost); border-radius: var(--r-sm); }
.col-fill { width: 100%; border-radius: var(--r-sm) var(--r-sm) 0 0; min-height: 3px; transition: height .25s ease; }
.col-fill.green { background: linear-gradient(180deg, var(--lt-green), color-mix(in srgb, var(--lt-green) 76%, #000)); }
.col-fill.amber { background: linear-gradient(180deg, var(--lt-amber), color-mix(in srgb, var(--lt-amber) 76%, #000)); }
.col-fill.red   { background: linear-gradient(180deg, var(--lt-red),   color-mix(in srgb, var(--lt-red)   76%, #000)); }
/* Kỳ chưa chốt vẽ sọc mờ — nhìn là biết số còn tăng */
.col-fill.pending {
  opacity: .5;
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.5) 0 5px, transparent 5px 10px);
}

/* Vạch ngưỡng nằm TRONG khu vẽ nên không lấn lên hàng số */
.chart-rule { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--lt-green); z-index: 2; pointer-events: none; }
.chart-rule span {
  /* Bên trái: cột đầu kỳ thường thấp hơn ngưỡng nên có khoảng trống, đặt bên
     phải sẽ che mất đỉnh cột gần nhất. */
  position: absolute; left: 0; top: -7px; background: var(--card);
  padding: 0 var(--sp-6) 0 var(--sp-3); font-size: 10px; font-weight: 600;
  color: var(--lt-green); white-space: nowrap; border-radius: var(--r-sm);
}

/* Hàng nhãn tháng/năm */
.chart-keys { margin-top: var(--sp-7); }
.chart-keys .cell { text-align: center; line-height: 1.35; }
.chart-keys b { display: block; font-size: var(--fs-xs); font-weight: 700; }
.chart-keys span { display: block; font-size: 10px; color: var(--muted); }
.chart-keys em { display: block; font-size: 10px; font-style: normal; color: var(--faint); }

.chart-note { margin: 0; padding: var(--sp-9) var(--sp-14) var(--sp-14); font-size: 11px; color: var(--muted); line-height: 1.5; }

/* ── Hướng dẫn người mới ───────────────────────────────────────────────────── */

body.tour-open { overflow: hidden; }

.tour { position: fixed; inset: 0; z-index: 9000; }

/* Lỗ sáng: dùng box-shadow toả rộng để làm tối phần còn lại — một phần tử,
   không cần cắt SVG hay bốn tấm che ghép lại. */
.tour-hole {
  position: fixed; border-radius: var(--r-md); pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(11, 17, 26, .68), 0 0 0 2px var(--bni-red) inset;
  transition: top .2s ease, left .2s ease, width .2s ease, height .2s ease;
}

.tour-pop {
  position: fixed; width: 330px; max-width: calc(100vw - 24px);
  background: var(--card); border-radius: var(--r-md);
  box-shadow: 0 20px 50px -12px rgba(0, 0, 0, .45); overflow: hidden;
}
.tour-pop-h {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-10);
  padding: var(--sp-12) var(--sp-14); border-bottom: 1px solid var(--line-2);
}
.tour-pop-h b { font-size: var(--fs-h3); font-weight: 700; }
.tour-pop-h span {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700; color: var(--muted);
  background: var(--ghost); padding: 2px var(--sp-7); border-radius: var(--r-pill); flex: none;
}
.tour-pop-b { padding: var(--sp-12) var(--sp-14); font-size: var(--fs-body); line-height: 1.6; color: var(--ink-2); }
.tour-pop-b b { color: var(--ink); font-weight: 600; }
.tour-pop-f {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-10);
  padding: var(--sp-10) var(--sp-14); border-top: 1px solid var(--line-2); background: #FAFBFC;
}

/* Mũi nhọn trỏ về phía thành phần được nói tới */
.tour-pop::before {
  content: ''; position: absolute; width: 10px; height: 10px;
  background: var(--card); transform: rotate(45deg);
}
.tour-pop[data-place="bottom"]::before { top: -5px; left: var(--arrow, 50%); margin-left: -5px; }
.tour-pop[data-place="top"]::before    { bottom: -5px; left: var(--arrow, 50%); margin-left: -5px; background: #FAFBFC; }
.tour-pop[data-place="right"]::before  { left: -5px; top: var(--arrow, 50%); margin-top: -5px; }
.tour-pop[data-place="left"]::before   { right: -5px; top: var(--arrow, 50%); margin-top: -5px; }
.tour-pop[data-place="center"]::before { display: none; }

@media (max-width: 700px) {
  .tour-pop { width: calc(100vw - 24px); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE — khu quản lý
   Toàn bộ nằm trong @media. Desktop không thể bị ảnh hưởng.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 860px) {
  /* ── Thanh điều hướng ─────────────────────────────────────────────────────
     Bám mép trên khi cuộn: danh sách 32 người dài, không thì phải cuộn ngược
     lên đầu trang mới đổi được màn. */
  .side { position: sticky; top: 0; z-index: 50; }

  /* Dòng "TRAFFIC LIGHTS" giãn chữ .24em ăn ~90px chỉ để trang trí, trong khi
     dải điều hướng chỉ còn ~208px cho 8 mục. */
  .side-brand { padding: var(--sp-10) var(--sp-12); }
  .side-brand i { display: none; }

  /* Không có nowrap + flex:none thì mục điều hướng co về min-content và nhãn
     vỡ giữa cụm từ: "Tổng"/"quan", "Nhập dữ"/"liệu". */
  .nav a { flex: none; white-space: nowrap; }

  /* ── Trả lại nút Đăng xuất ────────────────────────────────────────────────
     `.side-foot` từng bị display:none ở đây, mà đó là NƠI DUY NHẤT có nút đăng
     xuất — quản lý mở bằng điện thoại thì không có đường thoát.
     font-size:0 để thu gọn tên và email (email là text node trần, không có
     selector riêng), rồi trả lại cỡ chữ cho đúng cái nút. */
  .side-foot {
    display: flex; align-items: center; flex: none;
    padding: 0 var(--sp-12); border-top: 0; font-size: 0;
  }
  .side-foot b { display: none; }
  .side-foot button { margin-top: 0; font-size: var(--fs-sm); white-space: nowrap; }

  /* ── Khối số liệu đầu trang ───────────────────────────────────────────────
     `.st` dùng border-right + margin để ngăn cách, chỉ bỏ ở :last-child. Khi
     xuống hàng, mọi ô cuối HÀNG vẫn mang đường kẻ treo lơ lửng ở mép phải.
     Lưới 2 cột giải quyết cả khoảng cách lẫn đường kẻ. */
  .stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-14); }
  .st { padding-right: 0; margin-right: 0; border-right: 0; }
  .st .dist { width: 100%; }
  .warnbox, .stats > .warnbox { grid-column: 1 / -1; max-width: none; }

  .big { display: grid; grid-template-columns: 1fr 1fr; }
  .big-i { min-width: 0; border-right: 0; border-bottom: 1px solid var(--line-2); }
  .big-i:nth-child(odd) { border-right: 1px solid var(--line-2); }

  /* Ba nút ở bước 4 wizard cần ~371px trong 362px → nhãn vỡ 2-3 dòng. */
  .foot { flex-wrap: wrap; }

  /* ── Cột định danh dính cho MỌI bảng ──────────────────────────────────────
     Trước đây chỉ `.detail` có cột dính. Bảng Tổng quan rộng 818px = 2,1 màn,
     kéo sang xem TYFCB là tên người biến mất — xem điểm mà không biết của ai.
     Desktop không cần (bảng vừa khít) nên luật nằm trong media query này. */
  .tblwrap tbody td:first-child,
  .tblwrap tbody td:nth-child(2),
  .tblwrap thead th:first-child,
  .tblwrap thead th:nth-child(2) {
    position: sticky; background: var(--card); z-index: 2;
  }
  .tblwrap tbody td:first-child, .tblwrap thead th:first-child { left: 0; }
  .tblwrap tbody td:nth-child(2), .tblwrap thead th:nth-child(2) {
    left: 32px; box-shadow: 1px 0 0 var(--line);
  }
  .tblwrap thead th:first-child, .tblwrap thead th:nth-child(2) { z-index: 4; }
  .tblwrap tbody tr:hover td:first-child,
  .tblwrap tbody tr:hover td:nth-child(2) { background: var(--hover); }

  /* Cột dính phải có bề rộng CHỐT. Để tự co thì tên tiếng Việt vỡ 3 dòng, hàng
     cao 60px; để nguyên min-width:200px của .nm thì hai cột dính nuốt 56% màn.
     28 + 132 = 160px = 41% — đủ cho tên xuống tối đa 2 dòng, còn 230px cho số. */
  .tblwrap tbody td:first-child, .tblwrap thead th:first-child { width: 28px; min-width: 28px; }
  .tblwrap tbody td:nth-child(2), .tblwrap thead th:nth-child(2) { left: 28px; width: 132px; }
  .tblwrap tbody td:nth-child(2) .nm { min-width: 0; gap: var(--sp-6); }
  .tblwrap tbody td:nth-child(2) .nm i { display: none; }
  .tblwrap tbody td:nth-child(2) .nm b {
    font-size: 12px; line-height: 1.3;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* ── Dấu hiệu còn nội dung bên phải ───────────────────────────────────────
     Mẹo background-attachment: hai lớp phủ màu nền bám theo nội dung (local),
     hai lớp bóng bám theo khung (scroll). Cuộn tới đâu bóng tự hiện/ẩn tới đó
     — KHÔNG cần một dòng JS nào. */
  .tblwrap {
    background-image:
      linear-gradient(to right, var(--card) 60%, rgba(255, 255, 255, 0)),
      linear-gradient(to left, var(--card) 60%, rgba(255, 255, 255, 0)),
      linear-gradient(to right, rgba(11, 17, 26, .16), rgba(11, 17, 26, 0)),
      linear-gradient(to left, rgba(11, 17, 26, .16), rgba(11, 17, 26, 0));
    background-position: left center, right center, left center, right center;
    background-repeat: no-repeat;
    background-size: 28px 100%, 28px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
  }
}

/* Khung khối số liệu đầu bảng đèn. Trước đây là inline style trong bang-den.js
   nên nằm NGOÀI tầm với của mọi media query — lệch 8px so với header và thanh
   lọc ở mobile, và vi phạm quy tắc cấm inline style của dự án. */
.statshost { background: var(--card); padding: 0 var(--sp-22); border-bottom: 1px solid var(--line); }
@media (max-width: 860px) { .statshost { padding: 0 var(--sp-14); } }

/* Bọc trong suốt: giữ .tblwrap là con trực tiếp của vùng cuộn (flex:1) trong khi
   vẫn cho phép chèn thanh nhắc vuốt ngang ở trên nó. */
.viewhost { display: contents; }

/* Danh sách hàng gọn — bản thay bảng Tổng quan ở mobile (xem bang-den.js). */
.mlist { padding: var(--sp-10) var(--sp-12) var(--sp-16); overflow-y: auto; flex: 1; min-height: 0; }

/* Thanh nhắc trước bảng 28 cột ở mobile. */
.swipehint {
  display: flex; align-items: center; gap: var(--sp-8); flex-wrap: wrap;
  padding: var(--sp-9) var(--sp-14); background: var(--warn-bg, #FFF9E8);
  border-bottom: 1px solid var(--line); font-size: var(--fs-xs); color: var(--ink-2);
}
.swipehint span { flex: 1; min-width: 160px; }
.swipehint .ghost { flex: none; }

/* Năm biểu tượng thao tác cuối mỗi dòng (bản máy tính). Trước đây là inline
   style; tách ra để media query với tới được. */
.rowacts { display: flex; gap: var(--sp-4); }

/* Bảng thao tác gom lại ở màn hẹp — nhãn chữ, mỗi nút một hàng đủ rộng để bấm. */
.acts { display: flex; flex-direction: column; gap: var(--sp-8); }
.acts-i { justify-content: flex-start; width: 100%; min-height: 46px; gap: var(--sp-10); }
.acts-d { color: var(--bni-red); border-color: var(--lt-red); }

/* Màn Cấu hình — hai cột trên desktop, một cột dưới 1100px.
   Cột trái giữ mục 1-2-4, cột phải giữ 3-5-6 (chia theo chiều cao cho cân).
   Khi chồng lại thành một cột, thứ tự đọc sẽ thành 1-2-4-5-3-6 nếu không can
   thiệp — nên ở khổ hẹp bỏ hẳn hai hộp cột đi và xếp lại đúng 1→6. */
.cfg-col { display: flex; flex-direction: column; gap: var(--sp-16); }
@media (max-width: 1100px) {
  .cfg-col { display: contents; }
  .cfg-1 { order: 1; } .cfg-2 { order: 2; } .cfg-3 { order: 3; }
  .cfg-4 { order: 4; } .cfg-5 { order: 5; } .cfg-6 { order: 6; }
}
