/* ═══════════════════════════════════════════════════════════════════════════
   NSCA ERP — LỚP GIAO DIỆN CHUẨN  (erp-ui.css)
   Rút từ shadcn/ui (ui-main) và ánh xạ sang bộ token có sẵn của theme.css.

   VÌ SAO CÓ FILE NÀY
   Mỗi module trước đây tự chế cỡ nút, chiều cao hàng bảng, màu chữ phụ.
   Cùng một trạng thái mà ba màn ba kiểu thì người dùng phải học lại ở từng chỗ,
   và phần mềm trông như ghép từ nhiều bản nháp. File này là bộ DUY NHẤT.

   CÁCH DÙNG
   Nạp SAU theme.css và design-system.css. Mọi class có tiền tố `eu-`
   nên không đụng class cũ của module nào.

   NGUYÊN TẮC GỐC (shadcn): chuyên nghiệp đến từ ĐỘ TƯƠNG PHẢN và NHỊP
   KHOẢNG CÁCH, không đến từ màu. Bộ mặc định của họ là thang xám thuần.

   Phiên bản: 2026-08-12.1
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── Thang bo góc: nhân từ một gốc, không gõ số rời ── */
  --eu-radius: 10px;
  --eu-radius-sm: 6px;    /* = gốc × 0,6 — badge vuông, ô nhỏ */
  --eu-radius-md: 8px;    /* = gốc × 0,8 — NÚT, TAB, ô nhập */
  --eu-radius-lg: 10px;   /* = gốc       — khối rỗng, hộp thoại nhỏ */
  --eu-radius-xl: 14px;   /* = gốc × 1,4 — THẺ (card) */

  /* ── Ba nấc chiều cao control. Chỉ ba, không thêm ── */
  --eu-h-sm: 32px;
  --eu-h-md: 36px;
  --eu-h-lg: 40px;

  /* ── Nhịp khoảng cách 4px: chỉ dùng 6 giá trị này ── */
  --eu-1: 4px; --eu-2: 8px; --eu-3: 12px; --eu-4: 16px; --eu-6: 24px; --eu-7: 28px;

  /* ── Ba cỡ chữ trong UI dày đặc ── */
  --eu-fs-xs: 12px;   /* badge · nhãn nhóm · chữ phụ nhỏ */
  --eu-fs-sm: 14px;   /* MẶC ĐỊNH: bảng, nút, form, mô tả */
  --eu-fs-base: 16px; /* tiêu đề trang */

  /* ── Ánh xạ tên ngữ nghĩa sang token NSCA có sẵn ── */
  --eu-bg:        var(--surface);
  --eu-fg:        var(--text);
  --eu-card:      var(--surface);
  --eu-muted:     var(--surface-2);
  --eu-muted-fg:  var(--text-3);      /* MỌI chữ phụ dùng đúng biến này */
  --eu-border:    var(--border);
  --eu-input:     var(--border-2);
  --eu-ring:      var(--b400);
  --eu-primary:   var(--b400);
  --eu-primary-fg:#fff;
  --eu-destructive: var(--err);

  --eu-shadow-xs: 0 1px 2px 0 rgba(0,0,0,.05);
  --eu-shadow-sm: 0 1px 3px 0 rgba(0,0,0,.10), 0 1px 2px -1px rgba(0,0,0,.10);
}
:root[data-theme="dark"]{
  --eu-shadow-xs: 0 1px 2px 0 rgba(0,0,0,.45);
  --eu-shadow-sm: 0 1px 3px 0 rgba(0,0,0,.55), 0 1px 2px -1px rgba(0,0,0,.45);
  /* Chữ trên nút chính ở chế độ TỐI phải là mực đậm, không phải trắng.
     Đo bằng render thật 26/08: trắng trên --b400 bản Tối (#5B87F5) chỉ được
     3.37:1 — dưới ngưỡng 4.5 của WCAG AA, chữ nhoè trên nền xanh sáng. Đổi
     sang #0B0F17 thì lên 5.69:1.
     Đây là cách các hệ thiết kế lớn làm ở chế độ tối: nền nhấn sáng lên thì
     chữ phải tối đi, chứ không giữ nguyên trắng như bản Sáng. */
  --eu-primary-fg:#0B0F17;
}

/* ═══ VÒNG FOCUS — áp cho MỌI control, 3px, không bỏ sót cái nào ═══ */
.eu-btn:focus-visible, .eu-inp:focus-visible, .eu-sel:focus-visible,
.eu-tab:focus-visible, .eu-chk:focus-visible, .eu-inp:focus, .eu-sel:focus{
  outline: none;
  border-color: var(--eu-ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--eu-ring) 45%, transparent);
}

/* ═══════════════════ NÚT ═══════════════════ */
.eu-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--eu-2);
  height:var(--eu-h-md); padding:0 var(--eu-4);
  border:1px solid transparent; border-radius:var(--eu-radius-md);
  font-family:inherit; font-size:var(--eu-fs-sm); font-weight:500; line-height:1;
  white-space:nowrap; cursor:pointer; user-select:none;
  background:var(--eu-primary); color:var(--eu-primary-fg);
  transition:background .12s, border-color .12s, color .12s;
}
.eu-btn:hover{ background:color-mix(in srgb, var(--eu-primary) 90%, #000) }
.eu-btn:disabled{ opacity:.5; cursor:not-allowed }
.eu-btn svg,.eu-btn .ic{ width:16px; height:16px; flex:none }

.eu-btn.sm{ height:var(--eu-h-sm); padding:0 var(--eu-3); gap:6px; font-size:13px }
.eu-btn.lg{ height:var(--eu-h-lg); padding:0 var(--eu-6) }
.eu-btn.xs{ height:24px; padding:0 var(--eu-2); font-size:var(--eu-fs-xs); gap:4px }
.eu-btn.icon{ width:var(--eu-h-md); padding:0 }
.eu-btn.icon.sm{ width:var(--eu-h-sm) }

/* biến thể — có icon thì bớt 4px padding ngang (quy tắc shadcn) */
.eu-btn.has-ic{ padding-left:var(--eu-3); padding-right:var(--eu-3) }
.eu-btn.outline{ background:var(--eu-bg); color:var(--eu-fg);
  border-color:var(--eu-input); box-shadow:var(--eu-shadow-xs) }
.eu-btn.outline:hover{ background:var(--eu-muted) }
.eu-btn.secondary{ background:var(--eu-muted); color:var(--eu-fg) }
.eu-btn.secondary:hover{ background:color-mix(in srgb, var(--eu-muted) 80%, var(--eu-fg)) }
.eu-btn.ghost{ background:transparent; color:var(--eu-fg) }
.eu-btn.ghost:hover{ background:var(--eu-muted) }
.eu-btn.danger{ background:var(--eu-destructive); color:#fff }
.eu-btn.link{ background:transparent; color:var(--eu-primary); height:auto; padding:0;
  text-underline-offset:4px }
.eu-btn.link:hover{ text-decoration:underline; background:transparent }

/* ═══════════════════ THẺ ═══════════════════
   Mấu chốt: padding DỌC nằm ở thẻ, padding NGANG nằm ở từng phần.
   Nhờ vậy thêm đường kẻ vào đầu thẻ là tự có khoảng thở đúng. */
.eu-card{
  display:flex; flex-direction:column; gap:var(--eu-6);
  background:var(--eu-card); color:var(--eu-fg);
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-xl);
  padding:var(--eu-6) 0; box-shadow:var(--eu-shadow-sm);
}
.eu-card.flush{ gap:0; padding:0 }              /* thẻ chứa bảng full-bleed */
.eu-card-hd{
  display:grid; grid-auto-rows:min-content; align-items:start; gap:var(--eu-2);
  padding:0 var(--eu-6);
}
.eu-card-hd.has-act{ grid-template-columns:1fr auto }
.eu-card-hd.bd{ padding-bottom:var(--eu-6); border-bottom:1px solid var(--eu-border) }
.eu-card-t{ font-size:var(--eu-fs-sm); font-weight:600; line-height:1.2 }
.eu-card-d{ font-size:var(--eu-fs-sm); color:var(--eu-muted-fg); line-height:1.5 }
.eu-card-act{ grid-column:2; grid-row:1/span 2; justify-self:end; align-self:start }
.eu-card-ct{ padding:0 var(--eu-6) }
.eu-card-ct.flush{ padding:0 }
.eu-card-ft{ display:flex; align-items:center; gap:var(--eu-2); padding:0 var(--eu-6) }
.eu-card-ft.bd{ padding-top:var(--eu-6); border-top:1px solid var(--eu-border) }

/* ═══════════════════ THẺ SỐ (KPI) ═══════════════════
   4 phần theo dashboard-01: nhãn · số · badge xu hướng · chân giải thích */
.eu-stat{ position:relative; display:flex; flex-direction:column; gap:var(--eu-2);
  background:var(--eu-card); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-xl); padding:var(--eu-4) var(--eu-6);
  box-shadow:var(--eu-shadow-xs) }
.eu-stat .lb{ font-size:var(--eu-fs-sm); color:var(--eu-muted-fg); line-height:1.3 }
.eu-stat .v{ font-size:26px; font-weight:600; letter-spacing:-.6px; line-height:1.1;
  font-variant-numeric:tabular-nums }
.eu-stat .act{ position:absolute; top:var(--eu-4); right:var(--eu-6) }
.eu-stat .ft{ display:flex; flex-direction:column; gap:6px; font-size:13px; margin-top:2px }
.eu-stat .ft .l1{ font-weight:500; display:flex; align-items:center; gap:6px }
.eu-stat .ft .l2{ color:var(--eu-muted-fg) }
/* thiếu nguồn: KHÔNG hiện 0%, hiện gạch ngang + nền kẻ sọc */
.eu-stat.na .v{ font-size:var(--eu-fs-sm); font-weight:500; color:var(--eu-muted-fg);
  letter-spacing:0 }
.eu-stat.na .v:before{ content:'— chưa đủ dữ liệu' }

/* ═══════════════════ BẢNG ═══════════════════ */
.eu-tw{ position:relative; width:100%; overflow-x:auto;
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-lg) }
.eu-tw.bare{ border:0; border-radius:0 }
table.eu-tb{ width:100%; border-collapse:collapse; font-size:var(--eu-fs-sm);
  caption-side:bottom }
