/**
 * VendorPlus core styles — part 2 of 10: Badges, buttons, cards and shared components
 *
 * 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 910-2429 of the original file.
 */

/* ============================================================
   BADGES — the canonical VendorPlus pill
   ============================================================
   Keeps Bootstrap 5.3's badge model (em padding, line-height 1, .75em size,
   pill radius) but uses inline-flex so the icon gap is a real `gap` rather
   than a utility margin.

   IMPORTANT: the text inside a pill must live in an element, never as a bare
   text node. A bare text node beside an element child becomes an anonymous
   flex item, which `align-items: center` does not centre — measured ~0.9px
   high across every family on Manage Consignments. `line-height: 1` alone
   does not fix it; wrapping the text does. */
.vplus-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.3em 0.65em;
  min-height: 20px;
  border-radius: 999px;
  white-space: nowrap;
  vertical-align: middle;
  border: 1px solid transparent;
}
.vplus-pill > .fa-solid,
.vplus-pill > .fa-regular,
.vplus-pill > i {
  font-size: 1em;
  line-height: 1;
}
.vplus-pill > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A wrapping row of pills under a table-cell title. One grammar for every
   cell, replacing the ad-hoc .mt-1/.mt-2 wrapper mix. */
.vplus-badge-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  margin-top: 4px;
}

/* Decision-context chips (DW6, Pending rows) and the aging badge (O1). Moved
   here from auction-manager-submissions-body.php's inline <style> so every
   pill family is sized from one place — Core and Consignments deploy
   together. Colour is the only thing these still own. */
.vplus-dc-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-items: center;
}
.vplus-dc-chip {
  background: #f2f4f7;
  color: #667085;
  border-color: #e4e7ec;
}
.vplus-dc-chip--ok {
  background: #e3efe8;
  color: #2f6d4f;
  border-color: #bcd8c8;
}
.vplus-dc-chip--warn {
  background: #fdf1e3;
  color: #9a5b1f;
  border-color: #f0d9b8;
}
body.vplus-dark-mode .vplus-dc-chip {
  background: #2a2d31;
  color: #9aa0a6;
  border-color: #3a3f45;
}
body.vplus-dark-mode .vplus-dc-chip--ok {
  background: #1f3328;
  color: #7fc9a2;
  border-color: #2e4d3c;
}
body.vplus-dark-mode .vplus-dc-chip--warn {
  background: #3a2d1c;
  color: #d9a55f;
  border-color: #55452c;
}

/* O1 — aging badge. Colour is a signal, so it carries a text label too:
   "3 days waiting" reads the same to a colour-blind operator. */
.vplus-aging-badge {
  margin-left: 0.4rem;
}
.vplus-aging-badge--warn {
  background: #fff3cd;
  color: #7a5b00;
}
.vplus-aging-badge--late {
  background: #f8d7da;
  color: #842029;
}

