/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * BỘ ÁO TRỘN — anh Thắng 14/09/2026 gửi hai tệp DESIGN.md, chọn *"Trộn hai bản"*, xem thử trên
 * trang tổng rồi bảo *"thay cho trang ghế và chi phí văn phòng và mtd đi em"*.
 *
 * 🔴 SỬA Ở ĐÂY LÀ SỬA CHO CẢ BỐN BẢN CHI PHÍ. Bản «vp» và «mtd» KHÔNG có bộ áo riêng — chúng
 *    sinh ra từ chính thư mục này bằng `tools/tach-ban-vung.sh`. Muốn hai bản ấy đổi áo thì
 *    phải đổi ở đây, và bản khu vui chơi đổi theo. Không có đường nào khác trừ khi dựng ba
 *    bộ áo rời — mà ba bộ rời là ba chỗ phải nhớ sửa mỗi lần, tức sớm muộn chúng lệch nhau.
 *
 * Lấy gì của ai (hai tệp ấy mâu thuẫn nhau, nên phải nói rõ):
 *   · Officevibe cho MÀU  — nền kem ấm, viền KEM (nó cấm hẳn viền xám), chữ navy, nhấn cobalt.
 *   · shadcn     cho NHỊP — compact, đơn vị 4px, bóng gần như không thấy, và đỏ CHỈ cho xoá.
 *
 * ⚠️ BỐN TÔNG TRẠNG THÁI KHÔNG ĐỔI: cam = đang chờ · xanh dương = tiền đã ra khỏi két ·
 *    xanh lá = xong. Chúng mang nghĩa, không phải trang trí.
 * ⚠️ KHÔNG TẢI FONT NGOÀI — trang chạy ngoài internet; mạng chậm thì chữ nhảy một nhịp giữa
 *    lúc người ta đang gõ số tiền. Dùng chồng font hệ thống.
 * ⚠️ Cùng đúng bộ tên biến với trang tổng (`vhcp-chi-phi-tong`), để hai trang kế toán mở cạnh
 *    nhau không lệch tông.
 * ══════════════════════════════════════════════════════════════════════════════════════════════ */
