/* ==========================================================================
   .tp-toast — P1.F2.T3
   ©2026 Vexstorm Studios – All Rights Reserved

   Transient confirmations: "Contribution recorded", "Export queued". Django
   messages render either as toasts or as inline notices; _messages.html
   chooses, and both carry the type as an icon and a word, never as colour
   alone (ACC-004).

   Variants   --success  --warning  --danger  --info
   Elements   __region  __icon  __body  __title  __message  __dismiss
   States     .tp-is-leaving  :hover  :focus-visible  :disabled

   The region is a polite live region in the template. A toast is never the
   only record of an outcome: anything worth a toast is also visible in the
   page it returns to, because a toast a user did not see is a toast that never
   happened.
   ========================================================================== */

/* The fixed stack. Bottom-end so it never covers the page heading or the
   primary action, and inset by a full gutter so it clears a 320px viewport. */
.tp-toast__region {
  position: fixed;
  inset-block-end: var(--tp-space-4);
  inset-inline-end: var(--tp-space-4);
  z-index: var(--tp-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--tp-space-2);
  width: min(var(--tp-space-toast-width), calc(100vw - var(--tp-space-7)));
  /* The region itself must never intercept clicks meant for the page. */
  pointer-events: none;
}

.tp-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--tp-space-3);
  padding: var(--tp-space-4);
  border: var(--tp-border-width-hairline) solid var(--tp-color-border-subtle);
  border-inline-start: var(--tp-border-width-thick) solid var(--tp-color-border-strong);
  border-radius: var(--tp-radius-md);
  background-color: var(--tp-color-surface-overlay);
  color: var(--tp-color-text-primary);
  box-shadow: var(--tp-shadow-lg);
  pointer-events: auto;
  animation: tp-toast-enter var(--tp-motion-duration-slow)
    var(--tp-motion-ease-emphasized);
}

.tp-toast.tp-is-leaving {
  animation: tp-toast-leave var(--tp-motion-duration-base)
    var(--tp-motion-ease-standard) forwards;
}

/* --------------------------------------------------------------------------
   Elements
   -------------------------------------------------------------------------- */

.tp-toast__icon {
  flex: none;
  width: var(--tp-space-icon-lg);
  height: var(--tp-space-icon-lg);
  margin-top: var(--tp-space-1);
  color: var(--tp-color-text-secondary);
}

.tp-toast__body {
  flex: 1 1 auto;
  min-width: 0;
}

/* The word that names the type — "Saved", "Warning", "Error". This is the
   non-colour signal ACC-004 requires, and it is not optional. */
.tp-toast__title {
  color: var(--tp-color-text-primary);
  font-size: var(--tp-text-sm);
  font-weight: var(--tp-weight-bold);
  line-height: var(--tp-leading-tight);
}

.tp-toast__message {
  margin-top: var(--tp-space-1);
  color: var(--tp-color-text-secondary);
  font-size: var(--tp-text-sm);
  line-height: var(--tp-leading-normal);
  overflow-wrap: break-word;
}

.tp-toast__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--tp-space-target-min);
  height: var(--tp-space-target-min);
  border-radius: var(--tp-radius-sm);
  color: var(--tp-color-text-muted);
  cursor: pointer;
}

.tp-toast__dismiss:hover {
  background-color: var(--tp-color-surface-sunken);
  color: var(--tp-color-text-primary);
}

.tp-toast__dismiss:active {
  background-color: var(--tp-color-accent-subtle);
}

.tp-toast__dismiss:disabled {
  opacity: var(--tp-opacity-disabled);
  cursor: not-allowed;
}

.tp-toast__dismiss:focus-visible {
  outline-offset: 0;
}

.tp-toast__dismiss-icon {
  width: var(--tp-space-icon);
  height: var(--tp-space-icon);
}

/* --------------------------------------------------------------------------
   Types
   -------------------------------------------------------------------------- */

.tp-toast--success {
  border-inline-start-color: var(--tp-color-state-success);
}

.tp-toast--success .tp-toast__icon {
  color: var(--tp-color-state-success);
}

.tp-toast--warning {
  border-inline-start-color: var(--tp-color-state-warning);
}

.tp-toast--warning .tp-toast__icon {
  color: var(--tp-color-state-warning);
}

.tp-toast--danger {
  border-inline-start-color: var(--tp-color-state-danger);
}

.tp-toast--danger .tp-toast__icon {
  color: var(--tp-color-state-danger);
}

.tp-toast--info {
  border-inline-start-color: var(--tp-color-state-info);
}

.tp-toast--info .tp-toast__icon {
  color: var(--tp-color-state-info);
}

/* --------------------------------------------------------------------------
   Motion — both animations are removed entirely by the reduced-motion block in
   utilities.css (ACC-005). A toast still appears and still leaves.
   -------------------------------------------------------------------------- */

@keyframes tp-toast-enter {
  from {
    opacity: 0;
    transform: translateY(var(--tp-space-3));
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes tp-toast-leave {
  from {
    opacity: 1;
    transform: translateY(0);
  }

  to {
    opacity: 0;
    transform: translateY(var(--tp-space-2));
  }
}

/* At 320px a fixed-width stack would overhang the viewport; full width with
   gutters is the only arrangement that cannot produce horizontal scroll. */
@media (max-width: 30rem) {
  .tp-toast__region {
    inset-inline: var(--tp-space-3);
    width: auto;
  }
}
