/* ============================================================
   app-common.css — bổ sung CHỈ dành cho sản phẩm thật, KHÔNG có
   trong mockup gốc (app-shell.css giữ nguyên bản copy từ mockup
   để dễ đối chiếu/đồng bộ lại sau này, mọi thứ thật cần thêm thì
   để ở đây). Nạp SAU app-shell.css.
   ============================================================ */

/* Re-skin widget phân trang cũ (class/paging.class.php, incLibs/wsphpv2017/ws_paging.php)
   cho khớp tông màu app-shell — KHÔNG đổi logic phân trang, chỉ đổi giao diện.
   ".wraper-paging" = kiểu Trước/Sau đơn giản (vd Document_STP); ".pages" = kiểu đánh số trang
   đầy đủ (vd Litigant_STP, các trang khác dùng chung wsPaging::showDivPages()). */
.wraper-paging,
.pages {
   display: flex;
   align-items: center;
   justify-content: flex-end;
   gap: 8px;
   flex-wrap: wrap;
   padding: 16px 4px 4px;
   border-top: 1px solid var(--border);
   margin-top: 12px;
   font-family: var(--font-ui);
   font-size: 12.5px;
}

.wraper-paging a,
.pages a,
.pages span {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   gap: 5px;
   min-width: 30px;
   height: 30px;
   padding: 0 10px;
   border-radius: var(--radius-sm);
   color: var(--text-600);
   text-decoration: none;
   font-weight: 600;
   transition: background-color .12s, color .12s;
}

.wraper-paging a:hover,
.pages a:hover {
   background: var(--bg);
   color: var(--text-900);
}

.pages .current {
   background: var(--blue-600);
   color: #fff;
}

.pages .first-disabled,
.pages .last-disabled {
   color: var(--text-400);
   cursor: default;
}

.pages .elipses {
   color: var(--text-400);
   min-width: auto;
   padding: 0 2px;
}

/* Re-skin nút hành động server-render kiểu cũ (class/table.class.php: buttonAdd/buttonPublished...)
   khi đặt trong .head-actions của layout mới — KHÔNG sửa table.class.php (dùng chung ~20+ module)
   vì thay đổi ở đó ảnh hưởng diện rộng ngoài phạm vi các trang đã migrate. */
.head-actions .btn.btn-success,
.head-actions .btn.btn-primary {
   display: inline-flex;
   align-items: center;
   gap: 8px;
   padding: 8.5px 15px;
   border-radius: 9px;
   background: linear-gradient(135deg, var(--navy-900), var(--navy-800));
   color: #fff !important;
   font-size: 12.5px;
   font-weight: 600;
   box-shadow: var(--shadow-sm);
   border: none;
   transition: filter .15s, transform .12s;
   text-decoration: none;
}

.head-actions .btn.btn-success:hover,
.head-actions .btn.btn-primary:hover {
   filter: brightness(1.08);
   color: #fff !important;
}

.head-actions .btn.btn-success i,
.head-actions .btn.btn-primary i {
   color: var(--gold-600);
   margin-right: 2px;
}

/* Fix xung đột tên class ".modal": app-shell.css định nghĩa ".modal{display:flex}" cho hệ
   modal MỚI (luôn nằm trong ".modal-backdrop", ẩn/hiện qua ".modal-backdrop.open") — nhưng
   toàn bộ modal Bootstrap CŨ (chưa migrate, vd #login-form trong block.login.tpl load ở MỌI
   trang, và mọi form thêm/sửa còn dùng data-toggle="modal") cũng có class "modal" nên bị ép
   display:flex bất kể trạng thái ẩn/hiện thật của Bootstrap, làm modal luôn hiện đè lên trang.
   Modal Bootstrap luôn có thêm class "fade" (hệ mới không dùng class này) nên dùng nó để
   scope riêng, khôi phục đúng hành vi ẩn/hiện mặc định của Bootstrap. */
.modal.fade {
   display: none;
}

.modal.fade.in {
   display: block;
}

/* Nửa còn lại của cùng 1 xung đột tên class ở trên, theo chiều ngược lại: bootstrap.min.css có
   ".modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;overflow:hidden}" +
   ".modal{overflow-x:hidden;overflow-y:auto}" (dùng cho khung ngoài modal Bootstrap cũ — CẤU TRÚC
   HOÀN TOÀN KHÁC hệ mới: Bootstrap không có card con .modal-dialog ở đây). ".modal" mới (app-shell.css)
   không khai báo lại position/top/right/bottom/left/z-index/overflow nên các giá trị Bootstrap vẫn
   áp — card lẽ ra chỉ là 1 khối nằm YÊN giữa flex-centering của .modal-backdrop bị ép
   position:fixed;inset:0, dính chết góc trên-trái viewport, không còn được backdrop căn giữa nữa
   (đúng bug "popup nằm bên trái" người dùng chụp). Reset bằng selector 2 lớp (.modal-backdrop .modal)
   để chắc thắng specificity so với ".modal" 1 lớp của Bootstrap bất kể thứ tự nạp. */
.modal-backdrop .modal {
   position: relative;
   inset: auto;
   top: auto;
   right: auto;
   bottom: auto;
   left: auto;
   z-index: auto;
   overflow: visible;
}

/* Modal con nổi CHỒNG lên modal cha (#modalQuickCreate/#modalLitigantRep, mở qua openStackedModal()
   trong litigant-asset-modal.js — không đóng modal cha như openModal() thường làm). Lần sửa đầu
   (chỉ z-index:130, không !important) KHÔNG đủ: style.css (Inspinia cũ) có sẵn
   ".modal-backdrop{z-index:2040!important}" (và ".modal{z-index:2050!important}") — dùng
   !important nên MỌI .modal-backdrop (kể cả #modalAsset/#modalLitigant/#modalQuickCreate/
   #modalLitigantRep) đều bị ép về CÙNG 1 giá trị 2040 bất kể selector nào khác, khiến việc "ai đè
   lên ai" quay về đúng bug tie-break-theo-DOM-order ban đầu — 1 rule ID selector KHÔNG !important
   không thể thắng !important dù độ đặc hiệu cao hơn. Phải tự dùng !important + giá trị cao hơn
   2040 mới thắng được. */
#modalQuickCreate,
#modalLitigantRep {
   z-index: 2060 !important;
}

/* Khối text chỉ đọc trong modal chi tiết (vd lý do yêu cầu, ghi chú xử lý) — class có trong
   CSS riêng của một số trang mockup (vd yeu-cau-xoa-ho-so.css) nhưng không có trong app-shell.css
   dùng chung, nên thêm ở đây để tái dùng cho mọi trang cần. */
.readonly-text-block {
   padding: 10px 12px;
   background: var(--bg);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   font-size: 12.5px;
   line-height: 1.6;
   white-space: pre-wrap;
   color: var(--text-900);
}

/* Xung đột tên class ".show": Bootstrap 3 (bootstrap.min.css, vẫn nạp toàn cục cho các trang
   chưa migrate) định nghĩa sẵn ".show{display:block!important}" (dùng cho .collapse.show) —
   khớp trùng với MỌI phần tử có class "show" bất kể còn class gì khác, kể cả 3 component của
   app-shell.css dùng "show" làm trạng thái hiện (.toast/.picker-empty/.action-bar cần
   display:flex khi hiện, không phải display:block). Vì Bootstrap dùng !important, chỉ cách
   thắng là tự ép !important với specificity cao hơn (2 class vs 1 class của Bootstrap) — không
   đổi tên class "show" trong app-shell.css (giữ nguyên bản mockup) hay xoá rule Bootstrap (ảnh
   hưởng diện rộng các trang chưa migrate còn dùng component collapse thật của Bootstrap). */
.toast.show {
   display: flex !important;
}

.picker-empty.show {
   display: flex !important;
}

.action-bar.show {
   display: flex !important;
}

@media (max-width:767px) {
   .action-bar.show {
      display: flex !important;
   }
}

/* Trang "Chọn mẫu hồ sơ" (Document_STP, bước 2 của Tạo hồ sơ): tên biểu mẫu là câu tiêu đề pháp
   lý dài, khác hẳn nhãn ngắn ở bước 1 "Tạo hồ sơ" (dùng chung .picker-card/.picker-grid trên cùng
   1 file modify.tpl) — ghi đè cục bộ trong .theme-picker sang bố cục "dòng tài liệu" nằm ngang,
   theo đúng mockup gốc (assets/css/chon-mau-ho-so.css), KHÔNG sửa .picker-card gốc trong
   app-shell.css vì bước 1 vẫn cần dạng ô vuông cho nhãn ngắn. */
.theme-picker .picker-grid {
   grid-template-columns: repeat(2, 1fr);
}

@media (max-width:820px) {
   .theme-picker .picker-grid {
      grid-template-columns: 1fr;
   }
}

.theme-picker .picker-card {
   flex-direction: row;
   align-items: flex-start;
   gap: 14px;
   padding: 18px 20px;
}

.theme-picker .pc-icon {
   width: 38px;
   height: 38px;
   margin-bottom: 0;
   flex-shrink: 0;
   font-size: 15px;
}

.theme-picker .pc-content {
   min-width: 0;
   flex: 1;
}

.theme-picker .pc-tag {
   margin-bottom: 5px;
}

.theme-picker .pc-name {
   font-size: 13.5px;
   line-height: 1.4;
}

/* Trang "Tạo hồ sơ" (Document_STP, bước 1) — khối "Dùng gần đây" (lối tắt). Copy nguyên từ
   mockup assets/css/tao-ho-so.css (không có trong app-shell.css dùng chung). */
.recent-block {
   margin-bottom: 18px;
}

.recent-label {
   display: flex;
   align-items: center;
   gap: 7px;
   font-size: 11.5px;
   font-weight: 700;
   color: var(--text-600);
   text-transform: uppercase;
   letter-spacing: .04em;
   margin-bottom: 10px;
}

.recent-label i {
   color: var(--gold-600);
}

.recent-pills {
   display: flex;
   flex-wrap: wrap;
   gap: 9px;
}

.recent-pill {
   display: flex;
   align-items: center;
   gap: 8px;
   padding: 8px 14px;
   border-radius: 99px;
   background: var(--card);
   border: 1px solid var(--border);
   box-shadow: var(--shadow-sm);
   font-size: 12.5px;
   font-weight: 600;
   color: var(--text-600);
   transition: background-color .15s, color .15s, border-color .15s, transform .12s;
}

.recent-pill i {
   color: var(--blue-600);
   font-size: 12px;
}

.recent-pill:hover {
   background: var(--bg);
   color: var(--text-900);
   transform: translateY(-1px);
}

/* "Xem chi tiết hồ sơ 360°" (Document_STP, view=...): dòng thông tin dạng nhãn/giá trị dùng cho
   panel "Thông tin hồ sơ" — pattern chung, có thể tái dùng cho các trang chi tiết 360° khác sau
   này (đương sự/tài sản) khi tới lượt Giai đoạn 4. */
.detail-row {
   display: flex;
   justify-content: space-between;
   gap: 12px;
   padding: 7px 0;
   border-bottom: 1px solid var(--divider);
   font-size: 12.5px;
}

.detail-row:last-child {
   border-bottom: none;
}

/* style.css (Inspinia cũ) có sẵn ".label{background:#d1dade;color:#5e5e5e;padding:3px 8px;
   font-size:10px;font-weight:600;text-shadow:none}" (badge/pill component) — trùng tên class với
   <span class="label"> dùng trong .detail-row. Vì cùng độ đặc hiệu 1-class, thứ tự nạp không cứu
   được; phải tự reset lại toàn bộ property mà rule cũ set (không chỉ color) bằng selector 2-class
   này để thắng cascade. */
.detail-row .label {
   background: none;
   color: var(--text-400);
   font-family: inherit;
   font-size: 12.5px;
   font-weight: 400;
   padding: 0;
   text-shadow: none;
   flex-shrink: 0;
}

.detail-row .value {
   background: none;
   color: var(--text-900);
   font-family: inherit;
   font-size: 12.5px;
   font-weight: 600;
   padding: 0;
   text-shadow: none;
   text-align: right;
}

/* Giá trị + nút sửa đứng cạnh nhau (vd "Cùng với vợ là Bà X" + bút chì sửa nhanh trong card
   vợ/chồng) — trước đây .value-with-action hoàn toàn không có CSS, khiến tên và nút dính sát
   nhau không có khoảng cách. */
.value-with-action {
   display: inline-flex;
   align-items: center;
   gap: 6px;
}

.value-with-action .value {
   text-align: left;
}

.value-with-action .icon-btn {
   width: 24px;
   height: 24px;
   flex-shrink: 0;
}

/* File row (khu "Lưu trữ số hoá") — copy nguyên từ mockup xem-chi-tiet-ho-so.css, dùng chung mọi
   trang có danh sách tài liệu đính kèm. */
.file-row {
   display: flex;
   align-items: center;
   gap: 12px;
   padding: 10px 4px;
   border-bottom: 1px solid var(--divider);
}

.file-row:last-child {
   border-bottom: none;
}

.file-icon {
   width: 32px;
   height: 32px;
   border-radius: 8px;
   background: var(--bg);
   display: flex;
   align-items: center;
   justify-content: center;
   font-size: 14px;
   flex-shrink: 0;
}

.file-info {
   flex: 1;
   min-width: 0;
}

.file-name {
   font-size: 12.5px;
   font-weight: 600;
   color: var(--text-900);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}

.file-meta {
   font-size: 10.8px;
   color: var(--text-400);
   margin-top: 2px;
}

.file-actions {
   display: flex;
   gap: 4px;
   flex-shrink: 0;
}

/* Bản xem trước văn bản (chỉ đọc) — panel "Nội dung văn bản" ở trang "Xem chi tiết hồ sơ" —
   copy nguyên từ mockup xem-chi-tiet-ho-so.css, dùng với parseHtmlDocumentPreview() (KHÁC
   parseHtmlDocument()/xuất PDF, xem Document_STP/main.php). */
