/* ============================================================
   Motion graphics — Purple Hackers
   Portado del deck de soluciones: CSS puro, sin librerías.
   Cada diagrama explica un producto en movimiento.
   ============================================================ */

/* ---- gramática de animación (la misma del deck) ---- */
@keyframes mg-float   {0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
@keyframes mg-ping    {0%{transform:scale(1);opacity:.55}100%{transform:scale(2.6);opacity:0}}
@keyframes mg-blink   {0%,100%{opacity:1}50%{opacity:.28}}
@keyframes mg-dash    {to{stroke-dashoffset:-64}}
@keyframes mg-fill    {0%{width:0}70%{width:var(--w)}100%{width:var(--w)}}
/* --alto lo fija cada barra: la animacion va de 0 a su altura real,
   asi todas comparten escala y el pico se lee de verdad */
@keyframes mg-grow    {0%{height:2%}55%{height:var(--alto)}100%{height:var(--alto)}}
@keyframes mg-spike   {0%,30%{height:8%}48%,84%{height:var(--alto)}100%{height:8%}}
@keyframes mg-alert   {0%,50%{opacity:0}62%,88%{opacity:1}100%{opacity:0}}
@keyframes mg-line    {0%{width:0}80%{width:100%}100%{width:100%}}
@keyframes mg-marker  {0%,72%{opacity:0}82%,100%{opacity:1}}
@keyframes mg-draw    {0%{stroke-dashoffset:var(--dash,600)}70%{stroke-dashoffset:0}100%{stroke-dashoffset:0}}
@keyframes mg-sweep   {0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
@keyframes mg-msg     {0%,4%{opacity:0;transform:translateY(12px)}12%,92%{opacity:1;transform:translateY(0)}100%{opacity:0}}

/* ---- marco común de los diagramas ---- */
.mg{position:relative;background:var(--card);border:1px solid var(--line);
  padding:clamp(20px,3vw,32px);overflow:hidden;}

/* separaciones: en clases, no en style= — la CSP de producción
   prohíbe los estilos en línea (style-src 'self') */
.mg-sep{margin-top:34px;}
.mg-sep-s{margin-top:16px;}
.mg-sep-t{margin-top:22px;}
.mg-sep-b{margin-bottom:26px;}
.mg-cap{font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--bone-faint);margin-bottom:18px;}

/* las animaciones solo corren cuando el diagrama está a la vista:
   fuera de pantalla no gastan CPU ni batería */
.mg:not(.is-live) *{animation-play-state:paused !important;}

/* ============================================================
   1 · UMBRAL DDoS — un pico rompe la línea, salta la alerta
   ============================================================ */
.mg-ddos{--h:210px;}
/* el area de barras excluye la franja de la alerta, para que el 100%
   de una barra sea el alto real del grafico */
.mg-ddos .plot{position:relative;height:var(--h);display:flex;align-items:flex-end;
  gap:6px;padding-top:34px;box-sizing:content-box;}
/* cada barra lleva su --alto; la animacion crece hasta el */
.mg-ddos .bar{flex:1;background:linear-gradient(180deg,#8B58C4,#4A2578);
  border-radius:2px 2px 0 0;height:var(--alto);min-height:8px;
  animation:mg-grow 6s ease-out infinite;}
/* alturas y desfases por barra */
.mg-ddos .b1{--alto:30%}
.mg-ddos .b2{--alto:24%;animation-delay:.10s}
.mg-ddos .b3{--alto:34%;animation-delay:.20s}
.mg-ddos .b4{--alto:27%;animation-delay:.30s}
.mg-ddos .b5{--alto:32%;animation-delay:.40s}
.mg-ddos .b6{--alto:97%}
.mg-ddos .b7{--alto:86%;animation-delay:.12s}
.mg-ddos .b8{--alto:29%;animation-delay:.50s}
.mg-ddos .b9{--alto:25%;animation-delay:.60s}
.mg-ddos .bar.hit{background:linear-gradient(180deg,var(--ember),#B85543);
  box-shadow:0 0 18px rgba(255,138,115,.28);
  animation:mg-spike 6s ease-in-out infinite;}
/* el umbral queda sobre el trafico normal (~34%) y bajo el pico (~90%):
   asi el ataque lo rompe de forma visible */
.mg-ddos .umbral{position:absolute;left:0;right:0;bottom:calc(52% - 17px);height:0;
  border-top:1px dashed rgba(201,166,242,.5);}
.mg-ddos .umbral span{position:absolute;right:0;top:-9px;background:var(--card);
  padding:0 8px;font-family:var(--mono);font-size:.62rem;letter-spacing:.12em;
  color:var(--heliotrope);}
.mg-ddos .alerta{position:absolute;left:50%;top:8px;transform:translateX(-50%);
  font-family:var(--mono);font-size:.66rem;letter-spacing:.1em;
  color:var(--ember);border:1px solid rgba(255,138,115,.4);
  background:rgba(255,138,115,.1);padding:5px 12px;
  animation:mg-alert 6s ease-in-out infinite;white-space:nowrap;}
.mg-ddos .eje{display:flex;justify-content:space-between;margin-top:10px;
  font-family:var(--mono);font-size:.6rem;color:var(--bone-faint);}

/* ============================================================
   2 · TOPOLOGÍA — nodos, enlaces con tráfico, uno en alerta
   ============================================================ */
.mg-topo .lienzo{position:relative;height:230px;}
.mg-topo svg{position:absolute;inset:0;width:100%;height:100%;}
.mg-topo .enlace{stroke:rgba(201,166,242,.34);stroke-width:1.5;fill:none;
  stroke-dasharray:5 7;animation:mg-dash 2.4s linear infinite;}
.mg-topo .enlace.warn{stroke:rgba(255,138,115,.75);animation-duration:1.5s;}
.mg-topo .nodo{position:absolute;transform:translate(-50%,-50%);
  border:1px solid var(--line-strong);background:var(--card-2);
  padding:9px 14px;text-align:center;min-width:96px;}
.mg-topo .nodo .k{font-family:var(--mono);font-size:.58rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--bone-faint);display:block;}
.mg-topo .nodo .v{font-size:.82rem;color:var(--bone);white-space:nowrap;}
.mg-topo .nodo.core{border-color:rgba(201,166,242,.55);
  box-shadow:0 0 0 4px rgba(169,107,216,.09);}
.mg-topo .nodo.core .v{color:var(--heliotrope);}
.mg-topo .nodo.warn{border-color:rgba(255,138,115,.6);}
.mg-topo .nodo.warn .v{color:var(--ember);}
.mg-topo .nodo.off{opacity:.42;}
.mg-topo .pulso{position:absolute;width:11px;height:11px;border-radius:50%;
  background:var(--ember);transform:translate(-50%,-50%);}
.mg-topo .pulso::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:var(--ember);animation:mg-ping 3s ease-out infinite;}
.mg-topo .chip{position:absolute;left:50%;transform:translateX(-50%);
  font-family:var(--mono);font-size:.6rem;letter-spacing:.1em;color:var(--ember);
  border:1px solid rgba(255,138,115,.42);background:rgba(255,138,115,.1);
  padding:4px 11px;animation:mg-blink 1.7s ease-in-out infinite;white-space:nowrap;}
/* posiciones de los nodos */
.mg-topo .n-core{left:50%;top:22%}
.mg-topo .n-izq {left:20%;top:76%}
.mg-topo .n-mid {left:50%;top:76%}
.mg-topo .n-der {left:80%;top:76%}
.mg-topo .p-mid {left:50%;top:44%}
.mg-topo .c-mid {top:54%}

/* ============================================================
   3 · RELOJ ANCI — los plazos de la Ley 21.663 avanzando
   ============================================================ */
.mg-ley .pista{position:relative;height:2px;background:var(--line);margin:34px 0 16px;}
.mg-ley .avance{position:absolute;left:0;top:0;height:100%;
  background:linear-gradient(90deg,var(--viridian),var(--ember));
  animation:mg-line 8s ease-in-out infinite;}
.mg-ley .hito{position:absolute;top:50%;transform:translate(-50%,-50%);
  width:9px;height:9px;border-radius:50%;background:var(--card);
  border:1.5px solid var(--line-strong);}
.mg-ley .hito.on{border-color:var(--ember);background:var(--ember);
  animation:mg-marker 8s ease-in-out infinite;}
/* posiciones de los hitos en la linea de tiempo */
.mg-ley .h0{left:0}   .mg-ley .h20{left:20%}  .mg-ley .h46{left:46%}
.mg-ley .h72{left:72%} .mg-ley .h100{left:100%}
.mg-ley .etiquetas{display:flex;justify-content:space-between;
  font-family:var(--mono);font-size:.62rem;color:var(--bone-faint);}
.mg-ley .etiquetas b{display:block;color:var(--bone);font-weight:600;
  font-size:.72rem;margin-bottom:3px;}
.mg-ley .etiquetas .urg b{color:var(--ember);}

/* ============================================================
   4 · SONDA — el pozo: destinos orbitando el núcleo
   ============================================================ */
.mg-sonda .orbe{position:relative;height:250px;display:grid;place-items:center;}
.mg-sonda svg{width:100%;height:100%;}
.mg-sonda .anillo{fill:none;stroke:rgba(201,166,242,.16);stroke-width:1;}
.mg-sonda .radio{stroke:rgba(201,166,242,.1);stroke-width:1;}
.mg-sonda .haz{stroke:var(--viridian);stroke-width:1.5;fill:none;
  stroke-dasharray:4 6;animation:mg-dash 2s linear infinite;}
.mg-sonda .centro{fill:var(--amethyst);}
.mg-sonda .satelite{fill:var(--viridian);}
.mg-sonda .rot{transform-origin:center;animation:mg-sweep 34s linear infinite;}
.mg-sonda .txt{font-family:var(--mono);font-size:9px;fill:rgba(240,233,244,.5);}
/* desfases de los haces y detalles */
.mg-sonda .d1{animation-delay:.4s}
.mg-sonda .d2{animation-delay:.8s}
.mg-sonda .d3{animation-delay:1.2s}
.mg-sonda .sat-b{opacity:.6}
.mg-sonda .txt-n{fill:var(--heliotrope);}

/* ============================================================
   5 · AGENTE — la conversación que se escribe sola
   ============================================================ */
.mg-chat{display:flex;flex-direction:column;gap:11px;min-height:210px;}
.mg-chat .m{max-width:78%;padding:11px 15px;font-size:.9rem;line-height:1.5;
  border:1px solid var(--line);background:var(--card-2);
  animation:mg-msg 13s ease-in-out infinite;opacity:0;}
.mg-chat .m.tu{align-self:flex-end;border-color:rgba(201,166,242,.3);
  background:rgba(169,107,216,.12);color:var(--bone);}
.mg-chat .m.ph{align-self:flex-start;color:var(--bone-dim);}
.mg-chat .m.ph b{color:var(--viridian);font-family:var(--mono);
  font-size:.78rem;font-weight:400;}
.mg-chat .m:nth-child(1){animation-delay:0s}
.mg-chat .m:nth-child(2){animation-delay:1.1s}
.mg-chat .m:nth-child(3){animation-delay:4.4s}
.mg-chat .m:nth-child(4){animation-delay:5.6s}

/* ============================================================
   5b · CONVERSA — el chat real del agente, escribiéndose solo
   Se aplica sobre .agent-chat sin tocar su estilo: solo el ritmo.
   ============================================================ */
.mg-conversa{background:transparent;border:0;padding:0;overflow:visible;}
.mg-conversa .ac-msg{animation:mg-msg 15s ease-in-out infinite;opacity:0;}
.mg-conversa .ac-msg:nth-of-type(1){animation-delay:.2s}
.mg-conversa .ac-msg:nth-of-type(2){animation-delay:1.5s}
.mg-conversa .ac-msg:nth-of-type(3){animation-delay:5.4s}
.mg-conversa .ac-msg:nth-of-type(4){animation-delay:6.7s}
/* el punto de la barra late mientras "piensa" */
.mg-conversa .ac-dot{animation:mg-blink 1.8s ease-in-out infinite;}

/* ============================================================
   6 · BARRAS DE CAPACIDAD — se llenan escalonadas
   ============================================================ */
.mg-barras{display:flex;flex-direction:column;gap:15px;}
.mg-barras .fila .top{display:flex;justify-content:space-between;
  font-size:.86rem;margin-bottom:7px;}
.mg-barras .fila .top span:last-child{font-family:var(--mono);
  font-size:.78rem;color:var(--heliotrope);}
.mg-barras .canal{height:6px;background:rgba(240,233,244,.08);overflow:hidden;}
.mg-barras .relleno{height:100%;background:linear-gradient(90deg,var(--amethyst),var(--heliotrope));
  animation:mg-fill 5s ease-out infinite;}
.mg-barras .fila:nth-child(2) .relleno{animation-delay:.25s}
.mg-barras .fila:nth-child(3) .relleno{animation-delay:.5s}
.mg-barras .fila.ok .relleno{background:linear-gradient(90deg,#2FA877,var(--viridian));}

/* ---- respeta a quien pide menos movimiento ---- */
@media (prefers-reduced-motion:reduce){
  .mg *{animation:none !important;}
  .mg-ddos .bar,.mg-barras .relleno{transform:none;width:var(--w,100%);}
  .mg-ddos .alerta,.mg-chat .m,.mg-ley .hito.on{opacity:1;}
  .mg-ley .avance{width:100%;}
}

/* ---- móvil ---- */
@media (max-width:640px){
  .mg{padding:18px 16px;}
  .mg-topo .lienzo{height:250px;}
  .mg-topo .nodo{min-width:80px;padding:7px 10px;}
  .mg-topo .nodo .v{font-size:.74rem;}
  .mg-sonda .orbe{height:210px;}
  .mg-chat .m{max-width:92%;font-size:.85rem;}
  .mg-ley .etiquetas{font-size:.56rem;}
}
