/* Timings and curves from Telegram Web's Transition and Message CSS. */
@keyframes fade-in {
  from { opacity: 0; }
}

@keyframes fade-out {
  to { opacity: 0; }
}

@keyframes menu-in {
  from { opacity: 0; transform: scale(0.85); }
}

@keyframes menu-out {
  to { opacity: 0; transform: scale(0.85); }
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(-1rem); }
}

@keyframes modal-backdrop-in {
  from { background-color: rgb(0 0 0 / 0%); }
}

@keyframes ripple-animation {
  0% { opacity: 1; transform: scale(0); }
  50% { opacity: 1; }
  100% { opacity: 0; transform: scale(2); }
}

@keyframes live-tail-message-mount {
  from { transform: translateY(2rem); }
}

@keyframes grow-icon {
  0% { opacity: 0.8; transform: scale(0.5); }
  50% { opacity: 1; transform: scale(1.1); }
  100% { transform: scale(1); }
}

@keyframes slide-fade-in-move {
  from { opacity: 0; transform: translateX(1.5rem); }
}

@keyframes slide-fade-in-backwards-move {
  from { opacity: 0; transform: translateX(-1.5rem); }
}

@keyframes slide-fade-out-move {
  to { opacity: 0; transform: translateX(-1.5rem); }
}

@keyframes slide-fade-out-backwards-move {
  to { opacity: 0; transform: translateX(1.5rem); }
}

@keyframes slide-in-right {
  from { transform: translateX(100%); }
}

@keyframes slide-out-right {
  to { transform: translateX(100%); }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(0.5rem); }
}

@keyframes rise-out {
  to { opacity: 0; transform: translateY(0.5rem); }
}

@keyframes message-out {
  to { opacity: 0; transform: scale(0.8); }
}

@keyframes quote-flash {
  0%, 60% { background-color: rgb(var(--color-primary-rgb) / 35%); }
}

@keyframes pop {
  0% { transform: scale(0.4); }
  60% { transform: scale(1.15); }
  100% { transform: scale(1); }
}

@keyframes skeleton-wave {
  0% { transform: translateX(-100%); }
  50%, 100% { transform: translateX(100%); }
}

@keyframes dot-bounce {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-2px); }
}

@keyframes spoiler-drift {
  to { background-position: 128px 64px; }
}

@keyframes record-pulse {
  50% { opacity: 0.4; }
}

/* Touch feedback */
/* The wave needs a positioned host; motion.js makes a static host relative, and leaves absolute ones (the pencil button) where they are. */
.ripple-host {
  overflow: hidden;
}

.ripple {
  position: absolute;
  border-radius: 50%;
  background: rgb(0 0 0 / 8%);
  pointer-events: none;
  animation: ripple-animation 0.7s;
}

:root[data-theme="dark"] .ripple,
.chat-item.active .ripple,
.send .ripple,
.fab .ripple {
  background: rgb(255 255 255 / 8%);
}

/* What appears */
.bubble.entering {
  animation: live-tail-message-mount 0.2s ease-out;
}

.bubble.highlight {
  outline: 0;
  animation: quote-flash 1.5s ease-out;
}

.menu:not([hidden]):not(.ghost) {
  animation: menu-in 0.2s cubic-bezier(0.2, 0, 0.2, 1);
  transform-origin: top left;
}

.context-menu:not([hidden]):not(.ghost) {
  animation: menu-in 0.2s cubic-bezier(0.2, 0, 0.2, 1);
}

.modal-backdrop:not(.ghost) {
  animation: modal-backdrop-in 0.2s;
}

.modal-backdrop:not(.ghost) > .modal {
  animation: modal-in 0.2s, fade-in 0.2s;
}

.toast:not([hidden]) {
  animation: rise-in 0.2s ease-out;
}

#send:not([hidden]),
#record:not([hidden]) {
  animation: grow-icon 0.2s ease-out;
}

.fab {
  animation: none;
}

#to-latest:not([hidden]) {
  animation: rise-in 0.2s ease-out;
}