table.eu-tb th{
  height:40px; padding:0 var(--eu-2); text-align:left; vertical-align:middle;
  font-weight:500; font-size:13px; color:var(--eu-fg); white-space:nowrap;
  background:var(--eu-muted); border-bottom:1px solid var(--eu-border);
  position:sticky; top:0; z-index:10;
}
table.eu-tb td{ padding:var(--eu-2); vertical-align:middle;
  border-bottom:1px solid var(--eu-border) }
table.eu-tb tbody tr:last-child td{ border-bottom:0 }
table.eu-tb tbody tr{ transition:background .1s }
table.eu-tb tbody tr:hover{ background:color-mix(in srgb, var(--eu-muted) 50%, transparent) }
table.eu-tb tbody tr[data-sel="1"]{ background:var(--eu-muted) }
table.eu-tb tbody tr.clk{ cursor:pointer }
table.eu-tb tfoot td{ border-top:1px solid var(--eu-border); border-bottom:0;
  font-weight:500; background:color-mix(in srgb, var(--eu-muted) 50%, transparent) }
/* Số LUÔN căn phải và tabular — kể cả tiêu đề cột */
table.eu-tb .r,table.eu-tb th.r{ text-align:right; font-variant-numeric:tabular-nums }
table.eu-tb .c{ text-align:center }
table.eu-tb td.sub{ color:var(--eu-muted-fg); font-size:13px }
/* hàng rỗng của data-table shadcn: cao 96px, căn giữa */
table.eu-tb .no-row td{ height:96px; text-align:center; color:var(--eu-muted-fg) }
/* ô sửa tại chỗ: chỉ hiện viền khi focus */
.eu-cell-inp{ height:var(--eu-h-sm); width:100%; padding:0 6px; text-align:right;
  border:1px solid transparent; background:transparent; border-radius:var(--eu-radius-sm);
  font-family:var(--font-mono,monospace); font-size:13px; color:var(--eu-fg);
  font-variant-numeric:tabular-nums }
.eu-cell-inp:hover{ border-color:var(--eu-input) }

/* ═══════════════════ BADGE ═══════════════════
   Trạng thái trung tính dùng `outline` (viền + chữ xám), KHÔNG tô màu.
   Tô màu chỉ dành cho việc thật sự cần chú ý. */
.eu-bg{ display:inline-flex; width:fit-content; align-items:center; justify-content:center;
  gap:var(--eu-1); padding:2px var(--eu-2); border:1px solid transparent;
  border-radius:9999px; font-size:var(--eu-fs-xs); font-weight:500; line-height:1.4;
  white-space:nowrap; overflow:hidden }
.eu-bg svg{ width:12px; height:12px }
.eu-bg.outline{ border-color:var(--eu-border); color:var(--eu-muted-fg); background:transparent }
.eu-bg.solid{ background:var(--eu-primary); color:var(--eu-primary-fg) }
.eu-bg.ok{ background:var(--ok2); color:var(--ok) }
.eu-bg.warn{ background:var(--warn2); color:var(--warn) }
.eu-bg.err{ background:var(--err2); color:var(--err) }
.eu-bg.info{ background:var(--b50); color:var(--b500); border-color:var(--b200) }
.eu-bg.mute{ background:var(--eu-muted); color:var(--eu-muted-fg) }
/* badge đếm trong tab — ép tròn đều */
.eu-bg.cnt{ min-width:20px; height:20px; padding:0 5px;
  background:color-mix(in srgb, var(--eu-muted-fg) 22%, transparent); color:var(--eu-fg);
  font-variant-numeric:tabular-nums }

/* ═══════════════════ TAB ═══════════════════ */
/* kiểu hộp: nền muted, tab chọn nổi lên nền trắng + đổ bóng */
.eu-tabs{ display:inline-flex; align-items:center; gap:0; height:var(--eu-h-md);
  padding:3px; background:var(--eu-muted); border-radius:var(--eu-radius-lg);
  color:var(--eu-muted-fg) }
.eu-tab{ display:inline-flex; align-items:center; gap:6px; height:calc(100% - 1px);
  padding:0 var(--eu-2); border:0; background:transparent; cursor:pointer;
  border-radius:var(--eu-radius-md); font-family:inherit; font-size:var(--eu-fs-sm);
  font-weight:500; color:color-mix(in srgb, var(--eu-fg) 60%, transparent); white-space:nowrap }
.eu-tab:hover{ color:var(--eu-fg) }
.eu-tab[aria-selected="true"],.eu-tab.on{
  background:var(--eu-bg); color:var(--eu-fg); box-shadow:var(--eu-shadow-sm) }
/* kiểu gạch chân: dùng cho thanh tab chính của trang */
.eu-tabs.line{ background:transparent; padding:0; height:auto; gap:var(--eu-1);
  border-radius:0; display:flex; flex-wrap:wrap }
.eu-tabs.line .eu-tab{ position:relative; height:38px; padding:0 var(--eu-3);
  border-radius:0; box-shadow:none }
.eu-tabs.line .eu-tab.on{ background:transparent; color:var(--eu-fg); box-shadow:none }
.eu-tabs.line .eu-tab.on:after{ content:''; position:absolute; left:0; right:0; bottom:-1px;
  height:2px; background:var(--eu-fg); border-radius:2px }

/* ═══════════════════ Ô NHẬP · FORM ═══════════════════ */
/* 🪤 VÁ 18/08/2026 — box-sizing. Bộ này KHÔNG có reset toàn cục, mà ô nhập
   mặc định width:100%. Với content-box thì 100% + padding 2×12 + viền 2 =
   luôn rộng hơn khung cha 26px → tràn ngang ở mọi màn hẹp. Đặt width:300px
   cũng ra 326px thật. Bắt được bằng test trình duyệt ở khổ 390px. */
.eu-inp,.eu-sel,.eu-ta{
  box-sizing:border-box;
  width:100%; height:var(--eu-h-md); padding:0 var(--eu-3);
  border:1px solid var(--eu-input); border-radius:var(--eu-radius-md);
  background:var(--eu-bg); color:var(--eu-fg);
  font-family:inherit; font-size:var(--eu-fs-sm); box-shadow:var(--eu-shadow-xs) }
.eu-ta{ height:auto; padding:var(--eu-2) var(--eu-3); line-height:1.55; resize:vertical }
.eu-inp.sm,.eu-sel.sm{ height:var(--eu-h-sm); font-size:13px }
.eu-inp:disabled,.eu-sel:disabled{ background:var(--eu-muted); color:var(--eu-muted-fg);
  cursor:not-allowed; box-shadow:none }
.eu-inp::placeholder{ color:var(--text-5) }

/* Field: gap trong 1 field 6px · giữa 2 field 28px · giữa 2 nhóm 24px */
.eu-fset{ display:flex; flex-direction:column; gap:var(--eu-6); border:0; padding:0; margin:0 }
.eu-fgrp{ display:flex; flex-direction:column; gap:var(--eu-7) }
.eu-fgrid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:var(--eu-4) var(--eu-4) }
.eu-fld{ display:flex; flex-direction:column; gap:6px }
.eu-fld>label{ font-size:var(--eu-fs-sm); font-weight:500; line-height:1.2 }
.eu-fld>label .rq{ color:var(--eu-destructive); margin-left:2px }
.eu-fld .desc{ font-size:13px; color:var(--eu-muted-fg); line-height:1.5 }
.eu-fld .err{ font-size:13px; color:var(--eu-destructive); font-weight:500 }
.eu-fld[data-invalid="true"] .eu-inp,.eu-fld[data-invalid="true"] .eu-sel{
  border-color:var(--eu-destructive) }
.eu-fld[data-invalid="true"]>label{ color:var(--eu-destructive) }

/* ═══════════════════ ITEM — dòng danh sách media + nội dung + hành động ═══ */
.eu-items{ display:flex; flex-direction:column }
.eu-item{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--eu-4);
  padding:var(--eu-4); border:1px solid transparent; border-radius:var(--eu-radius-md);
  font-size:var(--eu-fs-sm) }
.eu-item.sm{ gap:10px; padding:var(--eu-3) var(--eu-4) }
.eu-item.outline{ border-color:var(--eu-border) }
.eu-item.muted{ background:color-mix(in srgb, var(--eu-muted) 50%, transparent) }
.eu-item+.eu-item.sep{ border-top:1px solid var(--eu-border); border-radius:0 }
.eu-item-md{ width:32px; height:32px; flex:none; display:grid; place-items:center;
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-sm);
  background:var(--eu-muted); font-size:15px }
.eu-item-md.lg{ width:40px; height:40px; font-size:17px }
.eu-item-ct{ flex:1; min-width:0; display:flex; flex-direction:column; gap:var(--eu-1) }
.eu-item-t{ font-weight:500; line-height:1.35 }
.eu-item-d{ color:var(--eu-muted-fg); line-height:1.5 }
.eu-item-ac{ display:flex; align-items:center; gap:var(--eu-2); flex:none }

/* ═══════════════════ TRẠNG THÁI RỖNG ═══════════════════ */
.eu-empty{ display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--eu-6); padding:var(--eu-6); text-align:center;
  border:1px dashed var(--eu-border); border-radius:var(--eu-radius-lg) }
@media(min-width:768px){ .eu-empty{ padding:48px var(--eu-6) } }
.eu-empty.bare{ border:0 }
.eu-empty-hd{ display:flex; flex-direction:column; align-items:center; gap:var(--eu-2);
  max-width:384px }
.eu-empty-md{ width:40px; height:40px; display:grid; place-items:center;
  background:var(--eu-muted); border-radius:var(--eu-radius-lg); font-size:20px;
  margin-bottom:var(--eu-2) }
