/* --- Font chữ ---------------------------------------------------------
   Tự lưu file .woff2 trong app/static/fonts/, không gọi CDN ngoài — CSP của
   hệ thống (default-src 'self') vốn đã không cho tải tài nguyên từ nơi khác,
   và tự lưu thì trang không phụ thuộc Google Fonts còn sống hay không.

   Đã kiểm bằng cách tải font thật về và soi từng ký tự (fontTools), không
   đoán: Kodchasan và Be Vietnam Pro đủ 46/46 tổ hợp dấu tiếng Việt phức tạp
   (ầấẩẫậ, ườ, ...). "FZ Poppins" không có trên Google Fonts (bộ font Việt hóa
   riêng, không tự tải được); Poppins gốc thiếu 36/46 tổ hợp — dùng cho tiêu
   đề sẽ vỡ dấu giữa từ, nên đổi sang Be Vietnam Pro (cùng phong cách geometric
   sans, do người Việt thiết kế riêng cho tiếng Việt). */
@font-face {
  font-family: "Kodchasan";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/kodchasan-400.woff2") format("woff2");
}
@font-face {
  font-family: "Kodchasan";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/kodchasan-500.woff2") format("woff2");
}
@font-face {
  font-family: "Kodchasan";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/kodchasan-600.woff2") format("woff2");
}
@font-face {
  font-family: "Kodchasan";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/kodchasan-700.woff2") format("woff2");
}
@font-face {
  font-family: "Be Vietnam Pro";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/bevietnampro-600.woff2") format("woff2");
}
@font-face {
  font-family: "Be Vietnam Pro";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/bevietnampro-700.woff2") format("woff2");
}

:root {
  /* Bảng màu thương hiệu chính thức của Bumas (theo tài liệu hướng dẫn màu
     sắc — 5 sắc xanh, tỉ lệ dùng 60/30/10). Đặt tên đúng thứ tự nhạt -> đậm
     như tài liệu gốc; mọi màu xanh khác trong file này PHẢI lấy từ đây,
     không tự chọn mã hex xanh tùy ý nữa. */
  --xanh-nhat-1: #7bcff5;
  --xanh-nhat-2: #00a7e1;
  --xanh-trung-1: #3f7cbe;
  --xanh-trung-2: #1f64af;
  --xanh-dam: #002c5b;

  /* Nền trang: pha loãng Xanh nhạt 1 thay vì xám-xanh chọn tùy ý trước đây
     — để khối card nền trắng vẫn nổi rõ, nhưng nền mang đúng tông thương
     hiệu chứ không phải xám chung chung. */
  --bg: #eaf5fc;
  --card: #ffffff;
  --ink: #16191d;
  --muted: #6b7280;
  --line: #e3e6ea;
  --brand: var(--xanh-trung-2);
  --brand-dark: var(--xanh-dam);
  --ok: #0f7b4f;
  --warn: #b45309;
  --danger: #b91c1c;
  --radius: 10px;
  --font-body: "Kodchasan", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  --font-heading: "Be Vietnam Pro", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
}

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

h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading); font-weight: 700; }
h1 { font-size: 1.6rem; margin: .2rem 0; }
h2 { font-size: 1.1rem; margin: 0 0 .8rem; }

.muted { color: var(--muted); }
.small { font-size: .85rem; }

/* --- Layout --------------------------------------------------------------- */

/* Logo canh giữa bằng lưới 3 cột (trái/giữa/phải). Đã THỬ định vị tuyệt đối
   (logo nổi độc lập, không chiếm chỗ trong luồng) trước — nhưng đo bằng ảnh
   chụp thật thì bên phải (tên + phòng ban + thẻ vai trò + 2 link) đủ dài để
   LẤN NGAY VÀO logo, chữ đè chồng lên nhau, đọc được. Lưới 3 cột thì bên
   phải chỉ bị đẩy XUỐNG DÒNG khi hết chỗ — vẫn đọc được đầy đủ, hơn hẳn chữ
   chồng chéo. Chặn xuống dòng riêng cho nhãn/nút (`.tag`, link, form) để
   dáng gọn không đổi trong đa số trường hợp; chỉ phần "tên · phòng ban" (dài
   nhất, ít quan trọng nhất) được phép xuống dòng nếu tên người dùng dài. */
.topbar {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 1rem;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 2px 12px rgba(20, 30, 55, .07);
  padding: .7rem 1.5rem;
  max-width: 1100px; width: calc(100% - 2rem); margin: 1rem auto 0;
  position: sticky; top: 1rem; z-index: 10;
}
.brand {
  /* `grid-row: 1` bắt buộc phải khai rõ ở cả 3 phần tử — thiếu dòng này thì
     trình duyệt tự xếp lưới theo THỨ TỰ TRONG HTML: brand (cột 2) đứng
     trước, chiếm hàng 1; topnav (cột 1, đứng SAU brand trong HTML) không
     "lùi lại" được để vào chung hàng 1 nữa nên tự bật sang hàng 2 — logo và
     menu tách thành hai hàng nhìn như xếp lệch nhau, dù CSS "trông có vẻ"
     đã đúng cột. Đã tự demo và đo tọa độ thật để xác nhận đúng nguyên nhân
     này trước khi sửa, không đoán. */
  grid-column: 2; grid-row: 1; justify-self: center;
  font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: .5rem;
}
.brand:hover { text-decoration: none; }
.brand-logo { height: 46px; width: auto; display: block; }
.topnav { grid-column: 1; grid-row: 1; justify-self: start; display: flex; gap: 1.2rem; flex-wrap: wrap; }
.topnav a { color: var(--muted); font-weight: 500; white-space: nowrap; }
.topbar-user {
  grid-column: 3; grid-row: 1; justify-self: end;
  display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; row-gap: .3rem;
}
.topbar-user .tag, .topbar-user a, .topbar-user form { white-space: nowrap; flex-shrink: 0; }
.topbar-user .who { font-size: .85rem; color: var(--muted); white-space: nowrap; }

