.mass-buyback-layout {
  max-width: 1700px;
  margin: 24px auto;
  padding: 0 20px 60px;
  display: flex;
  gap: 24px;
  align-items: flex-start;
}

.mass-panel {
  background: var(--parchment);
  border: 1px solid var(--mist);
  border-radius: 10px;
  padding: 20px;
}

.mass-setup-panel {
  flex: 1 1 380px;
  max-width: 760px;
  margin-inline: auto;
}

.mass-setup-panel h2 {
  margin: 0 0 10px 0;
  color: var(--ink);
}

.mass-input-textarea {
  width: 100%;
  min-height: 260px;
  padding: 10px 12px;
  border: 1px solid var(--mist);
  border-radius: 6px;
  font-family: monospace;
  font-size: 0.9rem;
  resize: vertical;
  margin-bottom: 14px;
}

.mass-start-btn {
  width: 100%;
  padding: 12px;
  font-size: 1rem;
}

.mass-review-panel {
  flex: 3 1 900px;
}

.mass-progress-bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--brass);
}

.mass-progress-text {
  font-weight: bold;
  color: var(--ink);
}

/* Tiles are 330px and do not shrink: auto-fill instead of a fixed column count. */
.mass-batch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
  gap: 16px;
  margin-bottom: 18px;
  justify-items: center;
}

.mass-tile-skip-btn,
.mass-done-restart-btn,
.mass-tile-add-btn,
.mass-tile-fix-btn,
.mass-done-cart-link,
.mass-start-btn,
.mass-import-btn,
.mass-commit-btn {
  flex: 1;
  padding: 8px;
  font-size: 0.85rem;
  font-weight: bold;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid var(--mist);
  border-bottom: 2px solid var(--mist);
}

.mass-tile-skip-btn,
.mass-done-restart-btn,
.mass-import-btn {
  background: #fff;
  color: var(--wine);
}

/* A <label> rather than a <button>: the only way to trigger a file input
   without rendering its untranslatable native text. */
.mass-import-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
}

.mass-import-btn input {
  display: none;
}

.mass-tile-fix-btn {
  background: #fff;
  color: var(--ink);
}
.mass-tile-skip-btn:hover,
.mass-done-restart-btn:hover {
  border-bottom-color: var(--wine);
}

.mass-tile-add-btn,
.mass-done-cart-link,
.mass-start-btn,
.mass-commit-btn {
  background: var(--shop-green);
  border-color: #006600;
  border-bottom-color: #004d00;
  color: #fff;
}

/* An <a>: it must be given what a <button> gets for free. */
.mass-done-cart-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}
.mass-done-cart-link:hover {
  background: #009600;
}
.mass-tile-add-btn:hover:not(:disabled) {
  background: #009600;
}
.mass-tile-add-btn:disabled {
  background: #ccc;
  border-color: #bbb;
  color: #888;
  cursor: not-allowed;
}

.mass-abort-btn {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 4px 12px;
  font-size: 0.8rem;
}

.mass-done-panel {
  flex: 1 1 100%;
  text-align: center;
  max-width: 480px;
  margin: 40px auto;
}

.mass-done-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-top: 16px;
}

/* Stacked, the panels take the screen's width: `flex-start` would size them to their
   content, wider than a phone. Tiles then shrink with their column, as on the search
   page. */
@media (max-width: 900px) {
  .mass-buyback-layout {
    flex-direction: column;
    align-items: stretch;
  }
  .mass-panel {
    min-width: 0;
  }
  .mass-setup-panel {
    max-width: none;
  }
  .mass-batch-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .mass-card {
    width: 100%;
    max-width: 350px;
  }
  .mass-card .slide {
    flex: none;
    width: auto;
  }
}

@media (max-width: 520px) {
  .mass-buyback-layout {
    margin-top: 12px;
    padding: 0 8px 40px;
  }
  .mass-panel {
    padding: 12px;
  }
}

.mass-actions-row {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}

.mass-bulk-actions {
  display: flex;
  flex: 2;
  gap: 12px;
}
.mass-bulk-actions button {
  flex: 1;
  padding: 10px;
  font-size: 0.9rem;
}

.mass-commit {
  display: flex;
  flex: 3;
  gap: 12px;
}

