/* GENERATED FILE — KHÔNG SỬA TRỰC TIẾP.
   Nguồn: styles/manifest.json · SHA-256 4cd2f4b10c2a7c5312a53dd03fb70c602686c084b253d2e7b44e7261bb2e54fd
   Tạo lại bằng: npm run build:styles */

/* ===== SOURCE: styles/foundation.css ===== */
/* ============================================================
   VLXD THANH HIỀN — phần mềm bán hàng
   Bảng màu: xanh da trời (chủ đạo) · cam sáng (điểm nhấn) · trắng
   ============================================================ */

:root{
  /* XÁM THAN trung tính (b105 — chủ tiệm chọn 05/08/2026):
     nền lùi lại để màu CAM một mình nổi bật. Tên biến giữ nguyên --sky-*
     cho đỡ phải sửa hàng trăm chỗ — hiểu là "thang màu chủ đạo". */
  --sky-900:#181B20;
  --sky-800:#22262E;
  --sky-700:#2E333D;
  --sky-600:#3B424F;
  --sky-500:#4E5766;
  --sky-400:#8791A0;
  --sky-300:#BBC2CC;
  --sky-100:#E7EAEE;
  --sky-50:#F4F5F7;
  /* cam sáng — CHỈ cho hành động chính và số cần chú ý */
  --or:#F97316;
  --or-6:#EA6A0B;
  --or-7:#C25706;
  --or-safe:#A94704;
  --or-safe-hover:#873801;
  --or-50:#FFF2E4;
  /* trung tính */
  --ink:#1B1E24;
  --ink-2:#2C313A;
  --slate:#61697A;
  --slate-2:#61697A;
  --line:#D8DCE2;
  --line-2:#EBEDF1;
  --paper:#FFFFFF;
  --bg:#ECEEF1;
  --green:#0C7A57;
  --green-soft:#E1F4ED;
  --red:#C6342A;
  --red-soft:#FCEBE9;

  --r:8px;
  --r-lg:12px;
  --r-sm:6px;
  --shadow:0 1px 2px rgba(24,27,32,.05), 0 2px 8px rgba(24,27,32,.05);
  --shadow-md:0 2px 6px rgba(24,27,32,.07), 0 8px 24px rgba(24,27,32,.08);
  --shadow-lg:0 12px 48px rgba(24,27,32,.24);

  /* Nhịp giao diện b157: một nguồn duy nhất cho khoảng cách, chiều cao điều
     khiển và chuyển động. Giữ nguyên hệ font và thang chữ của app cũ. */
  --space-1:4px;
  --space-2:8px;
  --space-3:12px;
  --space-4:16px;
  --space-5:24px;
  --control-h:40px;
  --motion-fast:120ms;
  --motion-base:180ms;
  --focus-ring:0 0 0 3px rgba(249,115,22,.2);

  --f-ui:"Be Vietnam Pro", ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  --f-mono:"TH Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  /* b225 · font cho SỐ. Cùng bộ với --f-mono (mỗi chữ số một bề ngang nên
     số thẳng cột), nhưng số 0 KHÔNG có dấu chấm ở giữa — anh Đạt soi phiếu
     bán thấy chấm giữa số 0 rối mắt. Xem fonts/TH-MONO-GHI-CHU.txt. */
  --f-num:var(--f-mono);

  --rail:92px;
  --head:56px;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; font-family:var(--f-ui); background:var(--bg); color:var(--ink);
  font-size:14px; line-height:1.45; -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale; overflow:hidden;
  font-feature-settings:"cv05","ss01";
}

button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
input,select,textarea{
  background:var(--paper); border:1px solid var(--line); border-radius:var(--r);
  padding:8px 10px; width:100%; outline:none; transition:border-color .12s, box-shadow .12s;
}
input:focus,select:focus,textarea:focus{border-color:var(--sky-500);box-shadow:0 0 0 3px var(--sky-100)}
input[readonly]{background:var(--sky-50);color:var(--slate)}
:focus-visible{outline:2.5px solid var(--or);outline-offset:2px;border-radius:4px}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline-offset:0}
button:focus-visible,a:focus-visible,[tabindex]:focus-visible{box-shadow:var(--focus-ring)}
.num{font-variant-numeric:tabular-nums;font-family:var(--f-mono)}
.mut{color:var(--slate)}

/* ---------- đăng nhập & tài khoản (b154) ----------
   Giữ nguyên hệ font cũ: tất cả thành phần kế thừa --f-ui/--f-mono. */
