/* ============================================================
   SHARED COMPONENTS — BNI Zenith Traffic Lights
   Dịch nguyên từ sample/Mockups/*.html. Mockup là chân lý về style.

   Cần class mới → THÊM VÀO ĐÂY, không viết CSS riêng cho từng trang.
   Trước khi thêm, kiểm tra xem đã có class tương tự chưa.
   ============================================================ */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

/* Mọi con số PHẢI dùng font mono — bảng 30 dòng với font tỷ lệ không thẳng cột */
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Icon SVG dùng chung: nét, không tô */
.ic {
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  flex: none; vertical-align: -3px;
}

a { color: inherit; }
h1 { margin: 0; font-size: var(--fs-h1); font-weight: 800; letter-spacing: -.015em; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Nút ──────────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: var(--sp-6);
  font: inherit; font-size: var(--fs-body); font-weight: 600;
  padding: var(--sp-7) var(--sp-12);
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--card); color: var(--ink-2); cursor: pointer;
  text-decoration: none; min-height: 32px;
}
.btn:hover { background: var(--thead); }
.btn:focus-visible { outline: 2px solid var(--bni-navy); outline-offset: 1px; }
.btn-p { background: var(--bni-red); border-color: var(--bni-red); color: #fff; }
.btn-p:hover { background: var(--bni-red-dark); }
.btn-g { background: var(--lt-green); border-color: var(--lt-green); color: #fff; }
.btn-g:hover { background: #17742F; }
.btn-s { padding: var(--sp-5) var(--sp-9); font-size: var(--fs-sm); min-height: 28px; }
.btn-lg { font-size: 13px; padding: 8px 15px; }
.btn:disabled, .btn[aria-disabled='true'] {
  background: #E7E9ED; border-color: #E7E9ED; color: #A9B0BB; cursor: not-allowed;
}
.ghost {
  border: 0; background: none; color: var(--muted);
  font: inherit; font-size: var(--fs-body); font-weight: 500; cursor: pointer;
}
.ghost:hover { color: var(--ink-2); }
.sel {
  display: inline-flex; align-items: center; gap: var(--sp-7);
  font: inherit; font-size: var(--fs-body); font-weight: 600;
  padding: var(--sp-7) var(--sp-11);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--card); color: var(--ink); cursor: pointer;
}

/* ── Thẻ ──────────────────────────────────────────────────────────────────── */
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); }
.card-h {
  padding: var(--sp-12) var(--sp-14); border-bottom: 1px solid var(--line-2);
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-10);
}
.card-h b { font-size: 13px; font-weight: 700; }
.card-h span { font-size: var(--fs-sm); color: var(--muted); }
.card-pad { padding: var(--sp-18); }

.sec {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 var(--sp-10);
}
.sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-10); margin: 0 0 var(--sp-12); }
.sec-head h2 { margin: 0; font-size: var(--fs-h2); font-weight: 800; letter-spacing: -.01em; }
.sec-head span { font-size: var(--fs-sm); color: var(--muted); }

/* ── Hộp thông báo ────────────────────────────────────────────────────────── */
.note {
  display: flex; gap: var(--sp-10); align-items: flex-start;
  border-radius: var(--r-sm); padding: var(--sp-11) 13px;
  font-size: 12px; line-height: 1.55;
}
.note b { font-weight: 700; }
.note-warn { background: var(--warn-bg); border: 1px solid var(--warn-bd); color: var(--warn-tx); }
.note-warn b { color: var(--warn-ink); }
.note-err  { background: var(--err-bg);  border: 1px solid var(--err-bd);  color: var(--err-tx); }
.note-err b { color: var(--err-ink); }
.note-info { background: var(--info-bg); border: 1px solid var(--info-bd); color: var(--info-tx); }
.note-info b { color: var(--info-ink); }
.note-ok   { background: var(--ok-bg);   border: 1px solid var(--ok-bd);   color: var(--ok-tx); }
.note + .note { margin-top: var(--sp-10); }
/* Cách khắc phục — mọi thông báo lỗi phải nói cách sửa (requirements.md H.2) */
.note .hint { display: block; margin-top: var(--sp-5); opacity: .85; }

