* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
:root {
  /* Bo mau thuong hieu AN CU - huong A "Mai am chieu muon" (quyet dinh #21).
     GIU NGUYEN TEN BIEN --blue-* de khong phai sua 186 cho dung; chi doi GIA TRI sang ramp xanh reu.
     Doc ten la "blue" nhung mau la XANH REU - dung sua ten, se vo ca app. */
  --blue-900: #062A1E; --blue-800: #0E5C43; --blue-600: #17795A; --blue-100: #BCDDCF; --blue-50: #E3F0EA;
  --bg: #FAF6EF; --card: #fff; --text: #1F2A24; --muted: #5F6D65; --border: #E6DFD3;
  /* --muted DOI GIA TRI 01/08/2026: #6B7A72 -> #5F6D65.
     Ma cu do duoc 4.19:1 tren nen kem #FAF6EF va 3.77:1 tren #EFEAE1 => DUOI chuan WCAG AA 4.5.
     Toan bo chu phu cua app dung bien nay (37 cho) nen ca app dang duoi chuan doc.
     Ma moi: 5.05 tren kem · 5.44 tren the trang · 4.54 tren #EFEAE1. Nguon: 04-BO-MA-THIET-KE.md muc 3 loi #1. */
  /* --border #E6DFD3 CHI CON LAM VACH CHIA TRANG TRI (1.23:1 — mien tru vi khong mang thong tin).
     VIEN O NHAP phai dung --vien-o-nhap: nguoi 55 tuoi khong thay o nhap o dau la loi kha dung. */
  --vien-o-nhap: #8A8F86;
  /* BA MAU TRANG THAI TACH 3 VAI (04-BO-MA-THIET-KE.md muc 2.5): nen nhat · mang/bieu tuong · CHU.
     Ma tuoi (#1D9E75 #D8402F #BA7517) lam nen thi dep nhung lam CHU thi truot het:
       #1D9E75 tren #E1F5EE = 2.98 · #BA7517 tren #FAEEDA = 3.24 · #D8402F tren #FAECE7 = 3.88.
     Trong app 3 bien nay bi dung lam CHU/BIEU TUONG o ~20 cho, lam nen chi 4 cho
     => doi GIA TRI sang bac CHU, va chuyen 4 cho lam nen sang bien *-mang moi. KHONG doi ten bien. */
  --green: #0B5C44; --green-bg: #E1F5EE; --red: #B32A1B; --red-bg: #FAECE7; --amber: #8F5A10; --amber-bg: #FAEEDA;
  --green-mang: #1D9E75; --red-mang: #D8402F; --amber-mang: #BA7517; --red-nut: #C6351F;
  /* Diem nhan cam den - luat 60-30-10: MOI MAN CHI MOT NUT CAM. Cam dam cho nut chinh (chu trang). */
  --warm: #F0A03C; --warm-bg: #FDF0DC; --btn: #B4530F; --btn-dark: #8E3F0A;
  /* Chu dat TREN nen cam (--warm / --amber): stop dam nhat cung ramp cam, KHONG dung den hay xam.
     Truoc day ma nay bi go thang vao 3 cho trong app.js va index.html — soi bang chan chuan
     31/07 thay "mau la ngoai bang mau". Nay khai thanh bien, bang mau phu luc phai co dong nay. */
  --warm-900: #3F2405;
  /* NHOM BIEN VAI — dung cho CHE DO TOI (public/che-do-toi.css chi ghi de nhom nay).
     Truoc 03/08/2026 nhung ma duoi day bi GO THANG vao 40 cho trong style.css: nen the go "#fff",
     nen chip go "#EFEAE1"... Ma go tay KHONG doi theo bien nen mo app ban dem van trang loa.
     Gia tri o day = dung ma cu tung chu => CHE DO SANG GIU NGUYEN TUNG PIXEL. */
  --card-2: #EFEAE1;          /* nen chip · nhan · o anh trong (bac tram nhat hon --card) */
  --nen-chim: #F0EAE0;        /* cho LOM xuong: mang thanh chuyen .seg */
  --chu-tren-chinh: #fff;     /* chu dat TREN nen --blue-800 / --blue-600 / --btn / --red / --green */
  /* Chu tren nen LUON TOI (lop phu den, --warm-900). Nhung nen do khong sang len o
     che do toi, nen bien nay CO Y giu #fff o ca hai che do — dung khai lai trong
     che-do-toi.css, doi la chu den tren nen den. */
  --chu-tren-toi: #fff;
  /* 🔴 NEN O MA QR — CO Y GIU TRANG O CA HAI CHE DO, dung khai lai trong che-do-toi.css.
     Thu vien qrcode.min.js ve ma sat mep canvas, khong chua le trang; le trang 10px
     cua o chinh LA "vung yen" (quiet zone) ma may quet can de tim duoc ma.
     Doi le do sang mau toi = khach gio dien thoai len quet mai khong an. */
  --nen-qr: #fff;
  --ov-thu: #CFE0D8; --ov-chi: #EFD3CC;   /* hai cot do thi thu · chi */
  /* BA NHOM MAU AVATAR (dot C bo nhan dien). Truoc 03/08 sau ma nay go thang trong
     avatar-an-cu.css => che do toi khong doi duoc, avatar thanh sau dom sang choi.
     KHONG tai dung --blue-100/--blue-800 cho nhom nha: o che do toi hai bien do la
     mau VIEN va mau CHU, dat chong len nhau chi duoc 1,3:1 — chu chim mat. */
  --av-nha-nen: #BCDDCF;   --av-nha-chu: #0E5C43;   /* 5,47:1 */
  --av-viec-nen: #D3E9E0;  --av-viec-chu: #20503F;  /* 7,24:1 */
  --av-khach-nen: #F3EEE6; --av-khach-chu: #1F2A24; /* 12,85:1 */
}
html, body { height: 100%; }
/* Phong chinh: Be Vietnam Pro (TC10 — dep voi dau tieng Viet, anh Quyet chot 31/07/2026).
   File phong nhung o vendor/fonts/bevietnampro. Danh sach sau la duong lui khi phong chua tai. */
body { font-family: "Be Vietnam Pro", -apple-system, "Segoe UI", Roboto, Arial, sans-serif; background: var(--bg); color: var(--text); }
#app { max-width: 460px; margin: 0 auto; min-height: 100vh; background: var(--bg); position: relative; padding-bottom: calc(76px + env(safe-area-inset-bottom)); }

.screen { display: none; padding: 0 14px 20px; }
.screen.active { display: block; }
.muted { color: var(--muted); font-size: 13px; }
.err { color: var(--red); font-size: 13px; min-height: 18px; margin-top: 10px; text-align: center; }

/* Topbar */
.topbar { display: flex; align-items: center; justify-content: space-between; padding: 16px 2px 12px; gap: 10px; }
/* 🔴 NOWRAP LÀ CỐ Ý (05/08/2026). `.topbar` là flex, và `<b class="page-title">` KHÔNG nằm
   trong danh sách `flex: 0 0 auto` ở cuối file ⇒ nó co được và KHÔNG có nowrap. Màn Sổ giao dịch
   và màn Báo cáo đều có `<input type="month">` đứng cạnh tiêu đề; ở khổ 375px input đẩy tiêu đề
   co lại, "Sổ giao dịch" rớt xuống 2 dòng. Cho tiêu đề nowrap thì input co thay — input co được
   thật, vì `.topbar > * { min-width: 0 }` ở cuối file đã mở đường. Gỡ nowrap là hai màn vỡ lại. */
.page-title { font-size: 18px; white-space: nowrap; }
.hello { display: flex; align-items: center; gap: 10px; }
.hello small { display: block; }
.avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--blue-50); color: var(--blue-800); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; }
.iconbtn { border: none; background: var(--card); width: 40px; height: 40px; border-radius: 50%; font-size: 20px; color: var(--blue-800); box-shadow: var(--bong-the, 0 1px 4px rgba(40,32,18,.08)); cursor: pointer; }

/* Login */
/* MAN DANG NHAP 2 BUOC (anh Quyet chot phuong an B, 31/07/2026).
   #app chua san 76px cho thanh tab, ma man dang nhap KHONG co thanh tab
   ⇒ keo lai bang margin am, neu khong ban phim so khong bao gio cham duoc day man. */
#scr-login { margin-bottom: calc(-76px - env(safe-area-inset-bottom)); }
.login-wrap { text-align: center; }
.login-man { min-height: 92vh; min-height: calc(100dvh - 30px); display: flex; flex-direction: column; align-items: center; }
.login-top { padding: 5vh 0 2vh; }
.login-step { flex: 1; width: 100%; max-width: 300px; display: flex; flex-direction: column; align-items: center; }
.login-field { width: 100%; margin-top: 14px; }
.login-field input { width: 100%; min-height: 52px; border: 1px solid var(--vien-o-nhap); border-radius: 14px; padding: 12px 14px; background: var(--card); color: var(--text); font-family: inherit; font-size: 17px; text-align: center; }
.login-field input:focus { outline: none; border-color: var(--blue-600); }
/* O mat khau + nut con mat. padding-right chua nut 48px, khong de chu chui xuong duoi nut.
   text-align:left vi mat khau chu doc tu trai — chi ma 6 so moi can canh giua. */
.pass-field { position: relative; }
.pass-field input { text-align: left; padding-right: 56px; letter-spacing: 1px; }
.pass-eye { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 48px; height: 48px; border: none; background: none; color: var(--muted); font-size: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
/* margin-top:auto = nut chinh roi xuong 1/3 duoi man (TC3 vung ngon cai). Dung go. */
.login-bottom { margin-top: auto; width: 100%; padding-bottom: 6px; }
.login-bottom .btn-primary.big { width: 100%; min-height: 52px; margin-top: 0; }
/* 🔴 TC3 — VÙNG CHẠM ≥44px, KHÔNG PHẢI CỠ CHỮ. Chữ 16px cho ô cao đúng 20px: phiên kiểm
   03/08/2026 bấm chuột thật vào "Đăng nhập bằng số điện thoại" mà TRƯỢT. Hai link này là
   LỐI VÀO CHÍNH của app (đổi cách đăng nhập · đăng ký) — trượt ở đây là không vào được nhà.
   Đệm dọc 12px + min-height 44px. `margin-top` hạ 14 → 2 để khoảng cách nhìn thấy giữ như cũ. */
.login-link { display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 12px 0; margin-top: 2px; color: var(--blue-600); font-size: 16px; cursor: pointer; }
.login-who { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 8px; }
.login-who b { font-size: 17px; }
.login-who button { border: none; background: var(--blue-50); color: var(--blue-800); border-radius: 999px; padding: 8px 16px; min-height: 44px; font-family: inherit; font-size: 16px; cursor: pointer; }
#login-b2 .pin-pad { margin-top: auto; margin-bottom: 10px; }
.login-logo { width: 72px; height: 72px; border-radius: 22px; background: var(--blue-800); color: var(--chu-tren-chinh); font-size: 38px; display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.login-logo svg { width: 72px; height: 72px; display: block; }
.login-wrap h1 { font-size: 22px; margin-bottom: 4px; }
/* Cau dinh vi duoi ten app (anh Quyet chot 30/07: "Nha yen, viec thuan") */
.login-tag { font-size: 13.5px; color: var(--muted); letter-spacing: .2px; margin-bottom: 2px; }
body.big-text .login-tag { font-size: 15.5px; }
.pin-dots { display: flex; gap: 12px; margin: 22px 0 8px; }
.pin-dots span { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--blue-600); }
.pin-dots span.on { background: var(--blue-600); }
.pin-pad { display: grid; grid-template-columns: repeat(3, 72px); gap: 12px; margin-top: 14px; }
.pin-pad button { height: 60px; border-radius: 18px; border: none; background: var(--card); font-size: 22px; font-weight: 600; color: var(--text); box-shadow: var(--bong-the, 0 1px 4px rgba(40,32,18,.07)); cursor: pointer; }
.pin-pad button:active { background: var(--blue-50); }

/* Balance card */
.balance-card { background: linear-gradient(135deg, var(--blue-800), var(--blue-600)); border-radius: 18px; padding: 18px; color: var(--blue-50); }
/* Chu phu tren the so du: PHAI la --blue-50, KHONG duoc --blue-100.
   The la nen chuyen sac #0E5C43 -> #17795A; do o dau SANG nhat (#17795A):
   #BCDDCF chi duoc 3.67:1 (truot), #E3F0EA duoc 4.57:1 (dat). */
.balance-card small { color: var(--blue-50); display: flex; align-items: center; gap: 6px; }
.balance-card small button { background: none; border: none; color: var(--blue-50); font-size: 16px; cursor: pointer; }
.balance { font-size: 30px; font-weight: 700; margin: 6px 0 10px; letter-spacing: .5px; }
.io-row { display: flex; gap: 16px; font-size: 12.5px; color: var(--blue-50); flex-wrap: wrap; }
.io-row b { color: var(--chu-tren-chinh); font-weight: 600; }

/* Wallet strip */
.wallet-strip { display: flex; gap: 10px; overflow-x: auto; padding: 12px 2px 2px; }
.wallet-chip { flex: 0 0 auto; background: var(--card); border-radius: 14px; padding: 10px 14px; display: flex; align-items: center; gap: 9px; box-shadow: var(--bong-the, 0 1px 4px rgba(40,32,18,.06)); }
.wallet-chip i { font-size: 20px; color: var(--blue-600); }
.wallet-chip small { display: block; color: var(--muted); font-size: 13px; }
.wallet-chip b { font-size: 15px; }

/* Quick grid */
.quick-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 14px 0 4px; }
.quick-grid button { border: none; background: none; font-size: 12.5px; color: var(--muted); display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; line-height: 1.3; }
.qi { width: 50px; height: 50px; border-radius: 15px; display: flex; align-items: center; justify-content: center; font-size: 23px; }
.qi-blue { background: var(--blue-50); color: var(--blue-600); }
/* O nhanh chu dao (Ghi thu chi) = diem cam 10% cua trang chu. CHI MOT o duoc dung qi-cam. */
/* Chu o day phai la --btn-dark #8E3F0A: #B4530F tren nen kem cam #FDF0DC chi duoc 4.46:1
   (thieu 0.04 — nhin thi tuong dat, do moi ra). #8E3F0A = 6.52:1. */