.vplus-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.3em 0.65em;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  min-height: 20px;
  letter-spacing: 0.015em;
  /* Transparent 1px border matches the .vplus-pill box; without it an
     unbordered badge renders ~1.2px shorter than the bordered ones beside it. */
  border: 1px solid transparent;
  border-radius: 1rem;
  white-space: nowrap;
  vertical-align: middle;
  /* A badge carrying a long auction name overran its card on narrow phones —
     nowrap with no ceiling, clipped by the card's overflow. Mirrors .vplus-pill
     above, which has had the ellipsis treatment since it was written. */
  max-width: 100%;
  min-width: 0;
}
.vplus-badge > span {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* --- Semantic colour variants --- */
.vplus-badge-pending {
  background: #fff3cd;
  color: #664d03;
}
.vplus-badge-approved {
  background: #d1e7dd;
  color: #0f5132;
}
.vplus-badge-rejected {
  background: #f8d7da;
  color: #842029;
}
.vplus-badge-assigned {
  background: #cff4fc;
  color: #055160;
}
.vplus-badge-live {
  background: #d1e7dd;
  color: #0f5132;
}
.vplus-badge-sold {
  background: #d1e7dd;
  color: #0f5132;
}
.vplus-badge-unsold {
  background: #e9ecef;
  color: #495057;
}
/* Closed - Pending Auctioneer Confirmation. Amber like Pending Review, because
   for the vendor it means the same thing: waiting on us. Deliberately NOT the
   green of Sold — the sale is not confirmed yet. */
.vplus-badge-closed {
  background: #fff3cd;
  color: #664d03;
}
.vplus-badge-withdrawn {
  background: #e9ecef;
  color: #495057;
}
/* --- Functional variants --- */
.vplus-badge-info {
  background: #cff4fc;
  color: #055160;
}
.vplus-badge-success {
  background: #d1e7dd;
  color: #0f5132;
}
.vplus-badge-warning {
  background: #fff3cd;
  color: #664d03;
}
.vplus-badge-danger {
  background: #f8d7da;
  color: #842029;
}
.vplus-badge-primary {
  background: #cfe2ff;
  color: #084298;
}
.vplus-badge-secondary {
  background: #e9ecef;
  color: #495057;
}
.vplus-badge-dark {
  background: #343a40;
  color: #fff;
}
/* AM-3 — the Auction Report link badge carries the Reports nav red so the
   route to Reports reads the same wherever it is offered. */
.vplus-badge-reports {
  background: #dc3545;
  color: #fff;
}
.vplus-badge-reports:hover,
.vplus-badge-reports:focus {
  background: #bb2d3b;
  color: #fff;
}

/* AMT-1 — "pull from the Dashboard" actions. A blue/indigo accent separates
   them from the non-descript grey secondary badge. Placed AFTER
   .vplus-badge-secondary: equal specificity, so source order decides.
   These live here rather than in archive-sale-auctions-panel.php because the
   item list uses the same two controls as .vplus-badge spans and never
   includes that partial's inline <style>. */
.vplus-refresh-btn {
  border-radius: 0.5rem !important;
  white-space: nowrap;
  border: 1px solid #b9cdf0;
  box-shadow: none;
  background: #eef4fe;
  color: #1d4ed8;
  font-weight: 500;
  line-height: 1.2;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease, box-shadow .12s ease;
}
.vplus-refresh-btn .fa-regular {
  opacity: 0.9;
}
.vplus-refresh-btn:hover,
.vplus-refresh-btn:focus,
.vplus-refresh-btn:focus-visible {
  background: #dfeafd;
  border-color: #8fb3ec;
  color: #1e40af;
  box-shadow: 0 1px 3px rgba(29, 78, 216, 0.14);
}
.vplus-refresh-btn:disabled,
.vplus-refresh-btn.disabled,
.vplus-refresh-btn.vplus-refresh-cooling {
  opacity: 0.55;
  box-shadow: none;
}
/* Refresh Auction Details — a deeper indigo so the two sit side-by-side
   distinctly. */
.vplus-refresh-btn--details {
  border-color: #c3bdf0;
  background: #f0eefe;
  color: #5b3fd8;
}
.vplus-refresh-btn--details:hover,
.vplus-refresh-btn--details:focus,
.vplus-refresh-btn--details:focus-visible {
  background: #e6e1fd;
  border-color: #a596ec;
  color: #4c33b8;
}
/* --- Context-specific --- */
.vplus-badge-required {
  background: #f8d7da;
  color: #842029;
  font-size: 0.65em;
}
.vplus-badge-recommended {
  background: #d1e7dd;
  color: #0f5132;
  font-size: 0.65em;
}
.vplus-badge-optional {
  background: #e9ecef;
  color: #495057;
  font-size: 0.65em;
}
.vplus-auction-details-btn,
.vplus-item-detail-btn,
.vplus-portal-link-badge {
  background: #4d4d4d;
  color: #fff;
}
/* B2 — a field the operator cannot change (e.g. Opening Bid once the Item has
   received a bid). Amber rather than red: nothing is wrong, the field is just
   closed for editing. */
.vplus-badge-locked {
  background: #fff3cd;
  color: #664d03;
  font-size: 0.65em;
}
.vplus-ob-lock-note {
  font-size: 0.8em;
  color: #6c757d;
}
/* R4.3 — Required/Optional presentation for the pricing cluster: the inline
   label badge is kept for the required-checklist's detection (hasRequiredBadge()
   queries `.vplus-badge-required` inside label[for=id]) but made a visually-hidden
   MARKER, while the visible cue moves to a red asterisk in the label plus a
   centred badge below the field (mirrors .vplus-auto-increment-note). */
.vplus-badge--marker {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.vplus-req-star {
  color: #dc3545;
  font-weight: 700;
  margin-left: 0.15em;
}
/* Below-field badge block — same rhythm as .vplus-auto-increment-note. */
.vplus-field-req-note {
  margin-top: 0.5rem;
  text-align: center;
}
/* R5.4 — Required + Auto-Increments notes on one centred line (Bid Increment). The
   auto note is d-none until active, so the Required badge sits centred alone until
   then; when both show they sit side-by-side. The wrapper owns the top gap, so its
   children drop their own margins. */
.vplus-field-notes-inline {
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  align-items: center;
}
.vplus-field-notes-inline .vplus-field-req-note,
.vplus-field-notes-inline .vplus-auto-increment-note {
  margin-top: 0;
}
.vplus-badge-timed {
  background: #cfe2ff;
  color: #084298;
}
.vplus-badge-webcast {
  background: #f8d7da;
  color: #842029;
}
.vplus-badge-marketplace {
  background: #343a40;
  color: #fff;
}
/* Holding-pattern state (e.g. "Revision Pending"): a burnt-orange/peach that is
   deliberately deeper + more saturated than the pale-amber "pending" token, so
   the two warm states don't read as the same colour. */
.vplus-badge-revision {
  background: #ffe5d0;
  color: #8a4b1f;
}
/* Live badge context variants. Base "live" stays green (open + active). These two
   split off the ambiguous cases so a vendor can tell them apart:
   - catalogue: publicly visible but NOT yet open for bidding → cool slate (calm,
     "just listed", clearly not the same as active green Live).
   - ring: webcast live-bidding running, item not yet reached → warm amber
     ("imminent / attention"), distinct from both the green Live and the
     yellow "Pending Review". */
.vplus-badge-live-catalogue {
  background: #dde7f0;
  color: #33506b;
}
.vplus-badge-live-ring {
  background: #ffe8c2;
  color: #8a5a12;
}

.badge-lighter {
  background: #e9eef6;
  color: var(--bs-gray-800);
}
.badge-light {
  background: #e9eef6;
  color: var(--bs-gray-800);
}

/* ── Multi-select checkbox dropdown ── */
.vplus-multi-select-dropdown .form-select {
  height: calc(3.5rem + calc(var(--bs-border-width) * 2));
  padding: 1rem 2.25rem 1rem 0.75rem;
  color: var(--bs-body-color);
  cursor: pointer;
}
.vplus-multi-select-dropdown .dropdown-menu {
  max-height: 280px;
  overflow-y: auto;
  border-radius: var(--bs-border-radius);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.vplus-multi-select-dropdown .form-check {
  margin-bottom: 0;
}
.vplus-multi-select-dropdown .form-check-label {
  cursor: pointer;
  font-size: 0.9rem;
}
/* Prevent double caret: .form-select adds bg-image caret, .dropdown-toggle adds ::after caret */
.vplus-multi-select-dropdown .dropdown-toggle::after {
  content: none;
}

.vplus-sale-status {
  font-size: 1.2em;
  padding: 10px 20px;
  margin-bottom: 20px;
  font-weight: 100;
  display: inline-block;
  background: #fff;
  box-shadow: #eee 0px 1px 3px;
}
.vplus-draft {
  border-left: 5px solid lightgrey;
}
.vplus-preview {
  border-left: 5px solid lightblue;
}
.vplus-live {
  border-left: 5px solid darkseagreen;
}
.vplus-reconciliation {
  border-left: 5px solid mediumpurple;
}
.vplus-archived {
  border-left: 5px solid brown;
}
.vplus-badge-floor {
  display: inline-block;
  cursor: help;
  padding: 3px 5px;
  margin-left: 3px;
  font-size: 10px;
  line-height: 1;
  color: #fff;
  text-align: center;
  vertical-align: baseline;
  background-color: #337ab7;
  border-radius: 3px;
}
.vplus-badge-commission {
  display: inline-block;
  cursor: help;
  padding: 3px 5px;
  margin-left: 3px;
  font-size: 10px;
  line-height: 1;
  color: #fff;
  text-align: center;
  vertical-align: baseline;
  background-color: #ff7565;
}

#vplus-sync-photos-wrapper {
  margin-top: 40px;
}
#vplus-load-icon {
  margin-bottom: 20px;
}

#woaBidHistoryModal .modal-body {
  padding: 0 15px;
}
.vplus-bid-history-items {
  padding: 10px 0;
}
.vplus-bid-history-items:nth-child(odd) {
  background-color: #f1f1f1;
}
.vplus-bid-history-items-info-2 {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.vplus-bid-history-items-username {
  font-size: 0.825rem;
  font-weight: bold;
  display: flex;
  align-items: center;
}
.vplus-bid-history-items-amount {
  text-align: right;
  font-weight: bold;
  font-size: 1.2rem;
  min-width: 150px;
}
.vplus-bid-history-items-time {
  font-size: 0.825rem;
}
@media (min-width: 768px) {
  .vplus-bid-history-items-username {
    margin-bottom: 0;
  }
  .vplus-col-name {
    width: 50%;
  }
}
.vplus-bid-status--unknown .vplus-bid-history-items-amount {
  color: purple;
  opacity: 0.5;
}
.vplus-bid-status--double .vplus-bid-history-items-amount {
  text-decoration: line-through;
  color: darkorange;
  opacity: 0.5;
}
.vplus-bid-status--suspended .vplus-bid-history-items-amount {
  text-decoration: line-through;
  color: darkred;
  opacity: 0.5;
}
.vplus-bid-status--cancelled .vplus-bid-history-items-amount {
  text-decoration: line-through;
  opacity: 0.5;
}

#woa-download-invoice {
  margin-left: 1rem;
}