.eu-empty-t{ font-size:18px; font-weight:500; letter-spacing:-.2px }
.eu-empty-d{ font-size:var(--eu-fs-sm); line-height:1.625; color:var(--eu-muted-fg) }
.eu-empty-ct{ display:flex; flex-direction:column; align-items:center; gap:var(--eu-4);
  max-width:384px; font-size:var(--eu-fs-sm) }
/* biến thể GỌN — dùng trong thẻ nhỏ, không chiếm nửa màn hình */
.eu-empty.slim{ flex-direction:row; align-items:flex-start; text-align:left;
  gap:var(--eu-3); padding:var(--eu-4); border-style:solid }
.eu-empty.slim .eu-empty-md{ width:28px; height:28px; font-size:15px; margin:0 }
.eu-empty.slim .eu-empty-hd{ align-items:flex-start; max-width:none }
.eu-empty.slim .eu-empty-t{ font-size:var(--eu-fs-sm); font-weight:600 }
.eu-empty.slim .eu-empty-d{ font-size:13px }

/* ═══════════════════ ĐẦU TRANG · THANH CÔNG CỤ ═══════════════════ */
.eu-head{ display:flex; align-items:center; gap:var(--eu-2); min-height:48px;
  padding:var(--eu-2) var(--eu-4); border-bottom:1px solid var(--eu-border);
  background:var(--eu-bg) }
@media(min-width:1024px){ .eu-head{ padding:var(--eu-2) var(--eu-6) } }
.eu-head h1{ font-size:var(--eu-fs-base); font-weight:500; letter-spacing:-.2px; margin:0 }
.eu-head .sep{ width:1px; height:16px; background:var(--eu-border); margin:0 var(--eu-2) }
.eu-head .sp{ flex:1 }
.eu-sub{ font-size:13px; color:var(--eu-muted-fg) }
.eu-bar{ display:flex; align-items:center; gap:var(--eu-2); flex-wrap:wrap;
  padding:var(--eu-2) var(--eu-4); background:var(--eu-bg);
  border-bottom:1px solid var(--eu-border) }
.eu-lbl{ font-size:var(--eu-fs-xs); font-weight:600; letter-spacing:.4px;
  text-transform:uppercase; color:var(--eu-muted-fg) }

/* ═══════════════════ PHÂN TRANG ═══════════════════ */
.eu-pag{ display:flex; align-items:center; gap:var(--eu-2); padding:var(--eu-3) var(--eu-4);
  font-size:var(--eu-fs-sm); border-top:1px solid var(--eu-border) }
.eu-pag .info{ color:var(--eu-muted-fg) }
.eu-pag .sp{ flex:1 }
.eu-pag .grp{ display:flex; align-items:center; gap:32px }
.eu-pag .pg{ font-weight:500; font-variant-numeric:tabular-nums }
.eu-pag .nav{ display:flex; gap:var(--eu-1) }

/* ═══════════════════ THANH TIẾN ĐỘ ═══════════════════ */
.eu-pr{ height:6px; background:var(--eu-muted); border-radius:9999px; overflow:hidden }
.eu-pr>i{ display:block; height:100%; background:var(--eu-primary); border-radius:9999px }
.eu-pr>i.ok{ background:var(--ok) } .eu-pr>i.warn{ background:var(--warn) }
.eu-pr>i.err{ background:var(--err) }
.eu-pr.hatch{ background:repeating-linear-gradient(45deg,
  var(--surface-3),var(--surface-3) 4px,var(--surface-2) 4px,var(--surface-2) 8px) }
/* có mốc mục tiêu */
.eu-prt{ position:relative; height:10px; background:var(--eu-muted); border-radius:4px }
.eu-prt>i{ display:block; height:100%; border-radius:4px; background:var(--eu-primary) }
.eu-prt>i.ok{ background:var(--ok) } .eu-prt>i.warn{ background:var(--warn) }
.eu-prt>i.err{ background:var(--err) }
.eu-prt>.mk{ position:absolute; top:-3px; bottom:-3px; width:2px; background:var(--eu-fg);
  opacity:.7 }

/* ═══════════════════ DẢI THÔNG BÁO (alert) ═══════════════════
   Nền nhạt + viền cùng tông. Không dùng nền đặc — chữ trên nền đặc
   khó đọc ở đoạn dài, và nó tranh chú ý với chỗ tô màu chính của màn. */
.eu-alert{ display:grid; grid-template-columns:20px 1fr; gap:var(--eu-3);
  align-items:start; padding:var(--eu-3) var(--eu-4);
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-lg);
  background:var(--eu-bg); font-size:var(--eu-fs-sm); line-height:1.6 }
.eu-alert>.ic{ font-size:15px; line-height:1.3 }
/* 🔴 13/08/2026 — DẢI KHÔNG CÓ Ô ICON THÌ ĐỪNG CHIA CỘT.
   Lưới `20px 1fr` giả định phần tử đầu là `.ic`. Rất nhiều chỗ gọi chỉ viết
   `<div class="eu-alert ok"><b>…</b> chữ…</div>` — thẻ <b> rơi vào cột 20px và
   VỠ DỌC TỪNG CHỮ (Alex bắt được ở ngăn chi tiết Temp giá: một cột chữ "Đã /
   lấy / giá / (file / không / có / mã / phát / hành)").
   Sửa ở bộ chung chứ không đi vá từng chỗ gọi: cùng một lỗi đang nằm rải rác
   ở nhiều module, và chỗ gọi thứ N+1 viết ngày mai sẽ lại dính. */
.eu-alert:not(:has(> .ic)){ display:block }
.eu-alert b{ display:block; font-weight:600; margin-bottom:2px }
.eu-alert.ok{ background:var(--ok2); border-color:transparent; color:var(--ok) }
.eu-alert.warn{ background:var(--warn2); border-color:transparent; color:var(--warn) }
.eu-alert.err{ background:var(--err2); border-color:transparent; color:var(--err) }
.eu-alert.info{ background:var(--b50); border-color:var(--b200); color:var(--b500) }

/* ═══════════════════ THANG MỨC (ladder) ═══════════════════
   Dùng cho tiến trình có thứ bậc: mức chỉ định, mốc vòng đời NPP. */
.eu-lad{ display:flex; border:1px solid var(--eu-border); border-radius:var(--eu-radius-md);
  overflow:hidden; font-size:var(--eu-fs-xs); font-weight:600 }
.eu-lad>div{ flex:1; padding:6px 4px; text-align:center; background:var(--eu-muted);
  color:var(--text-5); border-right:1px solid var(--eu-border) }
.eu-lad>div:last-child{ border-right:0 }
.eu-lad>div.done{ background:var(--ok); color:#fff }
.eu-lad>div.now{ background:var(--eu-primary); color:#fff }

/* ═══════════════════ DÒNG THUỘC TÍNH (property row) ═══════════════════ */
.eu-props{ display:flex; flex-direction:column }
.eu-prop{ display:flex; gap:var(--eu-3); padding:7px 0; font-size:13px;
  border-bottom:1px solid var(--eu-border) }
.eu-prop:last-child{ border-bottom:0 }
.eu-prop>b{ width:126px; flex:none; font-weight:400; color:var(--eu-muted-fg) }
.eu-prop>span{ flex:1; min-width:0 }

/* ═══════════════════ GHI CHÚ GIẢI THÍCH ═══════════════════
   Dùng cho đoạn nói VÌ SAO màn hình làm như vậy — đặt cuối thẻ. */
.eu-hint{ font-size:13px; color:var(--eu-muted-fg); line-height:1.6;
  padding:var(--eu-3) var(--eu-6); background:color-mix(in srgb,var(--eu-muted) 45%,transparent);
  border-top:1px solid var(--eu-border) }
.eu-hint b{ color:var(--eu-fg); font-weight:500 }
.eu-note{ font-size:13px; color:var(--eu-muted-fg); line-height:1.65;
  background:color-mix(in srgb,var(--eu-muted) 45%,transparent);
  border:1px dashed var(--eu-border); border-radius:var(--eu-radius-md);
  padding:var(--eu-3) var(--eu-4) }
.eu-note b{ color:var(--eu-fg); font-weight:500 }

/* ═══════════════════ CHẤM MÀU + PHÍM MÃ ═══════════════════
   Bổ sung 18/08/2026 — khuôn màn V12 (MOCKUP_BAN_HANH_GIA_V12) mà Alex duyệt
   cho toàn dự án dùng hai thứ này, nhưng bộ chung chưa có nên mỗi mockup lại
   tự chế `.dot` / `.kbd` riêng. Đưa vào đây, tiền tố eu- như mọi class khác.

   CHẤM MÀU đứng đầu dòng `.l1` của thẻ số: nó là chỗ tô màu RẺ NHẤT — một
   chấm 8px đủ dẫn mắt mà không biến bảng thành cầu vồng. Đúng nguyên tắc
   "mỗi màn một chỗ tô màu đặc". */
.eu-dot{ display:inline-block; width:8px; height:8px; border-radius:50%; flex:none }
.eu-dot.ok{ background:var(--ok) }
.eu-dot.wn{ background:var(--warn) }
.eu-dot.er{ background:var(--err) }
.eu-dot.mu{ background:var(--text-5) }
.eu-dot.pr{ background:var(--eu-primary) }

/* Tên cột / tên bảng / mã lệnh nhắc trong câu chữ */
.eu-kbd{ font-family:ui-monospace,Consolas,'JetBrains Mono',monospace; font-size:12px;
  padding:1px 5px; border:1px solid var(--eu-border); border-radius:4px;
  background:var(--eu-muted) }

/* ═══════════════════ TIỆN ÍCH ═══════════════════ */
.eu-xs{ font-size:var(--eu-fs-xs) }
.eu-sm{ font-size:13px }
.eu-skel{ background:linear-gradient(90deg,var(--surface-2) 25%,var(--surface-3) 50%,
  var(--surface-2) 75%); background-size:200% 100%; animation:euSkel 1.2s infinite;
  border-radius:var(--eu-radius-sm); height:13px }
@keyframes euSkel{ 0%{background-position:200% 0} 100%{background-position:-200% 0} }
/* Thang 1 cột — cần khi số thẻ sinh động (1 thẻ thì đừng kéo giãn hết dòng) */
.eu-grid-1{ display:grid; grid-template-columns:1fr; gap:var(--eu-4) }
.eu-grid-2{ display:grid; grid-template-columns:1fr 1fr; gap:var(--eu-4) }
.eu-grid-3{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--eu-4) }
.eu-grid-4{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--eu-4) }
.eu-grid-21{ display:grid; grid-template-columns:2fr 1fr; gap:var(--eu-4); align-items:start }
.eu-stack{ display:flex; flex-direction:column; gap:var(--eu-4) }
.eu-row{ display:flex; align-items:center; gap:var(--eu-2) }
.eu-wrap{ flex-wrap:wrap }
.eu-sp{ flex:1 }
.eu-mut{ color:var(--eu-muted-fg) }
.eu-num{ font-variant-numeric:tabular-nums }
.eu-mono{ font-family:var(--font-mono,ui-monospace,Consolas,monospace);
  font-variant-numeric:tabular-nums }
