/* =========================================================================
   ns-toast — the one toast surface for the NetShow creator path (OPUS5-M08)
   =========================================================================

   Every colour, radius, space, shadow, font and duration below resolves
   through design-system.css's --ns-* tokens, so the toast follows the live
   theme (gold / silver / light / dark) with no per-theme rules of its own.
   The two tokens the design system does not ship are declared here with the
   scale it does use: the stack sits above --ns-z-tooltip (500), and the
   dismiss timer is a duration the component owns.

   Layout contract:
     <375px..767px   full-bleed column pinned to the bottom, above thumb reach
     >=768px         bottom-right column, 380px wide

   The host is pointer-events:none so an empty stack never eats a click on the
   page behind it; each toast turns pointer events back on for itself.
   ========================================================================= */

.ns-toast-host {
    --ns-toast-z: 600;
    --ns-toast-width: 380px;

    position: fixed;
    z-index: var(--ns-toast-z);
    inset: auto var(--ns-space-3) var(--ns-space-3) var(--ns-space-3);
    display: flex;
    flex-direction: column;
    gap: var(--ns-space-2);
    pointer-events: none;
    /* iOS safe area: keep the stack clear of the home indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

@media (min-width: 768px) {
    .ns-toast-host {
        inset: auto var(--ns-space-5) var(--ns-space-5) auto;
        width: var(--ns-toast-width);
        max-width: calc(100vw - (var(--ns-space-5) * 2));
    }
}

/* -------------------------------------------------------------------------
   The toast card
   ------------------------------------------------------------------------- */

.ns-toast {
    pointer-events: auto;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: flex-start;
    gap: var(--ns-space-3);
    padding: var(--ns-space-3) var(--ns-space-4);
    background: var(--ns-bg-elevated);
    color: var(--ns-text-primary);
    border: 1px solid var(--ns-border);
    border-left: 3px solid var(--ns-toast-accent, var(--ns-info));
    border-radius: var(--ns-radius-lg);
    box-shadow: var(--ns-shadow-lg);
    font-family: var(--ns-font-sans);
    font-size: 0.9375rem;
    line-height: 1.45;
}

.ns-toast.is-success { --ns-toast-accent: var(--ns-success); }
.ns-toast.is-error   { --ns-toast-accent: var(--ns-error); }
.ns-toast.is-warning { --ns-toast-accent: var(--ns-warning); }
.ns-toast.is-info    { --ns-toast-accent: var(--ns-info); }

.ns-toast-icon {
    flex: 0 0 auto;
    margin-top: 0.125rem;
    color: var(--ns-toast-accent, var(--ns-info));
    font-size: 1rem;
    line-height: 1.45;
}

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

.ns-toast-title {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: var(--ns-font-semibold);
    color: var(--ns-text-primary);
}

.ns-toast-message {
    margin: 0;
    /* Long, unbroken strings (agent ids, URLs, embed snippets) wrap instead of
       widening the card past its column. */
    overflow-wrap: anywhere;
    color: var(--ns-text-primary);
}

/* Hierarchy under a title comes from SIZE and the title's weight, never from
   dimming the message.

   The obvious version of this rule set --ns-text-secondary here, and the 1440
   error shot is what caught it: --ns-text-secondary (#a0a0a0) is calibrated
   against --ns-bg-primary (#1a1a1a), but a toast sits on --ns-bg-elevated
   (#424649), where it measures 3.64:1 — under the 4.5:1 AA floor for body
   text. It put the least readable text in the component on the ERROR message,
   which is exactly backwards. --ns-text-primary on the same surface is
   9.53:1. */
.ns-toast-title + .ns-toast-message {
    margin-top: var(--ns-space-1);
    font-size: 0.875rem;
}

.ns-toast-dismiss {
    flex: 0 0 auto;
    /* 32px hit area at rest; the ::before below grows it to 44px for touch
       without changing how the card lays out. */
    width: 2rem;
    height: 2rem;
    margin: -0.25rem -0.5rem -0.25rem 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: var(--ns-radius-md);
    color: var(--ns-text-muted);
    font-size: 0.875rem;
    cursor: pointer;
    transition: color var(--ns-transition-fast), background var(--ns-transition-fast);
}

.ns-toast-dismiss::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 2.75rem;
    height: 2.75rem;
}

.ns-toast-dismiss:hover,
.ns-toast-dismiss:focus-visible {
    color: var(--ns-text-primary);
    background: var(--ns-bg-tertiary);
}

.ns-toast-dismiss:focus-visible {
    outline: 2px solid var(--ns-toast-accent, var(--ns-accent));
    outline-offset: 1px;
}

/* -------------------------------------------------------------------------
   Time-remaining rail — the visible half of pause-on-hover
   -------------------------------------------------------------------------
   Width is driven from the component's own countdown (inline style), not a CSS
   animation, so "paused" is one shared truth rather than two clocks that can
   disagree. Sticky toasts (timeout 0) render no rail at all.
   ------------------------------------------------------------------------- */

.ns-toast-rail {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    background: var(--ns-toast-accent, var(--ns-info));
    opacity: 0.55;
    transition: width 100ms linear;
}

.ns-toast.is-paused .ns-toast-rail {
    opacity: 0.9;
}

/* -------------------------------------------------------------------------
   Motion
   ------------------------------------------------------------------------- */

.ns-toast-enter {
    animation: ns-toast-in var(--ns-transition-normal) both;
}

.ns-toast-leave {
    animation: ns-toast-out var(--ns-transition-fast) both;
}

@keyframes ns-toast-in {
    from { opacity: 0; transform: translateY(0.5rem) scale(0.98); }
    to   { opacity: 1; transform: none; }
}

@keyframes ns-toast-out {
    from { opacity: 1; transform: none; }
    to   { opacity: 0; transform: translateY(0.25rem) scale(0.98); }
}

@media (prefers-reduced-motion: reduce) {
    .ns-toast-enter,
    .ns-toast-leave {
        animation: none;
    }

    .ns-toast-rail {
        transition: none;
    }
}

/* Forced-colours (Windows high contrast): the accent border is the only thing
   separating success from error, and system colours drop custom properties. */
@media (forced-colors: active) {
    .ns-toast {
        border: 1px solid CanvasText;
        border-left-width: 3px;
    }
}
