@keyframes fadeSlideUp {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---------- Cross-fade + scale when switching lessons/pages ----------
   Uses the View Transitions API (see js/contentRenderer.js swapMain()) to
   animate the outgoing panel out and the incoming one in. The root's
   default full-page cross-fade is switched off so only #main animates —
   sidebar/topbar stay put. No-op (progressively enhanced) in browsers
   without support; .node-view's fadeSlideUp above still covers those. */
@supports (view-transition-name: none) {
  #main { view-transition-name: kf-main; }

  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }

  ::view-transition-old(kf-main) {
    animation: kfMainOut var(--dur-fast) var(--ease-in-out) both;
  }
  ::view-transition-new(kf-main) {
    animation: kfMainIn var(--dur-med) var(--ease-out) both;
  }
}

@keyframes kfMainOut {
  to { opacity: 0; transform: scale(0.98); }
}
@keyframes kfMainIn {
  from { opacity: 0; transform: scale(1.015); }
  to { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Offline-save spinner (icon-toggle + course-download button, mid-save) */
@keyframes iconSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
.icon-spin {
  animation: iconSpin 0.8s linear infinite;
  transform-origin: center;
}
@media (prefers-reduced-motion: reduce) {
  .icon-spin { animation: none; }
}

.node-view {
  animation: fadeSlideUp var(--dur-slow) var(--ease-out);
}

.node-view .keypoint,
.node-view .branch-card,
.node-view .example-item,
.node-view .summary-item,
.node-view .quiz-card {
  animation: fadeSlideUp var(--dur-med) var(--ease-out) both;
}
.node-view .keypoint:nth-child(1),.node-view .branch-card:nth-child(1),.node-view .example-item:nth-child(1),.node-view .summary-item:nth-child(1),.node-view .quiz-card:nth-child(1) { animation-delay: 20ms; }
.node-view .keypoint:nth-child(2),.node-view .branch-card:nth-child(2),.node-view .example-item:nth-child(2),.node-view .summary-item:nth-child(2),.node-view .quiz-card:nth-child(2) { animation-delay: 50ms; }
.node-view .keypoint:nth-child(3),.node-view .branch-card:nth-child(3),.node-view .example-item:nth-child(3),.node-view .summary-item:nth-child(3),.node-view .quiz-card:nth-child(3) { animation-delay: 80ms; }
.node-view .keypoint:nth-child(4),.node-view .branch-card:nth-child(4),.node-view .example-item:nth-child(4),.node-view .summary-item:nth-child(4),.node-view .quiz-card:nth-child(4) { animation-delay: 110ms; }
.node-view .keypoint:nth-child(5),.node-view .branch-card:nth-child(5) { animation-delay: 140ms; }
.node-view .keypoint:nth-child(6),.node-view .branch-card:nth-child(6) { animation-delay: 170ms; }

@keyframes popIn {
  from { opacity: 0; transform: scale(0.9); }
  to { opacity: 1; transform: scale(1); }
}
.crumb { animation: popIn var(--dur-fast) var(--ease-out) both; }

@media (prefers-reduced-motion: reduce) {
  .node-view, .node-view *, .crumb {
    animation: none !important;
  }
}

/* ---------- Toast (e.g. "Link copied!" after Share) ---------- */
.kf-toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translate(-50%, 12px);
  background: var(--on-accent);
  color: #fff;
  font-size: var(--fs-sm, 13px);
  padding: 10px 18px;
  border-radius: var(--radius-lg, 14px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  opacity: 0;
  pointer-events: none;
  z-index: 999;
  transition: opacity var(--dur-fast, 160ms) var(--ease-out, ease),
    transform var(--dur-fast, 160ms) var(--ease-out, ease);
}
.kf-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}
@media (prefers-reduced-motion: reduce) {
  .kf-toast { transition: opacity 1ms linear; }
}

/* ---------- Confetti (quiz-pass celebration) ---------- */
.confetti-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 1000;
}
.confetti-piece {
  position: absolute;
  top: -12px;
  width: 8px;
  height: 14px;
  border-radius: 2px;
  opacity: 0.9;
  animation: confetti-fall 1.6s ease-in forwards;
}
@keyframes confetti-fall {
  0% { transform: translateY(0) translateX(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(100vh) translateX(var(--drift, 0px)) rotate(540deg); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .confetti-layer { display: none; }
}