.doc-preview {
   max-width: 100%;
   font-size: 13px;
   line-height: 1.7;
   color: var(--text-900);
}

.doc-preview-hd {
   text-align: center;
   margin-bottom: 14px;
}

.doc-preview-title {
   text-align: center;
   font-size: 15px;
   font-weight: 700;
   margin: 0 0 16px;
   text-transform: uppercase;
}

.doc-preview-term {
   margin: 14px 0;
}

.doc-preview-signature {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 16px;
   text-align: center;
   margin-top: 28px;
   font-weight: 600;
}

.doc-preview-signature span {
   display: block;
   font-weight: 400;
   font-size: 11px;
   color: var(--text-400);
   margin-top: 56px;
}

.doc-preview-note {
   margin-top: 20px;
   padding: 10px 12px;
   background: var(--blue-50);
   border-radius: var(--radius-sm);
   color: var(--blue-700);
   font-size: 11.5px;
   display: flex;
   gap: 8px;
   align-items: flex-start;
}

/* Modal "Thêm/Sửa đương sự" + "Thêm/Sửa tài sản" (Soạn hồ sơ) — copy nguyên từ mockup
   assets/css/soan-ho-so.css (các rule liên quan tới modal, không phải toàn bộ file vì phần lớn còn
   lại là cho trang soạn chính, chưa build ở giai đoạn này). */
.litigant-type-row {
   margin-bottom: 16px;
   padding-bottom: 16px;
   border-bottom: 1px solid var(--border);
}

.litigant-type-group {
   display: none;
}

.litigant-type-group.active,
.litigant-type-group[style*="display:block"] {
   display: block;
}

.org-rep-group {
   display: none;
}

.org-rep-group.active,
.org-rep-group[style*="display:block"] {
   display: block;
}

.cccd-scan-row {
   display: flex;
   align-items: center;
   gap: 10px;
   margin-bottom: 16px;
   padding-bottom: 16px;
   border-bottom: 1px solid var(--border);
   flex-wrap: wrap;
}

.cccd-scan-row .hint {
   margin: 0;
}

.cccd-scan-row input[type="text"] {
   padding: 7px 9px;
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   background: var(--card);
   color: var(--text-900);
   font-size: 12px;
}

.id-fields-grid {
   display: grid;
   grid-template-columns: 1fr;
   gap: 12px;
}

@media (min-width:820px) {
   .id-fields-grid {
      grid-template-columns: 1fr 1fr;
   }
}

.id-fields {
   display: none;
   margin: 0;
}

.id-fields.active {
   display: block;
}

.inline-add-row {
   display: flex;
   gap: 8px;
   align-items: center;
}

.inline-add-row select {
   flex: 1;
}

.btn-add-inline {
   flex: 0 0 auto;
   padding: 8px 10px;
}

.more-detail-info {
   display: none;
}

.more-detail-info.show {
   display: block;
   margin-top: 8px;
}

.more-info-toggle {
   margin-top: 4px;
}

.conditional-fields {
   display: none;
   margin-top: 12px;
   padding-top: 12px;
   border-top: 1px dashed var(--border);
}

.conditional-fields.active {
   display: block;
}

.select2-container--default .select2-selection--multiple {
   min-height: 36px;
   border-color: var(--border);
   border-radius: var(--radius-sm);
   background: var(--card);
   padding: 2px 4px;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
   background: var(--blue-50);
   border: 1px solid var(--blue-600);
   border-radius: 999px;
   color: var(--blue-700);
   font-size: 11.5px;
   font-weight: 600;
   padding: 2px 8px;
   margin: 3px 4px 3px 0;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
   color: var(--blue-700);
   margin-right: 5px;
   border: none;
   background: transparent;
}

.select2-container--default.select2-container--focus .select2-selection--multiple {
   border-color: var(--blue-600);
   box-shadow: 0 0 0 3px var(--blue-50);
}

/* Modal "Thêm/Sửa tài sản" — copy nguyên từ mockup soan-ho-so.css */
.asset-subheading {
   margin: 18px 0 10px;
   padding-bottom: 6px;
   border-bottom: 1px solid var(--border);
   font: 600 12.5px "Be Vietnam Pro", sans-serif;
   color: var(--text-900);
   text-transform: uppercase;
   letter-spacing: .02em;
}

.asset-subheading:first-child {
   margin-top: 0;
}

/* Trang "Soạn hồ sơ" chính (Document_STP, nhánh compose {else}) — Phase 4a: khung trang + panel
   "Thông tin chung"/"Phí & giá dịch vụ" dùng markup mới hoàn toàn (copy các rule liên quan nguyên
   văn từ mockup soan-ho-so.css). Bên trong 2 panel "Đương sự"/"Tài sản" (.panel-legacy-litigants/
   .panel-legacy-assets) và các khối chưa bọc panel (điều khoản/chữ ký/lời chứng/trích yếu) VẪN GIỮ
   NGUYÊN markup Bootstrap cũ (.col-sm-*/
.row/.btn.btn-primary...) — CỐ Ý CHƯA reskin đầy đủ (để dành Phase 4b/4c/4d khi viết lại markup của các hàm PHP sinh HTML tương ứng),
chỉ thêm rule tối thiểu bên dưới để không bị lệch quá nhiều so với phần đã reskin xung quanh. Xem CLAUDE.md mục Phase 4a. */ .dossier-form {
   display: flex;
   flex-direction: column;
   gap: 16px;
   max-width: 1180px;
   margin: 0 auto;
}

.doc-national-header {
   text-align: center;
   margin-bottom: 18px;
}

.doc-national-title {
   font-weight: 700;
   font-size: 14px;
   color: var(--text-900);
   text-transform: uppercase;
}

.doc-national-subtitle {
   font-weight: 600;
   font-size: 13px;
   color: var(--text-900);
   margin-top: 2px;
}

.doc-national-rule {
   width: 64px;
   height: 0;
   margin: 10px auto 0;
   border-top: 1px dashed var(--text-400);
}

.doc-content-input {
   width: 100%;
   padding: 6px 8px;
   color: var(--text-900);
   background: transparent;
   border: 1px solid transparent;
   border-radius: var(--radius-sm);
   font-family: "Be Vietnam Pro", sans-serif;
   resize: vertical;
}

.doc-content-input:hover,
.doc-content-input:focus {
   background: var(--bg);
   border-color: var(--border);
}

.doc-content-input:focus {
   outline: none;
   box-shadow: 0 0 0 3px var(--blue-50);
   border-color: var(--blue-600);
}

/* .block-testimonial-content: input "điền chỗ trống" nằm NGAY TRONG nội dung testimonial_lock —
   là rich text admin tự soạn ở ThemesDocument_STP (Mẫu hồ sơ), không phải markup do Document_STP
   sinh ra, nên không thể đổi class/cấu trúc — chỉ mượn style .doc-content-input cho đồng bộ. */
.block-testimonial-content {
   width: auto;
   min-width: 160px;
   padding: 6px 8px;
   color: var(--text-900);
   background: transparent;
   border: 1px solid transparent;
   border-radius: var(--radius-sm);
   font-family: "Be Vietnam Pro", sans-serif;
}

.block-testimonial-content:hover,
.block-testimonial-content:focus {
   background: var(--bg);
   border-color: var(--border);
   outline: none;
}

.fee-row {
   display: grid;
   grid-template-columns: 1fr minmax(180px, 260px);
   align-items: center;
   gap: 12px;
   padding: 8px 0;
   border-bottom: 1px solid var(--border);
}

.fee-row label {
   color: var(--text-600);
   font-size: 12px;
}

.fee-input {
   width: 100%;
   padding: 8px 10px;
   text-align: right;
   color: var(--text-900);
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   font-family: var(--font-num);
}

.fee-total-row {
   border-bottom: 0;
   font-weight: 700;
}

.fee-total-row span {
   text-align: right;
   color: var(--blue-700);
   font-family: var(--font-num);
}

.insert-template-list {
   list-style: none;
   margin: 0;
   padding: 0;
   display: flex;
   flex-direction: column;
   gap: 2px;
}

.insert-template-list li.hint {
   padding: 8px 4px;
}

.insert-template-item {
   display: block;
   padding: 9px 10px;
   border-radius: var(--radius-sm);
   color: var(--text-900);
   text-decoration: none;
   font-size: 12.5px;
}

.insert-template-item:hover {
   background: var(--bg);
}

@media (max-width:1300px) {
   .dossier-form {
      max-width: 100%;
   }
}

/* Panel "Tài sản" (Phase 4c) — copy pattern thẻ .asset-item từ mockup soan-ho-so.css
   (.litigant-item,.asset-item{...}), dùng chung .record-picker/.record-picker-actions/.form-row-2
   đã có sẵn. Giữ nguyên tên class cũ (.wraper-assets-document/.item-asset-document/.role/.limit/
   .limit-input) vì JS re-index (initAsset(), addRowsAsset, removeAssetsDocument) dò theo đúng các
   class/selector này — không đổi, chỉ thêm style. */
.wraper-assets-document {
   display: flex;
   flex-direction: column;
   gap: 12px;
}

.item-asset-document {
   position: relative;
   padding: 14px;
   background: var(--bg);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
}

.item-asset-document .item-remove {
   margin: 12px 0 0 auto;
   display: block;
   color: var(--red-700);
}

.add-asset {
   margin-top: 2px;
}

/* "Lấy thông tin"/"Cập nhật lời chứng" — copy nguyên .refresh-info-row từ mockup soan-ho-so.css,
   đặt sau khi đóng section Tài sản (khớp vị trí mockup) dù vẫn nằm trong cùng .panel-body vì phần
   JS/nội dung xen giữa (script tương tác tài sản + khối titleContentDocument không liên quan) chưa
   tách được an toàn — xem CLAUDE.md. */
.refresh-info-row {
   display: flex;
   align-items: center;
   justify-content: center;
   gap: 12px;
   padding: 12px;
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   margin-top: 16px;
}

.refresh-info-row .hint {
   max-width: 680px;
   margin: 0;
   font-size: 11px;
   color: var(--text-400);
}

@media (max-width:640px) {
   .refresh-info-row {
      align-items: stretch;
      flex-direction: column;
   }
}

/* Nhóm đối tượng đương sự (Phase 4b-1) — mỗi `.wraper-litigant-document` là 1 party-panel độc lập
   (không còn bọc trong 1 panel "Đương sự" chung — đã bỏ hẳn section bọc ngoài để khớp đúng cấu trúc
   mockup: mỗi nhóm party-panel riêng, không phải panel cha chứa nhiều panel con). Markup
   `.wraper-litigant-document`/`.litigant-item-document`/`.groupname`/`.signature`/`.text-note-litigant`
   giữ nguyên tên class để JS renumbering (initLitigant/addRowsLitigant/createGroupLitigant) không
   cần sửa — xem CLAUDE.md. */
.container-group-litigant {
   display: flex;
   flex-direction: column;
   gap: 16px;
   margin-bottom: 16px;
   float: none;
   width: auto;
}

.wraper-litigant-document {
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius);
   box-shadow: var(--shadow-sm);
   overflow: hidden;
   float: none;
}

.litigant-group-head {
   display: flex;
   align-items: flex-start;
   justify-content: space-between;
   gap: 12px;
   padding: 16px 20px;
   border-bottom: 1px solid var(--border);
}

.litigant-group-head .section-heading {
   display: flex;
   align-items: baseline;
   flex-wrap: wrap;
   gap: 6px;
   row-gap: 4px;
   flex: 1;
   min-width: 0;
}

.section-numeral {
   font-weight: 700;
   color: var(--text-900);
   font-size: 15px;
   flex-shrink: 0;
}

.vsis-ml {
   font-weight: 700;
   color: var(--text-900);
}

/* style.css có sẵn "input.wraper-input-litigant{border:#009441; margin-left:-33px; padding-left:35px;
   min-width:300px;}" (specificity tag+class, cao hơn 1 class thường) — phải dùng selector 2 lớp để
   thắng đúng specificity, không thì viền xanh lá + margin âm cũ đè lên giao diện mới. */
.section-heading .wraper-input-litigant {
   font-weight: 700;
   font-size: 15px;
   flex: 1;
   min-width: 160px;
   border: 1px solid transparent;
   background: transparent;
   padding: 2px 4px;
   margin: 0;
   border-radius: var(--radius-sm);
}

.section-heading .wraper-input-litigant:hover,
.section-heading .wraper-input-litigant:focus {
   background: var(--bg);
   border-color: var(--border);
   outline: none;
}

/* style.css (monolith cũ) có sẵn "chiêu" label đè lên input bằng position:absolute cho
   .lb-first-acr/.lb-last-acr (input.groupname xưa phải chừa padding-left:110px để lộ input ra sau
   label) — layout flex mới không cần chiêu này nữa, phải ép về static/normal flow, nếu không label
   cũ sẽ đè lên che mất input mới (không thấy, không bấm được). */
.group-acr-group {
   color: var(--text-600);
   font-size: 13px;
   font-weight: 500;
   display: inline-flex;
   align-items: baseline;
   gap: 4px;
   flex-wrap: wrap;
   position: static;
}

.group-acr-group .lb-first-acr,
.group-acr-group .lb-last-acr {
   position: static;
   width: auto;
   height: auto;
   margin: 0;
   padding: 0;
   background: none;
   border-radius: 0;
}

.group-acr-group .groupname {
   display: inline-block;
   width: auto;
   min-width: 70px;
   font-weight: 600;
   border: 1px solid transparent;
   background: transparent;
   padding: 2px 4px;
   border-radius: var(--radius-sm);
   margin: 0;
}

.group-acr-group .groupname:hover,
.group-acr-group .groupname:focus {
   background: var(--bg);
   border-color: var(--border);
   outline: none;
}

.litigant-group-head .closed-group {
   flex-shrink: 0;
}