/* Styles */
.vplus-logo {
  margin: 1rem 0;
}
.header > .container:after {
  border-bottom: 1px solid #d9d9d9;
  content: " ";
  display: block;
}

/* Container width. Bootstrap's stock 540/720/960 caps starved the dense app
   pages below 1200px — measured on /sales/, a 767px tablet got a 516px column
   while a 575px phone was fluid. One smooth ramp to the 1800px ceiling from
   sm up instead of the old ≥1200-only override. */
@media (min-width: 576px) {
  .container {
    max-width: min(100%, 1800px);
  }
}

.btn-collapse-toggle {
  padding: 0 1rem;
  color: #666;
}
.btn-collapse-toggle:not(.collapsed) span[class*="fa-"] {
  transform: rotate(180deg);
}
.btn-collapse-toggle:focus {
  border-color: transparent;
  background: #f5f5f5;
}
.btn-collapse-toggle:focus {
  outline: none;
  border-color: transparent;
}
.card {
  margin-bottom: 1rem;
}
.card h5 {
  color: #6b6b6b;
  font-size: 0.825rem;
  text-transform: uppercase;
  font-weight: bold;
  margin: 0;
}
.card-body + .card-body.collapse,
.card-body + .card-body.collapsing {
  padding-top: 0;
}
.card-body > .row {
  row-gap: 1rem;
}
/* .input-group .form-control {
  border-right-color: transparent;
}
.input-group .input-group-text + div > .form-control {

} */