.eu-sep{ height:1px; background:var(--eu-border); border:0; margin:0 }
@media(max-width:1100px){
  .eu-grid-21,.eu-grid-2,.eu-grid-3{ grid-template-columns:1fr }
  .eu-grid-4{ grid-template-columns:1fr 1fr }
}
@media(max-width:640px){ .eu-grid-4{ grid-template-columns:1fr } }

/* ═══════════════════ MẬT ĐỘ DÀY (compact) ═══════════════════
   Đặt data-dense="1" hoặc class .eu-dense lên một khối bao ngoài.
   Dùng cho màn nghiệp vụ mở tám tiếng mỗi ngày: hồ sơ thiết kế, BOM,
   danh mục vật tư. KHÔNG dùng cho màn báo cáo hay trang giới thiệu.

   Bộ mặc định có ba nấc chiều cao 32/36/40px — vẫn giữ nguyên.
   Đây là nấc thứ tư 24px CHỈ áp trong vùng dày, không phá thang chung. */
.eu-dense{
  --eu-h-sm: 28px;
  --eu-h-md: 32px;
  --eu-h-lg: 36px;
  --eu-fs-sm: 13px;
  --eu-row-h: 30px;      /* hàng bảng */
  --eu-th-h: 28px;       /* tiêu đề cột */
  --eu-tool-h: 34px;     /* thanh công cụ */
  --eu-radius-xl: 4px;   /* thẻ hết bo tròn to */
  --eu-radius-lg: 4px;
  --eu-radius-md: 4px;
  font-size:13px;
}
/* nút cỡ thanh công cụ — nấc 24px, chỉ có trong vùng dày */
.eu-dense .eu-btn.tool{ height:24px; padding:0 8px; gap:5px; font-size:12px;
  border-radius:4px; font-weight:500 }
.eu-dense .eu-btn.tool.icon{ width:24px; padding:0 }
/* thanh công cụ và thanh lọc — hai dải riêng, đúng kiểu structure browser */
.eu-dense .eu-tool{ height:var(--eu-tool-h); display:flex; align-items:center; gap:4px;
  padding:0 8px; background:var(--eu-muted); border-bottom:1px solid var(--eu-border);
  overflow-x:auto }
.eu-dense .eu-tool .eu-vs{ width:1px; height:18px; background:var(--eu-input); margin:0 4px; flex:none }
.eu-dense .eu-filter{ height:30px; display:flex; align-items:center; gap:10px; padding:0 8px;
  background:var(--eu-bg); border-bottom:1px solid var(--eu-border);
  font-size:12px; color:var(--eu-muted-fg); overflow-x:auto }
/* bảng dày */
.eu-dense table{ font-size:12px }
.eu-dense th{ height:var(--eu-th-h); padding:0 8px; font-size:11px; font-weight:600;
  text-transform:uppercase; letter-spacing:.3px; color:var(--eu-muted-fg) }
.eu-dense td{ padding:4px 8px; height:var(--eu-row-h) }
/* 🪤 VÁ 18/08/2026 — chế độ dày KHÔNG ăn vào .eu-tb.
   `table.eu-tb td` có độ cụ thể (0,1,2), `.eu-dense td` chỉ (0,1,1) → bảng
   chuẩn luôn thắng và hàng vẫn 47px dù đã bật chế độ dày. Bắt được bằng test
   trình duyệt thật (đo getBoundingClientRect), linkedom không thấy vì không
   tính bố cục. Ba dòng dưới nâng độ cụ thể cho khớp. */
.eu-dense table.eu-tb{ font-size:12px }
.eu-dense table.eu-tb th{ height:var(--eu-th-h); padding:0 8px; font-size:11px }
.eu-dense table.eu-tb td{ padding:4px 8px }
/* thẻ trong vùng dày */
.eu-dense .eu-card{ border-radius:4px; box-shadow:none }
.eu-dense .eu-card-hd{ min-height:34px; padding:0 10px }
.eu-dense .eu-card-ct{ padding:10px }
/* badge nhỏ lại một nấc */
.eu-dense .eu-bg{ height:18px; padding:0 6px; border-radius:3px }

/* ════════════════════════════════════════════════════════════════════════════
   BỔ SUNG 2026-08-17 — thành phần dựng cho module NSCA CRM.
   Đặt ở bộ chung vì đều dùng lại được: thanh giai đoạn, bảng luồng, phễu,
   dòng thời gian, thanh phân bố, thẻ việc cần xử lý, nút phân đoạn, chip lọc.
   ⚠ Icon dùng sprite <symbol> KHÔNG mang theo fill/stroke — phải khai .eu-ic.
   ════════════════════════════════════════════════════════════════════════════ */

/* icon nét: dùng cho mọi <svg> lấy từ sprite */
.eu-ic{ fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; width:16px; height:16px; flex:none }
.eu-ic.sm{ width:14px; height:14px }
.eu-ic.xs{ width:12px; height:12px }

/* ── THANH GIAI ĐOẠN (path) ────────────────────────────────────────────── */
.eu-path{ display:flex; gap:3px }
.eu-path .st{ flex:1; height:var(--eu-h-lg); display:flex; align-items:center;
  justify-content:center; gap:6px; padding:0 14px 0 22px; font-size:13px;
  background:var(--eu-muted); color:var(--eu-muted-fg); cursor:pointer;
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 50%,calc(100% - 12px) 100%,0 100%,12px 50%) }
.eu-path .st:first-child{ padding-left:var(--eu-4);
  border-radius:var(--eu-radius-md) 0 0 var(--eu-radius-md);
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 50%,calc(100% - 12px) 100%,0 100%) }
.eu-path .st:last-child{ border-radius:0 var(--eu-radius-md) var(--eu-radius-md) 0;
  clip-path:polygon(0 0,100% 0,100% 100%,0 100%,12px 50%) }
.eu-path .st.done{ background:var(--ok2); color:var(--ok) }
.eu-path .st.now{ background:var(--eu-primary); color:var(--eu-primary-fg); font-weight:600 }
/* điều kiện sang bước sau */
.eu-gate{ display:flex; align-items:center; gap:10px; margin-top:var(--eu-3);
  padding:var(--eu-3); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-lg); background:var(--warn2) }
.eu-gate .k{ font-size:13px; font-weight:500 }
.eu-gate .r{ margin-left:auto; display:flex; gap:var(--eu-2) }
@media(max-width:900px){
  .eu-path{ flex-direction:column }
  .eu-path .st,.eu-path .st:first-child,.eu-path .st:last-child{
    clip-path:none; border-radius:var(--eu-radius-md); padding:0 var(--eu-3);
    justify-content:flex-start }
}

/* ── BẢNG LUỒNG (kanban) ───────────────────────────────────────────────── */
.eu-kb{ display:grid; gap:var(--eu-3); align-items:start;
  grid-template-columns:repeat(var(--eu-kb-n,3),1fr) }
.eu-kb-c{ background:var(--eu-muted); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-lg); display:flex; flex-direction:column; min-height:260px }
.eu-kb-h{ display:flex; align-items:center; gap:var(--eu-2); height:var(--eu-h-lg);
  padding:0 var(--eu-3); border-bottom:1px solid var(--eu-border) }
.eu-kb-h .t{ font-size:13px; font-weight:500; font-variant-numeric:tabular-nums }
.eu-kb-h .v{ margin-left:auto; font-size:12px; color:var(--eu-muted-fg);
  font-variant-numeric:tabular-nums }
.eu-kb-b{ padding:var(--eu-2); display:flex; flex-direction:column; gap:var(--eu-2);
  max-height:62vh; overflow-y:auto }
.eu-dc{ background:var(--eu-card); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-lg); padding:10px; cursor:pointer }
.eu-dc:hover{ border-color:color-mix(in srgb,var(--eu-fg) 22%,transparent) }
.eu-dc .t{ font-size:13px; font-weight:500; line-height:1.35; display:-webkit-box;
  -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden }
.eu-dc .m{ font-size:12px; color:var(--eu-muted-fg); margin-top:3px }
.eu-dc .f{ display:flex; align-items:center; gap:6px; margin-top:var(--eu-2); flex-wrap:wrap }
.eu-dc .val{ margin-left:auto; font-size:13px; font-weight:600;
  font-variant-numeric:tabular-nums; letter-spacing:-.3px }
.eu-kb-more{ height:var(--eu-h-sm); display:grid; place-items:center; font-size:12px;
  color:var(--eu-muted-fg); border:1px dashed var(--eu-border);
  border-radius:var(--eu-radius-md); cursor:pointer }
@media(max-width:1000px){ .eu-kb{ grid-template-columns:1fr } }

/* ảnh đại diện chữ */
.eu-av{ width:20px; height:20px; border-radius:50%; background:var(--b400);
  color:var(--eu-primary-fg);
  display:grid; place-items:center; font-size:9px; font-weight:700; flex:none }
