/* Running step card — animated border glow.
   Consumed inline by StepCard.tsx (conic-gradient background + animation). */
@property --border-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}
@keyframes borderGlow {
  to { --border-angle: 360deg; }
}

/* ═════════════════════════════════════════════════════════════════════════
   NodeMap entrance + position animations (Spring)
   Scoped to `.node-map-root` (the container className applied by
   NodeMapView). Entrance is gated by `data-entry-state="entering"`, set on
   freshly-inserted nodes by `useNodeEnterObserver`. Edge draw relies on
   `pathLength="100"` set by the same hook so growth is uniform regardless
   of the underlying SVG path length.
   ═════════════════════════════════════════════════════════════════════════ */

@keyframes nm-spring-pop {
  0%   { opacity: 0; transform: scale(0.85); }
  60%  { opacity: 1; transform: scale(1.05); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes nm-edge-draw {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

/* Existing nodes glide on position changes. */
.node-map-root .react-flow__node {
  transition: transform 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* During the entrance window:
   1) Force opacity 1 — NodeMapView sets inline opacity:0 on new nodes
      (NodeMapView.tsx ~303), which would multiply away the child animation.
   2) Disable transform transition — new nodes are placed at a temp position
      below the layout and then moved by ELK; without this the node visibly
      slides from the bottom. */
.node-map-root .react-flow__node[data-entry-state="entering"] {
  opacity: 1 !important;
  transition: none !important;
}

/* Spring-pop on the inner StepCard, delayed so the edge starts first. */
.node-map-root .react-flow__node[data-entry-state="entering"] > * {
  animation: nm-spring-pop 520ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
  animation-delay: 350ms;
  transform-origin: center;
}

/* New edges draw from source — gated by `data-entry-state="entering"`
   set by useNodeEnterObserver, so existing edges don't re-animate when
   React Flow rebuilds the edge layer on any structural change. */
.node-map-root .react-flow__edge-path[data-entry-state="entering"] {
  stroke-dasharray: 100;
  animation: nm-edge-draw 480ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  .node-map-root .react-flow__node,
  .node-map-root .react-flow__node[data-entry-state="entering"],
  .node-map-root .react-flow__node[data-entry-state="entering"] > *,
  .node-map-root .react-flow__edge-path[data-entry-state="entering"] {
    animation: none !important;
    transition: none !important;
  }
}