.litigant-group-head .closed-group:hover {
   color: var(--red-700);
}

.record-picker .title-gender {
   float: none;
}

.litigant-items {
   display: flex;
   flex-direction: column;
   gap: 12px;
   padding: 16px 20px;
}

.wraper-litigant-document .add-litigant {
   margin: 0 20px 16px;
}

.litigant-item-document {
   position: relative;
   padding: 14px;
   background: var(--bg);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
}

.record-picker {
   display: grid;
   grid-template-columns: minmax(240px, 1fr) auto;
   gap: 8px;
   align-items: end;
}

.record-picker .form-field {
   margin: 0;
}

.record-picker-actions {
   display: flex;
   gap: 6px;
   flex-shrink: 0;
}

/* Select2 tự tính width bằng px inline dựa trên outerWidth() của <select> gốc lúc init — nếu tính
   sai (vd do đo lúc phần tử vừa clone/chưa layout ổn định) sẽ tràn ra ngoài cột grid, đè lên
   .record-picker-actions bên cạnh (đúng bug người dùng chụp màn hình: nút sửa nằm đè trong select).
   Ép max-width:100% theo đúng khổ cột grid, không phụ thuộc giá trị px Select2 tự tính. */
.record-picker .select2-container {
   max-width: 100%;
}

.form-row-3070 {
   display: grid;
   grid-template-columns: 3fr 7fr;
   gap: 12px;
}

@media (max-width:640px) {
   .form-row-3070 {
      grid-template-columns: 1fr;
   }
}

/* Hiển thị giá trị chỉ đọc (vd năm sinh) dưới dạng thẻ <p> nhưng có cùng kích thước/viền/bo góc
   với <input> thật trong .form-field — khác .detail-row (dòng nhãn:giá trị phẳng, không viền) vì
   ở đây cần đứng chung 1 hàng với các field nhập liệu khác nên phải trông giống input. Cố ý KHÔNG
   dùng input[readonly] (nền xám #eeeeee mặc định của .form-field) vì đây không phải field đang bị
   khoá sửa, mà là dữ liệu gốc không có cơ chế ghi đè theo từng hồ sơ — nền trắng như input thường. */
.field-display {
   margin: 0;
   width: 100%;
   box-sizing: border-box;
   padding: 9px 11px;
   border: 1px solid var(--border);
   border-radius: 9px;
   font-family: var(--font-ui);
   font-size: 12.8px;
   line-height: 1.4;
   color: var(--text-900);
   background: var(--card);
}

.check-couple:empty {
   display: none;
}

/* style.css cũ có .check-couple{float:left;margin-left:10px;} (dùng cho layout Bootstrap cũ) —
   khiến khối "Cùng vợ/chồng" nổi lên cạnh label giới tính thay vì xuống hàng riêng, đè lên
   .group-info-litigant bên dưới. Ép về block bình thường, đúng vị trí đã thiết kế (giữa
   .record-picker và .group-info-litigant). */
.check-couple {
   float: none;
   margin-left: 0;
   clear: both;
   margin-top: 8px;
   margin-bottom: 4px;
}

.check-couple .checkbox-wrap {
   display: inline-flex;
}

/* Ẩn phần thông tin chi tiết (đã chọn) + ghi chú cho tới khi thật sự chọn 1 đương sự — khớp hành vi
   .litigant-detail{display:none}.show{display:block} của mockup. `.has-litigant` do JS toggle ở
   handler change của select[data-func="cboxLitigant"] (xem modify.tpl). */
.litigant-item-document .group-info-litigant,
.litigant-item-document .litigant-note-field {
   display: none;
}

.litigant-item-document.has-litigant .group-info-litigant,
.litigant-item-document.has-litigant .litigant-note-field {
   display: block;
}

.group-info-litigant {
   margin-top: 10px;
}

.group-info-litigant:empty {
   display: none;
}

.text-note-litigant {
   width: 100%;
   min-height: 56px;
   padding: 8px 10px;
   color: var(--text-900);
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   font: 400 12.5px "Be Vietnam Pro", sans-serif;
   resize: vertical;
}

.text-note-litigant:focus {
   outline: none;
   border-color: var(--blue-600);
   box-shadow: 0 0 0 3px var(--blue-50);
}

.litigant-item-document .item-remove {
   margin: 10px 0 0 auto;
   display: block;
   color: var(--red-700);
}

.add-group-row {
   display: flex;
   justify-content: center;
   padding: 2px 0;
   float: none;
   width: auto;
   position: static;
   clear: both;
}

.add-group-row .btn-add-group {
   display: inline-flex;
   align-items: center;
   gap: 8px;
   padding: 8.5px 15px;
   border-radius: 9px;
   background: var(--card);
   border: 1px solid var(--border);
   color: var(--text-900);
   font: 600 12.5px "Be Vietnam Pro", sans-serif;
   text-decoration: none;
   box-shadow: var(--shadow-sm);
   transition: background-color .15s;
   float: none;
   margin: 0;
   position: static;
}

.add-group-row .btn-add-group:hover {
   background: var(--bg);
}

@media (max-width:640px) {
   .record-picker {
      grid-template-columns: 1fr;
   }
}

.wraper-term {
   margin-top: 16px;
   padding: 16px;
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius);
   box-shadow: var(--shadow-sm);
}

.panel-title-asset {
   display: block;
   margin-bottom: 10px;
   font: 600 13px "Be Vietnam Pro", sans-serif;
   color: var(--text-900);
}

/* .wraper-term dùng chung với ThemesDocument_STP (chưa reskin, vẫn cần padding/border/shadow ở
   trên) — khi đứng cùng .panel (Document_STP, đã có panel-head/panel-body lo phần khung) thì reset
   hẳn để tránh cộng dồn padding/border 2 lớp, đúng bài học "selector 2 lớp mới thắng specificity"
   đã áp dụng nhiều lần trong dự án. */
.panel.wraper-term {
   margin-top: 0;
   padding: 0;
}

/* .wraper-signature/.wraper-testimonial/.wraper-content-abstract CHỈ còn dùng ở Document_STP (đã
   luôn bọc trong .panel, không còn nơi nào dùng trần) — nên reset thẳng, không cần giữ bản 1-class
   "blend tối thiểu" như .wraper-term. style.css cũ có sẵn float:left/width:100% (đẩy khối ra khỏi
   luồng block bình thường) + .wraper-testimonial{color:black} (ép đen toàn bộ chữ bên trong, kể cả
   input/select mới) + .wraper-content-abstract{border:1px solid #019442;padding;margin} (viền xanh
   lá + khung riêng, cộng dồn với .panel) — phải reset đủ cả 3 chỗ, không chỉ margin/padding như
   .wraper-term (vì đây là rule 1-class, không phải rule "tag.class" nên không cần lo phần specificity
   giống các vụ trước, chỉ cần liệt kê đủ property đang bị rò rỉ). */
.panel.wraper-signature,
.panel.wraper-testimonial,
.panel.wraper-content-abstract {
   margin-top: 0;
   padding: 0;
   float: none;
   width: auto;
   position: static;
   color: inherit;
}

.signature-list {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
   gap: 16px;
}

.signature-item {
   position: relative;
   padding: 14px;
   text-align: center;
   border: 1px dashed var(--border);
   border-radius: var(--radius-sm);
   float: none;
   width: auto;
}

.signature-name {
   font-weight: 700;
   color: var(--text-900);
}

.signature-hint {
   margin-top: 40px;
   color: var(--text-400);
   font-size: 11.5px;
}

.signature-item .remove-signature {
   position: absolute;
   top: 6px;
   right: 6px;
}

.testimonial-statement {
   padding: 9px 0;
   font-size: 12.8px;
   color: var(--text-700);
   display: flex;
   align-items: center;
   gap: 6px;
   flex-wrap: wrap;
}

.inline-select {
   display: inline-block;
   vertical-align: middle;
   width: auto;
   min-width: 170px;
   margin: 0 5px;
   padding: 7px 9px;
   color: var(--text-900);
   background: var(--card);
   border: 0;
   border-bottom: 1px solid var(--blue-600);
   border-radius: 0;
   font: 500 13px "Be Vietnam Pro", sans-serif;
}

.testimonial-title {
   margin: 6px 0 10px;
   font-weight: 700;
   color: var(--text-900);
   text-align: center;
   letter-spacing: .02em;
}

.testimonial-litigant-list {
   margin-bottom: 10px;
}

.abstract-summary {
   padding: 12px;
   margin-bottom: 12px;
   background: var(--bg);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   font-size: 12.8px;
   color: var(--text-700);
   line-height: 1.6;
   display: inline-block;
}

.export-options,
.margin-row {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   gap: 14px;
   margin-bottom: 14px;
}

.margin-row {
   grid-template-columns: repeat(4, 1fr);
   margin-bottom: 0;
}

@media (max-width:640px) {

   .export-options,
   .margin-row,
   .signature-list {
      grid-template-columns: 1fr;
   }
}

/* Nội dung hợp đồng (điều khoản) — khớp .clause-* của mockup soan-ho-so. .term-item/.term-brief
   giữ lại làm hook JS (initTerm/addKeyCK) nên phải tự reset float/width kế thừa từ style.css cũ. */
.clause-intro {
   display: flex;
   align-items: baseline;
   gap: 8px;
   margin-bottom: 14px;
}

.clause-intro .section-numeral {
   flex-shrink: 0;
   color: var(--text-900);
   font-weight: 700;
}

.clause-intro-input {
   flex: 1;
   min-width: 0;
}

.clause-list {
   display: flex;
   flex-direction: column;
   gap: 12px;
}

.clause-block.term-item {
   float: none;
   width: auto;
   margin-bottom: 0;
   padding: 14px;
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   background: var(--card);
}

.clause-head {
   display: flex;
   align-items: center;
   gap: 10px;
   margin-bottom: 8px;
}

.clause-number.term-number {
   flex-shrink: 0;
   color: var(--text-900);
   font-weight: 700;
   font-size: 12.5px;
   text-transform: none;
   text-align: left;
   width: auto;
}

.clause-title-input {
   flex: 1;
   padding: 7px 9px;
   color: var(--text-900);
   background: var(--bg);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   font: 500 12.5px "Be Vietnam Pro", sans-serif;
}

.clause-title-input:focus {
   outline: none;
   border-color: var(--blue-600);
   box-shadow: 0 0 0 3px var(--blue-50);
}

.clause-block .term-brief {
   float: none;
   width: auto;
}

.cke {
   border-radius: var(--radius-sm) !important;
   overflow: hidden;
}

@media (max-width:640px) {
   .clause-block.term-item {
      padding: 11px;
   }

   .clause-head {
      align-items: flex-start;
      flex-wrap: wrap;
   }

   .clause-title-input {
      flex-basis: calc(100% - 92px);
   }
}

/* Nội dung lời chứng (parseDataLitigantDocument) — khớp .testimonial-* của mockup soan-ho-so,
   không dùng wrapper .testimonial-group (tránh phải mở/đóng div theo state qua nhiều vòng lặp
   PHP) nên .testimonial-group-title đứng rời, mỗi đương sự vẫn tự đóng gói trong .testimonial-person. */
.testimonial-group-title {
   font-weight: 700;
   color: var(--text-900);
   font-size: 12.5px;
   margin: 14px 0 8px;
}

.testimonial-group-title:first-child {
   margin-top: 0;
}

.testimonial-person {
   padding: 10px 0 14px;
   border-bottom: 1px solid var(--divider);
}

.testimonial-row {
   display: flex;
   align-items: baseline;
   gap: 8px;
   padding: 3px 0;
   font-size: 12.5px;
}

.testimonial-label {
   flex: 0 0 220px;
   color: var(--text-600);
   font-weight: 600;
}

.testimonial-colon {
   flex-shrink: 0;
   color: var(--text-400);
}

.testimonial-value {
   flex: 1;
   color: var(--text-900);
}

.testimonial-note-input {
   width: 100%;
   margin-top: 8px;
   padding: 8px 10px;
   color: var(--text-900);
   background: var(--bg);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   font: 400 12.5px "Be Vietnam Pro", sans-serif;
   resize: vertical;
}

.testimonial-note-input:focus {
   outline: none;
   border-color: var(--blue-600);
   box-shadow: 0 0 0 3px var(--blue-50);
}

@media (max-width:640px) {
   .testimonial-row {
      flex-direction: column;
      gap: 2px;
   }

   .testimonial-label {
      flex-basis: auto;
   }
}

/* Thẻ xem nhanh thông tin tài sản đã chọn (.asset-detail), khớp mockup soan-ho-so — populate qua
   AJAX task_loadAssetInfoDocument khi chọn/đã có sẵn tài sản (refreshAssetDetail() trong modify.tpl). */
.asset-detail {
   display: none;
}

.asset-detail.show {
   display: block;
}

.autofill-info {
   display: grid;
   grid-template-columns: repeat(3, minmax(0, 1fr));
   gap: 10px;
   margin-top: 12px;
   padding: 11px 12px;
   background: var(--bg);
   color: var(--text-600);
   border-radius: var(--radius-sm);
}

.autofill-info.empty {
   display: block;
   color: var(--text-400);
}

.autofill-field span {
   display: block;
   margin-bottom: 3px;
   font-size: 10px;
   font-weight: 700;
   text-transform: uppercase;
   letter-spacing: .04em;
}

.autofill-field strong {
   font-weight: 500;
}

.autofill-field .num {
   font-family: "IBM Plex Mono", monospace;
}

.asset-type-line {
   margin-top: 10px;
   color: var(--text-600);
}

@media (max-width:1024px) {
   .autofill-info {
      grid-template-columns: repeat(2, minmax(0, 1fr));
   }
}

@media (max-width:640px) {
   .autofill-info {
      grid-template-columns: 1fr;
   }
}

/* "Danh mục khoản thu / khoản chi" (ExpenseCategory_STP) — copy nguyên từ mockup
   danh-muc-khoan-thu-chi.css (chỉ phần còn cần dùng, bảng dùng <table> trần theo convention chung
   nên không cần .fee-category-table). */