.eu-av.lg{ width:var(--eu-7); height:var(--eu-7); font-size:11px }
.eu-av.no{ background:var(--eu-muted); color:var(--err);
  border:1px dashed color-mix(in srgb,var(--err) 55%,transparent) }

/* ── PHỄU ──────────────────────────────────────────────────────────────── */
.eu-fn{ display:flex; flex-direction:column; gap:2px }
.eu-fn-r{ display:grid; grid-template-columns:150px 1fr 88px 76px; gap:10px;
  align-items:center; height:var(--eu-h-md); font-size:13px }
.eu-fn-r .nm{ color:var(--eu-fg); overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.eu-fn-b{ height:22px; border-radius:var(--eu-radius-sm); background:var(--eu-muted);
  position:relative; overflow:hidden }
.eu-fn-b i{ position:absolute; inset:0 auto 0 0; border-radius:var(--eu-radius-sm);
  background:color-mix(in srgb,var(--b400) 22%,transparent); border-right:2px solid var(--b400) }
.eu-fn-b u{ position:absolute; inset:0 auto 0 0; border-radius:var(--eu-radius-sm);
  text-decoration:none; background:repeating-linear-gradient(135deg,
    color-mix(in srgb,var(--err) 18%,transparent) 0 5px,transparent 5px 10px) }
.eu-fn-r .n,.eu-fn-r .p{ text-align:right; font-variant-numeric:tabular-nums }
.eu-fn-r .p{ color:var(--eu-muted-fg) }
@media(max-width:760px){
  .eu-fn-r{ grid-template-columns:110px 1fr 62px; height:auto; padding:6px 0 }
  .eu-fn-r .p{ display:none } }

/* ── DÒNG THỜI GIAN ────────────────────────────────────────────────────── */
.eu-tl{ display:flex; flex-direction:column }
.eu-tl-i{ display:grid; grid-template-columns:var(--eu-7) 1fr; gap:10px;
  padding-bottom:14px; position:relative }
.eu-tl-i:before{ content:''; position:absolute; left:13px; top:30px; bottom:0; width:1px;
  background:var(--eu-border) }
.eu-tl-i:last-child{ padding-bottom:0 }
.eu-tl-i:last-child:before{ display:none }
.eu-tl-d{ width:var(--eu-7); height:var(--eu-7); border-radius:50%;
  background:var(--eu-muted); border:1px solid var(--eu-border);
  display:grid; place-items:center; color:var(--eu-muted-fg) }
.eu-tl-b .h{ font-size:13px; font-weight:500 }
.eu-tl-b .w{ font-size:12px; color:var(--eu-muted-fg); margin-top:1px }
.eu-tl-b .c{ font-size:13px; margin-top:var(--eu-1); padding:var(--eu-2) 10px;
  background:var(--eu-muted); border-radius:var(--eu-radius-md);
  border:1px solid var(--eu-border) }

/* ── THANH PHÂN BỐ ─────────────────────────────────────────────────────── */
.eu-dist{ display:flex; height:8px; border-radius:9999px; overflow:hidden;
  background:var(--eu-muted); margin-top:6px }
.eu-dist i{ display:block; height:100% }
.eu-dist-lg{ display:flex; flex-wrap:wrap; gap:var(--eu-1) var(--eu-3);
  margin-top:var(--eu-2); font-size:12px; color:var(--eu-muted-fg) }
.eu-dist-lg span{ display:inline-flex; align-items:center; gap:5px }
.eu-dist-lg u{ width:8px; height:8px; border-radius:2px; text-decoration:none }

/* ── THẺ VIỆC CẦN XỬ LÝ ────────────────────────────────────────────────── */
.eu-td{ display:flex; gap:10px; align-items:flex-start; background:var(--eu-card);
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-lg);
  padding:var(--eu-3); border-left:3px solid var(--eu-border) }
.eu-td.hi{ border-left-color:var(--err);
  background:color-mix(in srgb,var(--err) 4%,var(--eu-card)) }
.eu-td.md{ border-left-color:var(--warn) }
.eu-td .ic{ width:var(--eu-7); height:var(--eu-7); border-radius:var(--eu-radius-md);
  background:var(--eu-muted); display:grid; place-items:center; flex:none;
  color:var(--eu-muted-fg) }
.eu-td.hi .ic{ background:var(--err2); color:var(--err) }
.eu-td.md .ic{ background:var(--warn2); color:var(--warn) }
.eu-td .n{ font-size:20px; font-weight:600; letter-spacing:-.5px; line-height:1.15;
  font-variant-numeric:tabular-nums }
.eu-td .l{ font-size:13px; font-weight:500; margin-top:1px }
.eu-td .s{ font-size:12px; color:var(--eu-muted-fg); margin-top:2px; line-height:1.45 }
.eu-td .go{ margin-top:var(--eu-2) }

/* ── NÚT PHÂN ĐOẠN · CHIP LỌC ──────────────────────────────────────────── */
.eu-seg{ display:inline-flex; height:var(--eu-h-sm); padding:3px; gap:2px;
  background:var(--eu-muted); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-md) }
.eu-seg button{ height:100%; padding:0 10px; border:0; background:transparent;
  cursor:pointer; border-radius:var(--eu-radius-sm); font:inherit; font-size:13px;
  color:var(--eu-muted-fg); display:inline-flex; align-items:center; gap:5px }
.eu-seg button.on{ background:var(--eu-card); color:var(--eu-fg); font-weight:500;
  box-shadow:0 1px 2px color-mix(in srgb,var(--eu-fg) 10%,transparent) }
.eu-chips{ display:flex; gap:6px; flex-wrap:wrap; align-items:center }
.eu-chip{ display:inline-flex; align-items:center; gap:5px; height:var(--eu-7);
  padding:0 9px; border:1px solid var(--eu-border); border-radius:9999px;
  background:var(--eu-card); font-size:12px; color:var(--eu-fg); cursor:pointer }
.eu-chip.on{ background:var(--eu-primary); color:var(--eu-primary-fg);
  border-color:var(--eu-primary) }
.eu-chip.add{ border-style:dashed; color:var(--eu-muted-fg) }

/* ── THANH HÀNH ĐỘNG HÀNG LOẠT ─────────────────────────────────────────── */
.eu-bulk{ display:flex; align-items:center; gap:10px; padding:0 var(--eu-3);
  height:var(--eu-h-lg); background:var(--eu-primary); color:var(--eu-primary-fg);
  border-radius:var(--eu-radius-md); margin-bottom:10px; font-size:13px }
.eu-bulk .r{ margin-left:auto; display:flex; gap:var(--eu-2) }
.eu-bulk .eu-btn{ background:transparent; color:var(--eu-primary-fg);
  border-color:color-mix(in srgb,var(--eu-primary-fg) 40%,transparent) }

/* ── GHI CHÚ / TRẠNG THÁI RỖNG NGANG ───────────────────────────────────── */
.eu-note{ display:flex; gap:var(--eu-2); align-items:flex-start; padding:10px var(--eu-3);
  border:1px dashed var(--eu-border); border-radius:var(--eu-radius-lg);
  background:var(--eu-card); font-size:12.5px; color:var(--eu-muted-fg);
  margin-top:var(--eu-3) }
.eu-note b{ color:var(--eu-fg); font-weight:500 }
.eu-mt{ display:flex; align-items:center; gap:10px; padding:var(--eu-4);
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-lg);
  background:var(--eu-card) }
.eu-mt .ic{ width:var(--eu-7); height:var(--eu-7); border-radius:var(--eu-radius-md);
  background:var(--eu-muted); display:grid; place-items:center; flex:none;
  color:var(--eu-muted-fg) }
.eu-mt .t{ font-size:var(--eu-fs-sm); font-weight:500 }
.eu-mt .d{ font-size:13px; color:var(--eu-muted-fg) }
.eu-mt .a{ margin-left:auto; flex:none }

/* ── DANH SÁCH THUỘC TÍNH HỒ SƠ ────────────────────────────────────────── */
.eu-pf{ display:grid; grid-template-columns:170px 1fr; gap:6px var(--eu-3); font-size:13px }
.eu-pf dt{ color:var(--eu-muted-fg) }
.eu-pf dd{ color:var(--eu-fg) }
@media(max-width:640px){
  .eu-pf{ grid-template-columns:1fr; gap:2px 0 }
  .eu-pf dd{ margin-bottom:var(--eu-2) } }

/* ── ĐƯỜNG XU HƯỚNG ────────────────────────────────────────────────────── */
.eu-spark{ display:block; width:100%; height:26px; margin-top:2px }
.eu-spark path{ fill:none; stroke:var(--eu-muted-fg); stroke-width:1.5;
  vector-effect:non-scaling-stroke }

/* ════════════════════════════════════════════════════════════════════════════
   BỔ SUNG 2026-08-17 (2) — VỎ MODULE CÓ CÂY THƯ MỤC RIÊNG (nc-*)
   Dùng cho module nhiều màn phải có cây riêng lồng trong thanh bên của ERP.
   Chạy đúng ở cả hai nơi: nhúng trong #content của ERP, và web riêng.
   ════════════════════════════════════════════════════════════════════════════ */
.nc-app{ display:grid; grid-template-columns:236px 1fr; gap:0;
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-xl);
  overflow:hidden; background:var(--eu-card); min-height:70vh }

/* ── cây thư mục ─────────────────────────────────────────────────────────── */
.nc-sb{ border-right:1px solid var(--eu-border); background:var(--eu-muted);
  padding-bottom:var(--eu-3); transition:width 200ms linear; overflow:hidden }
.nc-sb.gon{ width:48px }
.nc-app:has(.nc-sb.gon){ grid-template-columns:48px 1fr }
.nc-sb-hd{ display:flex; align-items:center; gap:var(--eu-2);
  height:var(--eu-h-lg); padding:0 10px; border-bottom:1px solid var(--eu-border) }
