/* ============================================================================
   ZORRO3 WEB — NỀN GIAO DIỆN

   Bộ nền dùng chung cho toàn bộ web ZORRO3. Viết riêng cho ZORRO3, không dùng lại
   mã nguồn MEDUSA; chỉ giữ những nguyên tắc đã được chứng minh trên máy thật ở salon:

     1. MỘT giao diện responsive duy nhất. Máy tính và điện thoại dùng CHUNG một
        khối HTML, chỉ khác cách xếp. Không có bản mobile riêng để lệch nhau.
     2. Không phụ thuộc mạng ngoài: không font ngoài, không icon ngoài, không CDN.
        Salon mất mạng vẫn mở được giao diện.
     3. Mọi thứ bấm được tối thiểu 44×44px; chữ nhỏ nhất trên điện thoại là 14px;
        không bao giờ có thanh cuộn ngang.
     4. Sáng/tối đi theo hệ điều hành, không bắt người dùng chọn.
     5. Hộp thoại KHÔNG BAO GIỜ cao quá màn hình: đầu dính trên, thân cuộn riêng,
        chân luôn bấm được — kể cả khi bàn phím điện thoại đang bật.

   Không dùng thuộc tính style="" ở bất kỳ đâu: trang chạy dưới Content-Security-Policy
   chặn style nội tuyến, nên mọi thay đổi hình thức đều phải đi qua tệp này.
   ========================================================================= */

/* ── 1. TOKEN — nguồn duy nhất của màu, chữ, khoảng cách ─────────────────────
   MÃ MÀU LẤY NGUYÊN VĂN TỪ MEDUSA, không chọn màu "gần giống".

   Nguồn: `E:\PHẦN MỀM MEUDSA\medusa-v2\src\ui\dashboard.html` — khối
   "MEDUSA UI 2.0 — DESIGN SYSTEM", chính MEDUSA khai là "một bộ nền dùng chung
   cho TOÀN BỘ MEDUSA". Đây là thế hệ giao diện mới của MEDUSA (sidebar + topbar,
   đúng bố cục ZORRO3 đang chạy); 21 trang còn lại của MEDUSA vẫn ở thế hệ cũ
   (header ngang, token `--ink/--line/--accent` khai riêng TỪNG TRANG và mâu
   thuẫn nhau: review `--bg:#f6f7f9` ≠ reports `--bg:#eef1f6`), nên chúng KHÔNG
   thể là "một bộ token dùng chung". Bảng quy đổi thế hệ cũ → token dưới đây ghi
   ở `docs/medusa-sync/MEDUSA_COLOR_TOKENS.md`.
   ───────────────────────────────────────────────────────────────────────────── */
:root {
  /* Nền & bề mặt */
  --bg: #f5f7fa;
  --surface: #ffffff;
  --surface-2: #eef2f7;
  --border: #e2e7ee;
  --border-strong: #cfd7e2;

  /* Chữ */
  --text: #16202b;
  --text-muted: #5c6b7a;
  --text-invert: #ffffff;

  /* Màu thương hiệu */
  --brand: #2563eb;
  --brand-strong: #1d4ed8;
  --brand-weak: #e8f0fe;

  /* Năm mức trạng thái, đọc từ nặng xuống nhẹ */
  --do: #d32f2f;     --do-weak: #fdecec;      /* lỗi / cần xử lý ngay   */
  --cam: #c2620a;    --cam-weak: #fff2e2;     /* cần chú ý / kiểm tra   */
  --vang: #8d6a00;   --vang-weak: #fff7db;    /* cần bổ sung            */
  --xanh: #0f7b4f;   --xanh-weak: #e4f5ec;    /* đã xong / bình thường  */
  --xam: #64748b;    --xam-weak: #eef1f5;     /* chưa rõ / đang tắt     */
  --tim: #6d28d9;    --tim-weak: #f0e9fe;     /* tiền còn lại (MEDUSA)  */

  /* Đầu bảng báo cáo — MEDUSA `reports.html` khai riêng `--head`, thế hệ 2.0
     không có token tương đương nên giữ nguyên tên và mã của MEDUSA. */
  --head: #1f2b52;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-num: ui-monospace, "SF Mono", "Segoe UI Mono", monospace;

  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s7: 32px; --s8: 40px;
  --r-sm: 8px; --r-md: 10px; --r-lg: 14px; --r-pill: 999px;

  --sh-1: 0 1px 2px rgba(16, 24, 40, .05);
  --sh-2: 0 8px 28px rgba(16, 24, 40, .14);

  --nav-w: 248px;
  --tap: 44px;
  --content-max: 1240px;
}

/* Sáng/tối đi theo hệ điều hành — MEDUSA có, ZORRO3 trước đây KHÔNG có, nên trên
   máy đặt nền tối hai bên hiện ra hai màu khác hẳn nhau. Mã màu chép nguyên văn
   khối `@media (prefers-color-scheme: dark)` của MEDUSA UI 2.0. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d1117; --surface: #161b22; --surface-2: #1c232c;
    --border: #262e38; --border-strong: #37414e;
    --text: #e6edf3; --text-muted: #93a1b0;
    --brand: #5b8cf5; --brand-strong: #7ba4f8; --brand-weak: #16233a;
    --do: #f0776a;   --do-weak: #2b1414;
    --cam: #e5a14e;  --cam-weak: #2a1f12;
    --vang: #dcc05a; --vang-weak: #262112;
    --xanh: #4ade9b; --xanh-weak: #10261b;
    --xam: #94a3b8;  --xam-weak: #1c232c;
    --tim: #a78bfa;  --tim-weak: #1e1733;
    --head: #20304f;
    --sh-1: 0 1px 2px rgba(0, 0, 0, .3);
    --sh-2: 0 8px 28px rgba(0, 0, 0, .5);
  }
}

/* ── 2. NỀN TẢNG ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { max-width: 100%; overflow-x: hidden; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 15px/1.55 var(--font); -webkit-text-size-adjust: 100%;
}
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--r-sm); }
[hidden] { display: none !important; }
.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.ico {
  width: 20px; height: 20px; flex: none; display: inline-block; vertical-align: -4px;
  fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.ico--sm { width: 16px; height: 16px; }
.ico--lg { width: 24px; height: 24px; }

/* ── 3. CHỮ ──────────────────────────────────────────────────────────────── */
.t-display { font-size: 24px; line-height: 1.25; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.t-h1 { font-size: 20px; line-height: 1.3; font-weight: 800; margin: 0; }
.t-body { font-size: 15px; line-height: 1.55; }
.t-sm { font-size: 14px; line-height: 1.5; }
.t-h2 {
  font-size: 13px; line-height: 1.4; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted); margin: 0 0 var(--s3);
}
.t-cap { font-size: 13px; line-height: 1.45; color: var(--text-muted); }

/* ── 4. THẺ ĐĂNG NHẬP ────────────────────────────────────────────────────── */
.loginwrap {
  min-height: 100dvh; display: flex; align-items: center; justify-content: center;
  padding: var(--s5);
}
.logincard {
  width: 360px; max-width: 100%; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--s6) var(--s5); box-shadow: var(--sh-2);
}
.logincard__brand { display: flex; align-items: center; gap: var(--s2); font-size: 18px; font-weight: 800; }
.logincard__brand .mark { width: 10px; height: 10px; border-radius: 50%; background: var(--brand); flex: none; }
.logincard__sub { color: var(--text-muted); font-size: 14px; margin: var(--s1) 0 var(--s5); }
/* Ghi nhớ đăng nhập: cả dòng là một nhãn bấm được, ô tick 18px để trên điện thoại dễ chạm. */
.logincard__nho {
  display: flex; align-items: center; gap: var(--s2);
  margin: var(--s2) 0 var(--s4); font-size: 14px; cursor: pointer; user-select: none;
}
.logincard__nho input { width: 18px; height: 18px; accent-color: var(--brand); flex: none; cursor: pointer; }

/* ── 5. BỐ CỤC: menu trái + vùng nội dung ────────────────────────────────── */
.app { min-height: 100dvh; }

.sidebar {
  position: fixed; inset: 0 auto 0 0; width: var(--nav-w); z-index: 40;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border-right: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
/* Chỉ DANH SÁCH mục được cuộn. Ghim chân menu lại để nút Đăng xuất không bao giờ
   bị đẩy khuất khi menu dài hơn màn hình. */
.sidebar__nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-bottom: var(--s3); }
.sidebar__brand {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s4) var(--s5) var(--s3); font-size: 17px; font-weight: 800; letter-spacing: .02em;
}
.sidebar__brand .mark { width: 10px; height: 10px; border-radius: 50%; background: var(--brand); flex: none; }
.sidebar__foot { margin-top: auto; border-top: 1px solid var(--border); padding: var(--s3); }
.sidebar__who { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar__role { font-size: 13px; color: var(--text-muted); margin-bottom: var(--s2); }

.navgroup { padding: var(--s3) var(--s3) 0; }
.navgroup__title {
  font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-muted); padding: 0 var(--s2) var(--s1);
}
.navlink {
  display: flex; align-items: center; gap: var(--s3); min-height: var(--tap);
  padding: var(--s2) var(--s3); border-radius: var(--r-md); font-size: 15px;
}
.page-inline-head { display: flex; align-items: center; gap: var(--s5); min-height: 54px; margin: var(--s2) 0 var(--s5); }
.page-inline-head .link { color: var(--brand); font-weight: 600; }
.close-history { min-width: 0; font-size: 14px; }
.close-history th, .close-history td { padding: 8px 12px; vertical-align: middle; }
.close-history th { font-size: 12.5px; font-weight: 700; }
.close-history__date { font-weight: 800; }
.close-history__actions { display: flex; justify-content: flex-end; gap: 6px; white-space: nowrap; }
.close-history__actions .btn { min-height: 36px; padding: 0 12px; font-size: 13.5px; }
.close-history__actions .btn--danger { color: var(--do); border-color: var(--do); background: var(--surface); }
/* `.lock-toolbar` = `.daybar` của MEDUSA, chép nguyên: cho xuống dòng, còn kích thước ô
   ngày để `.dt` tự lo (xem khối `.dt` ở mục Biểu mẫu). Không đặt thêm bề ngang riêng ở
   đây — chính chỗ tự chế đó làm ô ngày lệch với bản MEDUSA. */
.lock-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); margin-top: var(--s2); }
.lock-toolbar .input { width: min(345px, 100%); }
.lock-issue-title { margin: var(--s6) 0 var(--s3); font-size: 15px; }
/* ── Việc chưa xong ở màn Khóa ngày ──────────────────────────────────────────
   Chép nguyên khối `.dk` của MEDUSA (`src/ui/khoangay.html`), chỉ đổi mã màu sang token
   ZORRO3. Trước đây mỗi việc là một thẻ xám rời như thẻ nội dung thường — nhìn không ra
   là việc PHẢI LÀM, và tiêu đề dùng cỡ `t-h1` nên trên điện thoại mỗi việc chiếm gần
   nửa màn hình. MEDUSA gom tất cả vào MỘT khung, mỗi việc một dòng có vạch đỏ. */
.lock-issue-box { padding: var(--s2); }
.dk { display: flex; gap: var(--s3); padding: var(--s3) var(--s4); border-left: 4px solid var(--do);
      background: linear-gradient(90deg, var(--do-weak), transparent 70%); border-radius: var(--r-md);
      align-items: flex-start; }
.dk + .dk { margin-top: var(--s2); }
.dk__ico { flex: none; width: 32px; height: 32px; border-radius: var(--r-sm); display: grid;
           place-items: center; background: var(--do-weak); color: var(--do); }
.dk__body { flex: 1; min-width: 0; }
.dk__t { font-size: 16px; font-weight: 700; }
.dk__h { font-size: 14px; color: var(--text-muted); margin-top: 2px; }
.dk__ds { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s2); }
.dk__act { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }
/* Thẻ tròn cho từng số hóa đơn / tên quỹ. Nút bên trong (vd "tờ hủy") nằm ngay cạnh số
   nó nói tới, không tách thành nút riêng cả dòng. */
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
        border-radius: var(--r-pill); background: var(--surface); border: 1px solid var(--border);
        font-size: 13px; font-variant-numeric: tabular-nums; }
.chip button { border: none; background: transparent; color: var(--brand); font-size: 12.5px;
               font-weight: 700; padding: 0; min-height: 0; cursor: pointer; }
.ok-all { display: flex; align-items: center; gap: var(--s3); padding: var(--s4) var(--s5);
          color: var(--xanh); font-weight: 700; font-size: 16px; }
.ok-all .b { width: 36px; height: 36px; border-radius: var(--r-sm); display: grid; place-items: center;
             background: var(--xanh-weak); }
