/* svc-react.html — hero animation (prefix: rx-)
   Theme: React component tree, SSR → hydration, state orb */

@keyframes rxGlow      { 0%,100% { opacity: 0.08; } 50% { opacity: 0.2; } }
@keyframes rxNodeIn    { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes rxBranchDraw{ from { stroke-dashoffset: 60; } to { stroke-dashoffset: 0; } }
@keyframes rxFlow      { 0% { stroke-dashoffset: 32; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes rxStateSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes rxStatePulse{ 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes rxCountUp   { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }

.rx-glow { animation: rxGlow 3.5s ease-in-out infinite; }

/* Tree nodes appear top-down, server first then client */
.rx-s-root   { animation: rxNodeIn 0.5s var(--ease-spring) 0.4s both; }
.rx-s-leaf1  { animation: rxNodeIn 0.4s var(--ease-spring) 0.75s both; }
.rx-s-leaf2  { animation: rxNodeIn 0.4s var(--ease-spring) 0.9s both; }
.rx-boundary { animation: rxNodeIn 0.4s ease-out 1.1s both; }
.rx-c-root   { animation: rxNodeIn 0.5s var(--ease-spring) 1.3s both; }
.rx-state    { animation: rxNodeIn 0.5s var(--ease-spring) 1.55s both; transform-box: fill-box; transform-origin: center; }
.rx-state    { animation: rxNodeIn 0.5s var(--ease-spring) 1.55s both, rxStatePulse 2.4s ease-in-out 2.3s infinite; }
.rx-c-leaf1  { animation: rxNodeIn 0.4s var(--ease-spring) 1.75s both; }
.rx-c-leaf2  { animation: rxNodeIn 0.4s var(--ease-spring) 1.9s both; }

/* Branches draw in after their parents */
.rx-branch { stroke-dasharray: 60; }
.rx-b1 { animation: rxBranchDraw 0.5s ease-out 0.7s both; }
.rx-b2 { animation: rxBranchDraw 0.5s ease-out 0.85s both; }
.rx-b3 { animation: rxBranchDraw 0.5s ease-out 1.7s both; }
.rx-b4 { animation: rxBranchDraw 0.5s ease-out 1.85s both; }

/* Hydration flow pulses forever */
.rx-flow { stroke-dasharray: 8; animation: rxFlow 2.4s linear 2.1s infinite; }

/* Metrics fade in last */
.rx-metrics text { animation: rxCountUp 0.45s ease-out 2.4s both; }
