/* ==========================================================================
   MAGPS — global notification skin.

   ONE stylesheet for every alert surface in the web app: the live map, every
   admin page, and the ~25 direct `toastr.*` calls scattered through Blade
   views. It replaces the 2012 toastr 2.0.1 look (flat colour blocks, base64
   PNG icons, opacity .8) and the page-scoped restyle that used to live in
   Admin/Objects/_styles.blade.php.

   Why a plain CSS file and not SCSS: `gulp` pulls in node-sass, which does not
   build on Node 18+, so the 17 compiled theme CSS files are frozen. This file
   is hand-maintained, loaded from both layouts, and cache-busted by
   asset_resource()'s ?t=filemtime.

   Markup is produced by notify.js. The legacy toastr class names
   (#toast-container / .toast-success|error|info|warning) are kept so that any
   code still reaching for them keeps working.
   ========================================================================== */

#toast-container {
    --mn-radius: 14px;
    --mn-surface: #fff;
    --mn-ink: #0f172a;
    --mn-ink-strong: #071a3d;
    --mn-ink-muted: #64748b;
    --mn-border: #e9edf3;
    --mn-success: #16a34a;
    --mn-error: #dc2626;
    --mn-info: #0b66ff;
    --mn-warning: #f59e0b;

    position: fixed;
    z-index: 10600;               /* above bootstrap modals (1050) and the map */
    top: 18px;
    right: 18px;
    left: auto;
    bottom: auto;
    width: 360px;
    max-width: calc(100vw - 28px);
    display: flex;
    flex-direction: column;
    gap: 10px;
    pointer-events: none;         /* the gaps must not eat map clicks */
    font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* toastr's own position classes must not fight the flex column above */
#toast-container.toast-top-right,
#toast-container.toast-top-left,
#toast-container.toast-bottom-right,
#toast-container.toast-bottom-left,
#toast-container.toast-top-full-width,
#toast-container.toast-bottom-full-width {
    top: 18px;
    right: 18px;
    left: auto;
    bottom: auto;
}

#toast-container * { box-sizing: border-box; }

/* --------------------------------------------------------------------------
   The "close all" bar. Sits above the stack and only appears once there is
   more than one notification, so a single toast never grows extra chrome.
   -------------------------------------------------------------------------- */
.mn-bulk {
    pointer-events: auto;
    display: none;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 8px 7px 13px;
    border-radius: 999px;
    background: rgba(7, 26, 61, .92);
    color: #fff;
    box-shadow: 0 8px 22px rgba(15, 23, 42, .22);
    backdrop-filter: saturate(140%) blur(6px);
    -webkit-backdrop-filter: saturate(140%) blur(6px);
}
#toast-container.mn-has-stack .mn-bulk { display: flex; }

.mn-bulk__count {
    /* a <button> since it toggles the phone stack — strip the UA chrome so it
       still reads as the plain label it was before */
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
    text-align: left;
    cursor: default;
}
.mn-bulk__count:focus-visible { outline: 2px solid #fff; outline-offset: 2px; border-radius: 6px; }
.mn-bulk__count b { font-weight: 800; }

.mn-bulk__btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, .14);
    color: #fff;
    font: inherit;
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.2;
    cursor: pointer;
    transition: background .15s ease;
}
.mn-bulk__btn:hover,
.mn-bulk__btn:focus-visible { background: rgba(255, 255, 255, .26); color: #fff; }
.mn-bulk__btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.mn-bulk__btn svg { width: 13px; height: 13px; flex: none; }

/* --------------------------------------------------------------------------
   A single notification card.
   -------------------------------------------------------------------------- */
#toast-container > .mn-toast,
#toast-container > div.toast {
    pointer-events: auto;
    position: relative;
    display: grid;
    grid-template-columns: 32px 1fr;
    align-items: start;
    column-gap: 12px;
    width: 100%;
    margin: 0;
    padding: 14px 38px 14px 15px;
    border: 1px solid var(--mn-border);
    border-radius: var(--mn-radius);
    background: var(--mn-surface) !important;
    background-image: none !important;   /* kills the 2012 base64 PNG icons */
    color: var(--mn-ink);
    opacity: 1;
    overflow: hidden;
    box-shadow: 0 14px 34px rgba(15, 23, 42, .15), 0 2px 8px rgba(15, 23, 42, .07);
    transition: box-shadow .18s ease, transform .18s ease;
}
#toast-container > .mn-toast:hover {
    box-shadow: 0 18px 42px rgba(15, 23, 42, .2), 0 4px 12px rgba(15, 23, 42, .09);
}