.category-rbac-hint {
   display: block;
   margin: -12px 0 18px;
}

.formula-field.is-disabled {
   opacity: .65;
}

#modalFeeCategory .modal {
   max-width: 560px;
}

/* "Công thức tính phí" (FeeFormula_STP, trang chi tiết) — copy nguyên phần còn cần dùng từ mockup
   cong-thuc-tinh-phi.css (bảng bậc thang + kết quả "Thử tính phí"). */
.tier-table {
   min-width: 900px;
}

.tier-input,
.tier-select {
   width: 100%;
   height: 38px;
   padding: 8px 10px;
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   background: var(--card);
   color: var(--text-900);
   font: 500 12px var(--font-num);
}

.tier-select {
   font-family: var(--font-ui);
}

.tier-input:focus,
.tier-select:focus {
   outline: none;
   border-color: var(--blue-600);
   box-shadow: 0 0 0 3px var(--blue-50);
}

.tier-input-percent {
   font-family: var(--font-num);
}

.calculator-result {
   margin-top: 16px;
   padding: 18px;
   border: 1px solid var(--border);
   border-radius: var(--radius);
   background: var(--bg);
}

.calculator-amount {
   color: var(--blue-700);
   font: 700 23px var(--font-num);
}

/* Receipt_STP ("Phiếu thu") — copy/adapt từ mockup phieu-thu.css + chi-tiet-phieu-thu.css */
.dossier-search-panel {
   display: none;
   overflow: visible;
   z-index: 4;
   margin-bottom: 16px;
}

.dossier-search-panel.open {
   display: block;
}

.dossier-search-panel .panel-body {
   position: relative;
}

.dossier-search-row {
   display: flex;
   gap: 8px;
   align-items: center;
   max-width: 760px;
}

.dossier-search-row .search-box {
   position: relative;
   display: flex;
   flex: 1;
   max-width: none;
}

.dossier-search-row .search-box input {
   width: 100%;
}

.dossier-results {
   position: absolute;
   left: 20px;
   right: 20px;
   top: calc(100% - 12px);
   max-width: 740px;
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius-sm, 8px);
   box-shadow: var(--shadow-lg, 0 12px 32px rgba(0, 0, 0, .16));
   max-height: 300px;
   overflow: auto;
   z-index: 20;
}

.dossier-result {
   display: flex;
   width: 100%;
   gap: 12px;
   align-items: center;
   padding: 11px 14px;
   border: 0;
   border-bottom: 1px solid var(--border);
   background: transparent;
   text-align: left;
   color: var(--text-900);
   cursor: pointer;
}

.dossier-result:last-child {
   border-bottom: 0;
}

.dossier-result:hover,
.dossier-result:focus {
   background: var(--blue-50);
   outline: none;
}

.dossier-result.is-locked {
   opacity: .55;
   cursor: not-allowed;
}

.dossier-result-icon {
   width: 34px;
   height: 34px;
   border-radius: 8px;
   background: var(--blue-50);
   color: var(--blue-600);
   display: flex;
   align-items: center;
   justify-content: center;
   flex: none;
}

.dossier-result-main {
   min-width: 0;
}

.dossier-result-name {
   display: block;
   font-weight: 600;
   font-size: 12.5px;
}

.dossier-result-meta {
   display: block;
   color: var(--text-400);
   font-size: 11px;
   margin-top: 3px;
}

.receipt-code {
   font-family: 'IBM Plex Mono', monospace;
   font-weight: 600;
   color: var(--blue-700);
   white-space: nowrap;
}

.receipt-toolbar {
   margin-bottom: 14px;
}

.receipt-toolbar .filter-field {
   min-width: 180px;
}

.receipt-toolbar .filter-field.grow {
   min-width: 250px;
}

.receipt-type {
   font-size: 12px;
   color: var(--text-600);
}

.receipt-table th:last-child,
.receipt-table td:last-child {
   white-space: nowrap;
}

.receipt-status-line {
   display: flex;
   align-items: center;
   gap: 10px;
   margin: 0 0 16px;
}

.receipt-status-line .badge {
   font-size: 12px;
   padding: 6px 11px;
}

.receipt-meta-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 16px;
}

.readonly-value {
   min-height: 38px;
   padding: 9px 11px;
   border: 1px solid var(--border);
   border-radius: var(--radius-sm, 8px);
   background: var(--bg);
   font-size: 12.5px;
}

.receipt-items-table {
   min-width: 980px;
}

.receipt-items-table select,
.receipt-items-table input {
   width: 100%;
   min-width: 110px;
   padding: 9px 11px;
   border: 1px solid var(--border);
   border-radius: 9px;
   font-family: var(--font-ui);
   font-size: 12.8px;
   color: var(--text-900);
   background: var(--card);
   transition: border-color .15s, box-shadow .15s;
}

.receipt-items-table select:focus,
.receipt-items-table input:focus {
   outline: none;
   border-color: var(--blue-600);
   box-shadow: 0 0 0 3px var(--blue-50);
}

.receipt-items-table .item-name {
   min-width: 190px;
}

.money-input {
   text-align: right;
   font-family: var(--font-num);
}

.receipt-items-table .money-input {
   min-width: 130px;
}

.receipt-items-table .note-input {
   min-width: 150px;
}

.receipt-items-table tfoot td {
   font-weight: 700;
   background: var(--bg);
}

.receipt-items-table .total-value {
   text-align: right;
   font-family: 'IBM Plex Mono', monospace;
   color: var(--blue-700);
   font-size: 14px;
}

.receipt-items-table .remove-item {
   width: 34px;
   height: 34px;
}

.item-actions {
   margin-top: 12px;
   display: flex;
   align-items: center;
   gap: 12px;
   flex-wrap: wrap;
}

.locked-hint {
   display: none;
   color: var(--amber-600);
   font-size: 11.5px;
}

.locked .locked-hint {
   display: block;
}

.attachment-box {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 16px;
   padding: 14px;
   border: 1px dashed var(--border);
   border-radius: var(--radius-sm, 8px);
   color: var(--text-600);
}

.attachment-list {
   margin-top: 10px;
   display: flex;
   flex-direction: column;
   gap: 8px;
}

.attachment-item {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   padding: 8px 12px;
   border: 1px solid var(--border);
   border-radius: 8px;
   font-size: 12.5px;
}

.attachment-item .attachment-meta {
   color: var(--text-400);
   font-size: 11px;
}

.form-actions-sticky {
   position: sticky;
   bottom: 0;
   z-index: 6;
   display: flex;
   justify-content: flex-end;
   gap: 8px;
   padding: 12px 0;
   background: linear-gradient(transparent, var(--bg) 24%);
}

.error-state {
   padding: 48px 20px;
   text-align: center;
}

.history-table td {
   vertical-align: top;
}

.adjustment-wrap {
   margin-top: 14px;
}

.adjustment-wrap textarea {
   width: 100%;
   min-height: 76px;
}

.field-hint {
   font-size: 11px;
   color: var(--text-400);
   margin-top: 5px;
}

.required-mark {
   color: var(--red-700);
}

/* Nhiều .checkbox-wrap xếp dọc trong cùng 1 .form-field (vd Permission_STP/modify.tpl) */
.form-field .checkbox-wrap+.checkbox-wrap {
   margin-top: 8px;
}

@media (max-width: 640px) {
   .dossier-search-row {
      align-items: stretch;
      flex-direction: column;
   }

   .dossier-results {
      left: 12px;
      right: 12px;
      top: calc(100% - 8px);
   }

   .receipt-toolbar .filter-field,
   .receipt-toolbar .filter-field.grow {
      min-width: 100%;
   }
}

/* Expense_STP ("Phiếu chi") — copy/adapt từ mockup phieu-chi.css + chi-tiet-phieu-chi.css */
.voucher-toolbar {
   margin-bottom: 14px;
}

.voucher-toolbar .filter-field {
   min-width: 190px;
}

.voucher-toolbar .filter-field.grow {
   min-width: 250px;
}

.voucher-code {
   font-family: 'IBM Plex Mono', monospace;
   font-weight: 600;
   color: var(--blue-700);
   white-space: nowrap;
}

.voucher-table {
   min-width: 1080px;
}

.voucher-table .description-cell {
   max-width: 280px;
}

.voucher-table th:last-child,
.voucher-table td:last-child {
   white-space: nowrap;
}

.voucher-status-line {
   display: flex;
   align-items: center;
   gap: 10px;
   margin: 0 0 16px;
   flex-wrap: wrap;
}

.voucher-status-line .badge {
   font-size: 12px;
   padding: 6px 11px;
}

.rejection-reason {
   color: var(--red-700);
   font-size: 12px;
}

.approval-limit .alert-item {
   margin: 0;
}

.approval-limit.over .alert-item {
   border: 1px solid var(--amber-600);
   background: var(--amber-100);
}

.approval-limit.over .alert-icon {
   color: var(--amber-600);
   background: var(--amber-100);
}

.attachment-state {
   display: flex;
   align-items: center;
   gap: 10px;
}

.attachment-state.available {
   color: var(--green-700);
}

.attachment-warning {
   color: var(--amber-600);
}

.attachment-warning .hint {
   color: var(--amber-600);
   font-size: 12px;
}

@media (max-width: 640px) {

   .voucher-toolbar .filter-field,
   .voucher-toolbar .filter-field.grow {
      min-width: 100%;
   }
}

/* ExpenseLimit_STP ("Hạn mức duyệt phiếu chi") — copy/adapt từ mockup han-muc-duyet-phieu-chi.css */
.approval-limit-page-hint {
   display: block;
   margin: -10px 0 16px;
}

.approval-limit-form {
   max-width: 640px;
}

.approval-limit-form .money-input {
   max-width: 280px;
   font-family: var(--font-num);
   text-align: right;
}

.approval-limit-previews {
   margin: 4px 0 20px;
}

.approval-limit-previews>div+div {
   margin-top: 10px;
}

.approval-limit-actions {
   display: flex;
   justify-content: flex-end;
   margin-top: 20px;
}

.approval-limit-history-table td:first-child,
.approval-limit-history-table td:nth-child(3),
.approval-limit-history-table td:nth-child(4) {
   font-family: var(--font-num);
}

@media (max-width: 640px) {
   .approval-limit-form .money-input {
      max-width: none;
   }

   .approval-limit-actions .btn-primary {
      width: 100%;
      justify-content: center;
   }
}

/* PreventAsset_STP / PreventSubject_STP ("Ngăn chặn tài sản"/"Ngăn chặn đương sự") — copy/adapt
   từ mockup ngan-chan-tai-san.css + ngan-chan-duong-su.css */
.list-panel {
   overflow: hidden;
}

.list-panel table {
   min-width: 1080px;
}

.list-panel td {
   vertical-align: top;
}

.doc-sub {
   display: block;
   margin-top: 3px;
   font-size: 11px;
   color: var(--text-400);
}

#assetDetailContent,
#subjectDetailContent {
   margin-bottom: 0;
}

#assetDetailContent dd,
#subjectDetailContent dd {
   overflow-wrap: anywhere;
}

.create-record-form .type-fields {
   display: none;
}

.create-record-form .type-fields.active {
   display: block;
}

.source-file-row {
   display: flex;
   align-items: center;
   gap: 12px;
   flex-wrap: wrap;
}

@media (max-width: 640px) {

   #assetDetailContent,
   #subjectDetailContent {
      grid-template-columns: 1fr;
      gap: 3px;
   }

   #assetDetailContent dd,
   #subjectDetailContent dd {
      margin-bottom: 9px;
   }
}

/* PreventLookup_STP ("Tra cứu nhanh ngăn chặn") — copy/adapt từ mockup ngan-chan-tra-cuu.css */
.ngan-chan-search {
   display: flex;
   gap: 10px;
   align-items: stretch;
}

.ngan-chan-search input {
   flex: 1;
   padding-right: 16px;
}

.ngan-chan-search>.fa {
   top: 22px;
}

.ngan-chan-search .btn-primary {
   flex: none;
   justify-content: center;
}

.ngan-chan-results {
   display: grid;
   gap: 16px;
}

.result-section {
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius);
   box-shadow: var(--shadow-sm);
   overflow: hidden;
}

.result-section-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   padding: 15px 18px;
   border-bottom: 1px solid var(--divider);
}

.result-section-head h2 {
   font-size: 14px;
}

.result-section-head .result-count {
   font-size: 11px;
   color: var(--text-400);
}

.result-section-body {
   display: grid;
   gap: 12px;
   padding: 16px 18px 18px;
}

.section-empty {
   display: flex;
   align-items: center;
   gap: 8px;
   padding: 14px;
   border: 1px dashed var(--border);
   border-radius: var(--radius-sm);
   color: var(--text-400);
}

.block-alert-card-link {
   display: block;
   color: inherit;
   text-decoration: none;
}

.block-alert-card {
   padding: 15px;
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   background: var(--card);
   transition: border-color .15s;
}

.block-alert-card-link:hover .block-alert-card {
   border-color: var(--blue-600);
}

.block-alert-card.danger {
   border-color: var(--red-700);
   background: var(--red-100);
}

.block-alert-card-link:hover .block-alert-card.danger {
   border-color: var(--red-700);
}

.block-alert-head {
   display: flex;
   align-items: center;
   gap: 8px;
   flex-wrap: wrap;
   margin-bottom: 10px;
}

.block-alert-code {
   font-family: var(--font-num);
   font-size: 12px;
   font-weight: 700;
   color: var(--text-900);
}

.block-alert-title {
   font-size: 14px;
   font-weight: 700;
   margin-bottom: 6px;
   color: var(--text-900);
}

.block-alert-reason {
   color: var(--text-600);
   margin-bottom: 10px;
}

