/* Transient top-center banner (DeepSeek Chat toast look): contrast fill, inverted label, slide-in, then hold-and-fade. The fade delay/duration MUST agree with HOLD_MS/FADE_MS in Toast.tsx: the component unmounts at their sum, so a mismatched sheet either cuts the fade or leaves an invisible banner blocking nothing. */ .toast { position: fixed; top: 120px; left: 50%; /* Above the 1000 the image lightbox backdrop uses: a failure reported while a preview is open must stay readable. */ z-index: 1100; /* Purely an announcement: it must never intercept clicks — in particular after the CSS fade finished while a throttled background-tab timer has not yet unmounted the still-hit-testable fixed element. */ pointer-events: none; display: flex; align-items: center; gap: 10px; max-width: min(560px, calc(100vw - 48px)); padding: 12px 16px; border-radius: 14px; background: var(--dsw-alias-button-contrast-fill); color: var(--dsw-alias-label-primary-inverted); font-size: 14px; line-height: 22px; box-shadow: var(--dsw-shadow-lv3); transform: translateX(-50%); animation: dsh-toast-in 160ms ease-out, dsh-toast-fade 1000ms ease 3000ms forwards; } .icon { display: grid; place-items: center; flex: none; color: var(--dsw-alias-state-warn-label); } .text { min-width: 0; } @keyframes dsh-toast-in { from { opacity: 0; transform: translate(-50%, -6px); } to { opacity: 1; transform: translate(-50%, 0); } } @keyframes dsh-toast-fade { to { opacity: 0; } } /* Reduced motion drops the slide-in; the delayed fade (an opacity change, not movement) still ends the banner before the timed unmount. */ @media (prefers-reduced-motion: reduce) { .toast { animation: dsh-toast-fade 1000ms ease 3000ms forwards; } }