/* =============================================================================
   BỘ CONTROL DÙNG CHUNG — dựng lại từ bản gốc His_Site_TheoVaiTro
   (GD-13, GD-14, GD-15 của docs/quanly/BACKLOG_GIAO_DIEN.md)

   Đây KHÔNG phải bản phỏng theo. Mọi số đo dưới đây chép từ tệp gốc trên máy
   192.168.1.241, đường dẫn ghi ngay cạnh từng khối:

     Css/partCss/bootStrapCustom.css   — biến --ex-input-* và .form-control, .btn
     Css/partCss/master.css            — --main-color và .button
     Css/module-shell.css              — control 28px, viền --line, bo 2px
     Css/exComponent/grid-inrow.css    — .dmg-btn (nút trong form chèn dòng)
     Script/Lib/exControl/dropDown/tom-select.bootstrap5.css — mũi tên ô chọn
     Script/Lib/exControl/tabControl/tabulator_bootstrap5.min.css — lưới newGrid
     Views/Home/ControlController.cshtml — catalog 23 control, nhóm Ô nhập /
       Danh sách chọn / Lưới dữ liệu

   VÌ SAO CÓ TỆP RIÊNG. Trước đây quy tắc ô nhập nằm trong site.css và bị bó vào
   bộ chọn `form.mau …`. Mọi ô nhập NGOÀI một thẻ <form class="mau"> — đáng kể
   nhất là ô số phiên và hai ô chọn nằm trong bảng Tài khoản, và ô lọc trên trang
   Gói dữ liệu — rơi về hình thức mặc định của trình duyệt: viền xám mảnh, bo góc
   của hệ điều hành, ô chọn còn nguyên mũi tên của hệ điều hành. Đó đúng là thứ
   người dùng chụp màn hình gửi lại hai lần. Tệp này gắn hình thức vào CHÍNH THẺ
   qua lớp `.o-nhap` / `.o-xo` / `.nut`, không qua tổ tiên, nên không còn chỗ
   nào tuột ra ngoài được nữa. Test KhongConTheNhapTran giữ điều đó.

   BA RÀNG BUỘC KHÔNG ĐƯỢC PHÁ (giống site.css):
   1. style-src 'self', không unsafe-inline → không style nội tuyến, mũi tên ô
      chọn là tệp SVG cùng nguồn chứ không phải data: URI trong thuộc tính style.
   2. Không :has(), không color-mix() — Firefox ESR 102/115 bỏ qua lặng lẽ.
   3. Không tải gì từ Internet.
   ============================================================================= */

