/* Sonner (vanilla port): stacked toast notifications.
   Default position: bottom-right. Up to 3 toasts visible at once;
   older toasts collapse behind the newest and expand on hover. */

.sonner-toaster {
  position: fixed;
  z-index: 999999;
  width: 356px;
  max-width: calc(100vw - 32px);
  pointer-events: none;
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  font-size: 13px;
  line-height: 1.5;
  color: #1e3a5f;
  transition: height 400ms cubic-bezier(0.21, 1.02, 0.73, 1);
  --sonner-gap: 14px;
  --sonner-offset: 16px;
  --sonner-width: 356px;
  --sonner-visible: 3;
}

/* Invisible hit-area that fills the expanded container so the mouse
   can travel between toasts without passing through empty space.
   Without this, the gaps between toasts would fire mouseleave on the
   toaster and collapse the stack, creating a flicker. Only present
   while expanded; sits behind the toasts (no z-index) so clicks still
   reach the real toasts on top. */
.sonner-toaster[data-expanded="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: auto;
}

.sonner-toaster[data-position="bottom-right"] {
  right: var(--sonner-offset);
  bottom: var(--sonner-offset);
}
.sonner-toaster[data-position="bottom-left"] {
  left: var(--sonner-offset);
  bottom: var(--sonner-offset);
}
.sonner-toaster[data-position="top-right"] {
  right: var(--sonner-offset);
  top: var(--sonner-offset);
}
.sonner-toaster[data-position="top-left"] {
  left: var(--sonner-offset);
  top: var(--sonner-offset);
}
.sonner-toaster[data-position="top-center"] {
  left: 50%;
  top: var(--sonner-offset);
  transform: translateX(-50%);
}
.sonner-toaster[data-position="bottom-center"] {
  left: 50%;
  bottom: var(--sonner-offset);
  transform: translateX(-50%);
}

/* ── Toast ──────────────────────────────────────────── */