.qi-cam { background: var(--warm-bg); color: var(--btn-dark); }
.qi-green { background: var(--green-bg); color: var(--green); }
.qi-amber { background: var(--amber-bg); color: var(--amber); }
.qi-red { background: var(--red-bg); color: var(--red); }

.section-head { display: flex; justify-content: space-between; align-items: baseline; padding: 14px 2px 8px; }
.section-head a { color: var(--blue-600); font-size: 13px; cursor: pointer; }

/* Transaction list */
.tx-list { display: flex; flex-direction: column; }
.tx-item { display: flex; align-items: center; gap: 11px; background: var(--card); padding: 11px 12px; border-radius: 14px; margin-bottom: 8px; box-shadow: var(--bong-the, 0 1px 3px rgba(40,32,18,.05)); cursor: pointer; }
.tx-icon { width: 38px; height: 38px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 19px; flex-shrink: 0; }
.tx-icon.chi { background: var(--red-bg); color: var(--red); }
.tx-icon.thu { background: var(--green-bg); color: var(--green); }
.tx-mid { flex: 1; min-width: 0; }
/* 🔴 HAI DÒNG, KHÔNG PHẢI BA CHẤM (05/08/2026). Trước đây dòng này `nowrap` + `ellipsis` ⇒ tên
   dài bị cắt cụt: tên tòa thật dài tới mức "534.58 Điện Biên Phủ" (xem chú thích rental.js
   ovExpiringHTML) nên người dùng đọc ra "534.58 Điện B…" — mất đúng phần phân biệt tòa này với
   tòa kia. Nay cho xuống tối đa 2 dòng rồi mới cắt.
   🟢 Tên NGẮN không đổi gì — hàng chỉ cao thêm khi tên thật sự dài, nên 29 chỗ dùng `.tx-mid`
   trong 11 file không bị đội hàng vô cớ.
   🔴 `-webkit-line-clamp` bắt buộc đi kèm `display: -webkit-box` + `-webkit-box-orient`; bỏ một
   trong ba là mất tác dụng và tên dài tràn ra vô hạn. App đóng gói Capacitor (Blink) nên tiền tố
   -webkit là đủ, KHÔNG phải thiếu sót. */
.tx-mid p {
  font-size: 16px; font-weight: 500;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  white-space: normal; overflow: hidden;
}
.tx-mid small { color: var(--muted); font-size: 13px; }
.tx-amt { font-weight: 700; font-size: 15.5px; white-space: nowrap; }
.tx-amt.chi { color: var(--red); }
.tx-amt.thu { color: var(--green); }
.tx-day-head { font-size: 12.5px; color: var(--muted); padding: 10px 4px 6px; font-weight: 600; }
.empty { text-align: center; color: var(--muted); padding: 30px 10px; font-size: 14px; }