.block-alert-meta {
   display: grid;
   grid-template-columns: repeat(2, minmax(0, 1fr));
   gap: 6px 18px;
   font-size: 11.5px;
   color: var(--text-600);
}

.block-alert-meta strong {
   color: var(--text-900);
   font-weight: 600;
}

.live-loading {
   display: flex;
   align-items: center;
   gap: 8px;
   padding: 16px;
   color: var(--text-600);
}

@media (max-width: 820px) {
   .block-alert-meta {
      grid-template-columns: 1fr;
   }
}

@media (max-width: 640px) {
   .ngan-chan-search {
      align-items: stretch;
      flex-direction: column;
   }

   .ngan-chan-search>.fa {
      top: 22px;
   }

   .ngan-chan-search .btn-primary {
      width: 100%;
   }
}

/* PreventSync_STP ("Đồng bộ dữ liệu liên thông") — copy/adapt từ mockup ngan-chan-dong-bo.css */
.sync-panel {
   margin-bottom: 18px;
}

.sync-panel .panel-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 16px;
}

.sync-panel .panel-head h2 {
   margin: 0;
   color: var(--text-900);
   font-size: 15px;
}

.sync-panel .panel-head p {
   margin: 4px 0 0;
   color: var(--text-600);
   font-size: 12.5px;
}

/* CHỈ áp dụng layout dạng lưới thẻ card khi .radio-group chứa .radio-option (PreventSync_STP/
   Configs_STP/Correspondence_STP) — không được để rule này áp cho .radio-group kiểu đơn giản
   (label+chấm tròn .radio-wrap, dùng ở rất nhiều nơi: modal đương sự, PaymentMethod_STP,
   ExpenseCategory_STP...), nếu không sẽ đè mất layout flex gốc của app-shell.css (bug thật đã xảy
   ra: 1 rule .radio-group{display:grid...} không scope làm vỡ layout "Ngày sinh" trong modal Thêm
   đương sự — phát hiện qua screenshot người dùng gửi). auto-fit thay vì cứng 4 cột để 2-3 lựa
   chọn (Configs_STP/Correspondence_STP) không bị kéo dãn thành 4 cột rỗng. */
.radio-group:has(.radio-option) {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
   gap: 10px;
}

.radio-option {
   display: flex;
   align-items: center;
   gap: 9px;
   min-height: 44px;
   padding: 10px 12px;
   border: 1px solid var(--border);
   border-radius: var(--radius-sm);
   background: var(--card);
   cursor: pointer;
   font-weight: 600;
   font-size: 13px;
}

.radio-option:has(input:checked) {
   border-color: var(--blue-600);
   background: var(--blue-50);
}

.radio-option input {
   accent-color: var(--blue-600);
}

.source-warning {
   margin: 14px 0;
   max-width: 980px;
   line-height: 1.6;
}

.source-warning i {
   margin-right: 5px;
   color: var(--blue-600);
}

.source-warning-danger {
   color: var(--red-700);
}

.source-warning-danger i {
   color: var(--red-700);
}

.connection-table,
.sync-log-table {
   width: 100%;
   border-collapse: collapse;
   min-width: 920px;
}

.sync-log-table {
   min-width: 1220px;
}

.connection-table th,
.connection-table td,
.sync-log-table th,
.sync-log-table td {
   padding: 12px 14px;
   border-bottom: 1px solid var(--divider);
   text-align: left;
   vertical-align: top;
   font-size: 12.5px;
}

.connection-table th,
.sync-log-table th {
   color: var(--text-600);
   font-size: 11px;
   text-transform: uppercase;
   white-space: nowrap;
}

.source-name {
   font-weight: 600;
   color: var(--text-900);
}

.data-code,
.sync-time,
.record-count {
   font-family: var(--font-num);
}

.sync-time span {
   display: block;
   white-space: nowrap;
}

.error-detail {
   max-width: 260px;
   color: var(--text-600);
}

.sync-log-head {
   align-items: center;
}

.auth-type {
   margin-bottom: 7px;
   color: var(--text-600);
   font-size: 12px;
}

.api-config-modal {
   max-width: 680px;
}

.api-config-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 16px;
}

.api-config-grid .full {
   grid-column: 1 / -1;
}

.input-with-unit {
   display: flex;
   align-items: center;
   gap: 8px;
}

.input-with-unit input {
   flex: 1;
}

.input-with-unit span {
   color: var(--text-600);
   font-size: 12px;
}

#btnRunSyncNow[disabled] {
   opacity: .6;
   cursor: wait;
}

@media (max-width: 820px) {
   .radio-group {
      grid-template-columns: repeat(2, minmax(0, 1fr));
   }

   .sync-log-head {
      align-items: flex-start;
      flex-direction: column;
   }
}

@media (max-width: 640px) {

   .radio-group,
   .api-config-grid {
      grid-template-columns: 1fr;
   }

   .api-config-grid .full {
      grid-column: auto;
   }
}

/* PreventReport_STP ("Báo cáo & thống kê ngăn chặn") — copy/adapt từ mockup ngan-chan-bao-cao.css */
.report-kpi-grid {
   display: grid;
   grid-template-columns: repeat(4, minmax(0, 1fr));
   gap: 16px;
   margin-bottom: 20px;
}

.kpi-card {
   position: relative;
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius);
   padding: 18px;
   box-shadow: var(--shadow-sm);
   min-height: 122px;
}

.kpi-top {
   display: flex;
   align-items: flex-start;
   justify-content: space-between;
   gap: 12px;
}

.kpi-label {
   font-size: 11px;
   font-weight: 700;
   color: var(--text-600);
   text-transform: uppercase;
   letter-spacing: .025em;
}

.kpi-icon {
   width: 36px;
   height: 36px;
   border-radius: var(--radius-sm);
   display: flex;
   align-items: center;
   justify-content: center;
   font-size: 16px;
}

.kpi-icon.total {
   background: var(--blue-50);
   color: var(--blue-700);
}

.kpi-icon.blocking {
   background: var(--red-100);
   color: var(--red-700);
}

.kpi-icon.removed {
   background: var(--green-100);
   color: var(--green-700);
}

.kpi-icon.expired {
   background: var(--amber-100);
   color: var(--amber-600);
}

.kpi-value {
   margin-top: 14px;
   font: 700 23px var(--font-num);
   color: var(--text-900);
}

.chart-box {
   height: 300px;
   padding: 16px;
}

.chart-box canvas {
   max-height: 268px;
}

.report-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 16px;
   margin-top: 16px;
}

.report-grid .panel {
   margin: 0;
}

.report-table {
   width: 100%;
   border-collapse: collapse;
}

.report-table th,
.report-table td {
   padding: 12px 14px;
   border-bottom: 1px solid var(--divider);
   text-align: left;
}

.report-table th {
   font-size: 11px;
   color: var(--text-600);
   text-transform: uppercase;
   letter-spacing: .025em;
}

.report-table td {
   font-size: 13px;
}

.report-table th.num,
.report-table td.num {
   text-align: right;
   font-family: var(--font-num);
}

.report-hint {
   margin-top: 14px;
}

@media (max-width: 1300px) {
   .report-kpi-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
   }
}

@media (max-width: 820px) {
   .report-grid {
      grid-template-columns: 1fr;
   }
}

@media (max-width: 640px) {
   .report-kpi-grid {
      grid-template-columns: 1fr;
   }
}

/* DossierReport_STP ("Báo cáo hồ sơ") — copy/adapt từ mockup bao-cao-ho-so.css. Trang này dùng
   chung tên class .report-grid/.chart-box/.report-kpi-grid với PreventReport_STP nhưng cần giá
   trị khác (layout 2 cột lệch thay vì đều, chart cao hơn) — scope riêng dưới .dossier-report-page
   (2 lớp, thắng chắc chắn specificity so với rule .report-grid/.chart-box 1 lớp dùng chung, không
   phụ thuộc thứ tự nạp CSS — đúng bài học specificity đã rút ra nhiều lần trong dự án này). */
.dossier-report-filter {
   margin-bottom: 16px;
}

.dossier-report-filter .filter-field {
   min-width: 170px;
}

.dossier-report-filter .filter-field.type-filter {
   min-width: 250px;
   flex: 1;
}

.dossier-report-filter .filter-actions {
   margin-left: auto;
}

.dossier-report-page .report-grid {
   grid-template-columns: minmax(0, 1.2fr) minmax(320px, .8fr);
}

.dossier-report-page .chart-box {
   height: 360px;
   padding: 16px;
}

.dossier-report-page .chart-box canvas {
   max-height: 328px;
}

.chart-box-donut {
   height: 360px;
   padding: 24px;
}

.chart-box-donut canvas {
   max-height: 312px;
}

.empty-table-cell {
   text-align: center !important;
   color: var(--text-400);
   padding: 28px 12px !important;
}

@media (max-width: 1100px) {
   .dossier-report-page .report-grid {
      grid-template-columns: 1fr;
   }
}

@media (max-width: 640px) {

   .dossier-report-filter .filter-field,
   .dossier-report-filter .filter-field.type-filter {
      width: 100%;
      min-width: 0;
   }

   .dossier-report-filter .filter-actions {
      width: 100%;
      margin-left: 0;
   }

   .dossier-report-filter .filter-actions .btn-ghost {
      width: 100%;
   }

   .dossier-report-page .chart-box,
   .chart-box-donut {
      height: 420px;
   }
}

/* Report_STP ("Báo cáo năm") — copy/adapt từ mockup bao-cao-nam.css. .report-kpi-grid dùng chung
   với PreventReport_STP/DossierReport_STP nhưng trang này chỉ có 3 KPI (không phải 4) -> scope
   riêng còn .chart-box-lg là class mới, không trùng tên nào khác nên không cần scope. */
.annual-report-page .report-kpi-grid {
   grid-template-columns: repeat(3, minmax(0, 1fr));
}

.chart-box-lg {
   height: 430px;
   padding: 18px;
}

.chart-box-lg canvas {
   max-height: 394px;
}

@media (max-width: 1300px) {
   .annual-report-page .report-kpi-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
   }
}

@media (max-width: 820px) {
   .chart-box-lg {
      height: 390px;
   }
}

@media (max-width: 640px) {
   .annual-report-page .report-kpi-grid {
      grid-template-columns: 1fr;
   }

   .chart-box-lg {
      height: 360px;
      padding: 12px;
   }
}

/* Statistic_STP ("Thống kê") — copy/adapt từ mockup thong-ke.css. Không trùng tên class nào khác
   (processing-*) nên không cần scope, chỉ .kpi-card/.report-table/.chart-box là dùng chung gốc. */
.processing-kpi-grid {
   display: grid;
   grid-template-columns: repeat(3, minmax(0, 1fr));
   gap: 16px;
   margin-bottom: 20px;
}

.processing-kpi-grid .kpi-card {
   min-height: 126px;
}

.processing-kpi-grid .kpi-value {
   font-size: 21px;
   line-height: 1.4;
}

.processing-layout {
   display: grid;
   grid-template-columns: minmax(0, 1.05fr) minmax(340px, .95fr);
   gap: 16px;
   margin-bottom: 16px;
}

.processing-layout .panel,
.processing-detail {
   margin: 0;
}

.processing-table th.num,
.processing-table td.num {
   text-align: right;
   font-family: var(--font-num);
   white-space: nowrap;
}

.processing-table .doc-code {
   white-space: nowrap;
}

.processing-chart {
   height: 360px;
   padding: 16px;
}

.processing-chart canvas {
   max-height: 328px;
}

@media (max-width: 1100px) {
   .processing-layout {
      grid-template-columns: 1fr;
   }
}

@media (max-width: 820px) {
   .processing-kpi-grid {
      grid-template-columns: 1fr;
   }
}

@media (max-width: 640px) {
   .processing-kpi-grid {
      gap: 12px;
   }

   .processing-chart {
      height: 420px;
   }
}

/* Report10b_STP ("Báo cáo thống kê công chứng") — copy/adapt từ mockup bao-cao-thong-ke-cong-chung.css.
   .report-kpi-grid/.chart-box dùng chung tên với các trang báo cáo khác nhưng cần giá trị khác
   (5 cột KPI, chart 350px) -> scope riêng dưới .bm10b-report-page, đúng kỹ thuật specificity đã
   dùng nhiều lần trong dự án. .report-layout/.report-hints là tên mới, không trùng nên không cần scope. */
.bm10b-report-page .report-kpi-grid {
   grid-template-columns: repeat(5, minmax(0, 1fr));
}

.bm10b-report-page .chart-box {
   height: 350px;
   padding: 16px;
}

.bm10b-report-page .chart-box canvas {
   max-height: 318px;
}

.report-layout {
   display: grid;
   grid-template-columns: minmax(0, 1.25fr) minmax(320px, .75fr);
   gap: 16px;
}

.report-layout .panel {
   margin: 0;
}

.report-hints {
   display: grid;
   gap: 6px;
   margin-bottom: 18px;
}

.report-hints .hint {
   margin: 0;
}

.bm10b-export-panel {
   margin-top: 16px;
}

@media (max-width: 1450px) {
   .bm10b-report-page .report-kpi-grid {
      grid-template-columns: repeat(3, minmax(0, 1fr));
   }
}

@media (max-width: 1100px) {
   .report-layout {
      grid-template-columns: 1fr;
   }

   .bm10b-report-page .report-kpi-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
   }
}

@media (max-width: 640px) {
   .bm10b-report-page .report-kpi-grid {
      grid-template-columns: 1fr;
   }

   .bm10b-report-page .chart-box {
      height: 420px;
   }
}

/* DocumentStatisticPrintSo_STP ("Kết xuất sổ công chứng") — copy/adapt từ mockup
   ket-xuat-so-cong-chung.css. Toàn bộ tên class mới, không trùng nên không cần scope. */
.book-filter-type {
   min-width: 310px;
}

.book-date-field {
   min-width: 160px;
}

.book-filter-actions {
   display: flex;
   gap: 9px;
   align-items: center;
}