/* ── Nhãn nhỏ ─────────────────────────────────────────────────────────────── */
.chip {
  white-space: nowrap; display: inline-block;
  font-size: var(--fs-xs); font-weight: 600;
  padding: var(--sp-3) 8px; border-radius: var(--r-pill);
  background: #EEF1F6; color: #4A5364; border: 1px solid #E0E5EC;
}
.chip-team { background: #FDECEE; color: #A50F26; border-color: #F7D4D9; }
.chip-ok   { background: var(--ok-bg); color: var(--ok-tx); border-color: var(--ok-bd); }
.chip-off  { background: #F2F3F5; color: var(--muted); border-color: var(--line); }

/* Ô điểm trong bảng — luôn mono, tối thiểu 30px cho thẳng cột */
.pchip {
  display: inline-block; min-width: 30px; padding: var(--sp-3) var(--sp-6);
  border-radius: var(--r-sm); font-size: 12px; font-weight: 700;
  font-family: var(--font-mono); color: #fff; text-align: center;
}
.pchip.green { background: var(--lt-green); }
.pchip.amber { background: var(--lt-amber); }
.pchip.red   { background: var(--lt-red); }
.pchip.gray  { background: #EDEFF2; color: var(--faint); }

/* Chênh lệch so kỳ trước — luôn kèm dấu, không chỉ dựa vào màu */
.d { font-size: 10.5px; font-weight: 700; }
.d.up { color: var(--lt-green); }
.d.dn { color: var(--lt-red); }
.d.fl { color: var(--lt-gray); }

/* ── Đèn ──────────────────────────────────────────────────────────────────── */
.lamp-s { width: 11px; height: 11px; border-radius: 50%; flex: none; display: inline-block; }
.lamp-s.green { background: var(--lt-green); }
.lamp-s.amber { background: var(--lt-amber); }
.lamp-s.red   { background: var(--lt-red); }
.lamp-s.gray  { background: var(--lt-gray); }

.lamp {
  width: 76px; height: 76px; border-radius: 50%; flex: none;
  display: grid; place-items: center; position: relative;
}
.lamp::after { content: ''; position: absolute; inset: 8px; border-radius: 50%; background: rgba(255,255,255,.22); }
.lamp i { position: relative; z-index: 1; color: #fff; }
.lamp-green { background: var(--lt-green); box-shadow: 0 0 0 6px rgba(30,142,62,.13); }
.lamp-amber { background: var(--lt-amber); box-shadow: 0 0 0 6px rgba(224,161,6,.15); }
.lamp-red   { background: var(--lt-red);   box-shadow: 0 0 0 6px rgba(217,48,37,.13); }
.lamp-sm { width: 66px; height: 66px; }

/* ── Phân bố đèn ──────────────────────────────────────────────────────────── */
.dist { display: flex; gap: var(--sp-3); }
.dist span { height: 7px; border-radius: 2px; }
.dist .g { background: var(--lt-green); }
.dist .a { background: var(--lt-amber); }
.dist .r { background: var(--lt-red); }
.dist-lb { display: flex; gap: var(--sp-12); font-size: var(--fs-xs); color: var(--ink-2); margin-top: var(--sp-6); flex-wrap: wrap; }
.dist-lb i { font-style: normal; width: 7px; height: 7px; border-radius: 2px; display: inline-block; margin-right: 4px; }

/* ── Bảng ─────────────────────────────────────────────────────────────────── */
table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: var(--fs-body); }
thead th {
  background: var(--thead); font-weight: 700; font-size: 10.5px;
  letter-spacing: .05em; text-transform: uppercase; color: #5A6270;
  padding: 8px var(--sp-10); text-align: left;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
tbody td { padding: var(--sp-9) var(--sp-10); border-bottom: 1px solid var(--line-2); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: var(--hover); }
th[aria-sort] { cursor: pointer; user-select: none; }
th[aria-sort='ascending']::after { content: ' ▲'; color: var(--bni-navy); }
th[aria-sort='descending']::after { content: ' ▼'; color: var(--bni-navy); }

.stt { color: var(--faint); width: 34px; font-size: var(--fs-sm); }
.nm { display: flex; align-items: center; gap: var(--sp-9); min-width: 200px; }
.nm b { font-weight: 600; font-size: 13px; display: block; line-height: 1.25; }
.nm i { font-style: normal; font-size: var(--fs-xs); color: var(--muted); }
.act { width: 38px; text-align: center; }
.lnk { color: var(--faint); text-decoration: none; font-size: 15px; cursor: pointer; background: none; border: 0; padding: 4px; }
.lnk:hover { color: var(--bni-red); }

/* Cột điểm kèm thanh tỷ lệ */
.sc { width: 132px; }
.sc-row { display: flex; align-items: baseline; gap: var(--sp-7); }
.sc-row b { font-size: 16px; font-weight: 700; letter-spacing: -.02em; }
.sc-bar { height: 4px; background: var(--line-2); border-radius: 2px; margin-top: 4px; overflow: hidden; }
.sc-bar span { display: block; height: 100%; border-radius: 2px; }
.sc-bar .green { background: var(--lt-green); }
.sc-bar .amber { background: var(--lt-amber); }
.sc-bar .red   { background: var(--lt-red); }
.pt { text-align: center; width: 64px; }

/* ── Ô nhập ───────────────────────────────────────────────────────────────── */
.inp {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--sp-7) var(--sp-10); font: inherit; font-size: var(--fs-body);
  width: 100%; background: var(--card); color: var(--ink);
}
.inp:focus { outline: 2px solid #C3D6F0; border-color: var(--bni-navy); }
.inp[aria-invalid='true'] { border-color: var(--lt-red); }
.fld { margin-bottom: var(--sp-14); }
.fld label { display: block; font-size: 12px; font-weight: 600; margin-bottom: var(--sp-5); }
.fld p { margin: var(--sp-5) 0 0; font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
.fld .err { color: var(--lt-red); font-weight: 500; }
.fld-row { display: flex; gap: var(--sp-10); align-items: flex-end; }

.search {
  display: flex; align-items: center; gap: var(--sp-7);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--sp-6) var(--sp-10); width: 210px; color: var(--muted); background: var(--card);
}
.search input { border: 0; outline: 0; font: inherit; font-size: var(--fs-body); width: 100%; background: none; color: var(--ink); }

/* Công tắc bật/tắt */
.sw {
  position: relative; width: 34px; height: 19px; border-radius: var(--r-pill);
  background: var(--line); flex: none; border: 0; cursor: pointer; padding: 0;
  transition: background .15s;
}
.sw::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 15px; height: 15px; border-radius: 50%; background: #fff;
  transition: transform .15s;
}
.sw[aria-checked='true'] { background: var(--lt-green); }
.sw[aria-checked='true']::after { transform: translateX(15px); }

/* Chip lọc bấm được */
.chips { display: flex; gap: var(--sp-5); flex-wrap: wrap; }
.ch {
  white-space: nowrap; font-size: var(--fs-sm); font-weight: 600;
  padding: var(--sp-5) var(--sp-10); border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--card); color: var(--ink-2);
  cursor: pointer; font-family: inherit; flex: none;
}
.ch b { margin-left: 4px; color: var(--faint); font-weight: 600; }
.ch.on { background: var(--bni-navy); border-color: var(--bni-navy); color: #fff; }
.ch.on b { color: rgba(255,255,255,.7); }
.ch-l { display: inline-flex; align-items: center; gap: var(--sp-5); }
.ch-l i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

/* ══ MilestoneBar — component đặc trưng của sản phẩm (requirements.md C.5) ══ */
.steps { display: flex; gap: var(--sp-3); margin-top: var(--sp-12); }
.step {
  flex: 1; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: #FBFCFD; padding: var(--sp-6) var(--sp-3) var(--sp-5);
  text-align: center; min-width: 0;
}
.step-pts { font-size: 10px; font-weight: 700; color: var(--faint); letter-spacing: .02em; }
.step-body {
  font-size: var(--fs-xs); font-weight: 700; margin-top: var(--sp-3);
  color: var(--ghost); line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.step.done { border-color: transparent; }
.step.done .step-pts { color: rgba(255,255,255,.82); }
.step.done .step-body { color: #fff; }
.step.done.t-green { background: var(--lt-green); }
.step.done.t-amber { background: var(--lt-amber); }
.step.done.t-red   { background: var(--lt-red); }
.step.next { border-color: var(--bni-navy); border-width: 1.5px; background: #F2F6FC; }
.step.next .step-pts, .step.next .step-body { color: var(--bni-navy); }
/* Không thể đạt trong kỳ này — viền nét đứt, kèm lý do ở ghi chú dưới thẻ */
.step.locked { background: var(--surface); border-style: dashed; }
.step.locked .step-body { color: var(--lt-gray); }

/* ── Thẻ chỉ số ───────────────────────────────────────────────────────────── */
.metrics { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); }
.m {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--sp-14) 15px 13px; display: flex; flex-direction: column;
}
.m-wide { grid-column: span 2; }
.m-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-10); }
.m-name { font-size: var(--fs-body); font-weight: 700; line-height: 1.3; }
.m-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-2); line-height: 1.4; }
.m-pts { text-align: right; flex: none; }
.m-pts b { font-size: var(--fs-metric); font-weight: 700; line-height: 1; }
.m-pts span { font-size: var(--fs-sm); color: var(--muted); }
.m-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-left: var(--sp-6); vertical-align: middle; }
.d-green { background: var(--lt-green); } .d-amber { background: var(--lt-amber); }
.d-red { background: var(--lt-red); }     .d-gray { background: var(--lt-gray); }
.m-val { margin: var(--sp-11) 0 0; font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1; }
.m-val small { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); letter-spacing: 0; margin-left: var(--sp-5); }
.m-note {
  margin-top: var(--sp-10); font-size: var(--fs-xs); line-height: 1.5;
  color: var(--muted); display: flex; gap: var(--sp-6); align-items: flex-start;
}
.m-note i { flex: none; margin-top: 1px; }
.m-note b { color: var(--ink); }
.m-note.warn { color: #8A6100; }
.m-note.max { color: #166B31; font-weight: 600; }

/* ── Khối tóm tắt điểm ────────────────────────────────────────────────────── */
.sum-head { padding: var(--sp-16) var(--sp-18) var(--sp-14); border-bottom: 1px solid var(--line-2); }
.sum-name { font-size: 20px; font-weight: 800; letter-spacing: -.01em; line-height: 1.2; margin: 0; }
.sum-meta { display: flex; gap: var(--sp-6); flex-wrap: wrap; margin-top: var(--sp-9); }

.lamp-row { display: flex; align-items: center; gap: var(--sp-16); padding: var(--sp-18); }
.score-val { font-size: var(--fs-score); font-weight: 700; line-height: 1; letter-spacing: -.03em; }
.score-max { font-size: 16px; color: var(--muted); font-weight: 500; }
.score-cap {
  font-size: var(--fs-sm); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; margin-top: var(--sp-5);
}
.score-cap.green { color: var(--lt-green); }
.score-cap.amber { color: var(--lt-amber); }
.score-cap.red   { color: var(--lt-red); }
.delta {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; padding: var(--sp-2) var(--sp-7);
  border-radius: var(--r-pill); margin-top: var(--sp-7);
}
.delta-down { background: var(--err-bg); color: #B3261E; }
.delta-up   { background: #E9F5EC; color: #166B31; }
.delta-flat { background: #F0F1F4; color: #5B6270; }

/* ── ScoreBand — dải 0-100 ba màu ─────────────────────────────────────────── */
.band { padding: 0 var(--sp-18) var(--sp-18); }
.band-title { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: var(--sp-10); }
.band-track { height: 9px; border-radius: var(--r-pill); display: flex; overflow: hidden; }
.band-track div:nth-child(1) { flex: 40; background: #F1B3AE; }
.band-track div:nth-child(2) { flex: 20; background: #F5DFA3; }
.band-track div:nth-child(3) { flex: 40; background: #A9DCB8; }
.band-rail { position: relative; height: 30px; margin-top: -9px; }
.pin { position: absolute; top: 0; transform: translateX(-50%); text-align: center; }
.pin-dot { width: 13px; height: 13px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.3); margin: 0 auto; }
.pin-now.green .pin-dot { background: var(--lt-green); }
.pin-now.amber .pin-dot { background: var(--lt-amber); }
.pin-now.red   .pin-dot { background: var(--lt-red); }
.pin-prev .pin-dot { background: #fff; border-color: var(--faint); width: 11px; height: 11px; }
.pin-lb { font-size: 10px; font-weight: 600; margin-top: var(--sp-3); white-space: nowrap; color: var(--ink-2); }
.pin-prev .pin-lb { color: var(--faint); font-weight: 500; }
.band-scale { position: relative; height: 14px; font-size: 10px; color: var(--faint); margin-top: var(--sp-2); }
.band-scale span { position: absolute; top: 0; }
.band-legend { font-size: 10.5px; color: var(--muted); margin-top: var(--sp-6); display: flex; align-items: center; gap: var(--sp-5); }
.band-legend b { color: var(--ink-2); }
.dot-prev { width: 9px; height: 9px; border-radius: 50%; background: #fff; border: 2px solid var(--faint); display: inline-block; }

.deadline {
  border-top: 1px solid var(--line-2); padding: 13px var(--sp-18);
  display: flex; gap: var(--sp-11); align-items: flex-start; background: #FBFCFD;
}
.deadline i { color: var(--bni-navy); flex: none; margin-top: 1px; }
.deadline b { display: block; font-size: var(--fs-body); font-weight: 700; }
.deadline p { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); color: var(--muted); line-height: 1.5; }

/* ── Khối "Việc cần làm" ──────────────────────────────────────────────────── */
.todo { background: var(--bni-navy); border-radius: var(--r-md); color: #fff; overflow: hidden; }
.todo-head { padding: 15px var(--sp-18) var(--sp-12); border-bottom: 1px solid rgba(255,255,255,.16); }
.todo-head h3 { margin: 0; font-size: var(--sp-14); font-weight: 800; letter-spacing: -.01em; }
.todo-head p { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: rgba(255,255,255,.72); line-height: 1.5; }
.todo-item { display: flex; align-items: center; gap: var(--sp-12); padding: var(--sp-12) var(--sp-18); border-bottom: 1px solid rgba(255,255,255,.1); }
.todo-rank { width: 22px; height: 22px; border-radius: 50%; background: rgba(255,255,255,.16); display: grid; place-items: center; font-size: var(--fs-xs); font-weight: 700; flex: none; }
.todo-txt { flex: 1; font-size: 13px; font-weight: 500; line-height: 1.4; }
.todo-txt b { font-weight: 700; }
.todo-pts { font-size: var(--fs-body); font-weight: 700; background: rgba(255,255,255,.15); padding: var(--sp-3) 8px; border-radius: var(--r-pill); flex: none; }
.todo-foot { padding: var(--sp-12) var(--sp-18); font-size: 12px; display: flex; justify-content: space-between; align-items: center; gap: var(--sp-10); background: rgba(0,0,0,.15); }
.todo-foot b { font-size: var(--fs-h2); font-weight: 700; }

/* ── Thông tin tham khảo ──────────────────────────────────────────────────── */
.ref { display: flex; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.ref-i { flex: 1; padding: var(--sp-12) 15px; border-right: 1px solid var(--line-2); }
.ref-i:last-child { border-right: 0; }
.ref-k { font-size: var(--fs-xs); color: var(--muted); line-height: 1.3; }
.ref-v { font-size: 17px; font-weight: 700; margin-top: var(--sp-3); letter-spacing: -.01em; }

/* ── Trạng thái rỗng / đang tải ───────────────────────────────────────────── */
.sk {
  background: linear-gradient(90deg, #E7EAEF 25%, #F1F3F6 50%, #E7EAEF 75%);
  background-size: 200% 100%; animation: sh 1.4s infinite; border-radius: var(--r-sm);
}
@keyframes sh { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }

.empty { display: grid; place-items: center; text-align: center; padding: 48px 28px; }
.empty i { color: var(--lt-gray); }
.empty h4 { margin: var(--sp-14) 0 var(--sp-6); font-size: var(--fs-h2); font-weight: 700; }
.empty p { margin: 0 0 var(--sp-16); font-size: var(--fs-body); color: var(--muted); line-height: 1.6; max-width: 380px; }

/* ── Hộp thoại ────────────────────────────────────────────────────────────── */
.modal-bg {
  position: fixed; inset: 0; background: rgba(20,25,40,.45);
  display: grid; place-items: center; padding: var(--sp-20); z-index: 50;
}
.modal-bg[hidden] { display: none; }
.modal { background: var(--card); border-radius: var(--r-md); width: min(560px, 100%); max-height: 88vh; display: flex; flex-direction: column; box-shadow: var(--shadow-pop); }
.modal-h { padding: var(--sp-16) var(--sp-18); border-bottom: 1px solid var(--line-2); display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-12); }
.modal-h h3 { margin: 0; font-size: var(--fs-h2); font-weight: 800; }
.modal-h p { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.modal-b { padding: var(--sp-18); overflow-y: auto; }
.modal-f { padding: var(--sp-12) var(--sp-18); border-top: 1px solid var(--line-2); display: flex; justify-content: flex-end; gap: 8px; }

/* ── Toast ────────────────────────────────────────────────────────────────── */
.toasts { position: fixed; top: var(--sp-16); right: var(--sp-16); display: flex; flex-direction: column; gap: 8px; z-index: 90; }
.toast {
  background: var(--ink); color: #fff; border-radius: var(--r-sm);
  padding: var(--sp-11) var(--sp-14); font-size: var(--fs-body); font-weight: 500;
  box-shadow: var(--shadow-pop); max-width: 360px; line-height: 1.5;
}
.toast.ok  { background: var(--lt-green); }
.toast.err { background: var(--lt-red); }

/* Đang tải lại danh sách — giữ dữ liệu cũ, chỉ giảm độ đậm (requirements.md H.3) */
.is-busy { opacity: .6; transition: opacity .15s; pointer-events: none; }

.st-k { font-size: var(--fs-xs); color: var(--muted); font-weight: 500; }
.st-v { font-size: 24px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; margin-top: var(--sp-2); }
.st-v small { font-size: 12px; color: var(--muted); font-weight: 500; }

/* ── Vùng chạm tối thiểu 44px trên thiết bị cảm ứng (WCAG 2.1 AA) ─────────── */
@media (pointer: coarse) {
  .btn, .ch, .lnk, .tab { min-height: 44px; }
  .btn-s { min-height: 38px; }
}

/* Nhãn ô mốc: bản ngắn cho thẻ chật, bản dài cho thẻ ≤2 mốc và thẻ rộng.
   Cả hai cùng nằm trong DOM, CSS chọn bản phù hợp — giữ đúng cả hai biến thể
   mà mockup 01 mô tả (desktop dùng "5 điểm / Đã đạt", mobile dùng "5 / ✓"). */
.lbl-long { display: none; }
.lbl-short { display: inline; }
.steps.roomy .lbl-long { display: inline; }
.steps.roomy .lbl-short { display: none; }
@media (min-width: 900px) {
  .m-wide .steps .lbl-long { display: inline; }
  .m-wide .steps .lbl-short { display: none; }
}

/* ── Màn đăng nhập (Màn 11) ───────────────────────────────────────────────── */
.login {
  min-height: 100vh; display: grid; place-items: center;
  background: linear-gradient(160deg, #141A24 0%, #1F2A3A 100%);
  padding: var(--sp-24);
}
.lbox { width: 370px; max-width: 100%; background: var(--card); border-radius: var(--r-lg); overflow: hidden; box-shadow: 0 24px 60px -20px rgba(0,0,0,.5); }
.lhead { background: var(--bni-red); color: #fff; padding: var(--sp-20) var(--sp-24); }
.lhead b { font-size: 21px; font-weight: 800; letter-spacing: -.02em; display: block; }
.lhead i { font-style: normal; font-size: 10.5px; font-weight: 700; letter-spacing: .26em; opacity: .9; }
/* Hai thẻ Đăng nhập / Đăng ký */
.ltabs { display: flex; border-bottom: 1px solid var(--line); background: #FAFBFC; }
.ltab {
  flex: 1; padding: var(--sp-12) var(--sp-10); border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: var(--fs-body); font-weight: 600; color: var(--muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.ltab:hover { color: var(--ink); }
.ltab.on { color: var(--bni-red); border-bottom-color: var(--bni-red); background: var(--card); }
.ltab:focus-visible { outline: 2px solid var(--bni-red); outline-offset: -2px; }

.lbody { padding: var(--sp-22) var(--sp-24) var(--sp-20); }
.lbody h2 { margin: 0 0 4px; font-size: 16px; font-weight: 700; }
.lbody .sublb { margin: 0 0 var(--sp-18); font-size: 12px; color: var(--muted); line-height: 1.55; }
.lfoot { padding: 13px var(--sp-24); border-top: 1px solid var(--line-2); background: #FAFBFC; font-size: var(--fs-sm); color: var(--muted); line-height: 1.6; }
.btn-block { width: 100%; justify-content: center; padding: var(--sp-10); }

/* ── Trang link hỏng / 404 ────────────────────────────────────────────────── */
.standalone { min-height: 100vh; display: flex; flex-direction: column; }
.standalone .empty { flex: 1; }

/* Thuộc tính hidden phải thắng mọi display của component.
   Không có dòng này, .note{display:flex} làm hộp lỗi vẫn hiện dù đã set hidden. */
[hidden] { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE — hàng rào an toàn dùng chung
   ---------------------------------------------------------------------------
   MỌI thứ dưới đây nằm trong @media. Desktop KHÔNG thể bị ảnh hưởng — đó là
   ràng buộc, không phải mong muốn.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Vùng chạm trên thiết bị cảm ứng ────────────────────────────────────────
   Quy tắc 44px ở trên chỉ đặt min-HEIGHT và thiếu nhiều selector, nên `.lnk`
   ra 23×44px — dưới cả mức tối thiểu 24px của WCAG 2.5.8. Năm nút thao tác ở
   màn Thành viên đứng cách nhau 4px, mà cặp nguy hiểm nhất là "Gửi link" cạnh
   "Tạo lại link": bấm nhầm là khai tử link cũ của thành viên ngay lập tức. */
@media (pointer: coarse) {
  .nav a, .mode, .hour, .ltab { min-height: 44px; }

  /* `.lnk` hay nằm TRỰC TIẾP trong <td>. Phần tử inline bỏ qua min-height,
     nên phải đổi sang inline-flex thì ràng buộc mới có hiệu lực. */
  .lnk {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px;
  }

  /* Công tắc giữ nguyên kích thước hình vẽ, chỉ nới vùng bấm bằng lớp phủ. */
  .sw { position: relative; }
  .sw::after {
    content: ''; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }

  .hour { min-width: 44px; }

  /* iOS Safari TỰ PHÓNG TO trang khi focus vào ô nhập có cỡ chữ dưới 16px, và
     KHÔNG tự thu lại — người dùng kẹt ở trạng thái phóng to, phải chụm tay để
     thoát. Xảy ra ở mọi form: đăng nhập, đăng ký, cấu hình, bot. */
  .inp, .search input, select, textarea { font-size: 16px; }
}

/* ── Chống tràn ngang cho component DÙNG CHUNG ──────────────────────────────
   Trước đây khối này chỉ có trong member.css, mà trang quản lý không nạp file
   đó — nên các màn admin dùng lại đúng những component này lại không có lưới
   an toàn. requirements.md mục K: trang KHÔNG được cuộn ngang. */
.card, .metrics, .metrics > *, .todo, .todo-item, .todo-txt,
.m, .rowline, .lamp-row, .lamp-row > div { min-width: 0; }

/* .tblwrap là flex item () nên min-width mặc định là AUTO = min-content
   của cái bảng bên trong. Bảng Tổng quan rộng 818px → ép cả trang rộng 818px,
   cắt cụt header, chip lọc, nút — chứ không phải chỉ cuộn trong khung như thiết
   kế. Đây là lý do CẢ TRANG tràn ngang ở 390px, không riêng bảng. */
.tblwrap { min-width: 0; }
.m-name, .m-val, .todo-txt { overflow-wrap: anywhere; }

/* ── Thẻ chỉ số về một cột ──────────────────────────────────────────────────
   `.metrics` được ĐỊNH NGHĨA ở shared.css (dùng chung), nhưng luật thu về một
   cột lại nằm trong member.css. Hậu quả: trang chi tiết thành viên của khu
   quản lý kẹt 2 cột ở 390px → mỗi thẻ 175px → ô mốc còn 26px → nhãn
   "Cần 5 khách" cắt còn "C…". Luật phải ở cùng file với component. */
@media (max-width: 899px) {
  .metrics { grid-template-columns: 1fr; }
  .m-wide { grid-column: auto; }
}

/* ── Thanh tab đáy tránh vạch home của iPhone ───────────────────────────────
   Hiện chưa hỏng vì viewport không có `viewport-fit=cover`. Đặt sẵn để sau này
   ai thêm thuộc tính đó thì thanh tab không bị vạch home che. */
.tabbar { padding-bottom: env(safe-area-inset-bottom, 0); }


/* ── Hàng gọn (mobile) ─────────────────────────────────────────────────────
   Một người = một hàng: hạng · tên/team · 7 vạch màu chỉ số · điểm.
   Không có cột nào nên không bao giờ phải cuộn ngang. Dùng ở cả trang
   thành viên (mọi bề rộng) lẫn trang quản trị Bảng đèn (≤700px). */
.mrow {
  display: flex; align-items: center; gap: var(--sp-11);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--sp-10) var(--sp-12); margin-bottom: var(--sp-7);
  width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer;
  text-decoration: none;
}
.mrow.me { border-color: var(--bni-red); border-width: 1.5px; background: #FFFAFB; }
.mrank { font-size: var(--fs-sm); color: var(--faint); width: 16px; flex: none; }
.mnm { flex: 1; min-width: 0; }
.mnm b { font-size: 13px; font-weight: 600; display: inline; }
.mnm i { font-style: normal; font-size: 10.5px; color: var(--muted); display: block; margin-top: 1px; }
.metag { font-size: 9.5px; font-weight: 700; background: var(--bni-red); color: #fff; padding: 1px var(--sp-5); border-radius: var(--r-pill); margin-left: var(--sp-6); vertical-align: 2px; }
/* Bảy vạch màu — mỗi vạch một chỉ số */
.mdots { display: flex; gap: var(--sp-3); margin-top: var(--sp-6); }
.md { height: 5px; border-radius: 2px; flex: 1; }
.md.green { background: var(--lt-green); }
.md.amber { background: var(--lt-amber); }
.md.red { background: var(--lt-red); }
.md.gray { background: #E4E7EC; }
.msc { text-align: right; flex: none; }
.msc b { font-size: 19px; font-weight: 700; letter-spacing: -.02em; display: block; line-height: 1; }
.msc b.green { color: var(--lt-green); }
.msc b.amber { color: var(--lt-amber-ink); }
.msc b.red { color: var(--lt-red); }

/* ── Sàn cỡ chữ ở màn hẹp ──────────────────────────────────────────────────
   Vài nhãn phụ được đặt 9.5–10.5px cho vừa bố cục desktop dày đặc. Trên điện
   thoại cầm xa mắt hơn thì cỡ đó đọc rất mệt, mà mobile lại rộng rãi hơn về
   chỗ nên nâng lên được mà không vỡ gì. */
@media (max-width: 700px) {
  .metag { font-size: 11px; }
  .mnm i { font-size: 12px; }
  .mrank { font-size: 12px; width: 20px; }
  .d, .tab { font-size: 12px; }
  .step-pts, .pin-lb { font-size: 11.5px; }
}

/* Thanh "có thay đổi chưa lưu" dính đáy (Cấu hình, Tự động).
   Trước đây là inline style dài 9 thuộc tính lặp ở hai file — nay là class. */
.savebar {
  position: sticky; bottom: 0; margin-top: var(--sp-16);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--sp-12) var(--sp-16);
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-12);
  box-shadow: var(--shadow-pop);
  /* Máy có tai thỏ: chừa lề dưới để nút không nằm dưới vạch home. */
  padding-bottom: calc(var(--sp-12) + env(safe-area-inset-bottom, 0px));
}
.savebar-t { font-size: 12.5px; color: var(--muted); }
.savebar-a { display: flex; gap: var(--sp-8); }
@media (max-width: 700px) {
  /* Màn hẹp: chữ và hai nút xếp dọc thay vì bóp nút còn nửa chữ. */
  .savebar { flex-direction: column; align-items: stretch; gap: var(--sp-8); }
  .savebar-a { justify-content: flex-end; }
}

/* Hàng ô nhập trong hộp thoại: hai ô cạnh nhau ở desktop, xuống dòng ở mobile
   thay vì bóp còn 60px mỗi ô. Đóng khung trong media query để desktop y nguyên. */
@media (max-width: 700px) {
  .fld-row { flex-wrap: wrap; }
  .fld-row > * { min-width: min(200px, 100%); }
}
