/**
 * VendorPlus core styles — part 3 of 10: Modals, image editor, media files and uploaders
 *
 * Split from the single 18,135-line vendor-plus.css. The parts are chained as
 * style dependencies and MUST load in numeric order: rules here are overridden
 * by later parts, and 173 selector pairs in this sheet set the same property
 * twice. Reordering the parts changes computed styles.
 *
 * Do not reorder rules between parts. To verify the split is still faithful:
 *     php vendorplus-core/tests/stylesheet-split-guard-test.php
 *
 * Lines 2430-7039 of the original file.
 */

/* ================================
   Image Editor Modal (Cropper.js)
   ================================ */
.vplus-editor-modal .modal-body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.vplus-editor-canvas {
  flex: 1 1 auto;
  min-height: 300px;
  max-height: 60vh;
  overflow: hidden;
  background: #1a1a2e;
  position: relative;
}
.vplus-editor-canvas.vplus-editor-loading::after {
  content: "\f110";
  font-family: "Font Awesome 7 Pro", "Font Awesome 6 Pro";
  font-weight: 400;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 2rem;
  color: rgba(255, 255, 255, 0.7);
  animation: fa-spin 1s linear infinite;
}
.vplus-editor-canvas img {
  display: block;
  max-width: 100%;
}
.vplus-editor-toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: #f8f9fa;
  border-top: 1px solid #dee2e6;
  flex-wrap: wrap;
}
.vplus-editor-tools {
  display: flex;
  gap: 2px;
}
.vplus-editor-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  background: #fff;
  color: #333;
  font-size: 0.85rem;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.vplus-editor-btn:hover {
  background: #e9ecef;
  border-color: #ced4da;
}
.vplus-editor-btn:active {
  background: #dee2e6;
}
.vplus-editor-ratios {
  display: flex;
  gap: 2px;
}
.vplus-editor-ratio {
  padding: 0.25rem 0.5rem;
  font-size: 0.7rem;
  font-weight: 600;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  background: #fff;
  color: #555;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}
.vplus-editor-ratio:hover {
  background: #e9ecef;
}
.vplus-editor-ratio.active {
  background: var(--bs-primary, #3b82f6);
  border-color: var(--bs-primary, #3b82f6);
  color: #fff;
}
@media (max-width: 575.98px) {
  .vplus-editor-canvas {
    max-height: 50vh;
  }
  .vplus-editor-toolbar {
    justify-content: center;
  }
}

.form-floating > label {
  color: #000000;
  font-weight: var(--vplus-font-weight-light);
  opacity: 1;
}

.input-group.input-group.input-group:has(.invalid-feedback)
  .input-group-text
  + .form-floating
  .form-control {
  border-right: 1px solid var(--bs-border-color);
}
.input-group.input-group.input-group:has(.invalid-feedback)
  .input-group-text
  + .form-floating
  .form-control,
.input-group.input-group.input-group:has(.invalid-feedback)
  .form-floating
  + .btn,
.input-group.input-group.input-group:has(.invalid-feedback)
  .form-floating
  + .input-group-text {
  border-top-right-radius: var(--bs-border-radius);
  border-bottom-right-radius: var(--bs-border-radius);
}

.card-featured {
  --bs-card-border-color: var(--bs-warning);
  border-color: var(--bs-warning) !important;
  box-shadow:
    0 0 12px 4px rgba(var(--bs-warning-rgb), 0.4),
    0 0 0 2px rgba(var(--bs-warning-rgb), 0.6);
}

.form-field-combine {
  display: flex;
}
.form-field-combine > .form-field-combine-item {
  flex: 1;
}
.form-field-combine > .form-field-combine-item:not(:last-child) input,
.form-field-combine > .form-field-combine-item:not(:last-child) select {
  border-radius: 0;
  border-right: 0;
}
.form-field-combine > .form-field-combine-item:first-child input,
.form-field-combine > .form-field-combine-item:first-child select {
  border-radius: var(--bs-border-radius) 0 0 var(--bs-border-radius);
  border-right: 0;
}
.form-field-combine > .form-field-combine-item:last-child input,
.form-field-combine > .form-field-combine-item:last-child select {
  border-radius: 0 var(--bs-border-radius) var(--bs-border-radius) 0;
  border-left-style: dashed;
}

/* Auction Date & Time combine groups (Bidding Start/End): the date + time
   fields sit side-by-side (flex, 50/50). In the narrow ~360px tablet-portrait
   col-md-6 the time field's floating label clips ("Bidding Start Time" →
   "Bidding Start…"). Below lg, stack the two items so each gets the full column
   width and its label fits, separated by a gap. Scoped to the date/time block
   so other form-field-combine groups are untouched. */
@media (max-width: 991.98px) {
  #vplus-auction-datetime .form-field-combine {
    flex-direction: column;
    gap: 0.5rem;
  }
}

#vplus-sign-in-form .row {
  gap: 1rem;
}

[data-ref].invalid-feedback:empty {
  display: none;
}
[data-ref].invalid-feedback {
  display: block;
}

.row > div > blockquote:last-child {
  margin: 0;
}

.alert:empty {
  display: none;
}

.vplus-table-header {
  font-weight: bold;
}
.ghost-item > div:not(.image-box) {
  display: none;
}
.ghost-item .image-box {
  opacity: 0.5;
  border: 2px dashed #ccc;
}
.ghost-item img {
  opacity: 0;
}

.vplus-file-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  /* Prevent accidental text selection during drag/scroll gestures */
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.vplus-file-item {
  --bs-card-border-width: var(--bs-border-width);
  --bs-card-border-color: var(--bs-border-color-translucent);
  --bs-card-border-radius: var(--bs-border-radius);
  --bs-card-bg: var(--bs-body-bg);
  position: relative;
  display: flex;
  color: var(--bs-body-color);
  background-color: var(--bs-card-bg);
  background-clip: border-box;
  border: var(--bs-card-border-width) solid var(--bs-card-border-color);
  border-radius: var(--bs-card-border-radius);
  align-items: center;
}

.vplus-file-item .vplus-file-name {
  flex: 1 0;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  /* Allow text selection on file names for copy purposes */
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
  user-select: text;
}
.vplus-file-item .vplus-file-icon {
  flex: 0 1 auto;
  display: block;
  padding: 1rem;
  color: var(--bs-gray-500);
}
.vplus-file-item .vplus-file-delete {
  flex: 0 1 auto;
  color: var(--bs-gray-800);
}

.vplus-file-item .vplus-file-progress {
  flex: 0 0 100px;
  padding: 0 0.5rem;
  position: relative;
}
.vplus-file-item .vplus-file-progress .progress {
  position: relative;
  width: 100%;
  height: 12px;
  margin: 0;
  top: auto;
  border-radius: 2px;
  background: #e9ecef;
}
.vplus-file-item .vplus-file-cancel {
  flex: 0 1 auto;
  color: var(--bs-gray-500);
  border: none;
  background: transparent;
  padding: 0.5rem 1rem;
}
.vplus-file-item .vplus-file-cancel:hover {
  color: var(--bs-danger);
}

.vplus-file-wrapper.vplus-file-wrapper:not(:has(.vplus-file-container)) {
  display: none;
}

.ql-editor.ql-editor > * {
  margin-bottom: 1rem;
}

.btn.btn.vplus-file-move-handle {
  position: absolute;
  bottom: 0;
  right: 0;
  border-radius: var(--bs-border-radius) 0 0 0;
  border-bottom: 0;
  border-right: 0;
}

.vplus-sales-list .card {
  overflow: visible;
}
.vplus-submission-card {
  overflow: visible !important;
}
#vplus-sale-filter .card,
.vplus-settings-card {
  overflow: visible !important;
}
.vplus-sales-list .card-body {
  row-gap: 0.25rem;
}
@media (max-width: 575px) {
  .vplus-sales-list .card-body {
    padding-top: 0.5rem;
  }
}
.vplus-sales-list .card-body > div {
  align-self: center;
}
.vplus-sales-list .card-body .dropdown {
  margin-right: -0.5rem;
}
.vplus-sales-list .card-body .dropdown-toggle {
  line-height: 1;
  padding: 0.25rem 0.625rem;
}
.vplus-sales-list .card-body .dropdown-toggle.show {
  background: #e9eef6;
}
.vplus-sales-list .sale-name-link {
  display: inline-block;
}
.vplus-sales-list .col-sale-date {
  min-width: 100px;
  font-size: 80%;
  display: inline-block;
}
.vplus-sales-list .col-sale-id {
  min-width: 60px;
  font-size: 80%;
  display: inline-block;
}
.vplus-status-live,
.vplus-status-live-synced {
  color: #2fa358;
}
.badge.vplus-status-sold {
  background-color: #49b5e4;
  color: #ffffff;
}
.vplus-status-sold-floor {
  color: #0a58ca;
  background-color: rgba(10, 88, 202, 0.15);
}
.vplus-status-draft,
.vplus-status-draft-synced {
  color: #5a7ab8;
  background-color: rgba(90, 122, 184, 0.15);
}
.vplus-status-preview,
.vplus-status-pending {
  color: #c99212;
  background-color: transparent;
}
.vplus-status-pending-floor {
  color: #c96712;
  background-color: rgba(246, 145, 83, 0.15);
}
.vplus-status-reconciled,
.vplus-status-reconciliation,
.vplus-status-withdrawn {
  color: #a03f32;
  background-color: transparent;
}
.vplus-status-withdrawn-ended {
  color: #a03f32;
  background-color: transparent;
}
.vplus-status-archived {
  color: #666;
}
/* Loading Bay: not a Dashboard status, so it takes a hue none of the real
   statuses use — it must not read as a stage of the auction lifecycle. */
.vplus-status-loading-bay {
  color: #1d4ed8;
  background-color: transparent;
}
.vplus-status-unsold {
  color: #ce2610;
  background-color: transparent;
}
.vplus-status-suspended {
  color: #c99212;
  background-color: transparent;
}
.vplus-status-sold-bidding {
  color: #4859db;
  background-color: transparent;
}
.vplus-status-sold-make-offer {
  color: #ebd62d;
  background-color: transparent;
}
.vplus-status-sold-buy-now {
  color: #902deb;
  background-color: transparent;
}
/* Vendor item badges (My Sales rows, Report Card blocks) put the status class
   on the dot, not the badge. .vplus-status-sold above only paints a .badge
   background, so a plain "Sold" dot stayed grey; the bucket fallbacks (open,
   none) had no colour at all. */
.vplus-vendor-item-status .fa-circle.vplus-status-sold {
  color: #49b5e4;
}
.vplus-vendor-item-status .fa-circle.vplus-status-open {
  color: #c99212;
}
.vplus-vendor-item-status .fa-circle.vplus-status-none {
  color: #8a939e;
}

.vplus-badge .vplus-status-preview,
.vplus-badge .vplus-status-pending,
.vplus-badge .vplus-status-reconciled,
.vplus-badge .vplus-status-reconciliation,
.vplus-badge .vplus-status-withdrawn,
.vplus-badge .vplus-status-withdrawn-ended,
.vplus-badge .vplus-status-unsold,
.vplus-badge .vplus-status-suspended,
.vplus-badge .vplus-status-sold-bidding,
.vplus-badge .vplus-status-sold-make-offer,
.vplus-badge .vplus-status-sold-buy-now,
.vplus-status-filter-label .vplus-status-preview,
.vplus-status-filter-label .vplus-status-pending,
.vplus-status-filter-label .vplus-status-reconciled,
.vplus-status-filter-label .vplus-status-reconciliation,
.vplus-status-filter-label .vplus-status-withdrawn,
.vplus-status-filter-label .vplus-status-withdrawn-ended,
.vplus-status-filter-label .vplus-status-unsold,
.vplus-status-filter-label .vplus-status-suspended,
.vplus-status-filter-label .vplus-status-sold-bidding,
.vplus-status-filter-label .vplus-status-sold-make-offer,
.vplus-status-filter-label .vplus-status-sold-buy-now {
  background: transparent !important;
  background-color: transparent !important;
}

.vplus-sale-meta {
  margin-bottom: 1rem;
  display: flex;
  /* The row's natural width is ~1578px, so without wrapping it forced the whole
     page to scroll horizontally at every viewport below 1600. */
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.vplus-sale-meta #print {
  margin-left: auto;
}

.vplus-lot-status-badge[data-status-synced="1"] {
  cursor: pointer;
}

.vplus-lot-status-badge.is-status-menu-open,
.vplus-lot-status-badge.has-pending-status,
.vplus-experimental-visibility-toggle.has-pending-visibility {
  outline: 2px solid rgba(13, 110, 253, 0.3);
  outline-offset: 2px;
}

/* Duplicate Lot Number badge — BidLogix requires unique numbers within an auction,
   so highlight collisions in red the same way we outline queued status edits in blue. */
.vplus-lot-number.is-duplicate-number {
  outline: 2px solid #dc3545;
  outline-offset: 2px;
  cursor: help;
}

/* Highlight the entire row when its Lot Number collides — covers the case where
   the colliding lot is outside the user's current viewport. */
.vplus-list-item.has-duplicate-number {
  position: relative;
  border-left: 4px solid #dc3545;
  background: rgba(220, 53, 69, 0.04);
}

/* AM-2 — Item List Sections.
   The divider is a full-width heading row; member rows carry the same custom
   property and wear it as a low-opacity left edge, so a section reads as one
   band without the colour fighting the row's own content. */
.vplus-list-item.vplus-section-divider {
  background: var(--vplus-section-color, #eef2f7);
  border-left: 4px solid var(--vplus-section-color, #eef2f7);
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  /* Dividers are headings, not rows: nothing here is selectable or draggable. */
  cursor: default;
  user-select: none;
}

.vplus-list-item.vplus-section-member {
  border-left: 4px solid var(--vplus-section-color, transparent);
}

/* The variable chips carry the section's resolved VALUES, so they are text of
   unbounded length rather than a fixed glyph: cap each one and let the title
   attribute hold the full string. */
.vplus-section-divider-var {
  font-size: 0.75rem;
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Sticky banner above the lot list listing duplicate-number collisions so the
   user can find and fix them. Sits between the filter panel and the list. */
.vplus-duplicate-number-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  margin: 0.75rem 0;
  border: 1px solid #dc3545;
  border-left-width: 4px;
  border-radius: 6px;
  background: #fff4f4;
  color: #842029;
}

.vplus-duplicate-number-banner .vplus-duplicate-number-banner-icon {
  flex-shrink: 0;
  font-size: 1.15rem;
  line-height: 1.4;
  color: #dc3545;
}

.vplus-duplicate-number-banner .vplus-duplicate-number-banner-body {
  flex: 1 1 auto;
  font-size: 0.9rem;
  line-height: 1.45;
}

.vplus-duplicate-number-banner .vplus-duplicate-number-banner-body strong {
  display: block;
  margin-bottom: 0.15rem;
}

.vplus-duplicate-number-banner .vplus-duplicate-number-group {
  display: block;
  margin-top: 0.35rem;
}

.vplus-duplicate-number-banner .vplus-duplicate-number-group-label {
  font-weight: 600;
  color: #dc3545;
  margin-right: 0.35rem;
}

.vplus-duplicate-number-banner a.vplus-duplicate-jump {
  color: #842029;
  text-decoration: underline;
  cursor: pointer;
}

.vplus-duplicate-number-banner a.vplus-duplicate-jump:hover {
  color: #58151c;
}

/* Missing Lot Number — show the badge with an em-dash placeholder and a softer
   outline so the user knows the badge is clickable to set a number. */
.vplus-lot-number.is-missing-number {
  outline: 1px dashed rgba(108, 117, 125, 0.6);
  outline-offset: 2px;
  opacity: 0.85;
}

.vplus-lot-number.is-missing-number .vplus-lot-meta-badge-value {
  font-style: italic;
  opacity: 0.7;
}

.vplus-dashboard-status-menu,
.vplus-experimental-status-menu {
  display: block;
  min-width: 9rem;
  margin-top: 0.25rem;
  z-index: 1060;
}

.vplus-dashboard-status-sync-btn,
.vplus-experimental-status-sync-btn {
  margin-left: 0.35rem;
  vertical-align: middle;
}

.vplus-experimental-visibility-toggle {
  padding: 0.1rem 0.25rem;
  color: inherit;
  line-height: 1;
  vertical-align: middle;
}

.vplus-experimental-visibility-toggle:hover,
.vplus-experimental-visibility-toggle:focus {
  color: #0d6efd;
}

.vplus-express-mode .form-row-separator {
  display: none;
}

/* Speed Lotting (a narrowed Express) — strip the chrome that only makes sense
   on a full-length form. Done in CSS rather than .hide() so nothing has to be
   restored on the way out: removing .vplus-speed-mode hands both elements back
   to their own logic (the checklist in particular owns a `hidden` attribute
   that a jQuery .show() would override). */
.vplus-speed-mode .vplus-sync-options-row,
.vplus-speed-mode #vplus-required-checklist,
.vplus-speed-mode .form-row-separator,
.vplus-speed-mode .vplus-express-group-caption,
.vplus-speed-mode .vplus-bp-line-toggle {
  display: none !important;
}

/* Same principle, applied to the FIELD ROWS. Speed Lotting used to hide these
   with .hide(), which writes an inline display:none — and the Express
   conditional-logic cascades (VP_TypeInteraction's "Lot" branch) unconditionally
   .show() the pricing rows. VP_NextLotEffect re-fires that cascade through its
   select .trigger("change") sweep, so after "Sync & Create Another Item" the
   Purchase Option, Opening Bid, Bid Increment, Reserve and Quantity rows all
   reappeared inside the Speed card. A class-keyed rule outranks the inline
   style, so the cascade can no longer win.
   Double-scoped (.vplus-speed-mode AND the class) so a stale marker left on a
   row can never hide it once the operator is back in Express or Full. */
.vplus-speed-mode .vplus-speed-hidden-row {
  display: none !important;
}

/* ── Speed Lotting card ───────────────────────────────────────────────────
   Speed reuses #vplus-card--express's markup, so it inherits Express's orange
   frame and header. These rules give it its own identity — dark blue, matching
   the toggle button below — without forking the template. Keyed on the form's
   .vplus-speed-mode class so the card reverts the moment the mode changes. */
.vplus-speed-mode #vplus-card--express {
  --bs-card-border-color: rgba(30, 58, 95, 0.55);
  box-shadow:
    0 0 0 2px rgba(30, 58, 95, 0.4),
    0 0 0 4px rgba(30, 58, 95, 0.18);
}

.vplus-speed-mode .vplus-express-card-header {
  background: linear-gradient(135deg, #d6e8fc, #e9f4ff);
  color: #143a66;
  border-bottom-color: #ffc107;
}

.vplus-speed-mode .vplus-express-card-header i {
  color: #1c3f85;
}

/* One icon per mode. Default state (any mode but Speed) shows the Express bolt;
   the rabbit only appears under .vplus-speed-mode. */
.vplus-speed-mode-icon {
  display: none;
}

.vplus-speed-mode .vplus-speed-mode-icon {
  display: inline-block;
}

.vplus-speed-mode .vplus-express-mode-icon {
  display: none;
}

/* RAB — the Speed Lotting rabbit runs. Two motions: a gallop in place (nav
   dropdown item and the Speed Lotting button, on hover/focus) and a runner
   that crosses the top border of "Sync & Create Another Item" while it syncs
   (.is-running, set by vendor-plus-lot-page.js, which also sets
   --vplus-runner-track to the button's width). Transform/opacity only, and
   only for users who have not asked for reduced motion; the static rule is
   the end state so nothing changes when the query does not match. */
@keyframes vplus-rabbit-run {
  0%   { transform: translateY(0) rotate(0deg); }
  25%  { transform: translateY(-2px) rotate(-8deg); }
  50%  { transform: translateY(0) rotate(0deg); }
  75%  { transform: translateY(-1px) rotate(5deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
@keyframes vplus-rabbit-cross {
  from { transform: translateX(-16px); }
  to   { transform: translateX(var(--vplus-runner-track, 240px)); }
}
.dropdown-item .fa-rabbit-fast,
.btn-speed-lotting .fa-rabbit-fast {
  display: inline-block;
  transform-origin: 50% 80%;
}
.is-running {
  position: relative;
  overflow: visible;
}
.vplus-rabbit-runner {
  position: absolute;
  top: 1px;
  left: 0;
  font-size: 36px;
  line-height: 1;
  pointer-events: none;
  transform: translateX(-16px);
}
.vplus-rabbit-runner > .fa-rabbit-fast {
  display: inline-block;
  transform-origin: 50% 80%;
}
@media (prefers-reduced-motion: no-preference) {
  .dropdown-item:hover .fa-rabbit-fast,
  .dropdown-item:focus-visible .fa-rabbit-fast,
  .btn-speed-lotting:hover .fa-rabbit-fast,
  .btn-speed-lotting:focus-visible .fa-rabbit-fast {
    animation: vplus-rabbit-run 0.45s ease-in-out infinite;
  }
  .vplus-rabbit-runner {
    animation: vplus-rabbit-cross 1.6s linear infinite;
  }
  .vplus-rabbit-runner > .fa-rabbit-fast {
    animation: vplus-rabbit-run 0.45s ease-in-out infinite;
  }
}

/* D2 carried into the header: Templates and Customise both act on the Express
   field set, which Speed deliberately narrows to three fields — so neither has
   anything meaningful to operate on here. The "Or" separator between them goes
   too, or it is left stranded. */
.vplus-speed-mode .vplus-express-templates-btn,
.vplus-speed-mode .vplus-express-customise-btn,
.vplus-speed-mode .vplus-express-btn-or {
  display: none !important;
}

/* The header label swaps to name the active mode. Each mode's string lives in
   its own <span> so the ACCESSIBLE NAME changes with the visual one — a
   font-size:0 + ::after swap would leave a screen reader announcing
   "Express Mode" while the header reads "Speed Lotting". */
.vplus-speed-mode-label {
  display: none;
}

.vplus-speed-mode .vplus-speed-mode-label {
  display: inline;
  color: #434343;
  text-shadow: 1px 1px 2px #c6def7;
}

.vplus-speed-mode .vplus-express-mode-label {
  display: none;
}

.card {
  transition:
    box-shadow 0.3s ease-in,
    border-color 0.3s ease-in;
}

/* R2-P2: Orange border + glow is the EXPRESS card's identity — scope it to the
   Express card ITSELF (#vplus-card--express), not `.vplus-express-form .card`.
   The old descendant selector also matched the Full-mode section cards (which are
   nested inside .vplus-express-form), bleeding Express's orange onto Full mode. */
#vplus-card--express {
  --bs-card-border-color: rgb(255, 69, 0, 0.5);
  box-shadow:
    0 0 0 2px rgba(255, 165, 0, 0.5),
    0 0 0 4px rgba(255, 165, 0, 0.25);
}

/* Full Mode section cards — bespoke calm identity (neutral translucent border +
   soft drop shadow), distinct from Express's orange. Matches the restrained P1
   header direction; the per-section colour lives on the header accent, not the
   card frame. */
.vplus-full-mode-cards .card {
  --bs-card-border-color: var(
    --bs-border-color-translucent,
    rgba(0, 0, 0, 0.12)
  );
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.12),
    0 1px 2px rgba(0, 0, 0, 0.24);
}

.btn-check:checked + .btn {
  font-weight: var(--vplus-font-weight-normal);
}

/* Express Mode toggle button - orange styling */
.btn-check:checked + .btn[for="vplus-lot-mode-express"],
.btn-check:checked + .btn[for="vplus-sale-mode-express"] {
  background: linear-gradient(45deg, #ff4500, #ffa500);
  color: #fff;
  border-color: rgba(172, 43, 11, 1);
  text-shadow: 1px 1px 2px rgba(172, 43, 11, 1);
  box-shadow:
    inset 0 0 0 2px rgba(172, 43, 11, 0.25),
    inset 0 0 0 4px rgba(255, 69, 0, 0.25);
}
.btn[for="vplus-lot-mode-express"]:hover,
.btn[for="vplus-sale-mode-express"]:hover {
  background: linear-gradient(45deg, #ff4500, #ffa500);
  color: #fff;
  border-color: rgba(172, 43, 11, 1);
}

#vplus-ai-generate {
  font-weight: 600;
  padding-top: 0.7rem;
  padding-bottom: 0.7rem;
  border-radius: 10px;
}

/* Idle affordance: a breathing AI-blue outer glow (deliberately distinct
   from the amber upload-field glow). Disabled and processing states are both
   disabled buttons, so :not(:disabled) is exactly "enabled and idle". */
#vplus-ai-generate:not(:disabled) {
  animation: vplus-ai-generate-glow 2.2s ease-in-out infinite;
}

@keyframes vplus-ai-generate-glow {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(26, 127, 255, 0);
  }
  50% {
    box-shadow: 0 0 18px 4px var(--vplus-ai-accent-glow);
  }
}

@media (prefers-reduced-motion: reduce) {
  #vplus-ai-generate:not(:disabled) {
    animation: none;
    box-shadow: 0 0 12px 3px var(--vplus-ai-accent-glow);
  }
}

/* Constrained on desktop/tablet (left-aligned so it lines up with the step
   number + title), full width on mobile. */
@media (min-width: 768px) {
  #vplus-ai-generate-row,
  #submission-ai-generate-row {
    max-width: 34rem;
  }
}

/* Speed Lotting toggle button — dark blue with a black border, matching the
   Speed card header. Express and Full both style :checked AND :hover; Speed had
   neither, so it was the only mode with no border and no hover feedback. */
.btn-check:checked + .btn[for="vplus-lot-mode-speed"],
.btn-check:checked + .btn[for="vplus-sale-mode-speed"] {
  background: linear-gradient(135deg, #cfe5ff, #e3f0ff);
  color: #143a66;
  border-color: #000;
  box-shadow:
    inset 0 0 0 2px rgb(28 63 133 / 15%),
    inset 0 0 0 4px rgb(79 171 255 / 20%);
}
/* NB: the unchecked resting border and the hover live AFTER
   `.vplus-form-mode-toggle .btn-group .btn { border-color: revert }` further
   down this file — `revert` rolls the border back to Bootstrap's
   .btn-outline-dark (#212529) and, being later in source order, beats any rule
   placed here regardless of specificity. Verified in-browser. */

/* Full Mode toggle button - dark styling */
.btn-check:checked + .btn[for="vplus-lot-mode-full"],
.btn-check:checked + .btn[for="vplus-sale-mode-full"] {
  background: linear-gradient(135deg, #4a5568, #1a202c);
  color: #fff;
  border-color: #1a202c;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
  box-shadow:
    inset 0 0 0 2px rgba(74, 85, 104, 0.25),
    inset 0 0 0 4px rgba(26, 32, 44, 0.25);
}

hr.dashed {
  border-style: dashed;
  margin: 0;
}

.card-body .ql-toolbar.ql-snow {
  border: 0;
  border-bottom: 1px solid var(--bs-border-color);
}
.card-body .ql-editor {
  padding: 1rem 0;
}
/* The submission description editor sits inside a .card-body, so the rule above
   strips its horizontal padding and the text runs flush to the field edges.
   Restore left/right breathing room for this editor specifically (matches the
   vertical 1rem above; higher specificity wins without !important). */
.card-body .vplus-submission-description-editor .ql-editor,
.vplus-submission-description-editor .ql-editor {
  padding-left: 1rem;
  padding-right: 1rem;
}
.card-body .ql-container {
  font-family: var(--vplus-font-family-base);
  font-size: 1rem;
}
.card-body .ql-container *:not(strong) {
  font-weight: var(--vplus-font-weight-normal);
}
.card-body .ql-container.ql-snow {
  border: 0;
}

.ql-snow .ql-picker.ql-expanded .ql-picker-options {
  z-index: 100;
}

.form-row .btn-group .btn {
  padding: 0.75rem 1rem;
  border-color: #ccc;
}
.form-row .btn-group .btn .vplus-po-sublabel,
.form-row .btn-group .btn .vplus-type-sublabel {
  font-size: 0.7rem;
  line-height: 1.2;
  margin-top: 0.15rem;
  opacity: 0.7;
  color: var(--bs-secondary-color);
}
.form-row .btn-group .btn-check:checked + .btn .vplus-po-sublabel,
.form-row .btn-group .btn-check:checked + .btn .vplus-type-sublabel {
  color: inherit;
  opacity: 0.85;
}

/* P2 (3.3): Item Type / Purchase Option segmented controls cramp in the tablet
   band (768–991px) — four two-line buttons squeezed onto one row make the
   sublabels unreadable. Below lg, drop btn-group's nowrap-overlap model and lay
   the buttons out as a wrapping flex grid (≥2-up). Each button becomes an
   independent rounded control (btn-group's shared-edge radius resets no longer
   apply once wrapped), so restore full radii and normal borders. ≤767px already
   stacks to one column via the mobile rule, and ≥992px keeps the original
   4-across desktop look — this rule only spans the awkward middle. */
@media (min-width: 768px) and (max-width: 991.98px) {
  .vplus-segmented-wrap.btn-group {
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .vplus-segmented-wrap.btn-group > .btn {
    /* Two per row: half the container minus half the single gap between them. */
    flex: 1 1 calc(50% - 0.25rem);
    border-radius: var(--bs-btn-border-radius, 0.375rem) !important;
    /* btn-group overlaps borders with a -1px left margin; the gap replaces that,
       so clear it or the first button in each wrapped row is nudged. */
    margin-left: 0;
  }
}
/* Preserve Express/Full mode toggle custom gradients */
.vplus-form-mode-toggle .btn-group .btn {
  padding: 0.5rem 1.5rem;
  border-color: revert;
}

/* Speed Lotting's resting border + hover. MUST come after the `border-color:
   revert` above: revert rolls the border back to Bootstrap's .btn-outline-dark
   and wins on source order otherwise (specificity alone is not enough — a
   3-class selector placed earlier still loses). Matched to the same 3-class
   weight so the two rules are decided by order, not by an arms race. */
.vplus-form-mode-toggle .btn-group .btn[for="vplus-lot-mode-speed"],
.vplus-form-mode-toggle .btn-group .btn[for="vplus-sale-mode-speed"] {
  border-color: #000;
}

.vplus-form-mode-toggle .btn-group .btn[for="vplus-lot-mode-speed"]:hover,
.vplus-form-mode-toggle .btn-group .btn[for="vplus-sale-mode-speed"]:hover {
  background: linear-gradient(135deg, #b9d9fb, #d4e8fd);
  color: #143a66;
  border-color: #000;
}

/* ── Mode toggle: .btn-toolbar with two real button groups ────────────────
   Three full labels need ~440px on one row at 16px type; a 402px phone offers
   378px. Bootstrap 5.3's .btn-group cannot wrap (it documents one line, or
   .btn-group-vertical — nothing else), and forcing it to with display:grid
   fought its :first-child/:last-child radius and negative-margin rules.

   The documented answer is .btn-toolbar, which exists to "combine sets of
   button groups". The markup is now:
     .btn-toolbar
       .btn-group  [ Speed Lotting | Express Mode ]   <- joined, 0 gap
       .btn-group  [ Full Mode ]                      <- joined, own group
   Each group keeps GENUINE btn-group styling, so there is no gap between its
   members and the outer radius is shared. The toolbar is flex-wrap:wrap, so
   Full Mode simply wraps to its own row when it cannot fit.

   Desktop: the two groups butt together and read as one control.
   Mobile:  Full Mode wraps to a full-width row beneath the pair.

   🔴 BREAKPOINT: must cover every phone. An earlier cut used 399.98px and an
   iPhone 16 Pro (402 CSS px = 1206 device px at DPR 3) missed it by TWO pixels,
   overflowing the row and sidescrolling the page. Phones run 390/402/412/430/
   440, so the cutoff sits at the Bootstrap sm boundary (575.98px). */
.vplus-form-mode-toolbar {
  /* .btn-toolbar is display:flex; justify-content:flex-start. Centre it to match
     the toggle's text-align:center, which the old single group inherited. */
  justify-content: center;
  /* 🔴 NOT the default `stretch`. The collapsed Full Mode group is max-width:0 +
     overflow:hidden, so its button is squeezed to zero width — and with
     white-space:normal the label wraps to ~4 lines, giving that hidden button an
     88px intrinsic height. Under `stretch` that height is imposed on the VISIBLE
     Speed/Express buttons, which is why they rendered ~90px tall in Speed mode.
     flex-start lets each group keep its own height. */
  align-items: flex-start;
}

/* Belt and braces for the same defect: keep the collapsing label on one line at
   every width, so zero available width can never make it wrap. (The mobile
   block sets nowrap too, but only below 576px — this bug was desktop/tablet.) */
.vplus-form-mode-toolbar .vplus-form-mode-group--full > .btn {
  white-space: nowrap;
}

/* Desktop: butt the two groups together so they read as ONE control — cancel
   the second group's leading edge radius and overlap the 1px border, exactly
   what btn-group does between its own members. */
@media (min-width: 576px) {
  .vplus-form-mode-toolbar .vplus-form-mode-group--full {
    margin-left: -1px;
  }

  /* !important on both: Bootstrap's `.btn-group > .btn:first-child` /
     `:last-child` radius rules are more specific than these, so without it the
     Full Mode button keeps its rounded LEFT corners and the two groups read as
     two pills butted together rather than one control. */
  .vplus-form-mode-toolbar .vplus-form-mode-group--primary > .btn:last-of-type {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
  }

  .vplus-form-mode-toolbar .vplus-form-mode-group--full > .btn {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
  }
}

@media (max-width: 575.98px) {
  /* Wrap Full Mode onto its own row. The primary pair keeps its natural
     btn-group behaviour — no grid, no radius overrides, no gap between Speed
     and Express, because it is still a real single-line button group. */
  .vplus-form-mode-toolbar {
    flex-wrap: wrap;
    /* No row-gap: the wrapped Full Mode row butts directly against the pair
       above, overlapping their shared 1px border exactly as btn-group does
       between its own members. A gap here would leave the group reading as two
       detached controls. */
    row-gap: 0;
  }

  .vplus-form-mode-toolbar .vplus-form-mode-group--primary {
    /* Fill the row so the two members split it evenly. */
    width: 100%;
  }

  .vplus-form-mode-toolbar .vplus-form-mode-group--primary > .btn {
    /* Equal halves regardless of label length. */
    flex: 1 1 0;
  }

  /* Full Mode: its own full-width row beneath the pair. The 14rem collapse cap
     is scoped to ≥576px, so nothing constrains it here. */
  .vplus-form-mode-toolbar .vplus-form-mode-group--full {
    width: 100%;
    /* Overlap the pair's bottom border, the vertical equivalent of btn-group's
       -1px between horizontal members — one shared edge, not two stacked. */
    margin-top: -1px;
  }

  .vplus-form-mode-toolbar .vplus-form-mode-group--full > .btn {
    width: 100%;
    /* The collapse cap belongs to the GROUP, never the button — an inherited or
       stale cap here pins the wrapped row to 14rem inside a full-width toolbar,
       which reads as "Full Mode isn't going full width" plus a gap on the right. */
    max-width: none;
    /* Bottom row of a stacked group: square the TOP corners so it butts against
       the pair above, round only the BOTTOM pair. !important beats Bootstrap's
       :first-child/:last-child radius rules (this button is both). */
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
    border-bottom-left-radius: var(--bs-border-radius) !important;
    border-bottom-right-radius: var(--bs-border-radius) !important;
  }

  /* The pair above is the TOP row of a stacked group: square its bottom corners
     so the shared edge with Full Mode is flat.
     ⚠ Only while Full Mode is actually SHOWN — in Speed mode its group is
     collapsed and the pair is the whole control, so it must keep all four
     rounded corners. :has() scopes this to the visible case. */
  .vplus-form-mode-toolbar:has(
      .vplus-form-mode-group--full:not(.vplus-mode-btn-hidden)
    )
    .vplus-form-mode-group--primary
    > .btn:first-of-type {
    border-bottom-left-radius: 0 !important;
  }

  .vplus-form-mode-toolbar:has(
      .vplus-form-mode-group--full:not(.vplus-mode-btn-hidden)
    )
    .vplus-form-mode-group--primary
    > .btn:last-of-type {
    border-bottom-right-radius: 0 !important;
  }

  .vplus-form-mode-toggle .btn-group > .btn {
    /* Roomier than the desktop 0.5rem/1.5rem: vertical padding buys the tap
       target (46px measured), horizontal can be tight because the group's
       width is what sets the button width. */
    padding: 0.625rem 0.5rem;
    font-size: 1rem;
    white-space: nowrap;
    min-width: 0;
  }
}

/* ── Full Mode button: animated show/hide ─────────────────────────────────
   Speed Lotting hides Full Mode (D3). Toggling .d-none made it pop in and out,
   which is jarring mid-form. Animate width/opacity/transform instead so the
   group re-flows smoothly.
   .d-none is Bootstrap's `display:none !important`, so it cannot be
   transitioned — the JS now toggles .vplus-mode-btn-hidden, which keeps the
   button in layout (display intact) and collapses it geometrically.
   max-width rather than width: the button is auto-sized, and a fixed width
   would break as soon as a translation makes the label longer. */
/* The whole GROUP collapses now, not the label — Full Mode is its own
   .btn-group inside the toolbar. Collapsing the group is what removes the
   wrapped row entirely rather than leaving an empty one behind.
   ⚠ The 14rem cap is scoped to ≥576px ON PURPOSE. When it was unscoped, it
   also applied on mobile and pinned the wrapped row to 224px inside a 378px
   toolbar — the "Full Mode isn't going full width" symptom, with the leftover
   space reading as a gap. A max-width:none override in the mobile block could
   not fix it: this rule sits LATER in the file and wins on source order. */
@media (min-width: 576px) {
  .vplus-form-mode-toolbar .vplus-form-mode-group--full {
    max-width: 14rem;
  }
}

.vplus-form-mode-toolbar .vplus-form-mode-group--full {
  overflow: hidden;
  transition:
    max-width 0.28s ease,
    opacity 0.2s ease,
    transform 0.28s ease;
}

.vplus-form-mode-toolbar .vplus-form-mode-group--full.vplus-mode-btn-hidden {
  max-width: 0;
  opacity: 0;
  transform: scaleX(0.85);
  pointer-events: none;
}

/* On phones Full Mode is a wrapped full-width ROW, so it has to collapse
   VERTICALLY — a max-width collapse would leave a full-height empty row. */
@media (max-width: 575.98px) {
  .vplus-form-mode-toolbar .vplus-form-mode-group--full {
    max-height: 5rem;
    transition:
      max-height 0.28s ease,
      opacity 0.2s ease,
      margin 0.28s ease,
      transform 0.28s ease;
  }

  .vplus-form-mode-toolbar .vplus-form-mode-group--full.vplus-mode-btn-hidden {
    max-width: none;
    max-height: 0;
    /* The visible state already sits at margin-top:-1px to overlap the pair's
       border; keep exactly that when collapsed. (The toolbar's row-gap is 0 now,
       so there is no extra gap left to cancel.) */
    margin-top: -1px;
    transform: scaleY(0.85);
  }
}

/* Respect a reduced-motion preference: still hide, just without the movement. */
@media (prefers-reduced-motion: reduce) {
  .vplus-form-mode-toolbar .vplus-form-mode-group--full {
    transition: none;
  }
}

/* Desktop only: when Full Mode's group is collapsed, the primary group is
   visually last, so its trailing corners must be rounded again (they are
   squared above to butt against Full Mode). Scoped to ≥576px because on mobile
   each group already owns full radii on its own row. */
@media (min-width: 576px) {
  .vplus-form-mode-toolbar
    .vplus-form-mode-group--full.vplus-mode-btn-hidden
    ~ .vplus-form-mode-group--primary
    > .btn:last-of-type,
  .vplus-form-mode-toolbar:has(
      .vplus-form-mode-group--full.vplus-mode-btn-hidden
    )
    .vplus-form-mode-group--primary
    > .btn:last-of-type {
    /* !important to match the squaring rule above — without it the pair keeps
       square right corners in Speed mode, where it is the entire control. */
    border-top-right-radius: var(--bs-border-radius) !important;
    border-bottom-right-radius: var(--bs-border-radius) !important;
  }
}

/* ── Speed Lotting stepped card (P7) ──────────────────────────────────────
   1-2-3 flow modelled on the Photo App's Sale→Lot→Upload selects and the AI
   card's numbered steps. The AI card's own step rules are scoped to
   #vplus-card--ai, so these are parallel definitions rather than a shared
   base — deliberately, so a future #vplus-card--ai pass can move without
   dragging this card with it. */
.vplus-speed-lotting-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.vplus-speed-session-count {
  background: #198754;
  color: #fff;
  white-space: nowrap;
}

.vplus-speed-step {
  position: relative;
  padding: 0 0 22px 46px;
}

/* The step is a scroll/focus anchor (tabindex="-1") — focusing it after a sync
   would otherwise draw the browser's focus ring around the whole step. */
.vplus-speed-step:focus,
.vplus-speed-step:focus-visible {
  outline: none;
}

/* Connector line between steps. */
.vplus-speed-step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 15px;
  top: 34px;
  bottom: -2px;
  width: 2px;
  background: #eceff3;
}

.vplus-speed-step-num {
  position: absolute;
  left: 0;
  top: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  /* Speed Lotting's dark blue, matching the mode button and card header —
     the AI card's amber is its own identity and shouldn't leak here. */
  background: #2c5282;
  color: #fff;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  box-shadow: 0 2px 6px rgba(44, 82, 130, 0.35);
}

/* A completed step reads as done rather than numbered. */
.vplus-speed-step.is-complete .vplus-speed-step-num {
  background: #198754;
  box-shadow: 0 2px 6px rgba(25, 135, 84, 0.35);
}

/* Steps 2 and 3 before an auction is chosen: legible, but visibly not yet
   actionable (the Photo App precedent — its Step 2 select ships disabled). */
.vplus-speed-step.is-pending .vplus-speed-step-num {
  background: var(--bs-secondary-bg, #e9ecef);
  color: var(--bs-secondary-color, #6c757d);
  box-shadow: none;
}

.vplus-speed-step.is-pending .vplus-speed-step-title {
  opacity: 0.65;
}

.vplus-speed-step-title {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #495057;
  margin: 4px 0 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}

body.vplus-dark-mode .vplus-speed-step-title {
  color: #adb5bd;
}

body.vplus-dark-mode .vplus-speed-step:not(:last-child)::before {
  background: rgba(255, 255, 255, 0.12);
}

/* The auction select needs room for long auction names; the button and the
   Item List link sit beside it and keep their natural width. */
.vplus-speed-lotting-field {
  flex: 1 1 16rem;
  min-width: 0;
}

/* With JS, choosing an auction navigates on its own — the submit button is
   redundant, so the script stamps .vplus-speed-has-js and it disappears. The
   markup stays for the no-JS case, where the <select> would otherwise be a
   dead end. */
.vplus-speed-lotting-form.vplus-speed-has-js .vplus-speed-lotting-go {
  display: none;
}

/* Auction rows in the searchable-select dropdown: name + Type (+ Auctioneer
   when the list spans more than one). Lets near-identical auction titles be
   told apart at a glance. */
.vplus-ss-auction-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

/* Name + Type are one group so the Type badge sits directly AGAINST the title.
   The group takes the free space (and truncates); the auctioneer badge is the
   only thing that trails to the right. */
.vplus-ss-auction-lead {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 1 1 auto;
  min-width: 0;
}

/* The name is the only shrinkable part, so a long auction title ellipsises and
   the badges are never what gets clipped. */
.vplus-ss-auction-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Badges reuse .vplus-badge/.vplus-badge-secondary wholesale (the auctions
   panel's construction) — only the dropdown-specific sizing is set here, so
   any future restyle of .vplus-badge carries across automatically. */
.vplus-ss-auction-row .vplus-badge {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: 0.6875rem;
}

/* CM3 — the auction's status in a picker row. The .vplus-status-* classes set
   a TEXT colour, so the colour is carried by the dot rather than a filled
   badge. Never shrinks: the name is the only part that should ellipsise. */
.vplus-ss-auction-status {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: 0.6875rem;
  color: #667085;
}
.vplus-ss-auction-status .fa-circle {
  font-size: 0.5rem;
  vertical-align: middle;
}
body.vplus-dark-mode .vplus-ss-auction-status {
  color: #9aa4b2;
}

/* The dropdown row is the only place badges belong: the collapsed trigger
   truncates with an ellipsis, and badges there fight it for space. */
.vplus-ss-trigger .vplus-badge,
.vplus-ss-trigger .vplus-ss-auction-status {
  display: none;
}

/* Auction swap in progress (P8.3): dim and lock the form while the replacement
   fragment is fetched, so the operator can't type into markup that is about to
   be replaced. */
.vplus-speed-step.is-loading .vplus-speed-step-form {
  opacity: 0.45;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.vplus-speed-step.is-loading .vplus-speed-step-title::after {
  content: "";
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.5rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: vplus-speed-spin 0.7s linear infinite;
  vertical-align: -0.1em;
}

@keyframes vplus-speed-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .vplus-speed-step.is-loading .vplus-speed-step-title::after {
    animation: none;
  }
}

/* Mobile & tablet portrait (≤991px): drop the 46px left spine rail and switch to
   full-width steps separated by horizontal dividers, matching #vplus-card--ai.
   The spine costs 46px of every row, which on a phone squeezed the embedded lot
   form — the widest content in the card — into a thin, cramped column. Same DOM
   serves both layouts; only the step chrome changes. */
@media (max-width: 991.98px) {
  /* Lay the step out as a flex-wrap column of full-width rows: the number chip
     sits centred on its own row at the top, straddling the divider that
     separates it from the step above; title and body follow as their own rows.
     No absolute rail, so left/right padding is symmetric and the form gets the
     full card width. */
  .vplus-speed-step {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    border-top: 1px solid #eceff3;
    padding: 30px 0 16px 0;
    margin-top: 10px;
  }

  /* The connector line belongs to the spine layout only. */
  .vplus-speed-step:not(:last-child)::before {
    display: none;
  }

  /* Keep the chip's circle EXACTLY as it is on desktop (fixed 30px, filled,
     shadowed) — it must not stretch to the flex row. It sits alone on the first
     line because the rows below are flex-basis:100%, and the step's
     justify-content centres the fixed-width circle. The negative top margin
     lifts it by half its height so it straddles the divider above, reading as a
     badge ON the line rather than pushing content down. */
  .vplus-speed-step-num {
    position: static;
    width: 30px;
    height: 30px;
    font-size: 15px;
    flex: 0 0 auto;
    margin: -45px 0 12px;
  }

  /* Title on its own centred full-width row under the chip. */
  .vplus-speed-step-title {
    margin: 0 0 6px;
    flex: 1 1 100%;
    justify-content: center;
    text-align: center;
  }

  /* Every OTHER direct child — crucially .vplus-speed-step-form, which hosts the
     entire lot form — drops to its own full-width row beneath chip + title. */
  .vplus-speed-step > :not(.vplus-speed-step-num):not(.vplus-speed-step-title) {
    flex: 1 1 100%;
  }

  body.vplus-dark-mode .vplus-speed-step {
    border-top-color: rgba(255, 255, 255, 0.12);
  }
}

@media (max-width: 575.98px) {
  /* Stack the auction row so the select and both actions get full width. */
  .vplus-speed-lotting-row > .btn,
  .vplus-speed-lotting-field {
    flex: 1 1 100%;
  }
}

/* P3 (3.5): Express-mode group captions. Replaces the bare <hr> dividers that
   used to separate the Pricing and Classification clusters with a labelled
   caption, matching the captioned Buyer's Premium / Videos / Location sections
   already present lower in the form. Keeps the visual break (subtle top rule +
   spacing) while naming what the cluster is. */
.vplus-express-group-caption {
  margin-top: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--bs-border-color, #dee2e6);
  /* Gap below the caption before its field rows, matching the sibling captioned
     sections' mb-2 (the caption is a standalone row here, so the space can't come
     from an mb-2 on a shared wrapper). */
  margin-bottom: 0.5rem;
}

.form-control.disabled {
  background-color: var(--bs-secondary-bg);
  opacity: 1;
}

.floating-buttons:has(#vplus-prev-lot.hidden).floating-buttons:has(
    #vplus-sync-photos.hidden
  ).floating-buttons:has(#vplus-next-lot.hidden) {
  display: none;
}
.floating-buttons {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 999;
  padding: 1rem 0;
}

#vplus-next-lot {
  margin-left: auto;
}
#vplus-sync-photos {
  margin-left: auto;
  margin-right: auto;
}
/* 
#vplus-photo-files:not(:has(.vplus-file-container)):before {
  content: "No photos uploaded";
} */

.table-responsive.card > .table {
  margin-bottom: 0;
}

.nav-tabs:has(+ .card) {
  border-bottom: 0;
}
.nav-tabs:has(+ .card) .nav-link {
  border: 1px solid #ddd;
  box-shadow: 0 3px 7px rgba(0, 0, 0, 0.05);
  margin-bottom: 0;
}
.nav-tabs:has(+ .card) .nav-link.active {
  border-bottom-color: #fff;
  color: var(--bs-primary);
}
.nav-tabs:has(+ .card) .nav-link:not(.active) {
  background: rgba(255, 255, 255, 0.25);
  color: #a1a1a1;
}

.nav-tabs .nav-link {
  font-weight: bold;
}
.nav-tabs + .card:has(.tab-content) {
  border-bottom: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.card-body > .tab-content {
  padding: 0;
  border: 0;
}

.vplus-column--lot-name {
  margin-bottom: 0.5rem;
  flex-basis: 100%;
  max-width: 100%;
  display: flex;
  align-items: center;
}
.vplus-column--lot-name strong {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.vplus-column--lot-number {
  font-size: 0.85rem;
  padding-right: 0;
  display: flex;
  flex-basis: 100%;
  align-items: center;
}
.vplus-column--lot-number .fa-hashtag {
  font-size: 0.5rem;
  margin-right: 0.15rem;
}
.vplus-column--lot-info {
  flex-grow: 1;
}
.vplus-column--lot-info > div {
  flex-wrap: wrap;
}
.chlength-1 {
  max-width: 1.5rem;
}
.chlength-2 {
  max-width: 3rem;
}
.chlength-3 {
  max-width: 2.5rem;
}
.chlength-4 {
  max-width: 3rem;
}
.vplus-column--final-bid {
  min-width: 50%;
  text-align: right;
  font-weight: bold;
}
.vplus-column--lot-status {
  flex-basis: 90px;
  font-size: 0.825rem;
  text-align: right;
  margin-left: auto;
}
.vplus-column--lot-status > span {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
  background-color: rgba(0, 0, 0, 0.05);
  font-weight: 500;
  line-height: 1;
}
.vplus-column--lot-status > span .fa-circle {
  margin-right: 0.35rem;
  font-size: 0.6rem;
}
.vplus-column--reserve {
  flex-basis: 120px;
  font-size: 0.825rem;
  text-align: right;
}
.vplus-column--reserve-not-met {
  color: var(--bs-danger);
  font-weight: bold;
}
.vplus-column--reserve-met {
  color: var(--bs-success);
  font-weight: bold;
}
.vplus-column--bids {
  flex-basis: 60px;
  display: flex;
  justify-content: flex-end;
}
.vplus-column--bids > * {
  font-size: 0.825rem;
}
.vplus-bidder-username {
  max-width: 160px;
  font-size: 0.875rem;
  display: flex;
  align-items: center;
  gap: 0.25rem;
}
.vplus-btn-badge {
  border-radius: 10rem;
  padding: 0.125rem 0.5rem;
}
@media (min-width: 576px) {
  .vplus-column--lot-status {
    text-align: left;
  }
  .vplus-column--bids {
    min-width: 60px;
  }
  .vplus-column--reserve {
    min-width: 7rem;
  }
  .vplus-column--final-bid {
    min-width: 9rem;
  }
}
@media (min-width: 992px) {
  .vplus-column--lot-name {
    flex-basis: 100%;
  }
  .vplus-column--lot-status {
    margin-left: auto;
  }
}
@media (min-width: 1200px) {
  .vplus-column--lot-name {
    margin-bottom: 0;
    flex-basis: 40%;
    max-width: 40%;
  }
}

.vplus-btn-badge.btn-light {
  color: var(--bs-primary);
}
.vplus-btn-badge.btn-light:hover {
  background-color: rgba(var(--bs-primary-rgb), 0.125);
}

/* The brand colour belongs to the WHOLE header. It used to paint only
   .vplus-snapshot-header-info — the `col-12 col-sm` cell — which read as a
   coloured box floating on a grey bar rather than a branded header. */
.vplus-report-card .card-header,
.vplus-vendor-report-card .card-header {
  --bs-card-cap-bg: var(--vplus-brand-color, #0d6efd);
  --bs-card-cap-color: var(--vplus-brand-contrast, #ffffff);
  border-bottom: 1px solid var(--bs-border-color);
  /* The fill moved here from the inner block, so the print exemption has to
     move with it or the printed report loses the colour. */
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
.vplus-report-card .card-header h2 {
  font-size: 1.5rem;
  font-weight: 500;
}

/* Header text outside .vplus-snapshot-header-info keeps its own colour
   otherwise, and disappears against a dark brand fill. */
.vplus-report-card .card-header h1,
.vplus-report-card .card-header h2,
.vplus-report-card .card-header h3,
.vplus-report-card .card-header h4,
.vplus-report-card .card-header h5,
.vplus-report-card .card-header h6,
.vplus-report-card .card-header p,
.vplus-report-card .card-header small,
.vplus-report-card .card-header .text-muted,
.vplus-report-card .card-header a,
.vplus-vendor-report-card .card-header h1,
.vplus-vendor-report-card .card-header h2,
.vplus-vendor-report-card .card-header h3,
.vplus-vendor-report-card .card-header h4,
.vplus-vendor-report-card .card-header h5,
.vplus-vendor-report-card .card-header h6,
.vplus-vendor-report-card .card-header p,
.vplus-vendor-report-card .card-header small,
.vplus-vendor-report-card .card-header .text-muted,
.vplus-vendor-report-card .card-header a {
  color: inherit;
}

/* The operator logo and woa-black.svg are IMAGES — --vplus-brand-contrast
   recolours text only, so neither follows the brand colour.
   MEASURED on the live card (2026-09-19): the two marks have OPPOSITE
   polarity — the operator logo averages luminance 227 (light) and the
   powered-by mark 79 (dark). White fails the light logo (1.28:1) and the
   brand fill fails the dark mark (1.48:1); a mid grey is the only backdrop
   that carries both (1.62:1 and 3.95:1). Do not "tidy" this to #fff. */
.vplus-report-card .card-header .vplus-client-brand,
.vplus-vendor-report-card .card-header .vplus-client-brand {
  background: #adb5bd;
  border-radius: var(--bs-border-radius, 0.375rem);
  padding: 0.5rem 0.75rem;
  align-items: center;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

/* Lot Filters */
.vplus-lot-filters .form-label {
  font-size: 0.875rem;
  font-weight: 500;
  margin-bottom: 0.25rem;
}
.vplus-lot-filters .btn-group [data-sort] {
  font-size: 0.875rem;
  transition: all 0.2s ease;
}
.vplus-lot-filters .btn-group [data-sort].active {
  background-color: var(--bs-primary);
  color: white;
  border-color: var(--bs-primary);
}
.vplus-lot-filters .btn-group [data-sort]:not(.active):hover {
  background-color: rgba(var(--bs-primary-rgb), 0.1);
  color: var(--bs-primary);
  border-color: var(--bs-primary);
}
.vplus-lot-filters .btn-group [data-sort].active:hover {
  background-color: var(--bs-primary);
  color: white;
  opacity: 0.85;
}
.vplus-filter-results {
  padding-top: 0.5rem;
  border-top: 1px solid var(--bs-border-color);
  font-size: 0.875rem;
  font-weight: 500;
}

/*----------------- SNAPSHOT REPORT -----------------*/

/* CORE-3 — the snapshot header carries the operator's Brand Colour. The text
   colour is chosen server-side by luminance (vplus_contrast_text_for), so a
   pale brand does not produce white-on-yellow. Both variables are emitted with
   the stylesheet by vplus_emit_brand_colour_vars(). */
.vplus-snapshot-header-info {
  align-content: space-between;
  height: 100%;
  /* Same fill as the header it now sits in, so it reads as one bar rather than
     a box. Kept (not deleted) so the block still stands alone if it is ever
     rendered outside a .card-header. */
  background: var(--vplus-brand-color, #0d6efd);
  color: var(--vplus-brand-contrast, #ffffff);
  padding: 0;
  border-radius: 0;
  /* Browsers drop background fills when printing unless told otherwise, which
     would leave the header's light text on white. */
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

/* Headings and muted text inside the header would otherwise keep their own
   colours and disappear against a dark brand fill. */
.vplus-snapshot-header-info h1,
.vplus-snapshot-header-info h2,
.vplus-snapshot-header-info h3,
.vplus-snapshot-header-info h4,
.vplus-snapshot-header-info h5,
.vplus-snapshot-header-info h6,
.vplus-snapshot-header-info p,
.vplus-snapshot-header-info small,
.vplus-snapshot-header-info .text-muted,
.vplus-snapshot-header-info a {
  color: inherit;
}
.vplus-snapshot-header-auction-info {
  font-size: 0.75rem;
}
.vplus-client-brand {
  display: flex;
  gap: 0.5rem;
  flex-direction: column;
}

.vplus-client-logo {
  width: 150px;
}
.vplus-powered-by-logo {
  width: 150px;
}
.vplus-snapshot-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.vplus-snapshot-body > div {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

@media (min-width: 768px) {
  /* .vplus-client-brand {
    flex-direction: column;
  } */
  .vplus-snapshot-body {
    display: grid;
    /* E7.2 — minmax(0, …) not 1fr. A bare `1fr` floors at min-content, so a
       long title or a canvas pushes its column wider than its share and the
       row overflows. The middle column is given a little more room for the
       item blocks. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr) minmax(0, 1fr);
  }
  /* Grid children default to min-width:auto, which defeats the minmax above. */
  .vplus-snapshot-body > * {
    min-width: 0;
  }
}

/* E7.1 — give the chart a real box. The canvas carries width/height attributes
   for a no-JS fallback; Chart.js `responsive` needs a sized parent to measure,
   or it inherits the attribute ratio and overflows. */
.vplus-snapshot-value.vplus-vendor-chart-box {
  height: 220px;
  min-width: 0;
}
.vplus-snapshot-value.vplus-vendor-chart-box > canvas {
  width: 100% !important;
  height: 100% !important;
}

/* MS4 — the compact card the My Sales slide-out renders ($compact in
   vendor-report-card.php): one row of figures, then a short bar chart beside
   the top lots. The staff /vendor-reports/ card keeps everything above.
   The font-* utilities are !important, so shrinking them here must be too. */
.vplus-vendor-report-card--compact .card-header {
  padding: 0.6rem 1rem;
}
.vplus-vendor-report-card--compact .card-header h2 {
  font-size: 1.1rem;
  margin-bottom: 0.15rem;
}
.vplus-vendor-report-card--compact .vplus-snapshot-header-auction-info {
  font-size: 0.8125rem;
}
.vplus-vendor-report-card--compact .card-body {
  padding: 0.75rem 1rem;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body > * {
  min-width: 0;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body-col-1 {
  display: contents;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body-col-1 > div:first-child {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 0.5rem;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body-total {
  margin-bottom: 0;
}
.vplus-vendor-report-card--compact
  .vplus-snapshot-body-col-1
  > div:first-child
  > .vplus-snapshot-body-total {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  padding: 0.5rem 0.75rem;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body-col-1 .vplus-icon-xl {
  display: none;
}
.vplus-vendor-report-card--compact .vplus-snapshot-body-col-1 .font-xl,
.vplus-vendor-report-card--compact .vplus-snapshot-body-col-1 .font-lg {
  font-size: 1.35rem !important;
}
.vplus-vendor-report-card--compact .vplus-snapshot-label {
  font-size: 0.7rem;
  margin-bottom: 0.25rem;
}
.vplus-vendor-report-card--compact .vplus-snapshot-value.vplus-vendor-chart-box {
  height: 110px;
}
/* The two top-lot lists sit side by side at every width: stacked, they were
   the bulk of the card's height on a phone (measured 720px at 390). */
.vplus-vendor-report-card--compact .vplus-snapshot-body-col-3 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}
.vplus-vendor-report-card--compact .vplus-snaptshot-blocks {
  gap: 0.35rem;
}
.vplus-vendor-report-card--compact .vplus-snaptshot-blocks-item {
  grid-template-columns: minmax(0, 1fr);
  gap: 0.5rem;
  padding: 0.35rem 0.5rem;
}
.vplus-vendor-report-card--compact
  .vplus-top-lots-with-most-bids
  .vplus-snaptshot-blocks-item {
  grid-template-columns: auto minmax(0, 1fr);
}
.vplus-vendor-report-card--compact .vplus-snaptshot-blocks-item-content {
  padding: 0;
  min-width: 0;
}
.vplus-vendor-report-card--compact .vplus-snaptshot-blocks-item .font-md {
  font-size: 1rem !important;
}
.vplus-vendor-report-card--compact .vplus-snaptshot-blocks-item-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (min-width: 768px) {
  .vplus-vendor-report-card--compact .vplus-snapshot-body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  }
  .vplus-vendor-report-card--compact
    .vplus-snapshot-body-col-1
    > div:first-child {
    grid-column: 1 / -1;
  }
}
.vplus-snapshot-body-total {
  width: 100%;
  margin-bottom: 1rem;
}
.vplus-snapshot-body-total .vplus-icon-xl {
  flex-basis: 30%;
}

.font-xs {
  font-size: 0.75rem !important;
  line-height: 1.2;
}
.font-sm {
  font-size: 1.25rem !important;
  line-height: 1;
}
.font-md {
  font-size: 1.75rem !important;
  line-height: 1;
}
.font-lg {
  font-size: 2.5rem !important;
  line-height: 1;
}
.font-xl {
  font-size: 3rem !important;
  line-height: 1;
}
.vplus-icon-xl {
  font-size: 4rem;
}

.vplus-snapshot-label {
  font-size: 0.875rem;
  font-weight: bold;
  text-transform: uppercase;
  margin-bottom: 0.5rem;
}
.vplus-snaptshot-blocks {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.vplus-snaptshot-blocks-item {
  display: grid;
  align-items: center;
  gap: 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  grid-template-columns: 1fr 2fr;
  padding: 0.5rem;
  overflow: hidden;
}
.vplus-snaptshot-blocks-item-content {
  padding: 0.5rem;
  padding-left: 0;
}
@media (min-width: 576px) {
  .vplus-snaptshot-blocks-item-image {
    height: 100%;
    object-fit: cover;
  }
}
.vplus-placeholder-image {
  opacity: 0.25;
  padding: 1rem;
}
.vplus-bidders-by-country .vplus-snaptshot-blocks-item,
.vplus-bidder-by-state .vplus-snaptshot-blocks-item,
.vplus-top-lots-with-most-bids .vplus-snaptshot-blocks-item {
  grid-template-columns: 1fr 5fr;
}
#vplus_bids_per_chart {
  max-width: 100%;
}
#vplus_report_charts .nav-tabs .nav-item button {
  width: 100%;
}
@media (max-width: 420px) {
  #vplus_report_charts .nav-tabs {
    display: flex;
    flex-direction: column;
  }
  #vplus_report_charts .nav-tabs .nav-link {
    border-bottom: 0;
    border-left-color: #eee;
    border-right-color: #eee;
  }
}

#vplus-copy-from-last {
  margin-bottom: 1rem;
  border-style: dashed;
  transition: all 0.2s ease;
}

#vplus-copy-from-last:hover {
  border-style: solid;
  background-color: #f8f9fa;
  color: #212529 !important;
}

#vplus-copy-from-last .fal {
  margin-right: 0.5rem;
}

/* Increment suggestion dropdown */
.vp-increment-suggestions {
  width: 100%;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    max-height 0.3s ease-out,
    opacity 0.3s ease-out,
    margin 0.3s ease-out;
  margin-top: 0;
}

.vp-increment-suggestions:not([style*="display: none"]) {
  max-height: 100px;
  opacity: 1;
  margin-top: 0.5rem;
}

.vp-increment-select,
.vp-reserve-select {
  cursor: pointer;
  transition: all 0.2s ease;
}

.vp-increment-select:hover,
.vp-reserve-select:hover {
  border-color: #0dcaf0;
  box-shadow: 0 0 0 0.2rem rgba(13, 202, 240, 0.25);
}

.vp-increment-select:focus,
.vp-reserve-select:focus {
  border-color: #0dcaf0;
  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
}

/* Reserve calculator dropdown */
.vp-reserve-calculator {
  width: 100%;
  margin-top: 0.5rem;
}

/* Mobile optimizations */
@media (max-width: 768px) {
  .vp-increment-select,
  .vp-reserve-select {
    font-size: 0.875rem;
  }
}

.vplus-dev-info-tooltip {
  position: relative;
  display: inline-block;
}

.vplus-dev-info-tooltip .vplus-dev-tooltip-text {
  visibility: hidden;
  width: 280px;
  background-color: #333;
  color: #fff;
  text-align: left;
  border-radius: 6px;
  padding: 10px;
  position: absolute;
  z-index: 1000;
  bottom: 125%;
  left: 50%;
  margin-left: -140px;
  opacity: 0;
  transition: opacity 0.3s;
  font-size: 0.875rem;
  font-weight: normal;
  line-height: 1.4;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  text-transform: none;
}

.vplus-dev-info-tooltip .vplus-dev-tooltip-text::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #333 transparent transparent transparent;
}

.vplus-dev-info-tooltip:hover .vplus-dev-tooltip-text {
  visibility: visible;
  opacity: 1;
}

.dev-notice-badge {
  background-color: var(--bs-warning-bg);
  color: var(--bs-warning-text);
  border: 1px solid var(--bs-warning-border-subtle);
  font-weight: var(--vplus-font-weight-normal);
  margin-right: 0.5rem;
  margin-bottom: 0.5rem;
}

.vplus-info-tooltip {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-left: 5px;
}

.vplus-info-tooltip .fal,
.vplus-info-tooltip .fa-regular {
  cursor: help;
  font-size: 0.9rem;
  color: #6c757d;
}

.vplus-info-tooltip .vplus-tooltip-text {
  visibility: hidden;
  width: 280px;
  max-width: 280px;
  background-color: #333;
  color: #fff;
  text-align: left;
  border-radius: 6px;
  padding: 10px 12px;
  position: absolute;
  z-index: 9999;
  bottom: 125%;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity 0.2s ease-in-out;
  font-size: 13px;
  font-weight: normal;
  line-height: 1.4;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  pointer-events: none;
  text-transform: none;
  white-space: normal;
  word-wrap: break-word;
}

.vplus-info-tooltip .vplus-tooltip-text::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #333 transparent transparent transparent;
}

.vplus-info-tooltip:hover .vplus-tooltip-text {
  visibility: visible;
  opacity: 1;
}

/* Input-group tooltip positioning fix */
.input-group .input-group-text .vplus-info-tooltip {
  margin-left: 0;
}
.input-group .input-group-text .vplus-info-tooltip .vplus-tooltip-text {
  left: 0;
  transform: translateX(0);
}
.input-group .input-group-text .vplus-info-tooltip .vplus-tooltip-text::after {
  left: 15px;
  margin-left: 0;
}

/* Auction Description field - appropriate height for desktop/tablet */
/* Using ID selector to override .form-floating>.form-control specificity */
#vplus-sale-description {
  min-height: 200px !important;
  height: 200px !important;
}

.vplus-lot-editor-shell.form-control,
.vplus-submission-editor-shell.form-control {
  height: auto !important;
  min-height: 8rem;
}

.form-floating > .vplus-lot-editor-shell.form-control,
.form-floating > .vplus-submission-editor-shell.form-control {
  height: auto !important;
  min-height: 8rem;
  padding-top: 1.625rem;
  padding-bottom: 0.625rem;
}

.form-floating > .vplus-lot-editor-shell.form-control .ql-container,
.form-floating > .vplus-submission-editor-shell.form-control .ql-container {
  min-height: 5.5rem;
}

@media (max-width: 767.98px) {
  #vplus-sale-description {
    min-height: 150px !important;
    height: 150px !important;
  }

  .vplus-lot-editor-shell.form-control,
  .form-floating > .vplus-lot-editor-shell.form-control,
  .vplus-submission-editor-shell.form-control,
  .form-floating > .vplus-submission-editor-shell.form-control {
    min-height: 10rem;
  }
}

/* Form card with styled header */
.vplus-form-card {
  overflow: hidden;
}
.vplus-card-header {
  color: #fff;
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transition: opacity 0.2s ease;
}
.vplus-card-header[data-bs-toggle="collapse"] {
  cursor: pointer;
}
.vplus-card-header i {
  font-size: 1rem;
  opacity: 0.9;
}
.vplus-card-header .vplus-collapse-icon {
  margin-left: auto;
  transition:
    transform 0.3s ease,
    background-color 0.2s ease;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  background-color: rgba(255, 255, 255, 0.1);
  /* Webfont icon sizing - normalize for consistent rendering vs SVG */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.75rem;
  min-height: 1.5rem;
  line-height: 1;
  font-size: 0.875rem; /* Slightly smaller for webfont icons to match SVG visual scale */
}
.vplus-card-header .vplus-collapse-icon:hover {
  background-color: rgba(255, 255, 255, 0.25);
}
.vplus-card-header .vplus-collapse-icon:focus {
  outline: 2px solid rgba(255, 255, 255, 0.5);
  outline-offset: 2px;
}
.vplus-card-header.collapsed .vplus-collapse-icon {
  transform: rotate(-90deg);
}

/* Card header color variations - Sale/Auction Form */
.vplus-card-header-1 {
  background: linear-gradient(135deg, #1e3a5f 0%, #0d1b2a 100%);
} /* Navy - Title & Description */
.vplus-card-header-2 {
  background: linear-gradient(135deg, #4a6fa5 0%, #2c4a7c 100%);
} /* Neutral Blue - Type & Dates */
.vplus-card-header-3 {
  background: linear-gradient(135deg, #2d6a4f 0%, #1b4332 100%);
} /* Green - Bidding Options */
.vplus-card-header-4 {
  background: linear-gradient(135deg, #a83232 0%, #6b1d1d 100%);
} /* Dark Red - Buyers Premium */
.vplus-card-header-5 {
  background: linear-gradient(135deg, #457b9d 0%, #1d3557 100%);
} /* Teal - Location */
.vplus-card-header-6 {
  background: linear-gradient(135deg, #4a4a4a 0%, #1a1a1a 100%);
} /* Charcoal - Inspection */
.vplus-card-header-7 {
  background: linear-gradient(135deg, #4a5568 0%, #1a202c 100%);
} /* Slate - Blank Lots */

/* Card header colour variations - sectioned forms (.vplus-section-cards)
   Neutral header + coloured LEFT ACCENT + tinted icon, replacing the saturated
   full-fill gradients above (which stacked into a ransom-note palette). Each
   section keeps its hue as wayfinding via --vplus-accent; the header itself is a
   quiet light band with dark text. Overrides for text/icon colour (the base
   .vplus-card-header is white-on-dark) live in this block.

   Scoped to the CLASS, not an id, so every sectioned surface shares one
   vocabulary: the lot form's Full Mode, the submission form's sections, and the
   consignment settings groups. #vplus-full-mode-cards keeps its id for the lot
   form's mode toggle only. */
.vplus-section-cards .vplus-card-header {
  --vplus-accent: #4a5568;
  color: #1f2933;
  background: #f8f9fa;
  border-left: 4px solid var(--vplus-accent);
  border-bottom: 1px solid #e9ecef;
}
.vplus-section-cards .vplus-card-header i {
  color: var(--vplus-accent);
  opacity: 1;
}
/* Collapse chevron: base uses white-on-dark rgba; recolour for the light band. */
.vplus-section-cards .vplus-card-header .vplus-collapse-icon {
  color: var(--vplus-accent);
  background-color: rgba(0, 0, 0, 0.04);
}
.vplus-section-cards .vplus-card-header .vplus-collapse-icon:hover {
  background-color: rgba(0, 0, 0, 0.08);
}
.vplus-section-cards .vplus-card-header .vplus-collapse-icon:focus {
  outline: 2px solid var(--vplus-accent);
}
/* Per-section accent. Each rule must match the specificity of the fallback
   `--vplus-accent` on `.vplus-section-cards .vplus-card-header` above (both
   class+class) and win on source order; a bare `.vplus-card-header-lot-N` would
   LOSE to that fallback and every header would render slate.
   NB: the -lot-N number is NOT the card's position — lot-form-body.php assigns
   these out of sequence (Card 3 "Tax" uses -lot-4, Card 4 "Photos" uses -lot-3).
   New sections use SLUG keys (-sub-videos, -set-media), never numbers. The
   comment on each line names the section it actually styles. */
.vplus-section-cards .vplus-card-header-lot-1 {
  --vplus-accent: #2c5282;
} /* Blue - Lot Details */
.vplus-section-cards .vplus-card-header-lot-2 {
  --vplus-accent: #2f855a;
} /* Green - Bidding & Pricing */
.vplus-section-cards .vplus-card-header-lot-3 {
  --vplus-accent: #6b46c1;
} /* Purple - Photos */
.vplus-section-cards .vplus-card-header-lot-4 {
  --vplus-accent: #b7791f;
} /* Amber - Tax & Fees */
.vplus-section-cards .vplus-card-header-lot-5 {
  --vplus-accent: #c05621;
} /* Burnt orange - Videos (was red; red now reserved for warnings) */
.vplus-section-cards .vplus-card-header-lot-6 {
  --vplus-accent: #2c7a7b;
} /* Teal - Location & Contact */
.vplus-section-cards .vplus-card-header-lot-7 {
  --vplus-accent: #4a5568;
} /* Slate - More Options */
.vplus-section-cards .vplus-card-header-lot-condition-report {
  --vplus-accent: #5a67d8;
} /* Indigo - Condition Report */

/* Submission form sections. Hues follow the lot form where the section means
   the same thing there, so an operator moving between the two forms reads the
   same colour for the same subject. */
.vplus-section-cards .vplus-card-header-sub-details {
  --vplus-accent: #2c5282;
} /* Blue - Item Details (matches Lot Details) */
.vplus-section-cards .vplus-card-header-sub-condition-report {
  --vplus-accent: #5a67d8;
} /* Indigo - Condition Report */
.vplus-section-cards .vplus-card-header-sub-specification-sheet {
  --vplus-accent: #805ad5;
} /* Violet - Specification Sheet (sibling of the CR) */
.vplus-section-cards .vplus-card-header-sub-documents {
  --vplus-accent: #4a5568;
} /* Slate - Documents */
.vplus-section-cards .vplus-card-header-sub-videos {
  --vplus-accent: #c05621;
} /* Burnt orange - Videos (matches the lot form) */
.vplus-section-cards .vplus-card-header-sub-bidding {
  --vplus-accent: #2f855a;
} /* Green - Bidding & Buying (matches Bidding & Pricing) */
.vplus-section-cards .vplus-card-header-sub-agent-contact {
  --vplus-accent: #b7791f;
} /* Ochre - Agent & Contact Details (adjacent to Collection, distinct from it) */
.vplus-section-cards .vplus-card-header-sub-location {
  --vplus-accent: #2c7a7b;
} /* Teal - Collection (matches the lot form's Location & Contact) */
.vplus-section-cards .vplus-card-header-sub-notes {
  --vplus-accent: #718096;
} /* Grey - Additional Notes */

/* ── Settings screens: section heads, group banners, sticky save ─────────────
   The consignment settings page is twenty near-identical cards with two Save
   buttons a long scroll apart, and its .vplus-cm-section wrappers had no rules
   at all -- which is why the sections read as one undifferentiated column.
   These give it the same vocabulary as the sectioned forms it configures. */
.vplus-cm-section {
  scroll-margin-top: 1rem;
}
.vplus-cm-section-head {
  border-left: 4px solid var(--vplus-accent, #2c5282);
  background: #f8f9fa;
  border-bottom: 1px solid #e9ecef;
  border-radius: 6px;
  padding: 0.85rem 1.15rem;
}
.vplus-cm-section-head h4 {
  font-size: 1.15rem;
  color: #1f2933;
}
.vplus-cm-section-head h4 i,
.vplus-cm-section-head h4 [class*="fa-"] {
  color: var(--vplus-accent, #2c5282);
}
.vplus-cm-section-general {
  --vplus-accent: #2c5282;
}
.vplus-cm-section-templates {
  --vplus-accent: #6b46c1;
}

/* A group of related cards inside a section. */
.vplus-cm-group {
  margin-bottom: 2rem;
}
.vplus-cm-group-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid #e9ecef;
  font-weight: 600;
  color: #4a5568;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  scroll-margin-top: 1rem;
}
.vplus-cm-group-head [class*="fa-"] {
  color: var(--vplus-accent, #4a5568);
}
/* The cards inside a group sit a level below its banner. */
.vplus-cm-group .card-header h5 {
  font-size: 1rem;
}

/* Which Save applies to what you just changed, without scrolling to find out. */
.vplus-cm-savebar {
  position: sticky;
  bottom: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  background: #fff;
  border: 1px solid #e9ecef;
  border-radius: 6px;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
}
.vplus-cm-savebar__state {
  margin-left: auto;
  font-size: 0.85rem;
  color: #718096;
}
.vplus-cm-savebar.is-dirty .vplus-cm-savebar__state {
  color: #b7791f;
  font-weight: 600;
}

/* In-pane group navigation. A rail beside the content on wide screens, a
   scrolling chip row below -- never a second row of tabs, which would compete
   with the page's own tab strip. */
.vplus-cm-nav {
  position: sticky;
  top: 1rem;
  align-self: start;
  display: flex;
  gap: 0.25rem;
  flex-direction: row;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  margin-bottom: 1rem;
  -webkit-overflow-scrolling: touch;
}
.vplus-cm-nav a {
  flex: 0 0 auto;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  border: 1px solid #e2e8f0;
  background: #fff;
  color: #4a5568;
  font-size: 0.85rem;
  text-decoration: none;
  white-space: nowrap;
}
.vplus-cm-nav a:hover {
  border-color: var(--vplus-accent, #2c5282);
  color: var(--vplus-accent, #2c5282);
}
.vplus-cm-nav a.is-current {
  background: var(--vplus-accent, #2c5282);
  border-color: var(--vplus-accent, #2c5282);
  color: #fff;
}

@media (min-width: 992px) {
  .vplus-cm-section-body {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
  }
  .vplus-cm-nav {
    flex-direction: column;
    overflow-x: visible;
    margin-bottom: 0;
  }
  .vplus-cm-nav a {
    border-radius: 6px;
  }
}
.vplus-card-header-ai {
  background: linear-gradient(135deg, #d69e2e 0%, #975a16 100%);
} /* Amber/Gold - AI */

/* ── AI card: numbered step flow (P3c) ───────────────────────────────────────
   Moved here from the INLINE <style> in
   vendorplus-auction-manager/templates/loop/partials/lot-form-body.php, where it
   was scoped `#vplus-card--ai …` and therefore unreachable from the consignment
   submission form. Re-scoped to `.vplus-ai-card`, a class BOTH cards now carry,
   so the two AI cards share one step treatment (Q1: unified).

   🔴 The AM template keeps its own `#vplus-card--ai` copies of the rules that
   are genuinely lot-form-only (the Lot Title / Web Search panel, .opt-tag, the
   split-view overrides). Only the step rail, the numbered chips, the titles and
   the disclaimer — the parts the submission card also needs — live here. ID
   selectors (1-0-0) still outrank these class rules (0-1-0), so where the AM
   template also styles a step, its version continues to win and the lot form
   renders unchanged. */

/* Compacted danger disclaimer (full text lives in the "Details" tooltip). */
.vplus-ai-card .vplus-ai-disclaimer {
  display: flex;
  align-items: center;
  gap: 8px;
  line-height: 1.35;
}
.vplus-ai-card .vplus-ai-disclaimer .vplus-ai-disclaimer-more {
  text-decoration: underline;
  cursor: pointer;
  white-space: nowrap;
}

/* Submit Consignment CSS */

#vplus-submission-ai-card > .vplus-card-header-ai > .vplus-ai-header-desc {
  display: none;
}

/* The step panel is a Bootstrap .row, whose negative gutter margins escape the
   .card-body padding and let steps run to the card edge. Zero them so the
   card-body padding is what constrains the content, at every width. */
.vplus-ai-card .vplus-ai-form-panel {
  margin-left: 0;
  margin-right: 0;
  --bs-gutter-x: 0;
}

/* Numbered step rail with a faint connector line down the left. */
.vplus-ai-card .vplus-ai-step {
  position: relative;
  padding: 0 0 22px 46px;
}
/* Steps are scroll/focus anchors (tabindex="-1"): focusing one programmatically
   would otherwise draw a focus ring around the whole step. Not keyboard
   focusable, so suppressing the outline is safe. */
.vplus-ai-card .vplus-ai-step:focus,
.vplus-ai-card .vplus-ai-step:focus-visible {
  outline: none;
}
.vplus-ai-card .vplus-ai-step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 15px;
  top: 34px;
  bottom: -2px;
  width: 2px;
  background: #eceff3;
}
.vplus-ai-card .vplus-ai-step-num {
  position: absolute;
  left: 0;
  top: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #ffc107;
  color: #000;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  box-shadow: 0 2px 6px rgba(255, 193, 7, 0.35);
}
.vplus-ai-card .vplus-ai-step-title {
  font-size: 18px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #131313;
  margin: 4px 0 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}
body.vplus-dark-mode .vplus-ai-card .vplus-ai-step-title {
  color: #cdd2da;
}
body.vplus-dark-mode .vplus-ai-card .vplus-ai-step-title i {
  color: #8fb6ff;
}

/* R1 item 3 — the Analyse Photos button IS the label for its step, so it
   carries the step's weight rather than Bootstrap's default 400. Scoped to the
   row so no other .btn-warning on the form is affected. */
#submission-ai-generate-row #vplus-ai-generate {
  font-weight: 600;
}

/* Mobile & tablet portrait: drop the 46px left rail for full-width steps
   separated by horizontal dividers, with the number chip inline and centred,
   straddling the divider. Same DOM serves both layouts. */
@media (max-width: 991.98px) {
  .vplus-ai-card .vplus-ai-step {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    border-top: 1px solid #eceff3;
    padding: 30px 0 16px 0;
    margin-top: 10px;
  }
  .vplus-ai-card .vplus-ai-step::before {
    display: none;
  }
  .vplus-ai-card .vplus-ai-step-num {
    position: static;
    width: 30px;
    height: 30px;
    flex: 0 0 auto;
    margin: -45px 0 12px;
  }
  .vplus-ai-card .vplus-ai-step-title {
    margin: 0 0 6px;
    flex: 1 1 100%;
    justify-content: center;
    text-align: center;
  }
  .vplus-ai-card
    .vplus-ai-step
    > :not(.vplus-ai-step-num):not(.vplus-ai-step-title) {
    flex: 1 1 100%;
  }
  .vplus-ai-card .vplus-ai-step .vplus-file-upload-field,
  .vplus-ai-card .vplus-ai-step .vplus-file-wrapper,
  .vplus-ai-card .vplus-consignment-prompt-grid {
    max-width: none;
  }
}
@media (min-width: 768px) {
  .vplus-ai-card .vplus-ai-step .vplus-file-wrapper {
    max-width: 90%;
  }
}

/* ── Required Fields checklist (OV-C) ─────────────────────────────────────────
   Moved here from the INLINE <style> in the AM lot form template so the
   consignment submission form (which runs the same shared engine,
   vendor-plus-required-checklist.js) gets the styling too. The Split-View
   relocation override stays in the AM template. Tabs preserved verbatim. */
/* ── P8: Required Fields Checklist ───────────────────────────────────────────
   A compact card listing the minimum required fields for the current Item Type +
   Purchase Options, each with a glowing ✗ that flips to a ✓ as it's satisfied.
   Rows are built at runtime to mirror the live [required]:visible:enabled set, so
   the list is always in step with the form's own submit gate. One node, relocated
   by JS between the AI card (Split) and the trailing form card (List/Express/Full). */
.vplus-required-checklist {
  border: 1px solid #e4e7ec;
  border-radius: 8px;
  background: #fff;
  padding: 14px 16px;
  margin-top: 16px;
  /* Match the top gap so the checklist doesn't sit flush on #vplus-lot-actions
	   below it (List/Express/Full). Split View zeroes margin-top above and the
	   checklist is the AI card's last child there, so a bottom gap is harmless. */
  margin-bottom: 16px;
}
.vplus-required-checklist__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.vplus-required-checklist__title {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #495057;
}
.vplus-required-checklist__info {
  color: #98a2b3;
  cursor: pointer;
  font-size: 13px;
}
.vplus-required-checklist__count {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  color: #667085;
  font-variant-numeric: tabular-nums;
}
.vplus-required-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px;
}
/* Each row is a button (click → scroll to the field, mode-aware). */
.vplus-required-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  border: 1px solid #e4e7ec;
  background: #fff;
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 13px;
  color: #344054;
  transition:
    border-color 0.15s,
    background 0.15s;
  cursor: pointer;
}
.vplus-required-item:hover,
.vplus-required-item:focus-visible {
  border-color: #ffc107;
  background: #fffdf5;
  outline: none;
}
.vplus-required-item__icon {
  flex: 0 0 auto;
  font-size: 14px;
  line-height: 1;
}
.vplus-required-item__label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Unsatisfied: red glowing ✗ (mirrors the amber photo-glow vocabulary, red hue). */
.vplus-required-item[data-vplus-required-state="todo"]
  .vplus-required-item__icon {
  color: #dc3545;
  border-radius: 50%;
  animation: vplus-required-glow 2s ease-in-out infinite;
}
/* Satisfied: solid green ✓, no glow. */
.vplus-required-item[data-vplus-required-state="done"]
  .vplus-required-item__icon {
  color: #198754;
}
.vplus-required-item[data-vplus-required-state="done"]
  .vplus-required-item__label {
  color: #667085;
}
/* Sync-readiness verdict, merged in from the retired #vplus-lot-status-message.
   Sits below the grid, separated by a hairline so it reads as the card's
   conclusion rather than another row. Same red/green vocabulary as the rows. */
.vplus-required-checklist__status {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid #eceff3;
  font-size: 12.5px;
  line-height: 1.45;
}
.vplus-required-checklist__status-icon {
  flex: 0 0 auto;
  font-size: 13px;
  line-height: 1.45;
}
.vplus-required-checklist__status[data-vplus-status-state="blocked"] {
  color: #b42318;
}
.vplus-required-checklist__status[data-vplus-status-state="blocked"]
  .vplus-required-checklist__status-icon {
  color: #dc3545;
}
.vplus-required-checklist__status[data-vplus-status-state="ready"] {
  color: #23794f;
}
.vplus-required-checklist__status[data-vplus-status-state="ready"]
  .vplus-required-checklist__status-icon {
  color: #198754;
}
@keyframes vplus-required-glow {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(220, 53, 69, 0);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(220, 53, 69, 0.28);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vplus-required-item[data-vplus-required-state="todo"]
    .vplus-required-item__icon {
    animation: none;
    box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.3);
  }
}
/* Transient highlight when the operator clicks a checklist row and we jump to the
   field — a short accent-gold pulse on the field's container so it's obvious which
   field we landed on. The class is added by scrollToField() and removed on
   animationend. Uses the same #ffc107 accent as the checklist hover. */
.vplus-field-flash {
  animation: vplus-field-flash 1.1s ease-out;
  border-radius: 6px;
}
@keyframes vplus-field-flash {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.55);
  }
  30% {
    box-shadow: 0 0 0 4px rgba(255, 193, 7, 0.45);
  }
  100% {
    box-shadow: 0 0 0 6px rgba(255, 193, 7, 0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vplus-field-flash {
    animation: none;
    box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.45);
  }
}

/* AI card header layout */
#vplus-card--ai .vplus-card-header {
  flex-wrap: wrap;
}
#vplus-card--ai .vplus-card-header .form-check {
  padding-left: 0;
  margin-bottom: 0;
  gap: 0.5rem;
}
#vplus-card--ai .vplus-card-header .form-check-input {
  width: 2.75em;
  height: 1.4em;
  margin: 0;
  float: none;
  cursor: pointer;
  background-color: #dc3545;
  border-color: rgba(255, 255, 255, 0.6);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease;
}
#vplus-card--ai .vplus-card-header .vplus-badge {
  flex: 0 0 auto;
}
#vplus-card--ai .vplus-card-header .form-check-input:checked {
  background-color: #198754;
  border-color: rgba(255, 255, 255, 0.6);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
}
#vplus-card--ai .vplus-card-header .form-check-label {
  color: #fff;
  font-weight: 600;
}
#vplus-card--ai .vplus-card-header .vplus-ai-header-desc {
  flex-basis: 100%;
  font-size: 0.8rem;
  opacity: 0.85;
  font-weight: 400;
  margin-top: 0.25rem;
  color: #fff;
}

/* AI badge - inverted warning with glow */
@keyframes vplus-badge-glow {
  0%,
  100% {
    box-shadow: 0 0 4px rgba(102, 77, 3, 0.4);
  }
  50% {
    box-shadow:
      0 0 12px rgba(102, 77, 3, 0.7),
      0 0 20px rgba(102, 77, 3, 0.3);
  }
}
.vplus-badge-ai {
  background: #664d03;
  color: #fff;
  animation: vplus-badge-glow 2s ease-in-out infinite;
}
.vplus-badge-ai .fa {
  color: #fff;
}

/* Nav "AI" pill (Auction Manager). Reuses .vplus-badge-ai's pulse but in the
   brand red, since the gold-brown reads as a warning against the nav's own
   palette. .nav-link is already flex with an 8px gap, which spaces the pill —
   so no margin here; adding one double-spaced it to 14px. */
/* "AI" is all-caps with NO descenders, so the ~2px of descent space the font
   reserves below the baseline is empty — and .vplus-badge centres the LINE BOX,
   not the ink, which parks the glyphs ~7px high inside the pill. Measured on
   the live site: 0.88px above the caps vs 7.94px below.

   align-items:center does NOT fix this (the descent travels with the line box —
   measured 7.06px → 7.05px, i.e. no change). The fix is to cancel the descent
   with asymmetric vertical padding: the 0.10em difference below is half the
   font descent at this size. Measured result: 0.04px imbalance.

   `display:inline-block` (not flex) because padding only moves the ink when the
   box height comes from line-height rather than a fixed height. */
.vplus-nav-ai-pill {
  display: inline-block;
  min-width: 1.75em;
  padding: 0.3em 0.45em 0.2em;
  line-height: 1.3;
  text-align: center;
  font-size: 0.62em;
  letter-spacing: 0.06em;
  background: #b42318;
  animation-name: vplus-nav-ai-glow;
  vertical-align: middle;
}
@keyframes vplus-nav-ai-glow {
  0%,
  100% {
    box-shadow: 0 0 4px rgba(180, 35, 24, 0.45);
  }
  50% {
    box-shadow:
      0 0 12px rgba(180, 35, 24, 0.75),
      0 0 20px rgba(180, 35, 24, 0.35);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vplus-nav-ai-pill {
    animation: none;
    box-shadow: 0 0 0 2px rgba(180, 35, 24, 0.35);
  }
}

/* Compact Full Mode Blue Flag to match Express */
#blueflag-lookup-row .card-body {
  padding-top: 0.5rem !important;
  padding-bottom: 0.5rem !important;
}
#blueflag-lookup-row h6,
#blueflag-lookup-row .fw-medium {
  font-size: 0.875rem;
  margin-bottom: 0;
}
#blueflag-lookup-row p.text-muted {
  display: none;
}

/* Condition Report Section Styling - Dark Wine Background */
/* P3 (3.6): Condition Report block. Was a DARK-RED gradient/border/icon that read
   as a warning or stray element beside the neutral field rows. Retheme to the
   CR's own INDIGO identity (its header icon is text-indigo; the CR template
   header accent is indigo, P1) — still a distinct, labelled grouped block (it's a
   template picker + Enable toggle, not a plain field), just no longer alarming.
   Same rule also skins the submission-form CR row, keeping the two consistent. */
#express-condition-report-row,
#full-condition-report-row,
#submission-condition-report-row {
  background: linear-gradient(
    135deg,
    rgba(90, 103, 216, 0.06) 0%,
    rgba(76, 81, 191, 0.1) 100%
  );
  border: 1px solid rgba(90, 103, 216, 0.18);
  border-radius: 0.5rem;
  padding: 1rem;
}
#express-condition-report-row .fa-clipboard-check,
#full-condition-report-row .fa-clipboard-check,
#submission-condition-report-row .fa-clipboard-check {
  color: #5a67d8 !important;
}
#express-condition-report-row .badge.bg-danger,
#full-condition-report-row .badge.bg-danger,
#submission-condition-report-row .badge.bg-danger {
  background-color: #4c51bf !important;
}
#express-condition-report-row .badge.bg-secondary,
#full-condition-report-row .badge.bg-secondary,
#submission-condition-report-row .badge.bg-secondary {
  background-color: rgba(76, 81, 191, 0.6) !important;
}
/* CR field grid vertical alignment */
#submission-condition-report-row > .row.g-2 {
  align-items: start;
}

/* ── List filter bar (P3 rebuild, 2026-09-05) ──────────────────────────────
   One component, two configurations: the item list (/sales/<id>/) and the
   auction list (/sales/). Markup is
   auction-manager/templates/partials/filter-bar.php.

   Shape: an always-visible bar carrying search, per-page, the Filters
   disclosure toggle, Apply and Reset; list actions (Refresh buttons, result
   count) in their own right-hand cluster; secondary filters in a labelled
   grid that the toggle reveals.

   Lives in Core, not inline in a template, because BOTH panels use it.

   🔴 `.is-enhanced` / `.is-open` are stamped SERVER-SIDE. Adding them from JS
   on ready made the full-height panel paint and then visibly collapse. Each
   template ships a <noscript> that undoes them for the no-JS path.

   🔴 Bootstrap utilities tie on specificity and win on source order, so any
   rule that has to beat `.d-flex` or `.btn` is written with two classes. */

.vp-filter {
  --vplus-filter-control-h: 38px;
  --vplus-filter-gap: 0.5rem;
  margin-bottom: 1rem;
}

.vp-filter .card-body {
  padding: 0.75rem 1rem;
}

/* ── The bar ─────────────────────────────────────────────────────────────── */

.vp-filter .vp-filter__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vplus-filter-gap);
  justify-content: space-between;
}