.book-table {
   width: 100%;
   border-collapse: collapse;
   background: var(--card);
}

.book-table th,
.book-table td {
   padding: 11px 12px;
   border-bottom: 1px solid var(--border);
   font-size: 12px;
   text-align: left;
   vertical-align: top;
}

.book-table th {
   font-size: 10.5px;
   text-transform: uppercase;
   letter-spacing: .03em;
   color: var(--text-600);
   background: var(--bg);
}

.book-table-empty {
   text-align: center !important;
   color: var(--text-600);
   padding: 28px 12px !important;
}

.book-result-count {
   font-size: 12px;
   color: var(--text-600);
   margin: 0 0 10px;
}

.book-rbac-hint {
   margin-top: 7px;
   font-size: 11.5px;
   color: var(--text-600);
}

@media (max-width: 640px) {

   .book-filter-type,
   .book-date-field {
      min-width: 100%;
      width: 100%;
   }

   .book-filter-actions {
      width: 100%;
      flex-wrap: wrap;
   }

   .book-filter-actions .btn-ghost,
   .book-filter-actions .btn-primary {
      flex: 1;
      justify-content: center;
   }
}

/* "Mẫu dấu/chữ ký CCV" (NotarySeal_STP) — copy/thích nghi từ mockup mau-dau-chu-ky.css */
.stamp-signature-table {
   min-width: 820px;
}

.stamp-signature-table td {
   vertical-align: middle;
}

.stamp-signature-table th:nth-child(2),
.stamp-signature-table td:nth-child(2),
.stamp-signature-table th:nth-child(3),
.stamp-signature-table td:nth-child(3) {
   text-align: center;
   min-width: 110px;
}

.notary-name {
   font-weight: 600;
   color: var(--text-900);
   white-space: nowrap;
}

.stamp-thumb,
.signature-thumb {
   display: block;
   margin: auto;
   border: 1px solid var(--border);
   background: var(--card);
   cursor: pointer;
}

.stamp-thumb {
   width: 48px;
   height: 48px;
   border-radius: 50%;
   object-fit: cover;
}

.signature-thumb {
   width: 72px;
   height: 40px;
   border-radius: var(--radius-sm);
   object-fit: contain;
}

.image-preview-button {
   padding: 0;
   border: 0;
   background: none;
   border-radius: var(--radius-sm);
}

.image-preview-button:focus-visible {
   outline: 3px solid var(--blue-50);
   box-shadow: 0 0 0 2px var(--blue-600);
}

.updated-at {
   font-family: var(--font-num);
   white-space: nowrap;
}

.preview-modal {
   max-width: 560px;
}

.image-preview-wrap {
   display: flex;
   align-items: center;
   justify-content: center;
   min-height: 260px;
   padding: 16px;
   background: var(--bg);
   border-radius: var(--radius);
}

.image-preview-wrap img {
   display: block;
   max-width: 480px;
   max-height: 480px;
   width: auto;
   height: auto;
}

.signature-stack>.panel+.panel {
   margin-top: 16px;
}

.signature-general-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 16px;
}

.signature-general-grid .note-field {
   grid-column: 1 / -1;
}

.active-field {
   padding-top: 25px;
}

.image-upload-preview {
   display: flex;
   align-items: center;
   justify-content: center;
   min-height: 220px;
   margin-bottom: 14px;
   padding: 16px;
   border: 1px solid var(--border);
   border-radius: var(--radius);
   background: var(--bg);
}

.image-upload-preview img {
   display: block;
   max-width: 100%;
   max-height: 300px;
   object-fit: contain;
}

.stamp-upload-preview img {
   width: 240px;
   height: 240px;
   border-radius: 50%;
   object-fit: contain;
}

.upload-dropzone input[type=file] {
   position: absolute;
   width: 1px;
   height: 1px;
   overflow: hidden;
   clip: rect(0 0 0 0);
   white-space: nowrap;
}

.upload-actions {
   display: flex;
   justify-content: center;
   gap: 8px;
   flex-wrap: wrap;
}

.validation-message {
   margin-top: 8px;
   color: var(--red-700);
   font-size: 11.5px;
}

.signature-detail-page {
   padding-bottom: 110px;
}

@media (max-width: 820px) {
   .signature-general-grid {
      grid-template-columns: 1fr;
   }

   .signature-general-grid .note-field {
      grid-column: auto;
   }

   .active-field {
      padding-top: 0;
   }
}

@media (max-width: 640px) {
   .stamp-signature-table {
      min-width: 780px;
   }

   .image-preview-wrap {
      min-height: 200px;
      padding: 10px;
   }

   .image-preview-wrap img {
      max-width: 100%;
      max-height: 360px;
   }

   .image-upload-preview {
      min-height: 180px;
   }

   .stamp-upload-preview img {
      width: 190px;
      height: 190px;
   }
}

/* OrganPlace_STP ("Đối tác & liên hệ") — trang gộp tab 5 module (Cơ quan/Ngân hàng/Đối tác/
   Người giới thiệu/Đơn vị hỗ trợ), copy .catalog-toolbar từ mockup doi-tac-lien-he.css. */
.catalog-toolbar {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   margin-bottom: 14px;
}

@media (max-width: 640px) {
   .catalog-toolbar {
      align-items: flex-start;
      flex-direction: column;
   }

   .catalog-toolbar .btn-primary {
      width: 100%;
      justify-content: center;
   }
}

/* DocumentType_STP ("Loại hồ sơ") — copy từ mockup loai-ho-so.css, các class mới hoàn toàn
   (đã grep xác nhận không trùng tên với class nào khác trong dự án). */
.general-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 16px;
}

.general-grid .full {
   grid-column: 1 / -1;
}

.section-toolbar {
   display: flex;
   justify-content: space-between;
   align-items: center;
   gap: 12px;
   margin-bottom: 14px;
}

.inline-role-list,
.modal-role-list {
   display: grid;
   gap: 10px;
   margin-bottom: 12px;
}

.inline-role-row {
   display: grid;
   grid-template-columns: minmax(180px, 1fr) minmax(160px, .7fr) auto;
   gap: 10px;
   align-items: end;
}

.modal-role-row {
   display: grid;
   grid-template-columns: minmax(170px, 1fr) auto;
   gap: 10px;
   align-items: end;
   margin-bottom: 10px;
}

.role-row-actions {
   display: flex;
   gap: 6px;
}

.role-code {
   font-family: var(--font-num);
}

/* "Mẫu file Word" (WordTemplate_STP) — copy/thích nghi từ mockup mau-file-word.css. Tái dùng
   .general-grid/.full đã có (DocumentType_STP) thay vì thêm .word-general-grid trùng lặp. */
.word-template-table td {
   vertical-align: top;
}

.stack-panels>.panel+.panel {
   margin-top: 16px;
}

.mapping-overview {
   display: grid;
   grid-template-columns: auto minmax(180px, 1fr);
   align-items: center;
   gap: 16px;
   margin-bottom: 16px;
}

.mapping-summary-count {
   font-weight: 700;
   color: var(--text-900);
   white-space: nowrap;
   font-family: var(--font-num);
}

.mapping-progress {
   height: 8px;
   border-radius: 999px;
   background: var(--divider);
   overflow: hidden;
}

.mapping-progress-bar {
   height: 100%;
   background: var(--amber-600);
   transition: width .2s;
}

.mapping-table {
   min-width: 600px;
}

.mapping-table td {
   vertical-align: top;
}

@media (max-width: 640px) {
   .mapping-overview {
      grid-template-columns: 1fr;
      gap: 8px;
   }
}

@media (max-width: 640px) {
   .general-grid {
      grid-template-columns: 1fr;
   }

   .general-grid .full {
      grid-column: auto;
   }

   .inline-role-row,
   .modal-role-row {
      grid-template-columns: 1fr;
   }

   .section-toolbar {
      align-items: flex-start;
      flex-direction: column;
   }
}

/* "Mẫu hồ sơ" (ThemesDocument_STP) — copy/thích nghi từ mockup mau-ho-so.css (bỏ phần
   .term-token-toolbar/.field-pill vì tính năng "chèn trường" chưa build ở lần này). */
.checkbox-grid {
   display: grid;
   grid-template-columns: repeat(3, minmax(0, 1fr));
   gap: 10px 16px;
}

.editor-field+.editor-field {
   margin-top: 16px;
}

.term-list {
   display: grid;
   gap: 16px;
}

.item-term {
   border: 1px solid var(--border);
   border-radius: 10px;
   background: var(--card);
   overflow: hidden;
}

.term-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   padding: 12px 16px;
   border-bottom: 1px solid var(--border);
   background: var(--bg);
}

.term-head h4 {
   margin: 0;
}

.term-actions {
   display: flex;
   align-items: center;
   gap: 10px;
   flex: 0 0 auto;
}

.term-actions .label-refresh {
   font-size: 11.5px;
   color: var(--text-600);
   cursor: pointer;
}

.term-body {
   padding: 16px;
}

.term-body>.form-field {
   margin-bottom: 12px;
}

.term-body>.form-field:last-child {
   margin-bottom: 0;
}

.panel-footer-action {
   margin-top: 16px;
   text-align: center;
}

@media (max-width: 820px) {
   .checkbox-grid {
      grid-template-columns: 1fr;
   }
}

/* Đăng nhập — nút "Quay lại đăng nhập" trong bước xác thực 2FA (mockup login gốc không có bước
   này vì là demo tĩnh không xử lý 2FA thật; hệ thống thật đã có 2FA nên cần thêm lối thoát). */
.btn-verify-back {
   display: block;
   width: 100%;
   margin-top: 12px;
   padding: 8px;
   text-align: center;
   background: none;
   border: none;
   color: var(--text-500);
   font-size: 12.5px;
   cursor: pointer;
}

.btn-verify-back:hover {
   color: var(--blue-600);
   text-decoration: underline;
}

/* Bù lại rule ".dropdown-menu" gốc của Bootstrap3 (đã gỡ khỏi index.tpl) — vẫn cần cho popup lịch
   của bootstrap-datetimepicker (vd Users_STP/modify.tpl "Ngày vào làm"), plugin này chỉ tự định
   nghĩa phần trang trí (.bootstrap-datetimepicker-widget.dropdown-menu), không tự định nghĩa lại
   phần định vị/ẩn-hiện cơ bản của .dropdown-menu — thiếu rule này thì popup sẽ không định vị nổi
   nữa (hoặc luôn hiện). Copy tối thiểu, không import lại toàn bộ component dropdown của Bootstrap. */
.dropdown-menu {
   position: absolute;
   top: 100%;
   left: 0;
   z-index: 1000;
   display: none;
   float: left;
   min-width: 160px;
   margin: 2px 0 0;
   background-color: #fff;
   border: 1px solid rgba(0, 0, 0, .15);
   border-radius: 4px;
   box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
}

/* Bù lại grid Bootstrap tối thiểu (.row/.col-sm-*) cho vài mảnh NỘI DUNG CŨ trên màn hình "Soạn
   hồ sơ" chưa/không thể reskin hết (phát hiện 2026-08-11, sau khi gỡ bootstrap.css khỏi index.tpl
   ở Giai đoạn 5 làm các chỗ này mất hẳn CSS, trước đó "ăn ké" bootstrap.css nạp toàn cục nên không
   lộ ra dù chưa từng đổi markup):
   (1) Nội dung "khoá" trong `theme_document.testimonial_lock` — dữ liệu ĐÃ LƯU sẵn theo từng mẫu
       hồ sơ (soạn qua CKEditor trong `ThemesDocument_STP`), field lockable `blockTestimonial` luôn
       được chèn kèm `<div class="col-sm-12"><div class="row label-content-testimonial">...`
       — không thể sửa hàng loạt qua 97 mẫu hồ sơ đã lưu (rủi ro cao, ngoài phạm vi 1 lần vá CSS).
   (2) `Db_View::parseAbstractDocument()` (panel "Trích yếu") — đã ghi chú từ Phase 4c là "cố ý
       chưa reskin", nay cũng bị lộ ra do mất CSS nền.
   (3) `Document_STP::parseLitigantDocument()`'s nhánh fallback hiếm gặp `data-view="QuyenSoHuu"`
       (hồ sơ chưa có nhóm đương sự nào).
   (4) **2026-08-12, phát hiện qua báo cáo người dùng** — `Ajax_STP::taskLoadInfoDocument()`/
       `taskLoadInfoTestimonial()` (2 hàm gần như sinh đôi — copy-paste, xử lý nút "Lấy thông tin"/
       "Cập nhật lời chứng" trên trang Soạn hồ sơ): phần liệt kê đương sự chèn vào
       `{{fullInfLitigant}}` bên trong lời chứng dùng ĐẦY ĐỦ khung lưới `col-sm-1` đến `col-sm-12`
       (không chỉ `col-sm-12` như 3 chỗ trên) — quy mô code build HTML ở đây rất lớn (~2000 dòng
       mỗi hàm, sinh nội dung văn bản công chứng thật), rủi ro sửa lại markup còn cao hơn cả (1),
       nên áp dụng đúng cùng chiến lược "bù CSS grid, không đụng logic". Đã kiểm tra: đây KHÔNG
       phải component mới nào của app-shell (không có gì khác trong toàn bộ `templates/` hiện đại
       dùng lại đúng tên `col-sm-1..11`), nên bù đủ cả bộ grid Bootstrap 3 chuẩn là an toàn.
   Không scope vì không có class `.row`/`.col-sm-*` nào khác (tên mới) trong toàn bộ app-shell.css/
   app-common.css đụng tên (khác hẳn HTML xuất PDF/Docx qua `parseHtmlDocument()`/
   `parseHtmlForDocx()`, luôn tự nạp riêng `bootstrap.min.css` qua `<link>` trong chính HTML xuất
   ra — xem `Document_STP::exportDocument()` — nên không cần rule ở đây, chỉ áp dụng cho màn hình). */