.lock-ready h3 { margin-bottom: var(--s1); }
.lock-ready { border-left: 5px solid var(--xanh); }
.lock-submit { width: 100%; min-height: 54px; margin-top: var(--s5); font-size: 16px; }
.day-close-page .sidebar, .day-close-page .scrim, .day-close-page > .app .topbar { display: none; }
.day-close-page .main { margin-left: 0; }
.day-close-page .content { max-width: none; padding: 0 0 var(--s8); }
.close-page-head {
  min-height: 76px; padding: 14px 24px; background: var(--surface); border-bottom: 1px solid var(--border);
  /* `flex-wrap` để trên máy rất hẹp (điện thoại bật phóng to màn hình, hoặc chia đôi màn
     hình) hai nút Chốt kỳ / Lịch sử xuống dòng thay vì đẩy ra ngoài mép. */
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s4);
}
.close-page-head__left, .close-page-head__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4); }
.close-page-head__left { min-width: 0; }
.close-page-head__left .t-display { min-width: 0; overflow-wrap: anywhere; }
.close-page-head__left .link { color: var(--brand); font-weight: 600; }
.close-page-head__left .t-display { font-size: 22px; }
.close-page-body { width: min(900px, calc(100% - 32px)); margin: 16px auto 0; }
.close-page-head--history { min-height: 54px; padding: 8px 16px; }
.close-page-head--history .close-page-head__left { gap: 8px; }
.close-page-head--history .close-page-head__left .link { font-size: 14px; }
.close-page-head--history .close-page-head__left .t-display { font-size: 16px; letter-spacing: 0; }
.close-page-body--history { width: min(900px, 100%); margin-top: 0; padding: 16px; }
.close-page-body--history > .card { border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.close-page-body .lock-toolbar { min-height: 116px; padding: 24px 30px; margin-top: 0; }
.close-page-body .lock-issue-title { margin-top: 34px; }
.close-page-body .lock-issue { padding: 26px 36px; }
.medusa-balance { color:#1c2430; font:15px/1.5 system-ui,"Segoe UI",Roboto,sans-serif; }
.medusa-balance__toolbar { display:flex; justify-content:flex-end; margin:12px 0; }
.medusa-balance .medusa-balance__save {
  min-height:40px; padding:7px 10px; border:1px solid #2f6fed; border-radius:8px;
  background:#2f6fed; color:#fff;
}
.medusa-balance .medusa-balance__save:hover { background:#2f6fed; border-color:#2f6fed; }
.medusa-balance .medusa-balance__save.is-done { background:#127a4b; border-color:#127a4b; }
.medusa-balance .medusa-balance__card { padding:14px 16px; border:1px solid #e6e9ee; border-radius:12px; box-shadow:none; }
.medusa-balance__title {
  margin:0 0 10px; color:#6b7684; font-size:13px; line-height:1.5;
  font-weight:700; text-transform:uppercase;
}
.medusa-balance__table { width:100%; border-collapse:collapse; font-size:14px; }
.medusa-balance__table th, .medusa-balance__table td {
  padding:7px 9px; border-bottom:1px solid #e6e9ee; text-align:left;
}
.medusa-balance__table th.num, .medusa-balance__table td.num { text-align:right; font-variant-numeric:tabular-nums; }
.medusa-balance__income { color:#127a4b; }
.medusa-balance__expense { color:#c0392b; }
.medusa-balance__input {
  width:130px; padding:7px 10px; border:1px solid #e6e9ee; border-radius:8px;
  background:#fff; color:#1c2430; text-align:right; font:inherit;
}
.medusa-balance__input:focus { outline:2px solid #1c2430; outline-offset:0; }
.medusa-balance__revenue { margin:10px 0 0; color:#6b7684; }
@media (prefers-color-scheme:dark) {
  .medusa-balance { color:#e6e9ee; }
  .medusa-balance .medusa-balance__card { background:#171d26; border-color:#252d38; }
  .medusa-balance__title, .medusa-balance__revenue { color:#9aa4b2; }
  .medusa-balance__table th, .medusa-balance__table td { border-color:#252d38; }
  .medusa-balance__income { color:#3fbf83; }
  .medusa-balance__expense { color:#e26d5c; }
  .medusa-balance__input { background:#171d26; color:#e6e9ee; border-color:#252d38; }
}
.navlink:hover { background: var(--surface-2); }
.navlink[aria-current="page"] { background: var(--brand-weak); color: var(--brand); font-weight: 700; }
.navlink .ico { flex: none; opacity: .85; }
.navlink[aria-current="page"] .ico { opacity: 1; }
.navlink__count {
  margin-left: auto; background: var(--do); color: var(--chu-tren-nen-mau); font-size: 12px; font-weight: 700;
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: var(--r-pill);
  display: grid; place-items: center;
}
/* Mục có trong menu nhưng chưa làm xong: nói thẳng, không để người dùng bấm vào
   rồi gặp màn hình trống. Vẫn đứng đúng chỗ để biết sắp có. */
.navlink--soon { color: var(--text-muted); cursor: default; flex-wrap: wrap; row-gap: 2px; }
.navlink--soon:hover { background: transparent; }
.navlink--soon .ico { opacity: .55; }
.navlink--soon .tag-soon { margin-left: 32px; }
.tag-soon {
  flex: none; background: var(--xam-weak); color: var(--xam);
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
  padding: 2px 7px; border-radius: var(--r-pill); white-space: nowrap;
}
.btn--soon { color: var(--text-muted); background: var(--surface-2); border-style: dashed; cursor: default; }
.btn--soon:hover { background: var(--surface-2); }
/* Nhóm phụ cuối menu (Giám sát · Nhật ký): chữ nhạt và nhỏ hơn để không tranh chỗ
   với việc chính — đúng `.navgroup--phu` của MEDUSA. */
.navgroup--phu .navlink { color: var(--text-muted); font-size: 14px; min-height: 40px; }
.navgroup--phu .navlink:hover { color: var(--text); }
.navgroup--phu .ico { opacity: .6; }

.main { margin-left: var(--nav-w); }
.topbar {
  position: sticky; top: 0; z-index: 20; display: flex; align-items: flex-start; gap: var(--s3);
  max-width: var(--content-max); margin: 0 auto;
  background: var(--bg); padding: var(--s5) var(--s5) var(--s3);
  border-bottom: 1px solid transparent;
}
.topbar--stuck { border-bottom-color: var(--border); }
.topbar__hello { flex: 1; min-width: 0; }
.topbar__hello p { margin: 2px 0 0; color: var(--text-muted); font-size: 15px; }
.content { max-width: var(--content-max); margin: 0 auto; padding: 0 var(--s5) var(--s8); }
.block { margin-top: var(--s6); }
.block:first-child { margin-top: var(--s2); }
.block__head { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s3); min-height: 28px; }
.block__head .t-h2 { margin: 0; }
.block__head .link { margin-left: auto; font-size: 13px; font-weight: 600; color: var(--brand); }
/* Nút thao tác của một khối luôn nằm về bên phải tiêu đề; màn hẹp thì xuống dòng
   thành một hàng riêng thay vì chen vào tiêu đề. */
.block__head .actions { margin-left: auto; }
@media (max-width: 900px) {
  .block__head { flex-wrap: wrap; }
  .block__head .actions { margin-left: 0; width: 100%; }
  .block__head .actions .btn { flex: 1 1 auto; }
}

/* ── 6. THẺ ──────────────────────────────────────────────────────────────── */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.card--pad { padding: var(--s4) var(--s5); }
/* Phần thân có đệm bên trong một thẻ còn có chân riêng — chân tự lo đệm của nó. */
.cardbody { padding: var(--s4) var(--s5); }
.card__foot {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  padding: var(--s3) var(--s5); border-top: 1px solid var(--border);
}
.card__foot .note { flex: 1; min-width: 180px; color: var(--text-muted); font-size: 14px; }

/* ── 7. NÚT ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: var(--tap); padding: 0 var(--s4);
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); color: var(--text); font-size: 14px; font-weight: 600;
  transition: background .12s, border-color .12s;
}
.btn:hover { background: var(--surface-2); }
.btn--primary { background: var(--brand); border-color: var(--brand); color: var(--text-invert); }
.btn--primary:hover { background: var(--brand-strong); border-color: var(--brand-strong); }
.btn--ghost { background: transparent; border-color: transparent; }
.btn--ghost:hover { background: var(--surface-2); }
.btn--danger { background: var(--do); border-color: var(--do); color: var(--chu-tren-nen-mau); }
.btn--block { width: 100%; }
.btn--icon { width: var(--tap); padding: 0; flex: none; }
.btn[disabled] { opacity: .55; cursor: not-allowed; }

/* ── 8. NHÃN TRẠNG THÁI ──────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 6px; min-height: 24px; padding: 0 10px;
  border-radius: var(--r-pill); font-size: 13px; font-weight: 700; white-space: nowrap;
}
.pill--do { background: var(--do-weak); color: var(--do); }
.pill--cam { background: var(--cam-weak); color: var(--cam); }
.pill--vang { background: var(--vang-weak); color: var(--vang); }
.pill--xanh { background: var(--xanh-weak); color: var(--xanh); }
.pill--xam { background: var(--xam-weak); color: var(--xam); }
.pill--brand { background: var(--brand-weak); color: var(--brand); }
/* Chip cảnh báo "⚠ N" trên hàng đợi (B2): tách khỏi số hóa đơn, cỡ nhỏ hơn để không lấn số. */
.pill--warn { margin-left: var(--s2); min-height: 20px; padding: 0 8px; font-size: 12px; }

/* ── 8b. VIỆC CẦN XỬ LÝ ──────────────────────────────────────────────────────
   Màn Tổng quan không phải chỗ ngắm số liệu — nó phải trả lời "giờ tôi phải làm
   gì". Mỗi dòng là MỘT việc, số việc nằm bên trái, bấm cả dòng là đi thẳng tới
   chỗ làm. Màu viền trái nói mức khẩn, đọc được cả khi liếc qua. */
.tasklist { padding: var(--s1); }
.task {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  min-height: 56px; padding: var(--s2) var(--s3);
  border: none; border-left: 4px solid transparent; border-radius: var(--r-md);
  background: none; color: inherit; text-align: left;
}
.task + .task { margin-top: 2px; }
.task:hover { background: var(--surface-2); }
.task__n {
  flex: none; min-width: 36px; height: 36px; padding: 0 var(--s2); border-radius: var(--r-sm);
  display: grid; place-items: center; font-weight: 800; font-size: 16px; font-variant-numeric: tabular-nums;
}
.task__t { flex: 1; min-width: 0; font-size: 16px; font-weight: 600; }
.task__go { flex: none; color: var(--text-muted); }
.task--do { border-left-color: var(--do); background: linear-gradient(90deg, var(--do-weak), transparent 62%); }
.task--cam { border-left-color: var(--cam); background: linear-gradient(90deg, var(--cam-weak), transparent 62%); }
.task--vang { border-left-color: var(--vang); background: linear-gradient(90deg, var(--vang-weak), transparent 62%); }
.task--xanh { border-left-color: var(--xanh); background: linear-gradient(90deg, var(--xanh-weak), transparent 62%); }
.task--do .task__n { background: var(--do-weak); color: var(--do); }
.task--cam .task__n { background: var(--cam-weak); color: var(--cam); }
.task--vang .task__n { background: var(--vang-weak); color: var(--vang); }
.task--xanh .task__n { background: var(--xanh-weak); color: var(--xanh); }

/* ── 8c. LỐI TẮT ─────────────────────────────────────────────────────────────
   Dành cho người chỉ làm một hai việc cố định: mở lên là bấm được ngay, không
   phải đi tìm trong menu. Ô to, một tay bấm trúng. */
.shortcuts { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--s3); }
.shortcut {
  display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: left;
  min-height: 68px; padding: var(--s4) var(--s5); font-size: 16px; font-weight: 600;
  color: inherit;
}
.shortcut:hover { background: var(--surface-2); }
.shortcut__ico {
  width: 40px; height: 40px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center; background: var(--brand-weak); color: var(--brand);
}
.shortcut__go { margin-left: auto; color: var(--text-muted); }

/* ── 9. Ô SỐ LIỆU ────────────────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3); }
.stats--1 { grid-template-columns: 1fr; max-width: 420px; }
.stat { padding: var(--s4) var(--s5); }
.stat__label { color: var(--text-muted); font-size: 14px; }
.stat__value { font-size: 26px; font-weight: 800; margin-top: var(--s1); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.stat__value--sm { font-size: 21px; }

/* ── 10. SỨC KHOẺ HỆ THỐNG ───────────────────────────────────────────────── */
.health { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3); }
.health__item { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--s4); }
.health__led { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.health__name { display: block; font-weight: 700; font-size: 15px; }
.health__state { display: block; font-size: 13px; color: var(--text-muted); }
.health__item--ok .health__led { background: var(--xanh); box-shadow: 0 0 0 3px var(--xanh-weak); }
.health__item--loi .health__led { background: var(--do); box-shadow: 0 0 0 3px var(--do-weak); }
.health__item--loi { border-color: var(--do); }
.health__item--loi .health__state { color: var(--do); font-weight: 600; }
.health__item--xam .health__led { background: var(--xam); box-shadow: 0 0 0 3px var(--xam-weak); }

/* ── 11. BẢNG → THẺ. Trên điện thoại KHÔNG có bảng nhiều cột ─────────────── */
.rowlist { padding: var(--s1) var(--s5); }
.row {
  display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: left;
  min-height: 46px; padding: var(--s2) 0; border-bottom: 1px solid var(--border);
  background: none; border-left: none; border-right: none; border-top: none; color: inherit;
}
.row:last-child { border-bottom: none; }
button.row:hover { background: var(--surface-2); }
.row__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: 15px; }
.row__sub { display: block; font-size: 13px; color: var(--text-muted); }
.row__amt { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.row__go { flex: none; color: var(--text-muted); }
/* Dòng tổng cộng: gạch đậm phía trên thay vì gạch mờ phía dưới, để mắt nhận ra
   ngay đây là con số cuối cùng chứ không phải một dòng dữ liệu nữa. */
.row--total { font-weight: 800; border-top: 2px solid var(--border); border-bottom: none; }
.row--total .row__amt { font-size: 19px; }
.row__rank {
  flex: none; width: 26px; height: 26px; border-radius: var(--r-sm); display: grid; place-items: center;
  background: var(--surface-2); color: var(--text-muted); font-size: 13px; font-weight: 700;
}
.row__rank--top { background: var(--brand-weak); color: var(--brand); }

.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border); text-align: left; }
.table th { color: var(--text-muted); font-weight: 600; font-size: 13px; }
/* Số tiền/số đếm KHÔNG BAO GIỜ bẻ dòng: "26.623.000đ" gãy thành "26.6/23.0/00đ" thì
   đọc thành ba con số khác nhau (ảnh chụp iPhone 13/08/2026). Ô ngày cũng vậy. */
.table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table td.cell-ngay { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Ô tiền bằng 0 trong thân bảng báo cáo: dấu "–" xám nhạt — chỗ không có gì thì không
   được kêu to bằng chỗ có tiền. */
.table td.cell-rong { color: var(--text-muted); opacity: .55; }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── 12. TRẠNG THÁI: ĐANG TẢI · RỖNG · LỖI ───────────────────────────────── */
.state { display: flex; align-items: center; gap: var(--s3); padding: var(--s5); color: var(--text-muted); font-size: 15px; }
.state__ico { width: 36px; height: 36px; border-radius: var(--r-sm); display: grid; place-items: center; flex: none; background: var(--surface-2); }
.state--done { color: var(--xanh); font-weight: 600; }
.state--done .state__ico { background: var(--xanh-weak); color: var(--xanh); }
.state--loi { color: var(--do); }
.state--loi .state__ico { background: var(--do-weak); color: var(--do); }
.state__body { flex: 1; min-width: 0; }

.skeleton {
  height: 14px; border-radius: var(--r-sm); background: var(--surface-2);
  animation: pulse 1.1s ease-in-out infinite;
}
.skeleton + .skeleton { margin-top: var(--s2); }
.skeleton--wide { width: 70%; }
.skeleton--narrow { width: 35%; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* ── 13. BIỂU MẪU ────────────────────────────────────────────────────────── */
.field { margin-bottom: var(--s3); }
.field__label { display: block; font-size: 13px; color: var(--text-muted); margin-bottom: var(--s1); }
.input, .select, .textarea {
  width: 100%; min-height: var(--tap); padding: var(--s2) var(--s3);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  font-size: 16px;   /* 16px: iPhone không tự phóng to trang khi bấm vào ô nhập */
}
.input:focus, .select:focus, .textarea:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px var(--brand-weak); }
.input--num { text-align: right; font-variant-numeric: tabular-nums; }
/* ── Ô MẬT KHẨU + NÚT CON MẮT ────────────────────────────────────────────────
   Nút nằm ĐÈ LÊN ô, nên phải chừa chỗ bên phải cho chữ khỏi chui xuống dưới nút.
   Vùng chạm giữ đúng var(--tap) để trên điện thoại ngón tay bấm không trượt. */
.pw { position: relative; }
.pw__input { padding-right: calc(var(--tap) + var(--s1)); }
.pw__eye {
  position: absolute; top: 0; right: 0;
  width: var(--tap); height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--text-muted); border-radius: var(--r-md);
}
.pw__eye:hover { color: var(--text); }
.pw__eye:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--brand-weak); }
/* Đang hiện mật khẩu thì nút sáng màu thương hiệu — nhìn là biết chữ đang lộ. */
.pw__eye[aria-pressed="true"] { color: var(--brand); }

.field__error { font-size: 13px; color: var(--do); margin-top: var(--s1); min-height: 18px; }
.field__hint { font-size: 13px; color: var(--text-muted); margin-top: var(--s1); }

/* ── Ô CHỌN NGÀY ─────────────────────────────────────────────────────────────
   Chép nguyên khối `.dt`/`.cal` của MEDUSA (`src/ui/khoangay.html`), chỉ đổi mã màu
   sang token ZORRO3. KHÔNG dùng `<input type="date">`: ô đó hiện theo lịch và ngôn
   ngữ của hệ điều hành nên mỗi máy một kiểu ngày — lý do đầy đủ ghi ở `ui.ts`. */
/* Kích thước chép ĐÚNG bản MEDUSA, không tự chế: `flex:1` + `min-width:200px` +
   `max-width:280px`, và bỏ trần bề ngang ở màn ≤640px. Bản tự chế trước đây đặt
   `min-width` cho Ô NHẬP (thứ MEDUSA không có) — trên iPhone nó ép ô rộng hơn chỗ còn
   trống nên chữ ngày bị đẩy ra ngoài, trong khi MEDUSA vừa khít không cần chỉnh gì. */
.dt { position: relative; display: flex; gap: 6px; flex: 1; min-width: 200px; max-width: 280px; }
.dt input {
  flex: 1; min-width: 0; min-height: var(--tap); padding: 0 var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface);
  color: var(--text); font-size: 16px; font-variant-numeric: tabular-nums;
  /* Ô chỉ đọc, chữ luôn vừa một dòng: cấm iOS tự phóng chữ trong ô làm tràn khung. */
  text-overflow: ellipsis; -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
}
.dt input:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px var(--brand-weak); }
/* Ô chỉ đọc: bấm vào là ra lịch, nên con trỏ phải là bàn tay chứ không phải con trỏ
   soạn thảo — nhìn con trỏ nháy mà không gõ được thì người dùng tưởng ô bị hỏng. */
.dt input[readonly] { cursor: pointer; }
.dt input:disabled, .dt .mo:disabled { opacity: .6; }
.dt .mo {
  flex: none; width: var(--tap); min-height: var(--tap); border: 1px solid var(--border);
  border-radius: var(--r-md); background: var(--surface); font-size: 17px; cursor: pointer;
}
.cal {
  position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; width: 280px; max-width: calc(100vw - 32px);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--sh-2); padding: 10px;
}
.cal .ch { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.cal .ch b { flex: 1; text-align: center; font-size: 14px; }
.cal .ch button { width: 34px; height: 34px; border: 0; border-radius: var(--r-sm); background: var(--surface-2); color: var(--text); cursor: pointer; }
/* `minmax(0, 1fr)` chứ KHÔNG phải `1fr`: `1fr` có sàn tự động bằng bề ngang tối thiểu
   của ô, nên nếu một ô đòi rộng hơn phần chia đều thì cả lưới phình ra khỏi khung lịch.
   Safari trên iPhone tính bề ngang tối thiểu của thẻ `<button>` theo cách riêng (còn tính
   cả padding mặc định của trình duyệt), nên lưới ngày rộng hơn khung ~19% và cột Chủ nhật
   rơi hẳn ra ngoài viền — đúng cái chủ salon chụp lại ngày 12/08/2026. Trên máy tính lưới
   vừa khít nên không ai thấy. `minmax(0, ...)` bỏ hẳn sàn đó, lưới không thể tràn nữa. */
.cal .wk, .cal .dd { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.cal .th12 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
.cal .wk span { text-align: center; font-size: 11px; color: var(--text-muted); padding: 3px 0; min-width: 0; }
.cal .dd button, .cal .th12 button {
  height: 34px; border: 0; border-radius: var(--r-sm); background: transparent;
  color: var(--text); font-size: 13px; cursor: pointer;
  /* Ba dòng dưới cùng phục vụ một việc: ô ngày co được về đúng phần chia đều. `padding: 0`
     bỏ đệm mặc định của trình duyệt (Safari: 1px 6px, cộng 12px mỗi ô × 7 ô = tràn),
     `min-width: 0` cho phép ô hẹp hơn nội dung, `appearance: none` bỏ nốt kích thước tối
     thiểu mà iOS gán cho nút bấm gốc. Trên máy tính không đổi một nét nào. */
  padding: 0; min-width: 0; -webkit-appearance: none; appearance: none;
}
.cal .th12 button { height: 40px; }
.cal .dd button:hover, .cal .th12 button:hover { background: var(--surface-2); }
.cal .dd button.ngoai { opacity: .35; }
.cal .dd button.hn, .cal .th12 button.hn { outline: 1px solid var(--brand); }
.cal .dd button.ch, .cal .th12 button.ch { background: var(--brand); color: #fff; font-weight: 700; }
/* Màn hẹp: bỏ trần 280px để ô ngày trải hết bề ngang còn lại — đúng dòng
   `@media (max-width:640px) { .dt { max-width:none } }` của MEDUSA. */
@media (max-width: 640px) { .dt { max-width: none; } }
/* Ô tích: MEDUSA cho hẳn 20×20px và tô theo màu thương hiệu. Thiếu khối này thì ô
   tích rơi về mặc định của trình duyệt — nhỏ hơn, và xanh hệ điều hành chứ không
   phải xanh ZORRO3. `.check` đang được dùng ở Hàng đợi và Giám sát. */
.check { display: flex; align-items: center; gap: var(--s2); min-height: var(--tap); }
.check input { width: 20px; height: 20px; accent-color: var(--brand); }

/* ── 14. NGĂN KÉO TRÊN ĐIỆN THOẠI ────────────────────────────────────────── */
.scrim {
  position: fixed; inset: 0; z-index: 35; background: rgba(9, 14, 20, .5);
  opacity: 0; pointer-events: none; transition: opacity .2s;
}
body.nav-open .scrim { opacity: 1; pointer-events: auto; }

/* ── 15. HỘP THOẠI ───────────────────────────────────────────────────────────
   Sự cố có thật trên MEDUSA (05/08/2026): hộp thoại cao hơn màn hình laptop nên
   không thấy nút Lưu/Huỷ, cuộn trong hộp không được, cuộn nền cũng không — người
   dùng kẹt cứng phải tải lại trang. Ở đây chặn ngay từ nền: hộp không bao giờ cao
   quá 100dvh (dvh trừ cả bàn phím điện thoại đang bật, vh thì không), và luôn chia
   ba phần đầu · thân cuộn · chân. */
.ov {
  position: fixed; inset: 0; z-index: 9000; display: flex; align-items: center; justify-content: center;
  padding: var(--s3); background: rgba(9, 14, 20, .55); overflow-y: auto;
}
.modal {
  display: flex; flex-direction: column; overflow: hidden;
  width: 560px; max-width: 100%; max-height: calc(100dvh - 24px);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-2);
}
@supports not (height: 100dvh) { .modal { max-height: calc(100vh - 24px); } }
.modal__head {
  flex: none; display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4); border-bottom: 1px solid var(--border);
}
.modal__head .t-h1 { flex: 1 1 auto; min-width: 0; }
.modal__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: var(--s4); }
.modal__foot {
  flex: none; display: flex; align-items: center; justify-content: flex-end; gap: var(--s2); flex-wrap: wrap;
  padding: var(--s3) var(--s4); border-top: 1px solid var(--border);
}
.modal__x {
  flex: none; width: 40px; height: 40px; padding: 0; line-height: 1; font-size: 19px;
  border-radius: var(--r-md); background: transparent; border: 1px solid var(--border); color: inherit; opacity: .8;
}
.modal__x:hover { opacity: 1; background: var(--surface-2); }
.modal--confirm { width: 420px; }
/* Lightbox phóng ảnh — lớp phủ riêng, z-index trên modal (9000) để không đóng modal Duyệt. */
.lightbox {
  position: fixed; inset: 0; z-index: 9500; display: flex; align-items: center; justify-content: center;
  padding: var(--s3); background: rgba(9, 14, 20, .82); cursor: zoom-out;
}
.lightbox__img { display: block; max-width: 100%; max-height: 100%; height: auto; border-radius: var(--r-sm); }
/* Đồng bộ MEDUSA màn Duyệt: modal rộng, thân 2 cột (ảnh trái · form sửa phải), xếp chồng ở
   điện thoại. Chỉ là khung — mọi hình thức qua class, không inline (CSP). */
/* `.modal` của `review.html`: rộng 1000px, tối đa 97vw. */
.modal--wide { width: 1000px; max-width: 97vw; }
/* Token legacy chính xác của MEDUSA review.html, chỉ áp dụng cho modal Duyệt. */
.modal--wide {
  --surface:#fff; --surface-2:#f6f7f9; --text:#1c2430; --text-muted:#6b7684;
  --border:#e6e9ee; --brand:#2f6fed; --brand-weak:#eaf0fb;
  --xanh:#127a4b; --xanh-weak:#e7f6ee; --cam:#b7791f; --cam-weak:#fff8e6;
  --do:#c0392b; --do-weak:#fdecea;
}
/* Thân modal = `.dbody` MEDUSA: ảnh trái 45% · form phải 55%, gap 14px; ≤760px xếp dọc. */
.modal2col { display: flex; gap: 14px; align-items: flex-start; }
.modal2col__col { min-width: 0; display: flex; flex-direction: column; gap: var(--s3); }
.modal2col__col:first-child { flex: 1 1 45%; }
.modal2col__col:last-child { flex: 1 1 55%; }
@media (max-width: 760px) { .modal2col { flex-direction: column; } .modal2col__col { flex: 1 1 auto; width: 100%; } }
/* B4: thân modal xếp dọc (2 cột ảnh·form ở trên, khối Quyết định ở dưới) + khối duyệt/từ chối. */
.modal-review { display: flex; flex-direction: column; gap: var(--s4); }
.decision { display: flex; flex-direction: column; gap: var(--s3); }
.decision__confirm { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s2); }
.modal--wide .modal__head { padding: 12px 16px; }
.modal--wide .modal__head .t-h1 { font-size:16px; font-weight:700; }
.modal--wide .modal__body { padding:14px 16px; }
.modal--wide .btn {
  min-height:0; padding:8px 12px; border:1px solid var(--md-line); border-radius:8px;
  background:var(--md-card); color:var(--md-ink); font-size:15px; font-weight:400;
}
.modal--wide .input, .modal--wide .select {
  min-height:0; padding:7px 10px; border:1px solid var(--md-line); border-radius:8px;
  background:var(--md-card); color:var(--md-ink); font-size:15px; font-weight:400;
}
.modal--wide .sohd { padding:3px 7px; border-width:2px; }
.modal-review--medusa .modal2col { align-items: stretch; }
.review-form { gap: 10px; }
.review-identity { display:flex; align-items:center; gap:7px; min-height:34px; }
.review-identity__label { white-space:nowrap; }
.review-identity .field { display:flex; align-items:center; gap:7px; margin:0; }
.review-identity .field__label { display:none; }
.review-identity .field__error { display:none; }
.review-identity__customer { color:var(--text-muted); }
.review-form > div:not(.review-identity):not(.decision) > .card { border:0; box-shadow:none; }
.modal--wide .modal2col__col:first-child > .card { border:0; box-shadow:none; background:transparent; }
.modal--wide .imgframe { padding:0; }
.review-form .editor-workers { padding:0; border:0; box-shadow:none; }
.review-form .card__foot { padding:8px 0 0; border:0; }
.decision--medusa { margin-top:auto; padding-top:8px; border-top:1px solid var(--border); }
.decision--medusa > .actions { display:flex; flex-direction:column; align-items:stretch; gap:8px; }
.decision--medusa .review-save { width:100%; color:#fff; background:#127a4b; border-color:#127a4b; }
.decision--medusa .review-save:hover:not(:disabled) { background:#127a4b; border-color:#127a4b; }
.review-form .card__foot .btn:not(.line-action--add) { display:none; }
.modal--wide .modal2col__col:first-child > .card > .card__foot { display:none; }
@media (max-width:560px) {
  .modal--wide .modal__head { gap:8px; padding:10px 12px; }
  .modal--wide .modal__head .t-h1 { font-size:14px; }
  .review-identity { gap:5px; }
  .review-identity .sohd { width:8.2em; font-size:15px; }
}
/* B5: bảng "Máy chủ tính (xem trước)" — viền trái thương hiệu để phân biệt với ô nhập. */
.preview { border-left: 3px solid var(--brand); }
/* Ô số hóa đơn lấy nguyên kích thước/trạng thái từ MEDUSA review.html. */
.sohd {
  font: 700 17px/1.2 ui-monospace, Consolas, monospace; letter-spacing: .14em;
  width: 9.5em; padding: 3px 7px; border-width: 2px; border-radius: 7px;
}
.sohd:focus { outline: none; border-color: #2f6fed; }
.sohd.xau { border-color: #c0392b; background: color-mix(in srgb, #c0392b 9%, transparent); }
/* ── CLONE màn /review MEDUSA (bố cục form sửa gần 1:1; màu chuyển sang biến ZORRO3) ────── */
/* Hàng Ngày + Thợ chính + Thợ phụ = .two/.fld của MEDUSA (flex, mỗi ô chia đều). */
.editor-workers { display: flex; gap: 10px; margin-bottom: 10px; }
.editor-workers > .field { flex: 1; margin: 0; }
@media (max-width: 560px) { .editor-workers { flex-direction: column; } }
/* Khối "Vì sao hóa đơn này cần kiểm tra" = .warns MEDUSA. */
.reason { background: var(--cam-weak); border-radius: 8px; padding: 6px 10px; margin-bottom: 10px; font-size: 13px; color: var(--cam); }
.reason__list { margin: 4px 0 0; padding-left: 18px; }
/* Lỗi CHẶN ghi sổ đọc khác hẳn lỗi chỉ cần liếc mắt: đỏ, đậm. Trộn chung một màu thì
   người duyệt không biết cái nào bắt buộc phải sửa mới bấm được nút. */
.reason__block { color: var(--do); font-weight: 700; }
/* Mỗi dòng dịch vụ = .eline MEDUSA. */
.eline { border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; margin-bottom: 8px; }
.cur { font-weight: 600; }
.cur.bad { color: var(--cam); }
.row2 { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.lsearch, .lprice {
  font: inherit; padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text);
}
.lsearch { flex: 1; min-width: 0; }
.lprice { width: 120px; text-align: right; }
.lcomm { font-size: 12.5px; color: var(--text-muted); margin-top: 5px; }
.lcomm--bad { color: var(--cam); }
.lresults { border: 1px solid var(--border); border-radius: 8px; margin-top: 4px; max-height: 160px; overflow: auto; display: none; }
.lresults.on { display: block; }
.lresults div { padding: 6px 9px; cursor: pointer; border-bottom: 1px solid var(--border); font-size: 14px; }
.lresults div:hover { background: var(--surface-2); }
/* Cuối form: Tổng dịch vụ (đậm) + khớp/lệch + tổng hoa hồng — .etot MEDUSA. */
.etot { margin: 8px 0; display: flex; flex-direction: column; gap: 2px; }
.etot__line { font-weight: 700; font-size: 15px; }
.etot__recon { font-size: 13px; }
.etot__comm { font-size: 13px; }
/* Xóa dòng = `.lxoa`/`.lxoabtn` của MEDUSA: nút nhỏ, viền đỏ, nằm sát mép PHẢI
   của dòng dịch vụ (trước đây ZORRO3 để mép trái và to bằng nút thường). */
.eline .btn--sm { align-self: flex-end; margin-top: 6px; }
/* Ba thao tác bổ sung được PO cho phép vẫn dùng nguyên token/nút MEDUSA. */
.line-action { white-space: nowrap; }
.line-action--add { color:var(--text); border-color:var(--border); background:var(--surface); }
.line-action--add:hover { color:var(--text); border-color:var(--border); background:var(--surface); }
.line-action--remove {
  background: transparent; color: var(--do); border-color: var(--do);
  min-height: 0; padding: 4px 10px; font-size: 12.5px;
}
.line-action--remove:hover { background: var(--do-weak); border-color: var(--do); }

/* ── MÀN DUYỆT HÓA ĐƠN OCR — BỘ MÀU RIÊNG, CHÉP NGUYÊN VĂN TỪ MEDUSA ─────────
   Nguồn: `medusa-v2/src/ui/review.html`, khối `:root` và khối
   `@media (prefers-color-scheme: dark)` của chính trang đó. Mã màu chép từ source,
   không dò từ ảnh chụp.

   VÌ SAO MÀN NÀY CÓ BỘ TOKEN RIÊNG, không dùng token chung của ZORRO3: MEDUSA có
   HAI thế hệ giao diện. Thế hệ 2.0 (`dashboard.html`) là nguồn của token chung
   ZORRO3; nhưng màn Duyệt hóa đơn OCR bên MEDUSA vẫn ở thế hệ cũ và khai bộ màu
   RIÊNG (`--ok:#127a4b` khác `--xanh:#0f7b4f`, `--warn:#b7791f` khác
   `--cam:#c2620a`, `--bg:#f6f7f9` khác `#f5f7fa`…). Chủ salon mở hai phần mềm cạnh
   nhau ở CÙNG màn này nên nó phải khớp với BẢN THẬT đang chạy, không phải với thế
   hệ 2.0. Phạm vi vì thế đóng khung trong `.ocr-review-screen` /
   `body.ocr-review-page` (main.ts gắn theo route `#/cho-duyet`) — các màn khác giữ
   nguyên token chung.

   LỖI ĐÃ SỬA Ở ĐÂY (19/08/2026): khối cũ viết CHẾT `background:#fff`,
   `border:#e6e9ee`, `#fff8e6`, `#1c2430` — chỉ đúng cho nền sáng. Điện thoại để nền
   tối thì thẻ hóa đơn ra MÀU TRẮNG giữa trang tối, mà chữ trong thẻ vẫn lấy `--text`
   sáng của nền tối, thành chữ trắng trên thẻ trắng: số hóa đơn, tên thợ, dòng dịch
   vụ gần như không đọc được. MEDUSA không dính vì nó dùng `var(--card)` có khai cả
   hai chế độ. Nay mọi màu ở đây đi qua token và có đủ hai chế độ. */
/* Phạm vi TOÀN CỤC (trước 21/08/2026 chỉ bó trong màn Duyệt hoá đơn). Nâng lên :root
   vì đã đo được: nhiều màn khác cũng ghim mã màu sáng của MEDUSA đời cũ mà KHÔNG có
   bản nền tối — nền thẻ giữ nguyên trắng trong khi chữ lấy `--text` sáng của nền tối,
   thành chữ trắng trên thẻ trắng. Đo trên production 21/08: tương phản 1.12–1.18
   (mức đọc được tối thiểu là 4.5). Có bộ token dùng chung khai đủ hai chế độ thì mọi
   màn hết lỗi một lần, và màn mới sau này không lặp lại được nữa. */
:root {
  --md-bg:#f6f7f9; --md-card:#fff; --md-ink:#1c2430; --md-muted:#6b7684;
  --md-line:#e6e9ee; --md-accent:#2f6fed; --md-ok:#127a4b; --md-okbg:#e7f6ee;
  --md-warn:#b7791f; --md-warnbg:#fff8e6; --md-err:#c0392b;
  /* Ba nền phụ mà các màn Thưởng/Lương đang ghim cứng — nay có bản cho cả hai chế độ. */
  --md-surface-2:#f1f5f9; --md-tong:#fff7dc; --md-chip:#fff5c8;
  /* Chữ đặt TRÊN nền màu đặc (nút xanh/đỏ, huy hiệu đếm). Nền sáng dùng nền màu ĐẬM
     nên chữ trắng đọc tốt; nền tối dùng cùng bộ màu ở sắc PASTEL SÁNG, chữ trắng trên
     đó chỉ còn tương phản 2.3–2.8 (đo trên production 21/08) nên phải đổi sang chữ
     thẫm. Một token, mọi nút cùng theo. */
  --chu-tren-nen-mau:#ffffff;
}
@media (prefers-color-scheme: dark) {
  :root {
    --md-bg:#0f1419; --md-card:#171d26; --md-ink:#e6e9ee; --md-muted:#9aa4b2;
    --md-line:#252d38; --md-accent:#5b8cf5; --md-ok:#3fbf83; --md-okbg:#12271c;
    --md-warn:#e0b341; --md-warnbg:#2a2410; --md-err:#e26d5c;
    --md-surface-2:#1c232c; --md-tong:#2a2410; --md-chip:#2a2410;
    --chu-tren-nen-mau:#0d1117;
  }
}
/* Nền toàn trang của riêng màn này — MEDUSA `body{background:var(--bg)}`. */
/* Màu chữ và giãn dòng đặt ở CẢ body: `.ocr-review-screen` chỉ phủ phần thân, còn
   MEDUSA khai `body{font:15px/1.5 …;color:var(--ink)}` cho toàn trang. ZORRO3 để
   giãn dòng 1.55 nên cùng một thẻ hóa đơn lại cao hơn MEDUSA vài pixel mỗi dòng. */
body.ocr-review-page { background: var(--md-bg); color: var(--md-ink); line-height: 1.5; }
.ocr-review-screen { color: var(--md-ink); line-height: 1.5; }

/* Hàng đợi dạng CARD — `.card` của review.html: hai thẻ cách nhau `margin-bottom:10px`,
   không phải 12px của lưới ZORRO3. */
.qlist { display: flex; flex-direction: column; gap: 10px; padding: var(--s3); }
.qcard {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px; border: 1px solid var(--md-line); border-radius: 12px;
  background: var(--md-card); color: var(--md-ink);
}
.qcard--warn { border-color: var(--md-warn); }
.qcard__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
/* `.hd` của MEDUSA: các mục cùng đường chân chữ, xuống hàng khi hết chỗ. */
.qcard__top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
/* `.hd .no` — đậm 700, KHÔNG phóng to. ZORRO3 trước để 800/16px nên số hóa đơn nhìn
   nặng hơn hẳn MEDUSA dù cùng nội dung. */
.qcard__num { font-weight: 700; }
.qcard__sum { color: var(--md-ok); font-weight: 700; font-variant-numeric: tabular-nums; }
.qcard__meta { color: var(--md-muted); font-size: 13px; }
/* `.staff` của MEDUSA: 13px và màu chữ phụ — ZORRO3 trước để 14px màu chữ chính. */
.qcard__workers, .qcard__hh { font-size: 13px; color: var(--md-muted); }
.qcard__hh strong { color: var(--md-ok); font-variant-numeric: tabular-nums; }
.qcard__lines { list-style: none; margin: 6px 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.qcard__line { font-size: 14px; }
.qcard__line::before { content: "• "; color: var(--md-muted); }
/* `.lines .bad` là màu CẢNH BÁO (vàng nâu), không phải màu lỗi đỏ. */
.qcard__line--warn { color: var(--md-warn); }
/* `.rowbtns` — cột nút bên phải, cách nhau 6px. */
.qcard__actions { flex: none; display: flex; flex-direction: column; gap: 6px; }
.qcard__actions .btn { white-space: nowrap; }
.qcard__actions .btn {
  min-height: 0; padding: 8px 12px; border: 1px solid var(--md-line); border-radius: 8px;
  background: var(--md-card); color: var(--md-ink); font-size: 15px; font-weight: 400;
}
/* `.warns` — ô cảnh báo vàng. */
.qcard__warnings {
  margin-top: 6px; padding: 6px 10px; border-radius: 8px;
  background: var(--md-warnbg); color: var(--md-warn); font-size: 13px;
}
/* `.chk input{width:18px;height:18px}` — ô tích MEDUSA nhỏ hơn ô 20px của ZORRO3. */
.ocr-review-screen .check input { width: 18px; height: 18px; accent-color: var(--md-accent); }
.qcard .check.tick { padding-top: 2px; }
/* `button.ok` — nút Duyệt nhanh. Nền tối MEDUSA đổi sang `#3fbf83`; bản cũ ZORRO3 ghim
   chết `#127a4b` cho cả hai chế độ nên nền tối nhìn tối hơn hẳn MEDUSA. */
.queue-action--ok {
  background: var(--md-ok) !important; border-color: var(--md-ok) !important;
  color: var(--chu-tren-nen-mau) !important;
}
/* Thanh thao tác hàng loạt, khung danh sách và chân trang cùng bộ màu với thẻ — nếu
   không, nền tối sẽ có một dải sáng lạc lõng ngay trên đầu danh sách. */
.ocr-review-screen .batchbar,
.ocr-review-screen .card,
.ocr-review-screen .cardbody { background: var(--md-card); border-color: var(--md-line); color: var(--md-ink); }
.ocr-review-screen .batchbar .note,
.ocr-review-screen .card__foot .note,
.ocr-review-screen .empty { color: var(--md-muted); }
.ocr-review-screen .btn { border-color: var(--md-line); background: var(--md-card); color: var(--md-ink); }
.ocr-review-screen .btn--primary { background: var(--md-accent); border-color: var(--md-accent); color: #fff; }
.ocr-review-screen .input, .ocr-review-screen .select {
  border-color: var(--md-line); background: var(--md-card); color: var(--md-ink);
}
.ocr-review-screen .input::placeholder { color: var(--md-muted); }
/* Điện thoại: nút xuống hàng, trải ngang cho dễ bấm. */
@media (max-width: 560px) {
  .qcard { flex-wrap: wrap; }
  .qcard__actions { flex-direction: row; width: 100%; }
  .qcard__actions .btn { flex: 1; }
}
/* Tô cảnh báo tại ô nhập khi sửa (port markChinh của MEDUSA) — qua class, không .style inline. */
.input.is-warn, .select.is-warn { border-color: var(--cam); background: var(--cam-weak); }
.input.is-error, .select.is-error { border-color: var(--do); background: var(--do-weak); }
body.modal-open { overflow: hidden; }

.deflist { margin: 0; display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: var(--s2) var(--s4); }
.deflist dt { color: var(--text-muted); font-size: 14px; }
.deflist dd { margin: 0; font-size: 15px; font-variant-numeric: tabular-nums; word-break: break-word; }
.rawbox {
  margin: 0; padding: var(--s3); border-radius: var(--r-md); background: var(--surface-2);
  border: 1px solid var(--border); font-size: 13px; line-height: 1.5; overflow-x: auto;
  font-family: ui-monospace, "SF Mono", "Segoe UI Mono", "Cascadia Mono", monospace;
}

/* ── 15b. CHỌN VÀ XEM ẢNH ────────────────────────────────────────────────── */
.picker {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  min-height: 76px; padding: var(--s4); cursor: pointer;
  border: 1px dashed var(--border-strong); border-radius: var(--r-md); background: var(--surface-2);
}
.picker:hover { border-color: var(--brand); }
.picker__ico {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-md); background: var(--brand-weak); color: var(--brand);
}
.picker__text { font-weight: 600; }
.picker__hint { display: block; font-weight: 400; font-size: 14px; color: var(--text-muted); }
input[type="file"]:focus-visible + .picker { outline: 2px solid var(--brand); outline-offset: 2px; }

.preview { margin-top: var(--s4); }
.preview__img {
  display: block; width: 100%; max-height: 340px; object-fit: contain;
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface-2);
}
.preview .t-cap { margin: var(--s2) 0 0; }

/* Khung ảnh gốc trên màn duyệt: luôn thấy trọn tờ hóa đơn, bấm vào xem to.
   Kích thước/viền/bo góc theo `.dimg img` của `review.html` MEDUSA. */
.imgframe { padding: var(--s3); text-align: center; }
.imgframe__zoom {
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  width: 100%; padding: 0; border: none; background: none; cursor: zoom-in;
}
.imgframe__img {
  display: block; max-width: 100%; max-height: 70vh; object-fit: contain;
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface-2);
  transform-origin: center center; transition: transform .15s ease;
}
/* ── XOAY ẢNH — CHỈ ĐỂ NHÌN (`.xoaybar` của MEDUSA) ────────────────────────────
   Telegram gỡ cờ xoay EXIF nên có tấm về tới nơi nằm ngang, người duyệt phải
   nghiêng đầu đọc ô Thợ chính/Thợ phụ. Xoay bằng `transform` nên tệp ảnh giữ
   NGUYÊN XI: không đọc lại, không tốn thêm một lượt gọi máy đọc ảnh nào.

   Góc quay là 4 giá trị rời rạc nên nằm hẳn trong tệp này; chỉ hai con số PHẢI
   tính lúc chạy (tỉ lệ thu nhỏ và chiều cao ô chiếm chỗ) mới truyền vào bằng
   biến CSS — trang chạy dưới CSP chặn style nội tuyến. */
.imgframe { --rot-scale: 1; }
.imgframe--r90  .imgframe__img { transform: rotate(90deg)  scale(var(--rot-scale)); }
.imgframe--r180 .imgframe__img { transform: rotate(180deg); }
.imgframe--r270 .imgframe__img { transform: rotate(270deg) scale(var(--rot-scale)); }
.imgframe--r90 .imgframe__zoom, .imgframe--r270 .imgframe__zoom { height: var(--rot-h); }
.xoaybar {
  display: flex; gap: var(--s2); justify-content: center; align-items: center;
  margin-top: var(--s2); flex-wrap: wrap;
}
.xoaybar .btn { min-height: 34px; padding: 6px 12px; font-size: 13px; }
.xoaybar__goc { font-size: 13px; color: var(--text-muted); min-width: 52px; }
.xoaybar__nhac { font-size: 13px; color: var(--cam); font-weight: 600; }
.imgfull { display: block; width: 100%; height: auto; border-radius: var(--r-sm); }

/* ── 15c. TAB LỌC · BẢNG BẤM ĐƯỢC · KHỐI GỢI Ý ───────────────────────────── */
.tabs { display: flex; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s3); }
/* Danh sách mẫu báo cáo = `.grp`/`.cards`/`.rcard` của `reports.html` MEDUSA.
   Trước đây ZORRO3 để thẻ cao 92px, chữ 17px, biểu tượng 54px và lưới cứng 3–4 cột;
   MEDUSA là thẻ 60px, chữ 15px, biểu tượng 36px, lưới tự xếp theo bề rộng 260px. */
.report-catalog { display:flex; flex-direction:column; margin-bottom:var(--s5); }
.report-catalog__title {
  margin:20px 2px 8px; color:var(--text-muted);
  font-size:12px; font-weight:800; text-transform:uppercase; letter-spacing:.05em;
}
.report-catalog__grid, .report-catalog__grid--four {
  display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:10px;
}
.report-choice {
  display:flex; align-items:center; gap:11px; width:100%; min-height:60px; padding:12px 14px;
  text-align:left; background:var(--surface); border:1px solid var(--border); border-radius:12px;
  color:var(--text); font-size:15px; font-weight:600;
}
.report-choice__icon {
  flex:none; width:36px; height:36px; border-radius:9px; background:var(--brand-weak);
  display:grid; place-items:center; font-size:17px;
}
.report-choice__label { min-width:0; line-height:1.35; }
.report-choice__arrow { margin-left:auto; color:var(--text-muted); font-size:18px; font-weight:400; }
.report-choice:hover { border-color:var(--brand); color:var(--brand); }
.report-choice--on { border-color:var(--brand); background:var(--brand-weak); color:var(--brand); }
.navgroup__title--link { display:block; color:inherit; text-decoration:none; cursor:pointer; }
.navgroup__title--link:hover, .navgroup__title--link:focus-visible { color:var(--brand); text-decoration:underline; }
.date-input { min-width:0; font-variant-numeric:tabular-nums; letter-spacing:.01em; }
@media (max-width: 600px) {
  .date-input { width:100%; min-height:44px; font-size:16px; }
  .close-page-body .lock-toolbar .date-input { flex:1 1 100%; }
}
@media (min-width: 901px) {
  .report-page .sidebar, .report-page .scrim, .report-page > .app .topbar { display:none; }
  .report-page .main { margin-left:0; }
  .report-page .content { max-width:1760px; padding:20px 44px var(--s8); }
}
/* Bảng báo cáo giữ mỗi ô trên MỘT dòng rồi cho cuộn ngang, đúng như golden
   `src/ui/reports.html`. Bảng nào rộng hơn màn hình thì dù sao cũng phải cuộn,
   nên để chữ xuống dòng chỉ làm dòng cao gấp ba mà không đỡ phải cuộn — trên
   390px "Nguyễn Thị Hương" vỡ thành ba dòng. Chỉ áp cho màn Báo cáo. */
.report-screen .table th, .report-screen .table td { white-space: nowrap; }
/* Token chính xác của MEDUSA reports.html, không làm đổi màu các màn khác. */
.report-screen {
  --bg:#eef1f6; --surface:#fff; --text:#1b2436; --text-muted:#6b7689;
  --border:#e4e8ef; --brand:#2f6fed; --brand-weak:#eaf1ff; --head:#1f2b52;
  --xanh:#1e874b; --do:#c0392b;
}
@media (prefers-color-scheme: dark) {
  .modal--wide {
    --surface:#171d26; --surface-2:#0f1419; --text:#e6e9ee; --text-muted:#9aa4b2;
    --border:#252d38; --brand:#5b8cf5; --brand-weak:#1b2534;
    --xanh:#3fbf83; --xanh-weak:#12271c; --cam:#e0b341; --cam-weak:#2a2410;
    --do:#e26d5c; --do-weak:#2a1512;
  }
  .report-screen {
    --bg:#0f1419; --surface:#161c26; --text:#e7ebf1; --text-muted:#98a2b3;
    --border:#242c38; --brand:#5b8cf5; --brand-weak:#1c2740; --head:#20304f;
    --xanh:#4cc38a; --do:#e06b5a;
  }
}
.report-filter { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--s3); align-items:end; margin-bottom:var(--s4); }
.report-filter > .field { margin-bottom:0; min-width:0; }
.report-filter > .field:last-child { grid-column:1 / -1; }
.presets { display:flex; flex-wrap:wrap; gap:var(--s2); }
.report-preset { min-height:36px; border-radius:var(--r-pill); color:var(--text-muted); }
.report-preset:hover { border-color:var(--brand); color:var(--brand); background:var(--brand-weak); }
/* Nút "Chọn nhanh" đang dùng tô đậm như `.pbtn.on` của MEDUSA — không tô thì chủ salon
   không biết tờ báo cáo đang lấy theo kỳ nào. */
.report-preset--on, .report-preset--on:hover { background:var(--brand); border-color:var(--brand); color:#fff; }

/* ── Trang CHỌN KỲ (bước 2 của MEDUSA) ───────────────────────────────────────
   `.panel` của `src/ui/reports.html`: một khối hẹp, mỗi điều kiện một dòng, nút "Xem
   báo cáo" trải hết bề ngang ở cuối. Khác hẳn `.report-filter` cũ (lưới 2 cột nhét
   chung trang với tờ báo cáo). */
.report-panel { max-width:520px; margin-top:var(--s4); }
.report-panel.report-filter { display:block; margin-bottom:0; }
.report-panel > .field { margin-bottom:14px; }
.report-panel .presets { display:flex; flex-wrap:wrap; gap:var(--s2); }
.report-view { width:100%; min-height:52px; margin-top:var(--s2); font-size:16px; }
.catalog-tabs { display:flex; gap:10px; overflow-x:auto; padding:2px 0 18px; scrollbar-width:thin; }
.catalog-tab { min-height:50px; flex:none; padding:0 20px; border:1px solid var(--border); border-radius:var(--r-pill); background:var(--surface); color:var(--text); font-size:16px; }
.catalog-tab:hover:not(:disabled) { border-color:var(--brand); color:var(--brand); }
.catalog-tab--on { background:var(--brand); border-color:var(--brand); color:#fff; }
.catalog-tab:disabled { opacity:.48; cursor:not-allowed; }
.catalog-screen > .block { scroll-margin-top:90px; }
.catalog-screen > .block:first-of-type { display:none; }
.catalog-screen #catalog-employees > .block__hint { display:none; }
.catalog-code { min-width:66px; min-height:46px; padding:0 10px; display:grid; place-items:center; border-radius:12px; background:var(--surface-2); font-weight:800; }
.employee-catalog { display:grid; grid-template-columns:minmax(420px,.9fr) minmax(520px,1.1fr); gap:16px; align-items:start; }
.employee-list,.employee-editor { padding:16px; min-width:0; }
.employee-panel-title { margin:0 0 14px; color:var(--text-muted); font-size:16px; font-weight:800; }
.employee-filters { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:10px; }
.employee-filter { min-height:38px; padding:7px 14px; border-radius:999px; }
.employee-filter--on { color:#fff; background:var(--brand); border-color:var(--brand); }
.employee-search { display:grid; grid-template-columns:1fr auto; gap:8px; margin-bottom:8px; }
.employee-list__rows { max-height:570px; overflow:auto; }
/* Hàng nhân viên = FLEX, KHÔNG lưới cột cứng (chốt 13/08/2026): khuôn cũ khóa ô mã ở
   54px trong khi "NV0001" chữ đậm — và cỡ chữ lớn trên iPhone — rộng hơn thế, tràn đè
   lên tên. Ô mã giờ to theo nội dung và không co; khối tên chiếm phần còn lại với
   min-width:0 nên tên dài cắt "…" chứ không bao giờ chồng chữ; thẻ hồ sơ một hàng riêng. */
.employee-row { width:100%; display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; padding:12px; border:0; border-bottom:1px solid var(--border); background:var(--surface); color:var(--text); text-align:left; }
.employee-row:hover,.employee-row--on { background:var(--vang-weak); }
.employee-row__code { flex:0 0 auto; min-height:38px; display:inline-grid; place-items:center; padding:4px 10px; border-radius:10px; background:var(--surface-2); font-weight:800; }
.employee-row__main { flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:2px; }
.employee-row__body { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:800; }
.employee-row__role { color:var(--text-muted); font-size:14px; }
.employee-row__foot { flex-basis:100%; }
.employee-profile-count { display:inline-block; border:1px solid #d97706; color:#b45309; border-radius:999px; padding:4px 8px; font-size:12px; font-weight:700; }
.employee-profile-count--ok { border-color:#16844a; color:#167444; }
.employee-form { display:grid; gap:12px; }
.employee-save { margin:14px 0 18px; }
.employee-delete { margin-bottom:18px; }
.employee-documents__title { padding-top:18px; border-top:1px solid var(--border); color:var(--text-muted); font-size:16px; }
.employee-documents { display:grid; gap:12px; }
.employee-document { min-height:126px; padding:14px; border:1px solid var(--border); border-radius:14px; }
.employee-document__head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.employee-document__head .note { margin-left:auto; }
.employee-document__previews { display:flex; align-items:center; gap:5px; margin-top:12px; }
.employee-document__preview { min-width:82px; height:66px; border:1px solid var(--border); border-radius:10px; background:var(--surface-2); font-weight:700; }
.employee-document__remove { width:28px; height:28px; padding:0; border:0; border-radius:50%; color:#fff; background:#4b5563; font-size:20px; }
.catalog-screen .row--stack { grid-template-columns:auto minmax(0,1fr) auto auto; }
@media (min-width:901px) {
  .catalog-page .sidebar, .catalog-page .scrim { display:none; }
  .catalog-page .main { margin-left:0; }
  .catalog-page .topbar { max-width:none; background:var(--surface); padding:30px 28px 24px; border-bottom:1px solid var(--border); }
  .catalog-page .topbar__hello #screen-title::before { content:"ZORRO3 — "; }
  .catalog-page .topbar__hello #screen-sub { display:none; }
  .catalog-page .content { max-width:1240px; padding-top:18px; }
}
@media (max-width: 760px) {
  .employee-catalog { grid-template-columns:1fr; }
  .employee-list,.employee-editor { padding:14px; }
  .employee-list__rows { max-height:430px; }
  /* Khuôn flex mới tự xếp đúng ở mọi bề ngang — không cần luật lưới riêng cho điện thoại. */
  .employee-document__head .note { margin-left:0; }
  .employee-document__head .btn { width:100%; }
}
/* Khung một báo cáo = `.report` MEDUSA: thẻ bo 14px, đệm 20px 22px, tiêu đề CĂN GIỮA
   19px, dòng phụ 13px mờ. Trước đây ZORRO3 để đệm 34px và tiêu đề 24–25px. */
.service-report { margin-top:28px; padding:20px 22px; }
.report-detail-head { margin:-20px -44px 0; padding:16px 32px; min-height:80px; display:flex; align-items:center; justify-content:space-between; gap:20px; background:var(--surface); border-bottom:1px solid var(--border); }
.report-detail-head__left { display:flex; align-items:center; gap:24px; }
.report-detail-head__left .t-display { font-size:21px; }
.report-detail-back { color:var(--brand); border-color:transparent; background:transparent; padding-left:0; }
.service-report__head { text-align:center; margin-bottom:16px; }
.service-report__title { margin:2px 0 4px; font-size:19px; }
.service-report__head .t-cap { font-size:13px; }
/* Ô số liệu đầu báo cáo = `.kpis`/`.kpi` MEDUSA: lưới TỰ xếp theo bề rộng 190px
   (không phải 3 hay 4 cột cứng), thẻ cao vừa nội dung, biểu tượng 40px, số 19px. */
.service-report__metrics, .commission-report__metrics {
  display:grid; grid-template-columns:repeat(auto-fit, minmax(190px, 1fr)); gap:12px; margin-bottom:16px;
}
/* Điện thoại: dưới 480px một cột, 480–900px hai cột — auto-fit ở khoảng này hay rơi vào
   thế 190px chật cứng làm con số bên trong phải gãy dòng (ảnh chụp iPhone 13/08/2026).
   Viết kèm `.service-report` để THẮNG luật `1fr 1fr` trong khối max-900px phía dưới
   (khối đó đứng sau trong tệp nên cùng độ ưu tiên là nó đè). */
@media (max-width:479px) {
  .service-report .service-report__metrics, .service-report .commission-report__metrics,
  .commission-report .commission-report__metrics { grid-template-columns:1fr; }
}
@media (min-width:480px) and (max-width:900px) {
  .service-report .service-report__metrics, .service-report .commission-report__metrics,
  .commission-report .commission-report__metrics { grid-template-columns:repeat(2, minmax(0, 1fr)); }
}
/* 900–1199px (đúng khổ màn 1280 để phóng to 125% = 1024px CSS): `auto-fit` vẫn nhét đủ
   BỐN ô một hàng vì 4×190+lề = 796px < chỗ có. Nhưng mỗi ô là một HÀNG NGANG gồm biểu
   tượng 40px + nhãn + con số 19px cấm bẻ dòng: "106.185.000" chiếm ~130px, nên phần còn
   lại cho chữ chỉ khoảng 3px và nhãn vỡ thành từng ký tự xếp dọc —
   "T / ổ / n / g / h / o / a / h / ồ / n / g". Chụp trên production 26/08/2026.
   Hai ô một hàng thì nhãn còn ~200px, thừa sức nằm gọn. */
@media (min-width:901px) and (max-width:1199px) {
  .service-report .service-report__metrics, .service-report .commission-report__metrics,
  .commission-report .commission-report__metrics { grid-template-columns:repeat(2, minmax(0, 1fr)); }
}
.commission-report__table .table { min-width:980px; }
.commission-report__table .table th,
.commission-report__table .table td { white-space:nowrap; }
/* Bảng nhiều cột (≥6 — `dataTable` tự gắn lớp): KHÔNG co theo màn hình. Giữ bề ngang
   tối thiểu rồi cuộn ngang trong `.table-wrap`; cột đầu (Ngày/tên) GHIM lại với nền đặc
   để chữ phía sau không đè lên khi cuộn. Nền dòng chẵn phải trộn ra MÀU ĐẶC (trộn với
   `--surface` thay vì transparent) — nền trong suốt thì ghim cũng như không. */
.table--rong { min-width:900px; }
.table--rong th:first-child, .table--rong td:first-child {
  position:sticky; left:0; z-index:2; background:var(--surface);
  box-shadow:2px 0 0 color-mix(in srgb, var(--border) 70%, transparent);
}
.report-screen .table--rong thead th:first-child { background:var(--head); }
.report-screen .table--rong tbody tr:nth-child(even):not(.row--total) td:first-child {
  background:color-mix(in srgb, var(--bg) 45%, var(--surface));
}
/* `tfoot` cũng là dòng TỔNG CỘNG (bảng chéo thống kê dịch vụ dựng tổng bằng tfoot chứ
   không bằng `.row--total`). Thiếu vế này thì ô đầu dòng tổng ăn nền trắng của cột ghim,
   nhìn ra một ô trắng lạc lõng giữa dải xanh. */
.report-screen .table--rong .row--total td:first-child,
.report-screen .table--rong tfoot td:first-child { background:var(--brand-weak); }

.service-report__metric {
  display:flex; align-items:center; gap:11px; min-width:0;
  border:1px solid var(--border); border-radius:12px; padding:12px 14px;
}
.service-report__metric-icon {
  flex:none; width:40px; height:40px; display:grid; place-items:center;
  border-radius:10px; background:var(--brand-weak); font-size:19px;
}
.service-report__metric > div { min-width:0; }
/* `anywhere` là thứ biến chỗ chật thành chữ vỡ từng ký tự: nó bẻ ngay khi thấy hết chỗ,
   không cần biết còn cách nào khác. `break-word` chỉ bẻ khi cả từ không nằm nổi một dòng —
   chật thì chữ tràn ra chứ không bao giờ rơi thành cột ký tự dọc. */
.service-report__metric-copy { color:var(--text-muted); font-size:12.5px; overflow-wrap:break-word; }
/* Con số KPI cấm bẻ dòng — `overflow-wrap:anywhere` cũ chính là thủ phạm bẻ
   "26.623.000đ" thành ba khúc trên iPhone. Lưới đã lo đủ chỗ (1 cột dưới 480px). */
.service-report__metric-value {
  font-size:19px; font-weight:800; margin-top:2px; line-height:1.2;
  white-space:nowrap; font-variant-numeric:tabular-nums;
}
.service-report__metric-value--brand { color:var(--brand); }
.service-report__table { overflow:hidden; border-radius:12px; border:1px solid var(--border); }
.service-report__table .table .row--total { background:var(--brand-weak); color:var(--brand); font-weight:800; border-top:2px solid var(--brand); }
.report-paper { margin-top:28px; padding:20px 22px; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); box-shadow:var(--sh-1); }
.report-screen .report-paper:has(.daily-report-card) {
  width:100%; margin:28px auto 0; padding:0; background:transparent; border:0; box-shadow:none;
}
.report-paper > .block:first-child .block__head { justify-content:center; text-align:center; }
/* Tiêu đề báo cáo = `.report h2` MEDUSA: chữ HOA nằm sẵn trong nội dung, thẻ h2
   KHÔNG giãn chữ. `.t-h2` giãn .06em nên tiêu đề rộng ra so với MEDUSA. */
.report-paper > .block:first-child .t-h2 { font-size:19px; color:var(--text); letter-spacing:normal; }
/* Cột bấm được ở "Tổng hợp hoa hồng" — `thead th.dr` MEDUSA. */
.report-screen .table th.dr { cursor:pointer; text-decoration:underline dotted; }
.report-screen .table th.dr:hover { background:var(--brand); }
.report-paper .block__hint { text-align:center; font-size:13px; }
.report-paper .card { box-shadow:none; }
.report-paper .table-wrap { border-radius:12px; border:1px solid var(--border); overflow:auto; }
.report-paper .card > .table-wrap { border:0; }
.revenue-summary { padding:18px 16px; overflow:hidden; }
.revenue-summary__head { text-align:center; margin-bottom:16px; }
.revenue-summary__mark { display:inline-grid; place-items:center; width:36px; height:36px; margin-right:10px; border-radius:8px; background:#67b489; color:#fff; font-size:20px; vertical-align:middle; }
.revenue-summary__title { display:inline; margin:0; font-size:20px; color:var(--text); }
.revenue-summary__head .note { margin:4px 0 0; }
.revenue-summary__table { width:100%; border-collapse:collapse; font-size:15px; }
.revenue-summary__table th { padding:12px 18px; background:#d9efd4; text-align:center; font-size:13px; }
.revenue-summary__table td { padding:15px 18px; border:1px solid var(--border); }
.revenue-summary__table td:last-child { width:45%; text-align:right; font-size:17px; font-weight:800; color:#26854b; }
.revenue-summary__icon { display:inline-grid; place-items:center; width:28px; height:28px; margin-right:12px; border-radius:50%; background:#4c9d5c; color:#fff; }
.revenue-summary__icon--2 { background:#4778df; }.revenue-summary__icon--3 { background:#e78911; }
.revenue-summary__icon--4 { background:#8e5bd3; }.revenue-summary__icon--5 { background:#39aeb0; }.revenue-summary__icon--6 { background:#d75b85; }
.revenue-summary__note { margin:12px 0 0; padding:10px 14px; background:#e8f3e5; color:var(--text-muted); font-size:13px; }
.reward-report { max-width:1180px; margin:0 auto; padding:14px 16px 16px; border-radius:14px; background:var(--md-card); color:var(--md-ink); }
.reward-report__brand { display:flex; justify-content:space-between; align-items:center; color:var(--md-accent); font-size:12px; }
.reward-tabs { display:inline-flex; margin:16px 0 10px; border:1px solid var(--md-line); border-radius:8px; overflow:hidden; }
.reward-tabs .btn { min-height:36px; padding:6px 18px; border:0; border-radius:0; background:var(--md-card); color:var(--md-ink); font-size:12px; }
.reward-tabs .reward-tabs__on { background:var(--md-accent); color:#fff; }
.reward-report__head { text-align:center; margin:-1px 0 14px; }
.reward-report__title { margin:0 0 3px; font-size:20px; line-height:1.2; }
.reward-report__head .note { margin:0; font-size:12px; }
.reward-filter { display:flex; align-items:flex-end; gap:12px; padding:14px; margin-bottom:14px; border:1px solid var(--md-line); border-radius:10px; background:var(--md-card); }
.reward-filter .field { flex:0 1 190px; min-width:150px; margin:0; }
.reward-filter .input { min-height:40px; }
.reward-filter > .btn { min-height:40px; padding-inline:18px; }
.reward-tools { display:flex; gap:8px; margin-left:auto; }
.reward-tools .btn { min-height:38px; padding:6px 13px; background:var(--md-card); color:var(--md-ink); }
.reward-metrics { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:14px; }
.reward-metric { display:grid; grid-template-columns:34px 1fr; grid-template-areas:"icon label" "icon value"; align-items:center; padding:13px 14px; border:1px solid var(--md-line); border-radius:10px; }
.reward-metric__icon { grid-area:icon; width:28px; height:28px; display:grid; place-items:center; border-radius:8px; background:var(--md-chip); }
.reward-metric__label { grid-area:label; color:var(--md-muted); font-size:12px; }
.reward-metric strong { grid-area:value; color:var(--md-ink); font-size:17px; }
.reward-report__scroll { overflow-x:auto; border:1px solid var(--md-line); border-radius:9px 9px 0 0; }
.reward-report__table { min-width:930px; width:100%; border-collapse:collapse; font-size:13px; }
.reward-report__table th,.reward-report__table td { height:42px; padding:7px 10px; border-right:1px solid var(--md-line); border-bottom:1px solid var(--md-line); text-align:right; white-space:nowrap; }
.reward-report__table th { height:48px; background:#15244f; color:#fff; text-align:center; font-size:11px; }
.reward-report__table .reward-report__employee { position:sticky; left:0; z-index:1; min-width:130px; background:var(--md-card); text-align:left; }
.reward-report__table th.reward-report__employee { z-index:2; background:#15244f; }
.reward-report__unit { display:block; color:#c7d2e8; font-size:10px; font-weight:400; }
.reward-report__total td { background:var(--md-tong); color:var(--md-ink); font-weight:800; }
.reward-report__total .reward-report__employee { background:var(--md-tong); }
.reward-report__note { margin-top:12px; padding:12px 14px; border-radius:8px; background:var(--md-surface-2); color:var(--md-muted); font-size:12px; }
.reward-admin{max-width:1180px;margin:0 auto;padding:10px 16px 24px}.reward-monthbar,.reward-admin-tabs{display:flex;align-items:center;gap:8px;margin-bottom:10px}.reward-monthbar .input,.reward-monthbar .dt{width:190px}.reward-open{padding:5px 10px;border:1px solid var(--md-warn);border-radius:999px;color:var(--md-warn);background:var(--md-warnbg);font-size:12px}.reward-admin-tabs .btn{border-radius:999px;background:var(--md-card);color:var(--md-ink)}.reward-admin-tabs .reward-admin-tabs__on{background:var(--md-accent);color:#fff;border-color:var(--md-accent)}.reward-report__salon{margin-bottom:7px;color:var(--md-accent);font-size:11px}.reward-config{padding:16px}.reward-config h3{margin:0 0 12px;color:var(--md-muted);font-size:14px}.reward-config__scroll{margin:14px 0;overflow:auto}.reward-config__table{min-width:1000px}.reward-config__table th{background:var(--md-surface-2);color:var(--md-ink);text-align:center}.reward-config__table td{vertical-align:middle}.reward-config__table td:last-child{white-space:nowrap}.btn--small{min-height:30px;padding:4px 10px;margin:2px}.btn--danger-outline{border-color:var(--md-err);color:var(--md-err);background:var(--md-card)}.reward-editor{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:14px 0;padding:16px;border:1px solid var(--md-line);border-radius:10px;background:var(--md-surface-2)}.reward-editor h3,.reward-editor .actions{grid-column:1/-1}.reward-editor .actions{display:flex;justify-content:flex-end;gap:8px}.reward-assign-list{margin-top:12px;border-top:1px solid var(--md-line)}.reward-assign-row{display:grid;grid-template-columns:2fr 1fr 1.4fr;align-items:center;gap:10px;min-height:48px;padding:7px 10px;border-bottom:1px solid var(--md-line)}.reward-audit{width:100%;min-width:800px}.reward-audit__detail{max-width:650px;white-space:normal;word-break:break-word}
.report-paper .table .row--total, .report-paper .table tfoot tr { background:var(--brand-weak); color:var(--brand); font-weight:800; border-top:2px solid var(--brand); }

/* ── BẢNG BÁO CÁO — chép đúng `reports.html` MEDUSA ─────────────────────────
   MEDUSA: `table{font-size:13px}` · `thead th{background:var(--head);color:#fff;
   padding:10px 11px;font-weight:700}` · `tbody td{padding:9px 11px}` · dòng chẵn
   `color-mix(in srgb,var(--bg) 45%,transparent)` · `tr.total` nền `--accent2`
   (= `--brand-weak` ở thế hệ 2.0) + viền trên 2px `--accent` (= `--brand`).
   Trước đây ZORRO3 tô cứng `#21305c` và `#f4f6fa` — không khớp mã nào của MEDUSA
   và không đổi được theo nền tối. */
.report-screen .table { font-size:13px; }
.report-screen .table th {
  background:var(--head); color:#fff; font-weight:700; padding:10px 11px; font-size:13px;
  -webkit-print-color-adjust:exact; print-color-adjust:exact;
}
.report-screen .table td { padding:9px 11px; }

/* ── Bảng ma trận trên MÀN HÌNH: tự co vừa khung, không tràn ra rồi bị xén ────
   `.table--in-vua` do `soCot()` gắn cho MỌI bảng ma trận từ 6 cột trở lên (Tổng hợp hoa
   hồng, Thống kê dịch vụ theo nhân viên/thợ phụ…), kèm `--so-cot` là số cột thật.

   Lỗi thật 23/08/2026 — ZORRO 1 có 13 nhân viên: bảng cần 1159px trong khi khung chỉ
   1067px. Mỗi nhân viên là MỘT cột, ô lại `white-space:nowrap` (luật `.report-screen`
   bên trên), nên phần thò ra bị `.table-wrap` xén — cột nhân viên cuối và số tiền của
   người đó ở dòng TỔNG CỘNG biến mất khỏi màn hình. Có thanh cuộn ngang nhưng người xem
   không thấy, nên tưởng báo cáo thiếu số, và mọi ảnh chụp màn hình đều mất cột thật.

   Cách sửa: bề ngang tối thiểu tính THEO SỐ CỘT thay vì một con số cứng, `width:100%`
   để lấp đầy khung khi còn chỗ, `table-layout:fixed` chia đều phần còn lại. Chỉ khi đông
   cột tới mức 68px/cột cũng không đủ mới rơi lại về cuộn ngang — bản in thì tự co riêng
   (mục 20) và không bao giờ cuộn.

   ĐẶT Ở ĐÂY, KHÔNG ĐẶT CẠNH `.table--rong` PHÍA TRÊN: `.report-screen .table td` ngay
   trên đây đặc hiệu hơn `.table--in-vua td`, để trên kia thì lề 9px×11px vẫn thắng, ô
   rộng thêm 22px mỗi cột và số 7 chữ số của dòng TỔNG CỘNG bị bẻ đôi. */
.report-screen .table--in-vua,
.commission-report__table .table--in-vua {
  min-width:calc(var(--so-cot, 8) * 68px); width:100%; table-layout:fixed;
}
/* Cho chữ xuống dòng ở tiêu đề (tên thợ dài), nhưng `break-word` chứ KHÔNG `anywhere` —
   "121.000" gãy thành "121.0/00" là đọc SAI TIỀN. Lề co lại để nhường chỗ cho con số. */
.report-screen .table--in-vua th,
.report-screen .table--in-vua td {
  white-space:normal; overflow-wrap:break-word; word-break:normal; padding:7px 5px;
  /* 10 cột → 13px (giữ nguyên như trước); 14 cột → 11px; đông hơn nữa vẫn dừng ở 11px
     để không bao giờ nhỏ tới mức khó đọc — chật quá thì cuộn, không co chữ tiếp. */
  font-size:clamp(11px, calc(150px / var(--so-cot, 8)), 13px);
}
/* Ô TIỀN và ô NGÀY cấm bẻ dòng: đó là hai chỗ bẻ ra là đọc sai. Cột đã đủ rộng cho
   "3.447.000" ở cỡ chữ trên; nếu vẫn không đủ thì cuộn, chứ không bẻ số. */
.report-screen .table--in-vua td.num,
.report-screen .table--in-vua td.cell-ngay { white-space:nowrap; }
/* Cột đầu của BẢNG CHÉO thống kê là TÊN THỢ (không phải ngày) — tên dài như
   "20- Trương Huyền Ngọc" mà cấm bẻ dòng thì với `table-layout:fixed` nó tràn đè sang
   cột bên cạnh. Chữ được xuống dòng, chỉ ngày và tiền là cấm. */
/* Cột đầu (Ngày / tên thợ) phải luôn đọc rõ — rộng hơn các cột số chia đều phía sau. */
.report-screen .table--in-vua th:first-child,
.report-screen .table--in-vua td:first-child { width:11%; }
/* Laptop 13–14" (khung bảng chỉ còn ~900px sau khi trừ thanh bên): 68px/cột không đủ
   cho 14 cột. Hạ một nấc — 60px/cột và sàn chữ 10px — để bảng vẫn lọt trọn thay vì phải
   cuộn. 10px vẫn đọc được; dưới nữa thì thà cuộn còn hơn bắt người ta nheo mắt. */
@media (max-width:1400px) {
  .report-screen .table--in-vua,
  .commission-report__table .table--in-vua { min-width:calc(var(--so-cot, 8) * 60px); }
  .report-screen .table--in-vua th,
  .report-screen .table--in-vua td {
    font-size:clamp(10px, calc(150px / var(--so-cot, 8)), 12px); padding:6px 4px;
  }
}
/* Nấc hẹp nhất — khung bảng còn ~820px. Đây KHÔNG phải trường hợp hiếm: màn 1280 để
   phóng to 125% (mặc định của nhiều laptop Windows) ra đúng 1024px CSS. Đo trên production
   26/08/2026: 14 cột vẫn tràn 22px và xén mất 7 ô. Hạ tiếp xuống 52px/cột, chữ 9px, lề sát
   và cột đầu nhường thêm chỗ — vừa đủ cho số 8 chữ số của dòng TỔNG CỘNG.

   Trần cỡ chữ ở hai nấc hẹp là 12px chứ không phải 13px: bảng ÍT cột (ZORRO 3, 10 cột) không
   chạm sàn nên ăn nguyên trần, mà ở 13px thì "10.375.000" rộng hơn ô đúng vài pixel và bị
   xén — đo trên production thấy 1 ô. */
@media (max-width:1100px) {
  .report-screen .table--in-vua,
  .commission-report__table .table--in-vua { min-width:calc(var(--so-cot, 8) * 52px); }
  .report-screen .table--in-vua th,
  .report-screen .table--in-vua td {
    font-size:clamp(9px, calc(140px / var(--so-cot, 8)), 12px); padding:5px 3px;
  }
  /* Bề ngang CỐ ĐỊNH chứ không phải phần trăm: chữ "TỔNG CỘNG" ở đầu dòng tổng cần 77px,
     mà 9% của bảng hẹp chỉ ra 74px — thiếu 3px là bị xén (đo trên production, ZORRO 3).
     Phần trăm còn có tật: bảng càng ít cột thì cột đầu càng rộng vô ích, bảng nhiều cột lại
     hụt. Một con số cố định vừa đủ chữ là đúng cho cả hai. */
  .report-screen .table--in-vua th:first-child,
  .report-screen .table--in-vua td:first-child { width:84px; }
}
/* Hẹp hơn nữa (~950–1000px, tức màn 1280 phóng 133%): cột chỉ còn ~46px, một số 8 chữ
   số không thể nằm trọn một dòng ở cỡ chữ còn đọc được. Ở đây cho số XUỐNG DÒNG.
   Xuống dòng thì xấu nhưng đọc vẫn đủ; còn giữ một dòng thì chữ tràn ra ngoài ô và bị xén
   — mất chữ số mà người đọc không hề biết. Đã đo trên production 26/08/2026: 7 ô bị xén ở
   khổ 960px trước khi có nấc này. Ngày vẫn cấm bẻ dòng. */
@media (max-width:1000px) {
  .report-screen .table--in-vua,
  .commission-report__table .table--in-vua { min-width:calc(var(--so-cot, 8) * 46px); }
  .report-screen .table--in-vua th,
  .report-screen .table--in-vua td { font-size:9px; padding:4px 2px; }
  .report-screen .table--in-vua td.num { white-space:normal; }
  .report-screen .table--in-vua th:first-child,
  .report-screen .table--in-vua td:first-child { width:72px; }
}
/* `:not(.row--total)` không phải cho gọn: dòng TỔNG rơi vào vị trí chẵn thì vằn
   nền của dòng chẵn đè mất nền xanh nhạt của dòng tổng. */
.report-screen .table tbody tr:nth-child(even):not(.row--total) { background:color-mix(in srgb, var(--bg) 45%, transparent); }
/* Dòng TỔNG đặt ở tầng `.report-screen` chứ không gắn vào từng khung báo cáo:
   trước đây quy tắc chỉ nằm trong `.report-paper`/`.service-report__table`, nên bảng
   nào dựng ngoài hai khung đó thì dòng tổng ra y hệt dòng dữ liệu thường. */
.report-screen .table .row--total, .report-screen .table tfoot tr {
  background:var(--brand-weak); color:var(--brand); font-weight:800; border-top:2px solid var(--brand);
}
.report-screen .table .row--total td, .report-screen .table tfoot td {
  -webkit-print-color-adjust:exact; print-color-adjust:exact;
}
.report-paper .empty { min-height:120px; display:grid; place-items:center; text-align:center; color:var(--text-muted); }
.report-paper .deflist dd, .report-paper .num { font-variant-numeric:tabular-nums; }
.tab {
  min-height: 38px; padding: 0 var(--s4); border-radius: var(--r-pill);
  border: 1px solid var(--border); background: var(--surface);
  font-size: 14px; font-weight: 600; color: var(--text-muted);
}
.tab:hover { background: var(--surface-2); color: var(--text); }
.tab--on { background: var(--brand-weak); border-color: var(--brand-weak); color: var(--brand); }

.table__row { cursor: pointer; }
.table__row:hover { background: var(--surface-2); }
.table__row:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.link-strong { color: var(--brand); font-weight: 700; }

/* ── 15f. BIỂU ĐỒ CỘT THEO NGÀY ──────────────────────────────────────────────
   Port từ `.trend` của `src/ui/staff.html` (MEDUSA). Cố ý không dùng thư viện đồ
   thị: một hàng cột cao thấp là đủ trả lời "ngày nào đông", mà không kéo theo mã
   nguồn ngoài — đúng nguyên tắc không phụ thuộc mạng của cả hai bản. */
.trend {
  display: flex; align-items: flex-end; gap: var(--s1); height: 140px;
  padding: var(--s3); overflow-x: auto; -webkit-overflow-scrolling: touch;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
}
.trend__col { display: flex; flex-direction: column; align-items: center; gap: var(--s1); flex: 0 0 auto; }
.trend__bar { width: 14px; background: var(--brand); border-radius: var(--r-sm) var(--r-sm) 0 0; min-height: 2px; }
.trend__day { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* Màu chữ theo mức trạng thái — dùng cho con số trong biên bản và bảng thu chi. */
.c-do { color: var(--do); }
.c-cam { color: var(--cam); }
.c-xanh { color: var(--xanh); }
.c-xam { color: var(--xam); }
.c-tim { color: var(--tim); }
.c-brand { color: var(--brand); }
/* Huy hiệu tròn của tờ báo cáo: nền nhạt + chữ đậm cùng gam — `.bg-*` của MEDUSA. */
.bg-do { background: var(--do-weak); color: var(--do); }
.bg-cam { background: var(--cam-weak); color: var(--cam); }
.bg-xanh { background: var(--xanh-weak); color: var(--xanh); }
.bg-xam { background: var(--xam-weak); color: var(--xam); }
.bg-tim { background: var(--tim-weak); color: var(--tim); }
.bg-brand { background: var(--brand-weak); color: var(--brand); }

/* ── 15e. BIÊN BẢN NGÀY LÀM VIỆC ─────────────────────────────────────────────
   Tờ giấy chủ salon ký và cất, nên nó phải ra dáng văn bản chứ không phải một khối
   giao diện: có tên đơn vị, tiêu đề, ngày, và dấu ĐÃ KHÓA / CHƯA KHÓA nhìn là thấy. */
.bienban { padding: var(--s5); }
.bienban__head {
  display: flex; align-items: flex-start; gap: var(--s4); flex-wrap: wrap;
  padding-bottom: var(--s4); border-bottom: 2px solid var(--border-strong); margin-bottom: var(--s4);
}
.bienban__brand { flex: 1; min-width: 140px; }
.bienban__logo { font-size: 18px; font-weight: 800; letter-spacing: .04em; color: var(--brand); }
.bienban__title { flex: 2 1 260px; text-align: center; }
.bienban__title .t-display { font-size: 21px; letter-spacing: .02em; }
.bienban__meta { flex: 1; min-width: 150px; display: flex; flex-direction: column; align-items: flex-end; gap: var(--s1); }
.bienban__muc { margin: var(--s5) 0 var(--s2); border-bottom: 1px solid var(--border); padding-bottom: var(--s1); }
.bienban .rowlist { padding-left: 0; padding-right: 0; }
.bienban__ghichu { margin: var(--s2) 0 0; }

/* Báo cáo ngày: cùng kích thước, màu và nhịp dòng với tờ MEDUSA. */
.daily-report-card {
  width: min(650px, 100%); margin: 0 auto; padding: 18px;
  border-color: var(--border); border-radius: 12px; box-shadow: none;
}
.daily-report-card .bienban__head {
  flex-wrap: nowrap; min-height: 82px; margin-bottom: 14px; padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.daily-report-card .bienban__logo { color: #0f2544; font-size: 18px; letter-spacing: 0; }
.daily-report-card .bienban__brand .t-cap { font-size: 9px; }
.daily-report-card .bienban__title { flex: 1 1 230px; }
.daily-report-card .bienban__title .t-display { color: #0f2544; font-size: 20px; }
.daily-report-card .bienban__title .t-cap { margin: 8px 0 0; color: var(--brand); font-size: 14px; font-weight: 800; }
.daily-report-card .bienban__meta { min-width: 180px; gap: 2px; }
.daily-report-card .bienban__meta .pill { min-height: 26px; padding: 4px 11px; font-size: 11px; }
.daily-report-card .bienban__meta .t-cap { font-size: 10.5px; }
.daily-report-card .bienban__muc {
  display: flex; align-items: center; gap: 10px; margin: 16px 0 9px; padding: 0;
  border: 0; color: var(--brand); font-size: 12px; letter-spacing: .02em;
}
/* Huy hiệu tròn ĐẶC có biểu tượng bên trong — `.h2i` của MEDUSA. Trước đây ZORRO3 vẽ
   một vòng tròn rỗng bằng `::before`, nhìn giống chấm đầu dòng chứ không ra huy hiệu. */
.daily-report-card .h2i {
  flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand); color: #fff;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.daily-report-card .h2i .ico { width: 15px; height: 15px; }
.daily-report-card .rowlist { overflow: hidden; border: 1px solid var(--border); border-radius: 10px; }
.daily-report-card .row { min-height: 41px; padding: 8px 14px; gap: 10px; }
.daily-report-card .row__ico {
  flex: none; width: 27px; height: 27px; border-radius: 50%; display: grid; place-items: center;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.daily-report-card .row__ico .ico { width: 15px; height: 15px; }
.daily-report-card .row__name { font-size: 12px; }
.daily-report-card .row__amt { font-size: 14px; font-weight: 800; }
.daily-report-card .row--total { background: var(--brand-weak); color: var(--brand); }
.daily-report-card .row--total .row__name { font-weight: 800; text-transform: uppercase; }
.daily-report-card .row--total .row__amt { color: var(--brand); }
.daily-report-card .bienban__ghichu { margin: 4px 2px 0; font-size: 9px; }
.daily-report-card > .state { min-height: 42px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; font-size: 11px; }
/* Bảng thu chi: cột Loại có biểu tượng cùng màu số tiền; chân bảng khép bằng Tổng chi. */
.bienban__loai { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.bienban__loai .ico { width: 15px; height: 15px; flex: none; }
.bienban__loai-ten { color: var(--text); }
/* Chân bảng của tờ báo cáo là "Tổng chi" màu đỏ — KHÔNG phải dòng tổng xanh của các
   mẫu báo cáo khác, nên phải gỡ cả nền lẫn viền trên mà `.report-screen` áp vào. */
.daily-report-card .table tfoot tr { background: transparent; border-top: 0; }
.daily-report-card .table tfoot td {
  background: var(--do-weak); border-bottom: 0; border-top: 0; font-weight: 800; color: var(--do);
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.daily-report-card .table tfoot .lbl { text-transform: uppercase; letter-spacing: .02em; }
.bienban__rong { padding: 14px; border: 1px solid var(--border); border-radius: 10px; color: var(--text-muted); font-size: 12px; }

/* Tờ báo cáo trên điện thoại — port khối `@media screen and (max-width:640px)` của
   MEDUSA (`src/ui/khoangay.html`).

   `screen and` là BẮT BUỘC, không phải cho đẹp: thiếu nó thì mọi thu gọn dưới đây
   lọt cả vào bản in (khổ A4 chỉ rộng ~794px CSS), nên tờ in ra giấy lại xếp dồn
   kiểu màn hình hẹp. Tờ giấy phải giống nhau bất kể in từ máy nào.

   Ba khối đầu trang xếp DỌC và CĂN GIỮA: giữ ba cột cạnh nhau trên màn 390px thì
   riêng ba cột đã cần ~550px — tiêu đề "BÁO CÁO NGÀY" bị bóp thành ba dòng, dấu
   ĐÃ KHÓA tràn khỏi mép phải và cả trang cuộn ngang. */
@media screen and (max-width: 640px) {
  .daily-report-card { padding: 14px 12px; border-radius: 10px; }
  .daily-report-card .bienban__head {
    flex-direction: column; flex-wrap: wrap; align-items: center; text-align: center;
    gap: 10px; min-height: 0; margin-bottom: 12px; padding-bottom: 12px;
  }
  .daily-report-card .bienban__brand,
  .daily-report-card .bienban__title,
  .daily-report-card .bienban__meta { flex: none; width: 100%; min-width: 0; }
  .daily-report-card .bienban__meta { align-items: center; }
  .daily-report-card .bienban__title .t-display { font-size: 22px; }
  .daily-report-card .bienban__title .t-cap { margin-top: 4px; font-size: 18px; }
  .daily-report-card .bienban__brand .t-cap { font-size: 12.5px; }
  .daily-report-card .bienban__meta .t-cap { font-size: 13px; }
  .daily-report-card .bienban__meta .pill { min-height: 28px; font-size: 12.5px; }
  .daily-report-card .bienban__muc { margin: 16px 0 8px; font-size: 13px; }
  .daily-report-card .row { padding: 8px 10px; gap: 8px; }
  .daily-report-card .row__name { font-size: 14px; }
  .daily-report-card .row__amt { font-size: 16px; }
  .daily-report-card .bienban__ghichu { font-size: 12px; }
  .daily-report-card > .state, .daily-report-card .bienban__rong { font-size: 13px; }
  .bienban__loai { white-space: normal; gap: 5px; }
  /* Bảng ba cột phải VỪA màn hình, không được cắt cụt cột Số tiền: khóa bề rộng
     từng cột theo tỉ lệ và cho chữ xuống dòng. Bấm vào tờ báo cáo trên điện thoại
     mà thấy mất cột tiền thì tờ báo cáo coi như hỏng. */
  .daily-report-card .table-wrap { overflow-x: visible; }
  .daily-report-card .table { table-layout: fixed; width: 100%; min-width: 0; font-size: 13px; }
  .daily-report-card .table th,
  .daily-report-card .table td { padding: 8px 10px; white-space: normal; word-break: break-word; }
  .daily-report-card .table th:nth-child(1), .daily-report-card .table td:nth-child(1) { width: 30%; }
  .daily-report-card .table th:nth-child(3), .daily-report-card .table td:nth-child(3) { width: 30%; }
}

/* Ô tìm số hóa đơn: ô nhập chiếm hết phần trống, nút bám bên phải. Trên điện thoại
   nút xuống dòng và trải rộng cho dễ bấm. */
.searchbar { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.searchbar .input { flex: 1 1 220px; }
@media (max-width: 900px) { .searchbar .btn { flex: 1 1 auto; } }

/* ── 15d. THAO TÁC HÀNG LOẠT ─────────────────────────────────────────────────
   Thanh này đứng NGAY TRÊN danh sách, không nổi ở chân màn hình: người duyệt phải
   thấy con số "đã chọn N" cùng lúc với những dòng mình vừa tick, nếu không sẽ bấm
   Duyệt nhanh mà không chắc đang duyệt đúng bấy nhiêu tờ. */
.batchbar {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  padding: var(--s3) var(--s5); border-bottom: 1px solid var(--border);
}
.batchbar .note { flex: 1; min-width: 150px; color: var(--text-muted); font-size: 14px; }
.batchbar .check { gap: var(--s2); font-size: 14px; font-weight: 600; white-space: nowrap; }

/* Ô tích trong bảng: đủ rộng cho ngón tay nhưng không chiếm chỗ của số hóa đơn. */
.table th.tick, .table td.tick { width: 44px; padding-right: 0; }
.check.tick { min-height: 0; }

/* Trên điện thoại một dòng có hai vùng bấm khác nhau — ô tích để CHỌN, phần còn lại
   để MỞ. Tách thành nút riêng thay vì cho cả dòng bấm được, nếu không tick một tờ
   lại mở luôn tờ đó. */
.row__open {
  display: flex; align-items: center; gap: var(--s3); flex: 1; min-width: 0;
  min-height: var(--tap); padding: 0; text-align: left;
  background: none; border: none; color: inherit;
}
.row__open:hover .row__name { color: var(--brand); }

.block__hint { margin: calc(-1 * var(--s2)) 0 var(--s3); }
.actions { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.raw { margin-top: var(--s4); }
.raw__summary { cursor: pointer; font-size: 14px; font-weight: 600; color: var(--brand); }
.raw .t-cap { margin: var(--s3) 0 var(--s1); }
.flip { transform: rotate(180deg); }

/* Bảng chỉ dùng trên máy tính; điện thoại xem cùng dữ liệu đó ở dạng thẻ. */
.only-mobile { display: none; }
@media (max-width: 900px) {
  .report-catalog__grid, .report-catalog__grid--four { grid-template-columns:1fr; }
  .service-report { padding:14px 12px; border-radius:12px; }
  .report-paper { margin-top:20px; padding:14px 12px; border-radius:12px; }
  /* Màn 390px chỉ còn ~166px mỗi ô — thu nhỏ biểu tượng và cỡ chữ để con số tiền nằm
     trọn trong ô, đúng khối `@media (max-width:600px)` của `reports.html`. */
  .service-report__metrics, .commission-report__metrics { grid-template-columns:1fr 1fr; gap:8px; }
  .service-report__metric { padding:10px; gap:8px; }
  .service-report__metric-icon { width:32px; height:32px; font-size:16px; }
  .service-report__metric-copy { font-size:12px; }
  .service-report__metric-value { font-size:16px; }
  .revenue-summary { padding:12px 10px; }
  .revenue-summary__mark { width:30px; height:30px; margin-right:6px; font-size:17px; }
  .revenue-summary__title { font-size:16px; }
  .revenue-summary__table { font-size:13px; }
  .revenue-summary__table th, .revenue-summary__table td { padding:10px 8px; }
  .revenue-summary__table td:last-child { font-size:14px; }
  .revenue-summary__icon { width:22px; height:22px; margin-right:6px; font-size:11px; }
  .reward-report { padding:12px 10px; border-radius:12px; }
  .reward-report__brand { font-size:11px; }
  .reward-tabs { display:flex; width:100%; margin:14px 0 10px; }
  .reward-tabs .btn { flex:1; min-height:36px; padding:5px 8px; font-size:10px; }
  .reward-report__head { margin-bottom:12px; }
  .reward-report__title { font-size:16px; }
  .reward-report__head .note { font-size:10.5px; }
  .reward-filter { display:grid; grid-template-columns:1fr; gap:8px; padding:10px; }
  .reward-filter .field { min-width:0; }
  .reward-filter > .btn { width:100%; }
  .reward-tools { width:100%; margin-left:0; }
  .reward-tools .btn { flex:1; }
  .reward-metrics { grid-template-columns:1fr 1fr; gap:8px; }
  .reward-metric { padding:9px; }
  .reward-metric__label { font-size:10px; }
  .reward-metric strong { font-size:14px; }
  .reward-report__table { min-width:900px; font-size:12px; }
  .reward-report__table th,.reward-report__table td { height:38px; padding:6px 8px; }
  .reward-report__table .reward-report__employee { min-width:112px; }
  .reward-report__note { font-size:11px; }
  .reward-admin{padding:8px 12px 20px}.reward-monthbar{display:grid;grid-template-columns:1fr auto}.reward-monthbar .input,.reward-monthbar .dt{width:100%}.reward-monthbar .reward-open{grid-column:1/-1;width:max-content}.reward-admin-tabs{overflow-x:auto;padding-bottom:4px}.reward-admin-tabs .btn{flex:0 0 auto}.reward-editor{grid-template-columns:1fr}.reward-assign-row{grid-template-columns:1fr}.reward-config{padding:12px}.reward-config>.input{width:100%}
  .report-detail-head { margin:0; padding:12px 0; flex-wrap:wrap; background:transparent; border:0; }
  .report-detail-head__left { width:100%; gap:10px; }
  .report-detail-head__left .t-display { font-size:18px; }
  .report-detail-head > .actions { width:100%; }
  .report-detail-head > .actions .btn { flex:1; }
  .only-desktop { display: none; }
  .only-mobile { display: block; }
}

/* ── 16. TOAST ───────────────────────────────────────────────────────────── */
.toasts {
  position: fixed; z-index: 9500; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--s5) + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: var(--s2); width: min(420px, calc(100vw - 24px));
  pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s4); border-radius: var(--r-md);
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--sh-2);
  font-size: 14px; font-weight: 600; pointer-events: auto;
  animation: toast-in .18s ease-out;
}
.toast--ok { border-color: var(--xanh); color: var(--xanh); }
.toast--loi { border-color: var(--do); color: var(--do); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Dải "có bản mới" — nằm trên cùng, không che nội dung đang gõ ở giữa màn hình. */
.banmoi {
  position: fixed; z-index: 9600; top: calc(env(safe-area-inset-top) + var(--s2));
  left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; justify-content: center;
  width: min(560px, calc(100vw - 24px));
  padding: var(--s3) var(--s4); border-radius: var(--r-md);
  background: var(--vang-weak); border: 1px solid var(--vang); color: var(--vang);
  box-shadow: var(--sh-2);
  font-size: 14px; font-weight: 600;
  animation: toast-in .18s ease-out;
}

/* ── 17. ĐIỆN THOẠI (390–430px) ─────────────────────────────────────────────
   Cùng một khối HTML, chỉ xếp lại. Menu trái thành ngăn kéo mở bằng nút ☰. */
#burger { display: none; }
@media (max-width: 900px) {
  .sidebar {
    width: min(84vw, 300px); transform: translateX(-100%);
    transition: transform .22s ease; box-shadow: var(--sh-2);
  }
  body.nav-open .sidebar { transform: none; }
  body.nav-open { overflow: hidden; }
  .main { margin-left: 0; }
  #burger { display: inline-flex; }
  .topbar { align-items: center; padding: var(--s3) var(--s4); }
  .content { padding: 0 var(--s4) var(--s7); }
  .t-display { font-size: 19px; }
  /* Chữ nhỏ nhất trên điện thoại là 14px — không ngoại lệ */
  .topbar__hello p, .stat__label, .card__foot .note, .btn, .t-cap,
  .health__state, .row__sub, .sidebar__role, .field__label, .field__hint, .deflist dt { font-size: 14px; }
  .stats, .health { grid-template-columns: 1fr; }
  .stat { display: flex; align-items: center; gap: var(--s3); }
  .stat__label { flex: 1; }
  .stat__value, .stat__value--sm { font-size: 21px; margin-top: 0; }
  .task { min-height: 60px; }        /* thao tác một tay: vùng bấm rộng hơn */
  .task__t { font-size: 15px; }
  .rowlist { padding-left: var(--s4); padding-right: var(--s4); }
  .card__foot { padding-left: var(--s4); padding-right: var(--s4); }
  .card__foot .btn { width: 100%; }
  .batchbar { padding-left: var(--s4); padding-right: var(--s4); }
  .batchbar .note { flex: 1 1 100%; }
  .batchbar .btn { flex: 1 1 auto; }
  .deflist { grid-template-columns: 1fr; gap: var(--s1) 0; }
  .deflist dd { margin-bottom: var(--s2); }
  .modal__foot .btn { flex: 1 1 auto; }
  .cardbody { padding: var(--s4); }
  .actions .btn { width: 100%; }
  .report-filter { grid-template-columns:1fr; }
  .report-filter > .field:last-child { grid-column:auto; }
  .report-filter .presets { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); }
  .report-filter .report-preset { width:100%; }
  .eline .line-action--remove { width:100%; }
  .imgframe__img { max-height: 70vh; }
  .close-history { min-width: 760px; }
  .lock-toolbar { align-items: stretch; }
  .lock-toolbar .input { flex: 1; min-width: 0; }
  /* Đúng hai dòng của MEDUSA cho màn hẹp: ô ngày bỏ trần bề ngang, nút chia đều phần
     còn lại. Không thêm luật nào khác — thêm là lệch khỏi bản MEDUSA. */
  .lock-toolbar .btn { flex: 1; }
  .lock-issue .actions { flex-direction: column; }
  .close-page-head { padding: 12px 14px; align-items: flex-start; }
  .close-page-head__left { gap: 7px; flex: none; white-space: nowrap; }
  .close-page-head__left .link { font-size: 13px; }
  .close-page-head__left .t-display { font-size: 19px; }
  .close-page-head__actions { gap: var(--s2); }
  .close-page-head__actions .btn { padding-left: 8px; padding-right: 8px; font-size: 13px; }
  .close-page-body { width: calc(100% - 24px); margin-top: 16px; }
  .close-page-body .lock-toolbar { min-height: 0; padding: 16px; }
  .close-page-body .lock-issue { padding: 20px; }
  .medusa-balance { font-size:15px; }
  .medusa-balance__toolbar { margin:12px 0; }
  .medusa-balance__save { width:100%; min-height:44px; font-size:16px; }
  .medusa-balance__card { padding:12px; border-radius:10px; }
  .medusa-balance__table, .medusa-balance__table tbody,
  .medusa-balance__table tr, .medusa-balance__table td { display:block; width:100%; }
  .medusa-balance__table thead { display:none; }
  .medusa-balance__table tr {
    margin-bottom:9px; padding:8px 11px; border:1px solid #e6e9ee;
    border-radius:10px; background:#fff;
  }
  .medusa-balance__table td {
    display:flex; align-items:center; gap:12px; padding:5px 0; border:0; text-align:left;
  }
  .medusa-balance__table td::before {
    content:attr(data-label); flex:1; min-width:0; color:#6b7684; font-size:13px;
  }
  .medusa-balance__table td.num { text-align:left; }
  .medusa-balance__table td > * { margin-left:auto; }
  .medusa-balance__input { width:150px; min-height:44px; font-size:16px; }
}
@media (max-width: 420px) {
  .content, .topbar { padding-left: var(--s3); padding-right: var(--s3); }
  .rowlist, .card__foot { padding-left: var(--s3); padding-right: var(--s3); }
  .ov { padding: var(--s2); }
  .modal { max-height: calc(100dvh - 16px); }
}
@media (max-width:900px) and (prefers-color-scheme:dark) {
  .medusa-balance__table tr { background:#171d26; border-color:#252d38; }
  .medusa-balance__table td::before { color:#9aa4b2; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }

/* ── 20. IN GIẤY ─────────────────────────────────────────────────────────────
   Bản in dùng cho sổ quỹ và biên bản khóa ngày: bỏ mọi thứ chỉ có nghĩa trên màn
   hình (menu, nút bấm, thanh trên cùng), trải nội dung ra hết khổ giấy và ép bảng
   hiện đầy đủ thay vì cuộn ngang. */

/* ── TỜ THƯỞNG MOBILE-FIRST (mockup chủ salon 02/09/2026) ─────────────────────
   Hai tầng chọn, cột TÊN dính trái, phần chỉ tiêu vuốt ngang, và mỗi khối số liệu
   một màu đi suốt bảng lẫn ô chi tiết: ZORRO3 tím · Tăng cường xanh lá · Tổng
   thưởng xanh dương. Người dùng chính thao tác trên điện thoại. */
.reward-seg { display: flex; gap: 6px; margin: 10px 0; flex-wrap: wrap; }
.reward-seg__nut {
  flex: 1 1 auto; min-height: 40px; padding: 8px 14px; border: 1px solid var(--border);
  border-radius: 999px; background: var(--surface); color: var(--text);
  font-size: 13px; font-weight: 600; cursor: pointer;
}
.reward-seg__nut--on { background: var(--head); border-color: var(--head); color: #fff; }
.reward-seg__nut--z3.reward-seg__nut--on { background: var(--tim, #6d28d9); border-color: var(--tim, #6d28d9); }
.reward-seg__nut--tc.reward-seg__nut--on { background: var(--xanh); border-color: var(--xanh); }
.reward-seg__nut--tong.reward-seg__nut--on { background: var(--brand); border-color: var(--brand); }

.reward-tip {
  display: flex; gap: 8px; align-items: flex-start; padding: 10px 12px; margin: 4px 0 12px;
  border-radius: 10px; font-size: 13px; line-height: 1.45;
  background: var(--brand-weak); color: var(--text);
}
.reward-tip--z3 { background: var(--tim-weak, #f1eafd); }
.reward-tip--tc { background: var(--xanh-weak); }
.reward-tip__icon { flex: 0 0 auto; }

.reward-bang { margin-bottom: 18px; }
.reward-bang__nhac {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; color: var(--text-muted); margin-bottom: 4px;
}
.reward-bang__vuot { color: var(--brand); }

/* Cột TÊN dính trái: vuốt sang phải vẫn biết đang đọc dòng của ai. Cần
   border-collapse:separate vì Chromium bỏ sticky trên ô của bảng collapse. */
.reward-table { border-collapse: separate; border-spacing: 0; }
.reward-table .reward-table__ten {
  position: sticky; left: 0; z-index: 3; background: var(--surface);
  min-width: 92px; max-width: 132px; text-align: left; font-weight: 600;
}
.reward-table thead .reward-table__ten { z-index: 4; background: var(--head); color: #fff; }
.reward-table tfoot .reward-table__ten { background: var(--surface-2); }
/* Cột TỔNG THƯỞNG dính phải — vuốt ngang vẫn nhìn được tiền.
   CHỈ từ 561px trở lên: trên điện thoại 320px lòng bảng, một cột dính trái cộng một cột
   dính phải ăn hết bề ngang và ĐÈ mất cột ở giữa (đo thật: cột Chuyên cần bị cắt còn
   "300.0"). Ở đó để bảng cuộn tự nhiên thì đọc được hết. */
.reward-table .reward-table__tong { font-weight: 700; }
@media (min-width: 561px) {
  .reward-table .reward-table__tong {
    position: sticky; right: 0; z-index: 3; background: var(--surface);
  }
  .reward-table thead .reward-table__tong { z-index: 4; background: var(--head); color: #fff; }
  .reward-table tfoot .reward-table__tong { background: var(--surface-2); }
}
/* Ô số KHÔNG được co lại: bảng phải tự rộng ra rồi cuộn ngang. Để co thì cột dính
   phải bóp mất cột bên cạnh và số bị cắt giữa chừng ("300.0"). */
.reward-table th, .reward-table td { white-space: nowrap; }
.reward-table td.num, .reward-table th.num { min-width: 74px; }
.reward-o { cursor: pointer; }
.reward-o:hover { background: var(--brand-weak); }
.reward-o--tc { color: var(--xanh); font-weight: 700; }
.reward-o__luot { display: block; }
.reward-o__tien { display: block; font-size: 11px; color: var(--brand); font-weight: 700; }

/* Khoản của CẢ NHÓM — đứng dưới bảng, không thành cột của từng người. */
.reward-nhom {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 9px 12px; margin-top: 8px; border-radius: 9px;
  background: var(--surface-2); font-size: 13px;
}
.reward-nhom--dat { background: var(--vang-weak); }
.reward-nhom__ten { flex: 1 1 160px; font-weight: 600; }
.reward-nhom__so { color: var(--text-muted); }
.reward-nhom__tien { font-weight: 700; color: var(--brand); }

/* Ô chi tiết (mockup: số lớn + các dòng bóc tách + mốc + tiền). */
.reward-ct__so { font-size: 30px; font-weight: 800; line-height: 1.15; text-align: center; }
.reward-ct__so--z3 { color: var(--tim, #6d28d9); }
.reward-ct__so--tong { color: var(--brand); }
.reward-ct .note { text-align: center; margin-top: 2px; }
.reward-ct__hop { margin-top: 14px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; }
.reward-ct__nhan { font-weight: 700; margin-bottom: 6px; }
.reward-ct__dong { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; }
.reward-ct__dong--tong { border-top: 1px solid var(--border); margin-top: 4px; font-weight: 700; }
.reward-ct .c-z3 { color: var(--tim, #6d28d9); }
.reward-ct .c-tc { color: var(--xanh); }
.reward-ct .c-tong { color: var(--brand); }
.reward-ct__moc {
  margin-top: 12px; padding: 9px 12px; border-radius: 9px;
  background: var(--vang-weak); font-weight: 600;
}
.reward-ct__tien {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 8px; padding: 12px; border-radius: 9px; background: var(--brand-weak);
}
.reward-ct__tien b { font-size: 20px; color: var(--brand); }

/* Nhập tăng cường: bộ đếm to, bấm được bằng ngón tay. */
.reward-tc__hang { display: flex; align-items: center; gap: 10px; }
.reward-tc__nut {
  width: 44px; height: 44px; flex: 0 0 44px; border: 1px solid var(--border);
  border-radius: 10px; background: var(--surface-2); font-size: 20px; cursor: pointer;
}
.reward-tc__so {
  flex: 1 1 auto; min-width: 70px; height: 44px; text-align: center;
  font-size: 22px; font-weight: 700; color: var(--xanh);
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
}
.reward-tc__ds { margin-top: 12px; display: grid; gap: 10px; }
.reward-tc__dong {
  display: flex; gap: 10px; align-items: center; justify-content: space-between;
  flex-wrap: wrap; padding-bottom: 10px; border-bottom: 1px solid var(--border);
}
.reward-tc__nhan { flex: 1 1 130px; font-weight: 600; }

.reward-tt { display: grid; gap: 8px; margin: 10px 0; }
.reward-tt__dong {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
}
.reward-tt__ten { flex: 1 1 120px; font-weight: 600; }
.reward-tt__da { color: var(--xanh); font-weight: 600; }
.reward-tt__chua { color: var(--text-muted); }
.reward-nut-lon { width: 100%; min-height: 52px; font-size: 15px; font-weight: 700; }
/* Nút của khối Tăng cường mang màu của chính khối ấy (mockup) — người dùng nhìn màu là
   biết mình đang ở bảng nhập tay, không phải bảng số máy đếm. */
.reward-nut-lon--tc { background: var(--xanh); border-color: var(--xanh); color: #fff; }

.reward-bang__chan {
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin-top: 6px; font-size: 12px; color: var(--text-muted);
}

@media (max-width: 560px) {
  .reward-report { padding: 10px 10px 14px; }
  .reward-seg__nut { flex: 1 1 30%; padding: 8px 6px; font-size: 12px; }
  .reward-report__title { font-size: 17px; }
  /* Ô hẹp lại để một màn thấy được NHIỀU chỉ tiêu hơn — mockup cho thấy 5 cột cùng lúc,
     chứ không phải 2 cột rồi phải vuốt mãi. */
  .reward-table .reward-table__ten { min-width: 76px; max-width: 84px; padding: 8px 6px; }
  .reward-table th, .reward-table td { padding: 8px 6px; font-size: 12.5px; }
  .reward-table thead th { font-size: 11.5px; }
  .reward-report__unit { font-size: 10px; }
}

@page { size: A4; margin: 12mm; }
@page report-wide { size: A4 landscape; margin: 10mm; }
@media print {
  /* Giấy luôn trắng. Từ khi có nền tối theo hệ điều hành, nếu không ép lại bảng
     màu sáng ở đây thì máy đang để nền tối in ra chữ #e6edf3 trên giấy trắng —
     gần như không đọc được. (MEDUSA `reports.html` chỉ ép `body{background:#fff}`
     nên vẫn dính lỗi này; ZORRO3 ép cả bộ token.) */
  :root {
    --bg: #ffffff; --surface: #ffffff; --surface-2: #eef2f7;
    --border: #e2e7ee; --border-strong: #cfd7e2;
    --text: #16202b; --text-muted: #5c6b7a;
    --brand: #2563eb; --brand-strong: #1d4ed8; --brand-weak: #e8f0fe;
    --do: #d32f2f; --do-weak: #fdecec;
    --cam: #c2620a; --cam-weak: #fff2e2;
    --vang: #8d6a00; --vang-weak: #fff7db;
    --xanh: #0f7b4f; --xanh-weak: #e4f5ec;
    --xam: #64748b; --xam-weak: #eef1f5;
    --head: #1f2b52;
  }
  /* Bảng báo cáo dài phải lặp lại phần đầu ở mỗi trang giấy. */
  .table thead { display: table-header-group; }
  .table tfoot { display: table-footer-group; }
  .table tr { break-inside: avoid; }
  .t-h2 { break-after: avoid; }
  .deflist { break-inside: avoid; }
  body { background: #fff; }
  .sidebar, .topbar, .scrim, .toasts, .banmoi, .actions, .card__foot .btn, .btn, .tabs, .report-catalog { display: none !important; }
  /* Lịch chỉ là công cụ trên màn hình; lỡ còn mở lúc bấm In thì không được lên giấy. */
  .cal, .dt .mo { display: none !important; }
  .report-detail-head, .report-filter { display:none !important; }
  .app, .main, .content { display: block; margin: 0; padding: 0; max-width: none; }
  /* `100dvh` của khung ứng dụng tính theo CẢ khổ giấy, còn vùng in được đã trừ
     lề trên/dưới — nên khung luôn cao hơn chỗ in được và đẩy ra thêm MỘT TỜ
     TRẮNG ở cuối mọi bản in. Với báo cáo in ngang, tờ thừa đó còn lấy khổ dọc
     mặc định, thành một lệnh in hai khổ giấy khác nhau. */
  .app { min-height: 0; }
  .card, .cardbody { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
  .block { break-inside: avoid; margin-bottom: 12px; }
  .table-wrap { overflow: visible; }
  .only-mobile { display: none !important; }
  .only-desktop { display: block !important; }
  a[href]::after { content: ""; }
  /* Chỉ in BIÊN BẢN — và CHỈ trên màn Khóa ngày. Bốn mục thao tác phía trên (đối chiếu
     quỹ, khóa ngày, chốt dữ liệu, lịch sử) là công cụ trên màn hình, in ra chỉ tốn giấy.

     `.day-close-page` là BẮT BUỘC, không phải cho gọn: thiếu nó thì luật này quét mọi màn
     hình, mà màn nào không có biên bản (Hoa hồng, Bảng lương…) sẽ bị ẩn SẠCH mọi khối và
     in ra TỜ GIẤY TRẮNG. Ca thật 12/08/2026: bấm In ở màn Hoa hồng trên điện thoại, hộp
     in hiện "Trang 1/1" trắng tinh. */
  .day-close-page .content > .block:not(:has(.bienban)) { display: none !important; }
  /* Màn Báo cáo là tài liệu in độc lập, không phải các khối thao tác của
     màn Khóa ngày. Cho hiện lại tất cả phần report; bỏ riêng khối chọn mẫu/ngày. */
  .content.report-screen > .block { display: block !important; }
  /* Khối đầu chỉ là công cụ trên màn hình: tên mẫu đang xem, nút In/Xuất CSV,
     danh sách 13 mẫu và bộ lọc ngày. Bản in đã có tiêu đề + khoảng ngày riêng
     của chính báo cáo, nên in thêm khối này ra là LẶP tiêu đề hai lần. */
  .content.report-screen > .block:first-child { display: none !important; }
  .content.report-screen.report-wide { page: report-wide; }
  /* Tờ thưởng có tới 13 cột: in khổ dọc là cắt mất cột Cộng nhóm và cột tiền.
     Cơ chế khổ ngang vốn đã có, trước chỉ bật cho hai tab của màn Báo cáo. */
  .content.report-screen:has(.reward-report) { page: report-wide; }
  /* Giấy không có chỗ cho ô nhập, nút bấm và khối quản trị. In GIÁ TRỊ, không in
     cái để gõ vào. */
  /* Thanh chọn tháng + nút Chốt kỳ nằm NGOÀI tờ (.reward-monthbar) nên phải gọi tên
     riêng; kỳ đã in ở dòng dưới tiêu đề rồi. */
  .reward-monthbar,
  .reward-report .no-print,
  .reward-report .reward-seg,
  .reward-report .reward-tip,
  .reward-report .reward-bang__nhac,
  .reward-report .reward-bang__chan,
  .reward-report .dt { display: none !important; }
  .reward-report .reward-table .reward-table__ten,
  .reward-report .reward-table .reward-table__tong { position: static; }
  .reward-report input {
    border: 0 !important; padding: 0 !important; background: transparent !important;
    color: var(--text) !important; text-align: right; font: inherit; width: auto;
  }
  .reward-report input::placeholder { color: transparent !important; }
  .content.report-screen .block { break-inside: auto; }
  .content.report-screen .report-paper { margin:0; padding:0; border:0; box-shadow:none; }
  /* Lề của thẻ chỉ có nghĩa trên màn hình. Trên giấy nó ăn mất 158px bề ngang (đo trên
     production 26/08/2026: bảng chỉ được 889px trong khi khổ in cho 1047px) — đúng phần
     chỗ mà mấy cột tiền đang thiếu. */
  .content.report-screen .card { break-inside: auto; border: 0; padding: 0; }
  .content.report-screen .service-report, .content.report-screen .commission-report { padding: 0; }
  .content.report-screen .table { width: 100%; font-size: 9pt; }
  .content.report-screen .table th,
  .content.report-screen .table td { padding: 3px 5px; }
  /* Trên màn hình mỗi ô giữ một dòng rồi cuộn ngang. Tờ giấy KHÔNG cuộn được:
     giữ nguyên một dòng thì bảng thu chi 8 cột cần 865px trong khi A4 dọc chỉ
     in được 703px — mất hẳn cột "Ghi chú" ở mép phải. Nên khi in cho xuống
     dòng lại, thà dòng cao hơn còn hơn cụt mất cột. */
  .content.report-screen .table th,
  .content.report-screen .table td { white-space: normal; }

  /* ── Bảng ma trận: TỰ CO VỪA KHỔ GIẤY, tuyệt đối không cắt cụt ─────────────
     Ba `min-width` bên trên (`.table--rong` 900px, bảng hoa hồng 980px) chỉ có
     nghĩa TRÊN MÀN HÌNH: rộng hơn khung thì cuộn ngang. Giấy không cuộn được —
     giữ nguyên min-width là trình duyệt cắt phăng phần thò ra khỏi mép phải và
     mất hẳn mấy cột cuối, mà bản in không để lại dấu vết gì cho người đọc biết
     mình đang thiếu số. Nên khi in: gỡ hết min-width, ép bảng đúng bề ngang
     vùng in được, rồi CO CHỮ theo số cột (`--so-cot` do `soCot()` gắn lúc dựng
     bảng — mỗi nhân viên/dịch vụ là một cột nên số này không viết cứng được).
     `table-layout: fixed` là chốt chặn cuối: các cột chia đều phần còn lại nên
     bảng KHÔNG BAO GIỜ rộng hơn 100%, dù có bao nhiêu nhân viên đi nữa. */
  .content.report-screen .table,
  .content.report-screen .table--rong,
  .content.report-screen .commission-report__table .table { min-width: 0; width: 100%; }
  /* Khung bảng: mọi lớp cha đang cắt/cuộn đều phải mở ra, nếu không thì gỡ
     min-width xong vẫn bị chính cái khung xén mất. */
  .content.report-screen .table-wrap,
  .content.report-screen .report-paper .table-wrap,
  .content.report-screen .service-report__table { overflow: visible; }
  /* Ghim cột đầu là cơ chế của thanh cuộn; trên giấy nó chỉ làm lệch nền. */
  .content.report-screen .table--rong th:first-child,
  .content.report-screen .table--rong td:first-child { position: static; box-shadow: none; }
  .content.report-screen .commission-report__table .table th,
  .content.report-screen .commission-report__table .table td { white-space: normal; }
  /* Nhưng SỐ TIỀN thì không: "10.375.000" bẻ thành "10.375.00 / 0" là đọc sai tiền — nguy
     hiểm hơn hẳn chữ nhỏ. Cỡ chữ đã tự co theo số cột nên còn chỗ; hết chỗ thật thì co tiếp,
     chứ không bẻ đôi con số. */
  .content.report-screen .table--in-vua td.num,
  .content.report-screen .commission-report__table .table td.num { white-space: nowrap; }
  /* Cỡ chữ phải khai LẠI trên chính `th`/`td`: `.report-screen .table th` bên trên
     đặt cứng 13px, đè mất cỡ chữ đặt ở thẻ `table`. Không khai lại thì tiêu đề cột
     vẫn 13px trong khi ô số đã co — và mã "NV0001" bị bẻ đôi giữa chừng. */
  .content.report-screen .table--in-vua,
  .content.report-screen .table--in-vua th,
  .content.report-screen .table--in-vua td {
    /* 6 cột → 9pt (giữ nguyên cỡ cũ); 12 cột → ~6,3pt; đông hơn nữa thì dừng ở
       5pt và để chữ xuống dòng — thà dòng cao hơn còn hơn mất cột. */
    /* Vùng in A4 ngang rộng 785pt; trừ 14% cho cột đầu còn 675pt chia cho các cột số.
       Một số tiền 9 ký tự chiếm khoảng 4,3 lần cỡ chữ, cộng 4pt lề — nên cỡ chữ vừa
       khít là (bề ngang cột − 4pt)/4,3. Hệ số 135 bám sát mức đó ở mọi số cột thực tế:
       14 cột → 8,6pt · 21 cột → 5,7pt · 27 cột → chạm sàn 5pt.

       Công thức 58pt cũ co xuống tận sàn 5pt ngay từ 12 cột: vừa nhỏ tới mức không đọc
       nổi, vừa BỎ PHÍ gần nửa bề ngang tờ giấy. Còn để hệ số quá lớn thì chữ không lọt
       bề ngang cột và `overflow-wrap` bẻ đôi con số — "14.808.000" thành "14.808/.000"
       là đọc SAI TIỀN, nguy hiểm hơn cả chữ nhỏ. */
    font-size: clamp(5pt, calc(120pt / var(--so-cot, 8)), 9pt);
  }
  .content.report-screen .table--in-vua { table-layout: fixed; }
  /* `break-word` chứ KHÔNG phải `anywhere`: chỉ bẻ khi cả từ không còn chỗ nào để
     nằm trọn một dòng. Đúng luật đã chốt cho ảnh báo cáo (13/08/2026) — "121.000"
     gãy thành "121.0 / 00" là đọc SAI TIỀN, và mã "NV0001" gãy thành "NV000 / 1"
     là gọi sai người. `anywhere` bẻ ngay khi thấy chật nên vi phạm cả hai. */
  .content.report-screen .table--in-vua th,
  .content.report-screen .table--in-vua td {
    padding: 2px 2px; overflow-wrap: break-word; word-break: normal;
  }
  /* Cột đầu là tên thợ / ngày — rộng hơn các cột số chia đều phía sau, nhưng bảng càng
     đông cột thì phần nhường cho nó càng phải nhỏ lại, nếu không chính nó ăn mất chỗ
     của các cột tiền và đẩy con số xuống hai dòng. Không nhỏ hơn 10% để cột Ngày /
     tên thợ luôn còn đọc được. */
  .content.report-screen .table--in-vua th:first-child,
  .content.report-screen .table--in-vua td:first-child {
    width: clamp(10%, calc(150% / var(--so-cot, 8)), 16%);
  }
  .bienban { border: none; padding: 0; }
  .bienban__head { border-bottom-color: #333; }

  /* ── Bảng lương (Q015, 10/09/2026): co vừa khổ giấy khi in ─────────────────
     Ca thật: in "Lương tháng" ZORRO1/ZORRO3 cắt cụt sau cột "HH tăng ca, tăng
     cường" — 12 cột sau (Các khoản cộng → Ghi chú) mất trắng, MEDUSA in đúng
     đủ 21 cột nên dùng làm chuẩn. Nguyên nhân giống hệt bảng ma trận ở mục 22:
     ba cột ghim đầu (`.luong-dinh`) khai `position:sticky` + width/min-width
     CỐ ĐỊNH bằng px (76/64/96) để cuộn ngang trên màn hình — bảng không co
     được khi in, Chrome cắt phăng phần thò khỏi mép phải mà không để lại dấu
     vết. Bảng này KHÔNG nằm trong `.content.report-screen` nên không tự có
     luật co giãn ở mục 22 — khai riêng, cùng công thức. 19 cột CỐ ĐỊNH (không
     đổi theo số nhân viên) nên viết cứng cỡ chữ, không cần biến `--so-cot`. */
  .card:has(.luong-dinh) { page: report-wide; }
  .luong-dinh { table-layout: fixed; width: 100% !important; font-size: 6.3pt; }
  .luong-dinh th, .luong-dinh td {
    position: static !important; width: auto !important; min-width: 0 !important;
    max-width: none !important; left: auto !important;
    padding: 1mm .6mm; overflow-wrap: break-word; word-break: normal;
  }
  /* Số tiền/mã không được xuống dòng giữa chừng — "16.921.393" gãy đôi là đọc
     sai tiền, "NV0001" gãy đôi là gọi sai người (đúng luật đã chốt cho ảnh báo
     cáo 13/08/2026). Chỉ cột Tên (chữ, thứ 3) và Ghi chú (cột cuối) được xuống dòng. */
  .luong-dinh td:not(:nth-child(3)):not(:last-child) { white-space: nowrap; }
  /* TIÊU ĐỀ thì NGƯỢC LẠI phải được xuống dòng — `.table th.num{white-space:
     nowrap}` (chung toàn site) ép mọi tiêu đề cột số nằm một dòng, mà 6,3pt
     không đủ chỗ cho "Các khoản cộng"/"Lương đảm bảo"/"Sau đảm bảo" trên một
     dòng nên CHỮ TRÀN ĐÈ LÊN cột bên cạnh (đọc nhầm tên cột, khác lỗi cắt cụt
     ở trên nhưng cùng gốc "khai cứng nowrap"). Tiêu đề không phải số tiền nên
     xuống dòng an toàn, không có rủi ro đọc sai như dữ liệu. */
  .luong-dinh th { white-space: normal !important; }
  .luong-dinh thead { display: table-header-group; }
  /* `table-row-group`, KHÔNG phải `table-footer-group` — bảng nhiều nhân viên
     tràn nhiều trang thì dòng TỔNG chỉ hiện một lần đúng vị trí của nó, không
     lặp lại ở cuối MỖI trang (đúng lỗi MEDUSA đã sửa, commit `256bb43`). */
  .luong-dinh tfoot { display: table-row-group; }
  .luong-dinh tr { break-inside: avoid; }
  /* Giấy không thao tác được — in GIÁ TRỊ, không in ô để gõ vào/nút bấm. */
  .luong-dinh input:not([type="checkbox"]) {
    width: 100% !important; min-width: 0; padding: 0 !important; border: 0 !important;
    background: transparent !important; color: inherit !important; font: inherit; text-align: inherit;
  }
  .luong-dinh input[type="checkbox"], .luong-dinh button { display: none !important; }
}

/* ── 21. HAI CỘT: DANH SÁCH · CHI TIẾT ───────────────────────────────────────
   Bố cục của `src/ui/users.html` (MEDUSA): chọn một dòng bên trái thì chi tiết hiện
   bên phải. Trên điện thoại hai cột xếp chồng — cùng một khối HTML, chỉ khác cách xếp. */
.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: var(--s3); align-items: start; }
.detailpane { min-width: 0; }
.row--on { background: var(--brand-weak); }
.row--on .row__name { color: var(--brand); font-weight: 700; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

/* Hai ô nhập cạnh nhau trong hộp thoại (Đơn vị · Giá) — trên điện thoại xếp chồng. */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
@media (max-width: 560px) { .grid2 { grid-template-columns: 1fr; } }

/* Cụm nút nhỏ trong một dòng bảng. */
.btn--sm { min-height: 34px; padding: 0 var(--s3); font-size: 13px; }
.actions--row { gap: var(--s1); flex-wrap: nowrap; justify-content: flex-end; }
@media (max-width: 900px) {
  .row--stack { flex-wrap: wrap; }
  .actions--row { flex: 1 1 100%; justify-content: flex-start; flex-wrap: wrap; gap: var(--s2); }
  /* Hai nút một hàng như `.vt__act` của MEDUSA — mỗi nút một dòng thì một dòng vật tư
     chiếm hết màn hình và danh sách 5 món phải cuộn ba lần mới hết. */
  .actions--row .btn { flex: 1 1 calc(50% - var(--s2)); min-height: 38px; }
}
.fund-catalog__toolbar{display:flex;gap:12px;justify-content:space-between;align-items:center;margin-bottom:16px}.fund-catalog__toolbar .input{max-width:360px}.fund-metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:16px}.fund-metric{padding:16px;border:1px solid var(--border);border-radius:12px;background:var(--surface)}.fund-metric__label{display:block;color:var(--text-muted);font-size:12px;margin-bottom:8px}.fund-metric__value{font-size:20px}.fund-metric--blue{border-color:#dbeafe}.fund-metric--green{border-color:#dcfce7}.fund-metric--amber{border-color:#fef3c7}.fund-metric--violet{border-color:#ede9fe}.fund-catalog__toggle{display:flex;justify-content:flex-end;align-items:center;font-size:13px;color:var(--text-muted);margin:0 0 10px}.fund-catalog__table td{vertical-align:middle}
@media(max-width:700px){.fund-catalog__toolbar{align-items:stretch;flex-direction:column}.fund-catalog__toolbar .input{max-width:none}.fund-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.fund-metric{padding:12px}.fund-metric__value{font-size:16px}}

/* MEDUSA thuchi.html: scoped 1:1 cho Tài chính > Sổ quỹ / Thu chi. */
.content.medusa-funds-screen{padding-top:16px;background:var(--md-bg)}
.medusa-funds{--mf-bg:#f6f7f9;--mf-card:#fff;--mf-ink:#1c2430;--mf-muted:#6b7684;--mf-line:#e6e9ee;--mf-accent:#2f6fed;--mf-thu:#127a4b;--mf-chi:#c0392b;--mf-thubg:#e7f6ee;--mf-chibg:#fdecea;max-width:900px;margin:0 auto;color:var(--mf-ink);font:15px/1.5 system-ui,"Segoe UI",Roboto,sans-serif}
.mf-tabs{display:flex;gap:6px;margin-bottom:12px}.mf-tab{min-height:38px;padding:7px 14px;border:1px solid var(--mf-line);border-radius:999px;background:var(--mf-card);color:var(--mf-ink);cursor:pointer}.mf-tab--on{background:var(--mf-accent);border-color:var(--mf-accent);color:#fff}
.mf-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px}.mf-date-label{color:var(--mf-ink)}
.mf-control,.mf-btn{min-height:40px;padding:7px 10px;border:1px solid var(--mf-line);border-radius:8px;background:var(--mf-card);color:var(--mf-ink);font:inherit}.mf-date{width:200px}
/* Ô ngày dùng chung `.dt` nhưng phải mang màu của màn Sổ quỹ (bộ token `--mf-*`),
   nếu không viền và nền của nó lệch hẳn với mấy nút bên cạnh. */
.medusa-funds .dt input,.medusa-funds .dt .mo{border-color:var(--mf-line);background:var(--mf-card);color:var(--mf-ink)}.mf-btn{cursor:pointer;white-space:nowrap}.mf-btn--primary{background:var(--mf-accent);border-color:var(--mf-accent);color:var(--chu-tren-nen-mau)}.mf-btn--thu{background:var(--mf-thu);border-color:var(--mf-thu);color:var(--chu-tren-nen-mau)}.mf-btn--chi{background:var(--mf-chi);border-color:var(--mf-chi);color:var(--chu-tren-nen-mau)}.mf-save{margin-left:auto}
.mf-card{margin:0 0 14px;padding:14px 16px;border:1px solid var(--mf-line);border-radius:12px;background:var(--mf-card);box-shadow:none}.mf-title{margin:0 0 10px;color:var(--mf-muted);font-size:13px;line-height:1.5;text-transform:uppercase}.mf-table{width:100%;border-collapse:collapse;font-size:14px}.mf-table th,.mf-table td{padding:7px 9px;border-bottom:1px solid var(--mf-line);text-align:left}.mf-table th{color:var(--mf-muted);font-weight:700}.mf-table td.num,.mf-table th.num{text-align:right;font-variant-numeric:tabular-nums}.mf-balance-table th:not(:first-child){text-align:right}.mf-fund-name{font-weight:700}.mf-income{color:var(--mf-thu)}.mf-expense{color:var(--mf-chi)}.mf-balance{width:130px;min-height:38px;text-align:right}.mf-revenue{margin:10px 0 0;color:var(--mf-muted);font-size:14px}.mf-empty{margin:0;color:var(--mf-muted)}
.mf-entry-table tr:last-child td{border-bottom:0}.mf-pill{display:inline-block;padding:1px 8px;border-radius:999px;font-size:12px;font-weight:600}.mf-pill--thu{background:var(--mf-thubg,var(--xanh-weak));color:var(--mf-thu,var(--xanh))}.mf-pill--chi{background:var(--mf-chibg,var(--do-weak));color:var(--mf-chi,var(--do))}.mf-entry-sub{display:block;margin-top:3px;color:var(--mf-muted);font-size:12.5px}.mf-lock h3{margin:0 0 4px;font-size:17px}.mf-lock-copy{margin:0 0 10px;color:var(--mf-muted);font-size:13.5px}.mf-lock-link{display:inline-flex;min-height:44px;align-items:center;color:var(--brand);text-decoration:none;font-weight:500}
.mf-lock-status{color:var(--mf-thu)}.mf-lock-status--closed{color:var(--mf-chi)}
/* Ba nút của một dòng phiếu: Xem · Sửa · Xoá — cùng cỡ, luôn đứng cạnh nhau, đúng khối
   `.mini` trong `thuchi.html` của MEDUSA. Cao tối thiểu 44px để bấm được bằng ngón tay. */
.mf-entry-actions{white-space:nowrap}.mf-entry-actions{display:flex;gap:6px;justify-content:flex-end}
.mf-mini{display:inline-flex;align-items:center;justify-content:center;gap:4px;min-height:36px;padding:0 10px;border:1px solid var(--mf-line);border-radius:8px;background:var(--mf-card);color:var(--mf-ink);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap}
.mf-mini--sua{border-color:var(--mf-accent);color:var(--mf-accent)}
.mf-mini--xoa{border-color:var(--mf-chibg);background:var(--mf-chibg);color:var(--mf-chi)}
/* Hộp thoại nằm trong `#overlay`, NGOÀI `.medusa-funds`, nên các token `--mf-*` không với
   tới đây — dùng token toàn cục, đúng cách `.modal--fund` phía trên đang làm. */
.mf-detail-list{display:flex;flex-direction:column;gap:2px}
.mf-detail{display:flex;align-items:center;gap:12px;padding:6px 0;border-bottom:1px solid var(--border)}
.mf-detail:last-child{border-bottom:0}
.mf-detail__label{flex:1;min-width:0;color:var(--text-muted);font-size:13px}
.mf-detail__value{margin-left:auto;text-align:right;font-weight:500;overflow-wrap:anywhere}
.mf-detail__edit{width:100%;margin-top:12px;min-height:44px}
.modal--fund{width:380px;max-width:94vw;border-radius:14px}.modal--fund .modal__head{padding:18px 20px 0;border-bottom:0}.modal--fund .modal__head .t-h1{font-size:17px}.modal--fund .modal__body{padding:12px 20px}.modal--fund .modal__foot{gap:10px;padding:0 20px 18px;border-top:0}.modal--fund .modal__foot .btn{flex:1;min-height:42px}.modal--fund .field{margin-bottom:11px}.modal--fund .field__label{font-size:13px;color:#6b7684}
@media(prefers-color-scheme:dark){.content.medusa-funds-screen{background:#0f1419}.medusa-funds{--mf-bg:#0f1419;--mf-card:#171d26;--mf-ink:#e6e9ee;--mf-muted:#9aa4b2;--mf-line:#252d38;--mf-accent:#5b8cf5;--mf-thu:#3fbf83;--mf-chi:#e26d5c;--mf-thubg:#12271c;--mf-chibg:#2a1512}}
@media(max-width:640px){.content.medusa-funds-screen{padding:12px}.medusa-funds{width:100%}.mf-card{padding:12px;border-radius:10px}.mf-tabs{flex-wrap:wrap}.mf-tab{flex:1 1 calc(50% - 6px);min-height:44px;display:flex;align-items:center;justify-content:center;padding:0 10px;font-size:14px}.mf-toolbar{display:grid;grid-template-columns:1fr 1fr;gap:8px}.mf-date-label{display:none}.mf-date{grid-column:1/-1;width:100%}.mf-toolbar .mf-btn{width:100%;min-height:44px;font-size:16px}.mf-save{grid-column:1/-1;margin-left:0}.mf-balance-table,.mf-balance-table tbody,.mf-balance-table tr,.mf-balance-table td{display:block;width:100%}.mf-balance-table thead{display:none}.mf-balance-table tr{margin-bottom:9px;padding:8px 11px;border:1px solid var(--mf-line);border-radius:10px;background:var(--mf-card)}.mf-balance-table td{display:flex;align-items:center;gap:12px;padding:5px 0;border:0;text-align:left}.mf-balance-table td::before{content:attr(data-label);flex:1;min-width:0;color:var(--mf-muted);font-size:13px}.mf-balance-table td.num{text-align:left}.mf-balance-table td>*{margin-left:auto}.mf-balance{width:150px;min-height:44px;font-size:16px}
/* Danh sách phiếu gập thành thẻ y như bảng số dư phía trên: mỗi phiếu một khung, nhãn
   lấy từ `data-label`, ba nút Xem/Sửa/Xoá chiếm trọn một dòng cuối thẻ — đúng thẻ phiếu
   của MEDUSA trên điện thoại. */
.mf-entry-table,.mf-entry-table tbody,.mf-entry-table tr,.mf-entry-table td{display:block;width:100%}
.mf-entry-table thead{display:none}
.mf-entry-table tr{margin-bottom:9px;padding:8px 11px;border:1px solid var(--mf-line);border-radius:10px;background:var(--mf-card)}
.mf-entry-table tr:last-child{margin-bottom:0}
.mf-entry-table td{display:flex;align-items:center;gap:12px;padding:5px 0;border:0;text-align:left}
.mf-entry-table td::before{content:attr(data-label);flex:1;min-width:0;color:var(--mf-muted);font-size:13px}
.mf-entry-table td.num{text-align:left}
.mf-entry-table td>*{margin-left:auto}
.mf-entry-table .mf-entry-value{text-align:right;overflow-wrap:anywhere}
.mf-entry-actions{margin-top:6px;padding-top:9px;border-top:1px solid var(--mf-line)}
.mf-entry-actions::before{content:none}
.mf-entry-actions>*{flex:1 1 0;margin-left:0;min-height:44px;font-size:14px}}

/* ── 22. XUẤT ẢNH BÁO CÁO ────────────────────────────────────────────────────
   Port khối `#ovAnh` của MEDUSA (`src/ui/_hop-thoai.html`). Xem `frontend/anhBaoCao.ts`
   để biết vì sao dựng ảnh bằng SVG chứ không bằng html2canvas.

   KHUNG CHỤP `#anh-khung` dựng ngoài màn hình để đo và để serialize. Luật ở đây phải
   KHỚP với khối `@media print` phía trên: ảnh và tờ giấy in ra phải giống nhau. MEDUSA
   bóc thẳng luật in ra rồi tiêm vào trang lúc chạy; ZORRO3 chạy dưới CSP chặn style nội
   tuyến nên khai sẵn tại đây — bộ luật in vẫn được bóc ra nhưng chỉ nhét vào trong SVG. */
#anh-khung {
  position: fixed; left: -99999px; top: 0; padding: 16px; background: #fff;
  /* Ảnh báo cáo LUÔN nền sáng, kể cả máy đang để nền tối: gửi cho chủ salon một tấm ảnh
     chữ trắng trên nền đen thì không ai đọc, và in ra giấy càng không. */
  --bg: #ffffff; --surface: #ffffff; --surface-2: #eef2f7;
  --border: #e2e7ee; --border-strong: #cfd7e2;
  --text: #16202b; --text-muted: #5c6b7a;
  --brand: #2563eb; --brand-strong: #1d4ed8; --brand-weak: #e8f0fe;
  --do: #d32f2f; --do-weak: #fdecec; --cam: #c2620a; --cam-weak: #fff2e2;
  --vang: #8d6a00; --vang-weak: #fff7db; --xanh: #0f7b4f; --xanh-weak: #e4f5ec;
  --xam: #64748b; --xam-weak: #eef1f5; --tim: #6d28d9; --tim-weak: #f0e9fe;
  --head: #1f2b52;
  color: var(--text);
}
/* Bỏ `position:fixed` ngay trước khi serialize: bê nguyên vào SVG thì nội dung nằm ngoài
   khung vẽ và ảnh ra TRẮNG TINH — hỏng mà không có lỗi nào để lần. */
#anh-khung.anh-khung--phang { position: static; left: auto; }
/* Bảng phải bung hết bề ngang: trong ảnh không có thanh cuộn để kéo.
   MỞ CHO MỌI LỚP, không kể tên từng cái. Ca thật 26/08/2026 — ảnh "Tổng hợp hoa hồng"
   của ZORRO 1 (13 nhân viên) mất mấy cột cuối: luật cũ chỉ mở `.table-wrap`, còn
   `.service-report__table` (khai `overflow:hidden` để bo góc) vẫn cắt. Đo được: khung đặt
   1200px, bảng thật rộng 1305px, cột cuối "QP" kết thúc ở 1369px — thò ra 185px và bị lớp
   đó xén mất.
   Tệ hơn: vì bị xén nên phần thò ra KHÔNG tính vào `scrollWidth` của khung, thành ra luật
   "bảng rộng hơn khung thì nới khung" trong `xuatAnhBaoCao` đo ra 1200 = 1200 và không bao
   giờ chạy. Cắt xong lại tưởng vừa.
   Trong một tấm ảnh thì KHÔNG có gì được phép cắt — không cuộn được để xem phần bị giấu. */
#anh-khung, #anh-khung * { overflow: visible !important; }
/* Ảnh giữ đúng khổ A4 và chỉ dài xuống, nên bảng phải CO VỀ VỪA KHUNG chứ không giữ
   `min-width` của bản trên màn hình (bảng hoa hồng theo ngày khai 980px). Không gỡ thì
   ở khổ 794px bảng tràn ra ngoài và ảnh cắt cụt mất mấy cột cuối — mất tiền của thợ mà
   người xem không biết mình đang thiếu. Cho chữ xuống dòng thay vì cắt. */
#anh-khung table { min-width: 0 !important; width: 100% !important; table-layout: auto; }
/* Trong ảnh không có thanh cuộn nên cột ghim phải trả về tĩnh, và CHỮ được xuống dòng
   nhưng CON SỐ thì không: "121.000đ" gãy thành "121.0/00đ" là đọc sai tiền (ảnh chụp
   iPhone 13/08/2026). Khung chụp rộng 1200px, bảng rộng hơn thì khung tự nới —
   xem `xuatAnhBaoCao` — nên cấm bẻ số không làm mất cột nào. */
#anh-khung .table th, #anh-khung .table td {
  white-space: normal !important; word-break: break-word; position: static !important;
}
#anh-khung .table th.num, #anh-khung .table td.num, #anh-khung .table td.cell-ngay {
  white-space: nowrap !important; word-break: normal;
}
/* Nút bấm là công cụ trên màn hình, không phải nội dung báo cáo. */
#anh-khung .btn, #anh-khung .actions, #anh-khung .reward-tools,
#anh-khung .reward-filter, #anh-khung .report-filter { display: none !important; }

#ovAnh {
  position: fixed; inset: 0; z-index: 9600; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(15, 23, 42, .6);
}
#ovAnh .hopAnh {
  display: flex; flex-direction: column; width: min(96vw, 900px); max-height: 92vh;
  background: var(--surface); color: var(--text); border-radius: var(--r-lg);
  overflow: hidden; box-shadow: var(--sh-2);
}
#ovAnh .hopAnh__dau { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
#ovAnh .hopAnh__dau b { font-size: 16px; }
#ovAnh .hopAnh__co { flex: 1; color: var(--text-muted); font-size: 13px; }
#ovAnh .hopAnh__than { flex: 1; min-height: 0; overflow: auto; padding: 12px; text-align: center; background: var(--surface-2); }
#ovAnh .hopAnh__than img { max-width: 100%; height: auto; background: #fff; box-shadow: var(--sh-1); }
/* Báo cáo quá dài phải chia nhiều tấm — đánh số ngay trên từng tấm để người gửi biết mình
   đang xem phần mấy trên mấy, và biết ngay nếu gửi sót một tấm. */
#ovAnh .hopAnh__so {
  margin: 14px 0 4px; font-size: 13px; font-weight: 600; color: var(--text-muted); text-align: left;
}
#ovAnh .hopAnh__so:first-child { margin-top: 0; }
#ovAnh .hopAnh__nut { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 14px 4px; }
#ovAnh .anhBtn {
  flex: 1; min-width: 140px; display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); padding: 0 15px; border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); color: var(--text); font: 600 15px/1 var(--font); cursor: pointer;
}
#ovAnh .anhBtn--chinh { background: var(--brand); border-color: var(--brand); color: #fff; }
#ovAnh .anhBtn--dong { flex: 0; min-width: 0; }
#ovAnh .hopAnh__mach { margin: 0; padding: 8px 14px 14px; font-size: 13px; color: var(--text-muted); }
#ovAnh .hopAnh__mach--tot { color: var(--xanh); }
#ovAnh .hopAnh__mach--xau { color: var(--do); }
/* Điện thoại: hộp chiếm trọn màn hình (ảnh báo cáo vốn dài) và nút xếp dọc cho dễ bấm
   bằng ngón tay — đây là đường dùng CHÍNH của chủ salon. */
@media (max-width: 560px) {
  #ovAnh { padding: 0; }
  #ovAnh .hopAnh { width: 100vw; max-height: 100vh; border-radius: 0; }
  #ovAnh .hopAnh__nut { flex-direction: column; }
  #ovAnh .anhBtn { width: 100%; min-width: 0; }
  #ovAnh .hopAnh__than { padding: 8px; }
}
@media print { #ovAnh, #anh-khung { display: none !important; } }

/* ── Bảng lương: BA CỘT ĐẦU DÍNH TRÁI (bản tối ưu MEDUSA 15/08/2026) ──────────
   Nút Lưu từng dòng + mã + tên phải luôn nhìn thấy dù bảng hơn 20 cột đã kéo
   sang phải — nhất là trên điện thoại. Hai điều bắt buộc:
   · border-collapse:separate — .table dùng collapse, mà Chromium bỏ
     position:sticky trên ô bảng khi collapse;
   · nằm ở FILE CSS này chứ không bơm <style> bằng JS — CSP default-src 'self'
     của site chặn stylesheet nội tuyến (đã đo: thẻ có trong DOM mà luật không ăn). */
.luong-dinh { border-collapse: separate; border-spacing: 0; }
.luong-dinh tr > :nth-child(-n+3) { position: sticky; z-index: 3; background: var(--surface); }
.luong-dinh thead tr > :nth-child(-n+3) { z-index: 4; }
.luong-dinh tr > :nth-child(1) { left: 0; width: 76px; min-width: 76px; max-width: 76px; }
.luong-dinh tr > :nth-child(2) { left: 76px; min-width: 64px; }
.luong-dinh tr > :nth-child(3) { left: 140px; min-width: 96px; }
.luong-dinh tfoot td { background: var(--surface); }

/* ── Báo cáo ngày BẢN MÀU ĐẬM (chủ salon chốt 15/08/2026: "màu cũ nhạt quá") ──────
   Chỉ đổi MÀU, giữ nguyên kích thước và bố cục. Phạm vi khoá trong .daily-report-card
   để phần còn lại của app giữ ngôn ngữ màu nhạt cũ. */
.daily-report-card .row__ico.bg-do    { background: var(--do);    color: #fff; }
.daily-report-card .row__ico.bg-cam   { background: var(--cam);   color: #fff; }
.daily-report-card .row__ico.bg-xanh  { background: var(--xanh);  color: #fff; }
.daily-report-card .row__ico.bg-tim   { background: var(--tim);   color: #fff; }
.daily-report-card .row__ico.bg-brand { background: var(--brand); color: #fff; }
.daily-report-card .row__ico { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.daily-report-card .bienban__muc { font-weight: 800; color: #1d4ed8; }
.daily-report-card .h2i { background: #1d4ed8; }
.daily-report-card .table thead th {
  background: #1e3a8a; color: #fff; border-color: #1e3a8a;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.daily-report-card .bienban__meta .t-cap { color: var(--text); font-weight: 600; }
/* Biểu tượng cột Loại: chấm tròn đặc cùng màu, hình trắng — như bản mẫu. */
.daily-report-card .bienban__loai .ico {
  width: 20px; height: 20px; padding: 4px; box-sizing: border-box; border-radius: 50%;
  color: #fff; -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.daily-report-card .bienban__loai.c-do .ico   { background: var(--do); }
.daily-report-card .bienban__loai.c-xanh .ico { background: var(--xanh); }
.daily-report-card .bienban__loai.c-cam .ico  { background: var(--cam); }


/* ── LƯƠNG TĂNG CƯỜNG ────────────────────────────────────────────────────────────────
   Bảng sáu cột (Nội dung · Tổng · MEDUSA · ZORRO1 · ZORRO3 · Ghi chú) chỉ hợp ở màn rộng;
   điện thoại đổi sang từng KHỐI một dòng để khỏi phải kéo ngang. Ô máy tự tính có nền xám
   và không có viền ô nhập, để mắt phân biệt ngay với ô gõ tay. */
.ltc-stats { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
/* Ô MÁY TỰ TÍNH — xanh nhạt, không phải xám.
   Chủ salon báo 23/08/2026: nền xám lẫn với nền thẻ, không phân biệt được đâu là ô mình gõ
   được, đâu là ô máy tính ra. Xanh nhạt + viền trái đậm nhìn một cái là biết. */
.cell--auto { background: var(--o-tu-tinh, #e8f1ff); color: var(--text);
  box-shadow: inset 2px 0 0 var(--o-tu-tinh-vien, #6aa2f7); }
@media (prefers-color-scheme: dark) {
  :root { --o-tu-tinh: #16283f; --o-tu-tinh-vien: #3d6ea8; }
}
/* BA LOẠI Ô — nhìn phát biết ô nào gõ được (yêu cầu chủ salon 23/08/2026).
   Ô nhập tay: nền trắng, viền rõ.  Ô công thức: xanh nhạt + viền trái xanh, chỉ đọc.
   Ô lấy từ hệ thống: chưa dùng ở module này, chỉ có trong chú giải. */
.o-nhap { background: var(--surface); border: 1px solid var(--border, #c7d0dc); }
.o-nhap:focus { outline: 2px solid var(--primary, #2563eb); outline-offset: -1px; }
.ltc-chugiai { flex-wrap: wrap; gap: var(--s3) var(--s5); align-items: center; }
.ltc-chugiai__muc { display: inline-flex; align-items: center; gap: var(--s2); }
.ltc-chugiai__mau { width: 16px; height: 16px; border-radius: 4px; flex: none; }
.ltc-chugiai__mau--o-nhap { background: var(--surface); border: 1px solid var(--border, #c7d0dc); }
.ltc-chugiai__mau--o-cong-thuc { background: var(--o-tu-tinh, #e8f1ff);
  box-shadow: inset 2px 0 0 var(--o-tu-tinh-vien, #6aa2f7); }
.ltc-chugiai__mau--o-he-thong { background: repeating-linear-gradient(45deg,
  var(--surface-2) 0 4px, transparent 4px 8px); border: 1px dashed var(--border, #c7d0dc); }
.ltc-giai-thich { margin-top: var(--s2); font-size: 12px; line-height: 1.5; opacity: .85; }
.ltc-debug { margin-top: var(--s4); }
.ltc-debug__pre { max-height: 320px; overflow: auto; font-size: 11px; line-height: 1.45;
  background: var(--surface-2); padding: var(--s3); border-radius: var(--r-md); }
.stat.cell--auto { box-shadow: inset 2px 0 0 var(--o-tu-tinh-vien, #6aa2f7); }
.ltc-block { padding: var(--s3) var(--s4); margin-bottom: var(--s3); }
.ltc-block__head { display: flex; justify-content: space-between; gap: var(--s3); font-weight: 600; }
.ltc-block__row { display: flex; justify-content: space-between; align-items: center;
  gap: var(--s3); margin-top: var(--s2); }
.ltc-block__row .input { max-width: 160px; text-align: right; }
.ltc-block--total { border: 1px solid var(--primary, #2563eb); }
.ltc-report .table { width: 100%; }
.ltc-report { padding: var(--s5); }
/* Ô tên nhân viên: rộng và nổi hơn ô tiền, vì đây là thứ phải điền đầu tiên của mỗi thẻ. */
.ltc-ten { min-width: 260px; flex: 1 1 260px; font-weight: 600; }
.ltc-ten[data-chua-dat-ten] { border-color: var(--primary, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, .15); }
.ltc-report__head { text-align: center; margin-bottom: var(--s4); }
.ltc-report__meta { display: flex; flex-wrap: wrap; gap: var(--s4); justify-content: center;
  margin-top: var(--s2); }
/* Bản in: A4 dọc, không cắt cột tiền — bảng thu nhỏ chữ thay vì tràn trang. */
@media print {
  .ltc-report { page-break-inside: avoid; font-size: 12px; }
  .ltc-report .table { font-size: 12px; }
}