:root {
  /* --- Ô nhập: chép nguyên bốn biến gốc -------------------------------------
     bootStrapCustom.css dòng 9–13:
         --ex-input-radius: 2px;  --ex-input-height: 32px;
         --ex-input-pad-y:  4px;  --ex-input-pad-x:  8px;
     và dòng 462–471: font-size 13px, line-height 18px, background #fff. */
  --o-cao: 32px;
  --o-dem-doc: 4px;
  --o-dem-ngang: 8px;
  --o-bo: 2px;
  --o-chu: 0.8125rem;   /* 13px */
  --o-dong: 18px;

  /* Viền ô nhập. Bản gốc dùng #ced4da (1,49:1 trên nền trắng). Ở đây KHÔNG chép
     được giá trị đó: WCAG 1.4.11 đòi ranh giới thành phần tương tác đạt 3:1, và
     hạ ngưỡng này là hạ tiêu chí nghiệm thu. #8a94a3 đạt 3,07:1 và là màu SÁNG
     NHẤT còn đạt — nhìn cạnh bản gốc gần như không phân biệt được, nhẹ hơn hẳn
     #6b7280 (4,83:1) mà bản trước dùng và bị chê là "viền xám mảnh xấu".
     Đây là khác biệt CÓ CHỦ Ý duy nhất so với bản gốc; ghi ở NGON_NGU_THIET_KE.md. */
  --o-vien: #8a94a3;
  --o-vien-mo: #b9c1cc;       /* ô chỉ đọc, ô bị vô hiệu */
  --o-nen: #ffffff;
  --o-nen-tat: #f1f3f6;
  --o-chu-mau: #1e293b;       /* bootStrapCustom: color #1e293b của .cc-*-in */
  --o-cho: #94a3b8;           /* placeholder */

  /* Tiêu điểm. bootStrapCustom.css dòng 456–460 và 490–493:
         border-color: var(--tranfer-color);            (= #2563eb85)
         box-shadow:   0 0 3px 1px var(--tranfer-color);
     #2563eb85 là #2563eb ở alpha 0x85 = 133/255 = 0,52. */
  --o-vien-tieu-diem: #2563eb;
  --o-quang-tieu-diem: 0 0 3px 1px rgba(37, 99, 235, .52);

  /* --- Nút: master.css .button + bootStrapCustom .btn/.btn-primary
     + grid-inrow.css .dmg-btn (padding 7px 18px, font-weight 600) ----------- */
  --nut-cao: var(--o-cao);
  --nut-cao-nho: 26px;        /* module-shell .ms-home/.ms-help là 28px vuông */
  --nut-dem-ngang: 18px;
  --nut-dem-ngang-nho: 10px;

  /* --- Lưới: tabulator_bootstrap5 + phần ghi đè của bootStrapCustom --------
     .tabulator            border 1px #dee2e6
     .tabulator-header     background #fff, color #555, font-weight 700,
                           border-bottom 1px #dee2e6
     .grid-header-title    height 34px, padding 0 10px, font-weight 600
     .tabulator-cell       padding 4px, border-right 1px #dee2e6
     ô lọc tiêu đề         height 34px, viền trên #e2e8f0 */
  --luoi-vien: #dee2e6;
  --luoi-vien-nhat: #e9edf2;
  /* Tiêu đề lưới của bản gốc là NỀN TRẮNG, chữ #555, đậm 700 — không phải dải xám như bản trước
     ở đây tự đặt. Chép đúng: đây là thứ đập vào mắt đầu tiên khi so hai lưới cạnh nhau. */
  --luoi-dau-nen: #ffffff;
  --luoi-dau-chu: #555555;
  --luoi-cao-dau: 34px;
  --luoi-dem-doc: 6px;
  --luoi-dem-ngang: 10px;
  --luoi-soc: #fafbfd;
  --luoi-di-chuot: #eef4ff;
}

/* =============================================================================
   1. Ô NHẬP — textBoxStyle / numberStyle / dateTimeStyle / textAreaStyle
   Catalog ControlController.cshtml nhóm "Ô nhập", file exComponent/02-inputs.js.
   Ở His_Site các hàm này gắn class .form-control vào thẻ; ở đây máy chủ sinh sẵn
   lớp .o-nhap nên không cần JavaScript mới có hình thức đúng — trang không bật
   JavaScript vẫn thấy ô nhập chuẩn.
   ============================================================================= */