/* Filters cluster — the only growable child is the search field, so this
   cluster takes the slack and the actions cluster keeps its natural width.

   The basis is deliberately large: the cluster's own controls (search,
   per-page, Filters, Apply, Reset) need ~36rem before they start wrapping
   among themselves, and a smaller basis let the actions cluster — two long
   Refresh buttons on the auction list — claim half the bar and push Apply onto
   a second line at 1024. Measured at 1024: filters 461px against ~580px of
   content. */
.vp-filter .vp-filter__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vplus-filter-gap);
  flex: 1 1 36rem;
  min-width: 0;
}

/* Actions cluster — list actions, not filters. The rule makes the separation
   visible rather than relying on spacing alone. */
.vp-filter .vp-filter__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vplus-filter-gap);
  flex: 0 0 auto;
  padding-left: 0.75rem;
  border-left: 1px solid var(--bs-border-color, #dee2e6);
}

/* No cluster to separate from when the bar has wrapped to one column. */
.vp-filter .vp-filter__actions:first-child {
  padding-left: 0;
  border-left: 0;
}

.vp-filter .vp-filter__count-text {
  white-space: nowrap;
}

/* Between 992 and ~1200 the auction list's two Refresh buttons are wide enough
   ("Refresh Statuses" + "Refresh Auction Details" = ~305px of label) to push
   the whole actions cluster onto its own line. Drop to the icon alone in that
   band: the tooltip already carries the explanation, and the alternative is
   losing the single-row bar the layout is built around. */