.to-latest-badge:not([hidden]),
.badge.pop {
  animation: pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.reaction {
  animation: pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.compose-bar:not([hidden]),
.pinned-bar:not([hidden]),
.chat-search:not([hidden]),
.player-bar:not([hidden]),
.tag-bar:not([hidden]),
.format-bar:not([hidden]) {
  animation: rise-in 0.15s ease-out;
}

.emoji-panel:not([hidden]):not(.ghost) {
  animation: rise-in 0.2s cubic-bezier(0.2, 0, 0.2, 1);
}

#conversation.chat-enter #messages {
  animation: slide-fade-in-move var(--slide-transition);
}

#conversation.chat-enter .peer-text {
  animation: fade-in 0.2s;
}

#chat-list.slide-forward {
  animation: slide-fade-in-move var(--slide-transition);
}

#chat-list.slide-backward {
  animation: slide-fade-in-backwards-move var(--slide-transition);
}

.settings:not([hidden]):not(.ghost) {
  animation: slide-fade-in-move var(--slide-transition);
}

.settings-page.page-in-forward {
  animation: slide-fade-in-move var(--slide-transition);
}

.settings-page.page-in-backward {
  animation: slide-fade-in-backwards-move var(--slide-transition);
}

#right:not([hidden]) {
  animation: slide-in-right var(--layer-transition);
}

.lightbox:not([hidden]) {
  animation: fade-in 0.2s;
}

.skeleton-bubble::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 18%), transparent);
  animation: skeleton-wave 1.6s infinite;
}

.typing-dots i {
  animation: dot-bounce 1.2s infinite;
}

.typing-dots i:nth-child(2) {
  animation-delay: 0.15s;
}

.typing-dots i:nth-child(3) {
  animation-delay: 0.3s;
}

.bubble:not(.spoilers-revealed) .spoiler {
  animation: spoiler-drift 6s linear infinite;
}

.recording-dot {
  animation: record-pulse 1.2s infinite;
}

.bubble.pending .ticks {
  animation: fade-in 0.4s;
}

/* What leaves: copies made by ghost() in motion.js */
.ghost {
  pointer-events: none;
  animation-fill-mode: forwards !important;
}

.ghost.menu-out {
  animation: menu-out 0.15s ease-in forwards;
  transform-origin: top left;
}

.ghost.modal-out {
  position: fixed !important;
  animation: fade-out 0.15s forwards;
}

.ghost.fade-out {
  animation: fade-out 0.2s forwards;
}

.ghost.panel-out {
  animation: rise-out 0.15s forwards;
}

.ghost.right-out {
  animation: slide-out-right var(--layer-transition) forwards;
}

.ghost.message-out {
  animation: message-out 0.2s ease-in forwards;
}

.ghost.page-out-forward {
  animation: slide-fade-out-move var(--slide-transition) forwards;
}

.ghost.page-out-backward {
  animation: slide-fade-out-backwards-move var(--slide-transition) forwards;
}

/* Switches from Animations and Performance */
.no-page-transitions #conversation.chat-enter #messages,
.no-page-transitions #conversation.chat-enter .peer-text,
.no-page-transitions #chat-list,
.no-page-transitions .settings,
.no-page-transitions .settings-page,
.no-page-transitions .lightbox {
  animation: none !important;
}

.no-message-animations .bubble.entering,
.no-message-animations .reaction,
.no-message-animations .badge.pop {
  animation: none !important;
}

.no-menu-animations .menu,
.no-menu-animations .context-menu,
.no-menu-animations .modal,
.no-menu-animations .modal-backdrop,
.no-menu-animations .emoji-panel {
  animation: none !important;
}

.no-right-column-animations #right,
.no-right-column-animations #messages,
.no-right-column-animations .top-stack,
.no-right-column-animations .composer-wrap {
  animation: none !important;
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
  }
}

/* The circular theme switch does its own animation. */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-new(root) {
  z-index: 2;
}