/* After the rules it overrides: at equal specificity, the later rule wins. */
@media (max-width: 520px) {
  .mass-actions-row {
    flex-wrap: wrap;
  }
  .mass-bulk-actions,
  .mass-commit {
    flex: 1 1 100%;
  }
}

.mass-resume-banner {
  background: #fff8e1;
  border: 2px solid var(--brass);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 16px;
}
.mass-resume-banner p {
  margin: 0 0 10px 0;
  font-size: 0.88rem;
  color: var(--ink);
}
.mass-resume-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.mass-resume-actions button {
  padding: 8px 12px;
  font-size: 0.85rem;
}
#massDiscardResumeBtn {
  background: none;
  border: 1px solid var(--mist);
  border-radius: 6px;
  color: var(--wine);
  cursor: pointer;
}

.mass-threshold {
  margin-left: 12px;
  font-size: 0.85rem;
  color: var(--wine);
}

.mass-repair-panel {
  max-width: 340px;
}

.mass-repair-count {
  color: var(--danger);
}

.mass-repair-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mass-repair-item {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.mass-repair-reason {
  flex: 0 0 100%;
  font-size: 0.8rem;
  color: var(--wine);
}

.mass-repair-input {
  flex: 1;
  min-width: 0;
  padding: 4px 6px;
  font-size: 0.85rem;
  border: 1px solid #c9b99b;
  border-radius: 4px;
}

.mass-repair-btn {
  flex: 0 0 auto;
  padding: 4px 10px;
  font-size: 0.85rem;
  font-weight: bold;
  color: var(--ink);
  background: #fff;
  border: 1px solid #c9b99b;
  border-radius: 4px;
  cursor: pointer;
}

.mass-repair-btn:hover {
  border-color: var(--brass);
}

.mass-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}

/* Whitespace between flex items is not rendered: gap separates them. */
.mass-filter-btn,
.mass-filter-threshold {
  gap: 6px;
}

/* margin-left:auto rather than justify-content on the parent, which would
   also spread the filters apart. */
.mass-filter-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-left: auto;
}

.mass-filter-count {
  opacity: 0.7;
  font-weight: normal;
}

.mass-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px;
  border: 1px solid #c9b99b;
  border-radius: 6px;
  background: #fff;
}

/* cards.css writes the name in white for the dark page background; the panel
   here is light. */
.mass-card .card-name {
  color: #6b5f45;
}

.mass-card-line {
  display: flex;
  margin: 0 0 4px;
  font-size: 0.85rem;
}

/* Shared by the pasted list and the cart: a new quantity field joins this rule. */
.mass-card-qty,
.cart-item-qty {
  display: flex;
  flex: none;
  align-items: center;
  gap: 2px;
  font-weight: bold;
  color: #333;
}

.mass-card-qty input,
.cart-item-qty input {
  /* Two digits at most (MAX_QTY_PER_CARD, core/buyback.ts) plus the spinner. */
  width: 38px;
  padding: 1px 3px;
  font-size: 0.85rem;
  font-weight: bold;
  border: 1px solid #c9b99b;
  border-radius: 3px;
}

.mass-card-uncosted,
.mass-card-mismatch {
  margin: 0 0 8px;
  font-family: 'Beleren';
  font-weight: bold;
  text-align: center;
  font-size: 0.9rem;
  color: var(--danger);
}

.mass-card-mismatch {
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--danger);
  color: #fff;
  /* It quotes the line as written, which may hold no space at all: it wraps anywhere,
     and takes the card's width rather than setting it. */
  overflow-wrap: anywhere;
  contain: inline-size;
}

.mass-card .price-display {
  flex: 0 0 100%;
  text-align: center;
}

/* Grid rows stretch tiles to the tallest one: pushed to the bottom, the
   buttons line up across tiles. */
.mass-card-actions {
  display: flex;
  margin-top: auto;
  gap: 6px;
}

.mass-tile-add-btn.active {
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.4);
  border-bottom-width: 1px;
}

.mass-tile-skip-btn.active {
  background: var(--wine);
  color: #fff;
  border-color: var(--wine);
}

.mass-commit-btn:disabled,
.mass-done-restart-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.mass-filter-threshold input {
  width: 60px;
  padding: 2px 4px;
  font-size: 0.85rem;
  border: 1px solid #c9b99b;
  border-radius: 3px;
}

.mass-empty-filter {
  margin: 0 0 12px;
  padding: 12px;
  text-align: center;
  font-size: 0.9rem;
  color: #6b5f45;
}