@media (min-width: 992px) and (max-width: 1279.98px) {
  .vp-filter .vp-filter__actions .vplus-refresh-btn {
    font-size: 0;
  }
  .vp-filter .vp-filter__actions .vplus-refresh-btn > [class*="fa-"] {
    font-size: 0.875rem;
    margin-right: 0 !important;
  }
}

/* ── Search ──────────────────────────────────────────────────────────────── */

.vp-filter .vp-filter__search {
  flex: 1 1 18rem;
  min-width: 0;
  width: auto;
}

/* The scope select sits inside the input group and must not stretch. */
.vp-filter .vp-filter__scope {
  flex: 0 0 auto;
  width: auto;
  max-width: 8rem;
  height: var(--vplus-filter-control-h);
}

/* The icon is positioned over the field, so the wrapper owns the padding. */
.vp-filter .vp-filter__search-wrap {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
}

.vp-filter .vp-filter__search-icon {
  position: absolute;
  left: 0.65rem;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--bs-secondary-color, #6c757d);
  font-size: 0.875rem;
  z-index: 4;
}

.vp-filter .vp-filter__search-input {
  padding-left: 2rem;
  height: var(--vplus-filter-control-h);
  width: 100%;
}

/* Square the joins so scope + field + go read as one control. */
.vp-filter .vp-filter__scope {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.vp-filter
  .vp-filter__scope
  ~ .vp-filter__search-wrap
  .vp-filter__search-input {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}
.vp-filter .vp-filter__search-wrap .vp-filter__search-input {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

/* The icon-only submit is a phone affordance; above 576px the labelled Apply
   takes over, so only one submit is ever visible. */
.vp-filter .vp-filter__go {
  flex: 0 0 auto;
  height: var(--vplus-filter-control-h);
}

/* ── Controls on the bar ─────────────────────────────────────────────────── */

.vp-filter .vp-filter__perpage select {
  height: var(--vplus-filter-control-h);
  width: auto;
}

.vp-filter .vp-filter__more,
.vp-filter .vp-filter__submit,
.vp-filter .vplus-reset-filters,
.vp-filter .vp-filter__actions .btn {
  height: var(--vplus-filter-control-h);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
}

/* Only meaningful once JS can toggle it; the <noscript> hides it again. */
.vp-filter .vp-filter__more {
  display: none;
}
.vp-filter.is-enhanced .vp-filter__more {
  display: inline-flex;
}

.vp-filter .vp-filter__count {
  font-size: 0.75rem;
}
.vp-filter .vp-filter__count[hidden] {
  display: none;
}

/* ── The disclosure ──────────────────────────────────────────────────────── */

/* Hidden by default once enhanced; `is-open` reveals it. A plain display
   toggle, not height/transform: the <noscript> has to be able to force it
   open, and an animated collapse fought the server-stamped initial state. */
.vp-filter .vp-filter__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0.75rem 1rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--bs-border-color, #dee2e6);
}

.vp-filter.is-enhanced .vp-filter__grid {
  display: none;
}
.vp-filter.is-enhanced.is-open .vp-filter__grid {
  display: grid;
}

.vp-filter .vp-filter__field {
  min-width: 0;
}

/* Status carries the most options, so it gets two columns where there is room
   for them. */
@media (min-width: 768px) {
  .vp-filter .vp-filter__field--wide {
    grid-column: span 2;
  }
}

.vp-filter .vp-filter__field .form-label {
  margin-bottom: 0.25rem;
}

.vp-filter .vp-filter__field .form-control,
.vp-filter .vp-filter__field .form-select {
  width: 100%;
}

/* The photos radio group is three equal segments across its cell. */
.vp-filter .vp-filter__photos-group .btn {
  flex: 1 1 0;
}

/* Tom Select renders its own wrapper in place of the select. */
.vp-filter .vp-filter__field .ts-wrapper {
  width: 100%;
}

/* Above the sticky list toolbar, or the status dropdown opens behind it. */
.vp-filter .ts-dropdown {
  z-index: 1030;
}

/* ── Responsive: three tiers, matching the widths the panel is measured at ── */

/* 576–991: the actions cluster wraps under the filters, still inside the bar. */
@media (max-width: 991.98px) {
  .vp-filter .vp-filter__actions {
    flex-basis: 100%;
    padding-left: 0;
    border-left: 0;
    padding-top: 0.5rem;
    border-top: 1px solid var(--bs-border-color, #dee2e6);
  }
}

/* Below 576 everything stacks: the search takes the full width, and the two
   clusters become full-width button rows. */
@media (max-width: 575.98px) {
  .vp-filter .vp-filter__filters,
  .vp-filter .vp-filter__actions {
    flex-basis: 100%;
  }
  .vp-filter .vp-filter__search {
    flex-basis: 100%;
  }
  .vp-filter .vp-filter__perpage,
  .vp-filter .vp-filter__perpage select {
    width: 100%;
  }
  .vp-filter .vp-filter__more,
  .vp-filter .vp-filter__submit,
  .vp-filter .vplus-reset-filters {
    flex: 1 1 auto;
    justify-content: center;
  }
  .vp-filter .vp-filter__actions .btn {
    flex: 1 1 auto;
    justify-content: center;
  }
  /* The phone submit replaces the labelled one at this width. */
  .vp-filter .vp-filter__submit {
    display: none;
  }
  .vp-filter .vp-filter__count-text {
    flex-basis: 100%;
    text-align: center;
  }
  /* 44px is the touch-target minimum; the small controls were under it. */
  .vp-filter {
    --vplus-filter-control-h: 44px;
  }
  .vp-filter .form-control-sm,
  .vp-filter .form-select-sm {
    font-size: 1rem; /* >=16px stops iOS zooming the page on focus */
  }
}

/* Above 576 the icon-only phone submit stands down. */
@media (min-width: 576px) {
  .vp-filter .vp-filter__go {
    display: none;
  }
}

/* Lot form mode toggle styling */
.vplus-form-mode-toggle {
  margin-bottom: 1rem;
}

/* Express/Full Mode Display - controlled by JavaScript inline styles */
.vplus-express-form {
  display: block;
}

/* Card and section heading styles */
.vplus-card-heading,
.vplus-section-heading {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}
.vplus-card-heading sup,
.vplus-section-heading sup,
label sup {
  font-size: 0.8em;
  color: #dc3545;
}

/* Card navigation buttons */
.vplus-card-nav {
  display: flex;
  gap: 1rem;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid #dee2e6;
}
.vplus-card-nav .btn {
  flex: 1 1 0;
}
.vplus-card-nav .vplus-card-next {
  background-color: #17a2b8;
  border-color: #17a2b8;
  color: #fff;
}
.vplus-card-nav .vplus-card-next:hover {
  background-color: #138496;
  border-color: #117a8b;
}

/* Create New Auction button - Auction Manager Green */
.btn-auction-submit {
  background-color: #28a745;
  border-color: #28a745;
  color: #fff;
}
.btn-auction-submit:hover {
  background-color: #218838;
  border-color: #1e7e34;
  color: #fff;
}

/* Toggle heading row with switch */
.vplus-toggle-heading-row .vplus-toggle-heading {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
}
.vplus-toggle-switch.form-switch {
  margin-bottom: 0;
  padding-left: 2.5em;
}

/* Section spacing for separation between groups */
.vplus-section-spacing {
  margin-top: 1rem;
}

/* Info callout box */
.vplus-info-callout {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
  background-color: #e8f4fd;
  border-left: 3px solid #0d6efd;
  border-radius: 0.25rem;
  font-size: 0.875rem;
  color: #495057;
}
.vplus-info-callout i {
  color: #0d6efd;
  flex-shrink: 0;
  margin-top: 0.125rem;
}

/* ── Status chips in the item-list status filter ───────────────────────────
   The filter's selected chips reuse the row badges' .vplus-status-<key>
   classes so the two can never drift apart. Those rules were written for a
   small dot and are inconsistent — some set a background, some only a colour —
   so the chip neutralises the background and keeps ONLY the colour, applying it
   as a left rail and a tinted fill via currentColor. That way one class works
   for every status without restating a single hex value here. */
.vplus-ss-badge.vplus-ss-badge--status {
  background-color: transparent;
  border-left: 3px solid currentColor;
}
.vplus-ss-badge.vplus-ss-badge--status .vplus-ss-badge__label {
  /* The status rules colour the whole chip; the label needs the page's text
     colour back or a pale status (e.g. sold-make-offer) becomes unreadable. */
  color: var(--bs-body-color, #212529);
}

/* Amber variant for a constraint the operator can actually trip — the plain
   blue callout reads as a tip, which is wrong for a rule the Dashboard will
   reject a save over. Modifier, not a separate block, so the two stay in step.
   align-items:flex-start because these run to two or three lines. */
.vplus-info-callout.vplus-info-callout--warning {
  background-color: #fff4e5;
  border-left-color: #f59e0b;
  color: #4a3c1d;
  align-items: flex-start;
}
.vplus-info-callout.vplus-info-callout--warning i {
  color: #b45309;
}

/* Comment field textarea min-height */
.vplus-comment-field {
  min-height: 100px;
}

:root {
  --vplus-primary: #1c3f85;
  --vplus-accent: #4fabff;
  /* AI affordance accent — deliberately NOT --bs-primary. That token follows the
     tenant's brand colour (default #1c3f85 navy), which left the selected AI
     badge indistinct against a photo thumbnail. Kept brand-independent so the
     "this is AI" signal reads the same on every site. */
  --vplus-ai-accent: #1a7fff;
  --vplus-ai-accent-glow: rgba(26, 127, 255, 0.35);
  --bs-link-color: var(--vplus-primary);
  --bs-link-color-rgb: 28, 63, 133;
  --vplus-font-family-base: Roboto, Arial, sans-serif;
  --vplus-font-weight-normal: 400;
  --vplus-font-weight-light: 300;
  --bs-primary-rgb: 28, 63, 133;
}
body {
  --bs-primary: var(--vplus-primary);
  --bs-body-font-weight: var(--vplus-font-weight-normal);
  background: var(--bs-gray-100);
  font-family: var(--vplus-font-family-base);
}

/* BOOTSTRAP OVERRIDES */
/* NOTE: the legacy block that poisoned --bs-success-rgb / --bs-warning-rgb /
   --bs-danger-rgb here has been removed. Those vars drive BOTH solid fills AND
   Bootstrap's .text-* utilities, so overriding danger to a pale pink
   (248,215,218) etc. made .text-danger / .text-success / .text-warning render
   as a barely-legible tint everywhere. The pale "subtle" look belongs on badge
   backgrounds only — and the .bg-* rules below already set those explicitly
   with hardcoded hex, so they don't depend on the poisoned vars. The active
   theme (vendor-plus-v2-1/css/styles.css) keeps the strong --bs-*-rgb values
   for legible text. */
.btn-link {
  --bs-btn-color: var(--vplus-primary);
  text-decoration: none;
}
.btn {
  --bs-btn-font-weight: 300;
}
.btn.btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--vplus-primary);
  --bs-btn-border-color: var(--vplus-primary);
}
.badge {
  --bs-badge-font-size: 0.875em;
  --bs-badge-border-radius: 1rem;
  --bs-badge-font-weight: 300;
}

/* Status badge colors matching vplus-filter-badge styles */
.bg-success {
  background-color: #2fa358 !important;
  color: #fff !important;
}
.bg-success .fa-circle {
  color: #fff;
}
.bg-warning {
  background-color: #c99212 !important;
  color: #fff !important;
}
.bg-warning .fa-circle {
  color: #fff;
}
.bg-danger {
  background-color: #a03f32 !important;
  color: #fff !important;
}
.bg-danger .fa-circle {
  color: #fff;
}
.bg-info {
  background-color: #17a2b8 !important;
  color: #fff !important;
}
.bg-info .fa-circle {
  color: #fff;
}
.bg-secondary {
  background-color: #666 !important;
  color: #fff !important;
}
.bg-secondary .fa-circle {
  color: #fff;
}

.bg-disclaimer {
  --bs-badge-color: #ffffff;
  background-color: rgb(81, 56, 99);
}

.form-control {
  font-weight: 400;
}

.page-title {
  font-size: 1.25rem;
  margin-bottom: 1rem;
}

/* Hide the theme's page title on VendorPlus surfaces (body.vplus-hide-page-title,
   set in front-end.php) so it doesn't double up with the heading each of these
   screens renders inside its own template.

   The active theme prints the page heading as `.entry-header > .page-title`
   (templates/loop/content-page.php) and archive titles as
   `.page-header > .page-title` (archive.php). Both are the page-CHROME heading,
   OUTSIDE `.entry-content`, so the in-content VendorPlus headings (which also use
   .page-title in some templates, but live inside .entry-content) are NOT hit.
   The extra page-builder selectors are harmless no-ops if the theme changes. */
body.vplus-hide-page-title .entry-header > .page-title,
body.vplus-hide-page-title .page-header > .page-title,
body.vplus-hide-page-title .entry-header > .entry-title,
body.vplus-hide-page-title .page-header > .entry-title,
body.vplus-hide-page-title .page-header .wp-block-post-title,
body.vplus-hide-page-title .elementor-page-title {
  display: none !important;
}

/* HEADER */
/* .header {
  margin-bottom: 1rem;
}
@media (min-width: 768px) {
  .header {
    margin-bottom: 2rem;
  }
} */
.vplus-logo {
  width: 120px;
  height: auto;
}
@media (min-width: 768px) {
  .vplus-logo {
    width: 180px;
  }
}

.dropdown-ellipsis .dropdown-toggle:after {
  content: none;
}

/* MENU */
.auction-nav .dropdown-toggle:not(.nav-link) {
  --bs-btn-color: var(--vplus-accent);
  text-decoration: none;
  font-size: 1.25rem;
}
.auction-nav .dropdown-toggle:not(.nav-link):after {
  content: none;
}
.auction-nav .dropdown-item {
  --bs-dropdown-link-color: var(--vplus-primary);
  /* Brand-consistent active item — Bootstrap's default active bg is raw blue
     (#0d6efd), which clashes with the suite palette. Drive it off the brand
     primary via Bootstrap's own var so .dropdown-item.active / :active follow.
     The matching active TEXT colour must be set too: .dropdown-item.active uses
     color:var(--bs-dropdown-link-active-color), which on this surface resolves
     to a dark value (the theme's BS4 SCSS $dropdown-link-active-color wins over
     the BS5 bundle's #fff default), rendering unreadable dark text on the
     #1c3f85 active bg — worst on the mobile/tablet offcanvas drawer (same
     class). Pin it white here. */
  --bs-dropdown-link-active-bg: var(--vplus-primary);
  --bs-dropdown-link-active-color: #fff;
  --bs-dropdown-item-padding-y: 0.75rem;
  --bs-dropdown-item-padding-x: 1.5rem;
}

/* Header-nav Phase 1 — caret breathing room + top-level item separation.
   Horizontal-nav range only (>=xl, where the desktop nav shows; below xl the
   hamburger offcanvas takes over). The submenu caret previously sat flush
   against the item's right edge, butting into the next item's leading icon —
   the #1 reported complaint AND the source of the "ambiguous grouping" read.
   The .nav-link is display:flex; gap:.5rem, so the caret ::after is a flex
   child already separated from the label by the gap — the fix is right-side
   padding on the toggle (breathing room), plus a small inter-item margin so
   groups read clearly. */
@media (min-width: 1200px) {
  .auction-nav .nav-link.dropdown-toggle {
    padding-right: 0.9rem;
  }
  .auction-nav .nav > .nav-item + .nav-item {
    margin-left: 0.25rem;
  }
}
.auction-nav .nav-link {
  --bs-nav-link-color: var(--vplus-primary);
}

/* Navigation Active/Hover Colored Borders */
.header .row.align-items-center {
  align-items: stretch !important;
}
.header .row > .col-auto {
  display: flex;
  align-items: stretch;
}
.auction-nav {
  display: flex;
  align-items: stretch;
}
.auction-nav .nav {
  align-items: stretch;
}
.auction-nav .nav-item {
  position: relative;
  display: flex;
  align-items: stretch;
}
.auction-nav .nav-item .nav-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border-bottom: 6px solid transparent;
  margin-bottom: -1px; /* Align with header bottom border */
  transition:
    border-color 0.2s ease,
    color 0.2s ease;
}
.auction-nav .nav-item .nav-link .fa-regular,
.auction-nav .nav-item .nav-link .fa-solid {
  font-size: 1rem;
  width: 1.25rem;
  text-align: center;
  line-height: 1;
  transition: color 0.2s ease;
}

