/* ==========================================================================
   Activity log — a plain, theme-aware log list (not a terminal pastiche):
   fixed-height scroll box, one row per event, oldest at the top and newest at
   the bottom like a real log tail. Static status dot instead of an icon/badge
   per row (quieter at a glance across many rows); no blinking anything —
   nothing here is ever typed into, so a cursor would just be decoration.
   ========================================================================== */
.log-panel {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
}
.log-panel-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.8rem;
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
  font-size: 0.72rem;
  color: var(--color-text-muted);
}
/* Scrollbar look itself (thin, violet-on-hover) lives in the shared
   .custom-scrollbar rule group near the top of this file — .log-list is
   grouped into those selectors directly. */
.log-list {
  overflow-y: auto;
  overflow-x: hidden;
}
.log-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.55rem;
  padding: 0.4rem 0.8rem;
  font-size: 0.82rem;
  border-bottom: 1px solid var(--color-border);
}
.log-row:last-child { border-bottom: none; }
.log-row:hover { background: var(--color-surface-muted); }
.log-status { width: 0.5rem; height: 0.5rem; border-radius: 50%; flex-shrink: 0; background: var(--color-text-faint); }
.log-status-ok { background: var(--color-success-text); }
.log-status-fail { background: var(--color-danger-text); }
.log-status-wait { background: var(--color-warning-text); }

/* Per-module colored icon circle on each log row — purely a "which module was
   this" grouping cue (decorative, not a status signal), the small dot right
   after it is still what tells success/fail/flood-wait apart. */
.log-icon-circle {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.log-icon-circle .icon { width: 0.85rem; height: 0.85rem; }
.log-icon-primary { background: var(--color-primary-bg); color: var(--color-primary); }
.log-icon-violet { background: color-mix(in srgb, var(--color-blue) 16%, transparent); color: var(--color-blue); }
.log-icon-accent { background: color-mix(in srgb, var(--color-accent) 16%, transparent); color: var(--color-accent); }
.log-icon-info { background: color-mix(in srgb, var(--color-info) 16%, transparent); color: var(--color-info); }
.log-icon-warning { background: var(--color-warning-bg); color: var(--color-warning-text); }
.log-time { font-family: var(--font-mono); font-size: 0.76rem; color: var(--color-text-faint); flex-shrink: 0; }
.log-account { font-weight: 600; color: var(--color-text); flex-shrink: 0; }
.log-meta { font-family: var(--font-mono); font-size: 0.76rem; color: var(--color-text-muted); flex-shrink: 0; }
.log-module {
  font-size: 0.75rem;
  color: var(--color-text-faint);
  flex-shrink: 0;
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.log-action { color: var(--color-text); overflow-wrap: anywhere; }
/* Technical error text (a caught exception's str(), a raw Telethon error, ...) never
   sits in the log as plain visible text — a real internal bug's message would be as
   unreadable to the operator as it is alarming-looking. Collapsed behind "Подробности"
   by default; a copy button covers reporting it to us without retyping. */
.log-error-details { flex-basis: 100%; padding-left: 1.1rem; font-size: 0.75rem; }
.log-error-details summary {
  cursor: pointer;
  color: var(--color-text-faint);
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.log-error-details summary::-webkit-details-marker { display: none; }
.log-error-details summary::before {
  content: '';
  width: 0.5rem;
  height: 0.5rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--transition-fast) var(--ease);
}
.log-error-details[open] summary::before { transform: rotate(45deg); }
.log-error-details summary:hover { color: var(--color-text-muted); }
.log-error-row { display: flex; align-items: flex-start; gap: 0.5rem; margin-top: 0.3rem; }
.log-error-text {
  color: var(--color-danger-text);
  font-family: var(--font-mono);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  flex: 1;
}
.log-error-copy-btn {
  flex-shrink: 0;
  color: var(--color-text-faint);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0.1rem;
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast) var(--ease), background var(--transition-fast) var(--ease);
}
.log-error-copy-btn:hover { color: var(--color-text); background: var(--color-surface-muted); }
.log-empty {
  padding: 1rem 0.8rem;
  color: var(--color-text-faint);
  font-size: 0.85rem;
  text-align: center;
}
.log-search-wrap {
  position: relative;
  padding: 0.6rem 0.7rem;
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}
.log-search-wrap .icon {
  position: absolute;
  left: 1.25rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-faint);
  pointer-events: none;
}
.log-search-wrap input {
  padding-left: 2.2rem;
  font-size: 0.82rem;
}
.log-row.log-row-hidden { display: none; }

.admin-tab {
  padding: 0.6rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--color-text-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.admin-tab:hover { color: var(--color-text); }
.admin-tab-active { color: var(--color-primary); border-color: var(--color-primary); }

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  padding: 2.5rem 1.5rem;
  color: var(--color-text-muted);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}
.empty-state .icon { width: 2rem; height: 2rem; color: var(--color-text-faint); }
/* The rule above is meant only for the empty-state's own big decorative icon — a
   .btn's icon (e.g. the "+" on an inline "Добавить" action added to an empty state)
   needs to stay the button's own text color and normal icon size, not inherit the
   faint/oversized decorative look just because it happens to sit inside the same
   container. */
.empty-state .btn .icon { width: 1.15rem; height: 1.15rem; color: inherit; }
.empty-state .btn .icon-sm { width: 0.95rem; height: 0.95rem; }
.empty-state-title { font-weight: 600; color: var(--color-text); font-size: 0.95rem; }
.empty-state-desc { font-size: 0.85rem; max-width: 26rem; }

.skeleton {
  background: linear-gradient(90deg, var(--color-surface-muted) 25%, var(--color-border) 37%, var(--color-surface-muted) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
  border-radius: var(--radius-md);
}
@keyframes skeleton-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; background: var(--color-surface-muted); }
}

/* Reusable skeleton primitives — compose with `.skeleton` (the shimmer) so every
   on-demand-loaded panel/modal shares one house style. Real content that replaces a
   skeleton gets `.skel-enter` to rise in, turning the swap into a single motion. */
.skel-enter { animation: skel-rise-in 0.34s var(--ease) both; }
@keyframes skel-rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
.skel-line { height: 0.75rem; border-radius: 6px; }
.skel-list { display: flex; flex-direction: column; }
.skel-list-row { display: flex; align-items: center; gap: 12px; padding: 14px 2px; }
.skel-list-row + .skel-list-row { border-top: 1px solid var(--color-border); }
.skel-dot { width: 38px; height: 38px; border-radius: 50%; flex: none; }
.skel-stack { display: flex; flex-direction: column; gap: 9px; flex: 1; min-width: 0; }
@media (prefers-reduced-motion: reduce) { .skel-enter { animation: none; } }

