/******************************************************/
/*     Modal dialogue boxes, alerts, and messages     */
/******************************************************/

/*
    To be used with a Javascript library that creates and displays
    alerts and other user messages and notices.
        This CSS sets the basic properties for displaying these
    alerts, but they can be customized further by the
    web site's own CSS.
*/


.modal_overlay {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1000; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgba(0, 0, 0, 0.3); /* Black w/ opacity */
}

.modal_dialog {
    background-color: #fefefe;
    padding: 10pt;
    width: 80%; /* Could be more or less, depending on screen size */
    max-width: 400px;
    text-align: center;
    border: 1px solid #888;
    border-radius: 5pt;
    position: absolute; /* Change to absolute for stacking */
    z-index: 1000; /* Base z-index for modals */
    top: 15%; /* Initial top position */
    left: 50%; /* Center horizontally */
    transform: translateX(-50%); /* Center horizontally */
}

.modal_title, .modal_message {
    margin: 6pt;
}
.modal_title {
    font-weight: bold;
}

.modal_buttons {
    margin-top: 1em;
    text-align: right;
}

/* CSS for "toast" style self-disappearing user messages. */
/*
    Note: The the CSS here is not very flexible, eg., it hard-codes
    the font size. I'd like it to be better at adopting the default
    styles of the website's own CSS. It would help, I think, if the
    JS code that generates these messages wrapped them in a <p> tag.
    But that will require looking at the order in which these style
    sheets are loaded by websites.
        I can also see a potential conflict between this and the code
    in js/ajax.js for cancelling an in-progress AJAX request. That
    code assumes the modal dialogue that shows the cancel button is
    the last element added to the DOM. But it's conceivable that a
    .toast-message element might be the most recently added DOM element.
*/
#toast-container {
    position: fixed;
    bottom: 30px;
    left: 30px;
    z-index: 9999;
    display: flex;
    flex-direction: column-reverse; /* Newest at the bottom */
    align-items: flex-start;
    pointer-events: none;
}
.toast-message {
    background: rgba(60, 60, 60, 0.95);
    color: #fff;
    padding: 6pt 12pt;
    margin-top: 8px;
    border-radius: 6px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.2);
    font-size: 10pt;
    opacity: 1;
    max-width: 50vw;
    min-width: 200px;
    word-break: break-word;
    white-space: normal;
    pointer-events: auto;
    transform: translateX(-100%);
    animation: toast-slide-in 0.4s cubic-bezier(.4,0,.2,1) forwards;
    transition: opacity 0.5s ease;
}
@keyframes toast-slide-in {
    from { transform: translateX(-100%); }
    to   { transform: translateX(0); }
}

/* Visual wait indicators to indicate something is in progress        */
/* Used by /shared/js/modals.js, which builds the HTML <div> directly */

/* HTML: <div class="spinner"></div> */
.spinner {
  color: var(--theme-color, grey); /* Color of the spinner, grey default */
  --d:12px; /* Basic radius for the visible shadows that rotate */
  width: 3px; /* Width of the center dot (not visible) */
  height: 3px; /* Height of the center dot (not visible) */
  border-radius: 50%; /* Make the center dot circular */
  /* Shadows of the center dot increasing in size, positioned in a circle. */
  box-shadow:
 /* calc(1*var(--d))      calc(0*var(--d))     0 0, */
    calc(0.707*var(--d))  calc(0.707*var(--d)) 0 0,
    calc(0*var(--d))      calc(1*var(--d))     0 0,
    calc(-0.707*var(--d)) calc(0.707*var(--d)) 0 0,
    calc(-1*var(--d))     calc(0*var(--d))     0 0,
    calc(-0.707*var(--d)) calc(-0.707*var(--d))0 1px,
    calc(0*var(--d))      calc(-1*var(--d))    0 2px;
  /* Rotate the spinner in 8 steps over 1 second */
  animation: spin 1s infinite steps(8);
  display: block; /* Ensure it is a block element */
  margin: calc(1.8*var(--d)) auto; /* Center horizontally in parent element */
}
@keyframes spin {
  100% { transform: rotate(1turn) } /* Rotate a full 360 degrees */
}

/* HTML: <div class="pulse"></div> */
.pulse {
  --d:16px; /* Size of the ripple */
  color:  var(--theme-color, grey); /* Color of the spinner, grey default */
  position: relative; /* Required to enable absolute positioning below */
  width: 32px; /* Width of the spinner */
  aspect-ratio: 1; /* Maintain a square aspect ratio */
  margin: var(--d) auto; /* Center horizontally in parent element */
}
.pulse::before,
.pulse::after {
  content: ""; /* Empty content to create the ripple */
  position: absolute; /* Position relative to the parent for overlay */
  inset: 0; /* Stretch to fill the parent element */
  border: 4px solid currentColor; /* Use the current text color for border */
  border-radius: 50%; /* Make the ripple circular */
  opacity: 0; /* Start with full transparency */
   /* Animate the ripple */
  animation: ripple 1.2s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
.pulse::after {
  animation-delay: -0.6s; /* Offset the animation for a staggered effect */
}
@keyframes ripple {
  0% {
    transform: scale(0); /* Start small */
    opacity: 1; /* Fully visible */
  }
  100% {
    transform: scale(1.8); /* Grow larger */
    opacity: 0; /* Fade out */
  }
}