/* Auction Manager - Green */
.auction-nav .nav-item.vplus-nav-auction-manager .nav-link:hover,
.auction-nav .nav-item.vplus-nav-auction-manager.active .nav-link {
  border-bottom-color: #28a745;
  color: #28a745;
}
.auction-nav .nav-item.vplus-nav-auction-manager .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-auction-manager.active .nav-link .fa-regular {
  color: #28a745;
}

/* Photo App - Neutral Blue */
.auction-nav .nav-item.vplus-nav-photo-app .nav-link:hover,
.auction-nav .nav-item.vplus-nav-photo-app.active .nav-link {
  border-bottom-color: #5b9bd5;
  color: #5b9bd5;
}
.auction-nav .nav-item.vplus-nav-photo-app .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-photo-app.active .nav-link .fa-regular {
  color: #5b9bd5;
}

/* Invoice Generator (legacy) & Invoicing (vp-invoicing) - Xero Blue */
.auction-nav .nav-item.vplus-nav-invoice-generator .nav-link:hover,
.auction-nav .nav-item.vplus-nav-invoice-generator.active .nav-link,
.auction-nav .nav-item.vplus-nav-invoicing .nav-link:hover,
.auction-nav .nav-item.vplus-nav-invoicing.active .nav-link {
  border-bottom-color: #13b5ea;
  color: #13b5ea;
}
.auction-nav .nav-item.vplus-nav-invoice-generator .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-invoice-generator.active .nav-link .fa-regular,
.auction-nav .nav-item.vplus-nav-invoicing .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-invoicing.active .nav-link .fa-regular {
  color: #13b5ea;
}

