/* ============================================================
   Theme Palette
   Single source of truth — change colors here only.
   ============================================================ */
:root {
  /* Palette */
  --vault-cream:       #f5f1e8;
  --vault-paper:       #fdfaf5;
  --vault-dark:        #3e3530;
  --vault-dark-rgb:    62, 53, 48;
  --vault-primary:     #8b6f47;
  --vault-primary-rgb: 139, 111, 71;
  --vault-muted:       #c2b280;
  --vault-border:      #d9cba0;
  --vault-border-rgb:  217, 203, 160;
  --vault-thead-bg:    #eee8d6;
  --vault-accent:      #a67c52;
  --vault-sage:        #6b8e6f;
  --vault-danger:      #8e4e3a;

  /* Bootstrap semantic colors — hex + rgb pairs */
  --bs-primary:        #8b6f47;
  --bs-primary-rgb:    139, 111, 71;
  --bs-secondary:      #d9cba0;
  --bs-secondary-rgb:  217, 203, 160;
  --bs-success:        #6b8e6f;
  --bs-success-rgb:    107, 142, 111;
  --bs-info:           #8b6f47;
  --bs-info-rgb:       139, 111, 71;
  --bs-warning:        #a67c52;
  --bs-warning-rgb:    166, 124, 82;
  --bs-danger:         #8e4e3a;
  --bs-danger-rgb:     142, 78, 58;
  --bs-dark:           #3e3530;
  --bs-dark-rgb:       62, 53, 48;
  --bs-light:          #f5f1e8;
  --bs-light-rgb:      245, 241, 232;

  /* Bootstrap emphasis / subtle / border variants */
  --bs-primary-text-emphasis:     #5c4a2f;
  --bs-primary-bg-subtle:         rgba(139, 111, 71, 0.1);
  --bs-primary-border-subtle:     rgba(139, 111, 71, 0.3);
  --bs-secondary-text-emphasis:   var(--vault-dark);
  --bs-secondary-bg-subtle:       rgba(var(--vault-border-rgb), 0.15);
  --bs-secondary-border-subtle:   var(--vault-border);
  --bs-success-text-emphasis:     #3d5e40;
  --bs-success-bg-subtle:         rgba(107, 142, 111, 0.1);
  --bs-success-border-subtle:     rgba(107, 142, 111, 0.3);
  --bs-info-text-emphasis:        #5c4a2f;
  --bs-info-bg-subtle:            #f0ebe2;
  --bs-info-border-subtle:        var(--vault-border);
  --bs-warning-text-emphasis:     #7a6240;
  --bs-warning-bg-subtle:         #faf3e0;
  --bs-warning-border-subtle:     #e8dbb8;
  --bs-danger-text-emphasis:      #5f342a;
  --bs-danger-bg-subtle:          #f8e8e8;
  --bs-danger-border-subtle:      #e8c4c4;
  --bs-dark-text-emphasis:        var(--vault-dark);
  --bs-dark-bg-subtle:            rgba(var(--vault-dark-rgb), 0.1);
  --bs-dark-border-subtle:        rgba(var(--vault-dark-rgb), 0.3);
  --bs-light-text-emphasis:       var(--vault-dark);
  --bs-light-bg-subtle:           var(--vault-cream);
  --bs-light-border-subtle:       var(--vault-border);

  /* Bootstrap global overrides */
  --bs-body-bg:                var(--vault-cream);
  --bs-body-color:             var(--vault-dark);
  --bs-body-font-family:       "Noto Sans TC", system-ui, -apple-system,
    "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --bs-heading-color:          var(--vault-dark);
  --bs-border-color:           var(--vault-border);
  --bs-secondary-color:        var(--vault-muted);
  --bs-link-color-rgb:         var(--vault-primary-rgb);
  --bs-link-hover-color-rgb:   var(--vault-dark-rgb);
  --bs-link-decoration:        none;
  --bs-link-hover-decoration:  underline;
  --bs-emphasis-color:         var(--vault-dark);
  --bs-focus-ring-color:       rgba(var(--vault-primary-rgb), 0.25);
}

/* ============================================================
   Base Typography
   ============================================================ */
img {
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
}

a {
  transition: color 0.2s;
}

::selection {
  background-color: rgba(var(--vault-primary-rgb), 0.2);
  color: var(--vault-dark);
}

/* ============================================================
   Bootstrap Icons (button alignment)
   ============================================================ */
.btn:has(.bi) {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
}
.btn .bi {
  flex-shrink: 0;
}

/* ============================================================
   Buttons — Bootstrap local-variable overrides
   ============================================================ */
.btn {
  transition: all 0.2s;
}

/* Primary — warm brown fill */
.btn-primary {
  --bs-btn-bg:                 var(--vault-primary);
  --bs-btn-border-color:       var(--vault-primary);
  --bs-btn-color:              #fff;
  --bs-btn-hover-bg:           var(--vault-accent);
  --bs-btn-hover-border-color: var(--vault-accent);
  --bs-btn-hover-color:        #fff;
  --bs-btn-active-bg:          #7a6240;
  --bs-btn-active-border-color:#7a6240;
  --bs-btn-active-color:       #fff;
  --bs-btn-disabled-bg:        var(--vault-muted);
  --bs-btn-disabled-border-color: var(--vault-muted);
  --bs-btn-disabled-color:     #fff;
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(var(--vault-primary-rgb), 0.3);
}