/* Book */
.book-sum { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.book-sum div { background: var(--card); border-radius: 12px; padding: 10px; text-align: center; }
.book-sum small { color: var(--muted); font-size: 13px; display: block; }
.book-sum b { font-size: 15px; }
input[type="month"], input[type="date"] { border: 1px solid var(--vien-o-nhap); border-radius: 10px; padding: 8px 10px; font-size: 14px; background: var(--card); color: var(--text); font-family: inherit; }

/* Cards */
.card { background: var(--card); border-radius: 16px; padding: 16px; margin-bottom: 12px; box-shadow: var(--bong-the, 0 1px 4px rgba(40,32,18,.05)); }
.card > b { display: flex; align-items: center; gap: 7px; margin-bottom: 10px; font-size: 15px; }
.card input, .card select { width: 100%; border: 1px solid var(--vien-o-nhap); border-radius: 10px; padding: 11px 12px; font-size: 16px; margin: 8px 0; font-family: inherit; }
.report-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.report-cards .rc { background: var(--card); border-radius: 14px; padding: 12px 14px; }
.report-cards small { color: var(--muted); font-size: 13px; }
.report-cards b { font-size: 17px; display: block; margin-top: 3px; }

/* Buttons */
.btn-primary { background: var(--blue-800); color: var(--chu-tren-chinh); border: none; border-radius: 12px; padding: 13px 16px; font-size: 16px; font-weight: 600; cursor: pointer; width: 100%; font-family: inherit; min-height: 48px; }
.btn-primary:active { background: var(--blue-900); }
/* Cam den chi cho MOT nut chu dao moi khung (luat 60-30-10, quyet dinh #21):
   - trong khay truot/hop thoai: nguoi dung dang lam DUT DIEM 1 viec -> nut do la nut cam
   - man dang nhap: chi co 1 nut
   - man danh sach (.screen) giu XANH REU vi thuong co nhieu the, nhieu nut Luu cung hien
   Muon them 1 nut cam o man nao thi gan class .cam - nho kiem con nut cam nao khac dang hien khong. */
/* LUẬT MÀU NÚT (anh Quyết chốt phương án C, 31/07/2026) — chỉ 2 màu, không đẻ màu thứ 3:
   CAM #B4530F = nút làm PHÁT SINH hoặc DI CHUYỂN TIỀN (tạo hóa đơn · thu · chi · cọc · giải ngân · thanh toán) → thêm class "cam"
   XANH #0E5C43 = mọi nút còn lại, kể cả nút xem trước / lưu cấu hình (không đụng tiền)
   🔴 CÂU CŨ "Nút trong .overlay và màn đăng nhập ĐÃ cam sẵn — khỏi thêm class" ĐÃ CHẾT
   (anh Quyết gõ `cam A`, thi hành 11/08/2026). Cam nay cấp theo NGHĨA của nút, KHÔNG theo
   CHỖ ĐỨNG của nút. Muốn cam thì khai class `cam` tường minh trên chính nút đó, hoặc
   `primaryClass: 'cam'` ở chỗ gọi askSheet/hoiLai/promptSheet.
   Vì sao bỏ: `.overlay .btn-primary` tô cam cả "Xóa luôn · Từ chối · Tiếp tục · Ẩn đi" —
   chúng mang đúng màu của nút Thu tiền. Một tín hiệu màu sai nghĩa được nhân lên theo số
   người dùng, và hiểu nhầm ở nút đụng tiền là hiểu nhầm đắt nhất.
   Rào chắn: routes/nhat-quan-o9.test.js — bài "luật cam KHÔNG được cấp theo chỗ đứng". */
#scr-login .btn-primary, .btn-primary.cam { background: var(--btn); }
#scr-login .btn-primary:active, .btn-primary.cam:active { background: var(--btn-dark); }
#cs-overlay .btn-ghost, .overlay .btn-secondary { color: var(--blue-800); }
.btn-primary.big { padding: 14px; font-size: 17px; margin-top: 14px; }
.btn-danger { background: var(--red-bg); color: var(--red); border: none; border-radius: 12px; padding: 12px; font-size: 14px; font-weight: 600; width: 100%; margin-top: 8px; cursor: pointer; font-family: inherit; }
.btn-ghost { background: none; border: none; color: var(--muted); font-size: 14px; padding: 14px; width: 100%; cursor: pointer; font-family: inherit; }

/* Scan */
.scan-area { padding-top: 8px; }
.scan-big { width: 100%; background: var(--card); border: 2px dashed var(--blue-100); border-radius: 18px; padding: 34px 18px; display: flex; flex-direction: column; align-items: center; gap: 8px; cursor: pointer; font-family: inherit; }
.scan-big i { font-size: 44px; color: var(--blue-600); }
.scan-big b { font-size: 16px; color: var(--text); }
#scan-status { margin: 14px 0; }
.scan-msg { display: flex; align-items: center; gap: 10px; background: var(--blue-50); color: var(--blue-800); border-radius: 12px; padding: 12px 14px; font-size: 14px; }
.scan-msg.err { background: var(--red-bg); color: var(--red); }
.spin { width: 18px; height: 18px; border: 3px solid var(--blue-100); border-top-color: var(--blue-600); border-radius: 50%; animation: sp 1s linear infinite; flex-shrink: 0; }
@keyframes sp { to { transform: rotate(360deg); } }
#scan-preview img { max-width: 100%; border-radius: 14px; margin-top: 6px; }

/* Chat */
.chat-box { display: flex; flex-direction: column; gap: 10px; padding: 6px 0 12px; min-height: 55vh; }
.msg { max-width: 82%; padding: 11px 14px; border-radius: 16px; font-size: 16px; line-height: 1.5; }
.msg.ai { background: var(--card); align-self: flex-start; border-bottom-left-radius: 6px; box-shadow: var(--bong-the, 0 1px 3px rgba(40,32,18,.05)); }
.msg.me { background: var(--blue-800); color: var(--chu-tren-chinh); align-self: flex-end; border-bottom-right-radius: 6px; }
.msg.note { background: var(--green-bg); color: var(--green); align-self: center; font-size: 12.5px; padding: 6px 12px; border-radius: 20px; }
/* Cùng bệnh với .tabbar — xem chú thích ở .tabbar. */
.chat-input { position: fixed; bottom: 76px; left: 0; right: 0; width: auto; margin-inline: auto; max-width: 460px; display: flex; gap: 8px; padding: 8px 14px; background: var(--bg); }
.chat-input input { flex: 1; border: 1px solid var(--vien-o-nhap); border-radius: 22px; padding: 12px 16px; font-size: 14.5px; font-family: inherit; }
.chat-input button { width: 46px; height: 46px; border-radius: 50%; border: none; background: var(--blue-800); color: var(--chu-tren-chinh); font-size: 19px; cursor: pointer; }

/* Overlay sheet */
.overlay { display: none; position: fixed; inset: 0; background: rgba(31,42,36,.45); z-index: 50; }
.overlay.active { display: flex; align-items: flex-end; justify-content: center; }
/* 🔴 HỘP HỎI LẠI VÀ HỘP NHẬP LUÔN NẰM TRÊN CÙNG — ĐỪNG HẠ XUỐNG 50 (đo 02/08/2026).
   Hai hộp này hay mở TỪ TRONG một sheet đang mở. Hơn 20 sheet của app tạo bằng appendChild nên
   nằm SAU trong DOM; cùng z-index 50 thì sheet đè lên hộp, nút "Bỏ vai"/"Xóa" bấm không ăn mà
   không báo gì — người dùng tưởng app đơ. Test tự động gọi thẳng API nên không bao giờ bắt được. */
/* 🔴 NÂNG 60 → 950 (đợt 0, 05/08/2026). 14 màn phủ toàn trang (`.man-phu`) đứng ở lớp 900,
   mà chúng CŨNG mở hộp hỏi lại từ bên trong (Hộp phiếu, Hộp thư vào, Nhập file…). Ở lớp 60
   hộp hỏi lại nằm DƯỚI màn phủ ⇒ bấm "Bỏ đi"/"Xóa" không thấy gì, y hệt bệnh đã tả ngay trên
   nhưng ở tầng cao hơn. Trước đây rào chắn không bắt được vì 900 nằm trong chuỗi JS, không
   nằm trong style.css. Số này phải LUÔN cao hơn `.man-phu`. */
#cs-overlay, #prompt-sheet-overlay { z-index: 950; }
.sheet { background: var(--bg); width: 100%; max-width: 460px; border-radius: 22px 22px 0 0; padding: 18px 18px 26px; max-height: 92vh; overflow-y: auto; }
.sheet-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.sheet-head b { font-size: 17px; }
.sheet label { font-size: 12.5px; color: var(--muted); display: block; margin: 10px 2px 4px; }
.sheet input, .sheet select { width: 100%; border: 1px solid var(--vien-o-nhap); border-radius: 12px; padding: 12px 13px; font-size: 16px; background: var(--card); font-family: inherit; }
#cs-q { width:100%; box-sizing:border-box; border:1px solid var(--vien-o-nhap); border-radius:12px; padding:13px 14px; font-size:16px; background: var(--card); color:var(--text); font-family:inherit; min-height:48px; }
#tx-amount { font-size: 22px; font-weight: 700; color: var(--blue-800); }
.seg { display: flex; background: var(--nen-chim); border-radius: 12px; padding: 4px; gap: 4px; }
.seg button { flex: 1; border: none; background: none; padding: 10px; border-radius: 9px; font-size: 14px; font-weight: 600; color: var(--muted); cursor: pointer; font-family: inherit; }
.seg button.active { background: var(--card); color: var(--blue-800); }
.seg button.active[data-v="chi"] { background: var(--card); color: var(--red); }
.seg button.active[data-v="thu"] { background: var(--card); color: var(--green); }

/* Tabbar */
/* 🔴 CĂN GIỮA BẰNG left:0+right:0+margin auto — KHÔNG dùng left:50%+translateX(-50%).
   Đo 03/08/2026 (Chrome thật, khổ 375): translateX chỉ dời lúc VẼ, hộp vẫn NẰM ở 50%→150%
   viewport ⇒ trang nở ngang (innerWidth 375→381/385/391 tùy vai) ⇒ nhãn tab tụt khỏi mép
   dưới màn (đáy 833 > 812). Vai 4 ô lộ nặng nhất nhưng MỌI vai đều dính. Đừng đổi lại. */
/* 🔴 `display: none` LÀ MẶC ĐỊNH CỐ Ý (anh Quyết gõ `ô A`, thi hành 11/08/2026) — ĐỪNG trả về `flex`.
   Bệnh đo được: #scr-login đã mang class .active NGAY TRONG index.html, mà thanh này để sẵn
   `flex` ⇒ người CHƯA đăng nhập nhìn thấy nguyên thanh 5 ô của vai chủ sổ cho tới khi
   /api/state trả về. JS có ẩn, nhưng ẩn SAU khi màn đã kịp hiện ra.
   Ai bật thanh lên: go() trong public/app.js đặt display inline cho mọi màn khác login
   (thêm giuThanhTab() + applyRole trong public/dieu-huong.js). Bỏ dòng đó là app mất thanh.
   Rào chắn: routes/nhat-quan-o9.test.js — hai bài đầu canh cả hai chiều. */
.tabbar { position: fixed; bottom: 0; left: 0; right: 0; width: auto; margin-inline: auto; max-width: 460px; background: var(--card); display: none; justify-content: space-around; align-items: flex-end; padding: 8px 6px calc(10px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); z-index: 40; }
/* 12px la san duoi cho nhan tab — 10.5px cu qua nho voi tep 45-65 tuoi (TC10). */
.tabbar button { border: none; background: none; display: flex; flex-direction: column; align-items: center; gap: 3px; font-size: 12px; color: var(--muted); cursor: pointer; width: 66px; font-family: inherit; }
.tabbar button i { font-size: 22px; }
.tabbar button.active { color: var(--blue-800); }
.scan-fab { width: 52px; height: 52px; border-radius: 50%; background: var(--blue-800); color: var(--chu-tren-chinh); display: flex; align-items: center; justify-content: center; font-size: 26px; margin-top: -30px; border: 4px solid var(--bg); }
.tab-scan { color: var(--blue-800) !important; }

/* === Khay nut noi (FAB dock): gom moi nut noi, tu xep doc, khong con de chong === */
/* Neo vao dung khung app 460px (giong tabbar): tren dien thoai = le 12px, tren man rong van bam khung */
#fab-dock { position: fixed; right: max(12px, calc(50% - 218px)); bottom: calc(84px + env(safe-area-inset-bottom)); z-index: 45; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; pointer-events: none; }
#fab-dock > * { pointer-events: auto; }
/* Thu tu tu tren xuong: chuong -> nhan su/admin -> cai dat/dang xuat (gan ngon tay nhat) */
#bell-fab { order: 1; }
#sdv-fab, #m6-fab { order: 2; }
#m8-fab, #m9-fab { order: 3; }
/* Gom 30/07: vai khong co trang chu chi con dung 1 nut "Tien ich" (gan ngon tay nhat) */
#settings-fab, #ctv-logout-fab, #role-switch-fab { order: 4; }
#tien-ich-fab { order: 5; }

/* === Chuan hoa nut ban 2 (TC 3+8, audit HT3) === */
.btn-danger { min-height: 48px; }
.tabbar button { min-height: 48px; padding: 4px 0; justify-content: flex-end; }
.chipbtn { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-height: 40px; padding: 8px 14px; border-radius: 10px; font-size: 13px; font-weight: 600; cursor: pointer; text-decoration: none; background: var(--blue-50); color: var(--blue-800); margin: 3px 3px 0 0; }
.chipbtn.act { min-height: 44px; padding: 10px 16px; font-size: 13.5px; }
.chipbtn.on { background: var(--blue-600); color: var(--chu-tren-chinh); }
.chipbtn-qr { background: var(--blue-50); color: var(--blue-800); }
.chipbtn-thu, .chipbtn.green { background: var(--green-bg); color: var(--green); }
.chipbtn.amber { background: var(--amber-bg); color: var(--amber); }
.chipbtn.red { background: var(--red-bg); color: var(--red); }
.iconbtn { width: 44px; height: 44px; }
.balance-card small button { padding: 12px; margin: -12px; min-height: 44px; min-width: 44px; }
.seg button { padding: 13px 10px; min-height: 48px; }
.chat-input button { width: 48px; height: 48px; }
.btn-secondary { background: var(--card); color: var(--blue-800); border: 1.5px solid var(--blue-100); border-radius: 12px; min-height: 48px; padding: 13px 16px; font-size: 16px; font-weight: 600; cursor: pointer; width: 100%; font-family: inherit; }
body.big-text .chipbtn { font-size: 15px; min-height: 48px; }
body.big-text .chipbtn.act { min-height: 52px; }

/* ===== Module 1: trang thai phong & form them/sua ===== */
/* ---- Bieu do thu chi 6 thang tren trang tong quan (v81) ----
   Nam TRONG the "Nha minh thang nay", khong phai khoi thu 5. Cot cao toi da 46px
   de ca cum khong đay 5 hang so xuong duoi vung ngon cai. */
.ov-bieudo { margin: 10px 2px 2px; cursor: pointer; }
.ov-bieudo-hang { display: flex; gap: 6px; align-items: flex-end; }
.ov-cot { flex: 1; text-align: center; }
.ov-cot-doi { display: flex; gap: 3px; align-items: flex-end; justify-content: center; height: 48px; }
.ov-cot-doi span { display: block; width: 9px; border-radius: 3px 3px 0 0; }
.ov-cot-doi .ov-thu { background: var(--ov-thu); }
.ov-cot-doi .ov-chi { background: var(--ov-chi); }
/* Cot bieu do la MANG HINH, khong phai chu => giu ma tuoi (nguong 3:1, do duoc 3.14 / 4.15). */
.ov-cot-doi .ov-thu.nay { background: var(--green-mang); }
.ov-cot-doi .ov-chi.nay { background: var(--red-mang); }
.ov-cot small { display: block; margin-top: 4px; color: var(--muted); font-size: 12px; }
.ov-cot small.nay { color: var(--text); font-weight: 700; }
.rstat { display: inline-block; font-size: 11.5px; font-weight: 700; padding: 1px 8px; border-radius: 999px; vertical-align: middle; line-height: 1.7; }
.rstat.trong { background: var(--green-bg); color: var(--green); }
.rstat.dacoc { background: var(--amber-bg); color: var(--amber); }
.rstat.dango { background: var(--card-2); color: var(--muted); }
.rstat.ngung { background: var(--card-2); color: var(--muted); }
.rstat-legend { display: flex; gap: 8px; margin: 0 0 12px; flex-wrap: wrap; }
.rstat-legend .rstat { font-size: 12.5px; padding: 5px 12px; }
.seg { display: flex; gap: 6px; background: var(--bg); border-radius: 12px; padding: 4px; margin: 4px 0 12px; }
.seg-btn { flex: 1; border: none; background: none; padding: 10px 0; border-radius: 9px; font-size: 14px; font-weight: 600; color: var(--muted); cursor: pointer; font-family: inherit; min-height: 46px; }
.seg-btn.on { background: var(--card); color: var(--blue-800); box-shadow: var(--bong-the, 0 1px 3px rgba(40,32,18,.1)); }
/* ===========================================================================
   DAI CHON — MOT KHUON DUY NHAT CHO MOI DAI TAB/CHIP CUON NGANG (04/08/2026)
   ---------------------------------------------------------------------------
   VI SAO CO KHOI NAY (do that o kho 375px, san rong cong 3988, TRUOC khi sua):
     · cho-dich-vu.js dung .seg  -> 5 nut chia deu 319px = o trong 37px moi nut
       => "Don cua toi" be thanh 3 dong, NUT CAO 106px. Do la benh nang nhat.
     · ban-phong-ctv.js tu che overflow-x + style inline tren TUNG nut
       => noi dung 734px trong khung 347px, 3 tab cuoi bi giau.
     · cho-cu-dan.js · giu-coc.js · rental.js (cs-chip, cs-toa): moi cho mot kieu.
   Rut chu tung cho = va. Man moi sau nay lai tu che tiep. Vi the: MOT khuon.

   Khac .seg the nao — dung dung cho, dung lan:
     .seg      = chon 2-3 muc, chia DEU be ngang, khong cuon (vd +6 thang / +1 nam).
     .dai-chon = chon NHIEU muc, nut giu nguyen be rong chu, TRAN thi cuon ngang.
   Nut khong co lai (flex 0 0 auto) + khong xuong dong (nowrap) => khong bao gio
   nat chu; tran thi lo mep nut ke tiep, nguoi biet la con cuon duoc.

   🔴 KHONG tu che `overflow-x` cho dai tab trong file .js nua — rao chan tinh
   `routes/dai-chon-chung.test.js` quet public/ va bao do. Them dai moi: dung
   class nay. Can khac mau thi them class con, dung viet style thang vao the.
   =========================================================================== */
.dai-chon { display: flex; gap: 6px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; background: var(--bg); border-radius: 12px; padding: 4px; margin: 4px 0 12px; }
.dai-chon::-webkit-scrollbar { display: none; }
/* 🔴 HAI LUAT CHONG NAT CHU DAT LEN CON CUA DAI, KHONG LEN TUNG NUT.
   Vi sao: dai chip dung .chipbtn / .cs-chip da co mau rieng; them mot class nut
   nua thi class sau de mau class truoc (do that: .dai-chon-nut lam .chipbtn mat
   nen xanh). Dat o day thi moi con — nut, the a, chip — deu duoc luat hinh hoc
   ma KHONG ai bi doi mau. Them dai moi khoi phai nho gan class len tung nut. */
.dai-chon > * { flex: 0 0 auto; white-space: nowrap; }
.dai-chon > .chipbtn { margin: 0; }
/* Nut kieu tab (nen chim, o dang chon noi len) — dung cho thanh tab dau man. */
.dai-chon-nut { display: inline-flex; align-items: center; justify-content: center; gap: 5px; border: none; background: none; padding: 10px 14px; border-radius: 9px; font-size: 14px; font-weight: 600; color: var(--muted); cursor: pointer; font-family: inherit; min-height: 46px; }
.dai-chon-nut.on { background: var(--card); color: var(--blue-800); box-shadow: var(--bong-the, 0 1px 3px rgba(40,32,18,.1)); }
/* Dai chip loc nam trong ruot man (khong phai thanh tab dau man): khong nen chim,
   khong bo goc khoi — de chip tu mang mau cua no (.chipbtn, .cs-chip). */
.dai-chon.tran { background: none; border-radius: 0; padding: 4px 0 6px; }
body.big-text .dai-chon-nut { font-size: 16px; }

/* 4 trang thai (v81) khong du cho tren 1 hang -> xuong 2 cot, nut van cao 48px. */
.rstat-pick { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.rstat-btn { flex: 1 1 calc(50% - 8px); border: 1.5px solid var(--vien-o-nhap); background: var(--card); padding: 11px 0; border-radius: 12px; font-size: 14px; font-weight: 600; color: var(--text); cursor: pointer; font-family: inherit; min-height: 48px; }
.rstat-btn.on.trong { background: var(--green-bg); color: var(--green); border-color: var(--green); }
.rstat-btn.on.dacoc { background: var(--amber-bg); color: var(--amber); border-color: var(--amber); }
.rstat-btn.on.dango { background: var(--card-2); color: var(--muted); border-color: var(--muted); }
.rstat-btn.on.ngung { background: var(--card-2); color: var(--muted); border-color: var(--muted); }
body.big-text .rstat { font-size: 13.5px; }
body.big-text .seg-btn, body.big-text .rstat-btn { font-size: 16px; }
body.big-text .btn-secondary { font-size: 18px; min-height: 52px; }
body.big-text .seg button { font-size: 16px; }
body.big-text .tabbar button { min-height: 52px; }

/* === SHEET XAC NHAN AM === */
.cs-icon { width: 56px; height: 56px; border-radius: 50%; background: var(--blue-50); color: var(--blue-800); display: flex; align-items: center; justify-content: center; font-size: 28px; margin: 4px auto 8px; }
.cs-icon.green { background: var(--green-bg); color: var(--green); }
.cs-icon.red { background: var(--red-bg); color: var(--red); }
.cs-icon.amber { background: var(--amber-bg); color: var(--amber); }
.cs-title { font-size: 18px; display: block; margin: 0 0 6px; }
.cs-body { font-size: 16px; line-height: 1.55; color: var(--muted); margin: 0 0 8px; }
.cs-detail { background: var(--card); border-radius: 12px; padding: 10px 14px; font-size: 13.5px; text-align: left; margin: 8px 0 4px; line-height: 1.7; }
/* Hai nut nay co CHU TRANG. Nen cu do duoc: trang tren #D8402F = 4.47 (truot sat),
   trang tren #1D9E75 = 3.39 (truot nang). Nay: trang tren #C6351F = 5.34 · tren #0B5C44 = 7.99. */
#cs-overlay .btn-primary.danger { background: var(--red-nut); }
#cs-overlay .btn-primary.green { background: var(--green); }
#cs-overlay .btn-ghost { min-height: 48px; }
body.big-text .cs-title { font-size: 20px; }
body.big-text .cs-body { font-size: 18px; }
body.big-text .cs-detail { font-size: 15.5px; }

/* Che do chu to (Cham la thuong TC10 — tep 45-65 tuoi) */
body.big-text .tx-mid p, body.big-text .msg, body.big-text .card input, body.big-text .card select, body.big-text .sheet input, body.big-text .sheet select { font-size: 18px; }
body.big-text .tx-mid small, body.big-text .wallet-chip small, body.big-text .muted, body.big-text .book-sum small { font-size: 15px; }
body.big-text .tx-amt { font-size: 17.5px; }
body.big-text .balance { font-size: 34px; }
body.big-text .btn-primary { font-size: 18px; min-height: 52px; }
body.big-text .quick-grid button { font-size: 13px; }
body.big-text .tabbar button { font-size: 12px; }

/* ===== Man phong drill-down: luoi o luong (Cham la thuong TC1 nhin-3-giay) ===== */
.room-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 12px; }
.room-tile { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 4px; background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 14px 6px 10px; cursor: pointer; font-family: inherit; min-height: 92px; text-align: center; transition: transform .06s, box-shadow .12s; }
.room-tile:active { transform: scale(.97); }
.room-tile:hover { box-shadow: var(--bong-the, 0 3px 10px rgba(14,92,67,.10)); border-color: var(--blue-100); }
.room-tile > i { font-size: 26px; color: var(--blue-600); }
.room-tile-label { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.25; }
.room-tile-badge { font-size: 12.5px; font-weight: 700; color: var(--muted); line-height: 1.3; min-height: 15px; }
body.big-text .room-tile-label { font-size: 15px; }
body.big-text .room-tile-badge { font-size: 12.5px; }
body.big-text .room-tile > i { font-size: 30px; }

/* ===== Man phong: 3 NHOM gap-mo (TC5 <=4 khoi, anh Quyet go `C` 04/08/2026) =====
   Dung <details> cua trinh duyet: gap/mo tuc thi (TC4 <0,4s), khong them dong JS nao,
   khong dung toi public/app.js. 🔴 Dai bam cao 48px = vung ngon cai (TC3).
   🔴 Badge canh bao cua o con noi len dai nhom khi nhom DONG; nhom MO thi an di vi
   o con da hien day du — an bang CSS, dung go dong duoi day. */
.room-nhom { margin-top: 12px; border: 1px solid var(--border); border-radius: 16px; background: var(--card); overflow: hidden; }
.room-nhom-dau { display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 10px 14px; cursor: pointer; font-size: 16px; font-weight: 700; color: var(--text); list-style: none; user-select: none; }
.room-nhom-dau::-webkit-details-marker { display: none; }
.room-nhom-mui { font-size: 18px; color: var(--muted); transition: transform .15s; }
.room-nhom[open] .room-nhom-mui { transform: rotate(90deg); }
.room-nhom-ten { flex: 1; }
.room-nhom-badge { font-size: 13px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--bg); white-space: nowrap; }
.room-nhom[open] .room-nhom-badge { display: none; }
.room-nhom .room-grid { margin: 0; padding: 0 10px 12px; }

