/* =============================================================================
   modal.css - Shared modal dialog.

   Reference: `.docs/steps/4.md` (file list); used from step 5 (card detail),
   step 6 (reset confirmation, save import) and step 8 (gift result).
   The markup contract is:
     <div class="modal" hidden>
       <div class="modal__dialog" role="dialog" aria-modal="true" aria-labelledby="...">
         <button class="modal__close" data-modal-close>×</button>
         <h2 class="modal__title" id="..."></h2>
         <div class="modal__body"></div>
         <div class="modal__actions">...</div>
       </div>
     </div>
   ============================================================================= */

.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background-color: var(--overlay);
  animation: modal-fade var(--duration-fast) var(--easing-standard);
}

.modal__dialog {
  position: relative;
  width: min(100%, 32rem);
  max-height: 85vh;
  overflow-y: auto;
  /* A long dialog scrolls without dragging the page behind it (mobile polish, step 7 point 4). */
  overscroll-behavior: contain;
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  box-shadow: var(--shadow-md);
  animation: modal-rise var(--duration-base) var(--easing-standard);
}

/* A dialog whose content is a set of control rows rather than a paragraph (the collection filter &
   sort popup): a little wider than a text dialog, and still clamped by the viewport. */
.modal__dialog--wide {
  width: min(100%, 40rem);
}

/* The purchase dialog of a card option: a little wider than the default, because it hosts a sample
   card next to its price and its confirmation. Not as wide as `--wide`: it is a question, not a
   gallery. */
.modal__dialog--buy {
  width: min(100%, 36rem);
}

/* A dialog opened FROM another dialog (the purchase of a swatch, opened by the colour picker):
   the later sibling would otherwise paint over it. One step is enough - a third dialog never opens
   on top of a purchase. */
.modal--stacked {
  z-index: calc(var(--z-overlay) + 1);
}

.modal__close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  display: grid;
  place-items: center;
  width: var(--touch-target);
  height: var(--touch-target);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background-color: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
}

.modal__close:hover {
  background-color: var(--color-surface-alt);
  color: var(--color-text);
}

.modal__title {
  margin-bottom: var(--space-3);
  font-size: var(--font-size-lg);
}

.modal__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.modal__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* --- Upcoming-extensions announcement (`SetAnnouncementPopup.js`) --------- */

.set-announcement__dialog {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  text-align: center;
}

.set-announcement__badge {
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background-color: var(--color-surface-alt);
  color: var(--color-accent);
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.set-announcement__booster {
  width: min(45%, 9rem);
  height: auto;
  margin-top: var(--space-2);
  /* Upside-down artwork: see the note in `css/components/booster-3d.css`. */
  rotate: 180deg;
}

.set-announcement__booster[hidden] {
  display: none;
}

.set-announcement__title {
  margin: 0;
}

.set-announcement__date {
  margin: 0;
  font-weight: 700;
  color: var(--color-accent);
}

.set-announcement__message {
  margin: 0;
  color: var(--color-text-muted);
}

/* --- Expired-currency announcement (`CurrencyExpiryPopup.js`) -------------- */

.currency-expiry__dialog {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.currency-expiry__title {
  margin: 0;
}

.currency-expiry__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One currency: its texture, then what became of the balance. Several currencies can expire at once
   (a long absence), so the rows share one dialog instead of stacking one dialog each. */
.currency-expiry__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-alt);
}

.currency-expiry__texture {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  image-rendering: pixelated;
}

.currency-expiry__texture[hidden] {
  display: none;
}

.currency-expiry__message {
  margin: 0;
  color: var(--color-text);
}

@keyframes modal-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes modal-rise {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