:root{
  --nen:#f9f8f6; --the:#ffffff; --nen-2:#f4f1ec;
  --vien:#f0e9e1; --vien-dam:#e2d6c7;
  --chu:#171417; --chu-dam:#0c1754; --chu-mo:#8c8781;
  --nhan:#2545ff; --nhan-dam:#1a34c9; --nhan-nhat:#eaebf8;
  --do:#e7000b;
  --d1:4px; --d2:8px; --d3:12px; --d4:16px; --d5:20px; --d6:24px;
  --bo-the:16px; --bo-nut:18px; --bo-o:10px; --bo-o-bang:6px; --bo-nho:8px; --bo-badge:16px;
  --bong:0 0 0 1px rgba(12,23,84,.03), 0 1px 3px rgba(12,23,84,.06), 0 1px 2px -1px rgba(12,23,84,.06);
}
/* GIAO DIỆN DÙNG CHUNG cho các trang của plugin (app chi phí và thư viện hợp đồng).
   Tách khỏi templates/*.html để hai trang luôn cùng một bộ style, sửa 1 chỗ ăn cả hai. */
  /* Bản WordPress: không còn Google Sheet nên ẩn 2 nút mở sheet */
  #daOpenSheet,#bpOpenSheet{display:none !important}
  *{box-sizing:border-box;margin:0;padding:0;
    font-family:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif}
  body{background:var(--nen);color:var(--chu);font-size:14px;line-height:1.5}
  /* CANH THẲNG HÀNG VỚI NỘI DUNG.
     Thanh xanh trên cùng và các thanh trắng chạy hết bề rộng màn hình, còn thẻ nội dung
     thì canh giữa trong 1600px — nên trên màn rộng, chữ ở thanh nằm sát lề trái mà thẻ
     bên dưới lại thụt vào giữa, nhìn như lệch trang. Đệm hai bên của thanh được tính cho
     bằng đúng lề của khối nội dung. */
  .top{background:var(--chu-dam);color:#fff;padding:14px max(22px, calc((100% - 1600px) / 2));display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px}
  .top h1{font-size:18px;display:flex;align-items:center;gap:8px}
  .top .sub{font-size:11px;color:#b9c0e8;margin-top:2px}
  .bar{background:#fff;border-bottom:1px solid #f0e9e1;padding:10px max(22px, calc((100% - 1600px) / 2));display:flex;gap:10px;align-items:center;flex-wrap:wrap}
  select,input,textarea{padding:8px 10px;border:1px solid var(--vien-dam);border-radius:var(--bo-o);
    font-size:14px;font-family:inherit;background:var(--the);color:var(--chu)}
  /* Ô nhập TRONG bảng bo nhỏ: chín ô bo tròn sát nhau ăn mất bề ngang và tạo một hàng sóng. */
  td input,td select,td textarea{border-radius:var(--bo-o-bang)}
  select:focus,input:focus,textarea:focus{outline:none;border-color:#2545ff;box-shadow:0 0 0 3px rgba(37,69,255,.12)}
  .btn{padding:8px 16px;border:none;border-radius:var(--bo-nut);font-size:13.5px;font-weight:500;cursor:pointer;white-space:nowrap}
  .btn:disabled{opacity:.5;cursor:not-allowed}
  .b-p{background:#2545ff;color:#fff}.b-p:hover{background:#1a34c9}
  .b-g{background:var(--chu-dam);color:#fff}.b-x{background:#f4f1ec;color:#171417}.b-d{background:#fdeaea;color:var(--do)}
  .b-s{background:var(--nhan-nhat);color:var(--chu-dam)}
  /* BỀ RỘNG TRANG THEO MÁY.
     Trước đây chốt 1250px: màn 24" thì bỏ trống hai bên gần 600px, còn điện thoại thì
     lề 22px ăn mất chỗ của bảng. Nay giãn tới 1600px trên màn rộng và bóp lề lại trên
     máy nhỏ. Các mốc dùng chung một hệ: 1200 · 900 · 820 · 560 · 420. */
  .wrap{padding:16px 22px;width:100%;max-width:1600px;margin:0 auto}
  .card{background:var(--the);border:1px solid var(--vien);border-radius:var(--bo-the);box-shadow:var(--bong);margin-bottom:16px;overflow:hidden}
  .ch{padding:12px 16px;border-bottom:1px solid #f4f1ec;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px}
  .ch h2{font-size:14px;font-weight:700}
  .cb{padding:14px 16px}

  /* 🔴 KHỐI QUYẾT TOÁN NỔI HẲN LÊN — anh Thắng 26/08: *"Đóng nguyên ô này nổi màu lên cho kế
     toán thấy"*. Mục 3) là chỗ kế toán phải dừng lại: đối chiếu tạm ứng với thực mua rồi trả
     tiền. Trước đây nó mặc đúng bộ đồ trắng của mọi khối khác trên màn, nên trong một trang
     dài toàn khối trắng thì đúng cái khối cần dừng lại lại là cái khó thấy nhất.
     Khung vàng + dải tiêu đề vàng là để MẮT DỪNG LẠI, không phải để trang trí — cả trang chỉ
     có MỘT khối mang màu này, mất tính "một" là mất luôn tác dụng. */
  /* Thanh đơn: hai hàng chia bằng tay — xem chú thích ở `#donBar` trong app.html.
     🔴 CHỈ HÀNG NÚT DÍNH Ở ĐẦU MÀN. Trước 06/09/2026 cả `#donBar` sticky, mà hàng 2 (trạng thái
        + sổ chỉnh đơn) nằm trong đó nên thanh cao hơn khung nhìn — sticky khi ấy dính ngay và ở
        nguyên, nội dung dưới không cuộn lên tới được. Nay hàng 2 là khối riêng, không dính. */
  .don-bar{display:block;position:sticky;top:0;z-index:40}
  /* Mở cụm "⋯" trên máy hẹp thì hàng nút cao lên hẳn — lúc ấy thôi dính, không thì lại đúng
     cái bẫy vừa gỡ, chỉ khác là nấp sau một cú bấm.
     ⚠️ Lớp `mo` do JS gắn thẳng lên thanh, KHÔNG dùng `:has()`: bộ chọn ấy chỉ có trên trình
        duyệt đời mới, và máy cũ thì lặng lẽ không áp — đúng kiểu hỏng không ai báo. */
  .don-bar.mo{position:static}
  /* Hàng 2 đứng riêng: cùng lề với thanh trên để hai khối thẳng mép, nhưng KHÔNG dính. */
  .don-hang2{padding:0 max(22px, calc((100% - 1600px) / 2));margin-top:10px}
  .db-hang1{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
  .db-day{flex:1;min-width:0}
  /* Hàng 2 chỉ chiếm chỗ khi có nội dung: đơn chưa mở thì cả hai ô đều rỗng/ẩn, và một khoảng
     trắng 14px treo lơ lửng dưới thanh trông y như lỗi. */
  .db-hang2{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap}
  .db-hang2:not(:empty){margin-top:10px}
  .db-hang2>#donBadge{flex:1 1 420px;min-width:0}
  .db-hang2>#donSuBox{flex:0 1 460px;min-width:280px}
  @media(max-width:900px){.db-hang2>#donSuBox{flex:1 1 100%}}

  /* 🔴 MẤY NÚT PHỤ RÚT VÀO SAU NÚT "⋯" TRÊN MÁY HẸP — anh Thắng 06/09/2026 gửi ảnh màn điện
     thoại: sáu nút xếp ba hàng, chiếm gần nửa màn trước khi thấy dòng chi nào, và nút đỏ đậm
     "Xoá (admin)" là thứ nổi bật nhất trên đó.
     `display:contents` cho khối bọc nghĩa là TRÊN MÁY TÍNH KHÔNG CÓ GÌ ĐỔI: mấy nút vẫn là con
     trực tiếp của hàng flex, vẫn tự xuống dòng y như trước. Cả cơ chế này chỉ tồn tại dưới
     820px. */
  #btnMoreDon{display:none}
  .db-phu{display:contents}
  .db-vach{display:none}
  @media(max-width:560px){.don-hang2{padding:0 10px}}
  @media(max-width:820px){
    #btnMoreDon{display:inline-block}
    .db-phu{display:none}
    .db-hang1.mo .db-phu{display:flex;flex-wrap:wrap;gap:8px;width:100%;
      margin-top:8px;padding-top:10px;border-top:1px dashed #e2d6c7}
    /* Hai nút một hàng: ngón tay cần bề rộng, và một cột nút dọc dài ngoằng thì cuộn lại y như
       cái đang muốn chữa. */
    .db-hang1.mo .db-phu .btn{flex:1 1 46%}
    /* Vạch ngăn trước hai nút Xoá — chúng hại nhất nên phải tách khỏi đám nút thường, không
       nằm lẫn để bấm nhầm. */
    .db-hang1.mo .db-vach{display:block;flex:1 1 100%;height:1px;background:#fecaca;margin:2px 0}
  }

  .card.qt-noi{border:2px solid #f59e0b;box-shadow:0 2px 10px rgba(245,158,11,.22)}
  .card.qt-noi>.ch{background:linear-gradient(180deg,#fffbeb,#fef3c7);border-bottom:1px solid #fde68a}
  .card.qt-noi>.ch h2{color:#92400e;font-size:15px}
  /* Cụm ba con số là KẾT LUẬN của cả cái đơn — tiền đã đưa · tiền đã tiêu · còn lại bao nhiêu.
     Đóng chung một khung để đọc như MỘT câu, chứ không phải ba ô rời cạnh nhau. */
  /* Dòng ngăn giữa hai đơn vị trong cùng một bảng — xem `_tachDonVi()` trong app.html. */
  tr.dv-ngan>td{background:#eef2ff;color:#3730a3;font-weight:800;font-size:12.5px;
    border-left:4px solid #6366f1;padding:8px 10px}

  .qt-cum{display:flex;gap:16px;flex-wrap:wrap;align-items:flex-end;
    background:#fffdf5;border:1px dashed #fcd34d;border-radius:10px;padding:12px 14px}
  @media(max-width:560px){.qt-cum{padding:10px}}
  .badge{padding:3px 10px;border-radius:12px;font-size:11px;font-weight:700}
  .st-nhap{background:#f4f1ec;color:#8c8781}.st-cho{background:#fef9c3;color:#854d0e}.st-cap{background:#dbeafe;color:#1e40af}.st-duyet{background:#dcfce7;color:#166534}
  .grid{display:grid;grid-template-columns:repeat(6,1fr);gap:10px}
  @media(max-width:1200px){.grid{grid-template-columns:repeat(3,1fr)}}
  @media(max-width:900px){.grid{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:560px){.grid{grid-template-columns:1fr}}
  /* ══════════════════════════════════════════════════════════════════════════════════════════
     🔴 FORM NHẬP HẠNG MỤC — anh Thắng 22/09/2026: *"Chỗ này tạo Form Nhập cho nó gọn trang"*.
     ══════════════════════════════════════════════════════════════════════════════════════════
     `.grid` dùng chung là SÁU cột và giãn hết bề ngang cửa sổ. Trên màn 1900px, một form 14 ô
     trải suốt gang tay: mắt phải quét từ mép này sang mép kia cho MỘT hạng mục, và hai ô có
     liên quan ("Số lượng" với "Đơn giá") thì nằm cách nhau nửa màn.

     ⚠️ CHẶN BỀ NGANG, KHÔNG PHẢI GIẢM SỐ CỘT. Giảm cột mà vẫn giãn hết màn thì mỗi ô rộng ra,
        form dài đúng như cũ — chỉ đổi kiểu dài. Cái cần chặn là bề ngang của cả khối.
     ⚠️ ĐÈ RIÊNG, KHÔNG SỬA `.grid`. Lớp chung dựng cả chục bảng khác trong app; đổi ở đó là
        sửa một màn, hỏng chín màn — và chín màn ấy không ai đi soi lại.
     ⚠️ Dưới 1200px thì NHƯỜNG lại cho `.grid`: ở đó màn vốn đã hẹp, chặn thêm nữa là ô bị bóp.

     🔴 VÀ PHẢI TỰ KHAI ĐỦ CÁC MỐC HẸP — "nhường cho `.grid`" KHÔNG TỰ XẢY RA. Anh Thắng
        22/09/2026 gửi ảnh màn iPhone: *"Hơi lệch ô nhập"*. Ba cột chen nhau trên màn 390px,
        nhãn dài xuống hai dòng còn nhãn ngắn một dòng, nên ô nhập trong cùng một hàng cao thấp
        so le.

        Nguyên do là một luật CSS im lặng: `.grid` và `.grid-nhap` CÙNG một mức riêng (mỗi bên
        một lớp), nên khi hai luật cùng khớp thì luật VIẾT SAU thắng. `.grid` hạ xuống 2 cột ở
        900px và 1 cột ở 560px; `.grid-nhap` chỉ có một mốc 1200px, mà nó viết sau — nên ở
        390px cái thắng vẫn là `repeat(3,1fr)`. Lời chú thích nói "nhường", còn trình duyệt thì
        không nhường gì cả.

        Không sửa bằng cách gỡ mốc 1200px: mốc ấy có việc của nó (4 cột -> 3). Khai đủ ba mốc,
        đi đúng theo `.grid` để hai bên không bao giờ nói ngược nhau nữa. */
  .grid-nhap{grid-template-columns:repeat(4,minmax(0,1fr));max-width:1120px}
  @media(max-width:1200px){.grid-nhap{grid-template-columns:repeat(3,minmax(0,1fr));max-width:none}}
  @media(max-width:900px){.grid-nhap{grid-template-columns:repeat(2,minmax(0,1fr))}}
  @media(max-width:560px){.grid-nhap{grid-template-columns:minmax(0,1fr)}}
  /* 🔴 Ô ĐÈ NHAU TRÊN IPHONE — anh Thắng 28/09/2026 (ảnh "Sửa dòng chi": ô Ngày đè sang ô Phân loại,
     cả form bị cắt mép phải): *"Ô nó đang đè nhau"*.
     Hai nguyên do, cùng một họ "ô tự nở to hơn cột":
       1. Ô "Ghi chú" mang `grid-column:span 2`. Lưới điện thoại chỉ có MỘT cột, nên trình duyệt
          tự đẻ thêm một cột ngầm co theo nội dung → form thành hai cột so le (đo trên 390px:
          98px | 235px) và mọi ô rộng tràn sang nhau. Dưới 560px mọi ô về đúng một cột.
       2. `1fr` = `minmax(auto,1fr)`: ô ngày của iOS và ô chọn có tên loại dài đòi bề ngang tối
          thiểu theo chữ, đẩy cột nở ra ngoài khung. `minmax(0,1fr)` + `min-width:0` bắt ô co
          theo cột, chữ dài thì cắt bằng dấu … thay vì đè ô bên cạnh.
     ⚠️ Chữ ô nhập 16px trên điện thoại: iOS tự PHÓNG TO cả trang khi chạm vào ô chữ nhỏ hơn 16px
        (chính là cảnh trong ảnh — form to ra, mất mép phải). Nhãn vẫn nhỏ như cũ. */
  .grid-nhap>.fld{min-width:0}
  .grid-nhap input,.grid-nhap select,.grid-nhap textarea{min-width:0;max-width:100%;box-sizing:border-box}
  .grid-nhap input[type=date]{-webkit-appearance:none;appearance:none;display:block;min-height:38px;text-align:left}
  .grid-nhap select{text-overflow:ellipsis}
  @media(max-width:560px){.grid-nhap>.fld{grid-column:auto !important}}
  /* 🔴 NÚT LƯU BỊ CHE — anh Thắng 28/09/2026 (ảnh iPhone: "Lưu thay đổi" nằm dưới nút nổi "← Về trạm
     chấm công"): *"Nút lưu thay đổi nó đang nằm dưới nên bị che"*.
       · Hàng nút DÍNH ĐÁY hộp (`sticky`) — form dài, không phải cuộn xuống tận cuối mới thấy Lưu.
       · `.card` mang `overflow:hidden`, mà `hidden` biến thẻ thành khung cuộn riêng nên `sticky`
         bên trong chết im. `clip` cắt góc bo y như cũ mà không đẻ khung cuộn (trình duyệt cũ
         không hiểu `clip` thì rơi về `visible` — vẫn dính được, chỉ mất góc bo).
       · Nút nổi "Về trạm" (z-index 2147483000) giấu khi hộp mở — lớp `vhcp-hop-mo` do
         `moLineForm()` / `dongLineForm()` bật tắt.
       · Chừa đáy theo `safe-area` cho vạch Home của iPhone. */
  #lineFormCard{overflow:visible;overflow:clip}
  #lineActs{position:sticky;bottom:0;z-index:3;background:var(--the,#fff);flex-wrap:wrap;
    padding:10px 0 calc(10px + env(safe-area-inset-bottom));border-top:1px solid var(--vien,#f0e9e1)}
  body.vhcp-hop-mo .vhcc-vt{display:none !important}
  @media(max-width:820px){
    #lineModal{padding:10px 6px !important}
    #lineModal input,#lineModal select,#lineModal textarea{font-size:16px}
  }
  .fld{display:flex;flex-direction:column;gap:3px}
  .fld label{font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.4px}
  /* 🔴 NHÃN CHIẾM CHỖ ĐỀU NHAU -> Ô NHẬP TRONG CÙNG MỘT HÀNG THẲNG NHAU.
     Mỗi ô là một ô lưới riêng, cao bao nhiêu tuỳ nội dung; nhãn "NGÀY" một dòng còn "PHÂN LOẠI
     (CÁ NHÂN / NCC) *" hai dòng, nên hai ô nhập cạnh nhau lệch đúng một dòng chữ. Chừa sẵn hai
     dòng cho MỌI nhãn rồi dán chữ xuống đáy khung ấy thì nhãn dài hay ngắn cũng kết thúc ở
     cùng một độ cao.
     ⚠️ ĐÈ TRONG `.grid-nhap`, không đè `.fld` dùng chung: lớp ấy dựng cả chục form khác, và
        cộng 11px cho mỗi ô ở mọi nơi là sửa một màn, đổi chín màn. */
  .grid-nhap>.fld>label{min-height:24px;display:flex;align-items:flex-end}
  /* ══════════════════════════════════════════════════════════════════════════════════════════
     🔴 DẢI LUỒNG LÀM VIỆC — TRÊN ĐIỆN THOẠI LÀ MỘT HÀNG CUỘN NGANG.
     ══════════════════════════════════════════════════════════════════════════════════════════
     Anh Thắng 22/09/2026 gửi ảnh màn iPhone: *"Với luồng duyệt"*, ngay sau lượt vá form nhập.

     Tám bước ×  `flex-wrap:wrap` trên màn 390px = BỐN HÀNG, chiếm gần nửa màn trước khi thấy
     đơn nào. Và mũi tên `→` giữa hai thẻ rơi xuống ĐẦU hàng sau mỗi lần xuống dòng — một mũi
     tên mồ côi trỏ vào khoảng không, đúng ba lần trong ảnh.

     Một hàng cuộn ngang thì đúng hình dạng của một LUỒNG (trái sang phải), mũi tên luôn nằm
     giữa hai bước, và cả dải chỉ chiếm một hàng.

     ⚠️ KHÔNG BỎ BƯỚC NÀO cho gọn. Dải này là BẢN ĐỒ: nhân viên phải biết đơn của mình sẽ đi
        đâu tiếp. Bỏ mấy bước đang rỗng là luồng trông như chỉ có hai bước. Cuộn thì vẫn còn
        đủ; `veThanhLuong()` tự kéo tới bước đang có đơn để chỗ tắc nằm sẵn trong tầm mắt.

     🔴 VÌ SAO LUẬT NẰM Ở ĐÂY CHỨ KHÔNG PHẢI `style=` TRÊN THẺ: một thuộc tính viết thẳng trên
        thẻ có mức riêng cao hơn MỌI luật trong tệp này, kể cả luật trong `@media`. Để
        `flex-wrap:wrap` ở đó thì media query dưới đây không với tới, và màn hẹp vẫn xuống bốn
        hàng — CÙNG MỘT HỌ LỖI với vụ `.grid-nhap` vừa vá cùng ngày, chỉ khác đường thắng. */
  .luongBar{display:flex;gap:6px;align-items:stretch;flex-wrap:wrap}
  .luongThe{flex:1 1 120px;min-width:112px;padding:9px 8px;display:flex;flex-direction:column;
    align-items:center;gap:3px;border-radius:10px;text-align:center}
  .luongMuiTen{align-self:center;color:#c9c2b8;font-size:13px}
  /* bước của TRANG ĐANG MỞ — tô đặc, chữ trắng (08/10/2026: "bấm tab tính năng, thanh trang trên không nhảy màu theo"). !important vì thẻ mang style= viết thẳng. */
  .luongThe[data-dang]{background:#2545ff !important;border-color:#2545ff !important;box-shadow:0 2px 8px rgba(37,69,255,.28)}
  .luongThe[data-dang] span{color:#fff !important}
  @media(max-width:560px){
    .luongBar{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px}
    .luongThe{flex:0 0 auto;min-width:96px;padding:7px 6px}
    .luongMuiTen{font-size:11px}
  }
  .fld input,.fld select,.fld textarea{width:100%}
  table{width:100%;border-collapse:collapse;min-width:920px}
  thead th{background:#f9f8f6;color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;text-align:left;padding:9px 10px;border-bottom:1px solid #f0e9e1;white-space:nowrap}
  tbody td{padding:8px 10px;border-bottom:1px solid #f4f1ec;font-size:12.5px;vertical-align:middle}
  tbody tr:hover{background:#f9f8f6}
  .tw{overflow-x:auto}
  .money{text-align:right;font-family:Consolas,monospace;white-space:nowrap}
  .pos{color:#166534;font-weight:700}.neg{color:#dc2626;font-weight:700}
  .chip{display:inline-flex;align-items:center;gap:6px;background:#f0fdfa;border:1px solid #99f6e4;color:#2545ff;border-radius:20px;padding:4px 10px;font-size:12px;font-weight:600;margin:3px}
  .chip b{color:#0c1754}.chip span{cursor:pointer;color:#8c8781;font-weight:700}
  .empty{text-align:center;color:#8c8781;padding:26px;font-size:13px}
  #toast{position:fixed;top:14px;right:14px;z-index:2000;display:flex;flex-direction:column;gap:8px}
  .t{background:#fff;border-left:4px solid #2545ff;border-radius:8px;padding:10px 15px;box-shadow:0 6px 20px rgba(0,0,0,.15);font-size:13px;min-width:220px}
  .t.err{border-left-color:#ef4444}.t.warn{border-left-color:#f59e0b}
  #lo{display:none;position:fixed;inset:0;background:rgba(15,23,42,.35);z-index:1500;align-items:center;justify-content:center}
  #lo.show{display:flex}.spin{width:40px;height:40px;border:4px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:sp .8s linear infinite}
  @keyframes sp{to{transform:rotate(360deg)}}
  .hide{display:none}
.csw{position:relative}
/* HỘP CHỌN CƠ SỞ — `fixed`, JS đặt chỗ (`_csDatCho`). 10/10/2026, anh Thắng: "rất khó thao tác với bảng này".
   Hộp cũ `absolute` rộng 260px từ hồi còn MỘT cột; tách hai cột (nhóm | cơ sở) thì cột nhóm ăn 150px, tên cơ sở bị
   bẻ từng chữ, nút Xong rơi ra ngoài khung, và hộp cuộn lồng trong hộp. `absolute` còn bị `.tw` / `.card` (overflow)
   cắt cụt ở hàng cuối mỗi bảng — bảng Admin chỉ một hàng thì hộp gần như không mở nổi. `fixed` thoát cả hai. */
.cs-pop{position:fixed;z-index:9000;left:0;top:0;width:580px;max-width:calc(100vw - 16px);overflow:hidden;background:#fff;border:1px solid #e2d6c7;border-radius:8px;box-shadow:0 12px 30px rgba(15,23,42,.22)}
.cs-pop .cs-than{display:flex;max-height:340px}
.cs-pop .cs-nhom{flex:0 0 200px;max-width:42%;border-right:1px solid #f0e9e1;overflow:auto}
.cs-pop .cs-list{flex:1 1 auto;min-width:0;overflow:auto}
.cs-pop .cs-list label{line-height:1.35}
.cs-pop .cs-nut{display:flex;flex-wrap:wrap;gap:6px;padding:6px 8px;border-bottom:1px solid #f0e9e1}
.cs-pop .cs-nut .btn{padding:6px 12px;font-size:12px}
.cs-pop .cs-nut .b-g{margin-left:auto}
.cs-list label:hover{background:#f4f1ec}

  /* ---------- MÁY TÍNH BẢNG & ĐIỆN THOẠI ---------- */
  @media(max-width:820px){
    body{font-size:13.5px}                                  /* chữ to hơn chút cho dễ đọc */
    .top{padding:12px 12px}
    .top h1{font-size:16px}
    .bar{padding:8px 10px}
    .wrap{padding:12px 10px}
    .ch{padding:10px 12px}
    .cb{padding:12px 12px}
    /* THANH TAB: 14 tab thì trên điện thoại xuống 4-5 dòng, đẩy nội dung tụt hẳn xuống.
       Cho trượt ngang một dòng — quen tay hơn và giữ được chỗ cho nội dung. */
    #tabbar{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
    #tabbar::-webkit-scrollbar{display:none}
    #tabbar .btn{flex:0 0 auto}
    /* Ô nhập cao hơn cho vừa đầu ngón tay */
    select,input,textarea{padding:9px 10px;font-size:13.5px}
    .btn{padding:9px 13px}
    #toast{left:10px;right:10px}
    .t{min-width:0}
  }
  @media(max-width:560px){
    .wrap{padding:10px 8px}
    .ch{padding:10px}
    .cb{padding:10px}
    .ch h2{font-size:13px}
    /* Tiêu đề card và nút của nó xuống dòng riêng, khỏi chen nhau */
    .ch{flex-direction:column;align-items:stretch}
    .ch>div{display:flex;flex-wrap:wrap;gap:6px}
  }
  @media(max-width:420px){
    .top>div:last-child{width:100%;justify-content:flex-end}
    .btn{padding:8px 11px;font-size:12.5px}
  }
  /* Màn rất rộng: cho bảng dùng hết chỗ, khỏi phải trượt ngang vô ích */
  @media(min-width:1700px){
    .wrap{max-width:1800px}
    .top,.bar{padding-left:max(22px, calc((100% - 1800px) / 2));padding-right:max(22px, calc((100% - 1800px) / 2))}
  }

  /* ------------------------------------------------------------------
     TRANG CẤU HÌNH DẠNG XỔ XUỐNG.
     11 thẻ cấu hình mở hết một lượt thì phải cuộn cả màn hình mới thấy
     bảng cần sửa. Gập lại: chỉ mở đúng phần đang khai. Trạng thái gập/mở
     nhớ trong máy người dùng (localStorage) nên mở lại trang vẫn như cũ.
     Bấm vào tiêu đề để gập/mở — các nút Lưu, Thêm… trong tiêu đề vẫn bấm
     bình thường (JS bỏ qua click rơi vào nút/ô nhập). */
  .card.xo > .ch{cursor:pointer;user-select:none}
  .card.xo > .ch h2::before{content:'▾';display:inline-block;width:14px;color:#8c8781;font-size:12px;transition:transform .12s}
  .card.xo.dong > .ch h2::before{transform:rotate(-90deg)}
  .card.xo.dong > .ch{border-bottom:none}
  .card.xo.dong > .ch ~ *{display:none !important}

  /* Cột "Cơ sở" của bảng dòng chi: một đơn = một cơ sở, đã chốt ở đầu form nên lặp lại ở
     từng dòng chỉ ăn chỗ. Ẩn CẢ CỘT bằng lớp này (đầu bảng + mọi dòng cùng lúc) thay vì
     bỏ ô ở dòng — bỏ lệch nhau là cả bảng trượt cột. Đơn cũ còn trộn cơ sở thì JS gỡ lớp
     này ra để cột hiện lại, kèm tô đỏ dòng lệch. */
  #lineTable.anCoso .colCoso{display:none}

  /* NÚT XỔ "DÒNG CŨ HƠN" CỦA LỊCH SỬ CHỈNH ĐƠN.
     🔴 Anh Thắng 28/08/2026: *"bấm nút xổ lịch sử chỉnh đơn, nó xổ ra và không tắt gọn lại
        được"*. <details> vẫn gập được — chỉ là cái mũi tên ▸ mặc định bé đến mức không ai
        đọc nó là một cái nút, nên mở ra rồi thì không còn manh mối nào bảo rằng bấm lại là
        đóng. Đổi hẳn CHỮ theo trạng thái thì không phải đoán nữa. */
  .su-tt .su-dong{display:none}
  details[open] > .su-tt .su-mo{display:none}
  details[open] > .su-tt .su-dong{display:inline}


/* ══════════════════════════════════════════════════════════════════════════════════════════
   RÊ CHUỘT VÀO ẢNH BILL -> PHÓNG TO (anh Thắng 07/09/2026)

   Ảnh chứng từ trong bảng chỉ cao 28-34px — vừa đủ biết CÓ ảnh, không đủ đọc số tiền trên
   bill. Muốn xem thì phải bấm, mở thẻ mới, xem xong đóng lại, mất chỗ đang đứng trong bảng.
   Kế toán soát cả chục dòng một lượt thì đó là cả chục lần mở-đóng.

   🔴 LỚP PHỦ NẰM Ở <body>, KHÔNG NẰM TRONG Ô BẢNG. Bảng có `overflow-x:auto` để cuộn ngang;
      một ảnh phóng to bên trong ô sẽ bị chính khung cuộn ấy CẮT — hiện ra đúng phần nằm lọt
      trong ô, tức là chẳng to hơn bao nhiêu. `position:fixed` ở body thì thoát khỏi mọi
      khung cuộn.

   ⚠️ Không đụng tới thẻ <a>: bấm vẫn mở ảnh gốc ở thẻ mới như cũ. Trên điện thoại không có
      "rê chuột", nên đường bấm ấy vẫn là đường chính. */
#billZoom{
  display:none;position:fixed;z-index:9999;pointer-events:none;
  background:#fff;border:1px solid #e2d6c7;border-radius:10px;padding:4px;
  box-shadow:0 12px 34px rgba(15,23,42,.28)
}
#billZoom img{display:block;max-width:none;border-radius:7px}
/* Ảnh nhỏ trong bảng: cho biết nó rê được. */
[data-bill]{cursor:zoom-in}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   BẤM ẢNH BILL TRÊN MÁY CẢM ỨNG -> LỚP PHỦ NGAY TẠI TRANG (anh Thắng 17/09/2026)

   🔴 Trước đây bấm ảnh là đi tới `<a target="_blank">`. Máy tính mở tab mới nên không sao,
      nhưng app điện thoại KHÔNG CÓ TAB: đó là một lượt rời trang, và quay lại thì đơn đang mở
      biến mất vì nó không nằm trong địa chỉ. Xem `_billTapInit()` trong app.html.

   ⚠️ `position:fixed` + `inset:0` — KHÔNG đặt trong ô bảng. Bảng có `overflow-x:auto`, một
      lớp phủ bên trong nó sẽ bị chính khung cuộn ấy CẮT, đúng lỗi mà `#billZoom` đã ghi.
   ⚠️ z-index 3000 — trên cả cổng PIN (`#gate` 3000) thì thôi, nhưng phải trên `#lo` (1500) và
      toast (2000): mở ảnh mà một cái toast nằm đè lên là bấm đóng trúng toast.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
#billTap{display:none;position:fixed;inset:0;z-index:2900;
  background:rgba(12,23,84,.92);
  align-items:center;justify-content:center;padding:10px;
  -webkit-tap-highlight-color:transparent}
#billTap.hien{display:flex}
/* Ảnh vừa khung, KHÔNG phóng quá cỡ thật: bill chụp bằng điện thoại vốn đã 3000px, kéo to hơn
   chỉ làm nó nhoè. `object-fit:contain` giữ đúng tỉ lệ cho bill dọc. */
#billTap img{max-width:100%;max-height:100%;object-fit:contain;border-radius:8px;
  background:#fff}
/* Nút ✕ chỉ là dấu hiệu — cả tấm màn đều bấm đóng được (xem chú thích ở `dung()`), vì ngón cái
   một tay khó với tới góc trên phải. */
#billTap button{position:absolute;top:calc(10px + env(safe-area-inset-top));right:12px;
  width:40px;height:40px;border:0;border-radius:50%;
  background:rgba(255,255,255,.18);color:#fff;font-size:17px;line-height:1;cursor:pointer}


/* ══════════════════════════════════════════════════════════════════════════════════════════
   DÒNG "CHÌM" TRONG BẢNG CHỜ QUYẾT TOÁN (anh Thắng 07/09/2026)

   Đơn đã cấp tiền mà chưa gửi quyết toán nằm chung bảng với đơn chờ, nhưng phải đọc ra ngay
   là KHÁC LOẠI: nhạt hơn, nền xám, chữ nghiêng ở cột trạng thái. Không làm mờ tới mức khó
   đọc — đây là mấy đơn đang treo tiền, thứ cần nhắc chứ không phải thứ cần giấu. */
tr.qt-chim > td{background:#fafafa;color:#64748b}
tr.qt-chim > td .badge{opacity:.8}

/* Ô GÕ THẲNG TRONG BẢNG DỰ ÁN — anh Thắng 18/09/2026: *"thay vì bấm sửa, thì cho sửa thẳng
   trong từng dòng đơn"*. Ô sửa được phải TRÔNG khác ô chỉ để đọc, không thì người ta không
   biết bấm vào được; nhưng cũng không được viền sẵn như ô nhập, kẻo bảng đọc thành một tờ khai. */
.o-sua{ cursor:text; border-radius:4px; }
.o-sua:hover{ background:#eef2ff; box-shadow:inset 0 0 0 1px #c7d2fe; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   MENU XỔ KHỐI TRÊN TAB DUYỆT — anh Thắng 21/09/2026: *"chỗ duyệt tạm ứng, rê chuột vào nó xổ
   ra bộ phận được không"*, và trước đó 20/09: *"để xem từng trang đơn vị, tránh duyệt lộn đơn
   vị"*.

   🔴 RÊ CHUỘT LÀ THỨ KHÔNG CÓ TRÊN iPHONE. Anh Thắng duyệt đơn bằng điện thoại — đã một lần ba
      hộp thoại nối nhau chết câm trên iOS (xem `#datKyBox`). Nên menu này mở bằng HAI đường:
      rê chuột (chỉ ở máy có chuột thật, `hover:hover`) và BẤM vào mũi ▾ (ở đâu cũng được).
      Chỉ có `:hover` thì trên điện thoại cái mũi ▾ là một nút bấm vào không ra gì.

   ⚠️ Vùng đệm `::before` phía trên hộp là CỐ Ý. Không có nó thì chuột đi từ nút xuống hộp phải
      băng qua một khe hở vài pixel, menu tắt giữa đường, và người ta tưởng nó giật. */
.tabMenu{ position:relative; display:inline-flex; align-items:stretch; gap:0 }
.tabMenu > .btn{ border-top-right-radius:0; border-bottom-right-radius:0 }
.tabMenuNut{
  border:0; cursor:pointer; padding:0 8px; margin-left:1px; font-size:11px; line-height:1;
  background:#e7e2da; color:#57534e; border-radius:0 8px 8px 0;
}
.tabMenuNut:hover{ background:#d6d0c6 }
/* 🔴 `position:fixed`, KHÔNG PHẢI `absolute` — VÀ CHỖ ĐẶT DO JS TÍNH (`_tmDatCho`).
   Trên màn hẹp `#tabbar` mang `overflow-x:auto` để cuộn ngang hàng tab. Mà `overflow-x:auto`
   với `overflow-y:visible` thì trình duyệt tính ra `overflow-y:auto` — tức nó CẮT theo chiều
   dọc luôn. Hộp `absolute` treo trong đó bị xén còn một vạch trắng: trên iPhone menu xổ ra
   mà không đọc được chữ nào. Đã chụp màn hình thấy tận mắt 21/09/2026.

   ⚠️ Kho mã ĐÃ ghi sẵn đúng bài học này hai lần cho lớp phủ trong bảng ("LỚP PHỦ NẰM Ở
      <body>, KHÔNG NẰM TRONG Ô BẢNG… bảng có `overflow-x:auto`"). Lần này đến lượt hàng tab. */
.tabMenuBox{
  display:none; position:fixed; top:0; left:0; z-index:60; min-width:236px;
  padding:6px; background:#fff; border:1px solid #e5e1d8; border-radius:10px;
  box-shadow:0 10px 28px rgba(0,0,0,.14);
}
/* Cầu nối vô hình giữa nút và hộp: chuột đi xuống không rơi qua khe 6px làm menu tắt giữa chừng. */
.tabMenuBox::before{ content:''; position:absolute; left:0; right:0; top:-8px; height:8px }
@media (hover:hover){ .tabMenu:hover .tabMenuBox{ display:block } }
.tabMenu.mo .tabMenuBox{ display:block }
.tabMenuBox .mk{
  display:flex; align-items:center; gap:8px; width:100%; padding:8px 10px; border:0;
  background:transparent; border-radius:8px; cursor:pointer; text-align:left; font-size:13px;
  color:#171417;
}
.tabMenuBox .mk:hover{ background:#f1efe9 }
.tabMenuBox .mk[disabled]{ opacity:.45; cursor:not-allowed }
.tabMenuBox .mk[disabled]:hover{ background:transparent }
.tabMenuBox .mk.dang{ background:#eef2ff; font-weight:700 }
.tabMenuBox .mk .so{ margin-left:auto; font-size:11px; opacity:.7; font-variant-numeric:tabular-nums }

/* ══════════════════════════════════════════════════════════════════════════════════════════
   🔎 Ô TK NỢ CỦA DÒNG — ô gõ số (`.tkGo`) + ô chọn (`.tkSel`) GHÉP MỘT KHỐI bo tròn, viền mảnh, sáng nhẹ khi gõ.
   Anh Thắng 01/10/2026 (ảnh ô gõ cạnh ô chọn 64214): *"Design nó đẹp với mịn màng hơn được không"*.
   ⚠️ Gắn `body` vào bộ chọn cho đủ nặng: `td input` / `body.gd-moi input:focus` bên trên nặng hơn bộ chọn một lớp.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
body input.tkGo{
  display:block; box-sizing:border-box; width:124px; margin:5px 0 0; padding:5px 8px 5px 25px;
  font:500 11.5px/1.25 Consolas,Menlo,monospace; color:#1e293b; letter-spacing:.2px;
  background:#f6f8fb url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") 8px 50%/12px no-repeat;
  border:1px solid #dbe1ea; border-bottom-color:#e8ecf2; border-radius:10px 10px 0 0; box-shadow:none; outline:0;
  transition:background-color .18s ease, border-color .18s ease, box-shadow .18s ease;
}
body input.tkGo::placeholder{ color:#a3adbd; font:500 11.5px/1.25 system-ui,-apple-system,'Segoe UI',Roboto,sans-serif; letter-spacing:0 }
body input.tkGo:hover{ background-color:#fff }
body input.tkGo.tkGo:focus{ background-color:#fff; border-color:#9dbcf0; box-shadow:0 0 0 3px rgba(59,130,246,.12) }
body input.tkGo.khong{ border-color:#f5b4b4; background-color:#fff7f7 }
body select.tkSel{
  display:block; box-sizing:border-box; width:124px; margin:0; padding:5px 8px;
  font:600 11.5px/1.25 Consolas,Menlo,monospace; color:#1e3a8a; background-color:#fff;
  border:1px solid #dbe1ea; border-top:0; border-radius:0 0 10px 10px; box-shadow:0 1px 2px rgba(15,23,42,.04); outline:0;
  transition:border-color .18s ease, box-shadow .18s ease; cursor:pointer;
}
body select.tkSel.tkSel:focus{ border-color:#9dbcf0; box-shadow:0 0 0 3px rgba(59,130,246,.12) }
body input.tkGo:focus + select.tkSel{ border-color:#9dbcf0 }
/* đang lọc: ô chọn mở thành danh sách — đổ bóng nhẹ cho nổi khỏi bảng */
body select.tkSel[size]:not([size="0"]):not([size="1"]){ position:relative; z-index:5; box-shadow:0 10px 24px rgba(15,23,42,.14); padding:3px 4px }
body select.tkSel option{ padding:3px 6px; border-radius:6px }
body select.tkSel optgroup{ font:700 10.5px/1.6 system-ui,-apple-system,'Segoe UI',sans-serif; color:#64748b }
body select.tkSel optgroup option{ font:600 11.5px/1.5 Consolas,Menlo,monospace; color:#1e3a8a }
body select.tkSel > option{ font:500 11.5px/1.5 system-ui,-apple-system,'Segoe UI',Roboto,sans-serif; color:#475569 }
body select.tkSel option:checked{ background:#e0eaff; color:#1e3a8a }
/* 🏦 ô TK Có đứng riêng dưới khối TK Nợ (12/10/2026) — bo đủ bốn góc, chữ xanh lá cho khác vế Nợ */
body select.tkSel.tkCoSel{ margin-top:4px; border-top:1px solid #dbe1ea; border-radius:10px; color:#166534; font:600 11px/1.25 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif; padding:5px 6px }
/* menu ▾ xổ khối, khi mở SANG PHẢI thanh menu trái (giao diện mới) — cầu nối nằm bên TRÁI hộp, không phải bên trên */
.tabMenuBox.phai::before{ left:-8px; right:auto; top:0; bottom:0; width:8px; height:auto }

/* 🗂 Hàng tab khối đầu trang Duyệt tạm ứng (08/10/2026 — "chia 3 bảng ra dạng 3 tab") */
.duyetTabKhoi{display:flex;gap:4px;border-bottom:2px solid #e2d6c7;margin:0 0 12px;overflow-x:auto}
.duyetTabKhoi .dvTab{border:1px solid #e2d6c7;border-bottom:none;background:#f9f8f6;color:#4b4642;padding:9px 18px;border-radius:10px 10px 0 0;font-weight:600;font-size:14px;cursor:pointer;margin-bottom:-2px;white-space:nowrap}
.duyetTabKhoi .dvTab.dang{background:#fff;color:#2545ff;border-color:#2545ff;border-bottom:2px solid #fff;font-weight:800}
.duyetTabKhoi .dvTab[disabled]{opacity:.45;cursor:not-allowed}
.duyetTabKhoi .dvTabSo{display:inline-block;min-width:20px;padding:1px 6px;margin-left:4px;border-radius:10px;background:#fde68a;color:#7c4a03;font-size:11px;font-weight:700}
.duyetTabKhoi .dvTab.rong:not(.dang){opacity:.65}

/* 🔔 Bảng tin nổi "có đơn mới cho kế toán" (09/10/2026 — `_moiBangTin`) */
.moiBt{position:fixed;inset:0;z-index:2100;background:rgba(15,23,42,.45);display:flex;align-items:center;justify-content:center;padding:16px;animation:moiBtNen .2s ease-out}
.moiBtHop{background:#fff;border-radius:16px;width:min(560px,100%);max-height:86vh;display:flex;flex-direction:column;box-shadow:0 24px 60px rgba(15,23,42,.35);border:2px solid #fde68a;animation:moiBtNoi .35s cubic-bezier(.2,1.4,.4,1)}
.moiBtDau{display:flex;gap:12px;align-items:flex-start;padding:18px 18px 12px;border-bottom:1px solid #f1ede7}
.moiBtChuong{font-size:30px;line-height:1;animation:moiBtLac 1s ease-in-out 2}
.moiBtTen{font-size:18px;font-weight:700;color:#171417}
.moiBtTen b{color:#2545ff}
.moiBtPhu{font-size:12.5px;color:#64748b;margin-top:3px}
.moiBtDong{margin-left:auto;border:none;background:#f4f1ec;border-radius:999px;width:32px;height:32px;cursor:pointer;font-size:14px;flex:0 0 auto}
.moiBtDs{overflow:auto;padding:6px 18px}
.moiBtDong1{display:flex;gap:10px;align-items:center;padding:10px 0;border-bottom:1px dashed #eee6dc}
.moiBtDong1>div:first-child{flex:1}
.moiBtNhan{font-size:13.5px;font-weight:600;color:#171417}
.moiBtChi{font-size:12px;color:#8c8781;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.moiBtTien{font-size:13px;font-weight:700;font-family:Consolas,monospace;white-space:nowrap}
.moiBtThem{font-size:12px;color:#8c8781;padding:8px 0}
.moiBtChan{display:flex;gap:8px;justify-content:flex-end;padding:12px 18px 16px}
.moiKtNhay{animation:moiKtNhay 1.2s ease-in-out 2}
@keyframes moiBtNen{from{opacity:0}to{opacity:1}}
@keyframes moiBtNoi{from{opacity:0;transform:translateY(24px) scale(.92)}to{opacity:1;transform:none}}
@keyframes moiBtLac{0%,100%{transform:rotate(0)}20%{transform:rotate(-18deg)}40%{transform:rotate(14deg)}60%{transform:rotate(-8deg)}80%{transform:rotate(4deg)}}
@keyframes moiKtNhay{0%,100%{box-shadow:0 0 0 0 rgba(250,204,21,0)}50%{box-shadow:0 0 0 6px rgba(250,204,21,.55)}}
@media(max-width:560px){.moiBtDong1{flex-wrap:wrap}.moiBtChi{white-space:normal}}
@media(prefers-reduced-motion:reduce){.moiBt,.moiBtHop,.moiBtChuong,.moiKtNhay{animation:none}}