.btn-primary:active { transform: none; }

/* Outline Primary — warm brown border */
.btn-outline-primary {
  --bs-btn-color:              var(--vault-primary);
  --bs-btn-border-color:       var(--vault-primary);
  --bs-btn-hover-bg:           var(--vault-primary);
  --bs-btn-hover-border-color: var(--vault-primary);
  --bs-btn-hover-color:        #fff;
  --bs-btn-active-bg:          #7a6240;
  --bs-btn-active-border-color:#7a6240;
  --bs-btn-active-color:       #fff;
  --bs-btn-disabled-color:     var(--vault-muted);
  --bs-btn-disabled-border-color: var(--vault-border);
}

.btn-outline-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(var(--vault-primary-rgb), 0.2);
}

.btn-outline-primary:active { transform: none; }

/* Outline Secondary — muted tan */
.btn-outline-secondary {
  --bs-btn-color:              var(--vault-muted);
  --bs-btn-border-color:       var(--vault-muted);
  --bs-btn-hover-bg:           var(--vault-muted);
  --bs-btn-hover-border-color: var(--vault-muted);
  --bs-btn-hover-color:        #fff;
  --bs-btn-active-bg:          var(--vault-border);
  --bs-btn-active-border-color:var(--vault-border);
  --bs-btn-active-color:       var(--vault-dark);
  --bs-btn-disabled-color:     var(--vault-border);
  --bs-btn-disabled-border-color: var(--vault-border);
}

/* Outline Dark — for auth pages */
.btn-outline-dark {
  --bs-btn-color:              var(--vault-dark);
  --bs-btn-border-color:       var(--vault-dark);
  --bs-btn-hover-bg:           var(--vault-dark);
  --bs-btn-hover-border-color: var(--vault-dark);
  --bs-btn-hover-color:        #fff;
  --bs-btn-active-bg:          #2e2520;
  --bs-btn-active-border-color:#2e2520;
  --bs-btn-active-color:       #fff;
}

/* ============================================================
   Navbar
   ============================================================ */
.navbar-vault {
  background-color: var(--vault-dark);
}

.navbar-vault .navbar-brand {
  letter-spacing: 0.05em;
}

.navbar-vault .nav-link {
  color: rgba(255, 255, 255, 0.85);
  transition: color 0.2s;
}

.navbar-vault .nav-link:hover,
.navbar-vault .nav-link:focus {
  color: #fff;
}

.navbar-vault .dropdown-toggle {
  color: rgba(255, 255, 255, 0.85);
}

/* ============================================================
   Cards
   ============================================================ */
.card {
  --bs-card-bg:            var(--vault-paper);
  --bs-card-border-width:  0;
  --bs-card-border-radius: 0.5rem;
  --bs-card-border-color:  var(--vault-border);
  --bs-card-cap-bg:        transparent;
  --bs-card-cap-color:     var(--vault-dark);
  box-shadow: 0 1px 4px rgba(var(--vault-dark-rgb), 0.08);
  transition: box-shadow 0.2s;
}

.card:hover {
  box-shadow: 0 4px 12px rgba(var(--vault-dark-rgb), 0.12);
}

.card-header {
  border-bottom: 1px solid var(--bs-card-border-color);
  font-weight: 600;
}

.auth-card {
  box-shadow: 0 2px 12px rgba(var(--vault-dark-rgb), 0.1);
}

.auth-card .card-body {
  padding: 2.5rem 2rem;
}

/* ============================================================
   Tables
   ============================================================ */
.table {
  --bs-table-bg: transparent;
  --bs-table-hover-bg: rgba(var(--vault-border-rgb), 0.15);
  --bs-table-border-color: var(--vault-border);
}

.table > thead {
  font-size: 0.875rem;
}

.table > thead th {
  border-bottom: 2px solid var(--vault-border);
  font-weight: 600;
}

.table > tbody > tr > td {
  border-bottom: 1px solid rgba(var(--vault-border-rgb), 0.4);
}

.table-light {
  --bs-table-bg: rgba(var(--vault-border-rgb), 0.25);
  --bs-table-border-color: var(--vault-border);
}

/* ============================================================
   Forms
   ============================================================ */
.form-control:focus,
.form-select:focus {
  border-color: var(--vault-primary);
  box-shadow: 0 0 0 0.2rem rgba(var(--vault-primary-rgb), 0.15);
}

.form-label {
  font-weight: 500;
  font-size: 0.875rem;
}

.form-check-input:checked {
  background-color: var(--vault-primary);
  border-color: var(--vault-primary);
}

.form-check-input:focus {
  border-color: var(--vault-primary);
  box-shadow: 0 0 0 0.2rem rgba(var(--vault-primary-rgb), 0.15);
}

/* Toggle switches read as clickable */
.form-switch .form-check-input,
.form-switch .form-check-label {
  cursor: pointer;
}

/* ============================================================
   Badges
   ============================================================ */
.badge {
  font-weight: 500;
}

.badge.text-bg-secondary {
  color: var(--vault-dark);
}