.file-upload {
  padding: 1rem 0.75rem;
  font-weight: 300;
  color: #666;
  border-top-left-radius: var(--bs-border-radius) !important;
  border-bottom-left-radius: var(--bs-border-radius) !important;
}
.file-upload--hidden + .file-upload {
  border-right: 0;
}
.file-upload--hidden + .file-upload + .btn {
  border-left: 0;
}
.file-upload--hidden.d-none + .file-upload,
.file-upload--hidden.d-none + .file-upload + .btn {
  background-color: var(--bs-secondary-bg);
}
.file-upload--hidden.d-none + .file-upload + .btn {
  border-color: var(--bs-border-color);
  color: var(--bs-gray-700);
}

.input-group .file-upload--hidden {
  position: absolute;
  opacity: 0;
  width: 100%;
  z-index: 3;
  height: 100%;
}
.input-group.input-group div ~ button {
  border: var(--bs-border-width) solid var(--bs-border-color);
  border-left-color: transparent;
}
.input-group.input-group div ~ button:hover {
  background: transparent;
  color: var(--bs-primary);
}
.input-group:has(.form-floating + button) input {
  border-right-color: transparent;
}

/* R5.3 — round the RIGHT edge of lot-form pricing/BP fields. Bootstrap's
   input-group rounding targets a direct-child .form-control; when the control is
   wrapped in .form-floating (as these fields are) the trailing radius never reaches
   the inner input, leaving the icon (left) edge rounded but the field's right edge
   square. Scoped to the lot form so unrelated input-groups are untouched. Three
   group shapes exist (see R5.3 in the assessment); each rounds its true right-most
   visible element. A stray .invalid-feedback block can be the DOM :last-child, so we
   avoid :last-child and target shapes explicitly. */
/* !important is required to beat the broad dictation-button rule near the end of
   this file (`.input-group > .form-floating > .form-control { border-*-right-radius:
   0 !important }`), which squares EVERY floating input's right edge. The
   `:last-child` guard keeps this correct when a dictation button IS injected as a
   later sibling — then .form-floating isn't :last-child, this rule doesn't fire, and
   the input stays square so the injected button abuts it flush. */
#vplus-lot-form .input-group > .form-floating:last-child > .form-control,
#vplus-lot-form .input-group > .form-floating:last-child > .form-select,
#vplus-express-form .input-group > .form-floating:last-child > .form-control,
#vplus-express-form .input-group > .form-floating:last-child > .form-select {
  border-top-right-radius: var(--bs-border-radius) !important;
  border-bottom-right-radius: var(--bs-border-radius) !important;
}
/* Shape 3 — trailing affix before an .invalid-feedback (R3.5 Charges/BP fields):
   the affix is the right-most visible element, round its right corners. */
#vplus-lot-form .input-group > .form-floating + .input-group-text,
#vplus-express-form .input-group > .form-floating + .input-group-text {
  border-top-right-radius: var(--bs-border-radius);
  border-bottom-right-radius: var(--bs-border-radius);
}
/* Shape 2 — trailing calculator button (Reserve): round its right corners. */
#vplus-lot-form .input-group > .form-floating + .vp-reserve-calculator,
#vplus-express-form .input-group > .form-floating + .vp-reserve-calculator {
  border-top-right-radius: var(--bs-border-radius);
  border-bottom-right-radius: var(--bs-border-radius);
}

.vplus-form-status:empty,
.vplus-file-photo-ai-uploaded:empty {
  display: none;
}
.vplus-file-photo-ai-uploaded {
  position: relative;
}
.vplus-file-photo-ai-uploaded img {
  border: 1px solid #f2f2f2;
  max-width: 100%;
  height: auto;
  border-radius: var(--bs-border-radius);
}

/* Minimum Offer Amount field highlight (red border) */
/* Special purchase-option field highlight (Minimum Acceptable Offer, Purchase
   Price / Display Price). R4.2d retoned this from a red `--bs-danger` border —
   which read as "danger/error" for what are notable-but-optional fields — to a
   calmer Bootstrap `--bs-info` treatment with a faint tint. `.vplus-special-field-highlight`
   is the shared class; `.vplus-minimum-offer-highlight` is kept as an alias so
   existing markup keeps working. */
.vplus-special-field-highlight,
.vplus-minimum-offer-highlight {
  border: 2px solid var(--bs-info);
  border-radius: var(--bs-border-radius);
  background-color: rgba(var(--bs-info-rgb), 0.06);
}
.vplus-special-field-highlight .input-group-text,
.vplus-minimum-offer-highlight .input-group-text {
  border: 0;
  background-color: transparent;
}
.vplus-special-field-highlight .form-control,
.vplus-minimum-offer-highlight .form-control {
  border: 0;
  background-color: transparent;
}

