/* Уведомления сайта.

   Раньше это были бутстраповские .toast с .bg-dark и .toast-header.bg-{тип}: собственных
   цветов у них не было, и в светлой теме тёмный текст ложился на тёмную подложку. Здесь
   всё нарисовано своими токенами, поэтому оформление меняется вместе с темой само —
   контейнер живёт внутри <body>, на котором и стоит класс темы.

   Стопка собирается в toast.js: он раскладывает карточки трансформами и передаёт сюда
   --tb-y / --tb-scale / --tb-opacity. Всё, что двигается, двигается только transform и
   opacity — иначе десяток уведомлений подряд перекладывал бы страницу. */

.tb-toasts {
    position: fixed;
    top: var(--tearinbot-space-4);
    right: var(--tearinbot-space-4);
    width: min(23rem, calc(100vw - 2 * var(--tearinbot-space-4)));
    z-index: var(--tearinbot-zIndices-toast);

    /* Куда растёт стопка и откуда приходит новая карточка. Знак читает toast.js: сама
       раскладка считается там, а направление — вопрос места на экране, то есть css. */
    --tb-dir: 1;
    --tb-enter: -0.75rem;

    /* Свёрнутая стопка занимает угол экрана, но кликам под собой мешать не должна:
       события ловят сами карточки. Развёрнутая — наоборот, ловит всё, иначе зазор
       между карточками считался бы уходом курсора и стопка схлопывалась бы. */
    pointer-events: none;
}

.tb-toasts.is-expanded {
    pointer-events: auto;
}

.tb-toast {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    box-sizing: border-box;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start;
    gap: var(--tearinbot-space-3);
    padding: var(--tearinbot-space-3-5) var(--tearinbot-space-3-5) var(--tearinbot-space-3-5) var(--tearinbot-space-4);
    overflow: hidden;
    border-radius: var(--tearinbot-radii-lg);
    border: 1px solid var(--border-color);
    background-color: var(--nav-surface-raised);
    color: var(--tearinbot-colors-textPrimary);
    box-shadow: var(--tearinbot-shadows-lg);
    pointer-events: auto;

    /* Начало координат сверху: стопка растёт вниз от самой свежей карточки, и уменьшенные
       соседи должны выглядывать снизу, а не разъезжаться в обе стороны. */
    transform-origin: top center;
    transform: translate3d(0, var(--tb-y, 0), 0) scale(var(--tb-scale, 1));
    opacity: var(--tb-opacity, 1);
    transition: transform var(--tearinbot-transition-duration-slow) var(--tearinbot-transition-easing-ease-out),
    opacity var(--tearinbot-transition-duration-normal) var(--tearinbot-transition-easing-ease-out),
    height var(--tearinbot-transition-duration-slow) var(--tearinbot-transition-easing-ease-out);
    will-change: transform, opacity;
}

/* Полоса слева — единственное, что отличает типы по цвету. Заливать ею всю карточку
   нельзя: в тёмной теме цветной фон под белым текстом выбивается из всего остального. */
.tb-toast::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background-color: var(--tb-toast-accent);
}

.tb-toast--enter {
    --tb-opacity: 0;

    transform: translate3d(0, var(--tb-enter), 0) scale(0.96);
}

.tb-toast--leave {
    --tb-opacity: 0;

    transform: translate3d(0, var(--tb-y, 0), 0) scale(0.92);
}

/* ————— Цвета по типу ————— */

.tb-toast {
    --tb-toast-accent: var(--tearinbot-colors-textLink);
}

.tb-toast[data-kind="success"] {
    --tb-toast-accent: var(--tearinbot-colors-success);
}

.tb-toast[data-kind="danger"] {
    --tb-toast-accent: var(--tearinbot-colors-negative);
}

.tb-toast[data-kind="warning"] {
    --tb-toast-accent: var(--tearinbot-colors-intermediate);
}

/* ————— Значок ————— */

.tb-toast-icon {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: var(--tearinbot-sizes-8);
    height: var(--tearinbot-sizes-8);
    border-radius: var(--tearinbot-radii-md);
    color: var(--tb-toast-accent);
}

/* Подложка значка — тот же акцент, приглушённый прозрачностью. Отдельным слоем, потому
   что цвет приходит переменной, и подмешать к нему альфу прямо в background нечем. */
.tb-toast-icon::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-color: currentColor;
    opacity: 0.14;
}

.tb-toast-icon svg {
    position: relative;
    width: 1.125rem;
    height: 1.125rem;
    fill: currentColor;
}

/* ————— Текст ————— */

.tb-toast-body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--tearinbot-space-0-5);
    padding-top: var(--tearinbot-space-0-5);
}

.tb-toast-title {
    display: flex;
    align-items: center;
    gap: var(--tearinbot-space-2);
    margin: 0;
    font-size: var(--tearinbot-fontSizes-sm);
    font-weight: 600;
    line-height: 1.3;
    color: var(--tearinbot-colors-textPrimary);
}

.tb-toast-text {
    margin: 0;
    font-size: var(--tearinbot-fontSizes-sm);
    line-height: 1.45;
    color: var(--tearinbot-colors-textSecondary);

    /* Длинные ошибки плеера приходят одной строкой без пробелов — без переноса
       такая строка растянула бы карточку за край экрана. */
    overflow-wrap: anywhere;
}