/* Marketing - Magenta (the studio's --vplus-ms-magenta, darkened to 4.6:1 on white) */
.auction-nav .nav-item.vplus-nav-marketing .nav-link:hover,
.auction-nav .nav-item.vplus-nav-marketing.active .nav-link {
  border-bottom-color: #c026d3;
  color: #c026d3;
}
.auction-nav .nav-item.vplus-nav-marketing .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-marketing.active .nav-link .fa-regular {
  color: #c026d3;
}

/* Reports - Red */
.auction-nav .nav-item.vplus-nav-reports .nav-link:hover,
.auction-nav .nav-item.vplus-nav-reports.active .nav-link {
  border-bottom-color: #dc3545;
  color: #dc3545;
}
.auction-nav .nav-item.vplus-nav-reports .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-reports.active .nav-link .fa-regular {
  color: #dc3545;
}

/* Integrations & Settings - Charcoal */
.auction-nav .nav-item.vplus-nav-integrations-settings .nav-link:hover,
.auction-nav .nav-item.vplus-nav-integrations-settings.active .nav-link {
  border-bottom-color: #333333;
  color: #333333;
}
.auction-nav
  .nav-item.vplus-nav-integrations-settings
  .nav-link:hover
  .fa-regular,
.auction-nav
  .nav-item.vplus-nav-integrations-settings.active
  .nav-link
  .fa-regular {
  color: #333333;
}

