/* ==========================================================================
   Launching a task — the card that gets drawn into the Задачи icon.

   The point is legibility, not decoration: starting a module used to change a toggle
   somewhere on the right of the screen while the thing that now tracks it lives in the
   sidebar. The animation is the sentence "this became a task over there", and it is the
   only place in the panel that moves anything across the viewport.

   Deliberately no rotation anywhere. The card keeps its horizontal orientation the
   whole way; the effect is motion, symmetric narrowing and a clip-path that pinches to
   a circle. A tumbling or swirling card reads as a toy — this has to read as the
   system filing something.
   ========================================================================== */

/* --- the target: a circle around the Задачи icon to collapse into --- */
.task-vortex {
  position: relative;
  display: inline-grid;
  place-items: center;
  /* The same box as a plain nav icon (.icon is 1.15rem). At 1.75rem this one element
     made the Задачи row half a rem taller than every other item in the sidebar — the
     highlight is drawn around the row, so the pill grew with it — and took that width
     from the label beside it. The rings are on ::before/::after with a negative inset,
     so they still have room to expand outside this box. */
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 50%;
  flex-shrink: 0;
  transition: transform var(--transition-base) var(--ease), background var(--transition-base) var(--ease);
}
/* Two rings, staggered, drawn on ::before/::after so nothing is added to the DOM per
   launch — repeated launches restart the same animation instead of stacking nodes. */
.task-vortex::before,
.task-vortex::after {
  content: '';
  position: absolute;
  inset: -2px;
  border: 2px solid transparent;
  border-radius: 50%;
  pointer-events: none;
}
.task-vortex.is-absorbing { animation: task-vortex-pulse 780ms cubic-bezier(0.2, 0.85, 0.25, 1); }
.task-vortex.is-absorbing::before { animation: task-vortex-ring 750ms ease-out; }
.task-vortex.is-absorbing::after { animation: task-vortex-ring 750ms 120ms ease-out; }

@keyframes task-vortex-pulse {
  0%, 100% { transform: scale(1); }
  35% { transform: scale(1.18); background: var(--color-primary-bg); }
  68% { transform: scale(0.95); }
  85% { transform: scale(1.04); }
}
@keyframes task-vortex-ring {
  0% { inset: -2px; border-color: color-mix(in srgb, var(--color-primary) 65%, transparent); opacity: 1; }
  100% { inset: -14px; border-color: transparent; opacity: 0; }
}

/* --- the running count, read from /tasks/count --- */
.task-count {
  margin-left: auto;
  min-width: 1.25rem;
  height: 1.25rem;
  line-height: 1;
  padding: 0 0.35rem;
  border-radius: var(--radius-full);
  display: inline-grid;
  place-items: center;
  background: var(--color-accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  flex-shrink: 0;
}
.task-count[hidden] { display: none; }
.task-count.is-bumping { animation: task-count-bump 620ms var(--ease); }
@keyframes task-count-bump {
  0%, 100% { transform: scale(1); }
  35% { transform: scale(1.3); }
  65% { transform: scale(0.94); }
}
/* Collapsed sidebar has no room for a number beside an icon — it becomes a dot on the
   icon itself, which still answers "is anything running". */
html.sidebar-collapsed .sidebar .task-count {
  position: absolute;
  top: 0.3rem;
  right: 0.55rem;
  min-width: 0.55rem;
  width: 0.55rem;
  height: 0.55rem;
  padding: 0;
  font-size: 0;
  margin-left: 0;
}
.nav-link-tasks { position: relative; }

.task-plus {
  position: absolute;
  left: 1.5rem;
  top: -0.25rem;
  opacity: 0;
  padding: 0.1rem 0.35rem;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  pointer-events: none;
  z-index: 2;
}
.task-plus.is-showing { animation: task-plus-pop 1050ms var(--ease) forwards; }
@keyframes task-plus-pop {
  0% { opacity: 0; transform: translateY(4px) scale(0.6); }
  25% { opacity: 1; transform: translateY(0) scale(1.12); }
  65% { opacity: 1; transform: translateY(-6px) scale(1); }
  100% { opacity: 0; transform: translateY(-12px) scale(0.8); }
}

/* --- the flying card --- */
.task-fly {
  position: fixed;
  z-index: 700; /* above the sidebar (45) and topbar (35), below modals (95) */
  width: 16.25rem;
  padding: 0.8rem 0.95rem;
  border-radius: var(--radius-lg);
  /* A gradient and a deep, wide shadow rather than a flat fill: for the second or so
     it is in the air this is the only thing moving on screen, and a flat rectangle
     sliding across the page looks like a bug. The shadow is what sells it as lifted
     off the page rather than drawn on it. */
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-grad-end));
  color: var(--color-on-primary);
  box-shadow: 0 22px 60px color-mix(in srgb, var(--color-primary) 45%, transparent),
              0 2px 6px rgba(0, 0, 0, 0.12);
  pointer-events: none;
  opacity: 0;
  transform-origin: center center;
  will-change: transform, opacity, clip-path;
}

