/* СЛОЙ 6 — УВЕДОМЛЕНИЯ И ОТМЕНА ДЕЙСТВИЙ.
   Отдельным файлом, чтобы работа над тостами не сходилась с работой над
   компонентами в одном месте. Грузится после компонентов, но до слоя
   доступности: кольцо фокуса обязано выигрывать и здесь. */

/* ---------- стопка ----------------------------------------------------------
   Селекторы намеренно идут через #toasts: в слое компонентов остались прежние
   правила .toast, и одного класса не хватило бы, чтобы их перекрыть. */
#toasts {
  position: fixed; right: 16px; bottom: 16px; z-index: 70;
  display: grid; gap: 10px; justify-items: end;
  width: min(400px, calc(100vw - 32px));
  /* Сама стопка кликов не ловит — сквозь просветы между тостами страница
     остаётся рабочей. Ловит их каждый тост, см. ниже. */
  pointer-events: none;
}

/* ---------- один тост -------------------------------------------------------
   Ряды оттенков из токенов: заливка --*-bg, рамка --*-line, иконка --*-base.
   Тип задаётся классом, а цвета приезжают в три переменные — правило рисунка
   одно на все четыре типа. */
#toasts .toast {
  --tone-bg: var(--cyan-bg);
  --tone-line: var(--cyan-line);
  --tone: var(--cyan-base);
  --toast-life: 4.5s;

  pointer-events: auto;
  position: relative; overflow: hidden;
  box-sizing: border-box; width: 100%; max-width: 100%;
  display: grid; align-items: center; gap: 4px 10px;
  grid-template-columns: auto minmax(0, 1fr) auto;
  padding: 12px 12px 14px;
  background: var(--tone-bg);
  border: 1px solid var(--tone-line);
  border-left-width: 3px;
  border-radius: var(--r-card);
  box-shadow: var(--elev-2);
  color: var(--txt); font-size: var(--t-sm); line-height: 1.45;
  animation: toast-in .22s cubic-bezier(.2, .8, .3, 1) both;
}

#toasts .toast.ok {
  --tone-bg: var(--green-bg); --tone-line: var(--green-line);
  --tone: var(--green-base);
}
#toasts .toast.err {
  --tone-bg: var(--red-bg); --tone-line: var(--red-line);
  --tone: var(--red-base);
}
#toasts .toast.warn {
  --tone-bg: var(--amber-bg); --tone-line: var(--amber-line);
  --tone: var(--amber-base);
}
#toasts .toast.info {
  --tone-bg: var(--cyan-bg); --tone-line: var(--cyan-line);
  --tone: var(--cyan-base);
}

.toast-ic { width: 18px; height: 18px; color: var(--tone); align-self: start; }
.toast-text { margin: 0; overflow-wrap: anywhere; }

/* Крестик — квадрат 28×28: у мыши цель мелкая, но соседство с «Вернуть»
   важнее, а закрыть тост можно и не закрывая — он уйдёт сам. */
.toast-x {
  width: 28px; height: 28px; padding: 0; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--r-xs);
  color: var(--muted); cursor: pointer;
}
.toast-x .ic { width: 14px; height: 14px; }
.toast-x:hover { color: var(--txt); background: rgba(148, 163, 184, .12); }

/* ---------- действие внутри тоста -------------------------------------------
   Это настоящая форма с методом POST и токеном: отмена по GET выполнялась бы
   чужой картинкой в письме. Строка отдана ей целиком — на узком экране кнопка
   «Вернуть» не должна тесниться с текстом. */
.toast-act { grid-column: 2 / -1; justify-self: start; margin-top: 2px; }
.toast-act .btn {
  background: var(--surface-2); border-color: var(--tone-line); color: var(--txt);
}
.toast-act .btn:hover { background: var(--surface-3); border-color: var(--tone); }
.toast-act .btn .ic { color: var(--tone); }

/* Отсчёт цифрами, а не только полосой: полоса показывает «скоро», а сколько
   именно осталось — вопрос, на который отвечает число. Моноширинный, иначе
   кнопка дёргается на каждой смене цифры. */
.toast-count {
  font-family: var(--mono); font-size: var(--t-xs);
  color: var(--muted); font-variant-numeric: tabular-nums;
  min-width: 2.2em; text-align: right;
}

/* ---------- полоса жизни ----------------------------------------------------
   Длительность берётся из --toast-life, её же читает app.js: одно значение
   на анимацию и на таймер, разъехаться нечему. Пауза при наведении сделана
   правилом CSS, а не классом от JS: у мыши и у клавиатуры одна причина —
   тост читают, и уходить он не должен. */
.toast-life {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--tone); opacity: .5;
  transform-origin: left center;
  animation: toast-life var(--toast-life) linear forwards;
}
#toasts .toast:hover .toast-life,
#toasts .toast:focus-within .toast-life { animation-play-state: paused; }

/* Окно отмены — десять секунд: меньше не хватает, чтобы прочитать, что
   произошло, и решить. Число живёт здесь, а не в JavaScript. */
#toasts .toast.is-undo { --toast-life: 10s; }

/* ---------- появление и уход ------------------------------------------------ */
@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateY(6px) scale(.98); }
}
@keyframes toast-life {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}
#toasts .toast.is-leaving {
  animation: toast-out .2s ease forwards;
  pointer-events: none;
}

/* ---------- узкий экран -----------------------------------------------------
   Кнопке «Вернуть» 44px по высоте даёт правило .btn из слоя экранов, а вот
   крестик кнопкой .btn не притворяется — норму под палец (WCAG 2.5.5) ему
   ставим здесь сами. */
@media (max-width: 900px) {
  /* Нижняя навигация занимает 64px плюс safe area. Тосты должны стоять над
     ней, иначе сообщение после действия на несколько секунд перекрывает все
     основные переходы и перехватывает нажатия. */
  #toasts { bottom: calc(76px + env(safe-area-inset-bottom)); }
}

@media (max-width: 520px) {
  #toasts { left: 12px; right: 12px; width: auto; }
  .toast-x { width: 44px; height: 44px; }
}

/* ---------- уважение к prefers-reduced-motion -------------------------------
   Слой доступности глушит длительность анимаций у всего подряд, и полоса
   жизни схлопнулась бы мгновенно — тост выглядел бы уходящим, оставаясь на
   месте. Врать не будем: полосы просто нет, отсчёт остаётся цифрами. */
@media (prefers-reduced-motion: reduce) {
  .toast-life { display: none; }
}

/* ---------- отмена действия в карточке --------------------------------------
   Тост живёт секунды, а вернуть действие бывает нужно и позже — поэтому та же
   отмена стоит рядом с журналом. Кнопки нет вовсе, когда отменять нечего:
   неактивная кнопка обещает возможность, которой нет. */
.undo-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 14px 0 4px; padding: 10px 12px;
  background: var(--amber-bg); border: 1px solid var(--amber-line);
  border-left-width: 3px; border-radius: var(--r-ctl);
  font-size: var(--t-sm);
}
.undo-bar > .ic { width: 16px; height: 16px; color: var(--amber-base); }
.undo-what { color: var(--muted); margin-right: auto; }
.undo-what b { color: var(--txt); font-weight: 600; }
.undo-when { color: var(--muted); font-family: var(--mono); font-size: var(--t-xs); }
.undo-bar form { margin: 0; }