/* the state accent runs down the leading edge */
.mn-toast::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    background: var(--mn-accent, var(--mn-info));
}
.mn-toast--success { --mn-accent: var(--mn-success); }
.mn-toast--error   { --mn-accent: var(--mn-error); }
.mn-toast--info    { --mn-accent: var(--mn-info); }
.mn-toast--warning { --mn-accent: var(--mn-warning); }

.mn-toast__ic {
    grid-row: 1 / span 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-top: 1px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--mn-accent) 13%, transparent);
    color: var(--mn-accent);
}
/* color-mix is widely supported but not universal — this keeps the badge
   readable on anything that ignores the rule above. */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
    .mn-toast__ic { background: #eef2f8; }
}
.mn-toast__ic svg { width: 17px; height: 17px; }

.mn-toast__title {
    margin: 0 0 2px;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--mn-ink-strong);
}
.mn-toast__msg {
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.5;
    color: var(--mn-ink);
    overflow-wrap: anywhere;
}
.mn-toast__msg a { color: var(--mn-info); font-weight: 600; }
.mn-toast__msg br:last-child { display: none; }   /* event.js ends its body with <br> */

.mn-toast__close {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: #9aa6b8;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    opacity: .9;
    transition: background .15s ease, color .15s ease;
}
.mn-toast__close:hover { background: #f1f5f9; color: #475569; opacity: 1; }
.mn-toast__close:focus-visible { outline: 2px solid var(--mn-info); outline-offset: 1px; }

/* duplicate collapsing — "×3" instead of three identical cards */
.mn-toast__dup {
    display: none;
    position: absolute;
    right: 36px;
    top: 11px;
    min-width: 20px;
    height: 18px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--mn-accent);
    color: #fff;
    font-size: 10.5px;
    font-weight: 800;
    line-height: 18px;
    text-align: center;
}
.mn-toast.is-dup .mn-toast__dup { display: block; }

/* real progress bar — toastr 2.0.1 has none, so notify.js drives this */
.mn-toast__bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    transform-origin: left center;
    background: var(--mn-accent);
    opacity: .5;
}
.mn-toast.is-paused .mn-toast__bar { animation-play-state: paused; }