/* ===== Man phong: DAI THE NGANG (phieu 01, anh Quyet go `a` 14/08/2026) =====
   Thay 3 nhom gap bang dai the: MOT the mo tai mot luc, than the ngay duoi dai.
   🔴 Cao 48px = vung ngon cai (TC3), giu y nhu dai bam cua nhom gap cu.
   🔴 Cuon ngang bang `overflow-x:auto` — 5 the khong vua man hep thi CUON, cam xuong
      hai hang: xuong hang la dai an mat mot phan man, dung cai vay khoi 4 khoi.
   🔴 Badge canh bao (do/cam) hien tren the DANG DONG — cung dieu kien nghiem thu cua
      nhom gap cu. The dang mo an badge di vi than the da bay day du.
   🔴 Khoi nay dung TRUOC khoi "CHU >=16px" nen duoc khai font-size (mucruot 4b). */
/* 🔴 THE CUOI PHAI LO RA O MEP PHAI (anh Quyet yeu cau 14/08/2026). Khuat han thi
      "Tai san & viec" thanh O AN — nguoi khong biet con cuon duoc, dung bang mat luon
      mot the. Hai lop giu dieu do, GIU CA HAI:
      ① `padding-right` chua san mot khoang o mep phai, nen the cuoi khong the dung khit
         canh man roi trong nhu het danh sach.
      ② `mask-image` lam mo dan 28px cuoi ⇒ luon co mot mep bi cat, mat doc ra ngay la
         "con nua ben phai". Trinh duyet cu khong hieu `mask` thi van con lop ①.
      🔴 KHONG doi sang `flex-wrap: wrap`: xuong hai hang la dai an mat mot phan man,
         dung cai vay khoi 4 khoi cua TC5.
      ③ 🔴 THE THU 4 PHAI LO RA 10-12px (dot D phieu 10, 15/08/2026). Hai lop tren van
         CHUA DU: anh Quyet nhin ban v142 bang mat va noi lop mo 28px "nhin khong nhan ra"
         — no phu len nen TRANG cua the nen gan nhu vo hinh. Do that o kho 375px: khung het
         o 347, the "Hop dong" het o 344, the "Giay to" bat dau o 352 => MEP KHUNG ROI DUNG
         VAO KHE TRONG 8px => KHONG the nao lo ra, nhin nhu dai chi co 3 the.
         Chua bang HAI CON SO duoi day, KHONG doi thiet ke:
           `gap` 8 -> 5px  va  dem ngang `.the-o` 14 -> 13px
         Cong lai keo the thu 4 sang trai 3x3 + 3x2 = 15px => bat dau o 337 => lo ra 10px.
         🔴 DUNG HA THEM cho "ro hon": gap 2px la the dinh nhau, ro TC ve khoang cach.
         🔴 DUNG DO O KHUNG RONG HON 375px — khung rong hon thi TU KHAC co lo, do o 432px
         thay lo 81px roi tuong dat. Chi 375px moi la canh that.
      Rao chan: routes/dai-the-lo-mep.test.js + tools/thu-rieng-dai-the.js (keo THAT) */
.dai-the { display: flex; gap: 5px; margin-top: 12px; overflow-x: auto; padding-bottom: 4px; padding-right: 28px; -webkit-overflow-scrolling: touch; scrollbar-width: none; scroll-padding-right: 28px; -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%); mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%); }
.dai-the::-webkit-scrollbar { display: none; }
/* Cuon toi cuoi thi bo lop mo di — het that roi ma con mo la nguoi cu keo mai. */
.dai-the.het-phai { -webkit-mask-image: none; mask-image: none; }
.the-o { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; min-height: 48px; padding: 10px 13px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); color: var(--text); font-family: inherit; font-size: 16px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: transform .06s, border-color .12s; }
.the-o:active { transform: scale(.97); }
.the-o > i { font-size: 20px; color: var(--blue-600); }
.the-o.on { border-color: var(--blue-600); background: var(--blue-50); font-weight: 700; }
.the-o.on > i { color: var(--blue-600); }
.the-badge { font-size: 13px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--bg); }
.the-o.on .the-badge { display: none; }
#the-than .room-grid { margin-top: 12px; }

/* ==========================================================================
   TANG 3 — KHUON DUNG CHUNG (Cham la thuong TC8 nhat quan + TC10 dep co chu dich)
   Truoc v58 moi man tu che the/hang/o-nhap/trang-thai-rong bang inline style
   voi mau cung lac bo mau -> "roi". Tu v58: MOI man tang 3 dung dung cac class
   duoi day, cam de inline style mau moi.
   ========================================================================== */

/* O nhap chuan — thay 5 chuoi inline style trung nhau o m6/m8/m9/sdv */
.inp { width: 100%; box-sizing: border-box; border: 1px solid var(--vien-o-nhap); border-radius: 12px; padding: 13px 14px; font-size: 16px; min-height: 48px; font-family: inherit; background: var(--card); color: var(--text); }
.inp:focus { outline: none; border-color: var(--blue-600); }
textarea.inp { min-height: 84px; line-height: 1.55; }
body.big-text .inp { font-size: 18px; min-height: 52px; }

/* Cau dan 1 dong dau moi tang 3 — TC1 nhin-3-giay */
.lead { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 2px 2px 10px; }
body.big-text .lead { font-size: 15.5px; }

/* Khoi noi dung tang 3 */
.panel { background: var(--card); border-radius: 16px; padding: 14px 15px; margin-bottom: 12px; box-shadow: var(--bong-the, 0 1px 4px rgba(40,32,18,.05)); }
.panel-head { display: flex; align-items: center; gap: 7px; font-size: 15px; font-weight: 700; margin-bottom: 8px; }
.panel-head i { color: var(--blue-600); font-size: 19px; }

/* Hang danh sach chuan — thay 5 kieu hang khac nhau (m3/m6/m8/m9/sdv) */
.line { background: var(--card); border-radius: 14px; padding: 12px 13px; margin-bottom: 8px; box-shadow: var(--bong-the, 0 1px 3px rgba(40,32,18,.05)); }
.line-top { display: flex; align-items: flex-start; gap: 11px; }
.line-ico { width: 38px; height: 38px; border-radius: 12px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 19px; background: var(--blue-50); color: var(--blue-600); }
.line-ico.green { background: var(--green-bg); color: var(--green); }
.line-ico.red { background: var(--red-bg); color: var(--red); }
.line-ico.amber { background: var(--amber-bg); color: var(--amber); }
.line-mid { flex: 1; min-width: 0; }
.line-mid b { font-size: 15.5px; font-weight: 600; display: block; line-height: 1.35; }
.line-mid small { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; line-height: 1.5; }
.line-right { text-align: right; white-space: nowrap; flex-shrink: 0; }
.line-right b { font-size: 15.5px; }
.line-right small { display: block; color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.line-act { display: flex; gap: 8px; margin-top: 10px; }
.line-act > * { flex: 1; margin: 0; }
.line.off { opacity: .55; }
/* Cai dat tang 1 (TC17): gia tri hien tai nam ben PHAI moi dong.
   ⚠️ ĐỪNG cho xuong dong (white-space: normal) va dung bo max-width chat:
   do 31/07 tren may 390px, cot phai an 118px thi .line-mid con 128px -> CA ten LAN dong phu
   deu xuong 2 dong, hang cao 120px thay vi 73px. Giu nowrap goc, chuoi qua dai thi cat "…"
   — va rut ngan chuoi ngay tu badgeNhomCaiDat() de khong bao gio phai cat.
   🔴 SUA 03/08/2026 — `max-width: 50%` LA GOC BENH, anh Quyet bat bang ngon tay.
   O day .line-right la o luoi nam trong cot `auto`, ma cot `auto` lai tu co theo noi dung
   con: "50% cua chinh no" thanh vong luan quan, trinh duyet giai ra be ti. Ket qua do duoc:
   "0900…794" con "078…", "Chua co" con "Chu…", "Da co" con "Đ…" — gia tri hien tai o tang 1
   thanh vo nghia, dung thu TC17 bat phai co.
   Thay bang tran PIXEL that: 108px du cho 11 ky tu o 15.5px/600. Doi so nay thi phai doi ca
   tran ky tu trong badgeNhomCaiDat() — co bai canh trong routes/cai-dat-tang-1.test.js. */
#settings-hub .line-right { max-width: 108px; overflow: hidden; text-overflow: ellipsis; }
/* Bo cuc hang Cai dat tang 1 — 2 HANG, kieu man Cai dat iPhone:
     [icon]  Ten nhom          gia tri hien tai  ›
             dong phu tran suot be ngang
   Ban dau xep 1 hang bang flex: cot phai an 118px + icon 38 + mui 20 + 3 khe 11px
   => con 127px cho ten, CA ten LAN dong phu deu xuong 2 dong, hang cao 120px.
   Chuyen sang luoi: dong phu xuong hang 2 nen khong tranh cho voi cot phai nua.
   ⚠️ Chi ap trong #settings-hub — .line la khuon dung chung cua 12 man khac. */
#settings-hub .line-top {
  display: grid; grid-template-columns: 38px 1fr auto 20px;
  grid-template-areas: "ico ten phai mui" "gap phu phu ."; align-items: center;
  column-gap: 11px; row-gap: 2px;
}
#settings-hub .line-mid { display: contents; }
#settings-hub .line-ico { grid-area: ico; }
#settings-hub .line-mid b { grid-area: ten; }
#settings-hub .line-mid small { grid-area: phu; margin-top: 0; }
#settings-hub .line-right { grid-area: phai; }
#settings-hub .ov-mui { grid-area: mui; }
/* Noi dung thu trong hop thu: mac dinh gon 2 dong, bam "Xem them" moi bung het */
.thu-body { display: block; white-space: pre-line; }
.thu-body.gon { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
body.big-text .line-mid b, body.big-text .line-right b { font-size: 17.5px; }
body.big-text .line-mid small { font-size: 15px; }

/* Nhan trang thai — dung chung 4 mau cua bo mau, cam mau la */
/* 12.5px la san duoi: tep 45-65 tuoi doc 11px rat met (TC10 + 7.7 JMIR). */
.tag { display: inline-block; font-size: 12.5px; font-weight: 700; padding: 2px 9px; border-radius: 999px; line-height: 1.7; vertical-align: middle; background: var(--card-2); color: var(--muted); }
.tag.green { background: var(--green-bg); color: var(--green); }
.tag.red { background: var(--red-bg); color: var(--red); }
.tag.amber { background: var(--amber-bg); color: var(--amber); }
.tag.blue { background: var(--blue-50); color: var(--blue-800); }
body.big-text .tag { font-size: 13px; }

/* So co ngu canh — TC12: khong bao gio hien so tran trui */
.stat-row { display: flex; gap: 10px; flex-wrap: wrap; }
.stat { flex: 1 1 150px; background: var(--card); border-radius: 16px; padding: 13px 15px; box-shadow: var(--bong-the, 0 1px 4px rgba(40,32,18,.05)); }
.stat-lb { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--blue-600); }
.stat-vl { font-size: 20px; font-weight: 800; color: var(--text); margin-top: 5px; line-height: 1.2; }
.stat-cx { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
body.big-text .stat-vl { font-size: 23px; }
body.big-text .stat-cx { font-size: 14px; }

/* Hang doi chieu label-gia tri trong panel */
.kv { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-top: 1px solid var(--border); }
.kv span { font-size: 13.5px; color: var(--muted); }
.kv b { font-size: 14px; white-space: nowrap; }
body.big-text .kv span { font-size: 15px; }
body.big-text .kv b { font-size: 16px; }

/* Trang thai rong AM — TC6 noi tieng nguoi, TC15 dung 1 trong 4 khoanh khac */
.trong { text-align: center; padding: 34px 18px; color: var(--muted); }
.trong i { font-size: 40px; opacity: .45; color: var(--blue-600); }
/* Hinh man trong co lon (8 hinh trong hinh-man-trong.svg) — thay icon phong to.
   Hinh mang mau CO DINH, khong theo currentColor ⇒ khong dat opacity o day. */
.trong .hinh-trong { display: block; width: 120px; height: 96px; margin: 0 auto; }
.trong p { margin-top: 10px; font-size: 14.5px; line-height: 1.6; }
.trong .btn-primary, .trong .btn-secondary { max-width: 280px; margin: 14px auto 0; }
body.big-text .trong p { font-size: 16.5px; }

/* Cho co ke viec — TC13 labor illusion: luon noi dang lam GI, khong vong xoay cam */
.dangcho { display: flex; align-items: center; gap: 10px; justify-content: center; padding: 26px 14px; color: var(--blue-800); font-size: 14.5px; }
body.big-text .dangcho { font-size: 16.5px; }

/* ---- KHUNG XÁM CHỜ DỮ LIỆU (04/08/2026 — phiếu 46 việc V5) ----
   Thay cho một dòng chữ "Đang tải" giữa màn trắng: vẽ sẵn hình hài của nội dung sắp tới nên
   mắt thấy màn ĐÃ CÓ GÌ ĐÓ, quãng chờ cảm giác ngắn hơn hẳn. Vẫn giữ 1 dòng chữ kể việc
   THẬT phía trên (TC13) — khung xám không thay được lời kể, hai thứ đi cùng nhau.
   Nhịp thở chậm (1,4s) và mờ nhẹ: nhấp nháy mạnh làm người lớn tuổi hoa mắt (TC16). */
.xam-nhom { padding: 4px 0 2px; }
.xam { height: 62px; border-radius: 14px; margin-bottom: 10px; background: var(--border); opacity: .55; animation: xam-tho 1.4s ease-in-out infinite; }
.xam.cao { height: 96px; }
.xam.thap { height: 34px; }
@keyframes xam-tho { 0%, 100% { opacity: .38; } 50% { opacity: .62; } }
@media (prefers-reduced-motion: reduce) { .xam { animation: none; opacity: .5; } }

/* ---- ICON CHỜ FONT (30/07/2026) ----
   Font icon nặng 878KB. Mạng chậm thì hết 3 giây chờ mặc định của trình duyệt, ký tự icon
   (nằm ở vùng dùng riêng của font) bị font hệ thống vẽ thành KÝ TỰ LẠ cạnh chữ — anh Quyết
   báo thấy ký tự lạ cạnh "Dọn dẹp" trong ô đăng tin. Ẩn glyph tới khi font sẵn sàng:
   dùng visibility nên vẫn giữ đúng chỗ, chữ không nhảy. Bật cờ .san-icon ở cau-hinh-app.js. */
html:not(.san-icon) .ti::before { visibility: hidden; }

/* ==========================================================================
   KHUNG CHUNG MỌI VAI + CHUẨN GIAO DIỆN iOS (31/07/2026)
   Đi cùng file dieu-huong.js. Đặt cuối file để gộp nhánh ít đụng nhau.
   ========================================================================== */

/* --- 1. THANH TAB 5 Ô: mọi vai giống nhau, không còn nút tròn nhô lên --- */
.tabbar button { width: auto; flex: 1 1 0; min-width: 0; gap: 4px; font-weight: 500; }
.tabbar button span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.tabbar button i { font-size: 23px; transition: transform .16s ease-out; }
/* Ô đang mở: khác cả MÀU lẫn ĐỘ ĐẬM (trước chỉ khác màu — chuẩn Apple đòi cả hai) */
.tabbar button.active { color: var(--blue-800); font-weight: 700; }
.tabbar button.active i { transform: scale(1.06); }
.tabbar button:active i { transform: scale(.9); }
/* Nút nổi "Tiện ích" nay là ô số 5 — chặn cứng để module cũ không dựng lại cửa thứ hai */
#tien-ich-fab { display: none !important; }

/* --- 2. NÚT LÙI: nút thật, đủ 44px, có chữ --- */
.nut-lui {
  display: inline-flex; align-items: center; gap: 2px;
  min-height: 44px; min-width: 44px; padding: 0 8px 0 0; margin-left: -6px;
  border: none; background: none; cursor: pointer;
  font-family: inherit; font-size: 16px; font-weight: 500; color: var(--blue-800);
  vertical-align: middle;
}
.nut-lui i { font-size: 24px; margin-right: -2px; }
.nut-lui span { max-width: 116px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nut-lui:active { opacity: .55; }
.page-title .nut-lui { font-size: 16px; }

/* --- 3. BẢNG KÉO: tay kéo + nút chữ "Xong" + vuốt xuống đóng --- */
.sheet-grab {
  width: 36px; height: 5px; border-radius: 3px; background: var(--border);
  margin: -8px auto 10px; flex: 0 0 auto;
}
.sheet-xong {
  border: none; background: none; cursor: pointer; font-family: inherit;
  font-size: 16px; font-weight: 500; color: var(--blue-800);
  min-height: 44px; min-width: 44px; padding: 0 2px;
}
.sheet-xong:active { opacity: .55; }
.overlay.active .sheet { animation: sheet-len .26s cubic-bezier(.22,.61,.36,1); }
@keyframes sheet-len { from { transform: translateY(22px); } to { transform: translateY(0); } }

/* --- 4. Ô NHẬP KIỂU DANH SÁCH GOM NHÓM (grouped list) --- */
/* iOS không viền từng ô: cả nhóm là một thẻ trắng, các ô ngăn nhau bằng vạch mảnh. */
#scr-settings .card input,
#scr-settings .card select,
#scr-settings .card textarea {
  border: none; border-bottom: 1px solid var(--vien-o-nhap); border-radius: 0;
  padding: 12px 2px; margin: 0; background: transparent; min-height: 48px;
}
#scr-settings .card input:last-of-type,
#scr-settings .card select:last-of-type { border-bottom: none; }
#scr-settings .card input:focus,
#scr-settings .card select:focus,
#scr-settings .card textarea:focus { outline: none; border-bottom-color: var(--blue-600); }
#scr-settings .card label,
#scr-settings .o-nhap > label {
  display: block; font-size: 12.5px; color: var(--muted); margin: 10px 0 -2px;
}
#scr-settings .card { padding: 6px 16px 14px; }
#scr-settings .card > b { display: block; padding: 12px 0 2px; }