.form-check-wrapper,
.form-radio-wrapper {
  min-height: 3.625rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* R4.5 — subtle animate-IN when a conditional pricing row is revealed on an
   item-type / purchase-option change. Applied by VP_AnimateRevealedRows() only on
   a real hidden→shown transition (display stays toggled synchronously so
   validation / the required-checklist never desync). Opacity + a small upward
   slide; class self-removes on animationend. */
.vplus-row-reveal {
  animation: vplus-row-reveal 0.28s ease-out;
}
@keyframes vplus-row-reveal {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vplus-row-reveal {
    animation: none;
  }
}
/* .form-row:not(:last-child) {
  margin-bottom: 1rem;
} */

.alert p:last-child {
  margin-bottom: 0;
}

.btn-link-toggle {
  padding: 0 0.5rem;
  line-height: 1rem;
}

.btn-link-toggle + .collapsing {
  transition: all 0.3s ease-in;
}
.btn-link-toggle + .collapse {
  margin-top: 0;
}
.btn-link-toggle + .collapse.show,
.btn-link-toggle + .collapsing {
  margin-top: 1rem;
}
.btn-link-toggle:focus,
.btn-link-toggle:active {
  outline: none;
  --bs-btn-active-border-color: transparent;
}
.btn-link-toggle[aria-expanded="false"] .fa-toggle-on,
.btn-link-toggle[aria-expanded="false"] .fa-toggle-large-on {
  display: none;
}
.btn-link-toggle[aria-expanded="true"] .fa-toggle-off,
.btn-link-toggle[aria-expanded="true"] .fa-toggle-large-off {
  display: none;
}

.card-body .tab-content {
  padding: 1rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0 0 var(--bs-border-radius) var(--bs-border-radius);
  border-top: 0;
}

.card-body .row {
  row-gap: 1rem;
}

.vplus-upload-status {
  font-weight: bold;
  font-size: 0.75rem;
}

#vplus-video-tabs-content + .vplus-upload-status {
  margin-top: 1rem;
}

/* This code is from v1 of AI photo upload area */
/* .vplus-file-wrapper {
  padding-top: 0%;
  position: relative;
  transition: padding-top 0.5s ease-out;
}
.vplus-file-wrapper.init,
.vplus-file-wrapper:has(img) {
  padding-top: 75%;
}
.vplus-file-loading {
  display: none;
}
.vplus-file-wrapper.init + .vplus-file-loading {
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 3rem;
  color: #666;
}
.vplus-file-wrapper img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
} */

blockquote {
  border-left: calc(1rem / 2) solid #d4edff;
  padding-left: 0.75rem;
  font-weight: 300;
}

p,
ul,
ol,
li {
  font-weight: 400;
}