.badge.text-bg-info {
  background-color: rgba(var(--vault-primary-rgb), 0.15) !important;
  color: var(--vault-dark);
}

.badge.text-bg-light {
  background-color: rgba(var(--vault-border-rgb), 0.3) !important;
  color: var(--vault-dark);
}

/* ============================================================
   Nav (shared link color for pills + tabs)
   ============================================================ */
.nav {
  --bs-nav-link-color: var(--vault-primary);
  --bs-nav-link-hover-color: var(--vault-dark);
}

.nav-pills {
  --bs-nav-pills-link-active-bg: var(--vault-primary);
  --bs-nav-pills-link-active-color: #fff;
}

.nav-tabs {
  --bs-nav-tabs-border-color: var(--vault-border);
  --bs-nav-tabs-link-active-color: var(--vault-primary);
  --bs-nav-tabs-link-active-bg: var(--vault-cream);
  --bs-nav-tabs-link-active-border-color:
    var(--vault-border) var(--vault-border) var(--vault-cream);
  --bs-nav-tabs-link-hover-border-color:
    var(--vault-border) var(--vault-border) var(--vault-border);
}

/* ============================================================
   Pagination
   ============================================================ */
.pagination {
  --bs-pagination-color:            var(--vault-primary);
  --bs-pagination-border-color:     var(--vault-border);
  --bs-pagination-hover-color:      #fff;
  --bs-pagination-hover-bg:         var(--vault-primary);
  --bs-pagination-hover-border-color: var(--vault-primary);
  --bs-pagination-active-bg:        var(--vault-primary);
  --bs-pagination-active-border-color: var(--vault-primary);
  --bs-pagination-active-color:     #fff;
  --bs-pagination-disabled-color:   var(--vault-muted);
  --bs-pagination-disabled-border-color: var(--vault-border);
}

/* ============================================================
   Dropdowns
   ============================================================ */
.dropdown-menu {
  --bs-dropdown-bg:               var(--vault-paper);
  --bs-dropdown-border-color:     var(--vault-border);
  --bs-dropdown-link-hover-bg:    rgba(var(--vault-border-rgb), 0.2);
  --bs-dropdown-link-hover-color: var(--vault-dark);
  --bs-dropdown-link-active-bg:   var(--vault-primary);
  --bs-dropdown-divider-bg:       var(--vault-border);
  box-shadow: 0 4px 12px rgba(var(--vault-dark-rgb), 0.1);
}

/* ============================================================
   List Group
   ============================================================ */
.list-group {
  --bs-list-group-bg:                   var(--vault-paper);
  --bs-list-group-border-color:         var(--vault-border);
  --bs-list-group-active-bg:            var(--vault-primary);
  --bs-list-group-active-border-color:  var(--vault-primary);
  --bs-list-group-action-hover-bg:      rgba(var(--vault-border-rgb), 0.15);
}

/* ============================================================
   Misc Components
   ============================================================ */
hr {
  border: none;
  height: 1px;
  background: linear-gradient(
    to right, transparent, var(--vault-border), transparent
  );
}

.toast {
  --bs-toast-border-width: 0;
  --bs-toast-box-shadow: 0 4px 12px rgba(var(--vault-dark-rgb), 0.15);
}

.modal {
  --bs-modal-bg:                   var(--vault-paper);
  --bs-modal-border-color:         transparent;
  --bs-modal-header-border-color:  var(--vault-border);
}

.modal-content {
  box-shadow: 0 8px 24px rgba(var(--vault-dark-rgb), 0.15);
}

/* ============================================================
   Footer
   ============================================================ */
.footer-vault {
  border-top: 1px solid var(--vault-border);
  color: var(--vault-muted);
  font-size: 0.85rem;
}

/* ============================================================
   Upload Drop Zone
   ============================================================ */
.border-dashed {
  border-style: dashed !important;
}

/* Multi-asset upload rows */
.upload-asset-row .card-header input {
  border: none;
  background: transparent;
  box-shadow: none;
}
.upload-asset-row .card-header input:focus {
  box-shadow: none;
}

.upload-dropzone {
  transition: border-color 0.2s, background-color 0.2s;
}
.upload-dropzone-trigger {
  cursor: pointer;
  padding: 0.75rem 0;
}
.upload-dropzone-trigger:hover {
  color: var(--vault-primary);
}

.upload-ghost-row {
  opacity: 0.5;
  transition: opacity 0.2s;
}
.upload-ghost-row:hover,
.upload-ghost-row:focus-within {
  opacity: 0.8;
}

/* File card (shared base for upload + edit file thumbnails) */
.file-card {
  width: 110px;
  text-align: center;
  position: relative;
  cursor: grab;
  transition: opacity 0.2s;
}
.file-card:active { cursor: grabbing; }
.file-card-inner {
  width: 110px;
  height: 110px;
  border: 1px solid var(--vault-border);
  border-radius: 0.375rem;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--vault-cream);
  position: relative;
}
.file-card-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.file-card-icon {
  font-size: 2rem;
  color: var(--vault-muted);
}
.file-card-remove {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 0.625rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.2s;
  cursor: pointer;
}
.file-card:hover .file-card-remove { opacity: 1; }
.file-card-remove:disabled {
  cursor: not-allowed;
  opacity: 0 !important;
}
.file-card-label {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  line-height: 1.3;
}