/* Sparks thrown off at the moment of absorption. Eight of them, radiating from the
   icon's centre — the one flourish in the whole effect, and the reason the landing
   reads as an event rather than the card simply running out of opacity. */
.task-spark {
  position: fixed;
  z-index: 699;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-accent);
  pointer-events: none;
  opacity: 0;
}
.task-spark.is-flying { animation: task-spark 820ms ease-out forwards; }
@keyframes task-spark {
  0% { opacity: 0.9; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(var(--spark-x), var(--spark-y)) scale(0.2); }
}
.task-fly strong { display: block; font-size: 0.82rem; font-weight: 600; }
.task-fly small { display: block; font-size: 0.7rem; opacity: 0.8; margin-top: 0.1rem; }

/* Motion is the whole feature, so this is not just a courtesy: with reduced motion the
   card never appears at all and the launch is reported by the badge and the toast,
   which is the information the animation was carrying anyway. */
@media (prefers-reduced-motion: reduce) {
  .task-fly { display: none; }
  .task-vortex.is-absorbing,
  .task-vortex.is-absorbing::before,
  .task-vortex.is-absorbing::after,
  .task-plus.is-showing,
  .task-spark.is-flying,
  .task-count.is-bumping { animation: none; }
  .task-spark { display: none; }
  .task-plus.is-showing { opacity: 0; }
}


/* A plain count on a nav item — currently Smart-диалоги' "waiting for a reply".
   Deliberately the neutral chrome colour, not the accent the task badge uses: the
   tasks badge means "work is running", this one means "somebody is waiting", and two
   different meanings should not arrive in the same colour. */
.nav-link-dialogues { position: relative; }
.nav-count {
  margin-left: auto;
  min-width: 1.4rem;
  height: 1.4rem;
  padding: 0 0.35rem;
  border-radius: var(--radius-full);
  display: inline-grid;
  place-items: center;
  background: var(--color-primary-bg);
  color: var(--color-primary-hover);
  font-size: 0.7rem;
  font-weight: 700;
  flex-shrink: 0;
}
.nav-count[hidden] { display: none; }
html.sidebar-collapsed .sidebar .nav-count {
  position: absolute;
  top: 0.3rem;
  right: 0.55rem;
  min-width: 0.55rem;
  width: 0.55rem;
  height: 0.55rem;
  padding: 0;
  font-size: 0;
  margin-left: 0;
  background: var(--color-primary);
}

/* --- приземление на блок страницы --- */
/* Вторая карточка летит не в иконку «Задачи», а в блок результатов на самой странице.
   Воронки там нет и засасывать нечем, поэтому блок отвечает по-другому: обводка
   вспыхивает акцентом и сразу гаснет. Кольцо рисуется тенью, а не рамкой, — рамка
   сдвинула бы содержимое на пиксель в момент вспышки. */
.is-task-landing {
  animation: task-landing 860ms cubic-bezier(0.2, 0.85, 0.25, 1);
}
@keyframes task-landing {
  0%   { box-shadow: var(--shadow-sm); }
  22%  { box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 55%, transparent),
                     0 18px 46px color-mix(in srgb, var(--color-primary) 28%, transparent); }
  55%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--color-primary) 16%, transparent),
                     0 14px 36px color-mix(in srgb, var(--color-primary) 16%, transparent); }
  100% { box-shadow: var(--shadow-sm); }
}

/* --- «результаты появятся здесь» --- */
/* Пустое состояние блока результатов на время работы поиска. Оно и так уже есть на
   странице — здесь оно просто оживает, вместо того чтобы городить второй блок:
   иконка пульсирует, снизу идёт бесконечная полоска. Полоска именно бесконечная,
   а не по проценту: настоящий процент показывает свой прогресс-бар в шапке блока,
   и два разных числа рядом читались бы как рассинхрон. */
.dm-empty-state.is-waiting {
  border-color: color-mix(in srgb, var(--color-primary) 35%, var(--color-border));
  background: color-mix(in srgb, var(--color-primary) 6%, transparent);
  color: var(--color-text);
  position: relative;
  overflow: hidden;
}
.dm-empty-state.is-waiting svg {
  color: var(--color-primary);
  animation: task-waiting-pulse 1.6s ease-in-out infinite;
}
.dm-empty-state.is-waiting::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--color-primary), transparent);
  animation: task-waiting-sweep 1.5s ease-in-out infinite;
}
@keyframes task-waiting-pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.94); }
  50%      { opacity: 1;    transform: scale(1.06); }
}
@keyframes task-waiting-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  .is-task-landing,
  .dm-empty-state.is-waiting svg,
  .dm-empty-state.is-waiting::after { animation: none; }
}
