/* ==========================================================================
   Dialog — shared modal primitives.
   Variants set their own width/padding via .dialog.<context>.
   Behaviour: assets/js/dialog.js (HagaDialog.setup).
   ========================================================================== */

.dialog {
  display: none;
  /* Override UA modal centring so the dialog flows with body scroll
     instead of being pinned to the viewport. JS sets `top` on open
     to (window.scrollY + offset) so the dialog appears near current
     scroll position; as the user scrolls, the dialog moves with the
     page (position: absolute, not fixed) and the body scrollbar
     handles overflow when the dialog is taller than the viewport. */
  position: absolute;
  inset-inline: 0;
  margin: 0 auto;
  max-height: none;
  overflow: visible;
  width: min(100% - var(--s-32), var(--mw-md));
  max-width: 100%;
  padding: var(--s-48) var(--s-32);
  border: 0;
  border-radius: var(--s-16);
  background: var(--wp--preset--color--off-white, #fff);
  color: inherit;
  /* Transition width + height so the success state can smoothly resize
     the dialog. Height only animates when an explicit value is set
     (the JS pins pre-height, then targets post-height via FLIP). */
  --dialog-transition-duration: 0.3s;
  --dialog-transition-easing: ease;
  transition:
    width var(--dialog-transition-duration) var(--dialog-transition-easing),
    height var(--dialog-transition-duration) var(--dialog-transition-easing);
}

/* Success state — narrower frame (same width as the auth dialog) for a
   calmer confirmation panel after a form is submitted. */
.dialog.is-success {
  width: min(100% - var(--s-32), var(--mw-sm));
}

.dialog[open] {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-24);
  animation: dialog-in 0.3s ease both;
}

.dialog::backdrop {
  background: color-mix(in srgb, var(--wp--preset--color--warm-brown, #3a2c1f) 60%, transparent);
}

.dialog[open]::backdrop {
  animation: dialog-backdrop-in 0.25s ease both;
}

.dialog[open].is-closing {
  animation: dialog-out 0.25s ease both;
}

.dialog[open].is-closing::backdrop {
  animation: dialog-backdrop-out 0.2s ease both;
}

.dialog .close {
  position: absolute;
  top: var(--s-16);
  right: var(--s-16);
}

/* === Animations ========================================================== */

@keyframes dialog-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes dialog-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes dialog-out {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(20px);
  }
}

@keyframes dialog-backdrop-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .dialog[open],
  .dialog[open]::backdrop,
  .dialog[open].is-closing,
  .dialog[open].is-closing::backdrop {
    animation: none;
  }
}

/* Success panel — shown inside a dialog after a valid form submit. The
   form is hidden ([hidden]) and this panel takes its place. Centered
   reads as a confirmation moment, and links invite the user to keep
   exploring. */
.dialog .success {
  display: grid;
  gap: var(--s-16);
  text-align: center;
}

.dialog .success > * {
  margin: 0;
}

/* Form ↔ success cross-fade. Both swap targets carry an opacity
   transition; JS toggles .is-fading on the form (1 → 0) and
   .is-pre-fade on the appended success panel (0 → 1) to ease the
   content swap while the dialog frame is resizing. */
.dialog .container > form,
.dialog .container > .success {
  transition: opacity var(--dialog-transition-duration) var(--dialog-transition-easing);
}

.dialog .container > form.is-fading,
.dialog .container > .success.is-pre-fade {
  opacity: 0;
}

.dialog .container > form[hidden] {
  display: none;
}

/* === Mobile (< sm, < 40rem): full-screen sheet ============================
   Mirrors the mobile navigation overlay — pinned, edge-to-edge, scrollable
   internally. dialog.js skips the inline `top` it normally sets for the
   scroll-aware absolute mode, so `inset: 0` here is authoritative. */

@media (max-width: 39.9375rem) {
  .dialog {
    position: fixed;
    inset: 0;
    margin: 0;
    width: 100%;
    max-width: 100%;
    height: 100%;
    border-radius: 0;
    padding: var(--s-72) var(--s-16) var(--s-24);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .dialog.is-success {
    width: 100%;
  }

  /* Slide up from below; backdrop fade still inherited from base. */
  .dialog[open] {
    animation: dialog-in-mobile 0.3s ease both;
  }

  .dialog[open].is-closing {
    animation: dialog-out-mobile 0.25s ease both;
  }
}

@keyframes dialog-in-mobile {
  from {
    opacity: 0;
    transform: translateY(100%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes dialog-out-mobile {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(100%);
  }
}