.vplus-file-wrapper {
  display: none;
  padding: 1rem;
  border: 1px dashed var(--gray-300);
  border-radius: var(--bs-border-radius);
  /* 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-wrapper.show {
  display: block !important;
  margin-top: 1rem;
}

.toast-close.toast-close {
  position: absolute;
  top: 0.25rem;
  right: 0.25rem;
  font-size: 0.75em;
}

@media (max-width: 575px) {
  .toastify {
    font-size: 0.825rem;
  }
}

.vplus-media-option {
  display: flex;
  pointer-events: none;
  opacity: 0;
  position: absolute;
  bottom: calc(100% - 0.5rem);
  z-index: -1;
  transition:
    bottom 0.3s ease-in,
    opacity 0.3s ease-in;
}
/* F1 — the panel was a near-invisible #eee hairline over a photo it floats
   above. Brand border + the same shadow the delete popover uses, so the two
   prompts read as one family. The :before caret colour must track the border
   or the arrow shows a grey seam. */
.vplus-media-option.show {
  border: 1px solid var(--vplus-primary, #1c3f85);
  opacity: 1;
  pointer-events: auto;
  border-radius: var(--bs-border-radius, 0.375rem);
  z-index: 100;
  background: #fff;
  bottom: calc(100% + 1rem);
  left: 50%;
  transform: translateX(-50%);
  box-shadow: 0 8px 28px rgba(15, 23, 42, 0.18);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem;
  padding: 0.5rem;
}
.vplus-media-option__btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.35rem;
  white-space: nowrap;
}
.vplus-media-option:before {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border-width: 10px;
  border-style: solid;
  border-color: var(--vplus-primary, #1c3f85) transparent transparent
    transparent;
}
.vplus-media-option:after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border-width: 8px;
  border-style: solid;
  border-color: #fff transparent transparent transparent;
}

/* P2 — keep the TILE-ANCHORED options row inside its tile.

   The row is 4 x 44px buttons (~132px) but a tile can be ~100px, and
   .vplus-file-container is `overflow: visible` (load-bearing — the
   delete-confirm popover must be able to escape the tile), so the buttons
   painted ~31px outside the card. Wrapping keeps every button >=24px wide
   instead of squeezing them into an untappable sliver.

   🔴 `:not(.show)` is load-bearing, NOT decoration. Below 576px the rule after
   this one turns .vplus-media-option.show into a FIXED bottom sheet with
   `max-width: none` and 2.75rem targets; clamping that to a ~100px tile would
   destroy the mobile treatment. But the RESTING state (no .show) stays
   `position: absolute` at every width — measured — so it must be clamped at
   every width too. Scoping this by breakpoint instead of by state left the
   overflow in place below 576px. */
.vplus-media-files .vplus-media-option:not(.show) {
  max-width: 100%;
  flex-wrap: wrap;
  justify-content: center;
}
.vplus-media-files .vplus-media-option:not(.show) > .btn {
  flex: 0 0 auto;
  min-width: 1.5rem;
  padding-left: 0.125rem;
  padding-right: 0.125rem;
}

/* >=576px the popover stays tile-anchored even when open. It is now a labelled
   2x2 grid, so it can no longer be clamped to the tile's width — that is what
   the old `max-width: 100%` + 1.5rem button clamp did, and it would shred the
   labels. It escapes the tile deliberately (.vplus-file-container is
   `overflow: visible`) and is centred on it, so `max-content` plus a viewport
   cap keeps it readable without overflowing the page. */
@media (min-width: 576px) {
  .vplus-media-files .vplus-media-option.show {
    width: max-content;
    max-width: min(20rem, calc(100vw - 2rem));
  }
}

@media (max-width: 575.98px) {
  .vplus-media-option.show {
    position: fixed;
    left: 0.75rem;
    right: 0.75rem;
    bottom: max(0.75rem, env(safe-area-inset-bottom));
    transform: none;
    width: auto;
    max-width: none;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem;
    border-radius: 12px 12px 10px 10px;
    box-shadow: 0 18px 45px rgba(15, 23, 42, 0.22);
    z-index: 1060;
  }

  .vplus-media-option:before,
  .vplus-media-option:after {
    display: none;
  }

  /* Labelled buttons: keep the 2.75rem tap height, drop the square min-width
     so the label decides the width inside the sheet's grid. */
  .vplus-media-option > .btn {
    min-height: 2.75rem;
  }
  .vplus-media-option.show > .vplus-media-option__btn {
    justify-content: center;
  }

  .vplus-media-option .vplus-delete-prompt.show {
    width: 100%;
    max-width: 22rem;
  }
}

.vplus-file-container:has(> .vplus-delete-prompt.show) > .vplus-media-option,
.vplus-file-item:has(> .vplus-delete-prompt.show) > .vplus-file-delete {
  display: none;
}

.vplus-delete-prompt {
  display: none;
}
.vplus-delete-prompt.show {
  display: flex;
  flex-direction: column;
  width: max-content;
  max-width: min(240px, calc(100vw - 2rem));
  justify-content: center;
  align-items: stretch;
  gap: 0.5rem;
  min-height: 0;
  padding: 0.7rem;
}
.vplus-delete-prompt-heading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-width: 0;
  width: 100%;
}
.vplus-delete-prompt-label {
  display: inline-flex;
  align-items: center;
  width: auto;
  min-width: 0;
  color: #212529;
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
}
.vplus-delete-prompt-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  color: #842029;
  font-size: 0.95rem;
}
.vplus-file-container .vplus-delete-prompt.show {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  min-width: 190px;
  z-index: 200;
  background: #fff;
  border: 1px solid #dee2e6;
  border-radius: 0.5rem;
  box-shadow: 0 8px 28px rgba(15, 23, 42, 0.18);
  pointer-events: auto;
}

.vplus-upload-status {
  display: none;
  margin-bottom: 1rem;
}

.vplus-file-container {
  position: relative;
}
.vplus-file-container.selected .image-box {
  box-shadow: 0px 0px 0 4px rgba(var(--bs-primary-rgb), 0.25);
  background: var(--bs-primary);
  border-color: var(--bs-primary);
}
.vplus-file-container.selected .image-box .photo {
  opacity: 0.75;
}
.vplus-file-container.already-synced .image-box {
  border-color: var(--bs-teal);
}
.vplus-file-container.to-be-synced .image-box {
  border-color: var(--bs-blue);
}
.vplus-file-container .vplus-cloud-check {
  color: var(--bs-teal);
  border-color: var(--bs-teal);
}
.vplus-file-container .vplus-cloud-upload {
  color: var(--bs-blue);
  border-color: var(--bs-blue);
}
.vplus-file-container .vplus-cloud-check,
.vplus-file-container .vplus-cloud-upload,
.vplus-file-container [class*=" vplus-cloud-"] {
  position: absolute;
  right: -0.5rem;
  bottom: calc(100% - 1rem);
  border: 1px solid;
  border-radius: 50%;
  background: #fff;
  width: 1.5rem;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.1);
}

.vplus-auctioneer-defaults-badge {
  cursor: pointer;
  transition:
    box-shadow 0.15s ease,
    filter 0.15s ease,
    transform 0.15s ease;
}

.vplus-auctioneer-defaults-badge:hover,
.vplus-auctioneer-defaults-badge:focus-visible {
  filter: brightness(1.08);
  transform: translateY(-1px);
  box-shadow: 0 0 0 0.15rem rgba(13, 110, 253, 0.2);
}

.vplus-auctioneer-defaults-badge.is-active {
  outline: 2px solid var(--bs-primary);
  outline-offset: 2px;
  box-shadow:
    0 0 0 0.2rem rgba(13, 110, 253, 0.35),
    0 0.25rem 0.65rem rgba(0, 0, 0, 0.16);
}

#vplus-card--auctioneer-defaults .vplus-auctioneer-defaults-tabs {
  gap: 0;
  justify-content: center;
}