/* Upload file strip */
.upload-file-strip {
  max-height: 320px;
  overflow-y: auto;
}
.upload-file-strip .file-card:hover {
  background-color: rgba(0, 0, 0, 0.04);
  border-radius: 0.375rem;
}
.upload-file-strip .file-card-inner {
  height: 90px;
}

/* ============================================================
   Preview Popup
   ============================================================ */
.preview-popup-float {
  display: none;
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  padding: 4px;
  border-radius: 4px;
  background: var(--vault-paper);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.preview-popup-float img {
  display: block;
}

.spinner-border.text-secondary {
  color: var(--vault-muted) !important;
}

/* ============================================================
   Tagify Overrides
   ============================================================ */
.tagify {
  --tags-border-color: var(--vault-border);
  --tags-hover-border-color: var(--vault-primary);
  --tags-focus-border-color: var(--vault-primary);
  --tag-bg: rgba(var(--vault-primary-rgb), 0.12);
  --tag-text-color: var(--vault-dark);
  --tag-remove-btn-color: var(--vault-muted);
  --tag-remove-btn-color--hover: var(--vault-dark);
  --tag-pad: 0.1rem 0.35rem;
  min-height: 0;
  padding: 0;
  font-size: 0.875rem;
  border-radius: 0.25rem;
  font-family: var(--bs-body-font-family);
  background: var(--vault-paper);
}

.tagify > .tagify__input {
  margin: 1px;
  padding: 0.2rem 0.5rem;
  min-height: 0;
  line-height: 1.5;
}

.tagify--focus {
  border-color: var(--vault-primary);
  box-shadow: 0 0 0 0.2rem rgba(var(--vault-primary-rgb), 0.15);
}

.tagify__dropdown {
  background: var(--vault-paper);
  border: 1px solid var(--vault-border);
  box-shadow: 0 4px 12px rgba(var(--vault-dark-rgb), 0.1);
  border-radius: 0.375rem;
}

.tagify__dropdown__item--active {
  background: rgba(var(--vault-primary-rgb), 0.1);
  color: var(--vault-dark);
}

.filter-form .tagify {
  overflow: hidden;
}

/* ============================================================
   Semantic Utilities
   ============================================================ */

/* Public-facing field accent */
.field-public {
  border-left: 3px solid var(--vault-sage);
  padding-left: 0.75rem;
}
.field-public-form {
  border: 1px solid var(--vault-sage);
  border-radius: 0.5rem;
  padding: 0.75rem;
  background: rgba(107, 142, 111, 0.04);
}
.field-public-label {
  color: var(--vault-sage);
  font-weight: 600;
}
.field-public-row {
  background: rgba(107, 142, 111, 0.06);
}

/* Download page preview column */
.download-preview-col { width: 60px; }
@media (min-width: 768px) {
  .download-preview-col { width: 100px; }
}

/* Detail page two-column property list */
.detail-props {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0;
}
.detail-props dt {
  padding: 0.5rem 0.75rem 0.5rem 0;
  border-bottom: 1px solid var(--vault-border);
  font-weight: 600;
  color: var(--vault-primary);
  white-space: nowrap;
}
.detail-props dd {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--vault-border);
  margin-bottom: 0;
  overflow-wrap: break-word;
  word-break: break-word;
  min-width: 0;
}
.detail-props dt:last-of-type,
.detail-props dd:last-of-type {
  border-bottom: none;
}

/* Audit change log (異動紀錄) */
.audit-entry + .audit-entry {
  border-top: 1px solid var(--vault-border);
  padding-top: 0.4rem;
  margin-top: 0.4rem;
}
.audit-entry-title {
  font-weight: 600;
}
.audit-entry-model {
  display: inline-block;
  margin-right: 0.4rem;
  padding: 0 0.4rem;
  border-radius: 0.25rem;
  background: var(--vault-thead-bg);
  color: var(--vault-accent);
  font-weight: 400;
  font-size: 0.8em;
}
.audit-changes {
  margin-left: 0.85rem;
  margin-top: 0.1rem;
}
.audit-field {
  display: inline-block;
  min-width: 4.5rem;
  color: var(--vault-accent);
}
.audit-field::after {
  content: "：";
}
.audit-old {
  color: var(--vault-muted);
  text-decoration: line-through;
}

/* Detail page sticky title bar — opaque page background when pinned */
.detail-title-bar {
  background: var(--vault-cream);
}

