/* ============================================================
   Action lifecycle animation
   Used only on docs/core-concepts/actions.md
   ============================================================ */

.action-demo {
  position: relative;
  width: 100%;
  max-width: 680px;
  height: 360px;
  margin: 1.5rem auto;
  font-family: var(--md-code-font, monospace);
  font-size: 0.82rem;
  user-select: none;
}

/* Vertical lifelines */
.anim-lifeline {
  position: absolute;
  top: 52px;
  bottom: 12px;
  width: 2px;
  background: var(--md-primary-fg-color);
  opacity: 0.35;
}
.anim-lifeline-l { left: 80px; }
.anim-lifeline-r { right: 80px; }

/* Actor boxes */
.anim-actor {
  position: absolute;
  top: 0;
  width: 120px;
  padding: 8px 0;
  text-align: center;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  border: 2px solid var(--md-primary-fg-color);
  border-radius: 6px;
  background: var(--md-primary-fg-color);
  color: #fff;
}
.anim-actor-client { left: 20px; }
.anim-actor-server { right: 20px; }

/* State label inside server box */
.anim-server-state {
  position: absolute;
  right: 20px;
  width: 120px;
  text-align: center;
  font-size: 0.72rem;
  opacity: 0;
  padding: 3px 0;
  border-radius: 4px;
  background: rgba(63,81,181,0.15);
  color: var(--md-primary-fg-color);
  font-weight: 600;
}

/* Arrow messages */
.anim-arrow {
  position: absolute;
  left: 100px;
  right: 100px;
  height: 24px;
  display: flex;
  align-items: center;
  opacity: 0;
}

.anim-arrow-line {
  flex: 1;
  height: 2px;
  background: currentColor;
  position: relative;
}

/* arrowhead */
.anim-arrow-line::after {
  content: '';
  position: absolute;
  top: -5px;
  width: 0; height: 0;
}

.anim-arrow.to-server .anim-arrow-line::after {
  right: -1px;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 10px solid currentColor;
}

.anim-arrow.to-client .anim-arrow-line::after {
  left: -1px;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 10px solid currentColor;
}

.anim-arrow-label {
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  color: #fff;
}

