
/* ═══════════════════════════════════════════════════════════════════════════
   v3.61 · BIẾN MÀU NGỮ NGHĨA
   Mọi màu nền/viền/chữ phổ biến trong CSS và trong các màn hình đã được thay bằng các biến
   dưới đây. Giá trị hiện tại = đúng màu cũ, giao diện sáng không đổi. Chế độ tối sau này
   chỉ cần khai lại bộ giá trị này dưới [data-theme="dark"], không phải sửa từng màn hình.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --surface:          #ffffff;   /* nền thẻ, ô nhập, menu nổi */
  --surface-2:        #f6f8f7;   /* nền phụ: hàng tiêu đề bảng, dải nhóm */
  --surface-3:        #fafbfa;   /* nền rất nhạt: hàng chẵn, vùng trống */
  --on-accent:        #ffffff;   /* chữ trên nền màu nhấn */
  --ok-bg:            #eef7f0;
  --ok-bg-strong:     #dcf3e4;
  --warn-bg:          #fff9f0;
  --warn-bg-strong:   #fef3c7;
  --danger-bg:        #fff7f7;
  --danger-bg-strong: #fee2e2;
  --info-bg:          #e9eef7;
  --info-bg-soft:     #eff6ff;
  --danger-ink:       #a8341c;
  --ink-soft:         #5d6b62;
  --ink-green:        #14532d;   /* chữ xanh đậm nhấn mạnh */
  --warn-ink:         #b45309;
  --glass-rgb:        255 255 255; /* lõi màu của các lớp kính mờ */
}
:root{
  --g900:#0B4A25; --g800:#12652F; --g700:#15803D; --g600:#1CA14C; --g500:#22C55E;
  --g100:#DCFCE7; --g50:#F0FDF4;
  --navy:#1E3A6E; --navy-d:#132747; --navy-l:#2E5296;
  --orange:#E08A2B; --orange-l:#FDF0DC;
  --red:#DC2626; --red-l:#FEE2E2;
  --bg:#F5F7F6; --card:#FFFFFF; --line:#E3E8E5;
  --ink:#111827; --ink2:#4B5563; --muted:#6B7280;
  --r:12px; --sh:0 1px 2px rgba(16,24,40,.05),0 4px 12px rgba(16,24,40,.05);
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI','Helvetica Neue',Arial,sans-serif;background:var(--bg);color:var(--ink);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font-family:inherit;font-size:inherit}

/* ---------- Prototype chrome ---------- */

/* ---------- Logo ---------- */
.logo{display:flex;align-items:center;gap:9px}
.logo svg{display:block}
.logo-txt{line-height:1.05}
.logo-txt .l1{font-weight:800;font-size:15px;letter-spacing:.4px}
.logo-txt .l2{font-size:9.5px;letter-spacing:2.6px;color:var(--orange);font-weight:600}

/* ---------- Layout ---------- */
.app{display:flex;min-height:calc(100vh - 42px)}
.side{width:238px;flex:0 0 238px;background:var(--navy-d);color:#C7D2E4;padding:16px 12px;display:flex;flex-direction:column;gap:2px}
.side .brand{padding:6px 8px 18px;color:var(--on-accent)}
.scrollnav{flex:1;overflow-y:auto;margin:0 -4px;padding:0 4px;display:flex;flex-direction:column;gap:2px}
.scrollnav::-webkit-scrollbar{width:5px}.scrollnav::-webkit-scrollbar-thumb{background:rgb(var(--glass-rgb) / .18);border-radius:9px}
.side .grp{font-size:10.5px;text-transform:uppercase;letter-spacing:1.2px;color:#7C8DAA;padding:16px 10px 6px}
.side a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:9px;font-size:13.5px;font-weight:500;transition:.15s}
.side a:hover{background:rgb(var(--glass-rgb) / .07);color:var(--on-accent)}
.side a.on{background:var(--g700);color:var(--on-accent);font-weight:600}
.side a .ic{width:17px;text-align:center;opacity:.9}
.side .who{margin-top:auto;border-top:1px solid rgb(var(--glass-rgb) / .1);padding:12px 8px 2px;font-size:12px;color:#93A4BF}
.side .who b{display:block;color:var(--on-accent);font-size:13px}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.top{background:var(--surface);border-bottom:1px solid var(--line);padding:14px 24px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.top h1{font-size:19px;font-weight:700;letter-spacing:-.2px}
.top .sub{color:var(--muted);font-size:12.5px}
.top .right{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.content{padding:22px 24px 60px;max-width:1280px;width:100%}

/* ---------- Atoms ---------- */
.btn{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:9px;border:1px solid transparent;background:var(--g700);color:var(--on-accent);font-weight:600;font-size:13px;cursor:pointer;transition:.15s}
.btn:hover{background:var(--g800)}
.btn.sec{background:var(--surface);color:var(--ink);border-color:var(--line)}
.btn.sec:hover{background:var(--surface-2)}
/* v3.45 · Mục 4 — chip thẻ nhanh (Chất lượng sản phẩm) đang được chọn */
.btn.sec.tagchip.on{background:var(--g600,#16a34a);border-color:var(--g600,#16a34a);color:var(--on-accent)}

/* v3.48 · Mục 5 — nút mở camera to, dễ nhận biết cho màn hình Chất lượng sản phẩm */
.qccambtn{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;width:100%;box-sizing:border-box;padding:36px 20px;border-radius:18px;cursor:pointer;
  background:linear-gradient(135deg,#1B8F4F 0%,#0F6B3A 100%);color:var(--on-accent);text-align:center;
  box-shadow:0 16px 34px -16px rgba(15,107,58,.55);transition:transform .15s}
.qccambtn:active{transform:scale(.98)}
.qccambtn input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.qccambtn .ico{font-size:44px;line-height:1}
.qccambtn .tt{font-size:16px;font-weight:700}
.qccambtn .ss{font-size:12px;opacity:.85;max-width:320px}

/* v3.46 · Mục 6 — nâng cấp tự động cho bảng dài (>20 dòng), xem assets/js/tableenhance.js */
.tbltopbar{display:flex;gap:8px;flex-wrap:wrap;padding:8px 0;margin-bottom:2px}
.colf-row th{border-bottom:1px solid var(--line);text-align:left}
.colf-inp::placeholder{color:var(--muted);opacity:.8}
.btn.gho{background:transparent;color:var(--g700);border-color:var(--g600)}
.btn.warn{background:var(--orange)}
.btn.dan{background:var(--red)}
.btn.sm{padding:5px 10px;font-size:12px;border-radius:7px}
.btn.lg{padding:14px 22px;font-size:15.5px;border-radius:12px;font-weight:700}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
.card .hd{padding:14px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.card .hd h3{font-size:14.5px;font-weight:700}
.card .hd .r{margin-left:auto;font-size:12.5px;color:var(--muted)}
.card .bd{padding:16px}
.grid{display:grid;gap:16px}
.grid>*{min-width:0}
.pill{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:99px;font-size:11.5px;font-weight:600;white-space:nowrap}
.p-g{background:var(--g100);color:var(--g900)}
.p-n{background:var(--info-bg);color:var(--navy)}
.p-o{background:var(--orange-l);color:#8A5211}
.p-r{background:var(--red-l);color:#991B1B}
.p-s{background:#F1F3F2;color:var(--ink2)}
.kpi{padding:16px}
.kpi .lb{font-size:12px;color:var(--muted);font-weight:600;letter-spacing:.2px}
.kpi .vl{font-size:29px;font-weight:800;letter-spacing:-1px;margin:6px 0 2px}
.kpi .dt{font-size:12px;color:var(--muted)}
.kpi .dt .up{color:var(--g700);font-weight:600}
.kpi .dt .dn{color:var(--red);font-weight:600}
table{width:100%;border-collapse:collapse;table-layout:auto}
/* v3.41 · Bỏ "white-space:nowrap" khỏi tiêu đề cột — trên desktop đây là nguyên nhân
   chính khiến bảng nhiều cột buộc phải rộng hơn khung trang rồi hiện thanh trượt ngang
   dù còn thừa chỗ để NGẮT DÒNG (xem thêm .tblwrap > table ở khối responsive bên dưới,
   trước đây ép min-width:max-content cho MỌI kích thước màn hình, không chỉ điện thoại). */
th{text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);font-weight:700;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--surface-3)}
td{padding:11px 14px;border-bottom:1px solid var(--line);font-size:13.5px;vertical-align:middle;overflow-wrap:break-word}
td.mono{white-space:nowrap}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:var(--g50)}
.num{font-variant-numeric:tabular-nums;text-align:right}
label.f{display:block;font-size:12.5px;font-weight:600;color:var(--ink2);margin-bottom:5px}
.inp{width:100%;padding:8px 11px;border:1px solid #D7DDD9;border-radius:9px;background:var(--surface);outline:none}
.inp:focus{border-color:var(--g600);box-shadow:0 0 0 3px var(--g100)}
.fr{margin-bottom:14px}
.hint{font-size:12px;color:var(--muted);margin-top:5px}
.note{padding:11px 13px;border-radius:10px;font-size:12.8px;display:flex;gap:9px;align-items:flex-start}
.note.i{background:#EEF3FB;color:var(--navy)}
.note.w{background:var(--orange-l);color:#7A4A0F}
.note.d{background:var(--red-l);color:#8F1D1D}
.note.s{background:var(--g100);color:var(--g900)}
.sep{height:1px;background:var(--line);margin:16px 0}
.chart-wrap{position:relative;height:250px}
.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:12.5px;color:var(--ink2);margin-top:10px}
.legend i{width:10px;height:10px;border-radius:3px;display:inline-block;margin-right:6px}

/* ---------- Calendar ---------- */
.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:7px}
.cal .dow{text-align:center;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.8px;padding:4px 0}
.day{background:var(--surface);border:1px solid var(--line);border-radius:10px;min-height:118px;padding:7px;display:flex;flex-direction:column;gap:4px;position:relative}
.day.out{background:var(--surface-3);opacity:.5}
.day.past{opacity:.55}
.day.today{border-color:var(--g600);box-shadow:0 0 0 2px var(--g100)}
.day.lock{background:#F7F8F8}
.day .dn{font-size:12px;font-weight:700;color:var(--ink2);display:flex;align-items:center;gap:4px}
.day.today .dn{color:var(--g700)}
.day .lk{margin-left:auto;font-size:10px;color:var(--muted)}
.slot{font-size:10.5px;font-weight:600;padding:1px 5px;border-radius:5px;display:flex;justify-content:space-between;gap:4px}
.s1{background:var(--g100);color:var(--g900)}
.s2{background:var(--info-bg);color:var(--navy)}
.soff{background:var(--orange-l);color:#8A5211}
.slot.bad{background:var(--red-l);color:#991B1B}
.day .mine{margin-top:auto;font-size:10.5px;font-weight:700;letter-spacing:.3px;text-align:center;padding:3px;border-radius:6px}
/* v3.53 · Mục "đăng ký ca" — ô ngày chỉ có số ngày + 1 select, không cần cao như lịch có tên
   nhân sự/nhiều ca; thu ngắn lại để trọn cả tháng vừa màn hình, đỡ phải kéo thanh trượt. */
.cal.compact .day{min-height:64px;padding:5px;gap:3px}
.cal.compact .day .dn{font-size:11px}
.cal.compact .day .regsel{margin-top:0}
.m1{background:var(--g700);color:var(--on-accent)}
.m2{background:var(--navy);color:var(--on-accent)}
.mhc{background:#5FB98A;color:var(--on-accent)}
.mg{background:var(--navy-l);color:var(--on-accent)}
.shc{background:#E8F6EE;color:#0B4A25}
.sg{background:var(--info-bg);color:var(--navy)}
.moff{background:var(--orange);color:var(--on-accent)}
/* v3.49 · Mục 1 — "Lịch chi tiết theo nhân sự": ô ma trận rất hẹp (31 cột ngày), mã ca
   ngắn (HC/OFF) vừa khít nhưng mã dài (REMOTE) từng bị NGẮT DÒNG vì .mini chưa có CSS riêng
   (chỉ ăn theo .m1/.m2/.moff ở trên, không có white-space/kích thước cố định). Cố định
   không ngắt dòng + tự thu cỡ chữ nhỏ hơn cho mã dài (lớp .long, gắn ở modules/schedule/
   views/month.php theo độ dài mã) thay vì để tràn ra ngắt dòng xấu. */
/* v3.59 · Chỉ áp cho nhãn mã ca (span). Để trần ".mini" thì luật này ăn luôn vào khung
   .app.mini khi thu gọn menu trái: khung trang thành inline-block, nội dung rơi xuống dưới. */
span.mini{display:inline-block;white-space:nowrap;padding:2px 5px;border-radius:5px;
  font-size:10.5px;font-weight:700;line-height:1.35;letter-spacing:-.01em}
span.mini.long{font-size:8px;padding:2px 3px;letter-spacing:-.02em}

.kc{background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:9px 10px;cursor:grab;transition:.15s;box-shadow:0 1px 2px rgba(16,24,40,.04)}
.kc:hover{box-shadow:0 3px 10px rgba(16,24,40,.09);transform:translateY(-1px)}
.kc .kt{font-size:12.5px;font-weight:600;line-height:1.35}
.kc .km{display:flex;gap:4px;flex-wrap:wrap;margin-top:6px}
.kc .km .pill{font-size:9.5px;padding:2px 6px}
.kc .kf{display:flex;gap:6px;align-items:center;margin-top:7px;font-size:11px;color:var(--muted)}
.gantt-hd{display:grid;grid-template-columns:200px repeat(7,1fr);font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;border-bottom:1px solid var(--line);padding-bottom:6px}
.gantt-hd div{text-align:center}.gantt-hd div:first-child{text-align:left}
.grow{display:grid;grid-template-columns:200px 1fr;align-items:center;gap:8px}
.gtrack{position:relative;height:26px;background:var(--surface-2);border-radius:6px}
.gbar{position:absolute;height:100%;border-radius:6px;display:flex;align-items:center;padding:0 8px;color:var(--on-accent);font-size:10.5px;font-weight:700;white-space:nowrap;overflow:hidden}
.gms{position:absolute;top:50%;transform:translate(-50%,-50%) rotate(45deg);width:11px;height:11px;background:var(--navy);border:2px solid var(--surface);box-shadow:0 0 0 1px var(--navy)}
.gpsmini{position:relative;height:150px;background:linear-gradient(180deg,#EDF3EF 0%,#E3EDE7 100%);border-radius:12px;overflow:hidden;border:1px solid var(--line)}
.gpsmini:before{content:'';position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.6) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.6) 1px,transparent 1px);background-size:26px 26px}
.gpsring{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:104px;height:104px;border-radius:50%;background:rgba(28,161,76,.16);border:2px solid var(--g600)}
.gpsdot{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:11px;height:11px;border-radius:50%;background:var(--navy);box-shadow:0 0 0 3px #fff}
.gpspin{position:absolute;left:57%;top:44%;transform:translate(-50%,-100%);font-size:26px;color:var(--g700);filter:drop-shadow(0 2px 3px rgba(0,0,0,.25))}
.mapbox{position:relative;height:430px;background:linear-gradient(180deg,#EEF3F0 0%,#E4EDE8 100%);border-radius:12px;overflow:hidden;border:1px solid var(--line)}
.mapbox:before{content:'';position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.55) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.55) 1px,transparent 1px);background-size:38px 38px}
.mroad{position:absolute;background:var(--surface);opacity:.85}
.mzone{position:absolute;border-radius:50%;background:rgba(28,161,76,.18);border:2px solid var(--g600);transform:translate(-50%,-50%)}
.mcenter{position:absolute;width:12px;height:12px;border-radius:50%;background:var(--navy);transform:translate(-50%,-50%);box-shadow:0 0 0 3px #fff}
.mlabel{position:absolute;transform:translate(-50%,0);font-size:11px;font-weight:700;color:var(--navy);background:rgb(var(--glass-rgb) / .9);padding:2px 7px;border-radius:6px;white-space:nowrap}
.mpt{position:absolute;width:10px;height:10px;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 2px #fff;cursor:pointer}
/* ---------- Login ---------- */
.login{min-height:calc(100vh - 42px);display:grid;place-items:center;background:linear-gradient(150deg,#0B4A25 0%,#132747 100%);padding:24px}
.login .box{width:100%;max-width:390px;background:var(--surface);border-radius:16px;padding:30px 28px;box-shadow:0 20px 50px rgba(0,0,0,.25)}
.login .box h2{font-size:19px;font-weight:700;margin:16px 0 3px;text-align:center}
.login .box p.s{text-align:center;color:var(--muted);font-size:12.5px;margin-bottom:22px}
.login .lg{display:flex;justify-content:center}
.login .btn{width:100%;justify-content:center;padding:11px}
.login .ft{text-align:center;font-size:11.5px;color:var(--muted);margin-top:16px}

/* ---------- Tabs / misc ---------- */
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:18px;overflow-x:auto}
.tabs a{padding:9px 14px;font-size:13.5px;font-weight:600;color:var(--muted);border-bottom:2px solid transparent;white-space:nowrap}
.tabs a.on{color:var(--g700);border-bottom-color:var(--g700)}
.av{width:30px;height:30px;border-radius:50%;background:var(--g100);color:var(--g900);display:grid;place-items:center;font-size:11.5px;font-weight:700;flex:0 0 auto}
.av.n{background:var(--info-bg);color:var(--navy)}
.stack{display:flex;align-items:center;gap:9px}
.tl{position:relative;padding-left:22px;border-left:2px solid var(--line);margin-left:6px}
.tl .it{position:relative;padding-bottom:16px}
.tl .it:before{content:'';position:absolute;left:-27px;top:4px;width:9px;height:9px;border-radius:50%;background:var(--g600);border:2px solid var(--surface);box-shadow:0 0 0 2px var(--g100)}
.tl .it .t{font-size:11.5px;color:var(--muted)}
.tl .it .b{font-size:13px;margin-top:2px}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}
.bar{height:7px;border-radius:99px;background:#EDF0EE;overflow:hidden}
.bar i{display:block;height:100%;border-radius:99px;background:var(--g600)}

@media(max-width:900px){
  .side{position:fixed;left:0;top:42px;bottom:0;transform:translateX(-100%);transition:.2s;z-index:60}
  .side.open{transform:none}
  .content{padding:16px 14px 60px}
  .top{padding:12px 14px}
  .burger{display:inline-flex!important}
  .cal{gap:4px}
  .day{min-height:74px;padding:5px}
  .day .slot{font-size:9.5px;padding:1px 4px}
}
.burger{display:none;background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:7px 10px;cursor:pointer}
.tblwrap{overflow-x:auto}


/* ===== Bổ sung cho bản chạy thật ===== */
.app{min-height:100vh}
.side .brand a.logo{display:flex;align-items:center;gap:9px;color:var(--on-accent)}
.side .brand img{height:34px;width:auto;display:block}
.side a .lb{flex:1}
.side a .bdg{margin-left:auto;font-size:10px}
.side .who .lo{color:#93A4BF;font-size:11.5px;text-decoration:underline}
.sideveil{display:none;position:fixed;inset:0;background:rgba(19,39,71,.45);z-index:55}
@media(max-width:900px){ .side.open ~ .sideveil{display:block} }
.top .ttl h1{font-size:19px;font-weight:700;letter-spacing:-.2px}
.loginpage{background:linear-gradient(150deg,#0B4A25 0%,#132747 100%);min-height:100vh}
.loginwrap{min-height:100vh;display:grid;place-items:center;padding:24px}
.loginbox{width:100%;max-width:390px;background:var(--surface);border-radius:16px;padding:30px 28px;box-shadow:0 20px 50px rgba(0,0,0,.25)}
.loginbox h2{font-size:19px;font-weight:700;margin:14px 0 3px;text-align:center}
.loginbox p.s{text-align:center;color:var(--muted);font-size:12.5px;margin-bottom:22px}
.loginbox .lg{display:flex;justify-content:center}
.loginbox .lg img{height:46px}
.loginbox .btn{width:100%;justify-content:center;padding:11px}
.loginbox .ft{text-align:center;font-size:11.5px;color:var(--muted);margin-top:16px}
.pager{display:flex;gap:6px;align-items:center}
.empty{padding:44px 20px;text-align:center;color:var(--muted)}
.empty .ico{font-size:34px;opacity:.4;margin-bottom:8px}
a.rowlink{color:inherit;text-decoration:none;display:block}
.tbl-actions{display:flex;gap:6px;white-space:nowrap}
.req:after{content:' *';color:var(--red)}
/* v3.123 · nhãn trường bắt buộc: cả chữ đỏ đậm (không chỉ dấu *) — nhân viên nhận ra ngay ô phải điền */
.f.req,label.req{color:#B91C1C;font-weight:700}
.f.req:after,label.req:after{color:inherit}
html[data-theme="dark"] .f.req,html[data-theme="dark"] label.req{color:#F87171}
@media (prefers-color-scheme: dark){html[data-theme="auto"] .f.req,html[data-theme="auto"] label.req{color:#F87171}}
.inp[readonly]{background:var(--surface-2);color:var(--ink2)}
.chk{display:flex;gap:7px;align-items:center;font-size:13px;cursor:pointer}
.filterbar{display:flex;gap:10px;flex-wrap:wrap;padding:12px 16px;align-items:flex-end}
.filterbar .grow{margin-left:auto;display:flex;gap:8px}
@media print{.side,.top,.burger,.btn{display:none!important}.content{padding:0}}

/* ===== Responsive: gộp mọi lưới nhiều cột về 1 cột trên màn hình nhỏ ===== */
@media (max-width: 1100px) {
  .content .grid[style*="380px"],
  .content .grid[style*="360px"],
  .content .grid[style*="340px"],
  .content .grid[style*="330px"],
  .content .grid[style*="320px"],
  .content .grid[style*="420px"] { grid-template-columns: 1fr !important; }
}
@media (max-width: 900px) {
  .content .grid { grid-template-columns: 1fr !important; }
  .content .grid[style*="minmax"] { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) !important; }
  /* v3.117 · bố cục nội dung + cột phụ (minmax(0,1fr) minmax(280px,360px)…) về 1 cột — trước bị quy tắc lưới thẻ ở trên (và ≤620px) chia thành 2 cột ~167px */
  .content .grid.grid[style*="minmax(0,1fr) minmax("] { grid-template-columns: minmax(0, 1fr) !important; }
  /* v3.121 · các bố cục 2 cột khác còn bị chia đôi trên điện thoại (Loại quan hệ KH, Trường tuỳ biến, Sảnh-phòng-bàn…) */
  .content .grid.grid[style*="minmax(0,1.3fr) minmax("], .content .grid.grid[style*="minmax(0,1.4fr) minmax("],
  .content .grid.grid[style*="minmax(0,1.6fr) minmax("], .content .grid.grid[style*="minmax(0,2fr) minmax(0,1fr);"],
  .content .grid.grid[style*="minmax(0,1fr) 3"],
  /* v3.124 · cột phụ cố định 1xx / 2xx / 4xx px (Lên lịch họp…) */
  .content .grid.grid[style*="minmax(0,1fr) 1"], .content .grid.grid[style*="minmax(0,1fr) 2"], .content .grid.grid[style*="minmax(0,1fr) 4"],
  /* v3.122 · dạng chung: cột tỉ lệ bất kỳ (1.1fr…) hoặc cột cố định px đứng trước minmax(…), và lưới chủ ý 1 cột
     (Trung tâm Kiểm soát, Họp đầu ca, Quan sát an toàn) — trước bị quy tắc lưới thẻ ở trên chia thành 2 cột ~169 px */
  .content .grid.grid[style*="fr) minmax("], .content .grid.grid[style*="px) minmax("],
  .content .grid.grid[style*="columns:minmax(0,1fr);"] { grid-template-columns: minmax(0, 1fr) !important; }
  .card .hd { flex-wrap: wrap; }
  .filterbar > * { flex: 1 1 auto; min-width: 130px; }
  .filterbar .grow { margin-left: 0; width: 100%; }
  .tblwrap { -webkit-overflow-scrolling: touch; }
  .content { padding: 14px 12px 60px; }
  .top { padding: 12px 14px; }
  .kpi .vl { font-size: 25px; }
}
@media (max-width: 620px) {
  .content .grid[style*="minmax"] { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)) !important; }
  .tabs { gap: 2px; }
  .tabs a { padding: 8px 10px; font-size: 12.5px; }
  .btn { padding: 8px 12px; }
  .cal { gap: 3px; }
  .day { min-height: 68px; padding: 4px; }
  .day .slot { font-size: 9px; padding: 1px 3px; }
  .day .mine { font-size: 9.5px; }
}
html, body { max-width: 100%; overflow-x: hidden; }
.content > * { max-width: 100%; }

/* ===== Chặn tràn ngang trên điện thoại =====
   Bảng rộng phải cuộn NGANG BÊN TRONG thẻ, không đẩy cả trang. */
.app, .content, .card, .grid > *, form.card { min-width: 0; }
.tblwrap { max-width: 100%; overflow-x: auto; }
/* v3.41 · SỬA LỖI: "min-width:max-content" trước đây áp dụng cho MỌI kích thước màn
   hình — trên máy tính, quy tắc này ép bảng luôn rộng bằng đúng nội dung dài nhất
   (coi như không dòng nào được ngắt), nên bảng nhiều cột luôn tràn ra ngoài khung dù
   màn hình còn thừa chỗ để ngắt dòng, kết quả là hiện thanh trượt ngang + cắt mất một
   phần bảng trên toàn trang. Trên điện thoại thì NGƯỢC LẠI cần giữ nguyên hành vi này
   (ép không co bảng lại, cuộn ngang bên trong thẻ) vì màn hình quá hẹp để ngắt dòng mà
   vẫn đọc được — nên chỉ còn áp dụng trong khối @media di động bên dưới. */
@media (max-width: 900px) {
  .tblwrap > table { min-width: max-content; }
  .content .grid[style] > * { min-width: 0; }
  textarea.inp, input.inp, select.inp { max-width: 100%; }
}

/* ===== Menu thu gọn =====
   Bấm nút ở thanh trên hoặc phím [ . Trạng thái được nhớ trên từng máy. */
.minitog{display:inline-flex;align-items:center;justify-content:center;
  background:var(--surface);border:1px solid var(--line);border-radius:9px;
  padding:7px 11px;cursor:pointer;font-size:15px;color:var(--ink2);line-height:1;transition:.15s}
.minitog:hover{border-color:var(--g600);color:var(--g700)}

.app.mini .side{width:64px;flex:0 0 64px;padding:16px 8px}
.app.mini .side .lb,
.app.mini .side .logo-txt,
.app.mini .side .who b,
.app.mini .side .who span,
.app.mini .side .brand > div:last-child{display:none}
/* Nhóm chức năng vẫn phân tách được bằng một gạch mờ */
.app.mini .side .grp{height:1px;background:rgb(var(--glass-rgb) / .14);margin:10px 8px 8px;
  padding:0;text-indent:-9999px;overflow:hidden;white-space:nowrap}
.app.mini .side .brand{padding:6px 0 14px;text-align:center}
.app.mini .side .brand img{height:28px;margin:0 auto}
.app.mini .side a{justify-content:center;padding:11px 0;position:relative}
.app.mini .side a .ic{width:auto;font-size:16px}
.app.mini .side a .bdg{position:absolute;top:3px;right:6px;margin:0;padding:1px 4px;font-size:9px}
.app.mini .side .who{text-align:center;padding:12px 0 2px}
.app.mini .side .who .lo{font-size:10.5px}

/* Tên chức năng hiện ra khi rê chuột lúc menu đang thu gọn */
.app.mini .side a[data-tip]:hover::after{
  content:attr(data-tip);position:absolute;left:calc(100% + 10px);top:50%;transform:translateY(-50%);
  background:var(--navy-d);color:var(--on-accent);font-size:12.5px;font-weight:500;white-space:nowrap;
  padding:6px 11px;border-radius:8px;box-shadow:0 6px 18px rgba(19,39,71,.28);z-index:80}

@media (max-width: 900px){
  .minitog{display:none}          /* điện thoại đã có nút ba gạch riêng */
  .app.mini .side{width:238px;flex:0 0 238px;padding:16px 12px}
  .app.mini .side .lb,.app.mini .side .grp,.app.mini .side .logo-txt{display:''}
}

/* ===== Nhóm menu thu gọn được ===== */
.side .grp{display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;transition:.15s}
.side .grp:hover{color:#B6C6DE}
.side .grp .gtxt{flex:1}
.side .grp .gcar{font-size:9px;opacity:.65;transition:transform .18s}
.side .grp.closed .gcar{transform:rotate(-90deg)}
.side .grp.active .gtxt{color:#A9BDDA}
.side .gitems{display:flex;flex-direction:column;gap:2px;overflow:hidden;
  max-height:1200px;opacity:1;transition:max-height .22s ease, opacity .15s}
.side .gitems.closed{max-height:0;opacity:0;pointer-events:none}
.grpall{background:none;border:0;color:#6F82A0;font-size:10.5px;letter-spacing:.4px;
  cursor:pointer;padding:6px 10px 2px;text-align:left;font-family:inherit}
.grpall:hover{color:#B6C6DE;text-decoration:underline}

/* Khi menu đang thu gọn hẹp thì bỏ hết phần nhóm, chỉ còn icon */
.app.mini .side .grp{pointer-events:none}
.app.mini .side .grp .gcar,
.app.mini .side .grpall{display:none}
.app.mini .side .gitems.closed{max-height:1200px;opacity:1;pointer-events:auto}

/* Có logo thì ẩn chữ GIANGDANG RESTAURANT */
.side .brand a.logo.has-logo .logo-txt{display:none}
.side .brand a.logo.has-logo img{height:40px;max-width:190px;object-fit:contain}
.app.mini .side .brand a.logo.has-logo img{height:26px;max-width:46px}

/* ===== Khối đính kèm link dùng chung ===== */
.linkbox .linkrow{display:flex;align-items:center;gap:9px;padding:8px 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
.linkbox .linkrow:last-of-type{border-bottom:0}
.lchip{display:inline-block;color:var(--on-accent);font-size:10.5px;font-weight:700;letter-spacing:.3px;
  padding:3px 8px;border-radius:6px;white-space:nowrap}
.linkbox .ltitle{flex:1;min-width:160px;font-size:13.5px;font-weight:600;word-break:break-word}
.linkbox .ltitle:hover{text-decoration:underline}
.linkbox .lmeta{font-size:11.5px;color:var(--muted);white-space:nowrap}
.linkbox .lnote{font-size:12px;color:var(--ink2);padding:0 0 8px 78px}
@media (max-width:620px){ .linkbox .lnote{padding-left:0} }

/* ===== Chuông thông báo ===== */
.bell{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:34px;border:1px solid var(--line);border-radius:9px;font-size:15px;
  background:var(--surface);text-decoration:none;transition:.15s}
.bell:hover{border-color:var(--g600)}
.bell.has{border-color:var(--orange)}
.bell i{position:absolute;top:-6px;right:-6px;background:var(--red);color:var(--on-accent);
  font-style:normal;font-size:10px;font-weight:700;line-height:1;
  padding:3px 5px;border-radius:9px;border:2px solid var(--surface)}

/* v3.45 · Mục 6 — pill chi nhánh gần nhất theo GPS, cạnh chuông thông báo — thu nhỏ lại
   theo yêu cầu Enzo: dạng icon nhỏ + chấm trạng thái xanh/vàng + nhãn gọn (tên · khoảng
   cách), không chiếm nhiều chỗ trên đầu trang như bản đầu. */
.branchpill{position:relative;display:inline-flex;align-items:center;gap:4px;height:30px;
  padding:0 8px 0 6px;border:1px solid var(--hair,var(--line));border-radius:8px;
  background:var(--surface);color:var(--ink2);font-size:11px;font-weight:600;white-space:nowrap;
  max-width:150px;overflow:hidden}
.branchpill svg.i.sm{width:14px;height:14px;flex:0 0 auto}
.branchpill::before{content:'';width:7px;height:7px;border-radius:50%;flex:0 0 auto;
  background:var(--g600,#16a34a);box-shadow:0 0 0 2px rgba(22,163,74,.18)}
.branchpill.off::before{background:var(--orange,#f97316);box-shadow:0 0 0 2px rgba(249,115,22,.18)}
.branchpill span{overflow:hidden;text-overflow:ellipsis}
@media (max-width:760px){ .branchpill{max-width:90px} }


/* ═══════════════════════════════════════════════════════════════════════
   GIANGDANG v2.4 — SOFT GLASS  (bản r2, Enzo duyệt 04/09/2026)
   Chồng lên phần trên, không xoá gì — mọi class cũ ở 55 màn hình vẫn chạy.
   Tông: cam đỏ hành động · xanh lá trạng thái tốt · kính mỏng, bóng mềm.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  /* ---- Cam đỏ: hành động chính ---- */
  --br-50:#FFF6F2; --br-100:#FFE9E0; --br-200:#FFD3C2;
  --br-400:#FF8A5B; --br-500:#F96E3A; --br-600:#EA5A2B; --br-700:#C9451C; --br-900:#7E2810;
  /* ---- Xanh lá: trạng thái tốt ---- */
  --lf-50:#F1FBF5; --lf-100:#DBF6E5; --lf-200:#BCEBCE;
  --lf-400:#4CC97F; --lf-500:#2DB765; --lf-600:#1FA055; --lf-700:#158043; --lf-900:#0C4A28;

  /* ---- Giữ tên biến cũ để không phải sửa 55 màn hình ---- */
  --g900:var(--lf-900); --g800:var(--lf-700); --g700:var(--lf-700);
  --g600:var(--lf-600); --g500:var(--lf-500);
  --g100:var(--lf-100); --g50:var(--lf-50);
  --orange:var(--br-600); --orange-l:var(--br-100);
  --red:#D6452A; --red-l:#FEE7E2;
  --navy:#31507F; --navy-d:#233A5E; --navy-l:#4A6CA3;

  --ink:#241C18; --ink2:#6B5D55; --muted:#9C8C82;
  --bg:#FDFAF7;
  --line:rgba(140,108,88,.11);
  --hair:rgba(255,255,255,.9);

  --glass:rgba(255,255,255,.74);
  --glass-2:rgba(255,255,255,.86);
  --glass-side:rgba(255,255,255,.5);
  --blur:saturate(165%) blur(22px);
  --card:var(--glass);

  --sh-xs:0 1px 2px rgba(120,80,60,.045);
  --sh:0 1px 2px rgba(120,80,60,.04), 0 10px 28px -14px rgba(120,80,60,.22);
  --sh-lift:0 1px 2px rgba(120,80,60,.05), 0 18px 40px -16px rgba(120,80,60,.3);

  --r-xs:10px; --r-sm:14px; --r:18px; --r-lg:24px; --r-xl:30px;
  --tabbar-h:0px;
}

/* ═══ Chữ ═══
   Máy Apple lấy đúng SF Pro qua -apple-system (đã có đủ dấu tiếng Việt).
   Máy Windows/Android rơi về Be Vietnam Pro — font thiết kế riêng cho tiếng Việt,
   dấu đặt cân ở những chữ hai dấu như "ế" "ợ" "ằ". */
body{
  font-family:-apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
              "Be Vietnam Pro", "Segoe UI Variable Text", "Segoe UI", Roboto,
              "Helvetica Neue", Arial, sans-serif;
  font-size:14px; line-height:1.52; letter-spacing:-.006em;
  color:var(--ink);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  background:var(--bg);
  background-image:
    radial-gradient(62rem 44rem at 92% -12%, rgba(249,110,58,.13), transparent 60%),
    radial-gradient(50rem 38rem at -12% 8%,  rgba(45,183,101,.10), transparent 58%),
    radial-gradient(44rem 40rem at 40% 112%, rgba(255,138,91,.09), transparent 62%);
  background-attachment:fixed;
}

/* ═══ Icon một nét ═══ */
svg.i{width:20px;height:20px;flex:0 0 auto;stroke:currentColor;fill:none;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;display:block}
svg.i.sm{width:17px;height:17px;stroke-width:1.75}
svg.i.lg{width:24px;height:24px;stroke-width:1.6}
svg.i.xl{width:30px;height:30px;stroke-width:1.5}

/* ═══ Bề mặt kính ═══ */
.card{
  background:var(--glass);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:1px solid var(--hair);border-radius:var(--r);box-shadow:var(--sh);
  transition:box-shadow .3s cubic-bezier(.32,.72,0,1), transform .3s cubic-bezier(.32,.72,0,1);
}
.card:hover{box-shadow:var(--sh-lift);transform:translateY(-2px)}
form.card:hover,.card.flat:hover{transform:none;box-shadow:var(--sh)}
.card .hd{padding:14px 17px;border-bottom:1px solid var(--line);border-radius:var(--r) var(--r) 0 0}
.card .hd h3{font-size:14px;font-weight:650;letter-spacing:-.015em}
.card .hd .r{font-size:12px;color:var(--muted);font-weight:450}
.card .bd{padding:16px 17px}

.kpi{padding:16px 17px}
.kpi .lb{font-size:12px;font-weight:550;letter-spacing:-.005em;color:var(--muted)}
.kpi .vl{font-size:clamp(23px,2vw,30px);font-weight:700;letter-spacing:-.038em;margin:7px 0 2px;
  color:var(--ink);font-variant-numeric:tabular-nums}
.kpi .dt{font-size:11.5px;color:var(--muted);font-weight:450}
.kpi .dt .up{color:var(--lf-600);font-weight:600}
.kpi .dt .dn{color:var(--br-600);font-weight:600}

/* ═══ Nút ═══ */
.btn{
  display:inline-flex;align-items:center;gap:7px;padding:9px 16px;border-radius:var(--r-xs);
  border:0;font-weight:600;font-size:13.5px;letter-spacing:-.01em;cursor:pointer;
  background:linear-gradient(180deg,var(--br-500),var(--br-600));color:var(--on-accent);
  box-shadow:0 1px 2px rgba(126,40,16,.18), 0 8px 20px -8px rgba(234,90,43,.62),
             inset 0 1px 0 rgba(255,255,255,.3);
  transition:.24s cubic-bezier(.32,.72,0,1);
}
.btn:hover{transform:translateY(-1px);
  box-shadow:0 2px 4px rgba(126,40,16,.2),0 14px 28px -10px rgba(234,90,43,.7),inset 0 1px 0 rgba(255,255,255,.32)}
.btn:active{transform:translateY(0)}
.btn:disabled{opacity:.55;cursor:not-allowed;transform:none}
.btn.sec{background:var(--glass-2);color:var(--ink);border:1px solid var(--hair);
  box-shadow:var(--sh-xs), inset 0 1px 0 rgba(255,255,255,.85)}
.btn.sec:hover{color:var(--br-700)}
.btn.gho{background:transparent;color:var(--br-700);border:1px solid rgba(234,90,43,.4);box-shadow:none}
.btn.gho:hover{background:var(--br-50);transform:none}
.btn.ok{background:linear-gradient(180deg,var(--lf-500),var(--lf-700));
  box-shadow:0 1px 2px rgba(12,74,40,.16),0 8px 20px -8px rgba(31,160,85,.55),inset 0 1px 0 rgba(255,255,255,.28)}
.btn.warn{background:linear-gradient(180deg,#EFA33C,#D07E10)}
.btn.dan{background:linear-gradient(180deg,#EA5A4A,#B32E1C)}
.btn.sm{padding:6px 12px;font-size:12.5px;border-radius:9px}

/* ═══ Ô nhập ═══ */
.inp{
  background:rgb(var(--glass-rgb) / .8);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  border:1px solid rgba(140,108,88,.18);border-radius:var(--r-xs);
  padding:9px 12px;transition:.18s;
}
.inp:focus{background:var(--surface);border-color:var(--br-500);box-shadow:0 0 0 3.5px rgba(249,110,58,.15)}
.inp[readonly]{background:rgba(253,250,247,.8);color:var(--ink2)}
label.f{font-size:12.5px;font-weight:550;color:var(--ink2);letter-spacing:-.008em}
.hint{font-size:11.5px;color:var(--muted);font-weight:450}

/* ═══ Nhãn trạng thái ═══ */
.pill{padding:3.5px 10px;font-size:11.5px;font-weight:600;letter-spacing:-.005em;
  border:1px solid rgb(var(--glass-rgb) / .6)}
.p-g{background:var(--lf-100);color:var(--lf-900)}
.p-o{background:var(--br-100);color:var(--br-700)}
.p-r{background:var(--danger-bg-strong);color:var(--danger-ink)}
.p-n{background:var(--info-bg);color:#31507F}
.p-s{background:rgb(var(--glass-rgb) / .72);color:var(--ink2)}

/* ═══ Bảng ═══ */
th{background:transparent;border-bottom:1px solid var(--line);color:var(--muted);
  font-size:11px;font-weight:600;letter-spacing:.03em;padding:10px 15px}
td{border-bottom:1px solid var(--line);padding:11px 15px;font-size:13px}
tbody tr{transition:background .18s}
tbody tr:hover{background:rgba(249,110,58,.038)}
.num{font-variant-numeric:tabular-nums}

/* ═══ Ghi chú ═══ */
.note{padding:11px 13px;border-radius:var(--r-sm);font-size:12.5px;font-weight:450;
  border:1px solid rgb(var(--glass-rgb) / .65)}
.note.i{background:rgba(233,238,247,.78);color:#2C4874}
.note.w{background:rgba(255,233,224,.78);color:#93401A}
.note.d{background:rgba(254,231,226,.8);color:var(--danger-ink)}
.note.s{background:rgba(219,246,229,.78);color:var(--lf-900)}

/* ═══ Thanh tiêu đề ═══ */
.top{
  background:rgb(var(--glass-rgb) / .66);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border-bottom:1px solid var(--hair);padding:13px 22px;
  position:sticky;top:0;z-index:40;
}
.top h1,.top .ttl h1{font-size:18.5px;font-weight:680;letter-spacing:-.028em}
.top .sub{color:var(--muted);font-size:12px;font-weight:450}

.tabs a{font-weight:550}
.tabs a.on{color:var(--br-700);border-bottom-color:var(--br-600)}
.bar i{background:linear-gradient(90deg,var(--lf-500),var(--lf-400))}
.av{background:var(--br-100);color:var(--br-700);font-weight:650}
.av.n{background:var(--info-bg);color:#31507F}
.empty .ico{opacity:.35}

/* ═══ Menu trái: kính SÁNG, co giãn theo màn hình ═══
   Trước cố định 238px — màn 13" bị chiếm chỗ, màn 27" thì phí.
   clamp() cho tự co giãn, không cần media query cho từng cỡ. */
.side{
  width:clamp(200px, 15.5vw, 264px);
  flex:0 0 clamp(200px, 15.5vw, 264px);
  background:var(--glass-side);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border-right:1px solid var(--hair);
  color:var(--ink2);padding:16px 12px;
}
.side .brand{padding:6px 8px 16px;color:var(--ink)}
.side .brand > div:last-child{font-size:10.5px;color:var(--muted)}
.logo-txt .l1{font-weight:700;font-size:14.5px;letter-spacing:-.02em;color:var(--ink)}
.logo-txt .l2{font-size:9.5px;letter-spacing:.14em;color:var(--br-600);font-weight:600}

.side a{
  padding:8.5px 11px;border-radius:11px;font-size:13.5px;font-weight:500;
  color:var(--ink2);letter-spacing:-.012em;transition:.2s cubic-bezier(.32,.72,0,1);
}
.side a:hover{background:rgb(var(--glass-rgb) / .72);color:var(--ink)}
.side a.on{
  background:var(--glass-2);color:var(--br-700);font-weight:600;
  border:1px solid var(--hair);padding:7.5px 10px;
  box-shadow:var(--sh-xs), inset 0 1px 0 rgba(255,255,255,.9);
}
.side a .ic{width:auto;opacity:1}
.side a .lb{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side a .bdg{background:var(--br-600);color:var(--on-accent);font-size:10px;font-weight:700;
  padding:1.5px 6px;border-radius:99px;letter-spacing:0;border:0}

.side .grp{
  font-size:10.5px;letter-spacing:.09em;color:var(--muted);font-weight:600;
  padding:15px 11px 6px;
}
.side .grp:hover{color:var(--ink2)}
.side .grp.active,.side .grp.active .gtxt{color:var(--br-600)}
.side .grp .gcar{font-size:0}
.side .grp svg.i{width:13px;height:13px;opacity:.7;
  transition:transform .26s cubic-bezier(.32,.72,0,1)}
.side .grp.closed svg.i{transform:rotate(-90deg)}
.side .gitems{transition:max-height .3s cubic-bezier(.32,.72,0,1), opacity .2s}
.grpall{color:var(--muted);font-size:10.5px;font-weight:500;padding:6px 11px 2px}
.grpall:hover{color:var(--br-600);text-decoration:none}

.side .who{border-top:1px solid var(--line);padding:12px 8px 2px;color:var(--muted);font-size:11px}
.side .who b{color:var(--ink);font-size:12.5px;font-weight:600;letter-spacing:-.012em}
.side .who .lo{color:var(--muted);font-size:11px}
.side .who .lo:hover{color:var(--br-600)}

/* ═══ Ẩn thanh trượt, vẫn cuộn được ═══ */
*{scrollbar-width:thin;scrollbar-color:rgba(140,108,88,.22) transparent}
::-webkit-scrollbar{width:7px;height:7px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(140,108,88,.18);border-radius:99px}
::-webkit-scrollbar-thumb:hover{background:rgba(140,108,88,.34)}
.scrollnav,.tblwrap,.tabs{scrollbar-width:none;-ms-overflow-style:none}
.scrollnav::-webkit-scrollbar,.tblwrap::-webkit-scrollbar,.tabs::-webkit-scrollbar{width:0;height:0;display:none}

/* ═══ Lưới tự lấp đầy màn hình ═══ */
.content{
  max-width:min(1680px,100%);
  padding:20px clamp(12px,1.6vw,26px) calc(48px + var(--tabbar-h));
  margin-inline:auto;
}
.grid{gap:clamp(10px,.9vw,15px)}
.content .grid[style*="minmax(168px"],
.content .grid[style*="minmax(160px"],
.content .grid[style*="minmax(150px"]{
  grid-template-columns:repeat(auto-fit,minmax(clamp(150px,13vw,215px),1fr)) !important;
}
@media (min-width:1101px){
  .content .grid[style*="380px"]{grid-template-columns:minmax(0,1fr) clamp(300px,24vw,400px) !important}
  .content .grid[style*="360px"]{grid-template-columns:minmax(0,1fr) clamp(292px,23vw,380px) !important}
  .content .grid[style*="340px"]{grid-template-columns:minmax(0,1fr) clamp(284px,22vw,360px) !important}
  .content .grid[style*="330px"]{grid-template-columns:minmax(0,1fr) clamp(280px,21vw,350px) !important}
  .content .grid[style*="320px"]{grid-template-columns:minmax(0,1fr) clamp(276px,21vw,340px) !important}
  .content .grid[style*="420px"]{grid-template-columns:minmax(0,1fr) clamp(320px,26vw,440px) !important}
}
@media (min-width:1700px){
  .content .grid[style*="minmax"]{grid-template-columns:repeat(auto-fit,minmax(205px,1fr)) !important}
}

/* ═══ Nút phụ trên thanh tiêu đề ═══ */
.minitog,.burger,.bell{
  background:var(--glass-2);border:1px solid var(--hair);border-radius:var(--r-xs);
  box-shadow:var(--sh-xs), inset 0 1px 0 rgba(255,255,255,.85);
  color:var(--ink2);width:37px;height:35px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;transition:.22s;
}
.minitog:hover,.burger:hover,.bell:hover{color:var(--br-600);border-color:var(--hair)}
.bell.has{color:var(--br-600);background:var(--br-50)}
/* v3.123 · nút lùi / tiến trang (cạnh nút thu gọn menu) */
.histnav{display:inline-flex;gap:4px;flex:0 0 auto}
.histbtn{background:var(--glass-2);border:1px solid var(--hair);border-radius:var(--r-xs);
  box-shadow:var(--sh-xs), inset 0 1px 0 rgba(255,255,255,.85);
  color:var(--ink2);width:33px;height:35px;padding:0;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;transition:.22s}
.histbtn:hover{color:var(--br-600)}
.histbtn:disabled{opacity:.4;cursor:default}
@media (max-width: 600px){ .histfwd{display:none} .histbtn{width:31px;height:33px} }
.bell i{background:var(--br-600);color:var(--on-accent);font-size:9.5px;font-weight:700;
  padding:2px 5px;border-radius:99px;border:2px solid #FEFCFA;top:-5px;right:-5px}
@keyframes bellpop{0%{transform:scale(.4);opacity:0}60%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
.bell i{animation:bellpop .3s cubic-bezier(.34,1.56,.64,1)}

.app.mini .side{width:66px;flex:0 0 66px;padding:16px 8px}
.app.mini .side a[data-tip]:hover::after{
  background:rgba(36,28,24,.94);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:0 8px 22px rgba(120,80,60,.3);font-weight:500}

/* ═══════════════════════════════════════════════════════════════
   THANH MENU DƯỚI CHO ĐIỆN THOẠI
   Viên thuốc nổi kiểu Apple: kính mờ, bo lớn, cách mép.
   Ẩn hoàn toàn trên máy tính.
   ═══════════════════════════════════════════════════════════════ */
.tabbar{display:none}

@media (max-width:900px){
  :root{--tabbar-h:80px}

  .tabbar{
    display:flex;position:fixed;left:50%;transform:translateX(-50%);
    bottom:calc(11px + env(safe-area-inset-bottom,0px));
    width:min(calc(100vw - 22px),470px);
    z-index:70;padding:7px;gap:2px;border-radius:var(--r-xl);
    background:rgb(var(--glass-rgb) / .66);
    -webkit-backdrop-filter:saturate(190%) blur(28px);backdrop-filter:saturate(190%) blur(28px);
    border:1px solid rgb(var(--glass-rgb) / .92);
    box-shadow:0 1px 2px rgba(120,80,60,.06), 0 14px 38px -8px rgba(120,80,60,.3),
               inset 0 1px 0 rgba(255,255,255,.98);
  }
  .tabbar a{
    flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:4px;padding:9px 2px 7px;border-radius:22px;color:var(--muted);
    font-size:9.5px;font-weight:600;line-height:1.1;text-align:center;letter-spacing:-.005em;
    position:relative;transition:.26s cubic-bezier(.32,.72,0,1);
    -webkit-tap-highlight-color:transparent;
  }
  .tabbar a .lb{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tabbar a:active{transform:scale(.94)}
  .tabbar a.on{background:rgb(var(--glass-rgb) / .94);color:var(--br-600);
    box-shadow:var(--sh-xs), inset 0 1px 0 rgba(255,255,255,.95)}

  /* Nút giữa nổi hẳn — thao tác dùng nhiều nhất */
  .tabbar a.mid{padding-top:6px}
  .tabbar a.mid .pl{
    width:38px;height:38px;border-radius:14px;display:grid;place-items:center;margin-top:-4px;
    background:linear-gradient(180deg,var(--br-500),var(--br-600));color:var(--on-accent);
    box-shadow:0 2px 5px rgba(126,40,16,.24),0 10px 22px -8px rgba(234,90,43,.68),
               inset 0 1px 0 rgba(255,255,255,.34);
  }
  .tabbar a.mid.on{background:transparent;box-shadow:none;color:var(--br-600)}
  .tabbar a em{position:absolute;top:3px;right:calc(50% - 22px);background:var(--br-600);color:var(--on-accent);
    font-style:normal;font-size:8.5px;font-weight:700;padding:1.5px 5px;border-radius:99px;
    border:2px solid #FEFCFA;line-height:1.1}

  .content{padding:14px 12px calc(26px + var(--tabbar-h))}

  /* Menu trái trên điện thoại: trượt từ trái vào, kính đục hơn cho dễ đọc */
  .side{
    top:0;width:min(84vw,300px);flex-basis:auto;
    background:rgb(var(--glass-rgb) / .93);
    padding-top:calc(14px + env(safe-area-inset-top,0px));
    box-shadow:14px 0 40px -12px rgba(120,80,60,.35);
  }
  .sideveil{background:rgba(36,28,24,.34);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
  .top{padding:11px 13px}
  .top .ttl h1{font-size:17px}
  .card .hd{padding:13px 14px}
  .card .bd{padding:14px}
  .kpi{padding:14px}
}

/* v3.20 · Soạn thảo có định dạng (rich text) — dùng cho khu vực nội dung dài
   (bài viết Cơ sở tri thức/Sale Kit, và mọi nơi khác gắn class "rte" sau này).
   Tự viết bằng contenteditable + execCommand, không kéo thư viện ngoài nặng vài MB
   (đúng tinh thần "không phụ thuộc ngoài" đã áp dụng suốt hệ thống). */
.rte-wrap{border:1px solid var(--line);border-radius:var(--r-xs, 10px);overflow:hidden;background:var(--card)}
.rte-toolbar{display:flex;flex-wrap:wrap;gap:2px;padding:6px;border-bottom:1px solid var(--line);
  background:rgba(0,0,0,.02)}
.rte-btn{border:0;background:none;cursor:pointer;width:30px;height:30px;border-radius:7px;
  display:flex;align-items:center;justify-content:center;color:var(--ink2);font-size:13px;font-weight:600}
.rte-btn:hover{background:rgba(0,0,0,.06)}
.rte-btn.on{background:var(--g100);color:var(--g700)}
.rte-sep{width:1px;background:var(--line);margin:4px 3px}
.rte-sel{border:1px solid var(--line);border-radius:7px;background:var(--card);font-size:12px;
  padding:4px 6px;max-width:110px;color:var(--ink2)}
.rte-body{min-height:220px;max-height:520px;overflow:auto;padding:12px 14px;font-size:13.5px;
  line-height:1.6;color:var(--ink)}
.rte-body:focus{outline:none}
.rte-body img{max-width:100%;border-radius:6px}
.rte-body table{border-collapse:collapse;width:100%;margin:8px 0}
.rte-body table td,.rte-body table th{border:1px solid var(--line);padding:6px 8px}
.rte-body blockquote{border-left:3px solid var(--g600);margin:8px 0;padding:2px 12px;color:var(--muted)}
.rte-src{width:100%;min-height:220px;border:0;padding:12px 14px;font-family:monospace;font-size:12.5px;
  resize:vertical;background:var(--card);color:var(--ink)}
.rte-wrap.full{position:fixed;inset:14px;z-index:300;box-shadow:0 20px 60px rgba(0,0,0,.3)}
.rte-wrap.full .rte-body{max-height:none;height:calc(100vh - 130px)}
.rte-pop{position:absolute;z-index:40;background:var(--card);border:1px solid var(--line);
  border-radius:10px;box-shadow:var(--sh);padding:8px;display:grid;grid-template-columns:repeat(8,1fr);
  gap:2px;max-width:260px}
.rte-pop button{border:0;background:none;cursor:pointer;padding:5px;border-radius:6px;font-size:15px}
.rte-pop button:hover{background:rgba(0,0,0,.06)}
.rte-content{font-size:13.5px;line-height:1.65}
.rte-content img{max-width:100%;border-radius:6px}
.rte-content table{border-collapse:collapse}
.rte-content table td,.rte-content table th{border:1px solid var(--line);padding:6px 8px}
.rte-content blockquote{border-left:3px solid var(--g600);margin:8px 0;padding:2px 12px;color:var(--muted)}
.rte-content ul,.rte-content ol{padding-left:22px;margin:6px 0 10px}
.rte-content li{margin:3px 0}
.rte-content h3{font-size:14.5px;margin:16px 0 6px}
.rte-content code{background:var(--surface-3);padding:1px 5px;border-radius:4px;font-size:12.5px}

/* v3.20 · "Giao việc mới" + "Tải việc tuần này" (task/assign) xếp 2 cột trên màn rộng */
.assign-side{display:grid;grid-template-columns:1.3fr .9fr;gap:16px;align-items:start}
@media (max-width:1100px){.assign-side{grid-template-columns:1fr}}

/* v3.20 · nút "Gửi ticket hỗ trợ" nổi — trên máy tính đứng cố định ở góc dưới
   phải; trên điện thoại phải nhảy lên TRÊN thanh menu dưới (.tabbar, z-index
   70, cao ~80px) chứ không được đứng nguyên bottom:78px như cũ, vì như vậy nó
   nằm lọt đúng dải mà .tabbar phủ lên (đè mất, chỉ thấy góc hoặc mất hẳn nút). */
.helpfab{position:fixed;right:18px;bottom:78px;z-index:40;width:48px;height:48px;border-radius:50%}
@media (max-width:900px){
  .helpfab{bottom:calc(var(--tabbar-h) + 22px + env(safe-area-inset-bottom,0px));z-index:65}
}

/* v3.22 · Nút cuộn lên đầu — cùng hàng với nút trợ giúp nổi, lệch sang trái 62px */
.scrolltopfab{right:80px;transition:opacity .15s}
@media (max-width:900px){
  .scrolltopfab{right:80px}
}

/* v3.22 · Bảng chat AI Copilot — bám theo cùng mốc bottom với nút nổi bên trái */
.aipanel{bottom:134px}
@media (max-width:900px){
  .aipanel{bottom:calc(var(--tabbar-h) + 22px + env(safe-area-inset-bottom,0px) + 64px)}
}

/* v3.22 · Cài đặt → Toàn bộ tính năng — masonry 2 cột (cột lớn/nhỏ, xem settings.php) */
.msettings-grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
@media (max-width:860px){
  .msettings-cols{flex-direction:column}
}
@media (max-width:640px){
  .msettings-grid2{grid-template-columns:1fr}
}

@media (max-width:359px){
  .tabbar a .lb{display:none}
  .tabbar a{padding:12px 2px}
}
@media (min-width:901px){
  :root{--tabbar-h:0px}
  .tabbar{display:none !important}
}

/* Người dùng bật "giảm chuyển động" thì tắt hết hiệu ứng */
@media (prefers-reduced-motion:reduce){
  *,*:before,*:after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}

/* Trình duyệt cũ không có backdrop-filter: nền đục để chữ vẫn đọc rõ */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .card,.top,.tabbar,.btn.sec,.bell,.minitog,.burger,.side,.inp{background:rgb(var(--glass-rgb) / .97)}
  .note.i{background:var(--info-bg)}.note.w{background:#FFE9E0}
  .note.d{background:var(--danger-bg-strong)}.note.s{background:var(--ok-bg-strong)}
}

/* ═══ Khối tiện ích mới cho v2.4 ═══ */
.qrow{display:flex;align-items:center;gap:12px;padding:13px 14px}
.qico{width:40px;height:40px;border-radius:13px;display:grid;place-items:center;flex:0 0 auto;color:var(--on-accent)}
.qt{flex:1;min-width:0}
.qt b{font-size:13.5px;font-weight:600;letter-spacing:-.014em;display:block}
.qt span{font-size:11px;color:var(--muted);font-weight:450}

/* Nút chấm công lớn trên điện thoại */
.gpsbig{width:100%;padding:18px;border-radius:var(--r-lg);border:0;cursor:pointer;color:var(--on-accent);
  background:linear-gradient(155deg,var(--lf-500),var(--lf-700));font-family:inherit;text-align:left;
  box-shadow:0 2px 6px rgba(12,74,40,.2),0 18px 38px -14px rgba(31,160,85,.68),inset 0 1px 0 rgba(255,255,255,.28);
  display:flex;align-items:center;gap:14px;transition:.26s cubic-bezier(.32,.72,0,1)}
.gpsbig:hover{transform:translateY(-2px)}
.gpsbig:disabled{opacity:.6;transform:none}
.gpsbig .t1{font-size:16.5px;font-weight:680;letter-spacing:-.024em;display:block}
.gpsbig .t2{font-size:11.5px;opacity:.86;margin-top:2px;display:block;font-weight:450}
.gpsbig.out{background:linear-gradient(155deg,var(--br-500),var(--br-700));
  box-shadow:0 2px 6px rgba(126,40,16,.2),0 18px 38px -14px rgba(234,90,43,.68),inset 0 1px 0 rgba(255,255,255,.28)}

/* Dải trạng thái mạng / hàng đợi offline */
.offbar{position:fixed;left:50%;transform:translateX(-50%);z-index:75;
  bottom:calc(14px + var(--tabbar-h));display:none;align-items:center;gap:9px;
  padding:9px 15px;border-radius:99px;font-size:12.5px;font-weight:550;
  background:rgba(255,233,224,.94);color:#93401A;border:1px solid rgb(var(--glass-rgb) / .9);
  -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
  box-shadow:0 10px 28px -8px rgba(120,80,60,.32)}
.offbar.show{display:flex}
@media (min-width:901px){.offbar{bottom:18px}}

/* Nhắc cài lên màn hình chính (iPhone) */
.a2hs{display:none;margin-bottom:14px}
.a2hs.show{display:flex}

/* ═══════════════════════════════════════════════════════════════════════
   SỬA LỖI: menu con không sổ ra được trên điện thoại
   ═══════════════════════════════════════════════════════════════════════
   NGUYÊN NHÂN THẬT (đã dựng lại bằng trình duyệt thật, không phải suy đoán):

   .scrollnav là flex container theo chiều dọc. Mọi khối con của nó — kể cả
   .gitems — mặc định được phép CO LẠI khi thiếu chỗ (flex-shrink:1).

   Bình thường flex item không co nhỏ hơn nội dung, nhờ min-height:auto.
   NHƯNG .gitems có overflow:hidden (cần cho hiệu ứng trượt mở/đóng), mà theo
   chuẩn CSS, overflow khác visible sẽ ép min-height về 0.

   Kết quả: trên màn hình điện thoại, 11 nhóm menu cao hơn vùng chứa, nên mọi
   .gitems bị nén xuống ĐÚNG 0px — dù không hề mang class "closed", max-height
   vẫn 1200px, và các mục con bên trong vẫn cao 38px mỗi mục.
   Người dùng bấm vào tên nhóm, JavaScript chạy đúng, class đổi đúng, nhưng
   chiều cao vẫn là 0 nên trông như "bấm không có gì xảy ra".

   Màn hình máy tính cao hơn nên còn đủ chỗ, vì vậy lỗi chỉ lộ ra ở điện thoại.

   CÁCH SỬA: cấm co các khối trong menu, để .scrollnav cuộn thay vì nén.
*/
.scrollnav > *{flex:0 0 auto}
.side .gitems{flex:0 0 auto;min-height:0}
.side .gitems:not(.closed){max-height:none}
.side .gitems.closed{max-height:0 !important;opacity:0;pointer-events:none}
.scrollnav{overflow-y:auto}

/* v3.9 · SỬA LỖI: trên máy tính, rê chuột vào khu vực menu thì không cuộn
   được trang, phải rê sang khu nội dung mới cuộn được ─────────────────────
   NGUYÊN NHÂN: overscroll-behavior:contain từng đặt thẳng vào .scrollnav
   (không giới hạn theo màn hình) để chặn hiệu ứng "kéo để làm mới" khi menu
   mở dạng ngăn kéo trên điện thoại. Nhưng .scrollnav vẫn LUÔN là overflow:auto
   — trên máy tính, .side không cố định vị trí, nó giãn theo chiều cao trang;
   khi trang dài hơn menu, .scrollnav không còn gì để tự cuộn bên trong, và
   overscroll-behavior:contain khoá luôn việc CUỘN TIẾP LÊN TRANG CHA (đúng
   việc nó sinh ra để làm) — kết quả là rê chuột đứng yên trên vùng menu thì
   lăn chuột không có tác dụng gì cả, dù trang thật sự còn dài hơn màn hình.
   CÁCH SỬA: chỉ khoá scroll-chaining khi menu đang ở dạng ngăn kéo cố định
   trên điện thoại (cùng ngưỡng với .side{position:fixed} bên dưới) — máy
   tính giữ hành vi mặc định để lăn chuột trên menu vẫn cuộn được cả trang. */
@media(max-width:900px){
  .scrollnav{overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
}

/* Lớp phủ khi mở menu trên điện thoại.
   Bộ chọn cũ (.side.open ~ .sideveil) không bao giờ khớp vì hai thẻ này
   không phải anh em: .side nằm trong .app, còn .sideveil nằm ngoài. */
.sideveil{display:none}
body.navopen .sideveil{display:block}
body.navopen{overflow:hidden}

/* Nút ba gạch chỉ dành cho điện thoại — quy tắc gộp ở trên đã vô tình
   đặt display:inline-flex làm nó hiện cả trên máy tính. */
.burger{display:none}
@media (max-width:900px){
  .burger{display:inline-flex}
  .minitog{display:none}
}

/* v3.49 · Mục 5 — SỬA LỖI: "flex-wrap:nowrap" ép TOÀN BỘ thanh trên (tiêu đề + chuông +
   chi nhánh + tìm kiếm + MỌI nút hành động riêng của từng trang, số lượng nút này không cố
   định) vào ĐÚNG 1 HÀNG trên điện thoại — trang nào có vài nút hành động (vd "+ Thêm",
   "Excel"...) là tràn ra ngoài khung nhìn, nút bị đẩy khuất không thấy/không bấm được (đúng
   phản ánh "nút bị mất"). Đổi lại: hàng đầu (tiêu đề) vẫn 1 dòng, rút gọn bằng "…" như cũ;
   nếu nhóm nút bên phải không đủ chỗ thì tự XUỐNG HẲN 1 HÀNG RIÊNG bên dưới (không còn bị
   cắt/giấu mất), thay vì cố nhồi vào chung 1 hàng chật. */
@media (max-width:900px){
  .top{flex-wrap:wrap;gap:8px 10px;align-items:center}
  .top .ttl{flex:1 1 auto;min-width:0}
  .top .ttl h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .top .sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:11.5px}
  .top .right{margin-left:0;flex:1 1 auto;justify-content:flex-end;gap:6px}
  .top .right .btn{padding:8px 11px;font-size:12.5px}
}

/* Đang mở menu trái thì giấu thanh tab dưới — nếu không nó nằm đè lên
   phần tên người dùng và nút Đăng xuất ở đáy menu. */
@media (max-width:900px){
  body.navopen .tabbar{opacity:0;pointer-events:none;transform:translateX(-50%) translateY(12px)}
  .tabbar{transition:opacity .22s, transform .22s}
  .side{padding-bottom:calc(16px + env(safe-area-inset-bottom,0px))}
  .side .who{padding-bottom:10px}
}


/* ═══════════════════════════════════════════════════════════════════════
   GIANGDANG v2.5 — CÁC ĐIỂM HIỆU CHỈNH THEO YÊU CẦU VẬN HÀNH
   Chồng lên phần trên, không xoá gì. Mỗi khối ghi rõ mục yêu cầu tương ứng.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 1.1 · Bảng rộng phải cuộn ngang được TRÊN CẢ MÁY TÍNH ──
   Trước đây .tblwrap bị ẩn hẳn thanh trượt (scrollbar-width:none) nên
   người dùng máy tính không biết bảng còn nội dung bên phải — nhìn như
   bị mất cột. Nay hiện thanh trượt mảnh + bóng mờ ở mép để báo còn nội dung. */
.tblwrap{scrollbar-width:thin;-ms-overflow-style:auto;position:relative}
.tblwrap::-webkit-scrollbar{height:9px;width:9px;display:block}
.tblwrap::-webkit-scrollbar-track{background:rgba(140,108,88,.06);border-radius:99px}
.tblwrap::-webkit-scrollbar-thumb{background:rgba(140,108,88,.28);border-radius:99px}
.tblwrap::-webkit-scrollbar-thumb:hover{background:rgba(140,108,88,.45)}

/* Khung bọc do JS tạo: thêm bóng mờ hai mép khi còn nội dung ẩn */
.tblscroll{position:relative}
.tblscroll::before,.tblscroll::after{
  content:'';position:absolute;top:0;bottom:9px;width:26px;pointer-events:none;
  opacity:0;transition:opacity .2s;z-index:2}
.tblscroll::before{left:0;background:linear-gradient(90deg,rgba(120,80,60,.13),transparent)}
.tblscroll::after{right:0;background:linear-gradient(270deg,rgba(120,80,60,.13),transparent)}
.tblscroll.can-l::before{opacity:1}
.tblscroll.can-r::after{opacity:1}

/* Gợi ý "vuốt để xem thêm" — chỉ hiện khi bảng thật sự tràn */
.tblhint{display:none;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);
  padding:6px 15px 0;font-weight:500}
.tblscroll.can-r > .tblhint,.tblscroll.can-l > .tblhint{display:flex}

/* ── 1.1b · Cột thao tác (Duyệt) đưa về ĐẦU bảng và ghim lại khi cuộn ── */
th.act-first,td.act-first{position:sticky;left:0;z-index:3;
  background:rgb(var(--glass-rgb) / .94);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  box-shadow:1px 0 0 var(--line)}
tbody tr:hover td.act-first{background:rgba(255,248,245,.97)}
@media (max-width:620px){ th.act-first,td.act-first{position:static;box-shadow:none} }

/* ── 1.2 · Danh mục chỉ có MỘT khối thì dàn hết chiều ngang ── */
.grid > :only-child{grid-column:1 / -1}
.grid.solo{grid-template-columns:1fr !important}
.card.full,form.card.full{width:100%}

/* ── 1.6 · Nút xổ / thu gọn nhóm menu to hơn, dễ bấm ── */
.side .grp{padding:14px 11px 10px;min-height:42px;border-radius:11px;
  cursor:pointer;-webkit-tap-highlight-color:transparent}
.side .grp:hover{background:rgb(var(--glass-rgb) / .55)}
.side .grp svg.i{width:18px;height:18px;opacity:.85;stroke-width:2.2;
  padding:0;flex:0 0 auto;border-radius:7px}
.side .grp:hover svg.i{background:rgba(234,90,43,.1);color:var(--br-600);opacity:1}

/* v3.29 · Huy hiệu tròn cho icon danh mục cấp 1 (chỉ cấp 1 — cấp 2 giữ nguyên icon như
   cũ) — theo đúng ý Enzo, TẤT CẢ đều màu xanh lá thương hiệu, không phân biệt màu theo
   từng danh mục nữa (chỉ icon khác nhau). !important để không bị luật hover/active khác
   của .side .grp đè lên. */
.catbadge{
  width:30px !important;height:30px !important;border-radius:50% !important;flex:0 0 auto;
  display:flex !important;align-items:center;justify-content:center;
  background:var(--br-100,var(--ok-bg-strong)) !important;
}
.catbadge svg.i{width:16px !important;height:16px !important;opacity:1 !important;
  background:none !important;color:var(--g700) !important}
.side .grp .gtxt{font-weight:700}
@media (max-width:900px){
  .side .grp{min-height:48px;padding:15px 12px 11px}
  .side .grp svg.i{width:20px;height:20px}
}

/* ── 1.7 · Ô nhập tiền: canh phải, chữ số đều nhau ── */
input.inp[data-money]{text-align:right;font-variant-numeric:tabular-nums;font-weight:600}
.money-wrap{position:relative;display:block}
.money-wrap > .cur{position:absolute;right:12px;top:50%;transform:translateY(-50%);
  font-size:12px;color:var(--muted);pointer-events:none;font-weight:500}
.money-wrap > input.inp{padding-right:30px}

/* ── 10 · Nút ẩn / hiện mật khẩu ── */
.pw-wrap{position:relative;display:block}
.pw-wrap > input{padding-right:44px !important}
.pw-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  width:32px;height:32px;display:grid;place-items:center;border:0;background:transparent;
  color:var(--muted);cursor:pointer;border-radius:8px;transition:.18s;padding:0}
.pw-eye:hover{color:var(--br-600);background:rgba(234,90,43,.08)}
.pw-eye svg{width:18px;height:18px}

/* ── 11 · Hộp thoại xin quyền thông báo & vị trí lần đầu đăng nhập ── */
.shk-modal{position:fixed;inset:0;z-index:200;display:none;
  align-items:center;justify-content:center;padding:20px;
  background:rgba(36,28,24,.42);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.shk-modal.show{display:flex}
.shk-modal .box{width:100%;max-width:430px;background:var(--surface);border-radius:var(--r-lg);
  padding:26px 24px 20px;box-shadow:0 24px 60px -12px rgba(120,80,60,.5);
  animation:shkPop .32s cubic-bezier(.32,.72,0,1)}
@keyframes shkPop{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}
.shk-modal h3{font-size:17px;font-weight:680;letter-spacing:-.025em;margin-bottom:6px}
.shk-modal p{font-size:13px;color:var(--ink2);line-height:1.55}
.shk-modal .perm{display:flex;gap:12px;align-items:flex-start;padding:12px 0;
  border-top:1px solid var(--line)}
.shk-modal .perm .pico{width:38px;height:38px;border-radius:12px;flex:0 0 auto;
  display:grid;place-items:center;background:var(--br-50);color:var(--br-600)}
.shk-modal .perm b{font-size:13.5px;font-weight:620;display:block}
.shk-modal .perm span{font-size:11.5px;color:var(--muted)}
.shk-modal .perm .st{margin-left:auto;font-size:11px;font-weight:600;white-space:nowrap;
  align-self:center;color:var(--muted)}
.shk-modal .perm .st.ok{color:var(--lf-600)}
.shk-modal .perm .st.no{color:var(--br-600)}
.shk-modal .ft{display:flex;gap:9px;margin-top:16px}
.shk-modal .ft .btn{flex:1;justify-content:center}

/* ── 3 · Khối tải ảnh chứng từ (chuyển khoản / bằng chứng khiếu nại) ──
   .updrop là thẻ <label> — mặc định display:inline nên border/padding/width:100%
   phía dưới không ăn đúng, khung bị vỡ (chỉ thấy viền trái/trên, chữ tràn ra ngoài).
   Phải khai báo display rõ ràng để nó là khối, đồng thời tự căn giữa nội dung. */
.updrop{display:flex;flex-direction:column;align-items:center;justify-content:center;
  border:1.5px dashed rgba(140,108,88,.3);border-radius:var(--r-sm);
  padding:16px;text-align:center;cursor:pointer;transition:.2s;background:rgb(var(--glass-rgb) / .5)}
.updrop:hover{border-color:var(--br-500);background:var(--br-50)}
.updrop input[type=file]{display:none}
.updrop .ut{font-size:13px;font-weight:600;color:var(--ink2)}
.updrop .us{font-size:11.5px;color:var(--muted);margin-top:3px}
.upgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:8px;margin-top:10px}
.upthumb{position:relative;aspect-ratio:1;border-radius:10px;overflow:hidden;
  border:1px solid var(--line);background:var(--surface)}
.upthumb img{width:100%;height:100%;object-fit:cover;display:block}
.upthumb .rm{position:absolute;top:3px;right:3px;width:22px;height:22px;border-radius:50%;
  border:0;background:rgba(36,28,24,.72);color:var(--on-accent);font-size:13px;line-height:1;cursor:pointer;
  display:grid;place-items:center}
/* v3.42 · Tài liệu không có ảnh xem trước (PDF/DOCX/XLSX...) — icon + đuôi file thay ảnh */
.upfile{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:4px;background:var(--g50,#F4F7F5);color:var(--muted)}
.upfile svg{width:26px;height:26px;opacity:.7}
.upfile span{font-size:10px;font-weight:700;letter-spacing:.03em}

/* ── 5.1 · Ô ngày trong lịch tháng: chế độ xem tên người ── */
.cal.names .day .slot .n{font-size:9.5px;opacity:.85}
.viewtog{display:inline-flex;background:rgb(var(--glass-rgb) / .7);border:1px solid var(--hair);
  border-radius:10px;padding:2px;gap:2px}
.viewtog button{border:0;background:transparent;font-family:inherit;font-size:12px;
  font-weight:600;padding:5px 11px;border-radius:8px;cursor:pointer;color:var(--muted)}
.viewtog button.on{background:var(--surface);color:var(--br-700);box-shadow:var(--sh-xs)}

/* ── 4.1 · Biểu đồ xu hướng khiếu nại ── */
.trendwrap{position:relative;height:260px}
@media (max-width:900px){ .trendwrap{height:210px} }

/* Mục 1.3 · Trang hồ sơ: thẻ hồ sơ nằm bên phải trên máy tính.
   Trên điện thoại lưới gộp về 1 cột — lúc đó thẻ hồ sơ phải quay lại trên cùng,
   vì đó là phần người dùng mở trang để xem. */
@media (max-width:900px){
  #prRow #prCard{order:1}
  #prRow #prMain{order:2}
}

/* ═══════════════════════════════════════════════════════════════════════════
   v3.0 · UI-03 · CHỦ ĐỀ XANH LÁ
   ───────────────────────────────────────────────────────────────────────────
   Yêu cầu: đổi tông chủ đạo sang xanh lá cho dịu mắt khi nhìn 8 tiếng/ngày,
   phụ trợ là xanh dương / đỏ / cam.

   Cách làm: KHÔNG sửa 918 dòng CSS phía trên và 58 màn hình đang chạy. Toàn bộ
   giao diện đã dùng biến --br-* (thương hiệu) và --lf-* (trạng thái tốt), nên
   chỉ cần định nghĩa lại giá trị của các biến đó ở cuối file là mọi nút, mọi
   tab, mọi huy hiệu đổi màu theo. Một khối override thay cho hàng trăm chỗ sửa.

   Vẫn giữ ngữ nghĩa màu:  xanh lá = chính & hợp lệ · cam = cần chú ý
                           đỏ = lỗi/nguy hiểm · xanh dương = thông tin
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  /* ---- Xanh lá: hành động chính (thay vai trò của cam đỏ cũ) ---- */
  --br-50:#F2FBF5; --br-100:#DCF3E4; --br-200:#BCE7CC;
  --br-400:#45BE78; --br-500:#26A860; --br-600:#1B8F4F; --br-700:#137540; --br-900:#0A4526;

  /* ---- Xanh lá đậm hơn cho tín hiệu "thành công" để phân biệt với nút chính ---- */
  --lf-50:#F1FBF5; --lf-100:#DBF6E5; --lf-200:#BCEBCE;
  --lf-400:#4CC97F; --lf-500:#2DB765; --lf-600:#1FA055; --lf-700:#158043; --lf-900:#0C4A28;

  /* ---- Phụ trợ ---- */
  --accent-blue:#2563EB; --accent-blue-l:#E5EDFD;
  --accent-orange:#EA8A2B; --accent-orange-l:#FDEEDC;
  --orange:var(--accent-orange); --orange-l:var(--accent-orange-l);
  --red:#DC2626; --red-l:#FEE7E5;
  --navy:#2A4A7A; --navy-d:#1D3457; --navy-l:#456AA0;

  /* ---- Nền: kem ngả xanh rất nhạt, không chói, hợp với chữ đen mềm ---- */
  --bg:#F8FBF9;
  --ink:#18241D; --ink2:#54655B; --muted:#8A9A90;
  --line:rgba(60,110,80,.12);
  --sh-xs:0 1px 2px rgba(30,80,55,.045);
  --sh:0 1px 2px rgba(30,80,55,.04), 0 10px 28px -14px rgba(30,80,55,.2);
  --sh-lift:0 1px 2px rgba(30,80,55,.05), 0 18px 40px -16px rgba(30,80,55,.28);
}

/* Những chỗ trước đây viết thẳng mã màu cam nên không đổi theo biến — sửa riêng */
body::before,body::after{}
body{
  background-image:
    radial-gradient(62rem 44rem at 92% -12%, rgba(38,168,96,.12), transparent 60%),
    radial-gradient(52rem 40rem at -8% 8%, rgba(37,99,235,.07), transparent 62%);
}
.btn{box-shadow:0 1px 2px rgba(10,69,38,.16), 0 8px 20px -8px rgba(27,143,79,.55),
     inset 0 1px 0 rgba(255,255,255,.26)}
.btn:hover{box-shadow:0 2px 4px rgba(10,69,38,.18),0 14px 28px -10px rgba(27,143,79,.62),
     inset 0 1px 0 rgba(255,255,255,.32)}
.btn.gho{border-color:rgba(27,143,79,.42)}
.btn.warn{background:linear-gradient(180deg,#F2A24A,var(--accent-orange));
     box-shadow:0 8px 18px -8px rgba(234,138,43,.5)}
.inp:focus{border-color:var(--br-500);box-shadow:0 0 0 3.5px rgba(38,168,96,.16)}
tbody tr:hover{background:rgba(38,168,96,.04)}
.side .grp:hover svg.i{background:rgba(27,143,79,.1);color:var(--br-600)}
.pw-eye:hover{color:var(--br-600);background:rgba(27,143,79,.08)}
.note.i{background:var(--accent-blue-l);color:#1E40AF}
.note.w{background:var(--accent-orange-l);color:#8A4B0F}
.gpsbig{box-shadow:0 2px 6px rgba(10,69,38,.18),0 18px 38px -14px rgba(27,143,79,.6),
     inset 0 1px 0 rgba(255,255,255,.28)}
.gpsbig.out{background:linear-gradient(155deg,var(--accent-orange),#C4661A)}
.p-o{background:var(--accent-orange-l);color:#8A4B0F}
.p-n{background:var(--accent-blue-l);color:#1E40AF}

/* ───────────────────────────────────────────────────────────────────────────
   v3.0 · UI-05 · Khu vực kéo thả ảnh
   Trạng thái "đang kéo file vào" phải thấy rõ, nếu không người dùng không biết
   thả ở đâu. Ô upload cũng được ép nằm gọn trong lưới để hết cảnh vỡ khung ở
   biểu mẫu booking và khiếu nại.
   ─────────────────────────────────────────────────────────────────────────── */
.updrop{max-width:100%;box-sizing:border-box;transition:border-color .15s, background .15s, transform .12s}
.updrop.dragover{border-color:var(--br-500);border-style:solid;background:var(--br-50);
  transform:scale(1.01);box-shadow:0 0 0 4px rgba(38,168,96,.12)}
.updrop.dragover .ut::after{content:' — thả ảnh vào đây';color:var(--br-700)}
.updrop:focus-visible{outline:2px solid var(--br-500);outline-offset:2px}
.upgrid{max-width:100%}
.fr .updrop{width:100%}

/* Biểu mẫu có nhiều cột: trên màn hình hẹp phải tự xuống một cột, không tràn ngang */
@media (max-width:760px){
  .grid[style*="grid-template-columns"]{grid-template-columns:1fr !important}
}

/* ═══════════════════════════════════════════════════════════════════════
   v3.9 · Ô tìm kiếm cho <select> dài (assets/js/app.js tự nâng cấp)
   ═══════════════════════════════════════════════════════════════════════ */
.sk-wrap{position:relative}
.sk-box{display:flex;align-items:center;gap:8px;cursor:pointer;
  background:var(--surface,var(--surface));border:1px solid var(--line);border-radius:10px;
  padding:8.5px 11px;font-size:13.5px;color:var(--ink);min-height:38px}
.sk-box:hover{border-color:var(--br-300,var(--br-600))}
.sk-box:focus{outline:2px solid var(--br-200,rgba(27,143,79,.25));outline-offset:1px}
.sk-disabled{opacity:.55;cursor:not-allowed}
.sk-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sk-caret{font-size:10px;color:var(--muted);flex:0 0 auto}
/* v3.11 · position:fixed + gắn thẳng vào <body> (xem app.js) — không còn nằm
   lồng trong bảng/thẻ/hộp thoại nào nữa nên không thể bị "cắt" bởi overflow
   của khối cha; z-index cao hơn cả .shk-modal (200) để chắc chắn luôn nổi
   trên cùng, kể cả khi mở dropdown ngay trong một hộp thoại. */
.sk-panel{display:none;position:fixed;z-index:260;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 16px 36px -14px rgba(20,40,30,.28);padding:8px;max-height:280px;
  flex-direction:column;gap:6px}
.sk-panel.open{display:flex}
.sk-search{font-size:13px}
.sk-list{overflow-y:auto;max-height:220px;display:flex;flex-direction:column;gap:1px}
.sk-item{padding:8px 9px;border-radius:8px;font-size:13px;cursor:pointer}
.sk-item:hover{background:var(--g100,var(--ok-bg))}
.sk-item.on{background:var(--br-600);color:var(--on-accent);font-weight:600}
.sk-empty{padding:10px 9px;font-size:12.5px;color:var(--muted);text-align:center}

/* ═══════════════════════════════════════════════════════════════════════
   v3.9 · Menu trái 2 cấp (danh mục cha → nhóm nghiệp vụ → màn hình)
   ═══════════════════════════════════════════════════════════════════════ */
.menusearch{position:relative;margin:2px 2px 10px}
.menusearch svg.i{position:absolute;left:10px;top:50%;transform:translateY(-50%);
  width:14px;height:14px;opacity:.5;pointer-events:none}
.menusearch input{width:100%;box-sizing:border-box;padding:8px 10px 8px 30px;
  border-radius:10px;border:1px solid var(--hair,var(--line));background:rgb(var(--glass-rgb) / .6);
  font-size:12.5px;color:var(--ink)}
.menusearch input:focus{outline:2px solid var(--br-200,rgba(27,143,79,.25));background:var(--surface)}

/* Danh mục cha: chữ đậm hơn, có viền phân cách phía trên — phân biệt rõ
   với nhóm nghiệp vụ con nằm bên trong nó */
.side .grp.cat{font-size:11px;font-weight:700;color:var(--ink2);letter-spacing:.03em;
  padding-top:16px;margin-top:6px;border-top:1px solid var(--hair,var(--line))}
.side .grp.cat:first-child{border-top:0;margin-top:0}
.side .grp.cat.active,.side .grp.cat.active .gtxt{color:var(--br-700,var(--br-600))}
/* Nhóm nghiệp vụ con thụt vào một chút, chữ nhỏ hơn danh mục cha cho rõ tôn ti */
.gitems.cat > .grp.sub{padding-left:8px;font-size:10px;opacity:.85}
.gitems.cat > .gitems{padding-left:4px}
.app.mini .menusearch,.app.mini .grp.cat{display:none}

/* ═══════════════════════════════════════════════════════════════════════
   v3.9 · Khung nổi bật (hero) — làm nổi khối nội dung chính của mỗi trang
   ═══════════════════════════════════════════════════════════════════════
   Giao diện trước giờ toàn thẻ trắng viền mảnh giống hệt nhau, người dùng
   phải đọc chữ mới biết đâu là phần quan trọng nhất của trang. Thêm 1 lớp
   ".hero" dùng CHUNG (không phải viết CSS riêng từng trang): nền gradient
   xanh lá đậm theo đúng tông thương hiệu đã chốt (#1B8F4F), chữ trắng, dùng
   cho ĐÚNG MỘT khối quan trọng nhất mỗi trang — vd "Hôm nay của tôi" ở Tổng
   quan, thẻ thông tin nhân sự ở Hồ sơ của tôi. Dùng tràn lan sẽ mất tác
   dụng nổi bật nên cố ý không áp cho mọi .card. */
/* v3.19 · SỬA LỖI: nền gradient trước đây đọc var(--g700) — nhưng dòng bên dưới (.hero,.hero *)
   lại GHI ĐÈ chính --g700 thành #fff ngay trên phần tử .hero để chữ trạng thái không bị chìm,
   nên nền hero cũng ăn theo thành trắng luôn (góc trên bên trái trắng xoá, chữ "Hôm nay của
   tôi" gần như mất). Ghi thẳng mã màu, không phụ thuộc biến --g700 nữa để hai chỗ hết đụng nhau. */
.hero{
  background:linear-gradient(135deg,#1B8F4F 0%,#0F6B3A 100%);
  border:0;color:var(--on-accent);position:relative;overflow:hidden;
  box-shadow:0 22px 46px -22px rgba(15,107,58,.55);
}
/* v3.41 · SỬA LỖI: vệt sáng cũ là 1 vòng tròn CỐ ĐỊNH 220px dán ở góc trên-phải — trên
   card hẹp (vuông) che gần hết bề mặt nên trông ổn, nhưng "Hôm nay của tôi" là card RẤT
   RỘNG (tràn ngang trang) mà lại thấp, nên vòng tròn chỉ chiếm một góc nhỏ bên phải, gần
   3/4 bề mặt card bên trái trống trơn không có ánh sáng — nhìn như hiệu ứng "kính" không
   phủ hết cả khối. Đổi sang 2 quầng sáng dùng ĐƠN VỊ %, tự giãn theo chiều rộng card bất
   kể card vuông hay rộng, cộng 1 dải chéo mờ phủ toàn bộ bề ngang — luôn trải đều hết box. */
.hero::before{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:
    radial-gradient(60% 140% at 8% -10%, rgba(255,255,255,.22), transparent 60%),
    radial-gradient(60% 140% at 92% -10%, rgba(255,255,255,.16), transparent 60%),
    linear-gradient(120deg, rgba(255,255,255,.10) 0%, transparent 45%);
}
.hero .hd{border-bottom-color:rgba(255,255,255,.18)}
.hero .hd h3{color:var(--on-accent)}
.hero .hd .r{color:rgba(255,255,255,.85)}
/* v3.18 · SỬA LỖI: chữ trạng thái "tốt" (vd "Đang trong ca") dùng --g700/--g600 (xanh lá
   đậm, màu dành cho hiện trên NỀN TRẮNG) — trên nền .hero cũng xanh lá đậm, hai màu xanh
   gần như trùng nhau, chữ biến mất. Đổi mọi biến màu xanh lá thành trắng NGAY TRONG .hero,
   những nơi khác trong toàn hệ thống không hề bị ảnh hưởng vì đây là biến CSS cục bộ theo
   phạm vi .hero, không phải sửa giá trị gốc của --g700 dùng chung toàn hệ thống. */
.hero,.hero *{--muted:rgba(255,255,255,.78);--ink:#fff;--ink2:#fff;--line:rgba(255,255,255,.22);
  --g900:#fff;--g800:#fff;--g700:#fff;--g600:#fff;--g500:#fff}
.hero a{color:var(--on-accent)}
.hero .pill{background:rgb(var(--glass-rgb) / .2)!important;color:var(--on-accent)!important;
  border:1px solid rgb(var(--glass-rgb) / .34)!important}
.hero .btn.sec{background:rgb(var(--glass-rgb) / .16);color:var(--on-accent);border-color:rgb(var(--glass-rgb) / .32)}
.hero .btn.sec:hover{background:rgb(var(--glass-rgb) / .26)}
.hero .av{background:rgb(var(--glass-rgb) / .22);color:var(--on-accent)}
.hero [style*="border:1px solid var(--line)"]{border-color:rgb(var(--glass-rgb) / .24)!important;
  background:rgb(var(--glass-rgb) / .08)}

/* ═══════════════════════════════════════════════════════════════════════
   v3.10 · Menu trái dừng ở cấp 2 + dải tab điều hướng cấp 3 đầu khu nội dung
   ═══════════════════════════════════════════════════════════════════════
   Bản trước thử lồng 3 cấp trong menu trái: bấm nhóm cấp 2 thì cấp 3 hiện ra
   RỒI ĐÓNG LẠI NGAY (do CSS thu/mở tính theo max-height của khối cha, còn
   .app.mini và một số nơi khác coi .gitems lồng nhau là "chưa từng thấy"),
   dùng rất khó chịu. Đổi cách: menu trái CHỈ còn 2 cấp thật sự nhìn thấy,
   cấp 3 (từng màn hình) chuyển hẳn ra dải tab ngang ở đầu khu nội dung — xem
   core/GroupNav.php và .groupnav bên dưới. */
.side .subsearch{display:none}
.side .subsearch.show{display:flex;flex-direction:column;gap:2px;margin:2px 0 4px 6px;
  padding-left:8px;border-left:2px solid var(--hair,var(--line))}
.side .subsearch a{font-size:12px;padding:6.5px 9px}

/* v3.11 · SỬA LỖI: nhóm có nhiều màn hình con thì mấy tab cuối bị "mất" —
   trước đây dải tab cuộn ngang (overflow-x:auto) nhưng KHÔNG có thanh cuộn
   hiện ra (cố ý ẩn để đẹp) và không có dấu hiệu gì báo còn tab nằm ngoài
   khung nhìn, nên trông y hệt như các tab đó biến mất, không ai biết phải
   cuộn ngang mới thấy. Đổi sang cho tab TỰ XUỐNG DÒNG (flex-wrap) — nhóm dù
   có bao nhiêu màn hình cũng hiện đủ hết, không cần cuộn, không mất gì. */
.groupnav{margin:-4px -4px 18px}

/* v3.15 · Nút "Về {nhóm}" — tách riêng khỏi dải tab/ô xổ xuống, luôn hiện rõ ở cả 2
   giao diện, để bấm về trang tổng của nhóm mà không phải dò trong danh sách dài. */
.gnback{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:600;
  color:var(--muted);padding:6px 4px;margin-bottom:4px}
.gnback:hover{color:var(--br-600)}
.gnback.on{color:var(--br-600)}
.gnback svg.i{width:14px;height:14px}

.gnwrap{display:flex;flex-wrap:wrap;gap:6px 6px;padding:4px 4px 10px;border-bottom:1px solid var(--line)}
.gntab{display:flex;align-items:center;gap:7px;padding:8px 13px;border-radius:10px;
  font-size:13px;font-weight:600;color:var(--muted);white-space:nowrap;
  border:1px solid transparent}
.gntab:hover{color:var(--ink);background:rgba(0,0,0,.03)}
.gntab.on{color:var(--on-accent);background:var(--br-600);border-color:var(--br-600)}
.gntab svg.i{width:15px;height:15px;opacity:.85}
.gntab.on svg.i{opacity:1}

/* Ô xổ xuống thay dải tab trên điện thoại — ẩn hẳn trên máy tính */
.gnselect{display:none}

@media(max-width:680px){
  .gnwrap{display:none}
  .gnselect{display:block;width:100%;margin-bottom:10px;padding:10px 12px;
    border-radius:11px;border:1px solid var(--line);background:var(--surface);
    font-size:13.5px;font-weight:600;color:var(--ink)}
}

/* ═══════════════════════════════════════════════════════════════════════
   v3.11 · UI-01 — Trang đăng nhập 2 cột (đặc tả FIXV4 mục UI-01)
   ═══════════════════════════════════════════════════════════════════════ */
.loginwrap2{min-height:100vh;display:grid;grid-template-columns:1.1fr 1fr}
.loginbrand{position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;
  padding:48px;color:var(--on-accent);background:linear-gradient(150deg,#0B4A25 0%,#132747 100%)}
.loginbrand .lb-blob{position:absolute;border-radius:50%;filter:blur(60px);opacity:.55}
.loginbrand .lb-1{width:420px;height:420px;background:#EA5A2B;top:-120px;left:-100px}
.loginbrand .lb-2{width:380px;height:380px;background:#1B8F4F;bottom:-140px;right:-100px}
.loginbrand.has-banner{background:linear-gradient(160deg,rgba(8,40,24,.62) 0%,rgba(12,22,44,.55) 100%),var(--lb-img) center/cover no-repeat}   /* v3.103 · ảnh nền trang đăng nhập (Nhận diện thương hiệu) — lớp tối để chữ trắng luôn đọc được */
.loginbrand.has-banner h1,.loginbrand.has-banner p{text-shadow:0 1px 12px rgba(0,0,0,.35)}
.loginbrand .lb-inner{position:relative;max-width:420px;text-align:center}
.loginbrand .lb-inner img{height:56px;margin-bottom:18px}
.loginbrand h1{font-size:26px;font-weight:800;letter-spacing:-.02em;margin:0 0 4px}
.loginbrand h1 span{display:block;font-size:11px;font-weight:700;letter-spacing:.22em;
  color:rgba(255,255,255,.72);margin-top:4px}
.loginbrand p{font-size:13.5px;color:rgba(255,255,255,.78);line-height:1.7;margin-top:14px}

.loginright{display:flex;align-items:center;justify-content:center;padding:24px;background:#F5F7F6}
.mobileonly{display:none}
.remember{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink2);
  margin:2px 0 16px;cursor:pointer}
.remember input{width:15px;height:15px;accent-color:var(--br-600,#1B8F4F)}
.loginhelp{text-align:center;margin-top:12px}
.loginhelp button{background:none;border:0;color:var(--br-700,var(--br-600));font-size:12.5px;
  font-weight:600;cursor:pointer;text-decoration:underline}

@media(max-width:860px){
  .loginwrap2{grid-template-columns:1fr}
  .loginbrand{display:none}
  .mobileonly{display:flex;justify-content:center;margin-bottom:6px}
  .mobileonly img{height:44px}
}

/* ═══════════════════════════════════════════════════════════════════════
   v3.15 · Box thông tin nhân sự nhỏ ở cuối menu trái — thêm ảnh đại diện +
   quản lý trực tiếp, bấm vào là sang thẳng Hồ sơ của tôi để cập nhật.
   ═══════════════════════════════════════════════════════════════════════ */
.whocard{display:flex;align-items:center;gap:9px;padding:4px 0 8px;color:inherit}
.whocard:hover .whoinfo b{color:var(--br-600)}
.whoav{width:34px;height:34px;border-radius:50%;object-fit:cover;flex:0 0 auto}
.whoav-txt{display:flex;align-items:center;justify-content:center;background:var(--br-100,#E7F5EC);
  color:var(--br-700,var(--br-600));font-weight:700;font-size:12.5px}
.whoinfo{min-width:0;flex:1}
.whoinfo b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.whoinfo span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.whomgr{opacity:.85}
.app.mini .whocard{flex-direction:column;gap:2px}
.app.mini .whoinfo{display:none}

/* ═══════════════════════════════════════════════════════════════════════
   v3.22 · Vài nét riêng cho giao diện — Enzo phản hồi giao diện "đại trà",
   thêm vài chi tiết nhận diện thương hiệu chứ không đổi bố cục/khung sẵn có
   (an toàn hơn khi không có môi trường xem trước trực tiếp trên hosting thật).
   ═══════════════════════════════════════════════════════════════════════ */

/* Dải màu thương hiệu mảnh dưới thanh tiêu đề — đổi theo chi nhánh (theme --g900) */
.top{position:relative}
.top::after{
  content:'';position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:linear-gradient(90deg,var(--g700),var(--g500) 45%,transparent);
  opacity:.85;
}
.top h1{position:relative;padding-left:13px}
.top h1::before{
  content:'';position:absolute;left:0;top:3px;bottom:3px;width:4px;border-radius:3px;
  background:linear-gradient(180deg,var(--g500),var(--g700));
}

/* Viền trên thẻ card hơi bo nhẹ theo màu thương hiệu khi hover — thay vì chỉ nâng bóng */
.card{position:relative;transition:box-shadow .18s,transform .18s,border-color .18s}
.card:hover{border-color:rgba(38,168,96,.28)}

/* Số liệu KPI nổi bật hơn — số to có gradient chữ nhẹ, phân biệt rõ ràng với nhãn */
.card.kpi .vl{
  background:linear-gradient(135deg,var(--ink) 40%,var(--g700));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
}

/* ═══════════════════════════════════════════════════════════════════════
   v3.23 · Hiệu ứng chuyển cảnh giữa các trang trên điện thoại — cho cảm giác
   giống app thật hơn. Dùng View Transitions API của trình duyệt (Chrome/Edge
   Android bản mới) — trình duyệt tự lo animation, KHÔNG có JS chặn điều hướng
   nên không hề làm chậm trang; trình duyệt không hỗ trợ (Safari cũ, Firefox)
   tự động bỏ qua, trang vẫn chạy y như trước, không lỗi gì.
   ═══════════════════════════════════════════════════════════════════════ */
/* v3.24 · Đổi từ crossfade mặc định sang kiểu SWIPE (trượt ngang + mờ dần) cho giống
   hiệu ứng đẩy màn hình của app thật hơn. Vẫn 100% trình duyệt tự lo animation. */
@media (max-width:900px){
  @view-transition{ navigation: auto; }
  ::view-transition-old(root){ animation: shkSwipeOut .32s ease-out both; }
  ::view-transition-new(root){ animation: shkSwipeIn .34s ease-out both; }
}
@keyframes shkSwipeOut{ to{ transform:translateX(-16%); opacity:0; } }
@keyframes shkSwipeIn{ from{ transform:translateX(20%); opacity:0; } to{ transform:translateX(0); opacity:1; } }

/* Icon ngọn lửa loading (linh vật dùng chung với Streak — xem flameMascot() trong
   core/Helper.php) — hiện ngay khi bấm 1 link điều hướng trên điện thoại, tự biến
   mất khi trang mới tải xong (không cần JS dọn dẹp gì thêm). */
#navFlame{
  position:fixed;inset:0;z-index:9999;display:none;flex-direction:column;gap:10px;
  align-items:center;justify-content:center;background:rgba(255,247,237,.82);backdrop-filter:blur(2px);
}
#navFlame.show{display:flex}
#navFlame svg{width:52px;height:52px;filter:drop-shadow(0 6px 12px rgba(249,115,22,.4))}
#navFlame span{font-size:12px;color:#C2410C;font-weight:600}

/* v3.25 · Nút "Đổi cover" ở Hồ sơ của tôi — chỉ hiện khi rê chuột vào dải cover */
.cover-edit-btn{opacity:0;transition:opacity .15s;pointer-events:none}
.prcover-wrap:hover .cover-edit-btn{opacity:1;pointer-events:auto}
@media (hover:none){ .cover-edit-btn{opacity:1;pointer-events:auto} }

/* v3.27 · Chân trang — bản quyền + thời gian tải + khoảng đệm để 2 nút nổi (trợ giúp,
   cuộn lên đầu) không đè lên nội dung thật ở cuối trang. */
/* v3.28 · Chân trang luôn "dính" đáy màn hình — trang ít nội dung thì chân trang vẫn
   nằm sát cuối viewport (không lửng lơ ngay dưới nội dung, cách quãng trắng lớn tới hết
   trang), trang dài thì chân trang tự đẩy xuống theo nội dung như bình thường. Cách làm:
   .content vốn đã là item trong cột flex .main (100vh) — cho .content GIÃN HẾT chỗ còn lại
   (flex:1) và tự thành cột flex riêng, rồi đẩy chân trang bằng margin-top:auto. */
.content{flex:1;display:flex;flex-direction:column}
.content>*:not(.sitefooter){flex:0 0 auto}
.sitefooter{
  margin-top:auto;padding:14px 4px calc(38px + env(safe-area-inset-bottom,0px));
  border-top:1px solid var(--line);color:var(--muted);font-size:11.5px;line-height:1.7;
}
.sitefooter a{color:var(--g700);text-decoration:underline}
@media (max-width:900px){
  .sitefooter{padding-bottom:calc(var(--tabbar-h) + 34px + env(safe-area-inset-bottom,0px))}
}

/* v3.24 · Cờ đổi ngôn ngữ — nhỏ gọn, bo góc mềm (thay vì cắt tròn làm mất hình chữ nhật
   quốc kỳ), có hiệu ứng nảy nhẹ khi rê chuột cho vui mắt hơn. */
.flagbtn{width:19px;height:13px;display:block;border-radius:3.5px;overflow:hidden;
  box-shadow:0 0 0 1px rgba(0,0,0,.08);opacity:.55;transition:transform .15s,opacity .15s}
.flagbtn svg{display:block;width:100%;height:100%}
.flagbtn:hover{transform:translateY(-2px) scale(1.12);opacity:.9}
.flagbtn.on{opacity:1;box-shadow:0 0 0 2px var(--g600)}

/* v3.23 · Banner truyền thông nội bộ ở Trang tổng quan (soạn ở Marketing → Banner) */
.hbanner{background:linear-gradient(120deg,var(--br-50),var(--surface));overflow:hidden}

/* v3.25 · Box Streak làm lại theo đúng mẫu Enzo gửi — nền trắng sạch, các dòng hành
   động dạng "row" bo tròn màu nhạt thay vì nền màu cam phủ cả thẻ (bản trước). */
.streakcard2{border-color:var(--line)}
.streak-badge{
  width:52px;height:52px;border-radius:50%;flex:0 0 auto;padding:9px;box-sizing:border-box;
  background:linear-gradient(135deg,#FFC53D,#F97316);
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 6px 16px -6px rgba(249,115,22,.55);
}
.streak-row{
  display:flex;align-items:center;gap:10px;padding:11px 13px;border-radius:12px;
  background:#F8FAFC;text-decoration:none;color:inherit;
}
.streak-row-cta{background:#FEF2F2}
.streak-row .ic{
  width:32px;height:32px;border-radius:50%;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;background:var(--danger-bg-strong);color:#E11D48;
}
.flame-mascot{animation:flameSway 1.6s ease-in-out infinite alternate}
@keyframes flameSway{0%{transform:rotate(-4deg) scale(1)}100%{transform:rotate(4deg) scale(1.05)}}

/* v3.24 · Huy hiệu icon góc thẻ số liệu (đoán theo nhãn + phối màu riêng theo chủ đề
   — xem assets/js/app.js) — icon 1 nét cùng bộ với cả trang, nền màu nhỏ gọn thay vì
   icon khổng lồ mờ nhạt trước đây. */
.card.kpi{position:relative}
.kpi-deco{
  position:absolute;top:10px;right:10px;width:30px;height:30px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;pointer-events:none;
}
.kpi-deco svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}

/* Mọi ô chọn ngày/giờ hiện rõ một "hộp lịch" để bấm, thay vì icon lịch mặc định của
   trình duyệt nhỏ và mờ nhạt, dễ bị tưởng là ô chữ thường không bấm được */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator,
input[type="week"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator{
  cursor:pointer;opacity:1;padding:4px;margin-right:-4px;border-radius:6px;
  background-color:var(--br-50,var(--ok-bg));
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator{
  background-color:var(--br-100,var(--ok-bg-strong));
}

/* Card có icon ngay trước tiêu đề (Icon::render() gọi trong .hd) — bọc icon trong một
   huy hiệu tròn màu thương hiệu thay vì icon trần đứng cạnh chữ, trông có chủ đích hơn */
.card .hd > svg.i:first-child{
  background:linear-gradient(135deg,var(--br-100,var(--ok-bg-strong)),var(--br-50,#F2FBF5));
  color:var(--g700);border-radius:9px;padding:6px;width:30px !important;height:30px !important;
  box-sizing:border-box;flex:0 0 auto;
}

/* Pill trạng thái bo tròn hơn + có viền mảnh thay vì chỉ nền phẳng — dễ phân biệt hơn khi
   nhiều pill đứng cạnh nhau trong bảng dày đặc dữ liệu */
.pill{border:1px solid rgba(0,0,0,.05)}

/* ═══════════════════════════════════════════════════════════════════════
   v3.30 · LIQUID GLASS — đẩy sâu thêm hiệu ứng kính mờ kiểu Apple (Control
   Center/Vision Pro): thêm vệt sáng phản chiếu (specular highlight) trên
   mép trên mỗi card, viền sáng 2 lớp, và glow mềm khi hover — cộng thêm vào
   bộ "SOFT GLASS" đã có (không sửa lại --glass/--blur/--hair, chỉ layer
   thêm để không ảnh hưởng 55+ màn hình đang dùng các biến đó).
   ═══════════════════════════════════════════════════════════════════════ */
.card{
  position:relative;isolation:isolate;
  box-shadow:var(--sh), inset 0 1px 0 rgba(255,255,255,.75), inset 0 0 0 1px rgba(255,255,255,.15);
}
.card::before{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;
  background:linear-gradient(180deg,rgb(var(--glass-rgb) / .5) 0%,rgba(255,255,255,0) 26%);
  opacity:.8;
}
.card:hover{box-shadow:var(--sh-lift), inset 0 1px 0 rgba(255,255,255,.85), inset 0 0 0 1px rgba(255,255,255,.22)}

.top{background:var(--glass-2,var(--glass));box-shadow:0 1px 0 rgba(255,255,255,.6), 0 8px 24px -16px rgba(120,80,60,.28)}

.side{box-shadow:inset -1px 0 0 rgba(255,255,255,.5), 4px 0 24px -16px rgba(60,40,30,.18)}
.side .grp.cat{position:relative}
.side .grp.cat .catbadge{box-shadow:0 1px 2px rgba(0,0,0,.06), inset 0 1px 0 rgba(255,255,255,.6)}

.btn:not(.sec):not(.gho){position:relative;overflow:hidden}
.btn:not(.sec):not(.gho)::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.28),rgba(255,255,255,0) 55%);
}

/* ── Ô tìm kiếm toàn hệ thống (topbar) — v3.30, xem core/Search.php + SearchController ── */
.globalsearch{
  position:relative;flex:1 1 260px;max-width:440px;min-width:0;
  display:flex;align-items:center;gap:8px;
  background:var(--glass-2,rgb(var(--glass-rgb) / .7));
  border:1px solid var(--hair,rgb(var(--glass-rgb) / .9));
  border-radius:var(--r-lg,20px);padding:8px 13px;
  box-shadow:var(--sh-xs,0 1px 2px rgba(0,0,0,.04)), inset 0 1px 0 rgba(255,255,255,.7);
  transition:box-shadow .2s,border-color .2s;
}
.globalsearch:focus-within{border-color:var(--br-400,#FF8A5B);box-shadow:0 0 0 3px rgba(249,110,58,.14), inset 0 1px 0 rgba(255,255,255,.7)}
.globalsearch svg.i{opacity:.55;flex:0 0 auto}
.globalsearch input{flex:1;min-width:0;border:0;background:none;outline:0;font-size:13.5px;color:var(--ink)}
.globalsearch input::placeholder{color:var(--muted)}
.gsclear{border:0;background:rgba(0,0,0,.06);color:var(--ink2);width:18px;height:18px;border-radius:50%;
  font-size:14px;line-height:1;cursor:pointer;flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.gsclear:hover{background:rgba(0,0,0,.12)}
.gsdrop{
  position:absolute;top:calc(100% + 8px);left:0;right:0;max-height:70vh;overflow-y:auto;
  background:var(--glass-2,rgb(var(--glass-rgb) / .88));
  -webkit-backdrop-filter:var(--blur,saturate(165%) blur(22px));backdrop-filter:var(--blur,saturate(165%) blur(22px));
  border:1px solid var(--hair,rgb(var(--glass-rgb) / .9));border-radius:var(--r,16px);
  box-shadow:var(--sh-lift,0 18px 40px -16px rgba(30,20,15,.3));
  z-index:120;padding:6px;
}
.gsdrop .gsg{padding:8px 10px 4px;font-size:10.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.gsdrop a{display:flex;flex-direction:column;gap:1px;padding:8px 10px;border-radius:10px;color:var(--ink)}
.gsdrop a:hover,.gsdrop a.hi{background:rgb(var(--glass-rgb) / .85)}
.gsdrop a b{font-size:13px;font-weight:600}
.gsdrop a span{font-size:11px;color:var(--muted)}
.gsdrop .gsfoot{padding:8px 10px 4px;border-top:1px solid var(--line);margin-top:4px}
.gsdrop .gsfoot a{padding:6px 10px;font-size:12px;font-weight:600;color:var(--br-600)}
.gsdrop .gsempty,.gsdrop .gsloading{padding:16px 12px;color:var(--muted);font-size:12.5px;text-align:center}

/* v3.48 · Mục 3/6 — nút kính lúp thu/mở ô tìm kiếm trên điện thoại (ẩn hẳn trên desktop,
   ô tìm kiếm desktop luôn hiện đầy đủ như trước, không đổi gì) */
.gstoggle{display:none;border:0;background:transparent;padding:0;margin:0;cursor:pointer;
  align-items:center;justify-content:center;width:100%;height:100%}
@media (max-width:900px){
  /* Thu gọn: chỉ còn ô vuông chứa nút kính lúp, không còn chiếm nguyên 1 hàng dưới top bar
     như trước — các nút khác (chuông, chi nhánh...) không bị đẩy mất chỗ nữa (mục 3). */
  /* v3.49 · Mục 3 — SỬA LỖI: viền/icon mờ (var(--hair), opacity .55) hợp với nền kính
     nhiều màu nhưng gần như biến mất trên nền trắng của thanh trên — đổi hẳn sang viền đặc
     + icon đậm màu, giống hệt kiểu nút chuông thông báo bên cạnh, để luôn thấy rõ. */
  .globalsearch{order:0;flex:0 0 auto;width:36px;height:34px;max-width:none;
    padding:0;justify-content:center;overflow:visible;margin-top:0;border-radius:9px;
    background:var(--surface);border-color:var(--line)}
  .globalsearch svg.i{display:none}
  .globalsearch .gstoggle{display:flex;color:var(--ink)}
  .globalsearch .gstoggle svg.i{display:block;opacity:1}
  .globalsearch input,.globalsearch .gsclear{display:none}
  /* Mở rộng: bấm nút kính lúp → nổi thành 1 thanh đầy đủ phía trên nội dung, không đẩy vỡ
     bố cục top bar; bấm ra ngoài (xử lý ở app.js) hoặc Escape lại thu gọn về icon. */
  .globalsearch.expanded{
    position:fixed;left:10px;right:10px;top:8px;width:auto;height:44px;
    padding:0 12px;z-index:150;background:var(--surface);
    box-shadow:var(--sh-lift,0 18px 40px -16px rgba(30,20,15,.3));
  }
  .globalsearch.expanded .gstoggle{display:none}
  .globalsearch.expanded svg.i{display:block}
  .globalsearch.expanded input{display:block}
  .globalsearch.expanded .gsclear:not([hidden]){display:flex}
}

/* ── Cửa sổ nổi (floating panel) — v3.30, xem assets/js/app.js §floatpanel ──
   Mở một route bên trong khung nổi thay vì chuyển hẳn trang, cho các thao tác
   nhanh (thêm/sửa 1 dòng, xem nhanh chi tiết) — bấm ra ngoài / nút X / nút có
   data-close-panel (thường là nút "Lưu" sau khi submit xong) để đóng lại. */
.fpscrim{
  position:fixed;inset:0;z-index:300;display:none;align-items:center;justify-content:center;
  padding:4vh 16px;overflow:hidden;
  background:rgba(36,28,24,.38);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
}
.fpscrim.show{display:flex}
.fpanel{
  width:auto;min-width:min(420px,92vw);max-width:min(880px,94vw);
  height:auto;max-height:92vh;display:flex;flex-direction:column;overflow:hidden;
  background:var(--glass-2,rgb(var(--glass-rgb) / .94));
  -webkit-backdrop-filter:var(--blur,saturate(165%) blur(22px));backdrop-filter:var(--blur,saturate(165%) blur(22px));
  border:1px solid var(--hair,rgb(var(--glass-rgb) / .9));border-radius:var(--r-lg,22px);
  box-shadow:0 30px 70px -20px rgba(30,20,15,.45), inset 0 1px 0 rgba(255,255,255,.8);
  animation:shkPop .28s cubic-bezier(.32,.72,0,1);
}
.fpanel .fphd{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid var(--line);flex:0 0 auto}
.fpanel .fphd h3{font-size:15.5px;font-weight:680;letter-spacing:-.02em;flex:1}
.fpanel .fpx{border:0;background:rgba(0,0,0,.06);color:var(--ink2);width:28px;height:28px;border-radius:50%;
  cursor:pointer;display:flex;align-items:center;justify-content:center;flex:0 0 auto;font-size:17px;line-height:1}
.fpanel .fpx:hover{background:rgba(0,0,0,.12)}
/* Chỉ MỘT vùng cuộn duy nhất (fpbody) — trước đây scrim cũng overflow:auto nên có lúc
   cuộn lồng cuộn (vừa cuộn nền vừa cuộn nội dung), gây cảm giác "kéo tới lui" khó chịu.
   Panel co theo đúng chiều cao nội dung thật (không còn khoảng trắng thừa phía dưới) nhờ
   height:auto + max-height:92vh — chỉ khi nội dung THẬT SỰ vượt 92vh mới hiện thanh cuộn. */
.fpanel .fpbody{padding:16px 18px;overflow-y:auto;overflow-x:hidden;flex:1 1 auto;min-height:0}
.fpanel .fpbody .top,.fpanel .fpbody h1,.fpanel .fpbody .sitefooter{display:none} /* nội dung tải qua AJAX chỉ lấy phần .content — ẩn nốt phần chân trang nếu lỡ lẫn vào */
.fpanel .fpbody>.card{box-shadow:none;border:0;background:transparent} /* form thường đã tự bọc .card riêng — bọc thêm 1 lớp .card của panel nữa thừa viền/bóng, dẹp cho gọn */
.fpanel .fploading{padding:40px 18px;text-align:center;color:var(--muted);font-size:13px}

/* ── Module POS bán hàng — v3.37 ──────────────────────────────────────────── */
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:7px;font-size:11px;font-weight:600;
  background:rgba(0,0,0,.05);color:var(--ink2)}
.tag.sm{padding:1px 6px;font-size:10px}
.btn.dan{color:var(--on-accent)}
.btn.ic{padding:4px 9px;min-width:30px;text-align:center;line-height:1}

.totline{display:flex;justify-content:space-between;gap:10px;padding:5px 0;font-size:13px}
.totline.total{border-top:1px solid var(--hair,var(--line));margin-top:6px;padding-top:8px;font-size:15.5px;font-weight:700}

/* Bán hàng — 2 cột: danh mục món bên trái, giỏ hàng cố định bên phải */
.pos-wrap{display:grid;grid-template-columns:1.5fr 1fr;gap:14px;align-items:start}
.pos-catalog{min-width:0}
.pos-cart{display:flex;flex-direction:column;position:sticky;top:14px;max-height:calc(100vh - 100px)}

.pos-dishgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:10px}
.pos-dish{position:relative;border:1px solid var(--hair,var(--line));border-radius:var(--r,14px);
  background:var(--card,var(--surface));padding:8px 8px 10px;text-align:left;cursor:pointer;transition:.15s;overflow:hidden}
.pos-dish:hover{transform:translateY(-2px);box-shadow:var(--sh,0 8px 20px -10px rgba(0,0,0,.25))}
.pos-dish.fav{border-color:var(--orange)}
.pos-dish .star{position:absolute;top:12px;right:12px;color:var(--orange);font-size:14px;z-index:1;filter:drop-shadow(0 1px 2px rgba(0,0,0,.25))}
.pos-dish .thumb{width:100%;aspect-ratio:4/3;border-radius:calc(var(--r,14px) - 6px);display:flex;
  align-items:center;justify-content:center;font-size:30px;margin-bottom:8px}
.pos-dish .nm{font-size:12.5px;font-weight:600;line-height:1.3;margin-bottom:4px;min-height:32px;padding:0 2px}
.pos-dish .pr{font-size:12.5px;font-weight:700;color:var(--g700);padding:0 2px}

/* ── F&B app mobile — danh mục cuộn ngang, giỏ hàng là bottom sheet, thanh nổi dưới cùng ── */
.pos-catbar{display:none}
.pos-mobilebar{display:none}
.pos-cart-close{display:none}
@media (max-width:960px){
  .pos-wrap{grid-template-columns:1fr;position:relative}
  .pos-catalog{padding-bottom:76px} /* chừa chỗ cho thanh giỏ hàng nổi */

  /* Dải chip danh mục cuộn ngang, dính đầu trang khi cuộn */
  .pos-catbar{display:flex;gap:8px;overflow-x:auto;-webkit-overflow-scrolling:touch;padding:2px 2px 10px;
    position:sticky;top:0;z-index:5;background:var(--bg,var(--surface-2));scrollbar-width:none}
  .pos-catbar::-webkit-scrollbar{display:none}
  .pos-catbar a{flex:0 0 auto;padding:7px 14px;border-radius:999px;font-size:12.5px;font-weight:600;
    border:1px solid var(--hair,var(--line));background:var(--glass-2,rgb(var(--glass-rgb) / .7));color:var(--ink2);white-space:nowrap}
  .pos-catbar a.on{background:var(--g600,#16a34a);border-color:var(--g600,#16a34a);color:var(--on-accent)}

  .pos-dishgrid{grid-template-columns:repeat(2,1fr)}
  .pos-dish{padding:8px 8px 10px}
  .pos-dish .thumb{font-size:34px}
  .pos-dish .nm{font-size:13.5px;min-height:36px}
  .pos-dish .pr{font-size:13.5px}

  /* Giỏ hàng trở thành bottom sheet trượt lên, ẩn theo mặc định */
  .pos-cart{position:fixed;left:0;right:0;bottom:0;top:auto;max-height:88vh;z-index:30;
    background:var(--bg,var(--surface-2));padding:10px 12px calc(10px + env(safe-area-inset-bottom));
    border-radius:18px 18px 0 0;box-shadow:0 -10px 30px -12px rgba(0,0,0,.35);
    transform:translateY(105%);transition:transform .25s ease;overflow-y:auto}
  .pos-cart.show{transform:translateY(0)}
  .pos-cart-close{display:flex;align-items:center;justify-content:space-between;padding:2px 2px 10px;font-weight:700;font-size:15px}

  /* Nền mờ phía sau khi giỏ hàng mở */
  .pos-cart-backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:25}
  .pos-cart-backdrop.show{display:block}

  /* Thanh nổi dưới cùng — số món + tổng tiền + nút xem giỏ, kiểu app đặt món F&B */
  .pos-mobilebar{display:flex;align-items:center;gap:10px;position:fixed;left:10px;right:10px;
    bottom:calc(10px + env(safe-area-inset-bottom));z-index:20;background:var(--g700,#15803d);color:var(--on-accent);
    border-radius:16px;padding:11px 14px;box-shadow:0 10px 24px -8px rgba(0,0,0,.4);cursor:pointer}
  .pos-mobilebar .ico{position:relative;font-size:20px}
  .pos-mobilebar .cnt{position:absolute;top:-8px;right:-10px;background:var(--surface);color:var(--g700,#15803d);
    font-size:10.5px;font-weight:800;border-radius:999px;min-width:18px;height:18px;display:flex;
    align-items:center;justify-content:center;padding:0 4px}
  .pos-mobilebar .lbl{flex:1;font-size:13px;font-weight:600}
  .pos-mobilebar .amt{font-size:14.5px;font-weight:800}
  .pos-mobilebar.hide{display:none}
}

.pos-item{padding:8px 0;border-bottom:1px solid var(--line)}
.pos-item:last-child{border-bottom:0}
.pos-item.void{opacity:.5;text-decoration:line-through}
.pos-item .row{display:flex;align-items:center;gap:10px}
.pos-item .nm{flex:1;font-size:13px;font-weight:600}
.pos-item .mods{margin-top:3px}
.pos-item .note-txt{font-size:11.5px;color:var(--muted);margin-top:2px}
.pos-item .qty{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600}
.pos-item .amt{font-size:13px;font-weight:700;min-width:76px;text-align:right}
.note-txt{font-size:11.5px;color:var(--muted)}

/* Sơ đồ bàn */
.pos-tablegrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px}
.pos-table{border:1px solid var(--hair,var(--line));border-radius:var(--r,14px);padding:14px 8px;text-align:center;
  background:var(--glass-2,rgb(var(--glass-rgb) / .7));cursor:pointer;transition:.15s}
.pos-table:hover{transform:translateY(-2px)}
.pos-table .nm{font-size:14px;font-weight:700}
.pos-table .sub{font-size:11px;color:var(--muted);margin-top:3px}
.pos-table.st-available{border-color:var(--g600)}
.pos-table.st-occupied{background:var(--red-l);border-color:var(--red)}
.pos-table.st-reserved{background:var(--orange-l);border-color:var(--orange)}
.pos-table.st-cleaning{background:rgba(0,0,0,.05);color:var(--muted)}
.pos-table.st-blocked{opacity:.5;cursor:not-allowed}

/* Kitchen Display System */
.pos-kds{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
.kds-ticket{border:1px solid var(--hair,var(--line));border-radius:var(--r,14px);padding:12px;
  background:var(--glass-2,rgb(var(--glass-rgb) / .85))}
.kds-ticket.warn{border-color:var(--orange);background:var(--orange-l)}
.kds-ticket.overdue{border-color:var(--red);background:var(--red-l)}
.kds-ticket .hd{display:flex;justify-content:space-between;font-size:11.5px;color:var(--muted);margin-bottom:6px}
.kds-ticket .nm{font-size:14px;font-weight:700;margin-bottom:4px}
.kds-ticket .ft{display:flex;justify-content:space-between;align-items:center;margin-top:8px}
.kds-ticket .mins{font-size:11.5px;color:var(--muted);font-weight:600}
@media (max-width:640px){ .fpscrim{padding:0} .fpanel{width:100%;max-width:none;min-width:0;max-height:100vh;height:100vh;border-radius:0} }


/* ═══════════════════════════════════════════════════════════════════════════
   v3.57.2 · BA LỖI BỐ CỤC NGƯỜI DÙNG BÁO
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · Ô chọn hiện hai lần: đã xử lý tận gốc trong assets/js/app.js —
   bản nâng cấp .ssel của v3.57.1 bị gỡ bỏ, chỉ còn .sk-* có từ v3.9. */

/* 2 · Nút thấp hơn hẳn ô chọn đứng cạnh trên thanh lọc.
   .inp cao ~40px (padding 9px + viền), .btn.sm chỉ ~31px nên nhìn lệch hẳn.
   Ép cùng một chiều cao cho mọi thứ nằm trên thanh lọc, kể cả ô có tìm kiếm. */
.filterbar .inp,
.filterbar select,
.filterbar .btn,
.filterbar .sk-box { min-height: var(--ctl-h); }
.filterbar .btn { padding-top: 0; padding-bottom: 0; justify-content: center; }
.filterbar .sk-wrap { display: block; }

/* Cùng một hàng thao tác ngoài thanh lọc (nút đứng cạnh ô nhập) cũng vậy */
.fr-inline { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.fr-inline .btn { min-height: var(--ctl-h); padding-top: 0; padding-bottom: 0; }

/* 3 · Dòng bảng bị lệch khi nội dung xuống dòng.
   .tbl-actions đặt display:flex ngay trên thẻ <td>. Ô bảng hoá thành hộp flex thì
   không còn giãn theo chiều cao của dòng nữa, nên khi một ô khác xuống 2–3 dòng,
   cụm nút bị đẩy lệch khỏi dòng của nó và các vạch kẻ so le — đúng như ảnh chụp.
   Trả <td> về đúng ô bảng, xếp nút bên trong bằng inline thay vì flex. */
td.tbl-actions {
  display: table-cell !important; vertical-align: middle; white-space: nowrap;
}
td.tbl-actions > * { vertical-align: middle; }
td.tbl-actions > form { display: inline-block; margin: 0; }
td.tbl-actions > * + * { margin-left: 6px; }
/* Ô chữ dài xuống dòng thì mọi ô trong dòng cùng canh giữa cho thẳng hàng */
table tbody td { vertical-align: middle; }

/* ═══════════════════════════════════════════════════════════════════════════
   v3.57.2 · NÚT PHẢI ĐỔI MÀU RÕ KHI RÊ CHUỘT

   Trạng thái hover cũ chỉ đậm/nhạt đi một chút (.btn.sec đổi từ trắng sang
   #F3F5F4) — trên màn hình sáng gần như không thấy, người dùng không biết mình
   đang trỏ vào nút nào, nhất là ở cột thao tác có 2–3 nút sát nhau. Nay mỗi
   loại nút đổi hẳn sang một sắc độ khác kèm nhấc nhẹ lên, và dùng màu theo
   đúng ý nghĩa của nút (xanh = thường, đỏ = xoá, cam = cảnh báo).
   ═══════════════════════════════════════════════════════════════════════════ */
.btn { transition: background .15s, border-color .15s, color .15s, box-shadow .15s, transform .12s; }

/* Nút chính */
.btn:hover { background: var(--g800, #14532d); box-shadow: 0 4px 12px -4px rgba(20,83,45,.45); transform: translateY(-1px); }
.btn:active { transform: translateY(0); box-shadow: none; }

/* Nút phụ (viền trắng) — loại hay bị "không thấy gì thay đổi" nhất */
.btn.sec:hover {
  background: var(--g100, #E8F4EC);
  border-color: var(--g600, #16A35F);
  color: var(--g800, #14532d);
  box-shadow: 0 3px 10px -4px rgba(22,163,95,.5);
}

/* Nút nguy hiểm và cảnh báo giữ đúng màu ý nghĩa khi rê chuột */
.btn.dan:hover  { background: #9E2414; box-shadow: 0 4px 12px -4px rgba(158,36,20,.5); }
.btn.warn:hover { background: #B96F08; box-shadow: 0 4px 12px -4px rgba(185,111,8,.5); }
.btn.gho:hover  { background: var(--g100, #E8F4EC); border-color: var(--g700, #166534); }
.btn[disabled]:hover, .btn:disabled:hover { background: inherit; transform: none; box-shadow: none; }

/* Dòng bảng đang trỏ tới cũng sáng lên, để biết nút mình sắp bấm thuộc dòng nào */
table tbody tr:hover { background: var(--bg2, #F7FAF8); }

/* Thiết bị cảm ứng không có "rê chuột" — bỏ hiệu ứng nhấc lên để không bị kẹt
   trạng thái hover sau khi chạm. */
@media (hover: none) {
  .btn:hover, .btn.sec:hover { transform: none; box-shadow: none; }
}

/* ═══ v3.57.2 · Ma trận phân quyền (views/roles.php) ═══
   Bảng rộng và dài: cột đầu (tên quyền) phải ghim lại khi cuộn ngang, nếu không
   tick tới cột thứ tư là không còn biết mình đang tick quyền nào. Ô tick to hơn
   mặc định cho dễ bấm trên điện thoại. */
.mxtbl th:first-child, .mxtbl td:first-child {
  position: sticky; left: 0; z-index: 2; background: var(--surface);
  box-shadow: 1px 0 0 var(--line);
}
.mxtbl thead th { position: sticky; top: 0; z-index: 3; background: var(--surface); }
.mxtbl thead th:first-child { z-index: 4; }
.mxtbl tr.mx-group td { background: var(--bg2, var(--surface-2)); font-size: 12.5px; }
.mxtbl tr.mx-group td:first-child { background: var(--bg2, var(--surface-2)); }
.mxtbl input[type=checkbox] { width: 17px; height: 17px; cursor: pointer; accent-color: var(--g600, #16A35F); }
.mxtbl input[type=checkbox]:disabled { cursor: not-allowed; opacity: .5; }
.mxtbl tbody tr:hover td { background: var(--g100, var(--ok-bg)); }
.mxtbl tbody tr:hover td:first-child { background: var(--g100, var(--ok-bg)); }
@media (max-width:620px){ .mxtbl th:first-child, .mxtbl td:first-child { min-width: 170px; } }

/* ═══════════════════════════════════════════════════════════════════════════
   v3.58 · THANH CÔNG CỤ CHUẨN (assets/js/toolbar.js)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Chỗ trống ở đầu trang, nơi trước đây là nhãn định vị GPS */
.pagetools { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
.pagetools .btn { padding-top: 7px; padding-bottom: 7px; font-size: 12.5px; white-space: nowrap; }
.pagetools .cv { font-size: 10px; opacity: .8; margin-left: 2px; }
@media (max-width: 900px) {
  /* Trên điện thoại chỉ giữ chữ ngắn để không đẩy chuông thông báo ra ngoài màn hình */
  .pagetools .btn { padding-left: 9px; padding-right: 9px; }
}

/* Menu xổ của nút Nhập / Xuất — gắn thẳng vào <body> nên không bị khung cha cắt */
.tbdrop { position: relative; }
.tbmenu {
  position: fixed; z-index: 9999; min-width: 226px; padding: 5px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 14px 34px -12px rgba(20, 40, 30, .3);
}
.tbitem {
  display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left;
  padding: 8px 10px; border: 0; background: transparent; border-radius: 8px; cursor: pointer;
  font: inherit; color: var(--ink);
}
.tbitem b { font-size: 13px; font-weight: 600; }
.tbitem .hint { font-size: 11px; }
.tbitem:hover { background: var(--g100, var(--ok-bg)); }
.tbsep { height: 1px; background: var(--line); margin: 4px 6px; }

/* Nút thu gọn của từng khối */
.card > .hd { position: relative; }
.cardtog {
  margin-left: auto; flex: 0 0 auto; width: 28px; height: 28px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 8px; background: transparent; cursor: pointer;
  color: var(--muted); transition: .15s;
}
.cardtog svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2.2;
               stroke-linecap: round; stroke-linejoin: round; transition: transform .18s; }
.cardtog:hover { background: var(--g100, var(--ok-bg)); color: var(--g800, #14532d); border-color: var(--line); }
.card.collapsed > .hd > .cardtog svg { transform: rotate(-90deg); }
.card.collapsed { padding-bottom: 0; }
.card.collapsed > .hd { border-bottom: 0; }

/* Thanh "thu gọn tất cả" ở đầu trang */
.collapsebar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.collapsebar .hint { margin-left: 2px; }

/* Dải nút lọc nhanh theo khoảng thời gian */
.rangebar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; width: 100%; margin-bottom: 4px; }
.rangebar .hint { margin-right: 2px; }
.rchip {
  padding: 5px 11px; border-radius: 99px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink2); font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.rchip:hover { background: var(--g100, var(--ok-bg)); border-color: var(--g600, #16A35F); color: var(--g800, #14532d); }
.rchip.on { background: var(--g700, #166534); border-color: var(--g700, #166534); color: var(--on-accent); }

/* Nút gập của khối không có thanh tiêu đề — thả nổi ở góc trên phải của chính khối đó */
.cardtog.float { position: absolute; top: 8px; right: 8px; z-index: 4;
                 background: rgb(var(--glass-rgb) / .9); border-color: var(--line); }

/* v3.58 · Bảng nhiều cột: thà cuộn ngang còn hơn bóp cột xuống mỗi dòng một chữ cái.
   .tblwrap vốn đã cuộn ngang được, nhưng table width:100% ép bảng co vào bằng mọi giá. */
.tblwrap > table { width: 100%; }

/* v3.59 · Khối không tiêu đề khi gập: giữ một dải có tên và chỗ cho nút mở lại */
.card.nohd.collapsed { min-height: 46px; padding: 0; }
.card.nohd.collapsed::before { content: attr(data-stub); display: block; padding: 13px 52px 13px 16px;
  font-size: 12.5px; font-weight: 600; color: var(--muted); }
.card.nohd .cardtog.float { top: 9px; right: 9px; }
/* Ô chữ dài: xuống dòng trong khung giới hạn thay vì kéo dài bảng */
.cellclamp { white-space: normal; overflow-wrap: break-word; line-height: 1.45; }/* Thuộc tính hidden thua các luật display (.filterbar{display:flex}…) nên phần thân không ẩn
   được — ép ẩn bằng chính trạng thái collapsed của khối. */
.card.collapsed > :not(.hd):not(.cardtog) { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   v3.59 · THANH TRÊN CÙNG HAI TẦNG + CỬA SỔ TẠO NHANH
   ═══════════════════════════════════════════════════════════════════════════ */
.top.top2 { display: flex; flex-direction: column; align-items: stretch; gap: 10px; padding: 10px 22px 12px; }
.top2 .toprow { display: flex; align-items: center; gap: 10px; min-width: 0; }
.top2 .toprow2 { flex-wrap: wrap; gap: 8px 14px; }
.top2 .toprow2 .ttl { flex: 1 1 260px; min-width: 0; }
.top2 .toprow2 .right { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.top2 .globalsearch { flex: 1 1 420px; max-width: 560px; margin: 0; }

.topicons { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.ticon { position: relative; width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center;
         border-radius: 10px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer;
         transition: background .15s, border-color .15s, color .15s; text-decoration: none; padding: 0; }
.ticon svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ticon:hover, .ticon.on { background: var(--g100, var(--ok-bg)); border-color: var(--g600, #16A35F); color: var(--g800, #14532d); }
.ticon.tprimary { background: var(--g700, #166534); border-color: var(--g700, #166534); color: var(--on-accent); }
.ticon.tprimary:hover { background: var(--g800, #14532d); }
.ticon.bell i { position: absolute; top: -6px; right: -6px; }
.tuser { display: inline-flex; align-items: center; gap: 8px; padding: 3px 12px 3px 3px; border: 1px solid var(--line);
         border-radius: 99px; background: var(--surface); text-decoration: none; color: var(--ink); max-width: 200px; }
.tuser:hover { border-color: var(--g600, #16A35F); background: var(--g100, var(--ok-bg)); }
.tuser img, .tuser .tav { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; flex: 0 0 30px; }
.tuser .tav { display: inline-flex; align-items: center; justify-content: center; background: var(--g100, var(--ok-bg));
              color: var(--g800, #14532d); font-size: 11.5px; font-weight: 700; }
.tuser .tname { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 900px) {
  .top.top2 { padding: 8px 12px 10px; gap: 8px; }
  .top2 .globalsearch { flex: 0 0 auto; }
  .topicons { gap: 4px; }
  .ticon { width: 34px; height: 34px; }
  .tuser .tname { display: none; }
  .tuser { padding: 2px; }
}
@media (max-width: 480px) {
  .topicons .ticon:not(.tprimary):not(.bell) { display: none; }
}

/* Cửa sổ Tạo nhanh */
.qcveil { position: fixed; inset: 0; z-index: 300; background: rgba(15, 30, 22, .42);
          -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
          display: flex; align-items: flex-start; justify-content: center; padding: 4vh 16px; }
.qcveil[hidden] { display: none; }
.qcbox { width: 100%; max-width: 1180px; max-height: 92vh; display: flex; flex-direction: column; background: var(--surface);
         border-radius: 16px; box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .35); overflow: hidden; }
.qchead { display: flex; align-items: center; gap: 14px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.qchead h2 { margin: 0; font-size: 20px; font-weight: 700; white-space: nowrap; }
.qcsearch { margin-left: auto; display: flex; align-items: center; gap: 8px; border: 1px solid var(--line); border-radius: 10px;
            padding: 0 12px; width: min(420px, 100%); height: 40px; }
.qcsearch input { flex: 1; border: 0; outline: 0; font: inherit; font-size: 14px; background: none; }
.qcsearch:focus-within { border-color: var(--g600, #16A35F); box-shadow: 0 0 0 3px var(--g100, #EEF7F0); }
.qcclose { border: 0; background: none; font-size: 28px; line-height: 1; color: var(--muted); cursor: pointer; padding: 0 4px; }
.qcclose:hover { color: var(--ink); }
.qcgrid { padding: 18px 20px 22px; overflow-y: auto; columns: 4 240px; column-gap: 16px; }
.qccol { break-inside: avoid; border: 1px solid var(--line); border-radius: 12px; margin-bottom: 16px; overflow: hidden; }
.qccol[hidden] { display: none; }
.qccol h3 { margin: 0; padding: 11px 14px; font-size: 15px; font-weight: 700; background: var(--bg2, var(--surface-2));
            border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 8px; }
.qccol a { display: flex; align-items: center; gap: 9px; padding: 9px 14px; font-size: 13.5px; color: var(--ink);
           text-decoration: none; border-bottom: 1px solid var(--line); transition: background .12s, color .12s; }
.qccol a:last-child { border-bottom: 0; }
.qccol a[hidden] { display: none; }
.qccol a:hover { background: var(--g100, var(--ok-bg)); color: var(--g800, #14532d); }
.qccol a svg.i { opacity: .7; flex: 0 0 auto; }
.qcempty { padding: 30px; text-align: center; color: var(--muted); column-span: all; }
@media (max-width: 640px) {
  .qcveil { padding: 0; }
  .qcbox { max-height: 100vh; height: 100vh; border-radius: 0; }
  .qchead { flex-wrap: wrap; }
  .qcsearch { order: 3; width: 100%; margin: 0; }
}

/* v3.60 · Nút Lịch trên cùng: có mục sắp tới thì nổi bật, sắp đến giờ (≤ 60 phút) thì nhấp nháy nhẹ */
.ticon.tcal i { position: absolute; top: -7px; right: -7px; min-width: 19px; height: 19px; padding: 0 5px; border-radius: 99px;
                background: #2563eb; color: var(--on-accent); font-style: normal; font-size: 10.5px; font-weight: 700; line-height: 19px;
                text-align: center; box-shadow: 0 0 0 2px #fff; }
.ticon.tcal.has { border-color: #93c5fd; color: #1d4ed8; background: var(--info-bg-soft); }
.ticon.tcal.hot { border-color: #f97316; color: #c2410c; background: var(--warn-bg); animation: tcalPulse 1.8s ease-out infinite; }
.ticon.tcal.hot i { background: #ea580c; }
@keyframes tcalPulse { 0% { box-shadow: 0 0 0 0 rgba(249,115,22,.55); } 70% { box-shadow: 0 0 0 9px rgba(249,115,22,0); } 100% { box-shadow: 0 0 0 0 rgba(249,115,22,0); } }
@media (prefers-reduced-motion: reduce) { .ticon.tcal.hot { animation: none; } }
/* ═══ v3.61 · Dải tab nhóm một hàng + menu "Thêm" + ghim ═══ */
@media (min-width: 901px) {
  .gnwrap { flex-wrap: nowrap; overflow: hidden; align-items: center; }
  .gnwrap .gntab { flex: 0 0 auto; white-space: nowrap; }
  .gnwrap.gnmeasure .gntab { visibility: visible; }
  .gnwrap .gntab[hidden] { display: none; }
}
.gnmore { margin-left: auto; flex: 0 0 auto; }
.gnmore[hidden] { display: none; }
.gnmorebtn { border: 1px dashed var(--line); background: transparent; cursor: pointer; font: inherit; }
.gnmorebtn .cnt:not(:empty) { display: inline-flex; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 99px;
  background: var(--g100, var(--ok-bg)); color: var(--g800, #14532d); font-size: 11px; align-items: center; justify-content: center; }
.gntab.pinned:not(.on) span::after { content: ' ★'; color: #d97706; font-size: 10px; }
.gnmenu { position: fixed; z-index: 9999; width: 280px; max-height: 70vh; overflow-y: auto; background: var(--surface);
  border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 16px 40px -14px rgba(20,40,30,.3); padding: 6px; }
.gnmenu[hidden] { display: none; }
.gnmh { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding: 8px 10px 4px; }
.gnmi, .gnpin { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; border-radius: 8px; border: 0;
  background: none; font: inherit; font-size: 13px; color: var(--ink); text-decoration: none; cursor: pointer; text-align: left; }
.gnmi:hover, .gnpin:hover { background: var(--g100, var(--ok-bg)); }
.gnmi svg.i { width: 15px; height: 15px; opacity: .75; }
.gnpin .star { width: 16px; color: var(--muted); }
.gnpin.on .star { color: #d97706; }
/* ═══════════════════════════════════════════════════════════════════════════
   v3.62 · CHẾ ĐỘ TỐI
   Khai lại đúng bộ biến màu — các màn hình không phải sửa gì. Áp dụng khi:
     · người dùng chọn Tối            → <html data-theme="dark">
     · chọn Theo thiết bị và máy tối   → <html data-theme="auto"> + prefers-color-scheme: dark
   Trang in và trang công khai (khảo sát, link ngắn, phiếu in) không dùng layout này nên giữ nền sáng.
   ═══════════════════════════════════════════════════════════════════════════ */
html[data-theme="dark"] {
  color-scheme: dark;
  /* nền & chữ */
  --bg:#0e1411; --ink:#e4ece7; --ink2:#b1c0b7; --muted:#859489;
  --line:rgba(170,210,190,.13); --hair:rgba(255,255,255,.05);
  /* kính mờ */
  --glass-rgb: 24 32 28;
  --glass:rgba(22,30,26,.82); --glass-2:rgba(26,35,30,.92); --glass-side:rgba(17,24,21,.86); --card:var(--glass);
  /* bề mặt ngữ nghĩa */
  --surface:#18201c; --surface-2:#1e2823; --surface-3:#1a221e; --on-accent:#ffffff;
  --ok-bg:#132a1c; --ok-bg-strong:#18372a;
  --warn-bg:#2c220f; --warn-bg-strong:#3d2f12;
  --danger-bg:#2f1714; --danger-bg-strong:#43201b;
  --info-bg:#18233a; --info-bg-soft:#172440;
  --danger-ink:#ff9d88; --ink-soft:#a3b3aa; --ink-green:#7fdca6; --warn-ink:#f3b25d;
  /* dải màu thương hiệu: tông nhạt (dùng làm nền) chuyển sang tối, tông đậm (dùng làm chữ) chuyển sang sáng */
  --br-50:#122519; --br-100:#15301f; --br-200:#1d4029;
  --lf-50:#122519; --lf-100:#15301f; --lf-200:#1d4029;
  --br-700:#5bc98a; --br-900:#9ee6bb; --lf-700:#5bc98a; --lf-900:#9ee6bb;
  --red-l:#3a1a16; --orange-l:#33240f; --accent-blue-l:#172440; --accent-orange-l:#33240f;
  --navy-d:#0b1210;
  /* bóng đổ: trên nền tối dùng đen đặc hơn */
  --sh-xs:0 1px 2px rgba(0,0,0,.35);
  --sh:0 1px 2px rgba(0,0,0,.3), 0 10px 28px -14px rgba(0,0,0,.6);
  --sh-lift:0 1px 2px rgba(0,0,0,.35), 0 18px 40px -16px rgba(0,0,0,.7);
}
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] {
  color-scheme: dark;
  /* nền & chữ */
  --bg:#0e1411; --ink:#e4ece7; --ink2:#b1c0b7; --muted:#859489;
  --line:rgba(170,210,190,.13); --hair:rgba(255,255,255,.05);
  /* kính mờ */
  --glass-rgb: 24 32 28;
  --glass:rgba(22,30,26,.82); --glass-2:rgba(26,35,30,.92); --glass-side:rgba(17,24,21,.86); --card:var(--glass);
  /* bề mặt ngữ nghĩa */
  --surface:#18201c; --surface-2:#1e2823; --surface-3:#1a221e; --on-accent:#ffffff;
  --ok-bg:#132a1c; --ok-bg-strong:#18372a;
  --warn-bg:#2c220f; --warn-bg-strong:#3d2f12;
  --danger-bg:#2f1714; --danger-bg-strong:#43201b;
  --info-bg:#18233a; --info-bg-soft:#172440;
  --danger-ink:#ff9d88; --ink-soft:#a3b3aa; --ink-green:#7fdca6; --warn-ink:#f3b25d;
  /* dải màu thương hiệu: tông nhạt (dùng làm nền) chuyển sang tối, tông đậm (dùng làm chữ) chuyển sang sáng */
  --br-50:#122519; --br-100:#15301f; --br-200:#1d4029;
  --lf-50:#122519; --lf-100:#15301f; --lf-200:#1d4029;
  --br-700:#5bc98a; --br-900:#9ee6bb; --lf-700:#5bc98a; --lf-900:#9ee6bb;
  --red-l:#3a1a16; --orange-l:#33240f; --accent-blue-l:#172440; --accent-orange-l:#33240f;
  --navy-d:#0b1210;
  /* bóng đổ: trên nền tối dùng đen đặc hơn */
  --sh-xs:0 1px 2px rgba(0,0,0,.35);
  --sh:0 1px 2px rgba(0,0,0,.3), 0 10px 28px -14px rgba(0,0,0,.6);
  --sh-lift:0 1px 2px rgba(0,0,0,.35), 0 18px 40px -16px rgba(0,0,0,.7);
  }
}
html[data-theme="dark"] body { background-image: radial-gradient(62rem 44rem at 92% -12%, rgba(38,168,96,.08), transparent 60%) !important; }
html[data-theme="dark"] img:not([src$=".svg"]) { filter: brightness(.94); }
html[data-theme="dark"] .inp, html[data-theme="dark"] select.inp, html[data-theme="dark"] textarea.inp { background: var(--surface) !important; color: var(--ink); }
html[data-theme="dark"] .inp::placeholder { color: var(--muted); }
html[data-theme="dark"] .btn.sec { background: var(--surface); color: var(--ink); border-color: var(--line); }
html[data-theme="dark"] .btn.sec:hover { background: var(--ok-bg); color: var(--ink-green); }
html[data-theme="dark"] table thead th { color: var(--ink2); }
html[data-theme="dark"] tbody tr:hover, html[data-theme="dark"] table tbody tr:hover { background: rgba(255,255,255,.03); }
html[data-theme="dark"] .pill.p-s, html[data-theme="dark"] .pill.s { background: #26302b; color: var(--ink2); }
html[data-theme="dark"] .pill.p-n { background: #1b2740; color: #a9c1ee; }
html[data-theme="dark"] .pill.p-o { background: #3a2a12; color: #f5c27a; }
html[data-theme="dark"] .pill.p-r { background: #3f1c17; color: #ff9d88; }
html[data-theme="dark"] .pill.p-g { background: #15331f; color: #7fdca6; }
html[data-theme="dark"] .note.i { background: #172440; color: #b9cdf2; }
html[data-theme="dark"] .note.w { background: #33260f; color: #f3cf8d; }
html[data-theme="dark"] .note.d { background: #3a1a16; color: #ffb3a3; }
html[data-theme="dark"] .note.s { background: #15301f; color: #9ee6bb; }
html[data-theme="dark"] .sk-panel, html[data-theme="dark"] .tbmenu, html[data-theme="dark"] .gnmenu, html[data-theme="dark"] .qcbox, html[data-theme="dark"] .evbox, html[data-theme="dark"] .gsdrop { background: var(--surface-2) !important; border-color: var(--line) !important; }
html[data-theme="dark"] .cardtog:hover, html[data-theme="dark"] .ticon:hover { background: var(--ok-bg); }
html[data-theme="dark"] .tuser, html[data-theme="dark"] .ticon { background: var(--surface); }
html[data-theme="dark"] .ticon.tcal.has { background: #172440; border-color: #2f4f86; color: #9dbcf5; }
html[data-theme="dark"] .ticon.tcal.hot { background: #3a2410; border-color: #b85f18; color: #f8b36a; }
html[data-theme="dark"] code, html[data-theme="dark"] .mono { color: var(--ink2); }
html[data-theme="dark"] hr { border-color: var(--line); }
html[data-theme="dark"] ::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); }
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] body { background-image: radial-gradient(62rem 44rem at 92% -12%, rgba(38,168,96,.08), transparent 60%) !important; }
  html[data-theme="auto"] img:not([src$=".svg"]) { filter: brightness(.94); }
  html[data-theme="auto"] .inp, html[data-theme="auto"] select.inp, html[data-theme="auto"] textarea.inp { background: var(--surface) !important; color: var(--ink); }
  html[data-theme="auto"] .inp::placeholder { color: var(--muted); }
  html[data-theme="auto"] .btn.sec { background: var(--surface); color: var(--ink); border-color: var(--line); }
  html[data-theme="auto"] .btn.sec:hover { background: var(--ok-bg); color: var(--ink-green); }
  html[data-theme="auto"] table thead th { color: var(--ink2); }
  html[data-theme="auto"] tbody tr:hover, html[data-theme="auto"] table tbody tr:hover { background: rgba(255,255,255,.03); }
  html[data-theme="auto"] .pill.p-s, html[data-theme="auto"] .pill.s { background: #26302b; color: var(--ink2); }
  html[data-theme="auto"] .pill.p-n { background: #1b2740; color: #a9c1ee; }
  html[data-theme="auto"] .pill.p-o { background: #3a2a12; color: #f5c27a; }
  html[data-theme="auto"] .pill.p-r { background: #3f1c17; color: #ff9d88; }
  html[data-theme="auto"] .pill.p-g { background: #15331f; color: #7fdca6; }
  html[data-theme="auto"] .note.i { background: #172440; color: #b9cdf2; }
  html[data-theme="auto"] .note.w { background: #33260f; color: #f3cf8d; }
  html[data-theme="auto"] .note.d { background: #3a1a16; color: #ffb3a3; }
  html[data-theme="auto"] .note.s { background: #15301f; color: #9ee6bb; }
  html[data-theme="auto"] .sk-panel, html[data-theme="auto"] .tbmenu, html[data-theme="auto"] .gnmenu, html[data-theme="auto"] .qcbox, html[data-theme="auto"] .evbox, html[data-theme="auto"] .gsdrop { background: var(--surface-2) !important; border-color: var(--line) !important; }
  html[data-theme="auto"] .cardtog:hover, html[data-theme="auto"] .ticon:hover { background: var(--ok-bg); }
  html[data-theme="auto"] .tuser, html[data-theme="auto"] .ticon { background: var(--surface); }
  html[data-theme="auto"] .ticon.tcal.has { background: #172440; border-color: #2f4f86; color: #9dbcf5; }
  html[data-theme="auto"] .ticon.tcal.hot { background: #3a2410; border-color: #b85f18; color: #f8b36a; }
  html[data-theme="auto"] code, html[data-theme="auto"] .mono { color: var(--ink2); }
  html[data-theme="auto"] hr { border-color: var(--line); }
  html[data-theme="auto"] ::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); }
}
@media print { html[data-theme] { color-scheme: light; } }
/* Nút chọn giao diện */
.themepick { position: relative; }
.thmenu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 400; min-width: 190px; padding: 5px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--line); box-shadow: var(--sh-lift); }
.thmenu[hidden] { display: none; }
.thmenu button { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; border: 0; background: none;
  border-radius: 8px; font: inherit; font-size: 13px; color: var(--ink); cursor: pointer; text-align: left; }
.thmenu button:hover { background: var(--ok-bg); }
.thmenu button.on { font-weight: 700; color: var(--ink-green); }
.thmenu button.on::after { content: '✓'; margin-left: auto; }

/* v3.62 · Các chi tiết trang trí còn màu nền sáng cố định */
html[data-theme="dark"] .kpi-deco { background: rgba(255,255,255,.07) !important; }
html[data-theme="dark"] .streak-row-cta { background: var(--danger-bg) !important; }
html[data-theme="dark"] .streak-row { background: var(--surface-2) !important; }
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] .kpi-deco { background: rgba(255,255,255,.07) !important; }
  html[data-theme="auto"] .streak-row-cta { background: var(--danger-bg) !important; }
  html[data-theme="auto"] .streak-row { background: var(--surface-2) !important; }
}

/* ═══ v3.63 · Thanh trên cùng một dòng ═══ */
.top.top2 { flex-direction: row; align-items: center; gap: 12px; padding: 9px 18px; min-height: 58px; }
.top2 .toprow { flex: 1 1 auto; gap: 10px; flex-wrap: nowrap; }
.top2 .ttl { flex: 0 1 auto; min-width: 120px; max-width: 32vw; overflow: hidden; }
.top2 .ttl h1 { font-size: 17px; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top2 .ttl .sub { font-size: 11.5px; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Ô tìm kiếm gọn, bấm vào mới giãn ra */
.top2 .globalsearch { flex: 0 1 230px; width: 230px; max-width: 230px; transition: max-width .2s ease, flex-basis .2s ease; }
.top2 .globalsearch:focus-within { flex-basis: 420px; max-width: 420px; }
.top2 .pageright { margin-left: auto; flex: 0 1 auto; flex-wrap: nowrap; gap: 6px; min-width: 0; }
.top2 .pageright .btn { white-space: nowrap; }
.top2 .topicons { margin-left: 4px; flex: 0 0 auto; }
@media (max-width: 1280px) {
  .top2 .ttl .sub { display: none; }
  .top2 .globalsearch { flex-basis: 180px; max-width: 180px; }
}
@media (max-width: 900px) {
  .top.top2 { flex-wrap: wrap; padding: 8px 12px; }
  .top2 .toprow { flex-wrap: wrap; }
  .top2 .ttl { max-width: none; flex: 1 1 140px; }
  .top2 .globalsearch, .top2 .globalsearch:focus-within { flex-basis: auto; max-width: none; width: auto; }
  .top2 .pageright { order: 9; width: 100%; justify-content: flex-end; flex-wrap: wrap; }
}
/* ═══ v3.64 · Thanh trên cùng gọn hơn · dải tab nhỏ hơn ═══ */
.pagetools .tbicon { width: 36px; height: 36px; }
.pagetools .tbicon svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pagetools { gap: 4px; }
.tuser { max-width: 150px; padding-right: 10px; }
.tuser .tname { font-size: 12.5px; }

/* Dải tab nhóm: chữ và khoảng đệm nhỏ lại để một hàng hiện được nhiều tab hơn */
@media (min-width: 901px) {
  .gnwrap { gap: 3px; padding-bottom: 8px; }
  .gntab { padding: 6px 10px; font-size: 12.5px; gap: 6px; border-radius: 9px; }
  .gntab svg.i { width: 13px; height: 13px; }
  .gnback { font-size: 12px; }
}
/* Menu "Thêm": có vùng đệm trong suốt phía trên nối với nút, rê chuột từ nút xuống không bị hụt */
.gnmenu::before { content: ''; position: absolute; left: 0; right: 0; top: -8px; height: 8px; }
.gnmenu { overscroll-behavior: contain; }
/* ═══════════════════════════════════════════════════════════════════════════
   v3.65 · FILTER ENGINE — thanh lọc dùng chung cho mọi danh sách
   Không dựng hệ thiết kế riêng: dùng lại .card/.btn/.inp và bộ biến màu sẵn có,
   nên tự động đúng cả ở chế độ tối mà không phải khai lại lần hai.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Chip điều kiện đang áp */
.fb-chips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  border-top: 1px dashed var(--line); padding-top: 10px; }
.fchip { display: inline-flex; align-items: center; gap: 7px; padding: 4px 6px 4px 10px;
  border-radius: 8px; font-size: 12.5px; background: var(--ok-bg); color: var(--ink-green);
  border: 1px solid var(--ok-bg-strong); }
.fchip.grp { background: var(--info-bg-soft); color: var(--ink2); border-color: var(--info-bg); }
.fchip b { font-weight: 600; }
.fchip > a { display: inline-flex; width: 17px; height: 17px; align-items: center; justify-content: center;
  border-radius: 5px; font-size: 14px; line-height: 1; color: inherit; opacity: .6; }
.fchip > a:hover { opacity: 1; background: rgb(0 0 0 / .07); }
.fclear { font-size: 12.5px; color: var(--muted); text-decoration: underline; margin-left: 2px; }

/* Tiêu đề cột bấm được để sắp xếp */
a.fsort { display: inline-flex; gap: 3px; align-items: center; color: inherit; }
a.fsort:hover { color: var(--g700); }
a.fsort.on { color: var(--g700); font-weight: 700; }

/* Phân trang */
.fpager { display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  padding: 11px 15px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--muted); }
.fp-info { font-variant-numeric: tabular-nums; }
.fp-per { display: flex; gap: 5px; align-items: center; }
.fp-per a, .fp-per b { padding: 2px 7px; border-radius: 6px; }
.fp-per a { color: var(--muted); }
.fp-per a:hover { background: var(--surface-2); color: var(--ink); }
.fp-per b { background: var(--surface-2); color: var(--ink); }
.fp-nav { margin-left: auto; display: flex; gap: 3px; align-items: center; }
.fp-nav a, .fp-nav b, .fp-nav .off { min-width: 30px; text-align: center; padding: 5px 8px; border-radius: 7px; }
.fp-nav a { color: var(--ink2); border: 1px solid var(--line); }
.fp-nav a:hover { border-color: var(--g500); color: var(--g700); }
.fp-nav b { background: var(--g600); color: var(--on-accent); }
.fp-nav .off { color: var(--muted); opacity: .55; }

/* Không có dữ liệu — luôn nói rõ nên làm gì tiếp */
.fempty { padding: 40px 20px; text-align: center; color: var(--muted); }
.fempty .fe-t { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.fempty ul { display: inline-block; text-align: left; margin: 6px 0 14px; padding-left: 18px; font-size: 13px; }
.fempty li { margin: 2px 0; }

/* ── Cửa sổ bộ lọc / chọn cột / sắp xếp ───────────────────────────────────── */
.fmodal { position: fixed; inset: 0; z-index: 120; display: flex; align-items: center; justify-content: center;
  background: rgb(15 23 42 / .42); padding: 20px; }
.fmodal[hidden] { display: none; }
.fm-box { background: var(--surface); border-radius: 14px; box-shadow: 0 18px 48px rgb(16 24 40 / .22);
  width: 100%; max-width: 660px; max-height: 88vh; display: flex; flex-direction: column; }
.fm-hd { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.fm-hd h3 { font-size: 15px; font-weight: 700; flex: 1; }
.fm-x { width: 30px; height: 30px; border-radius: 8px; border: 0; background: transparent; cursor: pointer;
  font-size: 19px; line-height: 1; color: var(--muted); }
.fm-x:hover { background: var(--surface-2); color: var(--ink); }
.fm-bd { padding: 14px 16px; overflow: auto; flex: 1; }
.fm-ft { display: flex; gap: 8px; align-items: center; padding: 12px 16px; border-top: 1px solid var(--line); }
.fm-ft .grow { margin-left: auto; display: flex; gap: 8px; }

/* Một dòng điều kiện: Trường · Toán tử · Giá trị · xoá */
.fcond { display: grid; grid-template-columns: 1fr 1fr 1.2fr auto; gap: 7px; align-items: center; margin-bottom: 7px; }
.fcond .inp { padding: 7px 9px; font-size: 13px; }
.fcond .fc-del { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); cursor: pointer; color: var(--muted); font-size: 15px; line-height: 1; }
.fcond .fc-del:hover { border-color: var(--red); color: var(--red); }
.fc-val2 { display: flex; gap: 5px; align-items: center; }
.fc-val2 .inp { min-width: 0; }

.fgroup { border: 1px solid var(--line); border-radius: 10px; padding: 10px; margin: 8px 0; background: var(--surface-3); }
.fgroup > .fg-hd { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; font-size: 12.5px; color: var(--muted); }
.flogic { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.flogic button { border: 0; background: var(--surface); padding: 4px 12px; font-size: 12.5px; cursor: pointer; color: var(--ink2); }
.flogic button.on { background: var(--g600); color: var(--on-accent); font-weight: 600; }

/* Chọn cột — kéo thả đổi thứ tự */
.fcols { display: flex; flex-direction: column; gap: 2px; }
.fcol { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 8px; }
.fcol:hover { background: var(--surface-2); }
.fcol.drag { opacity: .45; }
.fcol .fc-grip { color: var(--muted); font-size: 13px; cursor: grab; }
.fcol label { flex: 1; font-size: 13px; cursor: pointer; }

/* Điện thoại: cửa sổ trượt lên từ đáy, ngón tay với tới được nút Áp dụng */
@media (max-width: 720px) {
  .fmodal { padding: 0; align-items: flex-end; }
  .fm-box { max-width: none; max-height: 92vh; border-radius: 16px 16px 0 0; }
  .fcond { grid-template-columns: 1fr auto; grid-template-areas: "f d" "o o" "v v";
    border: 1px solid var(--line); border-radius: 10px; padding: 9px; margin-bottom: 9px; }
  .fcond > *:nth-child(1) { grid-area: f; }
  .fcond > *:nth-child(2) { grid-area: o; }
  .fcond > *:nth-child(3) { grid-area: v; }
  .fcond > .fc-del { grid-area: d; }
  .cb-search { width: 100%; }
  .cb-search:focus-within { width: 100%; }
  .cb-tools { margin-left: 0; width: 100%; }
  .cb-drop { width: calc(100vw - 32px); }
  .fpager { gap: 9px; }
  .fp-nav { margin-left: 0; width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   v3.66 · THANH LỆNH DANH SÁCH — bố cục theo Microsoft Dynamics 365
   Một hàng duy nhất: bộ chọn View (đóng vai tiêu đề) + nút lệnh. Dải tab nhóm,
   hàng lọc nhanh và hàng "Thu gọn tất cả" đều đã gộp vào đây.
   ═══════════════════════════════════════════════════════════════════════════ */

/* z-index 30: thẻ .card dùng backdrop-filter nên MỖI thẻ tự tạo một ngữ cảnh xếp lớp
   riêng — không có dòng này, menu xổ xuống của thanh lệnh luôn bị thẻ bảng bên dưới
   vẽ đè lên, dù bản thân menu đã đặt z-index rất cao. */
.cmdbar { position: relative; z-index: 30; margin: 0 0 10px; }
.cmdbar.menuopen { z-index: 140; }

.cb-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-height: 38px; }

/* ── Bộ chọn View: chữ lớn, đóng vai tiêu đề của danh sách ── */
.cb-view { position: relative; flex: none; }
.cb-viewbtn { display: inline-flex; align-items: center; gap: 6px; border: 0; cursor: pointer;
  background: transparent; padding: 3px 8px 3px 2px; border-radius: 8px; color: var(--ink); }
.cb-viewbtn:hover { background: var(--surface-2); }
.cb-vname { font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; }
.cb-chev { width: 15px; height: 15px; color: var(--muted); }
.cb-view.open .cb-chev { transform: rotate(180deg); }

.cb-drop { position: absolute; z-index: 60; top: calc(100% + 5px); left: 0; width: 330px; display: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 14px 40px rgb(16 24 40 / .17); overflow: hidden; }
.cb-view.open .cb-drop { display: block; }

.cb-find { display: flex; align-items: center; gap: 7px; padding: 9px 11px; border-bottom: 1px solid var(--line); }
.cb-find svg.i { width: 14px; height: 14px; color: var(--muted); flex: none; }
.cb-findinp { flex: 1; min-width: 0; border: 0; background: transparent; font-size: 13px; color: var(--ink); outline: none; }

.cb-scroll { max-height: 56vh; overflow: auto; padding: 5px; }
.cb-sec { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); padding: 9px 9px 4px; }
.cb-sec:first-child { padding-top: 4px; }
.cb-item { display: flex; align-items: center; gap: 8px; padding: 6px 9px; border-radius: 7px;
  font-size: 13px; color: var(--ink); }
.cb-item:hover { background: var(--surface-2); }
.cb-item.on { background: var(--ok-bg); color: var(--ink-green); font-weight: 600; }
.cb-item > span:nth-child(2), .cb-item > span:only-of-type { flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-item svg.i { width: 14px; height: 14px; flex: none; color: var(--muted); }
.cb-item.on svg.i { color: var(--g700); }
.cb-tick { width: 13px; flex: none; color: var(--g700); font-size: 12px; }
.cb-tag { font-style: normal; font-size: 10.5px; color: var(--muted); flex: none; }
.cb-tag.def { color: var(--g700); }
.cb-none { font-size: 12px; color: var(--muted); padding: 4px 10px 8px; line-height: 1.5; }

.cb-foot { border-top: 1px solid var(--line); padding: 5px; background: var(--surface-3); }
.cb-foot-a { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 7px;
  font-size: 12.5px; color: var(--ink2); }
.cb-foot-a:hover { background: var(--surface-2); color: var(--ink); }
.cb-foot-a svg.i { width: 14px; height: 14px; color: var(--muted); }

/* ── Nhóm nút lệnh ── */
.cb-tools { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-left: auto; }
.cb-btn { display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  border: 1px solid transparent; background: transparent; color: var(--ink2);
  padding: 5px 9px; border-radius: 7px; font-size: 12.5px; line-height: 1.3; }
.cb-btn:hover { background: var(--surface-2); color: var(--ink); border-color: var(--line); }
.cb-btn svg.i { width: 14px; height: 14px; }
.cb-count { display: inline-flex; min-width: 16px; height: 16px; padding: 0 4px;
  align-items: center; justify-content: center; border-radius: 8px;
  font-size: 10.5px; font-weight: 700; font-style: normal;
  background: var(--g600); color: var(--on-accent); }

.cb-search { display: flex; align-items: center; gap: 6px; width: 210px;
  border: 1px solid var(--line); border-radius: 8px; padding: 0 9px; background: var(--surface); }
.cb-search svg.i { width: 14px; height: 14px; flex: none; color: var(--muted); }
.cb-search .inp { border: 0; background: transparent; padding: 5px 0; font-size: 12.5px;
  flex: 1; min-width: 0; box-shadow: none; }
.cb-search .inp:focus { outline: none; }
.cb-search:focus-within { border-color: var(--g500); width: 280px; }

.cb-extra { display: inline-flex; gap: 5px; align-items: center; }
.cb-actions { display: inline-flex; gap: 6px; align-items: center; margin-left: 3px; }

/* Thanh lệnh đã có nút riêng — bỏ hàng "Thu gọn tất cả" cũ nếu toolbar.js kịp dựng */
.cmdbar ~ .collapsebar, .cmdbar + .collapsebar { display: none; }

/* ── Chip điều kiện đang áp ── */
.cb-chips { display: flex; gap: 5px; flex-wrap: wrap; align-items: center; margin-top: 7px; }

/* Cửa sổ bộ lọc mở ra phải nằm trên mọi thứ, kể cả thanh trên cùng */
.fmodal { z-index: 220; }

/* ═══════════════════════════════════════════════════════════════════════════
   v3.66 · MẬT ĐỘ GỌN — hiện được nhiều nội dung hơn trên cùng một màn hình
   ───────────────────────────────────────────────────────────────────────────
   Đặt CUỐI tệp và dùng đúng những bộ chọn đã có ở trên, nên chỉ cần xoá nguyên
   khối này là giao diện trở về mật độ cũ, không phải lần lại từng dòng.

   Thay đổi theo hướng: thu khoảng đệm trước, giảm cỡ chữ sau — cắt khoảng trắng
   ít ảnh hưởng tới việc đọc hơn là thu nhỏ chữ. Chữ trong bảng giữ ở 12,5px;
   dưới mức đó nhân viên nhìn màn hình cả ngày sẽ mỏi mắt.

   Kết quả đo trên màn hình 1080p: một trang danh sách hiện thêm khoảng 8 dòng
   dữ liệu so với v3.65 (26 → 34 dòng), chưa kể ba hàng đầu trang đã gộp vào
   thanh lệnh.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Khung trang: bớt lề, nới bề ngang tối đa cho bảng nhiều cột ── */
.content { padding: 14px 18px 44px; max-width: 1560px; }

/* ── Thẻ ── */
.card .hd { padding: 9px 13px; gap: 8px; }
.card .hd h3 { font-size: 13.5px; }
.card .hd .r { font-size: 11.5px; }
.card .bd { padding: 12px 13px; }
.grid { gap: 11px; }

/* Rất nhiều màn hình viết thẳng margin-bottom:16px vào thuộc tính style của thẻ —
   kiểu nội tuyến thắng mọi luật CSS thường, nên phải nhắm đúng và ghi đè có chủ ý.
   Đây là cách duy nhất siết được khoảng cách giữa các khối mà không phải sửa 240 view. */
.content .card[style*="margin-bottom:16px"],
.content .grid[style*="margin-bottom:16px"] { margin-bottom: 10px !important; }

/* ── Bảng: phần lấy lại được nhiều chỗ nhất ── */
th { font-size: 10.5px; padding: 7px 12px; }
td { font-size: 12.5px; padding: 7px 12px; }
td .mono, th .mono { font-size: 11.5px; }

/* Dòng phụ bên dưới ô chính (SĐT dưới tên khách, giờ dưới ngày…) — nhiều bảng dùng
   style nội tuyến font-size:11px, giữ nguyên; chỉ siết khoảng cách dòng để hai dòng
   trong một ô không đội cao cả hàng. */
td > div { line-height: 1.35; }

/* ── Thẻ số liệu ── */
.kpi { padding: 11px 13px; }
.kpi .lb { font-size: 11px; }
.kpi .vl { font-size: 23px; margin: 3px 0 1px; letter-spacing: -.6px; }
.kpi .dt { font-size: 11px; }

/* ── Nút, ô nhập, nhãn ── */
.btn { padding: 6px 12px; font-size: 12.5px; border-radius: 8px; }
.btn.sm { padding: 4px 10px; font-size: 12px; }
.inp { padding: 6px 10px; font-size: 13px; }
label.f { font-size: 12px; margin-bottom: 3px; }
.fr { margin-bottom: 10px; }
.hint { font-size: 11.5px; margin-top: 3px; }
.pill { padding: 2px 8px; font-size: 11px; }
.note { padding: 8px 11px; font-size: 12px; }

/* ── Dải tab trong trang (màn hình chưa chuyển sang thanh lệnh) ── */
.tabs { margin-bottom: 12px; gap: 3px; }
.tabs a { padding: 7px 11px; font-size: 12.5px; }

/* ── Phân trang của Filter Engine ── */
.fpager { padding: 8px 13px; font-size: 12px; gap: 11px; }
.fpager .fp-nav a, .fpager .fp-nav b, .fpager .fp-nav .off { min-width: 26px; padding: 3px 7px; }
.fchip { font-size: 12px; padding: 3px 5px 3px 9px; }

/* ── Chân trang: gọn lại, nó chỉ là dòng ghi chú ── */
.sitefooter { font-size: 11px; padding-top: 14px; }

/* Điện thoại: giữ vùng chạm đủ lớn — gọn không được đổi lấy việc bấm trượt.
   Nút và ô nhập quay về kích thước thoải mái, chỉ giữ phần thu khoảng đệm khung. */
@media (max-width: 900px) {
  .content { padding: 12px 12px 56px; }
  .btn { padding: 8px 13px; font-size: 13px; }
  .btn.sm { padding: 7px 11px; font-size: 12.5px; }
  .inp { padding: 9px 11px; font-size: 14px; }   /* < 16px trên iOS sẽ bị tự phóng to trang */
  td { padding: 9px 11px; }
  th { padding: 8px 11px; }
}

/* v3.90 · Form lọc có dải "Khoảng thời gian" đặt trong tiêu đề thẻ: tiêu đề một hàng, form xuống hàng riêng full-width */
.card > .hd.hd-has-range { flex-wrap: wrap; }
.card > .hd.hd-has-range > h3 { flex: 1 1 auto; white-space: nowrap; }
.card > .hd.hd-has-range > form.hd-range { flex: 1 1 100%; order: 3; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 4px 0 0; }
.card > .hd.hd-has-range > form.hd-range .inp[type=date], .card > .hd.hd-has-range > form.hd-range .inp[data-date] { max-width: 170px; }
/* v3.90 · dải 6 ô KPI (tuổi nợ…): 6 cột một hàng; màn vừa 3 × 2; điện thoại 2 × 3 — không để 5 + 1 lẻ loi */
.grid.aging6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1100px) { .content .grid.aging6 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; } }
@media (max-width: 600px)  { .content .grid.aging6 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } }

/* ===== v3.91 · UX-1 — không gian làm việc của bản ghi (core/Ui.php, master 9.4) ===== */
.ws-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 18px; margin-bottom: 12px; flex-wrap: wrap; }
.ws-id { display: flex; gap: 14px; align-items: flex-start; min-width: 0; flex: 1 1 420px; }
.ws-av { width: 52px; height: 52px; font-size: 19px; flex: 0 0 52px; }
.ws-idtext { min-width: 0; }
.ws-title { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ws-title h2 { margin: 0; font-size: 20px; line-height: 1.25; }
.ws-code { font-size: 12px; color: var(--muted); margin-top: 2px; }
.ws-meta { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 8px; font-size: 12.5px; }
.ws-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.ws-kpis { display: grid; grid-template-columns: repeat(var(--ws-n, 6), minmax(0, 1fr)); gap: 10px; margin-bottom: 12px; }
.ws-kpi { display: block; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; color: inherit; text-decoration: none; min-width: 0; }
.ws-kpi .lb { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-kpi .vl { font-size: 17px; font-weight: 700; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-kpi .dt { font-size: 11.5px; color: var(--muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-kpi.warn .vl { color: var(--orange, #c77700); } .ws-kpi.bad .vl { color: var(--red, #c0392b); } .ws-kpi.good .vl { color: var(--g700); }
a.ws-kpi:hover { border-color: var(--g300, #9fd4b5); }
.ws-body { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 14px; align-items: start; }
.ws-main { min-width: 0; }
.ws-rail { display: flex; flex-direction: column; gap: 12px; min-width: 0; position: sticky; top: 12px; }
.ws-tabs { display: flex; flex-wrap: nowrap; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: 12px; position: relative; }
.ws-tabs > a { flex: 0 0 auto; }
/* tab không vừa chiều ngang → gom vào "Thêm ▾" (workspace.js) — thanh tab luôn một hàng */
.ws-more { position: relative; flex: 0 0 auto; margin-left: auto; }
.ws-more > button { background: none; border: 0; padding: 8px 11px; font: inherit; font-size: 13px; font-weight: 600; color: var(--muted); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; }
.ws-more.on > button { color: var(--g700); border-bottom-color: var(--g700); }
.ws-more-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 40; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.10); min-width: 190px; padding: 4px; display: none; }
.ws-more.open .ws-more-menu { display: block; }
.ws-more-menu a { display: flex; justify-content: space-between; gap: 10px; padding: 8px 11px; border-radius: 7px; font-size: 13px; font-weight: 600; color: var(--ink2); text-decoration: none; border: 0; margin: 0; white-space: nowrap; }
.ws-more-menu a:hover { background: var(--g50, #eef7f1); } .ws-more-menu a.on { color: var(--g700); background: var(--g50, #eef7f1); }
.ws-tabs a { padding: 8px 11px; font-size: 13px; font-weight: 600; color: var(--muted); text-decoration: none; white-space: nowrap; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.ws-tabs a.on { color: var(--g700); border-bottom-color: var(--g700); }
.ws-cnt { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 99px; background: var(--surface-3, #eef2ef); font-size: 11px; text-align: center; color: var(--ink2); }
.ws-pane > .card, .ws-pane > form.card, .ws-pane > .grid { margin-bottom: 12px; }
html.ws-js .ws-pane { display: none; }
html.ws-js .ws-pane.on { display: block; }
.ws-kv { display: grid; grid-template-columns: fit-content(170px) minmax(0, 1fr); gap: 7px 12px; font-size: 13px; }
.ws-main { container-type: inline-size; }
@container (min-width: 820px) { .ws-kv.c2 { grid-template-columns: fit-content(170px) minmax(0, 1fr) fit-content(170px) minmax(0, 1fr); } }
.ws-kv > .k { color: var(--muted); } .ws-kv > .v { overflow-wrap: break-word; word-break: normal; min-width: 0; font-weight: 600; }
@media (max-width: 1200px) { .ws-body { grid-template-columns: minmax(0, 1fr) 320px; } .ws-kpis { grid-template-columns: repeat(var(--ws-h, 3), minmax(0, 1fr)); } }
@media (max-width: 1180px) { .ws-body { grid-template-columns: 1fr; } .ws-rail { position: static; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; } }
@media (max-width: 600px)  { .ws-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ws-kv { grid-template-columns: 110px minmax(0, 1fr); } }
/* v3.91 · UX-1 — ô tìm-chọn bản ghi (assets/js/lookup.js) */
.lk-wrap { position: relative; }
.lk-list { position: absolute; z-index: 50; left: 0; right: 0; top: calc(100% + 3px); background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.10); max-height: 300px; overflow-y: auto; }
.lk-opt { padding: 8px 11px; cursor: pointer; display: flex; flex-direction: column; gap: 1px; }
.lk-opt b { font-size: 13px; font-weight: 600; } .lk-opt span { font-size: 11.5px; color: var(--muted); }
.lk-opt.on, .lk-opt:hover { background: var(--g50, #eef7f1); }
.lk-empty { padding: 9px 11px; font-size: 12.5px; color: var(--muted); }
/* v3.91 · UX-1 — menu thao tác của một dòng "⋯" (thay nhiều nút xếp ngang làm bảng bị ép cột) */
.rowmenu { position: relative; display: inline-block; }
.rowmenu > summary { list-style: none; cursor: pointer; width: 30px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 18px; line-height: 1; color: var(--ink2); border: 1px solid var(--line); background: var(--surface); }
.rowmenu > summary::-webkit-details-marker { display: none; }
.rowmenu[open] > summary { background: var(--g50, #eef7f1); }
.rowmenu-list { position: absolute; right: 0; top: calc(100% + 4px); z-index: 45; min-width: 170px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.12); padding: 4px; display: flex; flex-direction: column; gap: 2px; text-align: left; }
.rowmenu-list form { margin: 0; display: block; }
.rowmenu-list button, .rowmenu-list a { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 7px 10px; border-radius: 7px; font: inherit; font-size: 13px; color: var(--ink2); cursor: pointer; text-decoration: none; white-space: nowrap; }
.rowmenu-list button:hover, .rowmenu-list a:hover { background: var(--g50, #eef7f1); }
.rowmenu-list .danger { color: var(--red, #c0392b); }
.rowmenu-list .rm-form { display: grid; gap: 4px; padding: 6px; min-width: 230px; } .rowmenu-list .rm-form .inp { width: 100%; } .rowmenu-list .rm-form button { text-align: center; }
.ws-audit { display: flex; justify-content: space-between; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.ws-audit:last-child { border-bottom: 0; }

/* ═══ v3.95 · UX-5 — danh sách chuẩn 9.2 (assets/js/listx.js) ═══ */
table.lx.lx-dense td { padding-top: 5px; padding-bottom: 5px; }
table.lx.lx-dense th { padding-top: 6px; padding-bottom: 6px; }
table.lx th.lx-th { position: relative; }
table.lx .lx-rs { position: absolute; top: 0; right: -3px; width: 7px; height: 100%; cursor: col-resize; z-index: 3; }
table.lx .lx-rs::after { content: ''; position: absolute; top: 25%; bottom: 25%; left: 3px; width: 1px; background: var(--line); }
table.lx th.lx-th:hover .lx-rs::after { background: var(--muted); }
table.lx th.lx-th:last-child .lx-rs { right: 0; width: 4px; }
table.lx th.lx-th:last-child .lx-rs::after { display: none; }
body.lx-resizing, body.lx-resizing * { cursor: col-resize !important; user-select: none; }
table.lx .lx-sel { width: 34px; padding-left: 12px; padding-right: 4px; }
table.lx .lx-sel input { width: 16px; height: 16px; margin: 0; vertical-align: middle; cursor: pointer; }
table.lx tbody tr.lx-on { background: var(--g50, #eef7f1); }
table.lx tbody tr.lx-peekable { cursor: pointer; }
table.lx tbody tr.lx-kf { box-shadow: inset 3px 0 0 var(--g700, #2f6f4f); background: var(--g50, #eef7f1); }
table.lx .lx-fz { position: sticky; z-index: 2; background-color: var(--surface); }
table.lx thead .lx-fz { z-index: 4; background-color: var(--surface); }   /* v3.111 · cùng nền với các ô tiêu đề khác (trước: xám khác màu) */
table.lx .lx-fzlast { box-shadow: 6px 0 6px -6px rgba(0,0,0,.18); }
.lx-dbtn { white-space: nowrap; }
/* thanh thao tác hàng loạt: hiện khi đã chọn dòng */
form.lx-bulk { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 14px; background: var(--g50, #eef7f1); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 5; }
form.lx-bulk[hidden] { display: none; }
form.lx-bulk .lx-bcount { font-size: 13px; white-space: nowrap; }
form.lx-bulk select.inp { width: auto; min-width: 200px; }
form.lx-bulk .lx-bfield { display: inline-flex; align-items: center; gap: 6px; min-width: 220px; }
form.lx-bulk .lx-bfield[hidden] { display: none; }
form.lx-bulk .lx-bfield .lk { min-width: 220px; }
.lx-tcap { font-size: 11.5px; color: var(--muted); margin: -4px 0 10px; }
/* khung xem nhanh */
.lx-peek { position: fixed; top: 0; right: 0; bottom: 0; width: min(780px, 58vw); background: var(--surface); box-shadow: -12px 0 32px -12px rgba(0,0,0,.28); z-index: 180; display: flex; flex-direction: column; transform: translateX(105%); transition: transform .18s ease; }
.lx-peek.open { transform: none; }
.lx-phd { display: flex; align-items: center; gap: 6px; padding: 8px 10px 8px 14px; border-bottom: 1px solid var(--line); }
.lx-pttl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.lx-pbtn { width: 30px; height: 28px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); cursor: pointer; font-size: 15px; line-height: 1; color: var(--ink2); }
.lx-pbtn:hover { background: var(--g50, #eef7f1); }
.lx-peek iframe { flex: 1; width: 100%; border: 0; background: var(--bg, var(--surface)); }
@media (max-width: 900px) { .lx-peek { width: 100vw; } }
/* trang chạy bên trong khung xem nhanh: bỏ menu bên, thanh trên cùng, nút nổi */
html.peek .side, html.peek .top, html.peek #navFlame, html.peek .helpfab, html.peek .scrolltopfab, html.peek #scrollTopFab, html.peek .shk-modal { display: none !important; }
html.peek .content { padding: 12px 14px 24px; }
/* v3.95 · danh sách chuẩn: ô ngắn không gãy dòng (bảng cuộn ngang, cột nhận diện cố định); chữ dài vẫn xuống dòng trong khung .cellclamp (toolbar.js) */
table.lx th, table.lx td { white-space: nowrap; }
table.lx td .cellclamp { white-space: normal; }

/* ═══ v3.96 · UX-6 — form chuẩn 9.3 ═══ */
/* thanh nút lưu dính đáy màn hình khi form dài hơn màn hình */
.fa-bar { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; position: sticky; bottom: 0; z-index: 6; margin-top: 8px; padding: 10px 0; background: var(--surface); border-top: 1px solid var(--line); }
.fa-bar .btn { height: var(--ctl-h); box-sizing: border-box; justify-content: center; }   /* v3.102 · nút lưu / lưu & tạo tiếp / huỷ cao bằng nhau (trước: 28 / 30 / 33px do button và a khác nhau) */

/* ═══ v3.96 · UX-6 — CHIỀU CAO Ô NHẬP THỐNG NHẤT (góp ý người dùng: ô chọn và ô nhập lệch nhau) ═══
   Trước: ô chữ 30 / 35 / 40px, ô chọn thường 31px, ô chọn có tìm kiếm (.sk-box) 39px, ô tìm-chọn 30px — nằm cạnh nhau là lệch.
   Nay mọi ô nhập một dòng (chữ, ngày, số, chọn, chọn có tìm kiếm, tìm-chọn) cao đúng --ctl-h; ô nhiều dòng (textarea) giữ tự do.
   Ngoại lệ có chủ ý (điều khiển gọn, không phải ô nhập liệu): ô tìm trên thanh lệnh danh sách, ô lọc cột trong bảng,
   thanh công cụ trình soạn thảo. */
:root { --ctl-h: 38px; }
@media (max-width: 760px), (pointer: coarse) { :root { --ctl-h: 42px; } }
html input.inp:where(:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range])),   /* :where() — không cộng độ ưu tiên, để ngoại lệ bên dưới ghi đè được */
html select.inp,
html .sk-box {
  height: var(--ctl-h); min-height: var(--ctl-h); box-sizing: border-box;
  padding-top: 0; padding-bottom: 0; font-size: 13.5px; line-height: normal;
}
html .sk-box { border-radius: var(--r-xs, 10px); }
html .cb-search input.inp { height: auto; min-height: 0; font-size: 12.5px; padding-top: 0; padding-bottom: 0; }   /* cỡ chữ bằng các nút cạnh bên (Bộ lọc, Cột…) — góp ý người dùng */
/* Bộ lọc: hàng điều kiện cùng cỡ; nút xoá điều kiện cao bằng ô; nút Thoả TẤT CẢ / BẤT KỲ cách hàng dưới */
html .fcond .inp { padding-top: 0; padding-bottom: 0; font-size: 13.5px; }
.fcond .fc-del { width: var(--ctl-h); height: var(--ctl-h); }
.flogic { margin-bottom: 12px; }
.fgroup > .fg-hd .flogic { margin-bottom: 0; }
.flogic button { padding: 6px 14px; }
/* ngoại lệ có chủ ý */
html select.inp[multiple], html select.inp[size] { height: auto; min-height: var(--ctl-h); padding-top: 6px; padding-bottom: 6px; }   /* danh sách chọn nhiều */
html input.inp[type=color] { padding: 4px; }
html input.inp.sm, html select.inp.sm { height: 32px; min-height: 32px; font-size: 12.5px; }   /* ô gọn trong hàng / thanh công cụ — cao bằng nút .btn.sm */
html .inp.inp-mini { height: auto; min-height: 0; padding: 2px 4px; font-size: 10px; }         /* ô chọn tí hon trên thẻ kanban */
/* ═══ v3.98 · khoảng cách khối & chân trang (góp ý người dùng: khối dính nhau, chân trang dính khối cuối) ═══
   Chân trang đẩy xuống bằng margin-top:auto (trang ngắn vẫn nằm sát đáy) — nên trang dài thì khoảng cách với khối cuối = 0.
   Tự vẽ đường kẻ cách mép trên 24px: luôn có khoảng trống phía trên đường kẻ, bất kể khối đứng trước là gì. */
.sitefooter { position: relative; border-top: 0; padding-top: 38px; }
.sitefooter::before { content: ''; position: absolute; left: 0; right: 0; top: 24px; border-top: 1px solid var(--line); }
/* Tiêu đề phụ (.r) căn phải, ngay trước nút gập / mở (góp ý người dùng: tiêu đề phụ trôi giữa tiêu đề).
   Nguyên nhân: .r và .cardtog cùng margin-left:auto → flex chia đôi khoảng trống, .r bị đẩy ra giữa.
   Đã có phần tử được đẩy sang phải thì nút gập chỉ đứng liền sau (cách bằng gap của tiêu đề), không tự đẩy nữa. */
.card > .hd > .r { margin-left: auto; flex: 0 1 auto; min-width: 0; text-align: right; }
.card > .hd > h3 { flex: 0 1 auto; min-width: 0; }
.card > .hd > :is(.r, .hd-actions, .actions, .r-actions) ~ .cardtog,
.card > .hd > [style*="margin-left:auto"] ~ .cardtog,
.card > .hd > [style*="margin-left: auto"] ~ .cardtog { margin-left: 0; }
/* Khối "dán link" (Core\LinkBox) in ra không có lề → dính vào khối trước / sau (hồ sơ nhân sự, báo cáo ngày…). Chừa 16px hai phía. */
.content :is(.card, .grid, form, .note) + .card.linkbox { margin-top: 16px; }
.content .card.linkbox + :is(.card, .grid, form) { margin-top: 16px; }
/* Chỉ phần tử ĐẦU TIÊN được đẩy sang phải giữ margin-left:auto; các phần tử sau (nút Xuất, nút gập…) đứng liền kề — kể cả khi
   view đặt margin-left:auto trực tiếp trên nút (vd Lịch sử chính sách booking: tiêu đề phụ trôi giữa vì nút Xuất PDF cũng tự đẩy). */
.card > .hd > .r ~ *,
.card > .hd > [style*="margin-left:auto"] ~ *,
.card > .hd > [style*="margin-left: auto"] ~ * { margin-left: 0 !important; }
/* v3.98 · dải "Khoảng thời gian" trong khung hẹp: một ô chọn thay cho nhiều hàng nút (toolbar.js thêm .rangebar-compact) */
.rangebar .rselect { display: none; width: auto; min-width: 150px; }
.rangebar.rangebar-compact { flex-wrap: nowrap; }
.rangebar.rangebar-compact .rchip { display: none; }
.rangebar.rangebar-compact .rselect { display: inline-block; flex: 1 1 auto; max-width: 240px; }
/* v3.98 · Nút gập nổi (.cardtog.float) ở khối không tiêu đề đè lên nội dung hàng đầu (vd tiêu đề cột cuối "THAM DỰ" ở Họp an toàn đầu ca).
   Chừa 44px bên phải cho hàng đầu: bảng → cột tiêu đề cuối; nội dung khác → phần tử đầu tiên của khối. */
.card:has(> .cardtog.float):not(.collapsed) > .tblwrap:first-child thead tr > th:last-child { padding-right: 44px !important; }   /* mọi hàng tiêu đề, kể cả hàng ô lọc cột (tableenhance.js) */
.card:has(> .cardtog.float):not(.collapsed) > :first-child:not(.cardtog):not(.tblwrap) { padding-right: 44px; }
/* v3.101 · khung xem nhanh: trang trong khung rộng < 900px nên tự hiện thanh menu điện thoại (Home · Nhân sự · Tạo mới…) đè lên nội dung
   (góp ý người dùng). Trong khung không cần menu — ẩn, và bỏ khoảng chừa cho menu ở đáy trang. */
html.peek .tabbar { display: none !important; }
html.peek { --tabbar-h: 0px; }

/* v3.111 · Di động: ẩn thanh trượt (vẫn vuốt được), chặn phóng to bằng chạm đúp (kèm viewport user-scalable=no) */
@media (max-width:760px){
  html{ -webkit-text-size-adjust:100%; text-size-adjust:100%; touch-action:manipulation; }
  *, .tblwrap{ scrollbar-width:none !important; -ms-overflow-style:none !important; }
  *::-webkit-scrollbar, .tblwrap::-webkit-scrollbar{ display:none !important; width:0 !important; height:0 !important; }
}
/* v3.111 · ô tiêu đề cột ghim (act-first) cùng nền với tiêu đề khác */
thead th.act-first{ background:var(--surface); -webkit-backdrop-filter:none; backdrop-filter:none; }
/* v3.111 · tên nhân sự trong danh sách là liên kết tới hồ sơ — giữ màu chữ của bảng, gạch chân khi rê */
a.stflink { color: inherit; text-decoration: none; font-weight: inherit; }
a.stflink:hover { color: var(--g700, #1b6b3c); text-decoration: underline; text-underline-offset: 2px; }
/* v3.111 · toàn bộ hàng tiêu đề cùng một nền (ô ghim cột tên không còn khác màu) */
.tblwrap thead th{ background-color:var(--surface); }
/* v3.111 · bảng chỉ tràn vài chục px: cho chữ xuống dòng để khỏi hiện thanh trượt (app.js gắn .lx-fit) */
.tblwrap.lx-fit th, .tblwrap.lx-fit td:not(.mono):not(.num):not(.act-first) { white-space: normal; }

/* v3.125.1 · Giao diện điện thoại: bỏ dòng credit cuối trang (giữ khoảng đệm cho thanh tab dưới) */
@media (max-width:900px){
  .sitefooter{font-size:0;line-height:0;border-top:0;padding-top:0}
  .sitefooter::before{display:none}
  .sitefooter a{display:none}
}

/* v3.126 · ô tìm & chọn nhiều (assets/js/multilookup.js) */
.ml-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.ml-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--g50, #eef7f1); font-size: 12.5px; }
.ml-chip button { border: 0; background: transparent; cursor: pointer; font-size: 15px; line-height: 1; padding: 0 5px; color: var(--muted); }
.ml-chip button:hover { color: var(--red, #dc2626); }

/* v3.126 · tab nhỏ trong thẻ / dòng (assets/js/workspace.js → .mtabs) */
.mtabs { margin-top: 8px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.mtabs-nav { display: flex; gap: 2px; padding: 4px; border-bottom: 1px solid var(--line); overflow-x: auto; }
.mtabs-nav button { border: 0; background: transparent; padding: 6px 10px; border-radius: 7px; font: inherit; font-size: 12.5px; color: var(--muted); cursor: pointer; white-space: nowrap; }
.mtabs-nav button.on { background: var(--g50, #eef7f1); color: var(--g700); font-weight: 700; }
.mtabs-pane { display: none; padding: 10px 12px; font-size: 13px; }
.mtabs-pane.on { display: block; }
.mtabs-pane .kv { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; font-size: 12.5px; }
.mtabs-pane .kv b { color: var(--muted); font-weight: 600; }

/* v3.126 · ảnh đại diện thật trong ô .av (core/Helper.php staffAvatar) */
.av.av-img { padding: 0; overflow: hidden; background: var(--surface-3, #eef2ef); }
.av.av-img img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }

/* v3.126 · trang tổng của nhóm (views/group.php) — một khối, các ô đều nhau */
.grp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.grp-item { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; text-decoration: none; color: inherit; background: var(--surface); transition: border-color .15s, box-shadow .15s; }
.grp-item:hover { border-color: var(--br-600); box-shadow: 0 2px 10px rgba(0,0,0,.06); }
.grp-ico { width: 40px; height: 40px; border-radius: 11px; background: var(--br-100, #E7F5EC); color: var(--br-700, var(--br-600)); display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.grp-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.grp-txt b { font-size: 14px; }
.grp-txt span { font-size: 12px; color: var(--muted); }
.grp-go { color: var(--muted); flex: 0 0 auto; }
@media (max-width:600px){ .grp-grid { grid-template-columns: 1fr; } }

/* v3.126 · quy trình xử lý khiếu nại theo bước (modules/complaint/views/_flow.php) */
.cmp-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
.cmp-step { display: flex; gap: 12px; padding: 10px 0; border-left: 2px solid var(--line); margin-left: 14px; padding-left: 18px; position: relative; }
.cmp-dot { position: absolute; left: -15px; top: 9px; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 700; background: var(--surface-3, #eef2ef); color: var(--muted); border: 2px solid var(--surface); }
.cmp-step.done .cmp-dot { background: var(--br-600); color: #fff; }
.cmp-step.current .cmp-dot { background: var(--orange, #ea580c); color: #fff; }
.cmp-step.current.late .cmp-dot { background: var(--red, #dc2626); }
.cmp-step.pending { opacity: .65; }
.cmp-body { min-width: 0; padding-left: 8px; }
