/* PG Modal — native <dialog>-based modal */
/* ====================================== */

dialog.pg-modal {
  width: 100%;
  max-width: 500px;
  max-height: calc(100vh - 3rem);
  padding: 0;
  border: none;
  border-radius: 0.5rem;
  overflow: hidden;                 /* round the corners over the content */
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.25);
}

dialog.pg-modal::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

/* Lock background scrolling while a modal is open (toggled by modal_controller),
   so touch scrolling stays inside the dialog body instead of the page behind.

   Deliberately the root element only. Adding `body` here as well makes body a
   scroll container, and position: sticky then resolves against body's scrollport
   rather than the viewport - body's own scrollTop is 0 while the page's actual
   offset lives on html, so a sticky header un-sticks, drops to its place at the
   top of the document and scrolls out of view the moment any dialog opens. On the
   calendar, which opens itself scrolled to the current week, that reads as the
   navbar vanishing. */
html.pg-modal-open {
  overflow: hidden;
}

/* The dialog receives focus on open (to avoid auto-focusing the close button);
   it shouldn't show a focus ring itself. */
dialog.pg-modal:focus,
dialog.pg-modal:focus-visible {
  outline: none;
}

/* A closed <dialog> must stay hidden — keep the UA `display:none` for the
   not-[open] state, and only apply the flex column layout when open. */
dialog.pg-modal:not([open]) {
  display: none;
}

/* Lay the dialog out as a column so a scrollable body sits between a fixed
   header and footer (replaces Bootstrap's modal-dialog-scrollable). */
dialog.pg-modal[open] {
  display: flex;
  flex-direction: column;
}

dialog.pg-modal > .modal-content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;        /* allow the inner body to scroll */
}

dialog.pg-modal .modal-header,
dialog.pg-modal .modal-footer {
  flex: 0 0 auto;
}

/* The scrollable region. For the profile dialog this is the turbo-frame that
   wraps the loaded content; for the crop dialog it's the .modal-body directly.
   min-height:0 is required so the flex child can shrink and scroll internally
   instead of pushing the dialog past the viewport. */
dialog.pg-modal .modal-content > turbo-frame,
dialog.pg-modal .modal-content > .modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;   /* momentum scroll on iOS */
  overscroll-behavior: contain;        /* don't chain scroll to the page behind */
}

dialog.pg-modal .modal-content > turbo-frame {
  display: block;
}

/* When the body lives inside the frame, it's just padding — the frame scrolls. */
dialog.pg-modal .modal-content > turbo-frame > .modal-body {
  overflow: visible;
}

/* Header / footer borders to match the card-based content. */
dialog.pg-modal .modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  border-bottom: 1px solid var(--bs-border-color);
}

dialog.pg-modal .modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--bs-border-color);
}

dialog.pg-modal .modal-body {
  padding: 1rem;
}

/* While saving, the primary button is disabled to prevent double-submit — keep
   it full-opacity (with its spinner) so it reads as "busy", not "unavailable". */
dialog.pg-modal .modal-footer .btn-primary:disabled {
  opacity: 1;
}