#vplus-card--auctioneer-defaults {
  text-align: center;
}

#vplus-card--auctioneer-defaults > .d-flex {
  justify-content: center !important;
}

#vplus-card--auctioneer-defaults .vplus-auctioneer-defaults-button {
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
  font-weight: 600;
  min-height: 2.25rem;
  transition:
    box-shadow 0.15s ease,
    filter 0.15s ease,
    transform 0.15s ease;
}

#vplus-card--auctioneer-defaults .vplus-auctioneer-defaults-button.bg-warning,
#vplus-card--auctioneer-defaults .vplus-auctioneer-defaults-button.bg-info {
  color: #1f2933;
}

#vplus-card--auctioneer-defaults .vplus-auctioneer-defaults-button:hover,
#vplus-card--auctioneer-defaults
  .vplus-auctioneer-defaults-button:focus-visible {
  filter: brightness(1.08);
  transform: translateY(-1px);
  box-shadow: 0 0 0 0.15rem rgba(13, 110, 253, 0.2);
}

#vplus-card--auctioneer-defaults .vplus-auctioneer-defaults-button.active {
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, 0.85),
    0 0 0 0.2rem rgba(13, 110, 253, 0.28);
  filter: saturate(1.12) brightness(1.04);
}
.vplus-file-item .vplus-delete-prompt.show {
  width: max-content;
  right: 0;
  border-radius: var(--bs-border-radius);
  max-width: 100%;
}

.vplus-delete-prompt--file.show {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 0.75rem;
  width: 100%;
  max-width: 100%;
  padding: 0.75rem 1rem;
}

.vplus-delete-prompt--file .vplus-delete-prompt-icon {
  flex: 0 0 auto;
}

.vplus-delete-prompt--file .vplus-delete-prompt-label {
  flex: 1 1 auto;
  width: auto;
  margin: 0;
}

.vplus-delete-prompt--file .vplus-delete-prompt-heading {
  order: 1;
  flex: 1 1 auto;
}

/* The consignments uploader emits .vplus-submission-delete-*; the two Core
   uploaders emit the bare .delete-* classes. Both must be ordered here, or the
   unmatched buttons fall to order:0 and render ahead of the heading. */
.vplus-delete-prompt--file > .delete-yes,
.vplus-delete-prompt--file > .vplus-submission-delete-yes {
  order: 3;
  flex: 0 0 auto;
}

.vplus-delete-prompt--file > .delete-no,
.vplus-delete-prompt--file > .vplus-submission-delete-no {
  order: 4;
  flex: 0 0 auto;
}

.vplus-delete-prompt .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 36px;
  font-size: 0.86rem;
  font-weight: 700;
  padding: 0.35rem 0.65rem;
  border-radius: 0.35rem;
  text-decoration: none;
  gap: 0.25rem;
}
.vplus-delete-prompt .btn span {
  line-height: 1;
}
.vplus-delete-prompt .delete-no {
  color: #495057;
  background: #e9ecef;
  border-color: #dee2e6;
}
.vplus-delete-prompt .delete-no:hover {
  background: #dee2e6;
}
.vplus-delete-prompt .delete-yes {
  color: #fff;
  background: var(--bs-danger);
  border-color: var(--bs-danger);
}
.vplus-delete-prompt .delete-yes:hover,
.vplus-delete-prompt .delete-yes:focus {
  color: #fff;
  background: #bb2d3b;
  border-color: #b02a37;
}
.vplus-delete-prompt--video .delete-yes {
  background: #6f42c1;
  border-color: #6f42c1;
}
.vplus-delete-prompt--video .delete-yes:hover,
.vplus-delete-prompt--video .delete-yes:focus {
  background: #5a34a0;
  border-color: #5a34a0;
}
.processing {
  display: none;
  gap: 0.25rem;
  padding: 0.5rem;
  min-height: 38px;
  align-items: center;
}
.processing.show {
  display: flex;
}
.vplus-featured-image-icon {
  position: absolute;
  z-index: 50;
  color: #ffa500;
  font-size: 1.5rem;
  bottom: calc(100% - 0.5rem);
  line-height: 1rem;
  left: -0.25rem;
  transform: rotate(-15deg);
  text-shadow: 1px 2px 5px rgba(0, 0, 0, 0.2);
}

.vplus-ai-file-icon {
  display: none;
  position: absolute;
  color: var(--bs-primary);
  z-index: 50;
  font-size: 1.25rem;
  bottom: calc(100% - 1rem);
  line-height: 1rem;
  right: -0.5rem;
  border: 1px solid #eee;
  padding: 0.25rem;
  box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.1);
  border-radius: 1rem;
  background: #fff;
}

#vplus-ai-form-panel .vplus-ai-file-icon,
#vplus-ai-form-panel .ai-link {
  display: block;
}

/* Always-visible AI Analysis corner toggle (tap-to-select). One control on
   EVERY submission thumbnail — additional photos (.vplus-file-container) and
   section thumbs (.vplus-section-thumb). Unselected: a subtle pill inviting a
   tap. Selected (.is-ai-selected on the container): solid primary. It sits in
   the top-RIGHT corner of the thumbnail. */
