/* ============================================================
   Bundles index — hero entrance + living "converge & flow" diagram
   Distinct design: four service chips converge into one hub, the
   seams draw in, then data continuously flows along the seams into
   the core while the hub emits a slow sonar ping.
   Animations only run when JS adds .hero-animate to
   #bundles-hero-block (skipped under prefers-reduced-motion).
   Default (no class) shows the finished, static state.
   ============================================================ */

/* --- Text line stagger --- */
#bundles-hero-block .hero-line { opacity: 1; transform: none; }
#bundles-hero-block.hero-animate .hero-line { opacity: 0; transform: translateY(12px); }
#bundles-hero-block.hero-animate .hero-line:nth-child(1) { animation: heroRise .55s ease-out 0s forwards; }
#bundles-hero-block.hero-animate .hero-line:nth-child(2) { animation: heroRise .55s ease-out .12s forwards; }
#bundles-hero-block.hero-animate .hero-line:nth-child(3) { animation: heroRise .55s ease-out .24s forwards; }
#bundles-hero-block.hero-animate .hero-line:nth-child(4) { animation: heroRise .55s ease-out .36s forwards; }
@keyframes heroRise { to { opacity: 1; transform: translateY(0); } }

/* --- Diagram base --- */
.bhero-svg { width: 100%; height: auto; max-width: 460px; display: block; margin: 0 auto; }
.bhero-node, .bhero-hub, .bhero-ring { transform-box: fill-box; transform-origin: center; }

/* Connector "seams": drawn by default; animate the draw under .hero-animate */
.bhero-link { stroke-dasharray: 240; stroke-dashoffset: 0; opacity: 1; }
.hero-animate .bhero-link { animation: linkDraw .7s ease-out both; }
.hero-animate .bhero-link.l1 { animation-delay: .42s; }
.hero-animate .bhero-link.l2 { animation-delay: .52s; }
.hero-animate .bhero-link.l3 { animation-delay: .62s; }
.hero-animate .bhero-link.l4 { animation-delay: .72s; }
@keyframes linkDraw { from { stroke-dashoffset: 240; opacity: 0; } to { stroke-dashoffset: 0; opacity: 1; } }

/* Outer chips converge inward from their corners */
.hero-animate .bhero-node.n1 { animation: convTL .6s cubic-bezier(.2,.7,.2,1) .02s both; }
.hero-animate .bhero-node.n2 { animation: convTR .6s cubic-bezier(.2,.7,.2,1) .14s both; }
.hero-animate .bhero-node.n3 { animation: convBL .6s cubic-bezier(.2,.7,.2,1) .26s both; }
.hero-animate .bhero-node.n4 { animation: convBR .6s cubic-bezier(.2,.7,.2,1) .38s both; }
@keyframes convTL { from { opacity: 0; transform: translate(-46px,-40px) scale(.7); } to { opacity: 1; transform: none; } }
@keyframes convTR { from { opacity: 0; transform: translate( 46px,-40px) scale(.7); } to { opacity: 1; transform: none; } }
@keyframes convBL { from { opacity: 0; transform: translate(-46px, 40px) scale(.7); } to { opacity: 1; transform: none; } }
@keyframes convBR { from { opacity: 0; transform: translate( 46px, 40px) scale(.7); } to { opacity: 1; transform: none; } }

/* Central hub scales in, then breathes gently */
.bhero-hub { transform: none; }
.hero-animate .bhero-hub { animation: hubIn .55s cubic-bezier(.2,.7,.2,1) .9s both, hubBreathe 4.5s ease-in-out 1.6s infinite; }
@keyframes hubIn { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
@keyframes hubBreathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }

/* Sonar ping radiating from the hub (hidden by default, lives only with motion) */
.bhero-ring { opacity: 0; }
.hero-animate .bhero-ring { animation: ringPing 3.2s ease-out 1.5s infinite; }
@keyframes ringPing { 0% { transform: scale(.45); opacity: .5; } 70% { opacity: 0; } 100% { transform: scale(1.8); opacity: 0; } }

/* Data flowing along each seam into the hub (continuous, after seams draw) */
.bhero-flow { opacity: 0; }
.hero-animate .bhero-flow.f1 { animation: flow1 2.4s ease-in-out 1.30s infinite; }
.hero-animate .bhero-flow.f2 { animation: flow2 2.4s ease-in-out 1.70s infinite; }
.hero-animate .bhero-flow.f3 { animation: flow3 2.4s ease-in-out 2.10s infinite; }
.hero-animate .bhero-flow.f4 { animation: flow4 2.4s ease-in-out 2.50s infinite; }
@keyframes flow1 { 0% { transform: translate(0,0); opacity: 0; } 12% { opacity: .95; } 85% { opacity: .95; } 100% { transform: translate( 115px, 94px); opacity: 0; } }
@keyframes flow2 { 0% { transform: translate(0,0); opacity: 0; } 12% { opacity: .95; } 85% { opacity: .95; } 100% { transform: translate(-115px, 94px); opacity: 0; } }
@keyframes flow3 { 0% { transform: translate(0,0); opacity: 0; } 12% { opacity: .95; } 85% { opacity: .95; } 100% { transform: translate( 115px,-94px); opacity: 0; } }
@keyframes flow4 { 0% { transform: translate(0,0); opacity: 0; } 12% { opacity: .95; } 85% { opacity: .95; } 100% { transform: translate(-115px,-94px); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .bhero-link, .bhero-node, .bhero-hub, .bhero-ring, .bhero-flow { animation: none !important; }
  .bhero-ring, .bhero-flow { display: none; }
}
