/* /Components/CompNewBill.razor.rz.scp.css */
/* Thanh hành động cố định đáy màn hình trên mobile (Xs/Sm, ngoài Md) — chỉ khối này mới render
   riêng cho mobile (điều kiện IsSmallDevice && _breakpoint != Md trong CompNewBill.razor), nên
   restyle an toàn không ảnh hưởng desktop. Không đụng markup/@code — chỉ CSS.

   Ghi chú ::deep: MudPaper/MudButton là component MudBlazor, DOM gốc của chúng không mang
   scope-attribute của CompNewBill.razor (đã kiểm chứng nhiều lần trong dự án), và phần tử này
   không nằm trong bất kỳ div thuần nào viết tay để làm điểm neo — nên dùng deep đứng riêng thay vì
   theo sau 1 class scoped. Vì tên class .bill-mobile-action-bar chỉ dùng riêng ở component này nên
   an toàn khi không neo theo ancestor. */
[b-wez96wtukv] .bill-mobile-action-bar {
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
}
[b-wez96wtukv] .bill-mobile-action-bar .mud-button-root {
  border-radius: var(--r-md) !important;
}
[b-wez96wtukv] .bill-mobile-action-bar .mud-button-filled-primary {
  background: var(--grad-hero) !important;
}
/* /DialogForm/DlgCustomerHistory.razor.rz.scp.css */
/* DlgCustomerHistory.razor.css — hoàn thiện nhánh mobile tab "Lịch sử đơn" (dialog "Xem chi tiết",
   không có prototype riêng). Đã đổi từ MudTable Breakpoint stacked-mode (render sai, cell tràn ngang
   khi đặt trong dialog — xác nhận qua browser thật) sang card thuần, tái dùng đúng class global
   (info-card/pd-row/incd-note) đã có sẵn từ trang khác. Không viết tên class kèm dấu chấm trong
   comment ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ
   qua (đã gặp bug thật, xem lịch sử fix ngày 2026-07-05). */

.dch-mscroll[b-xvzot86sox] {
  height: 600px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 8px 12px;
}

/* Thanh tab thay thế (xem ghi chú trong .razor) — ẩn hẳn tab-strip gốc của MudTabs trên mobile,
   chỉ giữ lại phần nội dung panel (MudTabs vẫn điều khiển việc hiện đúng panel qua _tabActiveIndex). */
.dch-tabs-m[b-xvzot86sox]  .mud-tabs-tabbar { display: none; }
.dch-tabbar[b-xvzot86sox] { margin: 4px 8px 0; border-radius: var(--r-md); overflow: hidden; }

/* Nút Đóng full-width — .btn-primary mặc định có margin-top:28px (dành cho theo sau 1 cụm field
   filter), không phù hợp trong DialogActions (đứng riêng, không có field phía trên). */
.dch-close-btn.mud-button-root[b-xvzot86sox] { margin-top: 0 !important; }

.dch-mscroll .cust-empty[b-xvzot86sox] {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  height: 100%; text-align: center; color: var(--text-3);
}

.dch-mscroll .info-card-detail .pd-row b[b-xvzot86sox]  .mud-icon-root {
  vertical-align: middle; margin-right: 2px; width: 15px; height: 15px; font-size: 15px;
}
/* /Pages/Functionality/Bills.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════════════
   Bills.razor.css — Giao diện trang Đơn hàng (desktop + mobile).
   Scoped CSS cho Bills.razor — Blazor tự động scope theo component.
   CSS variable: dùng trực tiếp token từ app.mobile.css :root (canonical + alias).

   Quy ước ::deep: các class gắn qua Class="..." lên component MudBlazor
   (MudChip/MudAvatar/MudPaper/MudIconButton/MudFab/MudDrawer/MudListItem...)
   phải dùng combinator ::deep vì phần tử gốc do MudBlazor render không tự
   mang scope-attribute của Bills.razor. Class trên phần tử HTML thuần
   (div/span/nav do Bills.razor viết trực tiếp) thì không cần ::deep.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Desktop layout ──────────────────────────────────────────────────────── */
.mt-2[b-k4349j6gea], .my-2[b-k4349j6gea] {
    margin-top: 1px !important;
}
#hlpPaymentPoints[b-k4349j6gea] {
    color: red;
    font-weight: bold;
    font-size: 11px;
}
.mud-drawer:not(.mud-drawer--open)[b-k4349j6gea] {
    transform: translateX(100%) !important;
    transform: translateY(-100%) !important;
}
.mud-chip.mud-chip-size-small[b-k4349j6gea] {
    padding-right: 3px !important;
}

/* Toolbar Bills: giữ 1 hàng; nút không wrap chữ */
#top-toolbar[b-k4349j6gea] {
    height: auto !important;
    min-height: 48px;
    flex-wrap: nowrap;
    align-items: center;
}
#top-toolbar .mud-button-root[b-k4349j6gea] {
    white-space: nowrap;
    min-width: 0;
    padding-left: 6px;
    padding-right: 6px;
}
#top-toolbar .mud-chipset[b-k4349j6gea] { flex-wrap: nowrap; margin-bottom: 0 !important; }
#top-toolbar .mud-chip[b-k4349j6gea] { margin: 2px 3px !important; flex: 0 0 auto; }