.vplus-file-container,
.vplus-section-thumb {
  position: relative;
}
.vplus-ai-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  padding: 0.15rem 0.45rem;
  border-radius: 1rem;
  background: rgba(255, 255, 255, 0.92);
  color: #6c757d;
  border: 1px solid #d7dbe0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1;
  z-index: 60;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    color 0.15s ease,
    background 0.15s ease,
    border-color 0.15s ease;
}
.vplus-ai-toggle .fa-regular,
.vplus-ai-toggle .fa-solid {
  font-size: 0.85rem;
}
.vplus-ai-toggle:hover {
  color: var(--vplus-ai-accent);
  border-color: var(--vplus-ai-accent);
}
/* Selected: the badge must read at a glance against a photo, so it uses the
   dedicated AI accent rather than --bs-primary. A tenant's brand primary is
   often a dark navy (default #1c3f85), which sat too close to the unselected
   grey chip to be distinct. Solid fill + glow ring reuses the treatment from
   the lot form's document AI badge. */
.vplus-file-container.is-ai-selected .vplus-ai-toggle,
.vplus-section-thumb.is-ai-selected .vplus-ai-toggle {
  color: #fff;
  background: var(--vplus-ai-accent);
  border-color: var(--vplus-ai-accent);
  box-shadow:
    0 0 0 3px var(--vplus-ai-accent-glow),
    0 1px 3px rgba(0, 0, 0, 0.15);
}
/* Inline copy of the badge, embedded in the instruction sentence via the
   {badge} token. Static (not absolutely positioned) and non-interactive — a
   visual reference to the on-photo control. Carries the AI accent so it matches
   the selected badge it is pointing at. */
.vplus-ai-toggle.vplus-ai-toggle-inline {
  position: static;
  top: auto;
  right: auto;
  vertical-align: middle;
  margin: 0 0.15rem;
  padding: 0.1rem 0.4rem;
  color: #fff;
  background: var(--vplus-ai-accent);
  border-color: var(--vplus-ai-accent);
  box-shadow: none;
  cursor: default;
}
/* A ring on the selected thumbnail reinforces the choice. Matches the badge. */
.vplus-file-container.is-ai-selected .image-box,
.vplus-section-thumb.is-ai-selected {
  outline: 2px solid var(--vplus-ai-accent);
  outline-offset: -2px;
  border-radius: 0.35rem;
}

a.delete-link {
  color: #fff;
}
a.ai-link {
  color: purple;
  display: none;
}
a.process-link {
  color: var(--bs-warning);
  display: none;
}
.vplus-img-proc-enabled a.process-link {
  display: block;
}

.vplus-process-prompt {
  display: none;
}
.vplus-process-prompt.show {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.35rem;
  min-width: 150px;
  padding: 0.5rem;
}
.vplus-process-prompt .btn-proc {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  font-weight: 500;
  padding: 0.4rem 0.75rem;
  min-height: 36px;
  border-radius: 2rem;
  white-space: nowrap;
  border: 1px solid #dee2e6;
  background: #f8f9fa;
  color: #333;
  text-decoration: none;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}
.vplus-process-prompt .btn-proc:hover {
  background: #e9ecef;
  border-color: #ced4da;
  color: #111;
  text-decoration: none;
}
.vplus-process-prompt .btn-proc:active {
  background: #dee2e6;
}
.vplus-process-prompt .process-revert {
  border-color: var(--bs-warning);
  color: #856404;
  background: #fff8e1;
}
.vplus-process-prompt .process-revert:hover {
  background: #fff3cd;
  border-color: #c69500;
  color: #664d03;
}
.vplus-process-prompt .process-cancel {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #999;
  font-size: 1rem;
  padding: 0.15rem;
  min-height: 28px;
  text-decoration: none;
  transition: color 0.15s ease;
}
.vplus-process-prompt .process-cancel:hover {
  color: #555;
}
.vplus-process-prompt .processing {
  display: none;
  text-align: center;
  color: #888;
  font-size: 0.8rem;
  padding: 0.25rem 0;
}
.vplus-process-prompt .processing.show {
  display: block;
}
.vplus-media-option:has(.vplus-process-prompt.show) > .btn {
  display: none;
}

.vplus-file-container.vplus-processing .image-box::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 10;
  border-radius: inherit;
}
/* Processing progress overlay (replaces gear spinner) */
.vplus-proc-overlay {
  position: absolute;
  inset: 0;
  z-index: 11;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  pointer-events: none;
}
.vplus-proc-overlay .vplus-proc-label {
  color: #fff;
  font-size: 0.65rem;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  white-space: nowrap;
}
.vplus-proc-overlay .vplus-proc-track {
  width: 70%;
  height: 8px;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 2px;
  overflow: hidden;
}
.vplus-proc-overlay .vplus-proc-fill {
  height: 100%;
  width: 0%;
  background: #f97316;
  border-radius: 2px;
  transition: width 0.4s ease;
}

.vplus-processed-badge {
  position: absolute;
  z-index: 50;
  color: var(--bs-warning);
  font-size: 1rem;
  top: -0.35rem;
  right: -0.35rem;
  border: 1px solid #eee;
  padding: 0.15rem;
  box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.1);
  border-radius: 1rem;
  background: #fff;
  line-height: 1;
}
