/* ============================================================================
   swal-premium.css — AIToolsay premium theme for SweetAlert2 v11
   Load AFTER sweetalert2.min.css (all pages). The toastr rules this file
   used to carry (§12, §15b) left with toastr itself on 2026-09-14: admin
   toasts are §NTFY — assets/css/aits-notify.css + aits-notify.js.
   Token-driven (--aits-*), dark-aware via token re-resolution, RTL-safe
   (logical properties only), WCAG-AA, reduced-motion guarded.
   Design: Stripe / Linear / Vercel — semantic-forward, calm, expensive.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   0. Local alias layer — resolve --aits-* ONCE with literal fallbacks.
   Everything downstream uses --sp-*; dark comes free via token re-resolution.
   Only literals THIS file introduces (backdrop dim, glass ghost fill) get an
   explicit .theme-dark override.
   --------------------------------------------------------------------------- */
.swal2-container {
  --sp-card:         var(--aits-card, #fff);
  --sp-surface-2:    var(--aits-surface-2, #fafafa);
  --sp-surface-3:    var(--aits-surface-3, #f7f7f8);
  --sp-ink:          var(--aits-ink, #111);
  --sp-ink-soft:     var(--aits-ink-soft, #2b2b2b);
  --sp-txt:          var(--aits-txt, #444);
  --sp-mut:          var(--aits-mut, #666);
  --sp-faint:        var(--aits-faint, #999);
  --sp-line:         var(--aits-line, #ececec);
  --sp-line-strong:  var(--aits-line-strong, #e0e0e0);

  --sp-blue:         var(--aits-blue, #3680ed);
  --sp-blue-dark:    var(--aits-blue-dark, #2060c0);
  --sp-blue-light:   var(--aits-blue-light, #60a4f5);
  --sp-blue-tint:    var(--aits-blue-tint, #eaf2fd);
  --sp-blue-line:    var(--aits-blue-line, #cfe0fa);
  --sp-focus:        var(--aits-focus, rgba(54,128,237,.28));

  --sp-green:        var(--aits-green, #0ca678);
  --sp-green-soft:   var(--aits-green-soft, #e6fcf3);
  --sp-green-ink:    var(--aits-green-ink, #087f5b);
  --sp-amber:        var(--aits-amber, #d97706);
  --sp-amber-soft:   var(--aits-amber-soft, #fff5e1);
  --sp-amber-ink:    var(--aits-amber-ink, #b45309);
  --sp-red:          var(--aits-red, #e03131);
  --sp-red-soft:     var(--aits-red-soft, #ffecec);
  --sp-red-ink:      var(--aits-red-ink, #b71c1c);
  --sp-violet:       var(--aits-violet, #0196FD);
  --sp-violet-soft:  var(--aits-violet-soft, #E1F3FF);
  --sp-violet-ink:   #5a34c9;

  /* Theme-aware link color: darker in light (AA on white), lighter in dark */
  --sp-link:         var(--aits-blue-dark, #2060c0);

  --sp-r-sm:   var(--r-sm, 8px);
  --sp-r-md:   var(--r-md, 10px);
  --sp-r-lg:   var(--r-lg, 14px);
  --sp-r-xl:   var(--r-xl, 18px);
  --sp-r-2xl:  var(--r-2xl, 24px);
  --sp-r-pill: var(--r-pill, 999px);

  --sp-sh-sm:    var(--sh-sm, 0 2px 6px rgba(15,23,42,.08));
  --sp-sh-md:    var(--sh-md, 0 8px 24px rgba(15,23,42,.12));
  --sp-sh-lg:    var(--sh-lg, 0 12px 32px rgba(15,23,42,.16));
  --sp-sh-pop:   var(--sh-pop, 0 16px 48px rgba(15,23,42,.16));
  --sp-ring:     var(--ring, 0 0 0 3px var(--sp-focus));

  --sp-ease:   var(--ease, cubic-bezier(.16,1,.3,1));
  --sp-t-fast: var(--t-fast, .12s);
  --sp-t:      var(--t, .18s);
  --sp-t-slow: var(--t-slow, .25s);
  --sp-font:   var(--font, 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);

  /* --- Surface + effect literals introduced by the 2026-09-20 redesign -----
     Light values assume a white card; the dark block below re-states every one
     of them, because these are raw rgba() and opacity numbers that no --aits-*
     token can re-resolve for us. */
  --sp-veil:   rgba(255,255,255,.62);   /* top-of-card sheen, light theme */
  --sp-edge:   rgba(255,255,255,.90);   /* 1px inner highlight on the top edge */
  --sp-aura:   .09;                     /* accent aura opacity behind the icon */
  --sp-halo:   .13;                     /* icon halo opacity */
  --sp-gloss:  rgba(255,255,255,.26);   /* top-lit button gloss */
  --sp-sheen:  rgba(255,255,255,.28);   /* button hover sweep */

  /* Literals this file introduces (dark-overridden below) */
  --sp-backdrop:      rgba(17,20,28,.44);
  --sp-backdrop-solid: rgba(17,20,28,.58);   /* no-blur fallback */
  --sp-ghost-bg:      var(--aits-card, #fff);
  --sp-ghost-hover:   var(--aits-surface-3, #f7f7f8);

  /* Per-dialog semantic accent — overridden by icon type via :has() below.
     Default = brand blue, which is also the graceful :has()-unsupported state. */
  --sp-accent:      var(--sp-blue);
  --sp-accent-ink:  var(--sp-blue-dark);
  --sp-accent-soft: var(--sp-blue-tint);
  --sp-accent-glow: var(--sp-focus);
  /* Confirm-button accent — usually follows --sp-accent, but warning => red */
  --sp-btn:         var(--sp-blue);
  --sp-btn-ink:     var(--sp-blue-dark);
  --sp-btn-glow:    var(--sp-focus);
}
body.theme-dark .swal2-container,
body.admin-shell.theme-dark .swal2-container {
  --sp-backdrop:       rgba(2,4,8,.62);
  --sp-backdrop-solid: rgba(2,4,8,.74);
  --sp-ghost-bg:       var(--aits-surface-2, var(--dk-surface-2,#17171B));
  --sp-ghost-hover:    var(--aits-surface-3, var(--dk-surface-3,#1D1D22));
  --sp-sh-pop:         var(--sh-pop, 0 18px 50px rgba(0,0,0,.65));
  /* Brand blue is legible on dark backgrounds — use the lighter link tone */
  --sp-link:           var(--aits-blue-light, #60a4f5);

  /* Redesign literals — restated for dark. A 62% white veil that reads as a
     soft highlight on white is a grey smear on #17171B, so every one of these
     drops by roughly an order of magnitude while the two ACCENT opacities go
     UP: a coloured glow needs more presence to register against a dark card. */
  --sp-veil:   rgba(255,255,255,.035);
  --sp-edge:   rgba(255,255,255,.085);
  --sp-aura:   .17;
  --sp-halo:   .20;
  --sp-gloss:  rgba(255,255,255,.16);
  --sp-sheen:  rgba(255,255,255,.20);
}

/* ===========================================================================
   1. OVERLAY / BACKDROP / PORTAL
   =========================================================================== */
.swal2-container {
  padding: clamp(12px, 4vw, 40px);
  font-family: var(--sp-font);
  -webkit-tap-highlight-color: transparent;
}
.swal2-container.swal2-backdrop-show,
.swal2-container.swal2-noanimation,
.swal2-container.swal2-shown:not(.swal2-toast-shown) {
  background: var(--sp-backdrop-solid);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .swal2-container.swal2-backdrop-show,
  .swal2-container.swal2-noanimation,
  .swal2-container.swal2-shown:not(.swal2-toast-shown) {
    background: var(--sp-backdrop);
    -webkit-backdrop-filter: saturate(118%) blur(6px);
            backdrop-filter: saturate(118%) blur(6px);
  }
}
.swal2-container.swal2-backdrop-show { animation: sp-backdrop-in var(--sp-t-slow) var(--sp-ease); }
.swal2-container.swal2-backdrop-hide {
  background: transparent !important;
  -webkit-backdrop-filter: blur(0);
          backdrop-filter: blur(0);
  animation: sp-backdrop-out var(--sp-t) var(--sp-ease);
}
@keyframes sp-backdrop-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes sp-backdrop-out { from { opacity: 1; } to { opacity: 0; } }

/* Toast-position containers must NEVER dim/blur the page */
.swal2-container.swal2-top-start,   .swal2-container.swal2-top,
.swal2-container.swal2-top-end,     .swal2-container.swal2-center-start,
.swal2-container.swal2-center-end,  .swal2-container.swal2-bottom-start,
.swal2-container.swal2-bottom,      .swal2-container.swal2-bottom-end,
.swal2-container.swal2-grow-row,    .swal2-container.swal2-grow-fullscreen {
  background: transparent !important;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  padding: 16px;
}

/* ===========================================================================
   2. POPUP (MODAL CARD)
   ---------------------------------------------------------------------------
   Redesigned 2026-09-20. Three things carry the weight here, and each one
   replaces something cruder:

   • A LIT SURFACE, not a flat one. A near-invisible top-down veil plus a 1px
     inner highlight makes the card read as lifted rather than pasted on. In
     dark mode the veil is 3.5% white — enough to separate the card from a
     #0E0E11 page without turning it grey.

   • A TAPERED accent hairline instead of the old hard 4px band. The band ran
     edge to edge across a 24px corner radius, so its two ends were sliced off
     square by `overflow:hidden` and it read as a printing error. This fades to
     transparent before it reaches either corner, so the radius stays intact.

   • An ACCENT AURA — one large, very soft radial of the dialog's semantic
     colour bleeding down from behind the icon. It is what makes a destructive
     dialog *feel* destructive before a single word is read. It sits at
     z-index:-1, which inside this stacking context paints it above the card
     background and below every piece of content, so no text ever sits on top
     of a gradient it has not been contrast-checked against.
   =========================================================================== */
.swal2-popup {
  position: relative;
  box-sizing: border-box;
  isolation: isolate;
  inline-size: 32em;
  max-inline-size: min(94vw, 470px);
  padding: clamp(24px, 3.2vw, 34px) clamp(20px, 3.2vw, 34px) clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--sp-line);
  border-radius: clamp(18px, 2.2vw, 26px);
  background:
    linear-gradient(180deg, var(--sp-veil) 0%, transparent 46%),
    var(--sp-card);
  color: var(--sp-txt);
  box-shadow:
    0 1px 1px rgba(15, 23, 42, .04),
    0 10px 26px -14px rgba(15, 23, 42, .20),
    0 34px 68px -30px rgba(15, 23, 42, .38),
    inset 0 1px 0 var(--sp-edge);
  font-family: var(--sp-font);
  font-size: 15px;
  overflow: hidden;
}
.swal2-popup.swal2-modal { position: relative; }
.swal2-popup:focus { outline: none; }

/* Accent aura — semantic colour bleeding from behind the icon. */
.swal2-popup.swal2-modal::before {
  content: "";
  position: absolute;
  inset-block-start: -52%;
  inset-inline-start: 50%;
  inline-size: 160%;
  aspect-ratio: 1;
  translate: -50% 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--sp-accent) 0%, transparent 72%);
  opacity: var(--sp-aura);
  z-index: -1;
  pointer-events: none;
}

/* Tapered accent hairline along the top edge. */
.swal2-popup.swal2-modal::after {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--sp-accent) 20%,
    var(--sp-accent-ink) 50%,
    var(--sp-accent) 80%,
    transparent 100%);
  pointer-events: none;
}

/* Toasts are a different object entirely — no aura, no hairline. §11 below
   styles them; these two lines stop §2 leaking into them. */
.swal2-popup.swal2-toast::before,
.swal2-popup.swal2-toast::after { display: none !important; }

/* --- Per-type semantic accent driven off the rendered icon via :has() ------
   Sets the hairline, the aura, the icon chip, focus, progress steps AND the
   confirm button. --sp-btn defaults to the accent; warning/error force RED. -- */
.swal2-popup:has(.swal2-icon.swal2-success) {
  --sp-accent: var(--sp-green); --sp-accent-ink: var(--sp-green-ink);
  --sp-accent-soft: var(--sp-green-soft); --sp-accent-glow: rgba(12,166,120,.30);
  --sp-btn: var(--sp-green); --sp-btn-ink: var(--sp-green-ink); --sp-btn-glow: rgba(12,166,120,.32);
}
.swal2-popup:has(.swal2-icon.swal2-info) {
  --sp-accent: var(--sp-blue); --sp-accent-ink: var(--sp-blue-dark);
  --sp-accent-soft: var(--sp-blue-tint); --sp-accent-glow: rgba(54,128,237,.30);
  --sp-btn: var(--sp-blue); --sp-btn-ink: var(--sp-blue-dark); --sp-btn-glow: rgba(54,128,237,.30);
}
.swal2-popup:has(.swal2-icon.swal2-question) {
  --sp-accent: var(--sp-violet); --sp-accent-ink: var(--sp-violet-ink);
  --sp-accent-soft: var(--sp-violet-soft); --sp-accent-glow: rgba(112,72,232,.30);
  --sp-btn: var(--sp-violet); --sp-btn-ink: var(--sp-violet-ink); --sp-btn-glow: rgba(112,72,232,.30);
}
/* Warning: amber chip + hairline (correct severity) but a RED confirm — the
   swal delete-confirmation convention uses icon:'warning'. */
.swal2-popup:has(.swal2-icon.swal2-warning) {
  --sp-accent: var(--sp-amber); --sp-accent-ink: var(--sp-amber-ink);
  --sp-accent-soft: var(--sp-amber-soft); --sp-accent-glow: rgba(217,119,6,.30);
  --sp-btn: var(--sp-red); --sp-btn-ink: var(--sp-red-ink); --sp-btn-glow: rgba(224,49,49,.32);
}
.swal2-popup:has(.swal2-icon.swal2-error) {
  --sp-accent: var(--sp-red); --sp-accent-ink: var(--sp-red-ink);
  --sp-accent-soft: var(--sp-red-soft); --sp-accent-glow: rgba(224,49,49,.30);
  --sp-btn: var(--sp-red); --sp-btn-ink: var(--sp-red-ink); --sp-btn-glow: rgba(224,49,49,.32);
}

/* Entrance / exit spring. The 58% keyframe overshoots by 2px and 0.8% — just
   enough for the card to feel like it has mass, not enough to read as bounce. */
.swal2-popup.swal2-show { animation: sp-modal-in .42s var(--sp-ease); }
.swal2-popup.swal2-hide { animation: sp-modal-out var(--sp-t) var(--sp-ease); }
@keyframes sp-modal-in {
  0%   { opacity: 0; transform: translateY(16px) scale(.93); }
  58%  { opacity: 1; transform: translateY(-2px) scale(1.008); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes sp-modal-out {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(6px) scale(.96); }
}

/* Modal timer progress bar (non-toast). Toast rules below win on specificity. */
.swal2-popup .swal2-timer-progress-bar-container {
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 3px;
  overflow: hidden;
  background: transparent;
}
.swal2-popup .swal2-timer-progress-bar {
  block-size: 3px;
  background: linear-gradient(90deg, var(--sp-accent-ink), var(--sp-accent));
}
/* ===========================================================================
   3. TITLE + HTML BODY
   ---------------------------------------------------------------------------
   Redesigned 2026-09-20. The brief was "text should not be hidden", so two
   rules here exist purely for that:

   • `text-wrap: balance` on the title. "Delete EVERY activity log row?" used
     to break as five words then one orphan; balanced wrapping splits it evenly
     and never leaves a single word stranded on line two.
   • A real max-block-size + `overflow:auto` on the body. A long message used
     to be clipped by the card's `overflow:hidden` with no way to reach the
     rest. Now it scrolls, and only when it actually needs to.
   =========================================================================== */
.swal2-title {
  margin: 2px 0 7px;
  padding: 0;
  color: var(--sp-ink);
  font-size: clamp(1.14rem, 1.02rem + .62vw, 1.4rem);
  font-weight: 750;
  line-height: 1.28;
  letter-spacing: -.018em;
  text-align: center;
  text-wrap: balance;
  overflow-wrap: break-word;
}
.swal2-html-container {
  margin: 0 auto;
  padding: 0 2px;
  /* ~40 characters is the comfortable measure for centred text. Without it a
     three-line message runs the full 400px and the eye loses the line start. */
  max-inline-size: 40ch;
  max-block-size: min(48vh, 400px);
  overflow: auto;
  overscroll-behavior: contain;
  color: var(--sp-txt);
  font-size: clamp(.9rem, .87rem + .16vw, .975rem);
  font-weight: 400;
  line-height: 1.62;
  text-align: center;
  text-wrap: pretty;
  overflow-wrap: break-word;
}
/* Quiet scrollbar for the rare long message. */
.swal2-html-container { scrollbar-width: thin; scrollbar-color: var(--sp-line-strong) transparent; }
.swal2-html-container::-webkit-scrollbar { inline-size: 8px; }
.swal2-html-container::-webkit-scrollbar-track { background: transparent; }
.swal2-html-container::-webkit-scrollbar-thumb {
  background: var(--sp-line-strong);
  border-radius: var(--sp-r-pill);
}

/* A `<strong>` inside the message is how these dialogs name the thing being
   destroyed. It should carry the dialog's own severity colour, not bold grey. */
.swal2-html-container b,
.swal2-html-container strong { color: var(--sp-ink); font-weight: 680; }

.swal2-html-container a {
  color: var(--sp-link);
  text-decoration: none;
  font-weight: 600;
  border-block-end: 1px solid var(--sp-blue-line);
  transition: border-color var(--sp-t) var(--sp-ease), color var(--sp-t) var(--sp-ease);
}
.swal2-html-container a:hover { border-block-end-color: var(--sp-link); }
.swal2-html-container a:focus-visible {
  outline: none;
  border-radius: 3px;
  box-shadow: var(--sp-ring);
}
/* ===========================================================================
   4. ICONS — soft-tinted squircle chips with a concentric halo
   ---------------------------------------------------------------------------
   Redesigned 2026-09-20. The chip was a flat 78px tinted square with a hard
   24px radius; at that size the radius reads as a rounded rectangle rather
   than a squircle, and the glyph inside floated. Now:

   • A percentage radius (28%) stays squircle-shaped at every breakpoint, which
     a fixed px radius cannot do once the chip scales with clamp().
   • A concentric halo (::after, z-index:-1) expands a beat AFTER the chip
     lands, so the entrance reads as two gestures instead of one pop.
   • EVERY measurement inside the chip is a percentage of the chip. This is not
     stylistic: the success tick and the error cross used to be positioned in
     hard pixels (`inset-block-start: 40px`, `inline-size: 34px`) tuned for the
     old fixed 78px chip. The moment the chip scales — which it now does, down
     to 58px on a phone — pixel offsets put the tick through the corner. In
     percentages the mark is correct at any size.
   =========================================================================== */
.swal2-icon {
  position: relative;
  box-sizing: border-box;
  inline-size: clamp(58px, 15vw, 74px);
  block-size: clamp(58px, 15vw, 74px);
  margin: 2px auto clamp(12px, 2vw, 18px);
  border: 0 !important;
  border-radius: 28%;
  background: var(--sp-accent-soft);
  color: var(--sp-accent-ink);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--sp-accent) 28%, transparent),
    inset 0 1px 0 var(--sp-edge),
    0 14px 30px -14px var(--sp-accent-glow);
  animation: sp-icon-pop .46s var(--sp-ease) both;
}
.swal2-icon.swal2-icon-show { animation: sp-icon-pop .46s var(--sp-ease) both; }

/* Concentric halo. Negative z-index keeps it behind the chip's own background
   and behind the mark, so it can never wash either of them out. */
.swal2-icon::after {
  content: "";
  position: absolute;
  inset: -11px;
  border-radius: 32%;
  background: var(--sp-accent);
  opacity: 0;
  z-index: -1;
  pointer-events: none;
  animation: sp-icon-halo .58s var(--sp-ease) .1s both;
}
@keyframes sp-icon-pop {
  0%   { opacity: 0; transform: scale(.62) rotate(-7deg); }
  58%  { opacity: 1; transform: scale(1.07) rotate(.5deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes sp-icon-halo {
  from { opacity: 0; transform: scale(.72); }
  to   { opacity: var(--sp-halo); transform: scale(1); }
}

/* Glyph chips (warning / info / question) carry their mark as a text node.
   Sizing it in `em` off the chip means it tracks the clamp() above instead of
   staying 2.6rem on a 58px phone chip, where it overflowed. */
.swal2-icon .swal2-icon-content {
  font-size: .52em;
  font-weight: 800;
  line-height: 1;
  color: inherit;
  /* "!" and "?" sit optically low in most UI faces; lift them to true centre. */
  transform: translateY(-.02em);
}

/* color-mix fallback for older engines (inset ring) */
@supports not (color: color-mix(in srgb, red, blue)) {
  .swal2-icon { box-shadow: 0 14px 30px -14px var(--sp-accent-glow); }
}

/* --- SUCCESS ---
   The ring and the circular sweep lines are swal2's own animation furniture
   for a circular icon; this chip is a squircle, so they are removed and the
   tick alone carries the mark. */
.swal2-icon.swal2-success {
  background: var(--sp-green-soft);
  color: var(--sp-green-ink);
}
.swal2-icon.swal2-success .swal2-success-ring,
.swal2-icon.swal2-success [class^='swal2-success-circular-line'],
.swal2-icon.swal2-success .swal2-success-fix { display: none !important; }
.swal2-icon.swal2-success .swal2-success-line-tip,
.swal2-icon.swal2-success .swal2-success-line-long {
  background-color: var(--sp-green);
  block-size: 6.5%;
  border-radius: var(--sp-r-pill);
}
.swal2-icon.swal2-success .swal2-success-line-tip {
  inset-inline-start: 23%; inset-block-start: 51.5%; inline-size: 23%;
}
.swal2-icon.swal2-success .swal2-success-line-long {
  inset-inline-end: 18%; inset-block-start: 43.5%; inline-size: 43.5%;
}

/* --- ERROR --- */
.swal2-icon.swal2-error {
  background: var(--sp-red-soft);
  color: var(--sp-red-ink);
}
.swal2-icon.swal2-error .swal2-x-mark { position: relative; display: block; }
.swal2-icon.swal2-error [class^='swal2-x-mark-line'] {
  background-color: var(--sp-red);
  block-size: 6.5%;
  border-radius: var(--sp-r-pill);
  inset-block-start: 47.5%;
  inline-size: 51.5%;
}
.swal2-icon.swal2-error [class^='swal2-x-mark-line'][class$='left']  { inset-inline-start: 24.5%; }
.swal2-icon.swal2-error [class^='swal2-x-mark-line'][class$='right'] { inset-inline-end: 24.5%; }

/* --- WARNING / INFO / QUESTION glyph chips ---
   :has() above already sets these through --sp-accent-*; these rules are the
   fallback for engines without :has(), so the chip is still the right colour
   there rather than defaulting to brand blue. */
.swal2-icon.swal2-warning  { background: var(--sp-amber-soft); color: var(--sp-amber-ink); }
.swal2-icon.swal2-info     { background: var(--sp-blue-tint);  color: var(--sp-blue-dark); }
.swal2-icon.swal2-question { background: var(--sp-violet-soft); color: var(--sp-violet-ink); }
/* ===========================================================================
   5. ACTIONS + BUTTONS
   ---------------------------------------------------------------------------
   Redesigned 2026-09-20. This section now also carries what used to be a
   separate "§15 PREMIUM PASS" bolted on at the end of the file. Two layers
   styling the same buttons, one overriding the other by specificity, is how a
   hover state ends up correct in one and wrong in the other — so there is one
   button system here and §15 is gone.

   ROLE BEATS COLOUR (inherited from §15a, and the reason it must not be lost).
   The admin delete dialogs fire:

       Swal.mixin({ customClass:{ confirmButton:'btn btn-success',
                                  cancelButton:'btn btn-danger' },
                    buttonsStyling:false })

   which paints the DESTRUCTIVE action green and the SAFE one red — backwards,
   and the single most dangerous thing on the page to get wrong. Fixing it in
   ~30 blade files would be thirty chances to miss one, so it is fixed here:
   the ROLE class decides the colour and the Bootstrap colour class is ignored.
   `body .swal2-actions button.swal2-confirm` is (0,2,2), which beats
   `body .swal2-actions .btn-success` at (0,2,1). `.swal2-styled` is NOT in
   these selectors because buttonsStyling:false means swal never adds it.

   THE HOVER WORK. Each button carries two pseudo-elements:
     ::before — a top-lit gloss that intensifies on hover. Its radial dies out
                by 52% of the button height, which is ABOVE the text, so a white
                wash can never eat into the label's contrast.
     ::after  — a diagonal sheen that sweeps across once on hover. It peaks at
                18% white and is purely decorative: `pointer-events:none`, and
                low enough alpha that the label reads through it the whole way.
   Both are hover-gated behind `(hover:hover) and (pointer:fine)` so a touch
   device never gets a sheen stuck mid-sweep after a tap, and both are killed
   outright under prefers-reduced-motion in §14.
   =========================================================================== */
.swal2-actions {
  position: relative;
  gap: 10px;
  margin: clamp(18px, 2.4vw, 24px) 0 2px;
  padding-block-start: clamp(16px, 2.2vw, 22px);
  inline-size: 100%;
  border: 0;
  flex-direction: row;
  justify-content: center;
  flex-wrap: wrap;
}

/* --- Button order is set by ROLE, never by DOM order ----------------------
   §SEOX-adjacent, 2026-09-20. This used to be `flex-direction: row-reverse`,
   which silently depended on SweetAlert2 emitting [confirm, cancel]. Four call
   sites pass `reverseButtons: true` and emit [cancel, confirm] instead:

       partials/crs-behaviors.blade.php      ← the SHARED crs:confirm bridge
       livewire/admin/payments/_kit.blade.php
       livewire/admin/newsletter/campaign-editor.blade.php

   Sixteen others do not. So the same admin panel showed Cancel on the left in
   one delete dialog and on the RIGHT in the next, depending on which helper
   fired it — on destructive dialogs, where the position of the confirm button
   is pure muscle memory and getting it wrong deletes something.

   Ordering by role makes the rendered layout identical either way, without
   touching twenty blade files or forbidding a valid swal option. */
.swal2-actions .swal2-cancel,
.swal2-actions button.swal2-cancel { order: 1; }
.swal2-actions .swal2-deny,
.swal2-actions button.swal2-deny { order: 2; }
.swal2-actions .swal2-confirm,
.swal2-actions button.swal2-confirm { order: 3; }
/* A hairline that fades at both ends, rather than a flat rule butting into
   the card's padding. */
.swal2-actions::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: -4%;
  block-size: 1px;
  background: linear-gradient(90deg,
    transparent, var(--sp-line-strong) 16%, var(--sp-line-strong) 84%, transparent);
  pointer-events: none;
}

/* --- Shared base ---------------------------------------------------------- */
.swal2-actions .swal2-styled,
body .swal2-actions .btn,
body .swal2-actions button.swal2-confirm,
body .swal2-actions button.swal2-cancel,
body .swal2-actions button.swal2-deny {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  box-sizing: border-box;
  appearance: none;
  margin: 0;
  padding: 12px 22px;
  min-inline-size: 122px;
  min-block-size: 46px;
  border: 1px solid transparent;
  border-radius: 12px;
  font-family: var(--sp-font);
  font-size: .9375rem;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -.006em;
  cursor: pointer;
  box-shadow: none;
  transition: transform .16s var(--sp-ease),
              box-shadow .22s var(--sp-ease),
              background-color .22s var(--sp-ease),
              border-color .22s var(--sp-ease),
              color .22s var(--sp-ease);
}

/* Top-lit gloss. Dies out at 52%, above the label. */
.swal2-actions .swal2-styled::before,
body .swal2-actions .btn::before,
body .swal2-actions button.swal2-confirm::before,
body .swal2-actions button.swal2-cancel::before,
body .swal2-actions button.swal2-deny::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(130% 150% at 50% 0%, var(--sp-gloss) 0%, transparent 52%);
  opacity: .6;
  transition: opacity .22s var(--sp-ease);
  pointer-events: none;
}

/* Diagonal sheen, parked off the leading edge until hover. */
.swal2-actions .swal2-styled::after,
body .swal2-actions .btn::after,
body .swal2-actions button.swal2-confirm::after,
body .swal2-actions button.swal2-cancel::after,
body .swal2-actions button.swal2-deny::after {
  content: "";
  position: absolute;
  inset-block: -20%;
  inset-inline-start: 0;
  inline-size: 46%;
  background: linear-gradient(100deg, transparent, var(--sp-sheen), transparent);
  transform: skewX(-18deg);
  translate: -180% 0;
  opacity: 0;
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  .swal2-actions .swal2-styled:hover::before,
  body .swal2-actions .btn:hover::before,
  body .swal2-actions button.swal2-confirm:hover::before,
  body .swal2-actions button.swal2-cancel:hover::before,
  body .swal2-actions button.swal2-deny:hover::before { opacity: 1; }

  .swal2-actions .swal2-styled:hover::after,
  body .swal2-actions .btn:hover::after,
  body .swal2-actions button.swal2-confirm:hover::after,
  body .swal2-actions button.swal2-cancel:hover::after,
  body .swal2-actions button.swal2-deny:hover::after { animation: sp-sheen .62s var(--sp-ease); }

  .swal2-actions .swal2-styled:hover,
  body .swal2-actions .btn:hover { transform: translateY(-2px); }
}
@keyframes sp-sheen {
  0%   { translate: -180% 0; opacity: 0; }
  22%  { opacity: 1; }
  100% { translate: 320% 0; opacity: 0; }
}
/* `translate` is a physical axis, so the sweep would run backwards in RTL. */
[dir="rtl"] .swal2-actions .swal2-styled:hover::after,
[dir="rtl"] body .swal2-actions .btn:hover::after { animation-name: sp-sheen-rtl; }
@keyframes sp-sheen-rtl {
  0%   { translate: 320% 0; opacity: 0; }
  22%  { opacity: 1; }
  100% { translate: -180% 0; opacity: 0; }
}

.swal2-actions .swal2-styled:active,
body .swal2-actions .btn:active { transform: translateY(0) scale(.985); }

/* Kill swal's default focus box; keyboard-only ring, drawn OUTSIDE the button
   so `overflow:hidden` above cannot clip it. */
.swal2-actions .swal2-styled:focus,
body .swal2-actions .btn:focus { outline: none; box-shadow: none; }
.swal2-actions .swal2-styled:focus-visible,
body .swal2-actions .btn:focus-visible {
  outline: 2px solid var(--sp-blue);
  outline-offset: 2px;
  box-shadow: var(--sp-ring);
}

.swal2-actions .swal2-styled:disabled,
body .swal2-actions .btn:disabled,
.swal2-actions .swal2-styled[disabled],
.swal2-actions .swal2-styled.swal2-disabled {
  opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; filter: none;
}
.swal2-actions .swal2-styled:disabled::after,
body .swal2-actions .btn:disabled::after { animation: none !important; }

/* --- PRIMARY / CONFIRM ----------------------------------------------------
   Follows the dialog type through --sp-btn, so a warning or error dialog
   (every delete flow) gets a red confirm and a neutral dialog stays brand
   blue. The resting gradient bottoms out at 84% colour / 16% black so a WHITE
   label clears WCAG AA (>=4.5:1); the flat background-color line above it is
   the vibrant fallback for engines without color-mix. */
.swal2-actions .swal2-styled.swal2-confirm,
body .swal2-actions .btn-primary,
body .swal2-actions button.swal2-confirm,
body .swal2-actions button.swal2-confirm.btn-success,
body .swal2-actions button.swal2-confirm.btn-danger {
  background-color: var(--sp-btn);
  background-color: color-mix(in srgb, var(--sp-btn) 84%, #000);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--sp-btn) 96%, #fff) 0%,
    color-mix(in srgb, var(--sp-btn) 78%, #000) 100%);
  border-color: color-mix(in srgb, var(--sp-btn) 58%, #000 42%);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    0 8px 20px -8px var(--sp-btn-glow),
    0 2px 6px -3px rgba(0,0,0,.30);
}
@media (hover: hover) and (pointer: fine) {
  .swal2-actions .swal2-styled.swal2-confirm:hover,
  body .swal2-actions .btn-primary:hover,
  body .swal2-actions button.swal2-confirm:hover {
    background-color: var(--sp-btn-ink);
    background-image: linear-gradient(180deg,
      color-mix(in srgb, var(--sp-btn) 90%, #fff) 0%,
      var(--sp-btn-ink) 100%);
    border-color: var(--sp-btn-ink);
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.28),
      0 16px 30px -10px var(--sp-btn-glow),
      0 3px 8px -3px rgba(0,0,0,.34);
  }
}
.swal2-actions .swal2-styled.swal2-confirm:active,
body .swal2-actions button.swal2-confirm:active {
  box-shadow: inset 0 2px 5px rgba(0,0,0,.24), 0 2px 6px -4px var(--sp-btn-glow);
}

/* Always-green success confirm (buttonsStyling:false, .btn-success used as a
   STANDALONE button, i.e. not also .swal2-confirm). */
body .swal2-actions .btn-success:not(.swal2-confirm):not(.swal2-cancel) {
  background-color: var(--sp-green);
  background-color: color-mix(in srgb, var(--sp-green) 84%, #000);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--sp-green) 96%, #fff), color-mix(in srgb, var(--sp-green) 78%, #000));
  border-color: color-mix(in srgb, var(--sp-green) 58%, #000 42%);
  color: #fff;
}
/* Always-red danger confirm (delete flows using .btn-danger standalone). */
body .swal2-actions .btn-danger:not(.swal2-confirm):not(.swal2-cancel) {
  background-color: var(--sp-red);
  background-color: color-mix(in srgb, var(--sp-red) 84%, #000);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--sp-red) 96%, #fff), color-mix(in srgb, var(--sp-red) 78%, #000));
  border-color: color-mix(in srgb, var(--sp-red) 58%, #000 42%);
  color: #fff;
}

/* --- SECONDARY / CANCEL / DENY — quiet ghost ------------------------------ */
.swal2-actions .swal2-styled.swal2-cancel,
.swal2-actions .swal2-styled.swal2-deny,
body .swal2-actions .btn-light,
body .swal2-actions .btn-secondary,
body .swal2-actions .btn-default,
body .swal2-actions button.swal2-cancel,
body .swal2-actions button.swal2-cancel.btn-danger,
body .swal2-actions button.swal2-cancel.btn-success {
  background-color: var(--sp-ghost-bg);
  background-image: none;
  border-color: var(--sp-line-strong);
  color: var(--sp-ink-soft);
  box-shadow: 0 1px 2px rgba(15,23,42,.05), inset 0 1px 0 var(--sp-edge);
}
@media (hover: hover) and (pointer: fine) {
  .swal2-actions .swal2-styled.swal2-cancel:hover,
  .swal2-actions .swal2-styled.swal2-deny:hover,
  body .swal2-actions .btn-light:hover,
  body .swal2-actions .btn-secondary:hover,
  body .swal2-actions .btn-default:hover,
  body .swal2-actions button.swal2-cancel:hover {
    background-color: var(--sp-ghost-hover);
    border-color: var(--sp-mut);
    color: var(--sp-ink);
    box-shadow: 0 6px 16px -8px rgba(15,23,42,.28), inset 0 1px 0 var(--sp-edge);
  }
}
/* The ghost surface is already light; a white gloss on top of it does nothing
   but wash the label, so the cancel button opts out of ::before. */
.swal2-actions .swal2-styled.swal2-cancel::before,
body .swal2-actions button.swal2-cancel::before { display: none; }

/* Deny leans quietly danger — signalled by a red-tinted BORDER, not red text,
   so the label keeps AA contrast on the ghost surface in both themes. */
.swal2-actions .swal2-styled.swal2-deny {
  color: var(--sp-ink-soft);
  border-color: color-mix(in srgb, var(--sp-red) 34%, var(--sp-line-strong));
}
.swal2-actions .swal2-styled.swal2-deny:hover { border-color: var(--sp-red); color: var(--sp-ink); }
/* ===========================================================================
   6. LOADER — premium accent spinner
   =========================================================================== */
.swal2-loader {
  margin: 18px auto;
  inline-size: 2.4em;
  block-size: 2.4em;
  border-width: 3px;
  border-style: solid;
  border-color: var(--sp-accent) transparent var(--sp-accent) transparent;
}

/* ===========================================================================
   7. INPUTS
   =========================================================================== */
.swal2-input,
.swal2-textarea,
.swal2-select,
.swal2-file {
  box-sizing: border-box;
  inline-size: 100%;
  max-inline-size: 100%;
  min-block-size: 44px;
  margin: 12px auto 4px;
  padding: 11px 14px;
  border: 1px solid var(--sp-line-strong);
  border-radius: var(--sp-r-md);
  background: var(--sp-card);
  color: var(--sp-ink);
  font-family: var(--sp-font);
  font-size: .95rem;
  line-height: 1.4;
  box-shadow: none;
  transition: border-color var(--sp-t) var(--sp-ease), box-shadow var(--sp-t) var(--sp-ease);
}
.swal2-textarea { min-block-size: 96px; resize: vertical; line-height: 1.55; }
.swal2-input::placeholder,
.swal2-textarea::placeholder { color: var(--sp-mut); }
.swal2-input:focus,
.swal2-textarea:focus,
.swal2-select:focus,
.swal2-file:focus {
  outline: none;
  border-color: var(--sp-accent);
  box-shadow: var(--sp-ring);
}
.swal2-input.swal2-inputerror,
.swal2-textarea.swal2-inputerror,
.swal2-select.swal2-inputerror {
  border-color: var(--sp-red) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sp-red) 22%, transparent) !important;
}
.swal2-input-label {
  margin: 10px auto 2px;
  color: var(--sp-ink-soft);
  font-size: .875rem;
  font-weight: 600;
}

/* range */
.swal2-range { margin: 12px auto; background: transparent; }
.swal2-range input { inline-size: 80%; accent-color: var(--sp-accent); }
.swal2-range output {
  color: var(--sp-ink);
  font-weight: 650;
  font-size: .95rem;
  font-variant-numeric: tabular-nums;
}

/* checkbox / radio */
.swal2-checkbox,
.swal2-radio {
  gap: 8px;
  margin: 12px auto;
  padding: 8px 12px;
  border-radius: var(--sp-r-sm);
  background: var(--sp-surface-3);
  color: var(--sp-txt);
  font-size: .95rem;
}
.swal2-checkbox input,
.swal2-radio input {
  margin-inline: 0 8px;
  accent-color: var(--sp-accent);
  inline-size: 1.05em;
  block-size: 1.05em;
}

/* validation message — danger pill with shape-bearing badge */
.swal2-validation-message {
  margin: 12px 0 0;
  padding: 9px 14px;
  border-radius: var(--sp-r-md);
  background: var(--sp-red-soft) !important;
  color: var(--sp-red-ink) !important;
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.4;
}
.swal2-validation-message::before {
  content: "!";
  display: inline-grid;
  place-items: center;
  inline-size: 18px;
  block-size: 18px;
  margin-inline: 0 8px;
  border-radius: var(--sp-r-pill);
  background: var(--sp-red);
  color: #fff;
  font-weight: 800;
  font-size: .78rem;
}

/* ===========================================================================
   8. CLOSE + FOOTER
   =========================================================================== */
.swal2-close {
  inset-block-start: 12px;
  inset-inline-end: 12px;
  inline-size: 38px;
  block-size: 38px;
  border-radius: var(--sp-r-sm);
  color: var(--sp-mut);
  font-size: 26px;
  line-height: 1;
  transition: color var(--sp-t) var(--sp-ease), background-color var(--sp-t) var(--sp-ease);
}
.swal2-close:hover { color: var(--sp-ink-soft); background: var(--sp-surface-3); }
.swal2-close:focus-visible { outline: none; color: var(--sp-ink-soft); box-shadow: var(--sp-ring); }
.swal2-footer {
  margin: 20px 0 0;
  padding-block-start: 16px;
  border-block-start: 1px solid var(--sp-line);
  color: var(--sp-mut);
  font-size: .85rem;
  line-height: 1.5;
}
.swal2-footer a { color: var(--sp-link); font-weight: 600; text-decoration: none; }

/* ===========================================================================
   9. IMAGE
   =========================================================================== */
.swal2-image {
  margin: 16px auto 6px;
  border-radius: var(--sp-r-lg);
  max-inline-size: 100%;
  box-shadow: var(--sp-sh-sm);
}

/* ===========================================================================
   10. PROGRESS STEPS — premium stepper
   =========================================================================== */
.swal2-progress-steps {
  margin: 4px auto 20px;
  padding: 0;
  gap: 0;
  font-weight: 650;
}
.swal2-progress-steps .swal2-progress-step {
  inline-size: 26px;
  block-size: 26px;
  border-radius: var(--sp-r-pill);
  background: var(--sp-surface-3);
  color: var(--sp-mut);
  font-size: .8rem;
  line-height: 26px;
  font-variant-numeric: tabular-nums;
}
/* Active step uses the darker accent-ink so the white numeral meets AA. */
.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step {
  background: var(--sp-accent-ink);
  color: #fff;
  box-shadow: 0 0 0 4px var(--sp-accent-soft);
}
.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step ~ .swal2-progress-step,
.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step ~ .swal2-progress-step-line {
  background: var(--sp-surface-3);
}
.swal2-progress-steps .swal2-progress-step-line {
  inline-size: 30px;
  block-size: 3px;
  margin-inline: 0;
  background: var(--sp-accent);
}

/* ===========================================================================
   11. TOAST (swal) — compact card, semantic left rail, accent timer bar
   =========================================================================== */
.swal2-popup.swal2-toast {
  box-sizing: border-box;
  inline-size: auto;
  max-inline-size: 380px;
  padding: 14px 16px;
  gap: 2px;
  border: 1px solid var(--sp-line);
  border-inline-start: 4px solid var(--sp-blue);
  border-radius: var(--sp-r-lg);
  background: var(--sp-card) !important;
  box-shadow: var(--sp-sh-md);
  overflow: hidden;
}
.swal2-popup.swal2-toast::before { display: none; } /* no modal top bar on toast */
.swal2-popup.swal2-toast.swal2-icon-success,
.swal2-popup.swal2-toast:has(.swal2-success) { border-inline-start-color: var(--sp-green); }
.swal2-popup.swal2-toast.swal2-icon-error,
.swal2-popup.swal2-toast:has(.swal2-error)   { border-inline-start-color: var(--sp-red); }
.swal2-popup.swal2-toast.swal2-icon-warning,
.swal2-popup.swal2-toast:has(.swal2-warning) { border-inline-start-color: var(--sp-amber); }
.swal2-popup.swal2-toast.swal2-icon-info,
.swal2-popup.swal2-toast:has(.swal2-info)    { border-inline-start-color: var(--sp-blue); }
.swal2-popup.swal2-toast.swal2-icon-question,
.swal2-popup.swal2-toast:has(.swal2-question){ border-inline-start-color: var(--sp-violet); }

.swal2-popup.swal2-toast .swal2-title {
  margin: 0;
  color: var(--sp-ink);
  font-size: .9rem;
  font-weight: 650;
  line-height: 1.4;
  text-align: start;
}
.swal2-popup.swal2-toast .swal2-html-container {
  margin: 2px 0 0;
  color: var(--sp-txt);
  font-size: .82rem;
  line-height: 1.45;
  text-align: start;
}
.swal2-popup.swal2-toast .swal2-icon {
  inline-size: 30px;
  block-size: 30px;
  min-inline-size: 30px;
  margin: 0;
  margin-inline: 2px 12px;
  border-radius: var(--sp-r-sm);
  box-shadow: none;
  animation: none;
}
.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content { font-size: 1.05rem; }
.swal2-popup.swal2-toast .swal2-success .swal2-success-line-tip  { inset-block-start: 15px; inset-inline-start: 6px; inline-size: 7px;  block-size: 3px; }
.swal2-popup.swal2-toast .swal2-success .swal2-success-line-long { inset-block-start: 12px; inset-inline-end: 5px;  inline-size: 14px; block-size: 3px; }
.swal2-popup.swal2-toast .swal2-error [class^='swal2-x-mark-line'] { inset-block-start: 14px; block-size: 3px; inline-size: 16px; }
.swal2-popup.swal2-toast .swal2-error [class^='swal2-x-mark-line'][class$='left']  { inset-inline-start: 7px; }
.swal2-popup.swal2-toast .swal2-error [class^='swal2-x-mark-line'][class$='right'] { inset-inline-end: 7px; }
.swal2-popup.swal2-toast .swal2-actions { margin: 8px 0 0; padding-block-start: 0; border: 0; gap: 6px; }
.swal2-popup.swal2-toast .swal2-styled { min-inline-size: 0; padding: 6px 12px; min-block-size: 32px; font-size: .8rem; }
.swal2-popup.swal2-toast .swal2-close { inline-size: 26px; block-size: 26px; font-size: 20px; inset-block-start: 6px; inset-inline-end: 6px; }

/* toast timer bar — accent gradient keyed to the icon */
.swal2-popup.swal2-toast .swal2-timer-progress-bar-container {
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 3px;
  border-radius: 0;
  overflow: hidden;
  background: transparent;
}
.swal2-popup.swal2-toast .swal2-timer-progress-bar {
  block-size: 3px;
  background: linear-gradient(90deg, var(--sp-blue-light), var(--sp-blue));
}
.swal2-popup.swal2-toast.swal2-icon-success .swal2-timer-progress-bar,
.swal2-popup.swal2-toast:has(.swal2-success) .swal2-timer-progress-bar { background: linear-gradient(90deg, var(--sp-green-ink), var(--sp-green)); }
.swal2-popup.swal2-toast.swal2-icon-error .swal2-timer-progress-bar,
.swal2-popup.swal2-toast:has(.swal2-error) .swal2-timer-progress-bar   { background: linear-gradient(90deg, var(--sp-red-ink), var(--sp-red)); }
.swal2-popup.swal2-toast.swal2-icon-warning .swal2-timer-progress-bar,
.swal2-popup.swal2-toast:has(.swal2-warning) .swal2-timer-progress-bar { background: linear-gradient(90deg, var(--sp-amber-ink), var(--sp-amber)); }
.swal2-popup.swal2-toast.swal2-icon-question .swal2-timer-progress-bar,
.swal2-popup.swal2-toast:has(.swal2-question) .swal2-timer-progress-bar { background: linear-gradient(90deg, var(--sp-violet-ink), var(--sp-violet)); }

/* toast entrance/exit — corner slide-in, RTL-mirrored */
.swal2-popup.swal2-toast.swal2-show { animation: sp-toast-in var(--sp-t-slow) var(--sp-ease); }
.swal2-popup.swal2-toast.swal2-hide { animation: sp-toast-out var(--sp-t) var(--sp-ease); }
@keyframes sp-toast-in  { from { opacity: 0; transform: translateX(24px) scale(.96); } to { opacity: 1; transform: translateX(0) scale(1); } }
@keyframes sp-toast-out { from { opacity: 1; transform: translateX(0) scale(1); }    to { opacity: 0; transform: translateX(24px) scale(.96); } }
[dir="rtl"] .swal2-popup.swal2-toast.swal2-show { animation-name: sp-toast-in-rtl; }
[dir="rtl"] .swal2-popup.swal2-toast.swal2-hide { animation-name: sp-toast-out-rtl; }
@keyframes sp-toast-in-rtl  { from { opacity: 0; transform: translateX(-24px) scale(.96); } to { opacity: 1; transform: translateX(0) scale(1); } }
@keyframes sp-toast-out-rtl { from { opacity: 1; transform: translateX(0) scale(1); }     to { opacity: 0; transform: translateX(-24px) scale(.96); } }
/* bottom-anchored toasts rise from below */
.swal2-container.swal2-bottom-end .swal2-popup.swal2-toast.swal2-show,
.swal2-container.swal2-bottom .swal2-popup.swal2-toast.swal2-show,
.swal2-container.swal2-bottom-start .swal2-popup.swal2-toast.swal2-show { animation-name: sp-toast-in-up; }
@keyframes sp-toast-in-up { from { opacity: 0; transform: translateY(12px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }

/* ===========================================================================
   13. RESPONSIVE — phone, tablet, desktop
   ---------------------------------------------------------------------------
   Redesigned 2026-09-20. There used to be two breakpoints that disagreed with
   each other: §13 stacked the buttons at 420px, and §15 stacked them again at
   640px in the opposite direction. Between 421px and 640px — which is most of
   the phone range in landscape, and every small tablet — you got a row of
   buttons laid out by whichever rule the cascade happened to favour.

   One ladder now, and the sizing between the rungs is handled by the clamp()
   values in §2–§5 rather than by more breakpoints.
   =========================================================================== */

/* --- Tablet and small laptop --------------------------------------------- */
@media (max-width: 900px) {
  .swal2-container { padding: clamp(14px, 4vw, 28px); }
  .swal2-popup { max-inline-size: min(92vw, 440px); }
}

/* --- Phone: the two actions stack, primary on top, both full width -------- */
@media (max-width: 600px) {
  .swal2-popup {
    max-inline-size: 94vw;
    border-radius: 20px;
  }
  /* column-REVERSE, so the role order above (cancel 1 … confirm 3) puts the
     confirm button on TOP when the row stacks, matching the primary-first
     convention for stacked dialog actions. */
  .swal2-actions {
    flex-direction: column-reverse;
    flex-wrap: nowrap;
    gap: 9px;
  }
  .swal2-actions .swal2-styled,
  body .swal2-actions .btn,
  body .swal2-actions button.swal2-confirm,
  body .swal2-actions button.swal2-cancel,
  body .swal2-actions button.swal2-deny {
    inline-size: 100%;
    min-inline-size: 0;
    min-block-size: 48px;   /* 48px is the comfortable touch target */
  }
  /* The measure cap earns nothing once the card IS the measure. */
  .swal2-html-container { max-inline-size: none; }
}

/* --- Very small phones ---------------------------------------------------- */
@media (max-width: 380px) {
  .swal2-container { padding: 10px; }
  .swal2-popup { padding: 22px 18px 18px; border-radius: 18px; }
  .swal2-actions .swal2-styled,
  body .swal2-actions .btn { padding-inline: 16px; }
}

/* --- Short viewports (landscape phone, split screen) ----------------------
   The card is centred with `overflow:hidden`, so on a 380px-tall viewport the
   icon + title + body + actions can exceed the screen and the buttons end up
   below the fold with no way to reach them. Trimming the icon and letting the
   body scroll keeps the actions on screen. */
@media (max-height: 560px) and (min-width: 601px) {
  .swal2-icon { inline-size: 52px; block-size: 52px; margin-block-end: 10px; }
  .swal2-icon::after { inset: -8px; }
  .swal2-popup { padding-block: 22px 18px; }
  .swal2-html-container { max-block-size: 34vh; }
}

/* --- Coarse pointers: no lift, bigger targets ----------------------------- */
@media (pointer: coarse) {
  .swal2-actions .swal2-styled,
  body .swal2-actions .btn { min-block-size: 48px; }
  .swal2-actions .swal2-styled:active,
  body .swal2-actions .btn:active { transform: scale(.975); }
}
/* ===========================================================================
   14. REDUCED MOTION
   ---------------------------------------------------------------------------
   Every animation and transition this file introduces is switched off here,
   including SweetAlert2's own success-line / x-mark draw animations and the
   button sheen.

   The two `opacity` lines are the part that is easy to get wrong: the icon
   halo and the aura start at opacity 0 and are brought up BY their keyframes.
   Killing the animation without restoring the end state would leave a reduced-
   motion user looking at a dialog with its halo missing — a different design,
   not the same design held still.
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .swal2-container,
  .swal2-container.swal2-backdrop-show,
  .swal2-container.swal2-backdrop-hide,
  .swal2-popup, .swal2-popup.swal2-show, .swal2-popup.swal2-hide,
  .swal2-popup.swal2-modal::before, .swal2-popup.swal2-modal::after,
  .swal2-popup.swal2-toast.swal2-show, .swal2-popup.swal2-toast.swal2-hide,
  [dir="rtl"] .swal2-popup.swal2-toast.swal2-show,
  [dir="rtl"] .swal2-popup.swal2-toast.swal2-hide,
  .swal2-icon, .swal2-icon.swal2-icon-show, .swal2-icon::after, .swal2-icon *,
  .swal2-icon .swal2-icon-content,
  .swal2-success-line-tip, .swal2-success-line-long,
  .swal2-icon.swal2-error [class^='swal2-x-mark-line'],
  .swal2-actions .swal2-styled, body .swal2-actions .btn,
  .swal2-actions .swal2-styled::before, .swal2-actions .swal2-styled::after,
  body .swal2-actions .btn::before, body .swal2-actions .btn::after,
  body .swal2-actions button.swal2-confirm::before,
  body .swal2-actions button.swal2-confirm::after,
  body .swal2-actions button.swal2-cancel::before,
  body .swal2-actions button.swal2-cancel::after,
  .swal2-input, .swal2-textarea, .swal2-select, .swal2-file,
  .swal2-close {
    animation: none !important;
    transition: none !important;
  }
  /* Restore the end state of the two animations that fade IN from zero. */
  .swal2-icon::after { opacity: var(--sp-halo); transform: scale(1); }
  .swal2-popup.swal2-modal::before { opacity: var(--sp-aura); }

  /* No lift, no sweep, no press. */
  .swal2-actions .swal2-styled:hover,
  body .swal2-actions .btn:hover,
  .swal2-actions .swal2-styled:active,
  body .swal2-actions .btn:active { transform: none !important; }
  .swal2-actions .swal2-styled:hover::after,
  body .swal2-actions .btn:hover::after { opacity: 0 !important; translate: -180% 0 !important; }
}