.nc-sb-tg{ width:28px; padding:0; flex:none; justify-content:center }
.nc-sb-ti{ min-width:0 }
.nc-sb-ti .t{ font-size:13px; font-weight:600; letter-spacing:-.2px; white-space:nowrap }
.nc-sb-ti .s{ font-size:11px; color:var(--eu-muted-fg); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis }
.nc-sb.gon .nc-sb-ti{ display:none }
.nc-sb-gr{ padding:10px 6px 2px }
.nc-sb-gr>span{ display:block; height:var(--eu-h-sm); line-height:var(--eu-h-sm);
  padding:0 8px; font-size:11px; font-weight:600; letter-spacing:.3px;
  color:var(--eu-muted-fg); white-space:nowrap }
.nc-sb.gon .nc-sb-gr>span{ visibility:hidden; height:var(--eu-1) }
.nc-sb-i{ display:flex; align-items:center; gap:var(--eu-2); height:var(--eu-h-sm);
  padding:0 8px; border-radius:var(--eu-radius-md); font-size:13.5px;
  color:var(--eu-fg); cursor:pointer; white-space:nowrap }
.nc-sb-i:hover{ background:var(--eu-card) }
.nc-sb-i.on{ background:var(--eu-card); font-weight:600;
  box-shadow:inset 2px 0 0 var(--eu-primary) }
.nc-sb-i .lbl{ overflow:hidden; text-overflow:ellipsis }
.nc-sb-i .bdg{ margin-left:auto; flex:none }
.nc-sb.gon .nc-sb-i .lbl,.nc-sb.gon .nc-sb-i .bdg{ display:none }
.nc-sb.gon .nc-sb-i{ justify-content:center; padding:0 }

/* ── thanh trên của module ───────────────────────────────────────────────── */
.nc-main{ min-width:0; display:flex; flex-direction:column }
.nc-bar{ display:flex; align-items:center; gap:var(--eu-3); min-height:var(--eu-h-lg);
  padding:6px var(--eu-3); border-bottom:1px solid var(--eu-border);
  background:var(--eu-card); flex-wrap:wrap }
.nc-bc{ font-size:14px; font-weight:600; letter-spacing:-.2px }
.nc-bar-r{ margin-left:auto; display:flex; align-items:center; gap:6px; flex-wrap:wrap }
.nc-body{ padding:var(--eu-4); min-width:0 }
@media(min-width:1280px){ .nc-body{ padding:var(--eu-6) } }

/* ════════════════════════════════════════════════════════════════════════════
   TOÀN MÀN HÌNH — thêm 26/08/2026 (Alex: "cho giao diện toàn màn hình")

   Vì sao cần lớp riêng: .nc-app vốn là một THẺ có viền và bo góc, để nhúng
   vừa vặn trong #content của ERP. Khi module chạy ở web riêng thì cái thẻ ấy
   thành một hộp lửng lơ giữa trang — thừa viền, thừa lề, và tệ nhất là cả
   trang cuộn chung nên cây thư mục trôi mất khi kéo xuống.

   .nc-app.full biến nó thành khung ứng dụng thật:
     · chiếm trọn chiều cao cửa sổ, không viền không bo góc
     · cây thư mục và thanh trên ĐỨNG YÊN, chỉ vùng nội dung cuộn
     · dưới 900px thì cây xếp lên trên, tránh bóp nội dung còn 1/3 màn

   ⚠ Chỉ thêm lớp `full`, KHÔNG sửa .nc-app gốc — mọi màn đang nhúng trong
   ERP vẫn giữ nguyên hình dạng cũ.
   ════════════════════════════════════════════════════════════════════════════ */
/* ── TOÀN MÀN HÌNH KHI NHÚNG TRONG VỎ ERP — 09/09/2026 ─────────────────────
   Alex: "cho toàn màn hình". Bản 26/08 chỉ bật ở WEB RIÊNG, và chú thích khi
   đó nêu đúng lý do không bật trong ERP: cho height:100vh ở giữa trang là đẩy
   chân trang ra khỏi màn và sinh hai thanh cuộn lồng nhau.

   Cách làm ở đây KHÔNG gán chiều cao và KHÔNG đoán chiều cao thanh trên.
   Vỏ ERP đã dựng sẵn đúng thứ cần:
       .main    { flex:1; overflow:hidden }
       .content { flex:1; overflow-y:auto; position:relative; padding:20px }
   `.content` đã là khối cuộn và đã chiếm trọn phần còn lại của cửa sổ, và nó
   được cho `position:relative` từ 03/07/2026 CHÍNH VÌ mục đích này (xem chú
   thích ở index.html:628 — trang module dùng inset:0 để nằm gọn trong nó).
   Nên `position:absolute; inset:0` là vừa khít: phủ luôn cả 20px padding để
   chạm mép, không đụng một dòng nào của vùng chung index.html, và không đẻ
   thanh cuộn thứ hai vì phần tử ra khỏi luồng — `.content` không còn gì để cuộn,
   chỗ cuộn duy nhất là `.nc-body` bên trong.

   ⚠ CHỈ dùng cho module chiếm trọn trang. Trang nào còn nội dung khác bên dưới
     mà thêm lớp này thì nội dung đó bị phủ mất. */
.nc-app.full-erp{ position:absolute; inset:0; min-height:0;
  border:0; border-radius:0 }
.nc-app.full-erp .nc-sb{ height:100%; overflow-y:auto; overscroll-behavior:contain }
.nc-app.full-erp .nc-main{ height:100%; min-height:0 }
.nc-app.full-erp .nc-bar{ position:sticky; top:0; z-index:30; flex:none }
.nc-app.full-erp .nc-body{ flex:1; min-height:0; overflow-y:auto;
  overscroll-behavior:contain }

@media(max-width:900px){
  /* Máy màn nhỏ: trả về luồng thường, cây xếp lên trên, cả trang cuộn như cũ.
     Giữ inset:0 ở đây là bóp nội dung còn một phần ba màn. */
  .nc-app.full-erp{ position:static; height:auto }
  .nc-app.full-erp .nc-sb{ height:auto; border-right:0;
    border-bottom:1px solid var(--eu-border) }
  .nc-app.full-erp .nc-body{ overflow:visible }
}

.nc-app.full{ height:100vh; height:100dvh; min-height:0;
  border:0; border-radius:0 }
.nc-app.full .nc-sb{ height:100%; overflow-y:auto; overscroll-behavior:contain }
.nc-app.full .nc-main{ height:100%; min-height:0 }
.nc-app.full .nc-bar{ position:sticky; top:0; z-index:30; flex:none }
.nc-app.full .nc-body{ flex:1; min-height:0; overflow-y:auto;
  overscroll-behavior:contain }
body.nc-full{ margin:0; overflow:hidden }

@media(max-width:900px){
  .nc-app.full{ grid-template-columns:1fr; height:auto; height:auto }
  .nc-app.full .nc-sb{ height:auto; border-right:0;
    border-bottom:1px solid var(--eu-border) }
  .nc-app.full .nc-body{ overflow:visible }
  body.nc-full{ overflow:auto }
}

/* ── Thanh tab con của module ─────────────────────────────────────────────
   Có từ 26/08 khi gom cây NSCA CRM từ 16 mục xuống 8: các màn cũ chui vào
   tab con của mục cha. Tab dính dưới thanh trên và KHÔNG cuộn theo nội dung,
   nếu không thì kéo xuống là mất lối quay lại màn anh em. */
.nc-tabs{ display:flex; gap:2px; padding:0 var(--eu-4);
  border-bottom:1px solid var(--eu-border); background:var(--eu-card);
  overflow-x:auto; flex:none }
.nc-app.full .nc-tabs{ position:sticky; top:var(--eu-h-lg); z-index:29 }
.nc-tab{ border:0; background:transparent; font:inherit; font-size:13px;
  font-weight:500; padding:10px 12px; cursor:pointer; color:var(--eu-muted-fg);
  border-bottom:2px solid transparent; margin-bottom:-1px; white-space:nowrap }
.nc-tab:hover{ color:var(--eu-fg) }
.nc-tab.on{ color:var(--b400); font-weight:600; border-bottom-color:var(--b400) }
:root[data-theme="dark"] .nc-tab.on{ color:var(--text) }
.nc-tab .n{ margin-left:6px; font-size:12px; color:var(--eu-muted-fg);
  font-variant-numeric:tabular-nums }
.nc-tab.on .n{ color:var(--b400) }

/* ── Lưới nhà phân phối (trang chính module) ─────────────────────────────── */
.nc-nl{ display:grid; gap:14px;
  grid-template-columns:repeat(auto-fill,minmax(268px,1fr)) }
.nc-nc{ background:var(--eu-card); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-xl); padding:16px; cursor:pointer;
  position:relative; box-shadow:var(--shadow) }
.nc-nc:hover{ border-color:var(--border-strong); box-shadow:var(--shadow-md) }
.nc-nc .top{ display:flex; align-items:flex-start; gap:11px; margin-bottom:14px }
.nc-nc .lo{ width:40px; height:40px; border-radius:11px; flex:none; display:grid;
  place-items:center; font-size:13px; font-weight:700; letter-spacing:-.4px;
  background:var(--surface-2); color:var(--text-2) }
.nc-nc.t1 .lo{ background:var(--b50); color:var(--b400) }
/* Chế độ Tối: --b400 trên --b50 chỉ được 4.46:1 — sát dưới ngưỡng AA.
   Đo bằng render thật 26/08. Dùng nấc sáng hơn một bậc thì lên 5.44:1. */
:root[data-theme="dark"] .nc-nc.t1 .lo{ color:var(--b500) }
.nc-nc .nm{ font-size:20px; font-weight:600; letter-spacing:-.35px; line-height:1.2 }
.nc-nc .mt{ font-size:12px; color:var(--text-4); margin-top:2px }
.nc-nc .on{ position:absolute; top:16px; right:16px }
.nc-nc .row{ display:flex; gap:14px; margin-bottom:12px }
.nc-nc .cell{ flex:1; min-width:0 }
.nc-nc .cl{ font-size:11px; font-weight:600; letter-spacing:.5px;
  text-transform:uppercase; color:var(--text-4) }