/* Detail page carousel preview */
.detail-preview-panel {
  min-height: 200px;
}
.detail-carousel-slide {
  height: 640px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.detail-carousel-img {
  max-height: 600px;
  max-width: 100%;
  object-fit: contain;
}
.detail-preview-panel .carousel-control-prev,
.detail-preview-panel .carousel-control-next {
  width: 2.5rem;
  opacity: 0.6;
}
.detail-preview-panel .carousel-control-prev:hover,
.detail-preview-panel .carousel-control-next:hover {
  opacity: 1;
}
.detail-preview-panel .carousel-control-prev-icon,
.detail-preview-panel .carousel-control-next-icon {
  filter: none;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  width: 2rem;
  height: 2rem;
  background-size: 50%;
}

/* Detail page file property list (compact) */
.detail-file-props {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0;
  font-size: 0.875rem;
}
.detail-file-props dt {
  padding: 0.25rem 0.75rem 0.25rem 0;
  font-weight: 600;
  color: var(--vault-primary);
  white-space: nowrap;
}
.detail-file-props dd {
  padding: 0.25rem 0;
  margin-bottom: 0;
  overflow-wrap: break-word;
  word-break: break-all;
  min-width: 0;
}

/* Detail page thumbnail strip (multi-file assets) */
.detail-thumb-strip {
  position: relative;
  z-index: 3;
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
  scrollbar-width: thin;
}
.detail-thumb-strip::-webkit-scrollbar {
  height: 4px;
}
.detail-thumb-btn {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  opacity: 0.6;
  padding: 0;
  border: 2px solid var(--vault-border);
  border-radius: 0.375rem;
  background: var(--vault-paper);
  cursor: pointer;
  overflow: hidden;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.detail-thumb-btn:hover {
  border-color: var(--vault-primary);
  opacity: 1;
}
.detail-thumb-active {
  border-color: var(--vault-primary);
  box-shadow: 0 0 0 3px rgba(var(--vault-primary-rgb), 0.4);
  opacity: 1;
}
.detail-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.detail-thumb-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--vault-muted);
  font-size: 1.25rem;
}

/* Thumbnail component (polaroid card fan, bottom-left pivot)
 *
 * Image: 60x45 + 3px border = 66x51 rendered.
 * Rotations: ±15deg around bottom-left, ±20px horizontal shift.
 * Container sized to enclose all rotated corners:
 *   width  = 132  (leftmost -33 to rightmost +97, offset left:34)
 *   height =  86  (topmost  -15 to bottommost +68, offset bottom:18)
 */
.thumbnail {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 132px;
  height: 86px;
}
.thumbnail img,
.thumbnail-protected {
  pointer-events: none;
}
.thumbnail img {
  width: 60px;
  height: 45px;
  object-fit: cover;
  border-radius: 4px;
  border: 3px solid #fff;
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.22),
    0 1px 3px rgba(0, 0, 0, 0.12);
  background: #fff;
}
.thumbnail-two > a,
.thumbnail-three > a {
  position: absolute;
  bottom: 18px;
  left: 34px;
  transform-origin: bottom left;
  transition: transform 0.3s ease;
  cursor: pointer;
}
.thumbnail > a.fan-active {
  z-index: 10 !important;
  transform: none !important;
}
.thumbnail-two > a:nth-child(1) {
  z-index: 1;
  transform: translateX(-20px) rotate(-15deg);
}
.thumbnail-two > a:nth-child(2) {
  z-index: 2;
}
.thumbnail-three > a:nth-child(1) {
  z-index: 1;
  transform: translateX(20px) rotate(15deg);
}
.thumbnail-three > a:nth-child(2) {
  z-index: 2;
  transform: translateX(-20px) rotate(-15deg);
}
.thumbnail-three > a:nth-child(3) {
  z-index: 3;
}

/* Chart containers */
.chart-container {
  position: relative;
  height: 280px;
}
.chart-container-tall {
  height: 400px;
}

/* Stats table sortable headers */
.stats-sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: color 0.2s;
}
.stats-sortable:hover {
  color: var(--vault-primary);
}
.stats-sort-active {
  color: var(--vault-primary);
}

/* Content formatting */
.formatted-text { white-space: pre-line; }

/* Narrow page containers */
.container-narrow { max-width: 600px; }
.container-xs { max-width: 480px; }

/* Preview images (tables, edit forms) */
.preview-xs { max-height: 50px; }

/* Card cover images / placeholders (fixed height) */
.card-cover-sm { height: 160px; }

/* Import-review file preview: larger inline preview, shown as a wrapping
   gallery beside the raw/parsed table */
/* Review card images: first scan full-size, the rest as a thumbnail list. */
.review-first-tile { max-width: 360px; }
/* Fixed box (reserved via aspect-ratio) so the card does not reflow when the
   lazily-signed image replaces the placeholder; object-fit-contain fits any
   real aspect inside without distortion. */
.review-first-preview {
  width: 360px;
  max-width: 100%;
  aspect-ratio: 3 / 4;
  cursor: pointer;
}
.review-rest-list { max-width: 220px; }
/* Let the filename caption shrink and wrap instead of widening the image list
   (flex children default to min-width:auto, which ignores the list's cap). */
.review-rest-list li { min-width: 0; }
.caption { min-width: 0; overflow-wrap: anywhere; }
/* Person field label sits inline with its input at a fixed width. */
.review-field-label { flex: 0 0 3rem; }
/* Fixed column widths so long values (e.g. 特別記載) wrap and the table never
   grows past its bounds, whatever the content. */
.review-parse-table {
  table-layout: fixed;
  width: 33rem;
  max-width: 100%;
}
.review-parse-table td,
.review-parse-table th { overflow-wrap: anywhere; }
.review-parse-table td:nth-child(1),
.review-parse-table th:nth-child(1) { width: 4.5rem; }
.review-parse-table td:nth-child(2),
.review-parse-table th:nth-child(2) { width: 11rem; }
/* Sender / receiver panels sit below the table at the same width; equal
   columns with the swap between. min-width:0 lets the inputs shrink to fit. */
