/* ============================================================================
   motion.css · SSOT языка движения (обе темы) — СКОПИРОВАН из motion-слоя
   канонического мокапа docs/mockups/cloud/F.html (ФАЗА 6 · motion.css).
   Инварианты: анимируются ТОЛЬКО transform/opacity; длительности — именованные
   токены ∈ [150…400]мс; единственный язык появления/исчезновения — sticker-transition;
   prefers-reduced-motion + зеркальный :root.rm обездвиживают всё; attention ≤2 импульса.
   ============================================================================ */

/* §1 — Токены движения (дублируют tokens.css; имена из мокапа) */
:root {
  --mot-dur-1: 160ms; /* fast — нажатие / тогл / «+1» */
  --mot-dur-2: 240ms; /* base — sticker-transition экрана / листа, тост */
  --mot-dur-3: 360ms; /* slow — крупный оверлей / диалог */
  --mot-ease-enter: cubic-bezier(0.2, 0.8, 0.25, 1);
  --mot-ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --mot-ease-state: cubic-bezier(0.4, 0, 0.2, 1);
  --mot-slide: 16px;
}

/* §2 — Sticker-transition: ЕДИНСТВЕННЫЙ язык появления/исчезновения */
@keyframes stk-in-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes stk-out-down { from { transform: none; } to { transform: translateY(100%); } }
@keyframes stk-in-right { from { transform: translateX(24px); opacity: 0.001; } to { transform: none; opacity: 1; } }
@keyframes stk-out-left { from { transform: none; opacity: 1; } to { transform: translateX(-24px); opacity: 0.001; } }

.stk-in { animation: stk-in-up var(--mot-dur-2) var(--mot-ease-enter) both; } /* лист/шит/тост снизу */
.stk-sheet { animation: stk-in-up var(--mot-dur-2) var(--mot-ease-enter) both; } /* bottom sheet ↔ диалог */
.stk-in-x { animation: stk-in-right var(--mot-dur-2) var(--mot-ease-enter) both; } /* экран вперёд (роут) */
.stk-out { animation: stk-out-down var(--mot-dur-2) var(--mot-ease-exit) both; }
.stk-out-x { animation: stk-out-left var(--mot-dur-2) var(--mot-ease-exit) both; } /* экран назад (роут) */
.stk-lg.stk-in, .stk-lg.stk-sheet, .stk-lg.stk-in-x { animation-duration: var(--mot-dur-3); }

/* Совместимость: старый алиас .stk-in-up = вход снизу (используется в .card/.overlay). */
.stk-in-up { animation: stk-in-up var(--mot-dur-2) var(--mot-ease-enter) both; }

/* §3 — Дисциплинированные on-place микро-анимации (feedback / waiting / attention) */
.mot-press { transition: transform var(--mot-dur-1) var(--mot-ease-state); }
.mot-press:active { transform: scale(0.97); }

.mot-toggle { transition: transform var(--mot-dur-1) var(--mot-ease-state); }
.is-on .mot-toggle, .mot-toggle.is-on { transform: translateX(var(--mot-slide)); }

@keyframes mot-plusone-pop { 0% { transform: scale(1); } 40% { transform: scale(1.18); } 100% { transform: scale(1); } }
.mot-plusone.bump { animation: mot-plusone-pop var(--mot-dur-1) var(--mot-ease-state); }

@keyframes mot-validate-nudge {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(calc(var(--mot-slide) * -0.4)); }
  75% { transform: translateX(calc(var(--mot-slide) * 0.4)); }
}
.mot-validate.invalid { animation: mot-validate-nudge var(--mot-dur-1) var(--mot-ease-state); }

@keyframes mot-skeleton-shimmer { 0% { opacity: 0.55; } 50% { opacity: 0.95; } 100% { opacity: 0.55; } }
.mot-skeleton { animation: mot-skeleton-shimmer var(--mot-dur-3) var(--mot-ease-state) infinite; }

@keyframes mot-offline-breathe { 0% { opacity: 0.7; } 50% { opacity: 1; } 100% { opacity: 0.7; } }
.mot-offline { animation: mot-offline-breathe var(--mot-dur-3) var(--mot-ease-state) infinite; }

@keyframes mot-attention-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } }
.mot-attention {
  animation: stk-in-right var(--mot-dur-2) var(--mot-ease-enter) both,
    mot-attention-pulse var(--mot-dur-3) var(--mot-ease-state) 2;
}

/* §3b — Амбиент-декор фона (sky-deco/стикеры): drift/twinkle/pulse — атмосфера,
   только transform/opacity, петля; глушится reduced-motion; не протекает в рабочий слой. */
@keyframes drift { to { transform: translateX(118vw); } }
@keyframes twinkle { 0%, 100% { opacity: 0.25; transform: scale(0.8); } 50% { opacity: 0.85; transform: scale(1.15); } }
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 3px rgba(115, 214, 168, 0.3); } 50% { box-shadow: 0 0 0 6px rgba(115, 214, 168, 0.12); } }

/* §4 — reduced-motion (системный) + зеркальный классовый тумблер :root.rm */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
:root.rm * { animation: none !important; transition: none !important; }