/* Consignments - Amber/Orange */
.auction-nav .nav-item.vplus-nav-consignments .nav-link:hover,
.auction-nav .nav-item.vplus-nav-consignments.active .nav-link {
  border-bottom-color: #e67e22;
  color: #e67e22;
}
.auction-nav .nav-item.vplus-nav-consignments .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-consignments.active .nav-link .fa-regular {
  color: #e67e22;
}

/* Consignment Manager - Royal Blue (differentiates the siloed manager
   surface from the vendor-facing amber Consignments menu) */
.auction-nav .nav-item.vplus-nav-consignment-manager .nav-link:hover,
.auction-nav .nav-item.vplus-nav-consignment-manager.active .nav-link {
  border-bottom-color: #4169e1;
  color: #4169e1;
}
.auction-nav
  .nav-item.vplus-nav-consignment-manager
  .nav-link:hover
  .fa-regular,
.auction-nav
  .nav-item.vplus-nav-consignment-manager.active
  .nav-link
  .fa-regular {
  color: #4169e1;
}

/* Vendors (Agents & Consignors + Vendor Profiles + Supplier Profiles) - Gold.
   Vendors straddles Consignments and Invoicing, so the colour sits between the
   amber Consignments menu (#e67e22) and the Xero blue of Invoicing (#13b5ea)
   rather than claiming either. */