.review-persons { width: 33rem; max-width: 100%; }
.review-person-panel { min-width: 0; }
.review-swap-col { flex: 0 0 auto; }
/* Keep the person tag input on the tags' row; Tagify's 110px default
   min-width forces it to wrap in the narrow panel, doubling the height. */
.review-person-panel .tagify__input { min-width: 2rem; }
.review-thumb {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  cursor: pointer;
}

/* Import review: keyboard selection, owner highlight, action countdown */
[x-cloak] { display: none !important; }
/* Person names are emphasised by weight only (no background); the owner
   additionally goes blue. Reset the <mark> default background/padding. */
.review-highlight {
  background-color: transparent;
  padding: 0;
  font-weight: 600;
}
.review-owner {
  color: #0d6efd;
}
.review-key {
  display: inline-block;
  min-width: 1.5em;
  margin: 0 0.15em;
  padding: 0.1em 0.4em;
  font-size: 0.8em;
  line-height: 1.3;
  text-align: center;
  color: var(--vault-dark);
  background-color: #fff;
  border: 1px solid var(--vault-border);
  border-radius: 4px;
  box-shadow: 0 1px 0 var(--vault-border);
}
/* Decision tints: the whole card reflects its confirm/reject state so a
   reviewer can scan decisions at a glance. Rejected uses a muted rose (not an
   alarming red). Selection is an outline (not a background) so it stays
   distinct from both the .card:hover shadow and these state tints. */
.review-confirmed {
  background-color: rgba(var(--bs-success-rgb), 0.1);
}
.review-rejected {
  background-color: rgba(var(--bs-danger-rgb), 0.06);
}
.review-selected {
  outline: 3px solid var(--vault-primary);
  outline-offset: 1px;
}
.review-countdown { position: relative; overflow: hidden; }
.review-countdown-fill {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.45);
  pointer-events: none;
}
/* Fixed dock of queued confirm/reject countdowns; a tall card's own
   countdown button can sit below the fold, this one never does. */
.review-pending-dock {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1050;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
  max-width: calc(100vw - 2rem);
}
/* Each countdown hugs its label; only a very long one truncates. */
.review-pending-dock button {
  max-width: 20rem;
}
/* Collapsed by default: only the newest countdown (last child) shows;
   hovering the dock expands the earlier ones upward. */
.review-pending-dock:not(:hover) button:not(:last-child) {
  display: none;
}

/* Caption-sized text */
.caption { font-size: 0.75rem; }

/* File strip (shared upload + edit) */
.file-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-start;
}
.file-card-grip {
  position: absolute;
  bottom: 4px;
  right: 4px;
  color: var(--vault-muted);
  font-size: 0.75rem;
  opacity: 0;
  transition: opacity 0.2s;
  cursor: grab;
  touch-action: none;
}
.file-card:hover .file-card-grip { opacity: 1; }
@media (hover: none) {
  .file-card-grip { opacity: 0.5; }
}
.file-card-deleted {
  opacity: 0.45;
}
.file-card-deleted .file-card-inner {
  border-style: dashed;
}
.file-card-deleted:hover .file-card-remove {
  opacity: 1 !important;
}

/* 對應圖檔 manual matching board */
.match-thumb {
  width: 96px;
  height: 96px;
}
.match-dropzone {
  min-height: 122px;
  padding: 0.5rem;
  border: 1px dashed var(--vault-border);
  border-radius: 0.5rem;
  transition: background-color 0.15s, border-color 0.15s;
}
/* While a tile is dragging, hint every drop zone and highlight the one the
   SortableJS ghost is hovering (the drop target). */
body:has(.sortable-ghost) .match-dropzone {
  border-color: var(--vault-primary);
}
.match-dropzone:has(.sortable-ghost) {
  border-style: solid;
  background-color: rgba(var(--vault-primary-rgb), 0.08);
}
.match-tile-name {
  line-height: 1.2;
  margin-top: 0.25rem;
  word-break: break-all;
}
.match-dropzone-empty {
  padding: 0.75rem;
  text-align: center;
}
/* Hide the "drag here" hint once the zone holds an image (:has re-evaluates
   live as SortableJS moves tiles in and out). */
.match-dropzone:has(.match-tile) + .match-dropzone-empty {
  display: none;
}
/* The 多餘圖檔 pool tracks the reviewer down the (long) record list. */
.match-pool-wrap {
  position: sticky;
  top: 1rem;
}
/* Once a stray image is placed (matched or built into an asset) its pool group
   has no tiles left, so drop it — nothing remains to act on. */
.match-pool-group:not(:has(.match-tile)) {
  display: none;
}
.match-pool {
  max-height: calc(100vh - 8rem);
  overflow-y: auto;
}
.file-card-lock {
  position: absolute;
  bottom: 4px;
  right: 4px;
  color: var(--vault-muted);
  font-size: 0.75rem;
  opacity: 0.7;
}

/* Upload dropzone in edit file strip */
.upload-dropzone .file-card-inner {
  border: 2px dashed var(--vault-border);
  background: transparent;
  color: var(--vault-muted);
  font-size: 1.5rem;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
}
.upload-dropzone:hover .file-card-inner {
  border-color: var(--vault-primary);
  color: var(--vault-primary);
}