.nc-nc .cv{ font-size:15px; font-weight:600; letter-spacing:-.15px; margin-top:3px;
  font-variant-numeric:tabular-nums }
.nc-nc .cv u{ text-decoration:none; font-size:12px; font-weight:500;
  color:var(--text-4); letter-spacing:0 }
.nc-nc .ft{ display:flex; align-items:center; gap:8px; padding-top:12px;
  border-top:1px solid var(--eu-border); font-size:12px; color:var(--text-4) }
.nc-nc .go{ margin-left:auto; font-size:12px; font-weight:600; color:var(--b400) }
.nc-live{ display:inline-flex; align-items:center; gap:6px; font-size:12px;
  font-weight:500; color:var(--ok) }
.nc-live i{ width:6px; height:6px; border-radius:50%; background:var(--ok);
  box-shadow:0 0 0 3px var(--ok2) }

/* ── Lớp giám sát (chỉ quản trị NSCA thấy) ───────────────────────────────── */
.nc-spy{ border:1px solid var(--b200); border-radius:var(--eu-radius-xl);
  overflow:hidden; background:var(--eu-card) }
.nc-spy>.h{ display:flex; align-items:center; gap:10px; padding:13px 16px;
  background:var(--b50); border-bottom:1px solid var(--b200) }
.nc-spy>.h b{ font-size:13px; font-weight:600; color:var(--b500) }
:root[data-theme="dark"] .nc-spy>.h b{ color:var(--text) }
.nc-spy>.b{ padding:16px }
.nc-spy .g3{ display:grid; grid-template-columns:repeat(3,1fr); gap:11px;
  margin-bottom:16px }
.nc-spy .g3 .u{ border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-md); padding:11px }
.nc-spy .g3 .u .l{ font-size:11px; font-weight:600; letter-spacing:.5px;
  text-transform:uppercase; color:var(--text-4) }
.nc-spy .g3 .u .v{ font-size:20px; font-weight:600; letter-spacing:-.35px;
  margin-top:4px; font-variant-numeric:tabular-nums }
@media(max-width:1100px){ .nc-spy .g3{ grid-template-columns:1fr } }

/* Logo gọn trên thanh trên — dùng khi module chạy web riêng và không còn
   thanh thương hiệu của trang ở phía trên nữa. */
.np-lg{ display:flex; align-items:center; gap:8px; flex:none }
.np-lg .m{ width:26px; height:26px; border-radius:7px; flex:none;
  display:grid; place-items:center; font-size:11px; font-weight:700;
  letter-spacing:-.3px; color:#fff;
  background:linear-gradient(140deg,var(--brand,#F26A21),#D9541A) }
.np-lg-t{ font-size:13px; font-weight:600; letter-spacing:-.15px;
  white-space:nowrap }
@media(max-width:760px){ .np-lg-t{ display:none } }

/* ── Bảng nhập cam kết theo tháng (cổng NPP) ─────────────────────────────── */
.np-ck td .in{ width:104px; text-align:right; font-variant-numeric:tabular-nums }
.np-ck tr.chot{ background:var(--eu-muted) }
.np-ck tr.chot td{ color:var(--eu-muted-fg) }
.np-ck .dl{ font-variant-numeric:tabular-nums }
.np-ck .dl.am{ color:var(--warn) } .np-ck .dl.duong{ color:var(--ok) }

/* ── ô tìm nhanh ─────────────────────────────────────────────────────────── */
.nc-find{ position:relative; display:flex; align-items:center; gap:6px;
  height:var(--eu-h-sm); padding:0 8px; border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-md); background:var(--eu-bg);
  color:var(--eu-muted-fg) }
.nc-find input{ border:0; background:transparent; outline:none; font:inherit;
  font-size:13px; width:180px; color:var(--eu-fg); height:100% }
.nc-find .kbd{ display:inline-flex; align-items:center; height:20px; padding:0 5px;
  border:1px solid var(--eu-border); border-radius:4px; font-size:10.5px;
  color:var(--eu-muted-fg); background:var(--eu-card) }
.nc-res{ display:none; position:absolute; top:calc(100% + 4px); right:0;
  width:min(420px,80vw); max-height:52vh; overflow-y:auto; z-index:70;
  background:var(--eu-card); border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-lg); box-shadow:var(--eu-shadow-md,0 8px 24px rgba(0,0,0,.12));
  padding:var(--eu-1) }
.nc-res-i{ display:flex; align-items:center; gap:var(--eu-2); padding:7px var(--eu-2);
  border-radius:var(--eu-radius-md); cursor:pointer; font-size:13px }
.nc-res-i:hover{ background:var(--eu-muted) }
.nc-res-i .t{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap }
.nc-res-i .p{ color:var(--eu-muted-fg); font-size:12px; flex:none }
/* Nhãn nhóm trong danh sách kết quả tìm — 27/08/2026, dùng cho mục "Gần đây" */
.nc-res-h{ padding:6px var(--eu-2) 4px; font-size:12px; font-weight:500;
  color:var(--eu-muted-fg); border-bottom:1px solid var(--eu-border) }

/* ═══════════════════ SỬA TẠI CHỖ (nc-st) — 28/08/2026 ═══════════════════
   Alex: "ấn tab nào nên sửa trực tiếp lên panel của tab đó cho tiện".
   Bút chì CHỈ hiện khi rê chuột hoặc khi ô được chọn bằng bàn phím — hiện
   thường trực thì mỗi dòng hồ sơ có một biểu tượng, mắt không biết nhìn đâu
   (nguyên tắc "một màn một chỗ tô đậm" của bộ giao diện). */
.nc-st{ display:inline-flex; align-items:center; gap:var(--eu-1);
  border-radius:var(--eu-radius-sm); padding:1px 4px; margin:-1px -4px;
  cursor:text; max-width:100% }
.nc-st:hover{ background:var(--eu-muted) }
.nc-st:focus-visible{ outline:none; border-color:var(--eu-ring);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--eu-ring) 45%, transparent) }
.nc-st-v{ min-width:0; overflow-wrap:anywhere }
.nc-st-p{ opacity:0; flex:none; color:var(--eu-muted-fg); line-height:0 }
.nc-st:hover .nc-st-p, .nc-st:focus-within .nc-st-p{ opacity:.65 }
.nc-st-p.ok{ opacity:1; color:var(--ok) }
.nc-st-h{ font-size:11.5px; color:var(--eu-muted-fg); margin-left:var(--eu-2);
  white-space:nowrap }
.nc-st .eu-inp, .nc-st .eu-sel{ min-width:160px }
.nc-st .eu-ta{ min-width:240px }

/* ═══════════════ Ô TÌM-TRƯỚC-TẠO-SAU (nc-ct) ═══════════════
   Mục "Tạo mới" LUÔN nằm CUỐI, sau mọi bản ghi đã có — đặt lên đầu là mời
   người dùng tạo trùng, và đó đúng là cách 23 nhóm bản trùng sinh ra. */
.nc-ct{ position:relative }
.nc-ct-ds{ display:none; position:absolute; top:calc(100% + 4px); left:0; right:0;
  z-index:40; max-height:300px; overflow:auto; background:var(--eu-bg);
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-md);
  box-shadow:var(--eu-shadow-sm) }
.nc-ct-h{ padding:6px var(--eu-2) 4px; font-size:12px; font-weight:500;
  color:var(--eu-muted-fg) }
.nc-ct-i{ display:flex; align-items:center; gap:var(--eu-2);
  padding:7px var(--eu-2); cursor:pointer; font-size:13px }
.nc-ct-i:hover{ background:var(--eu-muted) }
.nc-ct-i .t{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap }
.nc-ct-i .p{ color:var(--eu-muted-fg); font-size:12px; flex:none }
.nc-ct-i.moi{ border-top:1px solid var(--eu-border); color:var(--eu-primary) }
.nc-ct-tt{ margin-top:6px; font-size:12.5px }

/* ── mobile: cây thu về thanh cuộn ngang ─────────────────────────────────── */
@media(max-width:900px){
  .nc-app,.nc-app:has(.nc-sb.gon){ grid-template-columns:1fr }
  .nc-sb,.nc-sb.gon{ width:auto; border-right:0;
    border-bottom:1px solid var(--eu-border); display:flex; overflow-x:auto;
    padding:0 var(--eu-2) }
  .nc-sb-hd,.nc-sb-gr>span{ display:none }
  .nc-sb-gr{ display:flex; padding:6px 0; gap:var(--eu-1) }
  .nc-sb-i,.nc-sb.gon .nc-sb-i{ padding:0 10px; justify-content:flex-start }
  .nc-sb-i .lbl,.nc-sb.gon .nc-sb-i .lbl{ display:inline }
  .nc-sb.gon .nc-sb-i .bdg{ display:inline-flex }
  .nc-body{ padding:var(--eu-3) }
  .nc-find input{ width:120px }
  .nc-find .kbd{ display:none }
}

/* ════════════════════════════════════════════════════════════════════════════
   BỔ SUNG 2026-08-17 (3) — HỘP THOẠI NHẬP LIỆU (nc-dlg)
   Khoảng cách theo bộ chuẩn: trong một field 6px · giữa hai field 28px.
   ════════════════════════════════════════════════════════════════════════════ */
dialog.nc-dlg{ border:1px solid var(--eu-border); border-radius:var(--eu-radius-xl);
  padding:0; background:var(--eu-card); color:var(--eu-fg);
  width:min(560px,94vw); max-height:88vh; overflow:hidden;
  /* ⚠ BẮT BUỘC. <dialog> chỉ tự căn giữa nhờ margin:auto MẶC ĐỊNH của trình
     duyệt — mà index.html của ERP có reset `*{margin:0}` quét luôn cả dialog,
     nên hộp thoại rơi vào góc TRÊN-TRÁI màn hình. Alex bắt được 25/08/2026. */
  margin:auto;
  box-shadow:var(--eu-shadow-pop,0 16px 48px rgba(0,0,0,.22)) }