@keyframes mn-bar { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes mn-in  { from { opacity: 0; transform: translateX(14px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes mn-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(14px); } }

.mn-toast { animation: mn-in .2s cubic-bezier(.22, 1, .36, 1) both; }
.mn-toast.is-leaving { animation: mn-out .16s ease-in both; pointer-events: none; }

/* --------------------------------------------------------------------------
   Phones: full-width, bottom-anchored, thumb-reachable close targets.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
    #toast-container,
    #toast-container.toast-top-right,
    #toast-container.toast-top-left,
    #toast-container.toast-bottom-right,
    #toast-container.toast-bottom-left {
        top: auto;
        bottom: 12px;
        left: 10px;
        right: 10px;
        width: auto;
        max-width: none;
        flex-direction: column-reverse;   /* newest nearest the thumb */
    }
    #toast-container > .mn-toast { padding: 13px 36px 13px 13px; }
    .mn-toast__close { width: 28px; height: 28px; }

    /* ----------------------------------------------------------------------
       Collapsed pile.

       Four flat cards measured 442px on a 390x844 phone — 52% of the screen,
       covering the map the alerts are ABOUT. Collapsed, the pile is one card
       tall plus a few millimetres of peek, and tapping it expands the lot.

       The cards are stacked with grid rather than `position:absolute` so the
       container still has the height of the front card (absolute children
       would collapse it to zero and the bottom anchor would float away).
       ---------------------------------------------------------------------- */
    #toast-container.mn-collapsed {
        display: grid;
        grid-template-columns: 1fr;
    }
    /* every card lands in the same cell; depth decides how it is drawn */
    #toast-container.mn-collapsed > .mn-toast {
        grid-area: 1 / 1;
        align-self: end;
        /* Behind-cards peek out the TOP: the container is bottom-anchored, so
           growing upward keeps the front card pinned where the thumb expects.
           --mn-depth arrives from JS as a plain number; it is multiplied here
           rather than inside scale() because scale() needs a bare <number> and
           a calc() that mixes a length would silently void the whole
           transform (measured: it computed to matrix(1,0,0,1,0,0)). */
        transform: translateY(var(--mn-shift, 0px)) scale(var(--mn-scale, 1));
        transform-origin: bottom center;
        /* Deeper cards sit further back — z-index must invert depth. */
        z-index: var(--mn-z, 10);
        transition: transform .22s cubic-bezier(.22,1,.36,1),
                    opacity .22s ease, filter .22s ease;
        /* `.mn-toast` enters with `animation: mn-in ... both`, and a filled
           animation BEATS a plain declaration — its final `transform: none`
           was silently cancelling the offsets above (measured: every card
           computed to matrix(1,0,0,1,0,0)). Swap in an entry animation that
           lands on the depth transform instead of fighting it. */
        animation: mn-in-stack .2s cubic-bezier(.22, 1, .36, 1) both;
    }
    @keyframes mn-in-stack {
        from { opacity: 0;
               transform: translateY(calc(var(--mn-shift, 0px) + 10px))
                          scale(var(--mn-scale, 1)); }
        to   { opacity: 1;
               transform: translateY(var(--mn-shift, 0px))
                          scale(var(--mn-scale, 1)); }
    }
    /* Buried cards are wallpaper: no text should be legible through the front
       card's shadow, and they must not steal a tap. */
    #toast-container.mn-collapsed > .mn-toast.is-buried {
        pointer-events: none;
        opacity: .96;
    }
    #toast-container.mn-collapsed > .mn-toast.is-buried > * { visibility: hidden; }
    /* keep the accent rail visible so the pile reads as coloured layers */
    #toast-container.mn-collapsed > .mn-toast.is-buried::before { visibility: visible; }
    /* the 4th and deeper layers are fully hidden — three is all that reads */
    #toast-container.mn-collapsed > .mn-toast[data-mn-depth="3"] { opacity: 0; }

    /* The bulk bar is the pile's handle while collapsed: it names the count and
       expands on tap, so the buried cards are never a dead end. */
    #toast-container.mn-collapsed .mn-bulk { grid-area: 2 / 1; }

    /* ----------------------------------------------------------------- open */
    /* Expanded, the pile becomes a scrollable column so a long burst cannot run
       off the top of the screen the way the flat stack did. */
    #toast-container.mn-expanded {
        max-height: 76vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }
    #toast-container.mn-expanded > .mn-toast { flex: none; }

    .mn-bulk__count { cursor: pointer; }
}

@media (prefers-reduced-motion: reduce) {
    .mn-toast,
    .mn-toast.is-leaving { animation: none; }
    .mn-toast__bar { animation: none; opacity: .28; transform: none; }
}

/* --------------------------------------------------------------------------
   Dark themes. The app ships 7 `dark-*` skins; they set a dark body
   background, so match rather than punch a white hole in the page.
   -------------------------------------------------------------------------- */
body.dark-theme #toast-container,
body[class*="dark-"] #toast-container {
    --mn-surface: #151b26;
    --mn-ink: #e6ebf3;
    --mn-ink-strong: #f5f8fc;
    --mn-ink-muted: #94a3b8;
    --mn-border: #263041;
}
body.dark-theme .mn-toast__close:hover,
body[class*="dark-"] .mn-toast__close:hover { background: #222c3c; color: #cbd5e1; }