.row {
   margin-left: -15px;
   margin-right: -15px;
}

.row:before,
.row:after {
   content: " ";
   display: table;
}

.row:after {
   clear: both;
}

.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6,
.col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
   position: relative;
   min-height: 1px;
   padding-left: 15px;
   padding-right: 15px;
   float: left;
}

.col-sm-1 { width: 8.33333%; }
.col-sm-2 { width: 16.66667%; }
.col-sm-3 { width: 25%; }
.col-sm-4 { width: 33.33333%; }
.col-sm-5 { width: 41.66667%; }
.col-sm-6 { width: 50%; }
.col-sm-7 { width: 58.33333%; }
.col-sm-8 { width: 66.66667%; }
.col-sm-9 { width: 75%; }
.col-sm-10 { width: 83.33333%; }
.col-sm-11 { width: 91.66667%; }
.col-sm-12 { width: 100%; }

/* ================================================================
   Dashboard_STP ("Trang chủ" / Tổng quan hoạt động) — trang MỚI hoàn
   toàn (trước đây "trang-chu" chỉ redirect thẳng sang danh sách hồ
   sơ). Copy/thích nghi từ mockup assets/css/dashboard.css.
   Class trùng tên với `.kpi-card`/`.chart-box`/`.chart-box-lg`/
   `.chart-box-donut`/`.segmented-control` đã dùng ở các trang báo cáo
   khác (Report_STP, PreventReport_STP, DossierReport_STP...) — SCOPE
   toàn bộ dưới `.dashboard-page` (2 lớp, thắng chắc chắn specificity)
   để không đụng các định nghĩa gốc đó, đúng kỹ thuật đã áp dụng nhiều
   lần trong dự án cho đúng loại xung đột tên class này. */
.dashboard-page .kpi-grid {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
   gap: 14px;
   margin-bottom: 18px;
}

.dashboard-page .kpi-card {
   position: relative;
   overflow: hidden;
   background: var(--card);
   border: 1px solid var(--border);
   border-radius: var(--radius);
   padding: 16px 16px 14px;
   box-shadow: var(--shadow-sm);
   min-height: auto;
}

.dashboard-page .kpi-card.hero {
   background: linear-gradient(135deg, var(--navy-900) 0%, var(--navy-800) 60%, #16497D 100%);
   color: #fff;
   border: none;
}

.dashboard-page .kpi-card.hero .kpi-label {
   color: #B9CBE6;
}

.dashboard-page .kpi-card.hero .kpi-value {
   color: #fff;
}

.dashboard-page .kpi-card.hero .kpi-value small {
   color: #9DB4D6;
}

.dashboard-page .kpi-card.hero .kpi-delta .vs {
   color: #8CA3C6;
}

.dashboard-page .kpi-card-link {
   position: absolute;
   inset: 0;
   z-index: 1;
   border-radius: inherit;
}

.dashboard-page .kpi-top {
   display: flex;
   align-items: flex-start;
   justify-content: space-between;
   margin-bottom: 13px;
}

.dashboard-page .kpi-icon {
   width: 36px;
   height: 36px;
   border-radius: 10px;
   display: flex;
   align-items: center;
   justify-content: center;
   font-size: 15px;
   flex-shrink: 0;
}

.dashboard-page .kpi-label {
   font-size: 11px;
   color: var(--text-600);
   font-weight: 700;
   letter-spacing: .01em;
   margin-bottom: 6px;
   text-transform: uppercase;
}

.dashboard-page .kpi-value {
   margin-top: 0;
   font-size: 23px;
   font-weight: 700;
   letter-spacing: -.01em;
   font-family: var(--font-num);
}

.dashboard-page .kpi-value small {
   font-size: 12.5px;
   font-weight: 600;
   color: var(--text-400);
}

.dashboard-page .kpi-delta {
   display: inline-flex;
   align-items: center;
   gap: 5px;
   font-size: 11.3px;
   font-weight: 700;
   margin-top: 9px;
}

.dashboard-page .kpi-delta.up {
   color: var(--green-600);
}

.dashboard-page .kpi-delta.down {
   color: var(--red-600);
}

.dashboard-page .kpi-delta .vs {
   color: var(--text-400);
   font-weight: 500;
   margin-left: 2px;
}

.dashboard-page .chart-box {
   position: relative;
   width: 100%;
   height: 260px;
   padding: 16px;
}

.dashboard-page .chart-box canvas {
   max-height: 228px;
}

.dashboard-page .chart-box-lg {
   height: 340px;
}

.dashboard-page .chart-box-lg canvas {
   max-height: 308px;
}

.dashboard-page .chart-box-tall {
   height: 300px;
}

.dashboard-page .chart-box-tall canvas {
   max-height: 268px;
}

.dashboard-page .chart-box-donut {
   height: 240px;
   padding: 24px;
}

.dashboard-page .chart-box-donut canvas {
   max-height: 192px;
}

.dashboard-page .donut-wrap {
   position: relative;
}

.dashboard-page .donut-center {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
   text-align: center;
   pointer-events: none;
}

.dashboard-page .donut-center .num {
   font-size: 24px;
   font-weight: 700;
   color: var(--green-700);
}

.dashboard-page .donut-center .lbl {
   font-size: 10.5px;
   color: var(--text-400);
   margin-top: 2px;
   max-width: 88px;
}

.dashboard-page .legend-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 12px 16px;
   margin-top: 8px;
   padding: 2px 18px 18px;
}

.dashboard-page .legend-cell {
   min-width: 0;
}

.dashboard-page .legend-top {
   display: flex;
   align-items: center;
   gap: 7px;
   font-size: 12px;
   color: var(--text-600);
   font-weight: 600;
}

.dashboard-page .legend-pct {
   margin-left: auto;
   font-family: var(--font-num);
   font-weight: 700;
   color: var(--text-900);
   font-size: 12px;
}

.dashboard-page .legend-track {
   height: 5px;
   background: var(--bg);
   border-radius: 99px;
   margin: 6px 0 5px;
   overflow: hidden;
}

.dashboard-page .legend-fill {
   height: 100%;
   border-radius: 99px;
}

.dashboard-page .legend-num {
   font-size: 11px;
   color: var(--text-400);
}

.dashboard-page .legend-dot {
   width: 9px;
   height: 9px;
   border-radius: 3px;
   flex-shrink: 0;
}

.dashboard-page .staff-row {
   display: flex;
   align-items: center;
   gap: 12px;
   padding: 10.5px 0;
   border-bottom: 1px solid var(--divider);
}

.dashboard-page .staff-row:last-child {
   border-bottom: none;
}

.dashboard-page .staff-rank {
   width: 22px;
   font-weight: 700;
   font-size: 12px;
   color: var(--text-400);
   text-align: center;
   font-family: var(--font-num);
}

.dashboard-page .staff-rank.top {
   color: var(--gold-600);
   font-size: 14.5px;
}

.dashboard-page .staff-info {
   flex: 1;
   min-width: 0;
}

.dashboard-page .staff-name {
   font-size: 12.8px;
   font-weight: 600;
}

.dashboard-page .staff-bar-track {
   height: 6px;
   background: var(--bg);
   border-radius: 99px;
   margin-top: 6px;
   overflow: hidden;
}

.dashboard-page .staff-bar-fill {
   height: 100%;
   border-radius: 99px;
   background: var(--blue-600);
}

.dashboard-page .staff-count {
   font-weight: 700;
   font-size: 13.5px;
   text-align: right;
   width: 46px;
   font-family: var(--font-num);
   flex-shrink: 0;
}

.dashboard-page .segmented-control a {
   padding: 6px 12px;
   font-size: 12px;
   font-weight: 600;
   border-radius: 7px;
   color: var(--text-600);
   background: transparent;
   transition: background-color .15s, color .15s;
   text-decoration: none;
}

.dashboard-page .segmented-control a:hover:not(.active) {
   background: var(--bg);
   color: var(--text-900);
}

.dashboard-page .segmented-control a.active {
   background: var(--navy-900);
   color: #fff;
}

.dashboard-page .recent-empty,
.dashboard-page .alert-empty {
   color: var(--text-400);
   font-size: 12.5px;
   padding: 18px 4px;
   text-align: center;
}

@media (max-width: 1300px) {
   .dashboard-page .kpi-grid {
      grid-template-columns: repeat(3, 1fr);
   }
}

@media (max-width: 820px) {
   .dashboard-page .kpi-grid {
      grid-template-columns: repeat(2, 1fr);
   }
}

@media (max-width: 640px) {
   .dashboard-page .kpi-grid {
      grid-template-columns: 1fr 1fr;
      gap: 10px;
      margin-bottom: 12px;
   }

   .dashboard-page .kpi-card {
      padding: 14px 14px 12px;
   }

   .dashboard-page .kpi-value {
      font-size: 20px;
   }

   .dashboard-page .legend-grid {
      padding: 2px 14px 14px;
      gap: 10px 12px;
      grid-template-columns: 1fr 1fr;
   }
}

@media (max-width: 400px) {
   .dashboard-page .kpi-grid {
      grid-template-columns: 1fr;
   }
}

.dropdown-menu.open,
.open>.dropdown-menu {
   display: block;
}

/* Configs_STP ("Cấu hình chung") — panel "Sử dụng hệ thống" (biểu đồ dung lượng DB/file + số
   lượng người dùng, đọc từ class SystemLimits/.env). Donut+legend dùng chung tên class với
   Dashboard_STP (.donut-wrap/.donut-center/.legend-*) — SCOPE dưới .config-page (2 lớp, đúng kỹ
   thuật đã áp dụng nhiều lần trong dự án) thay vì tái dùng nguyên bản .dashboard-page, tránh phải
   gắn 1 class ngữ nghĩa sai (trang cấu hình không phải dashboard) lên khung trang. .report-kpi-grid/
   .kpi-card cho hàng KPI phía trên dùng thẳng bản gốc không scope (đã sẵn 4 cột, không cần đổi). */
.config-page .chart-box {
   position: relative;
   width: 100%;
}

.config-page .chart-box-donut {
   height: 220px;
   padding: 20px;
}

.config-page .chart-box-donut canvas {
   max-height: 176px;
}

.config-page .donut-wrap {
   position: relative;
}

.config-page .donut-center {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
   text-align: center;
   pointer-events: none;
}

.config-page .donut-center .num {
   font-size: 22px;
   font-weight: 700;
   color: var(--blue-700);
}

.config-page .donut-center .lbl {
   font-size: 10.5px;
   color: var(--text-400);
   margin-top: 2px;
   max-width: 88px;
}

.config-page .legend-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 12px 16px;
   margin-top: 4px;
   padding: 2px 18px 18px;
}

.config-page .legend-cell {
   min-width: 0;
}

.config-page .legend-top {
   display: flex;
   align-items: center;
   gap: 7px;
   font-size: 12px;
   color: var(--text-600);
   font-weight: 600;
}

.config-page .legend-pct {
   margin-left: auto;
   font-family: var(--font-num);
   font-weight: 700;
   color: var(--text-900);
   font-size: 12px;
}

.config-page .legend-track {
   height: 5px;
   background: var(--bg);
   border-radius: 99px;
   margin: 6px 0 5px;
   overflow: hidden;
}

.config-page .legend-fill {
   height: 100%;
   border-radius: 99px;
}

.config-page .legend-num {
   font-size: 11px;
   color: var(--text-400);
}

.config-page .legend-dot {
   width: 9px;
   height: 9px;
   border-radius: 3px;
   flex-shrink: 0;
}

.config-page .usage-progress-track {
   height: 6px;
   background: var(--bg);
   border-radius: 99px;
   overflow: hidden;
   margin-top: 8px;
}

.config-page .usage-progress-fill {
   height: 100%;
   border-radius: 99px;
   background: var(--blue-600);
}

.config-page .usage-progress-fill.warn {
   background: var(--gold-600);
}

.config-page .usage-progress-fill.danger {
   background: var(--red-600);
}

@media (max-width: 640px) {
   .config-page .legend-grid {
      padding: 2px 14px 14px;
      gap: 10px 12px;
   }
}

/* Banner thông báo kiểu Bootstrap 3 cũ (.alert/.alert-success/.alert-error/.alert-dismissable) —
   dùng bởi showMessage() (assets/js/dialog.js), Msg class (server-side) và nhiều nơi PHP tự build
   HTML thành công/lỗi (vd Configs_STP::save(), Profile_STP đổi mật khẩu). Hoàn toàn KHÔNG có CSS
   nào định nghĩa sau khi gỡ Bootstrap ở Giai đoạn 5 (chỉ còn .alert-item — tên khác, dùng cho card
   cảnh báo trong panel, không phải banner thông báo dạng này) — nút đóng (.close[data-dismiss])
   vẫn hoạt động đúng vì gắn bằng jQuery thuần (dialog.js dòng 180), chỉ thiếu style. */
.alert {
   position: relative;
   display: flex;
   align-items: flex-start;
   gap: 10px;
   padding: 12px 40px 12px 14px;
   margin-bottom: 14px;
   border-radius: var(--radius-sm);
   border: 1px solid transparent;
   font-size: 13px;
   line-height: 1.5;
}
.alert strong { font-weight: 600; }
.alert-success {
   background: var(--green-100);
   border-color: var(--green-600);
   color: var(--green-700);
}
.alert-error, .alert-danger {
   background: var(--red-100);
   border-color: var(--red-600);
   color: var(--red-700);
}
.alert-warning {
   background: var(--amber-100);
   border-color: var(--amber-600);
   color: var(--amber-600);
}
.alert-info {
   background: #E5EEFC;
   border-color: var(--blue-600);
   color: var(--blue-700);
}
.alert .close {
   position: absolute;
   top: 6px;
   right: 8px;
   background: none;
   border: 0;
   font-size: 18px;
   line-height: 1;
   cursor: pointer;
   color: inherit;
   opacity: .55;
   padding: 4px 6px;
}
.alert .close:hover { opacity: 1; }