/* colour palette per message type */
.anim-arrow.msg-goal        { color: #3f51b5; }
.anim-arrow.msg-goal        .anim-arrow-label { background: #3f51b5; }
.anim-arrow.msg-accept      { color: #2e7d32; }
.anim-arrow.msg-accept      .anim-arrow-label { background: #2e7d32; }
.anim-arrow.msg-feedback    { color: #f57c00; }
.anim-arrow.msg-feedback    .anim-arrow-label { background: #f57c00; }
.anim-arrow.msg-result      { color: #1565c0; }
.anim-arrow.msg-result      .anim-arrow-label { background: #1565c0; }
.anim-arrow.msg-cancel      { color: #c62828; }
.anim-arrow.msg-cancel      .anim-arrow-label { background: #c62828; }

/* Progress bar inside server zone */
.anim-progress-wrap {
  position: absolute;
  right: 20px;
  width: 120px;
  opacity: 0;
}
.anim-progress-bg {
  height: 6px;
  background: rgba(63,81,181,0.2);
  border-radius: 3px;
  overflow: hidden;
}
.anim-progress-bar {
  height: 100%;
  background: var(--md-primary-fg-color);
  border-radius: 3px;
  width: 0%;
  transition: width 0.4s ease;
}

/* ---- KEYFRAME DEFINITIONS ---- */

/* Slide-in then stay: used for server state labels */
@keyframes anim-fadein {
  0%   { opacity: 0; transform: translateY(4px); }
  15%  { opacity: 1; transform: translateY(0); }
  85%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Arrow: appear, move across, disappear */
@keyframes anim-arrow-ltr {
  0%   { opacity: 0; clip-path: inset(0 100% 0 0); }
  10%  { opacity: 1; clip-path: inset(0 100% 0 0); }
  60%  { opacity: 1; clip-path: inset(0 0% 0 0); }
  90%  { opacity: 1; clip-path: inset(0 0% 0 0); }
  100% { opacity: 0; clip-path: inset(0 0% 0 0); }
}
@keyframes anim-arrow-rtl {
  0%   { opacity: 0; clip-path: inset(0 0 0 100%); }
  10%  { opacity: 1; clip-path: inset(0 0 0 100%); }
  60%  { opacity: 1; clip-path: inset(0 0 0 0%); }
  90%  { opacity: 1; clip-path: inset(0 0 0 0%); }
  100% { opacity: 0; clip-path: inset(0 0 0 0%); }
}

@keyframes anim-progress-grow {
  0%   { opacity: 0; }
  5%   { opacity: 1; }
  10%  { width: 0%; }
  55%  { width: 100%; }
  90%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ---- ANIMATION TIMING (total cycle = 9s) ----
   t=0.0  Goal →
   t=1.0  ← Accepted
   t=1.8  progress bar grows
   t=2.2  ← Feedback 30%
   t=3.4  ← Feedback 65%
   t=4.6  ← Feedback 100%
   t=5.6  ← Result: Succeeded
   t=7.0  pause / fade
   t=9.0  loop
*/

.action-demo .anim-arrow { animation-duration: 1.4s; animation-fill-mode: both; animation-iteration-count: infinite; animation-timing-function: ease-in-out; }

.action-demo .arrow-goal     { animation-name: anim-arrow-ltr; animation-delay: 0s;   top: 100px; animation-duration: 1.2s; }
.action-demo .arrow-accept   { animation-name: anim-arrow-rtl; animation-delay: 1.3s; top: 140px; animation-duration: 1.2s; }
.action-demo .arrow-fb1      { animation-name: anim-arrow-rtl; animation-delay: 2.4s; top: 185px; animation-duration: 1.2s; }
.action-demo .arrow-fb2      { animation-name: anim-arrow-rtl; animation-delay: 3.5s; top: 225px; animation-duration: 1.2s; }
.action-demo .arrow-fb3      { animation-name: anim-arrow-rtl; animation-delay: 4.6s; top: 265px; animation-duration: 1.2s; }
.action-demo .arrow-result   { animation-name: anim-arrow-rtl; animation-delay: 5.7s; top: 308px; animation-duration: 1.4s; }

.action-demo .anim-progress-wrap {
  animation: anim-progress-grow 4.8s 1.8s infinite both;
  top: 150px;
}
.action-demo .anim-progress-wrap .anim-progress-bar {
  animation: none; width: 0%;
}

/* server state label */
.action-demo .state-executing {
  animation: anim-fadein 4.8s 1.8s infinite both;
  top: 168px;
}

/* Repeat cycle timing */
.action-demo .arrow-goal,
.action-demo .arrow-accept,
.action-demo .arrow-fb1,
.action-demo .arrow-fb2,
.action-demo .arrow-fb3,
.action-demo .arrow-result,
.action-demo .anim-progress-wrap,
.action-demo .state-executing {
  animation-duration: inherit; /* overridden per element above */
  /* all share 9s total cycle */
}

/* Override to share cycle period */
.action-demo .arrow-goal     { animation-duration: 9s; }
.action-demo .arrow-accept   { animation-duration: 9s; }
.action-demo .arrow-fb1      { animation-duration: 9s; }
.action-demo .arrow-fb2      { animation-duration: 9s; }
.action-demo .arrow-fb3      { animation-duration: 9s; }
.action-demo .arrow-result   { animation-duration: 9s; }
.action-demo .anim-progress-wrap { animation-duration: 9s; }
.action-demo .state-executing { animation-duration: 9s; }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .action-demo .anim-arrow,
  .action-demo .anim-progress-wrap,
  .action-demo .state-executing {
    animation: none;
    opacity: 1;
  }
}