/* Màn hình hẹp: 3 cột cạnh nhau (nav | logo | user-info) không đủ chỗ —
   4 link nav + tên người dùng + các nút bấm cạnh tranh cùng một hàng sẽ đè
   lên nhau. Xếp dọc thay vì cạnh nhau, mỗi khối căn giữa và tự xuống dòng
   theo nội dung của chính nó. */
@media (max-width: 720px) {
  .topbar {
    grid-template-columns: 1fr; grid-template-rows: auto auto auto;
    gap: .6rem; padding: .8rem 1rem; margin-top: .6rem;
  }
  .brand { grid-column: 1; grid-row: 1; justify-self: center; }
  .topnav {
    grid-column: 1; grid-row: 2; justify-self: center;
    justify-content: center; gap: .8rem 1rem;
  }
  .topbar-user {
    grid-column: 1; grid-row: 3; justify-self: center;
    justify-content: center;
  }
}

.page { max-width: 1100px; margin: 0 auto; padding: 1.5rem; }
/* Trang đăng nhập cần rộng hơn mức thường để card 2 nửa (mascot + form)
   không bị bó hẹp — xem base.html, khối page_class. */
.page.page-wide { max-width: 1280px; }

.page-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1.5rem; margin-bottom: 1.2rem; flex-wrap: wrap;
}
.back { display: inline-block; font-size: .9rem; margin-bottom: .8rem; color: var(--muted); }

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.2rem; margin-bottom: 1.2rem;
}
.card.narrow { max-width: 520px; }
.card.empty { text-align: center; color: var(--muted); }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; }
.two-col { display: grid; grid-template-columns: 1.4fr 1fr; gap: 1.2rem; align-items: start; }
@media (max-width: 800px) { .two-col { grid-template-columns: 1fr; } }

/* --- Thành phần ----------------------------------------------------------- */