/* Сколько раз повторилось одно и то же сообщение. Повтор не плодит новую карточку —
   именно так десяток одинаковых ошибок подряд и заваливал весь экран. */
.tb-toast-count {
    flex: none;
    padding: 0 var(--tearinbot-space-1-5);
    border-radius: var(--tearinbot-radii-full);
    background-color: var(--commands-bg);
    color: var(--tearinbot-colors-textSecondary);
    font-size: var(--tearinbot-fontSizes-xs);
    font-weight: 600;
    line-height: 1.4;
}

/* ————— Кнопка закрытия ————— */

.tb-toast-close {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tearinbot-sizes-6);
    height: var(--tearinbot-sizes-6);
    padding: 0;
    border: none;
    border-radius: var(--tearinbot-radii-md);
    background-color: transparent;
    color: var(--tearinbot-colors-textTertiary);
    cursor: pointer;
    transition: background-color var(--tearinbot-transition-duration-fast) var(--tearinbot-transition-easing-ease-out),
    color var(--tearinbot-transition-duration-fast) var(--tearinbot-transition-easing-ease-out);
}

.tb-toast-close:hover {
    background-color: var(--hover);
    color: var(--tearinbot-colors-textPrimary);
}

.tb-toast-close svg {
    width: 0.75rem;
    height: 0.75rem;
    fill: currentColor;
}

/* ————— Остаток жизни ————— */

.tb-toast-life {
    position: absolute;
    inset: auto 0 0 0;
    height: 2px;
    background-color: var(--tb-toast-accent);
    opacity: 0.45;
    transform-origin: left center;
    animation: tb-toast-life var(--tb-toast-life-ms, 7000ms) linear forwards;
}

/* Пока курсор на стопке, отсчёт стоит: читать уведомление и смотреть, как оно исчезает
   из-под курсора, — худшее, что может сделать эта штука. Таймер в toast.js
   останавливается там же. */
.tb-toasts.is-expanded .tb-toast-life {
    animation-play-state: paused;
}

/* В свёрнутой стопке от нижних карточек видно только край — и полоса остатка читается
   там как цветная черта чужого цвета под верхней карточкой. Показываем только у той,
   которую и правда видно целиком. */
.tb-toasts:not(.is-expanded) .tb-toast[data-front="false"] .tb-toast-life {
    opacity: 0;
}

@keyframes tb-toast-life {
    from {
        transform: scaleX(1);
    }
    to {
        transform: scaleX(0);
    }
}

/* ————— Убрать все ————— */

.tb-toasts-clear {
    position: absolute;
    top: 0;
    right: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--tearinbot-space-1-5);
    padding: var(--tearinbot-space-1) var(--tearinbot-space-3);
    border: 1px solid var(--border-color);
    border-radius: var(--tearinbot-radii-full);
    background-color: var(--nav-surface-raised);
    color: var(--tearinbot-colors-textSecondary);
    font-size: var(--tearinbot-fontSizes-xs);
    font-weight: 600;
    box-shadow: var(--tearinbot-shadows-md);
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transform: translate3d(0, var(--tb-y, 0), 0);
    transition: transform var(--tearinbot-transition-duration-slow) var(--tearinbot-transition-easing-ease-out),
    opacity var(--tearinbot-transition-duration-normal) var(--tearinbot-transition-easing-ease-out);
}

.tb-toasts.is-expanded .tb-toasts-clear[data-visible="true"] {
    opacity: 1;
    pointer-events: auto;
}

.tb-toasts-clear:hover {
    color: var(--tearinbot-colors-textPrimary);
    background-color: var(--hover);
}

.tb-toasts-clear svg {
    width: 0.625rem;
    height: 0.625rem;
    fill: currentColor;
}

/* ————— Узкий экран ————— */

/* На узком экране стопка переезжает вниз — там до неё дотягивается большой палец, и она
   не закрывает шапку. Расти вниз ей оттуда некуда, поэтому и порядок, и точка отсчёта
   карточек переворачиваются: свежая прижата к нижнему краю, прежние выглядывают над ней. */
@media (max-width: 30em) {
    .tb-toasts {
        --tb-dir: -1;
        --tb-enter: 0.75rem;

        top: auto;

        /* --tb-inset считает toast.js: столько нижней части окна закрыто панелями
           браузера. env(...) добавляет вырез под кнопку «домой» на телефонах, где он
           есть. Оба нулевые на настольном экране. */
        bottom: calc(var(--tb-inset, 0px) + max(var(--tearinbot-space-3), env(safe-area-inset-bottom, 0px)));
        left: var(--tearinbot-space-3);
        right: var(--tearinbot-space-3);
        width: auto;
    }

    .tb-toast,
    .tb-toasts-clear {
        top: auto;
        bottom: 0;
    }

    .tb-toast {
        transform-origin: bottom center;
    }
}

@media (prefers-reduced-motion: reduce) {
    .tb-toast,
    .tb-toasts-clear {
        transition-duration: 1ms;
    }

    .tb-toast-life {
        animation: none;
        transform: scaleX(1);
    }
}
