/* ==========================================================================
   Modals — CoachOS Design System
   Uses native <dialog> element with backdrop
   ========================================================================== */

/* Keyframes
   ========================================================================== */

@keyframes modal-enter {
  from {
    opacity: 0;
    transform: scale(0.95) translateY(8px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

@keyframes modal-exit {
  from {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
  to {
    opacity: 0;
    transform: scale(0.95) translateY(8px);
  }
}

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

/* Dialog Base
   ========================================================================== */

dialog.modal {
  position: fixed;
  margin: auto;
  border: none;
  padding: 0;
  background-color: var(--surface-overlay);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-xl);
  width: 420px;
  max-width: 100vw;
  max-height: 90vh;
  overflow: hidden;
  animation: modal-enter var(--duration-normal) var(--ease-spring);
}

dialog.modal[open] {
  display: flex;
  flex-direction: column;
}

/* Backdrop
   ========================================================================== */

dialog.modal::backdrop {
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: fade-in var(--duration-normal);
}

/* Closing State
   ========================================================================== */

dialog.modal.modal--wide {
  width: 35rem;
}

/* Header
   ========================================================================== */

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  flex-shrink: 0;
}

.modal__title {
  font-size: var(--text-base);
  font-weight: 700;
  color: var(--text-primary);
  margin: 0;
  flex: 1;
}

/* Pattern 7 — leading 28px accent-subtle icon next to title.
   Used by the Comments / Uploads / AI Assist settings modals. */
.modal__head-icon {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  background: var(--accent-subtle);
  color: var(--accent-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-right: var(--space-2);
}
.modal__head-icon .material-symbols-rounded { font-size: 18px; }

/* Status-tinted head-icon variants for action-flavored modals (reschedule
   uses warn, cancel/destroy uses danger). Color tokens only — no other
   geometry change. */
.modal__head-icon--warn {
  background: var(--status-warning-bg);
  color: var(--status-warning);
}
.modal__head-icon--danger {
  background: var(--status-error-bg);
  color: var(--status-error);
}

/* Close Button
   ========================================================================== */

.modal__close {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--text-tertiary);
  padding: var(--space-1);
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color var(--duration-fast);
}

.modal__close:hover {
  color: var(--text-primary);
}
.modal__close:focus,
.modal__close:focus-visible {
  outline: none;
}

/* Forms inside modals: flex column so body scrolls and footer pins.
   Use `flex: 1 1 auto` (not `flex: 1`, which is `1 1 0%`) for the same
   reason as .modal__body below — under content-height auto-sizing, a
   `flex-basis: 0%` item contributes 0 to the dialog's intrinsic height,
   so Safari collapses the form (and its body+footer) to nothing and the
   dialog renders header-only. Chrome silently survives this; Safari does
   not. Mirrors the .modal__body fix. */
dialog.modal > form,
dialog.modal > turbo-frame > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  /* Allow this flex item to shrink below its content's min-content width.
     Without it, wide intrinsic content (datetime-local inputs, multi-column
     .form-row grids, long unbreakable strings) pushes the form past the
     dialog's fixed width and triggers a horizontal scrollbar. */
  min-width: 0;
}

/* Lazy-loaded modal bodies (chart series CRUD, reference routes, etc.)
   host a turbo-frame between the dialog shell and the form. The frame must
   participate in the flex column or .modal__body never gets a bounded height
   to scroll within. */
dialog.modal > turbo-frame {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
}

/* Body
   ========================================================================== */

.modal__body {
  padding: var(--space-4);
  overflow-y: auto;
  /* flex-basis: auto so body sizes to content when dialog is content-height,
     while still allowing shrink + scroll when dialog hits max-height: 90vh.
     `flex: 1` (== 1 1 0%) collapses the body to 0 height under auto-sizing. */
  flex: 1 1 auto;
  min-height: 0;
  /* Same min-width:0 rationale as the form above — content (e.g. the
     reschedule modal's two datetime-local fields in a .form-row) must respect
     the dialog width and stack/scroll instead of overflowing it. */
  min-width: 0;
}

/* datetime-local inputs have a browser min-content width that exceeds half of
   the default 420px modal — stack side-by-side .form-row pairs instead of
   clipping at overflow:hidden. */
.modal__body .form-row:has([type="datetime-local"]) {
  grid-template-columns: 1fr;
}

/* Footer
   ========================================================================== */

.modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  flex-shrink: 0;
}

/* Pattern 7 — Settings-group width variant. Height is inherited from the
   base modal rule (content-sized up to 90vh), since that's the canonical
   behavior. This variant only narrows the width to 360px. */
dialog.modal.modal--settings {
  width: 360px;
}

/* Canonical section divider — self-contained "space + dashed line + space"
   block. Owns ALL the vertical breathing room between two sections so the
   line is ALWAYS visually equidistant from its neighbors regardless of
   what sits above or below. Use as <div class="modal__divider" role="separator">.

   Anatomy: total height 48px (var(--space-4) * 3). The negative margin
   cancels the parent flex gap (assumes .modal__fields gap = var(--space-4))
   so the divider's own height IS the total visible whitespace between
   neighbors, not added to it. */