/* File viewer (modal) */
.viewer-container {
  width: 100%;
  height: calc(100vh - 56px);
  background: #1a1a1a;
  user-select: none;
  -webkit-user-drag: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.viewer-container canvas {
  user-select: none;
  -webkit-user-drag: none;
}
.viewer-container video {
  max-width: 100%;
  max-height: 100%;
}
.viewer-container audio { width: 60%; }
.viewer-container pre {
  color: #e0e0e0;
  background: transparent;
  padding: 2rem;
  overflow: auto;
  width: 100%;
  height: 100%;
  user-select: none;
  margin: 0;
}

/* File viewer (standalone page) */
.viewer-standalone {
  width: 100%;
  height: calc(100vh - 200px);
  background: #1a1a1a;
  user-select: none;
  -webkit-user-drag: none;
}

/* Table column sizing */
.col-action { width: 40px; }

/* Expired/disabled table rows */
.row-expired {
  opacity: 0.55;
}
.row-expired:hover {
  opacity: 0.75;
}

/* Empty cell placeholder */
.cell-empty {
  color: var(--vault-border);
}


/* ============================================================
   Scrollbar
   ============================================================ */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--vault-cream); }
::-webkit-scrollbar-thumb {
  background: var(--vault-muted);
  border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--vault-primary);
}

/* ============================================================
   Help Tooltips
   ============================================================ */
.help-tip {
  color: var(--vault-muted);
  font-size: 0.75em;
  cursor: help;
  vertical-align: middle;
  margin-left: 0.25em;
  transition: color 0.2s;
}
h1 .help-tip,
h2 .help-tip,
h3 .help-tip,
h4 .help-tip,
h5 .help-tip,
h6 .help-tip {
  font-size: 0.875rem;
  font-weight: 400;
}

.help-tip:hover {
  color: var(--vault-primary);
}

.tooltip-inner {
  text-align: left;
}

/* ============================================================
   Sticky Table Headers (desktop only — mobile needs scroll)
   ============================================================ */
@media (min-width: 768px) {
  .table-responsive {
    overflow: visible;
  }
  .table > tbody {
    position: relative;
    z-index: 0;
  }
  .table > thead > tr > th {
    position: sticky;
    top: -1px;
    z-index: 2;
    box-shadow: inset 0 -1px 0 var(--vault-border);
  }
}
.table > thead > tr > th {
  background-color: var(--vault-thead-bg);
}
.table-light > thead > tr > th,
.table > thead.table-light > tr > th {
  background-color: var(--vault-thead-bg);
}

/* ============================================================
   Expandable Help Panels
   ============================================================ */
.help-panel {
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
}

.help-panel .accordion-button {
  padding: 0.5rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--vault-muted);
  background: transparent;
  box-shadow: none;
  justify-content: flex-start;
  gap: 0;
}

.help-panel .accordion-button:not(.collapsed) {
  color: var(--vault-primary);
  background: transparent;
}

.help-panel .accordion-button::after {
  width: 0.875rem;
  height: 0.875rem;
  background-size: 0.875rem;
  margin-left: 0.5rem;
  flex-shrink: 0;
}

.help-panel .accordion-body {
  padding: 0.5rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--vault-dark);
}

.help-panel .accordion-item {
  border: none;
  background: transparent;
}

/* ============================================================
   Login Page — Split layout with full-screen background
   ============================================================ */
.login-page {
  margin: 0;
  padding: 0;
  height: 100vh;
  overflow: hidden;
  background-color: var(--vault-dark);
}

/* Background image — full viewport */
.login-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
}

.login-bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Overlay — heavier on the left panel for card readability */
.login-overlay {
  position: fixed;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to right,
    rgba(40, 32, 26, 0.82) 0%,
    rgba(40, 32, 26, 0.65) 45%,
    rgba(40, 32, 26, 0.30) 70%,
    rgba(40, 32, 26, 0.15) 100%
  );
}

/* Split layout — left panel + right hero (transparent) */
.login-layout {
  position: relative;
  z-index: 2;
  display: flex;
  height: 100vh;
}

.login-panel {
  width: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.login-hero {
  width: 50%;
}

/* Glassmorphism card */
.login-card {
  width: 100%;
  max-width: 380px;
  border-radius: 1rem;
  background: rgba(253, 250, 245, 0.10);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border: 1px solid rgba(253, 250, 245, 0.15);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    0 1px 0 rgba(255, 255, 255, 0.06) inset;
  display: flex;
  flex-direction: column;
  animation: login-card-enter 0.6s ease-out;
}

@keyframes login-card-enter {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.login-card-inner {
  padding: 3rem 2.5rem 2rem;
  text-align: center;
}

/* Brand icon */
.login-brand {
  margin-bottom: 1.25rem;
}

.login-brand-icon {
  font-size: 2.5rem;
  color: var(--vault-cream);
  opacity: 0.85;
}

/* Title in serif */
.login-title {
  font-family: "Noto Serif TC", "Noto Sans TC", serif;
  font-weight: 700;
  font-size: 1.75rem;
  letter-spacing: 0.08em;
  color: var(--vault-cream);
  margin-bottom: 0.5rem;
}

.login-subtitle {
  font-family: "Noto Sans TC", sans-serif;
  font-size: 0.875rem;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: rgba(245, 241, 232, 0.65);
  margin-bottom: 0;
}

/* Decorative divider */
.login-divider {
  width: 48px;
  height: 1px;
  margin: 1.75rem auto;
  background: linear-gradient(
    to right,
    transparent,
    rgba(245, 241, 232, 0.4),
    transparent
  );
}

/* Google login button */
.login-btn-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.75rem 1.25rem;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--vault-dark);
  background: rgba(253, 250, 245, 0.92);
  border: 1px solid rgba(253, 250, 245, 0.6);
  border-radius: 0.5rem;
  transition: all 0.25s ease;
  text-decoration: none;
}