dialog.nc-dlg::backdrop{ background:color-mix(in srgb,#000 42%,transparent) }
.nc-dlg-in{ display:flex; flex-direction:column; max-height:88vh }

/* ── Biến thể NGĂN: trượt vào từ mép phải, cao hết màn ─────────────────────
   Dùng cho hồ sơ chi tiết — thứ người dùng vừa đọc vừa đối chiếu với bảng
   phía sau, khác hẳn hộp nhập liệu ngắn nên không dùng chung khuôn giữa màn. */
dialog.nc-dlg.ngan{ margin:0 0 0 auto; width:min(620px,100vw);
  height:100%; max-height:100%; border-radius:var(--eu-radius-xl) 0 0 var(--eu-radius-xl);
  border-right:0; animation:nc-ngan-vao .18s ease-out }
dialog.nc-dlg.ngan .nc-dlg-in{ max-height:100%; height:100% }
dialog.nc-dlg.ngan .nc-dlg-bd{ flex:1 }
/* Biến thể RỘNG — 27/08/2026, Alex: "cho to panel ra".
   Panel Đối tác 360 không phải hộp nhập liệu: nó chứa bảng dự án, danh sách
   đối tác liên quan và bảng nhật ký 5 cột. Ở 620px thì bảng nhật ký phải cuộn
   ngang, và tên công ty dài bị xuống ba dòng.
   ⚠ Là class RIÊNG chứ không nới thẳng .ngan: hồ sơ NPP (nc-view-npp.js) cũng
   dùng .ngan và nó vừa với 620px — nới chung là thay đổi một màn không ai xin. */
dialog.nc-dlg.ngan.rong{ width:min(980px,100vw) }
@media(max-width:1024px){ dialog.nc-dlg.ngan.rong{ width:min(760px,100vw) } }
@keyframes nc-ngan-vao{ from{ transform:translateX(24px); opacity:.4 } to{ transform:none; opacity:1 } }
@media(max-width:680px){
  dialog.nc-dlg.ngan{ width:100vw; border-radius:0; border-left:0 }
}
.nc-dlg-hd{ display:flex; align-items:flex-start; gap:var(--eu-3);
  padding:var(--eu-3) var(--eu-4); border-bottom:1px solid var(--eu-border) }
.nc-dlg-hd .eu-btn{ margin-left:auto; width:28px; padding:0; justify-content:center;
  flex:none }
.nc-dlg-bd{ padding:var(--eu-4); overflow-y:auto; display:flex;
  flex-direction:column; gap:var(--eu-7) }
.nc-dlg-ft{ display:flex; align-items:center; gap:var(--eu-2);
  padding:var(--eu-3) var(--eu-4); border-top:1px solid var(--eu-border);
  background:var(--eu-muted) }

.nc-fld{ display:flex; flex-direction:column; gap:6px }
.nc-fld>label{ font-size:13px; font-weight:500; color:var(--eu-fg) }
.nc-fld .eu-inp,.nc-fld .eu-sel,.nc-fld .eu-ta{ width:100% }
.nc-hint{ font-size:12px; color:var(--eu-muted-fg); line-height:1.5 }
.nc-fgrid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--eu-3) }
@media(max-width:560px){ .nc-fgrid{ grid-template-columns:1fr; gap:var(--eu-7) } }
.nc-chkline{ display:flex; align-items:center; gap:var(--eu-2); font-size:13px;
  cursor:pointer }

/* ════════════════════════════════════════════════════════════════════════════
   BỔ SUNG 2026-08-18 — DANH SÁCH TỆP ĐÍNH KÈM (nc-tep)
   Dùng cho tệp lưu trên Google Drive: CSDL chỉ giữ đường dẫn + file_id.
   ════════════════════════════════════════════════════════════════════════════ */
.nc-tep{ display:flex; flex-direction:column; gap:var(--eu-1) }
.nc-tep-i{ display:flex; align-items:center; gap:var(--eu-2); padding:7px var(--eu-2);
  border:1px solid var(--eu-border); border-radius:var(--eu-radius-md);
  background:var(--eu-card); font-size:13px }
.nc-tep-i:hover{ background:var(--eu-muted) }
.nc-tep-i .ic{ width:26px; height:26px; border-radius:var(--eu-radius-sm);
  background:var(--eu-muted); display:grid; place-items:center; flex:none;
  color:var(--eu-muted-fg) }
.nc-tep-i .t{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; color:var(--eu-fg); text-decoration:none; font-weight:500 }
.nc-tep-i .t:hover{ text-decoration:underline }
.nc-tep-i .m{ font-size:11.5px; color:var(--eu-muted-fg); flex:none; white-space:nowrap }
@media(max-width:640px){ .nc-tep-i .m{ display:none } }

/* ════════════════════════════════════════════════════════════════════════════
   BỔ SUNG 31/08/2026 — 4 component màn Nghỉ Phép cần mà bộ chung còn thiếu.
   Viết vào ĐÂY chứ không chế riêng trong module (luật nsca-ui §0).
   Số đo lấy từ _mockups/MOCKUP_DON_PHONG_TOI_V3_2026-08-31.html.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Thanh hành động hàng loạt — hiện khi có dòng được tick ─────────────── */
.eu-bulk{ display:flex; align-items:center; gap:var(--eu-3); height:40px;
  padding:0 var(--eu-4); background:var(--b50); border-bottom:1px solid var(--eu-border);
  font-size:var(--eu-fs-sm) }
.eu-bulk b{ font-weight:600 }

/* ── Ngăn trượt phải (sheet) ────────────────────────────────────────────── */
.eu-scrim{ position:fixed; inset:0; z-index:40;
  background:color-mix(in srgb, var(--ink) 45%, transparent) }
.eu-sheet{ position:fixed; top:0; right:0; bottom:0; width:520px; max-width:100%;
  z-index:41; background:var(--eu-card); border-left:1px solid var(--eu-border);
  box-shadow:var(--shadow-lg); display:flex; flex-direction:column }
.eu-sheet-hd{ display:flex; align-items:flex-start; gap:var(--eu-3);
  padding:var(--eu-4) var(--eu-6); border-bottom:1px solid var(--eu-border) }
.eu-sheet-hd .t{ font-size:16px; font-weight:600; letter-spacing:-.2px }
.eu-sheet-hd .s{ font-size:13px; color:var(--eu-muted-fg); margin-top:2px }
.eu-sheet-ct{ flex:1; overflow-y:auto; padding:var(--eu-6);
  display:flex; flex-direction:column; gap:var(--eu-6) }
.eu-sheet-ft{ display:flex; align-items:center; gap:var(--eu-2);
  padding:var(--eu-4) var(--eu-6); border-top:1px solid var(--eu-border);
  background:var(--surface-1) }
@media(max-width:640px){ .eu-sheet{ width:100% } }

/* ── Dải lịch tháng ─────────────────────────────────────────────────────── */
.eu-cal{ display:grid; grid-template-columns:repeat(7,1fr); gap:var(--eu-1) }
.eu-cal .hd{ height:24px; display:grid; place-items:center; font-size:12px;
  color:var(--eu-muted-fg); font-weight:500 }
.eu-cal .d{ min-height:56px; border:1px solid var(--eu-border);
  border-radius:var(--eu-radius-sm); padding:var(--eu-1);
  display:flex; flex-direction:column; gap:2px }
.eu-cal .d>.n{ font-size:12px; color:var(--text-3); font-variant-numeric:tabular-nums }
.eu-cal .d.off{ background:var(--surface-1); color:var(--text-5) }
.eu-cal .d.warn{ border-color:var(--warn); background:var(--warn2) }
.eu-cal .chip{ font-size:12px; line-height:1.35; padding:1px 4px; border-radius:4px;
  background:var(--b50); color:var(--b600); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis }
.eu-cal .chip.o{ background:var(--warn2); color:var(--warn) }

/* ── Lưới nhân sự ngày × người ──────────────────────────────────────────── */
.eu-hm{ border-collapse:separate; border-spacing:0; font-size:12px; width:100% }
.eu-hm th,.eu-hm td{ padding:0; text-align:center; vertical-align:middle }
.eu-hm th.nm,.eu-hm td.nm{ text-align:left; padding:0 var(--eu-2); min-width:180px;
  position:sticky; left:0; background:var(--eu-card); z-index:2;
  border-right:1px solid var(--eu-border) }
.eu-hm thead th{ height:40px; font-weight:500; background:var(--surface-1);
  border-bottom:1px solid var(--eu-border); font-variant-numeric:tabular-nums }
.eu-hm thead th.we{ color:var(--text-4) }
.eu-hm tbody td{ height:32px; border-bottom:1px solid var(--eu-border); min-width:32px }
.eu-hm tbody tr:last-child td{ border-bottom:0 }
.eu-hm tr.grp td{ height:28px; background:var(--surface-2); font-weight:500;
  text-align:left; padding:0 var(--eu-2); color:var(--text-2) }
.eu-hm .cell{ display:block; width:24px; height:24px; line-height:24px; margin:0 auto;
  border-radius:var(--eu-radius-sm); font-size:11px; font-weight:600 }
.eu-hm .cell.p{ background:var(--b50); color:var(--b600) }
.eu-hm .cell.c{ background:var(--warn2); color:var(--warn); border:1px dashed var(--warn) }
.eu-hm .cell.k{ background:var(--surface-2); color:var(--text-3);
  border:1px dashed var(--border-strong) }
.eu-hm .cell.o{ background:var(--warn2); color:var(--warn) }
.eu-hm .cell.we{ background:var(--surface-1) }
.eu-hm tr.sum td{ height:34px; border-top:1px solid var(--eu-border);
  border-bottom:1px solid var(--eu-border); font-weight:600;
  font-variant-numeric:tabular-nums; background:var(--surface-1) }
.eu-hm tr.sum td.lo{ background:var(--warn2); color:var(--warn) }
.eu-hm tr.sum td.nm{ font-weight:500; font-size:12px }