.auction-nav .nav-item.vplus-nav-vendors .nav-link:hover,
.auction-nav .nav-item.vplus-nav-vendors.active .nav-link {
  border-bottom-color: #c9962e;
  color: #c9962e;
}
.auction-nav .nav-item.vplus-nav-vendors .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-vendors.active .nav-link .fa-regular {
  color: #c9962e;
}

/* My Account - Slate Purple */
.auction-nav .nav-item.vplus-nav-my-account .nav-link:hover,
.auction-nav .nav-item.vplus-nav-my-account.active .nav-link {
  border-bottom-color: #6c5ce7;
  color: #6c5ce7;
}
.auction-nav .nav-item.vplus-nav-my-account .nav-link:hover .fa-regular,
.auction-nav .nav-item.vplus-nav-my-account.active .nav-link .fa-regular {
  color: #6c5ce7;
}

/* Dropdown hover-open and caret for desktop nav */
.auction-nav .nav-item.dropdown .nav-link.dropdown-toggle {
  cursor: pointer;
}
.auction-nav .nav-item.dropdown .nav-link.dropdown-toggle::after {
  display: inline-block;
  margin-left: 0.35em;
  vertical-align: 0.15em;
  content: "";
  border-top: 0.3em solid;
  border-right: 0.3em solid transparent;
  border-bottom: 0;
  border-left: 0.3em solid transparent;
  opacity: 0.4;
  transition: opacity 0.2s ease;
}
.auction-nav .nav-item.dropdown:hover .nav-link.dropdown-toggle::after {
  opacity: 1;
}
.auction-nav .nav-item.dropdown .nav-link.dropdown-toggle {
  padding: inherit;
  font-size: inherit;
  line-height: inherit;
}
@media (min-width: 1200px) {
  /* Open nav dropdowns on hover — but NOT the notification bell. The bell's
     panel relies on Bootstrap/Popper to position it (anchored to the toggle's
     right edge); hover-opening it with raw CSS skips Popper, so the panel
     renders right-aligned at top:100% and bleeds off the screen edge. Excluding
     .vplus-notif-item makes the bell click-only, letting Popper place it.

     Breakpoint is 1200px (xl) to match the horizontal-nav visibility window
     (the nav is d-xl-flex; below xl the hamburger offcanvas owns navigation).

     The menu is kept RENDERED (display:block) but hidden via opacity/visibility
     so the open/close can transition (display itself can't animate). It stays
     position:absolute / top:100% so the always-rendered box never reserves flow
     space; pointer-events:none + visibility:hidden keep the hidden menu from
     intercepting clicks. */
  .auction-nav .nav-item.dropdown:not(.vplus-notif-item) > .dropdown-menu {
    display: block;
    position: absolute;
    top: 100%;
    margin-top: 0;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
  .auction-nav
    .nav-item.dropdown:not(.vplus-notif-item):hover
    > .dropdown-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }

  /* Motion flourish — subtle fade + rise, gated by reduced-motion. The rise +
     transition only apply when the user hasn't asked to reduce motion; the
     show/hide above still works regardless. */
  @media (prefers-reduced-motion: no-preference) {
    .auction-nav .nav-item.dropdown:not(.vplus-notif-item) > .dropdown-menu {
      transform: translateY(-6px);
      transition:
        opacity 0.15s ease-out,
        transform 0.15s ease-out,
        visibility 0s linear 0.15s;
    }
    .auction-nav
      .nav-item.dropdown:not(.vplus-notif-item):hover
      > .dropdown-menu {
      transform: translateY(0);
      transition:
        opacity 0.15s ease-out,
        transform 0.15s ease-out;
    }
    /* Caret gentle rotate on hover (NOT [aria-expanded] — that's click-only;
       these dropdowns open on hover). */
    .auction-nav .nav-link.dropdown-toggle::after {
      transition:
        transform 0.15s ease-out,
        opacity 0.2s ease-out;
    }
    .auction-nav
      .nav-item.dropdown:not(.vplus-notif-item):hover
      > .nav-link.dropdown-toggle::after {
      transform: rotate(180deg);
    }
    /* Dropdown item: tiny lead-in nudge on hover (the item-x padding is 1.5rem;
       nudge to ~1.7rem). Decorative only. */
    .auction-nav .dropdown-item {
      transition:
        background-color 0.12s ease,
        color 0.12s ease,
        padding-left 0.12s ease;
    }
    .auction-nav .dropdown-menu .dropdown-item:hover {
      padding-left: 1.7rem;
    }
  }
}

@media (min-width: 768px) {
  li.nav-item.welcome-text {
    display: flex;
    align-items: center;
  }
  li.nav-item.welcome-text:before {
    content: "|";
    margin: 0 1rem;
    opacity: 0.2;
  }
}

/* User-menu dropdown button (in .auction-nav, replaces the old plain
   "Hi {name}" label — now a Bootstrap dropdown toggle bundling Integrations
   & Settings, Webtron Dashboard, and Log Out). */