/* Desktop: bills-page cao cố định = màn hình, chỉ áp dụng >= 992px */
@media (min-width: 992px) {
    html:has(.bills-page)[b-k4349j6gea],
    body:has(.bills-page)[b-k4349j6gea] {
        overflow: hidden;
    }

    .bills-page[b-k4349j6gea] {
        height: calc(100dvh - var(--navbar-height, 69px) - 16px);
        display: flex;
        flex-direction: column;
        min-height: 0;
        overflow: hidden;
    }

    .bills-page > .bills-table-shell[b-k4349j6gea] {
        flex: 1 1 auto;
        min-height: 0;
        margin-bottom: 5px;
    }

    .bills-page .mud-height-full[b-k4349j6gea],
    .bills-page .auto-table-height[b-k4349j6gea] {
        height: 100%;
        min-height: 0;
    }

    .bills-page .auto-table-height .mud-table[b-k4349j6gea] {
        height: 100%;
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    .bills-page .auto-table-height .mud-table > .mud-toolbar[b-k4349j6gea] {
        flex: 0 0 auto;
    }

    .bills-page .auto-table-height .mud-table-container[b-k4349j6gea] {
        flex: 1 1 auto;
        min-height: 0 !important;
        height: auto !important;
    }
}

/* ── Shell mobile: flex column fill viewport, header cố định, chỉ .list cuộn ──
   Theo kiến trúc prototype (.screen flex column + overflow:hidden; .header-zone
   không flex; .list flex:1 overflow-y:auto). Nhờ đó app bar + chips + search
   luôn dính đỉnh khi cuộn card, và .list là scroll-container ổn định cho MudVirtualize.
   .app-shell-body:has(.bills-m) bỏ padding-bottom trong app.mobile.css để không dư scroll ngoài.
   Shell flex-column 100dvh của .bills-m nay cũng đã gộp chung ở app.mobile.css. */

/* App bar (.header-zone/.topnav/.nav-icon-btn/.topnav-title/.topnav-actions) đã chuyển sang
   app.mobile.css (global) vì FinancialReport.razor dùng lại y hệt pattern này -> tránh lặp CSS. */

/* .menu-item (MudMenuItem trong dropdown app bar) render qua MudPopoverProvider,
   portal ra ngoài cây DOM của .bills-m -> CSS scoped (::deep) ở đây không áp dụng
   được. Style cho .menu-item đặt ở app.mobile.css (global). */

/* .search-collapse/.search/.search-field đã chuyển sang app.mobile.css (global) — dùng chung với
   RevenueReportDetail.razor, không lặp lại CSS ở đây. .qr-btn (nút QR) chỉ Bills mới có nên giữ lại. */
.bills-m[b-k4349j6gea]  .qr-btn {
  flex: none; width: 36px !important; height: 36px !important;
  border-radius: var(--r-sm) !important;
  background: var(--primary-soft) !important; color: var(--primary-dark) !important;
}
.bills-m[b-k4349j6gea]  .qr-btn:active { background: #DEDCF8 !important; }

/* ── Chip bar — <nav> thuần, không nền (hiện nền trang phía sau) ─────────── */
.bills-m .chips[b-k4349j6gea] {
  display: flex; gap: 8px; overflow-x: auto;
  padding: 10px 14px 8px;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg,#000 0,#000 calc(100% - 32px),transparent);
  mask-image: linear-gradient(90deg,#000 0,#000 calc(100% - 32px),transparent);
}
.bills-m .chips[b-k4349j6gea]::-webkit-scrollbar { display: none; }
.bills-m[b-k4349j6gea]  .chips .chip {
  flex: none; display: flex; align-items: center;
  /* MudChip tự có margin:4px mặc định -> cộng dồn với gap:8px của .chips thành 16px thực tế.
     Bỏ hẳn margin, để riêng gap của .chips quyết định khoảng cách giữa các chip. */
  margin: 0 !important;
  height: auto !important;
  padding: 8px 15px !important; border-radius: var(--r-pill) !important;
  background: var(--card) !important; color: var(--text-2);
  border: 1px solid var(--border);
  font-size: var(--font-size-base); font-weight: 600; cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: transform .14s cubic-bezier(.32,.72,.25,1),
              box-shadow .14s ease, background .2s ease, color .2s ease;
  white-space: nowrap;
}
.bills-m[b-k4349j6gea]  .chips .chip:active { transform: scale(.95); }
/* Text và .count không phải con trực tiếp của .chip mà nằm trong .mud-chip-content (wrapper
   MudBlazor tự bọc bên trong) -> gap phải đặt ở đây mới có tác dụng, đặt ở .chip (rule trên) vô
   nghĩa vì .chip chỉ có đúng 1 con trực tiếp là .mud-chip-content. */
.bills-m[b-k4349j6gea]  .chips .chip .mud-chip-content {
  display: flex; align-items: center; gap: 6px;
}
.bills-m .chips .chip .count[b-k4349j6gea] {
  background: var(--surface); border-radius: 999px;
  padding: 1px 7px; font-size: var(--font-size-sm); color: var(--text-3); font-weight: 700;
}
.bills-m[b-k4349j6gea]  .chips .chip.active {
  background: var(--grad-hero) !important; border-color: transparent;
  color: #fff !important; box-shadow: 0 6px 16px rgba(74,59,212,.30);
}
.bills-m .chips .chip.active .count[b-k4349j6gea] { background: rgba(255,255,255,.22); color: #fff; }

/* ── Danh sách thẻ phiếu ─────────────────────────────────────────────────────
   Block layout (KHÔNG flex/gap): Blazor Virtualize chèn 2 spacer <div>; flex+gap
   làm spacer đo sai -> render toàn bộ. Spacing giữa card qua margin-bottom. */
.bills-m .list[b-k4349j6gea] {
  flex: 1 1 auto;
  min-height: 0;   /* BẮT BUỘC: flex item mặc định min-height:auto -> .list nở hết chiều cao
                      240 card, không cuộn nội bộ -> MudVirtualize không virtualize. min-height:0
                      cho phép .list co lại đúng khung flex và tự cuộn -> virtualize hoạt động. */
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.bills-m .list[b-k4349j6gea]::-webkit-scrollbar { display: none; }
.bills-m .card[b-k4349j6gea] { margin-bottom: 10px; }
.bills-m[b-k4349j6gea]  .bill-skeleton { margin-bottom: 10px; animation: bills-card-in-b-k4349j6gea .6s cubic-bezier(.22,1,.36,1) both; }

/* ── Hiệu ứng zoom-in khi card THỰC SỰ lọt vào khung nhìn của .list (không phải lúc
   Virtualize mount) — JS (index.html) dùng IntersectionObserver (root=.list) phát hiện
   card lọt khung nhìn rồi mới gắn class .card-pop để phát animation. Nếu animate ngay
   lúc mount (như bản cũ) thì Virtualize dựng sẵn card trước theo OverscanCount khiến
   animation .6s chạy xong TRƯỚC khi card thật sự vào khung nhìn -> vô hình khi cuộn.
   Mặc định .card KHÔNG có animation (an toàn nếu JS lỗi/chưa kịp chạy -> card vẫn hiện
   đủ kích thước bình thường), chỉ .card-pop (JS gắn) mới animate. ── */
/* QA #3: đổi từ zoom-in (scale) sang fade thuần (chỉ opacity); tên keyframe riêng (bills-card-in,
   vì skeleton của Bills cũng dùng chung tên này). Easing/thời lượng đồng bộ với .card-pop chung ở
   app.mobile.css: ease-out dịu .8s thay cho bounce 1.2s (chống giật chủ yếu nhờ rootMargin pre-warm
   trong _appscript.mobile.js). */
@keyframes bills-card-in-b-k4349j6gea {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.bills-m .card.card-pop[b-k4349j6gea] {
  animation: bills-card-in-b-k4349j6gea .8s cubic-bezier(.22,1,.36,1) both;
}

@media (prefers-reduced-motion: reduce) {
  .bills-m .card.card-pop[b-k4349j6gea],
  .bills-m[b-k4349j6gea]  .bill-skeleton { animation: none; }
}

/* ── Thẻ phiếu (bill card) — HTML thuần (hot-path, xem ghi chú trong .razor) ── */
.bills-m .b-head[b-k4349j6gea] { display: flex; align-items: center; gap: 11px; }
/* .avatar (shape tròn 44px cơ bản) đã promote sang app.mobile.css (global) — Customers.razor là
   consumer thứ 2. Không lặp lại CSS ở đây. */
.bills-m .head-main[b-k4349j6gea] { flex: 1; min-width: 0; }
.bills-m .row-top[b-k4349j6gea] { display: flex; align-items: center; gap: 8px; }
.bills-m .bill-name[b-k4349j6gea] {
  font-size: var(--font-size-base); font-weight: 700; flex: 1; min-width: 0;
  text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--text);
}
/* .status (base + màu --new/--washing/--done/--delivered/--debt) đã promote sang app.mobile.css
   (global) để dùng chung đúng 1 nguồn màu với Trang chủ (Index.Mobile) — trước đây mỗi trang tự định
   nghĩa lệch màu nhau (Bills sai "Giao khách", Trang chủ sai "Đang giặt"/"Giặt xong"). Không lặp lại
   CSS ở đây. */
/* Màu var(--text-2) (rgba(0,0,0,.6)) thay vì var(--text-3) (rgba(0,0,0,.38) — đúng bằng ngưỡng
   "disabled" chuẩn Material Design) để chevron không bị hiểu lầm là control đang vô hiệu hóa. */
/* SĐT khách: base(14) thay vì sm(13) — số điện thoại cần đọc chính xác từng ký tự, khác vai trò
   "lướt qua" của các meta khác cùng mức sm (khớp .ordr-phone dùng chung ở app.mobile.css). */
.bills-m .row-phone[b-k4349j6gea] {
  margin-top: 3px; font-size: var(--font-size-base); color: var(--text-3); line-height: var(--lh-snug);
}
.bills-m .row-meta[b-k4349j6gea] {
  display: flex; align-items: center; gap: 8px; min-width: 0; margin-top: 10px;
}
.bills-m .bill-code[b-k4349j6gea],
.bills-m .shelf-chip[b-k4349j6gea] {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--card); color: var(--text-2);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 10px; font-size: var(--font-size-sm); font-weight: 600; cursor: pointer;
  transition: background .12s, border-color .12s;
}
.bills-m .bill-code:active[b-k4349j6gea],
.bills-m .shelf-chip:active[b-k4349j6gea] { background: var(--surface); border-color: var(--primary); }
.bills-m .bill-code[b-k4349j6gea] { flex: none; font-family: var(--font-mono); border-style: dashed; }
.bills-m .shelf-chip[b-k4349j6gea] { flex: 0 1 auto; min-width: 0; }
.bills-m .shelf-chip span[b-k4349j6gea] { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bills-m .shelf-chip.none[b-k4349j6gea] { color: var(--text-3); border-style: dashed; }
.bills-m .row-bottom[b-k4349j6gea] {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 8px;
  margin-top: 12px;
}
/* .pickup-col/.paidline/.amount ĐÃ CHUYỂN sang global (.ordr-leftcol/.ordr-paid/.ordr-amt-lg trong
   app.mobile.css) — trước đây Bills tự định nghĩa riêng gần như trùng lặp 100% với RevenueReportDetail,
   chỉ khác icon Check/CheckCircle và cách tô màu (Color="Color.Success" thay vì token --green), gây
   lệch icon giữa 2 trang. Gộp về 1 chỗ để luôn khớp nhau. .pickup (dòng "Hẹn trả") cũng đã promote
   sang app.mobile.css (global) — Trang chủ (Index.Mobile) dùng lại y hệt, không lặp lại CSS ở đây. */
.bills-m .row-note[b-k4349j6gea] {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 12px; border-top: 1px solid var(--line);
  padding: 12px 2px 0;
  font-size: var(--font-size-base); line-height: var(--lh-normal); color: var(--text-2);
}
.bills-m .row-note[b-k4349j6gea]  .mud-icon-root { flex: none; margin-top: 2px; width: 14px; height: 14px; font-size: 14px; }
.bills-m .row-note span[b-k4349j6gea] {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Cham card mo panel chi tiet. Thu gon: an panel; mo thi hien panel + an chip ma va ke + hang tien
   (thong tin da nam trong cac dong ben trong panel), ghi chu van o day card. Base panel va cac dong
   la class GLOBAL o app mobile, o day chi lo phan dong/mo rieng cho Bills.
   Luu y: comment KHONG duoc chua token dang selector hay ten file co dau cham -> hong scoped CSS. */
.bills-m .card.bill.collapsible[b-k4349j6gea] { cursor: pointer; }
.bills-m .card.bill.collapsible .ordr-detail[b-k4349j6gea] { display: none; margin-top: var(--space-3); padding: 6px 12px; }
.bills-m .card.bill.collapsible.open .ordr-detail[b-k4349j6gea] { display: block; }
/* Khi mo: an chip ma phieu/ke + hang tien thu gon + ghi chu ngoai (ghi chu da nam trong panel). */
.bills-m .card.bill.collapsible.open .row-meta[b-k4349j6gea],
.bills-m .card.bill.collapsible.open .row-bottom[b-k4349j6gea],
.bills-m .card.bill.collapsible.open .row-note[b-k4349j6gea] { display: none; }
/* Noi dung panel chi tiet (pd-row.hl / pd-row.due-urgent / pd-note + icon) DA CHUYEN sang global
   app.mobile.css (generic ordr-detail ...) — dung chung voi 3 report (ReceivableReport/
   RevenueReportDetail/FinancialDetail). Rule global khong scope nen van bat dung MudIcon trong panel
   cua Bills (khong can ::deep). Khong lap lai CSS o day. */
/* Wrapper chặn propagation cho nút menu (giữ đúng slot flex như MudIconButton trước đó). */
.bills-m .menu-hit[b-k4349j6gea] { flex: none; display: inline-flex; align-items: center; }

/* ── Trạng thái rỗng ─────────────────────────────────────────────────────── */
.bills-empty[b-k4349j6gea] {
  flex: 1 1 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 60px 24px 110px; text-align: center; color: var(--text-3);
}

/* ── FAB (MudFab) — position:fixed đã promote sang app.mobile.css (global) — Customers.razor và
   IncomeExpense.razor là các consumer khác dùng chung Class="fab". Không lặp lại CSS ở đây. ── */

/* ── Action sheet (nội dung riêng của Bills: sheet-head/sheet-list) ───────────
   Cơ chế sheet-backdrop/.sheet/.flt-sheet/.sheet-grip/.btn-primary dùng chung đã
   chuyển sang app.mobile.css (FinancialReport cũng dùng lại). Container là phần
   tử HTML thuần -> không ::deep; nội dung MudBlazor bên trong mới cần ::deep. */
/* .sheet-head/.avatar/.nm/.cd đã promote sang app.mobile.css (global) — IncomeExpense.razor là
   consumer thứ 2 (trước đây scoped ".bills-m .sheet-head" nên trang khác không thấy style, avatar
   bị rớt xuống dòng). Không lặp lại CSS ở đây. */
/* MudList/MudListItem trong action sheet — dùng lại pattern "settings-row" (icon
   trong ô nền màu bo góc, hairline inset) đã có ở Options.razor (app.mobile.css) để
   đồng bộ phong cách list iOS thay vì icon Material trần. Reset padding/min-height mặc định
   của MudListItem (sheet-list/settings-row/sheet-divider) đã promote sang app.mobile.css
   (global) — Customers.razor/CustomerDebtDetail.razor/IncomeExpense.razor là các consumer
   khác dùng chung action sheet này. Không lặp lại CSS ở đây. */
/* /Pages/Functionality/IncomeExpense.razor.rz.scp.css */
/* IncomeExpense trang mobile (desktop giữ nguyên), tham khảo prototype income-expense (khối
   SCREEN INCOME-EXPENSE trong styles global của prototype). Các primitive dùng chung như header
   app bar, topnav, thẻ card cơ bản, thẻ tương tác, khối 2 thẻ mini thu chi, thẻ mini, chip danh mục,
   thẻ thông tin, backdrop cho sheet, sheet lọc, nút chính, dòng dữ liệu, ghi chú đã có ở stylesheet
   mobile toàn cục rồi, không lặp lại ở đây. File này chỉ còn phần RIÊNG của trang: shell + vùng cuộn
   + rỗng/skeleton. Lưu ý: KHÔNG viết tên class kèm dấu chấm trong comment ở file này — bộ rewrite
   scope CSS của Blazor xử lý cả nội dung comment, một token giống selector từng làm hỏng parse và
   khiến rule .ince-m ngay sau bị trình duyệt bỏ qua hoàn toàn (xem lịch sử fix ngày 2026-07-05). */

/* .ince-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.ince-m .ince-scroll[b-gfwksifsuu] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 14px 14px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.ince-m .ince-scroll[b-gfwksifsuu]::-webkit-scrollbar { display: none; }

/* .ince-skel đặt trên <MudPaper> (component) -> cần ::deep để CSS scoped chạm tới. .ince-empty là
   <div> thuần nên không cần ::deep. */
.ince-m[b-gfwksifsuu]  .ince-skel { cursor: default; }
.ince-m .ince-empty[b-gfwksifsuu] {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 60px 24px; text-align: center; color: var(--text-3);
}
/* /Pages/Functionality/IncomeExpenseDetail.razor.rz.scp.css */
/* IncomeExpenseDetail.razor.css — Form thêm/sửa 1 khoản Thu/Chi, giao diện mobile (desktop giữ
   nguyên). Không có prototype riêng (xem Plans/Cashbook.md mục 11) — chỉ áp shell mobile chung
   (app bar và thanh điều hướng trên đã có ở stylesheet toàn cục) cho form, field vẫn giữ nguyên
   MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment ở file này — có thể làm hỏng bộ
   rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .inced-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.inced-m .inced-scroll[b-vz78vodft8] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.inced-m .inced-scroll[b-vz78vodft8]::-webkit-scrollbar { display: none; }

/* /Pages/Functionality/LoyaltyPrograms.razor.rz.scp.css */
/* LoyaltyPrograms.razor.css — Tích điểm & Khuyến mãi, giao diện mobile (desktop giữ nguyên). Tham
   khảo Mobile.Prototype/loyalty.html. Nội dung 2 tab do component con (CompLoyalty/CompPromotion)
   dựng, nằm bên trong shell .lyl-m; nên style cho phần tử của component con phải dùng ::deep để xuyên
   qua ranh giới scope. Primitive dùng chung (header-zone, seg, card, info-card, pd-row, sheet, fab)
   đã có ở stylesheet mobile toàn cục. Không viết tên class kèm dấu chấm trong comment ở file này —
   có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .lyl-m: shell flex-column 100dvh đã gộp global (app.mobile.css).
   Segment (MudToggleGroup, style toàn cục) — thêm khoảng cách dưới trong header */
.lyl-m[b-6tvz7ijsqt]  .seg.mud-toggle-group { margin-bottom: 12px; }

.lyl-m .lyl-scroll[b-6tvz7ijsqt] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.lyl-m .lyl-scroll[b-6tvz7ijsqt]::-webkit-scrollbar { display: none; }

/* Panel tab — cả 2 luôn mount, ẩn/hiện bằng CSS để giữ state form khi đổi tab */
.lyl-m .lyl-panel[b-6tvz7ijsqt] { display: none; }
.lyl-m .lyl-panel.active[b-6tvz7ijsqt] { display: block; }

/* ── Tab Tích điểm (CompLoyalty) ── */
.lyl-m[b-6tvz7ijsqt]  .lyl-card { margin-bottom: 12px; }
.lyl-m[b-6tvz7ijsqt]  .lyl-card-title {
  font-size: var(--font-size-sm); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-2); margin-bottom: 4px;
}
.lyl-m[b-6tvz7ijsqt]  .rate-row { display: flex; align-items: flex-start; gap: 8px; }
.lyl-m[b-6tvz7ijsqt]  .rate-row > .mud-input-control { flex: 1 1 0; min-width: 0; }
.lyl-m[b-6tvz7ijsqt]  .rate-eq { flex: none; padding-bottom: 0; padding-top: 28px; color: var(--text-3); font-size: var(--font-size-lg); font-weight: 700; }
.lyl-m[b-6tvz7ijsqt]  .lyl-switch-row {
  margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--line);
}
.lyl-m[b-6tvz7ijsqt]  .lyl-alert { margin-top: 12px; }
.lyl-m[b-6tvz7ijsqt]  .lyl-submit { margin-top: 4px; padding: 4px 2px 8px; }

/* ── Tab Khuyến mãi (CompPromotion) ── */
.lyl-m[b-6tvz7ijsqt]  .promo-wrap { position: relative; min-height: 40vh; }
.lyl-m[b-6tvz7ijsqt]  .promo-note {
  display: flex; align-items: flex-start; gap: 7px; margin-top: 11px;
  font-size: var(--font-size-sm); font-style: italic; color: var(--text-3); line-height: 1.4;
}
.lyl-m[b-6tvz7ijsqt]  .promo-note .mud-icon-root { flex: none; width: 16px; height: 16px; font-size: 16px; margin-top: 1px; }
.lyl-m[b-6tvz7ijsqt]  .promo-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 60px 24px; text-align: center; color: var(--text-3);
}
/* /Pages/Functionality/NewBill.razor.rz.scp.css */
/* Nhận đồ / tạo phiếu mới — polish nhẹ cho mobile (desktop giữ nguyên). Không có prototype HTML
   tham khảo cho màn này. Chỉ thêm shell header-zone (back + tiêu đề) — không đổi gì trong
   CompNewBill (form/logic tạo đơn giữ nguyên 100%). Dải tab "cửa sổ" bị ẩn hẳn trên mobile theo yêu
   cầu — chỉ còn 1 đơn tại 1 thời điểm. */

/* .newbill-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.newbill-m .newbill-scroll[b-3wmbiun07z] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Ngăn scroll-chaining: khi nội dung bên trong chưa đủ dài để tự cuộn (vd form rỗng), thao tác
     vuốt/lăn không được "dội biên" sang .main-content (vùng cuộn ngoài của MainLayout) — nếu không
     header-zone (đứng ngoài vùng cuộn này, xem cấu trúc .newbill-m) sẽ bị kéo trôi theo cùng
     .newbill-m khi .main-content bị cuộn/nảy đàn hồi. */
  overscroll-behavior: contain;
  /* Ẩn thanh cuộn native — mọi vùng cuộn mobile khác trong app đều ẩn (xem .list/.ov-scroll...),
     rule này bị bỏ sót khi tạo .newbill-scroll nên lộ thanh cuộn mặc định của trình duyệt. */
  scrollbar-width: none;
}
.newbill-m .newbill-scroll[b-3wmbiun07z]::-webkit-scrollbar { display: none; }

/* Thanh tab gốc của MudDynamicTabs (icon/nhãn/nút thêm cửa sổ) bị ẩn hẳn trên mobile — chỉ dùng 1
   cửa sổ duy nhất, không còn cách thêm/chuyển qua UI. MudBlazor tự vẽ DOM này (không mang
   scope-attribute của NewBill.razor) nên cần deep. */
.newbill-m[b-3wmbiun07z]  .mud-tabs-tabbar { display: none; }

/* Bỏ nền trắng của 2 lớp MudPaper bao ngoài (wrapper tab + new-bill-root) để nền gradient của trang
   hiện xuyên qua — 2 panel bên trong trở thành thẻ nổi riêng biệt như các trang mobile khác. */
.newbill-m[b-3wmbiun07z]  .newbill-tabwrap,
.newbill-m[b-3wmbiun07z]  .new-bill-root { background: transparent !important; }

/* 2 panel nội dung (trái: bill-detail-panel, phải: bill-right-paper) thành thẻ trắng bo góc + shadow
   theo chuẩn card chung (giống primitive .card ở app.mobile.css) thay cho viền đứt nét 2px cũ. */
.newbill-m[b-3wmbiun07z]  .bill-detail-panel,
.newbill-m[b-3wmbiun07z]  .bill-right-paper {
  background: var(--color-card) !important;
  border: none !important;
  border-radius: var(--radius-lg) !important;
  box-shadow: var(--shadow-sm) !important;
}

/* Card bọc ngoài phần thông tin phải (bill-right-card) làm trong suốt/không viền — để bill-right-paper
   bên trong nó mới là thẻ hiển thị thực sự (khớp đúng phần tử user chỉ định). */
.newbill-m[b-3wmbiun07z]  .bill-right-card {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

/* Chuẩn hoá khoảng cách dọc về 12px đều (khớp inset ngang 12px). Đo thực tế: gap giữa 2 thẻ = 12px
   (card1 mb 4 + p-1 hai cột 8). Bỏ padding-top cột trái vì đã có padding-top riêng ở .newbill-tabwrap
   (xem dưới) lo phần gap trên cùng, tránh cộng dồn 2 lớp. */
.newbill-m[b-3wmbiun07z]  .bill-left-col { padding-top: 0 !important; }
.newbill-m[b-3wmbiun07z]  .bill-detail-panel { margin-bottom: 4px !important; }

/* Gap trên cùng (topnav -> thẻ dịch vụ) = 12px, khớp gap giữa 2 thẻ + inset 2 bên. Ẩn hẳn
   .mud-tabs-tabbar (rule phía trên) làm khoảng đệm 12px vốn có của khối tab MudBlazor biến mất
   (display:none không còn chiếm không gian) nên phải bù lại thủ công tại đây. */
.newbill-m[b-3wmbiun07z]  .newbill-tabwrap { padding-top: 12px !important; }

/* Panel dịch vụ vốn có border (border-dotted) chặn margin-collapse cho ô MudAutocomplete con (margin-top
   12px của .mud-input-control.mt-3) — khi bỏ border ở rule .bill-detail-panel phía trên, panel không còn gì
   chặn nên margin đó "trồi" ra ngoài panel thay vì tạo khoảng cách bên trong (ô search dính sát mép trên).
   Thêm padding-top 4px vừa đủ để tự nó chặn collapse (bất kỳ padding-top > 0 đều chặn), tổng khoảng cách
   4 (padding) + 12 (margin con, giờ không còn collapse) = 16px, khớp đúng padding-top của bill-right-paper
   (card tìm khách hàng, dùng padding mặc định 16px của MudCardContent) theo yêu cầu đồng nhất 2 card. */
.newbill-m[b-3wmbiun07z]  .bill-detail-panel { padding-top: 4px !important; }

/* Fix regression desktop (QA #12): CompNewBill.razor có sẵn 1 khối <style> nội bộ định nghĩa chain
   flex/height cho >=992px, trong đó ".newbill-page > .mud-paper" dùng child combinator trực tiếp.
   Div bọc mới thêm ở trên (.newbill-wrap, luôn tồn tại kể cả khi không phải mobile) đã biến
   .newbill-tabwrap từ con trực tiếp của .newbill-page thành cháu, làm rule đó không còn khớp ->
   toàn bộ chain height:100% (bill-right-card, bill-right-paper...) sụp đổ trên desktop. Bắc cầu lại
   đúng 2 thuộc tính mà rule gốc từng cấp, không đụng vào <style> bảo vệ trong CompNewBill.razor. */
@media (min-width: 992px) {
  .newbill-page > .newbill-wrap[b-3wmbiun07z] {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  .newbill-page[b-3wmbiun07z]  .newbill-tabwrap {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
}
/* /Pages/Index.Mobile.razor.rz.scp.css */
/* Style cho giao diện Trang chủ trên thiết bị di động.
   NavLink và MudIcon render ra phần tử không mang scope-attribute của CSS isolation,
   nên các rule đặt qua tổ tiên có scope là ".home-mobile" bằng combinator ::deep. */

.home-mobile[b-asqd4d2305] {
    display: flex;
    flex-direction: column;
    /* dvh (không phải %) vì .app-shell-body (tổ tiên) cao theo nội dung (auto), không có
       chiều cao cố định để % phân giải đúng -> phải neo trực tiếp theo viewport. */
    min-height: 100dvh;
}

/* ── Thanh trên cùng nền gradient ── */
.home-mobile[b-asqd4d2305]  .home-topbar {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    padding: max(env(safe-area-inset-top), 12px) 16px 12px;
    background: var(--primary);
    border-bottom: 3px solid var(--accent);
}

.home-mobile[b-asqd4d2305]  .home-logo {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
}

.home-mobile[b-asqd4d2305]  .home-logo-u {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--accent);
    display: grid;
    place-items: center;
    font-size: var(--font-size-lg);
    font-weight: 800;
    color: #fff;
    line-height: 1;
    font-family: var(--font-brand);
}

.home-mobile[b-asqd4d2305]  .home-logo-word {
    font-size: var(--font-size-2xl);
    font-family: var(--font-brand);
    color: #fff;
    line-height: 1;
}

/* ── Vùng nội dung cuộn ── */
.home-mobile[b-asqd4d2305]  .home-scroll {
    flex: 1;
    /* Flex column để .home-footer margin-top:auto ghim được xuống đáy khi nội dung ngắn hơn màn hình. */
    display: flex;
    flex-direction: column;
    padding: 16px 14px 16px;
}

/* ── Hàng chào người dùng ── */
.home-mobile[b-asqd4d2305]  .home-user {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 2px 2px 18px;
    text-decoration: none;
}

.home-mobile[b-asqd4d2305]  .home-user-meta {
    flex: 1;
    min-width: 0;
}

.home-mobile[b-asqd4d2305]  .home-user-meta .hi {
    font-size: var(--font-size-xl);
    font-weight: 800;
    color: var(--text);
    line-height: var(--lh-tight);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.home-mobile[b-asqd4d2305]  .home-user-meta .store {
    font-size: var(--font-size-base);
    color: var(--text-2);
    margin-top: 5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* QA #7: nền --primary-soft (#ECEAFB) quá gần màu canvas nền trang (#F4F2FB) -> tương phản kém.
   Đổi sang --grad-hero (đồng bộ ngôn ngữ "hero" đang áp cho Options store-card) + icon trắng để
   tương phản mạnh hẳn so với nền trang. */
.home-mobile[b-asqd4d2305]  .home-user-av {
    flex: none;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background: var(--grad-hero);
    color: #fff;
    display: grid;
    place-items: center;
    box-shadow: 0 4px 12px rgba(74,59,212,.30);
}

.home-mobile[b-asqd4d2305]  .home-user-av .mud-icon-root {
    width: 30px;
    height: 30px;
    font-size: 30px;
}

/* ── Lưới thao tác nhanh ── */
.home-mobile[b-asqd4d2305]  .home-quick-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 24px;
}

.home-mobile[b-asqd4d2305]  .quick-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 22px 8px 18px;
    border: none;
    border-radius: var(--r-xl);
    cursor: pointer;
    color: #fff;
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: .02em;
    text-align: center;
    text-decoration: none;
    transition: transform var(--dur-fast) var(--ease-ios), box-shadow var(--dur-fast);
}

.home-mobile[b-asqd4d2305]  .quick-tile:active {
    transform: scale(.95);
    box-shadow: 0 4px 12px rgba(46, 40, 90, .22);
}

/* icon trong vòng tròn kính sáng trên nền gradient */
.home-mobile[b-asqd4d2305]  .quick-tile .mud-icon-root {
    width: 24px;
    height: 24px;
    font-size: 24px;
    padding: 8px;
    box-sizing: content-box;
    border-radius: 50%;
    background: rgba(255, 255, 255, .22);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
}

.home-mobile[b-asqd4d2305]  .quick-tile.violet { background: var(--grad-hero); box-shadow: 0 8px 20px rgba(74, 59, 212, .34); }
.home-mobile[b-asqd4d2305]  .quick-tile.blue   { background: var(--grad-blue);  box-shadow: 0 8px 20px rgba(30, 111, 224, .32); }
.home-mobile[b-asqd4d2305]  .quick-tile.orange { background: linear-gradient(140deg, #FB8C00 0%, #E65100 100%); box-shadow: 0 8px 20px rgba(230, 81, 0, .32); }

/* ── Tiêu đề nhóm nội dung ── */
.home-mobile[b-asqd4d2305]  .home-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0 2px 12px;
}

.home-mobile[b-asqd4d2305]  .home-section-title {
    font-size: var(--font-size-base);
    font-weight: 700;
    color: var(--text-2);
    letter-spacing: .02em;
}

.home-mobile[b-asqd4d2305]  .home-section-action {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    font-size: var(--font-size-base);
    font-weight: 600;
    color: var(--primary);
    text-decoration: none;
}

.home-mobile[b-asqd4d2305]  .home-section-action:active { opacity: .7; }

.home-mobile[b-asqd4d2305]  .home-section-action .mud-icon-root {
    width: 16px;
    height: 16px;
    font-size: 16px;
}

/* ── Lưới ô số liệu tổng quan ── */
.home-mobile[b-asqd4d2305]  .home-stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin-bottom: 28px;
}

.home-mobile[b-asqd4d2305]  .stat-tile {
    background: var(--card);
    border-radius: var(--r-md);
    padding: 16px 6px 13px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    box-shadow: var(--shadow-sm);
    /* .stat-tile giờ là NavLink (bấm được -> điều hướng Overview) — reset style link mặc định,
       thêm hiệu ứng nhấn giống .quick-tile để nhất quán trong cùng trang. */
    text-decoration: none;
    cursor: pointer;
    transition: transform var(--dur-fast) var(--ease-ios);
}

.home-mobile[b-asqd4d2305]  .stat-tile:active {
    transform: scale(.95);
}

.home-mobile[b-asqd4d2305]  .stat-value {
    font-size: var(--font-size-2xl);
    font-weight: 800;
    line-height: 1;
}

.home-mobile[b-asqd4d2305]  .stat-label {
    font-size: var(--font-size-2xs);
    font-weight: 500;
    color: var(--text-2);
    text-align: center;
    line-height: var(--lh-snug);
}

.home-mobile[b-asqd4d2305]  .u-text-primary { color: var(--primary); }
.home-mobile[b-asqd4d2305]  .u-text-info    { color: var(--blue); }
.home-mobile[b-asqd4d2305]  .u-text-warning { color: var(--orange); }
.home-mobile[b-asqd4d2305]  .u-text-success { color: var(--green); }

/* ── Danh sách dòng đơn hàng gần đây ──
   Dùng lại nguyên khối .ordr-item/.ordr-headtop/.ordr-av/.ordr-id/.ordr-cust/.ordr-phone/
   .ordr-headbot/.ordr-amt-lg/.pickup/.status đã có sẵn trong app.mobile.css (global, dùng chung với
   Bills/RevenueReportDetail) — file này chỉ còn 2 việc riêng: bỏ gạch chân của NavLink (thẻ <a>,
   .ordr-item ở nơi khác luôn là <article>/@onclick nên chưa cần reset text-decoration) và đệm đáy
   cho khối skeleton (chỉ có .ordr-headtop, không có .ordr-headbot nên thiếu padding-bottom). */
.home-mobile[b-asqd4d2305]  .home-recent {
    display: flex;
    flex-direction: column;
}

.home-mobile[b-asqd4d2305]  .home-recent .ordr-item {
    text-decoration: none;
}

.home-mobile[b-asqd4d2305]  .home-recent .recent-skeleton .ordr-headtop {
    padding-bottom: var(--pad-card);
}

/* ── Skeleton + empty state ── */
.home-mobile[b-asqd4d2305]  .recent-skeleton {
    pointer-events: none;
}

/* Skeleton cho ô số liệu — căn giữa giống .stat-tile thật (số lớn trên, label dưới) */
.home-mobile[b-asqd4d2305]  .stat-skeleton {
    pointer-events: none;
}

.home-mobile[b-asqd4d2305]  .stat-skeleton .mud-skeleton {
    border-radius: var(--r-sm);
}

.home-mobile[b-asqd4d2305]  .home-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 32px 0;
    color: var(--text-3);
}

.home-mobile[b-asqd4d2305]  .home-empty-ic {
    width: 40px;
    height: 40px;
    font-size: 40px;
    color: var(--text-3);
}

.home-mobile[b-asqd4d2305]  .home-empty-text {
    font-size: var(--font-size-sm);
}

/* ── Bản quyền / hotline hỗ trợ ──
   margin-top:auto đẩy khối này xuống đáy vùng cuộn khi nội dung ngắn hơn màn hình (giống
   margin-top:auto ở bản desktop); padding-top giữ khoảng cách tối thiểu khi danh sách dài
   tràn màn hình (lúc đó auto-margin tự co về 0, không tạo khoảng trống). */
.home-mobile[b-asqd4d2305]  .home-footer {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin-top: auto;
    padding-top: 22px;
    padding-bottom: 4px;
}

.home-mobile[b-asqd4d2305]  .home-footer-copy {
    font-size: var(--font-size-xs);
    color: var(--text-3);
}

.home-mobile[b-asqd4d2305]  .home-footer-hotline.mud-chip {
    height: auto;
    padding: 7px 14px;
    background: var(--red-soft);
    color: var(--red);
    font-size: var(--font-size-sm);
    font-weight: 700;
}

.home-mobile[b-asqd4d2305]  .home-footer-hotline .mud-chip-icon {
    color: var(--red);
    width: 16px;
    height: 16px;
    font-size: 16px;
}
/* /Pages/Index.razor.rz.scp.css */
/* QA #11 (desktop only): rule global .mt-2 { margin-top: 1px !important } trong app.css bị dùng
   chung ở nhiều trang report khác (Bills, RevenueReportDetail, OtherIncome, OtherExpenses,
   FinancialDetail, FinancialReport, DlgCustomerHistory) — KHÔNG được sửa trực tiếp rule đó (sẽ phá
   desktop/mobile các trang kia). Thêm 1 class riêng cho đúng khối lưới module ở trang Home desktop,
   specificity 2 lớp (.idx-module-grid.mt-2) thắng rule 1 lớp gốc mà không đụng gì ở nơi khác.
   ::deep bắt buộc vì class gắn qua Class= lên <MudPaper> (component, DOM gốc không mang
   scope-attribute của Index.razor). */
[b-c6j5mtsr3f] .idx-module-grid.mt-2 {
  margin-top: 16px !important;
}
/* /Pages/ListItemPages/BankDetail.razor.rz.scp.css */
/* BankDetail.razor.css — Form thêm/sửa tài khoản ngân hàng, giao diện mobile (desktop giữ nguyên).
   Không có prototype form riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn
   riêng) cho form, field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment
   ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .bankd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.bankd-m .bankd-scroll[b-7c6hvdqcel] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.bankd-m .bankd-scroll[b-7c6hvdqcel]::-webkit-scrollbar { display: none; }

/* /Pages/ListItemPages/Banks.razor.rz.scp.css */
/* Banks.razor.css — Tài khoản ngân hàng, giao diện mobile (desktop giữ nguyên). Tham khảo prototype
   banks (khối style riêng trong banks.html). Primitive dùng chung (app bar, thanh điều hướng trên,
   thẻ card, hàng grouped-list, sheet hành động) đã có ở stylesheet mobile toàn cục, không lặp lại ở
   đây. Không viết tên class kèm dấu chấm trong comment ở file này — có thể làm hỏng bộ rewrite scope
   CSS của Blazor và khiến rule ngay sau bị bỏ qua (đã gặp bug thật trước đây ở các trang khác). */

/* .bank-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.bank-m .bank-scroll[b-v1e87v5hwc] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.bank-m .bank-scroll[b-v1e87v5hwc]::-webkit-scrollbar { display: none; }

/* Hàng tài khoản — literal div trong .card card--grouped (không Virtualize, danh sách rất ít dòng)
   nên nhận scope bình thường, không cần ::deep. Dùng chung hairline/active-state của .settings-row
   (global); tự bố cục flex riêng vì hình dạng khác .settings-row__content (logo + khối chi tiết + chevron). */
/* display/width/lề trái-phải/cursor đã gộp global (.bank-row nằm trong selector list dùng chung,
   xem app.mobile.css) — ở đây chỉ còn phần khác biệt thật của riêng Banks. */
.bank-m .bank-row[b-v1e87v5hwc] {
  align-items: center;
  gap: 13px;
  padding-top: 13px;
  padding-bottom: 13px;
  --list-inset: 16px;
}

.bank-m .bank-logo[b-v1e87v5hwc] {
  flex: none;
  width: 66px;
  height: 50px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--line);
}
.bank-m .bank-logo[b-v1e87v5hwc]  img { max-width: 100%; max-height: 100%; object-fit: contain; }
.bank-m .bank-logo[b-v1e87v5hwc]  .mud-icon-root { width: 26px; height: 26px; font-size: 26px; color: var(--text-3); }

.bank-m .bank-main[b-v1e87v5hwc] { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bank-m .bank-name[b-v1e87v5hwc] { font-size: var(--font-size-md); font-weight: 700; color: var(--text); line-height: var(--lh-snug); }
.bank-m .bank-full[b-v1e87v5hwc] {
  font-size: var(--font-size-xs); color: var(--text-2); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bank-m .bank-detail[b-v1e87v5hwc] { display: flex; flex-direction: column; gap: 1px; margin-top: 6px; }
.bank-m .bank-holder[b-v1e87v5hwc] { font-size: var(--font-size-sm); font-weight: 700; color: var(--text); }
.bank-m .bank-no[b-v1e87v5hwc] { font-family: 'Roboto Mono', monospace; font-size: var(--font-size-xs); color: var(--text-2); margin-top: 2px; }
.bank-m .bank-note[b-v1e87v5hwc] { font-size: var(--font-size-xs); font-style: italic; color: var(--text-3); margin-top: 3px; }

.bank-m .settings-chev[b-v1e87v5hwc] { flex: none; margin-left: -2px; }

/* .bank-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

.bank-m .bank-skel[b-v1e87v5hwc] { align-items: flex-start; }
.bank-m .bank-skel[b-v1e87v5hwc]  .mud-skeleton { border-radius: 10px; }
/* /Pages/ListItemPages/BillPrintedTemplate.razor.rz.scp.css */
/* Mẫu phiếu in — giao diện mobile (desktop giữ nguyên). Giữ nguyên Summernote (JS interop có sẵn),
   chỉ restyle DOM của nó qua deep để lấp đầy khung flex thay vì chiều cao cố định 600px, và thêm
   thanh hành động 3 nút dưới cùng (Lấy mẫu/Xem trước/Lưu). */

/* .pt-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.pt-m .pt-editor-wrap[b-rcsmtfl3gx] {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  background: var(--color-card);
}

.pt-m[b-rcsmtfl3gx]  .pt-skel { height: 100% !important; }

/* Summernote (jQuery) tự chèn markup vào #summernote sau khi Blazor render xong -> các phần tử
   này KHÔNG mang scope-attribute của component, phải dùng ::deep mới với tới được. */
.pt-m[b-rcsmtfl3gx]  .note-editor.note-frame {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: none;
  border-radius: 0;
}
.pt-m[b-rcsmtfl3gx]  .note-toolbar {
  flex: none;
  background: var(--color-card);
  border-bottom: 1px solid var(--line);
}
.pt-m[b-rcsmtfl3gx]  .note-editing-area {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.pt-m[b-rcsmtfl3gx]  .note-editable {
  flex: 1 1 auto;
  min-height: 0 !important;
  height: auto !important;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
/* Thanh kéo giãn chiều cao editor không còn ý nghĩa khi editor đã lấp đầy khung flex sẵn. */
.pt-m[b-rcsmtfl3gx]  .note-statusbar { display: none; }

/* ── Thanh hành động 3 nút dưới cùng (Lấy mẫu / Xem trước / Lưu thay đổi) ──
   QA #14: tăng gap 8px->12px (khớp nhịp 12px đã dùng ở NewBill), thêm min-height 44px cho nút vì
   trước đây không có height nào riêng, phụ thuộc hoàn toàn mặc định Size.Small của MudButton nên
   bị nhỏ. */
.pt-m .pt-actions[b-rcsmtfl3gx] {
  flex: none;
  display: flex;
  gap: 12px;
  padding: 10px 12px calc(12px + var(--nav-clearance, 110px));
  background: var(--color-card);
  border-top: 1px solid var(--line);
}
.pt-m[b-rcsmtfl3gx]  .pt-act.mud-button-root {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  border-radius: var(--r-md) !important;
  text-transform: none;
  font-size: var(--font-size-xs);
  padding-left: 4px;
  padding-right: 4px;
}
.pt-m .pt-act-skel[b-rcsmtfl3gx] { flex: 1 1 0; min-width: 0; height: 44px; border-radius: var(--r-md); }
/* /Pages/ListItemPages/CustomerDebtDetail.razor.rz.scp.css */
/* CustomerDebtDetail.razor.css — Chi tiết nợ khách hàng, giao diện mobile (desktop giữ nguyên).
   Tham khảo prototype debt-detail (khối SCREEN DEBT DETAIL trong stylesheet global của prototype).
   Primitive dùng chung (app bar, thanh điều hướng trên, thẻ card cơ bản, sheet hành động, sheet lọc)
   đã có ở stylesheet mobile toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong
   comment ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ
   qua (đã gặp bug thật, xem lịch sử fix ngày 2026-07-05). */

/* .debt-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.debt-m .debt-scroll[b-lvn9qza78w] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.debt-m .debt-scroll[b-lvn9qza78w]::-webkit-scrollbar { display: none; }

/* .cust-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

/* Tab gạch dưới (Công nợ/Lịch sử) — đã promote sang app.mobile.css (global) — DlgCustomerHistory là
   consumer thứ 2 (dialog không có shell class riêng nên bắt buộc phải global). Không lặp lại ở đây. */

/* Thẻ tổng nợ (hero) */
.debt-m .debt-card[b-lvn9qza78w] { padding: 22px 16px 18px; text-align: center; margin-bottom: 16px; }
.debt-m .debt-card .nm[b-lvn9qza78w] { font-size: var(--font-size-lg); font-weight: 800; color: #fff; text-transform: uppercase; letter-spacing: .02em; }
.debt-m .debt-card .total-label[b-lvn9qza78w] { font-size: var(--font-size-sm); color: rgba(255,255,255,.85); margin-top: 10px; }
.debt-m .debt-card .total-amt[b-lvn9qza78w] { font-size: var(--font-size-2xl); font-weight: 800; color: #fff; margin-top: 3px; line-height: 1.1; }
/* .debt-pay2 giờ là MudButton (trước là <button> thô) -> mọi selector con phải dùng ::deep
   (DOM gốc MudButton không mang scope-attribute của trang cha), display:contents cho
   .mud-button-label để 3 span con tham gia thẳng vào flex-row, reset text-transform vì .sub
   là chữ thường tự nhiên. */
.debt-m[b-lvn9qza78w]  .debt-pay2 {
  width: 100%; border: none; border-radius: var(--r-md); background: #fff; color: var(--primary);
  font-family: inherit; cursor: pointer; padding: 12px 14px; margin-top: 16px; text-transform: none;
  display: flex; flex-direction: row; align-items: center; gap: 13px;
  box-shadow: 0 10px 26px rgba(28,18,70,.22); transition: transform .14s ease;
}
.debt-m[b-lvn9qza78w]  .debt-pay2 .mud-button-label { display: contents; }
.debt-m[b-lvn9qza78w]  .debt-pay2:disabled { opacity: .55; cursor: default; }
.debt-m[b-lvn9qza78w]  .debt-pay2:active:not(:disabled) { transform: scale(.98); }
.debt-m[b-lvn9qza78w]  .debt-pay2 .pay-ic2 {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary); display: grid; place-items: center;
}
.debt-m[b-lvn9qza78w]  .debt-pay2 .pay-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.debt-m[b-lvn9qza78w]  .debt-pay2 .main { font-size: var(--font-size-lg); font-weight: 800; color: var(--primary); }
.debt-m[b-lvn9qza78w]  .debt-pay2 .sub { font-size: var(--font-size-xs); font-weight: 500; color: var(--text-2); }
.debt-m[b-lvn9qza78w]  .debt-pay2 .pay-chev { flex: none; color: var(--primary); }

/* Tiêu đề danh sách (chọn tất cả + số phiếu) — margin trái/phải 14px khớp đúng padding-left của
   .debt-item (14px) để checkbox "chọn tất cả" thẳng hàng với checkbox từng phiếu bên dưới. */
.debt-m .pts-listhead[b-lvn9qza78w] { display: flex; align-items: center; gap: 12px; margin: 0 14px 12px; }
.debt-m .pts-listhead .cnt[b-lvn9qza78w] { margin-left: auto; font-size: var(--font-size-sm); color: var(--text-3); }
.debt-m .pts-listhead .t[b-lvn9qza78w] { font-size: var(--font-size-sm); font-weight: 700; color: var(--text-2); }
.debt-m .debt-selall[b-lvn9qza78w] { display: flex; cursor: pointer; }

/* Checkbox chọn-tất-cả + từng phiếu nợ — MudCheckBox thật (không còn span/MudIcon Check tự vẽ),
   style mặc định của MudBlazor, theo đúng tiền lệ .pck-row ở UserPermission.razor. ReadOnly vì
   toggle thật do CẢ HÀNG đảm nhận (tap bất kỳ đâu trên hàng) — pointer-events:none để click thẳng
   vào checkbox không bị MudCheckBox chặn bubbling, rơi xuống đúng @onclick của hàng phía sau. */
.debt-m[b-lvn9qza78w]  .chk-box { flex: none; margin: 0; padding: 0; }
/* Nền tròn nhạt bao quanh checkbox — chỉ áp cho checkbox TỪNG PHIẾU (.debt-item), không áp cho
   checkbox "Chọn tất cả" (.debt-selall). MudCheckBox mặc định vùng bấm .mud-icon-button đã sẵn
   border-radius:50% (dùng cho hiệu ứng ripple khi bấm) nhưng nền trong suốt lúc đứng yên; tô nền nhẹ
   thường trực cùng hình tròn đó để không "trôi" giữa 2 trạng thái đứng yên/đang bấm. */
.debt-m[b-lvn9qza78w]  .debt-item .chk-box .mud-icon-button { background: var(--surface); }
.debt-m[b-lvn9qza78w]  .debt-selall .chk-box .mud-checkbox,
.debt-m[b-lvn9qza78w]  .debt-selall .chk-box .mud-checkbox *,
.debt-m[b-lvn9qza78w]  .debt-item .chk-box .mud-checkbox,
.debt-m[b-lvn9qza78w]  .debt-item .chk-box .mud-checkbox * { pointer-events: none !important; }

/* Card phiếu nợ (chọn được) — align-items:center để checkbox canh giữa chiều dọc so với toàn bộ
   nội dung card (2 dòng: mã phiếu/tiền + người tạo/ngày), không lệch lên trên theo mặc định stretch. */
.debt-m .debt-item[b-lvn9qza78w] {
  background: var(--card); border-radius: var(--r-md); padding: 13px 14px; margin-bottom: 10px;
  box-shadow: var(--shadow-card); display: flex; align-items: center; gap: 12px; cursor: pointer;
}
.debt-m .debt-item-main[b-lvn9qza78w] { flex: 1; min-width: 0; }
.debt-m .debt-item-top[b-lvn9qza78w] { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* .code giờ là MudLink (trước là <span> thuần) để bấm mở được DlgBillInfo giống logic desktop
   (OnShowBillInfo) -> ::deep bắt buộc (DOM gốc MudLink không mang scope-attribute của trang). */
.debt-m[b-lvn9qza78w]  .debt-item .code { font-family: var(--font-mono); font-size: var(--font-size-base); font-weight: 700; color: var(--primary); }
.debt-m .debt-item .val[b-lvn9qza78w] {
  flex: none; font-size: var(--font-size-sm); font-weight: 700; color: var(--orange); background: var(--orange-soft);
  padding: 4px 11px; border-radius: 999px; white-space: nowrap;
}
.debt-m .debt-item-meta[b-lvn9qza78w] { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; margin-top: 9px; }
.debt-m .debt-item-meta .who[b-lvn9qza78w], .debt-m .debt-item-meta .when[b-lvn9qza78w] { display: flex; align-items: center; gap: 6px; font-size: var(--font-size-xs); }
.debt-m .debt-item-meta .who[b-lvn9qza78w] { color: var(--text-2); }
.debt-m .debt-item-meta .when[b-lvn9qza78w] { color: var(--text-3); }
.debt-m .debt-item-meta[b-lvn9qza78w]  .mud-icon-root { flex: none; color: var(--text-3); width: 13px; height: 13px; font-size: 13px; }

/* Phiếu thu (lịch sử thanh toán) */
.debt-m .pay-item[b-lvn9qza78w] { padding: 14px; margin-bottom: 12px; cursor: pointer; }
.debt-m .pay-head[b-lvn9qza78w] { display: flex; align-items: center; gap: 11px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.debt-m .pay-ic[b-lvn9qza78w] {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary); display: grid; place-items: center;
}
.debt-m .pay-ic[b-lvn9qza78w]  .mud-icon-root { width: 19px; height: 19px; font-size: 19px; }
.debt-m .pay-code[b-lvn9qza78w] { flex: 1; min-width: 0; font-family: var(--font-mono); font-size: var(--font-size-md); font-weight: 700; color: var(--primary); }
.debt-m .pay-amt[b-lvn9qza78w] {
  flex: none; font-size: var(--font-size-sm); font-weight: 700; color: var(--green); background: var(--green-soft);
  padding: 5px 12px; border-radius: 999px; white-space: nowrap;
}
.debt-m .pay-rows[b-lvn9qza78w] { margin-top: 12px; display: flex; flex-direction: column; gap: 11px; }
.debt-m .pay-row[b-lvn9qza78w] { display: flex; align-items: center; gap: 9px; font-size: var(--font-size-sm); color: var(--text-2); }
.debt-m .pay-row[b-lvn9qza78w]  .mud-icon-root { flex: none; width: 16px; height: 16px; font-size: 16px; color: var(--text-3); }
.debt-m .pay-row b[b-lvn9qza78w] { color: var(--text); font-weight: 700; margin-left: 2px; }
/* /Pages/ListItemPages/CustomerDetail.razor.rz.scp.css */
/* CustomerDetail.razor.css — Form thêm/sửa khách hàng, giao diện mobile (desktop giữ nguyên). Không
   có prototype riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn riêng) cho
   form, field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment ở file
   này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua (đã gặp bug
   thật, xem lịch sử fix ngày 2026-07-05). */

/* .custd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.custd-m .custd-scroll[b-l1yple4dge] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.custd-m .custd-scroll[b-l1yple4dge]::-webkit-scrollbar { display: none; }

/* /Pages/ListItemPages/CustomerPointHistory.razor.rz.scp.css */
/* CustomerPointHistory.razor.css — Lịch sử điểm tích lũy khách hàng, giao diện mobile (desktop giữ
   nguyên). Tham khảo prototype points-history (khối SCREEN POINTS HISTORY trong stylesheet global
   của prototype). Primitive dùng chung (app bar, thanh điều hướng trên, thẻ card cơ bản, sheet lọc)
   đã có ở stylesheet mobile toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong
   comment ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ
   qua (đã gặp bug thật, xem lịch sử fix ngày 2026-07-05). */

/* .pts-m: shell flex-column 100dvh đã gộp global (app.mobile.css).
   Vùng cố định (hero + tiêu đề danh sách) — KHÔNG cuộn cùng danh sách.
   Padding ngang 14px (= chuẩn --pad-card của các trang report) để hero/tiêu đề/card thẳng lề nhau
   và đồng nhất với OtherIncome/OtherExpenses/FinancialDetail/RevenueReportDetail. */
.pts-m .pts-fixed[b-k7u8usptxj] { flex: none; padding: 14px 14px 0; }

.pts-m .pts-scroll[b-k7u8usptxj] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* padding-top = 0 — khoảng cách với .pts-listhead đã do chính margin-bottom:12px của nó đảm nhận
     (chuẩn pts-listhead ở app.mobile.css); để top > 0 ở đây sẽ cộng dồn thành khoảng cách gấp đôi,
     giống OtherExpenses/OtherIncome/FinancialDetail (.list { padding: 0 14px ... }). */
  padding: 0 14px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.pts-m .pts-scroll[b-k7u8usptxj]::-webkit-scrollbar { display: none; }

/* .cust-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

/* Hero tóm tắt khách hàng */
.pts-m .pts-head-card[b-k7u8usptxj] { padding: 18px; margin-bottom: 20px; }
.pts-m .pts-cust[b-k7u8usptxj] { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.pts-m .pts-cust-av[b-k7u8usptxj] {
  flex: none; width: 46px; height: 46px; border-radius: 50%;
  background: rgba(255,255,255,.20); color: #fff; border: 1px solid rgba(255,255,255,.32);
  display: grid; place-items: center;
}
.pts-m .pts-cust-av[b-k7u8usptxj]  .mud-icon-root { width: 22px; height: 22px; font-size: 22px; }
.pts-m .pts-cust .lbl[b-k7u8usptxj] { font-size: var(--font-size-sm); color: rgba(255,255,255,.82); }
.pts-m .pts-cust .nm[b-k7u8usptxj] { font-size: var(--font-size-lg); font-weight: 800; color: #fff; text-transform: uppercase; margin-top: 1px; }

.pts-m .pts-stats[b-k7u8usptxj] {
  display: flex;
  background: rgba(255,255,255,.13); border: 1px solid rgba(255,255,255,.22);
  border-radius: var(--r-md); overflow: hidden;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.pts-m .pts-stat[b-k7u8usptxj] { flex: 1; text-align: center; padding: 12px 8px; }
.pts-m .pts-stat + .pts-stat[b-k7u8usptxj] { border-left: 1px solid rgba(255,255,255,.18); }
.pts-m .pts-stat .l[b-k7u8usptxj] { font-size: var(--font-size-2xs); font-weight: 700; color: rgba(255,255,255,.80); text-transform: uppercase; letter-spacing: .03em; }
.pts-m .pts-stat .n[b-k7u8usptxj] { font-size: var(--font-size-xl); font-weight: 800; margin-top: 7px; line-height: 1; color: #fff; }
.pts-m .pts-stat .n.pts-red[b-k7u8usptxj] { color: #FFC7D4; }
.pts-m .pts-stat .n.pts-green[b-k7u8usptxj] { color: #8CF3C6; }

/* Tiêu đề danh sách dùng CHUẨN chung pts-listhead (app.mobile.css): flex-start + cnt margin-left auto,
   gap 9px, margin 2px 0 12px, t/cnt 14px/text-3. Không override ở đây để đồng nhất với các trang khác. */

/* Card giao dịch */
.pts-m .pts-tx[b-k7u8usptxj] { margin-bottom: 12px; }
.pts-m .pts-tx-top[b-k7u8usptxj] { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
/* .pts-code (chip mã phiếu) đã promote lên app.mobile.css (global) — dùng chung với DlgCustomerHistory. */
.pts-m .pts-date[b-k7u8usptxj] { font-size: var(--font-size-xs); color: var(--text-3); margin-top: 8px; }
.pts-m .pts-delta[b-k7u8usptxj] { flex: none; text-align: right; }
.pts-m .pts-delta .d[b-k7u8usptxj] { font-size: var(--font-size-lg); font-weight: 800; color: var(--green); line-height: 1; }
.pts-m .pts-delta.pts-red .d[b-k7u8usptxj] { color: var(--red); }
.pts-m .pts-delta .l[b-k7u8usptxj] { font-size: var(--font-size-xs); font-weight: 600; color: var(--text-2); margin-top: 3px; }
.pts-m .pts-tx-foot[b-k7u8usptxj] {
  display: flex; justify-content: space-between; gap: 12px; margin-top: 13px;
  padding-top: 12px; border-top: 1px solid var(--line);
}
.pts-m .pts-f .l[b-k7u8usptxj] { font-size: var(--font-size-xs); color: var(--text-3); }
.pts-m .pts-f .v[b-k7u8usptxj] { font-size: var(--font-size-md); font-weight: 800; color: var(--text); margin-top: 4px; }
.pts-m .pts-f.right[b-k7u8usptxj] { text-align: right; }
/* /Pages/ListItemPages/Customers.razor.rz.scp.css */
/* Customers.razor.css — Danh sách khách hàng, giao diện mobile (desktop giữ nguyên). Tham khảo
   prototype customers (khối SCREEN CUSTOMERS trong stylesheet global của prototype). Primitive dùng
   chung (app bar, thanh điều hướng trên, thẻ card cơ bản, sheet hành động) đã có ở stylesheet mobile
   toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong comment ở file này — có thể
   làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua (đã gặp bug thật, xem
   lịch sử fix ngày 2026-07-05). */

/* .cust-m: shell flex-column 100dvh đã gộp global (app.mobile.css).
   Dòng tóm tắt dưới segment (.pts-listhead đã global — xem app.mobile.css) — cần thêm margin ngang
   14px vì header trang này không có 1 lớp bọc padding chung như các trang report, mỗi phần tử con tự
   lo margin riêng (khớp margin-left của .seg ngay phía trên). margin-bottom = 12px, GIỐNG HỆT chuẩn
   gốc .pts-listhead (app.mobile.css: margin:2px 0 12px) — không override thành 0 nữa (trước đây làm
   vậy rồi phải bù khoảng cách bị thiếu bằng padding-top của .cust-scroll, khiến 2 trang có margin
   nguồn khác nhau dù ra cùng 1 khoảng cách hiển thị; nay sửa tận gốc nên không cần bù ở đâu khác).
   TUYỆT ĐỐI không dùng margin-bottom ÂM ở đây để "kéo" khoảng cách lại gần — đã thử và gây lỗi thật khi
   cuộn (đo bằng browser thật): margin âm trên phần tử cuối của .header-zone (flex:0 0 auto) làm CO LẠI
   kích thước hộp mà header chiếm trong flex-column .cust-m, khiến .cust-scroll tràn ngược lên đúng phần
   âm đó -> card đầu cuộn qua sẽ bị đè/chồng lên dòng tóm tắt. */
.cust-m .cust-summary[b-3safisne2m] { margin: 12px 14px 12px; }

.cust-m .cust-scroll[b-3safisne2m] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Block layout (KHÔNG flex/gap) — GIỐNG HỆT .list ở OtherIncome/OtherExpenses/FinancialDetail/
     RevenueReportDetail: Virtualize chèn spacer <div>, nếu dùng flex+gap thì gap còn cộng thêm vào
     TRƯỚC card đầu tiên (giữa spacer và card thật), sinh ra ~10px "ảo" không kiểm soát được, khiến
     phải bù bằng padding-top lệch số khác trang này trang khác. Bỏ hẳn flex+gap, dùng margin-bottom
     trên từng card (xem .cust) để khoảng cách card-với-card, giống đúng pattern .oth-item (OtherIncome/OtherExpenses).
     padding-top = 0 vì khoảng cách với .cust-summary đã do margin-bottom:12px của chính nó đảm nhận. */
  padding: 0 var(--pad-card) calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.cust-m .cust-scroll[b-3safisne2m]::-webkit-scrollbar { display: none; }
/* ::deep bắt buộc: card thật <article class="card cust"> là HTML thuần (khớp bình thường không cần
   ::deep), nhưng card skeleton là <MudPaper Class="card cust cust-skel"> — DOM gốc không mang
   scope-attribute của trang, thiếu ::deep khiến skeleton mất hẳn margin-bottom -> các card skeleton
   dính sát nhau, khác hẳn khoảng cách 10px của dữ liệu thật (đúng gotcha đã ghi ở .cust-menu/.stat-box
   phía trên, tái diễn ở đây vì thêm rule sau nên quên mất). */
.cust-m[b-3safisne2m]  .cust { margin-bottom: var(--gap-list); }

/* .cust-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

.cust-m .cust-head[b-3safisne2m] { display: flex; gap: 11px; }
.cust-m .cust-head .head-main[b-3safisne2m] { flex: 1; min-width: 0; }
.cust-m .cust-row1[b-3safisne2m] { display: flex; align-items: center; gap: 8px; }
.cust-m .cust-name[b-3safisne2m] {
  flex: 1; min-width: 0; font-size: var(--font-size-base); font-weight: 700; color: var(--text);
  text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Màu var(--text-2) (rgba(0,0,0,.6)) thay vì var(--text-3) (rgba(0,0,0,.38) — đúng bằng ngưỡng
   "disabled" chuẩn Material Design) để chevron không bị hiểu lầm là control đang vô hiệu hóa. */
/* .cust-menu là MudIconButton -> ::deep bắt buộc (DOM gốc không mang scope-attribute của trang),
   thiếu ::deep khiến rule này chết hoàn toàn từ trước tới giờ (kể cả kích thước/margin gốc). */
.cust-m[b-3safisne2m]  .cust-menu {
  flex: none; width: 30px; height: 30px; margin: -4px -6px 0 0;
  border: none; background: none; color: var(--text-2); cursor: pointer;
  border-radius: 8px; display: grid; place-items: center;
}
.cust-m[b-3safisne2m]  .cust-menu:active { background: var(--surface); }
.cust-m[b-3safisne2m]  .cust-menu .mud-icon-root { width: 15px; height: 15px; font-size: 15px; }

.cust-m .debt-badge[b-3safisne2m] {
  flex: none; margin-top: 2px; font-size: var(--font-size-xs); font-weight: 700;
  color: var(--red); background: var(--red-soft); padding: 4px 11px; border-radius: 999px;
  white-space: nowrap; cursor: pointer;
}
/* Hiện SĐT (kèm địa chỉ nếu có) — base(14) thay vì sm(13): SĐT cần đọc chính xác từng ký tự.
   Ellipsis đã có sẵn nên tăng size không gây tràn, chỉ cắt bớt sớm hơn 1-2 ký tự khi quá dài. */
.cust-m .cust-line[b-3safisne2m] {
  display: flex; align-items: center; gap: 8px; margin-top: 3px;
  font-size: var(--font-size-base); line-height: var(--lh-snug); color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cust-m .cust-line.is-empty[b-3safisne2m] { color: var(--color-text-muted, var(--text-3)); }
.cust-m .cust-line .dot[b-3safisne2m] { color: var(--text-3); margin: 0 1px; }

.cust-m .cust-divider[b-3safisne2m] { height: 0; background: none; margin: 7px 0; }

/* Địa chỉ khi khách CHƯA từng phát sinh đơn — sibling của cust-head (căn trái theo mép card, không
   lồng trong head-main), có vạch kẻ trên đầu, style khớp đúng .row-note của Bills.razor (icon + text
   wrap tối đa 2 dòng). */
.cust-m .cust-addr[b-3safisne2m] {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 12px; border-top: 1px solid var(--line);
  padding: 12px 2px 0;
  font-size: var(--font-size-base); line-height: var(--lh-normal); color: var(--text-2);
}
.cust-m .cust-addr[b-3safisne2m]  .mud-icon-root { flex: none; margin-top: 2px; color: var(--text-3); width: 14px; height: 14px; font-size: 14px; }
.cust-m .cust-addr span[b-3safisne2m] {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.cust-m .cust-stats[b-3safisne2m] { display: flex; gap: 10px; }
/* Không nền — chỉ giữ nội dung + khoảng cách (padding), để .val màu xanh (action-link) tự báo hiệu
   bấm được thay vì dùng khối nền phẳng.
   ::deep bắt buộc: box "Tổng đơn/Chi" giờ là MudButton (DOM gốc không mang scope-attribute của
   trang), còn box "Tích điểm/Ghé tiệm" vẫn là <a>/<div> thường — ::deep vẫn khớp bình thường cho cả
   2 trường hợp nên dùng chung 1 rule là đủ. Thiếu ::deep khiến toàn bộ rule bên dưới bị bỏ qua với
   MudButton -> rơi về CSS mặc định của MudBlazor (display:flex, padding 6px 8px) -> .lbl/.val (vốn
   display:block) bị ép thành flex-item nằm NGANG hàng thay vì xếp CHỒNG dọc như thiết kế. */
.cust-m[b-3safisne2m]  .stat-box {
  flex: 1; min-width: 0;
  padding: 9px 10px; cursor: pointer;
  text-align: left; text-decoration: none; display: block;
}
/* Chưa có dữ liệu (0 điểm) -> không cho bấm, làm mờ để phân biệt trực quan. */
.cust-m[b-3safisne2m]  .stat-box.disabled,
.cust-m[b-3safisne2m]  .stat-box:disabled {
  cursor: default; opacity: .5; pointer-events: none;
}
/* Chưa bật tích điểm -> box "Ghé tiệm" không phải action-link (không @onclick, không phải <a>):
   trả .val về màu chữ mặc định của hệ thống (var(--text)) thay vì màu xanh action-link. */
.cust-m[b-3safisne2m]  .stat-box.static { cursor: default; }
.cust-m[b-3safisne2m]  .stat-box.static .val { color: var(--text); }
.cust-m[b-3safisne2m]  .stat-box .lbl {
  font-size: var(--font-size-2xs); font-weight: 700; color: var(--text-3); letter-spacing: .02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Action-link: cả khối giá trị tô màu xanh để báo hiệu bấm được, đồng nhất với hệ thống. */
.cust-m[b-3safisne2m]  .stat-box .val {
  font-size: var(--font-size-sm); font-weight: 600; color: var(--blue, #2196F3); margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cust-m[b-3safisne2m]  .stat-box .val b { font-weight: 800; }
.cust-m[b-3safisne2m]  .stat-box .val .sep { color: var(--text-3); margin: 0 2px; }

/* Skeleton loading — tái dùng đúng class layout thật để khớp kích thước, không giật khung */
.cust-m .cust-skel[b-3safisne2m] { cursor: default; }
.cust-m .cust-skel[b-3safisne2m]  .mud-skeleton-circle { flex: none; }
/* /Pages/ListItemPages/ImpCustomer.razor.rz.scp.css */
/* ImpCustomer.razor.css — Nhập khách hàng từ file Excel, giao diện mobile (desktop giữ nguyên).
   Markup thật (shell + scroll + card) đã chuyển vào component dùng chung
   Shared/Components/ImportExcelForm.razor — CSS tương ứng (.impc-m .impc-scroll...) cũng đã chuyển
   sang ImportExcelForm.razor.css vì phần tử giờ do component đó render, không phải file này (scoped
   CSS ở đây sẽ không khớp được — xem comment tại ImportExcelForm.razor.css). File này không còn CSS
   riêng nào. */
/* /Pages/ListItemPages/ImpService.razor.rz.scp.css */
/* ImpService.razor.css — Nhập dịch vụ từ file Excel, giao diện mobile (desktop giữ nguyên).
   Markup thật (shell + scroll + card) đã chuyển vào component dùng chung
   Shared/Components/ImportExcelForm.razor — CSS tương ứng (.imps-m .imps-scroll...) cũng đã chuyển
   sang ImportExcelForm.razor.css vì phần tử giờ do component đó render, không phải file này (scoped
   CSS ở đây sẽ không khớp được — xem comment tại ImportExcelForm.razor.css). File này không còn CSS
   riêng nào. */
/* /Pages/ListItemPages/RackDetail.razor.rz.scp.css */
/* RackDetail.razor.css — Form thêm/sửa kệ lưu đồ, giao diện mobile (desktop giữ nguyên). Không có
   prototype form riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn riêng) cho
   form, field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment ở file
   này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .rackd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.rackd-m .rackd-scroll[b-cikwlcqjop] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.rackd-m .rackd-scroll[b-cikwlcqjop]::-webkit-scrollbar { display: none; }

/* /Pages/ListItemPages/Racks.razor.rz.scp.css */
/* Racks.razor.css — Kệ lưu đồ, giao diện mobile (desktop giữ nguyên). Tham khảo prototype shelves
   (khối override trong shelves.html: không có leading icon nên đường kẻ/lề chạy từ 16px). Primitive
   dùng chung (app bar, thanh điều hướng trên, thẻ card, hàng grouped-list, sheet hành động) đã có ở
   stylesheet mobile toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong comment ở
   file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .rack-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.rack-m .rack-scroll[b-jm7ffi8g1i] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.rack-m .rack-scroll[b-jm7ffi8g1i]::-webkit-scrollbar { display: none; }

/* Hàng kệ — literal div trong .card card--grouped (không Virtualize). Dùng chung hairline/
   active-state của .settings-row (global); không có leading icon nên lề/đường kẻ thụt 16px. */
/* display/width/lề trái-phải/cursor đã gộp global (.rack-row nằm trong selector list dùng chung,
   xem app.mobile.css) — ở đây chỉ còn phần khác biệt thật của riêng Racks. */
.rack-m .rack-row[b-jm7ffi8g1i] {
  align-items: center;
  gap: 12px;
  padding-top: 14px;
  padding-bottom: 14px;
  --list-inset: 16px;
}

.rack-m .rack-main[b-jm7ffi8g1i] { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rack-m .rack-name[b-jm7ffi8g1i] {
  font-size: var(--font-size-md); font-weight: 500; color: var(--text); line-height: var(--lh-snug);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rack-m .rack-note[b-jm7ffi8g1i] {
  font-size: var(--font-size-xs); font-style: italic; color: var(--text-3); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.rack-m .settings-chev[b-jm7ffi8g1i] { flex: none; margin-left: -2px; }

/* .rack-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

.rack-m .rack-skel[b-jm7ffi8g1i] { min-height: 50px; }
/* /Pages/ListItemPages/ServiceDetail.razor.rz.scp.css */
/* ServiceDetail.razor.css — Form thêm/sửa dịch vụ, giao diện mobile (desktop giữ nguyên). Không có
   prototype riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn riêng) cho form,
   field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment ở file này —
   có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua (đã gặp bug thật
   ở các trang khác cùng dự án). */

/* .svcd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.svcd-m .svcd-scroll[b-2mfy9p2k21] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.svcd-m .svcd-scroll[b-2mfy9p2k21]::-webkit-scrollbar { display: none; }


/* Icon xoá trên topnav — .nav-icon-btn ép màu chữ mặc định (!important) nên cần selector riêng đè
   lại thành đỏ cho đúng ý nghĩa hành động huỷ. MudIconButton là component nên phải qua ::deep từ
   .svcd-m (element literal viết tay trong ServiceDetail.razor). */
.svcd-m[b-2mfy9p2k21]  .svcd-delete-btn { color: var(--red) !important; }
/* /Pages/ListItemPages/Services.razor.rz.scp.css */
/* Services.razor.css — Bảng giá dịch vụ, giao diện mobile (desktop giữ nguyên). Tham khảo prototype
   services (khối SCREEN SERVICES trong stylesheet global của prototype). Primitive dùng chung (app
   bar, thanh điều hướng trên, thẻ card, hàng grouped-list, sheet hành động) đã có ở stylesheet mobile
   toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong comment ở file này — có thể
   làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua (đã gặp bug thật trước
   đây ở các trang khác cùng dự án). */

/* .svc-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.svc-m .svc-scroll[b-24cwnwi3x4] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}

.svc-m .svc-scroll[b-24cwnwi3x4]::-webkit-scrollbar {
  display: none;
}

/* Banner nhắc khi ở chế độ Sắp xếp — tint cam. Đặt NGOÀI .svc-scroll (xem Services.razor) nên là 1
   vùng cố định (flex:0 0 auto), không cuộn cùng danh sách — tránh dùng position:sticky bên trong
   vùng cuộn vì làm lệch phép đo của <Virtualize> (đã gặp bug chồng hình thật khi cuộn). Không còn
   nút "Xong" riêng trên topnav (đã bỏ) — thoát chế độ Sắp xếp bằng nút back (xem MOnBackClick) hoặc
   bấm Lưu thứ tự ngay đây. */
.svc-m .svc-sortbar[b-24cwnwi3x4] {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px 12px;
  background: var(--color-card);
  border: 1px solid rgba(251, 140, 0, .35);
  border-radius: var(--r-md);
  padding: 12px 12px;
  box-shadow: var(--shadow-sm);
}

.svc-m .svc-sortbar .txt[b-24cwnwi3x4] {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-xs);
  line-height: var(--lh-normal);
  color: var(--text-2);
}

.svc-m .svc-sortbar .txt b[b-24cwnwi3x4] {
  color: var(--orange);
}

/* Icon check-circle chèn giữa dòng chữ (giống desktop) để người dùng nhận ra đúng nút "đưa lên đầu".
   MudIcon render SVG do component con -> KHÔNG mang scope-attribute của trang, phải dùng ::deep từ
   .txt (element literal viết tay, có scope) mới target được. Ép cỡ nhỏ + căn theo dòng chữ. */
.svc-m .svc-sortbar .txt[b-24cwnwi3x4]  .svc-sortbar-ic {
  width: 16px;
  height: 16px;
  font-size: 16px;
  color: var(--green);
  vertical-align: text-bottom;
  margin: 0 1px;
}

.svc-m .svc-sortbar .save[b-24cwnwi3x4] {
  flex: none;
  border: none;
  border-radius: var(--r-md);
  cursor: pointer;
  background: var(--primary);
  color: #fff;
  font-family: inherit;
  font-size: var(--font-size-sm);
  font-weight: 700;
  letter-spacing: .02em;
  padding: 10px 13px;
}

.svc-m .svc-sortbar .save:active[b-24cwnwi3x4] {
  opacity: .85;
}

/* Mỗi dòng dịch vụ — literal div viết trực tiếp trong Virtualize's ItemContent (không bọc thêm div
   "card" ngoài, xem lý do ở Services.razor), nên nhận scope bình thường, không cần ::deep. Dùng chung
   hairline/active-state của .settings-row (global); nền trắng + bo góc đầu/cuối tự vẽ ở đây để mô
   phỏng hiệu ứng "1 khối card liền" như prototype dù không có div bọc chung. */
.svc-m .svc-row[b-24cwnwi3x4] {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 13px 14px 13px 16px;
  background: var(--color-card);
  cursor: pointer;
  /* Hairline chia dòng (rule global .settings-row + .settings-row::before) căn theo biến này. Prototype
     dùng 16px cho svc-row (khớp mép trái nội dung) thay vì 53px mặc định của settings-row -> đường kẻ
     mới thẳng hàng với chữ, không thụt vào lệch như trước. */
  --list-inset: 16px;
}

.svc-m .svc-row--first[b-24cwnwi3x4] {
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
}

.svc-m .svc-row--last[b-24cwnwi3x4] {
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
}

.svc-m .svc-main[b-24cwnwi3x4] {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.svc-m .svc-name[b-24cwnwi3x4] {
  font-size: var(--font-size-md);
  font-weight: 700;
  color: var(--text);
  line-height: var(--lh-snug);
}

.svc-m .svc-note[b-24cwnwi3x4] {
  font-size: var(--font-size-xs);
  color: var(--text-3);
  margin-top: 3px;
  line-height: 1.35;
}

.svc-m .svc-unit[b-24cwnwi3x4] {
  flex: none;
  min-width: 42px;
  text-align: right;
  font-size: var(--font-size-sm);
  color: var(--text-2);
}

.svc-m .svc-unit.none[b-24cwnwi3x4] {
  color: var(--text-3);
}

.svc-m .svc-price[b-24cwnwi3x4] {
  flex: none;
  min-width: 66px;
  text-align: right;
  font-size: var(--font-size-md);
  font-weight: 800;
  color: var(--text);
  letter-spacing: -.01em;
}

/* Chevron cuối dòng — tái dùng đúng class .settings-chev đã global (Options.razor dùng cùng kiểu). */
.svc-m .settings-chev[b-24cwnwi3x4] {
  margin-left: -4px;
}

/* Ô nhập số thứ tự (chế độ Sắp xếp) — tái dùng nguyên MudNumericField/adornment sẵn có của desktop
   (add/clear qua AdornmentIcon), chỉ restyle nhỏ gọn qua ::deep vì đây là component MudBlazor, khác
   .svc-row là literal element viết tay ở trên. */
.svc-m .svc-order[b-24cwnwi3x4] {
  flex: none;
  width: 84px;
}

.svc-m .svc-order[b-24cwnwi3x4]  .mud-input-slot {
  text-align: center;
  font-size: var(--font-size-md);
  font-weight: 700;
}

.svc-m .svc-order[b-24cwnwi3x4]  .mud-input-adornment {
  margin-left: 0;
}

/* .svc-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

.svc-m .svc-skel[b-24cwnwi3x4] {
  display: flex;
}
/* /Pages/ListItemPages/ShopDetail.razor.rz.scp.css */
/* ShopDetail.razor.css — Form thêm/sửa cửa hàng, giao diện mobile (desktop giữ nguyên). Không có
   prototype form riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn riêng) cho
   form, field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment ở file
   này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .shopd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.shopd-m .shopd-scroll[b-fua3fxy72c] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.shopd-m .shopd-scroll[b-fua3fxy72c]::-webkit-scrollbar { display: none; }

/* /Pages/ListItemPages/Shops.razor.rz.scp.css */
/* Shops.razor.css — Danh sách cửa hàng, giao diện mobile (desktop giữ nguyên). Tham khảo prototype
   stores (khối SCREEN STORES trong stylesheet global của prototype). Primitive dùng chung (app bar,
   thanh điều hướng trên, thẻ card, sheet hành động) đã có ở stylesheet mobile toàn cục, không lặp lại
   ở đây. Không viết tên class kèm dấu chấm trong comment ở file này — có thể làm hỏng bộ rewrite scope
   CSS của Blazor và khiến rule ngay sau bị bỏ qua (đã gặp bug thật trước đây ở các trang khác). */

/* .shop-m: shell flex-column 100dvh đã gộp global (app.mobile.css).
   Card-list: mỗi cửa hàng 1 card rời, có gap dọc (khác grouped-list của Services/Banks) */
.shop-m .shop-scroll[b-lk553tda92] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.shop-m .shop-scroll[b-lk553tda92]::-webkit-scrollbar { display: none; }

/* Cả card bấm được để mở action sheet */
.shop-m .shop[b-lk553tda92] { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.shop-m .shop:active[b-lk553tda92] { background: var(--surface); }
.shop-m .shop.shop-skel[b-lk553tda92] { cursor: default; }
.shop-m .shop.shop-skel:active[b-lk553tda92] { background: var(--color-card); }

/* Hàng đầu card: mã cửa hàng (pill mono) + tên + chevron chỉ dấu tap được */
.shop-m .shop-top[b-lk553tda92] { display: flex; align-items: center; gap: 9px; }
.shop-m .shop-code[b-lk553tda92] {
  flex: none; font-family: var(--font-mono); font-size: var(--font-size-xs); font-weight: 700;
  color: var(--primary-dark); background: var(--primary-soft);
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.shop-m .shop-name[b-lk553tda92] {
  flex: 1; min-width: 0; font-size: var(--font-size-md); font-weight: 800; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.shop-m .shop-menu[b-lk553tda92] {
  flex: none; width: 30px; height: 30px; margin: -4px -6px 0 0;
  color: var(--text-3); display: grid; place-items: center;
}
.shop-m .shop-menu[b-lk553tda92]  .mud-icon-root { width: 20px; height: 20px; font-size: 20px; }

/* Dòng thông tin (điện thoại/VAT/email, địa chỉ) — icon nhỏ + text, tự xuống dòng khi tràn */
.shop-m .shop-line[b-lk553tda92] {
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-top: 10px;
  font-size: var(--font-size-base); color: var(--text-2); line-height: 1.35;
}
.shop-m .shop-line[b-lk553tda92]  .mud-icon-root { flex: none; width: 15px; height: 15px; font-size: 15px; color: var(--text-3); }
.shop-m .shop-line .dot[b-lk553tda92], .shop-m .shop-line .bar[b-lk553tda92] { color: var(--border); }
.shop-m .shop-line .mail[b-lk553tda92] { color: var(--text-2); word-break: break-all; }
.shop-m .shop-line .vat[b-lk553tda92] { font-weight: 600; color: var(--text-2); }

/* Nhãn "Sử dụng bảng giá riêng" — icon check xanh */
.shop-m .shop-tag[b-lk553tda92] {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 11px;
  font-size: var(--font-size-base); color: var(--text-2);
}
.shop-m .shop-tag[b-lk553tda92]  .mud-icon-root { flex: none; width: 15px; height: 15px; font-size: 15px; color: var(--green); }

/* .shop-empty: trạng thái rỗng đã gộp global (app.mobile.css). */
/* /Pages/ListItemPages/Status.razor.rz.scp.css */
/* Status.razor.css — Trạng thái phiếu, giao diện mobile (desktop giữ nguyên). Tham khảo prototype
   statuses (khối override trong statuses.html: hàng có tiêu đề + mô tả, canh trên, lề chạy từ 16px).
   Primitive dùng chung (app bar, thanh điều hướng trên, thẻ card, hàng grouped-list, sheet hành động)
   đã có ở stylesheet mobile toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong
   comment ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .status-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.status-m .status-scroll[b-igwkle63bx] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.status-m .status-scroll[b-igwkle63bx]::-webkit-scrollbar { display: none; }

/* Hàng trạng thái — MudListItem (Class settings-row st-row) trong MudList; hai dòng (tiêu đề + mô tả),
   canh trên. Dùng chung hairline/active-state của settings-row (global); không có leading icon nên lề/
   đường kẻ thụt 16px (biến list-inset đặt trên chính MudListItem). Flex/padding đặt ở div con st-row
   content vì MudListItem bọc nội dung trong list-item-text. KHÔNG viết tên class kèm dấu chấm trong
   comment ở file này — làm hỏng bộ rewrite scope CSS của Blazor, rule NGAY SAU bị bỏ qua. */
/* ::deep vì st-row nằm trên ROOT của MudListItem (child component) — Blazor scoped CSS KHÔNG gắn
   thuộc tính scope b-xxx cho root của component con, nên rule scoped thường sẽ không khớp. */
.status-m[b-igwkle63bx]  .st-row { --list-inset: 16px; }
/* display/width/lề trái-phải/cursor đã gộp global (.st-row__content nằm trong selector list dùng
   chung, xem app.mobile.css) — ở đây chỉ còn phần khác biệt thật của riêng Status. */
.status-m .st-row__content[b-igwkle63bx] {
  align-items: flex-start;
  gap: 10px;
  padding-top: 14px;
  padding-bottom: 14px;
}

.status-m .st-meta[b-igwkle63bx] { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.status-m .st-title[b-igwkle63bx] {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--font-size-md); font-weight: 700; color: var(--text); line-height: var(--lh-snug);
}
.status-m[b-igwkle63bx]  .st-lock { flex: none; width: 15px; height: 15px; font-size: 15px; color: var(--red, #e23b3b); }
.status-m .st-desc[b-igwkle63bx] {
  margin-top: 4px; font-size: var(--font-size-sm); line-height: 1.4; color: var(--text-3); font-style: italic;
}
.status-m .st-desc.custom[b-igwkle63bx] { font-style: normal; }

/* Chevron canh với dòng tiêu đề (hàng canh trên) */
.status-m .settings-chev[b-igwkle63bx] { flex: none; margin-top: 1px; }

/* .status-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

.status-m .st-skel[b-igwkle63bx] { align-items: flex-start; }

/* Ghi chú khoá trong action sheet (trạng thái hệ thống) — thay cho Sửa/Xoá */
.status-m .sheet-locked-note[b-igwkle63bx] {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 2px 6px 6px;
  padding: 12px 14px;
  border-radius: var(--r-md, 14px);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--font-size-sm);
  line-height: var(--lh-normal);
}
.status-m .sheet-locked-note[b-igwkle63bx]  .mud-icon-root {
  flex: none; width: 18px; height: 18px; font-size: 18px; color: var(--text-3); margin-top: 1px;
}
/* /Pages/ListItemPages/StatusDetail.razor.rz.scp.css */
/* StatusDetail.razor.css — Form thêm/sửa trạng thái phiếu, giao diện mobile (desktop giữ nguyên).
   Không có prototype form riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn
   riêng) cho form, field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment
   ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .statusd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.statusd-m .statusd-scroll[b-ergbsvh8t5] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.statusd-m .statusd-scroll[b-ergbsvh8t5]::-webkit-scrollbar { display: none; }

/* /Pages/ListItemPages/UnitDetail.razor.rz.scp.css */
/* UnitDetail.razor.css — Form thêm/sửa đơn vị tính, giao diện mobile (desktop giữ nguyên). Không có
   prototype form riêng — chỉ áp shell mobile chung (app bar cố định trên, nội dung cuộn riêng) cho
   form, field vẫn giữ nguyên MudBlazor gốc. Không viết tên class kèm dấu chấm trong comment ở file
   này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .unitd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.unitd-m .unitd-scroll[b-r4ctf1vkhj] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.unitd-m .unitd-scroll[b-r4ctf1vkhj]::-webkit-scrollbar { display: none; }

/* /Pages/ListItemPages/Units.razor.rz.scp.css */
/* Units.razor.css — Đơn vị tính, giao diện mobile (desktop giữ nguyên). Tham khảo prototype units
   (khối override trong units.html: không có leading icon nên đường kẻ/lề chạy từ 16px). Primitive
   dùng chung (app bar, thanh điều hướng trên, thẻ card, hàng grouped-list, sheet hành động) đã có ở
   stylesheet mobile toàn cục, không lặp lại ở đây. Không viết tên class kèm dấu chấm trong comment ở
   file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị bỏ qua. */

/* .unit-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.unit-m .unit-scroll[b-jvupg80h1t] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.unit-m .unit-scroll[b-jvupg80h1t]::-webkit-scrollbar { display: none; }

/* Hàng đơn vị — MudListItem (Class settings-row unit-row) trong MudList, không Virtualize. Dùng chung
   hairline/active-state của settings-row (global); không có leading icon nên lề/đường kẻ thụt 16px
   (đặt biến list-inset trên chính MudListItem để hairline before đọc được). Flex/padding đặt ở div con
   unit-row content vì MudListItem bọc nội dung trong list-item-text. KHÔNG viết tên class kèm dấu chấm
   trong comment ở file này — làm hỏng bộ rewrite scope CSS của Blazor, rule NGAY SAU bị bỏ qua. */
/* ::deep vì unit-row nằm trên ROOT của MudListItem (child component) — Blazor scoped CSS KHÔNG gắn
   thuộc tính scope b-xxx cho root của component con, nên rule scoped thường sẽ không khớp. */
.unit-m[b-jvupg80h1t]  .unit-row { --list-inset: 16px; }
/* display/width/lề trái-phải/cursor đã gộp global (.unit-row__content nằm trong selector list dùng
   chung, xem app.mobile.css) — ở đây chỉ còn phần khác biệt thật của riêng Units. */
.unit-m .unit-row__content[b-jvupg80h1t] {
  align-items: center;
  gap: 12px;
  padding-top: 13px;
  padding-bottom: 13px;
}

.unit-m .unit-main[b-jvupg80h1t] { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.unit-m .unit-name[b-jvupg80h1t] {
  font-size: var(--font-size-md); font-weight: 500; color: var(--text); line-height: var(--lh-snug);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.unit-m .unit-note[b-jvupg80h1t] {
  font-size: var(--font-size-xs); font-style: italic; color: var(--text-3); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.unit-m .settings-chev[b-jvupg80h1t] { flex: none; margin-left: -2px; }

/* .unit-empty: trạng thái rỗng đã gộp global (app.mobile.css). */

.unit-m .unit-skel[b-jvupg80h1t] { min-height: 48px; }
/* /Pages/Overview.razor.rz.scp.css */
/* Overview.razor.css — trang "Tổng quan hôm nay" (mobile-only, không có bản desktop).
   Các lớp dùng chung (.card, .card--hero, .card--compact, .card--raised, .card--grouped,
   .settings-list, .settings-row, .settings-row__content, .settings-icon/.settings-label,
   .ic-*, .u-text-*) đã có ở wwwroot/css/app.mobile.css nên không lặp lại ở đây — file này chỉ
   chứa phần RIÊNG của trang: shell .ov-m, hero doanh thu, lưới trạng thái đơn, thanh phân bổ,
   cột giá trị bên phải của danh sách thanh toán.

   Shell .ov-m tự quản chiều cao/overflow (giống .fd-m/.bills-m các trang report): app bar đứng yên
   (flex:0 0 auto), chỉ .ov-scroll cuộn nội bộ — để scrollbar KHÔNG tràn qua vùng app bar (khác với
   pattern đơn giản của Options.razor/.more-scroll, vốn để .main-content cuộn cả trang).
   Shell flex-column 100dvh của .ov-m nay đã gộp chung ở app.mobile.css. */

.ov-scroll[b-z5zabwicpa] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 14px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.ov-scroll[b-z5zabwicpa]::-webkit-scrollbar {
  display: none;
}

.ov-title[b-z5zabwicpa] {
  font-size: var(--font-size-md);
  font-weight: 700;
  color: var(--text);
  margin: 4px 4px 12px;
}
.ov-title.mt[b-z5zabwicpa] {
  margin-top: 24px;
}

/* ── Hero doanh thu hôm nay (nền .card--hero global) ── */
.ov-hero[b-z5zabwicpa] {
  padding: 20px 18px;
  margin-bottom: 4px;
}
.ov-hero-top[b-z5zabwicpa] {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.ov-hero-label[b-z5zabwicpa] {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--font-size-sm);
  opacity: .9;
}
.ov-hero-date[b-z5zabwicpa] {
  font-size: var(--font-size-xs);
  font-weight: 600;
  background: rgba(255,255,255,.16);
  padding: 4px 10px;
  border-radius: 999px;
}
.ov-hero-value[b-z5zabwicpa] {
  font-size: var(--font-size-display);
  font-weight: 800;
  letter-spacing: -.02em;
  margin-top: 8px;
  line-height: 1;
}
.ov-hero-value .u[b-z5zabwicpa] {
  font-size: var(--font-size-lg);
  font-weight: 700;
  opacity: .85;
}
.ov-hero-trend[b-z5zabwicpa] {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--font-size-sm);
  font-weight: 600;
  margin-top: 8px;
  opacity: .95;
}
.ov-hero-trend.down[b-z5zabwicpa] {
  color: #FFD3D0;
}
.ov-hero-skel[b-z5zabwicpa] {
  margin-top: 8px;
  background-color: rgba(255, 255, 255, .22) !important;
  border-radius: 6px;
}

/* ── Trạng thái đơn: lưới 2×2, thẻ KHÔNG bấm được (không cursor/hover) ── */
.ov-grid[b-z5zabwicpa] {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.ov-card[b-z5zabwicpa] {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding: 14px;
  cursor: default;
}
.ov-card-ic[b-z5zabwicpa] {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  display: grid;
  place-items: center;
}
.ov-card-ic .mud-icon-root[b-z5zabwicpa] {
  font-size: 20px;
}
.ov-card-body[b-z5zabwicpa] {
  flex: 1;
  min-width: 0;
}
.ov-card-num[b-z5zabwicpa] {
  font-size: var(--font-size-xl);
  font-weight: 800;
  line-height: 1;
}
.ov-card-lbl[b-z5zabwicpa] {
  font-size: var(--font-size-xs);
  color: var(--text-2);
  margin-top: 4px;
}

/* ── Phân bổ đơn: thanh ngang nhiều đoạn màu + chú giải ── */
.ov-bar-card[b-z5zabwicpa] {
  padding: 16px 14px;
}
.ov-bar[b-z5zabwicpa] {
  display: flex;
  gap: 3px;
  height: 12px;
}
.ov-bar > span[b-z5zabwicpa] {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
}
.ov-bar-skel[b-z5zabwicpa] {
  border-radius: var(--r-pill);
}
.ov-legend[b-z5zabwicpa] {
  display: flex;
  flex-wrap: wrap;
  gap: 9px 16px;
  margin-top: 14px;
}
.ov-legend-item[b-z5zabwicpa] {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--font-size-xs);
  color: var(--text-2);
}
.ov-legend-dot[b-z5zabwicpa] {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  flex: none;
}
.ov-legend-item b[b-z5zabwicpa] {
  color: var(--text);
  font-weight: 700;
}

/* ── Thanh toán hôm nay: cột giá trị bên phải của mỗi .settings-row ──
   MudListItem/MudPaper là component MudBlazor nên phải qua ::deep (rule 10.1). */
[b-z5zabwicpa] .ov-row-right {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  margin-left: auto;
}
[b-z5zabwicpa] .ov-row-val {
  font-size: var(--font-size-md);
  font-weight: 800;
  color: var(--text);
}
/* Đặt tên "ov-green"/"ov-red" (không dùng bare "green"/"red") vì MudBlazor.min.css có sẵn
   class Materialize-style ".green { background-color: ... }" toàn cục — trùng tên sẽ dính
   nhầm nền màu xanh lá vào chữ (đã gặp lúc verify). */
[b-z5zabwicpa] .ov-row-val.ov-green {
  color: var(--green);
}
[b-z5zabwicpa] .ov-row-val.ov-red {
  color: var(--red);
}
[b-z5zabwicpa] .ov-row-cnt {
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--text-3);
}

/* Dòng tổng: nền nhạt + nhấn đậm, giống .ov-row.total của prototype */
[b-z5zabwicpa] .ov-total {
  background: #FAFAFC;
}
[b-z5zabwicpa] .ov-total .settings-label {
  font-weight: 700;
}
[b-z5zabwicpa] .ov-total .ov-row-val {
  color: var(--primary);
  font-size: var(--font-size-md);
}
/* /Pages/Report/FinancialChart.razor.rz.scp.css */
/* FinancialChart.razor.css — Báo cáo kinh doanh mobile (port từ Mobile.Prototype/report.html).
   Desktop giữ nguyên; các primitive .card/.topnav/.header-zone lấy từ app.mobile.css. */

/* .rpt-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */

.rpt-m[b-qujzyengic]  .rpt-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 14px 16px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.rpt-m[b-qujzyengic]  .rpt-scroll::-webkit-scrollbar { display: none; }

.rpt-m[b-qujzyengic]  .flt-group { margin-bottom: 20px; }
.rpt-m[b-qujzyengic]  .flt-row {
  display: flex;
  align-items: center;
  gap: 13px;
  width: 100%;
  padding: 12px 14px;
  cursor: pointer;
  position: relative;
}
.rpt-m[b-qujzyengic]  .flt-row + .flt-row::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50px;
  right: 0;
  height: 1px;
  background: var(--color-hairline);
  transform: scaleY(.5);
}
.rpt-m[b-qujzyengic]  .flt-row:active { background: rgba(28,27,46,.045); }
.rpt-m[b-qujzyengic]  .flt-ic { flex: none; width: 30px; height: 30px; border-radius: var(--r-sm); background: var(--primary-soft); color: var(--primary-dark); display: grid; place-items: center; }
.rpt-m[b-qujzyengic]  .flt-ic svg { width: 17px; height: 17px; }
.rpt-m[b-qujzyengic]  .flt-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.rpt-m[b-qujzyengic]  .flt-label { font-size: var(--font-size-xs); color: var(--text-3); }
.rpt-m[b-qujzyengic]  .flt-value { font-size: var(--font-size-md); font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rpt-m[b-qujzyengic]  .flt-chev { flex: none; color: var(--text-3); }

.rpt-m[b-qujzyengic]  .rpt-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 22px; }
.rpt-m[b-qujzyengic]  .rpt-stat { cursor: pointer; transition: transform var(--dur-fast) var(--ease-ios), box-shadow var(--dur-fast); }
.rpt-m[b-qujzyengic]  .rpt-stat:active { transform: scale(.98); box-shadow: var(--shadow-md); }
.rpt-m[b-qujzyengic]  .rpt-stat .lbl { font-size: var(--font-size-sm); color: var(--text-2); line-height: var(--lh-snug); min-height: 31px; }
.rpt-m[b-qujzyengic]  .rpt-stat .amt { font-size: var(--font-size-lg); font-weight: 800; margin-top: 7px; color: var(--c, #5246E0); line-height: 1; }
.rpt-m[b-qujzyengic]  .rpt-stat .stat-foot { display: flex; align-items: center; margin-top: 8px; }
.rpt-m[b-qujzyengic]  .rpt-stat .cnt { flex: 0 1 auto; max-width: 100%; display: inline-flex; align-items: center; gap: 4px; width: fit-content; font-size: var(--font-size-xs); font-weight: 700; color: var(--c, #5246E0); background: color-mix(in srgb, var(--c, #5246E0) 10%, #fff 90%); border-radius: 999px; padding: 3px 6px 3px 8px; line-height: var(--lh-tight); white-space: nowrap; }
.rpt-m[b-qujzyengic]  .rpt-stat .cnt .flt-chev { opacity: .62; color: inherit; }
.rpt-m[b-qujzyengic]  .rpt-stat-skel { cursor: default; }
.rpt-m[b-qujzyengic]  .rpt-stat-skel:active { transform: none; }

.rpt-m[b-qujzyengic]  .rpt-card { padding: 16px; margin-bottom: 16px; overflow: hidden; }
.rpt-m[b-qujzyengic]  .rpt-card-title { font-size: var(--font-size-md); font-weight: 700; color: var(--text); margin-bottom: 12px; }
.rpt-m[b-qujzyengic]  .rpt-chart-skel { border-radius: var(--r-md); }

/* Style ApexCharts sát prototype: card trắng, chart gọn, legend nhỏ, không toolbar. */
.rpt-m[b-qujzyengic]  .apexcharts-canvas,
.rpt-m[b-qujzyengic]  .apexcharts-svg { max-width: 100%; }
.rpt-m[b-qujzyengic]  .apexcharts-gridline { stroke: rgba(127, 127, 160, .14) !important; }
.rpt-m[b-qujzyengic]  .apexcharts-xaxis-tick,
.rpt-m[b-qujzyengic]  .apexcharts-xaxis line,
.rpt-m[b-qujzyengic]  .apexcharts-yaxis line { stroke: transparent !important; }
.rpt-m[b-qujzyengic]  .apexcharts-bar-area { filter: drop-shadow(0 4px 8px rgba(82,70,224,.10)); }
.rpt-m[b-qujzyengic]  .rpt-card:first-of-type .apexcharts-bar-area:nth-of-type(odd) { fill: var(--primary) !important; }
.rpt-m[b-qujzyengic]  .rpt-card:first-of-type .apexcharts-bar-area:nth-of-type(even) { fill: var(--green) !important; }
.rpt-m[b-qujzyengic]  .apexcharts-legend { justify-content: center !important; gap: 12px; padding-top: 2px !important; }
.rpt-m[b-qujzyengic]  .apexcharts-legend-marker { border-radius: 999px !important; }
.rpt-m[b-qujzyengic]  .apexcharts-legend-text { font-family: var(--font-ui) !important; font-size: var(--font-size-sm) !important; color: var(--text-2) !important; }
.rpt-m[b-qujzyengic]  .apexcharts-xaxis text,
.rpt-m[b-qujzyengic]  .apexcharts-yaxis text,
.rpt-m[b-qujzyengic]  .apexcharts-datalabel,
.rpt-m[b-qujzyengic]  .apexcharts-text { font-family: var(--font-ui) !important; fill: var(--text-3) !important; }
.rpt-m[b-qujzyengic]  .apexcharts-tooltip { border-radius: var(--r-md) !important; box-shadow: var(--shadow-md) !important; border: 0 !important; }
.rpt-m[b-qujzyengic]  .apexcharts-tooltip-title { font-family: var(--font-ui) !important; background: var(--surface) !important; border-bottom-color: var(--line) !important; }
.rpt-m[b-qujzyengic]  .apexcharts-tooltip-series-group { font-family: var(--font-ui) !important; }
.rpt-m[b-qujzyengic]  .rpt-card:last-of-type .apexcharts-yaxis-label { font-size: var(--font-size-xs) !important; }
.rpt-m[b-qujzyengic]  .rpt-card:last-of-type .apexcharts-bar-area { fill: var(--primary) !important; }
/* Top dịch vụ — port từ .rpt-svc trong Mobile.Prototype/styles.css (dùng list gradient thay ApexCharts) */
.rpt-m[b-qujzyengic]  .top-service-item + .top-service-item { margin-top: 13px; }
.rpt-m[b-qujzyengic]  .top-service-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.rpt-m[b-qujzyengic]  .top-service-name { min-width: 0; color: var(--text); font-size: var(--font-size-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rpt-m[b-qujzyengic]  .top-service-amount { flex: none; color: var(--text-2); font-size: var(--font-size-base); font-weight: 700; }
.rpt-m[b-qujzyengic]  .top-service-track { height: 8px; border-radius: 999px; background: var(--surface); margin-top: 6px; overflow: hidden; }
.rpt-m[b-qujzyengic]  .top-service-bar { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #60A5FA, #2563EB); }

/* Trạng thái đơn — donut CSS + legend, port từ .rpt-donut/.rpt-legend2 trong Mobile.Prototype/styles.css */
.rpt-m[b-qujzyengic]  .rpt-donut-wrap { display: flex; align-items: center; gap: 18px; }
.rpt-m[b-qujzyengic]  .rpt-donut { position: relative; width: 132px; height: 132px; border-radius: 50%; flex: none; }
.rpt-m[b-qujzyengic]  .rpt-donut-hole { position: absolute; inset: 26px; background: var(--card); border-radius: 50%; display: grid; place-items: center; text-align: center; }
.rpt-m[b-qujzyengic]  .rpt-donut-hole .n { font-size: var(--font-size-xl); font-weight: 800; line-height: 1; color: var(--text); }
.rpt-m[b-qujzyengic]  .rpt-donut-hole .l { font-size: var(--font-size-2xs); color: var(--text-2); margin-top: 3px; }
.rpt-m[b-qujzyengic]  .rpt-legend2 { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 13px; }
.rpt-m[b-qujzyengic]  .rpt-legend2-item { display: flex; align-items: center; gap: 9px; font-size: var(--font-size-base); color: var(--text); }
.rpt-m[b-qujzyengic]  .rpt-legend2-dot { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.rpt-m[b-qujzyengic]  .rpt-legend2-item .c { margin-left: auto; font-weight: 800; color: var(--text-2); }
.rpt-m[b-qujzyengic]  .rpt-empty { padding: 28px 8px; text-align: center; font-size: var(--font-size-base); color: var(--text-3); }

/* Bottom sheet prototype (store/time).
   QA #1: tái dùng biến z-index/border-radius dùng chung (app.mobile.css) thay vì số cứng 42/43 và
   --r-xl riêng — trước đây lệch "họ" z-index song song với phần còn lại của app, dễ sai nếu sau
   này đổi --z-sheet mà quên đồng bộ ở đây. */
.rpt-m[b-qujzyengic]  .bsheet-backdrop { position: fixed; inset: 0; background: rgba(18,16,40,.45); opacity: 0; pointer-events: none; transition: opacity .22s ease; z-index: calc(var(--z-sheet) - 1); }
.rpt-m[b-qujzyengic]  .bsheet-backdrop.open { opacity: 1; pointer-events: auto; }
.rpt-m[b-qujzyengic]  .bsheet {
  position: fixed; bottom: 0; left: 0; right: 0; transform: translateY(105%);
  width: 100%; background: var(--card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0; padding: 8px 10px calc(14px + env(safe-area-inset-bottom));
  transition: transform .26s cubic-bezier(.32,.72,.25,1); z-index: var(--z-sheet);
  box-shadow: var(--shadow-pop); max-height: 80vh; overflow-y: auto;
}
.rpt-m[b-qujzyengic]  .bsheet.open { transform: translateY(0); }
.rpt-m[b-qujzyengic]  .bsheet-h { font-size: var(--font-size-md); font-weight: 700; text-align: center; padding: 4px 0 10px; }
.rpt-m[b-qujzyengic]  .opt { display: flex; align-items: center; gap: 12px; width: 100%; border: none; background: none; font-family: inherit; cursor: pointer; text-align: left; padding: 13px 12px; font-size: var(--font-size-md); color: var(--text); border-radius: var(--r-md); text-transform: none; }
/* .opt/.bsheet-apply giờ là MudButton (trước là <button> thô) — MudButton bọc nội dung trong
   .mud-button-label, phá layout flex-row của .opt (icon check bị margin-left:auto không đẩy sang phải
   được vì kẹt trong 1 span riêng). display:contents để nội dung tham gia thẳng vào flex của .opt. */
.rpt-m[b-qujzyengic]  .opt .mud-button-label { display: contents; }
.rpt-m[b-qujzyengic]  .opt:active { background: var(--surface); }
.rpt-m[b-qujzyengic]  .opt.sel { color: var(--primary); font-weight: 600; }
.rpt-m[b-qujzyengic]  .opt .opt-check { margin-left: auto; color: var(--primary); opacity: 0; }
.rpt-m[b-qujzyengic]  .opt.sel .opt-check { opacity: 1; }
.rpt-m[b-qujzyengic]  .opt + .opt { border-top: .5px solid rgba(60,60,67,.1); border-radius: 0; }
.rpt-m[b-qujzyengic]  .opt .box { flex: none; width: 22px; height: 22px; border-radius: 6px; border: 2px solid var(--color-border); display: grid; place-items: center; color: #fff; }
.rpt-m[b-qujzyengic]  .opt.on .box { background: var(--primary); border-color: var(--primary); }
.rpt-m[b-qujzyengic]  .opt .box svg { opacity: 0; }
.rpt-m[b-qujzyengic]  .opt.on .box svg { opacity: 1; }
.rpt-m[b-qujzyengic]  .opt .stx { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rpt-m[b-qujzyengic]  .bsheet-apply { width: calc(100% - 8px); justify-content: center; margin: 12px 4px 4px; padding: 12px; border: none; border-radius: var(--r-md); color: var(--primary); background: var(--primary-soft); font-size: var(--font-size-md); font-weight: 700; font-family: inherit; }
.rpt-m[b-qujzyengic]  .bsheet-apply:active { background: #DEDCF8; }
/* .daterow/.datefield/.df-mud (card ngày + MudDatePicker ẩn) đã promote lên global trong app.mobile.css — pattern dùng chung cho mọi trang report có filter "Theo tùy chọn". */
/* /Pages/Report/FinancialDetail.razor.rz.scp.css */
/*
   FinancialDetail.razor.css — Chi tiet don (New/Received/Pending/Debt), giao dien mobile
   (desktop giu nguyen). Nguon doi chieu: Mobile.Prototype income-detail (Received) +
   debt-detail (Debt). Cac primitive dung chung (header, sheet, filter, search, card, hero,
   note, status, order-card, day-card, cust-card) da o app.mobile.css. File nay chi con phan
   RIENG cua trang: hero tong no (Debt), skeleton/empty.

   LUU Y: khong viet ten selector (dau cham, combinator, dau gach cheo, hai dau hai cham) trong
   comment cua scoped CSS — bo rewrite scope cua Blazor se chen nham attribute vao trong comment
   va lam hong parse, khien rule NGAY SAU comment bi trinh duyet bo qua.
*/

/* Shell .fd-m: flex column phu 100dvh, header co dinh — da gop chung o app.mobile.css. */

/* Block layout (KHONG flex/gap): Virtualize chen 2 spacer <div>, flex+gap do sai. */
.fd-m[b-d1cgbm6g26]  .list {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 0 14px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.fd-m[b-d1cgbm6g26]  .list::-webkit-scrollbar { display: none; }

/* Địa chỉ khách hàng (.ordr-addr, trong .ordr-leftcol trên ordr-due) — ĐÃ CHUYỂN sang global
   app.mobile.css vì RevenueReportDetail/ReceivableReport dùng chung y hệt. */

/* Hero tổng nợ (chỉ DetailType Debt) — dùng <HeroBalanceCard_Mobile> (component dùng chung với
   ReceivableReport/FinancialReport), chỉ còn margin riêng của trang này ở đây. */
.fd-m[b-d1cgbm6g26]  .fd-debt-total { margin-bottom: 14px; }

/* Ghi chu — chi margin rieng (base .incd-note o app.mobile.css) */
.fd-m[b-d1cgbm6g26]  .incd-note { margin: 6px 14px 0; }

/* Ghi chu o day card (incd-note-bottom) da chuyen sang global app mobile css — dung chung 3 report. */

/* View "Theo ngay" nhanh KHONG-Received (.fd-plain) — khong accordion, giong ReceivableReport.
   Override global .day-card: bo con tro + hieu ung nhan vi khong bam duoc. .cust-card KHONG
   override (giu nguyen card--interactive) — dung y het precedent cua ReceivableReport. */
.fd-m[b-d1cgbm6g26]  .day-card.fd-plain { cursor: default; }
.fd-m[b-d1cgbm6g26]  .day-card.fd-plain:active { transform: none; }

/* Accordion "Theo ngày/Theo khách hàng" (chevron + panel .pr breakdown) đã promote sang
   app.mobile.css (global) — giống hệt RevenueReportDetail.razor.css, gộp về 1 nguồn duy nhất. */

/* Skeleton loading + rong */
.fd-m[b-d1cgbm6g26]  .fd-skel { cursor: default; }
.fd-m[b-d1cgbm6g26]  .fd-skel:active { transform: none; }
.fd-m[b-d1cgbm6g26]  .fd-skel-money { display: flex; flex-direction: column; align-items: flex-end; }
.fd-m[b-d1cgbm6g26]  .fd-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 60px 24px; text-align: center; color: var(--text-3);
}
/* /Pages/Report/FinancialReport.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════════════
   FinancialReport.razor.css — Sổ quỹ cửa hàng, giao diện mobile (desktop giữ nguyên).
   Tham khảo Mobile.Prototype/cashbook.html + styles.css (khối "SCREEN: CASHBOOK").
   Primitive dùng chung (.header-zone/.topnav/.card/.card--grouped/.card--hero/
   .sheet-backdrop/.flt-sheet/.btn-primary...) đã có ở app.mobile.css, không lặp lại.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Shell .cashbook-m: flex column fill viewport, header cố định — đã gộp chung ở app.mobile.css ── */

/* .seg (MudToggleGroup Tất cả/Tiền mặt/Chuyển khoản) đã chuyển sang app.mobile.css (global) —
   dùng chung với RevenueReportDetail.razor, không lặp lại CSS ở đây. */

/* ── Vùng cuộn nội dung ── */
.cashbook-m .cb-scroll[b-eetv0jc9iz] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.cashbook-m .cb-scroll[b-eetv0jc9iz]::-webkit-scrollbar { display: none; }

/* .cb-duo/.cb-mini/.cb-mini-ic (2 mini card Thu/Chi) đã promote sang app.mobile.css (global) —
   dùng chung với IncomeExpense.razor, không lặp lại CSS ở đây. */

/* Font/màu đã gộp chung với .pts-listhead .t (app.mobile.css) — chỉ còn margin riêng của trang này. */
.cashbook-m .cb-note[b-eetv0jc9iz] { margin: 0 4px 10px; }

/* ── Bảng thu chi (statement) ── */
.cashbook-m .cb-row[b-eetv0jc9iz] {
  position: relative;
  display: flex; align-items: flex-start;
  padding: 14px; gap: 8px;
  --list-inset: 14px;
}
.cashbook-m .cb-row + .cb-row[b-eetv0jc9iz]::before {
  content: '';
  position: absolute; top: 0; left: var(--list-inset,14px); right: 14px;
  height: 1px; background: var(--color-hairline);
  transform: scaleY(.5); transform-origin: 0 0;
}
.cashbook-m .cb-row-main[b-eetv0jc9iz] { flex: 1; min-width: 0; }
.cashbook-m .cb-row-title[b-eetv0jc9iz] { font-size: var(--font-size-base); color: var(--text); line-height: 1.35; }
.cashbook-m .cb-row-sub[b-eetv0jc9iz] { font-size: var(--font-size-sm); color: var(--text-3); margin-top: 3px; line-height: 1.35; }
.cashbook-m .cb-row-val[b-eetv0jc9iz] { flex: none; font-size: var(--font-size-md); font-weight: 700; color: var(--text); margin-top: 1px; }
/* Đặt tên riêng .cb-in (không dùng ".green") vì MudBlazor.min.css có sẵn tiện ích global
   ".green{background-color:...}" -> trùng tên sẽ vô tình bị tô nền xanh ngoài ý muốn. */
.cashbook-m .cb-row-val.cb-in[b-eetv0jc9iz] { color: var(--green); }
.cashbook-m .cb-row.link[b-eetv0jc9iz] { cursor: pointer; }
.cashbook-m .cb-row.link:active[b-eetv0jc9iz] { background: rgba(28,27,46,.04); }
.cashbook-m[b-eetv0jc9iz]  .cb-row-chev { flex: none; color: var(--text-3); margin: 1px -2px 0 0; }

/* Hàng tổng hợp A / B / C */
.cashbook-m .cb-row.sum[b-eetv0jc9iz] { background: var(--color-surface-sunken); align-items: center; }
.cashbook-m .cb-row.sum[b-eetv0jc9iz]::before { display: none; }
.cashbook-m .cb-row.sum .cb-row-title[b-eetv0jc9iz] { font-size: var(--font-size-base); font-weight: 700; color: var(--text); }
/* Công thức phụ (vd "= (A) + (1) + (2) - (3)") tách xuống dòng riêng, chữ nhỏ hơn tiêu đề chính
   thay vì dồn chung 1 dòng gây tràn/xuống dòng giữa chừng khó đọc. */
.cashbook-m .cb-row.sum .cb-row-sub[b-eetv0jc9iz] { font-size: var(--font-size-xs); color: var(--text-3); margin-top: 2px; }
.cashbook-m .cb-row.sum .cb-row-val[b-eetv0jc9iz] {
  background: var(--surface); padding: 6px 13px; border-radius: 999px;
  font-size: var(--font-size-md); font-weight: 800;
}
.cashbook-m .cb-row.total .cb-row-val[b-eetv0jc9iz] { background: var(--primary-soft); color: var(--primary-dark); }

/* ── Skeleton loading (hiện khi IsLoading) — tái dùng đúng class layout thật (.card--hero/.cb-mini/
   .cb-row) nên kích thước khớp 100% với dữ liệu, không giật khung khi load xong ── */
.cashbook-m .cb-hero-skel-txt[b-eetv0jc9iz] { flex: 1; min-width: 0; }
/* .cb-mini thật là flex-direction:row (icon trái, khối chữ phải, xem app.mobile.css) — khối chữ
   thật là 1 <div> trơn có flex:1 (".cb-mini > div"). Skeleton dùng class riêng ".cb-mini-skel-txt"
   (không phải <div> trơn) nên cần khai lại flex:1 + cột (lbl/val skeleton vẫn xếp chồng dọc). */
.cashbook-m .cb-mini-skel-txt[b-eetv0jc9iz] { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.cashbook-m .cb-skel-row .cb-skel-val[b-eetv0jc9iz] { flex: none; margin: 1px 0 0 auto; }
/* Màu skeleton trắng-mờ trên nền gradient hero đã gộp chung thành .hero-balance .mud-skeleton
   (app.mobile.css) — .cb-hero-skel luôn đi kèm class hero-balance trên cùng 1 phần tử nên tự động
   khớp, không cần khai lại ở đây. */
/* /Pages/Report/OtherExpenses.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════════════
   OtherExpenses.razor.css — Chi tiết chi khác, giao diện mobile (desktop giữ nguyên).
   Nguồn đối chiếu: Mobile.Prototype/expense-detail.html + styles.css khối "SCREEN: EXPENSE-DETAIL".

   Quy ước ::deep: dùng thống nhất `.oexp-m ::deep …` cho MỌI rule trong file này.
   PRIMITIVE DÙNG CHUNG đã ở app.mobile.css (global, KHÔNG lặp lại): .header-zone/.topnav/
   .sheet-backdrop/.flt-sheet/.btn-primary/.search-collapse/.search/.card/.card--interactive,
   .card-pop, .pts-listhead, .incd-filters/.incd-filt (+.incd-skelv), .pd-row (base),
   .incd-note (base), .status (base + màu cash/bank). Card "phiếu chi khác" (.oth-item/.oth-top/
   .oth-meta/.oth-detail/.oth-amt.chi/.oth-skel/.oth-empty) đã promote sang app.mobile.css — dùng
   chung với OtherIncome.razor (2 trang trước đây định nghĩa CSS giống hệt nhau 100%, chỉ khác
   tên class và màu tiền). File này chỉ còn phần thật sự riêng của trang: shell + vùng cuộn.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Shell .oexp-m: flex column fill viewport, header cố định — đã gộp chung ở app.mobile.css ── */

/* Block layout (KHÔNG flex/gap): Virtualize chèn 2 spacer <div>, flex+gap đo sai. */
.oexp-m[b-6af4tmc277]  .list {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 0 14px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.oexp-m[b-6af4tmc277]  .list::-webkit-scrollbar { display: none; }

/* Ghi chú (Description) — chỉ margin riêng (base .incd-note ở app.mobile.css), đặt sau panel */
.oexp-m[b-6af4tmc277]  .incd-note { margin: 10px 14px 0; }
/* /Pages/Report/OtherIncome.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════════════
   OtherIncome.razor.css — Chi tiết thu khác, giao diện mobile (desktop giữ nguyên).
   Nguồn đối chiếu: Mobile.Prototype/other-income.html + styles.css khối "SCREEN: OTHER-INCOME".

   Quy ước ::deep: dùng thống nhất `.oinc-m ::deep …` cho MỌI rule trong file này.
   PRIMITIVE DÙNG CHUNG đã ở app.mobile.css (global, KHÔNG lặp lại): .header-zone/.topnav/
   .sheet-backdrop/.flt-sheet/.btn-primary/.search-collapse/.search/.card/.card--interactive,
   .card-pop, .pts-listhead, .incd-filters/.incd-filt (+.incd-skelv), .pd-row (base),
   .incd-note (base), .status (base + màu cash/bank). Card "phiếu thu khác" (.oth-item/.oth-top/
   .oth-meta/.oth-detail/.oth-amt.thu/.oth-skel/.oth-empty) đã promote sang app.mobile.css — dùng
   chung với OtherExpenses.razor (2 trang trước đây định nghĩa CSS giống hệt nhau 100%, chỉ khác
   tên class và màu tiền). File này chỉ còn phần thật sự riêng của trang: shell + vùng cuộn.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Shell .oinc-m: flex column fill viewport, header cố định — đã gộp chung ở app.mobile.css ── */

/* Block layout (KHÔNG flex/gap): Virtualize chèn 2 spacer <div>, flex+gap đo sai. */
.oinc-m[b-fuiesgwimc]  .list {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 0 14px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.oinc-m[b-fuiesgwimc]  .list::-webkit-scrollbar { display: none; }

/* Ghi chú (Description) — chỉ margin riêng (base .incd-note ở app.mobile.css), đặt sau panel */
.oinc-m[b-fuiesgwimc]  .incd-note { margin: 10px 14px 0; }
/* /Pages/Report/ReceivableReport.razor.rz.scp.css */
/*
   ReceivableReport.razor.css — Chi tiet chua thu, giao dien mobile (desktop giu nguyen).
   Nguon doi chieu: Mobile.Prototype unpaid-detail. Cac primitive dung chung (header, sheet,
   filter, search, card, hero, note, status, order-card) da o app.mobile.css. File nay chi con
   phan RIENG: hero tong chua thu, ghi chu day, override day-card khong bam duoc, skeleton, empty.

   LUU Y: khong viet ten selector (dau cham, combinator, dau gach cheo, hai dau hai cham) trong
   comment cua scoped CSS — bo rewrite scope cua Blazor se chen nham attribute vao trong comment
   va lam hong parse, khien rule NGAY SAU comment bi trinh duyet bo qua (vd shell mat flex).
*/

/* Shell .rcv-m: flex column phu 100dvh, header co dinh — da gop chung o app.mobile.css. */

/* Block layout (KHÔNG flex/gap): Virtualize chèn 2 spacer <div>, flex+gap đo sai. */
.rcv-m[b-xnf50p1sq7]  .list {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 0 14px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.rcv-m[b-xnf50p1sq7]  .list::-webkit-scrollbar { display: none; }

/* ── Hero tổng tiền chưa thu — dùng <HeroBalanceCard_Mobile> (component dùng chung với
   FinancialDetail/FinancialReport, đã hỗ trợ badge đếm + skeleton), chỉ còn margin riêng ở đây. ── */
.rcv-m[b-xnf50p1sq7]  .unpd-total { margin-bottom: 14px; }

/* Địa chỉ khách hàng (.ordr-addr, trong .ordr-leftcol trên ordr-due) — ĐÃ CHUYỂN sang global
   app.mobile.css vì FinancialDetail/RevenueReportDetail dùng chung y hệt. */

/* Ghi chú/Tặng lần giặt — chỉ margin riêng (base .incd-note ở app.mobile.css) */
.rcv-m[b-xnf50p1sq7]  .incd-note { margin: 6px 14px 0; }

/* Ghi chu o day card (incd-note-bottom) da chuyen sang global app mobile css — dung chung 3 report. */

/* ── View "Theo ngày" — mỗi ngày 1 card riêng, KHÔNG accordion (trang này không có breakdown
   tiền mặt/chuyển khoản). Override global .day-card: bỏ con trỏ + hiệu ứng nhấn vì không bấm được. ── */
.rcv-m[b-xnf50p1sq7]  .day-card { cursor: default; }
.rcv-m[b-xnf50p1sq7]  .day-card:active { transform: none; }

/* ── Skeleton loading (tái dùng nguyên class layout thật .ordr-item/.day-card/.cust-card) + rỗng ── */
.rcv-m[b-xnf50p1sq7]  .rcv-skel { cursor: default; }
.rcv-m[b-xnf50p1sq7]  .rcv-skel:active { transform: none; }
.rcv-m[b-xnf50p1sq7]  .rcv-skel-money { display: flex; flex-direction: column; align-items: flex-end; }
.rcv-m[b-xnf50p1sq7]  .rcv-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 60px 24px; text-align: center; color: var(--text-3);
}
/* /Pages/Report/RevenueReportDetail.razor.rz.scp.css */
/*
   RevenueReportDetail.razor.css — Chi tiet thu, giao dien mobile (desktop giu nguyen).
   Nguon doi chieu: Mobile.Prototype income-detail. Xem Plans RevenueReportDetail muc 10.
   Cac primitive dung chung (header, sheet, filter, seg, search, card, filters, note, status,
   order-card) da o app.mobile.css. File nay chi con phan RIENG cua trang: chon nhieu, cot trai,
   dong thanh toan, nut xuat HDDT, thanh chon, accordion day va cust, skeleton, empty.

   LUU Y: khong viet ten selector (dau cham, combinator, dau gach cheo, hai dau hai cham) trong
   comment cua scoped CSS — bo rewrite scope cua Blazor se chen nham attribute vao trong comment
   va lam hong parse, khien rule NGAY SAU comment bi trinh duyet bo qua (vd shell .rrd-m mat flex).
*/

/* Shell .rrd-m: flex column phu 100dvh, header co dinh — da gop chung o app.mobile.css. */

/* Block layout (KHÔNG flex/gap): Virtualize chèn 2 spacer <div>, flex+gap đo sai. */
.rrd-m[b-lhclj7hln7]  .list {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 2px 14px calc(var(--nav-clearance,110px) + env(safe-area-inset-bottom));
}
.rrd-m[b-lhclj7hln7]  .list::-webkit-scrollbar { display: none; }

/* ── Chọn tất cả + checkbox vuông (riêng RevenueReportDetail — chọn nhiều để xuất HĐĐT) ── */
/* margin-left: var(--pad-card) — .incd-chk trong mỗi card lùi vào 14px do .ordr-headtop có
   padding-left = --pad-card, còn .incd-selall (nằm trong .pts-listhead, KHÔNG có padding đó) lại nằm
   sát mép trái -> lệch 14px so với checkbox của item bên dưới. Cộng thêm để 2 cột checkbox thẳng hàng. */
/* Checkbox chọn-tất-cả + từng phiếu — MudCheckBox thật (không còn span/MudIcon Check tự vẽ), style
   mặc định của MudBlazor, theo đúng tiền lệ .pck-row (UserPermission.razor) / .chk-box
   (CustomerDebtDetail.razor). incd-selall header dùng ValueChanged trực tiếp (không cần ReadOnly +
   click cả hàng vì đây là tap-target riêng, không dùng để mở/đóng gì khác); còn checkbox từng dòng
   nằm trong .ordr-headtop vốn đã @onclick:stopPropagation để không kích hoạt MToggleExpand của card. */
.rrd-m[b-lhclj7hln7]  .incd-selall { display: flex; cursor: pointer; margin-left: var(--pad-card); }
.rrd-m[b-lhclj7hln7]  .incd-chk { flex: none; margin: 0; padding: 0; }
/* Nền tròn nhạt bao quanh checkbox — chỉ áp cho checkbox TỪNG PHIẾU (trong .ordr-headtop), không
   áp cho checkbox "Chọn tất cả". MudCheckBox mặc định vùng bấm .mud-icon-button đã sẵn
   border-radius:50% (dùng cho hiệu ứng ripple khi bấm) nhưng nền trong suốt lúc đứng yên; tô nền nhẹ
   thường trực cùng hình tròn đó để không "trôi" giữa 2 trạng thái đứng yên/đang bấm. */
.rrd-m[b-lhclj7hln7]  .ordr-headtop .incd-chk .mud-icon-button { background: var(--surface); }
.rrd-m[b-lhclj7hln7]  .incd-item.sel { box-shadow: 0 0 0 1.5px var(--primary), var(--shadow-card); }

/* ── Cột trái hàng đáy đơn (đã thanh toán trước + ngày thu) — ĐÃ CHUYỂN sang global
   (.ordr-leftcol/.ordr-paid trong app.mobile.css) vì Bills.razor dùng chung y hệt. ── */

/* Địa chỉ khách hàng (.ordr-addr, trong .ordr-leftcol trên ordr-paid/ordr-due) — ĐÃ CHUYỂN sang
   global app.mobile.css vì FinancialDetail/ReceivableReport dùng chung y hệt. */

/* Ghi chú — chỉ margin riêng (base .incd-note ở app.mobile.css). */
.rrd-m[b-lhclj7hln7]  .incd-note { margin: 6px 14px 0; }

/* Ghi chu o day card (incd-note-bottom) da chuyen sang global app mobile css — dung chung 3 report. */

/* Nút "Xuất hoá đơn điện tử" — full-width, kẻ phân cách trên, bo góc theo đáy card.
   .incd-einv giờ là MudButton (trước là <button> thô) -> display:contents cho .mud-button-label
   để icon/text tham gia thẳng vào flex justify-content:center của thẻ cha, và reset text-transform
   (MudButton mặc định uppercase) vì @item.IssueStatus là chữ hoa/thường tự nhiên, không phải hằng số. */
.rrd-m[b-lhclj7hln7]  .incd-einv {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; border: none; border-top: 1px solid var(--line);
  background: transparent; color: var(--primary);
  font-family: inherit; font-size: var(--font-size-base); font-weight: 600;
  padding: 12px; cursor: pointer; text-transform: none;
  border-radius: 0 0 var(--radius) var(--radius);
}
.rrd-m[b-lhclj7hln7]  .incd-einv .mud-button-label { display: contents; }
.rrd-m[b-lhclj7hln7]  .incd-einv:active { background: var(--primary-soft); }

/* ── Thanh hành động đáy: xuất HĐĐT hàng loạt ── */
/* .incd-selbar giờ là MudButton (trước là <button> thô) -> display:contents cho .mud-button-label
   để 3 span con (ic/txt/chev) tham gia thẳng vào flex-row của thẻ cha; reset text-transform vì
   .sub có chữ thường tự nhiên. */
.rrd-m[b-lhclj7hln7]  .incd-selbar {
  position: fixed; bottom: 0; left: 50%; transform: translate(-50%, 110%);
  width: 100%; max-width: 430px;
  background: var(--card); color: var(--text);
  border: none; border-top: 1px solid var(--line); cursor: pointer; font-family: inherit; text-align: left;
  padding: 16px 18px calc(12px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 13px; text-transform: none;
  box-shadow: 0 -8px 28px rgba(46,40,90,.14);
  z-index: 30; transition: transform .28s cubic-bezier(.32,.72,.25,1);
}
.rrd-m[b-lhclj7hln7]  .incd-selbar .mud-button-label { display: contents; }
.rrd-m[b-lhclj7hln7]  .incd-selbar.show { transform: translate(-50%, 0); }
.rrd-m[b-lhclj7hln7]  .incd-selbar:active { background: var(--surface); }
.rrd-m[b-lhclj7hln7]  .incd-selbar .ic { flex: none; width: 44px; height: 44px; border-radius: 50%; background: var(--primary-soft); color: var(--primary); display: grid; place-items: center; }
.rrd-m[b-lhclj7hln7]  .incd-selbar .txt { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.rrd-m[b-lhclj7hln7]  .incd-selbar .main { font-size: var(--font-size-base); font-weight: 800; color: var(--primary); }
.rrd-m[b-lhclj7hln7]  .incd-selbar .sub { font-size: var(--font-size-base); color: var(--text-2); font-weight: 600; }
.rrd-m[b-lhclj7hln7]  .incd-selbar .chev { flex: none; color: var(--text-3); }

/* ── Accordion "Theo ngày/Theo khách hàng" (chevron + panel .pr breakdown) đã promote sang
   app.mobile.css (global) — giống hệt FinancialDetail.razor.css, gộp về 1 nguồn duy nhất. ── */

/* ── Skeleton loading (tái dùng nguyên class layout thật .ordr-item/.day-card/.cust-card
   ở markup -> chỉ vô hiệu hoá cảm giác "bấm được" + căn phải khối 2 dòng ở .cust-money) + rỗng ── */
.rrd-m[b-lhclj7hln7]  .rrd-skel { cursor: default; }
.rrd-m[b-lhclj7hln7]  .rrd-skel:active { transform: none; }
.rrd-m[b-lhclj7hln7]  .rrd-skel-money { display: flex; flex-direction: column; align-items: flex-end; }
.rrd-m[b-lhclj7hln7]  .rrd-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 60px 24px; text-align: center; color: var(--text-3);
}
/* /Pages/SystemPages/ChangePassword.razor.rz.scp.css */
/* ChangePassword.razor.css — Đổi mật khẩu, giao diện mobile (desktop giữ nguyên). Không có
   prototype riêng — áp đúng khuôn shell "Detail form" chung đã dùng ở ServiceDetail.razor (app bar
   cố định trên, nội dung cuộn riêng, nút submit ghim đáy). Không viết tên class kèm dấu chấm trong
   comment ở file này — có thể làm hỏng bộ rewrite scope CSS của Blazor và khiến rule ngay sau bị
   bỏ qua (đã gặp bug thật ở các trang khác cùng dự án). */

/* .chpwd-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.chpwd-m .chpwd-scroll[b-efzyh320fa] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.chpwd-m .chpwd-scroll[b-efzyh320fa]::-webkit-scrollbar { display: none; }

/* Nút submit ghim đáy vùng cuộn — markup dùng chung class "form-submit-bar" (position:sticky/bottom/
   padding đã ở app.mobile.css, dùng chung với 8 trang Detail khác) + "chpwd-submit" chỉ còn override
   phần khác biệt thật của riêng trang này: margin-top hẹp hơn (form ngắn, 3 field) và nền gradient
   che nội dung cuộn phía sau nút (form-submit-bar chung hiện không có nền — cố ý không đổi global ở
   đây để không ảnh hưởng 8 trang Detail khác chưa được test lại). */
.chpwd-m .chpwd-submit[b-efzyh320fa] {
  margin-top: 20px;
  background: linear-gradient(180deg, transparent, var(--bg, #F4F3FB) 24%);
}
/* /Pages/SystemPages/Options.razor.rz.scp.css */
/* Style riêng cho trang Quản lý trên thiết bị di động.
   Các lớp dùng chung (.card, .card--grouped, .group-label, .settings-list, .settings-row,
   .settings-row__content, .settings-icon/.settings-label/.settings-chev/.settings-value,
   .ic-*, .app-ver) được định nghĩa toàn cục trong wwwroot/css/app.mobile.css nên không lặp lại ở đây.
   Các khối bên dưới đặt trên component MudBlazor trong file scoped, nên phải đi qua ".more-scroll ::deep". */

/* Khoảng đệm nội dung; phần đáy nhỏ vì .main-content đã chừa khoảng trống cho thanh điều hướng dưới */
.more-scroll[b-7lhkksrs86] {
    padding: 14px 16px 24px;
}

/* settings-group: khoảng cách giữa các nhóm (riêng trang này) */
.more-scroll[b-7lhkksrs86]  .settings-group {
    margin-bottom: 22px;
}

/* ── Thẻ thông tin cửa hàng ──
   Đặt flex-direction: row để ghi đè mặc định flex-direction: column của .card từ bootstrap.
   QA #7: nền tím hero dùng chung của hệ thống (--grad-hero) thay cho nền trắng mặc định của
   .card — chữ/icon bên trong đổi sang trắng để đủ tương phản trên nền tối. */
.more-scroll[b-7lhkksrs86]  .store-card {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 16px 14px;
    margin-bottom: 22px;
    background: var(--grad-hero) !important;
    box-shadow: 0 8px 20px rgba(74,59,212,.30);
}

/* MudAvatar override (logo cửa hàng) — nền trắng mờ để nổi trên gradient tím thay vì nền cam cũ */
.more-scroll[b-7lhkksrs86]  .store-logo {
    flex: none;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .18);
    color: #fff;
    font-size: var(--font-size-2xl);
    font-weight: 800;
    line-height: 1;
    font-family: var(--font-brand);
}

.more-scroll[b-7lhkksrs86]  .store-info {
    flex: 1;
    min-width: 0;
}

/* Tên tiệm: chỉ 1 dòng, dài hơn thì cắt bằng dấu "…" (không rớt dòng làm cao thẻ) */
.more-scroll[b-7lhkksrs86]  .store-name {
    font-size: var(--font-size-lg);
    font-weight: 800;
    color: #fff;
    line-height: var(--lh-snug);
    letter-spacing: -.01em;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    line-clamp: 1;
    overflow: hidden;
    word-break: break-word;
}

.more-scroll[b-7lhkksrs86]  .store-addr {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: var(--font-size-sm);
    color: rgba(255, 255, 255, .85);
    margin-top: 4px;
    line-height: 1.35;
    min-width: 0;
}

/* Địa chỉ: cũng chỉ 1 dòng + ellipsis */
.more-scroll[b-7lhkksrs86]  .store-addr span {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    line-clamp: 1;
    overflow: hidden;
    word-break: break-word;
}

.more-scroll[b-7lhkksrs86]  .store-addr .mud-icon-root {
    flex: none;
    color: rgba(255, 255, 255, .85);
    font-size: 14px;
}

.more-scroll[b-7lhkksrs86]  .store-card > .chev {
    flex: none;
    color: rgba(255, 255, 255, .85);
    font-size: 20px;
}

/* ── Hàng tài khoản người dùng ── */
.more-scroll[b-7lhkksrs86]  .uavatar {
    flex: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(180deg, #FFE4C4 0%, #FFD1A8 100%);
    border: 2px solid #fff;
    box-shadow: 0 1px 4px rgba(28, 27, 46, .12);
}

.more-scroll[b-7lhkksrs86]  .uavatar .mud-icon-root {
    font-size: 18px;
    color: #8A4D16;
}

.more-scroll[b-7lhkksrs86]  .user-label {
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-weight: 400;
}

.more-scroll[b-7lhkksrs86]  .uname {
    display: block;
    font-size: var(--font-size-md);
    font-weight: 700;
    color: var(--text);
    line-height: var(--lh-snug);
}

.more-scroll[b-7lhkksrs86]  .urole {
    display: block;
    font-size: var(--font-size-xs);
    color: var(--text-3);
    margin-top: 2px;
}

/* ── Hàng đăng xuất ── */
.more-scroll[b-7lhkksrs86]  .settings-row.logout {
    color: var(--red);
    font-weight: 600;
    font-size: var(--font-size-md);
    --list-inset: 0;
}

.more-scroll[b-7lhkksrs86]  .logout-icon {
    color: var(--red);
    font-size: 19px;
}

.more-scroll[b-7lhkksrs86]  .settings-row.logout::before {
    left: 0;
}
/* /Pages/SystemPages/SystemLogs.razor.rz.scp.css */
/* SystemLogs.razor.css — Nhật ký hệ thống, giao diện mobile (desktop giữ nguyên). Tham khảo
   Mobile.Prototype/logs.html. Trang chỉ xem, không có action sheet/FAB. Header/search-collapse/
   flt-sheet/daterow/df-mud dùng chung style global (app.mobile.css) — chỉ khai báo phần riêng trang. */

/* .log-m: shell flex-column 100dvh đã gộp global (app.mobile.css). */
.log-m .log-scroll[b-2n9hy6d0hs] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.log-m .log-scroll[b-2n9hy6d0hs]::-webkit-scrollbar { display: none; }

/* Badge hành động — nền trong suốt, viền theo màu (khớp Mobile.Prototype .log-act) */
.log-m .log-act[b-2n9hy6d0hs] {
  flex: none;
  margin-left: auto;
  font-size: var(--font-size-2xs);
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  background: transparent;
  border: 1px solid currentColor;
}
.log-m .log-act.green[b-2n9hy6d0hs]  { color: var(--green); }
.log-m .log-act.orange[b-2n9hy6d0hs] { color: var(--orange); }
.log-m .log-act.red[b-2n9hy6d0hs]    { color: var(--red); }
.log-m .log-act.violet[b-2n9hy6d0hs] { color: var(--primary-dark); }

.log-m .log-detail[b-2n9hy6d0hs] {
  font-size: var(--font-size-sm);
  color: var(--text-2);
  line-height: 1.5;
  padding: 10px 2px 0;
}
.log-m .log-detail b[b-2n9hy6d0hs] { color: var(--text); font-weight: 700; }

/* .log-skel đặt trên <MudPaper> (component) -> cần ::deep. .log-empty là <div> thuần nên không cần. */
.log-m[b-2n9hy6d0hs]  .log-skel { cursor: default; }
.log-m .log-empty[b-2n9hy6d0hs] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 60px 24px;
  text-align: center;
  color: var(--text-3);
}
/* /Pages/SystemPages/UserPermission.razor.rz.scp.css */
/* Phân quyền — giao diện mobile (desktop giữ nguyên). Tham khảo prototype permissions trong
   Mobile Prototype. Cây quyền tab Chức năng tái dùng nguyên MudTreeView của desktop (tri-state +
   AutoSelectParent), chỉ restyle qua deep để trông giống checkbox-row của prototype — không viết
   lại logic indeterminate bằng JS/HTML thuần. Danh sách cửa hàng dùng HTML thuần theo tiền lệ đã
  có ở trang FinancialChart cho kiểu chọn cửa hàng trên mobile. */
.mud-chip>.mud-chip-content[b-23aebmchoq] {
    padding-right: 6px !important;
}
/* .perm-m: shell flex-column 100dvh đã gộp global (app.mobile.css), chỉ còn phần riêng dưới đây. */
.perm-m[b-23aebmchoq]  .seg.mud-toggle-group { margin-bottom: 12px; }

.perm-m .perm-scroll[b-23aebmchoq] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 12px 12px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.perm-m .perm-scroll[b-23aebmchoq]::-webkit-scrollbar { display: none; }

/* ── Thẻ "Nhân viên đang phân quyền" ──
   flex-direction: row BẮT BUỘC ghi rõ: thẻ mang class card của Bootstrap (global) vốn set
   flex-direction: column; rule scoped này không set thì con xếp dọc, sai layout hàng ngang. */
.perm-m .perm-emp[b-23aebmchoq] {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  padding: 0;
  overflow: hidden;
  margin-bottom: 14px;
}
/* .perm-emp-pick giờ là MudButton (trước là <button> thô) -> ::deep bắt buộc cho mọi selector con
   (DOM gốc MudButton không mang scope-attribute), display:contents cho .mud-button-label để 3 phần
   tử con (avatar/main/chev) tham gia thẳng vào flex-row, reset text-transform vì .nm/.ac chữ thường. */
.perm-m[b-23aebmchoq]  .perm-emp-pick {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding: 13px 14px;
  border: none;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  text-transform: none;
}
.perm-m[b-23aebmchoq]  .perm-emp-pick .mud-button-label { display: contents; }
.perm-m[b-23aebmchoq]  .perm-emp-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.perm-m[b-23aebmchoq]  .perm-emp-main .lbl { font-size: var(--font-size-2xs); font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .03em; }
.perm-m[b-23aebmchoq]  .perm-emp-main .nm { font-size: var(--font-size-lg); font-weight: 800; color: var(--text); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perm-m[b-23aebmchoq]  .perm-emp-main .ac { font-size: var(--font-size-sm); color: var(--text-2); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perm-m[b-23aebmchoq]  .perm-emp-pick .chev { flex: none; color: var(--primary); }
.perm-m[b-23aebmchoq]  .perm-emp-edit { flex: none; align-self: center; margin-right: 4px; color: var(--text-2); }

/* ── Panel tab (Cửa hàng/Chức năng) — cả 2 luôn mount, ẩn/hiện bằng CSS ── */
.perm-m .perm-panel[b-23aebmchoq] { display: none; }
.perm-m .perm-panel.active[b-23aebmchoq] { display: block; }

.perm-m .perm-funchead[b-23aebmchoq] { display: flex; align-items: center; justify-content: space-between; margin: 0 2px 10px; }
.perm-m .perm-funchead .t[b-23aebmchoq] { font-size: var(--font-size-sm); font-weight: 600; color: var(--text-2); }
/* .perm-selall giờ là MudButton (trước là <button> thô) -> ::deep + display:contents cho
   .mud-button-label, giống pattern .perm-emp-pick ở trên. */
.perm-m[b-23aebmchoq]  .perm-selall { display: inline-flex; align-items: center; gap: 4px; font-size: var(--font-size-sm); font-weight: 600; color: var(--primary); background: none; border: none; cursor: pointer; font-family: inherit; padding: 0; text-transform: none; }
.perm-m[b-23aebmchoq]  .perm-selall .mud-button-label { display: contents; }
.perm-m[b-23aebmchoq]  .perm-selall .mud-icon-root { font-size: 16px; }

.perm-m .perm-card[b-23aebmchoq] { margin-bottom: 12px; }

/* ── Danh sách cửa hàng — hàng HTML thuần (.pck-row, tap bất kỳ đâu để toggle), ô checkbox thị giác
   bên trong là MudCheckBox THẬT (ReadOnly, Class="pck") thay vì span/svg tự vẽ trước đây — hiển thị
   đúng theo giao diện MẶC ĐỊNH của MudBlazor (không còn CSS tuỳ biến kích thước/màu). Chỉ còn giữ layout
   hàng (flex/gap) + xoá padding-margin mặc định để không lệch khoảng cách với pck-main. ── */
.perm-m .pck-row[b-23aebmchoq] {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 14px;
  cursor: pointer;
}
.perm-m .perm-card .pck-row + .pck-row[b-23aebmchoq] { border-top: 1px solid var(--line); }
/* Class="pck" gắn lên .mud-input-control-boolean-input (DIV bọc NGOÀI của MudCheckBox — đo bằng
   outerHTML thật, KHÔNG phải lên .mud-checkbox/label bên trong như tưởng ban đầu). Selector dưới đây
   viết lại cho khớp đúng cấu trúc DOM thật đó — không dùng ".pck.mud-checkbox" (0 phần tử nào có cả 2
   class này cùng lúc nên rule cũ hoàn toàn không match). */
.perm-m[b-23aebmchoq]  .pck-row .pck { flex: none; margin: 0; padding: 0; }
/* pointer-events:none — MudCheckBox tự chặn bubbling click lên .pck-row (đo được: click thẳng vào ô
   checkbox không kích hoạt @onclick của hàng, dù đã ReadOnly). Đặt none để trình duyệt bỏ qua hẳn
   phần tử này khi hit-test chuột, click luôn rơi xuống .pck-row phía sau -> tap bất kỳ đâu trên hàng
   (kể cả đúng ô checkbox) đều toggle như hành vi cũ (span/svg tay không có handler riêng). !important
   vì MudBlazor tự set pointer-events:auto ngay trên .mud-icon-button, ghi đè giá trị inherited. */
.perm-m[b-23aebmchoq]  .pck-row .pck .mud-checkbox,
.perm-m[b-23aebmchoq]  .pck-row .pck .mud-checkbox * { pointer-events: none !important; }
.perm-m .pck-main[b-23aebmchoq] { flex: 1; min-width: 0; }
.perm-m .pck-name[b-23aebmchoq] { font-size: var(--font-size-md); font-weight: 700; color: var(--text); }
.perm-m .pck-sub[b-23aebmchoq] { display: flex; align-items: center; gap: 5px; font-size: var(--font-size-sm); color: var(--text-2); margin-top: 4px; }
.perm-m[b-23aebmchoq]  .pck-sub .mud-icon-root { flex: none; font-size: 15px; color: var(--text-3); }

/* ── Cây quyền (tab Chức năng) — restyle MudTreeView thành checkbox-row ── */
.perm-m[b-23aebmchoq]  .perm-tree .mud-treeview,
.perm-m[b-23aebmchoq]  .perm-tree .mud-treeview-group { padding: 0; margin: 0; }
.perm-m[b-23aebmchoq]  .perm-tree > .mud-treeview > .mud-treeview-item + .mud-treeview-item { border-top: 1px solid var(--line); }
.perm-m[b-23aebmchoq]  .perm-tree .mud-treeview-item-content {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 14px;
  min-height: 0;
}
.perm-m[b-23aebmchoq]  .perm-tree .mud-treeview-item-checkbox { order: 1; margin: 0; }
.perm-m[b-23aebmchoq]  .perm-tree .mud-treeview-item-label {
  order: 2;
  flex: 1;
  font-size: var(--font-size-md) !important;
  font-weight: 700 !important;
  white-space: normal !important;
  color: var(--text);
}
.perm-m[b-23aebmchoq]  .perm-tree .mud-treeview-item-arrow { order: 3; margin: 0; }
/* Node không có mục con (subItems.Count == 0 -> Class="perm-leaf" gắn ở @foreach trong .razor)
   thì ẩn hẳn nút mở rộng — MudBlazor luôn render nút này bất kể có children hay không (không tự
   disable), nên phải tự đánh dấu bằng class thay vì dựa vào :disabled. */
.perm-m[b-23aebmchoq]  .perm-tree .perm-leaf > .mud-treeview-item-content .mud-treeview-item-arrow { visibility: hidden; }

/* Children (Xem/Thêm/Sửa/Xoá): nền surface + thụt lề, giống .pf-children của prototype.
   transition-duration nhỏ để bung/thu items con nhanh, không còn cảm giác trễ. */
.perm-m[b-23aebmchoq]  .perm-tree .mud-collapse-container { background: var(--surface); transition-duration: .16s !important; }
.perm-m[b-23aebmchoq]  .perm-tree .mud-collapse-container .mud-treeview { padding-left: 34px; }
.perm-m[b-23aebmchoq]  .perm-tree .mud-collapse-container .mud-treeview-item + .mud-treeview-item { border-top: 1px solid var(--border); }
.perm-m[b-23aebmchoq]  .perm-tree .mud-collapse-container .mud-treeview-item-content { padding: 11px 14px 11px 0; }
.perm-m[b-23aebmchoq]  .perm-tree .mud-collapse-container .mud-treeview-item-label {
  font-size: var(--font-size-base) !important;
  font-weight: 400 !important;
}
.perm-m[b-23aebmchoq]  .perm-tree .mud-collapse-container .mud-treeview-item-arrow { display: none; }

/* ── Read-only khi xem quyền của CHÍNH mình ──
   Cây vẫn enabled (bung xem thoải mái) nhưng chặn SỬA: pointer-events:none lên vùng nội dung để
   không tick được checkbox/label, riêng nút mũi tên bật lại pointer-events để vẫn bung được. Làm mờ
   checkbox+label để báo hiệu chỉ-xem. Backstop: "Chọn tất cả"/"Lưu thay đổi" đã ẩn ở markup. */
.perm-m[b-23aebmchoq]  .perm-tree-readonly .mud-treeview-item-content { pointer-events: none; }
.perm-m[b-23aebmchoq]  .perm-tree-readonly .mud-treeview-item-arrow { pointer-events: auto; }
.perm-m[b-23aebmchoq]  .perm-tree-readonly .mud-treeview-item-checkbox,
.perm-m[b-23aebmchoq]  .perm-tree-readonly .mud-treeview-item-label { opacity: .55; }

.perm-m .perm-selfnote[b-23aebmchoq] {
  display: flex; align-items: center; gap: 8px;
  margin-top: 4px; padding: 13px 15px;
  background: var(--surface); border-radius: var(--r-md);
  font-size: var(--font-size-sm); font-style: italic; color: var(--text-2); line-height: 1.4;
}
.perm-m[b-23aebmchoq]  .perm-selfnote .mud-icon-root { flex: none; font-size: 18px; color: var(--text-3); }

/* ── Nút Lưu thay đổi ──
   QA #6: đồng bộ style nút hành động chính về chuẩn dùng chung .btn-mobile-pill (bo tròn hoàn
   toàn, primary phẳng — style hiện tại của ShopDetail.razor). Trước đây bo góc 14px + uppercase +
   letter-spacing riêng, lệch với chuẩn chung — bỏ hết các override hình dáng, chỉ giữ margin-top
   (khoảng cách với phần tử phía trên, không phải style hình dáng nút). */
.perm-m[b-23aebmchoq]  .perm-save.mud-button-root {
  margin-top: 4px;
}

/* ── Sheet chọn nhân viên (danh sách 50+ người -> tận dụng .sheet/.settings-row toàn cục) ──
   .sheet toàn cục KHÔNG có max-height/overflow (chỉ .flt-sheet có) vì action sheet thường chỉ vài
   dòng; danh sách nhân viên có thể 50+ nên phải tự giới hạn chiều cao + cho cuộn, nếu không sheet
   tràn quá đỉnh màn hình và không cuộn được. */
.perm-m .emp-sheet[b-23aebmchoq] { max-height: 82dvh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.perm-m .emp-sheet-title[b-23aebmchoq] { font-size: var(--font-size-md); font-weight: 700; text-align: center; padding: 4px 0 10px; }
.perm-m[b-23aebmchoq]  .emp-opt.sel .emp-opt-name { color: var(--primary); }
.perm-m .emp-opt-txt[b-23aebmchoq] { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.perm-m .emp-opt-name[b-23aebmchoq] { font-size: var(--font-size-md); font-weight: 600; color: var(--text); line-height: var(--lh-snug); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perm-m .emp-opt-acc[b-23aebmchoq] { font-size: var(--font-size-sm); color: var(--text-3); line-height: var(--lh-snug); }
.perm-m[b-23aebmchoq]  .opt-check { flex: none; color: var(--primary); margin-left: auto; }
/* /Shared/Components/BottomNavigation.Mobile.razor.rz.scp.css */
/* Thanh điều hướng dưới cùng và action sheet "Báo cáo".
   Trạng thái mở của action sheet điều khiển bằng class .open. */

.bottomnav[b-np1whk94xn] {
    position: fixed;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 100%;
    background: var(--glass-bg-strong);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-top: 1px solid var(--glass-border);
    box-shadow: 0 -6px 24px rgba(46,40,90,.12);
    display: flex;
    padding: 7px 10px calc(7px + env(safe-area-inset-bottom));
    z-index: 26;
    transition: transform .25s cubic-bezier(.32,.72,.25,1);
}

/* An han thanh nav khi co bat ky bottom sheet trang nao dang mo (loai tru action sheet cua chinh
   thanh nav vi no khong bi che). Ly do: tren iOS that, thanh nav la sibling nam ngoai vung cuon
   chinh, con moi sheet nam trong vung cuon do; WebKit ve vung cuon thanh mot layer duoi sibling co
   z-index duong, nen sheet lan backdrop deu bi nav ve de bat ke z-index noi bo. An nav khi co sheet
   mo lam bay stacking nay vo hieu (nav bi doi khoi man hinh), dong thoi dung chuan iOS (tab bar tu an
   duoi sheet dang trinh bay). Ham has duoc iOS 15 tro len ho tro, da dung o cac shell mobile khac.
   Giu translateX(-50 phan tram) de thanh van can giua khi truot xuong. */
:root:has(.sheet.open, .flt-sheet.open, .bsheet.open) .bottomnav[b-np1whk94xn] {
    transform: translate(-50%, 100%);
}

@media (prefers-reduced-transparency: reduce) {
    .bottomnav[b-np1whk94xn] {
        background: #fff;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
}

/* Các mục điều hướng là NavLink (mục "Báo cáo" giờ là MudButton) — đều là component con, phần tử
   render ra không mang scope-attribute của CSS isolation, nên rule đi qua tổ tiên có scope là
   .bottomnav bằng combinator ::deep, tránh bị màu/icon từ app.css hoặc MudBlazor ghi đè. !important
   trên các thuộc tính MudButton tự có default (padding/background/text-transform/min-width) để chắc
   chắn thắng CSS gốc của MudBlazor bất kể thứ tự nạp file. */
.bottomnav[b-np1whk94xn]  .nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    border: none;
    background: none !important;
    font-family: inherit;
    font-size: var(--font-size-2xs) !important;
    font-weight: 600 !important;
    line-height: var(--lh-tight);
    text-transform: none !important;
    color: var(--text-3);
    padding: 6px 0 5px !important;
    min-width: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    cursor: pointer;
    text-decoration: none;
}

/* MudButton bọc nội dung trong .mud-button-label — display:contents để icon/text bên trong tham gia
   trực tiếp vào flex-column của .nav-item (không tạo thêm 1 tầng box chỉ chứa 1 item). */
.bottomnav[b-np1whk94xn]  .nav-item .mud-button-label {
    display: contents;
}

.bottomnav[b-np1whk94xn]  .nav-item svg {
    width: 23px;
    height: 23px;
    font-size: 23px;
    transition: transform .2s cubic-bezier(.32,.72,.25,1);
}

.bottomnav[b-np1whk94xn]  .nav-item.active {
    color: var(--primary);
}

.bottomnav[b-np1whk94xn]  .nav-item.active svg {
    transform: translateY(-1px) scale(1.06);
}

/* ── Action sheet "Báo cáo" ── */
/* Backdrop dùng thẳng class .sheet-backdrop toàn cục (app.mobile.css) — trước đây .rp-backdrop tự
   định nghĩa lại y hệt CSS đó, đổi tên class trên markup thay vì lặp lại ở đây. */

.rp-sheet[b-np1whk94xn] {
    position: fixed;
    bottom: 0;
    left: 50%;
    transform: translate(-50%, 105%);
    width: 100%;
    background: var(--card);
    /* QA #1: bo góc theo --radius-lg (18px, đúng tỷ lệ card chuẩn) thay vì --r-xl (22px). */
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    padding: 8px 12px calc(14px + env(safe-area-inset-bottom));
    transition: transform .26s cubic-bezier(.32,.72,.25,1);
    z-index: var(--z-sheet);
    box-shadow: var(--shadow-pop);
}

.rp-sheet.open[b-np1whk94xn] {
    transform: translate(-50%, 0);
}

/* .sheet-grip: đã có sẵn style toàn cục giống hệt (app.mobile.css), markup dùng thẳng không cần
   định nghĩa lại ở đây. */

.sheet-title[b-np1whk94xn] {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-3);
    text-align: center;
    padding: 2px 0 8px;
}

/* .rp-list/.sheet-item giờ là MudList/MudListItem (component con) — cần ::deep + reset padding/
   min-height mặc định của MudList/MudListItem (giống pattern .settings-list đã dùng khắp app) để
   .sheet-item tự kiểm soát toàn bộ layout/kích thước như hồi còn là <button> thô. */
.rp-sheet[b-np1whk94xn]  .rp-list,
.rp-sheet[b-np1whk94xn]  .rp-list .mud-list { padding: 0; background: transparent; }
.rp-sheet[b-np1whk94xn]  .rp-list .mud-list-item,
.rp-sheet[b-np1whk94xn]  .rp-list .mud-list-item-gutters { min-height: 0; padding: 0; border-bottom: none !important; }
.rp-sheet[b-np1whk94xn]  .rp-list .mud-list-item-text { margin: 0; }
.rp-sheet[b-np1whk94xn]  .rp-list .mud-list-item-text p { margin: 0; }

/* MudListItem bọc ChildContent trong <div class="mud-list-item-text"><p>...</p></div> (không phải
   flex, giống hệt gotcha đã gặp với .settings-row) -> layout thật phải đặt trên div con tự viết
   .sheet-item-content, KHÔNG đặt trực tiếp trên .sheet-item (root MudListItem). .sheet-item chỉ còn
   giữ cursor/active-state/border-radius cho toàn hàng. */
.rp-sheet[b-np1whk94xn]  .sheet-item {
    width: 100%;
    border: none;
    background: none;
    border-radius: 8px;
    cursor: pointer;
}

.rp-sheet[b-np1whk94xn]  .sheet-item:active {
    background: var(--surface);
}

.rp-sheet[b-np1whk94xn]  .sheet-item-content {
    display: flex;
    align-items: center;
    gap: 13px;
    width: 100%;
    font-family: inherit;
    padding: 13px 8px;
    font-size: var(--font-size-base);
    font-weight: 500;
    color: var(--text);
    text-align: left;
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-ic {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: var(--r-sm);
    display: grid;
    place-items: center;
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-ic.ic-green {
    background: var(--green-soft);
    color: var(--green);
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-ic.ic-violet {
    background: var(--primary-soft);
    color: var(--primary);
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-ic svg {
    width: 19px;
    height: 19px;
    font-size: 19px;
    color: inherit;
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-meta {
    flex: 1;
    min-width: 0;
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-meta .st {
    display: block;
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--text);
}

.rp-sheet[b-np1whk94xn]  .sheet-item .sheet-meta .sd {
    display: block;
    font-size: var(--font-size-xs);
    color: var(--text-3);
    margin-top: 2px;
}

.rp-sheet[b-np1whk94xn]  .sheet-item .chev {
    flex: none;
    color: var(--text-3);
    margin-left: auto;
}
/* /Shared/Components/ImportExcelForm.razor.rz.scp.css */
/* ImportExcelForm.razor.css — dùng chung cho ImpCustomer.razor/ImpService.razor.

   LƯU Ý QUAN TRỌNG: .impc-scroll/.imps-scroll trước đây có CSS scoped riêng trong
   ImpCustomer.razor.css/ImpService.razor.css, nhưng phần tử này giờ do COMPONENT CON
   (ImportExcelForm) render chứ không phải chính ImpCustomer.razor/ImpService.razor — Blazor CSS
   isolation chỉ gắn scope-attribute cho phần tử viết trực tiếp trong file .razor đang biên dịch, nên
   rule scoped ở 2 file kia không còn khớp (đã gặp bug thật: card dính sát topnav, mất padding trái/
   phải). Phải đặt CSS ở đây — đúng file nơi 2 div này thực sự được render — không cần ::deep vì
   .impc-m/.imps-m/.impc-scroll/.imps-scroll đều là phần tử gốc của chính component này. */
.impc-m .impc-scroll[b-4a10fju21o],
.imps-m .imps-scroll[b-4a10fju21o] {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 16px 16px calc(var(--nav-clearance, 110px) + env(safe-area-inset-bottom));
}
.impc-m .impc-scroll[b-4a10fju21o]::-webkit-scrollbar,
.imps-m .imps-scroll[b-4a10fju21o]::-webkit-scrollbar { display: none; }
/* /Shared/Components/MobileAppBar.Mobile.razor.rz.scp.css */
/* Thanh tiêu đề (app bar) cho các trang mobile.
   .topnav/.topnav-title.t/.topnav-actions/.nav-icon-btn đã có style toàn cục giống hệt
   (app.mobile.css) — trước đây file này tự định nghĩa lại, đã bỏ để dựa thẳng vào global. Markup
   title cũng đổi sang <MudText Class="topnav-title t"> (1 phần tử, 2 class gộp) để khớp đúng selector
   `.topnav-title.t` của global thay vì cấu trúc div lồng nhau cũ.

   .header-zone thì KHÔNG bỏ theo global — 2 consumer của component này (Options.razor/Overview.razor)
   không giống các trang report/list khác: Options dùng đúng pattern "đơn giản" (không có shell
   .xxx-m riêng, .main-content tự cuộn cả trang, xem comment trong Overview.razor.css) nên header BẮT
   BUỘC phải position:sticky mới đứng yên khi cuộn — global (flex:0 0 auto) chỉ đúng cho trang có
   shell .xxx-m riêng tự quản overflow. Overview.razor tuy có shell .ov-m riêng nhưng overflow:hidden
   của nó khiến sticky vô hại nên không ảnh hưởng. Đã thử đổi sang global và xác nhận bằng browser thật:
   header của Options trôi mất khi cuộn — revert giữ nguyên sticky ở đây. */
.header-zone[b-b5m7x992n6] {
    position: sticky;
    top: 0;
    z-index: 30;
    background: transparent;
    padding-bottom: 8px;
}
/* /Shared/MainLayout.razor.rz.scp.css */
.page[b-iyvggadnll] {
    position: relative;
    display: flex;
    flex-direction: column;
}

main[b-iyvggadnll] {
    flex: 1;
}

.sidebar[b-iyvggadnll] {
    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row[b-iyvggadnll] {
    background-color: #f7f7f7;
    border-bottom: 1px solid #d6d5d5;
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

    .top-row[b-iyvggadnll]  a, .top-row[b-iyvggadnll]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
    }

        .top-row[b-iyvggadnll]  a:hover, .top-row[b-iyvggadnll]  .btn-link:hover {
            text-decoration: underline;
        }

        .top-row[b-iyvggadnll]  a:first-child {
            overflow: hidden;
            text-overflow: ellipsis;
        }

@media (max-width: 640.98px) {
    .top-row:not(.auth)[b-iyvggadnll] {
        display: none;
    }

    .top-row.auth[b-iyvggadnll] {
        justify-content: space-between;
    }

    .top-row[b-iyvggadnll]  a, .top-row[b-iyvggadnll]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 641px) {
    .page[b-iyvggadnll] {
        flex-direction: row;
    }

    .sidebar[b-iyvggadnll] {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }

    .top-row[b-iyvggadnll] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

        .top-row.auth[b-iyvggadnll]  a:first-child {
            flex: 1;
            text-align: right;
            width: 0;
        }

    .top-row[b-iyvggadnll], article[b-iyvggadnll] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}
