/* Движение интерфейса, общее для панели и модулей комментариев.
   Появление блоков новой страницы и рост графиков — в nav.js (appear):
   там же решается, когда страница новая. Здесь — ожидание: кнопка, которая
   ждёт ответа, заготовка ответа ИИ, отклик на нажатие. Цвета — токены
   --t-*, они есть в обоих каркасах. */

:root { --m-ease: cubic-bezier(.23, 1, .32, 1); }

/* --- нажатие -----------------------------------------------------------------
   Кнопка чуть проседает под пальцем и плавно меняет цвет под мышью. :where —
   у кнопки со своим переходом остаётся свой. */
:where(button, .button) {
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease, opacity .15s ease, transform .16s var(--m-ease);
}
@media (prefers-reduced-motion: no-preference) {
  :where(button, .button):active:not(:disabled) { transform: scale(.97); }
}

/* --- кнопка ждёт ответа ------------------------------------------------------
   Кружок рядом с надписью «Ищу…»; у кнопки без надписи — кружок на месте
   текста, ширина та же. Через три секунды рядом идут секунды. */
.ui-spin {
  flex: none; width: 1em; height: 1em; border-radius: 50%; box-sizing: border-box;
  border: 2px solid currentColor; border-right-color: transparent; opacity: .85;
  animation: ui-spin .6s linear infinite;
}
@keyframes ui-spin { to { transform: rotate(360deg); } }
button.is-busy, .button.is-busy { cursor: progress; }
button.is-busy:disabled { opacity: .82; }
.is-quiet { position: relative; }
.is-quiet > .ui-keep { display: inline-flex; align-items: center; gap: inherit; visibility: hidden; }
.is-quiet > .ui-spin { position: absolute; inset: 0; margin: auto; }
.ui-secs {
  font-size: .86em; font-weight: 500; opacity: .7; font-variant-numeric: tabular-nums;
  animation: ui-fade .2s ease-out both;
}
@keyframes ui-fade { from { opacity: 0; } }

/* --- заготовка ответа ИИ -------------------------------------------------------
   Пока модель пишет, на месте ответа — его контур: строки мерцают, точки
   идут. Появляется по кнопке с data-pending (nav.js). */
.ui-think {
  display: grid; gap: 10px; padding: 16px; border-radius: 14px;
  background: hsl(var(--t-surface, var(--t-card))); border: 1px solid hsl(var(--t-border));
  animation: ui-rise .3s var(--m-ease) both;
}
.ui-think[hidden] { display: none; }
.ui-think-h { display: flex; align-items: center; gap: 8px; margin: 0 0 2px; font-size: 13px; font-weight: 600; color: hsl(var(--t-foreground)); }
.ui-think-h small { font-weight: 400; color: hsl(var(--t-muted-foreground)); }
.ui-dots { display: inline-flex; gap: 3px; color: hsl(var(--t-primary)); }
.ui-dots i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; animation: ui-dot 1.1s ease-in-out infinite; }
.ui-dots i:nth-child(2) { animation-delay: .15s; }
.ui-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes ui-dot { 0%, 80%, 100% { opacity: .25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-2px); } }
.ui-line {
  height: 10px; border-radius: 6px; width: var(--w, 100%);
  background: linear-gradient(90deg, hsl(var(--t-muted)) 0%, hsl(var(--t-foreground) / .09) 45%, hsl(var(--t-muted)) 90%);
  background-size: 220% 100%; animation: ui-shimmer 1.5s linear infinite;
}
@keyframes ui-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@keyframes ui-rise { from { opacity: 0; transform: translateY(6px); } }

@media (prefers-reduced-motion: reduce) {
  .ui-spin { animation-duration: 1.4s; }
  .ui-line, .ui-think { animation: none; }
  .ui-dots i { animation: none; opacity: .6; }
}