.auction-nav .nav-item.dropdown:has(.vp-user-menu-btn) {
  display: flex;
  align-items: center;
}
.vp-user-menu-btn {
  display: inline-flex !important;
  align-items: center;
  gap: 0.3125rem;
  padding: 0.25rem 0.5rem;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(0, 0, 0, 0.09);
  border-radius: 2rem;
  font-size: 0.8125rem !important;
  font-weight: 500;
  line-height: 1;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s,
    box-shadow 0.15s;
  max-width: 14rem;
  white-space: nowrap;
}
.vp-user-menu-btn:hover {
  background: #fff;
  border-color: rgba(0, 0, 0, 0.16);
  box-shadow: 0 1px 0.1875rem rgba(0, 0, 0, 0.08);
}
.vp-user-menu-btn.show,
.vp-user-menu-btn[aria-expanded="true"] {
  background: #fff;
  border-color: rgba(0, 0, 0, 0.18);
  box-shadow: 0 1px 0.1875rem rgba(0, 0, 0, 0.1);
}
.vp-user-menu-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.875rem;
  color: #6c757d;
  flex-shrink: 0;
}
.vp-user-menu-name {
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.vp-user-menu-caret {
  font-size: 0.5625rem;
  color: #6c757d;
  flex-shrink: 0;
  transition: transform 0.2s;
}
.vp-user-menu-btn[aria-expanded="true"] .vp-user-menu-caret {
  transform: rotate(180deg);
}
.vp-user-menu-btn + .dropdown-menu {
  padding: 0;
  /* Right-align to the button regardless of Popper. The menu carries
     .dropdown-menu-end, but Bootstrap only applies end-alignment when Popper
     has stamped [data-bs-popper]; in the STATIC (pre-open / no-Popper) render
     state the menu falls back to the base `left: 0` and — being a fixed ~192px
     wide — spills past the viewport's right edge (the user menu sits at the far
     right of the nav), adding ~22px of horizontal scroll on wider desktops.
     Forcing right-alignment here fixes that static state; when Popper IS active
     its inline `inset`/`transform` still win, so the open dropdown is unchanged. */
  right: 0;
  left: auto;
}
.vp-user-menu-btn + .dropdown-menu .dropdown-divider {
  margin: 0;
}
.vp-user-menu-btn + .dropdown-menu .dropdown-item {
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
  color: #2c3338;
}

/* The user pill is a .nav-link, so it inherits the nav's active-tab indicator
   (`border-bottom: 6px solid transparent` + `margin-bottom: -1px`, :5932).
   On a 2rem-radius pill that reads as a lopsided border and pushes it out of
   line with its siblings. Measured via CDP, not guessed. */
.auction-nav .nav-item .nav-link.vp-user-menu-btn {
  border-bottom-width: 1px;
  margin-bottom: 0;
}

/* The nav's generic hover indent (`padding-left: 1.7rem`, :6149) is written for
   full-width nav dropdowns whose items pad to 1.5rem. These items pad to 1rem,
   so the same rule jumps them 16px -> 27.2px on hover — measured. Match the
   nesting (both media queries) so this lands in the same conditional, and pin
   the resting padding. */
@media (min-width: 1200px) {
  @media (prefers-reduced-motion: no-preference) {
    .auction-nav .vp-user-menu-btn + .dropdown-menu .dropdown-item:hover {
      padding-left: 1rem;
    }
  }
}

/* BREADCRUMBS */
.vplus-breadcrumbs {
  font-size: 0.825rem;
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 1rem;
}
.vplus-breadcrumbs > * {
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: calc(100% / 3);
  overflow: hidden;
}
.vplus-breadcrumbs a {
  text-decoration: none;
  color: var(--vplus-primary);
}
.vplus-breadcrumbs .fa {
  font-size: 0.5rem;
}

/* LOT NAV */
.vplus-lot-nav {
  display: flex;
  align-items: center;
  margin-bottom: 1rem;
  gap: 0.5rem;
}
.vplus-lot-nav > * {
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: calc(100% / 2);
  overflow: hidden;
}
.vplus-lot-nav .me-auto {
  text-align: left;
}

.vplus-lot-nav .btn {
  padding: 0.375rem 0.5rem;
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  /* These buttons are `icon <space> label`, but inline-flex COLLAPSES that
     literal whitespace, so the icon butts up against the text. A gap on the
     flex container spaces every icon/label pair evenly without restructuring
     the markup or hand-tuning a margin per button. */
  gap: 0.5rem;
}

.vplus-lot-nav .vplus-bulk-actions {
  margin-right: 0;
}

/* AI Speed Lotting — solid fill, reusing the Speed Lotting mode button's exact
   treatment (the dark-blue gradient + black border it wears when active) so the
   feature reads as the same thing in both places. Outline would have made it
   the odd one out in a row of solid buttons.
   Not .btn-primary: Speed Lotting owns this dark blue, distinct from the row's
   primary-blue Create New Auction / Create New Item. */
/* ⚠ `.btn.btn-speed-lotting`, not `.vplus-lot-nav .btn-speed-lotting`: both are
   2 classes, so against Bootstrap's own `.btn.btn-primary` the winner would be
   decided by SOURCE ORDER — and vendor-plus.css registers with EMPTY deps
   (enqueue-scripts.php), so it is not guaranteed to load after Bootstrap.
   Adding .vplus-lot-nav makes it 3 classes, which wins on specificity alone
   regardless of which stylesheet lands first. */
.vplus-lot-nav .btn.btn-speed-lotting {
  background: linear-gradient(135deg, #2c5282, #1a365d);
  border-color: #000;
  color: #fff;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.55);
}

.vplus-lot-nav .btn.btn-speed-lotting:hover,
.vplus-lot-nav .btn.btn-speed-lotting:focus {
  background: linear-gradient(135deg, #35629b, #1f4270);
  border-color: #000;
  color: #fff;
}

/* ── Desktop/tablet ordering ──────────────────────────────────────────────
   AI Speed Lotting sits BEFORE Create New Auction.

   🔴 This MUST be an explicit rule. It previously relied on DOM order, on the
   (incorrect) assumption that the button was emitted first — it is emitted at
   lot-nav.php:106, AFTER Create New Auction at :90, so it rendered on the wrong
   side. Desktop order is otherwise an undocumented side effect of PHP statement
   order, which silently reorders the row whenever the template is edited.

   ⚠ `.me-auto` (Back link / spacer) is pinned to -1 so a negative order here
   cannot jump it. Both are explicit precisely so neither depends on the other's
   default. */
.vplus-lot-nav .me-auto {
  order: -1;
}

.vplus-lot-nav .btn-speed-lotting {
  order: 1;
}

/* Everything else defaults to order 0 — i.e. AFTER Speed Lotting — so this one
   value is all that is needed to place it. */
.vplus-lot-nav .btn-new-sale,
.vplus-lot-nav .btn-new-lot,
.vplus-lot-nav .btn-new-lot-pick,
.vplus-lot-nav .vplus-bulk-actions {
  order: 2;
}

/* Create New Item is the primary action in this row — give it a little more
   presence than the buttons beside it. */
.vplus-lot-nav .btn-new-lot {
  padding: 0.5rem 0.875rem;
  min-height: 42px;
  font-weight: 500;
}

/* Empty-state glow on Create New Item, matching the Upload Photos affordance on
   the lot form: the same amber ring and 2s cadence, applied while the auction
   has no items yet so the operator has an obvious place to start. Added by
   vendor-plus-lot-list.js only when the list is genuinely empty. */
.vplus-lot-nav .btn-new-lot.is-empty {
  animation: vplus-new-lot-glow 2s ease-in-out infinite;
}
@keyframes vplus-new-lot-glow {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(255, 193, 7, 0);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(255, 193, 7, 0.4);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vplus-lot-nav .btn-new-lot.is-empty {
    animation: none;
    box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.45);
  }
}

/* Lot List Action Buttons - Consistent Styling */
.vplus-action-row .btn {
  height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  white-space: nowrap;
}

/* Sync to Dashboard - Green like Sync & Next */
.vplus-btn-sync-to {
  background-color: #1c8575;
  border-color: #1c8575;
  color: #fff;
}
.vplus-btn-sync-to:hover,
.vplus-btn-sync-to:focus {
  background-color: #25b19c;
  border-color: #25b19c;
  color: #fff;
}
.vplus-btn-sync-to:disabled {
  background-color: #1c8575;
  border-color: #1c8575;
  color: #fff;
  opacity: 0.5;
}

/* Pull from Dashboard - Blue */
.vplus-btn-pull-from {
  background-color: #4a90d9;
  border-color: #4a90d9;
  color: #fff;
}
.vplus-btn-pull-from:hover,
.vplus-btn-pull-from:focus {
  background-color: #3a7fc8;
  border-color: #3a7fc8;
  color: #fff;
}

/* Sync Statuses - Green like Sync to Dashboard */
.vplus-btn-sync-statuses {
  background-color: #1c8575;
  border-color: #1c8575;
  color: #fff;
}
.vplus-btn-sync-statuses:hover,
.vplus-btn-sync-statuses:focus {
  background-color: #25b19c;
  border-color: #25b19c;
  color: #fff;
}

/* Bulk AI Analysis - Warning/Orange like AI Description buttons */
.vplus-btn-bulk-ai {
  background-color: #ffc107;
  border-color: #ffc107;
  color: #212529;
}
.vplus-btn-bulk-ai:hover,
.vplus-btn-bulk-ai:focus {
  background-color: #ffca2c;
  border-color: #ffc720;
  color: #212529;
}
.vplus-btn-bulk-ai:disabled {
  background-color: #ffc107;
  border-color: #ffc107;
  color: #212529;
  opacity: 0.5;
}

/* Re-Stagger - Warning/Orange like AI Description buttons */
.vplus-action-restagger {
  background-color: #ffa407;
  border-color: #ffc107;
  color: #212529;
}
.vplus-action-restagger:hover,
.vplus-action-restagger:focus {
  background-color: #ffa42c;
  border-color: #ffc720;
  color: #212529;
}
.vplus-action-restagger:disabled {
  background-color: #fedb6f;
  border-color: #ffc107;
  color: #212529;
  opacity: 0.5;
}

/* Validate - Warning/Orange like AI Description buttons */
.vplus-action-validate {
  background-color: #13df00;
  border-color: #66ff07;
  color: #212529;
}
.vplus-action-validate:hover,
.vplus-action-validate:focus {
  background-color: #0fb400;
  border-color: #474747;
  color: #ffffff;
}
.vplus-action-validate:disabled {
  background-color: #0fb400;
  border-color: #474747;
  color: #ffffff;
  opacity: 0.5;
}

/* Lot List Header */
.vplus-lot-list-header {
  padding: 0.75rem 1rem;
  font-size: 0.875rem;
}
.vplus-lot-list-header .row {
  align-items: center;
}

/* Select All Checkbox */
#vplus-select-all {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

/* Lot Item Checkbox */
.vplus-lot-checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

.vplus-sale-archive #content .btn-primary {
  --vplus-primary: #1c8575;
  --bs-btn-border-color: #1c8575;
  --bs-btn-hover-bg: #25b19c;
  --bs-btn-hover-border-color: #25b19c;
  --bs-btn-active-bg: #25b19c;
  --bs-btn-active-border-color: #25b19c;
}

.vplus-sale-archive #content a:not(.btn) {
  --bs-link-color-rgb: 28, 133, 117;
}
.vplus-sale-archive #content a:not(.btn):hover {
  --bs-link-color-rgb: 37, 177, 156;
}

/* FOOTER */
.footer {
  margin-bottom: 2rem;
}
.powered-by {
  text-align: center;
  margin-top: 2rem;
}
.powered-by-text {
  font-size: 0.7em;
  display: inline-block;
  vertical-align: sub;
}
.powered-by a {
  opacity: 0.4;
  transition: opacity 0.2s ease;
  text-decoration: none;
}
.powered-by a:hover,
.powered-by a:active {
  opacity: 1;
}
.powered-by img {
  width: 120px;
  vertical-align: bottom;
}
.wt-logo a:hover {
  opacity: 1;
}
.wt-logo img {
  width: 150px;
}

@keyframes pulsate {
  0% {
    box-shadow: none;
  }
  50% {
    box-shadow: 0 0 10px var(--vplus-accent);
  }
  100% {
    box-shadow: none;
  }
}

.element {
  animation: pulsate 1s infinite;
}

.vplus-link--main {
  text-decoration: none;
  font-weight: bold;
  line-height: 1.25;
  display: block;
}

#vplus-photo-filter label:has(input:checked) {
  background: #e9eef6;
}

.vplus-lot-summary > .row {
  gap: 0.5rem;
}

.vplus-lot-summary .vplus-link--main {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.vplus-lot-number {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  background: #000;
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  white-space: nowrap;
}

.vplus-lot-summary-badges {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.35rem;
  max-width: 100%;
}

.vplus-lot-meta-link {
  text-decoration: none;
}

.vplus-lot-meta-link:hover .vplus-lot-meta-badge {
  border-color: rgba(0, 0, 0, 0.25);
  color: var(--vplus-accent);
}

.vplus-lot-meta-badge-label {
  font-weight: 600;
}

/* The .vplus-lot-summary-badges row already wraps badge-to-badge, so the only
   residual overflow risk is a SINGLE badge whose value is longer than the
   content column. Below lg this caps each lot-meta badge to the container width
   and lets its text wrap, so a long value (e.g. "End Date and Time: 30 July
   2026 6:00 pm" in the narrow tablet-portrait content column, or a long
   Purchase Option on mobile) wraps instead of clipping with a dangling
   separator / pushing the row past the edge. The connected single-line look
   returns at lg+ where the column is wide enough. */
@media (max-width: 991.98px) {
  .vplus-lot-summary-badges .vplus-lot-meta-badge {
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
  }
}

.vplus-list-item .vplus-lot-summary > .row {
  --bs-gutter-y: 0.35rem;
  flex-wrap: nowrap;
}

.vplus-list-item .vplus-lot-summary > .row > .col {
  min-width: 0;
}

.vplus-list-item-actions {
  margin-top: 0 !important;
  white-space: nowrap;
}

.vplus-list-item-select,
.vplus-list-item > .row > .vplus-list-item-select,
.vplus-list-item > .row > .vplus-list-item-actions {
  margin-top: 0 !important;
}

.vplus-list-item > .row > .vplus-list-item-select > input[type="checkbox"] {
  display: block;
  margin: 0;
}

.vplus-status-filter-option:hover {
  border-color: #b6c6dc;
  background: #f8fbff;
}

.vplus-status-filter-option:hover .vplus-status-filter-label {
  color: #1f3f66;
}

.vplus-status-filter-input:focus-visible + .vplus-status-filter-label {
  outline: 2px solid rgba(13, 110, 253, 0.35);
  outline-offset: 3px;
  border-radius: 6px;
}

.vplus-auction-status-tabs .nav-link:hover,
.vplus-lot-status-tabs .nav-link:hover {
  border-color: #b6c6dc;
  background: #f8fbff;
  color: #1f3f66;
}

.vplus-auction-status-tabs,
.vplus-lot-status-tabs {
  justify-content: center;
}

@media (max-width: 767.98px) {
  .vplus-list-item > .row {
    align-items: flex-start !important;
  }

  .vplus-list-item .vplus-lot-summary > .row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    column-gap: 0.5rem;
  }

  .vplus-list-item .vplus-lot-summary > .row > .col {
    grid-column: 1;
    grid-row: 1;
  }

  .vplus-list-item .vplus-lot-summary > .row > .col-12 {
    grid-column: 1 / -1;
    grid-row: 2;
    width: auto;
  }

  .vplus-list-item .vplus-list-item-actions {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    text-align: right;
  }

  .vplus-list-item .vplus-lot-summary-badges .vplus-badge {
    max-width: 100%;
    white-space: normal;
    text-align: left;
  }
}

/* Lot List Quick Edit Styles */
.vplus-lot-summary {
  transition: background-color 0.2s ease;
}

.vplus-lot-summary:has(.vplus-lot-details-panel:visible) {
  background-color: #f8f9fa;
  border-radius: 0.5rem;
  padding: 0.5rem;
  margin: -0.5rem;
  margin-bottom: 0.5rem;
}

.vplus-lot-toggle-details {
  border-radius: var(--bs-border-radius);
  padding: 0.25rem 0.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  white-space: nowrap;
  font-size: 0.8125rem;
  gap: 0.25rem;
  background-color: #5c7cfa;
  border-color: #5c7cfa;
  color: white;
}

.vplus-lot-toggle-details .fa-regular {
  margin-right: 0 !important;
}

.vplus-lot-toggle-details:hover {
  background-color: #4263eb;
  border-color: #4263eb;
  color: white;
}

.vplus-lot-details-panel {
  background: white;
  border-radius: 0.5rem;
  padding: 1rem;
  margin-top: 0.5rem;
}

.vplus-lot-gallery-thumbs {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.vplus-lot-thumb {
  width: 60px;
  height: 60px;
  border-radius: 0.25rem;
  overflow: hidden;
  background: #f0f0f0;
}

.vplus-lot-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.vplus-lot-thumb-more {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #e0e0e0;
  color: #666;
  font-weight: 600;
  font-size: 0.875rem;
}

.vplus-lot-dropzone {
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.vplus-lot-dropzone:hover {
  background-color: #e9ecef;
}

/* Lot List Checkbox Styles */
.vplus-sales-list [type="checkbox"] {
  display: block;
  width: 1.25rem;
  height: 1.25rem;
  cursor: pointer;
  accent-color: var(--bs-primary);
  margin-top: 0.5rem;
}

/* Syncing Badge Styles */
.vplus-status-syncing {
  color: #0dcaf0;
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

/* Revision Pending Pulse Animation */
.vplus-revision-pulse {
  animation: vplus-revision-glow 2s ease-in-out infinite;
}
@keyframes vplus-revision-glow {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.5);
  }
  50% {
    box-shadow: 0 0 8px 3px rgba(255, 193, 7, 0.35);
  }
}

.vplus-lot-quick-edit .vplus-sync-status {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: 0.5rem;
  font-size: 0.75rem;
}

/* Quick Edit Rich Text Editor Styles */
.vplus-lot-quick-edit .ql-container {
  min-height: 150px;
  font-size: 0.875rem;
}

.vplus-lot-quick-edit .ql-editor {
  min-height: 150px;
}

/* Quick Edit Section Styles */
.vplus-lot-section-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--bs-secondary);
  margin-bottom: 1rem;
}

.vplus-lot-edit-section {
  background: #fafbfc;
  padding: 1rem;
  border-radius: var(--bs-border-radius);
  margin-bottom: 1rem;
}

.vplus-lot-edit-section:last-child {
  margin-bottom: 0;
}

/* Lot Gallery Area (Photo App style) */
.vplus-lot-gallery-area {
  background: #f8f9fa;
  padding: 1rem;
  border-radius: var(--bs-border-radius);
  height: 100%;
}

.vplus-lot-photo-upload-field .file-upload {
  cursor: pointer;
  display: flex;
  align-items: center;
  font-size: 0.875rem;
}

.vplus-lot-photo-upload-field .file-upload--hidden {
  display: none;
}

.vplus-lot-file-wrapper {
  margin-top: 0.5rem;
}