/* --- 5. TIÊU ĐỀ LỚN: to ở đầu trang, cuộn xuống thì thu về thanh nhỏ --- */
/* ⚠️ ĐỪNG cho transition vào font-size (đã trả giá 31/07): chữ bò rất chậm, và mỗi lần
   màn vẽ lại header là nó chạy lại từ đầu → tiêu đề nhấp nháy cỡ chữ. Thu nhỏ bằng
   transform: chạy trên card của trình duyệt, mượt và không đụng bố cục. */
.topbar.tieude-lon .page-title {
  font-size: 28px; letter-spacing: -.4px; line-height: 1.25;
  display: inline-block; transform-origin: left center;
  transition: transform .2s cubic-bezier(.22,.61,.36,1);
}
.topbar.tieude-lon.da-thu .page-title { transform: scale(.643); }
.topbar.tieude-lon { padding-top: 20px; }
.topbar.tieude-lon.da-thu {
  position: sticky; top: 0; z-index: 30; background: var(--bg);
  padding-top: calc(8px + env(safe-area-inset-top)); padding-bottom: 8px;
  border-bottom: 1px solid var(--border); margin: 0 -14px; padding-left: 14px; padding-right: 14px;
}
body.big-text .topbar.tieude-lon .page-title { font-size: 31px; }

/* --- 6. TAY CHẠM MƯỢT --- */
/* Cuộn có đà như app thật + không dính vệt xám khi chạm */
body { -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain; }
.screen { transform: translateZ(0); }
/* Màn mới trượt vào từ phải — đúng nhịp đẩy/lùi của iOS */
.screen.active { animation: man-vao .24s cubic-bezier(.22,.61,.36,1); }
@keyframes man-vao { from { opacity: .55; transform: translateX(16px); } to { opacity: 1; transform: translateX(0); } }
/* Đang kéo bằng ngón thì TẮT hiệu ứng, ảnh phải bám sát ngón mới thật tay */
.screen.dang-vuot { animation: none !important; transition: none !important; will-change: transform, opacity; }
/* Nút bấm lún nhẹ khi chạm */
.btn-primary:active, .btn-secondary:active, .chipbtn:active, .tx-item:active { transform: scale(.985); }
.btn-primary, .btn-secondary, .chipbtn, .tx-item { transition: transform .09s ease-out; }
/* Vùng chạm tối thiểu cho mọi ô danh sách */
.tx-item { min-height: 48px; }
/* Chữ không bị bôi đen khi vuốt nhanh */
.tabbar, .sheet-head, .nut-lui, .topbar { -webkit-user-select: none; user-select: none; }
/* Máy nào tắt hiệu ứng cho đỡ chóng mặt thì tôn trọng cài đặt đó */
@media (prefers-reduced-motion: reduce) {
  .screen.active, .overlay.active .sheet { animation: none; }
  .topbar.tieude-lon .page-title, .tabbar button i { transition: none; }
}
/* Mốc vô hình cho tiêu đề lớn — cao 1px, không chiếm chỗ nhìn thấy */
.tieude-moc { height: 1px; margin-bottom: -1px; pointer-events: none; }

/* ==========================================================================
   HUB NHÀ CHO THUÊ — 4 KHỐI (Gác Chuẩn 31/07/2026, anh Quyết chốt gói C)
   Trước: 8 khối rời (6 ô số + 2 banner + hộp duyệt + 2 nút + thẻ hết hạn + lưới).
   Nay: thẻ số · thẻ việc gấp · lưới ô · thanh hành động dính đáy = 4 khối (TC5).
   ========================================================================== */