.login-btn-google:hover {
  background: rgba(253, 250, 245, 1);
  color: var(--vault-dark);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

.login-btn-google:active {
  transform: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.login-google-icon {
  flex-shrink: 0;
}

/* Dev login separator */
.login-dev-separator {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  color: rgba(245, 241, 232, 0.35);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.login-dev-separator::before,
.login-dev-separator::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(245, 241, 232, 0.15);
}

/* Dev login button */
.login-btn-dev {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.625rem 1.25rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: rgba(245, 241, 232, 0.65);
  background: rgba(245, 241, 232, 0.06);
  border: 1px solid rgba(245, 241, 232, 0.12);
  border-radius: 0.5rem;
  transition: all 0.25s ease;
  text-decoration: none;
}

.login-btn-dev:hover {
  color: rgba(245, 241, 232, 0.9);
  background: rgba(245, 241, 232, 0.12);
  border-color: rgba(245, 241, 232, 0.25);
  text-decoration: none;
}

/* Card footer */
.login-card-footer {
  padding: 0.875rem 2.5rem;
  text-align: center;
  border-top: 1px solid rgba(245, 241, 232, 0.08);
  color: rgba(245, 241, 232, 0.3);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
}

/* Mobile — centered card over full-bleed background */
@media (max-width: 767.98px) {
  .login-bg-img {
    object-position: 70% center;
  }

  .login-overlay {
    background: rgba(40, 32, 26, 0.7);
  }

  .login-layout {
    justify-content: center;
  }

  .login-panel {
    width: 100%;
    padding: 1.5rem;
  }

  .login-hero {
    display: none;
  }

  .login-card {
    max-width: 100%;
    border-radius: 0.875rem;
  }

  .login-card-inner {
    padding: 2rem 1.75rem 1.5rem;
  }

  .login-title {
    font-size: 1.5rem;
  }

  .login-card-footer {
    padding: 0.75rem 1.75rem;
  }
}

/* Filter collapse: always visible on sm+ */
@media (min-width: 576px) {
  .filter-collapse {
    display: block !important;
  }
}

/* ============================================================
   Mobile Responsive (iPhone 16 — 390px)
   ============================================================ */
@media (max-width: 575.98px) {
  /* Tighter container padding */
  main.container {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }

  /* Smaller page headings */
  main h2 {
    font-size: 1.35rem;
  }

  /* Filter form: full-width inputs, override size attr */
  .filter-form input[size] {
    width: 100% !important;
  }
  .filter-form .btn {
    width: 100%;
  }

  /* Tables: smaller text on mobile */
  .table {
    font-size: 0.8125rem;
  }
  .table th,
  .table td {
    padding: 0.4rem 0.35rem;
  }

  /* Tabs: smaller text */
  .nav-tabs .nav-link {
    font-size: 0.8125rem;
    padding: 0.375rem 0.5rem;
  }

  /* Cards: reduce padding */
  .card-body {
    padding: 0.75rem;
  }
}

/* ============================================================
   Asset Relationship Timeline
   ============================================================ */
.asset-timeline {
  position: relative;
  padding-left: 0.5rem;
}

.timeline-item {
  display: flex;
  gap: 0.75rem;
  min-height: 4rem;
}

.timeline-marker {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  width: 1rem;
  padding-top: 0.25rem;
}

.timeline-dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--vault-muted);
  border: 2px solid var(--vault-border);
  flex-shrink: 0;
}

.timeline-dot-current {
  width: 0.75rem;
  height: 0.75rem;
  background: var(--vault-accent);
  border-color: var(--vault-accent);
}

.timeline-line {
  width: 2px;
  flex-grow: 1;
  background: var(--vault-border);
  margin-top: 0.25rem;
}

.timeline-content {
  flex-grow: 1;
  padding-bottom: 1rem;
}

.timeline-date {
  font-size: 0.75rem;
  color: var(--vault-muted);
  margin-bottom: 0.25rem;
}

.timeline-card {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--vault-border);
  border-radius: 0.375rem;
  background: var(--vault-paper);
  font-size: 0.875rem;
}

a.timeline-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s;
}

a.timeline-card-link:hover {
  border-color: var(--vault-accent);
}

.timeline-card-current {
  border-color: var(--vault-accent);
  border-width: 2px;
  background: rgba(var(--vault-accent-rgb, 180, 157, 115), 0.08);
}

.timeline-arrow {
  color: var(--vault-muted);
  font-size: 0.875rem;
}
