{"id":5472,"date":"2026-05-11T02:57:40","date_gmt":"2026-05-11T02:57:40","guid":{"rendered":"https:\/\/ruvic.ai\/?page_id=5472"},"modified":"2026-06-10T06:23:13","modified_gmt":"2026-06-10T06:23:13","slug":"demos","status":"publish","type":"page","link":"https:\/\/ruvic.ai\/en\/demos\/","title":{"rendered":"Demos"},"content":{"rendered":"\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800\" rel=\"stylesheet\">\n\n\n\n<style id=\"ruvic-css\">\n\n\/* ============================================================\n   RUVIC AI \u2014 DEMO INTERACTIVA  \u00b7  bloque WordPress autocontenido\n   Todo el CSS est\u00e1 namespaced bajo #ruvic-demo para no chocar\n   con el tema de WordPress. Toggle claro\/oscuro incluido.\n   ============================================================ *\/\n\n#ruvic-demo, #ruvic-demo *{box-sizing:border-box;margin:0;padding:0;line-height:1.4}\n#ruvic-demo{\n  --font:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;\n  font-family:var(--font);\n  width:100%;max-width:1400px;margin:0 auto;\n  padding:30px 30px 34px;\n  border-radius:30px;\n  position:relative;\n  -webkit-font-smoothing:antialiased;\n  text-align:left;\n  isolation:isolate;\n}\n#ruvic-demo *{font-family:var(--font)}\n\n\/* Fondo navy profundo que rodea el widget \u2014 se extiende a todo el ancho.\n   La t\u00e9cnica de m\u00e1rgenes negativos lo lleva de borde a borde de la pantalla;\n   si la secci\u00f3n tiene overflow oculto, simplemente queda al ancho del contenido. *\/\n#ruvic-bg{background:#0A0E1F;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);\n  padding:48px clamp(14px,4vw,40px)}\n\n\/* ---------- TEMA OSCURO (por defecto, colores actuales) ---------- *\/\n#ruvic-demo[data-theme=\"dark\"]{\n  --surface:#111b3d; --surface2:#0d1530; --sb:#0f1834; --sb2:rgba(0,0,0,.28);\n  --card-hi:#1b2658; --card:#141e48; --ghost:#172148;\n  --border:rgba(250,240,228,.12); --border2:rgba(250,240,228,.2);\n  --text:#faf0e4; --text2:rgba(250,240,228,.62); --text3:rgba(250,240,228,.34);\n  --red:#ff363a; --orange:#fdaa4c; --purple:#8b80ff;\n  --grid:rgba(250,240,228,.05); --glow:rgba(83,74,183,.30);\n  --shadow:0 36px 70px -28px rgba(0,0,0,.7); --nshadow:0 3px 10px -2px rgba(0,0,0,.4);\n  --kpi-bg:rgba(253,170,76,.16); --kpi-tx:#fdaa4c;\n  background:\n    radial-gradient(130% 90% at 50% -10%, #18244f 0%, #0d1430 52%, #090e22 100%);\n  box-shadow:inset 0 1px 0 rgba(250,240,228,.05);\n}\n\/* ---------- TEMA CLARO (versi\u00f3n white) ---------- *\/\n#ruvic-demo[data-theme=\"light\"]{\n  --surface:#ffffff; --surface2:#f6f8fd; --sb:#ffffff; --sb2:#f6f8fd;\n  --card-hi:#ffffff; --card:#fbfcfe; --ghost:#f1f4fb;\n  --border:rgba(22,26,55,.1); --border2:rgba(22,26,55,.16);\n  --text:#161a33; --text2:rgba(22,26,51,.6); --text3:rgba(22,26,51,.4);\n  --red:#ff363a; --orange:#e8890a; --purple:#534AB7;\n  --grid:rgba(22,26,55,.05); --glow:rgba(83,74,183,.14);\n  --shadow:0 30px 60px -28px rgba(30,40,90,.32); --nshadow:0 6px 16px -8px rgba(30,40,90,.22);\n  --kpi-bg:rgba(232,137,10,.12); --kpi-tx:#c9760a;\n  background:\n    radial-gradient(120% 90% at 50% -10%, #ffffff 0%, #eef1fa 60%, #e6eaf6 100%);\n  box-shadow:inset 0 1px 0 rgba(255,255,255,.6);\n}\n\n\/* ---------------- HEADER ---------------- *\/\n#ruvic-demo .rb-header{position:relative;text-align:center;padding:6px 96px 26px}\n#ruvic-demo .rb-eyebrow{display:inline-flex;align-items:center;gap:7px;font-size:11px;font-weight:800;white-space:nowrap;\n  letter-spacing:2.2px;color:var(--red);text-transform:uppercase;\n  padding:6px 14px;border-radius:100px;border:1px solid rgba(255,54,58,.35);\n  background:rgba(255,54,58,.10)}\n#ruvic-demo .rb-eyebrow .pd{width:7px;height:7px;border-radius:50%;background:var(--red);\n  box-shadow:0 0 0 0 rgba(255,54,58,.70);animation:rbPing 1.8s ease-out infinite}\n@keyframes rbPing{0%{box-shadow:0 0 0 0 rgba(255,54,58,.55)}\n  70%{box-shadow:0 0 0 8px transparent}100%{box-shadow:0 0 0 0 transparent}}\n#ruvic-demo .rb-title{margin:16px 0 0;font-size:38px;line-height:42px;font-weight:800;letter-spacing:-1px;color:var(--text);text-wrap:balance}\n#ruvic-demo .rb-title .ac{background:linear-gradient(96deg,var(--red),var(--orange));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:var(--red)}\n#ruvic-demo .rb-sub{margin:12px auto 0;max-width:560px;font-size:14.5px;line-height:22px;color:var(--text2);text-wrap:pretty}\n\n\/* Theme toggle *\/\n#ruvic-demo .rb-theme{position:absolute;top:2px;right:0;display:inline-flex;align-items:center;gap:0;\n  background:var(--ghost);border:1px solid var(--border);border-radius:100px;padding:4px;cursor:pointer;\n  user-select:none}\n#ruvic-demo .rb-theme i{width:30px;height:28px;border-radius:100px;display:flex;align-items:center;justify-content:center;\n  font-style:normal;font-size:14px;color:var(--text3);transition:all .25s;position:relative;z-index:1}\n#ruvic-demo .rb-theme .knob{position:absolute;top:4px;left:4px;width:30px;height:28px;border-radius:100px;\n  background:linear-gradient(180deg,var(--red),#e02d31);box-shadow:0 4px 10px -3px var(--red);transition:transform .28s cubic-bezier(.5,1.4,.5,1)}\n#ruvic-demo[data-theme=\"light\"] .rb-theme .knob{transform:translateX(30px)}\n#ruvic-demo[data-theme=\"dark\"] .rb-theme i.moon{color:#fff}\n#ruvic-demo[data-theme=\"light\"] .rb-theme i.sun{color:#fff}\n\n\/* ---------------- WIDGET CARD ---------------- *\/\n#ruvic-demo .rb-widget{position:relative;border-radius:24px;overflow:hidden;height:750px;\n  background:var(--surface);border:1px solid var(--border2);box-shadow:var(--shadow);\n  display:grid;grid-template-columns:1fr 310px}\n#ruvic-demo[data-theme=\"dark\"] .rb-widget::after{content:\"\";position:absolute;inset:0;border-radius:24px;pointer-events:none;\n  box-shadow:inset 0 1px 0 rgba(250,240,228,.08)}\n#ruvic-demo[data-theme=\"light\"] .rb-widget::after{content:\"\";position:absolute;inset:0;border-radius:24px;pointer-events:none;\n  box-shadow:inset 0 1px 0 rgba(22,26,51,.08)}\n\n\/* ---- diagrama (canvas) ---- *\/\n#ruvic-demo .rb-canvas-area{position:relative;overflow:hidden;height:100%;\n  background:\n    radial-gradient(circle at 41% 42%, var(--glow) 0%, transparent 46%),\n    radial-gradient(var(--grid) 1.1px, transparent 1.1px);\n  background-size:auto, 26px 26px;background-color:var(--surface2)}\n#ruvic-demo .rb-zp{position:absolute;top:0;left:0;transform-origin:0 0}\n#ruvic-demo #rb-fc{position:absolute;top:0;left:0;z-index:1}\n#ruvic-demo .rb-nl{position:absolute;top:0;left:0;z-index:2;pointer-events:none}\n#ruvic-demo .rb-nl>*{pointer-events:auto}\n#ruvic-demo .rb-hint{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);z-index:4;\n  font-size:10.5px;font-weight:600;color:var(--text3);background:var(--sb2);\n  border:1px solid var(--border);padding:5px 12px;border-radius:100px;display:none;pointer-events:none}\n\n\/* ---- sidebar ---- *\/\n#ruvic-demo .rb-sb{background:var(--sb);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;min-height:0}\n#ruvic-demo .rb-sb-head{padding:18px 18px 14px;border-bottom:1px solid var(--border);display:flex;gap:11px;align-items:flex-start}\n#ruvic-demo .rb-mark{width:34px;height:34px;border-radius:10px;flex-shrink:0;display:flex;align-items:center;justify-content:center;\n  font-weight:800;font-size:16px;color:#fff;background:linear-gradient(150deg,var(--red),#b41f5e);\n  box-shadow:0 6px 16px -6px var(--red)}\n#ruvic-demo .rb-sb-head h3{font-size:15px;font-weight:800;color:var(--text);letter-spacing:-.3px;line-height:17px}\n#ruvic-demo .rb-sb-head h3 b{color:var(--red);font-weight:800}\n#ruvic-demo .rb-sb-head p{font-size:10.5px;color:var(--text3);margin-top:4px;line-height:15px}\n#ruvic-demo .rb-filter{padding:11px 18px;border-bottom:1px solid var(--border);display:flex;gap:6px;flex-wrap:wrap}\n#ruvic-demo .rb-filter::-webkit-scrollbar{display:none}\n#ruvic-demo .fb{padding:6px 11px;line-height:14px;border:1px solid var(--border2);border-radius:9px;font-size:10.5px;font-weight:600;cursor:pointer;flex-shrink:0;white-space:nowrap;\n  background:var(--ghost);color:var(--text2);transition:color .15s,border-color .15s,box-shadow .15s;line-height:1}\n#ruvic-demo .fb:hover{border-color:var(--orange);color:var(--orange);box-shadow:none !important}\n#ruvic-demo .fb.act{background:#ff363a !important;color:#fff !important;border-color:#ff363a !important;box-shadow:0 4px 12px -4px #ff363a !important}\n#ruvic-demo .rb-cases{flex:1;overflow-y:auto;padding:12px 14px;min-height:0}\n#ruvic-demo .rb-cases::-webkit-scrollbar, #ruvic-demo .rb-trk::-webkit-scrollbar{width:5px}\n#ruvic-demo .rb-cases::-webkit-scrollbar-thumb, #ruvic-demo .rb-trk::-webkit-scrollbar-thumb{background:var(--border2);border-radius:5px}\n#ruvic-demo .cb{width:100%;text-align:left;padding:12px 14px;border:1.5px solid var(--border);border-radius:13px;\n  background:var(--card);cursor:pointer;margin-bottom:8px;transition:transform .18s,box-shadow .18s,border-color .18s;display:block;position:relative;overflow:hidden}\n#ruvic-demo .cb::before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--cbc,var(--red));opacity:0;transition:opacity .2s}\n#ruvic-demo .cb:hover{border-color:var(--orange);transform:translateY(-2px);box-shadow:0 10px 24px -12px rgba(0,0,0,.4) !important}\n#ruvic-demo[data-theme=\"dark\"] .cb.act{border-color:#ff363a !important;background:#1e1d48 !important;box-shadow:0 8px 24px -10px rgba(255,54,58,.6) !important}\n#ruvic-demo[data-theme=\"light\"] .cb.act{border-color:#ff363a !important;background:#fce9e9 !important;box-shadow:0 8px 24px -10px rgba(255,54,58,.6) !important}\n#ruvic-demo .cb.act::before{opacity:1}\n#ruvic-demo .cb-ch{font-size:9px;line-height:12px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:var(--text3);display:flex;align-items:center;gap:6px}\n#ruvic-demo .cb-ch .d{width:7px;height:7px;border-radius:50%;flex-shrink:0}\n#ruvic-demo .cb-t{font-size:13px;font-weight:700;color:var(--text);line-height:17px;margin-top:5px}\n#ruvic-demo .cb-desc{font-size:11px;color:var(--text2);margin-top:4px;line-height:15px}\n#ruvic-demo .cb-kpi{display:inline-flex;line-height:13px;align-items:center;gap:4px;margin-top:8px;font-size:9.5px;font-weight:800;padding:4px 9px;border-radius:7px;background:var(--kpi-bg);color:var(--kpi-tx)}\n\n\/* tracker *\/\n#ruvic-demo .rb-trk{border-top:1px solid var(--border);padding:14px 18px;background:var(--sb2);max-height:248px;overflow-y:auto}\n#ruvic-demo .rb-trk h4{font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:var(--text3);margin-bottom:11px;display:flex;justify-content:space-between;align-items:center}\n#ruvic-demo .rb-trk h4 span{color:var(--orange);font-weight:800}\n#ruvic-demo .rb-empty{font-size:11px;color:var(--text3);line-height:17px}\n#ruvic-demo .stp{display:flex;gap:11px;margin-bottom:10px;opacity:.3;transition:opacity .35s,transform .35s}\n#ruvic-demo .stp:last-child{margin-bottom:2px}\n#ruvic-demo .stp.on{opacity:1;transform:translateX(3px)}\n#ruvic-demo .stp.dn{opacity:.5}\n#ruvic-demo .stp-n{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:9.5px;font-weight:800;color:#fff;flex-shrink:0;box-shadow:0 3px 8px -2px rgba(0,0,0,.4)}\n#ruvic-demo .stp-n.pulse{animation:rbPulse .55s ease}\n@keyframes rbPulse{0%{transform:scale(1)}45%{transform:scale(1.32)}100%{transform:scale(1)}}\n#ruvic-demo .stp-i{flex:1;min-width:0}\n#ruvic-demo .stp-nm{font-size:11.5px;font-weight:700;color:var(--text);line-height:15px}\n#ruvic-demo .stp-dt{font-size:10px;color:var(--text2);margin-top:2px;line-height:14px}\n\n\/* controls *\/\n#ruvic-demo .rb-ctrls{padding:12px 18px 16px;border-top:1px solid var(--border);background:var(--sb2)}\n#ruvic-demo .rb-ctrls-row{display:flex;gap:8px;margin-bottom:11px}\n#ruvic-demo .btn{flex:1;padding:11px;border:none;border-radius:11px;font-size:11.5px;font-weight:800;cursor:pointer;transition:color .15s,border-color .15s,box-shadow .15s,filter .15s;display:flex;align-items:center;justify-content:center;gap:6px}\n#ruvic-demo .btn-play{background:linear-gradient(180deg,var(--red),#e02d31);color:#fff;box-shadow:0 8px 18px -8px var(--red);gap:0}\n#ruvic-demo .btn-play::before{content:\"\";display:inline-block;width:0;height:0;border-style:solid;border-width:5px 0 5px 9px;border-color:transparent transparent transparent #fff;margin-right:7px;flex-shrink:0}\n#ruvic-demo .btn-play:hover{filter:brightness(1.06);box-shadow:0 8px 18px -8px #ff363a !important}\n#ruvic-demo .btn-play:disabled{background:var(--ghost);color:var(--text3);cursor:not-allowed;box-shadow:none}\n#ruvic-demo .btn-play:disabled::before{border-left-color:var(--text3)}\n#ruvic-demo .btn-rst{background:var(--ghost);color:var(--text2);border:1px solid var(--border)}\n#ruvic-demo .btn-rst:hover{border-color:var(--border2);color:var(--text);box-shadow:none !important}\n#ruvic-demo .speed-row{display:flex;align-items:center;gap:10px}\n#ruvic-demo .speed-row label{font-size:10.5px;color:var(--text3);font-weight:700;white-space:nowrap}\n#ruvic-demo .speed-row input[type=range]{flex:1;height:6px;-webkit-appearance:none;appearance:none;border-radius:4px;outline:none;background:transparent;border:none !important;box-shadow:none !important;padding:0 !important}\n#ruvic-demo[data-theme=\"dark\"] .speed-row input[type=range]{background-color:#0b1125 !important;border-color:#0b1125 !important}\n#ruvic-demo .speed-row input[type=range]::-webkit-slider-runnable-track{height:6px;border-radius:4px;background:rgba(250,240,228,.25);border:none;box-shadow:none}\n#ruvic-demo[data-theme=\"light\"] .speed-row input[type=range]::-webkit-slider-runnable-track{background:rgba(22,26,51,.15)}\n#ruvic-demo .speed-row input[type=range]::-moz-range-track{height:6px;border-radius:4px;background:rgba(250,240,228,.25);border:none}\n#ruvic-demo[data-theme=\"light\"] .speed-row input[type=range]::-moz-range-track{background:rgba(22,26,51,.15)}\n#ruvic-demo .speed-row input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--orange);cursor:pointer;box-shadow:0 2px 8px -1px var(--orange);margin-top:-6px}\n#ruvic-demo .speed-row input[type=range]::-moz-range-thumb{width:18px;height:18px;border:none;border-radius:50%;background:var(--orange);cursor:pointer;box-shadow:0 2px 8px -1px var(--orange)}\n#ruvic-demo .speed-row .sv{font-size:11px;font-weight:800;color:var(--orange);min-width:24px;text-align:right}\n\n\/* ---------------- NODES ---------------- *\/\n#ruvic-demo .nd{position:absolute;display:flex;flex-direction:column;align-items:center;text-align:center;transition:opacity .5s,filter .5s;cursor:default}\n#ruvic-demo .nd.dim{opacity:.14;filter:grayscale(.85)}\n#ruvic-demo .nd.hl{z-index:5}\n#ruvic-demo .nd.clk{cursor:pointer}\n#ruvic-demo .nc{background:linear-gradient(180deg,var(--card-hi),var(--card));border:1.5px solid var(--border);border-radius:14px;padding:9px 11px;display:flex;flex-direction:column;align-items:center;gap:4px;min-width:104px;transition:border-color .35s,box-shadow .35s,transform .25s;box-shadow:var(--nshadow)}\n#ruvic-demo .nd.clk:hover .nc{transform:translateY(-2px);border-color:var(--orange);box-shadow:none !important}\n#ruvic-demo .nc.gp{box-shadow:0 0 28px var(--glow),var(--nshadow);border-color:#7c74e6}\n#ruvic-demo .nc.gt{box-shadow:0 0 28px rgba(16,185,129,.28),var(--nshadow);border-color:#10b981}\n#ruvic-demo .nc.go{box-shadow:0 0 28px rgba(249,115,22,.28),var(--nshadow);border-color:#f97316}\n#ruvic-demo .nc.gb{box-shadow:0 0 28px rgba(59,130,246,.28),var(--nshadow);border-color:#3b82f6}\n#ruvic-demo .nc.gr{box-shadow:0 0 28px rgba(239,68,68,.28),var(--nshadow);border-color:#ef4444}\n#ruvic-demo .nc-core{border:2.5px solid #7c74e6;box-shadow:0 0 40px var(--glow),0 18px 40px -16px rgba(83,74,183,.5);padding:17px 24px;min-width:208px;border-radius:20px;position:relative}\n\/* Iconos \u2014 ahora son <img> con SVG data-URI: aislados 100% del CSS de Kadence *\/\n#ruvic-demo .ic{width:36px !important;height:36px !important;border-radius:50%;display:block !important;flex-shrink:0;transition:transform .3s;box-shadow:0 5px 14px -5px rgba(0,0,0,.45);max-width:none !important;border:none !important;padding:0 !important;vertical-align:middle}\n#ruvic-demo .ic-lg{width:48px !important;height:48px !important;border-radius:14px}\n#ruvic-demo .ic-sm{width:30px !important;height:30px !important;border-radius:8px;box-shadow:0 3px 8px -3px rgba(0,0,0,.4);display:block !important;margin:0 auto !important;flex-shrink:0;max-width:none !important;border:none !important;padding:0 !important;vertical-align:middle}\n#ruvic-demo .ic.pulse{animation:rbNode .6s ease}\n@keyframes rbNode{0%{transform:scale(1)}40%{transform:scale(1.22)}100%{transform:scale(1)}}\n#ruvic-demo .ng{background:linear-gradient(180deg,var(--card-hi),var(--ghost));border:1px solid var(--border);border-radius:10px;padding:7px 10px;min-width:0;width:auto;transition:border-color .35s,box-shadow .35s;text-align:center;box-shadow:var(--nshadow)}\n#ruvic-demo .ng .nt{font-size:10px;white-space:nowrap;overflow:visible;line-height:13px}\n#ruvic-demo .nt{font-size:12px;font-weight:700;color:var(--text);line-height:15px}\n#ruvic-demo .nt-lg{font-size:16px;white-space:nowrap}\n#ruvic-demo .ns{font-size:10px;color:var(--text2);line-height:13px}\n#ruvic-demo .tg{font-size:8px;padding:3px 8px;border-radius:7px;font-weight:800;letter-spacing:.2px}\n#ruvic-demo .sl{position:absolute;font-size:10px;line-height:13px;font-weight:800;text-transform:uppercase;letter-spacing:1.6px;color:var(--text3);pointer-events:none;white-space:nowrap}\n\n\/* ============ RESPONSIVE \/ M\u00d3VIL \u2014 layout 2 columnas, sin diagrama ============ *\/\n#ruvic-demo.is-narrow{padding:14px 10px 20px;border-radius:22px}\n#ruvic-demo.is-narrow .rb-header{padding:2px 4px 14px}\n#ruvic-demo.is-narrow .rb-title{font-size:22px;letter-spacing:-.5px}\n#ruvic-demo.is-narrow .rb-sub{font-size:13px;margin-top:8px}\n#ruvic-demo.is-narrow .rb-theme{top:0}\n\/* Diagrama arriba, panel 2 columnas abajo *\/\n#ruvic-demo.is-narrow .rb-canvas-area{\n  display:block;height:320px;width:100%;\n  border-bottom:1px solid var(--border);touch-action:none;\n}\n#ruvic-demo.is-narrow .rb-hint{display:block}\n#ruvic-demo.is-narrow .rb-hint{display:none}\n\/* Widget: bloque simple, altura autom\u00e1tica *\/\n#ruvic-demo.is-narrow .rb-widget{display:block;height:auto}\n\/* Sidebar: 2 columnas \u2014 casos | tracker+controles *\/\n#ruvic-demo.is-narrow .rb-sb{\n  display:grid;\n  grid-template-columns:58% 42%;\n  grid-template-rows:auto auto 1fr auto;\n  border-left:none;\n  height:420px;\n}\n#ruvic-demo.is-narrow .rb-sb-head{\n  grid-column:1;grid-row:1;\n  border-right:1px solid var(--border);border-bottom:1px solid var(--border);\n  padding:14px 12px;\n}\n#ruvic-demo.is-narrow .rb-sb-head h3{font-size:13px}\n#ruvic-demo.is-narrow .rb-sb-head p{font-size:10px}\n#ruvic-demo.is-narrow .rb-filter{\n  grid-column:1;grid-row:2;\n  border-right:1px solid var(--border);border-bottom:1px solid var(--border);\n  padding:8px 10px;gap:4px;\n  flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;\n}\n#ruvic-demo.is-narrow .rb-cases{\n  grid-column:1;grid-row:3;\n  border-right:1px solid var(--border);\n  max-height:175px;flex:none;\n  overflow-y:auto;\n  padding:8px 10px;\n}\n#ruvic-demo.is-narrow .rb-cases .cb{padding:9px 10px;margin-bottom:6px}\n#ruvic-demo.is-narrow .rb-cases .cb-t{font-size:12px}\n#ruvic-demo.is-narrow .rb-cases .cb-desc{font-size:10px}\n#ruvic-demo.is-narrow .rb-trk{\n  grid-column:2;grid-row:1\/4;\n  max-height:none;border-top:none;\n  overflow-y:auto;\n  padding:12px 10px;\n}\n#ruvic-demo.is-narrow .rb-trk h4{font-size:9.5px}\n#ruvic-demo.is-narrow .stp-nm{font-size:10.5px}\n#ruvic-demo.is-narrow .stp-dt{font-size:9px}\n#ruvic-demo.is-narrow .rb-ctrls{\n  grid-column:1\/3;grid-row:4;\n  padding:8px 12px 12px;\n  border-top:1px solid var(--border);\n}\n#ruvic-demo.is-narrow .btn{font-size:10.5px;padding:9px}\n#ruvic-demo.is-narrow .speed-row label{font-size:9.5px}\n#ruvic-demo.is-narrow .sv{font-size:10px}\n\/* Ajuste tipograf\u00eda xnarrow *\/\n#ruvic-demo.is-xnarrow{padding:10px 8px 16px}\n#ruvic-demo.is-xnarrow .rb-title{font-size:19px}\n#ruvic-demo.is-xnarrow .rb-eyebrow{font-size:9px;letter-spacing:1.4px;padding:5px 9px}\n#ruvic-demo.is-xnarrow .rb-sb-head{padding:10px}\n#ruvic-demo.is-xnarrow .rb-theme{transform:scale(.9);transform-origin:top right}\n\n\n\/* Kadence theme overrides *\/\n#ruvic-demo button:hover{box-shadow:none !important}\n#ruvic-demo button{line-height:14px}\n@media (prefers-reduced-motion:reduce){\n  #ruvic-demo *{animation-duration:.001ms!important;transition-duration:.08s!important}\n}\n\n\/* Nuclear reset \u2014 Kadence body\/global-palette color bleed fix\n   \"body #ruvic-demo\" tiene especificidad (0,1,1) y gana a \"body{color:...}\" de Kadence (0,0,1) *\/\nbody #ruvic-demo{color:#faf0e4}\nbody #ruvic-demo[data-theme=\"light\"]{color:#161a33}\nbody #ruvic-demo .nt{color:var(--text) !important}\nbody #ruvic-demo .ns{color:var(--text2) !important}\nbody #ruvic-demo .nt-lg{color:var(--text) !important}\nbody #ruvic-demo .stp-nm{color:var(--text) !important}\nbody #ruvic-demo .stp-dt{color:var(--text2) !important}\nbody #ruvic-demo .rb-sb-head h3{color:var(--text) !important}\nbody #ruvic-demo .rb-sb-head p{color:var(--text3) !important}\nbody #ruvic-demo .cb-t{color:var(--text) !important}\nbody #ruvic-demo .cb-desc{color:var(--text2) !important}\nbody #ruvic-demo .rb-trk h4{color:var(--text3) !important}\nbody #ruvic-demo .rb-title{color:var(--text) !important}\nbody #ruvic-demo .rb-sub{color:var(--text2) !important}\nbody #ruvic-demo .speed-row label{color:var(--text3) !important}\nbody #ruvic-demo .sv{color:var(--orange) !important}\n\n<\/style>\n\n<div id=\"ruvic-bg\">\n<div id=\"ruvic-demo\" data-theme=\"dark\">\n\n  <header class=\"rb-header\">\n    <button class=\"rb-theme\" id=\"rb-theme\" type=\"button\" aria-label=\"Cambiar tema claro\/oscuro\">\n      <span class=\"knob\"><\/span>\n      <i class=\"moon\">\u263e<\/i>\n      <i class=\"sun\"><svg viewBox=\"0 0 24 24\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"display:block\"><circle cx=\"12\" cy=\"12\" r=\"4\"\/><path d=\"M12 2.5v2.2M12 19.3v2.2M5.1 5.1l1.5 1.5M17.4 17.4l1.5 1.5M2.5 12h2.2M19.3 12h2.2M5.1 18.9l1.5-1.5M17.4 6.6l1.5-1.5\"\/><\/svg><\/i>\n    <\/button>\n    <span class=\"rb-eyebrow\"><span class=\"pd\"><\/span>Demo interactiva<\/span>\n    <h2 class=\"rb-title\">Mira c\u00f3mo Ruvic orquesta el flujo <span class=\"ac\">en tiempo real<\/span><\/h2>\n    <p class=\"rb-sub\">Selecciona un caso de uso y reproduce el flujo completo de principio a fin.<\/p>\n  <\/header>\n\n  <div class=\"rb-widget\" id=\"rb-widget\">\n    <div class=\"rb-canvas-area\" id=\"rb-ca\">\n      <div class=\"rb-zp\" id=\"rb-zp\">\n        <canvas id=\"rb-fc\"><\/canvas>\n        <div class=\"rb-nl\" id=\"rb-nl\"><\/div>\n      <\/div>\n      <div class=\"rb-hint\">Arrastra para mover \u00b7 pellizca para hacer zoom<\/div>\n    <\/div>\n    <aside class=\"rb-sb\">\n      <div class=\"rb-sb-head\">\n        <div class=\"rb-mark\">R<\/div>\n        <div>\n          <h3><b>Ruvic AI<\/b> \u00b7 Casos de uso<\/h3>\n          <p>Haz clic en un canal o elige un caso para ver el flujo de ida y vuelta<\/p>\n        <\/div>\n      <\/div>\n      <div class=\"rb-filter\" id=\"rb-filters\"><\/div>\n      <div class=\"rb-cases\" id=\"rb-cl\"><\/div>\n      <div class=\"rb-trk\" id=\"rb-trk\">\n        <h4>Flujo activo<\/h4>\n        <p class=\"rb-empty\">Selecciona un caso de uso para visualizar cada paso.<\/p>\n      <\/div>\n      <div class=\"rb-ctrls\">\n        <div class=\"rb-ctrls-row\">\n          <button class=\"btn btn-play\" id=\"rb-pb\" type=\"button\" disabled>Reproducir flujo<\/button>\n          <button class=\"btn btn-rst\" id=\"rb-rst\" type=\"button\">\u21ba Reiniciar<\/button>\n        <\/div>\n        <div class=\"speed-row\">\n          <label for=\"rb-spd\">Velocidad<\/label>\n          <input type=\"range\" min=\"1\" max=\"5\" value=\"3\" id=\"rb-spd\">\n          <span class=\"sv\" id=\"rb-spdV\">3x<\/span>\n        <\/div>\n      <\/div>\n    <\/aside>\n  <\/div>\n<\/div>\n<\/div>\n\n<script>\n(function(){\n\"use strict\";\nconst root=document.getElementById('ruvic-demo');\n\n\/* ---------------- DATOS (sin cambios de contenido) ---------------- *\/\nconst N={\n  'whatsapp':{x:13,y:11,l:'WhatsApp',c:'#25D366',lt:'W',t:'ch'},\n  'telegram':{x:13,y:25,l:'Telegram',c:'#0088cc',lt:'T',t:'ch'},\n  'email':{x:13,y:40,l:'Correo electr\u00f3nico',c:'#EA4335',lt:'E',t:'ch'},\n  'voice':{x:13,y:54,l:'Voz \/ SIP',c:'#378ADD',lt:'V',t:'ch'},\n  'api':{x:13,y:68,l:'API directa',c:'#4a5568',lt:'{}',t:'ch'},\n  'widget':{x:13,y:81,l:'Widget web',c:'#7c3aed',lt:'JS',t:'ch'},\n\n  'engine':{x:41,y:43,l:'Ruvic AI Engine',c:'#534AB7',lt:'R',t:'core'},\n  'memory':{x:34,y:66,l:'Memoria',c:'#10b981',lt:'M',t:'sub'},\n  'queue':{x:46,y:66,l:'Cola de mensajes',c:'#f97316',lt:'Q',t:'sub'},\n\n  'gpt4o':{x:25,y:84,l:'GPT-4o',c:'#10a37f',lt:'G',t:'llm'},\n  'gemini':{x:35,y:84,l:'Gemini',c:'#4285F4',lt:'G',t:'llm'},\n  'claude':{x:45,y:84,l:'Claude',c:'#d4537e',lt:'C',t:'llm'},\n  'deepseek':{x:55,y:84,l:'DeepSeek',c:'#3B6D11',lt:'D',t:'llm'},\n\n  'agent-conv':{x:68,y:15,l:'Agente conversacional',c:'#10b981',lt:'C',t:'ag'},\n  'agent-voz':{x:68,y:29,l:'Agente de voz',c:'#3b82f6',lt:'V',t:'ag'},\n  'agent-soporte':{x:68,y:43,l:'Agente de soporte',c:'#f97316',lt:'S',t:'ag'},\n  'agent-fact':{x:68,y:58,l:'Agente de facturaci\u00f3n',c:'#eab308',lt:'F',t:'ag'},\n  'agent-anal':{x:68,y:73,l:'Agente de an\u00e1lisis',c:'#8b5cf6',lt:'A',t:'ag'},\n\n  'crm':{x:87,y:11,l:'CRM',c:'#3b82f6',t:'cn',sub:'Salesforce, HubSpot'},\n  'erp':{x:87,y:25,l:'ERP',c:'#3b82f6',t:'cn',sub:'SAP, Dynamics 365'},\n  'ticketing':{x:87,y:40,l:'Mesa de ayuda',c:'#3b82f6',t:'cn',sub:'Jira, Freshdesk'},\n  'fact-elec':{x:87,y:54,l:'Facturaci\u00f3n electr\u00f3nica',c:'#ef4444',t:'cn',sub:'DIAN, SII, SUNAT'},\n  'google-ws':{x:87,y:68,l:'Google Workspace',c:'#3b82f6',t:'cn',sub:'Sheets, Drive, Calendar'},\n  'slack':{x:87,y:82,l:'Slack \/ Teams',c:'#3b82f6',t:'cn',sub:'Notificaciones'},\n\n  'postgresql':{x:13,y:95,l:'PostgreSQL',c:'#10b981',t:'dt'},\n  'mongodb':{x:27,y:95,l:'MongoDB',c:'#10b981',t:'dt'},\n  'redis':{x:41,y:95,l:'Redis',c:'#10b981',t:'dt'},\n  'archivos':{x:56,y:95,l:'Archivos',c:'#f97316',t:'dt'},\n  'storage':{x:71,y:95,l:'Almacenamiento',c:'#10b981',t:'dt'},\n  'audio':{x:87,y:95,l:'Audio',c:'#f97316',t:'dt'},\n};\n\nconst CS=[\n{id:'wa-sup',ch:'whatsapp',t:'Soporte al cliente v\u00eda WhatsApp',d:'Un cliente consulta el estado de su pedido. Ruvic busca en el CRM y responde autom\u00e1ticamente.',kpi:'Reduce tiempo de respuesta un 60%',\n path:['whatsapp','engine','memory','claude','agent-conv','crm','agent-conv','engine','whatsapp'],\n steps:[\n  {n:'WhatsApp',dt:'El cliente env\u00eda: \"\u00bfD\u00f3nde est\u00e1 mi pedido #4521?\"',c:'#25D366',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica la intenci\u00f3n: consulta de estado de pedido',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Recupera el contexto previo del cliente',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Genera una consulta estructurada para el CRM',c:'#d4537e',dir:'out'},\n  {n:'Agente conversacional',dt:'Ejecuta la consulta y formatea la respuesta',c:'#10b981',dir:'out'},\n  {n:'CRM',dt:'Salesforce retorna: pedido en camino, llega ma\u00f1ana',c:'#3b82f6',dir:'ret'},\n  {n:'Agente conversacional',dt:'Compone respuesta amigable para el cliente',c:'#10b981',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Valida la respuesta y la enruta al canal de salida',c:'#534AB7',dir:'ret'},\n  {n:'WhatsApp',dt:'Responde: \"Tu pedido #4521 est\u00e1 en camino \\uD83D\\uDCE6\"',c:'#25D366',dir:'ret'},\n]},\n{id:'wa-tkt',ch:'whatsapp',t:'Crear ticket desde WhatsApp',d:'Un cliente reporta un problema t\u00e9cnico. Ruvic crea un ticket en Jira autom\u00e1ticamente.',kpi:'Reduce creaci\u00f3n de tickets un 55%',\n path:['whatsapp','engine','memory','gpt4o','agent-soporte','ticketing','agent-soporte','engine','whatsapp'],\n steps:[\n  {n:'WhatsApp',dt:'El cliente escribe: \"Mi factura tiene un error en el monto\"',c:'#25D366',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como incidencia t\u00e9cnica, prioridad media',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga el historial de tickets previos del cliente',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Extrae detalles: tipo de error, n\u00famero de factura, monto',c:'#10a37f',dir:'out'},\n  {n:'Agente de soporte',dt:'Formatea el ticket con los campos requeridos',c:'#f97316',dir:'out'},\n  {n:'Mesa de ayuda',dt:'Jira crea ticket BILL-892: \"Error en factura #1204\"',c:'#3b82f6',dir:'ret'},\n  {n:'Agente de soporte',dt:'Confirma la creaci\u00f3n y obtiene n\u00famero de ticket',c:'#f97316',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Enruta la confirmaci\u00f3n al canal original',c:'#534AB7',dir:'ret'},\n  {n:'WhatsApp',dt:'Responde: \"Ticket BILL-892 creado, te notificaremos\"',c:'#25D366',dir:'ret'},\n]},\n{id:'tg-info',ch:'telegram',t:'Consulta de informaci\u00f3n por Telegram',d:'Un empleado consulta pol\u00edticas internas. Ruvic busca en la base de conocimiento.',kpi:'Ahorra 40 min diarios por empleado',\n path:['telegram','engine','memory','gemini','agent-conv','google-ws','agent-conv','engine','telegram'],\n steps:[\n  {n:'Telegram',dt:'El empleado pregunta: \"\u00bfCu\u00e1l es la pol\u00edtica de vacaciones?\"',c:'#0088cc',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como consulta interna, base de conocimiento',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Identifica al empleado y sus permisos de acceso',c:'#10b981',dir:'out'},\n  {n:'Gemini',dt:'Realiza b\u00fasqueda sem\u00e1ntica en documentos corporativos',c:'#4285F4',dir:'out'},\n  {n:'Agente conversacional',dt:'Procesa el resultado y extrae la secci\u00f3n relevante',c:'#10b981',dir:'out'},\n  {n:'Google Workspace',dt:'Drive retorna: Pol\u00edtica_RRHH_2026.pdf, p\u00e1gina 12',c:'#3b82f6',dir:'ret'},\n  {n:'Agente conversacional',dt:'Resume la pol\u00edtica en lenguaje claro',c:'#10b981',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Formatea la respuesta y la enruta',c:'#534AB7',dir:'ret'},\n  {n:'Telegram',dt:'Responde con el resumen y un enlace al documento',c:'#0088cc',dir:'ret'},\n]},\n{id:'em-inv',ch:'email',t:'Procesamiento autom\u00e1tico de facturas',d:'Ruvic recibe una factura por correo, la valida y la registra en el sistema contable.',kpi:'Reduce errores de facturaci\u00f3n un 80%',\n path:['email','engine','memory','claude','agent-fact','fact-elec','agent-fact','engine','email'],\n steps:[\n  {n:'Correo electr\u00f3nico',dt:'El proveedor env\u00eda una factura adjunta en PDF',c:'#EA4335',dir:'out'},\n  {n:'Ruvic Engine',dt:'Detecta el adjunto PDF y lo clasifica como factura',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Verifica al proveedor en la base de datos',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'OCR y extracci\u00f3n: NIT, monto, \u00edtems, impuestos',c:'#d4537e',dir:'out'},\n  {n:'Agente de facturaci\u00f3n',dt:'Valida los datos fiscales contra las reglas de la DIAN',c:'#eab308',dir:'out'},\n  {n:'Facturaci\u00f3n electr\u00f3nica',dt:'La DIAN valida y registra la factura electr\u00f3nica',c:'#ef4444',dir:'ret'},\n  {n:'Agente de facturaci\u00f3n',dt:'Registra en el sistema contable y genera el asiento',c:'#eab308',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Prepara la confirmaci\u00f3n con el n\u00famero de radicado',c:'#534AB7',dir:'ret'},\n  {n:'Correo electr\u00f3nico',dt:'Responde: \"Factura FE-2026-4521 radicada con \u00e9xito\"',c:'#EA4335',dir:'ret'},\n]},\n{id:'vz-cc',ch:'voice',t:'Centro de llamadas inteligente',d:'Una llamada de cliente se transcribe en tiempo real. Ruvic resuelve sin agente humano.',kpi:'Reduce tiempos de espera un 60%',\n path:['voice','engine','memory','deepseek','agent-voz','crm','agent-voz','engine','voice'],\n steps:[\n  {n:'Voz \/ SIP',dt:'El cliente llama: audio en streaming v\u00eda WebSocket',c:'#378ADD',dir:'out'},\n  {n:'Ruvic Engine',dt:'Transcripci\u00f3n en tiempo real (STT), clasifica intenci\u00f3n',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Identifica al cliente por n\u00famero, carga su perfil',c:'#10b981',dir:'out'},\n  {n:'DeepSeek',dt:'Analiza la intenci\u00f3n: cambio de plan de servicio',c:'#3B6D11',dir:'out'},\n  {n:'Agente de voz',dt:'Consulta los planes disponibles seg\u00fan el perfil',c:'#3b82f6',dir:'out'},\n  {n:'CRM',dt:'Retorna: plan actual Bronce, elegible para Plata',c:'#3b82f6',dir:'ret'},\n  {n:'Agente de voz',dt:'Genera respuesta de voz (TTS) con las opciones',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Env\u00eda el audio de respuesta en streaming',c:'#534AB7',dir:'ret'},\n  {n:'Voz \/ SIP',dt:'El cliente escucha las opciones y confirma el cambio',c:'#378ADD',dir:'ret'},\n]},\n{id:'api-an',ch:'api',t:'An\u00e1lisis de datos v\u00eda API',d:'Un sistema externo solicita un reporte. Ruvic consulta la base de datos y retorna JSON.',kpi:'Genera reportes en 3 segundos',\n path:['api','engine','memory','gpt4o','agent-anal','postgresql','agent-anal','engine','api'],\n steps:[\n  {n:'API directa',dt:'GET \/analytics\/ventas?periodo=Q1-2026',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Autentica la API key, clasifica como consulta anal\u00edtica',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Cach\u00e9: verifica si hay un reporte reciente en Redis',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Genera una consulta SQL optimizada para el reporte',c:'#10a37f',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'Ejecuta la consulta con par\u00e1metros seguros',c:'#8b5cf6',dir:'out'},\n  {n:'PostgreSQL',dt:'Retorna 1.247 registros de ventas del Q1',c:'#10b981',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Procesa, agrega, calcula KPIs y tendencias',c:'#8b5cf6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Formatea la respuesta JSON estructurada',c:'#534AB7',dir:'ret'},\n  {n:'API directa',dt:'Retorna: {ingresos: $142K, crecimiento: +23%}',c:'#4a5568',dir:'ret'},\n]},\n{id:'wg-lead',ch:'widget',t:'Captura de prospectos desde el sitio web',d:'Un visitante chatea en el widget. Ruvic califica al prospecto y lo registra en HubSpot.',kpi:'Aumenta conversi\u00f3n de leads un 35%',\n path:['widget','engine','memory','gemini','agent-conv','crm','agent-conv','engine','widget'],\n steps:[\n  {n:'Widget web',dt:'El visitante escribe: \"Quiero conocer los precios\"',c:'#7c3aed',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como prospecto potencial, inicia calificaci\u00f3n',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Nuevo visitante, se crea un perfil temporal',c:'#10b981',dir:'out'},\n  {n:'Gemini',dt:'Genera preguntas de calificaci\u00f3n BANT',c:'#4285F4',dir:'out'},\n  {n:'Agente conversacional',dt:'Conversa: tama\u00f1o de empresa, presupuesto, plazo',c:'#10b981',dir:'out'},\n  {n:'CRM',dt:'HubSpot: crea contacto y oportunidad, puntaje 78\/100',c:'#3b82f6',dir:'ret'},\n  {n:'Agente conversacional',dt:'Agenda una demostraci\u00f3n con el equipo de ventas',c:'#10b981',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Notifica al equipo de ventas v\u00eda Slack',c:'#534AB7',dir:'ret'},\n  {n:'Widget web',dt:'Responde: \"Demo agendada para el jueves a las 2 p.m.\"',c:'#7c3aed',dir:'ret'},\n]},\n{id:'wa-fac',ch:'whatsapp',t:'Consulta de facturaci\u00f3n por WhatsApp',d:'Un cliente solicita copia de su factura. Ruvic la busca y la env\u00eda como PDF.',kpi:'Respuesta en menos de 10 segundos',\n path:['whatsapp','engine','memory','gpt4o','agent-fact','fact-elec','agent-fact','engine','whatsapp'],\n steps:[\n  {n:'WhatsApp',dt:'El cliente escribe: \"Necesito mi factura de febrero\"',c:'#25D366',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como solicitud de documento de facturaci\u00f3n',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Identifica al cliente, NIT e historial de facturas',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Interpreta \"febrero\" como el rango 2026-02-01 a 2026-02-28',c:'#10a37f',dir:'out'},\n  {n:'Agente de facturaci\u00f3n',dt:'Busca la factura en el sistema de facturaci\u00f3n',c:'#eab308',dir:'out'},\n  {n:'Facturaci\u00f3n electr\u00f3nica',dt:'Retorna el PDF de la factura FE-2026-0287',c:'#ef4444',dir:'ret'},\n  {n:'Agente de facturaci\u00f3n',dt:'Prepara el archivo para env\u00edo por WhatsApp',c:'#eab308',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Enruta el documento al canal de salida',c:'#534AB7',dir:'ret'},\n  {n:'WhatsApp',dt:'Env\u00eda el PDF y el mensaje: \"Aqu\u00ed est\u00e1 tu factura \\uD83D\\uDCC4\"',c:'#25D366',dir:'ret'},\n]},\n{id:'em-rh',ch:'email',t:'Gesti\u00f3n de recursos humanos automatizada',d:'Un empleado solicita un permiso por correo. Ruvic lo valida, aprueba y notifica.',kpi:'Aprobaci\u00f3n en menos de 1 minuto',\n path:['email','engine','memory','claude','agent-soporte','google-ws','agent-soporte','engine','email'],\n steps:[\n  {n:'Correo electr\u00f3nico',dt:'El empleado solicita permiso para el viernes 21',c:'#EA4335',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como solicitud de RRHH, tipo permiso',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Verifica el saldo de permisos del empleado',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Valida la pol\u00edtica: tiene 3 d\u00edas disponibles',c:'#d4537e',dir:'out'},\n  {n:'Agente de soporte',dt:'Crea la solicitud formal y la env\u00eda al aprobador',c:'#f97316',dir:'out'},\n  {n:'Google Workspace',dt:'Calendar: verifica conflictos, registra la ausencia',c:'#3b82f6',dir:'ret'},\n  {n:'Agente de soporte',dt:'Registra la aprobaci\u00f3n autom\u00e1tica (pol\u00edtica cumplida)',c:'#f97316',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera la confirmaci\u00f3n y las notificaciones',c:'#534AB7',dir:'ret'},\n  {n:'Correo electr\u00f3nico',dt:'Responde: \"Permiso aprobado. Saldo restante: 2 d\u00edas\"',c:'#EA4335',dir:'ret'},\n]},\n{id:'tg-sec',ch:'telegram',t:'Monitoreo de seguridad proactivo',d:'Ruvic detecta una anomal\u00eda en los logs, la analiza y alerta al equipo v\u00eda Telegram.',kpi:'Reduce incidentes de seguridad un 50%',\n path:['api','engine','memory','deepseek','agent-anal','postgresql','agent-anal','engine','telegram'],\n steps:[\n  {n:'API (webhook)',dt:'Alerta autom\u00e1tica: m\u00e1s de 50 intentos de inicio de sesi\u00f3n fallidos',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como incidente de seguridad, prioridad alta',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Correlaciona con incidentes previos de la misma IP',c:'#10b981',dir:'out'},\n  {n:'DeepSeek',dt:'Analiza el patr\u00f3n: fuerza bruta desde la IP 45.33.x.x',c:'#3B6D11',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'Consulta logs detallados y geolocaliza la IP',c:'#8b5cf6',dir:'out'},\n  {n:'PostgreSQL',dt:'Retorna: 847 intentos en 10 minutos, origen Rusia',c:'#10b981',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Genera reporte del incidente con recomendaciones',c:'#8b5cf6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Bloquea la IP autom\u00e1ticamente, prepara la alerta',c:'#534AB7',dir:'ret'},\n  {n:'Telegram',dt:'Alerta al equipo: \"\\uD83D\\uDEA8 IP bloqueada, ver reporte adjunto\"',c:'#0088cc',dir:'ret'},\n]}\n];\n\nconst CHANNELS=[\n  {id:'all',l:'Todos',c:'#6b7280'},\n  {id:'whatsapp',l:'WhatsApp',c:'#25D366'},\n  {id:'telegram',l:'Telegram',c:'#0088cc'},\n  {id:'email',l:'Correo',c:'#EA4335'},\n  {id:'voice',l:'Voz',c:'#378ADD'},\n  {id:'api',l:'API',c:'#4a5568'},\n  {id:'widget',l:'Widget',c:'#7c3aed'},\n];\n\n\/* ---------------- ESTADO ---------------- *\/\nlet ac=null,anim=false,cs=0,dots=[],hl=new Set(),W,H,cvs,ctx,filt='all',spd=3,advTmr=null,isNarrow=false;\nconst $=id=>root.querySelector('#'+id);\nconst widget=$('rb-widget'),ca=$('rb-ca'),zp=$('rb-zp');\n\nfunction lineIdle(){return root.dataset.theme==='light'?'rgba(34,38,71,0.14)':'rgba(250,240,228,0.12)';}\n\n\/* ---------------- INIT ---------------- *\/\nfunction init(){\n  cvs=$('rb-fc');ctx=cvs.getContext('2d');\n  renderFilters();renderCases();\n  \/\/ Doble rAF: garantiza que el browser ya calcul\u00f3 dimensiones reales (importante en WP)\n  requestAnimationFrame(()=>requestAnimationFrame(applyLayout));\n  window.addEventListener('load',applyLayout);\n  \/\/ listeners\n  $('rb-pb').addEventListener('click',play);\n  $('rb-rst').addEventListener('click',reset);\n  $('rb-spd').addEventListener('input',updSpd);\n  $('rb-theme').addEventListener('click',toggleTheme);\n  ca.addEventListener('click',e=>{ if(!didPan ? (e.target===cvs ? true : e.target===ca ? true : e.target===zp) : false) reset(); });\n  \/\/ tema guardado\n  try{const sv=localStorage.getItem('ruvicTheme');if(sv)root.dataset.theme=sv;}catch(e){}\n  \/\/ decidir layout: load + resize + orientationchange (+ ResizeObserver si est\u00e1 disponible)\n  let rt;\n  window.addEventListener('resize',()=>{clearTimeout(rt);rt=setTimeout(applyLayout,120);});\n  window.addEventListener('orientationchange',()=>setTimeout(applyLayout,250));\n  if(window.ResizeObserver){let raf;new ResizeObserver(()=>{cancelAnimationFrame(raf);raf=requestAnimationFrame(applyLayout);}).observe(widget);}\n  setupTouch();\n  requestAnimationFrame(dr);\n}\n\nfunction toggleTheme(){\n  const next=root.dataset.theme==='light'?'dark':'light';\n  root.dataset.theme=next;\n  try{localStorage.setItem('ruvicTheme',next);}catch(e){}\n}\n\n\/* ---------------- LAYOUT (desktop vs m\u00f3vil) ---------------- *\/\nfunction applyLayout(){\n  isNarrow=widget.clientWidth<760;\n  root.classList.toggle('is-narrow',isNarrow);\n  root.classList.toggle('is-xnarrow',widget.clientWidth<440);\n  rsz();renderNodes();\n  if(isNarrow){recalcZoom();}else{resetTransform();}\n}\n\nfunction rsz(){\n  const dp=window.devicePixelRatio ? window.devicePixelRatio : 1;\n  if(isNarrow){W=1400;H=900;}\n  else{W=ca.clientWidth;H=ca.clientHeight;}\n  cvs.width=W*dp;cvs.height=H*dp;\n  cvs.style.width=W+'px';cvs.style.height=H+'px';\n  const nl=$('rb-nl');\n  nl.style.width=W+'px';nl.style.height=H+'px';\n  zp.style.width=W+'px';zp.style.height=H+'px';\n  ctx.setTransform(dp,0,0,dp,0,0);\n}\n\nfunction p(id){const n=N[id];return{x:n.x\/100*W,y:n.y\/100*H};}\n\n\/* ---------------- RENDER: filtros \/ casos ---------------- *\/\nfunction renderFilters(){\n  $('rb-filters').innerHTML=CHANNELS.map(c=>\n    `<button class=\"fb${filt===c.id?' act':''}\" data-f=\"${c.id}\" type=\"button\"\n       style=\"${filt===c.id?'background:'+c.c+';color:#fff;border-color:'+c.c:''}\">${c.l}<\/button>`).join('');\n  $('rb-filters').querySelectorAll('.fb').forEach(b=>b.addEventListener('click',()=>setFilt(b.dataset.f)));\n}\nfunction setFilt(f){\n  filt=f;renderFilters();\n  if(f==='all'){renderCases();return;}\n  const m=CS.filter(c=>c.ch===f);if(m.length)sel(CS.indexOf(m[0]));else renderCases();\n}\n\nfunction renderCases(){\n  const el=$('rb-cl');\n  const filtered=filt==='all'?CS:CS.filter(c=>c.ch===filt);\n  if(!filtered.length){el.innerHTML='<p class=\"rb-empty\" style=\"padding:18px;text-align:center\">No hay casos para este canal<\/p>';return;}\n  el.innerHTML=filtered.map(c=>{\n    const ri=CS.indexOf(c);const ch=N[c.path[0]];\n    return`<button class=\"cb${(ac ? ac.id===c.id : false) ? ' act' : ''}\" data-i=\"${ri}\" type=\"button\" style=\"--cbc:${ch.c}\">\n      <div class=\"cb-ch\"><span class=\"d\" style=\"background:${ch.c}\"><\/span>${ch.l}<\/div>\n      <div class=\"cb-t\">${c.t}<\/div>\n      <div class=\"cb-desc\">${c.d}<\/div>\n      <div class=\"cb-kpi\">\u25b2 ${c.kpi}<\/div>\n    <\/button>`;}).join('');\n  el.querySelectorAll('.cb').forEach(b=>b.addEventListener('click',()=>sel(+b.dataset.i)));\n}\n\n\/* ---------------- RENDER: nodos ---------------- *\/\nfunction renderNodes(){\n  const ly=$('rb-nl');ly.innerHTML='';\n  const labels=[\n    {t:'Canales',x:13,y:1.5},{t:'Ruvic Engine',x:41,y:1.5},\n    {t:'Orquestaci\u00f3n',x:68,y:1.5},{t:'Conectores',x:88,y:1.5},\n    {t:'Datos \u00b7 Archivos \u00b7 Almacenamiento',x:50,y:89}\n  ];\n  labels.forEach(l=>{\n    const e=document.createElement('div');e.className='sl';\n    e.style.cssText=`left:${l.x}%;top:${l.y}%;transform:translateX(-50%)`;e.textContent=l.t;ly.appendChild(e);\n  });\n\n  Object.entries(N).forEach(([id,n])=>{\n    const e=document.createElement('div');\n    const dim=(hl.size>0 ? !hl.has(id) : false) ? ' dim' : '';\n    const hlc=hl.has(id)?' hl':'';\n    const clk=n.t==='ch'?' clk':'';\n    e.className='nd'+dim+hlc+clk;e.id='rb-nd-'+id;\n    let gc='';\n    if(hl.has(id)){\n      if(n.t==='ch')gc='gt';else if(n.t==='core' ? true : n.t==='sub' ? true : n.t==='llm')gc='gp';\n      else if(n.t==='ag')gc='go';else if(n.t==='cn')gc=n.c==='#ef4444'?'gr':'gb';else gc='gb';\n    }\n    e.style.cssText=`left:${n.x}%;top:${n.y}%;transform:translate(-50%,-50%)`;\n    \/\/ Icono como <canvas>: caja de color + letra se DIBUJAN como p\u00edxeles.\n    \/\/ Los p\u00edxeles de un canvas son 100% inmunes al CSS de Kadence Y a cualquier\n    \/\/ plugin de WordPress (lazy-load, optimizador de im\u00e1genes, sanitizador, CSP).\n    \/\/ Es la \u00fanica t\u00e9cnica que no puede fallar por configuraci\u00f3n externa.\n    function svgIc(icId,color,letter,w,h,rx,fs,cls){\n      return `<canvas id=\"rb-ic-${icId}\" class=\"${cls}\" data-w=\"${w}\" data-h=\"${h}\" data-rx=\"${rx}\" data-fs=\"${fs}\" data-color=\"${color}\" data-letter=\"${letter}\"><\/canvas>`;\n    }\n    if(n.t==='core'){\n      e.innerHTML=`<div class=\"nc nc-core ${gc}\">${svgIc(id,n.c,n.lt,48,48,12,20,'ic ic-lg')}<div class=\"nt nt-lg\">${n.l}<\/div><div class=\"ns\">Orquestaci\u00f3n multi-agente<\/div><div style=\"display:flex;gap:5px;margin-top:8px;flex-wrap:wrap;justify-content:center\"><span class=\"tg\" style=\"background:rgba(139,128,255,.22);color:#a59cff\">Clasificador<\/span><span class=\"tg\" style=\"background:rgba(139,128,255,.22);color:#a59cff\">Enrutador LLM<\/span><span class=\"tg\" style=\"background:rgba(16,185,129,.22);color:#34d399\">Contexto<\/span><\/div><\/div>`;\n    }else if(n.t==='ch'){\n      e.addEventListener('click',()=>filterCh(id));\n      e.innerHTML=`<div class=\"nc ${gc}\">${svgIc(id,n.c,n.lt,36,36,18,13,'ic')}<div class=\"nt\">${n.l}<\/div><\/div>`;\n    }else if(n.t==='ag'){\n      e.innerHTML=`<div class=\"nc ${gc}\">${svgIc(id,n.c,n.lt,36,36,18,13,'ic')}<div class=\"nt\">${n.l}<\/div><\/div>`;\n    }else if(n.t==='sub' ? true : n.t==='llm'){\n      e.innerHTML=`<div class=\"ng ${gc}\" style=\"text-align:center\">${svgIc(id,n.c,n.lt,30,30,8,14,'ic-sm')}<div class=\"nt\" style=\"font-size:10.5px;margin-top:5px\">${n.l}<\/div><\/div>`;\n    }else if(n.t==='cn'){\n      e.innerHTML=`<div class=\"nc ${gc}\" style=\"min-width:128px\"><div class=\"nt\">${n.l}<\/div>${n.sub?'<div class=\"ns\">'+n.sub+'<\/div>':''}<\/div>`;\n    }else{\n      e.innerHTML=`<div class=\"ng ${gc}\" style=\"min-width:auto;white-space:nowrap\"><div class=\"nt\" style=\"font-size:11px\">${n.l}<\/div><\/div>`;\n    }\n    ly.appendChild(e);\n  });\n  \/\/ Dibuja cada icono en su canvas (caja + letra como p\u00edxeles, inmune a CSS\/plugins)\n  ly.querySelectorAll('canvas[data-letter]').forEach(drawIc);\n}\n\n\/* Dibuja un icono (rect redondeado + letra blanca) en un <canvas> *\/\nfunction drawIc(cv){\n  const w=+cv.dataset.w,h=+cv.dataset.h,rx=Math.min(+cv.dataset.rx,w\/2,h\/2),fs=+cv.dataset.fs;\n  const color=cv.dataset.color,letter=cv.dataset.letter;\n  const dpr=window.devicePixelRatio||1;\n  cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);\n  cv.style.width=w+'px';cv.style.height=h+'px';\n  const x=cv.getContext('2d');\n  x.scale(dpr,dpr);\n  x.clearRect(0,0,w,h);\n  \/\/ rect redondeado\n  x.beginPath();\n  x.moveTo(rx,0);\n  x.arcTo(w,0,w,h,rx);\n  x.arcTo(w,h,0,h,rx);\n  x.arcTo(0,h,0,0,rx);\n  x.arcTo(0,0,w,0,rx);\n  x.closePath();\n  x.fillStyle=color;x.fill();\n  \/\/ letra blanca centrada\n  x.fillStyle='#ffffff';\n  x.font='800 '+fs+'px system-ui,-apple-system,\"Segoe UI\",sans-serif';\n  x.textAlign='center';x.textBaseline='middle';\n  x.fillText(letter,w\/2,h\/2+0.5);\n}\n\n\/* ---------------- RENDER: tracker ---------------- *\/\nfunction renderSteps(c){\n  const t=$('rb-trk');\n  t.innerHTML=`<h4>Flujo activo <span>0 \/ ${c.steps.length}<\/span><\/h4>`+\n    c.steps.map((s,i)=>`<div class=\"stp\" id=\"rb-s-${i}\"><div class=\"stp-n\" id=\"rb-sn-${i}\" style=\"background:${s.c}\">${i+1}<\/div><div class=\"stp-i\"><div class=\"stp-nm\">${s.dir==='ret'?'\u2190 ':'\u2192 '}${s.n}<\/div><div class=\"stp-dt\">${s.dt}<\/div><\/div><\/div>`).join('');\n}\n\n\/* ---------------- INTERACCI\u00d3N ---------------- *\/\nfunction sel(i){\n  if(advTmr){clearTimeout(advTmr);advTmr=null;}\n  ac=CS[i];cs=0;dots=[];anim=false;\n  hl=new Set(ac.path);renderNodes();renderSteps(ac);renderCases();\n  $('rb-pb').disabled=false;\n}\nfunction filterCh(id){\n  filt=id;renderFilters();renderCases();\n  const m=CS.filter(c=>c.ch===id);if(m.length)sel(CS.indexOf(m[0]));\n}\nfunction updSpd(){spd=+$('rb-spd').value;$('rb-spdV').textContent=spd+'x';}\n\nfunction play(){\n  if(!ac ? true : anim)return;anim=true;cs=0;dots=[];\n  $('rb-pb').disabled=true;advance();\n}\nfunction advance(){\n  if(!ac ? true : cs>=ac.path.length-1){anim=false;$('rb-pb').disabled=false;return;}\n  const se=$('rb-s-'+cs);\n  if(se){\n    se.classList.add('on');\n    const trk=$('rb-trk');\n    trk.scrollTo({top:Math.max(0,se.offsetTop-trk.offsetTop-18),behavior:'smooth'});\n  }\n  for(let i=0;i<cs;i++){const pe=$('rb-s-'+i);if(pe){pe.classList.remove('on');pe.classList.add('dn');}}\n  const h4=$('rb-trk').querySelector('h4 span');if(h4)h4.textContent=(cs+1)+' \/ '+ac.steps.length;\n  const icEl=$('rb-ic-'+ac.path[cs]);\n  if(icEl){icEl.classList.remove('pulse');void icEl.offsetWidth;icEl.classList.add('pulse');}\n  const snEl=$('rb-sn-'+cs);\n  if(snEl){snEl.classList.remove('pulse');void snEl.offsetWidth;snEl.classList.add('pulse');}\n\n  const p1=p(ac.path[cs]),p2=p(ac.path[cs+1]);\n  const dir=ac.steps[cs]?ac.steps[cs].dir:'out';\n  const col=dir==='ret'?'#3b82f6':(ac.steps[cs]?ac.steps[cs].c:'#534AB7');\n  dots.push({x1:p1.x,y1:p1.y,x2:p2.x,y2:p2.y,t:0,sp:0.012*spd,c:col,a:true});\n  cs++;\n  advTmr=setTimeout(advance,Math.max(300,800\/spd));\n}\nfunction reset(){\n  if(advTmr){clearTimeout(advTmr);advTmr=null;}\n  ac=null;anim=false;cs=0;dots=[];hl.clear();filt='all';\n  renderFilters();renderCases();renderNodes();\n  $('rb-pb').disabled=true;\n  $('rb-trk').innerHTML='<h4>Flujo activo<\/h4><p class=\"rb-empty\">Selecciona un caso de uso para visualizar cada paso.<\/p>';\n}\n\n\/* ---------------- CANVAS LOOP ---------------- *\/\nfunction dr(){\n  ctx.clearRect(0,0,W,H);\n  if(!ac)drawIdle();else drawActive();\n  dots.forEach(d=>{\n    if(!d.a)return;d.t+=d.sp;if(d.t>=1){d.a=false;return;}\n    const t=d.t,mx=(d.x1+d.x2)\/2,my=(d.y1+d.y2)\/2;\n    const x=(1-t)**2*d.x1+2*(1-t)*t*mx+t**2*d.x2;\n    const y=(1-t)**2*d.y1+2*(1-t)*t*my+t**2*d.y2;\n    ctx.beginPath();ctx.arc(x,y,18,0,Math.PI*2);ctx.fillStyle=hr(d.c,.09);ctx.fill();\n    ctx.beginPath();ctx.arc(x,y,10,0,Math.PI*2);ctx.fillStyle=hr(d.c,.28);ctx.fill();\n    ctx.beginPath();ctx.arc(x,y,5,0,Math.PI*2);ctx.fillStyle=d.c;ctx.fill();\n  });\n  dots=dots.filter(d=>d.a);\n  requestAnimationFrame(dr);\n}\nfunction drawIdle(){\n  const col=lineIdle();\n  \/\/ Canales \u2192 Engine\n  ['whatsapp','telegram','email','voice','api','widget'].forEach(c=>{const a=p(c),b=p('engine');bz(a.x+50,a.y,b.x-90,b.y,col,1.4);});\n  \/\/ Engine \u2192 Agentes\n  ['agent-conv','agent-voz','agent-soporte','agent-fact','agent-anal'].forEach(a=>{const s=p('engine'),e=p(a);bz(s.x+90,s.y,e.x-60,e.y,col,1.4);});\n}\nfunction drawActive(){\n  for(let i=0;i<ac.path.length-1;i++){\n    const a=p(ac.path[i]),b=p(ac.path[i+1]);\n    const done=i<cs,dir=ac.steps[i]?ac.steps[i].dir:'out';\n    const col=dir==='ret'?'#3b82f6':(ac.steps[i]?ac.steps[i].c:'#534AB7');\n    bz(a.x,a.y,b.x,b.y,hr(col,done?.32:.07),done?2.6:1.2);\n  }\n}\nfunction bz(x1,y1,x2,y2,c,w){\n  ctx.beginPath();ctx.moveTo(x1,y1);\n  const mx=(x1+x2)\/2,my=(y1+y2)\/2;\n  ctx.quadraticCurveTo(mx,my,x2,y2);\n  ctx.strokeStyle=c;ctx.lineWidth=w;ctx.stroke();\n}\nfunction hr(h,a){const r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16);return`rgba(${r},${g},${b},${a})`;}\n\n\/* ---------------- ZOOM \/ PAN T\u00c1CTIL (m\u00f3vil) ---------------- *\/\nlet scale=1,tx=0,ty=0,lastDist=0,isPinching=false,isDragging=false,startTx=0,startTy=0,didPan=false;\nfunction applyTransform(){zp.style.transform=`translate(${tx}px,${ty}px) scale(${scale})`;}\nfunction resetTransform(){scale=1;tx=0;ty=0;zp.style.transform='none';}\nfunction recalcZoom(){\n  const cw=ca.clientWidth,ch=ca.clientHeight;\n  scale=Math.min(cw\/1400,ch\/900);\n  tx=(cw-1400*scale)\/2;ty=(ch-900*scale)\/2;\n  applyTransform();\n}\nfunction setupTouch(){\n  if(!('ontouchstart' in window))return;\n  ca.addEventListener('touchstart',e=>{\n    if(!isNarrow)return;\n    if(e.touches.length===2){isPinching=true;isDragging=false;\n      const dx=e.touches[0].clientX-e.touches[1].clientX,dy=e.touches[0].clientY-e.touches[1].clientY;\n      lastDist=Math.hypot(dx,dy);\n    }else if(e.touches.length===1){isDragging=true;didPan=false;\n      startTx=e.touches[0].clientX-tx;startTy=e.touches[0].clientY-ty;}\n  },{passive:true});\n  ca.addEventListener('touchmove',e=>{\n    if(!isNarrow)return;\n    if(e.touches.length===2 ? isPinching : false){e.preventDefault();\n      const dx=e.touches[0].clientX-e.touches[1].clientX,dy=e.touches[0].clientY-e.touches[1].clientY;\n      const dist=Math.hypot(dx,dy),ratio=dist\/lastDist;\n      const ns=Math.min(4,Math.max(0.2,scale*ratio));\n      const rect=ca.getBoundingClientRect();\n      const mx=(e.touches[0].clientX+e.touches[1].clientX)\/2-rect.left;\n      const my=(e.touches[0].clientY+e.touches[1].clientY)\/2-rect.top;\n      tx=mx-(mx-tx)*ns\/scale;ty=my-(my-ty)*ns\/scale;scale=ns;lastDist=dist;applyTransform();\n    }else if(e.touches.length===1 ? isDragging : false){e.preventDefault();didPan=true;\n      tx=e.touches[0].clientX-startTx;ty=e.touches[0].clientY-startTy;applyTransform();}\n  },{passive:false});\n  ca.addEventListener('touchend',e=>{\n    if(e.touches.length<2)isPinching=false;\n    if(e.touches.length===0){isDragging=false;setTimeout(()=>{didPan=false;},50);}\n  },{passive:true});\n}\n\ninit();\n\n\/\/ Forzar estilos del slider que Kadence sobreescribe (solo lo independiente del tema:\n\/\/ borde\/sombra\/padding). El COLOR de fondo lo maneja el CSS por tema para que cambie\n\/\/ correctamente al alternar claro\/oscuro.\n(function(){\n  const rng=root.querySelector('#rb-spd');\n  if(!rng)return;\n  rng.style.setProperty('border','none','important');\n  rng.style.setProperty('box-shadow','none','important');\n  rng.style.setProperty('padding','0','important');\n  rng.style.setProperty('outline','none','important');\n})();\n\n})();\n<\/script>\n\n\n\n<style id=\"ruvic-ciber-css\">\n\n\/* ============================================================\n   RUVIC AI \u2014 DEMO INTERACTIVA  \u00b7  bloque WordPress autocontenido\n   Todo el CSS est\u00e1 namespaced bajo #ruvic-ciber para no chocar\n   con el tema de WordPress. Toggle claro\/oscuro incluido.\n   ============================================================ *\/\n\n#ruvic-ciber, #ruvic-ciber *{box-sizing:border-box;margin:0;padding:0;line-height:1.4}\n#ruvic-ciber{\n  --font:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;\n  font-family:var(--font);\n  width:100%;max-width:1400px;margin:0 auto;\n  padding:30px 30px 34px;\n  border-radius:30px;\n  position:relative;\n  -webkit-font-smoothing:antialiased;\n  text-align:left;\n  isolation:isolate;\n}\n#ruvic-ciber *{font-family:var(--font)}\n\n\/* Fondo navy profundo que rodea el widget \u2014 se extiende a todo el ancho.\n   La t\u00e9cnica de m\u00e1rgenes negativos lo lleva de borde a borde de la pantalla;\n   si la secci\u00f3n tiene overflow oculto, simplemente queda al ancho del contenido. *\/\n#ruvic-ciber-bg{background:#0A0E1F;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);\n  padding:48px clamp(14px,4vw,40px)}\n\n\/* ---------- TEMA OSCURO (por defecto, colores actuales) ---------- *\/\n#ruvic-ciber[data-theme=\"dark\"]{\n  --surface:#111b3d; --surface2:#0d1530; --sb:#0f1834; --sb2:rgba(0,0,0,.28);\n  --card-hi:#1b2658; --card:#141e48; --ghost:#172148;\n  --border:rgba(250,240,228,.12); --border2:rgba(250,240,228,.2);\n  --text:#faf0e4; --text2:rgba(250,240,228,.62); --text3:rgba(250,240,228,.34);\n  --red:#ff363a; --orange:#fdaa4c; --purple:#8b80ff;\n  --grid:rgba(250,240,228,.05); --glow:rgba(83,74,183,.30);\n  --shadow:0 36px 70px -28px rgba(0,0,0,.7); --nshadow:0 3px 10px -2px rgba(0,0,0,.4);\n  --kpi-bg:rgba(253,170,76,.16); --kpi-tx:#fdaa4c;\n  background:\n    radial-gradient(130% 90% at 50% -10%, #18244f 0%, #0d1430 52%, #090e22 100%);\n  box-shadow:inset 0 1px 0 rgba(250,240,228,.05);\n}\n\/* ---------- TEMA CLARO (versi\u00f3n white) ---------- *\/\n#ruvic-ciber[data-theme=\"light\"]{\n  --surface:#ffffff; --surface2:#f6f8fd; --sb:#ffffff; --sb2:#f6f8fd;\n  --card-hi:#ffffff; --card:#fbfcfe; --ghost:#f1f4fb;\n  --border:rgba(22,26,55,.1); --border2:rgba(22,26,55,.16);\n  --text:#161a33; --text2:rgba(22,26,51,.6); --text3:rgba(22,26,51,.4);\n  --red:#ff363a; --orange:#e8890a; --purple:#534AB7;\n  --grid:rgba(22,26,55,.05); --glow:rgba(83,74,183,.14);\n  --shadow:0 30px 60px -28px rgba(30,40,90,.32); --nshadow:0 6px 16px -8px rgba(30,40,90,.22);\n  --kpi-bg:rgba(232,137,10,.12); --kpi-tx:#c9760a;\n  background:\n    radial-gradient(120% 90% at 50% -10%, #ffffff 0%, #eef1fa 60%, #e6eaf6 100%);\n  box-shadow:inset 0 1px 0 rgba(255,255,255,.6);\n}\n\n\/* ---------------- HEADER ---------------- *\/\n#ruvic-ciber .rb-header{position:relative;text-align:center;padding:6px 96px 26px}\n#ruvic-ciber .rb-eyebrow{display:inline-flex;align-items:center;gap:7px;font-size:11px;font-weight:800;white-space:nowrap;\n  letter-spacing:2.2px;color:var(--red);text-transform:uppercase;\n  padding:6px 14px;border-radius:100px;border:1px solid rgba(255,54,58,.35);\n  background:rgba(255,54,58,.10)}\n#ruvic-ciber .rb-eyebrow .pd{width:7px;height:7px;border-radius:50%;background:var(--red);\n  box-shadow:0 0 0 0 rgba(255,54,58,.70);animation:rbPing 1.8s ease-out infinite}\n@keyframes rbPing{0%{box-shadow:0 0 0 0 rgba(255,54,58,.55)}\n  70%{box-shadow:0 0 0 8px transparent}100%{box-shadow:0 0 0 0 transparent}}\n#ruvic-ciber .rb-title{margin:16px 0 0;font-size:38px;line-height:42px;font-weight:800;letter-spacing:-1px;color:var(--text);text-wrap:balance}\n#ruvic-ciber .rb-title .ac{background:linear-gradient(96deg,var(--red),var(--orange));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:var(--red)}\n#ruvic-ciber .rb-sub{margin:12px auto 0;max-width:560px;font-size:14.5px;line-height:22px;color:var(--text2);text-wrap:pretty}\n\n\/* Theme toggle *\/\n#ruvic-ciber .rb-theme{position:absolute;top:2px;right:0;display:inline-flex;align-items:center;gap:0;\n  background:var(--ghost);border:1px solid var(--border);border-radius:100px;padding:4px;cursor:pointer;\n  user-select:none}\n#ruvic-ciber .rb-theme i{width:30px;height:28px;border-radius:100px;display:flex;align-items:center;justify-content:center;\n  font-style:normal;font-size:14px;color:var(--text3);transition:all .25s;position:relative;z-index:1}\n#ruvic-ciber .rb-theme .knob{position:absolute;top:4px;left:4px;width:30px;height:28px;border-radius:100px;\n  background:linear-gradient(180deg,var(--red),#e02d31);box-shadow:0 4px 10px -3px var(--red);transition:transform .28s cubic-bezier(.5,1.4,.5,1)}\n#ruvic-ciber[data-theme=\"light\"] .rb-theme .knob{transform:translateX(30px)}\n#ruvic-ciber[data-theme=\"dark\"] .rb-theme i.moon{color:#fff}\n#ruvic-ciber[data-theme=\"light\"] .rb-theme i.sun{color:#fff}\n\n\/* ---------------- WIDGET CARD ---------------- *\/\n#ruvic-ciber .rb-widget{position:relative;border-radius:24px;overflow:hidden;height:750px;\n  background:var(--surface);border:1px solid var(--border2);box-shadow:var(--shadow);\n  display:grid;grid-template-columns:1fr 310px}\n#ruvic-ciber[data-theme=\"dark\"] .rb-widget::after{content:\"\";position:absolute;inset:0;border-radius:24px;pointer-events:none;\n  box-shadow:inset 0 1px 0 rgba(250,240,228,.08)}\n#ruvic-ciber[data-theme=\"light\"] .rb-widget::after{content:\"\";position:absolute;inset:0;border-radius:24px;pointer-events:none;\n  box-shadow:inset 0 1px 0 rgba(22,26,51,.08)}\n\n\/* ---- diagrama (canvas) ---- *\/\n#ruvic-ciber .rb-canvas-area{position:relative;overflow:hidden;height:100%;\n  background:\n    radial-gradient(circle at 41% 42%, var(--glow) 0%, transparent 46%),\n    radial-gradient(var(--grid) 1.1px, transparent 1.1px);\n  background-size:auto, 26px 26px;background-color:var(--surface2)}\n#ruvic-ciber .rb-zp{position:absolute;top:0;left:0;transform-origin:0 0}\n#ruvic-ciber #rb-fc{position:absolute;top:0;left:0;z-index:1}\n#ruvic-ciber .rb-nl{position:absolute;top:0;left:0;z-index:2;pointer-events:none}\n#ruvic-ciber .rb-nl>*{pointer-events:auto}\n#ruvic-ciber .rb-hint{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);z-index:4;\n  font-size:10.5px;font-weight:600;color:var(--text3);background:var(--sb2);\n  border:1px solid var(--border);padding:5px 12px;border-radius:100px;display:none;pointer-events:none}\n\n\/* ---- sidebar ---- *\/\n#ruvic-ciber .rb-sb{background:var(--sb);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;min-height:0}\n#ruvic-ciber .rb-sb-head{padding:18px 18px 14px;border-bottom:1px solid var(--border);display:flex;gap:11px;align-items:flex-start}\n#ruvic-ciber .rb-mark{width:34px;height:34px;border-radius:10px;flex-shrink:0;display:flex;align-items:center;justify-content:center;\n  font-weight:800;font-size:16px;color:#fff;background:linear-gradient(150deg,var(--red),#b41f5e);\n  box-shadow:0 6px 16px -6px var(--red)}\n#ruvic-ciber .rb-sb-head h3{font-size:15px;font-weight:800;color:var(--text);letter-spacing:-.3px;line-height:17px}\n#ruvic-ciber .rb-sb-head h3 b{color:var(--red);font-weight:800}\n#ruvic-ciber .rb-sb-head p{font-size:10.5px;color:var(--text3);margin-top:4px;line-height:15px}\n#ruvic-ciber .rb-filter{padding:11px 18px;border-bottom:1px solid var(--border);display:flex;gap:6px;flex-wrap:wrap}\n#ruvic-ciber .rb-filter::-webkit-scrollbar{display:none}\n#ruvic-ciber .fb{padding:6px 11px;line-height:14px;border:1px solid var(--border2);border-radius:9px;font-size:10.5px;font-weight:600;cursor:pointer;flex-shrink:0;white-space:nowrap;\n  background:var(--ghost);color:var(--text2);transition:color .15s,border-color .15s,box-shadow .15s;line-height:1}\n#ruvic-ciber .fb:hover{border-color:var(--orange);color:var(--orange);box-shadow:none !important}\n#ruvic-ciber .fb.act{background:#ff363a !important;color:#fff !important;border-color:#ff363a !important;box-shadow:0 4px 12px -4px #ff363a !important}\n#ruvic-ciber .rb-cases{flex:1;overflow-y:auto;padding:12px 14px;min-height:0}\n#ruvic-ciber .rb-cases::-webkit-scrollbar, #ruvic-ciber .rb-trk::-webkit-scrollbar{width:5px}\n#ruvic-ciber .rb-cases::-webkit-scrollbar-thumb, #ruvic-ciber .rb-trk::-webkit-scrollbar-thumb{background:var(--border2);border-radius:5px}\n#ruvic-ciber .cb{width:100%;text-align:left;padding:12px 14px;border:1.5px solid var(--border);border-radius:13px;\n  background:var(--card);cursor:pointer;margin-bottom:8px;transition:transform .18s,box-shadow .18s,border-color .18s;display:block;position:relative;overflow:hidden}\n#ruvic-ciber .cb::before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--cbc,var(--red));opacity:0;transition:opacity .2s}\n#ruvic-ciber .cb:hover{border-color:var(--orange);transform:translateY(-2px);box-shadow:0 10px 24px -12px rgba(0,0,0,.4) !important}\n#ruvic-ciber[data-theme=\"dark\"] .cb.act{border-color:#ff363a !important;background:#1e1d48 !important;box-shadow:0 8px 24px -10px rgba(255,54,58,.6) !important}\n#ruvic-ciber[data-theme=\"light\"] .cb.act{border-color:#ff363a !important;background:#fce9e9 !important;box-shadow:0 8px 24px -10px rgba(255,54,58,.6) !important}\n#ruvic-ciber .cb.act::before{opacity:1}\n#ruvic-ciber .cb-ch{font-size:9px;line-height:12px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:var(--text3);display:flex;align-items:center;gap:6px}\n#ruvic-ciber .cb-ch .d{width:7px;height:7px;border-radius:50%;flex-shrink:0}\n#ruvic-ciber .cb-t{font-size:13px;font-weight:700;color:var(--text);line-height:17px;margin-top:5px}\n#ruvic-ciber .cb-desc{font-size:11px;color:var(--text2);margin-top:4px;line-height:15px}\n#ruvic-ciber .cb-kpi{display:inline-flex;line-height:13px;align-items:center;gap:4px;margin-top:8px;font-size:9.5px;font-weight:800;padding:4px 9px;border-radius:7px;background:var(--kpi-bg);color:var(--kpi-tx)}\n\n\/* tracker *\/\n#ruvic-ciber .rb-trk{border-top:1px solid var(--border);padding:14px 18px;background:var(--sb2);max-height:248px;overflow-y:auto}\n#ruvic-ciber .rb-trk h4{font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:var(--text3);margin-bottom:11px;display:flex;justify-content:space-between;align-items:center}\n#ruvic-ciber .rb-trk h4 span{color:var(--orange);font-weight:800}\n#ruvic-ciber .rb-empty{font-size:11px;color:var(--text3);line-height:17px}\n#ruvic-ciber .stp{display:flex;gap:11px;margin-bottom:10px;opacity:.3;transition:opacity .35s,transform .35s}\n#ruvic-ciber .stp:last-child{margin-bottom:2px}\n#ruvic-ciber .stp.on{opacity:1;transform:translateX(3px)}\n#ruvic-ciber .stp.dn{opacity:.5}\n#ruvic-ciber .stp-n{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:9.5px;font-weight:800;color:#fff;flex-shrink:0;box-shadow:0 3px 8px -2px rgba(0,0,0,.4)}\n#ruvic-ciber .stp-n.pulse{animation:rbPulse .55s ease}\n@keyframes rbPulse{0%{transform:scale(1)}45%{transform:scale(1.32)}100%{transform:scale(1)}}\n#ruvic-ciber .stp-i{flex:1;min-width:0}\n#ruvic-ciber .stp-nm{font-size:11.5px;font-weight:700;color:var(--text);line-height:15px}\n#ruvic-ciber .stp-dt{font-size:10px;color:var(--text2);margin-top:2px;line-height:14px}\n\n\/* controls *\/\n#ruvic-ciber .rb-ctrls{padding:12px 18px 16px;border-top:1px solid var(--border);background:var(--sb2)}\n#ruvic-ciber .rb-ctrls-row{display:flex;gap:8px;margin-bottom:11px}\n#ruvic-ciber .btn{flex:1;padding:11px;border:none;border-radius:11px;font-size:11.5px;font-weight:800;cursor:pointer;transition:color .15s,border-color .15s,box-shadow .15s,filter .15s;display:flex;align-items:center;justify-content:center;gap:6px}\n#ruvic-ciber .btn-play{background:linear-gradient(180deg,var(--red),#e02d31);color:#fff;box-shadow:0 8px 18px -8px var(--red);gap:0}\n#ruvic-ciber .btn-play::before{content:\"\";display:inline-block;width:0;height:0;border-style:solid;border-width:5px 0 5px 9px;border-color:transparent transparent transparent #fff;margin-right:7px;flex-shrink:0}\n#ruvic-ciber .btn-play:hover{filter:brightness(1.06);box-shadow:0 8px 18px -8px #ff363a !important}\n#ruvic-ciber .btn-play:disabled{background:var(--ghost);color:var(--text3);cursor:not-allowed;box-shadow:none}\n#ruvic-ciber .btn-play:disabled::before{border-left-color:var(--text3)}\n#ruvic-ciber .btn-rst{background:var(--ghost);color:var(--text2);border:1px solid var(--border)}\n#ruvic-ciber .btn-rst:hover{border-color:var(--border2);color:var(--text);box-shadow:none !important}\n#ruvic-ciber .speed-row{display:flex;align-items:center;gap:10px}\n#ruvic-ciber .speed-row label{font-size:10.5px;color:var(--text3);font-weight:700;white-space:nowrap}\n#ruvic-ciber .speed-row input[type=range]{flex:1;height:6px;-webkit-appearance:none;appearance:none;border-radius:4px;outline:none;background:transparent;border:none !important;box-shadow:none !important;padding:0 !important}\n#ruvic-ciber[data-theme=\"dark\"] .speed-row input[type=range]{background-color:#0b1125 !important;border-color:#0b1125 !important}\n#ruvic-ciber .speed-row input[type=range]::-webkit-slider-runnable-track{height:6px;border-radius:4px;background:rgba(250,240,228,.25);border:none;box-shadow:none}\n#ruvic-ciber[data-theme=\"light\"] .speed-row input[type=range]::-webkit-slider-runnable-track{background:rgba(22,26,51,.15)}\n#ruvic-ciber .speed-row input[type=range]::-moz-range-track{height:6px;border-radius:4px;background:rgba(250,240,228,.25);border:none}\n#ruvic-ciber[data-theme=\"light\"] .speed-row input[type=range]::-moz-range-track{background:rgba(22,26,51,.15)}\n#ruvic-ciber .speed-row input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--orange);cursor:pointer;box-shadow:0 2px 8px -1px var(--orange);margin-top:-6px}\n#ruvic-ciber .speed-row input[type=range]::-moz-range-thumb{width:18px;height:18px;border:none;border-radius:50%;background:var(--orange);cursor:pointer;box-shadow:0 2px 8px -1px var(--orange)}\n#ruvic-ciber .speed-row .sv{font-size:11px;font-weight:800;color:var(--orange);min-width:24px;text-align:right}\n\n\/* ---------------- NODES ---------------- *\/\n#ruvic-ciber .nd{position:absolute;display:flex;flex-direction:column;align-items:center;text-align:center;transition:opacity .5s,filter .5s;cursor:default}\n#ruvic-ciber .nd.dim{opacity:.14;filter:grayscale(.85)}\n#ruvic-ciber .nd.hl{z-index:5}\n#ruvic-ciber .nd.clk{cursor:pointer}\n#ruvic-ciber .nc{background:linear-gradient(180deg,var(--card-hi),var(--card));border:1.5px solid var(--border);border-radius:14px;padding:9px 11px;display:flex;flex-direction:column;align-items:center;gap:4px;min-width:104px;transition:border-color .35s,box-shadow .35s,transform .25s;box-shadow:var(--nshadow)}\n#ruvic-ciber .nd.clk:hover .nc{transform:translateY(-2px);border-color:var(--orange);box-shadow:none !important}\n#ruvic-ciber .nc.gp{box-shadow:0 0 28px var(--glow),var(--nshadow);border-color:#7c74e6}\n#ruvic-ciber .nc.gt{box-shadow:0 0 28px rgba(16,185,129,.28),var(--nshadow);border-color:#10b981}\n#ruvic-ciber .nc.go{box-shadow:0 0 28px rgba(249,115,22,.28),var(--nshadow);border-color:#f97316}\n#ruvic-ciber .nc.gb{box-shadow:0 0 28px rgba(59,130,246,.28),var(--nshadow);border-color:#3b82f6}\n#ruvic-ciber .nc.gr{box-shadow:0 0 28px rgba(239,68,68,.28),var(--nshadow);border-color:#ef4444}\n#ruvic-ciber .nc-core{border:2.5px solid #7c74e6;box-shadow:0 0 40px var(--glow),0 18px 40px -16px rgba(83,74,183,.5);padding:17px 24px;min-width:208px;border-radius:20px;position:relative}\n\/* Iconos \u2014 ahora son <img> con SVG data-URI: aislados 100% del CSS de Kadence *\/\n#ruvic-ciber .ic{width:36px !important;height:36px !important;border-radius:50%;display:block !important;flex-shrink:0;transition:transform .3s;box-shadow:0 5px 14px -5px rgba(0,0,0,.45);max-width:none !important;border:none !important;padding:0 !important;vertical-align:middle}\n#ruvic-ciber .ic-lg{width:48px !important;height:48px !important;border-radius:14px}\n#ruvic-ciber .ic-sm{width:30px !important;height:30px !important;border-radius:8px;box-shadow:0 3px 8px -3px rgba(0,0,0,.4);display:block !important;margin:0 auto !important;flex-shrink:0;max-width:none !important;border:none !important;padding:0 !important;vertical-align:middle}\n#ruvic-ciber .ic.pulse{animation:rbNode .6s ease}\n@keyframes rbNode{0%{transform:scale(1)}40%{transform:scale(1.22)}100%{transform:scale(1)}}\n#ruvic-ciber .ng{background:linear-gradient(180deg,var(--card-hi),var(--ghost));border:1px solid var(--border);border-radius:10px;padding:7px 10px;min-width:0;width:auto;transition:border-color .35s,box-shadow .35s;text-align:center;box-shadow:var(--nshadow)}\n#ruvic-ciber .ng .nt{font-size:10px;white-space:nowrap;overflow:visible;line-height:13px}\n#ruvic-ciber .nt{font-size:12px;font-weight:700;color:var(--text);line-height:15px}\n#ruvic-ciber .nt-lg{font-size:16px;white-space:nowrap}\n#ruvic-ciber .ns{font-size:10px;color:var(--text2);line-height:13px}\n#ruvic-ciber .tg{font-size:8px;padding:3px 8px;border-radius:7px;font-weight:800;letter-spacing:.2px}\n#ruvic-ciber .sl{position:absolute;font-size:10px;line-height:13px;font-weight:800;text-transform:uppercase;letter-spacing:1.6px;color:var(--text3);pointer-events:none;white-space:nowrap}\n\n\/* ============ RESPONSIVE \/ M\u00d3VIL \u2014 layout 2 columnas, sin diagrama ============ *\/\n#ruvic-ciber.is-narrow{padding:14px 10px 20px;border-radius:22px}\n#ruvic-ciber.is-narrow .rb-header{padding:2px 4px 14px}\n#ruvic-ciber.is-narrow .rb-title{font-size:22px;letter-spacing:-.5px}\n#ruvic-ciber.is-narrow .rb-sub{font-size:13px;margin-top:8px}\n#ruvic-ciber.is-narrow .rb-theme{top:0}\n\/* Diagrama arriba, panel 2 columnas abajo *\/\n#ruvic-ciber.is-narrow .rb-canvas-area{\n  display:block;height:320px;width:100%;\n  border-bottom:1px solid var(--border);touch-action:none;\n}\n#ruvic-ciber.is-narrow .rb-hint{display:block}\n#ruvic-ciber.is-narrow .rb-hint{display:none}\n\/* Widget: bloque simple, altura autom\u00e1tica *\/\n#ruvic-ciber.is-narrow .rb-widget{display:block;height:auto}\n\/* Sidebar: 2 columnas \u2014 casos | tracker+controles *\/\n#ruvic-ciber.is-narrow .rb-sb{\n  display:grid;\n  grid-template-columns:58% 42%;\n  grid-template-rows:auto auto 1fr auto;\n  border-left:none;\n  height:420px;\n}\n#ruvic-ciber.is-narrow .rb-sb-head{\n  grid-column:1;grid-row:1;\n  border-right:1px solid var(--border);border-bottom:1px solid var(--border);\n  padding:14px 12px;\n}\n#ruvic-ciber.is-narrow .rb-sb-head h3{font-size:13px}\n#ruvic-ciber.is-narrow .rb-sb-head p{font-size:10px}\n#ruvic-ciber.is-narrow .rb-filter{\n  grid-column:1;grid-row:2;\n  border-right:1px solid var(--border);border-bottom:1px solid var(--border);\n  padding:8px 10px;gap:4px;\n  flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;\n}\n#ruvic-ciber.is-narrow .rb-cases{\n  grid-column:1;grid-row:3;\n  border-right:1px solid var(--border);\n  max-height:175px;flex:none;\n  overflow-y:auto;\n  padding:8px 10px;\n}\n#ruvic-ciber.is-narrow .rb-cases .cb{padding:9px 10px;margin-bottom:6px}\n#ruvic-ciber.is-narrow .rb-cases .cb-t{font-size:12px}\n#ruvic-ciber.is-narrow .rb-cases .cb-desc{font-size:10px}\n#ruvic-ciber.is-narrow .rb-trk{\n  grid-column:2;grid-row:1\/4;\n  max-height:none;border-top:none;\n  overflow-y:auto;\n  padding:12px 10px;\n}\n#ruvic-ciber.is-narrow .rb-trk h4{font-size:9.5px}\n#ruvic-ciber.is-narrow .stp-nm{font-size:10.5px}\n#ruvic-ciber.is-narrow .stp-dt{font-size:9px}\n#ruvic-ciber.is-narrow .rb-ctrls{\n  grid-column:1\/3;grid-row:4;\n  padding:8px 12px 12px;\n  border-top:1px solid var(--border);\n}\n#ruvic-ciber.is-narrow .btn{font-size:10.5px;padding:9px}\n#ruvic-ciber.is-narrow .speed-row label{font-size:9.5px}\n#ruvic-ciber.is-narrow .sv{font-size:10px}\n\/* Ajuste tipograf\u00eda xnarrow *\/\n#ruvic-ciber.is-xnarrow{padding:10px 8px 16px}\n#ruvic-ciber.is-xnarrow .rb-title{font-size:19px}\n#ruvic-ciber.is-xnarrow .rb-eyebrow{font-size:9px;letter-spacing:1.4px;padding:5px 9px}\n#ruvic-ciber.is-xnarrow .rb-sb-head{padding:10px}\n#ruvic-ciber.is-xnarrow .rb-theme{transform:scale(.9);transform-origin:top right}\n\n\n\/* Kadence theme overrides *\/\n#ruvic-ciber button:hover{box-shadow:none !important}\n#ruvic-ciber button{line-height:14px}\n@media (prefers-reduced-motion:reduce){\n  #ruvic-ciber *{animation-duration:.001ms!important;transition-duration:.08s!important}\n}\n\n\/* Nuclear reset \u2014 Kadence body\/global-palette color bleed fix\n   \"body #ruvic-ciber\" tiene especificidad (0,1,1) y gana a \"body{color:...}\" de Kadence (0,0,1) *\/\nbody #ruvic-ciber{color:#faf0e4}\nbody #ruvic-ciber[data-theme=\"light\"]{color:#161a33}\nbody #ruvic-ciber .nt{color:var(--text) !important}\nbody #ruvic-ciber .ns{color:var(--text2) !important}\nbody #ruvic-ciber .nt-lg{color:var(--text) !important}\nbody #ruvic-ciber .stp-nm{color:var(--text) !important}\nbody #ruvic-ciber .stp-dt{color:var(--text2) !important}\nbody #ruvic-ciber .rb-sb-head h3{color:var(--text) !important}\nbody #ruvic-ciber .rb-sb-head p{color:var(--text3) !important}\nbody #ruvic-ciber .cb-t{color:var(--text) !important}\nbody #ruvic-ciber .cb-desc{color:var(--text2) !important}\nbody #ruvic-ciber .rb-trk h4{color:var(--text3) !important}\nbody #ruvic-ciber .rb-title{color:var(--text) !important}\nbody #ruvic-ciber .rb-sub{color:var(--text2) !important}\nbody #ruvic-ciber .speed-row label{color:var(--text3) !important}\nbody #ruvic-ciber .sv{color:var(--orange) !important}\n\n<\/style>\n\n<div id=\"ruvic-ciber-bg\">\n<div id=\"ruvic-ciber\" data-theme=\"dark\">\n\n  <header class=\"rb-header\">\n    <button class=\"rb-theme\" id=\"rb-theme\" type=\"button\" aria-label=\"Cambiar tema claro\/oscuro\">\n      <span class=\"knob\"><\/span>\n      <i class=\"moon\">\u263e<\/i>\n      <i class=\"sun\"><svg viewBox=\"0 0 24 24\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"display:block\"><circle cx=\"12\" cy=\"12\" r=\"4\"\/><path d=\"M12 2.5v2.2M12 19.3v2.2M5.1 5.1l1.5 1.5M17.4 17.4l1.5 1.5M2.5 12h2.2M19.3 12h2.2M5.1 18.9l1.5-1.5M17.4 6.6l1.5-1.5\"\/><\/svg><\/i>\n    <\/button>\n    <span class=\"rb-eyebrow\"><span class=\"pd\"><\/span>Ciberseguridad<\/span>\n    <h2 class=\"rb-title\">Mira c\u00f3mo Ruvic orquesta tu <span class=\"ac\">seguridad en tiempo real<\/span><\/h2>\n    <p class=\"rb-sub\">Selecciona un caso de uso de ciberseguridad y reproduce el flujo completo de principio a fin.<\/p>\n  <\/header>\n\n  <div class=\"rb-widget\" id=\"rb-widget\">\n    <div class=\"rb-canvas-area\" id=\"rb-ca\">\n      <div class=\"rb-zp\" id=\"rb-zp\">\n        <canvas id=\"rb-fc\"><\/canvas>\n        <div class=\"rb-nl\" id=\"rb-nl\"><\/div>\n      <\/div>\n      <div class=\"rb-hint\">Arrastra para mover \u00b7 pellizca para hacer zoom<\/div>\n    <\/div>\n    <aside class=\"rb-sb\">\n      <div class=\"rb-sb-head\">\n        <div class=\"rb-mark\">R<\/div>\n        <div>\n          <h3><b>Ruvic AI<\/b> \u00b7 Ciberseguridad<\/h3>\n          <p>Haz clic en una fuente o elige un caso para ver el flujo de ida y vuelta<\/p>\n        <\/div>\n      <\/div>\n      <div class=\"rb-filter\" id=\"rb-filters\"><\/div>\n      <div class=\"rb-cases\" id=\"rb-cl\"><\/div>\n      <div class=\"rb-trk\" id=\"rb-trk\">\n        <h4>Flujo activo<\/h4>\n        <p class=\"rb-empty\">Selecciona un caso de uso para visualizar cada paso.<\/p>\n      <\/div>\n      <div class=\"rb-ctrls\">\n        <div class=\"rb-ctrls-row\">\n          <button class=\"btn btn-play\" id=\"rb-pb\" type=\"button\" disabled>Reproducir flujo<\/button>\n          <button class=\"btn btn-rst\" id=\"rb-rst\" type=\"button\">\u21ba Reiniciar<\/button>\n        <\/div>\n        <div class=\"speed-row\">\n          <label for=\"rb-spd\">Velocidad<\/label>\n          <input type=\"range\" min=\"1\" max=\"5\" value=\"3\" id=\"rb-spd\">\n          <span class=\"sv\" id=\"rb-spdV\">3x<\/span>\n        <\/div>\n      <\/div>\n    <\/aside>\n  <\/div>\n<\/div>\n<\/div>\n\n<script>\n(function(){\n\"use strict\";\nconst root=document.getElementById('ruvic-ciber');\n\n\/* ---------------- DATOS (sin cambios de contenido) ---------------- *\/\nconst N={\n  'siem':{x:13,y:11,l:'SIEM',c:'#dc2626',lt:'S',t:'ch'},\n  'edr':{x:13,y:25,l:'EDR \/ XDR',c:'#ea580c',lt:'E',t:'ch'},\n  'firewall':{x:13,y:40,l:'Firewall \/ IDS',c:'#0891b2',lt:'F',t:'ch'},\n  'email-gw':{x:13,y:54,l:'Gateway de correo',c:'#7c3aed',lt:'M',t:'ch'},\n  'scanner':{x:13,y:68,l:'Esc\u00e1ner de vuln.',c:'#16a34a',lt:'V',t:'ch'},\n  'webhook':{x:13,y:81,l:'API \/ Webhook',c:'#4a5568',lt:'{}',t:'ch'},\n\n  'engine':{x:41,y:43,l:'Ruvic AI Engine',c:'#534AB7',lt:'R',t:'core'},\n  'memory':{x:34,y:66,l:'Memoria',c:'#10b981',lt:'M',t:'sub'},\n  'queue':{x:46,y:66,l:'Cola de eventos',c:'#f97316',lt:'Q',t:'sub'},\n\n  'gpt4o':{x:25,y:84,l:'GPT-4o',c:'#10a37f',lt:'G',t:'llm'},\n  'gemini':{x:35,y:84,l:'Gemini',c:'#4285F4',lt:'G',t:'llm'},\n  'claude':{x:45,y:84,l:'Claude',c:'#d4537e',lt:'C',t:'llm'},\n  'deepseek':{x:55,y:84,l:'DeepSeek',c:'#3B6D11',lt:'D',t:'llm'},\n\n  'agent-triage':{x:68,y:15,l:'Agente de triaje',c:'#dc2626',lt:'T',t:'ag'},\n  'agent-resp':{x:68,y:29,l:'Agente de respuesta',c:'#ea580c',lt:'R',t:'ag'},\n  'agent-anal':{x:68,y:43,l:'Agente de an\u00e1lisis',c:'#8b5cf6',lt:'A',t:'ag'},\n  'agent-compl':{x:68,y:58,l:'Agente de cumplimiento',c:'#0891b2',lt:'C',t:'ag'},\n  'agent-pentest':{x:68,y:73,l:'Agente de pentesting',c:'#16a34a',lt:'P',t:'ag'},\n\n  'soar':{x:87,y:11,l:'SOAR \/ Ticketing',c:'#3b82f6',t:'cn',sub:'ServiceNow, Jira'},\n  'threat-intel':{x:87,y:25,l:'Inteligencia de amenazas',c:'#dc2626',t:'cn',sub:'MISP, VirusTotal'},\n  'ad':{x:87,y:40,l:'Active Directory',c:'#0891b2',t:'cn',sub:'LDAP, Azure AD'},\n  'fw-waf':{x:87,y:54,l:'Firewall \/ WAF',c:'#ea580c',t:'cn',sub:'Palo Alto, Fortinet'},\n  'sast-dast':{x:87,y:68,l:'SAST \/ DAST',c:'#16a34a',t:'cn',sub:'SonarQube, Burp Suite'},\n  'kb':{x:87,y:82,l:'Base de conocimiento',c:'#8b5cf6',t:'cn',sub:'Playbooks, pol\u00edticas'},\n\n  'logs':{x:13,y:95,l:'Logs SIEM',c:'#dc2626',t:'dt'},\n  'iocs':{x:27,y:95,l:'IOCs',c:'#ea580c',t:'dt'},\n  'vulns':{x:41,y:95,l:'Vulnerabilidades',c:'#16a34a',t:'dt'},\n  'evidencias':{x:56,y:95,l:'Evidencias',c:'#8b5cf6',t:'dt'},\n  'reportes':{x:71,y:95,l:'Reportes',c:'#0891b2',t:'dt'},\n  'politicas':{x:87,y:95,l:'Pol\u00edticas',c:'#7c3aed',t:'dt'},\n};\n\nconst CS=[\n\/\/ === BLUE TEAM (1-8) ===\n{id:'bt1',ch:'siem',t:'Triaje inteligente de alertas SIEM',d:'Ruvic recibe alertas del SIEM y despacha dos agentes en paralelo: triaje enriquece IOCs mientras an\u00e1lisis correlaciona eventos.',kpi:'Reduce alertas manuales un 90%',\n path:['siem','engine','memory','claude','agent-triage','threat-intel','agent-anal','soar','engine','siem'],\n steps:[\n  {n:'SIEM',dt:'Splunk genera alerta: tr\u00e1fico an\u00f3malo desde IP 45.33.x.x',c:'#dc2626',dir:'out'},\n  {n:'Ruvic Engine',dt:'Recibe alerta, normaliza formato y clasifica severidad',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Correlaciona con alertas previas de la misma IP',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Analiza patr\u00f3n: posible comando y control (C2) activo',c:'#d4537e',dir:'out'},\n  {n:'Agente de triaje',dt:'\u26a1 EN PARALELO: enriquece IOCs (geolocalizaci\u00f3n, reputaci\u00f3n)',c:'#dc2626',dir:'out',par:{to:'agent-anal',label:'Correlaciona eventos de las \u00faltimas 24h'}},\n  {n:'Inteligencia de amenazas',dt:'VirusTotal confirma: IP asociada a botnet Emotet',c:'#dc2626',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: detecta 3 alertas correlacionadas adicionales',c:'#8b5cf6',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea incidente INC-2026-0892, prioridad P1, con contexto completo',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Notifica al equipo SOC con reporte de ambos agentes',c:'#534AB7',dir:'ret'},\n  {n:'SIEM',dt:'Actualiza alerta con clasificaci\u00f3n y acciones tomadas',c:'#dc2626',dir:'ret'},\n]},\n{id:'bt2',ch:'edr',t:'Gesti\u00f3n autom\u00e1tica de incidentes',d:'Ruvic detecta malware v\u00eda EDR y ejecuta dos agentes: respuesta a\u00edsla el endpoint mientras triaje documenta la cadena de ataque.',kpi:'Reduce tiempo de gesti\u00f3n un 70%',\n path:['edr','engine','memory','gpt4o','agent-resp','fw-waf','agent-triage','soar','engine','edr'],\n steps:[\n  {n:'EDR \/ XDR',dt:'CrowdStrike detecta ejecuci\u00f3n de PowerShell sospechosa',c:'#ea580c',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como posible ejecuci\u00f3n de c\u00f3digo malicioso',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Verifica historial del endpoint y usuario afectado',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Analiza el script PowerShell: descarga desde dominio malicioso',c:'#10a37f',dir:'out'},\n  {n:'Agente de respuesta',dt:'\u26a1 EN PARALELO: a\u00edsla endpoint y preserva evidencia RAM',c:'#ea580c',dir:'out',par:{to:'agent-triage',label:'Documenta timeline y extrae IOCs'}},\n  {n:'Firewall \/ WAF',dt:'Bloquea dominio malicioso en todas las pol\u00edticas',c:'#ea580c',dir:'out'},\n  {n:'Agente de triaje',dt:'Resultado paralelo: timeline completo con 12 artefactos',c:'#dc2626',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea ticket con evidencia de ambos agentes, asigna a L2',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera notificaci\u00f3n con playbook de respuesta sugerido',c:'#534AB7',dir:'ret'},\n  {n:'EDR \/ XDR',dt:'Confirma aislamiento del endpoint comprometido',c:'#ea580c',dir:'ret'},\n]},\n{id:'bt3',ch:'webhook',t:'Asistente SOC 24\/7 para analistas',d:'Un analista consulta a Ruvic sobre una alerta. Ruvic busca en la base de conocimiento y sugiere el playbook correcto.',kpi:'Reduce tiempo de resoluci\u00f3n N1 un 50%',\n path:['webhook','engine','memory','gemini','agent-triage','kb','agent-triage','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Analista pregunta: \"\u00bfQu\u00e9 hago con alerta de lateral movement?\"',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como consulta de analista SOC',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga contexto del incidente actual y alertas relacionadas',c:'#10b981',dir:'out'},\n  {n:'Gemini',dt:'Busca en playbooks y procedimientos internos',c:'#4285F4',dir:'out'},\n  {n:'Agente de triaje',dt:'Identifica playbook PB-034: Movimiento lateral',c:'#dc2626',dir:'out'},\n  {n:'Base de conocimiento',dt:'Retorna pasos: verificar cuentas, revisar logs, aislar',c:'#8b5cf6',dir:'ret'},\n  {n:'Agente de triaje',dt:'Formatea instrucciones paso a paso con contexto',c:'#dc2626',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Env\u00eda respuesta estructurada al analista',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Analista recibe: playbook + IOCs + acciones sugeridas',c:'#4a5568',dir:'ret'},\n]},\n{id:'bt4',ch:'firewall',t:'Contenci\u00f3n autom\u00e1tica de amenazas',d:'Ruvic detecta fuerza bruta y despacha dos agentes: respuesta bloquea la IP mientras an\u00e1lisis documenta el patr\u00f3n de ataque.',kpi:'Contenci\u00f3n en menos de 30 segundos',\n path:['firewall','engine','memory','deepseek','agent-resp','fw-waf','agent-anal','soar','engine','firewall'],\n steps:[\n  {n:'Firewall \/ IDS',dt:'Palo Alto reporta: 500+ intentos SSH desde IP externa',c:'#0891b2',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como ataque de fuerza bruta, prioridad alta',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'IP no vista antes, sin historial de conexiones leg\u00edtimas',c:'#10b981',dir:'out'},\n  {n:'DeepSeek',dt:'Confirma patr\u00f3n de fuerza bruta, recomienda bloqueo inmediato',c:'#3B6D11',dir:'out'},\n  {n:'Agente de respuesta',dt:'\u26a1 EN PARALELO: genera y aplica regla de bloqueo',c:'#ea580c',dir:'out',par:{to:'agent-anal',label:'Analiza patr\u00f3n completo y geolocaliza IP'}},\n  {n:'Firewall \/ WAF',dt:'Aplica regla: IP 45.33.x.x bloqueada por 72 horas',c:'#ea580c',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: origen Rusia, patr\u00f3n consistente con botnet',c:'#8b5cf6',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea registro con evidencia de ambos agentes',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Notifica al equipo y actualiza m\u00e9tricas de contenci\u00f3n',c:'#534AB7',dir:'ret'},\n  {n:'Firewall \/ IDS',dt:'Confirma bloqueo y actualiza listas negras',c:'#0891b2',dir:'ret'},\n]},\n{id:'bt5',ch:'siem',t:'Correlaci\u00f3n de eventos multi-fuente',d:'Ruvic despacha triaje y an\u00e1lisis en paralelo para correlacionar alertas dispersas y detectar cadenas de ataque.',kpi:'Detecta ataques multi-fase un 80% m\u00e1s r\u00e1pido',\n path:['siem','engine','memory','claude','agent-triage','threat-intel','agent-anal','soar','engine','siem'],\n steps:[\n  {n:'SIEM',dt:'M\u00faltiples alertas dispersas de 3 fuentes en \u00faltimas 2 horas',c:'#dc2626',dir:'out'},\n  {n:'Ruvic Engine',dt:'Detecta patr\u00f3n temporal: 3 fuentes, mismo segmento de red',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga alertas hist\u00f3ricas del mismo segmento para comparar',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Hip\u00f3tesis: kill chain en progreso seg\u00fan MITRE ATT'+String.fromCharCode(38)+'CK',c:'#d4537e',dir:'out'},\n  {n:'Agente de triaje',dt:'\u26a1 EN PARALELO: enriquece cada alerta con threat intel',c:'#dc2626',dir:'out',par:{to:'agent-anal',label:'Mapea t\u00e9cnicas ATT'+String.fromCharCode(38)+'CK y activos afectados'}},\n  {n:'Inteligencia de amenazas',dt:'Confirma TTPs asociados a grupo APT-29',c:'#dc2626',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: 5 activos comprometidos, kill chain completa',c:'#8b5cf6',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea incidente mayor con mapa completo de la cadena',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Escala a CISO con reporte ejecutivo de ambos agentes',c:'#534AB7',dir:'ret'},\n  {n:'SIEM',dt:'Actualiza reglas de correlaci\u00f3n con nuevo patr\u00f3n detectado',c:'#dc2626',dir:'ret'},\n]},\n{id:'bt6',ch:'edr',t:'An\u00e1lisis forense automatizado',d:'Ruvic ejecuta an\u00e1lisis y respuesta en paralelo: uno recolecta artefactos forenses mientras el otro preserva la cadena de custodia.',kpi:'An\u00e1lisis forense en minutos vs. horas',\n path:['edr','engine','memory','claude','agent-anal','logs','agent-resp','engine','edr'],\n steps:[\n  {n:'EDR \/ XDR',dt:'Endpoint comprometido identificado, se requiere an\u00e1lisis forense',c:'#ea580c',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia flujo forense con dos agentes en paralelo',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga contexto del incidente y acciones previas',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Define plan forense: qu\u00e9 artefactos recolectar y preservar',c:'#d4537e',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'\u26a1 EN PARALELO: recolecta procesos, conexiones, registros',c:'#8b5cf6',dir:'out',par:{to:'agent-resp',label:'Preserva RAM, disco y logs de red'}},\n  {n:'Logs SIEM',dt:'Retorna: logs de autenticaci\u00f3n, DNS, proxy de las \u00faltimas 48h',c:'#dc2626',dir:'ret'},\n  {n:'Agente de respuesta',dt:'Resultado paralelo: imagen de RAM y disco preservadas',c:'#ea580c',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Consolida hallazgos de ambos agentes en reporte forense',c:'#534AB7',dir:'ret'},\n  {n:'EDR \/ XDR',dt:'Recibe: timeline + evidencias + recomendaciones de limpieza',c:'#ea580c',dir:'ret'},\n]},\n{id:'bt7',ch:'webhook',t:'Reportes ejecutivos de seguridad',d:'Ruvic genera autom\u00e1ticamente el reporte semanal con KPIs, tendencias y recomendaciones para el CISO.',kpi:'De 6 horas manuales a 100% autom\u00e1tico',\n path:['webhook','engine','memory','gpt4o','agent-anal','logs','agent-anal','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Trigger programado: lunes 8:00 AM, reporte semanal',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia recolecci\u00f3n de m\u00e9tricas de la \u00faltima semana',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga m\u00e9tricas previas para comparaci\u00f3n de tendencias',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Calcula KPIs: MTTD, MTTR, volumen de alertas, SLA',c:'#10a37f',dir:'out'},\n  {n:'Agente de an\u00e1lisis',dt:'Consolida datos de todas las fuentes de seguridad',c:'#8b5cf6',dir:'out'},\n  {n:'Logs SIEM',dt:'Retorna: 12.847 alertas, 47 incidentes, 3 cr\u00edticos',c:'#dc2626',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Genera reporte con gr\u00e1ficos, tendencias y recomendaciones',c:'#8b5cf6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Formatea y env\u00eda a stakeholders seg\u00fan distribuci\u00f3n',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'CISO recibe: PDF ejecutivo + dashboard interactivo',c:'#4a5568',dir:'ret'},\n]},\n{id:'bt8',ch:'email-gw',t:'Detecci\u00f3n y respuesta a phishing',d:'Ruvic analiza el correo y despacha dos agentes: respuesta elimina correos de bandejas mientras triaje extrae y bloquea IOCs.',kpi:'Neutraliza campa\u00f1as de phishing en 2 minutos',\n path:['email-gw','engine','memory','claude','agent-resp','ad','agent-triage','threat-intel','engine','email-gw'],\n steps:[\n  {n:'Gateway de correo',dt:'Correo sospechoso con enlace detectado por sandbox',c:'#7c3aed',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica como phishing, despacha dos agentes simult\u00e1neos',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Verifica si la URL o dominio ha sido reportado antes',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Confirma: suplantaci\u00f3n de identidad del CEO',c:'#d4537e',dir:'out'},\n  {n:'Agente de respuesta',dt:'\u26a1 EN PARALELO: elimina correo de 23 bandejas afectadas',c:'#ea580c',dir:'out',par:{to:'agent-triage',label:'Extrae IOCs: dominio, IP, hash del adjunto'}},\n  {n:'Active Directory',dt:'Resetea sesiones de los 23 usuarios que abrieron el correo',c:'#0891b2',dir:'out'},\n  {n:'Agente de triaje',dt:'Resultado paralelo: 4 IOCs extra\u00eddos y clasificados',c:'#dc2626',dir:'ret'},\n  {n:'Inteligencia de amenazas',dt:'IOCs publicados en MISP interno para bloqueo global',c:'#dc2626',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera alerta unificada con acciones de ambos agentes',c:'#534AB7',dir:'ret'},\n  {n:'Gateway de correo',dt:'Actualiza reglas: bloquea dominio, remitente e IP',c:'#7c3aed',dir:'ret'},\n]},\n\n\/\/ === RED TEAM (9-14) ===\n{id:'rt1',ch:'scanner',t:'An\u00e1lisis de vulnerabilidades automatizado',d:'Ruvic ejecuta pentesting y cumplimiento en paralelo: uno valida la explotabilidad mientras el otro mapea a normativas.',kpi:'Priorizaci\u00f3n en contexto un 75% m\u00e1s precisa',\n path:['scanner','engine','memory','gpt4o','agent-pentest','vulns','agent-compl','soar','engine','scanner'],\n steps:[\n  {n:'Esc\u00e1ner de vuln.',dt:'Nessus completa escaneo: 342 vulnerabilidades encontradas',c:'#16a34a',dir:'out'},\n  {n:'Ruvic Engine',dt:'Ingesta de resultados, normaliza por CVE y CVSS',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Cruza con activos cr\u00edticos y vulnerabilidades previas',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Prioriza por riesgo real: explotabilidad + criticidad del activo',c:'#10a37f',dir:'out'},\n  {n:'Agente de pentesting',dt:'\u26a1 EN PARALELO: valida explotabilidad de las 12 cr\u00edticas',c:'#16a34a',dir:'out',par:{to:'agent-compl',label:'Mapea hallazgos a controles ISO 27001 y PCI-DSS'}},\n  {n:'Vulnerabilidades',dt:'Registra: 12 cr\u00edticas, 45 altas, 128 medias, 157 bajas',c:'#16a34a',dir:'ret'},\n  {n:'Agente de cumplimiento',dt:'Resultado paralelo: 8 hallazgos impactan cumplimiento PCI',c:'#0891b2',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea tickets con contexto t\u00e9cnico + normativo de ambos agentes',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Distribuye tickets priorizados a los equipos responsables',c:'#534AB7',dir:'ret'},\n  {n:'Esc\u00e1ner de vuln.',dt:'Programa re-escaneo seg\u00fan SLAs definidos por severidad',c:'#16a34a',dir:'ret'},\n]},\n{id:'rt2',ch:'webhook',t:'An\u00e1lisis de c\u00f3digo est\u00e1tico (SAST)',d:'Ruvic analiza c\u00f3digo en cada pull request y ejecuta pentesting junto con an\u00e1lisis de dependencias en paralelo.',kpi:'Detecta un 85% de vulnerabilidades pre-producci\u00f3n',\n path:['webhook','engine','memory','claude','agent-pentest','sast-dast','agent-anal','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'GitHub webhook: nuevo pull request en repositorio principal',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia pipeline de seguridad con dos agentes simult\u00e1neos',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga reglas de seguridad y vulnerabilidades previas del repo',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Analiza diferencias del c\u00f3digo: inyecci\u00f3n SQL, XSS, secretos',c:'#d4537e',dir:'out'},\n  {n:'Agente de pentesting',dt:'\u26a1 EN PARALELO: ejecuta OWASP Top 10 sobre el c\u00f3digo',c:'#16a34a',dir:'out',par:{to:'agent-anal',label:'Analiza dependencias: CVEs en librer\u00edas de terceros'}},\n  {n:'SAST \/ DAST',dt:'SonarQube confirma: 3 vulnerabilidades, 2 code smells',c:'#16a34a',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: 1 dependencia con CVE cr\u00edtico conocido',c:'#8b5cf6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Consolida hallazgos y bloquea merge hasta correcci\u00f3n',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Desarrollador recibe: reporte unificado con correcciones sugeridas',c:'#4a5568',dir:'ret'},\n]},\n{id:'rt3',ch:'scanner',t:'Orquestaci\u00f3n de pentesting automatizado',d:'Ruvic coordina Nmap, Nikto y OWASP ZAP en ejecuci\u00f3n paralela, consolida resultados y genera el reporte.',kpi:'Reduce tiempo de evaluaci\u00f3n un 50%',\n path:['scanner','engine','memory','gpt4o','agent-pentest','sast-dast','agent-pentest','engine','scanner'],\n steps:[\n  {n:'Esc\u00e1ner de vuln.',dt:'Inicia evaluaci\u00f3n de seguridad programada del cliente X',c:'#16a34a',dir:'out'},\n  {n:'Ruvic Engine',dt:'\u26a1 Orquesta ejecuci\u00f3n PARALELA de Nmap + Nikto + OWASP ZAP',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga alcance aprobado y exclusiones del pentesting',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Consolida resultados de las 3 herramientas, elimina duplicados',c:'#10a37f',dir:'out'},\n  {n:'Agente de pentesting',dt:'Valida hallazgos con pruebas de explotaci\u00f3n automatizadas',c:'#16a34a',dir:'out'},\n  {n:'SAST \/ DAST',dt:'Burp Suite confirma 2 vulnerabilidades adicionales en API',c:'#16a34a',dir:'ret'},\n  {n:'Agente de pentesting',dt:'Genera reporte profesional con evidencias y remediaci\u00f3n',c:'#16a34a',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Formatea reporte ejecutivo + t\u00e9cnico en PDF',c:'#534AB7',dir:'ret'},\n  {n:'Esc\u00e1ner de vuln.',dt:'Entrega: reporte completo con score de riesgo global',c:'#16a34a',dir:'ret'},\n]},\n{id:'rt4',ch:'webhook',t:'Re-testing y validaci\u00f3n de remediaciones',d:'Cuando un equipo marca una vulnerabilidad como corregida, Ruvic ejecuta el re-test autom\u00e1ticamente.',kpi:'Validaci\u00f3n en horas vs. semanas',\n path:['webhook','engine','memory','deepseek','agent-pentest','sast-dast','agent-pentest','soar','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Jira: ticket VULN-445 marcado como \"remediado\"',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Identifica la vulnerabilidad original y m\u00e9todo de validaci\u00f3n',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Recupera evidencia original: tipo, ubicaci\u00f3n, severidad',c:'#10b981',dir:'out'},\n  {n:'DeepSeek',dt:'Genera prueba de validaci\u00f3n espec\u00edfica para esa vulnerabilidad',c:'#3B6D11',dir:'out'},\n  {n:'Agente de pentesting',dt:'Ejecuta re-test t\u00e9cnico contra el activo corregido',c:'#16a34a',dir:'out'},\n  {n:'SAST \/ DAST',dt:'Resultado: vulnerabilidad ya no es explotable, correcci\u00f3n v\u00e1lida',c:'#16a34a',dir:'ret'},\n  {n:'Agente de pentesting',dt:'Genera certificado de remediaci\u00f3n con evidencia',c:'#16a34a',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Cierra ticket VULN-445 con evidencia de validaci\u00f3n',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Actualiza m\u00e9tricas de remediaci\u00f3n del cliente',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Notifica al cliente: \"Vulnerabilidad remediada y validada \u2713\"',c:'#4a5568',dir:'ret'},\n]},\n{id:'rt5',ch:'webhook',t:'Reconocimiento OSINT automatizado',d:'Ruvic ejecuta pentesting y an\u00e1lisis en paralelo: uno consulta Shodan\/Censys mientras el otro cruza con brechas conocidas.',kpi:'Descubre un 40% m\u00e1s de activos expuestos',\n path:['webhook','engine','memory','gemini','agent-pentest','threat-intel','agent-anal','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Solicitud: reconocimiento de superficie de ataque para dominio X',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia pipeline OSINT con dos agentes en paralelo',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga resultados de reconocimientos anteriores para comparar',c:'#10b981',dir:'out'},\n  {n:'Gemini',dt:'Busca en Shodan, Censys, crt.sh: 47 subdominios, 12 IPs',c:'#4285F4',dir:'out'},\n  {n:'Agente de pentesting',dt:'\u26a1 EN PARALELO: valida servicios activos y tecnolog\u00edas',c:'#16a34a',dir:'out',par:{to:'agent-anal',label:'Cruza con bases de brechas y credenciales filtradas'}},\n  {n:'Inteligencia de amenazas',dt:'3 subdominios con credenciales filtradas encontradas',c:'#dc2626',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: 2 servicios con versiones vulnerables',c:'#8b5cf6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Consolida mapa de superficie de ambos agentes',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Entrega: mapa completo + 5 hallazgos cr\u00edticos priorizados',c:'#4a5568',dir:'ret'},\n]},\n{id:'rt6',ch:'scanner',t:'Generaci\u00f3n de reportes de pentesting',d:'Ruvic toma los hallazgos y genera autom\u00e1ticamente el reporte profesional con narrativa ejecutiva y t\u00e9cnica.',kpi:'De 20 horas a 2 horas por reporte',\n path:['scanner','engine','memory','claude','agent-pentest','evidencias','agent-pentest','engine','scanner'],\n steps:[\n  {n:'Esc\u00e1ner de vuln.',dt:'Pentester completa evaluaci\u00f3n, Ruvic indexa las evidencias',c:'#16a34a',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica y organiza hallazgos por categor\u00eda OWASP',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga plantilla del cliente y resultados de tests previos',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Genera narrativa ejecutiva y descripciones t\u00e9cnicas detalladas',c:'#d4537e',dir:'out'},\n  {n:'Agente de pentesting',dt:'Incorpora evidencias multimedia (capturas, PoCs)',c:'#16a34a',dir:'out'},\n  {n:'Evidencias',dt:'Retorna: 45 capturas, 12 PoCs, 8 videos de explotaci\u00f3n',c:'#8b5cf6',dir:'ret'},\n  {n:'Agente de pentesting',dt:'Compila reporte final con resumen ejecutivo + t\u00e9cnico',c:'#16a34a',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera PDF profesional con branding del cliente',c:'#534AB7',dir:'ret'},\n  {n:'Esc\u00e1ner de vuln.',dt:'Entrega: reporte de 80 p\u00e1ginas listo para revisi\u00f3n final',c:'#16a34a',dir:'ret'},\n]},\n\n\/\/ === COMPLIANCE (15-18) ===\n{id:'co1',ch:'webhook',t:'Evaluaci\u00f3n de cumplimiento ISO 27001',d:'Ruvic ejecuta un gap analysis automatizado contra controles ISO 27001 y genera un plan de acci\u00f3n priorizado.',kpi:'Gap analysis en d\u00edas vs. semanas',\n path:['webhook','engine','memory','claude','agent-compl','kb','agent-compl','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Solicitud: evaluaci\u00f3n de madurez ISO 27001 para cliente Y',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Carga framework ISO 27001:2022 con 93 controles del Anexo A',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Recupera evaluaciones previas y evidencias existentes',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Genera cuestionario adaptativo seg\u00fan el sector del cliente',c:'#d4537e',dir:'out'},\n  {n:'Agente de cumplimiento',dt:'Eval\u00faa cada control: cumple, parcial, no cumple, N\/A',c:'#0891b2',dir:'out'},\n  {n:'Base de conocimiento',dt:'Compara con benchmarks de industria y mejores pr\u00e1cticas',c:'#8b5cf6',dir:'ret'},\n  {n:'Agente de cumplimiento',dt:'Genera gap analysis con roadmap de implementaci\u00f3n',c:'#0891b2',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Formatea reporte ejecutivo con nivel de madurez y gr\u00e1ficos',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Entrega: reporte de madurez + plan de acci\u00f3n priorizado',c:'#4a5568',dir:'ret'},\n]},\n{id:'co2',ch:'webhook',t:'Gesti\u00f3n de cumplimiento continuo',d:'Ruvic despacha cumplimiento y an\u00e1lisis en paralelo: uno verifica controles mientras el otro valida evidencias t\u00e9cnicas.',kpi:'Preparaci\u00f3n de auditor\u00eda un 80% m\u00e1s r\u00e1pida',\n path:['webhook','engine','memory','gemini','agent-compl','politicas','agent-anal','soar','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Trigger semanal: verificaci\u00f3n de controles activos',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia ciclo de verificaci\u00f3n con dos agentes simult\u00e1neos',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga estado previo de cada control y fechas de vencimiento',c:'#10b981',dir:'out'},\n  {n:'Gemini',dt:'Prepara checklist de verificaci\u00f3n por control',c:'#4285F4',dir:'out'},\n  {n:'Agente de cumplimiento',dt:'\u26a1 EN PARALELO: verifica estado de 93 controles ISO',c:'#0891b2',dir:'out',par:{to:'agent-anal',label:'Valida evidencias t\u00e9cnicas: backups, MFA, parches'}},\n  {n:'Pol\u00edticas',dt:'3 pol\u00edticas pr\u00f3ximas a vencer identificadas',c:'#7c3aed',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: 4 evidencias t\u00e9cnicas desactualizadas',c:'#8b5cf6',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea tickets para cada hallazgo de ambos agentes',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Env\u00eda dashboard de cumplimiento consolidado al CISO',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Stakeholders reciben: estado de cumplimiento al 94%',c:'#4a5568',dir:'ret'},\n]},\n{id:'co3',ch:'webhook',t:'Generaci\u00f3n de pol\u00edticas de seguridad',d:'Ruvic genera pol\u00edticas y procedimientos personalizados seg\u00fan el framework y sector del cliente.',kpi:'Genera pol\u00edticas en horas vs. semanas',\n path:['webhook','engine','memory','claude','agent-compl','kb','agent-compl','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Solicitud: generar pol\u00edtica de control de acceso para fintech',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Identifica: sector financiero, regulaci\u00f3n SFC, ISO 27001',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga plantillas base y pol\u00edticas previas del cliente',c:'#10b981',dir:'out'},\n  {n:'Claude',dt:'Genera pol\u00edtica completa con secciones, roles y procedimientos',c:'#d4537e',dir:'out'},\n  {n:'Agente de cumplimiento',dt:'Valida contra requisitos regulatorios y mejores pr\u00e1cticas',c:'#0891b2',dir:'out'},\n  {n:'Base de conocimiento',dt:'Enriquece con controles t\u00e9cnicos espec\u00edficos del sector',c:'#8b5cf6',dir:'ret'},\n  {n:'Agente de cumplimiento',dt:'Finaliza documento con formato corporativo del cliente',c:'#0891b2',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera documento en formato DOCX con branding',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'Entrega: pol\u00edtica de 25 p\u00e1ginas lista para aprobaci\u00f3n',c:'#4a5568',dir:'ret'},\n]},\n{id:'co4',ch:'webhook',t:'Auditor\u00eda de accesos y privilegios',d:'Ruvic despacha cumplimiento y an\u00e1lisis en paralelo: uno audita la matriz de roles mientras el otro detecta anomal\u00edas.',kpi:'Identifica un 30% de cuentas sobre-privilegiadas',\n path:['webhook','engine','memory','gpt4o','agent-compl','ad','agent-anal','soar','engine','webhook'],\n steps:[\n  {n:'API \/ Webhook',dt:'Trigger trimestral: auditor\u00eda de accesos y privilegios',c:'#4a5568',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia auditor\u00eda con dos agentes en paralelo',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Carga l\u00ednea base de permisos aprobados por cargo',c:'#10b981',dir:'out'},\n  {n:'GPT-4o',dt:'Define reglas de detecci\u00f3n: cuentas hu\u00e9rfanas, SoD, excesos',c:'#10a37f',dir:'out'},\n  {n:'Agente de cumplimiento',dt:'\u26a1 EN PARALELO: compara permisos vs. matriz de roles',c:'#0891b2',dir:'out',par:{to:'agent-anal',label:'Detecta patrones an\u00f3malos de uso de privilegios'}},\n  {n:'Active Directory',dt:'Retorna: 1.247 cuentas, 89 con admin, 34 inactivas >90 d\u00edas',c:'#0891b2',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: 5 cuentas con uso an\u00f3malo de privilegios',c:'#8b5cf6',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Crea tickets con hallazgos de ambos agentes priorizados',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera reporte de auditor\u00eda consolidado',c:'#534AB7',dir:'ret'},\n  {n:'API \/ Webhook',dt:'CISO recibe: reporte de auditor\u00eda + acciones correctivas',c:'#4a5568',dir:'ret'},\n]},\n\n\/\/ === GENERAL (19-20) ===\n{id:'gs1',ch:'email-gw',t:'Simulaci\u00f3n de phishing y concientizaci\u00f3n',d:'Ruvic ejecuta respuesta y an\u00e1lisis en paralelo: uno genera la campa\u00f1a mientras el otro mide resultados en tiempo real.',kpi:'Reduce clics en phishing un 70%',\n path:['email-gw','engine','memory','gemini','agent-resp','ad','agent-anal','engine','email-gw'],\n steps:[\n  {n:'Gateway de correo',dt:'Ruvic env\u00eda correo de phishing simulado a 500 empleados',c:'#7c3aed',dir:'out'},\n  {n:'Ruvic Engine',dt:'Inicia monitoreo con dos agentes simult\u00e1neos',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Compara con resultados de campa\u00f1as anteriores por \u00e1rea',c:'#10b981',dir:'out'},\n  {n:'Gemini',dt:'Personaliza correos de phishing por departamento y rol',c:'#4285F4',dir:'out'},\n  {n:'Agente de respuesta',dt:'\u26a1 EN PARALELO: monitorea clics y reportes en tiempo real',c:'#ea580c',dir:'out',par:{to:'agent-anal',label:'Analiza patrones: qu\u00e9 departamentos caen m\u00e1s'}},\n  {n:'Active Directory',dt:'Identifica grupos de alto riesgo y sus managers',c:'#0891b2',dir:'ret'},\n  {n:'Agente de an\u00e1lisis',dt:'Resultado paralelo: financiero tiene 3x m\u00e1s clics que IT',c:'#8b5cf6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera reporte + plan de entrenamiento personalizado',c:'#534AB7',dir:'ret'},\n  {n:'Gateway de correo',dt:'Entrega: m\u00e9tricas de campa\u00f1a + micro-entrenamientos por \u00e1rea',c:'#7c3aed',dir:'ret'},\n]},\n{id:'gs2',ch:'scanner',t:'Gesti\u00f3n de parches y actualizaciones',d:'Ruvic despacha respuesta y cumplimiento en paralelo: uno aplica parches mientras el otro documenta para auditor\u00eda.',kpi:'Reduce ventana de exposici\u00f3n un 65%',\n path:['scanner','engine','memory','deepseek','agent-resp','fw-waf','agent-compl','soar','engine','scanner'],\n steps:[\n  {n:'Esc\u00e1ner de vuln.',dt:'Escaneo detecta 127 parches pendientes en 45 servidores',c:'#16a34a',dir:'out'},\n  {n:'Ruvic Engine',dt:'Clasifica parches y despacha dos agentes simult\u00e1neos',c:'#534AB7',dir:'out'},\n  {n:'Memoria',dt:'Cruza con ventanas de mantenimiento aprobadas',c:'#10b981',dir:'out'},\n  {n:'DeepSeek',dt:'Prioriza: 8 cr\u00edticos con exploit p\u00fablico, aplicar inmediatamente',c:'#3B6D11',dir:'out'},\n  {n:'Agente de respuesta',dt:'\u26a1 EN PARALELO: aplica parches y verifica estado post-update',c:'#ea580c',dir:'out',par:{to:'agent-compl',label:'Documenta cada parche para cumplimiento y auditor\u00eda'}},\n  {n:'Firewall \/ WAF',dt:'Aplica mitigaci\u00f3n virtual para los que no tienen parche a\u00fan',c:'#ea580c',dir:'ret'},\n  {n:'Agente de cumplimiento',dt:'Resultado paralelo: evidencia de parcheo para ISO 27001',c:'#0891b2',dir:'ret'},\n  {n:'SOAR \/ Ticketing',dt:'Documenta con evidencia t\u00e9cnica + normativa de ambos agentes',c:'#3b82f6',dir:'ret'},\n  {n:'Ruvic Engine',dt:'Genera reporte de cumplimiento de parcheo consolidado',c:'#534AB7',dir:'ret'},\n  {n:'Esc\u00e1ner de vuln.',dt:'Re-escanea: 119 de 127 parches aplicados exitosamente',c:'#16a34a',dir:'ret'},\n]}\n];\nconst CHANNELS=[\n  {id:'all',l:'Todos',c:'#6b7280'},\n  {id:'siem',l:'SIEM',c:'#dc2626'},\n  {id:'edr',l:'EDR',c:'#ea580c'},\n  {id:'firewall',l:'Firewall',c:'#0891b2'},\n  {id:'email-gw',l:'Gateway',c:'#7c3aed'},\n  {id:'scanner',l:'Esc\u00e1ner',c:'#16a34a'},\n  {id:'webhook',l:'API',c:'#4a5568'},\n];\n\n\/* ---------------- ESTADO ---------------- *\/\nlet ac=null,anim=false,cs=0,dots=[],hl=new Set(),W,H,cvs,ctx,filt='all',spd=3,advTmr=null,isNarrow=false;\nconst $=id=>root.querySelector('#'+id);\nconst widget=$('rb-widget'),ca=$('rb-ca'),zp=$('rb-zp');\n\nfunction lineIdle(){return root.dataset.theme==='light'?'rgba(34,38,71,0.14)':'rgba(250,240,228,0.12)';}\n\n\/* ---------------- INIT ---------------- *\/\nfunction init(){\n  cvs=$('rb-fc');ctx=cvs.getContext('2d');\n  renderFilters();renderCases();\n  \/\/ Doble rAF: garantiza que el browser ya calcul\u00f3 dimensiones reales (importante en WP)\n  requestAnimationFrame(()=>requestAnimationFrame(applyLayout));\n  window.addEventListener('load',applyLayout);\n  \/\/ listeners\n  $('rb-pb').addEventListener('click',play);\n  $('rb-rst').addEventListener('click',reset);\n  $('rb-spd').addEventListener('input',updSpd);\n  $('rb-theme').addEventListener('click',toggleTheme);\n  ca.addEventListener('click',e=>{ if(!didPan ? (e.target===cvs ? true : e.target===ca ? true : e.target===zp) : false) reset(); });\n  \/\/ tema guardado\n  try{const sv=localStorage.getItem('ruvicCiberTheme');if(sv)root.dataset.theme=sv;}catch(e){}\n  \/\/ decidir layout: load + resize + orientationchange (+ ResizeObserver si est\u00e1 disponible)\n  let rt;\n  window.addEventListener('resize',()=>{clearTimeout(rt);rt=setTimeout(applyLayout,120);});\n  window.addEventListener('orientationchange',()=>setTimeout(applyLayout,250));\n  if(window.ResizeObserver){let raf;new ResizeObserver(()=>{cancelAnimationFrame(raf);raf=requestAnimationFrame(applyLayout);}).observe(widget);}\n  setupTouch();\n  requestAnimationFrame(dr);\n}\n\nfunction toggleTheme(){\n  const next=root.dataset.theme==='light'?'dark':'light';\n  root.dataset.theme=next;\n  try{localStorage.setItem('ruvicCiberTheme',next);}catch(e){}\n}\n\n\/* ---------------- LAYOUT (desktop vs m\u00f3vil) ---------------- *\/\nfunction applyLayout(){\n  isNarrow=widget.clientWidth<760;\n  root.classList.toggle('is-narrow',isNarrow);\n  root.classList.toggle('is-xnarrow',widget.clientWidth<440);\n  rsz();renderNodes();\n  if(isNarrow){recalcZoom();}else{resetTransform();}\n}\n\nfunction rsz(){\n  const dp=window.devicePixelRatio ? window.devicePixelRatio : 1;\n  if(isNarrow){W=1400;H=900;}\n  else{W=ca.clientWidth;H=ca.clientHeight;}\n  cvs.width=W*dp;cvs.height=H*dp;\n  cvs.style.width=W+'px';cvs.style.height=H+'px';\n  const nl=$('rb-nl');\n  nl.style.width=W+'px';nl.style.height=H+'px';\n  zp.style.width=W+'px';zp.style.height=H+'px';\n  ctx.setTransform(dp,0,0,dp,0,0);\n}\n\nfunction p(id){const n=N[id];return{x:n.x\/100*W,y:n.y\/100*H};}\n\n\/* ---------------- RENDER: filtros \/ casos ---------------- *\/\nfunction renderFilters(){\n  $('rb-filters').innerHTML=CHANNELS.map(c=>\n    `<button class=\"fb${filt===c.id?' act':''}\" data-f=\"${c.id}\" type=\"button\"\n       style=\"${filt===c.id?'background:'+c.c+';color:#fff;border-color:'+c.c:''}\">${c.l}<\/button>`).join('');\n  $('rb-filters').querySelectorAll('.fb').forEach(b=>b.addEventListener('click',()=>setFilt(b.dataset.f)));\n}\nfunction setFilt(f){\n  filt=f;renderFilters();\n  if(f==='all'){renderCases();return;}\n  const m=CS.filter(c=>c.ch===f);if(m.length)sel(CS.indexOf(m[0]));else renderCases();\n}\n\nfunction renderCases(){\n  const el=$('rb-cl');\n  const filtered=filt==='all'?CS:CS.filter(c=>c.ch===filt);\n  if(!filtered.length){el.innerHTML='<p class=\"rb-empty\" style=\"padding:18px;text-align:center\">No hay casos para este canal<\/p>';return;}\n  el.innerHTML=filtered.map(c=>{\n    const ri=CS.indexOf(c);const ch=N[c.path[0]];\n    const hasPar=c.steps.some(s=>s.par);\n    return`<button class=\"cb${(ac ? ac.id===c.id : false) ? ' act' : ''}\" data-i=\"${ri}\" type=\"button\" style=\"--cbc:${ch.c}\">\n      <div class=\"cb-ch\"><span class=\"d\" style=\"background:${ch.c}\"><\/span>${ch.l}${hasPar?' \u00b7 <span style=\"color:var(--purple);font-weight:800\">MULTI-AGENTE<\/span>':''}<\/div>\n      <div class=\"cb-t\">${c.t}<\/div>\n      <div class=\"cb-desc\">${c.d}<\/div>\n      <div class=\"cb-kpi\">\u25b2 ${c.kpi}<\/div>\n    <\/button>`;}).join('');\n  el.querySelectorAll('.cb').forEach(b=>b.addEventListener('click',()=>sel(+b.dataset.i)));\n}\n\n\/* ---------------- RENDER: nodos ---------------- *\/\nfunction renderNodes(){\n  const ly=$('rb-nl');ly.innerHTML='';\n  const labels=[\n    {t:'Fuentes de seguridad',x:13,y:1.5},{t:'Ruvic Engine',x:41,y:1.5},\n    {t:'Agentes especializados',x:68,y:1.5},{t:'Integraciones',x:88,y:1.5},\n    {t:'Datos \u00b7 Logs \u00b7 Evidencias \u00b7 Pol\u00edticas',x:50,y:89}\n  ];\n  labels.forEach(l=>{\n    const e=document.createElement('div');e.className='sl';\n    e.style.cssText=`left:${l.x}%;top:${l.y}%;transform:translateX(-50%)`;e.textContent=l.t;ly.appendChild(e);\n  });\n\n  Object.entries(N).forEach(([id,n])=>{\n    const e=document.createElement('div');\n    const dim=(hl.size>0 ? !hl.has(id) : false) ? ' dim' : '';\n    const hlc=hl.has(id)?' hl':'';\n    const clk=n.t==='ch'?' clk':'';\n    e.className='nd'+dim+hlc+clk;e.id='rb-nd-'+id;\n    let gc='';\n    if(hl.has(id)){\n      if(n.t==='ch')gc='gt';else if(n.t==='core' ? true : n.t==='sub' ? true : n.t==='llm')gc='gp';\n      else if(n.t==='ag')gc='go';else if(n.t==='cn')gc=(n.c==='#dc2626'||n.c==='#ef4444')?'gr':'gb';else gc='gb';\n    }\n    e.style.cssText=`left:${n.x}%;top:${n.y}%;transform:translate(-50%,-50%)`;\n    \/\/ Icono como <canvas>: caja de color + letra se DIBUJAN como p\u00edxeles.\n    \/\/ Los p\u00edxeles de un canvas son 100% inmunes al CSS de Kadence Y a cualquier\n    \/\/ plugin de WordPress (lazy-load, optimizador de im\u00e1genes, sanitizador, CSP).\n    \/\/ Es la \u00fanica t\u00e9cnica que no puede fallar por configuraci\u00f3n externa.\n    function svgIc(icId,color,letter,w,h,rx,fs,cls){\n      return `<canvas id=\"rb-ic-${icId}\" class=\"${cls}\" data-w=\"${w}\" data-h=\"${h}\" data-rx=\"${rx}\" data-fs=\"${fs}\" data-color=\"${color}\" data-letter=\"${letter}\"><\/canvas>`;\n    }\n    if(n.t==='core'){\n      e.innerHTML=`<div class=\"nc nc-core ${gc}\">${svgIc(id,n.c,n.lt,48,48,12,20,'ic ic-lg')}<div class=\"nt nt-lg\">${n.l}<\/div><div class=\"ns\">Orquestaci\u00f3n multi-agente<\/div><div style=\"display:flex;gap:5px;margin-top:8px;flex-wrap:wrap;justify-content:center\"><span class=\"tg\" style=\"background:rgba(139,128,255,.22);color:#a59cff\">Clasificador<\/span><span class=\"tg\" style=\"background:rgba(139,128,255,.22);color:#a59cff\">Enrutador LLM<\/span><span class=\"tg\" style=\"background:rgba(16,185,129,.22);color:#34d399\">Contexto<\/span><\/div><\/div>`;\n    }else if(n.t==='ch'){\n      e.addEventListener('click',()=>filterCh(id));\n      e.innerHTML=`<div class=\"nc ${gc}\">${svgIc(id,n.c,n.lt,36,36,18,13,'ic')}<div class=\"nt\">${n.l}<\/div><\/div>`;\n    }else if(n.t==='ag'){\n      e.innerHTML=`<div class=\"nc ${gc}\">${svgIc(id,n.c,n.lt,36,36,18,13,'ic')}<div class=\"nt\">${n.l}<\/div><\/div>`;\n    }else if(n.t==='sub' ? true : n.t==='llm'){\n      e.innerHTML=`<div class=\"ng ${gc}\" style=\"text-align:center\">${svgIc(id,n.c,n.lt,30,30,8,14,'ic-sm')}<div class=\"nt\" style=\"font-size:10.5px;margin-top:5px\">${n.l}<\/div><\/div>`;\n    }else if(n.t==='cn'){\n      e.innerHTML=`<div class=\"nc ${gc}\" style=\"min-width:128px\"><div class=\"nt\">${n.l}<\/div>${n.sub?'<div class=\"ns\">'+n.sub+'<\/div>':''}<\/div>`;\n    }else{\n      e.innerHTML=`<div class=\"ng ${gc}\" style=\"min-width:auto;white-space:nowrap\"><div class=\"nt\" style=\"font-size:11px\">${n.l}<\/div><\/div>`;\n    }\n    ly.appendChild(e);\n  });\n  \/\/ Dibuja cada icono en su canvas (caja + letra como p\u00edxeles, inmune a CSS\/plugins)\n  ly.querySelectorAll('canvas[data-letter]').forEach(drawIc);\n}\n\n\/* Dibuja un icono (rect redondeado + letra blanca) en un <canvas> *\/\nfunction drawIc(cv){\n  const w=+cv.dataset.w,h=+cv.dataset.h,rx=Math.min(+cv.dataset.rx,w\/2,h\/2),fs=+cv.dataset.fs;\n  const color=cv.dataset.color,letter=cv.dataset.letter;\n  const dpr=window.devicePixelRatio||1;\n  cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);\n  cv.style.width=w+'px';cv.style.height=h+'px';\n  const x=cv.getContext('2d');\n  x.scale(dpr,dpr);\n  x.clearRect(0,0,w,h);\n  \/\/ rect redondeado\n  x.beginPath();\n  x.moveTo(rx,0);\n  x.arcTo(w,0,w,h,rx);\n  x.arcTo(w,h,0,h,rx);\n  x.arcTo(0,h,0,0,rx);\n  x.arcTo(0,0,w,0,rx);\n  x.closePath();\n  x.fillStyle=color;x.fill();\n  \/\/ letra blanca centrada\n  x.fillStyle='#ffffff';\n  x.font='800 '+fs+'px system-ui,-apple-system,\"Segoe UI\",sans-serif';\n  x.textAlign='center';x.textBaseline='middle';\n  x.fillText(letter,w\/2,h\/2+0.5);\n}\n\n\/* ---------------- RENDER: tracker ---------------- *\/\nfunction renderSteps(c){\n  const t=$('rb-trk');\n  t.innerHTML=`<h4>Flujo activo <span>0 \/ ${c.steps.length}<\/span><\/h4>`+\n    c.steps.map((s,i)=>{\n      const parBadge=s.par?`<div style=\"margin-top:4px;font-size:8px;font-weight:800;color:var(--purple);background:rgba(139,128,255,.18);display:inline-block;padding:2px 7px;border-radius:5px\">\u26a1 EN PARALELO \u2192 ${s.par.label}<\/div>`:'';\n      return`<div class=\"stp\" id=\"rb-s-${i}\"><div class=\"stp-n\" id=\"rb-sn-${i}\" style=\"background:${s.c}\">${i+1}<\/div><div class=\"stp-i\"><div class=\"stp-nm\">${s.dir==='ret'?'\u2190 ':'\u2192 '}${s.n}<\/div><div class=\"stp-dt\">${s.dt}<\/div>${parBadge}<\/div><\/div>`;\n    }).join('');\n}\n\n\/* ---------------- INTERACCI\u00d3N ---------------- *\/\nfunction sel(i){\n  if(advTmr){clearTimeout(advTmr);advTmr=null;}\n  ac=CS[i];cs=0;dots=[];anim=false;\n  const allNodes=new Set(ac.path);\n  ac.steps.forEach(s=>{if(s.par)allNodes.add(s.par.to);});\n  hl=allNodes;renderNodes();renderSteps(ac);renderCases();\n  $('rb-pb').disabled=false;\n}\nfunction filterCh(id){\n  filt=id;renderFilters();renderCases();\n  const m=CS.filter(c=>c.ch===id);if(m.length)sel(CS.indexOf(m[0]));\n}\nfunction updSpd(){spd=+$('rb-spd').value;$('rb-spdV').textContent=spd+'x';}\n\nfunction play(){\n  if(!ac ? true : anim)return;anim=true;cs=0;dots=[];\n  $('rb-pb').disabled=true;advance();\n}\nfunction advance(){\n  if(!ac ? true : cs>=ac.path.length-1){anim=false;$('rb-pb').disabled=false;return;}\n  const se=$('rb-s-'+cs);\n  if(se){\n    se.classList.add('on');\n    const trk=$('rb-trk');\n    trk.scrollTo({top:Math.max(0,se.offsetTop-trk.offsetTop-18),behavior:'smooth'});\n  }\n  for(let i=0;i<cs;i++){const pe=$('rb-s-'+i);if(pe){pe.classList.remove('on');pe.classList.add('dn');}}\n  const h4=$('rb-trk').querySelector('h4 span');if(h4)h4.textContent=(cs+1)+' \/ '+ac.steps.length;\n  const icEl=$('rb-ic-'+ac.path[cs]);\n  if(icEl){icEl.classList.remove('pulse');void icEl.offsetWidth;icEl.classList.add('pulse');}\n  const snEl=$('rb-sn-'+cs);\n  if(snEl){snEl.classList.remove('pulse');void snEl.offsetWidth;snEl.classList.add('pulse');}\n\n  const p1=p(ac.path[cs]),p2=p(ac.path[cs+1]);\n  const dir=ac.steps[cs]?ac.steps[cs].dir:'out';\n  const col=dir==='ret'?'#3b82f6':(ac.steps[cs]?ac.steps[cs].c:'#534AB7');\n  dots.push({x1:p1.x,y1:p1.y,x2:p2.x,y2:p2.y,t:0,sp:0.012*spd,c:col,a:true});\n  \/\/ PASO PARALELO: lanza un segundo punto al agente paralelo simult\u00e1neamente\n  const step=ac.steps[cs];\n  if(step ? step.par : false){\n    const pPar=p(step.par.to);\n    dots.push({x1:p1.x,y1:p1.y,x2:pPar.x,y2:pPar.y,t:0,sp:0.012*spd,c:'#534AB7',a:true});\n    const parIc=$('rb-ic-'+step.par.to);\n    if(parIc){setTimeout(()=>{parIc.classList.remove('pulse');void parIc.offsetWidth;parIc.classList.add('pulse');},300);}\n  }\n  cs++;\n  advTmr=setTimeout(advance,Math.max(300,800\/spd));\n}\nfunction reset(){\n  if(advTmr){clearTimeout(advTmr);advTmr=null;}\n  ac=null;anim=false;cs=0;dots=[];hl.clear();filt='all';\n  renderFilters();renderCases();renderNodes();\n  $('rb-pb').disabled=true;\n  $('rb-trk').innerHTML='<h4>Flujo activo<\/h4><p class=\"rb-empty\">Selecciona un caso de uso para visualizar cada paso.<\/p>';\n}\n\n\/* ---------------- CANVAS LOOP ---------------- *\/\nfunction dr(){\n  ctx.clearRect(0,0,W,H);\n  if(!ac)drawIdle();else drawActive();\n  dots.forEach(d=>{\n    if(!d.a)return;d.t+=d.sp;if(d.t>=1){d.a=false;return;}\n    const t=d.t,mx=(d.x1+d.x2)\/2,my=(d.y1+d.y2)\/2;\n    const x=(1-t)**2*d.x1+2*(1-t)*t*mx+t**2*d.x2;\n    const y=(1-t)**2*d.y1+2*(1-t)*t*my+t**2*d.y2;\n    ctx.beginPath();ctx.arc(x,y,18,0,Math.PI*2);ctx.fillStyle=hr(d.c,.09);ctx.fill();\n    ctx.beginPath();ctx.arc(x,y,10,0,Math.PI*2);ctx.fillStyle=hr(d.c,.28);ctx.fill();\n    ctx.beginPath();ctx.arc(x,y,5,0,Math.PI*2);ctx.fillStyle=d.c;ctx.fill();\n  });\n  dots=dots.filter(d=>d.a);\n  requestAnimationFrame(dr);\n}\nfunction drawIdle(){\n  const col=lineIdle();\n  \/\/ Canales \u2192 Engine\n  ['siem','edr','firewall','email-gw','scanner','webhook'].forEach(c=>{const a=p(c),b=p('engine');bz(a.x+50,a.y,b.x-90,b.y,col,1.4);});\n  \/\/ Engine \u2192 Agentes\n  ['agent-triage','agent-resp','agent-anal','agent-compl','agent-pentest'].forEach(a=>{const s=p('engine'),e=p(a);bz(s.x+90,s.y,e.x-60,e.y,col,1.4);});\n}\nfunction drawActive(){\n  for(let i=0;i<ac.path.length-1;i++){\n    const a=p(ac.path[i]),b=p(ac.path[i+1]);\n    const done=i<cs,dir=ac.steps[i]?ac.steps[i].dir:'out';\n    const col=dir==='ret'?'#3b82f6':(ac.steps[i]?ac.steps[i].c:'#534AB7');\n    bz(a.x,a.y,b.x,b.y,hr(col,done?.32:.07),done?2.6:1.2);\n  }\n  \/\/ Rutas paralelas (multi-agente): l\u00ednea morada hacia el agente paralelo\n  ac.steps.forEach((s,i)=>{\n    if(s.par ? i<cs : false){\n      const from=p(ac.path[i]),to=p(s.par.to);\n      bz(from.x,from.y,to.x,to.y,hr('#534AB7',.28),2);\n    }\n  });\n}\nfunction bz(x1,y1,x2,y2,c,w){\n  ctx.beginPath();ctx.moveTo(x1,y1);\n  const mx=(x1+x2)\/2,my=(y1+y2)\/2;\n  ctx.quadraticCurveTo(mx,my,x2,y2);\n  ctx.strokeStyle=c;ctx.lineWidth=w;ctx.stroke();\n}\nfunction hr(h,a){const r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16);return`rgba(${r},${g},${b},${a})`;}\n\n\/* ---------------- ZOOM \/ PAN T\u00c1CTIL (m\u00f3vil) ---------------- *\/\nlet scale=1,tx=0,ty=0,lastDist=0,isPinching=false,isDragging=false,startTx=0,startTy=0,didPan=false;\nfunction applyTransform(){zp.style.transform=`translate(${tx}px,${ty}px) scale(${scale})`;}\nfunction resetTransform(){scale=1;tx=0;ty=0;zp.style.transform='none';}\nfunction recalcZoom(){\n  const cw=ca.clientWidth,ch=ca.clientHeight;\n  scale=Math.min(cw\/1400,ch\/900);\n  tx=(cw-1400*scale)\/2;ty=(ch-900*scale)\/2;\n  applyTransform();\n}\nfunction setupTouch(){\n  if(!('ontouchstart' in window))return;\n  ca.addEventListener('touchstart',e=>{\n    if(!isNarrow)return;\n    if(e.touches.length===2){isPinching=true;isDragging=false;\n      const dx=e.touches[0].clientX-e.touches[1].clientX,dy=e.touches[0].clientY-e.touches[1].clientY;\n      lastDist=Math.hypot(dx,dy);\n    }else if(e.touches.length===1){isDragging=true;didPan=false;\n      startTx=e.touches[0].clientX-tx;startTy=e.touches[0].clientY-ty;}\n  },{passive:true});\n  ca.addEventListener('touchmove',e=>{\n    if(!isNarrow)return;\n    if(e.touches.length===2 ? isPinching : false){e.preventDefault();\n      const dx=e.touches[0].clientX-e.touches[1].clientX,dy=e.touches[0].clientY-e.touches[1].clientY;\n      const dist=Math.hypot(dx,dy),ratio=dist\/lastDist;\n      const ns=Math.min(4,Math.max(0.2,scale*ratio));\n      const rect=ca.getBoundingClientRect();\n      const mx=(e.touches[0].clientX+e.touches[1].clientX)\/2-rect.left;\n      const my=(e.touches[0].clientY+e.touches[1].clientY)\/2-rect.top;\n      tx=mx-(mx-tx)*ns\/scale;ty=my-(my-ty)*ns\/scale;scale=ns;lastDist=dist;applyTransform();\n    }else if(e.touches.length===1 ? isDragging : false){e.preventDefault();didPan=true;\n      tx=e.touches[0].clientX-startTx;ty=e.touches[0].clientY-startTy;applyTransform();}\n  },{passive:false});\n  ca.addEventListener('touchend',e=>{\n    if(e.touches.length<2)isPinching=false;\n    if(e.touches.length===0){isDragging=false;setTimeout(()=>{didPan=false;},50);}\n  },{passive:true});\n}\n\ninit();\n\n\/\/ Forzar estilos del slider que Kadence sobreescribe (solo lo independiente del tema:\n\/\/ borde\/sombra\/padding). El COLOR de fondo lo maneja el CSS por tema para que cambie\n\/\/ correctamente al alternar claro\/oscuro.\n(function(){\n  const rng=root.querySelector('#rb-spd');\n  if(!rng)return;\n  rng.style.setProperty('border','none','important');\n  rng.style.setProperty('box-shadow','none','important');\n  rng.style.setProperty('padding','0','important');\n  rng.style.setProperty('outline','none','important');\n})();\n\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>\u263e Demo interactiva Mira c\u00f3mo Ruvic orquesta el flujo en tiempo real Selecciona un caso de uso y reproduce el flujo completo de principio a fin. Arrastra para mover \u00b7 pellizca para hacer zoom R Ruvic AI \u00b7 Casos de uso Haz clic en un canal o elige un caso para ver el flujo de&#8230;<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kad_post_transparent":"","_kad_post_title":"hide","_kad_post_layout":"fullwidth","_kad_post_sidebar_id":"","_kad_post_content_style":"unboxed","_kad_post_vertical_padding":"hide","_kad_post_feature":"hide","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"<!-- ================================================   BLOQUE 00 \u00b7 TOKENS GLOBALES   \u25ba Pegar UNA SOLA VEZ en WordPress:     Apariencia \u2192 Personalizar \u2192 CSS adicional     O en el primer bloque \"HTML personalizado\" de la p\u00e1gina.   \u25ba Fuentes: a\u00f1adir en el <head> del tema (functions.php o plugin):     <link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@400;500;600&family=JetBrains+Mono:wght@400;500&family=Syne:wght@500;600;700;800&display=swap\" rel=\"stylesheet\" \/> ================================================ -->  <style> \/* \u2500\u2500 TOKENS GLOBALES ROBIN AI \u00b7 MOTOR DE IA \u2500\u2500 *\/ :root {   --rvp-navy:        #0F1B3C;   --rvp-navy-deep:   #0A1230;   --rvp-navy-soft:   #18234A;   --rvp-navy-card:   #1A2649;   --rvp-navy-line:   rgba(255,255,255,0.08);    --rvp-red:         #E8344B;   --rvp-red-deep:    #C42339;   --rvp-red-soft:    #F76A7B;   --rvp-mustard:     #E8B53C;   --rvp-coral:       #F4A78C;    --rvp-white:       #FFFFFF;   --rvp-cream:       #FDF2E1;   --rvp-cream-border:#F0E6D3;    --rvp-text:        #F5F5F8;   --rvp-text-muted:  rgba(245,245,248,0.68);   --rvp-text-subtle: rgba(245,245,248,0.42);   --rvp-text-dark:   #0F1B3C;   --rvp-text-gray:   #6B7280;    --rvp-r-sm:   8px;   --rvp-r-md:   14px;   --rvp-r-lg:   22px;   --rvp-r-pill: 999px;    --rvp-sp3:  12px;   --rvp-sp4:  16px;   --rvp-sp5:  24px;   --rvp-sp6:  32px;   --rvp-sp7:  48px;   --rvp-sp8:  64px;   --rvp-sp9:  96px;   --rvp-sp10: 128px;    --rvp-font-display: 'Syne', sans-serif;   --rvp-font-body:    'DM Sans', sans-serif;   --rvp-font-mono:    'JetBrains Mono', monospace;    --rvp-ease: cubic-bezier(0.22,1,0.36,1);   --rvp-container: 1240px; }  \/* \u2500\u2500 RESET SCOPED (no afecta el tema WP) \u2500\u2500 *\/ .rvp-wrap *, .rvp-wrap *::before, .rvp-wrap *::after { box-sizing: border-box; } .rvp-wrap { -webkit-font-smoothing: antialiased; } .rvp-wrap img, .rvp-wrap svg { display: block; max-width: 100%; } .rvp-wrap a { color: inherit; text-decoration: none; } .rvp-wrap ul { list-style: none; padding: 0; margin: 0; }  \/* \u2500\u2500 CONTENEDOR \u2500\u2500 *\/ .rvp-inner {   width: 100%;   max-width: var(--rvp-container);   margin: 0 auto;   padding: 0 var(--rvp-sp5); }  \/* \u2500\u2500 EYEBROW \u2500\u2500 *\/ .rvp-eyebrow {   display: inline-flex;   align-items: center;   gap: var(--rvp-sp3);   font-family: var(--rvp-font-body);   font-size: 11px;   font-weight: 500;   letter-spacing: 0.16em;   text-transform: uppercase;   color: var(--rvp-red);   margin-bottom: 16px; } .rvp-eyebrow::before {   content: '';   width: 6px; height: 6px;   background: var(--rvp-red);   border-radius: 50%;   flex-shrink: 0; }  \/* \u2500\u2500 SECTION HEAD \u2500\u2500 *\/ .rvp-section-head { max-width: 720px; margin-bottom: var(--rvp-sp8); } .rvp-section-head h2 {   font-family: var(--rvp-font-display);   font-size: clamp(1.9rem, 3.6vw, 2.8rem);   font-weight: 700;   letter-spacing: -0.025em;   line-height: 1.08;   margin: 0 0 var(--rvp-sp5); } .rvp-section-head--dark h2  { color: var(--rvp-text-dark); } .rvp-section-head--dark .rvp-lead { color: var(--rvp-text-gray); } .rvp-section-head--light h2  { color: var(--rvp-text); } .rvp-section-head--light .rvp-lead { color: var(--rvp-text-muted); }  .rvp-lead {   font-family: var(--rvp-font-body);   font-size: clamp(1rem,1.6vw,1.125rem);   line-height: 1.65;   max-width: 56ch;   margin: 0; }  \/* \u2500\u2500 BOTONES \u2500\u2500 *\/ .rvp-btn {   display: inline-flex;   align-items: center;   justify-content: center;   gap: var(--rvp-sp3);   padding: 14px 24px;   border-radius: var(--rvp-r-pill);   font-family: var(--rvp-font-body);   font-weight: 500;   font-size: 14px;   letter-spacing: 0.04em;   text-transform: uppercase;   text-decoration: none;   cursor: pointer;   border: none;   transition: transform 220ms var(--rvp-ease), background 220ms var(--rvp-ease), box-shadow 220ms var(--rvp-ease);   white-space: nowrap; } .rvp-btn--primary { background: var(--rvp-red); color: #fff; box-shadow: 0 6px 24px rgba(232,52,75,0.28); } .rvp-btn--primary:hover { background: var(--rvp-red-deep); transform: translateY(-2px); box-shadow: 0 10px 32px rgba(232,52,75,0.42); color: #fff; } .rvp-btn--ghost { background: transparent; color: #fff; border: 1px solid rgba(255,255,255,0.22); } .rvp-btn--ghost:hover { border-color: #fff; background: rgba(255,255,255,0.04); color: #fff; } .rvp-btn--inverted { background: #fff; color: var(--rvp-red); box-shadow: 0 8px 28px rgba(0,0,0,0.22); } .rvp-btn--inverted:hover { transform: translateY(-3px); box-shadow: 0 14px 36px rgba(0,0,0,0.3); background: #F9F9F9; color: var(--rvp-red-deep); }  \/* \u2500\u2500 REVEAL ANIMATION \u2500\u2500 *\/ .rvp-reveal {   opacity: 0;   transform: translateY(22px);   transition: opacity 650ms var(--rvp-ease), transform 650ms var(--rvp-ease); } .rvp-reveal.is-vis { opacity: 1; transform: translateY(0); } .rvp-reveal:nth-child(2) { transition-delay: 80ms; } .rvp-reveal:nth-child(3) { transition-delay: 160ms; } .rvp-reveal:nth-child(4) { transition-delay: 240ms; } .rvp-reveal:nth-child(5) { transition-delay: 300ms; } .rvp-reveal:nth-child(6) { transition-delay: 360ms; }  \/* \u2500\u2500 FADE-UP (hero) \u2500\u2500 *\/ @keyframes rvp-fadeup {   from { opacity:0; transform:translateY(20px); }   to   { opacity:1; transform:translateY(0); } } .rvp-fu   { animation: rvp-fadeup 700ms var(--rvp-ease) both; } .rvp-fu-1 { animation-delay: 80ms; } .rvp-fu-2 { animation-delay: 180ms; } .rvp-fu-3 { animation-delay: 280ms; } <\/style>  <script> \/* \u2500\u2500 REVEAL OBSERVER GLOBAL \u2500\u2500 *\/ (function(){   if (!('IntersectionObserver' in window)) {     document.querySelectorAll('.rvp-reveal').forEach(function(el){ el.classList.add('is-vis'); });     return;   }   var obs = new IntersectionObserver(function(entries){     entries.forEach(function(entry){       if (entry.isIntersecting) {         entry.target.classList.add('is-vis');         obs.unobserve(entry.target);       }     });   }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });   document.querySelectorAll('.rvp-reveal').forEach(function(el){ obs.observe(el); }); })(); <\/script>","footnotes":""},"class_list":["post-5472","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/pages\/5472","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/comments?post=5472"}],"version-history":[{"count":9,"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/pages\/5472\/revisions"}],"predecessor-version":[{"id":6274,"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/pages\/5472\/revisions\/6274"}],"wp:attachment":[{"href":"https:\/\/ruvic.ai\/en\/wp-json\/wp\/v2\/media?parent=5472"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}