/* --- Khối 1: thẻ số gộp. 6 ô rời cũ nay là 5 hàng trong MỘT thẻ trắng --- */
.ov-hang { display: block; padding: 12px 0; border-top: 1px solid var(--border); min-height: 48px; cursor: pointer; }
.ov-tong > b + .ov-hang { border-top: none; padding-top: 2px; }
.ov-hang:active { opacity: .6; }
.ov-hang-tren { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ov-nhan { font-size: 16px; color: var(--muted); }
.ov-gia { font-size: 19px; font-weight: 700; white-space: nowrap; text-align: right; }
.ov-phu { display: block; font-size: 16px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
body.big-text .ov-nhan, body.big-text .ov-phu { font-size: 18px; }
body.big-text .ov-gia { font-size: 22px; }

/* --- Khối 2: VỎ "việc đang chờ anh" — gộp hộp chờ duyệt + thẻ việc gấp (12/08/2026) ---
   Vì sao có vỏ này: màn Nhà của chu-nha đo được 5–6 khối / trần 4 (bảng 12/08). Hai thứ
   "đang chờ anh xử lý" trước đây nằm rời thành hai khối. Nay ngồi chung một vỏ ⇒ 4 khối.
   🔴 GỘP KHỐI, KHÔNG GỘP THẺ: #pending-box vẫn nằm NGOÀI thẻ mà khoiDauTheHTML() thay
   cho, nên luật 09/08 (hộp chờ duyệt không được biến mất cùng thẻ kia) còn nguyên.
   🔴 KHỐI NÀY LÀM PHẲNG THẺ CON — bỏ nó là hiện ra hai lớp viền lồng nhau, nhìn như lỗi.
   Thẻ con GIỮ class `card` vì bài [3.5] routes/khoi-dau.test.js soi đúng chuỗi đó.
   🔴 Vỏ tự xẹp khi rỗng: chưa Dựng nhà xong thì khoiDauTheHTML() trả thẻ, luôn có ruột;
   nhưng nếu cả hai cùng rỗng thì `:empty` cho vỏ biến mất, khỏi để lại một ô trắng trơ. */
.ov-canlam { padding: 0; background: transparent; box-shadow: none; border: 0; }
.ov-canlam:empty { display: none; }
.ov-canlam > #pending-box:empty { display: none; }
.ov-canlam > .card { margin: 0; }
.ov-canlam > #pending-box:not(:empty) + .card { margin-top: 12px; }

/* --- Khối 2b: thẻ việc gấp. Mỗi việc là một hàng, cả hàng là vùng chạm --- */
.ov-gap { border-left: 4px solid var(--amber); border-radius: 4px 16px 16px 4px; }
.ov-gap > b { color: var(--amber); }
.ov-gap-rong { border-left-color: var(--green); }
.ov-gap-rong > b { color: var(--green); }
.ov-viec { display: flex; align-items: center; gap: 11px; background: var(--card); border-radius: 14px; padding: 12px; margin-top: 8px; box-shadow: var(--bong-the, 0 1px 3px rgba(40,32,18,.05)); cursor: pointer; min-height: 48px; }
.card .ov-viec { background: transparent; box-shadow: var(--bong-the, none); border-radius: 0; margin-top: 0; padding: 12px 0; border-top: 1px solid var(--border); }
.ov-viec:active { opacity: .6; }
/* Hang viec CO nut hanh dong — xep HAI TANG (anh Quyet chot phuong an B, 03/08/2026).
   Goc benh: .ov-viec la flex MOT tang, .line-mid de `flex: 1` nen chi nhan phan THUA.
   Hang hop dong sap het han deo them nhan han + nut "Hoi o tiep" => o chu con vai chuc px,
   ten toa roi doc tung chu mot. Anh Quyet bat bang ngon tay tren ancu.app v104.
   🔴 DUNG go `flex-basis: 100%` cua .ov-viec-act — chinh no ep hang duoi xuong tang rieng.
   🔴 DUNG ap flex-wrap cho .ov-viec CHUNG: hai hang kia (chua co tai khoan · con no) chi co
      3 o va o thu 3 la mui ten `>`, wrap chung se rung mui ten xuong dong.
   margin-left 49px = 38px be ngang .line-ico + 11px gap => tang duoi thang hang voi chu. */
.ov-viec-2tang { flex-wrap: wrap; row-gap: 8px; }
.ov-viec-2tang .line-mid { flex: 1 1 auto; }
.ov-viec-act { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: 49px; }
.ov-viec-act .chipbtn { margin: 0; }
.ov-mui { color: var(--muted); font-size: 20px; flex-shrink: 0; }
.ov-nhom-ten { display: flex; align-items: center; gap: 7px; color: var(--blue-800); font-size: 16px; padding: 12px 0 2px; border-top: 1px solid var(--border); }
.ov-tong > b + .ov-nhom .ov-nhom-ten, .card > b + div > .ov-nhom-ten { border-top: none; padding-top: 4px; }
.ov-xem-tat-ca { margin-top: 12px; }

/* --- Khối 4: thanh hành động dính đáy. Nút chính luôn trong tầm ngón cái (TC3) --- */
/* Sticky chứ KHÔNG fixed: nằm trong luồng nên không cần chừa chỗ thủ công, và không
   đụng luật "màn phụ cấm treo nút nổi" (v59) — đây không phải FAB. */
.thanh-hanh-dong {
  position: sticky; bottom: calc(84px + env(safe-area-inset-bottom)); z-index: 35;
  display: flex; gap: 8px; margin: 14px -14px 0; padding: 10px 14px calc(4px + env(safe-area-inset-bottom));
  background: var(--bg); border-top: 1px solid var(--border);
}
.thanh-hanh-dong .btn-primary, .thanh-hanh-dong .btn-secondary { flex: 1; margin: 0; }
/* Hop thu vao: luoi anh xem truoc. Chi layout, khong dat mau moi. */
.htv-anh { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.htv-o { width: 72px; height: 72px; border-radius: 12px; object-fit: cover;
  background: var(--card-2); display: flex; align-items: center; justify-content: center; }


/* ==========================================================================
   CHỮ ≥16px TOÀN APP (TC10 — tệp 40–65 tuổi, anh Quyết chốt gói C 31/07/2026)
   Đặt CUỐI file để đè các khai báo cũ mà không phải sửa 45 dòng rải rác —
   dòng cũ giữ nguyên làm dấu vết. Chỗ nào KHÔNG nâng được thì ghi rõ lý do.
   ========================================================================== */
.muted, .err, .avatar, .login-tag, .section-head a, .empty,
.wallet-chip small, .wallet-chip b, .book-sum small, .book-sum b,
.tx-mid small, .tx-amt, .tx-day-head, .io-row,
input[type="month"], input[type="date"],
.card > b, .report-cards small, .btn-danger, .btn-ghost, .scan-msg,
.chat-input input, .msg.note, .sheet label, .seg button, .seg-btn, .rstat-btn,
.chipbtn, .chipbtn.act, .cs-detail, .lead, .panel-head,
.line-mid b, .line-mid small, .line-right b, .line-right small,
.tag, .stat-lb, .stat-cx, .kv span, .kv b, .trong p, .dangcho,
.room-tile-label, .room-tile-badge, .rstat, .rstat-legend .rstat,
.quick-grid button, #scr-settings .card label, #scr-settings .o-nhap > label {
  font-size: 16px;
}
/* Vài chỗ cần to hơn 16px để giữ thứ bậc thị giác (số tiền, tiêu đề nhóm) */
.tx-amt, .line-mid b, .line-right b { font-size: 17px; }
.card > b, .panel-head { font-size: 17px; }
/* Nhãn tròn (tag/rstat) 16px thì viên bị bè — nới đệm cho cân */
.tag, .rstat { padding: 3px 11px; line-height: 1.5; }
.chipbtn { min-height: 48px; }
.chipbtn.act { min-height: 48px; }
/* Ô lưới phòng 3 cột: nhãn 16px vừa đúng bề ngang, badge xuống dòng được */
.room-tile { min-height: 104px; }
.room-tile-badge { line-height: 1.3; }
/* Thanh tab 5 ô: 16px chỉ vừa khi nhãn ≤5 chữ cái — nhãn dài đã rút trong dieu-huong.js */
.tabbar button { font-size: 16px; }
/* Do 31/07: o tab rong 78px tren may 390px. O 16px, "Phong toi" 75px va "Bao hong" 75px
   deu cham vach — siet khoang cach chu 0,2px la vua, khong phai rut chu. "Gio phong" 81px
   khong cuu duoc bang cach nay nen da rut con "Gio" trong dieu-huong.js. */
.tabbar button span { font-weight: 500; letter-spacing: -.2px; }
body.big-text .tabbar button { font-size: 17px; }
/* GIỮ NGUYÊN, KHÔNG nâng: .quick-grid nhãn 4 cột (nâng riêng ở trên, có line-height 1.3),
   .balance (đã 30px), .page-title (18px là tiêu đề, không phải thân chữ). */
/* Thẻ <small> TRẦN (không class, không style) bị trình duyệt tự thu còn 0.83em = 14,2px —
   đo được 18 chỗ ở màn tòa nhà. Cho nó bằng cỡ chữ của cha; chỗ nào muốn nhỏ hơn thì
   phải khai class riêng. Độ đặc hiệu 0,0,1 nên KHÔNG đè lên các class đã có cỡ. */
small { font-size: 1em; }

/* ─────────────────────────────────────────────────────────────────────────────
   TC8 NHẤT QUÁN + TC3 VÙNG NGÓN CÁI — vá 2 chỗ người thử bắt được 02/08/2026.
   Khối này để CUỐI FILE có chủ đích, sau khối "CHỮ ≥16px", vì nó chỉ đè MÀU và
   KÍCH THƯỚC CHẠM — không đụng font-size, nên không phá luật chữ ≥16px ở trên.
   ───────────────────────────────────────────────────────────────────────────── */

/* ① Ô tích (checkbox) đang dùng màu xanh dương mặc định của trình duyệt — lạc hẳn
      khỏi bảng màu xanh lá / cam của app. Người thử bắt ở ô "Bật chữ to hơn", nhưng
      app có 12 ô tích rải 7 file ⇒ sửa một chỗ cho tất cả, đừng vá riêng ô đó.
      Dùng biến màu, KHÔNG gõ mã màu thẳng (rào chắn mau-bien-css.test.js). */
input[type="checkbox"], input[type="radio"] { accent-color: var(--blue-800); }

/* ② Nút con mắt ẩn/hiện số dư nằm trong thẻ <small> nên vùng chạm bé xíu —
      bấm hay trượt, người thử tưởng nút hỏng. Nút phụ phải ≥44px (số đo cứng 0a). */
#eye-btn {
  min-width: 44px;
  min-height: 44px;
  border: none;
  background: none;
  color: inherit;
  cursor: pointer;
  vertical-align: middle;
}

/* ③ DÒNG GẬP (<details>/<summary>) — TC1 "nhìn 3 giây là hiểu", vá 03/08/2026.
      Bốn dòng gập ở màn Mã xác minh đặt `display:flex` ngay trên <summary>. Theo chuẩn
      HTML, marker tam giác chỉ vẽ khi summary còn `display: list-item` — đổi sang flex là
      trình duyệt BỎ marker. Kết quả: bốn dòng trông y hệt nhãn tĩnh, không nền, không mũi
      tên; người thử không biết bấm được nên tưởng màn thiếu ô nhập.
      Sửa bằng nền + mũi tên THẬT (<i class="ti ti-chevron-down" class="gap-mui">), KHÔNG
      dùng ::after với mã glyph — font Tabler đã có tiền lệ thiếu glyph và render ô vuông.
      Chỗ gập nào giữ marker mặc định (giu-coc.js, rental.js) thì không cần class này. */
details.gap { border-top: 1px solid var(--border); padding: 8px 0; }
details.gap > summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 48px;
  padding: 0 14px;
  border-radius: 12px;
  background: var(--blue-50);
  color: var(--blue-800);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}
details.gap > summary::-webkit-details-marker { display: none; }
details.gap > summary .gap-mui { font-size: 20px; flex: 0 0 auto; transition: transform .15s ease-out; }
details.gap[open] > summary .gap-mui { transform: rotate(180deg); }

/* ④ THANH ĐẦU MÀN CHÍNH — chống tràn ngang, vá 03/08/2026.
      Đo trên khổ 375px: thanh chứa [lời chào 103px] + [3 nút icon 148px] + [nút hướng dẫn
      90px] + 2 khe 10px + đệm 4px = 365px, trong khi thanh chỉ rộng 347px ⇒ dư 18px.
      ⚠️ Số 90px đo hồi 03/08 khi nhãn nút còn là "Chỉ tôi". Nhãn đổi thành "Cách làm"
      ngày 05/08 (dài hơn 1 ký tự) ⇒ phần dư nhích lên, và chỗ co vẫn là LỜI CHÀO đúng
      như khối này định — không phát sinh cuộn ngang vì lời chào đã cắt bằng ellipsis.
      Trước đây nút hướng dẫn tự co nên hai chữ bị bẻ xuống hai dòng (lỗi #7). Cho nút thôi
      co thì hết gãy chữ, nhưng phần dư đẩy ra ngoài mép và CẢ TRANG cuộn ngang được 2px —
      đúng bệnh "app cuộn ngang trên màn 375" mà sổ ghi treo lâu nay.
      Chỗ đáng co là LỜI CHÀO, không phải nút: lời chào cắt bớt vẫn hiểu, nút cắt thì mất
      nghĩa. `min-width: 0` là mấu chốt — mặc định flex item không co dưới min-content nên
      dù khai `flex: 0 1 auto` nó vẫn cứng đơ. */
.topbar .hello { min-width: 0; }
.topbar .hello > div:last-child { min-width: 0; }
.topbar .hello small,
.topbar .hello b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }

/* ⑤ THANH ĐẦU TRANG — CHẶN TRÀN TẬN GỐC (03/08/2026, phiên chữa cuộn ngang).
      Khối ④ ngay trên chỉ chữa ĐÚNG ô lời chào ở màn chính, không rà chỗ cùng dạng,
      nên hai màn khác vẫn tràn. Gốc bệnh chung: flex item mặc định `min-width: auto`
      ⇒ KHÔNG co dưới bề rộng nội tại của chính nó, dù khai `flex: 0 1 auto`.
      Số đo thật trước khi vá (khổ 375px, đã ép animation chạy xong):
        màn Sổ tràn 21px · màn Báo cáo tràn 16px · 6 màn còn lại 0px.
      Thủ phạm là `input[type=month]`: Chrome cho nó bề rộng nội tại 251px (kèm nút lịch).
      251 + tiêu đề 56 + nút chuông 44 + 2 khe 10 = 371px, trong thanh chỉ rộng 347px
      ⇒ nút chuông bị đẩy ra x=387, rồi `nav.tabbar` (fixed, `width: 100%`) nở theo khổ
      đã tràn ⇒ CẢ TRANG cuộn ngang. Tabbar là hệ quả, không phải nguyên nhân.
      Luật chữa: ai cũng được co, TRỪ nút và nhóm nút — nút co lại là mất nghĩa và tụt
      dưới 44px (TC3). Ô nhập co bớt vẫn đọc được ngày tháng. */
.topbar > * { min-width: 0; }
.topbar > button, .topbar > a, .topbar > .iconbtn, .topbar > div { flex: 0 0 auto; }
.topbar > .hello { flex: 0 1 auto; }

