/*
  Global @keyframes for Blok UI animations.

  Keyframes live in the animation-name namespace and do not participate in
  the cascade. Grouped here so their call sites (checklist pop, spring-load
  flash, emoji picker, callout emoji swap, property popover, image
  shimmer/retry) stay lean.
*/

@keyframes blok-checkbox-pop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.18); }
  65%  { transform: scale(0.9); }
  82%  { transform: scale(1.07); }
  100% { transform: scale(1); }
}

@keyframes spring-loaded-flash {
  0% { background-color: var(--blok-selection); }
  100% { background-color: transparent; }
}

@keyframes blok-emoji-picker-in {
  from {
    opacity: 0;
    transform: translateY(4px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes blok-emoji-tones-in {
  from { opacity: 0; transform: translateY(-5px) scale(0.82, 0.94); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes blok-emoji-card-in {
  from { opacity: 0; transform: translateY(10px) rotate(0deg) scale(0.8); }
  to { opacity: 1; transform: translateY(0) rotate(var(--emoji-card-tilt)) scale(1); }
}

@keyframes blok-emoji-empty-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Callout emoji swap — the newcomer leaps in from above and lands with a
   squash-and-rebound (transform-origin: bottom on the call site), while the
   incumbent tips over and falls off its perch. Both run simultaneously so the
   landing reads as what knocks the old emoji out. */
@keyframes blok-callout-emoji-jump-in {
  0%   { transform: translateY(-18px) scale(0.55); opacity: 0; }
  30%  { opacity: 1; }
  45%  { transform: translateY(0) scaleX(1.15) scaleY(0.8); }
  70%  { transform: translateY(-3px) scaleX(0.94) scaleY(1.05); }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}

@keyframes blok-callout-emoji-knock-out {
  0%   { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; }
  100% { transform: translateY(20px) rotate(28deg) scale(0.6); opacity: 0; }
}

@keyframes blok-prop-popover-in {
  from {
    opacity: 0;
    transform: scale(0.96) translateY(-4px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

@keyframes blok-image-shimmer {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

@keyframes blok-image-retry-spin {
  to { transform: rotate(360deg); }
}

@keyframes blok-block-target-pulse {
  0%   { background-color: var(--blok-selection); }
  60%  { background-color: var(--blok-selection); }
  100% { background-color: transparent; }
}

/* Link-field suggestion row / inline error reveal — call sites in
   popover-animation.css. Restarts only when the element toggles from
   display:none, so it fires on appear, not on every keystroke. */
@keyframes blok-link-reveal {
  from {
    opacity: 0;
    transform: translateY(-2px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Soft nudge when a resizable block (image/video/embed) hits its minimum
   width — shared by the resize-cue rules in resize-cue.css. */
@keyframes blok-resize-recoil {
  0%   { transform: translateX(0); }
  50%  { transform: translateX(3px); }
  100% { transform: translateX(0); }
}
