/* ── Toasts ──────────────────────────────────────────────────────────
   Rendered by <app-toast> (TagHelpers/AppToastTagHelper.cs) or built by
   app-toast.js; both produce the same markup. Bootstrap's .toast supplies
   the fade and the .show class; everything else is here.

   Colours are Bootstrap's own variables so the toast follows the theme (dark
   by default). The accent - a rule down the left and the icon - is the one
   thing that says which kind it is, because four fully-tinted boxes stacked
   in a corner read as a warning wall whatever they say. */

.app-toasts {
  z-index: 1090; /* above Bootstrap's modal (1055) and its backdrop */
  width: min(26rem, calc(100vw - 2rem));
  pointer-events: none; /* the container is invisible; only the toasts take clicks */
}

.app-toasts .toast {
  pointer-events: auto;
  width: 100%;
  max-width: none;
}

.app-toast {
  --toast-accent: var(--bs-primary);
  position: relative;
  overflow: hidden;
  background-color: var(--bs-body-bg);
  color: var(--bs-body-color);
  border: 1px solid var(--bs-border-color);
  border-left: 0.25rem solid var(--toast-accent);
  box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.35);
  font-size: 0.9375rem;
}

.app-toast-success { --toast-accent: var(--bs-success); }
.app-toast-info    { --toast-accent: var(--bs-primary); }
.app-toast-warning { --toast-accent: var(--bs-warning); }
.app-toast-danger  { --toast-accent: var(--bs-danger); }

.app-toast .toast-body {
  padding: 0.75rem 0.875rem 0.875rem;
}

.app-toast-icon {
  color: var(--toast-accent);
  font-size: 1.15rem;
  line-height: 1.35;
  flex-shrink: 0;
}

.app-toast-title {
  margin-bottom: 0.125rem;
}

.app-toast-text {
  overflow-wrap: anywhere;
}

/* A lifted .alert may carry a paragraph or a list; keep them tight. */
.app-toast-text p:last-child,
.app-toast-text ul:last-child {
  margin-bottom: 0;
}

.app-toast-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* The action button paints from the accent so it reads on the light theme
   too - btn-outline-light was white on white there (caught 2026-09-23). */
.app-toast-action {
  --bs-btn-color: var(--toast-accent);
  --bs-btn-border-color: var(--toast-accent);
  --bs-btn-hover-color: var(--bs-body-bg);
  --bs-btn-hover-bg: var(--toast-accent);
  --bs-btn-hover-border-color: var(--toast-accent);
  --bs-btn-active-color: var(--bs-body-bg);
  --bs-btn-active-bg: var(--toast-accent);
  --bs-btn-active-border-color: var(--toast-accent);
  --bs-btn-focus-shadow-rgb: 128, 128, 128;
  font-weight: 600;
}

.app-toast-close {
  flex-shrink: 0;
  margin: -0.125rem -0.25rem 0 0;
}

/* THE TIMER, VISIBLE. A bar along the bottom empties over the toast's life,
   so a reader can see that a message is about to go and rest the pointer on
   it to keep it - the script pauses the timer and this animation together. */
.app-toast-progress {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 100%;
  background-color: var(--toast-accent);
  opacity: 0.85;
  transform-origin: left center;
  transform: scaleX(0);
}

.app-toast.is-timed .app-toast-progress {
  transform: scaleX(1);
  animation: app-toast-progress var(--toast-duration, 7s) linear forwards;
}

.app-toast.is-paused .app-toast-progress {
  animation-play-state: paused;
}

@keyframes app-toast-progress {
  to { transform: scaleX(0); }
}

/* Phones: the corner is the whole bottom edge. */
@media (max-width: 575.98px) {
  .app-toasts {
    left: 0;
    right: 0;
    width: auto;
    padding: 0.75rem !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-toast.is-timed .app-toast-progress {
    animation: none;
    transform: scaleX(1);
  }
}

/* The alerts app-toast.js is about to lift stay unpainted until it has.
   `data-app-alerts-pending` is set on <html> by a blocking script in
   _Layout's <head> and removed by app-toast.js once fromAlerts has run, or
   by window load if it never does. The selector mirrors what fromAlerts
   takes - a DIRECT child .alert of a [data-app-alerts] holder - and leaves
   validation summaries alone, exactly as the script does, so nothing this
   rule hides is something the script would have left inline. Alerts inside
   #app-modal are not on the page at first paint, so they need no exclusion. */
html[data-app-alerts-pending] [data-app-alerts] > .alert:not(.validation-summary-errors):not(.validation-summary-valid) {
  display: none;
}