.sonner-toast {
  position: absolute;
  left: 0;
  right: 0;
  width: 100%;
  pointer-events: auto;
  box-sizing: border-box;
  padding: 14px 16px;
  background: #ffffff;
  color: #1e3a5f;
  border: 1px solid rgba(30, 58, 95, 0.08);
  border-radius: 10px;
  box-shadow:
    0 4px 12px rgba(0, 0, 0, 0.06),
    0 1px 3px rgba(0, 0, 0, 0.04);
  transition:
    transform 400ms cubic-bezier(0.21, 1.02, 0.73, 1),
    opacity 400ms cubic-bezier(0.21, 1.02, 0.73, 1),
    box-shadow 200ms;
  will-change: transform, opacity;
  /* pan-y lets the browser handle vertical scroll gestures normally
     (touch + precision trackpad). Critical so hovering the stack
     never blocks page scrolling. Horizontal movement still reaches
     the pointer handlers for swipe-to-dismiss. */
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

/* Bottom positions: toast anchored to its parent's bottom.
   transform-origin at the anchored edge so scale-down collapses
   "into the distance" behind the front toast rather than shrinking
   from the centre. */
.sonner-toaster[data-y="bottom"] .sonner-toast {
  bottom: 0;
  transform-origin: 50% 100%;
}
.sonner-toaster[data-y="top"] .sonner-toast {
  top: 0;
  transform-origin: 50% 0%;
}

/* ── Stacking transforms ────────────────────────────── */

/* Both states use the SAME transform function order
   (translateY + scale) so the browser interpolates smoothly
   between collapsed and expanded instead of snapping. Only the
   [data-mounted="true"] selector applies stack transforms, so
   mid-mount toasts stay in their offscreen pre-mount position. */

/* Collapsed: newer toasts sit on top; older ones peek above the stack,
   scaled smaller (into the distance). --index: 0 = front, 1 = behind...
   --y-direction is +1 for bottom (peek = negative translate = up)
   and -1 for top (peek = positive translate = down). JS sets it.

   --stack-index is the index clamped to (visible - 1) so that any
   toast past the visible count piles up at the same position as the
   last visible toast (and then fades to opacity 0 via the calc below).
   Without the clamp, toasts 6, 7, 8... would poke out further back
   with their own translateY, creating a visible gap above the hidden
   3..5 and then reappearing past them. */
.sonner-toaster[data-expanded="false"] .sonner-toast[data-mounted="true"] {
  transform: translateY(calc(var(--stack-index) * -16px * var(--y-direction)))
    scale(calc(1 - var(--stack-index) * 0.07));
  /* Subtle per-level opacity fade gives the cards-on-a-desk depth cue
     without washing them out. Combined with the overflow term so any
     toast past --sonner-visible collapses to opacity 0. */
  opacity: clamp(
    0,
    calc(
      (1 - var(--stack-index) * 0.18) -
        max(0, var(--index) - (var(--sonner-visible) - 1))
    ),
    1
  );
}

/* Toasts past the visible limit can't receive pointer events
   (they're opacity 0 anyway, but we don't want invisible hit targets
   floating above the front of the stack). */
.sonner-toaster[data-expanded="false"] .sonner-toast[data-overflow="true"] {
  pointer-events: none;
}

/* Expanded: each toast moves to its own pixel position along the
   column. Explicit scale(1) matches the collapsed function list. */
.sonner-toaster[data-expanded="true"] .sonner-toast[data-mounted="true"] {
  transform: translateY(var(--stack-offset)) scale(1);
  opacity: 1;
}

/* ── Entry / exit via the same transition system ────── */

/* Before mount (or once the toast starts leaving) the toast sits
   offscreen in the direction of its anchor. Because this uses the
   same `transition: transform` declared on .sonner-toast, entry and
   exit share the same easing as the hover collapse/expand, so one
   animation never "fights" another if the mouse enters mid-flight. */

.sonner-toaster[data-y="bottom"] .sonner-toast[data-mounted="false"] {
  transform: translateY(calc(100% + var(--sonner-offset, 16px))) scale(1);
  opacity: 0;
}
.sonner-toaster[data-y="top"] .sonner-toast[data-mounted="false"] {
  transform: translateY(calc(-100% - var(--sonner-offset, 16px))) scale(1);
  opacity: 0;
}

.sonner-toast[data-mounted="false"] {
  pointer-events: none;
}

/* Swipe-to-dismiss: JS writes --swipe-x / --swipe-y inline */
.sonner-toast[data-swiping="true"] {
  transition: none;
  transform: translate(var(--swipe-x, 0), var(--swipe-y, 0));
}

.sonner-toast[data-swipe-out="true"] {
  animation: sonner-swipe-out 200ms ease-out both;
}

@keyframes sonner-swipe-out {
  to {
    transform: translate(var(--swipe-x, 0), var(--swipe-y, 0));
    opacity: 0;
  }
}

/* ── Content ────────────────────────────────────────── */

.sonner-toast-content {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.sonner-toast-icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}

.sonner-toast-body {
  flex: 1;
  min-width: 0;
}

.sonner-toast-title {
  font-weight: 600;
  color: #1e3a5f;
  word-wrap: break-word;
}

.sonner-toast-description {
  margin-top: 2px;
  font-size: 12.5px;
  color: rgba(30, 58, 95, 0.7);
  word-wrap: break-word;
}

.sonner-toast-close {
  position: absolute;
  top: -6px;
  left: -6px;
  width: 20px;
  height: 20px;
  padding: 0;
  border-radius: 50%;
  background: #ffffff;
  color: rgba(30, 58, 95, 0.7);
  border: 1px solid rgba(30, 58, 95, 0.1);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition:
    opacity 150ms,
    color 150ms;
}

.sonner-toast:hover .sonner-toast-close,
.sonner-toast:focus-within .sonner-toast-close {
  opacity: 1;
}

.sonner-toast-close:hover {
  color: #1e3a5f;
}

.sonner-toast-action {
  margin-top: 8px;
  padding: 5px 10px;
  background: #1e3a5f;
  color: #ffffff;
  border: none;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms;
}
.sonner-toast-action:hover {
  background: #2a4a75;
}

/* ── Type variants ──────────────────────────────────── */

.sonner-toast[data-type="success"] .sonner-toast-icon {
  color: #16a34a;
}
.sonner-toast[data-type="error"] .sonner-toast-icon {
  color: #dc2626;
}
.sonner-toast[data-type="warning"] .sonner-toast-icon {
  color: #d4a84b;
}
.sonner-toast[data-type="info"] .sonner-toast-icon {
  color: #2563eb;
}
.sonner-toast[data-type="loading"] .sonner-toast-icon {
  color: #1e3a5f;
}

/* Spinner for loading toasts */
.sonner-spinner {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(30, 58, 95, 0.2);
  border-top-color: #1e3a5f;
  animation: sonner-spin 700ms linear infinite;
}
@keyframes sonner-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── Dark theme opt-in ─────────────────────────────── */

.sonner-toaster[data-theme="dark"] .sonner-toast {
  background: #1e1e1e;
  color: #e8eaed;
  border-color: rgba(255, 255, 255, 0.08);
}
.sonner-toaster[data-theme="dark"] .sonner-toast-title {
  color: #f1f3f4;
}
.sonner-toaster[data-theme="dark"] .sonner-toast-description {
  color: rgba(255, 255, 255, 0.65);
}
.sonner-toaster[data-theme="dark"] .sonner-toast-close {
  background: #1e1e1e;
  color: rgba(255, 255, 255, 0.5);
  border-color: rgba(255, 255, 255, 0.1);
}
.sonner-toaster[data-theme="dark"] .sonner-toast-close:hover {
  color: #f1f3f4;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .sonner-toast,
  .sonner-toast[data-state="entering"],
  .sonner-toast[data-state="leaving"] {
    animation: none;
    transition: opacity 200ms;
  }
}