.authgate{
  position:fixed;inset:0;z-index:10000;display:grid;place-items:center;padding:20px;
  background:radial-gradient(circle at 50% 15%,#3B424F 0,#22262E 42%,#181B20 100%);
}
.authgate[hidden]{display:none}
.auth-card{width:min(410px,100%);background:var(--paper);border:1px solid rgba(255,255,255,.15);
  border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:28px}
.auth-logo{width:52px;height:52px;margin:0 auto 10px;border-radius:12px;background:var(--or);
  color:#fff;display:grid;place-items:center}
.auth-logo svg{width:30px;height:30px}
.auth-title{text-align:center;font-size:24px;font-weight:800;letter-spacing:-.3px}
.auth-sub{text-align:center;color:var(--slate);font-size:12.5px;margin:2px 0 22px}
.auth-card form{display:grid;gap:12px}
.auth-go{width:100%;height:42px;margin-top:2px}
.auth-err{padding:9px 11px;border-radius:var(--r-sm);background:var(--red-soft);color:var(--red);
  font-size:12.5px;font-weight:600}
.auth-err[hidden]{display:none}
.auth-first{margin-top:16px;padding-top:14px;border-top:1px solid var(--line-2);color:var(--slate);
  font-size:11.5px;line-height:1.65;text-align:center}
.auth-who{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:12px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--sky-50)}
.auth-who>span:not(.tag){color:var(--slate);font-size:12px}
.auth-actions{display:grid;gap:8px;margin-top:14px}
.auth-actions .btn{justify-content:center}
.auth-table .mut{font-size:11.5px;margin-top:2px}
.auth-user-chip{display:flex;align-items:center;gap:6px;max-width:180px}
.auth-user-chip span{max-width:112px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body.auth-locked>.app{filter:blur(2px);pointer-events:none;user-select:none}

/* ---------- khung ---------- */
.app{display:grid;grid-template-columns:var(--rail) 1fr;height:100vh}

.rail{
  background:linear-gradient(180deg,#2E333D 0%,#1F232B 100%);
  display:flex; flex-direction:column; padding:10px 8px 8px; gap:1px; overflow-y:auto;
  box-shadow:inset -1px 0 0 rgba(255,255,255,.06);
}
.rail::-webkit-scrollbar{width:0}
.brand{
  display:flex;flex-direction:column;align-items:center;gap:7px;
  padding:8px 4px 16px; color:#fff;
}
.brand-mark{
  width:40px;height:40px;border-radius:11px;background:#fff;
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:16px;
  letter-spacing:-.4px;box-shadow:0 3px 10px rgba(0,0,0,.22);
}
.brand-mark.logo{padding:4px}
.brand-mark svg{width:100%;height:100%;display:block}
.brand-name{
  font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:#fff;text-align:center;line-height:1.4;
}
.brand-name .brand-sub{
  font-size:8.5px;font-weight:600;letter-spacing:.1em;color:var(--sky-300);
}

.navbtn{
  position:relative;display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:10px 4px;border-radius:var(--r);color:#9AA3B2;
  font-size:10.5px;font-weight:600;text-align:center;line-height:1.25;letter-spacing:.01em;
  transition:background .12s,color .12s;
}
.navbtn svg{width:20px;height:20px;stroke-width:1.75;opacity:.92}
.navbtn:hover{background:rgba(255,255,255,.07);color:#fff}
.navbtn.on{background:rgba(255,255,255,.12);color:#fff}
.navbtn.on svg{opacity:1}
.navbtn.on::before{
  content:'';position:absolute;left:-8px;top:10px;bottom:10px;width:3px;border-radius:0 3px 3px 0;
  background:var(--or);
}
.rail-sp{flex:1}
.rail-line{height:1px;background:var(--sky-600);margin:6px 14px 4px}
.rail-ft{
  color:#8B95A6;font-size:9.5px;text-align:center;padding:8px 2px 2px;
  letter-spacing:.06em;line-height:1.4;
}

.main{display:flex;flex-direction:column;min-width:0;overflow:hidden}
.head{
  height:var(--head);flex:0 0 var(--head);background:var(--paper);
  border-bottom:1px solid var(--line);display:flex;align-items:center;
  gap:10px;padding:0 16px;
}
.head h1{margin:0;font-size:16px;font-weight:750;letter-spacing:-.35px;white-space:nowrap;line-height:1.2}
.head .sub{font-size:11.5px;color:var(--slate);font-weight:500;white-space:nowrap;line-height:1.2}
/* Đầu màn Bán hàng (anh Đạt chốt 03/09): tên màn và số hóa đơn cùng độ cao
   chữ, không cái nào bị đẩy lên. Tên tiệm là thông tin PHỤ — chữ thường,
   nhạt, tách bằng một vạch đứng chứ không dính thành một chuỗi nặng. */
.pos-head-invoice{display:inline-flex;align-items:baseline;gap:9px;padding-left:2px}
.pos-head-invoice b{font-family:var(--f-mono);font-size:13px;color:var(--ink-2);font-weight:700;letter-spacing:-.01em}
.pos-head-shop{font-style:normal;font-size:11px;font-weight:500;color:var(--slate-2);letter-spacing:.01em;
  padding-left:9px;border-left:1px solid var(--line-2)}
.head-sp{flex:1}
@media (max-width:1240px){.pos-head-shop{display:none}}
.pill{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:100px;
  font-size:11.5px;font-weight:600;background:var(--sky-50);color:var(--sky-700);
  white-space:nowrap;
}
.pill .dot{width:7px;height:7px;border-radius:50%;background:var(--green)}
.pill.or{background:var(--or-50);color:var(--or-7)}
.pill.or .dot{background:var(--or)}
.pill.warn{background:var(--red-soft);color:var(--red)}
.pill.warn .dot{background:var(--red)}

.view{flex:1;overflow:auto;padding:18px}
.view.pos{padding:0;overflow:hidden}

/* ---------- nút ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-height:var(--control-h);padding:9px 15px;border-radius:var(--r);font-weight:600;font-size:13.5px;
  background:var(--paper);border:1px solid var(--line);color:var(--ink);
  white-space:nowrap;transition:background .08s ease-out,border-color .08s ease-out;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.btn:hover{background:var(--sky-50);border-color:var(--sky-300)}
.btn:active{transform:translateY(1px)}
.btn svg{width:16px;height:16px;stroke-width:2}
.btn.pri{background:var(--sky-600);border-color:var(--sky-600);color:#fff}
.btn.pri:hover{background:var(--sky-700);border-color:var(--sky-700)}
.btn.acc{
  background:var(--or);border-color:var(--or);color:#fff;
  box-shadow:0 1px 2px rgba(194,87,6,.2);
}
.btn.acc:hover{background:var(--or-6);border-color:var(--or-6)}
.btn.ink{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
.btn.ink:hover{background:var(--sky-800)}
.btn.dg{color:var(--red);border-color:#EDD3D0}
.btn.dg:hover{background:var(--red-soft);border-color:#E3B9B4}
.btn.sm{min-height:34px;padding:6px 11px;font-size:12.5px}
.btn.big{padding:13px 20px;font-size:15px;font-weight:700;width:100%;letter-spacing:.01em}
.btn[disabled]{opacity:1;cursor:not-allowed;box-shadow:none;background:#F1F3F5;
  border-color:#DEE1E6;color:#9097A2}
.btn.pri[disabled]{background:#D9DDE2;border-color:#D9DDE2;color:#7D858F}
.btn.acc[disabled]{background:#F6E7DA;border-color:#EED8C5;color:#A47D64}
.btn[disabled]:hover{background:#F1F3F5;border-color:#DEE1E6;color:#9097A2}
.btn.pri[disabled]:hover{background:#D9DDE2;border-color:#D9DDE2;color:#7D858F}
.btn.acc[disabled]:hover{background:#F6E7DA;border-color:#EED8C5;color:#A47D64}
.btn[disabled]:active{transform:none}

/* Một hành động chính, các công cụ ít dùng nằm trong menu theo ngữ cảnh. */
.head-actions{position:relative;z-index:12}
.head-actions>summary{list-style:none;cursor:pointer}
.head-actions>summary::-webkit-details-marker{display:none}
.head-actions[open]>summary{background:var(--sky-50);border-color:var(--sky-300)}
.head-actions-menu{
  position:absolute;right:0;top:calc(100% + 8px);width:300px;padding:6px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-md);display:grid;gap:2px
}
.head-actions-menu button{display:flex;align-items:center;gap:10px;width:100%;padding:10px;
  border-radius:var(--r);text-align:left;color:var(--ink)}
.head-actions-menu button:hover{background:var(--sky-50)}
.head-actions-menu button>svg{width:18px;height:18px;flex:0 0 auto;color:var(--slate)}
.head-actions-menu button>span{display:flex;flex-direction:column;min-width:0}
.head-actions-menu strong{font-size:13px;font-weight:700}
.head-actions-menu small{font-size:11px;color:var(--slate);margin-top:1px}
/* Nút icon 33px -> 40px cho đạt vùng bấm (sổ tay mục 1, đồng bộ .icobtn.lg b130).
   RIÊNG nút bỏ dòng trong phiếu (.item .xoa, b229) 26px (cỡ lớn 28px): nó nằm ở đầu
   dòng, ngang dòng đầu của tên — to hơn là dòng hàng cao thêm, vỡ chuẩn b107. */
.icobtn{
  width:40px;height:40px;border-radius:var(--r);display:grid;place-items:center;
  color:var(--slate);transition:background .12s,color .12s;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.icobtn svg{width:18px;height:18px}
.icobtn:hover{background:var(--sky-100);color:var(--sky-700)}
.icobtn svg{width:18px;height:18px;stroke-width:2}
.icobtn.xl{width:33px;height:33px}
.icobtn.xl svg{width:16px;height:16px}
.icobtn.dg:hover{background:var(--red-soft);color:var(--red)}

/* ===== SOURCE: styles/pos.css ===== */
/* ---------- màn bán hàng ---------- */
/* Bố cục màn Bán hàng:
   tab hóa đơn trên cùng · thanh quét · phiếu bán hàng ở giữa · bán chạy bên phải
   Kết quả tìm chỉ bung ra khi gõ/nói, không chiếm chỗ thường trực. */
/* Bố cục màn Bán hàng: hàng hóa bên trái · phiếu bán hàng bên phải, cả hai cùng nhìn thấy.
   Cột trái là một vùng cuộn: gõ tìm thì kết quả chèn lên trên, hàng bán chạy tụt xuống. */
.pos3{display:grid;grid-template-columns:minmax(0,1fr) 440px;gap:18px;height:100%;min-height:0;padding:12px 14px 14px}
.pos3-main{display:flex;flex-direction:column;min-width:0;min-height:0;gap:10px;overflow:hidden}
/* Khu trên cuộn được (hàng trong kho / kết quả tìm),
   dải Hàng bán chạy ghim cứng ở đáy — không xê dịch khi tìm hàng. */
.pane{flex:1;min-height:0;display:flex;flex-direction:column;contain:layout paint;
  padding:9px 10px 10px;background:#EEF3F7;border:1px solid #C8D4DC;border-radius:var(--r-lg)}
.results{overflow:auto;min-height:0;padding-right:2px}
.results::-webkit-scrollbar{width:8px}
.results::-webkit-scrollbar-thumb{background:var(--line);border-radius:8px}
.tabsbar:empty{display:none}
.results[hidden]{display:none}
.results,.quick{display:block}

.scanner{
  background:var(--paper);border:1.5px solid var(--sky-600);
  border-radius:var(--r-lg);padding:11px 14px;
  display:flex;align-items:center;gap:12px;box-shadow:0 2px 12px rgba(24,27,32,.08);
  transition:border-color .12s, box-shadow .12s;
}
.led{
  width:9px;height:9px;border-radius:50%;background:#42D39B;flex:0 0 auto;
  box-shadow:0 0 0 3px rgba(66,211,155,.22);animation:pulse 2.2s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.led{animation:none}}
.scan-field{flex:1;min-width:0}
.scan-field label{
  display:block;font-size:10.5px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--slate-2);margin-bottom:3px;
}
.scan-field input{
  background:transparent;border:0;padding:0;color:var(--ink);font-family:var(--f-mono);
  font-size:19px;font-weight:700;letter-spacing:.04em;
}
.scan-field input:focus{box-shadow:none}
/* Ô quét lúc nào cũng đang chờ gõ — vẽ khung cam quanh input thành cái hộp thô.
   Bỏ khung ở riêng ô này; thay bằng cả THANH QUÉT sáng nhẹ lên khi có con trỏ. */
#scan:focus-visible{outline:none}
.scanner:focus-within{border-color:var(--ink-2);box-shadow:0 0 0 3px rgba(59,66,79,.14), 0 2px 12px rgba(24,27,32,.08)}
.scan-field input::placeholder{color:var(--slate);font-weight:400;letter-spacing:0}
.scan-cam{
  width:40px;height:40px;border-radius:var(--r);background:var(--sky-50);border:1px solid var(--line);
  display:grid;place-items:center;color:var(--sky-700);flex:0 0 auto;transition:background .12s,color .12s;
}
.scan-cam:hover{background:var(--or);border-color:var(--or);color:#fff}
.scan-cam svg{width:19px;height:19px;stroke-width:1.8}

/* thẻ sản phẩm */

.grid-p>.pcard{content-visibility:auto;contain-intrinsic-size:118px}

/* khóa cứng 3 cột — màn rộng thì thẻ TO ra chứ không đẻ thêm cột (chủ tiệm chốt) */
.grid-p{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.pcard{
  background:var(--paper);border:1.5px solid #173247;border-radius:var(--r-lg);
  padding:11px 13px;text-align:left;display:flex;flex-direction:column;gap:4px;
  min-height:104px;
  transition:border-color .08s ease-out, background-color .08s ease-out;
  position:relative;overflow:hidden;
  contain:layout style paint;              /* trình duyệt khỏi tính lại cả trang */
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;               /* bỏ 300ms chờ bấm đúp trên cảm ứng */
}
.pcard{box-shadow:0 1px 3px rgba(7,31,49,.10)}
.pcard:hover{border-color:#071F31;background:#F5FAFD;box-shadow:0 3px 10px rgba(7,31,49,.13)}
/* kết quả khớp nhất: viền cam + nhãn góc — chỉ dán cho ĐÚNG MỘT thẻ đầu khi khớp đủ chữ */
.pcard.best{border:2px solid var(--or);padding:11px 12px}
.pcard.best:hover{background:var(--or-50)}
/* dấu tích cam nhỏ ở góc — không che tên hàng (tên chừa sẵn chỗ bên phải) */
.best-tick{position:absolute;top:6px;right:6px;width:20px;height:20px;border-radius:50%;
  background:var(--or);color:#fff;display:grid;place-items:center}
.best-tick svg{width:12px;height:12px;stroke-width:3}
.pcard.best .pn{padding-right:24px}
.res-more{text-align:center;font-size:12px;color:var(--slate);padding:10px 0 4px}
.res-more b{color:var(--ink-2)}
.pcard:active,.pcard.tapped{border-color:var(--or);background:var(--or-50)}
.pcard .pn{
  font-weight:700;font-size:15px;line-height:1.3;color:var(--ink);padding-right:46px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
.pcard .pmeta{font-size:11.5px;color:var(--slate);font-family:var(--f-mono);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pcard.wide{min-height:126px}
.pcard .pwhole{
  font-size:11px;color:var(--sky-700);background:var(--sky-50);
  border-radius:5px;padding:3px 6px;line-height:1.35;
}
.pcard .pwhole b{font-family:var(--f-mono);font-size:11.5px}
.pcard .pwhole .mut{font-size:10px}
.plv{
  font-size:10px;font-weight:700;padding:1px 5px;border-radius:4px;margin-left:5px;
  background:var(--sky-100);color:var(--sky-700);vertical-align:1px;
}
.pcard .prow{display:flex;align-items:baseline;gap:6px;margin-top:auto;padding-right:51px}
.pcard .pp{font-weight:800;font-size:17px;color:var(--ink);font-family:var(--f-mono);letter-spacing:-.02em}
.pcard .pu{font-size:12px;color:var(--slate);font-weight:500}
.stk{
  position:absolute;right:9px;top:8px;font-size:11px;font-weight:800;padding:3px 7px;border-radius:999px;
  background:var(--green-soft);color:var(--green);font-family:var(--f-mono)
}
.pcard.best .stk{top:34px}
.stk.low{background:var(--or-50);color:var(--or-safe)}
.stk.zero{background:var(--red-soft);color:var(--red)}

/* b183 · Dải danh mục ở quầy (anh Đạt chốt 03/09): không tiêu đề, không khung
   bao, không nút Quản lý. Chỉ còn những ô LỚN tô đặc màu xanh than — khác hẳn
   thẻ hàng màu trắng bên trên nên nhìn một cái là biết đâu là bộ lọc, đâu là
   hàng. Ô đang chọn đổi sang cam, chữ đen (6,35:1). */
.pos-quick{flex:0 0 auto;padding:0;background:transparent;border:0}
.pos-quick[hidden]{display:none}
.res-sp{flex:1}
/* Máy tính: ô xuống dòng thay vì trốn sang phải — cuộn ngang bằng chuột khó, mà ô bị cắt nửa thì không ai bấm. */
.pos-qcats{display:flex;flex-wrap:wrap;gap:var(--space-3);padding:2px 2px 4px}
.pos-qcat{flex:1 1 150px;min-width:0;min-height:64px;display:flex;flex-direction:column;justify-content:center;gap:2px;
  padding:var(--space-2) var(--space-4);text-align:left;background:#173247;border:2px solid #173247;border-radius:var(--r-lg);color:#fff;
  transition:background-color var(--motion-fast),border-color var(--motion-fast),transform var(--motion-fast)}
.pos-qcat:hover{background:#071F31;border-color:#071F31}
.pos-qcat:active{transform:scale(.98)}
.pos-qcat.on{background:var(--or);border-color:var(--or-6);color:var(--ink)}
.pos-qcat.on:hover{background:var(--or-6)}
.pos-qcat strong,.pos-qcat small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pos-qcat strong{font-size:16px;font-weight:700;line-height:1.25}
.pos-qcat small{font-size:12.5px;font-weight:400}

/* Trình quản lý danh mục: chỉ sửa bản nháp. posQuickSave mới ghi cấu hình. */
.posq-manager{display:grid;grid-template-columns:290px minmax(0,1fr);gap:14px;min-height:430px}
.posq-side,.posq-edit{min-width:0;border:1px solid var(--line);border-radius:var(--r);padding:10px;background:var(--bg)}
.posq-side{display:flex;flex-direction:column;gap:9px}.posq-side-hd{display:flex;justify-content:space-between;color:var(--slate);font-size:11px}
.posq-catlist{display:flex;flex-direction:column;gap:6px;overflow:auto;max-height:340px}
.posq-note{margin:0 0 var(--space-3);font-size:12.5px;color:var(--slate)}
.posq-catrow{display:grid;grid-template-columns:minmax(0,1fr) 40px 30px 30px 30px;gap:4px;align-items:center;padding:3px;border:1px solid transparent;border-radius:8px}
.posq-catrow.off .posq-catpick strong{color:var(--slate);text-decoration:line-through}
/* công tắc bật/tắt danh mục — xanh than = đang hiện ở quầy */
.posq-toggle{width:36px;height:20px;border-radius:999px;background:#AEBFCB;border:0;position:relative;justify-self:center;
  transition:background-color var(--motion-fast)}
.posq-toggle i{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:left var(--motion-fast)}
.posq-toggle.on{background:#173247}.posq-toggle.on i{left:18px}
.posq-catrow.on{border-color:#173247;background:#EAF3F8}.posq-catpick{text-align:left;min-width:0;padding:5px}
.posq-catpick strong,.posq-catpick small{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.posq-catpick strong{font-size:12px}.posq-catpick small{font-size:10px;color:var(--slate)}
.posq-edit{background:#fff}.posq-picked{display:flex;justify-content:space-between;align-items:center;gap:var(--space-2);flex-wrap:wrap;font-size:11px;color:var(--slate);margin:7px 0}
.posq-picked-act{display:flex;gap:var(--space-3)}.posq-picked-act .text-action{font-size:12px}.posq-picked-act .text-action.dgr{color:var(--red)}
.posq-products{display:grid;grid-template-columns:1fr 1fr;gap:7px;max-height:326px;overflow:auto;padding-right:3px}
.posq-product{display:grid;grid-template-columns:24px minmax(0,1fr);align-items:center;gap:7px;text-align:left;
  padding:8px;border:1px solid var(--line);border-radius:8px;background:#fff}
.posq-product.on{border-color:#173247;background:#EAF3F8}.posq-check{width:20px;height:20px;display:grid;place-items:center;
  border:1px solid #9EB1BE;border-radius:5px;color:#fff;background:#fff;font-weight:800}
.posq-product.on .posq-check{background:#173247;border-color:#173247}
.posq-product strong,.posq-product small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.posq-product strong{font-size:11.5px}.posq-product small{font-size:9.5px;color:var(--slate)}
.posq-none,.posq-empty{padding:20px;text-align:center;color:var(--slate);font-size:12px}.posq-products>.posq-none{grid-column:1/-1;padding:8px 4px 10px;text-align:left}.posq-empty{display:grid;place-content:center;gap:5px;height:100%}

/* Một popup duy nhất, không nhận chuột, nên rê ảnh không bao giờ cướp cú bấm
   của thẻ sản phẩm. JavaScript tự đặt nó bên trái khi bên phải là phiếu. */
.pos-img-preview{position:fixed;z-index:120;width:270px;pointer-events:none;filter:drop-shadow(0 12px 25px rgba(7,31,49,.24))}
.pos-img-preview[hidden]{display:none}.pos-img-frame{padding:10px;background:#fff;border:2px solid #173247;border-radius:12px}
.pos-img-frame img{display:block;width:246px;height:222px;object-fit:contain;background:#F7FAFC;border-radius:8px}
.pos-img-frame strong,.pos-img-frame small,.pos-img-frame b{display:block;margin-top:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pos-img-frame strong{font-size:14px;color:var(--ink)}.pos-img-frame small{font-size:11px;color:var(--slate)}
.pos-img-frame b{font-size:16px;color:#173247}

/* ---------- hóa đơn đang bán ---------- */
.tape-col{position:relative;display:grid;grid-template-rows:1fr;min-height:0;min-width:0;overflow:hidden}
/* Khung phiếu dùng lưới 3 hàng: đầu phiếu · danh sách hàng (co giãn) · phần
   thanh toán. Phần thanh toán luôn dính đáy, không bao giờ bị đẩy khỏi màn hình. */
.tape{
  background:var(--paper);display:grid;grid-template-rows:auto 1fr auto;min-height:0;
  position:relative;border-radius:8px;overflow:hidden;
  /* Tách hẳn khỏi khu giữa: viền xanh đậm + bóng đổ sâu.
     Trước đây nền #F4F5F7 và phiếu #FFFFFF chỉ chênh 1,07 lần — mắt không tách được. */
  border:2px solid var(--sky-600);
  box-shadow:0 4px 16px rgba(8,51,79,.14), 0 1px 3px rgba(8,51,79,.10);
}

/* Thanh tiêu đề phiếu — dải màu đậm để nhận ra ngay đây là phiếu bán hàng */
.tape-bar{
  background:linear-gradient(135deg,#3B424F,#22262E);
  color:#fff;padding:9px 16px;margin:0 -16px;display:flex;align-items:center;justify-content:space-between;gap:10px;
}
.tape-bar .tt{
  font-size:12px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  display:flex;align-items:center;gap:7px;white-space:nowrap;
}
.tape-bar .tt svg{width:15px;height:15px;opacity:.85}
.tape-bar .no{
  font-family:var(--f-mono);font-size:12.5px;font-weight:700;color:#AEB6C2;white-space:nowrap;
}
.tape-no{display:flex;flex-direction:column;align-items:flex-end;gap:2px;line-height:1}
.tape-date{font-family:var(--f-mono);font-size:9.5px;font-weight:500;letter-spacing:.02em;color:#AEB6C2;white-space:nowrap}

.zig{height:7px;flex:0 0 7px;background-color:transparent;
  background-image:
    linear-gradient(45deg, var(--paper) 50%, transparent 50%),
    linear-gradient(-45deg, var(--paper) 50%, transparent 50%);
  background-size:10px 7px;background-repeat:repeat-x;
}
.zig.top{transform:rotate(180deg)}
/* 4 hàng: thanh tiêu đề / đầu phiếu / danh sách hàng / thanh toán.
   Đệm ngang đặt ở khung; phần nào cần tràn hết bề ngang thì kéo margin âm ra. */
.tape-in{display:grid;grid-template-rows:auto auto 1fr auto;min-height:0;min-width:0;overflow:hidden;padding:0 16px}

.tape-shopline{display:flex;align-items:center;justify-content:space-between;gap:10px}
.tape-hd .shop{font-weight:800;font-size:14px;letter-spacing:-.2px;color:var(--sky-800)}
.tape-items{font-size:10.5px;color:var(--slate);white-space:nowrap}
.tape-hd .meta{
  display:flex;justify-content:space-between;gap:8px;margin-top:3px;
  font-size:11px;color:var(--slate);font-family:var(--f-mono)
}
.cust-band{margin-top:7px;padding:6px 7px;background:#EEF5F8;border-left:3px solid #315C73;border-radius:8px}
.cust-row{display:grid;grid-template-columns:minmax(0,1fr) 134px 34px;gap:6px}
.cust-row input{padding:7px 9px;font-size:13px;background:#fff;border-color:#C8D8E1}
.cbtn{
  display:grid;place-items:center;border:1px solid var(--line);border-radius:var(--r);
  background:#fff;color:var(--sky-700);
}
.cbtn svg{width:15px;height:15px;stroke-width:2}
.cbtn:hover{background:var(--sky-100);border-color:var(--sky-400)}
.cbtn.on{background:var(--sky-600);border-color:var(--sky-600);color:#fff}
.custline{
  display:flex;align-items:center;gap:6px;margin-top:5px;font-size:12px;font-weight:600;color:var(--ink-2);
}
/* --giu-day: đệm đáy tạm sau khi bỏ dòng (xem GIU_DAY trong pos.js) */
.items{overflow-y:auto;overflow-x:hidden;min-height:0;padding:5px 8px calc(5px + var(--giu-day, 0px)) 0}
.items::-webkit-scrollbar{width:7px}
.items::-webkit-scrollbar-thumb{background:var(--line);border-radius:7px}
/* b229 · DÒNG PHIẾU BỐN CỘT: [X] [tên] [giá] [bút] — anh Đạt 11/09, ba lần soi:
   ① "10 sản phẩm, bấm nhanh chuột cùng 1 vị trí thì thấy dấu X có di chuyển" ⇒ X ở cột
      RIÊNG rộng cố định, canh giữa DÒNG ĐẦU của tên (--dong1): tên dài mấy dòng thì X
      vẫn cách mép trên thẻ đúng một khoảng; bỏ một dòng thì dòng kế trồi lên đúng chỗ.
   ② soi bản thử 21:43: X để bên phải thì lúc ẩn cột phải trống, "số bị đẩy sang trái quá
      nhiều, mất cân đối" ⇒ chọn phương án C: X ở ĐẦU dòng, CHỈ hiện khi rê vào dòng.
   ③ "dấu X và cây bút nên dịch ra 2 bên tý để nội dung chính rõ ràng" ⇒ X và bút ở hai
      cột ngoài cùng, lấn vào lề thẻ đúng bằng lề thẻ (6px); tên–số nằm giữa.
   Nguyên tắc tham khảo: NN/g 2021 — nút xóa phải XA nút thao tác thường (cây bút). */
.item{
  --cot-xoa:20px;--xoa:26px;--cot-but:16px;--dong1:18px;
  padding:6px 0;border-bottom:1px dashed var(--line-2);display:grid;
  grid-template-columns:var(--cot-xoa) minmax(0,1fr) auto var(--cot-but);gap:3px 8px;
}
.item .nm{grid-column:2;grid-row:1;font-size:12.5px;font-weight:600;line-height:var(--dong1);padding-right:8px}   /* + khe cột 8px = tên cách giá 16px — anh Đạt 11/09: "không sát giá, sát giá sẽ bị nhiễu" */
/* b223 · CỤM TIỀN của một dòng: đúng MỘT con số (thành tiền) + cây bút (từ b229 cây bút
   ở cột riêng ngoài cùng bên phải, cách số 8px).
   Trước b223 dòng phiếu có hai con số bằng nhau — thành tiền ở trên và ô
   "ĐƠN GIÁ" ở dưới — anh Đạt 10/09: "nhìn nhiều, đầy quá". */
/* Giá cũng canh DÒNG ĐẦU của tên (tên 2 dòng thì giá không trôi xuống giữa nữa):
   cụm cao 22px = cây bút, canh giữa --dong1 bằng lề âm. */
.item .tt{
  grid-column:3;grid-row:1;
  display:flex;align-items:center;justify-content:flex-end;gap:4px;flex-wrap:wrap;
  align-self:start;margin-block:calc((var(--dong1) - 22px) / 2);
  font-weight:800;font-family:var(--f-mono);text-align:right;white-space:nowrap;
}
.item .tt b{font-weight:800;line-height:22px}
.item .tt.over b,.item .tt.over .ttin{color:var(--or-7)}
.item .ttbut{
  grid-column:4;grid-row:1;align-self:start;justify-self:end;
  margin:calc((var(--dong1) - 22px) / 2) -6px calc((var(--dong1) - 22px) / 2) 0;
  display:grid;place-items:center;width:22px;height:22px;flex:0 0 22px;border-radius:5px;
  color:var(--slate-2);font-size:12px;line-height:1;opacity:.4;transition:opacity .12s,color .12s,background .12s;
}
.item .ttbut svg{width:12px;height:12px;stroke-width:2.4}
/* Cây bút MỜ THƯỜNG TRỰC chứ không ẩn hẳn: anh Đạt 10/09 chốt "sửa giá thì bấm
   cây bút kế bên giá" — ẩn đi thì không ai biết là bấm được. Rê vào mới đậm. */
.item:hover .ttbut,.item:focus-within .ttbut,.item .ttbut.over{opacity:1}
.item .ttbut:hover{background:var(--sky-100);color:var(--sky-700)}
.item .ttbut.over{color:var(--or-7)}
/* Ô nhập đơn giá mở ra ĐÚNG chỗ con số vừa đứng — mắt không phải đi tìm. */
.item .ttin{
  width:7em;min-width:7em;height:22px;padding:0 5px;text-align:right;
  font-family:var(--f-mono);font-size:inherit;font-weight:800;color:var(--ink);
  border:1px solid var(--sky-400);border-radius:5px;background:var(--sky-50);
}
.item .ttin:focus{box-shadow:none;background:#fff}
/* Số lượng khác 1 thì mới cần nhắc đơn giá — bỏ hẳn là mất thông tin, để
   thường trực là lại thành hai số như cũ. */
.item .ttx{
  flex:0 0 100%;font-size:10.5px;font-weight:500;color:var(--slate-2);
  font-family:var(--f-mono);letter-spacing:0;
}
.item .ln{
  grid-column:2/-1;display:flex;align-items:center;gap:5px;flex-wrap:wrap;row-gap:3px;
  font-size:11px;color:var(--slate);font-family:var(--f-mono)
}
.item .icobtn.xoa{
  grid-column:1;grid-row:1;align-self:start;justify-self:start;width:var(--xoa);height:var(--xoa);
  margin:calc((var(--dong1) - var(--xoa)) / 2) 0 calc((var(--dong1) - var(--xoa)) / 2) -6px;
}
.item .icobtn.xoa svg{width:16px;height:16px}
/* ĐƠN GIÁ THẲNG HÀNG GIỮA CÁC DÒNG (anh Đạt yêu cầu 09/08):
   khung số lượng không co (co là nút + bị cắt), ô đơn vị rộng CỐ ĐỊNH
   để cột đơn giá bắt đầu cùng một mép ở mọi dòng. */
.item .ln .qty{flex:0 0 auto}
/* b223 · ô đơn vị KHÔNG còn rộng cố định 60px. Chiều rộng đó sinh ra chỉ để
   cột "ĐƠN GIÁ" của mọi dòng bắt đầu cùng một mép — nay không còn cột đó nữa,
   giữ lại chỉ tổ chừa một khoảng trắng vô nghĩa giữa số lượng và đơn vị. */
.item .ln .uplain,.item .ln .umode{
  flex:0 0 auto;max-width:96px;justify-content:flex-start;
  overflow:hidden;text-overflow:ellipsis;
}
.item .ln .uplain{display:inline-block}
.qty{display:inline-flex;align-items:center;border:1px solid var(--line);border-radius:5px;overflow:hidden;background:var(--paper)}
/* Nút +/- là nút bấm nhiều nhất màn bán hàng. 23px cũ dưới cả mức tối thiểu
   24px của WCAG (Apple đòi 44) — nâng lên 28px, ô số nới theo (sổ tay mục 1). */
.qty button{width:28px;height:28px;display:grid;place-items:center;color:var(--sky-700);font-weight:700;font-size:15px}
.qty button:hover{background:var(--sky-100)}
.qty input{
  width:48px;border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);
  border-radius:0;text-align:center;padding:2px;font-family:var(--f-mono);font-size:13px;font-weight:700;
}
.qty input:focus{box-shadow:none;background:var(--sky-50)}
.umode{
  display:inline-flex;align-items:center;gap:2px;height:25px;padding:0 6px;flex:0 0 auto;
  border:1px solid var(--line);border-radius:5px;background:var(--paper);
  font-size:11.5px;font-weight:700;color:var(--ink-2);white-space:nowrap;
}
.umode i{font-style:normal;font-size:9px;color:var(--slate-2)}
.umode:hover{border-color:var(--sky-400);background:var(--sky-50)}
.umode.whole{background:var(--sky-100);color:var(--sky-700);border-color:var(--sky-300)}
.umode.whole i{color:var(--sky-600)}
.uplain{flex:0 0 auto;white-space:nowrap;font-size:11.5px}
/* b225 · CHỌN DUNG TÍCH ngay trên dòng hàng sơn. Anh Đạt 10/09: "phần này chủ
   động thay đổi được số lít vì có sơn 15L, 17L". Dùng <select> chứ không dựng
   hộp riêng: trên điện thoại nó mở bằng bánh xe sẵn có của máy, một chạm là
   xong, và không cần thêm một lớp nổi nào nữa trong phiếu. */
.litsel{
  /* `width:auto` KHÔNG thừa: luật nền cho mọi select là width:100%, để nguyên
     thì ô dung tích chiếm trọn một dòng và đẩy hàng màu xuống — đúng cái ảnh
     chụp 10/09. Sổ lỗi #121. */
  flex:0 0 auto;width:auto;min-width:62px;height:26px;padding:0 2px 0 6px;
  border:1px solid var(--line);border-radius:6px;
  background:var(--paper);font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:11.5px;font-weight:700;color:var(--ink-2);cursor:pointer;
}
.litsel:hover{border-color:var(--sky-400);background:var(--sky-50)}
.litsel:focus{outline:2px solid var(--sky-400);outline-offset:1px}
/* Chưa chọn dung tích thì nổi màu cam: chưa có số lít là chưa tính được tiền màu. */
.litsel.chua{border-color:#F3C9A2;background:var(--or-50);color:var(--or-safe)}
.empty-tape{
  display:grid;place-content:center;text-align:center;gap:8px;color:var(--slate);
  padding:30px 10px;
}
.empty-tape svg{width:34px;height:34px;stroke-width:1.4;margin:0 auto;color:var(--sky-300)}
.empty-tape p{margin:0;font-size:12.5px;max-width:220px}
.empty-tape .kbd-hint{font-size:11px;color:var(--slate-2)}

/* Phần thanh toán: nền riêng, viền rõ để không lẫn với danh sách hàng */

.tape-ft .trow{color:var(--ink-2)}
.tape-ft .trow .num{color:var(--ink)}
.tape-ft input,.tape-ft select{background:var(--paper)}

.trow input{width:92px;text-align:right;padding:3px 7px;font-size:12px;font-family:var(--f-mono);font-weight:700}
.trow select{width:auto;padding:3px 6px;font-size:11.5px;font-weight:700;color:var(--sky-700);background:var(--sky-50);border-color:var(--sky-300)}
.trow .lb{display:inline-flex;align-items:center;gap:6px}
.trow.tot{
  font-size:12px;font-weight:700;color:var(--sky-700);padding-top:7px;margin-top:5px;
  border-top:1px solid #D2D7DE;letter-spacing:.08em;text-transform:uppercase;
}
.trow.tot .num{font-size:21px;color:var(--or-safe);letter-spacing:-.5px;white-space:nowrap}   /* b229 · chữ "đ" không rớt xuống dòng riêng trên điện thoại */
.tape-acts{display:grid;gap:5px;margin-top:5px}
.acts-2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.kbd{
  font-family:var(--f-mono);font-size:10px;font-weight:700;padding:1px 5px;border-radius:4px;
  background:var(--sky-50);border:1px solid var(--line);color:var(--slate);
}
.btn.acc .kbd,.btn.pri .kbd,.btn.ink .kbd{background:rgba(255,255,255,.22);border-color:rgba(255,255,255,.3);color:#fff}
/* Phím tắt in trên nút cam: mảng trắng mờ .22 làm nền sáng lên, chữ trắng chỉ
   còn 3,84. Đổi sang mảng TỐI mờ — nền đậm lại, chữ trắng lên 6,3
   (đo bằng tests/browser/pos-do.js). */
.tape-acts .btn.acc .kbd{background:rgba(0,0,0,.16);border-color:rgba(255,255,255,.34);color:#fff}

/* ===== SOURCE: styles/components.css ===== */
/* ---------- bảng ---------- */
.panel{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.panel-hd{
  padding:13px 16px;border-bottom:1px solid var(--line);display:flex;
  align-items:center;gap:12px;flex-wrap:wrap;background:var(--paper);
}
.panel-hd h2{margin:0;font-size:14px;font-weight:700;display:inline-flex;align-items:center;gap:7px}
.panel-hd h2 svg{width:17px;height:17px;stroke-width:2;flex:0 0 auto}
input[type=file]{padding:6px 8px;font-size:12.5px;cursor:pointer}
input[type=file]::file-selector-button{
  font:inherit;font-weight:600;font-size:12.5px;margin-right:9px;padding:5px 11px;cursor:pointer;
  border:1px solid var(--sky-300);border-radius:5px;background:var(--sky-50);color:var(--sky-700);
}
input[type=file]::file-selector-button:hover{background:var(--sky-100)}
details summary::marker{color:var(--sky-500)}
.panel-hd .head-sp{flex:1}
.panel-bd{padding:16px}

table{width:100%;border-collapse:collapse;font-size:13px}
thead th{
  position:sticky;top:0;background:var(--paper);z-index:1;text-align:left;
  padding:10px 12px;font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--slate);border-bottom:1.5px solid var(--line);
  white-space:nowrap;
}
tbody td{padding:9px 12px;border-bottom:1px solid var(--line-2);vertical-align:middle}
tbody tr:hover{background:var(--sky-50)}
tbody tr:last-child td{border-bottom:0}
.tbl-wrap{overflow:auto;max-height:calc(100vh - 210px);contain:layout paint}
tbody tr{content-visibility:auto;contain-intrinsic-size:41px}
tbody tr.clk{cursor:pointer}
td.r,th.r{text-align:right}
td.c,th.c{text-align:center}
.tag{
  display:inline-block;padding:2px 7px;border-radius:4px;font-size:11px;font-weight:600;
  background:var(--sky-100);color:var(--sky-700);white-space:nowrap;
}
.tag.bp{background:var(--sky-100);color:var(--sky-700)}
.tag.gn{background:var(--green-soft);color:var(--green)}
.tag.rd{background:var(--red-soft);color:var(--red)}
.tag.am{background:var(--or-50);color:var(--or-7)}
.tag.gy{background:#EEF0F3;color:var(--slate)}
.status-tag{display:inline-flex;align-items:center;gap:5px}
.status-tag svg{width:13px;height:13px;stroke-width:2.1;flex:0 0 auto}

.toolbar{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.toolbar input,.toolbar select{width:auto;min-width:150px}
.toolbar label{font-size:12px;font-weight:600;color:var(--slate)}
.toolbar-sp{flex:1}
.resource-toolbar{min-height:40px}
.resource-toolbar .resource-search{max-width:420px}
.search-in{position:relative;flex:1;max-width:340px}
.search-in input{padding-left:32px}
.search-in svg{
  position:absolute;left:10px;top:50%;transform:translateY(-50%);
  width:15px;height:15px;color:var(--slate-2);stroke-width:2;pointer-events:none
}

/* ---------- KPI ---------- */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(184px,1fr));gap:12px;margin-bottom:16px}
.kpi{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:13px 15px 14px;position:relative;overflow:hidden;
}
.kpi::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--sky-500)}
.kpi .k{
  font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--slate);margin-bottom:6px
}
.kpi .v{font-size:23px;font-weight:800;font-family:var(--f-mono);letter-spacing:-.8px;line-height:1.1}
.kpi .n{font-size:11.5px;color:var(--slate);margin-top:3px}
.kpi.gn::before{background:var(--green)}  .kpi.gn .v{color:var(--green)}
.kpi.rd::before{background:var(--red)}     .kpi.rd .v{color:var(--red)}
.kpi.bp::before{background:var(--sky-600)} .kpi.bp .v{color:var(--sky-700)}
.kpi.am::before{background:var(--or)}      .kpi.am .v{color:var(--or-7)}

/* ---------- hộp thoại ---------- */
.ov{
  position:fixed;inset:0;background:rgba(6,43,68,.45);display:grid;place-items:center;
  padding:20px;z-index:80;backdrop-filter:blur(2px);
}
.ov[hidden]{display:none}
.modal{
  /* b175: min-width:0 — modal là con của lưới .ov, không có nó thì một hàng
     nowrap bên trong (thanh mục Cài đặt) đẩy modal RỘNG HƠN màn điện thoại. */
  background:var(--paper);border-radius:var(--r-lg);width:100%;max-width:660px;min-width:0;
  max-height:90vh;display:flex;flex-direction:column;box-shadow:var(--shadow-lg);
}
.modal.wide{max-width:880px}
.modal.narrow{max-width:440px}
.ov.drawer-host{place-items:stretch end;padding:0;background:rgba(24,27,32,.38)}
.modal.drawer{
  width:min(680px,calc(100vw - 88px));height:100vh;max-width:680px;max-height:100vh;
  border-radius:var(--r-lg) 0 0 var(--r-lg);animation:drawerIn .18s ease-out
}
.modal.drawer.wide{max-width:760px}
.modal.drawer .m-hd{border-radius:var(--r-lg) 0 0 0;position:sticky;top:0;z-index:2}
.modal.drawer .m-ft{position:sticky;bottom:0;background:var(--paper);z-index:2}
.modal.focus{max-width:960px;max-height:94vh}
@keyframes drawerIn{from{transform:translateX(24px);opacity:.7}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.modal.drawer{animation:none}}
.m-hd{
  padding:15px 18px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px;
  background:var(--paper);border-radius:var(--r-lg) var(--r-lg) 0 0;
}
.m-hd h3{margin:0;font-size:15.5px;font-weight:700;color:var(--ink);letter-spacing:-.2px}
.m-bd{padding:18px;overflow:auto;flex:1}
.m-ft{padding:13px 18px;border-top:1px solid var(--line);display:flex;gap:9px;justify-content:flex-end;flex-wrap:wrap}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.fgrid .full{grid-column:1/-1}
.f label{
  display:block;font-size:11px;font-weight:700;color:var(--slate);margin-bottom:4px;
  letter-spacing:.02em
}
.f .hint{font-size:11px;color:var(--slate-2);margin-top:3px}
.sect{
  font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--sky-700);margin:20px 0 11px;padding-bottom:6px;border-bottom:1px solid var(--line);
  grid-column:1/-1
}
.sect:first-child{margin-top:0}
.note{
  background:var(--sky-50);border:1px solid var(--line);border-left:3px solid var(--sky-500);
  border-radius:var(--r);padding:11px 13px;font-size:12.5px;color:var(--ink-2);
}
.note.am{background:var(--or-50);border-color:#F6D9BC;border-left-color:var(--or)}
.note strong{color:var(--ink)}
/* b238 · khối "lúc mất mạng thì việc gì phải đợi" trong hộp bật bán dự phòng.
   Có lớp riêng để không phải nhét style thẳng vào thẻ — cùng cỡ chữ với danh sách ngay trên nó. */
.note-ds{margin-top:12px}
.note-ds ul{font-size:13px;line-height:1.65;margin:6px 0 0;padding-left:20px}
.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:8px 16px;font-size:12.5px}

/* ---------- thông báo ---------- */
.toasts{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:99;display:grid;gap:8px;justify-items:center}
.toast{
  background:var(--sky-900);color:#fff;padding:10px 16px;border-radius:100px;font-size:13px;
  font-weight:600;box-shadow:var(--shadow-lg);animation:up .22s ease-out;max-width:88vw;text-align:center;
}
.toast.ok{background:var(--green)}
.toast.err{background:var(--red)}
@keyframes up{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* Dải sau bán: phản hồi + hành động tiếp theo, không khóa màn Bán hàng. */
.sale-follow{
  position:fixed;left:calc(var(--rail) + 18px);right:18px;bottom:18px;z-index:70;
  min-height:64px;padding:10px 12px;display:flex;align-items:center;gap:10px;
  background:var(--sky-900);color:#fff;border:1px solid rgba(255,255,255,.14);
  border-radius:14px;box-shadow:var(--shadow-lg);overflow:hidden
}
.sale-follow[hidden]{display:none}
.sale-follow:not([hidden]) + .toasts{bottom:96px}
.sale-follow.on{animation:followIn .18s ease-out}
.sf-state{width:38px;height:38px;flex:0 0 38px;border-radius:11px;background:var(--green);
  display:grid;place-items:center}
.sf-state svg{width:21px;height:21px;stroke-width:2.5}
.sf-copy{display:flex;align-items:baseline;gap:7px;min-width:0;flex:1;flex-wrap:wrap}
.sf-copy strong{font-size:13.5px;white-space:nowrap}
.sf-copy span{font-size:12px;color:#C9CFD8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-copy .num{font-size:14px;font-weight:800;color:#fff}
.sf-actions{display:flex;align-items:center;gap:5px;flex:0 0 auto}
.sf-actions button{min-height:40px;padding:8px 11px;border-radius:9px;color:#fff;
  border:1px solid rgba(255,255,255,.18);display:inline-flex;align-items:center;gap:6px;
  font-size:12px;font-weight:700}
.sf-actions button:hover{background:rgba(255,255,255,.12)}
.sf-actions button svg{width:15px;height:15px}
.sf-actions .sf-close{width:40px;padding:0;justify-content:center;color:#C9CFD8}
.sf-life{position:absolute;left:0;bottom:0;height:3px;background:var(--or);width:100%;
  transform-origin:left;animation:followLife 15s linear forwards}
@keyframes followIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes followLife{to{transform:scaleX(0)}}
@media (prefers-reduced-motion:reduce){.sale-follow.on,.sf-life{animation:none}}

/* ---------- mã vạch / tem ---------- */
.bc svg{display:block;max-width:100%;height:auto}
.labels{display:grid;grid-template-columns:repeat(3,1fr);gap:5px}
.label{
  border:1px dashed var(--line);padding:7px;text-align:center;
  display:flex;flex-direction:column;gap:3px;align-items:center;break-inside:avoid;
}
.label .lc{font-size:9.5px;font-weight:700;font-family:var(--f-mono);align-self:flex-start}
.label .lp{font-size:11px;font-weight:800;font-family:var(--f-mono)}
.label .ln2{font-size:9px;line-height:1.2}
.label .bcn{font-size:8px;font-family:var(--f-mono);letter-spacing:.06em}

.empty{
  text-align:center;padding:48px 20px;color:var(--slate);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
}
.empty svg{width:38px;height:38px;stroke-width:1.4;color:var(--sky-300);margin-bottom:10px}
.empty h3{margin:0 0 5px;font-size:15px;color:var(--ink);font-weight:700}
.empty p{margin:0 auto 14px;font-size:13px;max-width:420px;line-height:1.55}
.empty-actions{display:flex;align-items:center;justify-content:center;gap:var(--space-3);flex-wrap:wrap}
.text-action{min-height:40px;padding:8px 6px;color:var(--sky-700);font-size:12.5px;font-weight:700;
  text-decoration:underline;text-decoration-color:var(--sky-300);text-underline-offset:3px;border-radius:var(--r-sm)}
.text-action:hover{color:var(--ink);text-decoration-color:var(--or)}
.empty-note{margin-top:4px;padding:9px 12px;border-radius:var(--r);background:var(--sky-50);
  color:var(--slate);font-size:12px;font-weight:600}
.onboard-empty{min-height:360px;padding:36px 24px}
.onboard-empty>svg{width:44px;height:44px}
.empty-steps{display:flex;align-items:center;justify-content:center;gap:10px;margin:2px 0 20px;
  width:min(620px,100%)}
.empty-steps>span{flex:1;min-width:0;display:flex;align-items:center;gap:8px;padding:9px 11px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r)}
.empty-steps b{width:24px;height:24px;flex:0 0 24px;border-radius:50%;display:grid;place-items:center;
  background:var(--sky-900);color:#fff;font:700 11px var(--f-mono)}
.empty-steps em{font-style:normal;color:var(--ink);font-size:11.5px;font-weight:650;white-space:nowrap}
.empty-steps>i{font-style:normal;color:var(--sky-400);font-size:22px;font-weight:300}

.cam-box{position:relative;background:#000;border-radius:var(--r);overflow:hidden;aspect-ratio:4/3}
.cam-box video{width:100%;height:100%;object-fit:cover;display:block}
.cam-line{
  position:absolute;left:8%;right:8%;top:50%;height:2px;background:var(--or);
  box-shadow:0 0 12px var(--or);animation:sweep 2s ease-in-out infinite;
}
@keyframes sweep{0%,100%{top:26%}50%{top:74%}}
@media (prefers-reduced-motion:reduce){.cam-line{animation:none}}
/* b229 · B5 · dải đỏ BẢN THỬ (máy chủ THU.cmd chạy trên sổ CHÉP từ sổ thật) — viền đỏ quanh màn + nhãn giữa đỉnh.
   pointer-events:none: không chặn bấm; không in ra giấy. */
.ban-thu{position:fixed;top:0;left:50%;transform:translateX(-50%);z-index:2147483000;background:#b71c1c;color:#fff;
  font-weight:700;font-size:12px;line-height:1.5;padding:3px 12px;border-radius:0 0 8px 8px;pointer-events:none;
  box-shadow:0 2px 6px rgba(0,0,0,.35);white-space:nowrap;max-width:96vw;overflow:hidden;text-overflow:ellipsis}
html.co-ban-thu::after{content:"";position:fixed;inset:0;border:4px solid #b71c1c;pointer-events:none;z-index:2147483000}
@media print{.ban-thu{display:none}html.co-ban-thu::after{display:none}}

/* b229 · B8: chốt ngày nói Thừa/Thiếu/Khớp có màu; chừa khoảng giữa hai dòng số máy chủ và ô nhập */
#rc_diff.lech { color: var(--red); font-weight: 700; }
#rc_diff.khop { color: var(--green); font-weight: 700; }
.fgrid:has(#rc_open) { margin-top: 12px; }

/* b229 · B8 (soi ảnh điện thoại): bảng Quản lý tài khoản rộng hơn màn 390px — nút "Cấp mật khẩu tạm" bị giấu bên phải,
   phải vuốt ngang mới thấy. Lên b229 chủ PHẢI cấp mật khẩu tạm cho từng người (000000 bị khóa), có khi làm từ điện thoại
   ⇒ màn hẹp xếp mỗi tài khoản thành một thẻ: tên + nhóm + trạng thái bên trái, hai nút bên phải. */
@media (max-width: 560px) {
  .auth-table thead { display: none; }
  .auth-table tr { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; padding: 10px 0; border-bottom: 1px solid var(--line); }
  .auth-table td { display: block; padding: 0; border: 0; }
  .auth-table td:nth-child(2), .auth-table td:nth-child(3) { grid-column: 1; font-size: 13px; color: var(--slate); }
  .auth-table td.r { grid-column: 2; grid-row: 1 / span 3; align-self: center; display: flex; flex-direction: column; gap: 6px; }
}

/* ===== SOURCE: styles/print.css ===== */
/* ---------- in ấn ---------- */
#print{display:none}
#print.measure{display:block !important;position:absolute;left:-10000px;top:0;background:#fff}
/* .p-80 đặt NGOÀI @media print để app đo được chiều dài phiếu trước khi in
   (in vẫn đúng vì trên màn hình #print luôn ẩn) */
/* hóa đơn khổ 80mm (máy in nhiệt) — bố cục kiểu UNIQLO, chốt b114 */
.p-80{width:72mm;box-sizing:border-box;padding:2.5mm 4mm 3mm;font-size:9pt;line-height:1.4;color:#000}
.p-80 tr,.p-80 .nm,.p-80 .chuyen,.p-80 .ft,.p-80 .rvq{break-inside:avoid;page-break-inside:avoid}
.p-80 .c{text-align:center}
.p-80 .b{font-weight:700}
.p-80 .lk{display:flex;align-items:center;justify-content:center;gap:2.5mm}
.p-80 .lk-m{width:15mm;height:10mm}
.p-80 .lk-t{text-align:left}
.p-80 .lk-tag{font-size:6.3pt;font-weight:700;letter-spacing:1.6pt;white-space:nowrap}
.p-80 .lk-w{width:33mm;height:6.6mm;display:block}
.p-80 .lk-ad{font-size:8.5pt;line-height:1.45;margin-top:1.2mm;text-align:center}
.p-80 h1{font-size:12pt;margin:2.2mm 0 .5mm;text-align:center;letter-spacing:2pt;font-weight:800}
.p-80 .mt{font-size:8.5pt;margin-bottom:.8mm}
.p-80 hr{border:0;border-top:1px dashed #000;margin:1.8mm 0}
.p-80 table{width:100%;border-collapse:collapse;font-size:9pt}
.p-80 td{padding:.4mm 0;vertical-align:top}
.p-80 .r{text-align:right;white-space:nowrap}
.p-80 .nm{font-weight:600}
.p-80 .sb{font-size:8.5pt}
.p-80 .inote{font-size:8pt;font-style:italic;padding-left:2.5mm;line-height:1.25}
.p-80 .ct{text-align:center}
.p-80 .sum td{padding:.5mm 0}
.p-80 .tot td{font-weight:800;font-size:12pt;padding-top:1.2mm;border-top:1px solid #000}
.p-80 .words{font-size:8pt;font-style:italic;margin-top:.8mm}
.p-80 .chuyen{font-size:8pt;text-align:center;line-height:1.5}
.p-80 .chuyen b{font-weight:800}
.p-80 .ft{text-align:center;font-size:8.5pt;line-height:1.5}
/* VietQR trên bill nhiệt: 30mm cho dễ quét (b132, anh Đạt góp ý — mốc tối
   thiểu của sổ tay là 20mm), viền trắng 4 mô-đun nằm sẵn trong SVG.
   Chữ chỉ một dòng ngắn, SỐ TIỀN tách riêng in to — không để chữ rớt dòng. */
.p-80 .vqr{text-align:center;margin:1.5mm 0 .5mm}
.p-80 .vqr svg{width:30mm;height:30mm}
.p-80 .vqr .t{font-size:8pt;line-height:1.4}
.p-80 .vqr .vamt{font-size:12pt;font-weight:800;margin:.2mm 0 .4mm}
/* Tài khoản dưới mã QR (sửa b147): ngân hàng + số tài khoản một dòng, TÊN CHỦ
   một dòng riêng. Trước đây ba thứ nối bằng dấu chấm giữa nên tên công ty dài
   bị bẻ ngang, nhìn như lỗi in. Tên chừa lề hai bên 3mm để nếu có xuống dòng
   thì cũng gãy ở giữa từ chứ không sát mép giấy. */
.p-80 .vqr .vbank{font-size:8.5pt;font-weight:700;line-height:1.35;margin-top:.3mm}
.p-80 .vqr .vstk{letter-spacing:.35pt}
.p-80 .vqr .vown{font-size:7.5pt;line-height:1.3;letter-spacing:.1pt;padding:0 3mm}
/* Mã vạch số HĐ ở chân bill: cao ~7mm, vạch mảnh ~0.4mm, hai bên trống rộng */
.p-80 .bchd{text-align:center;margin-top:1.6mm}
.p-80 .bchd svg{width:40mm;height:auto}


@media print{
  body{overflow:visible;background:#fff}
  .app,.toasts,.ov{display:none !important}
  #print{display:block !important}

  /* hóa đơn A4/A5 */
  .p-inv{max-width:100%;font-size:11pt;color:#000}
  .p-inv .p-shop{text-align:center;margin-bottom:4mm;font-size:9.5pt;line-height:1.4}
  .p-inv h1{font-size:16pt;margin:0 0 1mm;text-align:center;letter-spacing:.5pt}
  .p-inv .p-sub{text-align:center;font-size:9pt;margin-bottom:5mm}
  .p-inv table{width:100%;border-collapse:collapse;font-size:10pt}
  .p-inv th,.p-inv td{border:1px solid #000;padding:1.6mm 2mm}
  .p-inv th{background:#eee;font-size:9pt;text-transform:uppercase}
  /* Trên màn hình dòng cuối bảng bỏ viền dưới cho thoáng (tbody tr:last-child td),
     nhưng khi IN thì bảng bị hở đáy — trả lại viền cho phiếu in (b123). */
  .p-inv tbody tr:last-child td,.p-list tbody tr:last-child td{border-bottom:1px solid #000}
  .p-inv .p-meta td{border:0;padding:0 0 1mm}
  /* Cột phải của phần thông tin đầu phiếu: trước canh phải nên chữ dí sát mép
     giấy. Nay là một cột rộng cố định, canh trái (b126). */
  .p-inv .p-meta td.rt{width:46%;text-align:left;padding-left:8mm}
  /* Phiếu giao hàng: nhãn thành cột riêng, giá trị có gạch chân để điền tay.
     Trước đây ĐT/Số xe canh phải nên bị dí sát rìa giấy (b123). */
  .p-inv .p-dl{table-layout:fixed}
  .p-inv .p-dl td{padding:0 0 2mm;vertical-align:bottom}
  .p-inv .p-dl .lb{width:26mm;font-weight:700;white-space:nowrap}
  .p-inv .p-dl .lb2{width:18mm;font-weight:700;white-space:nowrap;padding-left:6mm}
  .p-inv .p-dl .vl,.p-inv .p-dl .vl2{border-bottom:1px dotted #999;padding:0 4mm 1mm 2mm}
  .p-inv .p-dl .vl2{width:40mm;padding-right:1mm}
  /* Khối tiền thu hộ khi giao (COD) — b131 thêm ô VietQR bên phải */
  .p-inv .p-cod{border:1.6pt solid #000;padding:2.5mm 3mm;margin-top:4mm;text-align:center;
    display:flex;align-items:center;justify-content:center;gap:5mm}
  .p-inv .p-cod .cod-main{flex:1;min-width:0}
  .p-inv .p-cod .cod-qr{flex:0 0 auto;font-size:7.5pt;line-height:1.35;text-align:center}
  .p-inv .p-cod .cod-qr svg{width:22mm;height:22mm;display:block;margin:0 auto .5mm}
  .p-inv .p-cod .cod-hd{font-size:9.5pt;font-weight:700;letter-spacing:.6pt}
  .p-inv .p-cod .cod-amt{font-size:19pt;font-weight:800;line-height:1.15;margin:.6mm 0}
  .p-inv .p-cod .cod-w{font-size:9pt;font-style:italic}
  .p-inv .p-cod .cod-note{font-size:9pt;margin-top:1.4mm}
  .p-inv .p-cod .cod-tick{margin-left:3mm;white-space:nowrap}
  .p-inv .p-cod.none{border:1pt dashed #666;font-size:9.5pt;font-weight:700;padding:2mm 3mm}
  .p-inv .p-sum{width:74mm;margin-left:auto;margin-top:3mm}
  .p-inv .p-sum td{border:0;padding:.8mm 0;font-size:10pt}
  .p-inv .p-sum tr.g td{border-top:1px solid #000;font-weight:700;font-size:11.5pt;padding-top:1.4mm}
  .p-inv .p-words{margin-top:3mm;font-size:9.5pt;font-style:italic}
  .p-sign{display:flex;justify-content:space-around;margin-top:14mm;font-size:10pt;text-align:center}
  .p-ft{margin-top:8mm;text-align:center;font-size:9pt;font-style:italic}

  /* bảng giá / báo cáo */
  .p-list table{width:100%;border-collapse:collapse;font-size:9.5pt}
  .p-list th,.p-list td{border:1px solid #999;padding:1.4mm 2mm}
  .p-list th{background:#eee}
  .p-list tr,.p-list .label{page-break-inside:avoid}
  .labels{display:grid;grid-template-columns:repeat(3,1fr);gap:2mm}
  .label{border:1px dashed #999;padding:2mm}
  .p-h{font-size:14pt;font-weight:800;margin:0 0 4mm}
  @page{size:A4;margin:11mm}
}
@media print{
  body.k80 .p-inv{display:none}
  body:not(.k80) .p-80{display:none}
}

/* ===== SOURCE: styles/responsive-core.css ===== */
/* ---------- màn nhỏ ---------- */
@media (max-width:1240px){ .pos3{grid-template-columns:minmax(0,1fr) 400px} }
@media (max-width:1024px){ .pos3{grid-template-columns:minmax(0,1fr) 360px} }
@media (max-width:880px){
  :root{--rail:0px}
  .app{grid-template-columns:1fr}
  .rail{
    position:fixed;bottom:0;left:0;right:0;z-index:60;flex-direction:row;
    padding:4px 2px;gap:0;overflow-x:auto;box-shadow:0 -2px 14px rgba(8,51,79,.2);
  }
  .brand,.rail-sp,.rail-ft,.rail-line{display:none}
  .navbtn{flex:1 0 auto;min-width:68px;padding:7px 3px;font-size:9.5px}
  .navbtn svg{width:19px;height:19px}
  .navbtn.on::before{left:12%;right:12%;top:0;bottom:auto;width:auto;height:3px;border-radius:0 0 3px 3px}
  .view{padding:12px 12px 78px}
  .pos3{grid-template-columns:1fr;padding:10px 10px 78px;height:auto}
  .pane{overflow:visible}
  .tape-col{border-left:0;padding:0;min-height:340px}
  .tape{min-height:300px}
  .results{overflow:visible}
  .fgrid{grid-template-columns:1fr}
  .head{padding:0 12px;gap:9px}
  .head h1{font-size:14.5px}
  .head .sub{display:none}
  .mobile-account{margin-left:auto;flex:0 0 40px;border:1px solid var(--line);background:var(--sky-50)}
  .tbl-wrap{max-height:none}
  .kpi .v{font-size:19px}
  .m-ft .btn{flex:1}
  .ov.drawer-host{padding:0;place-items:stretch}
  .modal.drawer,.modal.drawer.wide{width:100vw;max-width:none;height:100dvh;max-height:100dvh;border-radius:0}
  .modal.drawer .m-hd{border-radius:0}
  .resource-toolbar .resource-search{max-width:none;flex:1 0 100%}
  .resource-toolbar .toolbar-sp{display:none}
  .sale-follow{left:8px;right:8px;bottom:66px;padding:9px;gap:8px;min-height:60px}
  .sale-follow:not([hidden]) + .toasts{bottom:138px}
  .sf-state{width:34px;height:34px;flex-basis:34px}
  .sf-copy{display:block}
  .sf-copy strong,.sf-copy span{display:block;max-width:100%}
  .sf-copy span:not(.num){display:none}
  .sf-actions button{width:40px;padding:0;justify-content:center}
  .sf-actions button span{display:none}
  .sf-actions .sf-close{display:none}
}

@media (max-width:560px){
  .onboard-empty{min-height:0;padding:28px 14px}
  .empty-steps{gap:6px;margin-bottom:17px}
  .empty-steps>span{display:block;padding:8px 5px;text-align:center}
  .empty-steps b{margin:0 auto 4px}
  .empty-steps em{font-size:10px;white-space:normal}
  .empty-steps>i{font-size:17px}
  .empty-actions{flex-direction:column;width:100%}
  .empty-actions .btn{width:100%;max-width:320px}
}

/* ---------- bán hàng bằng giọng nói ---------- */
.scan-mic{
  width:40px;height:40px;border-radius:var(--r);background:var(--or);
  display:grid;place-items:center;color:#fff;flex:0 0 auto;transition:background .12s,color .12s;
}
.scan-mic:hover{background:var(--or-6)}
.scan-mic svg{width:19px;height:19px;stroke-width:1.8}
.scan-mic.on{background:var(--or);color:#fff;box-shadow:0 0 0 0 rgba(249,115,22,.6);animation:mic 1.6s ease-out infinite}
@keyframes mic{0%{box-shadow:0 0 0 0 rgba(249,115,22,.55)}70%{box-shadow:0 0 0 12px rgba(249,115,22,0)}100%{box-shadow:0 0 0 0 rgba(249,115,22,0)}}
@media (prefers-reduced-motion:reduce){.scan-mic.on{animation:none}}

.vpanel{
  background:var(--paper);border:1px solid var(--line);border-left:4px solid var(--or);
  border-radius:var(--r-lg);padding:11px 13px;box-shadow:var(--shadow);
}
.vhead{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--sky-800)}
.vdot{width:9px;height:9px;border-radius:50%;background:var(--or);animation:pulse 1.4s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){.vdot{animation:none}}
.vtts{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:600;color:var(--slate);white-space:nowrap}
.vtts input{width:auto;margin:0}
.vheard{
  margin-top:8px;font-size:16px;font-weight:600;color:var(--ink);min-height:24px;line-height:1.35;
}
.vmsg{
  margin-top:8px;padding:8px 11px;border-radius:var(--r);font-size:13px;
  background:var(--sky-50);color:var(--ink-2);border:1px solid var(--line);
}
.vmsg.ok{background:var(--green-soft);border-color:#BFE3D5;color:#0B5F44}
.vmsg.err{background:var(--red-soft);border-color:#EDD3D0;color:var(--red)}
.vmsg.ask{background:var(--or-50);border-color:#F6D9BC;color:var(--or-7)}
.vchoices{display:grid;gap:6px;margin-top:8px}
.vch{
  display:flex;align-items:center;gap:9px;text-align:left;width:100%;
  border:1px solid var(--line);border-radius:var(--r);padding:8px 11px;background:var(--paper);
  font-size:13px;transition:border-color .12s,background .12s;
}
.vch:hover{border-color:var(--or);background:var(--or-50)}
.vch b{
  width:22px;height:22px;border-radius:5px;background:var(--sky-600);color:#fff;
  display:grid;place-items:center;font-size:12px;flex:0 0 auto;
}
.vch span:nth-of-type(1){flex:1;font-weight:600}
.vcmds{margin-top:9px;font-size:11px;color:var(--slate-2);line-height:1.5}

/* ---------- cho thuê ---------- */
.eqrow{display:grid;grid-template-columns:1fr 92px 118px 34px;gap:8px;align-items:center;margin-bottom:7px}
.eqrow input,.eqrow select{padding:7px 9px;font-size:13px}
.eqrow.eqhd{
  font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--slate);
  margin-bottom:3px;
}
.eqrow.eqhd span{padding-left:2px}
@media (max-width:880px){
  .eqrow{grid-template-columns:1fr 70px 96px 30px;gap:5px}
  .eqrow.eqhd{font-size:10px}
}

/* b223 · khối .pin (ô ĐƠN GIÁ trong hàng dưới) đã BỎ: anh Đạt 10/09 thấy hai
   con số giá trùng nhau trên cùng một dòng. Nay chỉ còn một số — thành tiền —
   và cây bút cạnh nó (.tt / .ttin / .ttbut ở pos.css). */
.pin button{
  width:19px;height:19px;border-radius:4px;display:grid;place-items:center;
  font-size:12px;color:#fff;background:var(--or);border:0;
}
.pin button:hover{background:var(--or-7)}
@media (max-width:1240px){ .pin b{display:none} }
@media (max-width:880px){ .pin input{width:82px;min-width:82px;flex:0 0 82px} }

/* bộ lọc bảng giá */
.chips{display:flex;gap:7px;flex-wrap:wrap}
.chip{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:100px;
  background:var(--sky-100);color:var(--sky-700);font-size:12px;font-weight:600;
  border:1px solid var(--sky-300);
}
.chip i{font-style:normal;font-size:11px;opacity:.7}
.chip:hover{background:var(--sky-300);color:var(--sky-900)}
.pickbar{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 11px;margin-bottom:12px;
  background:var(--or-50);border:1px solid #F6D9BC;border-radius:var(--r);
}
@media print{ .pickbar{display:none} .p-list input[type=checkbox]{display:none} }

/* ===== SOURCE: styles/filters.css ===== */
/* hàng thẻ chọn nhiều mục */
.chiprow:empty{display:none}
.chiprow{margin-top:10px}

.chiprow-lb{
  font-size:10px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--slate);flex:0 0 auto;margin-right:2px;
}
.chiprow-hint{font-size:11.5px;color:var(--slate-2)}
.chip2{
  display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:999px;
  border:1px solid var(--line);background:var(--paper);color:var(--ink-2);
  font-size:12.5px;font-weight:600;white-space:nowrap;
}
.chip2 i{
  font-style:normal;font-size:10.5px;font-weight:700;font-family:var(--f-mono);
  color:var(--slate-2);background:var(--bg);padding:0 5px;border-radius:999px;
}
.chip2:hover{border-color:var(--sky-400);background:var(--sky-50)}
.chip2.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
.chip2.on i{background:rgba(255,255,255,.22);color:#fff}
.chip2.clr{border-style:dashed;color:var(--slate);font-weight:500}
.chip2.lv2{font-size:11.5px;font-weight:500;color:var(--slate);border-style:dashed}
.chip2.lv2.on{color:#fff;border-style:solid}
.chip2.more{border-style:dashed;color:var(--sky-700);border-color:var(--sky-300);background:var(--sky-50);font-weight:600}
.chip2.more:hover{background:var(--sky-100)}
.chiprow-in{display:flex;align-items:center;gap:6px;flex-wrap:wrap;row-gap:6px}

/* ===== SOURCE: styles/commerce.css ===== */
/* ============ b175 · ngăn Bộ lọc + Cài đặt chia mục + kho tài khoản ============ */

.fpanel{
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r);
  padding:4px 12px 12px;margin-top:10px;
}
.fpanel .chiprow{margin-top:8px}
.btn.fbtn .fn{
  font-family:var(--f-mono);font-size:10.5px;font-weight:700;background:var(--sky-900);
  color:#fff;border-radius:999px;padding:0 6px;margin-left:2px;
}
.btn.fbtn .caret{margin-left:4px;font-size:10px;color:var(--slate)}
.btn.fbtn.on{border-color:var(--sky-400);background:var(--sky-50)}

.set-nav{
  display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px;
  border-bottom:1px solid var(--line);padding-bottom:12px;
}
.set-nav button{
  border:1px solid var(--line);background:var(--paper);color:var(--ink-2);
  border-radius:999px;padding:6px 14px;font-size:12.5px;font-weight:600;cursor:pointer;
}
.set-nav button:hover{background:var(--sky-50);border-color:var(--sky-300)}
.set-nav button.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}

.bk-list{display:flex;flex-direction:column;gap:8px}
.bk-row{
  display:flex;align-items:center;gap:10px;justify-content:space-between;
  border:1px solid var(--line);border-radius:var(--r);padding:9px 12px;background:var(--paper);
}
.bk-info{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;min-width:0}
.bk-info .num{font-family:var(--f-mono);font-weight:700}
.bk-ten{font-size:12.5px;color:var(--slate)}
.bk-act{display:flex;gap:6px;flex:0 0 auto}
.bk-edit{
  border:1px solid var(--sky-300);border-radius:var(--r);padding:12px;background:var(--sky-50);
  display:grid;grid-template-columns:1fr 1fr;gap:10px;
}
.bk-edit .f{margin:0}
.bk-edit-bar{grid-column:1/-1;display:flex;justify-content:flex-end}
@media (max-width:880px){
  .bk-edit{grid-template-columns:1fr}
  .bk-row{flex-wrap:wrap}
  .set-nav{overflow-x:auto;flex-wrap:nowrap;padding-bottom:10px}
  .set-nav button{white-space:nowrap}
}

.lrn{
  font-size:10px;font-weight:700;padding:1px 5px;border-radius:4px;
  background:var(--green-soft);color:var(--green);white-space:nowrap;
}
.navbtn.lockbtn{margin-top:6px;border-top:1px solid rgba(255,255,255,.14);padding-top:12px}
.navbtn.lockbtn.on{background:var(--or);color:#fff}
.navbtn.lockbtn.on::before{display:none}
.navbtn.lockbtn.on:hover{background:var(--or-6)}

/* ============ nhiều hóa đơn cùng lúc ============ */

.tabs::-webkit-scrollbar{height:0}

.tab:hover{background:var(--sky-50);color:var(--ink)}
.tab.on{
  background:var(--sky-900);color:#fff;border-color:var(--sky-900);
}
.tab.on .ts{color:#9AA3B2}
.tab.on i{opacity:.6;color:#fff}
.tab.on i:hover{background:rgba(255,255,255,.18);color:#fff}
.tab .tn{
  font-size:11px;font-weight:800;min-width:19px;height:19px;padding:0 5px;border-radius:10px;
  background:var(--or);color:#fff;display:grid;place-items:center;
}
.tab .ts{font-size:12.5px;color:var(--slate);font-weight:700}

.tab i{font-style:normal;font-size:13px;opacity:.4;padding:2px 4px;border-radius:4px;margin:-2px -4px -2px 0}
.tab i:hover{opacity:1;color:var(--red);background:var(--red-soft)}
.tab.add{
  background:var(--sky-50);border:1.5px dashed var(--sky-300);color:var(--sky-700);
  font-size:13.5px;font-weight:700;padding:9px 14px 9px 11px;gap:6px;
}
.tab.add b{
  font-size:17px;font-weight:700;line-height:1;width:22px;height:22px;border-radius:6px;
  background:var(--sky-600);color:#fff;display:grid;place-items:center;
}
.tab.add:hover{background:var(--sky-100);border-color:var(--sky-500);border-style:solid}
.tab.add:hover b{background:var(--or)}

/* ============ tiền khách đưa · tiền thối ============ */
.cashbox{
  margin-top:7px;padding:7px 9px;border-radius:var(--r);
  background:var(--paper);border:1px solid #D2D7DE;
}
.cashrow{display:flex;align-items:center;gap:10px;min-width:0;flex-wrap:wrap;margin-top:4px}
.cashrow .lb{font-size:12.5px;color:var(--slate);flex:0 0 auto}
.cashbox input{
  width:106px;flex:0 0 106px;text-align:right;font-family:var(--f-mono);font-size:14px;font-weight:700;
  padding:3px 8px;background:var(--paper);
}
.cashrow .chg{
  margin-left:auto;font-size:12px;font-weight:700;color:var(--green);white-space:nowrap;
}
.cashrow .chg b{font-family:var(--f-mono);font-size:15.5px;letter-spacing:-.3px;margin-left:3px}
.cashrow .chg.short{color:var(--red)}
.quickcash{display:flex;gap:5px;margin:9px 0 0;overflow-x:auto;min-width:0;scrollbar-width:none}
.quickcash::-webkit-scrollbar{height:0}
.quickcash button{
  flex:0 0 auto;padding:3px 8px;border-radius:5px;border:1px solid var(--line);background:var(--paper);
  font-family:var(--f-mono);font-size:11px;font-weight:700;color:var(--sky-700);
}
.quickcash button:hover{background:var(--sky-600);border-color:var(--sky-600);color:#fff}
.quickcash button.clr{font-family:var(--f-ui);color:var(--slate-2);border-style:dashed}
.quickcash button.clr:hover{background:var(--red-soft);border-color:#EDD3D0;color:var(--red)}

/* ============ kiểm kho bằng máy quét ============ */
.ck-scan{border-radius:var(--r-lg)}
.ck-step{display:flex;gap:3px;flex:0 0 auto}
.ck-step button{
  padding:6px 9px;border-radius:var(--r-sm);font-size:12px;font-weight:700;
  background:rgba(255,255,255,.12);color:#C9CFD8;
}
.ck-step button:hover{background:rgba(255,255,255,.2);color:#fff}
.ck-step button.on{background:var(--or);color:#fff}
.ck-last:empty{display:none}
.ck-last{margin-bottom:11px}
.ck-last-in{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.ck-lb{
  font-size:10px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--slate);
}
.ck-chip{
  display:inline-flex;align-items:baseline;gap:5px;padding:4px 9px;border-radius:100px;
  background:var(--sky-50);border:1px solid var(--line);font-size:12px;color:var(--ink-2);
}
.ck-chip.new{background:var(--green-soft);border-color:#BFE3D5;color:#0B5F44}
.ck-chip b{font-family:var(--f-mono);font-size:12.5px}
.ck-chip em{font-style:normal;font-size:10.5px;color:var(--slate-2);font-family:var(--f-mono)}

/* thanh tab xuống dòng thay vì cuộn ngang */
.tabs{display:flex;gap:5px;overflow-x:auto;padding-bottom:0;flex-wrap:wrap;overflow:visible;row-gap:5px}
.tab{display:inline-flex;align-items:center;gap:8px;flex:0 0 auto;padding:10px 14px;border-radius:var(--r);min-height:40px;background:var(--paper);border:1px solid var(--line);color:var(--ink-2);font-size:14px;font-weight:600;white-space:nowrap;transition:background .12s,color .12s,border-color .12s;max-width:180px}
.tab .tl{overflow:hidden;text-overflow:ellipsis}

/* khối kết quả tìm nằm ngay trên hàng bán chạy */

.res-x{
  width:27px;height:27px;border-radius:7px;display:grid;place-items:center;
  background:var(--red);color:#fff;font-size:14px;font-weight:800;box-shadow:0 1px 3px rgba(180,35,35,.24);
}
.res-x:hover{background:#9F1D1D;color:#fff}
/* Tiêu đề khu hàng là MỘT Ô SÁNG bên trái, không phải dải xám vắt ngang cả
   hàng (anh Đạt chốt 03/09). Đệm đều trên dưới nên chữ nằm giữa ô, không bị
   đẩy lên. Số lượng nằm trong huy hiệu cam đặc để đọc được từ xa. */
.res-head{display:flex;align-items:center;gap:8px;margin-bottom:9px;padding:0 0 8px;position:sticky;top:0;background:#EEF3F7;z-index:2}
.res-title{display:inline-flex;align-items:center;gap:7px;min-width:0;padding:7px 12px;border-radius:999px;
  background:var(--paper);border:1.5px solid var(--or);box-shadow:0 1px 4px rgba(249,115,22,.16);
  color:var(--or-safe);font-size:11px;font-weight:800;letter-spacing:.11em;text-transform:uppercase;line-height:1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.res-count{display:inline-grid;place-items:center;min-width:21px;height:21px;padding:0 6px;border-radius:999px;
  background:var(--or);color:var(--ink);font-size:11.5px;font-weight:800;letter-spacing:0}
.res-actions{margin-left:auto;display:flex;align-items:center;justify-content:flex-end;min-width:27px}
.res-head svg{width:14px;height:14px;stroke-width:2.2;color:var(--or)}
/* phiếu bán hàng ở giữa: chữ to hơn cho dễ soát */
.tape-hd{padding:9px 0 8px;border-bottom:1.5px dashed var(--line)}
.tape-hd .shop{font-size:15px}
.item .nm{font-size:13.5px;min-width:0;overflow-wrap:anywhere}
.item .icode{
  font-family:var(--f-mono);font-size:10px;font-weight:500;color:var(--slate-2);
  margin-left:6px;letter-spacing:.02em;
}
.item .tt{font-size:16px}   /* b229 · anh Đạt 11/09: "giá tiền nhìn to hơn 1 chút" — 14 → 16 */
.tape-ft{border-top:2px solid var(--sky-600);padding:6px 16px 8px;margin:0 -16px;background:#F7F9FB}
/* hàng đôi: hai cặp nhãn+ô trên cùng một dòng cho đỡ tốn chiều cao */
/* lưới 2x2: nhãn thẳng cột trái, ô nhập thẳng mép phải, cùng cỡ */
.ftgrid{display:grid;grid-template-columns:1fr 1fr;gap:4px 14px;margin:0}
.fcell{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-size:13px;color:var(--slate);white-space:nowrap;min-width:0}
.fcell input,.fcell select{width:112px;min-height:29px;flex:none;text-align:right;padding:3px 8px;
  font-size:12.5px;font-weight:700;font-family:var(--f-mono)}
.fcell select{text-align:left;font-family:var(--f-ui);color:var(--ink-2)}
/* Hình thức thanh toán: 3 nút liền nhau thay ô chọn xổ xuống (đối chiếu
   KiotViet, sổ tay mục 1b) — nhìn phát thấy đang chọn gì, bấm 1 nhịp.
   Nút đang chọn nền THAN (cam để dành cho Thanh toán & số tiền — ý đã chốt). */
.fcell.payseg{justify-content:stretch;gap:0}
.pseg{flex:1;min-height:29px;padding:4px;font-size:12px;font-weight:700;text-align:center;
  border:1px solid var(--line);background:var(--paper);color:var(--slate);
  white-space:nowrap;cursor:pointer;transition:background .1s,color .1s,border-color .1s}
.pseg:first-child{border-radius:8px 0 0 8px}
.pseg:last-child{border-radius:0 8px 8px 0}
.pseg+.pseg{border-left:0}
.pseg:hover:not(.on){background:var(--sky-50);color:var(--ink)}
.pseg.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
body.big .pseg{font-size:13.5px;padding:7px 4px}
.chgline{display:flex;justify-content:flex-end;align-items:center;gap:7px;
  font-size:12.5px;font-weight:600;color:var(--green);padding:2px 0}
.chgline.short{color:var(--red)}
.chgline b{font-size:15px}
.chgline .chgclr{width:20px;height:20px;border-radius:5px;display:grid;place-items:center;
  color:var(--slate-2);font-size:13px;font-weight:700;border:1px solid var(--line)}
.chgline .chgclr:hover{background:var(--red-soft);color:var(--red);border-color:#E3B9B4}
/* gợi ý mệnh giá khách hay đưa — bấm là điền, điền xong tự ẩn */
.cashsug{display:flex;justify-content:flex-end;gap:6px;padding:3px 0 1px;flex-wrap:nowrap}
.cashsug button{font-size:11.5px;font-weight:700;padding:3px 9px;border-radius:6px;
  background:var(--paper);border:1px solid var(--line);color:var(--ink-2);white-space:nowrap}
.cashsug button:hover{border-color:var(--or);color:var(--or-6)}
.trow{display:flex;justify-content:space-between;align-items:center;font-size:13px;padding:2px 0;color:var(--slate);gap:8px}
/* dòng hàng vừa thêm: sáng lên một nhịp cho dễ thấy */
.item.fresh{
  /* KHÔNG kéo lề âm — khung cắt phần tràn làm mất chữ cái đầu ("Vòi" thành "òi") */
  background:linear-gradient(90deg,var(--or-50),transparent 70%);
  animation:freshIn 1.1s ease-out;
  border-radius:5px;
}
@keyframes freshIn{0%{background-color:#FFE3C6}100%{background-color:transparent}}
@media (prefers-reduced-motion:reduce){.item.fresh{animation:none}}

/* ============ nhận diện bằng ảnh ============ */
.scan-eye{
  width:40px;height:40px;border-radius:var(--r);background:var(--sky-50);border:1px solid var(--line);
  display:grid;place-items:center;color:var(--sky-700);flex:0 0 auto;transition:background .12s,color .12s;
}
.scan-eye:hover{background:var(--or);border-color:var(--or);color:#fff}
.scan-eye svg{width:19px;height:19px;stroke-width:1.8}
.campane{
  display:flex;flex-direction:column;gap:10px;min-height:0;overflow:auto;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);padding:11px 12px 12px;
}
.campane[hidden]{display:none}
.cam-hd{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink)}
.cam-hd svg{width:16px;height:16px;stroke-width:2;color:var(--or)}
.cam-hd .ph-ai{margin:0}
.ph-wrap{display:grid;grid-template-columns:1fr minmax(230px,300px);gap:12px;min-height:0}
.ph-cam{position:relative;background:#000;border-radius:var(--r);overflow:hidden;aspect-ratio:4/3;max-height:46vh}
.ph-cam video{width:100%;height:100%;object-fit:cover;display:block}
.ph-box{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:62%;aspect-ratio:1;border:2px dashed rgba(255,255,255,.75);border-radius:12px;
  box-shadow:0 0 0 2000px rgba(0,0,0,.28);
}
.ph-side{min-height:180px;overflow:auto}
.ph-lb{font-size:10px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--slate);margin-bottom:7px}
.ph-empty{color:var(--slate-2);font-size:13px;padding:16px 0;text-align:center}
.ph-shot{width:100%;border-radius:var(--r);border:1px solid var(--line)}
.ph-list{display:grid;gap:5px;max-height:38vh;overflow:auto}
.ph-hit{
  display:flex;align-items:center;gap:9px;text-align:left;width:100%;
  padding:6px 8px;border:1px solid var(--line);border-radius:var(--r);background:var(--paper);
}
.ph-hit:hover{border-color:var(--sky-400);background:var(--sky-50)}
.ph-hit img,.ph-noimg{width:38px;height:38px;border-radius:6px;object-fit:cover;flex:0 0 auto;background:var(--line-2)}
.ph-n{flex:1;min-width:0;font-size:12.5px;font-weight:600;line-height:1.3}
.ph-n em{display:block;font-style:normal;font-size:10.5px;font-weight:500;color:var(--slate-2);font-family:var(--f-mono)}
.ph-hit b{font-family:var(--f-mono);font-size:13px;color:var(--slate)}
.ph-hit.hi{border-color:#BFE3D5;background:var(--green-soft)}
.ph-hit.hi b{color:var(--green)}
.ph-hit.mid{border-color:#F6D9BC;background:var(--or-50)}
.ph-hit.mid b{color:var(--or-7)}
.ph-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
.ph-acts .btn.acc{min-width:180px}
.ph-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.ph-card{border:1px solid var(--line);border-radius:var(--r-lg);padding:8px;text-align:center}
.ph-card img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:var(--r-sm);margin-bottom:6px}
.ph-cn{font-size:12px;font-weight:600;line-height:1.3;margin-bottom:2px}
.ph-cm{font-size:10.5px;color:var(--slate-2);font-family:var(--f-mono);margin-bottom:6px}
@media (max-width:900px){ .ph-wrap{grid-template-columns:1fr} }
.ph-tog{
  display:inline-flex;align-items:center;gap:6px;padding:7px 10px;font-size:12px;border-radius:var(--r);
  border:1px solid var(--line);background:var(--paper);font-size:12.5px;font-weight:600;color:var(--ink-2);
}
.ph-tog input{width:auto;margin:0}
.ph-tog:hover{border-color:var(--sky-400);background:var(--sky-50)}
.ph-badge-wrap{position:absolute;left:0;right:0;bottom:10px;display:flex;justify-content:center;pointer-events:none}
.ph-badge{
  padding:7px 14px;border-radius:100px;font-size:13px;font-weight:700;
  background:rgba(6,43,68,.82);color:#fff;backdrop-filter:blur(4px);
}
.ph-badge.ok{background:var(--green);animation:pop .25s ease-out}
@keyframes pop{from{transform:scale(.9);opacity:.6}to{transform:scale(1);opacity:1}}
@media (prefers-reduced-motion:reduce){.ph-badge.ok{animation:none}}
.ph-ai{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:10px}
.ph-i{
  width:19px;height:19px;border-radius:5px;flex:0 0 auto;display:grid;place-items:center;
  background:var(--sky-100);color:var(--sky-700);font-size:10.5px;font-weight:800;font-family:var(--f-mono);
}
.ph-hit.hi .ph-i{background:var(--green);color:#fff}
.ph-hit.mid .ph-i{background:var(--or);color:#fff}
.ph-cam.mirror video{transform:scaleX(-1)}
.ph-tools{position:absolute;top:8px;right:8px;display:flex;gap:6px}
.ph-tools button{
  width:34px;height:34px;border-radius:8px;display:grid;place-items:center;
  background:rgba(6,43,68,.62);color:#fff;backdrop-filter:blur(4px);
}
.ph-tools button:hover{background:var(--or)}
.ph-tools button svg{width:17px;height:17px;stroke-width:2}
.ph-tools button[hidden]{display:none}
.ph-badge.pick{background:var(--or);animation:pop .25s ease-out}

.ph-badge.look{background:rgba(6,43,68,.78)}

/* cảnh báo bán vượt tồn ngay trên dòng hàng */
.item .over{
  font-size:9.5px;font-weight:700;padding:1px 5px;border-radius:4px;margin-left:6px;
  background:var(--red-soft);color:var(--red);white-space:nowrap;vertical-align:1px;
}

/* bảng tra nhanh */
.hgrid{display:grid;grid-template-columns:1fr 1fr;gap:22px}
.hlb{
  font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--or-7);margin-bottom:7px;padding-bottom:5px;border-bottom:1px solid var(--line);
}
.htab{font-size:12.5px;width:100%}
.htab td{padding:5px 8px 5px 0;border:0;vertical-align:top;line-height:1.45}
.htab td:first-child{width:150px;color:var(--ink)}
.htab tr:hover{background:transparent}
.htab .kbd{font-size:11px}
@media (max-width:880px){ .hgrid{grid-template-columns:1fr;gap:14px} }

/* ===== SOURCE: styles/large-ui.css ===== */
/* ============================================================
   CỠ CHỮ LỚN — bấm nút "A" ở góc phải để bật
   Ưu tiên: chữ trên phiếu > nút bấm > thẻ hàng > ô nhập
   ============================================================ */
.bigbtn strong{font-size:16px;font-weight:800}
.bigbtn.on{background:var(--or);color:#fff}
.bigbtn.on:hover{background:var(--or-6);color:#fff}

/* ---- 1. Chữ và số tiền trên phiếu bán hàng ---- */
body.big .tape-hd .shop{font-size:18px}
body.big .item .nm{font-size:14px;font-weight:700}   /* b229 · 15,5 → 14: anh Đạt 11/09 "tên sp cũng không nên to quá" — giá 18px mới là thứ nổi */
body.big .item .icode{font-size:12px}
body.big .item .tt{font-size:18px;font-weight:800}
body.big .trow{font-size:14.5px;padding:3px 0}
body.big .fcell{font-size:14px}
body.big .fcell input,body.big .fcell select{width:118px;font-size:14px}
body.big .chgline{font-size:14px}
body.big .cashsug button{font-size:13px;padding:5px 11px}
body.big .chgline b{font-size:17px}
body.big .trow.tot{font-size:14px;letter-spacing:.06em}
body.big .trow.tot .num{font-size:25px}
body.big .cashrow .lb{font-size:15px}
body.big .cashrow .chg{font-size:15px}
body.big .cashrow .chg b{font-size:20px}
body.big .cust-row input{font-size:14.5px;padding:7px 10px}
body.big .custline{font-size:14px}

/* ---- 2. Nút bấm ---- */
body.big .btn{font-size:15px;padding:11px 18px}
body.big .btn.sm{font-size:13.5px;padding:8px 13px}
body.big .btn.big{padding:12px 18px;font-size:17px}
body.big .qbtn{width:29px;height:29px;font-size:17px}
body.big .item .del{width:28px;height:28px;font-size:16px}
body.big .icobtn{width:32px;height:32px}
body.big .icobtn svg{width:19px;height:19px}
body.big .quickcash button{font-size:13.5px;padding:6px 11px}
body.big .umode{font-size:13px;padding:4px 9px}

/* ---- 3. Thẻ hàng bán chạy ---- */
body.big .grid-p{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
body.big .pcard{min-height:132px;padding:14px 15px}
body.big .pcard .pn{font-size:17.5px;-webkit-line-clamp:3}
body.big .pcard .pmeta{font-size:13.5px}
body.big .pcard .pp{font-size:20px}
body.big .pcard .pu{font-size:13px}
body.big .pcard .stk{font-size:13px;padding:3px 8px}

/* ---- 4. Ô nhập số lượng và đơn giá ---- */
/* LỖI CŨ: width:62px bóp khung số lượng làm nút + bị CẮT MẤT ở cỡ chữ lớn
   (đo Playwright: nút chỉ còn 20-21px). Bỏ width cứng, nút nở theo con. */
body.big .item .qty{width:auto;font-size:15px;padding:0}
body.big .qty button{width:32px;height:32px;font-size:17px}
body.big .qty input{width:52px;font-size:14px}
body.big .item .ln .uplain,body.big .item .ln .umode{flex:0 0 auto}
body.big .item .ttx{font-size:12px}
body.big input,body.big select{font-size:15px}

/* ---- các phần khác vừa phải ---- */
body.big{font-size:15px}
body.big .scan-field input{font-size:19px}
body.big .scan-field label{font-size:11.5px}
body.big .head h1{font-size:17.5px}
body.big .navbtn{font-size:11.5px;padding:12px 4px}
body.big .navbtn svg{width:23px;height:23px}
body.big .tab{font-size:15.5px;min-height:46px;padding:11px 16px}
body.big .tab .ts{font-size:14px}
body.big .tab.add{font-size:15px}
body.big table{font-size:14.5px}
body.big thead th{font-size:11px}
body.big .kpi .v{font-size:26px}
body.big .kpi .k{font-size:12.5px}
body.big .m-hd h3{font-size:17px}
body.big .empty h3{font-size:17px}
body.big .empty p{font-size:14.5px}
body.big .res-title{font-size:12.5px;padding:8px 13px}
body.big .res-count{min-width:23px;height:23px;font-size:13px}
body.big .hint,body.big .note{font-size:13.5px}
body.big .pill{font-size:12.5px}

/* cột phiếu rộng thêm khi chữ to, để tên hàng không bị cắt */
body.big .tape{border-width:3px}
body.big .tape-in{padding:0 18px}
body.big .tape-bar{padding:13px 18px;margin:0 -18px}
body.big .tape-ft{padding:9px 18px 11px;margin:0 -18px}
/* b229 · lề ngang 6px như cỡ thường: thẻ dòng có viền khi rê chuột (b127), lề 0 là chữ và
   khung số lượng dính sát viền thẻ */
body.big .item{padding:12px 6px;--cot-xoa:22px;--xoa:28px;--dong1:20px}
body.big .tape-bar .tt{font-size:14px}
body.big .tape-bar .no{font-size:15px}
body.big .tape-date{font-size:10.5px}
body.big .pos3{grid-template-columns:minmax(0,1fr) 520px}
body.big .tape-in{padding:0 16px}
@media (max-width:1500px){ body.big .pos3{grid-template-columns:minmax(0,1fr) 470px} }
@media (max-width:1200px){ body.big .pos3{grid-template-columns:minmax(0,1fr) 420px} }

/* ============ đo & đếm bằng camera ============ */
.mz-wrap{display:grid;grid-template-columns:1fr 300px;gap:14px}
.mz-stage{position:relative;background:#0b1b26;border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/3}
.mz-stage video,.mz-stage canvas{width:100%;height:100%;object-fit:contain;display:block}
.mz-stage canvas{display:none}
.mz-stage.shot video{display:none}
.mz-stage.shot canvas{display:block}
.mz-stage.shot .mz-hint-live{display:none}
.mz-hint-live{
  position:absolute;left:0;right:0;bottom:10px;text-align:center;
  font-size:12.5px;color:#fff;text-shadow:0 1px 4px rgba(0,0,0,.7);pointer-events:none;
}
.mz-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.mz-side{min-width:0}
.mz-range{width:100%;margin:2px 0 4px}
.mz-count{
  font-family:var(--f-mono);font-size:34px;font-weight:800;color:var(--or-7);line-height:1;
}
.mz-count span{display:block;font-family:var(--f-ui);font-size:11.5px;font-weight:600;color:var(--slate-2);margin-top:3px}
.mz-tab{width:100%;font-size:12.5px}
.mz-tab td{padding:4px 6px 4px 0;border-bottom:1px solid var(--line-2)}
.mz-tab tr:hover{background:transparent}
@media (max-width:900px){ .mz-wrap{grid-template-columns:1fr} }

/* ---------- ảnh sản phẩm ---------- */
.pcard .pimg{
  position:absolute;right:9px;bottom:8px;top:auto;width:39px;height:39px;object-fit:contain;
  background:#fff;border:1px solid #AEBFCB;border-radius:7px;padding:2px;cursor:zoom-in;
}
.pcard.wide .pimg{width:46px;height:46px}
/* b202 · MÀU ĐỘ DÀY nằm ở VIỀN Ô ẢNH — anh Đạt 05/09: "ý t chỉ cần đổi màu phần viền
   nhỏ này thôi". Chỉ thẻ hàng sắt mới mang `data-ly`, xem lySat() trong catalog-core.js.
   Viền dày lên 2px và bớt padding 1px để ô ảnh không đổi kích thước.
   Quy ước: xám 0,8–0,9ly · xanh lá 1ly · đỏ 1,1–1,2ly · vàng 1,3–1,4ly (và 2ly). */
.pcard[data-ly] .pimg{border-color:var(--ly);border-width:2px;padding:1px}
.pcard[data-ly="08"]{--ly:#8A939F}
.pcard[data-ly="10"]{--ly:#0B8A34}
.pcard[data-ly="12"]{--ly:#D42A20}
.pcard[data-ly="14"]{--ly:#F5C400}
.pimg-prog{height:8px;border-radius:8px;background:var(--sky-100);overflow:hidden;margin:6px 0}
.pimg-prog>div{height:100%;background:var(--sky-600);transition:width .2s}
body.big .pcard .pimg{width:48px;height:48px;bottom:9px}
body.big .pcard .pn{padding-right:58px}
body.big .pcard .prow{padding-right:60px}
.ph-badge.warn{background:#B45309;color:#fff}

/* thấy nhiều món trong khung */
.ph-many{
  text-align:center;padding:22px 16px;border:2px dashed var(--or);border-radius:var(--r-lg);
  background:var(--or-50);
}
.ph-many .n{font-family:var(--f-mono);font-size:42px;font-weight:800;color:var(--or-7);line-height:1}
.ph-many .t{font-size:13px;color:var(--slate);margin-top:2px;font-weight:600}

/* nút Tiếp tục — to, dễ bấm */
.btn-next{
  width:100%;margin-top:12px;padding:16px 18px;border-radius:var(--r-lg);
  background:linear-gradient(180deg,var(--or),var(--or-6));color:#fff;
  font-size:16px;font-weight:800;letter-spacing:.01em;
  display:flex;flex-direction:column;align-items:center;gap:3px;
  box-shadow:0 3px 10px rgba(249,115,22,.30);transition:transform .1s,box-shadow .12s;
  border:0;cursor:pointer;
}
.btn-next:hover{box-shadow:0 5px 16px rgba(249,115,22,.42)}
.btn-next:active{transform:translateY(1px)}
.btn-next svg{width:19px;height:19px}
.btn-next em{font-size:11.5px;font-weight:600;font-style:normal;opacity:.9}
body.big .btn-next{padding:20px;font-size:19px}
body.big .btn-next em{font-size:13px}

/* báo đã thêm xong */
.ph-done{
  text-align:center;padding:20px 14px;border-radius:var(--r-lg);
  background:var(--green-soft);color:var(--green);font-size:14.5px;font-weight:700;
}
.ph-done svg{width:32px;height:32px;stroke-width:2.4;margin-bottom:6px}

/* ===== SOURCE: styles/management.css ===== */
/* ---------- THẺ CHUYỂN MỤC kiểu mới (b121) — có biểu tượng, tương phản mạnh ----------
   Dùng ở: Sản phẩm, Công nợ, Báo cáo. Thẻ đang chọn nền THAN chữ trắng;
   bên nào có khoản quá hạn thì nền ĐỎ SẪM + huy hiệu. */
.tabs2{display:flex;gap:9px;margin-bottom:16px;flex-wrap:wrap}
.tb{flex:1;min-width:210px;display:flex;align-items:center;gap:11px;cursor:pointer;text-align:left;
  border:1.5px solid var(--line);background:#fff;border-radius:13px;padding:11px 14px;font:inherit;color:var(--ink)}
.tb-ic{width:36px;height:36px;flex:0 0 36px;border-radius:10px;background:var(--sky-50);
  display:flex;align-items:center;justify-content:center}
.tb-ic svg{width:19px;height:19px;stroke:var(--slate);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.tb-tx{display:flex;flex-direction:column;min-width:0}
.tb .t{font-size:14.5px;font-weight:800;line-height:1.25}
.tb .n{font-size:12px;font-weight:600;color:var(--slate);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tb:hover:not(.on){border-color:var(--sky-300);background:var(--sky-50)}
.tb.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
.tb.on .tb-ic{background:rgba(255,255,255,.14)}
.tb.on .tb-ic svg{stroke:#fff}
.tb.on .n{color:#C5CBD4}
.tb.on.warn{background:#6E1E19;border-color:#6E1E19}
.tb-bg{margin-left:auto;flex:0 0 auto;background:var(--red);color:#fff;font-size:11px;font-weight:800;
  border-radius:99px;padding:2px 9px;white-space:nowrap}
@media (max-width:820px){ .tb{min-width:100%} }

/* Trung tâm Quản lý b157: số cần quyết định trước, lối vào công cụ sau.
   b229 · anh Đạt 11/09: "chỉ có 8 mục cho gọn trong 1 trang k phải cuộn" — ba tầng: dòng trạng thái · việc chờ chủ
   (chỉ khi có) · số hôm nay + công cụ 4 × 2. Khối chữ giới thiệu đầu màn (~100px) bỏ: tiêu đề màn đã nói điều đó. */
.smart-section{max-width:1120px;margin:0 auto}
.mg-top{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin:0 2px var(--space-3)}
.mg-status{margin:0;font-size:12.5px;color:var(--slate);display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}
.mg-link{min-height:32px}
.mg-viec{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2);margin:0 0 var(--space-3);
  padding:var(--space-2) var(--space-3);background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg)}
.mg-viec-t{font-size:12.5px;font-weight:700;margin-right:var(--space-1)}
.viec-chip{display:inline-flex;align-items:center;gap:var(--space-1);min-height:40px;padding:0 var(--space-3);border-radius:999px;
  border:1px solid var(--line);background:var(--sky-50);color:var(--ink);font:inherit;font-size:12.5px;font-weight:600;
  cursor:pointer;transition:border-color var(--motion-fast),box-shadow var(--motion-fast)}
.viec-chip b{font-size:14px;font-weight:800}
.viec-chip.rd{background:var(--red-soft);border-color:transparent;color:var(--red)}
.viec-chip.am{background:var(--or-50);border-color:transparent;color:var(--or-safe)}
.viec-chip:hover{border-color:currentColor;box-shadow:var(--shadow)}
.mg-h{margin:0 2px var(--space-2);font-size:12.5px;font-weight:700}
.ops-overview{display:grid;grid-template-columns:repeat(auto-fit,minmax(205px,1fr));gap:var(--space-3);margin-bottom:var(--space-4)}
.ops-stat{position:relative;min-height:84px;display:flex;flex-direction:column;align-items:flex-start;
  justify-content:center;padding:var(--space-3) var(--space-4);text-align:left;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-lg);color:var(--ink);overflow:hidden;transition:border-color var(--motion-fast),box-shadow var(--motion-fast)}
button.ops-stat:hover{border-color:var(--sky-300);box-shadow:var(--shadow)}
.ops-stat::before{content:'';position:absolute;inset:0 auto 0 0;width:3px;background:var(--sky-500)}
.ops-stat.am::before{background:var(--or)}
.ops-stat.rd::before{background:var(--red)}
.ops-label{font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--slate)}
.ops-value{margin-top:5px;font-size:22px;font-weight:800;letter-spacing:-.6px;line-height:1.15;color:var(--ink)}
.ops-note{margin-top:4px;max-width:100%;font-size:11px;color:var(--slate);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ops-open{position:absolute;right:13px;top:12px;color:var(--sky-400);font-size:22px;font-weight:300}
.smart-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-3)}
.smart-tile{
  min-height:86px;width:100%;display:grid;grid-template-columns:44px minmax(0,1fr) auto 18px;
  align-items:center;gap:12px;padding:14px;text-align:left;background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r-lg);color:var(--ink);
  transition:border-color .12s,background .12s,box-shadow .12s
}
.smart-tile:hover{background:var(--sky-50);border-color:var(--sky-300);box-shadow:var(--shadow)}
.smart-icon{width:44px;height:44px;border-radius:12px;background:var(--sky-50);color:var(--slate);
  display:grid;place-items:center}
.smart-icon svg{width:21px;height:21px;stroke-width:1.9}
.smart-icon.am{background:var(--or-50);color:var(--or-safe)}
.smart-icon.bp{background:var(--sky-100);color:var(--sky-700)}
.smart-icon.rd{background:var(--red-soft);color:var(--red)}
.smart-copy{display:flex;flex-direction:column;min-width:0}
.smart-copy strong{font-size:14px;font-weight:750}
.smart-copy span{font-size:11.5px;color:var(--slate);margin-top:3px;line-height:1.45}
.smart-count{min-width:27px;height:27px;padding:0 7px;border-radius:99px;display:grid;place-items:center;
  background:var(--sky-100);color:var(--sky-700);font-size:11px;font-weight:800}
.smart-count.am{background:var(--or-50);color:var(--or-safe)}
.smart-count.rd{background:var(--red-soft);color:var(--red)}
.smart-arrow{font-size:25px;line-height:1;color:var(--sky-400);font-weight:300}
/* Công cụ 4 × 2: ô thấp, chữ phụ tối đa hai dòng (đủ chữ thì rê chuột đọc ở title), số đếm góc phải. */
.smart-grid.cong-cu{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:1fr}
.cong-cu .smart-tile{min-height:76px;grid-template-columns:36px minmax(0,1fr) auto;gap:var(--space-3);padding:var(--space-3)}
.cong-cu .smart-icon{width:36px;height:36px;border-radius:var(--r)}
.cong-cu .smart-icon svg{width:19px;height:19px}
.cong-cu .smart-copy span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (max-width:1120px){ .smart-grid.cong-cu{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:760px){
  .smart-grid,.smart-grid.cong-cu{grid-template-columns:1fr}.smart-section{max-width:none}
  .ops-overview{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-bottom:var(--space-4)}
  .ops-stat{min-height:84px;padding:12px}.ops-value{font-size:19px}.ops-note{white-space:normal}
  .mg-top{align-items:flex-start}.viec-chip{min-height:44px}
}

/* ---------- bảng hóa đơn gọn + nút hành động nằm ngang (b121) ---------- */
/* Dòng phụ là chữ nhỏ nhất màn hình — --slate-2 chỉ đạt tương phản 3.35:1,
   đổi sang --slate cho đạt 5.51:1 (WCAG 4.5:1, sổ tay mục 1). */
.cell-sub{font-size:11.5px;color:var(--slate);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rowacts{display:flex;gap:5px;justify-content:flex-end;flex-wrap:nowrap}
/* Cao ~40px cho đạt vùng bấm (padding dọc 10px, sổ tay mục 1) */
.actbtn{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--line);background:#fff;
  border-radius:9px;padding:10px 12px;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink);cursor:pointer;white-space:nowrap}
.actbtn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.actbtn:hover{background:var(--sky-50);border-color:var(--sky-300)}
/* chữ #A34A05 thay --or-7: qua mốc tương phản 4.5:1 trên nền cam nhạt */
.actbtn.key{background:var(--or-50);border-color:#F5C89A;color:#A34A05}
.actbtn.key:hover{background:#FFE7CE}
.actbtn.dg{color:var(--red);border-color:#F0D2D0}
.actbtn.dg:hover{background:#FDF2F2}
.inv-tbl td,.prod-tbl td,.sup-tbl td{vertical-align:middle}
/* Dòng hóa đơn / phiếu giao để THOÁNG hơn — mỗi trang chỉ 8 dòng, dưới còn
   trống nhiều mà chữ lại nhỏ, nhìn mỏi mắt (b125). */
.inv-tbl td{padding:18px 12px;font-size:14px}
.inv-tbl thead th{padding-top:12px;padding-bottom:12px;font-size:11.5px}
.inv-tbl td strong{font-size:14.5px}
.inv-tbl .cell-sub{font-size:12.5px;margin-top:4px}
.inv-tbl .tag{font-size:12px;padding:4px 9px}
.inv-tbl .actbtn{padding:10px 12px;font-size:13px;border-radius:10px}
.inv-tbl .actbtn svg{width:16px;height:16px}
.inv-tbl .rowacts{gap:6px}
.prod-tbl td strong{font-size:13.5px}
.prod-tbl .cell-sub{max-width:340px}
/* Ảnh thu nhỏ 28px trước tên hàng (đối chiếu KiotViet, sổ tay mục 1b) —
   hàng VLXD tên na ná nhau, cái ảnh nhận ra nhanh hơn đọc chữ. */
.pcell{display:flex;align-items:center;gap:10px;min-width:0}
.pcell>div{min-width:0}
.ptimg{width:28px;height:28px;flex:0 0 28px;object-fit:cover;border-radius:6px;
  border:1px solid var(--line-2);background:#fff}
.ptimg.none{background:var(--sky-50);border-style:dashed}

/* ---------- dòng TỔNG tách hẳn khỏi dòng cuối (b122) ----------
   Trước đây dòng tổng chỉ khác nền một chút nên nhìn như một dòng dữ liệu nữa. */
tfoot.tf-sum tr td{
  border-top:2px solid var(--sky-300);
  background:var(--sky-50);
  padding-top:13px;padding-bottom:13px;
  font-weight:800;font-size:12px;letter-spacing:.4px;color:var(--sky-600);
}
tfoot.tf-sum tr td.big{font-size:15.5px;letter-spacing:-.3px;color:var(--ink)}
tfoot.tf-sum tr td.num{font-family:var(--f-mono)}

/* ---------- chuyển trang (b122) ---------- */
.pgbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:space-between;
  padding:11px 14px;border-top:1px solid var(--line)}
.pgi{font-size:12.5px;color:var(--slate)}
.pgi strong{color:var(--ink);font-family:var(--f-mono)}
.pgn-wrap{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.pgn{min-width:40px;height:40px;padding:0 9px;border:1px solid var(--line);background:#fff;border-radius:8px;
  font:inherit;font-size:13px;font-weight:700;color:var(--ink);cursor:pointer;font-family:var(--f-mono)}
.pgn.nav{font-family:var(--f-ui);font-size:12.5px;font-weight:600;color:var(--slate)}
.pgn:hover:not(:disabled){background:var(--sky-50);border-color:var(--sky-300)}
.pgn.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
.pgn:disabled{opacity:.38;cursor:default}
.pgd{color:var(--slate-2);padding:0 2px}

/* ---------- chip lọc nhanh (b122) ---------- */
.fchips{display:flex;gap:6px;flex-wrap:wrap}
.fchip{border:1px solid var(--line);background:#fff;border-radius:999px;padding:5px 12px;
  font:inherit;font-size:12.5px;font-weight:600;color:var(--slate);cursor:pointer}
.fchip:hover{background:var(--sky-50);border-color:var(--sky-300);color:var(--ink)}
.fchip.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
.fchip .fn{font-family:var(--f-mono);opacity:.75;margin-left:2px}
.actbtn.done{background:var(--green-soft);border-color:#A9D8C6;color:var(--green)}
/* ô tick trong form (b123) */
.chk{display:flex;align-items:center;gap:8px;min-height:40px;font-size:13px;cursor:pointer}
.chk input{width:17px;height:17px;flex:none;accent-color:var(--or-6);cursor:pointer}

/* Trả hàng trong màn Sửa hóa đơn */
.ei-ret{display:flex;align-items:center;gap:14px;justify-content:space-between;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:11px;padding:11px 14px;margin-bottom:12px;background:var(--sky-50)}
.ei-ret .btn{white-space:nowrap}

/* ---------- thẻ chuyển mục cũ (Dữ liệu) ---------- */
.dtabs{display:flex;gap:4px;background:var(--sky-100);border-radius:12px;padding:4px;margin-bottom:16px;flex-wrap:wrap}
.dtab{flex:1;min-width:150px;border:0;background:transparent;border-radius:9px;padding:9px 12px;cursor:pointer;
  font:inherit;font-size:14px;font-weight:700;color:var(--sky-500);text-align:center;line-height:1.25}
.dtab small{display:block;font-size:11.5px;font-weight:600;color:var(--sky-400);margin-top:2px}
.dtab.on{background:#fff;color:var(--sky-900);box-shadow:0 1px 3px rgba(0,0,0,.12)}
.dtab.on small{color:var(--or-6)}
.dtab:hover:not(.on){background:rgba(255,255,255,.55)}
.dtab .bg{display:inline-block;background:var(--red);color:#fff;border-radius:99px;font-size:10.5px;padding:0 6px;margin-left:5px;vertical-align:1px}

/* ---------- BÁO CÁO: biểu đồ cột, thanh ngang, dòng tiền, tuổi nợ (b120) ---------- */
.rgrid2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}
@media (max-width:1100px){ .rgrid2{grid-template-columns:1fr} }
.delta{display:inline-block;font-size:11.5px;font-weight:800;border-radius:99px;padding:1px 7px;margin-left:6px}
.delta.up{background:#E7F6EC;color:#177245}
.delta.dn{background:#FDECEC;color:#B3261E}

.rchart{padding:2px 0 0}
.rcols{display:flex;align-items:flex-end;gap:3px;height:180px}
.rcol{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%;min-width:6px}
.rcol i{display:block;width:100%;background:#FDBA74;border-radius:4px 4px 0 0;transition:background .12s}
.rcol.hi i{background:var(--or-7)}
.rcol:hover i{background:var(--or)}
.rcol b{font-size:11px;font-weight:800;color:var(--slate);margin-bottom:3px;white-space:nowrap}
.rxax{display:flex;gap:3px;margin-top:6px}
.rxax span{flex:1;text-align:center;font-size:10.5px;color:var(--slate-2);min-width:6px;overflow:hidden}

.hbar{display:grid;grid-template-columns:130px 1fr 96px;align-items:center;gap:10px;margin-bottom:8px}
.hbar .hb-n{font-size:13px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hbar .hb-t{height:15px;background:var(--sky-100);border-radius:5px;overflow:hidden}
.hbar .hb-t i{display:block;height:100%;background:#FDBA74;border-radius:5px}
.hbar.top .hb-t i{background:var(--or-7)}
.hbar .hb-v{font-size:13px;font-weight:700;text-align:right;font-variant-numeric:tabular-nums}

.stkbar{display:flex;height:36px;border-radius:9px;overflow:hidden;gap:2px}
.stkbar div{display:flex;align-items:center;justify-content:center;color:#fff;font-size:12.5px;font-weight:700;white-space:nowrap;overflow:hidden}
.stkbar .s1{background:var(--or-7)}
.stkbar .s2{background:#8791A0}
.stklg{display:flex;gap:18px;flex-wrap:wrap;font-size:12.5px;color:var(--slate);font-weight:600;margin-top:8px}
.stklg i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:-1px}
.stklg i.c1{background:var(--or-7)} .stklg i.c2{background:#8791A0}
.cashline{display:flex;gap:26px;flex-wrap:wrap;margin-top:12px;padding-top:12px;border-top:1px solid var(--line);font-size:13px}

.ages{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
.agec{border:1px solid var(--line);border-radius:10px;padding:10px 12px}
.agec .t{font-size:12px;font-weight:700;color:var(--ink)}
.agec .m{font-size:19px;font-weight:800;margin-top:3px;font-variant-numeric:tabular-nums}
.agec .c{font-size:11.5px;color:var(--slate);margin-top:2px}
.agec.gn{background:#F1FAF4;border-color:#CBE9D6} .agec.gn .m{color:#177245}
.agec.am{background:#FFF8EC;border-color:#F5E0B8} .agec.am .m{color:#9A6200}
.agec.rd{background:#FDF2F2;border-color:#F3CFCC} .agec.rd .m{color:#B3261E}

.minibar{height:5px;background:var(--sky-100);border-radius:3px;margin:4px 0 2px;max-width:280px}
.minibar i{display:block;height:100%;background:#FDBA74;border-radius:3px}
@media print{ .rchart,.hbar,.stkbar,.ages{break-inside:avoid} }


/* chấm cam đánh dấu tab khách đang mở (b121 — tab không còn hiện số món/tiền) */
.tab .tdot{width:7px;height:7px;border-radius:99px;background:var(--or);flex:0 0 7px}
/* KPI có viền màu bên trái cho dễ phân biệt (b121) */
.kpi{border-left:4px solid var(--line)}
.kpi.gn{border-left-color:#2E9E63} .kpi.rd{border-left-color:#D8524A}
.kpi.am{border-left-color:#E3A008} .kpi.bp{border-left-color:#5A7BA6}
.kpi.or,.kpis .kpi:first-child{border-left-color:var(--or)}

/* ---------- Khóa khi app mở ở cửa sổ khác (b127) ---------- */
#tablock{position:fixed;inset:0;z-index:9000;background:rgba(24,27,32,.72);
  display:grid;place-items:center;padding:24px;backdrop-filter:blur(3px)}
#tablock .tl-box{background:#fff;border-radius:16px;max-width:460px;width:100%;
  padding:26px 26px 22px;text-align:center;box-shadow:var(--shadow-lg)}
#tablock .tl-ic{width:52px;height:52px;margin:0 auto 12px;border-radius:14px;
  background:var(--or-50);display:grid;place-items:center}
#tablock .tl-ic svg{width:28px;height:28px;stroke:var(--or-7);fill:none;stroke-width:1.9}
#tablock h2{font-size:18px;margin:0 0 10px;color:var(--ink)}
#tablock p{font-size:13.5px;color:var(--slate);margin:0 0 10px;line-height:1.55}
#tablock .tl-sub{font-size:12.5px;color:var(--slate-2)}
#tablock .btn{margin-top:6px;padding:11px 20px;font-size:14px}

/* ---------- Ghi chú từng món trong phiếu bán + dòng nổi lên (b127) ---------- */
.item{border:1px solid transparent;border-radius:10px;padding:6px 6px;
  transition:box-shadow .12s, border-color .12s, background .12s}
.item:hover,.item:focus-within{
  border-color:#B9D4F5;background:#fff;
  box-shadow:0 2px 4px rgba(24,27,32,.06), 0 8px 20px rgba(24,27,32,.10)}
/* b229 · ô ghi chú nằm NGAY TRONG hàng số lượng (bên phải) và chỉ hiện/ẩn bằng ĐỘ
   MỜ. Trước đây nó là một hàng riêng bung ra khi rê chuột (0 → 22px), đẩy mọi dòng
   bên dưới xuống: rê từ dòng trên xuống bấm X dòng dưới thì X chạy lên 22px đúng lúc
   con trỏ tới (anh Đạt 11/09: "thấy dấu X có di chuyển"). Dòng ĐÃ có ghi chú thì ô
   chiếm trọn một hàng để đọc đủ chữ — cái đó cố định, không đổi theo con trỏ. */
.item .ntrow{flex:1 1 120px;min-width:0;display:flex;align-items:center;gap:5px;
  font-family:var(--f-ui);opacity:0;transition:opacity .12s}
.item .ntrow.has{flex-basis:100%}
.item:hover .ntrow,.item:focus-within .ntrow,.item .ntrow.has{opacity:1}
.item .ntrow svg{width:12px;height:12px;stroke:var(--slate-2);fill:none;stroke-width:1.9;flex:0 0 auto}
.item .ntin{flex:1;min-width:0;border:0;border-bottom:1px dashed var(--line);border-radius:0;
  background:transparent;font:inherit;font-size:11.5px;color:var(--ink);padding:2px 0}
.item .ntin::placeholder{color:var(--slate-2);font-style:italic}
.item .ntin:focus{border-bottom-color:var(--or);box-shadow:none;background:var(--or-50)}
.item .ntrow.has .ntin{color:var(--sky-600);font-style:italic}
/* b222 · hàng PHA MÀU của dòng sơn — b224 dựng lại theo ba ý anh Đạt 10/09:
   ô màu TO như ảnh sản phẩm · chỗ tiền chỉ có SỐ, không chữ thừa · không được
   tràn ra rìa (ảnh anh gửi: ô màu đè lên viền trái, "/lon" bị cắt).
   Chống tràn bằng ba thứ: cột giữa `min-width:0` (mặc định của flex là auto,
   chính nó làm hàng phình ra), `flex-wrap`, và ô nhập co được. */
/* b225 · Hàng màu là MỘT PHẦN của dòng sơn, không phải một dòng hàng nữa.
   Vạch đứt cũ trông y hệt vạch ngăn giữa hai món, nên trên ảnh 10/09 hàng màu
   như đang thuộc về món kế tiếp. Nay: nền xanh nhạt bo góc, thụt vào — mắt
   thấy ngay nó dính với dòng bên trên.
   `padding-right` chừa đúng cột cây bút sửa giá (b229: --cot-but + 8px khe cột) để
   tiền màu THẲNG CỘT với thành tiền của dòng. Hàng màu bắt đầu ở cột tên (cột 2), cột
   nút X bên trái để trống cho thẳng mép với tên và khung số lượng. */
.item .maurow{
  grid-column:2/-1;display:flex;align-items:center;gap:8px;flex-wrap:wrap;row-gap:4px;
  margin-top:5px;padding:5px calc(var(--cot-but) + 8px) 5px 6px;border-radius:8px;
  background:var(--sky-50);min-width:0;
}
/* Ô màu bằng đúng cỡ ảnh sản phẩm ở thẻ hàng (39px) — anh Đạt: "muốn màu nhìn
   to như ảnh sản phẩm luôn, không phải chỉ nhỏ như vậy". Rê vào phóng 2,4× và
   NỔI LÊN TRÊN (z-index) chứ không đẩy chữ, vì transform không chiếm chỗ. */
.item .mauo{
  width:39px;height:39px;flex:0 0 39px;border-radius:7px;border:1px solid #AEBFCB;
  background:var(--mau,#fff);cursor:zoom-in;
  transition:transform .12s cubic-bezier(.2,.7,.3,1), box-shadow .12s;
  transform-origin:left center;
}
.item .mauo:hover{transform:scale(2.4);box-shadow:0 6px 22px rgba(24,27,32,.3);position:relative;z-index:6}
/* Chưa có mẫu màu thì GẠCH CHÉO — không tô một màu đoán. Ô trắng trơn dễ bị
   hiểu là "màu trắng"; vạch chéo nói rõ "chưa biết". */
.item .mauo.trong{background:repeating-linear-gradient(45deg,#fff 0 5px,var(--line) 5px 6px);cursor:default}
.item .mauo.trong:hover{transform:none;box-shadow:none}
/* Cột giữa: ô gõ mã + tên màu + danh sách gợi ý. `min-width:0` là chốt chống
   tràn — thiếu nó là cả hàng đẩy ra ngoài khung phiếu. */
.item .maugiua{flex:1 1 130px;min-width:0;display:flex;flex-direction:column;gap:1px}
.item .mauin{
  width:100%;min-width:0;border:0;border-bottom:1px dashed var(--line);border-radius:0;
  background:transparent;font:inherit;font-size:12px;font-weight:700;letter-spacing:.02em;
  text-transform:uppercase;color:var(--ink);padding:2px 0;
}
.item .mauin::placeholder{color:var(--slate-2);font-weight:400;font-style:italic;text-transform:none}
.item .mauin:focus{border-bottom-color:var(--or);box-shadow:none;background:var(--or-50)}
/* b227 · Dòng dưới mã màu: [Base C] + tên màu. Base phải NỔI hơn tên, vì tên
   là để đối chiếu với khách còn base là để người bán đi lấy đúng thùng. */
.item .maudb{display:flex;align-items:center;gap:5px;min-width:0}
.item .maubase{
  flex:0 0 auto;font-size:10px;font-weight:800;letter-spacing:.02em;
  padding:1px 5px;border-radius:4px;white-space:nowrap;
  background:var(--sky-100);color:var(--sky-700);border:1px solid var(--sky-300);
}
.item .mauten{font-size:10.5px;color:var(--slate);line-height:1.25;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Ba gợi ý — chọn bằng mắt: ô màu thật đứng trước mã và tên. */
.item .maugoi{display:flex;flex-direction:column;gap:2px;margin-top:3px}
.item .maugoi button{
  display:flex;align-items:center;gap:6px;width:100%;min-width:0;padding:3px 5px;
  border:1px solid var(--line);border-radius:6px;background:var(--paper);text-align:left;
}
.item .maugoi button:hover{border-color:var(--sky-400);background:var(--sky-50)}
.item .maugoi b{font-size:11px;font-weight:700;font-family:var(--f-mono);color:var(--ink);white-space:nowrap}
/* b228 · Mỗi dòng gợi ý phải đủ để CHỌN BẰNG MẮT: ô màu + mã + BASE + tên.
   Anh Đạt 10/09: "bằng tên ghi chưa đủ" — nhiều mã hãng không đặt tên, chỉ
   thấy mỗi mã thì không biết dòng nào là dòng mình cần. */
.item .maugoi .maugb{
  flex:0 0 auto;font-style:normal;font-size:9.5px;font-weight:800;
  padding:0 4px;border-radius:3px;white-space:nowrap;
  background:var(--sky-100);color:var(--sky-700);
}
.item .maugoi span{font-size:10.5px;color:var(--slate);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.item .mauog{width:18px;height:18px;flex:0 0 18px;border-radius:4px;border:1px solid #AEBFCB;background:var(--mau,#fff)}
.item .mauog.trong{background:repeating-linear-gradient(45deg,#fff 0 4px,var(--line) 4px 5px)}
/* b225b · Hàng màu chỉ còn ĐÚNG MỘT con số. Anh Đạt 10/09, hai lần: "chỗ tiền
   chỉ hiện số, không ghi thêm gì" rồi "phần giá/lít bỏ". Ô "lít/lon" đã bỏ ở
   b225 (dung tích chọn trên dòng hàng), ô "số màu/lít" bỏ nốt ở đây.
   Con số này CHÍNH LÀ chỗ sửa — trông như chữ thường, rê vào mới hiện viền. */
.item .mautt{display:flex;align-items:center;gap:2px;flex:0 0 auto;margin-left:auto;
  font-size:12.5px;color:var(--ink);white-space:nowrap}
.item .mautti{
  width:84px;min-width:84px;padding:2px 4px;text-align:right;border:1px solid transparent;
  border-radius:5px;background:transparent;font-family:var(--f-num);font-size:12.5px;
  font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;
}
.item:hover .mautti,.item:focus-within .mautti{border-color:var(--sky-300);background:var(--paper)}
.item .mautti:focus{border-color:var(--sky-400);background:#fff;box-shadow:none}
/* Sửa tay rồi thì nổi cam — để người bán biết con số này không còn là công thức. */
.item .mautt.sua .mautti{color:var(--or-7);border-color:#F3C9A2;background:var(--or-50)}
.item .mautra{display:grid;place-items:center;width:18px;height:18px;flex:0 0 18px;
  border-radius:4px;color:var(--or-7);font-size:11px;line-height:1}
.item .mautra:hover{background:var(--or-50)}
.item .mauwarn{flex:0 0 auto;margin-left:auto;font-size:11px;color:var(--or-safe);font-style:italic}
/* nút bỏ dòng CHỈ hiện (rõ, không mờ) khi rê vào dòng — anh Đạt 11/09 chọn. `.vuaxoa` =
   dòng vừa trồi lên dưới con trỏ sau một lần bỏ (pos.js delLine): hiện NGAY, không mờ dần,
   để nhịp bấm liên tục không gãy. Máy cảm ứng không có "rê" nên hiện thường trực: nút tàng
   hình mà vẫn bấm được là chạm nhầm mất dòng. */
.item .xoa{opacity:0;transition:opacity .12s}
.item:hover .xoa,.item:focus-within .xoa,.item.vuaxoa .xoa{opacity:1}
.item.vuaxoa .xoa{transition:none}
@media (hover:none){ .item .xoa{opacity:1} }
/* b186 · ô ảnh trong thẻ sản phẩm: ảnh hiện tại + nút chọn tệp / xóa */
.pimg-pick{display:flex;align-items:center;gap:var(--space-3)}
.pimg-cur{width:72px;height:72px;flex:0 0 72px;object-fit:contain;border:1px solid var(--line);border-radius:var(--r);background:#fff}
.pimg-cur.none{display:block;background:var(--sky-50);border-style:dashed}
.pimg-act{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.pimg-act .hint{margin:0;flex-basis:100%}

/* b192 · đáy bảng Sản phẩm: đang xem bao nhiêu trong bao nhiêu + nút nạp thêm */
.p-more{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:14px 16px;border-top:1px solid var(--line)}
.p-more strong{color:var(--ink)}

/* ============================================================
   b231 · BẢNG TICK NHÓM QUYỀN
   Bảng này dài (37 quyền) nên nó tự cuộn trong khung của mình, không kéo dài cả hộp thoại.
   Ô tick cao 24px cho ngón tay, và mỗi nhóm việc có đường viền riêng để mắt bám được hàng.
   ============================================================ */
.ap-bang { max-height: 46vh; overflow-y: auto; margin-top: 12px;
  border: 1px solid var(--line); border-radius: 8px; padding: 12px; background: var(--bg); }
.ap-nhom { border: 0; border-top: 1px solid var(--line); margin: 0; padding: 8px 0 4px; }
.ap-nhom:first-child { border-top: 0; padding-top: 0; }
.ap-nhom legend { padding: 0; font-size: 10.5px; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--slate); }
.ap-q { display: flex; align-items: center; gap: 8px; min-height: 24px;
  padding: 2px 0; font-size: 12.5px; cursor: pointer; }
.ap-q input { width: 16px; height: 16px; flex: 0 0 auto; margin: 0; }
@media (max-width: 880px) {
  .ap-bang { max-height: 40vh; }
  .ap-q { font-size: 14px; min-height: 32px; }
}

/* ===== SOURCE: styles/mobile.css ===== */
/* ============================================================
   BẢN CHO ĐIỆN THOẠI (b128) — chỉ bán 1 khách + tra giá
   ============================================================ */
.paybar{display:none}
@media (max-width:880px){
  /* thẻ hàng: xếp một cột thành dòng ngang, hết cảnh chữ bị cắt cụt */
  .grid-p{grid-template-columns:1fr;gap:7px}
  .pcard{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;
    gap:2px 10px;text-align:left;padding:11px 12px}
  .pcard .rank{position:static;grid-row:1/3;display:none}
  .pcard .pimg{display:none}
  .pcard .pn{grid-column:1;font-size:14px;line-height:1.3;padding-right:0;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .pcard .pmeta{grid-column:1;font-size:11.5px}
  .pcard .pwhole{grid-column:1/-1;font-size:11.5px}
  .pcard .prow{grid-column:2;grid-row:1/3;display:flex;flex-direction:column;
    align-items:flex-end;gap:3px;white-space:nowrap;padding-right:0}
  .pcard .pp{font-size:15px}
  .pcard .stk{position:static;flex:0 0 auto}
  .pos-quick{padding:0}
  .pos-qcats{gap:8px;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:thin}.pos-qcat{flex:0 0 150px;min-height:56px}
  .posq-manager{grid-template-columns:1fr;min-height:0}.posq-catlist{max-height:170px}
  .posq-products{grid-template-columns:1fr;max-height:290px}

  /* đầu trang gọn */
  .head h1{font-size:17px}
  .head .sub{font-size:11.5px}

  /* thanh thanh toán dính đáy, luôn nhìn thấy */
  .paybar{display:none}
  .paybar.on{display:flex;position:fixed;left:8px;right:8px;bottom:60px;z-index:55;
    align-items:center;gap:10px;background:var(--sky-900);color:#fff;
    border-radius:14px;padding:9px 10px 9px 15px;box-shadow:0 8px 26px rgba(24,27,32,.35)}
  .paybar .pb-l{display:flex;flex-direction:column;min-width:0;flex:1}
  .paybar .pb-n{font-size:11px;opacity:.72;letter-spacing:.3px}
  .paybar .pb-t{font-size:19px;font-weight:800;font-family:var(--f-mono);letter-spacing:-.5px}
  .paybar .pb-go{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;
    background:var(--or);color:#fff;border:0;border-radius:11px;
    padding:12px 16px;font:inherit;font-size:14.5px;font-weight:800;cursor:pointer}
  .paybar .pb-go svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2.4}
  .paybar .pb-go:active{background:var(--or-7)}
  /* chừa chỗ cho thanh đó khỏi che nút cuối phiếu */
  .tape{padding-bottom:76px}

  /* ---- màn Tra giá ---- */
  .ph-search{display:flex;align-items:center;gap:8px;background:var(--paper);
    border:1px solid var(--line);border-radius:12px;padding:0 10px;margin-bottom:10px}
  .ph-search svg{width:18px;height:18px;stroke:var(--slate-2);fill:none;stroke-width:2;flex:none}
  .ph-search input{flex:1;min-width:0;border:0;background:transparent;padding:13px 0;font-size:16px}
  .ph-search input:focus{box-shadow:none}
  .ph-search .phcam{flex:none;border:0;background:var(--or-50);border-radius:9px;
    padding:8px;display:grid;place-items:center;cursor:pointer}
  .ph-search .phcam svg{width:20px;height:20px;stroke:var(--or-7)}
  .ph-hint{font-size:12px;color:var(--slate);margin:0 2px 8px}
  .ph-list{display:flex;flex-direction:column;gap:7px}
  .ph-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:center;
    background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:11px 13px}
  .ph-nm{font-size:14.5px;font-weight:700;line-height:1.3;min-width:0}
  .ph-sub{font-size:11.5px;color:var(--slate-2);font-weight:400;margin-top:3px}
  .ph-pr{text-align:right;white-space:nowrap;display:flex;flex-direction:column;align-items:flex-end;gap:3px}
  .ph-p{font-size:16px;font-weight:800;font-family:var(--f-mono);letter-spacing:-.3px}
  .ph-p span{font-size:11px;font-weight:500;color:var(--slate-2);margin-left:2px;font-family:var(--f-ui)}
  .ph-w{font-size:11px;color:var(--slate)}
}

@media (max-width:880px){
  /* Ô đếm: 2 cột, nén lại — xếp dọc 4 ô là hết cả màn hình trước khi thấy nội dung */
  .kpis{grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px}
  .kpi{padding:10px 11px}
  .kpi .k{font-size:9.5px;letter-spacing:.3px}
  .kpi .v{font-size:17px}
  .kpi .n{font-size:10.5px;margin-top:2px;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  /* mấy dòng nhắc trên thanh công cụ không cần trên màn nhỏ */
  .toolbar .pill{display:none}
  .toolbar{gap:8px}
  .panel-hd h2{font-size:14.5px}
}

/* ---------- Thẻ thay bảng trên điện thoại (b130) ----------
   Bảng 7 cột không nhét vừa màn 390px, cuộn ngang thì mất nửa thông tin.
   Mỗi bản ghi thành một thẻ, đọc trọn trong một khung hình. */
.mcards{display:flex;flex-direction:column;gap:9px}
.mcard{background:var(--paper);border:1px solid var(--line);border-radius:13px;
  padding:12px 13px 11px;display:flex;flex-direction:column;gap:5px}
.mcard:active{background:var(--sky-50)}
.mc-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.mc-id{display:flex;flex-direction:column;min-width:0}
.mc-id strong{font-size:16px;letter-spacing:-.3px}
.mc-id span{font-size:11.5px;color:var(--slate)}
.mc-money{font-size:17px;font-weight:800;letter-spacing:-.4px;white-space:nowrap}
.mc-cust{font-size:14px;font-weight:700;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-cust span{font-weight:400;color:var(--slate);font-size:12.5px}
.mc-meta{font-size:12.5px;color:var(--slate);line-height:1.35;
  display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.mc-cod{font-size:12.5px;color:var(--red);background:var(--red-soft);
  border-radius:7px;padding:5px 9px}
.mc-cod.ok{color:var(--green);background:var(--green-soft)}
.mc-acts{display:flex;gap:6px;margin-top:4px;flex-wrap:wrap}
.mc-acts .actbtn{flex:1;justify-content:center;padding:11px 8px;font-size:13px;min-height:42px}
.mc-acts .actbtn.wide{flex:1 0 100%}
.mc-sum{display:flex;align-items:center;justify-content:space-between;
  padding:12px 14px;margin-top:10px;background:var(--sky-50);
  border:1px solid var(--sky-100);border-radius:12px;font-size:13px;color:var(--sky-600);font-weight:700}
.mc-sum strong{font-size:16px;color:var(--ink)}
@media (max-width:880px){
  .pgbar{flex-direction:column;align-items:stretch;gap:9px;border-top:0;padding:12px 2px 0}
  .pgn-wrap{justify-content:center}
  .pgi{text-align:center}
}

/* thẻ hóa đơn bản nén — mỗi màn thấy 6 hóa đơn thay vì 3 (b130) */
.mcard.tight{gap:3px;padding:11px 13px 9px}
.mc-line{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0}
.mc-line .mc-cust{flex:1;min-width:0;font-size:13.5px}
.mc-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:2px}
.mc-btns{display:flex;gap:6px;flex:0 0 auto}
.icobtn.lg{width:40px;height:40px;border:1px solid var(--line);border-radius:10px;
  display:grid;place-items:center;background:#fff}
.icobtn.lg svg{width:19px;height:19px}
.icobtn.lg.done{background:var(--green-soft);border-color:#A9D8C6;color:var(--green)}
.mcard.tight .mc-meta{font-size:12.5px}

@media (max-width:880px){
  /* Thẻ đã có khung riêng rồi — bỏ khung panel bọc ngoài cho đỡ hai lớp viền */
  .panel:has(.mcards){background:transparent;border:0;box-shadow:none;padding:0;margin-bottom:14px}
  .panel:has(.mcards) .panel-hd{padding:0 2px 9px;border:0;background:transparent;
    display:flex;align-items:center;gap:8px;flex-wrap:nowrap}
  .panel:has(.mcards) .panel-hd h2{font-size:14px;white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis}
  .panel:has(.mcards) .panel-hd .tag{flex:0 0 auto}
  .panel:has(.mcards) .head-sp{flex:1}
  /* chip lọc phiếu giao: cho cuộn ngang thay vì xuống 2 hàng */
  .fchips{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px}
  .fchips::-webkit-scrollbar{display:none}
  .fchip{flex:0 0 auto}
}

/* ---------- b133: thẻ "Sao lưu & phục hồi" — MỘT tấm 4 dòng ----------
   Anh Đạt duyệt qua mockup 10/08: mỗi dòng = icon + tên + 1 dòng tình
   trạng + huy hiệu màu + 1 nút. Chi tiết (bảng bản lưu) giấu sau nút. */
.bkrow{display:flex;align-items:center;gap:14px;padding:15px 16px;border-bottom:1px solid var(--line-2)}
.bkrow:last-child{border-bottom:0}
.bkic{width:38px;height:38px;flex:0 0 38px;border-radius:10px;background:var(--sky-50);
  display:grid;place-items:center;color:var(--slate)}
.bkic svg{width:19px;height:19px;stroke-width:1.9;fill:none;stroke:currentColor;
  stroke-linecap:round;stroke-linejoin:round}
.bktx{flex:1;min-width:0}
.bkt{font-size:14px;font-weight:700;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.bkt .tag{border-radius:99px;padding:2px 9px}
.bks{font-size:12.5px;color:var(--slate);margin-top:3px;overflow-wrap:anywhere}
.bkrow .btn{flex:0 0 auto}
#snaplist{border-bottom:1px solid var(--line-2)}
#snaplist .tbl-wrap{max-height:300px}
@media (max-width:880px){
  .bkrow{flex-wrap:wrap;padding:13px 12px;gap:10px}
  .bkrow .btn{flex:1;min-width:110px}
  .bkic{display:none}
}

/* ===== SOURCE: styles/workflows.css ===== */
/* ============================================================
   BẢO HÀNH (b136) — sổ hàng đang giữ của khách
   Anh Đạt 14/08/2026: bỏ hẳn màn tra + huy hiệu đếm ngược.
   Còn lại đúng một bảng: món của ai, lỗi gì, cầm bao lâu rồi.
   ============================================================ */
.bh-tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.bh-tbl td{padding:13px 15px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.bh-tbl tbody tr:last-child td{border-bottom:0}
.bh-tbl .nm{font-weight:700;font-size:14px;line-height:1.35}
.bh-tbl .sub2{font-size:12px;color:var(--slate);margin-top:3px;font-family:var(--f-mono)}
.bh-tbl .bh-fault{font-size:12.5px;color:var(--ink-2);margin-top:4px;font-style:italic}
.bh-tbl td.c-who{width:210px}
.bh-tbl td.c-age{width:150px}
.bh-tbl td.a{width:190px;text-align:right}

/* Cầm hàng của khách bao lâu rồi. Quá 10 ngày tô cam — không phải cảnh báo
   hệ thống, mà là nhắc gọi cho khách trước khi khách gọi cho mình. */
.wbadge{display:inline-flex;align-items:center;border-radius:9px;padding:7px 12px;
  font-size:13px;font-weight:800;line-height:1.2;white-space:nowrap}
.wb-soon{background:#FFF3E0;color:#8A4B00}
.wb-non{background:#EEF0F3;color:var(--slate)}

/* bốn bước — bấm để lọc, con số là số món đang đứng ở bước đó */
.stepbar{display:flex;margin:0 0 14px}
.step{flex:1;padding:9px 6px;text-align:center;font-size:12.5px;font-weight:700;
  border:1px solid var(--line);background:var(--paper);color:var(--slate);
  font-family:inherit;cursor:pointer;min-height:44px}
.step:first-child{border-radius:9px 0 0 9px}
.step:last-child{border-radius:0 9px 9px 0}
.step+.step{border-left:0}
.step:hover:not(.on){background:var(--sky-50);color:var(--ink)}
.step.on{background:var(--sky-900);border-color:var(--sky-900);color:#fff}
.step b{display:block;font-family:var(--f-mono);font-size:15px;margin-top:2px}

/* thẻ trên điện thoại — tên khách đứng trước, vì câu hỏi luôn là "của ai" */
.bcard{background:var(--paper);border:1px solid var(--line);border-radius:13px;padding:12px 13px;margin-bottom:9px}
.bcard .l1{display:flex;justify-content:space-between;gap:8px;align-items:baseline}
.bcard .l1 b{font-size:15px;line-height:1.3;min-width:0}
.bcard .l1 span{font-family:var(--f-mono);font-size:12px;color:var(--slate);flex:0 0 auto}
.bcard .l2{font-size:12.5px;color:var(--slate);font-family:var(--f-mono);margin:2px 0 7px}
.bcard .bh-item{font-size:13.5px;font-weight:700;line-height:1.35}
.bcard .bh-fault{font-size:12.5px;color:var(--ink-2);font-style:italic;margin:3px 0 8px}
.pill2{display:inline-flex;align-items:center;border-radius:100px;padding:5px 11px;font-size:12px;font-weight:700}

@media (max-width:880px){
  .stepbar{overflow-x:auto}
  .step{flex:0 0 auto;min-width:126px}
}

/* thanh tiến độ đẩy máy chủ (b137) */
.pgline{height:8px;border-radius:100px;background:var(--line-2);overflow:hidden;margin:0 0 13px}
.pgfill{height:100%;background:var(--or);border-radius:100px;transition:width .25s ease-out}

/* thanh gập trong Danh mục & hệ thống (b141) */
.acchd{cursor:pointer;user-select:none}
.acchd:hover h2{color:var(--sky-700)}
.acar{font-size:13px;color:var(--slate-2);width:18px;text-align:center}

/* ---- b144: mã đánh giá Google trên bill nhiệt ---- */
.p-80 .rvq{text-align:center;margin:1.5mm 0 .5mm}
.p-80 .rvq svg{width:24mm;height:24mm}
.p-80 .rvq .t{font-size:8pt;line-height:1.4}

/* ---- b145 → b147: Sổ màu sơn ----
   Bỏ bảng, đổi sang thẻ từng khách: câu hỏi ở quầy luôn là "màu của AI",
   nên tên khách phải là thứ to nhất, mã màu nằm bên trong.
   Đệm theo thang 4/8/12 của sổ tay mục 4; CAM vẫn chỉ dành cho hành động
   chính (nút Thêm màu), thẻ mã màu dùng cam NHẠT vì nó là thứ cần chú ý
   nhất trong khối, không phải nút hành động thứ hai. */
.smwrap{max-height:calc(100vh - 268px);overflow:auto}
.smlist{display:grid;gap:8px}
.smk{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--paper);overflow:hidden}
.smk.on{border-color:var(--sky-300);box-shadow:var(--shadow)}
.smhd{display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:8px 12px;background:none}
.smhd:hover{background:var(--sky-50)}
.smav{
  flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:var(--sky-100);color:var(--sky-700);font-weight:700;font-size:14px;
}
.smnm{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.smnm b{font-size:14px;font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.smnm i{font-style:normal;font-size:12px;color:var(--slate-2)}
.smdt{flex:0 0 auto;font-size:12px;color:var(--slate-2)}
.smar{flex:0 0 auto;width:16px;text-align:center;color:var(--slate-2);font-size:12px}
.smbd{padding:0 12px 12px 58px;display:grid;gap:8px}
.smm{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--sky-50);border:1px solid var(--line-2);border-radius:var(--r);padding:6px 8px 6px 10px;
}
.smmi{flex:1;min-width:140px;font-size:12px;color:var(--slate);line-height:1.5}
.smmi i{font-style:italic;color:var(--ink-2)}
.smact{flex:0 0 auto;display:flex;gap:2px;margin-left:auto}
.smadd{justify-self:start;margin-top:2px}
.smchips{display:flex;flex-wrap:wrap;gap:7px}
.smchip{display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  font-family:inherit;font-size:12.5px;font-weight:700;color:var(--or-7);
  background:#FFF4EC;border:1px solid #F3C9A6;border-radius:999px;padding:5px 11px;
  line-height:1.3;white-space:nowrap}
.smchip:hover{background:#FFE8D6;border-color:#E9A96F}
.smchip b{font-weight:800;color:var(--slate);font-size:11.5px}

/* Điện thoại: bỏ thụt lề theo vòng tròn tên khách cho rộng chỗ, và để màn
   tự cao — cuộn của cả trang lo, không cần khung cuộn riêng. */
@media (max-width:880px){
  .smwrap{max-height:none;overflow:visible}
  .smbd{padding-left:12px}
  .smm{gap:8px}
  .smmi{min-width:100%;order:3}
  .smact{order:2}
}

/* ================= b146 — CHỐNG IPHONE PHÓNG TO KHI CHẠM / LƯỚT =================
   Anh Đạt báo 19/08: "vào app bằng điện thoại, vẫn bị zoom khi lướt."
   Web đã trị hồi bản 34, app thì quên — hai bên hai bộ CSS khác nhau.
   Có BA nguyên nhân, phải trị đủ cả ba mới hết:

   1. Chạm đôi phóng trang. Trước đây chỉ đặt cho nút và thẻ, nên chạm trúng
      khoảng trống giữa chúng là lỗi quay lại. PHẢI đặt cho `*`.
      `manipulation` vẫn cho véo hai ngón phóng to — người lớn tuổi cần cái đó,
      chỉ tắt riêng phóng-bằng-chạm-đôi.
   2. Safari tự phóng khi con trỏ vào ô nhập có cỡ chữ dưới 16px, và KHÔNG tự
      thu lại. App đang có mấy ô 11,5–13px.
   3. Chữ tự phồng khi xoay ngang máy.
   Bài kiểm bắt buộc trước mỗi bản: xem `so-tay-web.md` mục A. */
*{touch-action:manipulation}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
@media (max-width:880px){
  input,select,textarea{font-size:16px}
  .cust-row input,.eqrow input,.eqrow select,input[type=file]{font-size:16px}
  /* mấy ô hẹp phải nới ra cho vừa cỡ chữ 16px, không thì chữ bị cắt */
  .trow input{width:104px;font-size:16px;padding:4px 7px}
  .trow select{font-size:16px;padding:4px 6px}
  .qty input{font-size:16px}
  .pin input{font-size:16px}
  /* ô Thuế GTGT và ô Giảm giá ở chân giỏ hàng — hai ô này thừa hưởng cỡ
     12,5px của khối .fcell, phải nói rõ mới thắng được */
  .fcell input,.fcell select{font-size:16px;width:124px;padding:5px 8px}
}

/* Tương phản WCAG 2.2 AA cho các nút dùng chữ/biểu tượng trắng.
   Không thay font, cỡ chữ hay kích thước vùng bấm. */
.btn.acc,.scan-mic,.scan-mic.on,.best-tick,.pin button,.tab .tn,
.ck-step button.on,.ph-hit.mid .ph-i,.ph-badge.pick,.bigbtn.on,
.navbtn.lockbtn.on,.paybar .pb-go{background:var(--or-safe);border-color:var(--or-safe)}
.btn.acc:hover,.scan-mic:hover,.pin button:hover,.bigbtn.on:hover,.navbtn.lockbtn.on:hover,
.paybar .pb-go:active{background:var(--or-safe-hover);border-color:var(--or-safe-hover)}
.scan-cam:hover,.scan-eye:hover,.ph-tools button:hover{background:var(--or-safe);border-color:var(--or-safe)}
.btn-next{background:linear-gradient(180deg,var(--or-safe),var(--or-safe-hover))}

/* ═══════════════════════════════════════════════════════════════════════════
   BẢN 149 — SỬA HÓA ĐƠN: THÊM / BỚT HÀNG
   ═══════════════════════════════════════════════════════════════════════════
   Băng nhắc "đang sửa hóa đơn" phải ĐẬP VÀO MẮT. Người bán quen bấm F2 rồi
   quét hàng liên tục; lỡ quét nhầm vào thẻ đang sửa thì hóa đơn cũ bị ghi đè
   mà không ai hay. Nên dùng nền đỏ nhạt + viền trái đỏ đậm, đứng ngay trên ô
   quét — chỗ mắt nhìn tới đầu tiên. */
.edbar{display:flex;align-items:center;gap:12px;margin:0 0 10px;
  padding:10px 12px;border-radius:8px;background:#FEF2F2;
  border:1px solid #FCA5A5;border-left:4px solid #DC2626}
.edbar .ed-ic{flex:0 0 auto;display:flex;color:#B91C1C}
.edbar .ed-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;line-height:1.35}
.edbar .ed-tx strong{font-size:14px;color:#991B1B}
.edbar .ed-tx span{font-size:12.5px;color:var(--slate-2)}
.edbar .btn{flex:0 0 auto}
/* Nút thanh toán lúc đang sửa: đổi hẳn màu để không bấm theo quán tính. */
.pb-go.ed{background:#B91C1C;border-color:#B91C1C;color:#fff}
.pb-go.ed:hover{background:#991B1B;border-color:#991B1B}

/* Ô tìm hàng trong hộp Sửa hóa đơn. Cố ý chỉ 8 dòng và cao tối đa 210px —
   đây là hộp sửa chữa, cần danh sách dài thì mở ra màn Bán hàng. */
.ei-add{margin-top:12px}
.ei-add>label{display:block;font-size:12px;font-weight:600;color:var(--slate-2);margin-bottom:5px}
.ei-add>input{width:100%}
.ei-res{margin-top:6px;max-height:210px;overflow-y:auto;overscroll-behavior:contain}
.ei-res:empty{display:none}
.ei-r{display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:6px}
.ei-r+.ei-r{border-top:1px solid var(--line)}
.ei-r:hover{background:var(--sky-1)}
.ei-n{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.ei-n strong{font-size:13.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ei-n i{font-style:normal;font-size:11.5px;color:var(--slate-2)}
.ei-r .btn{flex:0 0 auto}
.ei-non{padding:12px 8px;font-size:13px;color:var(--slate-2);text-align:center}

/* Dòng "BẢN SỬA LẦN N" trên phiếu in. In ra giấy nhiệt và giấy A4 đều phải
   thấy — đây là thứ để biết tờ nào mới khi hai tờ cùng một số hóa đơn. */
.ed-mark{font-weight:700}
@media print{ .ed-mark{display:block} }

@media (max-width:880px){
  .edbar{flex-wrap:wrap;gap:8px}
  .edbar .ed-tx{flex:1 1 100%;order:2}
  .edbar .btn{order:3;margin-left:auto;font-size:16px}
  .ei-res{max-height:240px}
  .ei-add>input{font-size:16px}     /* dưới 16px là iPhone tự phóng to cả trang */
}

/* Khung xem trước lúc đang sửa: đổi màu thanh tiêu đề để không nhìn nhầm
   thành phiếu bán mới. Nút chính cũng đổi sang đỏ — bấm theo quán tính vào
   nút cam quen thuộc là ghi đè hóa đơn cũ mà không kịp nghĩ. */
.tape-bar.ed{background:#7F1D1D}
.tape-hd .meta .ed-t{color:#B91C1C;font-weight:700}
.btn.acc.big.ed{background:#B91C1C;border-color:#B91C1C;color:#fff}
.btn.acc.big.ed:hover{background:#991B1B;border-color:#991B1B}

/* ── b149, vá kèm: hai chỗ nhỏ trên iPhone ──────────────────────────────────
   Cả hai đều CÓ SẴN từ trước, không phải do bản sửa hóa đơn đẻ ra. Nhưng bản
   sửa làm chúng lộ ra thường xuyên nên vá luôn — đúng Sổ lỗi #10: "vá một chỗ
   thì hỏi ngay, chỗ kia có dính không".

   1. Ô ghi chú từng món (.ntin) đang 11,5px. Safari tự phóng to CẢ TRANG khi
      con trỏ vào ô dưới 16px và KHÔNG tự thu lại — đúng con bệnh anh Đạt báo
      ở b146. Lần đó vá Thuế GTGT với Giảm giá mà sót ô này vì nó chỉ hiện khi
      rê chuột, trên máy tính không ai thấy.
   2. Nút ↺ "trả về giá gốc" đang 19×19px, dưới mức 24px sờ được. Lúc bán
      thường nó chỉ hiện khi tự gõ đè giá nên ít gặp; lúc SỬA hóa đơn thì mọi
      dòng đều mang giá đã bán, tức là dòng nào cũng hiện nút này. */
@media (max-width:880px){
  .item .ntin{font-size:16px}
  .item .ntrow{max-height:none}
  .item .ntrow svg{width:14px;height:14px}
  .pin button{min-width:24px;min-height:24px;display:inline-flex;
    align-items:center;justify-content:center;font-size:15px;line-height:1}
}


/* ═══════════════════════════════════════════════════════════════════════════
   BẢN 150 — HỘP SỬA HÓA ĐƠN GỌN LẠI
   ═══════════════════════════════════════════════════════════════════════════
   Anh Đạt xem mẫu 20/08 rồi chốt: bỏ ô Giảm giá, Thuế GTGT, Thanh toán; hai
   khối chữ dài gom thành hai nút.

   NGUYÊN TẮC CỦA HỘP NÀY SAU BẢN 150: hộp Sửa chỉ lo HÀNG và KHÁCH. Giảm giá,
   thuế, hình thức trả tiền đều làm ở màn Bán hàng. Đừng nhét mấy ô đó về lại —
   nhét về là hộp dài ra, mà việc thì đã có chỗ làm tử tế hơn.

   BA CON SỐ BỊ BỎ Ô NHẬP VẪN PHẢI HIỆN RA BẰNG CHỮ ở dòng tổng (.eis-2).
   Giấu một con số tiền đi là kiểu lỗi tệ nhất: người bán tưởng hóa đơn không
   giảm giá, thực ra đang giảm 200 nghìn nằm im. Xóa dòng đó là phạm luật này. */
/* ── LUẬT MÀU CỦA HỘP NÀY ───────────────────────────────────────────────
   Mỗi màu mang MỘT nghĩa, dùng đúng nghĩa đó, không tô cho đẹp:
     XANH LÁ  dòng MỚI thêm vào · hàng còn tồn
     CAM      dòng ĐÃ SỬA số · số tiền khách trả · hàng sắp hết
     ĐỎ       dòng ĐÃ BỎ · nút bỏ dòng · hàng hết
     XÁM THAN khung sườn, số thứ tự các phần
   Dòng KHÔNG đụng gì thì để trắng — mắt chỉ phải nhìn chỗ đã đổi.
   Đừng thêm màu thứ năm. Thêm là hết phân biệt được. */

/* nhãn đánh số từng phần — thứ giúp mắt bám nhanh nhất, rẻ nhất */
/* Lề TRÊN 20px là bắt buộc, không phải cho đẹp: nhãn phần 3 nằm ngay dưới ô
   tìm hàng, không có lề thì hai thứ dán vào nhau và vòng cam lúc gõ đè lên
   chữ. Lề trên của phần 1 và 2 sẽ tự gộp với lề dưới của khối phía trước
   (margin collapsing), nên không đẻ thêm khoảng trống thừa ở hai chỗ đó. */
.ei-sec{display:flex;align-items:center;gap:8px;margin:20px 0 8px;
  font-size:11.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--sky-600)}
.ei-sec i{font-style:normal;font-size:10.5px;font-weight:600;letter-spacing:.04em;
  text-transform:none;color:var(--red);background:var(--red-soft);padding:2px 7px;border-radius:99px}
.ei-no{flex:0 0 auto;width:19px;height:19px;border-radius:50%;background:var(--sky-800);color:#fff;
  display:grid;place-items:center;font-size:11px;font-weight:700;letter-spacing:0}

/* hai nút lối tắt — chip màu bên trong nói nghĩa của nút */
.ei-jump{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:6px}
.ei-jump .btn{justify-content:flex-start;gap:9px;padding-left:8px}
.ei-jc{flex:0 0 auto;width:28px;height:28px;border-radius:var(--r-sm);display:grid;place-items:center}
.ei-jc svg{width:15px;height:15px}
.ei-j1 .ei-jc{background:var(--red-soft);color:var(--red)}      /* hàng đi ngược về kho */
.ei-j2 .ei-jc{background:var(--or-50);color:var(--or-7)}        /* đi bán tiếp */
.ei-j1:hover{border-color:var(--red)} .ei-j2:hover{border-color:var(--or-6)}
/* b152: đã bỏ dòng nhắc .ei-jh. Nghĩa của hai nút nay nằm trong thuộc tính
   title — rê chuột vào là hiện. Cần nói lại thì để trong title, đừng đắp thêm
   một dòng chữ xám nữa: chữ xám mà lần nào cũng hiện thì không ai đọc. */
.ei-jump{margin-bottom:16px}

/* bảng dòng hàng */
#ei_rows .eir>td{padding:9px 8px;border-bottom:1px solid var(--line-2);vertical-align:middle}
#ei_rows .eir:hover>td{background:var(--sky-50)}
/* KHÔNG BAO GIỜ đặt display:flex thẳng lên thẻ <td>. Trình duyệt lôi nó ra
   khỏi bảng rồi bọc vào một ô vô danh — nền và đường kẻ đứt một khoảng ngay
   cạnh cột đó, nhìn như bảng bị vỡ. Flex phải nằm trong một <span> bên trong. */
.ei-tnc{max-width:0;width:38%}
.ei-tn{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.ei-tn .nm{font-weight:600}
.ei-dv{color:var(--slate-2);font-size:13px}
.ei-tt{font-weight:700;font-family:var(--f-mono);font-size:13.5px}
/* ô nhập được thì có nền — ô chỉ để đọc thì không. Nhìn là biết chỗ nào gõ được. */
.ei-in{width:76px;text-align:right;padding:5px 8px;background:var(--sky-50);
  border:1px solid var(--line);border-radius:var(--r-sm);font-family:var(--f-mono);font-size:13px}
.ei-in.wide{width:98px}
.ei-in:focus{background:#fff;border-color:var(--sky-500)}

/* ba trạng thái, ba màu — vạch dọc bên trái là thứ mắt bắt trước cả chữ */
.ei-tag{font-size:10.5px;font-weight:700;letter-spacing:.02em;padding:2px 7px;border-radius:99px;white-space:nowrap}
.ei-cu{font-size:11px;color:var(--slate-2);text-decoration:line-through;font-variant-numeric:tabular-nums}
#ei_rows .eir.moi>td:first-child{box-shadow:inset 3px 0 0 var(--green)}
#ei_rows .eir.moi>td{background:var(--green-soft)}
.ei-tag.moi{background:var(--green);color:#fff}
#ei_rows .eir.sua>td:first-child{box-shadow:inset 3px 0 0 var(--or-6)}
#ei_rows .eir.sua>td{background:var(--or-50)}
.ei-tag.sua{background:var(--or-safe);color:#fff}
#ei_rows .eir.bo>td:first-child{box-shadow:inset 3px 0 0 var(--red)}
#ei_rows .eir.bo>td{background:var(--red-soft)}
#ei_rows .eir.bo .nm,#ei_rows .eir.bo .ei-tt{text-decoration:line-through;color:var(--slate-2)}
.ei-tag.bo{background:var(--red);color:#fff}
.ei-del:hover{background:var(--red-soft);color:var(--red)}
.ei-undo{background:var(--red-soft);color:var(--red)}
.ei-undo:hover{background:var(--red);color:#fff}

/* ô tìm hàng */
.ei-add{margin-top:16px}
.ei-add>label{display:flex;align-items:center;gap:6px;font-size:12px;font-weight:650;
  color:var(--sky-600);margin-bottom:6px}
.ei-add>label svg{width:14px;height:14px}
.ei-ton{font-weight:650;padding:1px 6px;border-radius:99px}
.ei-ton.con{background:var(--green-soft);color:var(--green)}
.ei-ton.sap{background:var(--or-50);color:var(--or-safe)}
.ei-ton.het{background:var(--red-soft);color:var(--red)}

/* thẻ tổng tiền — nền xám than, số cam. Giống hệt thanh KHÁCH TRẢ ở màn Bán
   hàng nên mắt quen sẵn; và cam trên xám than đo được 5,61:1, đạt chuẩn AA. */
.ei-sum{margin-top:14px;background:var(--sky-800);border-radius:var(--r);padding:12px 14px;color:#fff}
.eis-hd{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.eis-l{flex:1;min-width:0;font-size:11.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sky-300)}
.eis-l b{color:#fff}
.eis-v{font-size:21px;font-weight:800;color:var(--or);font-family:var(--f-mono);letter-spacing:-.02em}
.eis-d{font-weight:700;font-size:12px;padding:2px 8px;border-radius:99px}
.eis-d.up{background:var(--or-50);color:var(--or-safe)}
.eis-d.dn{background:var(--green-soft);color:var(--green)}
/* KHÔNG dùng font mono cho dòng có CHỮ TIẾNG VIỆT. JetBrains Mono không dựng
   được dấu, "Tiền" ra "Tiêǹ", "sửa" ra "sưả" — nhìn như trang bị lỗi phông.
   Mono chỉ dành cho ô toàn số: .ei-in, .ei-tt, .eis-v. */
.eis-2{margin-top:7px;padding-top:7px;border-top:1px solid rgba(255,255,255,.14);
  font-size:12px;color:var(--sky-300);font-variant-numeric:tabular-nums}
.eis-3{margin-top:3px;font-size:11.5px;color:var(--sky-400);line-height:1.5}
.eis-3 i{font-style:normal;opacity:.9}

@media (max-width:880px){
  .ei-jump{grid-template-columns:1fr}
  .ei-in{width:70px;font-size:16px} .ei-in.wide{width:92px;font-size:16px}
  .eis-v{font-size:19px}
}


/* ═══════════════════════════════════════════════════════════════════════════
   BẢN 150 — DANH SÁCH HÓA ĐƠN: MỌI DÒNG CAO BẰNG NHAU
   ═══════════════════════════════════════════════════════════════════════════
   Luật của khối này, đừng phá:

   1. MỖI DÒNG ĐÚNG HAI HÀNG CHỮ. Chiều cao ghim cứng 62px. Muốn thêm thông
      tin thì thay chữ trong hai hàng đó, TUYỆT ĐỐI không đẻ hàng thứ ba —
      một dòng cao lên là gãy nhịp cả danh sách, mắt phải rà lại từ đầu.
   2. BÁO CHUYỆN KHÁC THƯỜNG BẰNG MÀU CHỮ SẴN CÓ, không bằng thẻ mới.
      Còn nợ  -> chấm cam đầu dòng + dòng dưới cột tiền đổi sang đỏ.
      Đã sửa  -> dấu bút chì mờ cạnh số hóa đơn.
      Cả hai đều nằm lọt trong hai hàng, nên chiều cao không đổi.
   3. DÙNG LƯỚI, KHÔNG DÙNG <table>. Ô bảng cao theo nội dung dài nhất nên
      không ghim được; lưới thì ghim được. Tiện thể hết luôn cái bẫy
      display:flex trên thẻ <td>.
   4. HÀNG BÌNH THƯỜNG KHÔNG ĐEO GÌ CẢ. Chín trên mười hóa đơn là bình
      thường — tô hết thì màu mất nghĩa, mà đó mới đúng là lúc cần màu. */

.ipanel{padding:0;overflow:hidden}
.ilist{display:flex;flex-direction:column}
/* Một chỗ khai bề ngang cột cho CẢ đầu bảng lẫn mọi dòng — hai chỗ khai riêng
   là có ngày lệch nhau mà không ai để ý. */
.ilist .ihead,.ilist .irow{
  display:grid;align-items:center;
  grid-template-columns:22px 132px minmax(0,1fr) 156px 78px;
  gap:0 14px;padding:0 16px 0 4px}
.ilist.loi .ihead,.ilist.loi .irow{grid-template-columns:22px 132px minmax(0,1fr) 116px 156px 78px}
.ilist .ihead{height:38px;border-bottom:1px solid var(--line);
  font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--slate-2)}
.ilist .ihead .r{text-align:right}

.ilist .irow{height:62px;border-bottom:1px solid var(--line-2);cursor:pointer;
  background:none;border-left:0;border-right:0;border-top:0;width:100%;text-align:left;
  font:inherit;color:inherit;transition:background .12s}
.ilist .irow:hover{background:var(--sky-50)}
.ilist .irow:focus-visible{outline:2.5px solid var(--or-safe);outline-offset:-3px}
.ilist .irow:last-of-type{border-bottom:0}

/* hai hàng chữ — cùng một khuôn cho cả ba cột, nên chúng thẳng hàng nhau */
.ic1,.ic2,.ic3,.ic4{min-width:0;display:block;line-height:1.3}
.ic1 b,.ic2 b,.ic3 b,.ic4 b{display:block;font-size:14px;font-weight:650;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ic1 i,.ic2 i,.ic3 i,.ic4 i{display:block;font-style:normal;font-size:11.5px;color:var(--slate-2);
  margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-height:15px}
.ic3,.ic4{text-align:right}
.ic3 b{font-size:14.5px;font-weight:700}

/* chấm báo còn nợ — 7px, nằm gọn trong hàng, không đẩy gì đi đâu */
.idot{width:7px;height:7px;border-radius:50%;background:transparent;margin-left:9px}
.irow.no .idot{background:var(--or)}
.ic3 i.no{color:var(--red);font-weight:650}

/* Dấu bút chì "đã sửa" — nhỏ, mờ, nằm NGAY TRONG dòng số hóa đơn.
   Đừng dùng position:absolute cho nó: bỏ absolute ra thì nó tự tìm chỗ, còn
   để absolute mà quên khai left/right là nó rơi xuống dòng dưới, mất tăm. */
.ic1 b{display:flex;align-items:center;gap:5px}
.ic1 b>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ic1 .ised{display:inline-flex;flex:0 0 auto;color:var(--slate-2);opacity:.8}
.ic1 .ised svg{width:11px;height:11px}

/* hai nút im lặng, chỉ đậm lên khi rê chuột. Cố ý KHÔNG ẩn hẳn: màn cảm ứng
   không có rê chuột, ẩn là nhân viên không tìm ra nút. */
.iact{display:flex;gap:2px;justify-content:flex-end}
/* Màu nghỉ phải là --sky-400 (3,2:1), KHÔNG được dùng --sky-300 (2,0:1) —
   dưới mốc 3:1 cho thành phần bấm được. Mờ là để nó im lặng, không phải để
   nó biến mất. */
.iact .icobtn{width:30px;height:30px;color:var(--sky-400)}
.irow:hover .iact .icobtn{color:var(--slate)}
.iact .icobtn:hover{background:var(--sky-100);color:var(--ink)}

.ifoot{display:flex;align-items:center;justify-content:space-between;gap:16px;
  height:48px;padding:0 16px 0 26px;border-top:1px solid var(--line);background:var(--sky-50);
  font-size:11.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--slate-2)}
.ifoot strong{font-size:16px;letter-spacing:0;text-transform:none;color:var(--ink)}

/* thanh chọn ngày thay cho dãy 5 chip cũ */
.itool{gap:10px}
.idate{display:flex;align-items:center;gap:6px;margin-left:auto}
.ilb{font-size:11.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--slate-2)}
.idate input[type=date]{width:auto;padding:7px 9px;font-size:13px}
.idash{color:var(--slate-2)}
.ixoa{width:32px;height:32px;flex:0 0 auto;border:1px solid var(--line);background:var(--paper);
  border-radius:var(--r-sm);color:var(--slate-2);cursor:pointer;display:grid;place-items:center}
.ixoa:hover{border-color:var(--red);color:var(--red)}
.ixoa svg{width:13px;height:13px}

@media (max-width:880px){
  /* Điện thoại: thẻ ba cột không nhét vừa 390px — xếp thành thẻ, nhưng vẫn
     giữ đúng luật: mọi thẻ cao bằng nhau. */
  .ilist.ph{gap:8px;background:none}
  .ilist.ph .irow{height:auto;min-height:0;display:grid;
    grid-template-columns:14px minmax(0,1fr) auto;gap:2px 8px;
    padding:12px 14px;background:var(--paper);border:1px solid var(--line);border-radius:var(--r)}
  .ilist.ph .irow .idot{grid-row:1;margin-left:0}
  .ilist.ph .ic1{grid-column:2}
  .ilist.ph .ic3{grid-column:3;grid-row:1}
  .ilist.ph .ic2{grid-column:2/4;grid-row:2;text-align:left}
  .ilist.ph .ic1 b,.ilist.ph .ic1 i{display:inline-block;vertical-align:middle}
  .ilist.ph .ic1 i{margin:0 0 0 8px;font-size:11.5px}
  .ilist.ph .ic2 b{display:inline;font-size:13.5px}
  .ilist.ph .ic2 i{display:inline;margin-left:6px}
  .ilist.ph .ic3 b{font-size:15px}
  .ilist.ph .irow:last-of-type{border-bottom:1px solid var(--line)}
  .ifoot{border-radius:var(--r);border:1px solid var(--line);margin-top:10px;padding:0 14px}
  .itool{flex-wrap:wrap}
  .idate{margin-left:0;width:100%}
  .idate input[type=date]{flex:1;font-size:16px}
}

/* ── b151: tự lưu khách khi bán ─────────────────────────────────────────
   Ô tích CHỈ hiện khi nó thật sự sắp làm gì đó — có đủ tên và số mà chưa gán
   khách. Hiện lúc nào cũng thấy thì thành thứ trang trí, người bán nhìn quen
   rồi thôi không đọc nữa. */
.kh-luu{display:flex;align-items:center;gap:8px;margin-top:7px;padding:6px 8px;
  border-radius:var(--r-sm);background:var(--sky-50);cursor:pointer;
  font-size:12px;color:var(--slate);line-height:1.4}
.kh-luu input{width:16px;height:16px;flex:0 0 auto;accent-color:var(--or-6);margin:0}
.kh-luu b{color:var(--ink);font-weight:650}
.kh-luu:hover{background:var(--sky-100)}

.custline .kh-sua{margin-left:auto;width:24px;height:24px;flex:0 0 auto;border:0;background:none;
  border-radius:var(--r-sm);color:var(--slate-2);cursor:pointer;display:grid;place-items:center}
.custline .kh-sua svg{width:13px;height:13px}
.custline .kh-sua:hover{background:var(--sky-100);color:var(--ink)}

/* Tên vừa gõ khác tên trong sổ — mời đổi bằng một cú bấm, KHÔNG tự đổi.
   Gõ tắt "Ba" một lần là ghi đè mất "Anh Ba Thợ Hồ" đã lưu công phu. */
.kh-doi{margin-top:5px;font-size:11.5px;color:var(--slate-2);line-height:1.45}
.kh-doi b{color:var(--ink);font-weight:650}
.kh-doi button{margin-left:6px;border:0;background:none;padding:0;cursor:pointer;font:inherit;
  color:var(--blue-2,#1C5A8F);text-decoration:underline;text-underline-offset:2px}
.kh-doi button:hover{color:var(--ink)}

@media (max-width:880px){ .kh-luu{font-size:13px} .kh-luu input{width:20px;height:20px} }

/* ── b152: danh sách hóa đơn giãn ra lấp đầy trang ──────────────────────────
   Anh Đạt: "phóng to phần hóa đơn cho fix với trang, giữ 8 hóa đơn là được."

   Trước: mỗi dòng cao cứng 62px, 8 dòng hết ~700px, màn 1080 còn dư một mảng
   trắng to ở dưới. Chữ thì nhỏ mà chỗ thì thừa.

   Nay: DÙNG FLEX CHO NÓ TỰ CHIA, không đoán số pixel. Chuỗi co giãn chạy từ
   .view xuống tận từng dòng, mỗi khâu đều phải có min-height:0 — thiếu một
   chỗ là cả chuỗi đứt, flex item không co nhỏ hơn nội dung được.
     .view  ->  #itbl  ->  .ipanel  ->  .ilist  ->  .irow

   Chặn hai đầu: KHÔNG dưới 62px (màn thấp thì cho cuộn, đừng bóp chữ dính
   nhau) và KHÔNG quá 104px (màn 2K mà mỗi dòng cao bằng bàn tay thì trống
   huếch, đọc còn mệt hơn).

   Vẫn ĐÚNG 8 hóa đơn mỗi trang — IPP không đổi. */
.view:has(.ilist){display:flex;flex-direction:column}
.view:has(.ilist) .itool{flex:0 0 auto}
.view:has(.ilist) #itbl{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
#itbl .ipanel{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
#itbl .ipanel .ilist{flex:1 1 auto;min-height:0;overflow:auto}
#itbl .ipanel .ihead,#itbl .ipanel .ifoot{flex:0 0 auto}
#itbl .ipanel .irow{flex:1 1 0;min-height:62px;max-height:104px}
#itbl .pgbar{flex:0 0 auto;margin-top:12px}
/* Dòng cao lên thì chữ cũng nở theo một chút cho cân — nhưng KHÔNG đụng tới
   cỡ chữ chung của app (luật b147/b148: không đổi font, cỡ chữ, kích thước). */
#itbl .ipanel .ic1 b,#itbl .ipanel .ic2 b{font-size:14.5px}
#itbl .ipanel .ic3 b{font-size:15.5px}

@media (max-width:880px){
  /* Điện thoại: thẻ xếp dọc và cuộn bình thường, đừng ép giãn. */
  .view:has(.ilist){display:block}
  #itbl .ilist.ph .irow{flex:0 0 auto;min-height:0;max-height:none}
}
/* Trạng thái nguồn dữ liệu máy chủ; không thay đổi font hoặc thang chữ của app. */
.rail-ft{display:flex;align-items:center;justify-content:space-between;gap:7px}
.server-mode{display:inline-flex;align-items:center;gap:4px;font-size:8px;font-weight:800;letter-spacing:.06em;border-radius:999px;padding:3px 5px;background:#E8EDF2;color:#52606D}
.server-mode.online{background:#DDF4E7;color:#167348}
.server-mode.offline{background:#FCE4DE;color:#A52C24}
.server-mode.local{background:#EEF0F3;color:#626A75}
/* b240 · CHẤM ĐƯỜNG TRUYỀN — anh Đạt 14/09: "chỉ cần xanh lá, cam, đỏ là được".
   Chấm nói CHẤT LƯỢNG ĐƯỜNG, nền huy hiệu vẫn nói TRẠNG THÁI MÁY CHỦ như cũ —
   hai thứ khác nhau, đừng gộp: máy chủ online mà đường chậm là có thật.
   Màu lấy đúng thang nhận diện: xanh #167348 · cam #B4690E · đỏ #A52C24.
   Không dùng MÌNH màu để báo (người mù màu đỏ–lục không phân biệt được):
   kèm aria-label và title bằng chữ, và chấm đỏ có viền trong cho khác hình. */
.sm-cham{width:6px;height:6px;border-radius:50%;flex:0 0 auto;background:currentColor}
.server-mode.dt-tot .sm-cham{background:#167348}
.server-mode.dt-cham .sm-cham{background:#B4690E}
.server-mode.dt-mat .sm-cham{background:#A52C24;box-shadow:inset 0 0 0 1.5px #FCE4DE}
.server-mode.dt-local .sm-cham{background:#8A94A0}
.sm-ms{font-style:normal;font-weight:600;opacity:.72;letter-spacing:0;font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:no-preference){.sm-cham{transition:background .2s ease}}

/* Tôn trọng thiết lập giảm chuyển động của hệ điều hành trên toàn app. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{scroll-behavior:auto!important;animation-duration:.01ms!important;
    animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ===== SOURCE: styles/mobile-runtime.css ===== */
/* ═══════════════ b164 — ĐIỆN THOẠI: LỀ AN TOÀN + BÀN PHÍM ═══════════════
   Anh Đạt báo 25/08: "bàn phím của điện thoại ảnh hưởng tầm nhìn app, khi tắt
   bàn phím xuống thì tạm ổn." Anh dùng kiểu ĐÃ THÊM VÀO MÀN HÌNH CHÍNH — không
   còn thanh địa chỉ che, nên cả hai lỗi dưới đây lộ rõ nhất ở kiểu đó.

   HAI nguyên nhân, phải trị đủ cả hai:

   1. LỀ AN TOÀN. index.html bật `viewport-fit=cover` và status bar
      `black-translucent` — tức đã bảo iOS cho nội dung tràn ra tận mép máy.
      Nhưng CSS chưa dùng env(safe-area-inset-*) một lần nào (đếm được 0 trong
      cả cây 81 file), nên thanh 5 nút nằm đè lên vạch home — dải iOS giữ riêng
      cho cử chỉ vuốt, bấm hay không ăn — và đầu trang chui lên dưới đồng hồ.

   2. BÀN PHÍM. Bàn phím iOS làm màn hình NHÌN THẤY co lại, nhưng khung layout
      thì KHÔNG. Nên `height:100vh` và `position:fixed;bottom:0` vẫn tính theo
      cả màn hình: thanh 5 nút, thanh đơn-đang-theo-dõi và dòng thông báo rơi
      ra sau lưng bàn phím, còn vùng cuộn `.view` thì kéo dài xuống dưới bàn
      phím nên ô đang gõ trôi khỏi tầm nhìn.
      ⚠️ `100dvh` KHÔNG chữa được — iOS cố ý loại bàn phím khỏi mọi đơn vị
      viewport. Chỉ `visualViewport` đo được, app.js đặt --vvh và --kb.
      Máy nào không có visualViewport thì hai biến đó vắng mặt và mọi dòng
      dưới đây rơi về đúng giá trị cũ — không hỏng gì.

   ĐỪNG hạ cỡ chữ ô nhập xuống dưới 16px: chuyện iPhone tự phóng to đã trị từ
   b146, khối ở trên. Hai chuyện khác nhau, đừng gộp.
   Bài kiểm bắt buộc trên MÁY THẬT (Sổ lỗi #27): trang "Thước đo iPhone". */

@media (max-width:880px){
  /* ---- 1 · lề an toàn ---- */
  .app{padding-top:env(safe-area-inset-top)}
  .rail{padding-bottom:calc(4px + env(safe-area-inset-bottom))}
  .view{padding-bottom:calc(78px + env(safe-area-inset-bottom))}
  .pos3{padding-bottom:calc(78px + env(safe-area-inset-bottom))}

  /* ---- 2 · bàn phím ---- */
  .app{height:var(--vvh,100dvh)}
  .rail{bottom:var(--kb,0px)}
  .sale-follow{bottom:calc(66px + var(--kb,0px) + env(safe-area-inset-bottom))}
  .toasts{bottom:calc(18px + var(--kb,0px) + env(safe-area-inset-bottom))}
  .sale-follow:not([hidden]) + .toasts{bottom:calc(138px + var(--kb,0px) + env(safe-area-inset-bottom))}

  /* ⚠️ TÊN LỚP: phải là `banphim`, KHÔNG được đặt `kbd`.
     App đã có sẵn `.kbd` từ trước — đó là cái phím giả in chữ F2/F9, và nó
     khai `font-family:var(--f-mono)` cùng viền, nền, padding. Đặt `body.kbd`
     là biến CẢ CÁI APP thành một phím bấm: toàn bộ chữ nhảy sang phông máy
     chữ. Ba bộ kiểm (17/17 · 271/271 · 63/63) và 23 phép đo trong trình duyệt
     đều XANH HẾT khi đang dính lỗi này — chỉ chụp màn hình ra nhìn mới thấy.
     Sổ lỗi #40. Đặt tên lớp mới thì grep xem tên đó có ai dùng chưa.

     Bàn phím lên thì giấu thanh điều hướng: lúc đang gõ không ai bấm nó, mà
     giấu đi thì phần màn hình còn lại dành hết cho kết quả tìm hàng. Bỏ luôn
     78px chừa cho nó, không thì đáy vùng cuộn thừa một mảng trống. */
  body.banphim .rail{display:none}
  body.banphim .view{padding-bottom:12px}
  body.banphim .pos3{padding-bottom:10px}
  body.banphim .sale-follow{bottom:calc(10px + var(--kb,0px))}
  body.banphim .toasts{bottom:calc(10px + var(--kb,0px))}
  body.banphim .sale-follow:not([hidden]) + .toasts{bottom:calc(80px + var(--kb,0px))}
}

/* ═══════════════ b165 — ĐIỆN THOẠI: PHIẾU BÁN HÀNG THÀNH NGĂN KÉO ═══════════════
   Anh Đạt 26/08, sau khi thử b164 trên iPhone thật:
   *"Phần chính là phiếu bán hàng nằm tận dưới đáy, việc theo dõi k tiện vì thêm
   sản phẩm kéo xuống càng dài. Bạn có thể làm 1 nút gọn (như kiểu xem giỏ hàng),
   khi mình chọn sản phẩm thì Số lượng sẽ hiển thị nhỏ bên trên, nhấn vào thì là
   phiếu bán hàng."*

   ⚠️ ĐỌC TRƯỚC KHI SỬA: một nửa việc này ĐÃ CÓ SẴN từ trước — khối
   `@media(max-width:880px){.paybar.on{...}}` ở trên đã là thanh dính đáy có số
   mặt hàng và tổng tiền. Anh Đạt không thấy nó vì `renderPaybar()` giấu thanh
   khi giỏ TRỐNG, mà lúc anh thử thì sổ chưa có mặt hàng nào.
   → b165 KHÔNG dựng lại thanh đó. Chỉ làm hai việc: cho nó luôn hiện trên điện
   thoại, và cho nửa trái bấm được để kéo phiếu lên.

   🔴 VÀ VÁ NỐT MỘT CHỖ b164 BỎ SÓT: b164 kéo `.rail`, `.sale-follow`, `.toasts`
   lên theo bàn phím nhưng QUÊN `.paybar` — nó vẫn đóng đinh `bottom:60px`, nên
   bàn phím lên là thanh tổng tiền nằm sau lưng bàn phím, đúng cái lỗi b164 sinh
   ra để chữa. Đếm sót vì lúc đó giỏ trống nên thanh không hiện, không ai thấy.
   → Bài học: liệt kê MỌI thứ `position:fixed` rồi mới vá, đừng vá thứ đang nhìn thấy. */

@media (max-width:880px){

  /* ---- 1 · vá chỗ b164 bỏ sót ---- */
  .paybar.on{
    bottom:calc(60px + var(--kb,0px) + env(safe-area-inset-bottom));
  }
  body.banphim .paybar.on{ bottom:calc(8px + var(--kb,0px)); }
  /* bàn phím lên thì thanh nút đã giấu, nhưng thanh tổng tiền vẫn còn —
     chừa chỗ cho nó, không thì dòng cuối chui xuống dưới nó */
  body.banphim .pos3{ padding-bottom:70px; }

  /* ---- 2 · nửa trái thanh = nút mở phiếu ---- */
  .paybar .pb-l{
    text-align:left; padding:0; background:none; border:0; color:inherit;
    align-items:flex-start;
  }
  .paybar .pb-n{ display:flex; align-items:center; gap:5px; }
  .paybar .pb-n svg{
    width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.2; opacity:.85;
  }
  .paybar.trong .pb-t{ font-size:15px; font-weight:700; opacity:.82; font-family:var(--f-ui); letter-spacing:0; }
  .paybar .pb-nhe{
    background:rgba(255,255,255,.16); border:1px solid rgba(255,255,255,.3);
  }
  .paybar .pb-nhe:active{ background:rgba(255,255,255,.26); }

  /* ---- 3 · phiếu bán hàng thành ngăn kéo ---- */
  .gio-nen{
    position:fixed; inset:0; z-index:75; background:rgba(8,32,52,.44);
    opacity:0; pointer-events:none; transition:opacity .2s ease-out;
  }
  body.gio .gio-nen{ opacity:1; pointer-events:auto; }

  .tape-col{
    position:fixed; left:0; right:0; bottom:0; z-index:80;
    grid-template-rows:auto 1fr;
    /* ⚠️ CHIỀU CAO PHẢI XÁC ĐỊNH. Thử `height:auto; max-height:...` thì hỏng:
       chiều cao không xác định nên `1fr` của lưới bên trong chia theo NỘI DUNG
       chứ không theo khung, rồi khung mới bị kéo tới trần — dư ra 85px trắng
       nằm dưới nút Thanh toán (đo được 26/08: .tape cao 719 mà tổng hàng 639).
       Đặt chiều cao xác định rồi cho cả chuỗi co giãn bằng flex. */
    height:min(92vh, calc(var(--vvh,100dvh) - 44px));
    background:var(--bg);
    border-top:1px solid var(--line);
    border-radius:18px 18px 0 0;
    box-shadow:0 -12px 40px rgba(8,51,79,.30);
    /* Bề ngang phải bằng đúng lúc phiếu nằm trong dòng, không thì ruột phiếu
       (ô Giảm giá, hàng tiền gợi ý, dòng KHÁCH TRẢ) bị cắt mất mép phải.
       Trước: .tape-col padding 0 → tape 390 − viền 4 − .tape-in 32 = 354.
       Nay:   padding 0 4px      → tape 382 − viền 4 − .tape-in 24 = 354. Bằng nhau. */
    padding:0 4px calc(6px + env(safe-area-inset-bottom));
    overflow:hidden; min-height:0;
    transform:translateY(102%);
    transition:transform .22s ease-out;
  }
  body.gio .tape-col{ transform:translateY(0); }
  /* Chuỗi co giãn từ ngăn kéo xuống tới danh sách hàng: mỗi mắt phải min-height:0
     thì con mới co được, không thì phần thừa dồn xuống đáy thành mảng trắng. */
  .tape-col{ display:flex; flex-direction:column; }
  .tape-col .tape{ flex:1 1 0%; min-height:0; display:flex; flex-direction:column; }
  /* Cơ sở phải là 0%, KHÔNG phải auto. Với `flex-basis:auto` trình duyệt lấy
     chiều cao nội dung làm mốc rồi mới chia phần dư — đo 26/08 thì nó không
     chia, để lại đúng 85px trắng dưới nút Thanh toán. `0%` buộc chia theo khung. */
  .tape-col .tape-in{ flex:1 1 0%; min-height:0; display:flex; flex-direction:column; }
  .tape-col .tape-in > .items{ flex:1 1 0%; min-height:0; overflow-y:auto; }
  .tape-col .tape-in > .tape-hd,
  .tape-col .tape-in > .tape-ft{ flex:0 0 auto; }
  /* Hai dải răng cưa trang trí: trong ngăn kéo chúng chỉ làm rối phép chia
     chiều cao. Giấu đi, rồi cho ruột phiếu chiếm trọn khung. */
  .tape-col .zig{ display:none; }
  .tape-col .tape-in{ height:100%; }
  /* 🔴 CHỖ THẬT SỰ GÂY RA 85px TRẮNG: `.tape` có padding-bottom 76px, chừa sẵn
     cho thanh thanh toán hồi nó còn nằm TRONG dòng. Nay phiếu là ngăn kéo và
     thanh thanh toán nằm ngoài, khoảng chừa đó thành mảng trắng dưới nút.
     Mất gần một tiếng đi tìm trong flex/grid, hoá ra chỉ là một dòng padding —
     Sổ lỗi #43: đọc padding và margin TRƯỚC khi nghi ngờ cách chia khung. */
  .tape-col .tape{ padding-bottom:0; }
  .tape-col .tape-in{ padding:0 12px; }

  .gio-top{
    display:flex; align-items:center; gap:10px;
    padding:11px 8px 5px; position:relative; flex:0 0 auto;
  }
  .gio-top strong{ font-size:15.5px; font-weight:800; letter-spacing:-.01em; }
  .gio-keo{
    position:absolute; top:6px; left:50%; transform:translateX(-50%);
    width:42px; height:4px; border-radius:99px; background:var(--line);
  }
  .gio-x{
    margin-left:auto; width:34px; height:34px; border-radius:9px;
    display:grid; place-items:center;
    background:var(--sky-50); border:1px solid var(--line); color:var(--slate);
  }
  .gio-x svg{ width:18px; height:18px; stroke:currentColor; fill:none; stroke-width:2.2; }

  /* ---- 4 · dòng thông báo phải tránh thanh giỏ ----
     .toasts nằm NGOÀI .view nên không có quan hệ anh em với .paybar — chọn
     bằng lớp trên body (app.js đặt trong renderPaybar). Không có khối này thì
     toast "Đã thêm ..." đè thẳng lên tổng tiền. */
  body.cogio .toasts{
    bottom:calc(126px + var(--kb,0px) + env(safe-area-inset-bottom));
  }
  /* Ngăn kéo mở thì đáy màn hình là dòng KHÁCH TRẢ và nút Thanh toán — hai thứ
     KHÔNG được để bất cứ gì đè lên. Đẩy dòng thông báo lên đầu màn hình.
     Ảnh chụp 26/08 cho thấy toast "Đã thêm ..." nằm chồng đúng lên tổng tiền. */
  body.gio .toasts{
    top:calc(env(safe-area-inset-top) + 12px);
    bottom:auto;
  }
  body.cogio.banphim .toasts{ bottom:calc(74px + var(--kb,0px)); }
  body.cogio .sale-follow{
    bottom:calc(126px + var(--kb,0px) + env(safe-area-inset-bottom));
  }
  body.cogio .sale-follow:not([hidden]) + .toasts{
    bottom:calc(200px + var(--kb,0px) + env(safe-area-inset-bottom));
  }
  .toasts .toast{ max-width:min(300px, calc(100vw - 40px)); }

  /* ---- 5 · góc phải thanh nút: huy hiệu + số bản, xếp như một nút ----
     Anh Đạt 26/08: "Phiên bản có thể ghi nhìn chuyên nghiệp hơn k".
     Xếp dọc cho khớp nhịp mấy nút bên cạnh (biểu tượng trên, chữ dưới),
     và nowrap để "Online 1" không bị bẻ làm hai dòng. */
  /* ⚠️ ĐO TRƯỚC KHI SỬA CHỖ NÀY. Thanh dưới là một hàng flex: 5 nút đích +
     ô này. Máy hẹp nhất hay gặp là iPhone SE 375px. Ô này rộng thêm một chút
     là 5 nút đẩy nó tràn khỏi mép phải và huy hiệu bị CẮT — đã xảy ra thật khi
     đặt min-width:64px, và không phép đo nào bắt được, chỉ chụp ảnh mới thấy.
     Tính: 5 × 56 + 70 + 4 = 354 < 375. Còn dư chỗ.
     Nới min-width của .navbtn xuống 56px (vẫn hơn ngưỡng chạm 44px) để nhường. */
  .navbtn{ min-width:56px; }
  .rail-ft{
    flex:0 0 auto; flex-direction:column; align-items:center; justify-content:center;
    gap:2px; padding:5px 6px 4px; min-width:68px; max-width:80px; text-align:center;
    font-size:8.5px; color:rgba(255,255,255,.40); letter-spacing:.06em;
    font-family:var(--f-mono);
  }
  .rail-ft .server-mode{
    font-size:9px; font-weight:800; letter-spacing:.02em; padding:3px 7px;
    white-space:nowrap; max-width:100%;
  }
}

/* ═══ b165 · NGĂN KÉO PHIẾU: ƯU TIÊN DANH SÁCH HÀNG ═══
   Anh Đạt 26/08: *"màn hình phải nhìn được ít nhất 4 sản phẩm"*.
   **(ĐÃ ĐO 26/08, iPhone 390×844)** ngăn kéo cao 709px, chia ra:
   `.gio-top` 58 · `.tape-hd` 116 · **`.items` 124** · **`.tape-ft` 274**.
   Một dòng hàng cao **117px** → chỉ thấy **1 sản phẩm**. Khối thanh toán ăn
   gần hết chỗ, mà lúc đang thêm hàng thì chưa ai cần tới nó.
   → Gấp `.ftgrid` + `.quickcash` lại sau nút "Thuế · giảm giá".
   → Dòng KHÁCH TRẢ và nút Thanh toán KHÔNG bao giờ giấu.
   Ngưỡng nghiệm thu: `thu/kiem-gio.js` đếm số dòng hàng NHÌN THẤY TRỌN VẸN,
   phải **>= 4**. Đừng sửa chỗ này mà không chạy lại phép đếm đó. */
@media (max-width:880px){
  /* ⚠️ Lớp của hàng tiền gợi ý là `.cashsug`, KHÔNG phải `.quickcash`.
     Lần đầu nhắm nhầm `.quickcash` nên nó vẫn chiếm 31px mà không ai thấy —
     chỉ lộ ra khi đo chiều cao từng khối con. Đo, đừng nhắm. */
  body.gio .tape-ft .ftgrid,
  body.gio .tape-ft .cashsug{ display:none; }
  body.gio.chitiet .tape-ft .ftgrid{ display:grid; }
  body.gio.chitiet .tape-ft .cashsug{ display:flex; }

  /* Tiêu đề chồng tiêu đề: `.gio-top` đã ghi "Phiếu bán hàng" rồi thì thanh
     `.tape-bar` bên trong lặp lại y hệt — 36px không nói thêm điều gì. */
  body.gio .tape .tape-bar{ display:none; }
  /* Dòng ngày giờ + đếm mặt hàng: số mặt hàng đã có trên thanh giỏ, ngày giờ
     có trên phiếu in. Trong ngăn kéo thì 16px này chỉ để chiếm chỗ. */
  body.gio .tape-hd .meta{ display:none; }

  /* Ô ghi chú từng dòng hàng cao 28px × mỗi dòng — nhân với 5 dòng là 140px,
     tức mất hơn một sản phẩm rưỡi. Gấp lại, nhưng dòng nào ĐÃ GÕ ghi chú thì
     vẫn hiện (`:has`), để không có chữ nào của anh Đạt bị giấu đi. */
  body.gio .item .ntrow{ display:none; }
  body.gio.chitiet .item .ntrow{ display:flex; }
  body.gio .item:has(.ntrow input:not(:placeholder-shown)) .ntrow{ display:flex; }

  .gio-ct{
    margin-left:auto; display:inline-flex; align-items:center; gap:4px;
    font-size:11.5px; font-weight:700; color:var(--sky-700);
    background:var(--sky-50); border:1px solid var(--line);
    border-radius:99px; padding:5px 10px; white-space:nowrap;
  }
  .gio-ct svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4;
    transition:transform .18s ease-out; }
  body.chitiet .gio-ct{ background:var(--sky-100); color:var(--sky-800); }
  body.chitiet .gio-ct svg{ transform:rotate(180deg); }
  .gio-top .gio-x{ margin-left:6px; }

  /* Ô Giảm giá và Khách đưa đóng đinh width:124px từ khối b146, cộng nhãn là
     tràn khỏi mép phải phiếu — đo được 26/08: mép phải 392 và 403 trên khung
     rộng 390. Cho chúng co lại theo ô chứa. */
  body.gio .tape-ft .fcell{ min-width:0; }
  body.gio .tape-ft .fcell input,
  body.gio .tape-ft .fcell select{ width:100%; min-width:0; }
}

/* ═══════ b166 · 🔴 MÀN BÁN HÀNG TRÊN ĐIỆN THOẠI KHÔNG CUỘN ĐƯỢC ═══════
   Anh Đạt 26/08: *"Gợi ý 12 sản phẩm nhưng lướt xem k được. Giữ lướt thì app
   nhận diện chọn sản phẩm luôn. Cái này quan trọng vì nó sẽ làm việc chọn nhầm
   hàng xảy ra thường xuyên."*

   NGUYÊN NHÂN — có sẵn từ b163, không phải do b164/b165 (đã so ba bản):

     app.css:190  .view.pos{ overflow:hidden }        ← màn Bán hàng khoá cuộn
     app.css:268  .results{ overflow:auto }           ← máy tính: DANH SÁCH tự cuộn
     app.css:849  @media(<=880px){ .results{overflow:visible} }
                                                      ← điện thoại: bỏ luôn cuộn đó

   Máy tính: `.view` khoá nhưng `.results` cuộn → đúng.
   Điện thoại: `.view` khoá, `.results` cũng bỏ cuộn → **KHÔNG CÒN AI CUỘN.**

   Trước đây không ai thấy vì danh mục rỗng, chẳng có gì để cuộn. Nạp 20 mặt
   hàng vào sổ thử là lộ ngay.

   ⚠️ VÌ SAO PHÉP ĐO CỦA CLAUDE BÁO "CUỘN ĐƯỢC": nó kiểm
   `scrollHeight > clientHeight` — **đúng cả khi overflow:hidden**, và
   `element.scrollTop = 120` bằng mã **cũng chạy** trên khung overflow:hidden.
   Hai phép đo đều trả về giá trị hợp lệ mà sai — Sổ lỗi #35, #44.
   Muốn biết có cuộn được bằng NGÓN TAY thì phải đọc `getComputedStyle().overflowY`,
   hoặc vuốt thật rồi đo. */
@media (max-width:880px){
  .view.pos{ overflow-y:auto; -webkit-overflow-scrolling:touch; }
}

/* ═══════════════════════════════════════════════════════════════════════
   b169 · THANH TÌM HÀNG DÍNH LẠI · HUY HIỆU MÁY CHỦ LÊN THANH TIÊU ĐỀ
   Anh Đạt 26/08: "khi cuộn xuống xem hàng là thanh tìm hàng bị trôi luôn.
   Và ô Online + phiên bản để trên cùng bên phải, sát tài khoản đang dùng."
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width:880px){

  /* ---- 1 · thanh tìm hàng dính lại ----------------------------------
     b166 mở cuộn cho .view.pos để vuốt xem 12 gợi ý (Sổ lỗi #44). Hệ quả
     KHÔNG AI LƯỜNG: cả .pos3 cuộn theo, nên THANH TÌM trôi khỏi màn hình.
     Một bản vá đẻ ra một lỗi mới, và ba tuần sau không ai nối được hai
     chuyện với nhau nếu không ghi ở đây.

     ⚠️ Vì sao phải mở .pos3-main ra trước: nó đang overflow:hidden, mà một
     phần tử overflow khác visible thì TỰ NÓ thành khung cuộn. position:sticky
     dính vào khung cuộn GẦN NHẤT — tức dính vào .pos3-main chứ không phải
     .view.pos. Mà .pos3-main không cuộn, nên sticky nằm im không làm gì cả,
     KHÔNG báo lỗi, KHÔNG hiện ra trong bộ kiểm. Đúng họ Sổ lỗi #44:
     thứ trông như đã bật mà thật ra chưa bao giờ chạy. */
  .pos3-main{ overflow:visible; }

  .scanner{
    position:sticky; top:0;
    z-index:3;                 /* trên .res-head (2), dưới .paybar (55),
                                  thanh dưới (60), ngăn kéo phiếu (80).
                                  Đo thật trong app.css, không đoán. */
    /* .scanner đã có background:var(--paper) từ đầu — sticky mà nền trong
       suốt thì hàng cuộn lên sẽ hiện xuyên qua chữ. Ghi lại đây để ai gỡ
       nền ở trên biết là nó đang gánh thêm việc này. */

    /* DẢI NỀN NỐI THÊM DƯỚI ĐÁY — đo được rồi mới thêm, không phải cho đẹp:
       chụp màn hình lúc cuộn 400px thấy một thẻ hàng trắng thò ra ngay sát
       dưới viền đáy thanh tìm, lộ cả góc bo và viền, trông như thanh tìm bị
       dán thêm một thẻ ma. Bộ kiểm không thấy — nó chỉ đếm toạ độ, mà toạ độ
       thì đúng (Sổ lỗi #40: bộ kiểm đo số, không đo xấu — mở ra nhìn).
       Nguyên do: dính rồi thì hàng cuộn lên chạm ĐÚNG mép đáy thanh tìm,
       không còn khoảng thở như lúc nằm yên.
       Cách chữa: bóng thứ hai, không nhoè, nở 10px và dời xuống 10px — thành
       một dải var(--bg) đặc dài đúng 20px dưới đáy, hàng cuộn chui sau nó.
       Vì sao đúng 20px: đo trong trình duyệt — .pos3-main gap 10px và có một
       div rỗng chen giữa ăn thêm một gap nữa, nên lúc nằm yên đáy thanh tìm
       ở y=151 mà khối hàng bắt đầu ở y=171. Lấy đúng 20 thì lúc nằm yên dải
       này phủ vừa khít khoảng trống sẵn có, KHÔNG che mất mép thẻ đầu tiên.
       Đổi gap thì phải đổi số này — không thì nó ăn vào thẻ.

       ⚠️ LẦN ĐẦU LÀM BẰNG box-shadow LỚP HAI — KHÔNG ĂN, và không báo gì.
       Vì `.scanner:focus-within` (dòng 300) cũng đặt box-shadow, mà nó nặng
       ký hơn (0,2,0 so với 0,1,0) nên đè mất. Ô tìm hàng thì gần như LÚC NÀO
       CŨNG đang được chọn — focusScan() gọi sau mỗi lần thêm/bớt hàng — nên
       lớp bóng mới không bao giờ được vẽ. Đo pixel ra vẫn trắng y như cũ.
       Dùng ::after thì không ai đè được, và cũng không đụng vào bóng sẵn có. */
  }
  .scanner::after{
    /* Nới ra -10px cho bằng ĐÚNG padding hai bên của .pos3 trên màn nhỏ
       (10px), để dải chạm mép màn hình. Để -2px thì cái đuôi bóng mờ của
       thanh tìm còn thò ra hai bên rồi bị cắt ngang, thành hai vệt xám nhỏ.
       Đổi padding .pos3 thì đổi luôn số này. Không nới quá 10 — quá thì
       .view.pos sinh thanh cuộn ngang. */
    content:''; position:absolute; left:-10px; right:-10px;
    top:calc(100% + 1.5px);      /* 100% là đáy hộp ĐỆM, cộng 1.5px cho hết viền */
    height:20px; background:var(--bg); pointer-events:none;
  }

  /* .res-head ("HÀNG BÁN CHẠY 12") cũng sticky top:0. Hai thứ cùng dính ở
     một mốc thì chồng lên nhau — cái z-index thấp hơn chui xuống dưới rồi
     biến mất, trông như lỗi vẽ. Chỉ để ĐÚNG MỘT thứ dính: thanh tìm. */
  .results .res-head{ position:static; }

  /* ---- 2 · huy hiệu máy chủ + số bản lên thanh tiêu đề ---------------
     Rời khỏi chân thanh bên. Thanh dưới nay chỉ còn 5 nút đích. */
  .rail-ft{ display:none; }

  /* Trả .navbtn về bề rộng cũ. Con số 56px đặt ra hồi huy hiệu còn chen
     chỗ ở thanh dưới; nay nó đi rồi thì không phải bóp nữa.
     ĐO LẠI cho máy hẹp nhất hay gặp — iPhone SE 375px:
        5 nút × 68 = 340 < 375.  Còn dư 35px. */
  .navbtn{ min-width:68px; }

  .head-may{
    margin-left:auto;           /* việc đẩy sang phải nay là của khối này */
    display:inline-flex; flex-direction:column; align-items:flex-end;
    gap:2px; line-height:1; flex:0 0 auto;
  }
  .head-ban{
    font-family:var(--f-mono); font-size:10.5px; font-weight:700;
    letter-spacing:.04em; color:var(--slate-2);
  }
  .head-may .server-mode{
    white-space:nowrap;
    /* .server-mode sinh ra cho CHÂN THANH BÊN, cỡ 8px. Trên thanh tiêu đề
       điện thoại thì 8px quá nhỏ — mà 8px cũng KHÔNG nằm trên thang chữ:
       nấc nhỏ nhất của tờ nhận diện là --t0 10.5px. Kéo lên đúng nấc, cho
       bằng .head-ban ngay dưới nó.
       Viết thẳng 10.5px chứ không var(--t0): app.css KHÔNG khai --t0 (đã
       grep 26/08). Dùng biến không khai thì nó im lặng không ăn — đúng cái
       bẫy .ei-r:hover/--sky-1 mà tờ nhận diện ghi. */
    font-size:10.5px; padding:2px 6px;
  }

  /* .mobile-account đang giữ margin-left:auto từ khối trước. Nay .head-may
     làm việc đó, nên nút tài khoản chỉ cần nằm SÁT bên phải huy hiệu —
     đúng chỗ anh Đạt yêu cầu. */
  .mobile-account{ margin-left:6px; }

  /* ---- 2b · giữ huy hiệu + nút tài khoản KHÔNG bị đẩy khỏi màn ----------
     ĐO ĐƯỢC 26/08 trên iPhone SE 375px, màn Hóa đơn:
        #head nội dung 439px / khung 375  →  nút tài khoản hết ở x=439.
     Tức là nó đã NẰM NGOÀI MÀN TỪ TRƯỚC b169, không phải lỗi mới —
     đo lại sau khi bỏ .head-may đi vẫn 439. b169 chỉ làm nó tệ thêm
     (507) và làm nó lộ ra. Ghi rõ để đừng ai đi tìm nhầm ở b169.

     Vì sao: .head là một hàng flex nowrap. Màn Hóa đơn nhét thêm hai nút
     chữ dài — "Xem lợi nhuận" 148px và "Xuất Excel" 127px. Cộng tiêu đề
     70 + huy hiệu 58 + nút tài khoản 40 + 5 khoảng cách là quá 375.
     Nút cuối hàng bị đẩy ra ngoài, mà .head không cuộn ngang nên nó mất hẳn.

     ĐÃ THỬ VÀ BỎ — cho nút co lại bằng `flex:0 1 auto; overflow:hidden;
     text-overflow:ellipsis`. Số đo đẹp (375/375, không nút nào ra ngoài)
     nhưng MỞ RA NHÌN thì chữ bị cắt cụt KHÔNG có dấu ba chấm — hiện ra
     "Xem lợi nh" và "Xuất Exc". Lý do: text-overflow chỉ ăn trên hộp khối,
     .btn là hộp flex nên nó lờ đi. Đúng Sổ lỗi #40: bộ kiểm đo số, không
     đo xấu — chụp ảnh ra nhìn mới thấy.
     Nay chữa ở MÃ chứ không ở CSS: màn hẹp thì rút gọn nhãn (xem
     VIEWS.invoices.head trong app.js). Ở đây chỉ chốt một luật: huy hiệu
     và nút tài khoản KHÔNG BAO GIỜ bị bóp — hai thứ này anh Đạt yêu cầu
     phải nằm trên cùng bên phải. */
  .head{ min-width:0; }
  .head-may, .head .mobile-account{ flex:0 0 auto; }
}
