/* style.css — design system "Sổ điểm danh" (spec 044, issue #287) port sang
   hub apps/api (templ + CSS thuần): giấy ấm + mực gần đen, navy ĐHBK accent
   DUY NHẤT, đỏ chỉ cảnh báo, radius 0 tuyệt đối, masthead mực full-bleed,
   motif ô đánh dấu OMR, double-rule kế toán. Token giữ 1:1 với
   apps/{student,lecturer}/web/src/index.css. Không CDN ngoài — font self-host
   ở fonts/ (subset vietnamese + latin, woff2).

   Quy ước: chỉ dùng token có sẵn — không chế màu mới (ngoài shade hover
   --red-deep của --red, song song --navy-deep của --navy). */

/* ---- Font self-host (fontsource, subset vietnamese + latin) ---- */
/* Be Vietnam Pro 400–800: UI + display. IBM Plex Mono 400–600: dữ liệu số,
   MSSV, timestamp, nhãn cap. font-display swap + unicode-range như fontsource. */
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:400;src:url(fonts/be-vietnam-pro-vietnamese-400-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:400;src:url(fonts/be-vietnam-pro-latin-400-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:500;src:url(fonts/be-vietnam-pro-vietnamese-500-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:500;src:url(fonts/be-vietnam-pro-latin-500-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:600;src:url(fonts/be-vietnam-pro-vietnamese-600-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:600;src:url(fonts/be-vietnam-pro-latin-600-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:700;src:url(fonts/be-vietnam-pro-vietnamese-700-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:700;src:url(fonts/be-vietnam-pro-latin-700-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:800;src:url(fonts/be-vietnam-pro-vietnamese-800-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-display:swap;font-weight:800;src:url(fonts/be-vietnam-pro-latin-800-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-display:swap;font-weight:400;src:url(fonts/ibm-plex-mono-vietnamese-400-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-display:swap;font-weight:400;src:url(fonts/ibm-plex-mono-latin-400-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-display:swap;font-weight:500;src:url(fonts/ibm-plex-mono-vietnamese-500-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-display:swap;font-weight:500;src:url(fonts/ibm-plex-mono-latin-500-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-display:swap;font-weight:600;src:url(fonts/ibm-plex-mono-vietnamese-600-normal.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-display:swap;font-weight:600;src:url(fonts/ibm-plex-mono-latin-600-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* ---- Token (spec 044, 1:1 với index.css của 2 SPA) ---- */
:root {
  --paper: #f5f1e8;            /* giấy ấm — nền trang tính */
  --ink: #15171f;              /* mực gần đen — chữ, khung, masthead */
  --navy: #1c3aa9;             /* navy ĐHBK — accent duy nhất */
  --navy-deep: #16307f;
  --navy-tint: #e9ecf8;
  --paper-shade: #eae4d5;      /* giấy đậm hơn — nền phụ/hover */
  --red: #b42318;              /* chỉ hành động phá dữ liệu + lỗi */
  --red-deep: #8f1c13;         /* shade hover của đỏ */
  --muted-ink: #4a4e5c;        /* chữ phụ — 7.3:1 trên paper */
  --hair: rgba(21, 23, 31, 0.22);
  --hair-strong: rgba(21, 23, 31, 0.45);
  --font-sans: 'Be Vietnam Pro', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
}
a { color: var(--navy); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, summary:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

/* cap — nhãn mono viết hoa tracking rộng (thẻ phụ, tiêu đề phụ, login). */
.cap {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-ink);
}

/* Monogram "BK" — ô navy đặc, nét khung trong (port brand.tsx của SPA). */
.monogram {
  display: inline-grid;
  place-items: center;
  width: 2.15rem;
  height: 2.15rem;
  background: var(--navy);
  color: #fff;
  font-weight: 800;
  font-size: 0.95rem;
  line-height: 1;
  letter-spacing: 0.02em;
  position: relative;
}
.monogram::after {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid rgba(255, 255, 255, 0.35);
}

/* ---- Masthead mực full-bleed (UserLayout) — port masthead.tsx của SPA ---- */
header.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  min-height: 3.5rem;
  padding: 0.4rem 1.25rem;
  background: var(--ink);
  color: var(--paper);
  border-bottom: 3px solid var(--navy);
}
header.topbar a.brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  color: var(--paper);
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none;
}
header.topbar a.brand:hover { text-decoration: none; }
header.topbar .brand-name { line-height: 1.15; }
header.topbar .brand-sub {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(245, 241, 232, 0.7);
  font-weight: 500;
}
header.topbar nav { display: flex; gap: 1.1rem; flex-wrap: wrap; align-items: center; }
header.topbar nav a {
  color: rgba(245, 241, 232, 0.78);
  font-size: 0.92rem;
  padding: 0.3rem 0;
  border-bottom: 2px solid transparent;
}
header.topbar nav a.active {
  color: #fff;
  border-bottom-color: rgba(245, 241, 232, 0.9);
  font-weight: 500;
}
header.topbar nav a:hover { color: #fff; text-decoration: none; }
header.topbar .spacer { flex: 1; }
header.topbar .me { color: rgba(245, 241, 232, 0.82); font-size: 0.88rem; }
/* Ô đánh dấu nhỏ lặp motif ở mép phải masthead (mirror masthead.tsx). */
header.topbar .masthead-mark {
  width: 0.75rem;
  height: 0.75rem;
  background: var(--navy);
  border: 1px solid rgba(245, 241, 232, 0.5);
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  flex-shrink: 0;
}
/* Dropdown profile góc phải masthead — details/summary thuần CSS, JS ở layout
   đóng khi click ngoài. Mục account (credentials/token/admin/logout). */
details.profile-menu { position: relative; }
details.profile-menu > summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
  white-space: nowrap;
}
details.profile-menu > summary::-webkit-details-marker { display: none; }
details.profile-menu > summary:hover .me, details.profile-menu[open] > summary .me { color: #fff; }
details.profile-menu .caret { font-size: 0.7rem; color: rgba(245, 241, 232, 0.6); }
.profile-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  z-index: 30;
  min-width: 210px;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 0.5rem;
  box-shadow: 0 8px 20px rgba(21, 23, 31, 0.25);
}
.profile-menu-panel a { color: var(--ink); padding: 0.4rem 0.5rem; }
.profile-menu-panel a:hover { background: var(--paper-shade); text-decoration: none; }
.profile-menu-panel a.active { background: var(--paper-shade); font-weight: 600; }
.profile-menu-panel hr { border: 0; border-top: 1px solid var(--hair); margin: 0.35rem 0; }
.profile-menu-panel .btn { width: 100%; margin-top: 0.25rem; }

/* ---- Nội dung: trang tính full-width trên giấy (không panel trắng) ---- */
.container { max-width: 72rem; margin: 1.75rem auto; padding: 0 1.5rem; }
.card {
  background: transparent;
  border: 0;
  padding: 0;
  margin-bottom: 2rem;
}
.card h2 { margin: 0 0 0.9rem; font-size: 1.15rem; font-weight: 700; }
.muted { color: var(--muted-ink); }
.hint { color: var(--muted-ink); font-size: 0.85rem; }
label { display: block; margin: 0.5rem 0 0.15rem; font-size: 0.9rem; font-weight: 500; }
input[type=text], input[type=password], input[type=search], input[type=url], input[type=email], select, textarea {
  width: 100%;
  padding: 0.5rem 0.6rem;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink); /* ô điền của sổ — viền mực đậm */
  font-family: inherit;
  font-size: 0.95rem;
}
input[type=text]:focus, input[type=password]:focus, input[type=search]:focus, input[type=url]:focus, input[type=email]:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 1px var(--navy);
}
input::placeholder { color: var(--muted-ink); }
/* Checkbox/radio lấy accent navy (IAM matrix, email primary, scope token). */
input[type=checkbox], input[type=radio] { accent-color: var(--navy); }

/* ---- Nút: navy đặc (chính) / viền mực (phụ) / đỏ (phá dữ liệu) ---- */
button, .btn {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: var(--navy);
  color: #fff;
  border: 1px solid var(--navy);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
button:hover, .btn:hover { background: var(--navy-deep); border-color: var(--navy-deep); text-decoration: none; }
button:disabled, .btn:disabled { opacity: 0.55; cursor: default; }
button.danger, .btn.danger { background: var(--red); border-color: var(--red); }
button.danger:hover, .btn.danger:hover { background: var(--red-deep); border-color: var(--red-deep); }
button.secondary, .btn.secondary { background: transparent; color: var(--ink); border: 1px solid var(--ink); }
button.secondary:hover, .btn.secondary:hover { background: var(--paper-shade); }
.row-form { display: inline-flex; gap: 0.4rem; align-items: center; }
/* Form scope token (spec 34) — label radio/checkbox nằm ngang, hộp dịch vụ. */
.choice { display: flex; align-items: center; gap: 0.4rem; margin: 0.3rem 0; font-size: 0.9rem; }
.choice input { margin: 0; accent-color: var(--navy); }
.scope-box { border: 1px solid var(--hair-strong); padding: 0.5rem 0.75rem; margin: 0.25rem 0 0.5rem; background: var(--paper-shade); }

/* Form nhiều trường (admin contacts — thêm/sửa): grid tự co, hẹp về 1 cột. */
.form-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.6rem 0.75rem;
  margin-bottom: 0.75rem;
}
/* Dòng email trong form sửa contact (radio primary + ô email) — cùng kiểu
   .choice: nằm ngang một hàng. */
.email-row { display: flex; align-items: center; gap: 0.4rem; margin: 0.3rem 0; font-size: 0.9rem; }

/* ---- Bảng = trung tâm: khung trang tính 2 nét mực, header cap mono ---- */
.sheet {
  overflow-x: auto;
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
}
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--hair); vertical-align: middle; }
th {
  font-family: var(--font-mono);
  color: var(--muted-ink);
  font-weight: 500;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-bottom: 1px solid var(--hair-strong);
  white-space: nowrap;
}
tbody tr:hover td { background: rgba(21, 23, 31, 0.04); }
tr:last-child td { border-bottom: none; }
/* Double-rule kế toán — viền đơn mảnh + viền đậm ngăn hàng tổng/tóm lại. */
tr.total td {
  border-top: 1px solid var(--hair-strong);
  box-shadow: inset 0 3px 0 -2px var(--ink);
  font-weight: 600;
}
/* Double-rule cấp khối — ngăn phần tóm tắt cuối trang (khối audit, như
   footer): cùng nét 3px double mực. */
.double-rule { border-top: 3px double var(--ink); padding-top: 1.25rem; }

/* Cột sticky — bảng nhiều cột (IAM matrix, danh bạ 14 cột): cột đầu ghim
   trái khi cuộn ngang trong .sheet. Nền đục để che nội dung trượt dưới;
   hover khớp màu hover hàng (fallback paper-shade cho browser không color-mix). */
.sheet th.sticky-col, .sheet td.sticky-col {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--paper);
  box-shadow: inset -1px 0 0 var(--hair);
}
tbody tr:hover td.sticky-col {
  background: var(--paper-shade);
  background: color-mix(in srgb, var(--ink) 4%, var(--paper));
}

/* ---- IAM matrix (spec 045) — sheet cao giới hạn, header sticky dọc ---- */
/* Bảng dài (hàng nghìn user, xem theo trang) cuộn TRONG sheet: header cap
   mono ghim trên, nền đục che hàng trượt dưới. Ô góc (header × cột ghim
   trái) cần z-index cao nhất để không bị hàng trượt lọt khe. */
.sheet.sticky-head { max-height: 70vh; overflow-y: auto; }
.sheet.sticky-head thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--paper);
  box-shadow: inset 0 -1px 0 var(--hair-strong), inset 0 -2px 0 var(--ink);
}
.sheet.sticky-head thead th.sticky-col { z-index: 3; }
/* Cột chọn hẹp ghim trái + cột User ghim kế tiếp (offset đúng chiều rộng
   cột chọn cố định — 2 cột trái đều đứng yên khi cuộn ngang 12 cột perm). */
.sheet th.iam-select-col, .sheet td.iam-select-col { width: 2.8rem; text-align: center; }
.sheet th.sticky-col.iam-user-col, .sheet td.sticky-col.iam-user-col { left: 2.8rem; }
/* Key mono phụ chú nhỏ dưới nhãn cột permission (nhãn là chính — spec 045 §1). */
th .sub { display: block; font-size: 0.62rem; letter-spacing: 0.04em; color: var(--muted-ink); }

/* Thanh action IAM (spec 045 §2) — dính đáy viewport khi cuộn: nút Lưu toàn
   trang + bulk bar luôn trong tầm mắt, không phải lùng cuối bảng. */
.action-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  background: var(--paper);
  border-top: 1px solid var(--hair-strong);
  margin-top: 0.5rem;
  padding: 0.6rem 0;
}
.action-bar .spacer { flex: 1; }
.action-bar label.choice { margin: 0; white-space: nowrap; }
.action-bar select { width: auto; }

/* Pager "‹ › · trang x/y" (spec 045 §2) — không jump, cạnh bảng trong card. */
.pager { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.75rem; }

/* Motif ô đánh dấu (OMR): ô đặc = trạng thái có hiệu lực, ô trống = đã
   thu hồi/vô hiệu. Port markbar.tsx — aria-hidden ở templ, giá trị nằm
   ở chữ cạnh ô. */
.mark {
  display: inline-block;
  width: 9px;
  height: 9px;
  border: 1.5px solid var(--ink);
  margin-right: 0.45rem;
  vertical-align: baseline;
}
.mark.on { background: var(--ink); }

code, .mono, pre, .jwt-box {
  font-family: var(--font-mono);
  font-size: 0.85rem;
}
.jwt-box, .code-block pre {
  background: var(--paper-shade);
  border: 1px solid var(--hair-strong);
  padding: 0.6rem 0.75rem;
  word-break: break-all;
  white-space: pre-wrap;
  max-height: 12rem;
  overflow: auto;
}
/* Code block + nút sao chép ([data-copy], trang token). */
.code-block { display: flex; flex-direction: column; align-items: flex-start; gap: 0.4rem; margin-bottom: 0.5rem; }
.code-block pre { width: 100%; margin: 0; }
.copy-btn { font-size: 0.8rem; padding: 0.3rem 0.7rem; }
.copy-btn[disabled] { background: var(--navy); border-color: var(--navy); cursor: default; }
/* Guide MCP — details collapse mặc định (trang token). */
details.card { border-top: 1px solid var(--hair); padding-top: 1.4rem; }
details.card > summary { cursor: pointer; font-size: 1.15rem; font-weight: 700; }
details.card > summary:hover { color: var(--navy); }
details.card[open] > summary { margin-bottom: 0.75rem; }
.mcp-guide h3 { font-size: 0.95rem; margin: 0.75rem 0 0.35rem; }
.mcp-guide ul { margin: 0.75rem 0 0; padding-left: 1.2rem; }
.mcp-guide li { font-size: 0.85rem; color: var(--muted-ink); margin-bottom: 0.25rem; }

/* ---- Thông báo: lỗi = đỏ, cảnh báo = mực, thành công = navy-tint ---- */
.alert { padding: 0.6rem 0.8rem; border: 1px solid var(--hair-strong); margin-bottom: 0.75rem; font-size: 0.9rem; }
.alert.warn { background: var(--paper-shade); }
.alert.error { background: rgba(180, 35, 24, 0.07); border-color: var(--red); }
.alert.ok { background: var(--navy-tint); border-color: var(--navy); }
.badge {
  display: inline-block;
  padding: 0.12rem 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  background: transparent;
  border: 1px solid var(--hair);
  color: var(--muted-ink);
}
.badge.admin { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.badge.force { border-color: var(--red); color: var(--red); }
.badge.ok { background: var(--navy-tint); border-color: var(--hair-strong); color: var(--ink); }
/* Roster (spec 046): cảnh báo conflict email / lỗi duyệt từng row. */
.badge.danger { border-color: var(--red); color: var(--red); background: rgba(180, 35, 24, 0.07); }

/* ---- Login — trang giấy standalone giữa màn (front door) ---- */
.login-wrap { max-width: 24rem; margin: clamp(3rem, 10vh, 6rem) auto 0; padding: 0 1rem; }
.login-head { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 0.4rem; }
.login-monogram { width: 3.25rem; height: 3.25rem; font-size: 1.4rem; }
.login-head h1 { font-size: 1.45rem; font-weight: 800; margin: 0; line-height: 1.2; }
.login-rule { border: 0; border-top: 1px solid var(--hair-strong); margin: 1.1rem 0; }
.login-wrap .btn {
  display: block;
  width: 100%;
  text-align: center;
  padding: 0.7rem 1rem;
  font-size: 1rem;
}
.login-foot {
  text-align: center;
  margin-top: 3rem;
  padding: 0 1rem 1.5rem;
  color: var(--muted-ink);
  font-size: 0.85rem;
}
.login-foot a { color: var(--muted-ink); }
.login-foot a:hover { color: var(--navy); }

/* Trang tài liệu (privacy/tos) — masthead thu gọn 1 hàng. */
.doc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 3px solid var(--navy);
  background: var(--ink);
  color: var(--paper);
  padding: 0.6rem 1.5rem;
}
.doc-head a { color: var(--paper); font-weight: 700; }
.doc-head .cap { color: rgba(245, 241, 232, 0.7); }
.doc-monogram { width: 1.7rem; height: 1.7rem; font-size: 0.72rem; }
.doc h1 { font-size: 1.6rem; font-weight: 800; margin: 1.5rem 0 0.75rem; }
.doc h2 { font-size: 1.1rem; font-weight: 700; margin: 1.5rem 0 0.5rem; }

.htmx-indicator { display: none; }
.htmx-request .htmx-indicator, .htmx-indicator.htmx-request { display: inline; }

/* Empty state — khung nét đứt + nhãn chữ (không illustration). */
.empty {
  border: 1px dashed var(--hair-strong);
  color: var(--muted-ink);
  font-style: normal;
  text-align: center;
  padding: 0.9rem 0.75rem;
  font-size: 0.9rem;
}

/* Tabs settings (spec 049) — nav ngang underline trên nền giấy; cùng nhịp
   topbar nav nhưng mực trên giấy. 3 trang: Hồ sơ · Tài khoản ĐHBK · Token. */
nav.tabs {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--hair);
  margin: 0 0 1.25rem;
}
nav.tabs a {
  color: var(--muted-ink);
  font-size: 0.95rem;
  padding: 0.35rem 0;
  border-bottom: 2px solid transparent;
}
nav.tabs a.active { color: var(--ink); border-bottom-color: var(--ink); font-weight: 500; }
nav.tabs a:hover { color: var(--ink); text-decoration: none; }

/* Hồ sơ /settings (spec 049) — empty state card nổi (khung nét đứt, căn trái
   khác .empty căn giữa dùng cho hàng bảng) + bảng thông tin dl 2 cột. */
.empty.profile-empty { text-align: left; padding: 1.1rem 1.25rem; margin-bottom: 1.25rem; }
.empty.profile-empty h2 { margin: 0 0 0.5rem; font-size: 1.1rem; color: var(--ink); }
.empty.profile-empty p { margin: 0.3rem 0; }
dl.profile-facts { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 0.5rem 1.25rem; }
dl.profile-facts dt { color: var(--muted-ink); font-size: 0.88rem; }
dl.profile-facts dd { margin: 0; display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }

/* Pager (spec 046 roster, pattern spec 045): ‹ › · trang x/y — không jump. */
.pager { display: flex; align-items: center; gap: 0.6rem; margin: 0.6rem 0 0; font-size: 0.85rem; color: var(--muted-ink); }

/* Audit (issue #288) — bảng trung tâm; đổi từ ul cũ sang table trong .sheet
   (class .audit-list/.audit-time đã dỡ cùng DOM cũ). */

/* Footer — double-rule ngăn phần kết trang; version là dữ liệu số → mono. */
.site-footer {
  max-width: 72rem;
  margin: 1.5rem auto 0;
  padding: 0.75rem 1.5rem;
  border-top: 3px double var(--ink);
  color: var(--muted-ink);
  font-size: 0.8rem;
  text-align: center;
}
.site-footer .mono { font-size: 0.8rem; }

/* ---- Admin (issue #288) — masthead mực full-bleed thay sidebar cũ ---- */
/* AdminLayout dùng header.topbar của UserLayout (#287) + class .admin; các
   override dưới SCOPED .admin (chỉ masthead AdminLayout có class này) để
   không đè nút/badge của UserLayout nằm trong header.topbar (nút Đăng xuất
   trong .profile-menu-panel nền paper — review #288); chỉ đảo fore/back
   giấy↔mực — không thêm màu mới. */
header.topbar.admin .admin-tag {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
  border: 1px solid rgba(245, 241, 232, 0.5);
  padding: 0.16rem 0.55rem;
  white-space: nowrap;
  flex-shrink: 0;
}
header.topbar.admin .badge.admin {
  background: transparent;
  border-color: rgba(245, 241, 232, 0.5);
  color: var(--paper);
}
header.topbar.admin .btn.secondary {
  background: transparent;
  color: var(--paper);
  border-color: rgba(245, 241, 232, 0.55);
}
header.topbar.admin .btn.secondary:hover {
  background: rgba(245, 241, 232, 0.14);
  border-color: rgba(245, 241, 232, 0.55);
}

/* Toggle "Sửa" (details trong ô thao tác bảng contacts) — đọc như link. */
td.actions summary { cursor: pointer; color: var(--navy); font-weight: 500; }
td.actions summary:hover { text-decoration: underline; }

/* Responsive mobile (issue #30): bảng 6 cột tràn → mỗi <tr> thành card dọc,
 * label cột lấy từ attr data-label trên <td> (ghi ở templ). Nút wrap. */
@media (max-width: 720px) {
  header.topbar { padding: 0.4rem 0.75rem; gap: 0.75rem; }
  header.topbar .brand-sub, header.topbar .masthead-mark { display: none; }
  /* Admin masthead có nhiều mục (nhãn + 5 nav + user + logout) → cho wrap
   * xuống hàng; nav chiếm hàng riêng cho dễ bấm. */
  header.topbar.admin { flex-wrap: wrap; row-gap: 0.35rem; }
  header.topbar.admin nav { row-gap: 0.15rem; }
  .container { margin: 1rem auto; padding: 0 0.75rem; }
  .row-form { flex-wrap: wrap; }
  table, tbody, tr, td { display: block; width: 100%; }
  thead { display: none; }
  /* Cột sticky vô nghĩa ở chế độ card dọc — bỏ ghim cho khỏi che nội dung. */
  .sheet th.sticky-col, .sheet td.sticky-col { position: static; background: transparent; box-shadow: none; }
  /* Sheet cao + header sticky cũng vô nghĩa khi bảng thành card dọc — mở toàn
   * chiều cao, thanh action dính đáy thường trực (nút Lưu luôn thấy). */
  .sheet.sticky-head { max-height: none; overflow-y: visible; }
  .sheet.sticky-head thead th { position: static; box-shadow: none; }
  tbody tr {
    border: 1px solid var(--hair-strong);
    padding: 0.25rem 0.75rem;
    margin-bottom: 0.6rem;
  }
  tbody tr:last-child { margin-bottom: 0; }
  tbody td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    border-bottom: 1px solid var(--hair);
    padding: 0.4rem 0;
  }
  /* Specificity: rule desktop `tr:last-child td` (0,1,2) vẫn thắng rule
   * mobile ở card cuối → khôi phục separator giữa các field, chỉ bỏ ở field cuối. */
  tbody tr:last-child td { border-bottom: 1px solid var(--hair); }
  tbody td:last-child { border-bottom: none; }
  tbody td::before {
    content: attr(data-label);
    font-family: var(--font-mono);
    color: var(--muted-ink);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    flex-shrink: 0;
  }
  tbody td:empty { display: none; }
  tbody td[colspan] { display: block; } /* dòng "Chưa có token nào." */
  tbody td.actions { flex-wrap: wrap; justify-content: flex-start; row-gap: 0.4rem; }
}