.btn {
  display: inline-block; border: 1px solid var(--line); background: #fff;
  color: var(--ink); padding: .5rem .9rem; border-radius: 8px;
  font-size: .92rem; cursor: pointer; font-family: inherit;
}
.btn:hover { background: #f0f2f5; text-decoration: none; }
.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dark); }
.btn-danger { color: var(--danger); border-color: #f3c7c7; }
.btn-ghost { border-color: transparent; background: transparent; color: var(--muted); }
.btn-sm { padding: .3rem .7rem; font-size: .85rem; }
.btn.disabled { opacity: .45; pointer-events: none; }

.tag {
  display: inline-block; font-size: .75rem; padding: .15rem .55rem;
  border-radius: 999px; background: #eef1f6; color: var(--muted);
}
.tag-done { background: #e3f5ec; color: var(--ok); }
.tag-warn { background: #fdf0dc; color: var(--warn); }
.tag-admin { background: #e3f4fc; color: var(--brand); }

.alert { padding: .7rem .9rem; border-radius: 8px; margin-bottom: 1rem; font-size: .9rem; }
.alert-error { background: #fdecec; color: var(--danger); }
.alert-ok { background: #e3f5ec; color: var(--ok); }

.head-actions { display: flex; gap: .5rem; align-items: center; }

/* Nhiều form nhỏ nằm cạnh nhau trên một hàng (sửa nhanh, đổi thứ tự bài...) */
.inline-form { display: inline-flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.inline-form input, .inline-form select { margin-top: 0; width: auto; }
.inline-form + .inline-form { margin-top: .4rem; }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }
@media (max-width: 600px) { .row { grid-template-columns: 1fr; } }

.checkbox { display: flex; gap: .5rem; align-items: flex-start; font-weight: 400; }
.checkbox input { width: auto; margin-top: .25rem; flex: none; }

ul.plain { list-style: none; margin: 0 0 .8rem; padding: 0; }
ul.plain li { padding: .3rem 0; border-bottom: 1px solid #f0f2f5; font-size: .9rem; }
ul.plain li:last-child { border-bottom: none; }

/* Team lồng trong từng phòng ban (users.html) — thụt vào, chữ nhỏ hơn một
   chút để phân biệt rõ với dòng phòng ban chứa nó. */
.team-list { list-style: none; margin: .4rem 0 .6rem 1.3rem; padding: 0; }
.team-list li { padding: .25rem 0; border-bottom: none; font-size: .85rem; }

/* Mỗi phòng ban là một khối đóng/mở được (<details>) — danh sách nhiều phòng
   mà bung hết cùng lúc thì chiếm gần hết màn hình. */
.dept-item > summary { cursor: pointer; padding: .15rem 0; }
.dept-item > summary:hover { color: var(--brand); }
.dept-body { padding: .5rem 0 .3rem 1rem; }

button:disabled { opacity: .35; cursor: not-allowed; }

.stack { display: flex; flex-direction: column; gap: .9rem; }

/* --- Soạn đề bài kiểm tra (admin/quiz_form.html, admin/question_form.html) */

/* Hai ô cài đặt + nút Lưu nằm ngang trên MỘT hàng. Ô số phải tự đặt bề rộng
   vì luật chung là `input { width: 100% }` — một ô nhập số "80" dài hết khung
   rộng cả trang trông rất dở, mà cũng làm khung cài đặt cao vô ích. */
.cai-dat-hang {
  display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap;
}
.cai-dat-hang label { flex: none; }
.cai-dat-hang input[type="number"] { width: 11rem; }

/* Ô chọn chỉ có 2 lựa chọn — kéo dài hết khung rộng cả trang thì trống trải,
   giữ hẹp lại cho vừa nội dung. */
.o-hep { max-width: 22rem; }

/* 6 ô đáp án xếp 2 CỘT khi khung đủ rộng (form thêm câu hỏi rộng cả trang):
   xếp 1 cột thì riêng khối đáp án đã cao gần bằng toàn bộ phần còn lại của
   form. Form sửa một câu hỏi (question_form.html) nằm trong .card.narrow nên
   cố tình KHÔNG dùng lưới này — 2 cột trong 520px thì mỗi ô quá chật. */
.dap-an-luoi { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem .9rem; }
.dap-an-luoi .dap-an-hang { margin-bottom: 0; }
@media (max-width: 700px) { .dap-an-luoi { grid-template-columns: 1fr; } }

/* Một hàng đáp án: ô nhập nội dung + hộp "Đúng". Ô nhập chiếm hết chỗ còn
   lại, hộp "Đúng" giữ nguyên bề rộng chữ — flex-shrink:0 để không bị bóp khi
   ô nội dung dài. */
.dap-an-hang {
  display: flex; align-items: center; gap: .7rem;
  margin-bottom: .5rem;
}
.dap-an-hang input[type="text"] { margin-top: 0; }
.dap-an-dung {
  display: flex; align-items: center; gap: .35rem;
  flex-shrink: 0; white-space: nowrap;
  font-weight: 400; font-size: .88rem;
}
.dap-an-dung input[type="checkbox"] { width: auto; margin: 0; }

/* --- Làm bài / xem lại bài kiểm tra (quiz_take.html, quiz_result.html) --- */

.cau-hoi-lam-bai, .cau-hoi-xem-lai { margin-bottom: 1rem; }
.cau-hoi-so {
  margin: 0 0 .4rem; font-size: .82rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: .03em;
  display: flex; align-items: center; gap: .6rem;
}
.cau-hoi-noi-dung { margin: 0 0 .8rem; font-size: 1.05rem; font-weight: 600; }

.dap-an-list { display: flex; flex-direction: column; gap: .5rem; }
.dap-an-item {
  display: flex; align-items: center; gap: .6rem;
  padding: .6rem .8rem; border: 1px solid var(--line); border-radius: 8px;
  font-weight: 400; cursor: pointer;
}
.dap-an-item:hover { background: #f7f8fa; }
.dap-an-item input { width: auto; margin: 0; }

.dap-an-xem-lai { list-style: none; margin: 0; padding: 0; }
.dap-an-xem-lai li {
  padding: .55rem .8rem; border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: .4rem; font-size: .95rem;
}
/* Đã chọn: viền xanh thương hiệu — trung tính, không tự ý nói "đúng hay sai".
   Sai/đúng chỉ tô màu khi CHẮC CHẮN được phép hiện (nhánh xem_duoc_dap_an). */
.dap-an-xem-lai li.da-chon { border-color: var(--brand); background: #eef4fb; }
.dap-an-xem-lai li.la-dap-an-dung { border-color: var(--ok); background: #eaf6ef; }
.dap-an-xem-lai li.da-chon.la-dap-an-dung { background: #dcf3e6; }
/* Đã chọn nhưng KHÔNG phải đáp án đúng — chỉ tô đỏ khi có cả hai class, tức
   chỉ trong nhánh được xem đáp án; nhánh còn lại không có class thứ hai để
   mà khớp luật này. */
.dap-an-xem-lai li.da-chon:not(.la-dap-an-dung) { border-color: var(--danger); background: #fbebeb; }
label { font-size: .88rem; font-weight: 500; display: block; }
input, textarea, select {
  width: 100%; margin-top: .3rem; padding: .55rem .7rem; font-size: .95rem;
  border: 1px solid var(--line); border-radius: 8px; font-family: inherit;
  background: #fff; color: var(--ink);
}
input[type="range"] { padding: 0; }
input:focus, textarea:focus { outline: 2px solid #cfeaf9; border-color: var(--brand); }

.bar { height: 8px; background: #e9ecf1; border-radius: 999px; overflow: hidden; margin: .5rem 0 .3rem; }
.bar-thin { height: 6px; margin: .2rem 0; min-width: 90px; }
.bar-fill { height: 100%; background: var(--brand); border-radius: 999px; transition: width .3s; }
.bar-label { font-size: .85rem; color: var(--muted); }

/* Bọc ngoài <table> để cuộn ngang trên màn hình hẹp — không co cột/vỡ chữ
   như tự động chèn xuống dòng, chỉ vuốt sang ngang để xem hết. */
.table-wrap { overflow-x: auto; }

/* Bảng dài thì cuộn TRONG khung thay vì kéo dài cả trang — càng nhiều khóa học
   thì trang càng dài, mà mấy thứ nằm dưới bảng bị đẩy ra khỏi tầm mắt.
   `max-height` theo vh chứ không theo px cố định: màn hình laptop 13" và màn
   hình rời 27" khác nhau nhiều, cố định px thì một trong hai luôn sai. */
.table-scroll { overflow-y: auto; max-height: min(60vh, 34rem); }

/* Tiêu đề cột phải dính lại khi cuộn. Không dính thì cuộn xuống vài dòng là
   mất tên cột, đọc số mà không biết số của cột nào — cuộn xong còn khó hiểu
   hơn lúc chưa cuộn. */
.table-scroll .table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--card);
  /* thead dính cần đường kẻ riêng: border của chính nó bị cuộn qua mất trong
     một số trình duyệt, nên vẽ bằng box-shadow để luôn thấy. */
  box-shadow: inset 0 -1px 0 var(--line);
}
.table { width: 100%; border-collapse: collapse; font-size: .9rem; }
@media (max-width: 720px) {
  .table-wrap .table { min-width: 560px; }
}
.table th {
  text-align: left; font-weight: 600; color: var(--muted); font-size: .8rem;
  text-transform: uppercase; letter-spacing: .02em;
  padding: .5rem .6rem; border-bottom: 1px solid var(--line);
}
.table td { padding: .65rem .6rem; border-bottom: 1px solid #f0f2f5; vertical-align: top; }

/* Khối "Quá hạn" ở bảng điều khiển: đúng 3 dòng cao, hết 3 dòng thì TRƯỢT
   NGANG sang nhóm 3 người tiếp theo thay vì kéo dài cả trang hay cuộn dọc.
   grid-auto-flow: column + grid-template-rows: repeat(3, ...) tự xếp cứ 3
   phần tử thì sang cột (trang) mới; grid-auto-columns: 100% làm mỗi cột
   rộng đúng bằng khung nhìn, nên cuộn ngang tự "nhảy" theo từng cụm 3
   người một, không dừng lửng giữa chừng (kết hợp scroll-snap). Vì mỗi
   dòng có 4 mốc (họ tên/phòng ban/khóa học/trễ) dùng chung một track hàng
   trên mọi cột, chiều cao 3 hàng luôn khớp nhau giữa các trang. */
.qua-han-head-row, .qua-han-row {
  display: grid; grid-template-columns: 1.3fr 1fr 1.6fr 1fr; gap: .6rem; align-items: center;
}
.qua-han-head-row {
  font-weight: 600; color: var(--muted); font-size: .8rem;
  text-transform: uppercase; letter-spacing: .02em;
  padding: .3rem .6rem .6rem; border-bottom: 1px solid var(--line);
}
.qua-han-carousel { display: flex; align-items: stretch; gap: .5rem; }
.qua-han-scroll {
  flex: 1; min-width: 0;
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(3, auto);
  grid-auto-columns: 100%;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
}
.qua-han-row {
  scroll-snap-align: start;
  padding: .65rem .6rem; border-bottom: 1px solid #f0f2f5;
}
.qua-han-row[hidden] { display: none; }
.qua-han-trong { display: block; text-align: center; color: var(--muted); padding: 1.5rem; }
.qua-han-trong[hidden] { display: none; }
.qua-han-nav {
  flex: none; align-self: center; width: 2.1rem; height: 2.1rem;
  border: 1px solid var(--line); background: #fff; border-radius: 50%;
  cursor: pointer; font-size: 1.2rem; line-height: 1; color: var(--muted);
}
.qua-han-nav:hover { background: #f0f2f5; color: var(--ink); }

/* Màn hình hẹp: 4 cột cạnh nhau không đủ chỗ, chữ vỡ dòng liên tục trong
   cột hẹp tí xíu. Xếp dọc từng mục thành một thẻ nhỏ thay vì bảng — ẩn luôn
   header hàng ngang vì không còn khớp với bố cục dọc nữa. */
@media (max-width: 720px) {
  .qua-han-head-row { display: none; }
  .qua-han-row { grid-template-columns: 1fr; gap: .25rem; padding: .8rem .7rem; }
}

/* Khu bộ lọc phía trên bảng tài khoản: ô tìm + các dropdown, xuống dòng gọn
   trên màn hình hẹp thay vì tràn ngang. */
.bo-loc { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.bo-loc input, .bo-loc select { margin-top: 0; width: auto; }
.bo-loc input[type="search"] { min-width: 16em; }

/* Trên điện thoại, ô tìm chiếm cả hàng thay vì để trống bên phải — ô tìm là
   thứ dùng nhiều nhất trong thanh lọc, cho nó rộng nhất. Các ô chọn tự chia
   nhau hàng dưới. */
@media (max-width: 560px) {
  .bo-loc { width: 100%; }
  .bo-loc input[type="search"] { flex: 1 1 100%; min-width: 0; }
  .bo-loc select { flex: 1 1 44%; min-width: 0; }
}

/* Dropdown "Ai học khóa này" (app/templates/admin/course_form.html): một
   <details> duy nhất, mở ra là cây Cả công ty -> phòng ban -> team -> người,
   mỗi dòng một ô tick. Danh sách cuộn riêng trong khung để công ty đông người
   không kéo dài cả trang. */
.field-label { font-size: .88rem; font-weight: 500; display: block; }
.pham-vi { margin-top: .3rem; position: relative; }
.pham-vi-summary {
  list-style: none; cursor: pointer; padding: .55rem 2rem .55rem .7rem;
  border: 1px solid var(--line); border-radius: 8px; background: #fff;
  font-size: .95rem; position: relative;
}
.pham-vi-summary::-webkit-details-marker { display: none; }
.pham-vi-summary::after {
  content: "▾"; position: absolute; right: .7rem; top: 50%;
  transform: translateY(-50%); color: var(--muted);
}
.pham-vi[open] .pham-vi-summary { border-color: var(--brand); }
.pham-vi[open] .pham-vi-summary::after { content: "▴"; }
.pham-vi-panel {
  border: 1px solid var(--line); border-radius: 8px; margin-top: .3rem;
  background: #fff; padding: .5rem .6rem;
}
.pham-vi-tim { margin-top: 0; }
.pham-vi-list, .pham-vi-list ul { list-style: none; margin: 0; padding: 0; }
.pham-vi-list { max-height: 320px; overflow-y: auto; margin-top: .4rem; }
.pham-vi-list ul { padding-left: 1.4rem; }
.pv-muc { padding: .25rem 0; }
.pv-muc .checkbox { font-size: .92rem; }
.pv-sau { padding-left: 1.4rem; }
.pv-cong-ty { border-bottom: 1px solid var(--line); padding-bottom: .45rem; margin-bottom: .2rem; }
.pv-nhom + .pv-nhom { border-top: 1px dashed var(--line); margin-top: .2rem; padding-top: .2rem; }
/* Ô con đã nằm trong một mục cha đang tick — khóa lại, nhạt đi. */
.pv-muc input:disabled + * , .pv-muc input:disabled ~ * { opacity: .55; }

/* Mật khẩu ban đầu trong danh sách tài khoản — chữ đều nét để đọc/chép không
   nhầm l với 1, O với 0; nền nhạt để thấy rõ đâu là đầu và cuối chuỗi. */
.mat-khau-ban-dau {
  font-family: Consolas, "Courier New", monospace; font-size: .88rem;
  background: #f2f4f8; border: 1px solid var(--line); border-radius: 5px;
  padding: .12rem .4rem; user-select: all;
}

/* Khung sửa mở rộng dưới mỗi dòng tài khoản (users.html). Ẩn/hiện bằng thuộc
   tính HTML `hidden`, do toggle_row.js đặt — không đặt sẵn `hidden` trong
   HTML, để trang vẫn dùng được đầy đủ nếu JS không chạy (khung hiện sẵn, chỉ
   mất phần gọn gàng chứ không mất chức năng). */
.edit-panel { background: #f8f9fb; border: 1px solid var(--line); border-radius: 8px; padding: 1rem 1.2rem; }
.edit-panel form + form { margin-top: 1rem; padding-top: 1rem; border-top: 1px dashed var(--line); }

/* Khi khung sửa của một tài khoản đang mở: gộp dòng tóm tắt + khung sửa
   thành MỘT khối liền màu (bỏ đường kẻ ở giữa), rồi kẻ đậm hẳn đường ranh
   giới ở CUỐI khối — để không lẫn với tài khoản kế tiếp. Không có cặp luật
   này, hai đường kẻ (giữa tóm tắt/khung sửa, và giữa khung sửa/tài khoản
   sau) nhạt như nhau, nhìn không biết đâu là ranh giới thật. */
.table tr.account-row.is-editing td { background: #f8f9fb; border-bottom: none; }
.table tr[data-edit-panel]:not([hidden]) td { border-bottom: 2px solid var(--line); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .8rem; margin-bottom: 1.2rem; }
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .9rem 1rem; display: flex; flex-direction: column;
}
.stat-value { font-size: 1.7rem; font-weight: 600; line-height: 1.1; }
.stat-label { font-size: .8rem; color: var(--muted); }
.stat-warn .stat-value { color: var(--warn); }

/* --- Khóa học ------------------------------------------------------------- */

.course-card { display: block; color: inherit; transition: box-shadow .15s, transform .15s; }
.course-card:hover { text-decoration: none; box-shadow: 0 4px 14px rgba(20, 30, 55, .09); transform: translateY(-1px); }
.course-card h2 { margin: .5rem 0 .3rem; font-size: 1.05rem; }
.clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.8em; }
.course-meta { display: flex; gap: 1rem; font-size: .82rem; color: var(--muted); margin-top: .6rem; }

.lesson-list { list-style: none; margin: 0; padding: 0; counter-reset: lesson; }
.lesson-row {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: .75rem 0; border-bottom: 1px solid #f0f2f5;
}
.lesson-row:last-child { border-bottom: none; }
.lesson-row.locked { opacity: .55; }
.lesson-main { display: flex; align-items: center; gap: .8rem; }
.lesson-index {
  width: 26px; height: 26px; flex: none; border-radius: 50%; background: #eef1f6;
  color: var(--muted); display: grid; place-items: center; font-size: .8rem; font-weight: 600;
}
.lesson-title { font-weight: 500; }

/* --- Biểu đồ tiến độ ở bảng điều khiển ------------------------------------

   Toàn bộ vẽ bằng CSS, không SVG và không thư viện: hai hình cần vẽ là thanh
   ngang và thanh xếp lớp, mà cả hai chỉ là hộp có chiều rộng theo phần trăm.
   Kéo cả thư viện đồ thị vào cho hai hình đó là thêm phụ thuộc, thêm dung
   lượng, và vướng Content-Security-Policy (script-src chỉ cho 'self').

   Sắc nhạt của khay và của ô chú giải viết thẳng bằng mã màu chứ không dùng
   color-mix(): giữ đúng lối viết của phần còn lại trong file này, và chạy được
   trên cả trình duyệt cũ hơn. */

.tien-do {
  display: grid;
  gap: 1.6rem 2.4rem;
  grid-template-columns: minmax(13rem, 18rem) 1fr;
  align-items: start;
}
@media (max-width: 760px) {
  .tien-do { grid-template-columns: 1fr; }
}

.tien-do-nhan {
  margin: 0 0 .5rem;
  font-size: .8rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .03em;
}

/* Con số dẫn dắt: cỡ lớn, cùng bộ chữ với mọi thứ khác. Dùng chữ số theo tỷ lệ
   tự nhiên (không tabular-nums) — tabular cho mọi chữ số bề rộng của số 0, ở cỡ
   lớn nhìn rời rạc. Tabular chỉ để dành cho cột số cần thẳng hàng. */
.tien-do-so {
  margin: 0 0 .15rem;
  font-size: 3.2rem;
  line-height: 1;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -.02em;
}

/* Thanh đo. Đầu bên phải là đầu DỮ LIỆU nên bo 4px; đầu bên trái là gốc nên để
   vuông. Khay dùng sắc nhạt cùng gốc màu với phần đầy, để trạng thái đọc được
   trên cả chiều dài thanh chứ không chỉ ở phần đã tô. */
.do {
  height: 10px;
  border-radius: 0 5px 5px 0;
  overflow: hidden;
  margin-top: .7rem;
}
.tien-do-ghi-chu { margin: .55rem 0 0; }
.do-day { height: 100%; border-radius: 0 5px 5px 0; }

.do-tot      { background: #dbe7f5; }
.do-tot  .do-day { background: var(--brand); }
.do-vua      { background: #f6e6d5; }
.do-vua  .do-day { background: var(--warn); }
.do-kem      { background: #f7dcdc; }
.do-kem  .do-day { background: var(--danger); }

/* Thanh xếp lớp. Các đoạn tách nhau bằng KHE màu nền, không phải bằng viền —
   viền làm dày mảng màu và đọc nặng hơn hẳn ở cỡ nhỏ. */
.xep-lop {
  display: flex;
  gap: 2px;
  height: 26px;
  margin: .1rem 0 .9rem;
}

.lop {
  flex-grow: 0;
  flex-shrink: 1;
  min-width: 3px;
  display: grid;
  place-items: center;
  border-radius: 2px;
  overflow: hidden;
}
/* Đầu ngoài cùng của cả thanh mới bo 4px; các mối nối bên trong để vuông vì
   chúng không phải đầu dữ liệu. */
.lop:first-child { border-radius: 4px 2px 2px 4px; }
.lop:last-child  { border-radius: 2px 4px 4px 2px; }
.lop:only-child  { border-radius: 4px; }

.lop span {
  font-size: .78rem;
  font-weight: 600;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.lop-xong      { background: var(--ok); }
.lop-trong-han { background: var(--brand); }
.lop-tre       { background: var(--danger); }
.lop-rong      { background: var(--line); flex-basis: 100%; }

/* Chú giải mang đủ số của từng nhóm — số liệu không được chỉ nằm ở màu. */
.chu-giai {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1.4rem;
  font-size: .88rem;
}
.chu-giai li { display: flex; align-items: center; gap: .4rem; }
.chu-giai b { font-weight: 600; }

/* Riêng mục "Quá hạn" bấm được để mở popup danh sách từng người — kế thừa hệt
   như <li> thường (không viền, không nền) rồi chỉ thêm con trỏ tay + gạch
   chân khi rê chuột, để không rối mắt so với hai mục còn lại. */
.chu-giai-nut {
  display: flex; align-items: center; gap: .4rem;
  border: none; background: none; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
}
.chu-giai-nut:hover { text-decoration: underline; }
.chu-giai-nut:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.o { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.o-xong      { background: var(--ok); }
.o-trong-han { background: var(--brand); }
.o-tre       { background: var(--danger); }

/* --- Trình phát ----------------------------------------------------------- */

.lesson-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }

.player-shell {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; margin-bottom: 1.2rem;
}
.video-frame { position: relative; background: #000; aspect-ratio: 16 / 9; }
.video-frame video { width: 100%; height: 100%; display: block; }

/* --- Bài học là tài liệu -------------------------------------------------

   Dùng chung khung với trình phát video để hai loại bài học trông là một hệ
   thống, chỉ khác phần ruột.

   Chiều cao đặt theo chiều cao MÀN HÌNH chứ không theo tỷ lệ khung như video:
   tài liệu là trang dọc, ép vào khung 16/9 thì mỗi lần chỉ thấy được vài dòng
   và người đọc phải cuộn liên tục trong một ô hẹp. `min-height` giữ cho khung
   không bị dẹt trên màn hình laptop thấp. */
.doc-shell {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; margin-bottom: 1.2rem;
  position: relative;
}
.doc-frame {
  background: #525659;  /* nền xám của trình xem PDF, để không lóe trắng lúc tải */
  height: min(78vh, 900px);
  min-height: 420px;
}
.doc-frame iframe { width: 100%; height: 100%; display: block; border: 0; }
.doc-loi { display: grid; place-items: center; color: #fff; text-align: center; padding: 2rem; }

/* Cột ảnh từng trang. Cuộn bên trong khung chứ không kéo dài cả trang, để
   thanh tiến độ và nút chuyển bài luôn nằm trong tầm mắt. */
.doc-trang {
  height: min(78vh, 900px);
  min-height: 420px;
  overflow-y: auto;
  overflow-x: hidden;
  background: #525659;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  /* Chặn bôi đen: ảnh thì không có chữ để bôi, nhưng thao tác kéo bôi vẫn
     tạo ra vùng chọn xanh nhấp nháy trông như trang bị lỗi. */
  user-select: none;
  -webkit-user-select: none;
}

.doc-anh {
  display: block;
  max-width: 100%;
  width: min(100%, 860px);
  height: auto;
  background: #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, .35);
  /* Chặn menu "Lưu ảnh" của iOS/Android khi nhấn giữ. */
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
}

@media (max-width: 640px) {
  .doc-trang { height: 82vh; min-height: 340px; padding: .5rem; gap: .5rem; }
}

/* In trang: bỏ trắng phần tài liệu.
 *
 * Nói rõ đây KHÔNG phải lớp chặn thật — "In ra PDF" của trình duyệt là một
 * đường sao chép hoàn toàn hợp lệ mà trang web không có quyền cấm. Đoạn này
 * chỉ khiến thao tác Ctrl+P quen tay ra một tờ giấy trắng kèm lời nhắc, thay
 * vì lặng lẽ đưa cho người ta bản sao sạch không có dấu.
 */
@media print {
  .doc-trang, .doc-anh, .video-frame, .doc-frame { display: none !important; }
  .doc-shell::after {
    content: "Tài liệu đào tạo nội bộ — không in được. Hãy xem trong hệ thống.";
    display: block;
    padding: 2rem;
    font-size: 1rem;
  }
}

/* Màn hình hẹp: cho khung cao hơn theo tỷ lệ, vì trên điện thoại phần chữ bị
   thu nhỏ nhiều hơn nên cần thêm chiều cao mới đọc được ngần ấy nội dung. */
@media (max-width: 640px) {
  .doc-frame { height: 82vh; min-height: 340px; }
}

/* --- Tab chọn hình thức bài học (trang quản trị) --------------------------

   Chuyển tab bằng CSS thuần: radio bị ẩn khỏi mắt nhưng KHÔNG dùng
   `display:none` — làm vậy là bàn phím không tới được nó nữa và trình đọc màn
   hình cũng bỏ qua. Đẩy ra ngoài vùng nhìn thay thế, radio vẫn còn nguyên
   trong cây tài liệu. */
.ht-radio {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.ht-tab {
  display: flex;
  gap: .3rem;
  border-bottom: 1px solid var(--line);
  margin: 0 0 1rem;
}
.ht-tab label {
  padding: .55rem .95rem;
  cursor: pointer;
  font-size: .92rem;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  user-select: none;
}
.ht-tab label:hover { color: var(--ink); }

/* Tab đang chọn. Bộ chọn `~` chỉ với được phần tử ĐỨNG SAU và cùng cấp cha,
   nên hai radio phải nằm trước cả thanh tab lẫn hai khối nội dung. */
#ht-video:checked ~ .ht-tab label[for="ht-video"],
#ht-tep:checked ~ .ht-tab label[for="ht-tep"] {
  color: var(--brand);
  border-bottom-color: var(--brand);
}

/* Bàn phím Tab tới radio: phải thấy được đang ở đâu, nếu không thì người dùng
   bàn phím bấm mũi tên trong bóng tối. */
#ht-video:focus-visible ~ .ht-tab label[for="ht-video"],
#ht-tep:focus-visible ~ .ht-tab label[for="ht-tep"] {
  outline: 2px solid var(--brand);
  outline-offset: -2px;
  border-radius: 4px 4px 0 0;
}

/* Ẩn khối KHÔNG được chọn, thay vì hiện khối được chọn — cách này giữ đúng
   một khối hiện ngay từ HTML kể cả khi CSS chưa tải xong. */
#ht-video:checked ~ #khoi-tep,
#ht-tep:checked ~ #khoi-video { display: none; }

.video-overlay {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(0, 0, 0, .28); transition: opacity .2s;
}
.video-overlay.hidden { opacity: 0; pointer-events: none; }
.big-play {
  width: 64px; height: 64px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255, 255, 255, .9); font-size: 1.5rem; color: #16191d;
}

.toast {
  position: absolute; left: 50%; bottom: 1rem; transform: translateX(-50%);
  background: rgba(20, 20, 24, .9); color: #fff; padding: .5rem .9rem;
  border-radius: 8px; font-size: .85rem; white-space: nowrap;
}

.controls { display: flex; align-items: center; gap: .9rem; padding: .8rem 1rem; }
.track {
  flex: 1; position: relative; height: 18px; cursor: pointer; display: flex; align-items: center;
}
.track::before {
  content: ""; position: absolute; left: 0; right: 0; height: 6px;
  background: #e2e5ea; border-radius: 999px;
}
.track-watched, .track-played {
  position: absolute; left: 0; height: 6px; border-radius: 999px;
}
/* Vùng đã xem = vùng duy nhất được phép tua lại. */
.track-watched { background: #bfe0f5; }
.track-played { background: var(--brand); }
.track-knob {
  position: absolute; width: 12px; height: 12px; border-radius: 50%;
  background: var(--brand); transform: translateX(-50%); pointer-events: none;
}
.time { font-size: .85rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.volume { display: flex; align-items: center; gap: .4rem; width: 130px; font-weight: 400; }
.volume input { margin-top: 0; }

.progress-note { padding: 0 1rem 1rem; }
.lesson-nav { display: flex; justify-content: space-between; gap: 1rem; }

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

/* Bọc giữa trang theo cả chiều ngang lẫn dọc — dùng cho login và các trang
   chỉ có đúng một khối nội dung (đổi mật khẩu), không phải trang có nhiều
   card cạnh nhau. */
.center-page { display: grid; place-items: center; min-height: 70vh; padding: 1rem; }

/* Card đăng nhập chia 2 nửa: minh họa bên trái, form bên phải. Bỏ padding
   mặc định của .card vì mỗi nửa tự đặt padding riêng — nửa trái cần nền màu
   tràn hết viền, padding chung sẽ để lộ viền trắng quanh nó. Cột bằng nhau
   (1fr 1fr) để đường phân cách uốn lượn (.login-wave) nằm đúng giữa card,
   không phải tính lại theo tỉ lệ cột lệch. */
.login-card {
  width: 100%; max-width: 1140px; padding: 0; position: relative;
  display: grid; grid-template-columns: 1fr 1fr;
  overflow: hidden; align-items: stretch;
  /* Bo tròn hẳn lên + đổ bóng rõ để card nổi hẳn khỏi nền, không dùng viền
     mảnh (border) của .card mặc định nữa — bóng đã đủ tách khối. */
  border: none; border-radius: 28px;
  box-shadow: 0 24px 60px -12px rgba(0, 44, 91, .28), 0 4px 18px rgba(0, 44, 91, .1);
  /* Nền xanh đặt ở CHÍNH card, tràn hết cả 2 cột — nửa form không tự tô
     trắng nữa mà để .login-wave "vẽ" phần trắng đè lên theo hình sóng, chỗ
     nào sóng lõm vào thì lộ màu xanh của card ra, tạo đúng hiệu ứng ranh
     giới uốn lượn (không phải một đường kẻ thẳng chồng lên trên). */
  background: linear-gradient(160deg, #d5eefb 0%, #f3fafd 100%);
}
.login-illustration {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 3rem;
}
.login-mascot { width: 100%; max-width: 380px; height: auto; display: block; }
.login-fields {
  position: relative; z-index: 1; background: none;
  padding: 3.4rem 4rem; display: flex; flex-direction: column; justify-content: center;
}
/* Ảnh logo có sẵn một dải trong suốt khá dày ở trên và dưới — phần hình thật
   chỉ chiếm khoảng một nửa chiều cao tệp. Nên chiều cao ở đây phải đặt gấp đôi
   kích thước muốn thấy, và margin âm phía trên để hút lại chỗ trống đó thay vì
   đẩy dòng chào xuống. */
.login-logo {
  display: block; margin: -1.2rem auto -0.9rem;
  height: 118px; width: auto; max-width: 100%;
}
/* Căn giữa cho thẳng trục với logo ngay trên nó — chỉ dòng chào này, các nhãn
   và ô nhập bên dưới vẫn căn lề trái như thường. Margin dưới của .login-logo
   âm là để hút lại dải trong suốt của ảnh, cho dòng chào nằm sát logo. */
.login-fields h1 { margin: 0 0 1.1rem; font-size: 2.6rem; text-align: center; }

/* Phủ kín cả card, vẽ đúng phần "lẽ ra là nền trắng của nửa form" nhưng với
   biên bên trái uốn lượn (xem path trong login.html) thay vì thẳng đứng —
   chỗ sóng lõm về bên phải thì để lộ màu xanh của .login-card bên dưới. */
.login-wave {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; fill: var(--card); pointer-events: none;
}

.forgot-link {
  display: inline-block; margin-top: .9rem; font-size: .88rem; color: var(--muted);
}
.forgot-link:hover { color: var(--brand); text-decoration: underline; }

.demo-hint {
  margin-top: 1.3rem; padding-top: 1rem; border-top: 1px dashed var(--line);
  font-size: .85rem; color: var(--muted);
}
.demo-hint table { margin-top: .4rem; border-collapse: collapse; }
.demo-hint td { padding: .15rem .8rem .15rem 0; font-family: Consolas, monospace; }

/* Xếp dọc trên màn hình hẹp: minh họa co lại thành dải trên, form bên dưới,
   thay vì bị bóp ngang tới mức vỡ chữ. Sóng dọc chỉ hợp khi 2 nửa nằm CẠNH
   NHAU — xếp chồng lên nhau thì ẩn đi, không thì cắt ngang giữa card. */
/* Thanh điều khiển có 4 thứ (phát / thanh tiến độ / thời gian / âm lượng) —
   trên điện thoại một hàng không đủ chỗ, cho xuống dòng và để thanh tiến độ
   chiếm trọn hàng đầu thay vì bị bóp còn vài chục pixel. */
@media (max-width: 560px) {
  .controls { flex-wrap: wrap; gap: .6rem .8rem; }
  .controls .track { order: -1; flex-basis: 100%; }
  .volume { width: 92px; }
}

@media (max-width: 640px) {
  .login-card { grid-template-columns: 1fr; }
  .login-illustration { padding: 1.2rem; }
  .login-mascot { max-width: 170px; }
  .login-fields { padding: 2rem 1.6rem; background: var(--card); }
  .login-fields h1 { font-size: 1.9rem; }
  .login-wave { display: none; }
}

/* --- Popup trượt lên rồi dừng giữa màn hình (vd "Quên mật khẩu?", xem
   sheet.js) --------------------------------------------------------------- */

.sheet-backdrop {
  position: fixed; inset: 0; background: rgba(20, 30, 55, .45);
  display: flex; align-items: center; justify-content: center;
  padding: 1rem; z-index: 50; opacity: 0; transition: opacity .25s ease;
}
.sheet-backdrop[hidden] { display: none; }
.sheet-backdrop.is-open { opacity: 1; }

.sheet-panel {
  position: relative; width: 100%; max-width: 540px;
  background: var(--card); border-radius: 24px;
  padding: 3.2rem 2.4rem; text-align: center; font-size: 1.1rem;
  box-shadow: 0 10px 40px rgba(20, 30, 55, .25);
  /* Trượt lên từ dưới rồi dừng lại NGAY GIỮA MÀN HÌNH — không phải ghé sát
     mép dưới như bản trước — nên "lên" ở đây chỉ là quãng đường ngắn cho có
     hiệu ứng, không phải đẩy hẳn ra rìa. */
  transform: translateY(40px); opacity: 0;
  transition: transform .28s ease, opacity .28s ease;
}
.sheet-backdrop.is-open .sheet-panel { transform: translateY(0); opacity: 1; }

/* Ảnh CẢNH trong popup (mascot đang làm gì đó), khác `.sheet-avatar` là ảnh
   chân dung cắt tròn. Không cắt tròn ở đây vì cắt là mất mất cái laptop — mà
   cái laptop mới là chỗ kể câu chuyện. */
.sheet-canh {
  display: block; margin: 0 auto 1.2rem;
  width: 100%; max-width: 280px; height: auto;
}

.sheet-avatar {
  width: 168px; height: 168px; object-fit: cover; border-radius: 50%;
  display: block; margin: 0 auto 1.4rem;
  border: 4px solid #fff; box-shadow: 0 4px 16px rgba(20, 30, 55, .2);
}
.sheet-panel p { margin: 0; font-weight: 500; }

/* Biến thể rộng, căn trái — dùng cho popup chứa BẢNG NHIỀU CỘT (danh sách quá
   hạn) thay vì một câu thông báo ngắn. `.sheet-panel` mặc định căn giữa và hẹp
   (max-width 540px), hợp với "Quên mật khẩu?" nhưng một bảng 4 cột căn giữa
   thì đọc rất khó chịu — chữ nhảy lung tung theo độ dài từng dòng. */
.sheet-panel-rong {
  max-width: 900px;
  text-align: left;
  padding: 1.6rem 1.8rem;
  max-height: 85vh;
  overflow-y: auto;
}
@media (max-width: 640px) {
  .sheet-panel-rong { padding: 1.3rem 1rem; }
}

.sheet-close {
  position: absolute; top: .9rem; right: 1.1rem;
  border: none; background: none; color: var(--muted);
  font-size: 1.7rem; line-height: 1; padding: .3rem .6rem; cursor: pointer;
}
.sheet-close:hover { color: var(--ink); }

/* --- Hiệu ứng tràn màu khi đăng nhập thành công (login_transition.js) ----- */

.login-flood {
  position: fixed; border-radius: 50%; background: var(--brand);
  transform: translate(-50%, -50%) scale(0);
  transition: transform .7s cubic-bezier(.65, 0, .35, 1);
  z-index: 200; pointer-events: none;
}
.login-flood.is-mo-rong { transform: translate(-50%, -50%) scale(1); }

/* Màn hình phủ kín đầu trang kế tiếp, mờ dần để lộ trang thật ra
   (page_reveal.js) — nối tiếp hình tròn tràn màu ở trên cho liền mạch giữa
   2 lượt tải trang. */
.man-hinh-chao {
  position: fixed; inset: 0; background: var(--brand); z-index: 300;
  opacity: 1; transition: opacity .6s ease;
}
.man-hinh-chao[hidden] { display: none; }
.man-hinh-chao.dang-an { opacity: 0; }

/* --- Hạn hoàn thành ------------------------------------------------------- */

/* Dùng cho dòng hạn trên thẻ khóa học: đã quá hạn thì đổi màu, không dùng tag
   vì thẻ khóa học là một <a> lớn, nhồi thêm tag làm rối bố cục. */
.text-warn { color: var(--danger); font-weight: 600; }
