/* ===== FLASH MESSAGE TOASTS =====
   The single definition. Before this file there were five: .msg-toast in
   styles.css (inline block), auth.css (fixed and centred) and twice in
   landing.css, plus a whole second implementation in navbar.css keyed on the
   bare class names `.success, .error, .warning, .info`.

   That last one is why this file exists. Four of the most generic class names
   in a stylesheet cost two real bugs:

   * On the login page, auth.css set `top` and navbar.css's mobile block set
     `bottom` on the same fixed box. A box with both is stretched, so the
     session-expired message grew to 725 px — 86 % of a 845 px viewport.
   * `class="error"` is what seven templates put on *form field* errors. They
     were being pulled out of the form to `position: fixed; z-index: 9999`, all
     landing on the same spot, so two invalid fields produced one unreadable
     stack.

   Rules here therefore key on `.msg-toast` only. Positioning belongs to the
   region, appearance to the toast — never both on one element, which is what
   made the top/bottom collision possible in the first place. */

/* ── Region: where toasts live ───────────────────────────────
   Desktop: under the navbar, top right. Mobile: across the bottom, in the
   thumb's reach and consistent with the nav sheet. `top: auto` on mobile is
   load-bearing — setting top and bottom together is the original bug. */
.msg-toast-region {
    position: fixed;
    top: 80px;
    right: 20px;
    left: auto;
    bottom: auto;
    z-index: 500;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: min(400px, calc(100vw - 40px));
    /* The region spans its stack but must not swallow clicks in the gaps. */
    pointer-events: none;
}

/* No `:empty` guard here — a pretty-printed template leaves whitespace text
   nodes, so it would never match. The component renders the region only inside
   {% if messages %} instead. */

@media (max-width: 640px) {
    .msg-toast-region {
        top: auto;
        bottom: calc(20px + env(safe-area-inset-bottom, 0px));
        left: 10px;
        right: 10px;
        width: auto;
    }
}

/* ── Toast ───────────────────────────────────────────────────
   Appearance only. No position, no top/bottom, no z-index. */
.msg-toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.9rem 1rem;
    border-radius: 12px;
    border-top: 1px solid var(--at-12, rgba(196, 168, 96, 0.12));
    border-left: 4px solid var(--border);
    background: rgba(12, 22, 12, 0.92);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
    font-size: 0.9rem;
    font-weight: 500;
    line-height: 1.45;
    text-wrap: pretty;
    animation: msgToastIn 0.25s ease-out;
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.msg-toast-text {
    flex: 1;
    min-width: 0;
    /* A long message wraps; it does not stretch the toast off screen. */
    overflow-wrap: break-word;
}

.msg-toast.success { color: #a8d5ab; border-left-color: #6b8e6f; }
.msg-toast.error   { color: #f08080; border-left-color: var(--error); }
.msg-toast.warning { color: #e8d5a3; border-left-color: var(--primary); }
.msg-toast.info,
.msg-toast.debug   { color: rgba(240, 237, 231, 0.9); border-left-color: #5a7a6a; }

/* ── Close button ────────────────────────────────────────────
   Errors and warnings carry data-persist and never auto-dismiss, so without
   this they stayed on screen until the user navigated away — which on the
   login page meant they could not be got rid of at all. */
.msg-toast-close {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    margin: -0.15rem -0.25rem 0 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: none;
    color: inherit;
    opacity: 0.65;
    cursor: pointer;
    transition-property: opacity, background-color;
    transition-duration: 0.2s;
}

.msg-toast-close:hover {
    opacity: 1;
    background: rgba(255, 255, 255, 0.1);
}

.msg-toast-close svg {
    width: 14px;
    height: 14px;
}

/* ── Leaving ─────────────────────────────────────────────────
   Kept off max-height/padding: animating those made the stack below jump. */
.msg-toast--fade {
    opacity: 0;
    transform: translateX(12px);
}

@keyframes msgToastIn {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 640px) {
    @keyframes msgToastIn {
        from { opacity: 0; transform: translateY(8px); }
        to   { opacity: 1; transform: translateY(0); }
    }

    .msg-toast--fade {
        transform: translateY(12px);
    }
}

/* ── Light mode ──────────────────────────────────────────── */
html:not(.dark-mode) .msg-toast {
    background: rgba(255, 255, 255, 0.97);
    border-top-color: rgba(0, 0, 0, 0.05);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}

html:not(.dark-mode) .msg-toast.success { color: #3d6b40; }
html:not(.dark-mode) .msg-toast.error   { color: #a33; }
html:not(.dark-mode) .msg-toast.warning { color: #7a5c1a; }
html:not(.dark-mode) .msg-toast.info,
html:not(.dark-mode) .msg-toast.debug   { color: rgba(26, 26, 26, 0.75); }

html:not(.dark-mode) .msg-toast-close:hover {
    background: rgba(0, 0, 0, 0.07);
}

@media (prefers-reduced-motion: reduce) {
    .msg-toast {
        animation: none;
        transition: none;
    }
}
