/* ─────────────────────────────────────────────────────────────
   TVZA UI FX — skeletons · page transitions · micro-animations
   Shared across the whole site. Theme-aware (uses CSS vars with
   safe fallbacks) and fully disabled under prefers-reduced-motion.
   ───────────────────────────────────────────────────────────── */

/* ── 1. Page enter / leave transition ───────────────────────── */
/* Only the CONTENT region fades — never the header — so the top bar
   appears to stay put across page navigations instead of blinking.
   Opacity-only: a transform on an ancestor would break position:fixed
   overlays/modals on mobile. */
@keyframes fx-page-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
main, .main {
  animation: fx-page-in 0.3s ease both;
}
/* Fade the content out just before navigating to another internal page.
   Applied by JS to the content element (main/.main, or body as fallback). */
.fx-leaving {
  opacity: 0 !important;
  transition: opacity 0.18s ease;
  animation: none !important;
}

/* ── 2. Skeleton placeholders (YouTube style) ───────────────── */
.fx-skeleton-host {
  display: block;
  padding: 8px 0;
}
.fx-skel-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 4px;
}
.fx-skel-row + .fx-skel-row {
  border-top: 1px solid var(--border, rgba(128, 128, 128, 0.16));
}
.fx-skel {
  position: relative;
  overflow: hidden;
  background: var(--surface-2, rgba(128, 128, 128, 0.16));
  border-radius: var(--r-icon, 11px);
}
/* moving sheen */
.fx-skel::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.55) 50%,
    transparent 100%
  );
  animation: fx-shimmer 1.4s ease-in-out infinite;
}
:root[data-theme="dark"] .fx-skel::after {
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.09) 50%,
    transparent 100%
  );
}
@keyframes fx-shimmer {
  100% { transform: translateX(100%); }
}
.fx-skel-avatar {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--r-row, 14px);
}
.fx-skel-lines {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.fx-skel-line { height: 12px; width: 78%; }
.fx-skel-line.short { width: 46%; height: 10px; }
.fx-skel-pill {
  flex: 0 0 auto;
  width: 58px;
  height: 26px;
  border-radius: var(--r-pill, 999px);
}

/* ── 3. Content fade-in (skeleton → real content, once) ─────── */
@keyframes fx-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.fx-fade-in {
  animation: fx-fade-in 0.28s ease both;
}

/* ── 3b. Indeterminate loading bar on the header ────────────────
   Shown whenever a skeleton/spinner is on the page (body.fx-loading,
   toggled by ui-fx.js). Sits flush on the header's bottom edge and
   sweeps a soft highlight across — a clean "still loading" cue that
   never shifts layout. */
.header { position: sticky; }              /* ensure ::after anchors to header */
/* fx-loadbar removed (§9): it ran at the same time as the skeletons,
   so one wait was drawn twice. The skeletons are the waiting state. */

/* ── 4. Subtle tap/press feedback site-wide ─────────────────── */
button:active,
.btn:active,
.icon-btn:active,
.user-chip:active,
[role="button"]:active {
  transform: scale(0.97);
}
button, .btn, .icon-btn, .user-chip, [role="button"] {
  transition: transform 0.08s ease;
}

/* ── 4b. Version footer (injected on every page) ────────────── */
.fx-version {
  width: 100%;
  text-align: center;
  font-family: var(--font-ui, system-ui, sans-serif);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-soft, #8a8a93);
  opacity: 0.7;
  padding: 22px 0 calc(20px + env(safe-area-inset-bottom));
  margin-top: 28px;
  user-select: none;
}

/* ── 5. Respect reduced-motion: kill all of the above ───────── */
@media (prefers-reduced-motion: reduce) {
  main, .main,
  .fx-leaving,
  .fx-fade-in,
  .fx-skel::after,
  body.fx-loading .header::after,
  button, .btn, .icon-btn, .user-chip, [role="button"] {
    animation: none !important;
    transition: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
  /* Keep a calm static hint instead of motion */
  body.fx-loading .header::after { background: rgba(255,255,255,0.35) !important; }
}