/* What a sorted list grouped (weighed box, bulk zones): the count, its button, the cards. */
.mass-sorted {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 12px;
  text-align: center;
  font-size: 0.9rem;
  color: #6b5f45;
}
.mass-sorted p {
  margin: 0;
}
.mass-sorted .mass-commit-btn {
  flex: none;
  padding: 8px 24px;
}

/* One zone per bulk-tier price: its title carries the price, so a tile is the card alone. */
.mass-zone {
  width: 100%;
}
.mass-zone h3 {
  margin: 8px 0;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--mist);
  text-align: left;
  font-size: 1rem;
  color: var(--ink);
}
.mass-zone-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.mass-zone-grid li {
  position: relative;
  min-width: 0;
}
/* Until its card is fetched, a tile holds the card's place and name. */
.mass-zone-missing {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 488 / 680;
  padding: 4px;
  border: 1px solid #c9b99b;
  border-radius: 4px;
  font-size: 0.7rem;
  overflow-wrap: anywhere;
}
/* The in-cart badge's shape; a quantity, not the cart's green. */
.mass-zone-grid .mass-zone-qty {
  bottom: 4px;
  right: 4px;
  background-color: var(--ink);
}

/* Phone: the review's controls keep to a few short rows and the tiles lose their white
   frame, the grey card box being frame enough. Last in the file: these override base
   rules of the same specificity. */
@media (max-width: 768px) {
  /* The drawer also takes the decision filters, and its button sits left of the
     actions row, which acts on what the filters show. Opened, it takes the full width,
     the decision filters on its first row. */
  .mass-sticky {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: 8px;
  }
  .mass-sticky > * {
    flex: 1 1 100%;
  }
  .mass-sticky > .mass-filters:not(:has(.is-open)) {
    flex: none;
  }
  .mass-sticky > .mass-actions-row {
    flex: 1 1 200px;
    min-width: 0;
  }
  .mass-filters .filters-toggle-btn[aria-expanded='false'] ~ .mass-filter-tabs {
    display: none;
  }
  .mass-filters .secondary-controls.is-open {
    order: 1;
  }
}

@media (max-width: 520px) {
  .mass-progress-bar {
    margin-bottom: 10px;
    padding-bottom: 8px;
  }
  .mass-progress-text {
    font-size: 0.85rem;
  }
  .mass-progress-bar .mass-abort-btn {
    height: 28px;
    padding: 0 8px;
    font-size: 0.7rem;
  }
  .mass-filter-tabs {
    gap: 4px;
  }
  .mass-filters .mass-filter-btn {
    height: 32px;
    padding: 0 8px;
    font-size: 0.72rem;
    letter-spacing: 0;
  }
  .mass-bulk-actions button {
    padding: 8px 4px;
    font-size: 0.82rem;
  }
}

/* Narrow screen: one card per row, the search's list view (layout.css) inside the
   review's white frame. After the grid's own rules, which it overrides. */
.mass-batch-grid.list-view {
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}
.mass-batch-grid.list-view .mass-card {
  width: 100%;
  max-width: none;
}
/* The row sits on the white frame, without the search's grey band. */
.mass-batch-grid.list-view .slide {
  padding: 0;
  border: none;
  background: none;
}
/* First line beside the thumbnail: the name, then its printing; the controls start the
   second line, at the break below. */
.mass-batch-grid.list-view .card-name {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
}
/* Over two lines if need be, beside the thumbnail's height: the number names the
   printing, and an ellipsis would cut it first. */
.mass-batch-grid.list-view .card-set-info {
  max-width: 45%;
  padding: 2px 6px;
  font-size: 0.75rem;
  text-align: left;
  white-space: normal;
}
/* Order 4 like the first controls, and first in the DOM: the break falls just before
   them. */
.mass-batch-grid.list-view .slide::before {
  content: '';
  order: 4;
  flex-basis: 100%;
  height: 0;
}
/* Inside the pill, which the list view dissolves: the default order 0 would put it
   before the thumbnail. */
.mass-batch-grid.list-view .mass-card-qty {
  order: 4;
}
/* The grid gives the price a row of its own. */
.mass-batch-grid.list-view .price-display {
  flex: none;
}
.mass-batch-grid.list-view .mass-card-actions {
  margin-top: 6px;
}
