﻿/* motion.css — анимации форума (без layout-shift, 2026-10-16) */

:root {
  --motion-micro: 120ms;
  --motion-fast: 180ms;
  --motion-base: 220ms;
  --motion-route: 220ms;
  --motion-ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
  --motion-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --motion-ease-decel: cubic-bezier(0, 0, 0.2, 1);
  --motion-ease-accel: cubic-bezier(0.4, 0, 1, 1);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-micro: 0ms;
    --motion-fast: 0ms;
    --motion-base: 0ms;
    --motion-route: 0ms;
  }
}

#view {
  view-transition-name: forum-view;
  transition: opacity var(--motion-base) var(--motion-ease-emphasized);
}

#view.is-leaving {
  opacity: 0;
}

#view.is-entering {
  animation: fr-view-enter var(--motion-base) var(--motion-ease-emphasized) both;
}

@keyframes fr-view-enter {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Поверхности, вход (видимый финальный state; ≤ 5 элементов по спискам). */
.fr-fade-in,
.forum-card, .conversation-item, .chat-message,
.pf-card, .pf-side-card, .pf-person, .pf-act-row,
.board-card, .sv-card, .topic-row,
.hero, .pf-hero, .section-header, .chat-header,
.profile-empty, .msg-menu-item, .peer-menu-item,
.notif-panel, .ui-select, .ui-date,
.auth-modal, .gs-modal, .msg-modal,
.bd-modal, .sv-modal, .th-modal, .mod-modal,
.crop-modal, .card {
  animation: fr-surface-in var(--motion-micro) var(--motion-ease-decel) both;
}

@keyframes fr-surface-in {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Stagger utility, applied by JS только там, где нужен. */
.motion-stagger-1 { animation-delay: 40ms; }
.motion-stagger-2 { animation-delay: 80ms; }
.motion-stagger-3 { animation-delay: 120ms; }
.motion-stagger-4 { animation-delay: 160ms; }
.motion-stagger-5 { animation-delay: 200ms; }

/* Модалки и оверлеи. */
.auth-modal-backdrop,
.msg-modal-backdrop,
.gs-modal-backdrop,
.sv-modal-backdrop,
.bd-modal-backdrop,
.th-modal-backdrop,
.mod-backdrop,
.crop-backdrop,
.th-modal-backdrop {
  animation: fr-backdrop-in var(--motion-fast) var(--motion-ease-standard) both;
}

@keyframes fr-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.auth-modal-backdrop.is-leaving,
.mod-backdrop.is-leaving,
.crop-backdrop.is-leaving,
.gs-modal-backdrop.is-leaving,
.msg-modal-backdrop.is-leaving,
.sv-modal-backdrop.is-leaving,
.bd-modal-backdrop.is-leaving,
.th-modal-backdrop.is-leaving {
  animation: fr-backdrop-out var(--motion-micro) var(--motion-ease-accel) both;
}

@keyframes fr-backdrop-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

.auth-modal,
.gs-modal,
.msg-modal,
.bd-modal,
.sv-modal,
.th-modal,
.mod-modal,
.crop-modal {
  animation: fr-modal-in var(--motion-fast) var(--motion-ease-decel) both;
  transform-origin: center;
}

@keyframes fr-modal-in {
  from { opacity: 0; transform: scale(0.97); }
  to { opacity: 1; transform: scale(1); }
}

.auth-modal.is-leaving,
.gs-modal.is-leaving,
.msg-modal.is-leaving,
.bd-modal.is-leaving,
.sv-modal.is-leaving,
.th-modal.is-leaving,
.mod-modal.is-leaving,
.crop-modal.is-leaving {
  animation: fr-modal-out var(--motion-micro) var(--motion-ease-accel) both;
}

@keyframes fr-modal-out {
  from { opacity: 1; transform: scale(1); }
  to { opacity: 0; transform: scale(0.97); }
}

/* Всплывания (auth profile, context menu, chat menus, notif). */
.auth-menu,
.peer-menu,
.msg-menu,
.dropdown,
.popover,
.tooltip,
.notif-panel {
  animation: fr-popup-in var(--motion-micro) var(--motion-ease-decel) both;
  transform-origin: top center;
}

@keyframes fr-popup-in {
  from { opacity: 0; transform: scaleY(0.96) translateY(-2px); }
  to { opacity: 1; transform: scaleY(1) translateY(0); }
}

/* Toast. */
.toast-wrap {
  pointer-events: none;
}

.toast {
  animation: fr-toast-in var(--motion-fast) var(--motion-ease-decel) both;
}

.toast.is-leaving {
  animation: fr-toast-out var(--motion-fast) var(--motion-ease-accel) both;
}

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

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

@keyframes fr-badge-bump {
  from { transform: scale(1); }
  50% { transform: scale(1.18); }
  to { transform: scale(1); }
}

.badge {
  animation: fr-badge-bump var(--motion-fast) var(--motion-ease-emphasized) both;
}

.skeleton {
  animation: fr-skeleton-pulse 1.2s var(--motion-ease-standard) infinite alternate;
}

.server-card-skeleton {
  display: grid;
  gap: 10px;
}

.server-skeleton-label,
.server-skeleton-name,
.server-skeleton-row i {
  display: block;
  height: 8px;
  border-radius: 4px;
  background: var(--border-light, #3a3f4a);
}

.server-skeleton-label { width: 72px; }
.server-skeleton-name { width: 78%; height: 12px; margin: 3px 0; }

.server-skeleton-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.server-skeleton-row i:first-child { width: 42px; }
.server-skeleton-row i:last-child { width: 58px; }

@keyframes fr-skeleton-pulse {
  from { opacity: 0.35; }
  to { opacity: 0.75; }
}

/* Формы / ошибки. */
.auth-error.is-shake,
.form-shake {
  animation: fr-shake 220ms var(--motion-ease-standard) both;
}

@keyframes fr-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  50% { transform: translateX(3px); }
  75% { transform: translateX(-1px); }
}

/* Капча: смена картинки по opacity. */
.auth-captcha img {
  transition: opacity var(--motion-micro) var(--motion-ease-standard);
  will-change: opacity;
}

.auth-captcha img.is-crossfading {
  opacity: 0;
}

/* Сообщения ЛС. */
.chat-message {
  animation: fr-message-in var(--motion-fast) var(--motion-ease-decel) both;
}

@keyframes fr-message-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.chat-message.is-new {
  animation: fr-new-message var(--motion-fast) var(--motion-ease-decel) both;
}

@keyframes fr-new-message {
  from { opacity: 0; transform: translateY(8px); }
  40% { opacity: 0.95; }
  to { opacity: 1; transform: translateY(0); }
}

/* Кнопки и поля. */
button, .button {
  transition: background var(--motion-micro) var(--motion-ease-standard),
              border-color var(--motion-micro) var(--motion-ease-standard),
              color var(--motion-micro) var(--motion-ease-standard),
              transform var(--motion-micro) var(--motion-ease-standard);
}

button:active, .button:active {
  transform: scale(0.98);
}

input, textarea, select {
  transition: border-color var(--motion-micro) var(--motion-ease-standard),
              box-shadow var(--motion-micro) var(--motion-ease-standard),
              background var(--motion-micro) var(--motion-ease-standard);
}

input:focus, textarea:focus, select:focus {
  border-color: var(--accent, #D6332E);
}

/* Переход затрагивает только содержимое страницы; оболочка остаётся статичной. */
::view-transition-old(forum-view) {
  animation: fr-root-out var(--motion-route) var(--motion-ease-accel) both;
}

::view-transition-new(forum-view) {
  animation: fr-root-in var(--motion-route) var(--motion-ease-decel) both;
}

@keyframes fr-root-out {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-2px); }
}

@keyframes fr-root-in {
  from { opacity: 0; transform: translateY(2px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Небольшой stagger только для первых пяти элементов видимых списков. */
#view .forum-grid > .forum-card:nth-child(1),
#view .topic-row:nth-child(1),
#view .sv-card:nth-child(1),
#view .conversation-item:nth-child(1) { animation-delay: 40ms; }

#view .forum-grid > .forum-card:nth-child(2),
#view .topic-row:nth-child(2),
#view .sv-card:nth-child(2),
#view .conversation-item:nth-child(2) { animation-delay: 80ms; }

#view .forum-grid > .forum-card:nth-child(3),
#view .topic-row:nth-child(3),
#view .sv-card:nth-child(3),
#view .conversation-item:nth-child(3) { animation-delay: 120ms; }

#view .forum-grid > .forum-card:nth-child(4),
#view .topic-row:nth-child(4),
#view .sv-card:nth-child(4),
#view .conversation-item:nth-child(4) { animation-delay: 160ms; }

#view .forum-grid > .forum-card:nth-child(5),
#view .topic-row:nth-child(5),
#view .sv-card:nth-child(5),
#view .conversation-item:nth-child(5) { animation-delay: 200ms; }

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  #view .forum-card,
  #view .topic-row,
  #view .sv-card {
    transition: background var(--motion-micro) var(--motion-ease-standard),
                translate var(--motion-micro) var(--motion-ease-standard);
  }

  #view .forum-card:hover,
  #view .forum-card:focus-visible,
  #view .topic-row:hover,
  #view .topic-row:focus-visible,
  #view .sv-card:hover {
    translate: 0 -1px;
  }

  .forum-icon,
  .topic-icon {
    transition: transform var(--motion-fast) var(--motion-ease-standard);
  }

  .forum-card:hover .forum-icon,
  .forum-card:focus-visible .forum-icon,
  .topic-row:hover .topic-icon,
  .topic-row:focus-visible .topic-icon {
    transform: scale(1.05);
  }
}

@media (prefers-reduced-motion: reduce) {
  .fr-fade-in, .auth-error.is-shake, .form-shake, .auth-captcha img,
  #view, #view.is-entering, #view.is-leaving,
  .auth-modal-backdrop, .msg-modal-backdrop, .gs-modal-backdrop,
  .sv-modal-backdrop, .bd-modal-backdrop, .th-modal-backdrop,
  .mod-backdrop, .crop-backdrop,
  .forum-card, .forum-icon, .topic-icon, .topic-row, .sv-card, .conversation-item, .chat-message,
  .pf-card, .pf-side-card, .pf-person, .pf-act-row,
  .board-card, .sv-card, .topic-row,
  .hero, .pf-hero, .section-header, .chat-header,
  .profile-empty, .msg-menu-item, .peer-menu-item,
  .notif-panel, .ui-select, .ui-date,
  .auth-modal, .gs-modal, .msg-modal, .bd-modal, .sv-modal,
  .th-modal, .mod-modal, .crop-modal, .card,
  .auth-menu, .peer-menu, .msg-menu, .dropdown, .popover, .tooltip,
  .toast, .badge, .skeleton, button, .button, input, textarea, select {
    transition: none !important;
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    translate: none !important;
  }

  .server-skeleton-label,
  .server-skeleton-name,
  .server-skeleton-row i {
    opacity: 0.55 !important;
  }

  ::view-transition-old(forum-view),
  ::view-transition-new(forum-view) {
    animation: none !important;
  }
}