.o-nhap,
.o-xo,
.o-van-ban {
  display: block;
  width: 100%;
  min-height: var(--o-cao);
  height: var(--o-cao);
  padding: var(--o-dem-doc) var(--o-dem-ngang);
  border: 1px solid var(--o-vien);
  border-radius: var(--o-bo);
  background: var(--o-nen);
  color: var(--o-chu-mau);
  font-family: inherit;
  font-size: var(--o-chu);
  line-height: var(--o-dong);
  box-shadow: none;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

/* Bản gốc có HAI cỡ chữ ô nhập, và đó không phải sơ suất của họ mà là hai quy tắc chồng nhau:
   bootStrapCustom.css dòng 135–141 đặt `input.form-control { font-size: 14px; line-height: 1.2 }`,
   đặc hiệu hơn quy tắc `.form-control { font-size: 13px; line-height: 18px }` ở dòng 462–471.
   Kết quả: Ô VĂN BẢN và Ô SỐ là 14px/1.2, còn Ô CHỌN và TEXTAREA là 13px/18px. Chép đúng cả
   chỗ này để đo cạnh nhau không lệch — mục tiêu của lượt này là giống bản gốc, không phải
   "dọn cho nhất quán theo ý mình". */
input.o-nhap { font-size: 0.875rem; line-height: 1.2; }

/* Ô nhập đứng trong một hàng thao tác (bảng Tài khoản, thanh lọc) phải co theo
   chỗ trống chứ không chiếm cả hàng. */
.o-nhap-hep { width: auto; }
.o-nhap-so { width: 72px; text-align: right; font-variant-numeric: tabular-nums; }

.o-van-ban {
  height: auto;
  min-height: 84px;
  line-height: 1.55;
  padding: var(--o-dem-ngang) var(--o-dem-ngang);
  resize: vertical;
}

/* Ô tệp không có chiều cao cố định được: nút "Chọn tệp" do trình duyệt vẽ bên
   trong. Giữ đúng viền và bo góc, nới đệm để nút bên trong không chạm viền. */
.o-tep {
  display: block;
  width: 100%;
  padding: 5px var(--o-dem-ngang);
  border: 1px solid var(--o-vien);
  border-radius: var(--o-bo);
  background: var(--o-nen);
  color: var(--o-chu-mau);
  font-family: inherit;
  font-size: var(--o-chu);
  line-height: 1.4;
}

.o-nhap:focus,
.o-xo:focus,
.o-van-ban:focus,
.o-tep:focus {
  border-color: var(--o-vien-tieu-diem);
  box-shadow: var(--o-quang-tieu-diem);
  outline: none;
}
/* Bàn phím vẫn phải có vòng tiêu điểm dày của hệ (site.css :focus-visible) —
   quầng xanh của His_Site quá mảnh để làm chỉ báo bàn phím duy nhất. */
.o-nhap:focus-visible,
.o-xo:focus-visible,
.o-van-ban:focus-visible,
.o-tep:focus-visible { outline: 3px solid #ffbf00; outline-offset: 1px; }

.o-nhap::placeholder,
.o-van-ban::placeholder { color: var(--o-cho); opacity: 1; }

.o-nhap[readonly],
.o-van-ban[readonly],
.o-nhap:disabled,
.o-xo:disabled,
.o-van-ban:disabled {
  background: var(--o-nen-tat);
  border-color: var(--o-vien-mo);
  color: #64748b;
}
.o-nhap:disabled, .o-xo:disabled { cursor: not-allowed; }

/* Ô sai: viền đỏ + quầng đỏ, cùng lối với quầng xanh của tiêu điểm. */
.o-nhap.o-sai, .o-xo.o-sai, .o-van-ban.o-sai {
  border-color: #b91c1c;
  box-shadow: 0 0 3px 1px rgba(185, 28, 28, .45);
}

/* =============================================================================
   2. Ô CHỌN — newDropDownSingle
   His_Site KHÔNG dùng <select> của trình duyệt: catalog dựng TomSelect, và
   tom-select.bootstrap5.css vẽ mũi tên bằng ảnh nền SVG:
       background-image: svg viewBox="0 0 16 16" path d="m2 5 6 6 6-6"
                         stroke #343a40, stroke-width 2, linecap/linejoin round
       background-position: right .75rem center;   (= right 12px center)
       background-size: 16px 12px;
       --ts-pr-caret: 2.25rem   → chừa 36px bên phải cho mũi tên
   Ta dùng <select> thật (không JavaScript vẫn chạy, đọc được bằng trình đọc màn
   hình) nhưng TẮT HẲN hình thức của hệ điều hành bằng appearance:none rồi vẽ lại
   đúng mũi tên đó. Đây là điểm người dùng chỉ đích danh: "ô chọn còn nguyên mũi
   tên mặc định của hệ điều hành".
   ============================================================================= */
.o-xo {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("/img/mui-xo.svg");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px 12px;
  /* 28px = 12px cách mép phải + 16px bề ngang mũi tên — đúng con số bản gốc tính ra. */
  padding-right: 28px;
  cursor: pointer;
}
/* Firefox ESR vẫn vẽ nền xanh cho option đang chọn khi ô đóng; ép về nền ô. */
.o-xo:-moz-focusring { color: transparent; text-shadow: 0 0 0 var(--o-chu-mau); }
.o-xo::-ms-expand { display: none; }
.o-xo option { color: var(--o-chu-mau); background: var(--o-nen); }
.o-xo-hep { width: auto; min-width: 118px; }

/* =============================================================================
   3. NHÃN VÀ KHỐI TRƯỜNG
   grouppanel.css: --gp-font-nhan 12px, --gp-mau-nhan #334155, --gp-font-o 13px.
   ============================================================================= */
.o-nhan {
  display: block;
  min-height: 17px;
  margin: 0 0 4px;
  font-size: 0.75rem;     /* 12px — --gp-font-nhan */
  font-weight: 600;
  color: #334155;         /* --gp-mau-nhan */
  line-height: 1.35;
}
.o-nhan-batbuoc::after { content: " *"; color: #b91c1c; font-weight: 700; }
.o-truong { min-width: 0; }
.o-truong + .o-truong { margin-top: 10px; }
.o-goi-y { display: block; margin-top: 4px; font-size: 0.6875rem; color: #64748b; line-height: 1.4; }

/* Hàng trường: grouppanel dựng các trường thành lưới ngang, nhãn trên ô.

   Căn theo ĐỈNH chứ không theo đáy. Căn đáy (align-items:flex-end) là cách làm quen tay nhưng
   sai ở đây: trường nào có câu gợi ý bên dưới thì câu đó đẩy cả ô nhập lên, và hàng bốn ô hoá
   ra bốn độ cao khác nhau — thấy rõ ở ảnh trang Tài khoản trước khi sửa. Căn đỉnh cộng nhãn có
   chiều cao sàn thì mọi ô bắt đầu cùng một dòng, gợi ý cứ việc treo bên dưới. Nút trong hàng
   không có nhãn nên phải tự bù đúng chiều cao nhãn (17px) cộng khoảng cách (4px). */
.o-hang { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; }
.o-hang > .o-truong { flex: 1 1 200px; }
/* Trường thứ hai trở đi trong MỘT HÀNG không được nhận margin-top của luật xếp DỌC
   (.o-truong + .o-truong { margin-top: 10px }). Không có dòng này thì trong hàng hai ô, ô bên
   phải tụt đúng 10px so với ô bên trái — thấy rõ ở trang Nhận diện hệ thống: nhãn "Tên hệ thống"
   thấp hơn nhãn "Tên cơ quan chủ quản" một nhịp, và cả hai hàng dưới cũng vậy. Khe ngang đã do
   gap lo, luật xếp dọc chỉ dành cho trường xếp chồng. */
.o-hang > .o-truong + .o-truong { margin-top: 0; }
.o-hang > .o-truong.o-truong-hep { flex: 0 0 auto; }
.o-hang > .o-truong.o-truong-rong { flex: 1 1 100%; }
/* GD-30. Sàn chiều cao của nhãn gắn vào CHÍNH lớp .o-nhan (xem mục GD-30 ở site.css), không
   gắn theo .o-hang: nhãn nằm ngoài hàng thì cũng phải cùng chiều cao, nếu không chân ô nhập
   trong hàng và ngoài hàng lệch nhau. */
.o-hang > .hang-nut { margin-top: 21px; }
/* Hai hàng trường liền nhau phải có khoảng thở, nếu không nhãn của hàng dưới dính vào ô của
   hàng trên và đọc thành một khối (thấy rõ ở trang Nhận diện hệ thống trước khi sửa). */
.o-hang + .o-hang { margin-top: 12px; }
.o-hang + .hang-nut { margin-top: 16px; }

/* Ô tick: master.css ép accent-color theo màu phân hệ. */
/* GD-30. Nhãn ô tích: cả cụm là một đích bấm CAO TỐI THIỂU 24px (WCAG 2.5.5 — đích bấm không
   nhỏ hơn 24×24, và đích ở đây là cái nhãn bọc ngoài chứ không phải riêng ô vuông 16px).
   align-items:center đặt tâm ô tích thẳng tâm dòng chữ; trước đây nó vô hiệu vì luật
   `form.mau label { display:block }` của site.css đè mất display:inline-flex. */
.o-tick {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  gap: 8px;
  font-size: var(--o-chu);
  font-weight: 400;
  cursor: pointer;
  user-select: none;
}
/* Hình thức của chính ô vuông gắn vào lớp của nó, KHÔNG theo tổ tiên .o-tick: ô tích đặt ngoài
   nhãn (trong ô bảng, trong thanh lọc) vẫn phải đúng cỡ và đúng màu. */
.o-tick-hop {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: #1d4ed8;
  flex: none;
  cursor: pointer;
}

/* =============================================================================
   4. NÚT — .button (master.css) · .btn / .btn-primary (bootStrapCustom)
            · .dmg-btn (grid-inrow.css: padding 7px 18px, font-weight 600)
   Chiều cao bằng ĐÚNG chiều cao ô nhập (32px) để chân nút và chân ô thẳng hàng
   khi đứng cạnh nhau trong một hàng thao tác.
   ============================================================================= */
.nut {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: var(--nut-cao);
  padding: 0 var(--nut-dem-ngang);
  border: 1px solid #1d4ed8;
  border-radius: var(--o-bo);
  background: #1d4ed8;
  color: #ffffff;
  font-family: inherit;
  font-size: var(--o-chu);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
}
.nut:hover { background: #1e3a8a; border-color: #1e3a8a; color: #fff; text-decoration: none; }
.nut:active { background: #172554; border-color: #172554; }
.nut:disabled, .nut[aria-disabled="true"] {
  background: #cbd5e1; border-color: #cbd5e1; color: #64748b; cursor: not-allowed;
}

/* Nút phụ = .btn của bootStrapCustom: nền trắng, chữ và viền màu phân hệ,
   di chuột thì đảo màu (đúng .button:hover của master.css). */
.nut-phu { background: #ffffff; color: #1d4ed8; border-color: #1d4ed8; }
.nut-phu:hover { background: #1d4ed8; color: #ffffff; border-color: #1d4ed8; }

/* Nút trung tính: dùng cho thao tác không mang màu nghiệp vụ (Đóng, Huỷ).
   Lấy .dmg-btn — viền #dce3ea, di chuột thì viền và chữ chuyển màu phân hệ. */
.nut-trung { background: #ffffff; color: #334155; border-color: #cbd3dd; }
.nut-trung:hover { background: #ffffff; color: #1d4ed8; border-color: #1d4ed8; }

/* Nút nguy hiểm: khoá tài khoản, gỡ logo. Tô đặc chứ không chỉ viền — thao tác
   không lấy lại được thì phải nặng hơn các nút cạnh nó về thị giác. */
.nut-nguy { background: #b91c1c; color: #ffffff; border-color: #b91c1c; }
.nut-nguy:hover { background: #7f1d1d; color: #ffffff; border-color: #7f1d1d; }
/* Biến thể viền, dùng khi nút nguy hiểm đứng lẫn trong một hàng nhiều nút nhỏ
   (hàng thao tác của lưới) — tô đặc ở đó thành ra cả hàng đỏ rực. */
.nut-nguy-vien { background: #ffffff; color: #b91c1c; border-color: #b91c1c; }
.nut-nguy-vien:hover { background: #b91c1c; color: #ffffff; border-color: #b91c1c; }

/* Nút trần: chỉ có chữ, dùng trong dòng văn bản và trong ô lưới. */
.nut-tran { background: transparent; border-color: transparent; color: #1d4ed8; padding: 0 6px; }
.nut-tran:hover { background: #eef4ff; border-color: transparent; color: #1e3a8a; }

/* Nút nhỏ trong lưới: module-shell .ms-home là 28px vuông; nút có chữ trong ô
   lưới phải thấp hơn ô nhập nếu không hàng lưới dày gấp đôi. */
.nut-nho { height: var(--nut-cao-nho); padding: 0 var(--nut-dem-ngang-nho); font-size: 0.75rem; gap: 5px; }
.nut-bieu-tuong { width: var(--nut-cao-nho); padding: 0; }
.nut-bieu-tuong svg { width: 14px; height: 14px; }

.hang-nut { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.hang-nut-phai { margin-left: auto; }

/* =============================================================================
   5. LƯỚI DỮ LIỆU — newGrid (exComponent/04-grid.js trên nền Tabulator)
   Số đo lấy của tabulator_bootstrap5.min.css sau khi bootStrapCustom ghi đè:
     khung        border 1px #dee2e6
     tiêu đề      cao 34px, đệm ngang 10px, đậm 700, kẻ dưới 1px #dee2e6, DÍNH
     ô            đệm 4px (ở đây 6px 10px cho dễ đọc), kẻ phải 1px #dee2e6
     chữ          13px
     cột số       căn phải, chữ số đều bề ngang
     di chuột     đổi nền cả hàng
   ============================================================================= */
.luoi-cuon, .cuon { overflow: auto; }

table.luoi, table.bang {
  width: 100%;
  border-collapse: separate;   /* separate để viền dính của <thead> không biến mất khi cuộn */
  border-spacing: 0;
  background: #ffffff;
  font-size: var(--o-chu);
  line-height: 1.45;
  color: var(--o-chu-mau);
}

table.luoi > thead > tr > th, table.bang > thead > tr > th {
  position: sticky;
  top: 0;
  z-index: 2;
  height: var(--luoi-cao-dau);
  padding: 0 var(--luoi-dem-ngang);
  background: var(--luoi-dau-nen);
  color: var(--luoi-dau-chu);
  font-weight: 700;
  font-size: var(--o-chu);
  text-align: left;
  white-space: nowrap;
  vertical-align: middle;
  border-bottom: 2px solid var(--luoi-vien);
  border-right: 1px solid var(--luoi-vien-nhat);
}
table.luoi > thead > tr > th:last-child, table.bang > thead > tr > th:last-child { border-right: 0; }

table.luoi > tbody > tr > td, table.bang > tbody > tr > td {
  padding: var(--luoi-dem-doc) var(--luoi-dem-ngang);
  border-bottom: 1px solid var(--luoi-vien-nhat);
  border-right: 1px solid var(--luoi-vien-nhat);
  vertical-align: middle;
  text-align: left;
}
table.luoi > tbody > tr > td:last-child, table.bang > tbody > tr > td:last-child { border-right: 0; }
table.luoi > tbody > tr:last-child > td, table.bang > tbody > tr:last-child > td { border-bottom: 0; }

/* Hàng sọc và hàng di chuột. Bản gốc tắt sọc (bootStrapCustom ghi đè
   .tabulator-row-even về transparent) nhưng bảng ở đây rộng tới 47 cột và cuộn
   ngang, mất sọc là lạc dòng — dùng sọc rất nhạt #fafbfd thay vì #e9ecef của
   Tabulator, đủ dẫn mắt mà không thành vằn. */
table.luoi > tbody > tr:nth-child(even), table.bang > tbody > tr:nth-child(even) { background: var(--luoi-soc); }
table.luoi > tbody > tr:hover, table.bang > tbody > tr:hover { background: var(--luoi-di-chuot); }

/* Cột số: căn phải, chữ số đều bề ngang để hàng đơn vị thẳng cột. */
table.luoi td.so, table.luoi th.so, table.bang td.so, table.bang th.so {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
table.luoi td.ma, table.bang td.ma {
  font-family: ui-monospace, "Cascadia Mono", "Consolas", "Liberation Mono", "DejaVu Sans Mono", monospace;
  font-size: 0.75rem;
  white-space: nowrap;
}
table.luoi td.giua, table.luoi th.giua, table.bang td.giua, table.bang th.giua { text-align: center; }

/* Ô chứa thao tác: nút và ô nhập trong lưới không được làm hàng cao gấp đôi. */
td.o-thao-tac { padding: 4px var(--luoi-dem-ngang); white-space: nowrap; }
table.luoi td.o-thao-tac .hang-nut, table.bang td.o-thao-tac .hang-nut { flex-wrap: nowrap; gap: 6px; justify-content: flex-end; }

/* Khung lưới khi đứng một mình (không nằm trong thẻ). */
.luoi-khung {
  border: 1px solid var(--luoi-vien);
  border-radius: var(--o-bo);
  overflow: hidden;
  background: #fff;
}

/* =============================================================================
   5b. DÒNG CHI TIẾT TRONG LƯỚI — "form chèn vào dòng" của His_Site
   Nguồn: Css/exComponent/grid-inrow.css
       .dm-rowdetail { border-top-color: #2563eb; border-bottom-color: #2563eb;
                       background: #f6f8fb; }
       .dmg-form .dmg-foot { border-top-color: #dce3ea; margin-top: 14px;
                             padding-top: 12px; }
       .dmg-btn { border-radius: 0; border: 1px solid #dce3ea; padding: 7px 18px;
                  font-weight: 600; }

   Đây là lối SỬA MỘT DÒNG của His_Site và là cách giải GD-15: thay vì nhồi bảy
   control lên một hàng bảng, hàng chỉ giữ hai thao tác hay dùng, phần còn lại mở
   ra trong dòng chi tiết ngay bên dưới. Khác hộp thoại nổi ở một điểm quan trọng:
   trang KHÔNG có JavaScript thì dòng chi tiết mở sẵn (quy tắc .khong-js dưới đây)
   nên không mất đường vào thao tác nào.
   ============================================================================= */
tr.dong-chi-tiet { display: none; }
tr.dong-chi-tiet.mo { display: table-row; }
/* Không có JavaScript: hiện sẵn mọi dòng chi tiết. site.js gỡ .khong-js ở dòng đầu. */
.khong-js tr.dong-chi-tiet { display: table-row; }

tr.dong-chi-tiet > td {
  padding: 0 !important;
  border-top: 2px solid #1d4ed8;
  border-bottom: 2px solid #1d4ed8;
  background: #f6f8fb;
}
.dong-chi-tiet-noi { padding: 14px 16px 16px; }
.dong-chi-tiet-ten {
  margin: 0 0 12px;
  font-size: 0.8125rem;
  color: #334155;
  padding-bottom: 8px;
  border-bottom: 1px solid #dce3ea;
}
/* Ba cụm thao tác cạnh nhau khi còn chỗ, xếp dọc khi hẹp — mỗi cụm là một <form>
   riêng nên không thể gộp thành một hàng dài như bản trước. */
/* GD-27. Bỏ repeat(auto-fit, minmax(258px, 1fr)): lưới 24 rãnh dùng chung của site.css
   (.luoi-noi-dung) quyết định số cụm một hàng theo bậc bề rộng, nên ở 1920 không còn sinh ra
   bốn năm cột hẹp ngoài ý muốn. Lớp .luoi-noi-dung gắn kèm trong Razor. */
.dong-chi-tiet-cot {
  gap: 16px;
  align-items: start;
}
.dong-chi-tiet-cot:not(.luoi-noi-dung) { display: grid; grid-template-columns: minmax(0, 1fr); }
.dong-chi-tiet-cot > form {
  background: #ffffff;
  border: 1px solid #dce3ea;
  border-radius: var(--o-bo);
  padding: 11px 13px 13px;
}
/* Tên cụm: lối .oh của .cc-ex-opts trong catalog — 11px, đậm 700, chữ hoa nhỏ. */
.o-nhom-ten {
  display: block;
  margin: 0 0 9px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: #64748b;
}
.dong-chi-tiet-cot .o-hang { align-items: flex-end; }

/* Nút mở dòng chi tiết: đổi chữ theo trạng thái mà không cần JavaScript viết chữ. */
.nut-mo-dong[aria-expanded="true"] { background: #1d4ed8; color: #fff; border-color: #1d4ed8; }
.cot-thao-tac { width: 1%; }

/* =============================================================================
   6. NHÃN TRẠNG THÁI — badge của catalog (.cc-h .badge2 / .lib):
      font-size 11px, font-weight 700, padding 2px 9px, bo tròn 999px.
   ============================================================================= */
.nhan {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
  background: #e2e8f0;
  color: #334155;
}
.nhan-xanh { background: #e0e7ff; color: #3730a3; }   /* .badge2 của catalog */
.nhan-luc  { background: #dcfce7; color: #166534; }   /* .lib của catalog */
.nhan-vang { background: #fef3c7; color: #854d0e; }
.nhan-do   { background: #fee2e2; color: #991b1b; }
.nhan-tim  { background: #f3e8ff; color: #6b21a8; }
.nhan-xam  { background: #eef1f5; color: #475569; }

/* =============================================================================
   7. THANH LỌC — hàng ô nhập + nút đứng ngang, chân thẳng nhau.
   ============================================================================= */
.thanh-loc-hang { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; }
.thanh-loc-hang > .o-truong { flex: 0 1 200px; }
.thanh-loc-hang > .hang-nut { flex: 0 0 auto; margin-top: 21px; }


/* =============================================================================
   8. HỘP THOẠI (GD-17) — .ms-help-ov / .ms-help-box của module-shell.css:
        nền phủ rgba(0,0,0,.42)
        hộp   width min(720px, 92vw), max-height 84vh, cột flex,
              viền 1px --line, bóng 0 10px 40px rgba(0,0,0,.3)
        đầu   đệm 10px 14px, nền màu phân hệ, chữ trắng, kẻ dưới
        thân  đệm 12px 16px, cuộn được
   Dựng bằng <dialog> gốc: Esc và bẫy tiêu điểm là hành vi sẵn có của trình duyệt
   khi mở bằng showModal(), không phải thứ phải tự viết rồi viết sai.
   ============================================================================= */
/* GD-27. Nới từ 1040px lên 1360px: hộp thoại nay chứa KHỐI GOM NHÓM của Bảng 1 (sáu nhóm nghiệp
   vụ, lưới 12 cột) chứ không còn là bảng ba cột thô. Ở 1040px mỗi cột chỉ còn 66px và giá trị
   ngày "20250101" bị bẻ đôi giữa dòng. */
dialog.hop-thoai {
  width: min(1360px, 94vw);
  max-width: 94vw;
  max-height: 86vh;
  padding: 0;
  border: 1px solid #cbd3dd;
  border-radius: 6px;
  background: #ffffff;
  color: var(--o-chu-mau);
  box-shadow: 0 10px 40px rgba(0, 0, 0, .3);
  overflow: hidden;
}
dialog.hop-thoai::backdrop { background: rgba(0, 0, 0, .42); }
/* Firefox ESR 102 chưa có <dialog>; site.js khi đó dựng hộp bằng div mang cùng
   lớp cộng .hop-thoai-the. Hai nhánh dùng chung mọi quy tắc con bên dưới. */
.hop-thoai-the {
  position: fixed;
  z-index: 9999;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(1360px, 94vw);
  max-height: 86vh;
  border: 1px solid #cbd3dd;
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.hop-thoai-phu {
  position: fixed;
  z-index: 9998;
  inset: 0;
  background: rgba(0, 0, 0, .42);
}

dialog.hop-thoai[open] { display: flex; flex-direction: column; }

.hop-thoai-dau {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  padding: 10px 14px;
  background: #1d4ed8;
  color: #ffffff;
  border-bottom: 1px solid #1e3a8a;
}
.hop-thoai-ten { font-weight: 700; font-size: 0.9375rem; margin: 0; }
.hop-thoai-phu-de { font-size: 0.75rem; color: #c7d7fe; }
.hop-thoai-dong {
  margin-left: auto;
  width: 28px;
  height: 28px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, .45);
  border-radius: var(--o-bo);
  background: transparent;
  color: #ffffff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.hop-thoai-dong:hover { background: rgba(255, 255, 255, .18); border-color: #fff; }
.hop-thoai-than { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 12px 16px; }
.hop-thoai-than > .luoi-cuon, .cuon { overflow: auto; }
.hop-thoai-chan {
  flex: 0 0 auto;
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 10px 14px;
  border-top: 1px solid #e3e8ef;
  background: #f8fafc;
}

/* Khi hộp thoại mở, trang nền không cuộn theo. */
body.co-hop-thoai { overflow: hidden; }

/* Phần tử được MƯỢN vào hộp thoại (GD-17) là chính khối gấp của bảng, nên nó mang theo tiêu đề
   riêng — trùng với tên đã in trên thanh đầu hộp thoại. Giấu tên trùng và cái mũi nhọn thu/mở,
   giữ lại dải số liệu (số dòng, số tiền, số trường, số trường che) vì đó mới là thứ đáng đọc.
   Và ép thân khối mở sẵn: thu nó lại khi đang ở trong hộp thoại thì hộp rỗng, vô nghĩa. */
.hop-thoai-than > .khoi-gap { border: 0; box-shadow: none; margin: 0; }
.hop-thoai-than > .khoi-gap > .khoi-gap-dau {
  background: transparent;
  border-bottom: 1px solid #e3e8ef;
  cursor: default;
  padding-left: 0;
  padding-right: 0;
}
.hop-thoai-than > .khoi-gap > .khoi-gap-dau > .khoi-gap-caret,
.hop-thoai-than > .khoi-gap > .khoi-gap-dau > .khoi-gap-ten { display: none; }
.hop-thoai-than > .khoi-gap > .khoi-gap-than { display: block; grid-template-rows: none; }
.hop-thoai-than > .khoi-gap .khoi-gap-cat { overflow: visible; }

/* =============================================================================
   9. BẢN IN
   Hộp thoại KHÔNG ra giấy (nó chỉ là lối xem nhanh), nhưng mọi bảng gốc vẫn ra
   đủ — đó là điều kiện của GD-17 và của test BanIn_BungMoiTabVaMoiKhoiGap.
   ============================================================================= */
@media print {
  dialog.hop-thoai, .hop-thoai-the, .hop-thoai-phu { display: none !important; }
  body.co-hop-thoai { overflow: visible !important; }

  .o-nhap, .o-xo, .o-van-ban, .o-tep {
    border: 1px solid #94a3b8;
    box-shadow: none;
    background: #fff;
  }
  .nut, .hang-nut { display: none !important; }

  table.luoi, table.bang { font-size: 9.5pt; }
  table.luoi > thead > tr > th, table.bang > thead > tr > th {
    position: static;
    background: #f1f3f6 !important;
    color: #000;
    border-bottom: 1px solid #94a3b8;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  table.luoi > tbody > tr:nth-child(even), table.bang > tbody > tr:nth-child(even) { background: transparent; }
  table.luoi > tbody > tr:hover, table.bang > tbody > tr:hover { background: transparent; }
  table.luoi > tbody > tr > td, table.bang > tbody > tr > td { border-bottom: 1px solid #d5dae1; }
  /* Dòng chi tiết chỉ để sửa dữ liệu, không thuộc nội dung bản in. */
  tr.dong-chi-tiet { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .o-nhap, .o-xo, .o-van-ban, .o-tep, .nut { transition: none; }
}