/* ==========================================================================
   ⑥ THANH ĐẦU TRANG — CO THÌ PHẢI CẮT, KHÔNG ĐƯỢC TRÀN ĐÈ HÀNG XÓM
   (06/08/2026, trả 2 nợ kỹ thuật ghi trong sổ chốt 05/08 khối ~23:3x)
   --------------------------------------------------------------------------
   Khối ⑤ ngay trên mở đường cho mọi con của `.topbar` CO LẠI (`min-width: 0`),
   nhưng KHÔNG nói co xong thì cắt thế nào, cũng KHÔNG nói co tới đâu là dừng.
   Hai nợ đều mọc từ đúng chỗ hở đó.

   NỢ 1 — TIÊU ĐỀ TRÀN RA ĐÈ NÚT. `.page-title` có `nowrap` (cố ý, xem dòng 66)
   nhưng KHÔNG có `overflow: hidden` ⇒ hộp co lại mà chữ cứ vẽ tiếp ra ngoài, phủ
   lên nút bút chì bên phải. Đối chứng ngay trong file: `.topbar .hello b` ở khối ④
   có ĐỦ BỘ BA (hidden + ellipsis + nowrap) nên không bao giờ tràn — `.page-title`
   chính là chỗ CÙNG DẠNG bị sót khi chữa khối ④.
   Số đo thật trước khi vá (Chrome headless, sân kho rỗng, tên tòa giả 32 ký tự):
     khổ 360 · chi tiết tòa   chữ 381px trong hộp 220px ⇒ tràn 161, ĐÈ TRỌN nút 44px
     khổ 360 · chi tiết phòng chữ 435px trong hộp 220px ⇒ tràn 215, ĐÈ TRỌN nút 44px
     khổ 375 · hai màn đó     tràn 146 và 200, vẫn đè trọn nút 44px
     khổ 360 · Hộp thư · Cài đặt tràn 6px ⇒ diện RỘNG HƠN 2 màn sổ chốt đã ghi.
   Rà cả màn bằng máy (duyệt mọi phần tử `nowrap` không cắt, so bề rộng chữ đo bằng
   Range với bề rộng hộp) trên 8 màn: CHỈ `.page-title` tràn, không cái nào khác
   ⇒ một luật ở đây là chữa hết diện, khỏi vá từng màn.
   🔴 `overflow: hidden` CẮT CẢ CHIỀU DỌC — và chữ Việt thì cao hơn dòng chữ. Đo bằng
      canvas trên chính phông app (chuỗi có đủ dấu đội trên lẫn dấu móc dưới):
        cỡ 18px · dòng 24.3px · MỰC 27px   ⇒ mực vượt hộp 2,7px
        cỡ 28px · dòng 35px   · MỰC 40px   ⇒ mực vượt hộp 5px  (tiêu đề lớn ở màn gốc)
      ⇒ chỉ nâng `line-height` là KHÔNG đủ. Phải nới hộp cắt bằng đệm dọc rồi KÉO LẠI
      bằng lề âm cùng số — vùng cắt cao thêm 12px, bố cục không dịch một pixel nào
      (cùng mẹo đã dùng cho `.section-head a` ở khối TC3 phía dưới).
      🔴 Bỏ cặp `padding: 6px 0` + `margin: -6px 0` là dấu bị cắt cụt ngay, mà nhìn lướt
         rất giống lỗi phông — đừng "dọn cho gọn".

   NỢ 2 — Ô CHỌN THÁNG CO QUÁ ĐÀ, mất chữ số năm ("Tháng Tám 202"). Cùng gốc:
   `min-width: 0` cho nó co không đáy. Số đo thật: bề rộng nội tại của
   `input[type=month]` là 247px, nhưng màn Sổ chỉ cho 162px (khổ 360) và 170px
   (khổ 375) ⇒ hụt 85 và 77px.
   🟠 SỬA LẠI MỘT CÂU TRONG SỔ CHỐT: màn Báo cáo KHÔNG "đúng sẵn" để lấy làm đối
      chứng — nó cũng hụt 62px (khổ 360) và 52px (khổ 375), chỉ hụt ít hơn nên
      tháng có tên ngắn còn đọc được. Cùng một bệnh, khác mức.
   Cách chữa KHÔNG cắt chữ nào: cho thanh xuống hàng. Ô nhập giữ đúng bề rộng nội
   tại (`min-width: max-content` — số do trình duyệt tự tính, không phải số ma
   thuật của ta, nên đổi phông hay bật chữ to vẫn đúng), thiếu chỗ thì nó tự rơi
   xuống hàng dưới và giãn hết hàng. Khổ rộng (khung app tối đa 460px) đủ chỗ nên
   KHÔNG xuống hàng — bố cục cũ giữ nguyên.
   🔴 PHẢI LÀ CLASS RIÊNG `co-o-nhap`, ĐỪNG cho cả `.topbar` wrap: trang chủ có lời
      chào + nút chuông, wrap sẽ đẩy nút chuông xuống hàng thay vì cắt lời chào —
      flex quyết wrap TRƯỚC khi co, nên khối ④ mất tác dụng ngay.

   SÀN CẮT — bắt được bằng MẮT sau khi vá hai nợ trên, không bài test nào báo:
   cắt chữ thì hết đè nút thật, nhưng có màn bị cắt tới mức MẤT NGHĨA. Chụp ở khổ 360:
     màn Quét (tiêu đề + nút "Cách làm" + chuông)                 ⇒ "Quét chứ…"
     màn Phòng của tôi (tiêu đề + "Đổi mật khẩu" + "Cách làm" + chuông) ⇒ "P.."
   Gốc: những thanh này có 2-3 nút KHÔNG co được (đúng luật khối ⑤), nên phần bị ép
   co chỉ còn mỗi tiêu đề — mà tiêu đề là thứ nói màn này là màn gì.
   Chữa: cho tiêu đề một SÀN `min-width: 8em` (theo cỡ chữ, nên đúng cả ở tiêu đề lớn
   28px lẫn chế độ chữ to 31px), rồi cho thanh CÓ TIÊU ĐỀ được xuống hàng — hết chỗ
   thì NÚT rơi xuống hàng dưới, tiêu đề giữ nguyên nghĩa.
   🔴 Bộ chọn phải là `.topbar:has(.page-title)`, KHÔNG phải `.topbar`: trang chủ dùng
      `.hello` chứ không có `.page-title`, nên nó không dính wrap và khối ④ còn nguyên
      tác dụng. Trình duyệt quá cũ không hiểu `:has()` thì bỏ qua luật này và quay về
      cảnh "cắt ngắn" — vẫn không đè nút, tức là thoái lui an toàn.
   ========================================================================== */
.page-title {
  overflow: hidden; text-overflow: ellipsis; line-height: 1.35;
  padding: 6px 0; margin: -6px 0;      /* nới vùng cắt cho dấu, không dịch bố cục */
  min-width: 8em;                      /* SÀN — cắt tới đây là dừng, xem chú thích dưới */
}
.topbar:has(.page-title) { flex-wrap: wrap; }
.topbar.co-o-nhap { flex-wrap: wrap; }
.topbar.co-o-nhap > input { flex: 1 1 auto; min-width: max-content; }

/* ==========================================================================
   TC3 — VÙNG CHẠM CHO LINK NẰM GIỮA DÒNG CHỮ (phiên sửa tờ 39, 03/08/2026)
   --------------------------------------------------------------------------
   Thẻ <a> inline chỉ cao bằng cỡ chữ — đo thật ra ĐÚNG 20px, dù dòng chứa nó
   cao 28px. Ba chỗ đã đo hụt: "Xem tất cả" ở màn Nhà, và số điện thoại do
   goi-sdt.js tự bọc (class `sdt-nhanh`) trên dòng thư / dòng khách.
   Cách chữa: nới đệm dọc cho đủ 44px rồi KÉO LẠI bằng margin âm cùng số —
   vùng bấm to ra, bố cục không dịch một pixel nào. Đừng đổi cỡ chữ: TC3 nói
   về VÙNG CHẠM, không phải cỡ chữ (chữ đã 16px và đang đúng).
   ========================================================================== */
.section-head a, .sdt-nhanh {
  display: inline-block;
  padding: 12px 0;
  margin-top: -12px;
  margin-bottom: -12px;
  min-height: 44px;
  box-sizing: border-box;
}

/* ==========================================================================
   CHẶN TRÀN NGANG — khung app không bao giờ rộng hơn màn (tờ 40 mục 2.1,
   anh Quyết chốt phương án A ngày 03/08/2026)
   --------------------------------------------------------------------------
   Bệnh đo được ở khổ 375×812: vai cộng tác viên có thanh dưới rộng 391px ⇒
   trình duyệt di động THU NHỎ CẢ TRANG để nhét vừa (innerWidth 375 → 391) ⇒
   nhãn chữ dưới icon tụt xuống đáy 833 > 812, khuất khỏi màn. Nhìn ảnh chỉ
   thấy 4 icon trơ, không chữ — rớt TC8 (icon luôn kèm chữ) và TC1.

   Phiên trước đã dọn 6 chỗ căn giữa bằng translateX(-50%); còn 16px chưa
   truy ra nguồn. Anh Quyết chốt CHẶN Ở KHUNG thay vì truy tiếp:

   🔴 `overflow-x: clip` chứ KHÔNG PHẢI `hidden`. `hidden` tạo scroll
   container ⇒ giết mọi `position: sticky` bên trong (`.thanh-hanh-dong` là
   sticky, xem mục 4b). `clip` chặn tràn mà không tạo scroll container nên
   sticky vẫn sống. Đổi sang `hidden` là phá thanh hành động.

   Ba lớp chặn, mỗi lớp một việc:
     1. html/body — chặn mọi nguồn tràn, kể cả nguồn chưa biết tên.
     2. .tabbar — không bao giờ rộng hơn màn dù màn hẹp hơn 460px.
     3. .tabbar button — ô đang chia đều bằng `flex: 1 1 0`, nên vai 4 ô ăn
        (375−12)/4 = 93px MỖI Ô, vượt trần 78px của bộ chuẩn. `max-width` chốt
        trần lại; phần dư để `justify-content: space-around` dàn ra hai bên.
        GIỮ `flex: 1 1 0`: cơ số 0 cho ô CO được, nên dù màn hẹp bao nhiêu tổng
        vẫn vừa. Đổi sang bề rộng cố định là mở lại đường tràn.
   Rào chắn: `routes/thanh-duoi-khong-tran.test.js` tính lại bề rộng tối đa
   cho cả 8 vai. Gỡ dòng nào ở đây thì bài đó đỏ.
   ========================================================================== */
html, body { overflow-x: clip; max-width: 100%; }
.tabbar { max-width: min(460px, 100vw); box-sizing: border-box; overflow: hidden; }
.tabbar button { min-width: 0; max-width: 78px; flex: 1 1 0; }
.tabbar button span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ==========================================================================
   TC3 — LINK CHỮ ĐỨNG MỘT MÌNH: LỚP `link-cham` (tờ 40 mục 2.7, 04/08/2026)
   --------------------------------------------------------------------------
   Khối TC3 phía trên chỉ chữa 2 chỗ đã biết tên (`.section-head a`, `.sdt-nhanh`).
   Đo lại 04/08 còn 6 thẻ <a> chữ trơ cao ĐÚNG 20px: "Đổi PIN" ở thanh đầu màn
   Phòng của tôi (2 chỗ), "Quét QR trực tiếp" · "Dán chuỗi QR" · "Ký lại" ở luồng
   hợp đồng điện tử, và nút mở/gập danh sách khách ở màn Thành viên.
   Cùng thủ thuật đã dùng: nới đệm dọc cho đủ 44px rồi KÉO LẠI bằng margin âm cùng
   số ⇒ vùng bấm to ra, bố cục không dịch một pixel. KHÔNG đổi cỡ chữ (chữ đã 16px).
   Rào chắn: `routes/vung-cham-link.test.js` — thêm thẻ <a> chữ trơ mới mà quên lớp
   này thì bài đỏ.
   ========================================================================== */
.link-cham {
  display: inline-block;
  padding: 12px 0;
  margin-top: -12px;
  margin-bottom: -12px;
  min-height: 44px;
  box-sizing: border-box;
}

/* ==========================================================================
   LÀN CSS ĐỢT 4 — phiếu 52, anh Quyết bấm tay 05/08/2026
   --------------------------------------------------------------------------
   Bốn khối dưới đây cùng MỘT gốc bệnh: app đã có luật đúng, nhưng luật đó bị
   một dòng khác đè lên, hoặc chưa được kéo tới hết mọi chỗ cùng dạng.
   Rào chắn: `routes/chu-to-va-o-chon.test.js`.
   ========================================================================== */

/* ① DẢI CUỘN NGANG DÙNG CHUNG — giấu thanh cuộn xám (việc B).
      `.dai-chon` (dòng 332) đã giấu đúng cách từ 04/08, nhưng luật chỉ nằm ở
      MỘT class nên 7 chỗ cuộn ngang khác không ai kéo theo: hàng ví ở trang chủ
      quản trị (`.wallet-strip`), 4 dải ảnh trong rental.js, bảng trong bài HKD
      và PCCC. Gom 3 dòng đó ra lớp riêng để chỗ nào cũng dùng lại được —
      dải CHỌN thì dùng `.dai-chon`, dải ẢNH / bảng văn bản thì `.cuon-ngang`.
      🔴 Ai thêm dải mới: dùng lớp này, ĐỪNG tự chế `overflow-x` trong `style=`
      của file .js (bài B của rào chắn quét đúng cái đó). */