/* Configs_STP ("Cấu hình chung") — ô chọn Logo/Favicon (thay thế nút CKFinder cũ chưa từng hoạt
   động vì <script src> trỏ sai đường dẫn — xem uploadConfigImage() trong main.tpl). */
.config-image-field {
   display: flex;
   align-items: center;
   gap: 12px;
   flex-wrap: wrap;
}
.config-image-field .inline-add-row {
   flex: 1;
   min-width: 200px;
}
.config-image-field .inline-add-row input[type="text"] {
   background: var(--bg);
   color: var(--text-400);
}
.config-image-field #messageconfig_logo,
.config-image-field #messageconfig_favicon {
   width: 100%;
}
.config-image-preview {
   width: 56px;
   height: 56px;
   flex-shrink: 0;
   border-radius: var(--radius-sm);
   border: 1px solid var(--border);
   object-fit: contain;
   background: var(--card);
   padding: 4px;
}
.config-image-preview-empty {
   display: flex;
   align-items: center;
   justify-content: center;
   color: var(--text-400);
   font-size: 18px;
}

/* ============================================================
   DigitizeFile_STP ("So hoa ho so") - port tu mockup/assets/css/so-hoa-ho-so.css.
   .kpi-grid/.kpi-card/.badge.processing/.badge.readysign scope duoi .digitize-page vi cac ten
   class nay da bi Dashboard_STP chiem dung duoi scope ".dashboard-page" voi gia tri khac - dung ky
   thuat "scope 2 lop" da dung lap lai nhieu lan trong du an de tranh xung dot ten class dung chung.
   ============================================================ */
.digitize-page .service-status-bar{display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:var(--radius-sm);border:1px solid var(--green-600);background:var(--green-100);color:var(--green-700);font-size:12.5px;margin-bottom:16px;flex-wrap:wrap;}
.digitize-page .service-status-bar.is-down{border-color:var(--red-600);background:var(--red-100);color:var(--red-700);}
.digitize-page .service-status-bar .dot{width:8px;height:8px;border-radius:50%;background:var(--green-600);flex-shrink:0;box-shadow:0 0 0 3px rgba(21,160,90,.18);}
.digitize-page .service-status-bar.is-down .dot{background:var(--red-600);box-shadow:0 0 0 3px rgba(220,38,38,.18);}
.digitize-page .service-status-bar b{font-weight:700;}
.digitize-page .service-status-bar .sep{color:var(--text-400);}
.digitize-page .service-status-bar .meta{color:inherit;opacity:.8;}
.digitize-page .service-status-bar .spacer{flex:1;}

.digitize-page .kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:18px;}
.digitize-page .kpi-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:var(--shadow-sm);cursor:pointer;transition:transform .12s,box-shadow .12s;}
.digitize-page .kpi-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);}
.digitize-page .kpi-card.active{border-color:var(--blue-600);box-shadow:0 0 0 2px var(--blue-50);}
.digitize-page .kpi-top{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:11px;}
.digitize-page .kpi-icon{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0;}
.digitize-page .kpi-label{font-size:10.6px;color:var(--text-600);font-weight:700;letter-spacing:.01em;margin-bottom:5px;text-transform:uppercase;}
.digitize-page .kpi-value{font-family:var(--font-num);font-size:22px;font-weight:700;letter-spacing:-.01em;color:var(--text-900);}

.digitize-page .so-hoa-toolbar .filter-field{min-width:170px;}
.digitize-page .so-hoa-toolbar .filter-field.grow{min-width:230px;}

.digitize-page .so-hoa-table{min-width:1180px;}
.digitize-page .so-hoa-table th:first-child,.digitize-page .so-hoa-table td:first-child{width:34px;}
.digitize-page .file-cell{display:flex;align-items:center;gap:10px;min-width:0;}
.digitize-page .file-cell-icon{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0;background:var(--bg);color:var(--blue-600);}
.digitize-page .file-cell-main{min-width:0;}
.digitize-page .file-cell-name{font-weight:600;color:var(--text-900);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:270px;}
.digitize-page .file-cell-meta{font-size:11px;color:var(--text-400);margin-top:2px;font-family:var(--font-num);}

.digitize-page .badge.processing{background:var(--blue-50);color:var(--blue-600);}
.digitize-page .badge.readysign{background:var(--purple-100);color:var(--purple-600);}
.digitize-page .status-error-link{display:block;margin-top:4px;font-size:10.8px;color:var(--red-600);cursor:pointer;text-decoration:underline;}

.digitize-page .assign-cell{font-size:12px;color:var(--text-900);line-height:1.5;}
.digitize-page .assign-cell a{color:inherit;text-decoration:none;}
.digitize-page .assign-cell a:hover{text-decoration:underline;}
.digitize-page .assign-cell .line2{display:block;color:var(--text-400);font-size:11px;margin-top:2px;}
.digitize-page .assign-ghost{display:inline-flex;align-items:center;gap:6px;color:var(--text-400);font-size:11.5px;font-style:italic;background:none;border:0;cursor:pointer;padding:0;}
.digitize-page .assign-ghost:hover{color:var(--blue-600);}
.digitize-page .assign-ghost i{font-size:11px;}

.digitize-page .date-cell{font-family:var(--font-num);font-size:11.5px;color:var(--text-600);white-space:nowrap;}

.digitize-page .action-bar-actions .btn-ghost i,.digitize-page .action-bar-actions .btn-primary i{margin-right:5px;}

.digitize-page .upload-hint{font-size:11.5px;color:var(--text-400);margin:10px 0 14px;display:flex;align-items:center;gap:6px;}
.digitize-page .upload-hint i{color:var(--gold-600);}
.digitize-page .upload-file-list{display:flex;flex-direction:column;gap:8px;max-height:280px;overflow-y:auto;margin-top:14px;}
.digitize-page .upload-file-row{display:flex;align-items:center;gap:10px;padding:9px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);}
.digitize-page .upload-file-row .file-cell-icon{width:30px;height:30px;font-size:12px;}
.digitize-page .upload-file-row .file-cell-name{max-width:320px;}
.digitize-page .upload-file-row .remove-file{margin-left:auto;background:none;border:0;color:var(--text-400);cursor:pointer;padding:4px;flex-shrink:0;}
.digitize-page .upload-file-row .remove-file:hover{color:var(--red-600);}
.digitize-page .upload-file-row.is-over-limit{border-color:var(--red-600);background:var(--red-100);}
.digitize-page .upload-summary{display:flex;align-items:center;justify-content:space-between;margin-top:12px;font-size:11.5px;color:var(--text-600);}
.digitize-page .upload-summary b{font-family:var(--font-num);color:var(--text-900);}
.digitize-page .upload-summary.over-limit b{color:var(--red-600);}

.digitize-page .assign-file-preview{display:flex;align-items:center;gap:12px;padding:12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);margin-bottom:16px;}
.digitize-page .assign-file-preview .file-cell-icon{width:40px;height:40px;font-size:16px;}

.digitize-page .search-select{position:relative;}
.digitize-page .search-select-input-wrap{position:relative;}
.digitize-page .search-select-input-wrap i.fa-search{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--text-400);font-size:12px;}
.digitize-page .search-select-input-wrap input{padding-left:32px;}
.digitize-page .search-select-results{position:absolute;left:0;right:0;top:calc(100% + 4px);background:var(--card);border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);max-height:260px;overflow-y:auto;z-index:30;display:none;}
.digitize-page .search-select-results.open{display:block;}
.digitize-page .search-select-result{display:flex;width:100%;gap:11px;align-items:center;padding:10px 12px;border:0;border-bottom:1px solid var(--divider);background:transparent;text-align:left;color:var(--text-900);cursor:pointer;}
.digitize-page .search-select-result:last-child{border-bottom:0;}
.digitize-page .search-select-result:hover,.digitize-page .search-select-result:focus{background:var(--blue-50);outline:none;}
.digitize-page .search-select-result-icon{width:30px;height:30px;border-radius:8px;background:var(--blue-50);color:var(--blue-600);display:flex;align-items:center;justify-content:center;flex:none;font-size:12px;}
.digitize-page .search-select-result-main{min-width:0;}
.digitize-page .search-select-result-name{display:block;font-weight:600;font-size:12.3px;}
.digitize-page .search-select-result-meta{display:block;color:var(--text-400);font-size:11px;margin-top:2px;}
.digitize-page .search-select-empty{padding:16px 14px;text-align:center;color:var(--text-400);font-size:12px;}
.digitize-page .search-select-create{display:flex;align-items:center;gap:8px;width:100%;padding:11px 12px;border:0;background:var(--bg);color:var(--blue-700);font-weight:600;font-size:12px;cursor:pointer;text-align:left;}
.digitize-page .search-select-create:hover{background:var(--blue-50);}

.digitize-page .selected-chip{display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--blue-600);background:var(--blue-50);border-radius:var(--radius-sm);margin-top:8px;}
.digitize-page .selected-chip-icon{width:30px;height:30px;border-radius:8px;background:var(--card);color:var(--blue-700);display:flex;align-items:center;justify-content:center;flex:none;font-size:12px;}
.digitize-page .selected-chip-main{min-width:0;flex:1;}
.digitize-page .selected-chip-name{display:block;font-weight:600;font-size:12.3px;color:var(--text-900);}
.digitize-page .selected-chip-meta{display:block;font-size:11px;color:var(--text-600);margin-top:2px;}
.digitize-page .selected-chip-clear{background:none;border:0;color:var(--text-400);cursor:pointer;padding:4px;flex-shrink:0;}
.digitize-page .selected-chip-clear:hover{color:var(--red-600);}

.digitize-page .quick-create-location{display:none;margin-top:10px;padding:12px;border:1px dashed var(--border);border-radius:var(--radius-sm);background:var(--bg);}
.digitize-page .quick-create-location.open{display:block;}
.digitize-page .quick-create-location .form-row-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;}
.digitize-page .quick-create-location .qc-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px;}

.digitize-page .batch-sign-list{display:flex;flex-direction:column;gap:7px;max-height:220px;overflow-y:auto;margin:12px 0 16px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);}
.digitize-page .batch-sign-row{display:flex;align-items:center;gap:9px;font-size:12px;color:var(--text-900);}
.digitize-page .batch-sign-row i{color:var(--blue-600);}
.digitize-page .batch-sign-row .skip{color:var(--text-400);text-decoration:line-through;}
.digitize-page .batch-sign-note{display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:var(--radius-sm);background:var(--amber-100);color:var(--amber-600);font-size:11.5px;margin-bottom:14px;}
.digitize-page .batch-sign-note i{margin-top:1px;}

.digitize-page .sign-method-options{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.digitize-page .sign-method-option{position:relative;display:flex;align-items:flex-start;gap:10px;padding:12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card);cursor:pointer;transition:border-color .12s,background .12s;}
.digitize-page .sign-method-option:has(input:checked){border-color:var(--blue-600);background:var(--blue-50);}
.digitize-page .sign-method-option input{position:absolute;opacity:0;width:0;height:0;}
.digitize-page .sign-method-icon{width:34px;height:34px;border-radius:9px;background:var(--bg);color:var(--blue-600);display:flex;align-items:center;justify-content:center;font-size:15px;flex-shrink:0;transition:background-color .12s,color .12s;}
.digitize-page .sign-method-option:has(input:checked) .sign-method-icon{background:var(--blue-600);color:#fff;}
.digitize-page .sign-method-title{display:block;font-size:12.8px;font-weight:700;color:var(--text-900);margin-bottom:3px;}
.digitize-page .sign-method-desc{display:block;font-size:11px;color:var(--text-400);line-height:1.5;}

.digitize-page .sign-pending-state{display:none;flex-direction:column;align-items:center;text-align:center;padding:18px 10px 4px;}
.digitize-page .sign-pending-state.show{display:flex;}
.digitize-page .sign-pending-spinner{position:relative;width:60px;height:60px;border-radius:50%;background:var(--blue-50);color:var(--blue-600);display:flex;align-items:center;justify-content:center;font-size:22px;margin-bottom:16px;}
.digitize-page .sign-pending-spinner .pulse-ring{position:absolute;inset:-6px;border-radius:50%;border:2px solid var(--blue-600);opacity:.5;animation:digitizeSignPulse 1.6s ease-out infinite;}
@keyframes digitizeSignPulse{0%{transform:scale(.85);opacity:.6;}100%{transform:scale(1.3);opacity:0;}}
.digitize-page .sign-pending-title{font-size:13.5px;font-weight:700;color:var(--text-900);margin-bottom:6px;}
.digitize-page .sign-pending-desc{font-size:12px;color:var(--text-600);line-height:1.6;margin-bottom:16px;max-width:340px;}

.preview-modal{max-width:560px;}
.digitize-page .doc-preview-wrap{display:flex;align-items:center;justify-content:center;min-height:320px;padding:16px;background:var(--bg);border-radius:var(--radius);}
.digitize-page .doc-preview-wrap iframe{width:100%;height:480px;border:0;border-radius:var(--radius-sm);background:var(--card);}
.digitize-page .doc-preview-wrap img{display:block;max-width:100%;max-height:480px;object-fit:contain;border-radius:var(--radius-sm);box-shadow:var(--shadow-sm);}
.digitize-page .doc-preview-pdf{display:flex;flex-direction:column;align-items:center;gap:10px;color:var(--text-400);}
.digitize-page .doc-preview-pdf i{font-size:56px;color:var(--red-600);}

@media(max-width:640px){
  .digitize-page .kpi-grid{grid-template-columns:repeat(2,1fr);}
  .digitize-page .so-hoa-toolbar .filter-field,.digitize-page .so-hoa-toolbar .filter-field.grow{min-width:100%;}
  .digitize-page .quick-create-location .form-row-3{grid-template-columns:1fr;}
  .digitize-page .service-status-bar{flex-wrap:wrap;}
  .digitize-page .sign-method-options{grid-template-columns:1fr;}
}