.modal__divider {
  position: relative;
  display: block;
  height: calc(var(--space-4) * 3); /* 24px above + line + 24px below */
  margin: calc(var(--space-4) * -1) 0;
  padding: 0;
  border: none;
  background: transparent;
}
.modal__divider::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  border-top: 1px dashed var(--border-subtle);
}

/* Pattern 7 — fields wrapper that collapses when the hero switch is toggled
   OFF inside the modal. Animated max-height + opacity. Uses --space-4 gap
   so multi-line rows (label + wrapping hint) read with comfortable, equal
   space between each row regardless of how many lines the hint occupies. */
.modal__fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow: hidden;
  max-height: 1000px;
  opacity: 1;
  transition: max-height var(--duration-normal) var(--ease-out),
              opacity var(--duration-normal) var(--ease-out);
}

/* Hero switch row inside a Pattern 7 modal sits outside .modal__fields and
   therefore doesn't participate in its flex gap — give it a bottom margin
   matching that gap so the hero and the first sub-switch are visually
   separated by the same comfortable distance as adjacent sub-switches. */
.modal__body > .switch-row--hero {
  margin-bottom: var(--space-4);
}
.modal__fields--collapsed {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
}

/* Pattern 7 — auto-close countdown ribbon. Lives at the bottom of the
   modal as a dedicated row beneath the body when the disable-inside flow
   is active. Carries a thin animated progress bar along its bottom edge. */
.modal__autoclose {
  position: relative;
  padding: 8px var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-sunken);
  border-top: 1px solid var(--border-subtle);
  font-size: 11px;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.modal__autoclose[hidden] { display: none; }
.modal__autoclose-msg { flex: 1; }
.modal__autoclose-msg strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}
.modal__autoclose-link {
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 11px;
  font-weight: var(--weight-semibold);
  color: var(--accent-primary);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.modal__autoclose-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  overflow: hidden;
}
.modal__autoclose-progress::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0;
  background: var(--accent-primary);
  border-radius: 0 1px 1px 0;
}
.modal__autoclose-progress--running::after {
  animation: modal-autoclose-bar 2s linear forwards;
}
@keyframes modal-autoclose-bar {
  from { width: 0; }
  to   { width: 100%; }
}

/* Lightbox variant — auto-sizes to image, no fixed dimensions */
dialog.modal.modal--lightbox {
  width: auto;
  height: auto;
  max-width: min(90vw, 800px);
  max-height: 90vh;
}

.modal__body--lightbox {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
}

.modal__lightbox-img {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border-radius: var(--radius-md);
}

/* Responsive – full-screen on small devices */
@media (max-width: 480px) {
  dialog.modal {
    width: 100vw;
    height: 100vh;
    border-radius: 0;
    margin: 0;
    inset: 0;
  }

  .modal__header {
    padding: var(--space-4);
  }

  .modal__body {
    padding: var(--space-4);
  }

  .modal__footer {
    padding: var(--space-3) var(--space-4);
  }
}

/* Modal Multi-Select — searchable checkbox list (DS gallery pattern).
   Composes dialog.modal + .ee-picker__search + .ee-picker__options +
   .ee-picker__option + list-filter. Canonical copy for admin surfaces;
   experience_editor/editor.css carries the same rules for EE modals. */
.modal .ee-picker__options {
  max-height: min(40vh, 240px);
}

.ee-picker__search {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  outline: none;
  background: var(--input-bg);
  margin-bottom: var(--space-3);
}

.ee-picker__search:focus {
  border-color: var(--input-border-focus);
  box-shadow: 0 0 0 3px var(--accent-muted);
}

.ee-picker__search::placeholder {
  color: var(--text-secondary);
}

.ee-picker__options {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-base);
  max-height: 200px;
  overflow-y: auto;
}

.ee-picker__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}

.ee-picker__option[hidden] {
  display: none;
}

.ee-picker__option[data-org-hidden] {
  display: none;
}

.ee-picker__option:hover {
  background: var(--surface-hover);
}

.ee-picker__option input[type="checkbox"],
.ee-picker__option input[type="radio"] {
  accent-color: var(--accent-primary);
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin: 0;
}

.ee-picker__option-label {
  font-size: var(--text-sm);
  color: var(--text-primary);
  line-height: 1.4;
}

.ee-picker__option-meta {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  white-space: nowrap;
}

.ee-inline-multi-select .ee-picker__option {
  justify-content: flex-start;
  gap: var(--space-2);
}

.ee-inline-multi-select .ee-picker__chips:not(:empty) {
  margin-bottom: var(--space-2);
}

.ee-picker__empty {
  padding: var(--space-3);
  text-align: center;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-style: italic;
}

.highlight-publish-modal__filter-list {
  max-height: min(24vh, 160px);
}