.cuon-ngang, .wallet-strip, .dai-chon {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.cuon-ngang::-webkit-scrollbar,
.wallet-strip::-webkit-scrollbar,
.dai-chon::-webkit-scrollbar { display: none; }

/* ② SỐ ĐIỆN THOẠI — không để rơi về xanh gạch chân mặc định (việc C).
      App có 3 đường hiện số: goi-sdt.js tự bọc (`.sdt-nhanh`), chỗ viết tay CÓ
      màu, và chỗ viết tay KHÔNG màu. Đường thứ ba rơi về màu xanh dương + gạch
      chân mặc định của trình duyệt — lạc hẳn bảng màu app. Đặt luật ở ĐÍCH
      (`a[href^="tel:"]`) thay vì ở từng chỗ gọi thì chỗ viết mới sau này cũng
      tự đúng. Bỏ gạch chân rồi phải bù dấu hiệu bấm được bằng icon `ti-phone`
      đứng trước số (TC8 icon luôn kèm chữ) — bài C của rào chắn canh chỗ đó. */
.sdt-nhanh, a[href^="tel:"] { color: var(--blue-600); text-decoration: none; }

/* ③ Ô CHỌN — sơn cho đều cả bộ (việc D1, anh Quyết gõ `ô chọn B`).
      🔴 Hiểu đúng giới hạn: CSS chỉ đổi được CÁI Ô LÚC ĐÓNG. Danh sách bung ra
      khi bấm là màn do Android/iOS vẽ, web KHÔNG chạm tới được — chữ bôi xanh
      ở đó vẫn còn. Muốn đổi hẳn thì phải thay bằng bảng kéo tự vẽ (vế 2 của
      phương án B), đó là việc riêng.
      Mũi tên vẽ bằng HAI mảng màu chéo nhau, KHÔNG dùng ảnh nền data-URI —
      ảnh nền buộc phải nhúng mã màu cứng vào chuỗi, mà mã cứng thì không đổi
      theo chế độ nền tối. Hai mảng này ăn `var(--muted)` nên tối/sáng đều đúng.

      🔴 VÌ SAO BỘ CHỌN CÓ CẢ `select` TRẦN chứ không chỉ `.card select`:
      11 ô chọn tự khai `style=` inline không phải vì người viết lười — mà vì
      chúng KHÔNG nằm trong `.card` hay `.sheet`. Ô "Xem tòa nào" của Báo cáo
      thuế và ô chọn của Hộ kinh doanh nằm trong `.panel`, không lớp chung nào
      với tới ⇒ gỡ `style=` mà không nới bộ chọn là ô trần trụi, mất cả viền.
      Ba mảnh trong bộ chọn có đặc hiệu khác nhau và ĐÓ LÀ CỐ Ý: `.card select`
      (0,1,1) phải đủ nặng để đè dòng 173 · `select` (0,0,1) phủ nốt chỗ còn lại.
      Bỏ mảnh `.card select` đi thì dòng 173 thắng và mũi tên đè lên chữ. */
select, .card select, .sheet select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  box-sizing: border-box;
  min-height: 48px;
  border: 1px solid var(--vien-o-nhap);
  border-radius: 12px;
  padding: 11px 34px 11px 12px;
  /* 🔴 `!important` ĐÚNG MỘT LẦN, cho ĐÚNG MỘT thuộc tính — và có lý do đo được.
     Mũi tên vẽ bằng nền thì CHỖ CỦA NÓ phải được chừa bằng đệm phải; ô nào tự khai
     `padding` trong `style=` là ăn đè, đệm tụt về 12px và CHỮ CHẠY ĐÈ LÊN MŨI TÊN.
     Đo thật trên sân 3994: `inc-kind` và `inc-prio` (form báo sự cố) ra đúng cảnh
     đó — đệm phải 12px, mũi tên nằm ở 14–19px tính từ mép.
     Hai ô đó nằm trong `public/rental.js`, file phiên `loi-tat-2-cham` đang giữ
     (anh Quyết dặn né ra 05/08) nên chưa gỡ `style=` được. Nhưng dòng này KHÔNG
     phải để vá riêng hai ô: chỗ nào lỡ khai `padding` inline sau này cũng dính,
     và đó mới là gốc. Gỡ `style=` xong thì dòng này thành vô hại, ĐỪNG gỡ nó —
     gỡ là mở lại đường cho chữ đè mũi tên. */
  padding-right: 34px !important;
  font-size: 16px;
  font-family: inherit;
  color: var(--text);
  background-color: var(--card);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% - 2px), calc(100% - 14px) calc(50% - 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
/* Ô chọn trong Cài đặt đi khuôn danh sách gom nhóm kiểu iPhone (mục 4 ở trên):
   không viền, nền trong suốt. Bộ chọn đó có ID nên đặc hiệu cao hơn khối ngay
   trên ⇒ nó thắng `background`, và ô mất luôn mũi tên. Trả mũi tên lại cho
   riêng nó, giữ nguyên nền trong suốt. */
#scr-settings .card select {
  appearance: none;
  -webkit-appearance: none;
  /* Cũng `!important` vì khối trên đã `!important` — không có nó thì 34px của khối
     trên thắng, mũi tên của Cài đặt (nằm sát mép, 2–7px) tách rời chữ một khoảng
     trống 34px trông như lỗi bố cục. Đặc hiệu (1,1,1) cao hơn nên dòng này thắng. */
  padding-right: 30px !important;
  background-color: transparent;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 7px) calc(50% - 2px), calc(100% - 2px) calc(50% - 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
/* Ô chọn tháng KHÔNG phải <select> mà là <input type="month"> — nó bung ra lịch
   của hệ điều hành, không thay bằng bảng kéo được và cũng không nên thay.
   Việc ở đây chỉ là cho nó cao bằng anh em: số đo cứng 0a đòi ≥48px. */
input[type="month"], input[type="date"] { min-height: 48px; }

/* ==========================================================================
   ④ GOM CHỮ TO — khối này PHẢI nằm sau khối "CHỮ ≥16px" (việc A, nặng nhất)
   --------------------------------------------------------------------------
   Bệnh đo được trên `main` = 0b9074d: 20 lớp có cả hai chế độ mà chế độ CHỮ TO
   lại nhỏ hơn hoặc bằng chế độ thường — 16 lớp trong đó còn tụt xuống DƯỚI 16px.
   Nặng nhất: `.tag` 13px · `.room-tile-badge` 12,5px · `.quick-grid button` 13px.

   Vì sao 14 dòng `body.big-text` cũ viết TRƯỚC khối "CHỮ ≥16px" mà vẫn thắng:
   ĐẶC HIỆU THẮNG THỨ TỰ. `body.big-text .tag` = (0,2,1) còn `.tag` = (0,1,0).
   Thứ tự chỉ phân thắng bại khi đặc hiệu BẰNG NHAU.

   Hậu quả bằng lời người: người 50+ bật chữ to cho dễ đọc, app lại đưa họ về
   cỡ chữ NHỎ HƠN cả người không bật. Ô 11 và ô 12 cùng trượt.

   🔴 KHÔNG xoá 14 dòng cũ — giữ làm dấu vết, đúng nếp đã ghi ở dòng 713 của
      chính file này. Khối này đặt SAU nên nó đè, cùng đặc hiệu thì dòng sau
      thắng. Sửa cỡ chữ chế độ to thì sửa Ở ĐÂY, đừng đi sửa dòng cũ.
   🔴 Sàn là 17px, không phải 16px: chữ to phải TO HƠN chữ thường (16px), bằng
      nhau thì nút "chữ to hơn" thành nút không làm gì. Bài A2 của rào chắn canh
      đúng chỗ đó — bài A1 chỉ bắt triệu chứng "dưới 16".
   ⚪ `.tabbar button` giữ 17px như dòng 744: ô tab chỉ rộng 78px trên máy 390px
      (đo 31/07), nhãn dài đã rút trong dieu-huong.js.
   ========================================================================== */
body.big-text .login-tag,
body.big-text .muted,
body.big-text .lead,
body.big-text .cs-detail,
body.big-text .chipbtn,
body.big-text .seg button, body.big-text .seg-btn, body.big-text .rstat-btn,
body.big-text .tag, body.big-text .rstat, body.big-text .rstat-legend .rstat,
body.big-text .stat-cx,
body.big-text .kv span, body.big-text .kv b,
body.big-text .tx-mid small, body.big-text .wallet-chip small,
body.big-text .book-sum small, body.big-text .line-mid small,
body.big-text .quick-grid button,
body.big-text .room-tile-label, body.big-text .room-tile-badge {
  font-size: 17px;
}
/* Chữ to kéo theo chỗ đứng: hai dòng dưới đây là hệ quả của khối trên, không
   phải trang trí. Nhãn 4 ô hành động nhanh và nhãn ô phòng đều xuống dòng
   được, nhưng ô phải cao thêm thì chữ mới không bị cắt cụt. */
body.big-text .quick-grid button { line-height: 1.25; }
body.big-text .room-tile { min-height: 124px; }

/* ==========================================================================
   ⑦ CHỈ ĐỌC MÀN HÌNH NGHE — ẩn mắt, KHÔNG ẩn với trình đọc (phiếu 78, 06/08/2026)
   Dùng cho hai ô loa aria-live đặt sẵn ngay dưới <body>.
   🔴 KHÔNG được thay bằng display:none hay visibility:hidden — hai cách đó gỡ
      phần tử khỏi cây trợ năng, TalkBack/VoiceOver không còn thấy nó để đọc.
      Cách duy nhất đúng: co còn 1px rồi cắt hết phần nhìn thấy.
   🔴 KHÔNG thêm font-size vào đây — khối này đứng sau khối "CHỮ ≥16px" nên nó
      sẽ đè, mà đè cỡ chữ là phá luật TC10.
   ⚪ Không đặt width/height = 0: vài trình đọc bỏ qua phần tử kích thước 0.
   ========================================================================== */
.chi-doc-man {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ==========================================================================
   ⑧ BÀN PHÍM ẢO KHÔNG ĐƯỢC CHE Ô NHẬP (phiếu 78 việc ②, 06/08/2026)

   ĐO ĐƯỢC trước khi sửa (Chrome headless, khung nhìn thật 360×640 và 390×844,
   màn "Ghi thu chi", CUỘN HẾT CỠ rồi mới đo):
     · 360×640 — nút "Lưu giao dịch" còn thò xuống dưới mép bàn phím 234px,
                 ô nhập cuối 170px. Sheet cuộn được 142px, cuộn hết vẫn kẹt.
     · 390×844 — nút "Lưu giao dịch" thò 310px, ô nhập cuối 246px.
                 Sheet cuộn được 0px — không có gì để cuộn, kẹt hoàn toàn.
   Nghĩa là: người dùng gõ xong KHÔNG bấm nổi nút Lưu, phải tắt bàn phím trước.

   GỐC BỆNH là đơn vị `vh`: `.sheet { max-height: 92vh }` (dòng 247) đo theo khung
   nhìn TĨNH, mà `vh` KHÔNG đổi khi bàn phím ảo bật lên. Sheet vẫn cao 92% màn,
   đáy nó nằm sau bàn phím, và cuộn BÊN TRONG sheet không kéo đáy sheet lên được.

   CHỮA: public/tro-nang.js nghe visualViewport rồi ghi chiều cao bàn phím vào
   --cao-ban-phim; hai luật dưới đây trừ đi phần đó.
   🔴 KHÔNG đổi `position` của .thanh-hanh-dong — nó là sticky CỐ Ý (mục 4b), ở đây
      chỉ nâng mép dưới của nó lên khỏi bàn phím.
   🔴 Máy không có visualViewport thì --cao-ban-phim giữ 0px ⇒ hai luật này trở về
      đúng số cũ, không vá gì. Đó là lý do phải khai mặc định 0px.
   ⚪ Bàn phím mở thì thanh tab dưới cũng nằm sau nó ⇒ không cần chừa 84px nữa,
      chỉ chừa 8px cho thoáng.
   ========================================================================== */
:root { --cao-ban-phim: 0px; }

/* ① Sheet CO LẠI cho vừa phần màn còn nhìn thấy… */
.sheet { max-height: calc(92vh - var(--cao-ban-phim)); }

/* …② nhưng co không thôi thì CHƯA ĐỦ, và đây là chỗ bản vá đầu hụt: `.overlay`
   là `inset: 0` và sheet dính đáy nó, nên sheet co xong vẫn tụt xuống đáy MÀN,
   tức vẫn nằm sau bàn phím. Đo lượt đầu sau khi vá: sheet cao 589→329px, cuộn
   được 142→402px — vậy mà nút "Lưu giao dịch" vẫn đứng nguyên y=564→614.
   Phải kéo cả đáy khung phủ lên khỏi bàn phím thì sheet mới theo lên. */
body.ban-phim-dang-mo .overlay { bottom: var(--cao-ban-phim); }

/* ③ Thanh hành động dính đáy ở màn thường — cùng bệnh, khác chỗ. */
body.ban-phim-dang-mo .thanh-hanh-dong { bottom: calc(var(--cao-ban-phim) + 8px); }
/* ==========================================================================
   MÀN PHỦ TOÀN TRANG PHẢI Ở TRONG KHUNG APP — `.man-phu` (đợt 0, 05/08/2026)
   --------------------------------------------------------------------------
   Anh Quyết bắt bằng mắt: màn "Nhắn & báo" của vai Quản trị TRÀN RA NGOÀI khung
   điện thoại — header xanh kéo hết bề ngang trình duyệt, nội dung cắt cụt.

   Gốc bệnh: 14 màn phụ tự dựng bằng `position:fixed;inset:0` nên bám VIEWPORT,
   trong khi cả app sống trong `#app { max-width:460px; margin:0 auto }`. Trên
   màn rộng hơn 460px (máy tính bảng, trình duyệt máy bàn, ảnh chụp) chúng phình
   ra hết bề ngang ⇒ nhìn như app vỡ.

   Cách chữa dùng ĐÚNG thủ thuật đã có sẵn của `.tabbar` ngay trên: left:0 +
   right:0 + width:auto + margin-inline:auto + max-width. KHÔNG dùng
   left:50%+translateX(-50%) — xem lời cảnh báo ở khối `.tabbar`, cách đó làm
   trang nở ngang.

   Rào chắn: `routes/man-phu-trong-khung.test.js` — thêm màn phủ mới bằng
   `position:fixed;inset:0` mà quên lớp này thì bài đỏ.
   ========================================================================== */
.man-phu {
  position: fixed;
  top: 0; bottom: 0; left: 0; right: 0;
  width: auto;
  margin-inline: auto;
  max-width: 460px;
  background: var(--bg);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  z-index: 900;
  display: none;
}

/* ==========================================================================
   ⑨ ICON VẼ BẰNG <svg> NHÚNG THẲNG — tắt mask cho thẻ đã được bơm hình.

   Gốc bệnh (đo 16/08/2026, ảnh anh Quyết chụp trên iPhone thật lúc 09:54):
   bộ icon vẽ bằng CSS `mask-image`. Trên iOS beta, cách đó để lộ NÉT THỪA —
   mảnh khung vuông của chính phần tử rò ra ngoài mặt nạ — ở 6/10 icon thử.
   Sân so 5 cách (cổng 3964) đo được: mask+percent VỠ · mask+base64 VỠ y hệt ·
   background-image sạch nhưng MẤT đổi màu · thẻ <img> sạch nhưng MẤT đổi màu ·
   <svg> nhúng thẳng SẠCH và GIỮ đổi màu. Nên chọn <svg>.

   🟢 HAI TẦNG, CỐ Ý — ĐỪNG GỠ: lớp `co-svg` do `public/ve-icon.js` gắn SAU khi
   bơm <svg> vào trong thẻ. Thẻ nào chưa được bơm thì KHÔNG có lớp này và vẫn
   vẽ bằng mask như cũ. Nhờ vậy JS tải hụt hay ném lỗi thì icon vẫn hiện, không
   có cảnh màn trống icon.

   🔴 KHÔNG khai `font-size` ở đây. Khối «CHỮ ≥16px» (dòng 804) không có
   `!important`, nên khối nào đặt SAU nó mà khai cỡ chữ là đè lên nó.
   ⚠️ Đo 16/08/2026: `routes/tro-nang.test.js` `[1.3]` CHỈ canh riêng class
   `.chi-doc-man`, KHÔNG quét toàn cục — nên luật này phần lớn là quy ước bằng
   lời. Bài canh riêng khối này là `routes/icon-svg-nhung-thang.test.js` `[3.2]`.

   Icon lấy cỡ theo `1em` của khối `.ti` gốc trong vendor/an-cu-icons.css; cỡ thật
   do `font-size` đặt trên chính thẻ `<i>` ở các khối phía trên (`.tabbar button i`
   22px, `.room-tile > i` 26px, `.trong i` 40px…). Vì vậy `width/height:100%` bên
   dưới là đủ, đừng thêm số cứng.

   Rào chắn: `routes/icon-svg-nhung-thang.test.js`.
   ========================================================================== */
.ti.co-svg {
  -webkit-mask-image: none;
  mask-image: none;
  background-color: transparent;
}
.ti.co-svg > svg {
  display: block;
  width: 100%;
  height: 100%;
}
