react-dashstream 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -69,6 +69,21 @@ Click a service to expand its topology. Click a component to drill into its inte
69
69
 
70
70
  ---
71
71
 
72
+ ## AI assistant skills
73
+
74
+ Published with the package under **`skills/`** — each folder is a small, topic-focused reference for coding agents (Cursor, OpenCode, etc.):
75
+
76
+ | Skill | Focus |
77
+ | ----- | ----- |
78
+ | `dashstream-core` | Package overview, install, theming, exports, types, pitfalls |
79
+ | `dashstream-3d-dashboard` | `AIOPsDashboard`, services, nodes, positioning, connections |
80
+ | `dashstream-live-data` | `DataProvider`, bindings, hooks, endpoint contract |
81
+ | `dashstream-component-dialogs` | Drill-down metrics, internals, sparklines, alerts |
82
+ | `dashstream-event-view` | `EventView`, event API, event-to-dashboard bridge |
83
+ | `dashstream-datacenter-view` | `DatacenterView`, topology, geography, buildings |
84
+
85
+ ---
86
+
72
87
  ## Theme (light / dark)
73
88
 
74
89
  The dashboard ships with **light** and **dark** visual modes. `AIOPsDashboard` defaults to **light**; the header includes a control to toggle modes.
@@ -139,7 +154,7 @@ See `example/Dashboard.tsx` in this package for a complete two-service example w
139
154
 
140
155
  The demo app (`src/App.tsx`) uses `example/SaudiMapView.tsx`, a thin wrapper around `DatacenterView` that composes the map with **`DatacenterSite`** / shape components (`TowerDC`, `FlatDC`, …). Scenario data (configs and drill-down services) lives in `example/saudiMapDemoData.tsx`; optional mock metric sliders use `example/DemoMetricPanel.tsx` + `example/DemoMetricPanel.css` (not part of the published package).
141
156
 
142
- **Agent-oriented reference:** see **`dashstream-skill.md`** (section **DatacenterView — topology / geography map**) for props, types, mock vs live data, and composition with `DataProvider`.
157
+ **Agent-oriented reference:** see **`skills/dashstream-datacenter-view/SKILL.md`** for props, types, mock vs live data, and composition with `DataProvider`. Other topics live under **`skills/<name>/SKILL.md`** — see **AI assistant skills** below.
143
158
 
144
159
  ### Minimal import
145
160
 
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- @keyframes status-change-pulse{0%{opacity:0;transform:scale(.6)}10%{opacity:1;transform:scale(1.15)}25%{opacity:.1;transform:scale(.95)}40%{opacity:.9;transform:scale(1.1)}60%{opacity:.15;transform:scale(1)}to{opacity:0;transform:scale(1.3)}}@keyframes comp-dialog-border-glow-light{0%,to{border-color:var(--dialog-color, #64748b)44;box-shadow:0 4px 28px #0f172a1a,0 0 24px var(--dialog-color, #64748b) 14,inset 0 1px #ffffffd9}50%{border-color:var(--dialog-color, #64748b)66;box-shadow:0 8px 36px #0f172a1f,0 0 32px var(--dialog-color, #64748b) 20,inset 0 1px #ffffffe6}}.app{display:grid;grid-template-rows:52px 1fr;width:100%;height:100vh;overflow:hidden;position:relative;background:#020810;color:#c8dff0;font-family:var(--aiops-font-family, "Segoe UI", system-ui, -apple-system, sans-serif);-webkit-font-smoothing:antialiased}.app-header{display:flex;align-items:center;gap:18px;padding:0 24px;border-bottom:1px solid rgba(0,229,255,.08);background:#020810eb;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);position:relative;z-index:10}.hdr-brand{display:flex;align-items:center;gap:8px}.brand-pulse{width:7px;height:7px;border-radius:50%;background:#00e5ff;box-shadow:0 0 8px #00e5ff,0 0 18px #00e5ff80;animation:holo-led-blink 2s linear infinite}.brand-text{font-size:10px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff;opacity:.7}.hdr-theme-toggle{background:#00e5ff14;border:1px solid rgba(0,229,255,.2);color:#00e5ff;border-radius:4px;padding:4px 10px;font-size:14px;cursor:pointer;transition:background .2s,border-color .2s;line-height:1}.hdr-theme-toggle:hover{background:#00e5ff2e;border-color:#00e5ff66}.hdr-right{display:flex;align-items:center;gap:8px;margin-left:auto}.hdr-tag{font-size:9px;letter-spacing:.2em;color:#00e5ff59;border:1px solid rgba(0,229,255,.15);padding:3px 8px;border-radius:2px}.app--light{background:transparent;color:#1e293b}.app--light .app-header{border-bottom:1px solid rgba(15,23,42,.08);background:#ffffffe0;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.app--light .brand-pulse{background:#0d9488;box-shadow:0 0 6px #0d948873,0 0 14px #0d948838}.app--light .brand-text{color:#0f766e;opacity:.95}.app--light .hdr-theme-toggle{background:#0d948814;border:1px solid rgba(13,148,136,.22);color:#0f766e}.app--light .hdr-theme-toggle:hover{background:#0d948829;border-color:#0d948861}.app--light .hdr-tag{color:#334155c7;border-color:#33415533}.scene{display:flex;flex-direction:column;align-items:center;overflow:hidden;padding:0;position:relative;z-index:1;gap:0;background:transparent}.float-node{display:flex;flex-direction:column;align-items:center;position:relative}.float-node--interactive:before{content:"";position:absolute;inset:-40px -35px -15px}.float-body{position:relative;animation:holo-float 4s ease-in-out infinite}.scan-line{position:absolute;top:0;left:0;right:0;height:1.5px;animation:holo-scan 3.5s linear infinite;pointer-events:none;z-index:10}.node-tag{font-size:24px;letter-spacing:.2em;text-transform:uppercase;font-family:var(--aiops-font-family, "Courier New", monospace);margin-top:14px;text-align:center;text-shadow:0 0 6px currentColor}.node-subtag{font-size:11px;letter-spacing:.15em;text-transform:uppercase;font-family:var(--aiops-font-family, "Courier New", monospace);margin-top:4px;text-align:center}.sync-bridge{display:flex;flex-direction:column;align-items:center;justify-content:center;width:110px;gap:6px;flex-shrink:0;font-family:var(--aiops-font-family, "Courier New", monospace)}.sync-arrows{display:flex;align-items:center;width:100%;gap:4px}.sync-line{flex:1;height:2px;border-radius:1px;animation:holo-beam-pulse 1.8s ease-in-out infinite}.sync-status{font-size:8px;letter-spacing:.18em;text-transform:uppercase;text-align:center}.sync-latency{font-size:6.5px;letter-spacing:.1em;text-align:center;font-family:var(--aiops-font-family, "Courier New", monospace)}.base-ring{position:absolute;top:50%;left:50%;border-style:solid;border-radius:50%;transform:translate(-50%,-50%) scaleY(.22);animation:holo-ring-pulse 2.5s ease-in-out infinite}.base-hotspot{position:absolute;top:50%;left:50%;width:8%;height:8%;border-radius:50%;transform:translate(-50%,-50%) scaleY(.22);background:radial-gradient(circle,#ffffff 0%,#ff8c00 35%,transparent 70%);box-shadow:0 0 20px #ff8c00,0 0 40px #ff8c0080}@keyframes refresh-error-pulse{0%,to{opacity:1;box-shadow:0 0 6px #f25,0 0 14px #f256}50%{opacity:.5;box-shadow:0 0 3px #f25}}.hdr-refresh-error{display:flex;align-items:center;gap:7px;padding:3px 10px;border:1px solid rgba(255,34,85,.35);border-radius:3px;background:#ff22550f;animation:refresh-error-pulse 2s ease-in-out infinite}.refresh-error-dot{width:6px;height:6px;border-radius:50%;background:#f25;box-shadow:0 0 6px #f25;flex-shrink:0}.refresh-error-text{font-size:8px;letter-spacing:.18em;text-transform:uppercase;color:#f25;white-space:nowrap;font-family:var(--aiops-font-family, "Courier New", monospace)}@keyframes cred-panel-glow{0%,to{border-color:#00e5ff2e;box-shadow:0 0 40px #00e5ff14,0 20px 80px #000c,inset 0 0 60px #00000080}50%{border-color:#00e5ff59;box-shadow:0 0 60px #00e5ff26,0 20px 80px #000c,inset 0 0 60px #00000080}}@keyframes cred-fade-in{0%{opacity:0}to{opacity:1}}@keyframes cred-panel-enter{0%{opacity:0;transform:translateY(20px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes cred-icon-pop{0%{opacity:0;transform:scale(.4) translateY(10px)}60%{opacity:1;transform:scale(1.1) translateY(-3px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes cred-scanline-sweep{0%{top:-2px;opacity:0}5%{opacity:.7}90%{opacity:.4}to{top:100%;opacity:0}}@keyframes cred-btn-shine{0%{left:-100%}to{left:200%}}.cred-overlay{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#020810e0;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);animation:cred-fade-in .4s ease-out}.cred-panel{position:relative;width:380px;padding:40px 36px 32px;border:1px solid rgba(0,229,255,.18);border-radius:6px;background:linear-gradient(170deg,#061226f7,#030a16fa);animation:cred-panel-enter .5s ease-out,cred-panel-glow 4s ease-in-out infinite;overflow:hidden}.cred-scanline{position:absolute;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 0%,rgba(0,229,255,.5) 50%,transparent 100%);animation:cred-scanline-sweep 4s linear infinite;pointer-events:none;z-index:2}.cred-corner{position:absolute;width:18px;height:18px;pointer-events:none;z-index:3}.cred-corner:before,.cred-corner:after{content:"";position:absolute;background:#00e5ff73}.cred-corner:before{top:0;left:0;width:18px;height:1px}.cred-corner:after{top:0;left:0;width:1px;height:18px}.cred-corner--tl{top:-1px;left:-1px}.cred-corner--tr{top:-1px;right:-1px;transform:scaleX(-1)}.cred-corner--bl{bottom:-1px;left:-1px;transform:scaleY(-1)}.cred-corner--br{bottom:-1px;right:-1px;transform:scale(-1)}.cred-icon{display:flex;justify-content:center;margin-bottom:18px;animation:cred-icon-pop .6s ease-out .15s both}.cred-title{text-align:center;font-size:13px;font-weight:700;letter-spacing:.28em;text-transform:uppercase;color:#00e5ff;margin-bottom:6px}.cred-subtitle{text-align:center;font-size:9px;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff59;margin-bottom:28px;font-family:var(--aiops-font-family, "Courier New", monospace)}.cred-field{margin-bottom:18px}.cred-label{display:block;font-size:8px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff8c;margin-bottom:6px;font-family:var(--aiops-font-family, "Courier New", monospace)}.cred-input{width:100%;padding:10px 14px;border:1px solid rgba(0,229,255,.15);border-radius:4px;background:#000a19b3;color:#c8dff0;font-size:13px;font-family:var(--aiops-font-family, "Courier New", monospace);letter-spacing:.04em;outline:none;transition:border-color .25s,box-shadow .25s;box-sizing:border-box}.cred-input::placeholder{color:#c8dff02e;letter-spacing:.06em}.cred-btn{position:relative;display:block;width:100%;margin-top:26px;padding:12px 0;border:1px solid rgba(0,229,255,.3);border-radius:4px;background:#00e5ff0f;color:#00e5ff;font-size:11px;font-weight:700;letter-spacing:.3em;text-transform:uppercase;font-family:inherit;transition:background .25s,box-shadow .25s,opacity .25s;overflow:hidden}.cred-btn-glow{position:absolute;top:0;left:-100%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(0,229,255,.08),transparent);pointer-events:none;animation:cred-btn-shine 3s ease-in-out infinite}.cred-footer{margin-top:20px;text-align:center;font-size:7px;letter-spacing:.2em;text-transform:uppercase;color:#c8dff02e;font-family:var(--aiops-font-family, "Courier New", monospace)}@keyframes cred-panel-glow-light{0%,to{border-color:#0d948838;box-shadow:0 4px 40px #0f172a14,0 0 32px #0d94880f,inset 0 1px #fffffff2}50%{border-color:#0d948861;box-shadow:0 8px 48px #0f172a1a,0 0 40px #0d94881a,inset 0 1px #fff}}.cred-overlay--light{background:#f1f5f9eb}.cred-panel--light{border:1px solid rgba(15,23,42,.1);background:linear-gradient(170deg,#fffffffa,#f8fafcfc);animation:cred-panel-enter .5s ease-out,cred-panel-glow-light 4s ease-in-out infinite}.cred-panel--light .cred-scanline{background:linear-gradient(90deg,transparent 0%,rgba(13,148,136,.35) 50%,transparent 100%)}.cred-panel--light .cred-corner:before,.cred-panel--light .cred-corner:after{background:#0d948866}.cred-panel--light .cred-title{color:#0f766e}.cred-panel--light .cred-subtitle{color:#3341558c}.cred-panel--light .cred-label{color:#334155a6}.cred-panel--light .cred-input{border-color:#0f172a1f;background:#fffffff2;color:#1e293b}.cred-panel--light .cred-input::placeholder{color:#64748b73}.cred-panel--light .cred-btn{border-color:#0d948859;background:#0d948814;color:#0f766e}.cred-panel--light .cred-btn-glow{background:linear-gradient(90deg,transparent,rgba(13,148,136,.12),transparent)}.cred-panel--light .cred-footer{color:#47556973}.cred-panel--light .cred-btn:hover:not(:disabled){background:#0d948829;box-shadow:0 0 20px #0d948826,inset 0 0 12px #0d94880f}.ev-root{display:flex;flex-direction:column;height:100%;width:100%;background:linear-gradient(180deg,#020810f7,#030c18fa);color:#c8dff0;font-family:var(--aiops-font-family, "Segoe UI", system-ui, -apple-system, sans-serif);overflow:hidden}.ev-header{position:relative;display:flex;align-items:center;justify-content:space-between;padding:14px 24px;border-bottom:1px solid rgba(0,229,255,.1);background:#040e1cd9;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);flex-shrink:0}.ev-header-left{display:flex;align-items:center;gap:12px}.ev-header-pulse{width:7px;height:7px;border-radius:50%;background:#00e5ff;box-shadow:0 0 8px #00e5ff,0 0 18px #00e5ff80;animation:holo-led-blink 2s linear infinite}.ev-title{font-size:14px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:#00e5ff;margin:0}.ev-event-count{font-size:11px;color:#00e5ff73;letter-spacing:.08em;border:1px solid rgba(0,229,255,.15);padding:2px 10px;border-radius:10px}.ev-header-right{display:flex;align-items:center;gap:12px}.ev-live-tag{display:flex;align-items:center;gap:6px;font-size:9px;font-weight:700;letter-spacing:.25em;color:#0f8;border:1px solid rgba(0,255,136,.25);padding:3px 10px;border-radius:3px}.ev-live-dot{width:6px;height:6px;border-radius:50%;background:#0f8;box-shadow:0 0 6px #0f8;animation:holo-led-blink 1.5s linear infinite}.ev-live-dot--err{background:#f25;box-shadow:0 0 6px #f25}.ev-error-tag{display:flex;align-items:center;gap:5px;font-size:9px;font-weight:700;letter-spacing:.15em;color:#f25;cursor:default}.ev-error-dot{width:5px;height:5px;border-radius:50%;background:#f25;box-shadow:0 0 5px #f25;animation:holo-led-blink 1s linear infinite}.ev-loading-tag{display:flex;align-items:center;gap:6px;font-size:9px;font-weight:600;letter-spacing:.15em;color:#00e5ff99}.ev-loading-spinner{width:10px;height:10px;border:1.5px solid rgba(0,229,255,.15);border-top-color:#00e5ff;border-radius:50%;animation:ev-spin .8s linear infinite}@keyframes ev-spin{to{transform:rotate(360deg)}}.ev-refresh-tag{font-size:9px;letter-spacing:.06em;color:#648caa73;font-family:Cascadia Code,Fira Code,Consolas,monospace}.ev-refresh-btn{padding:2px 8px;border:1px solid rgba(0,229,255,.15);border-radius:3px;background:transparent;color:#00e5ff99;font-size:14px;cursor:pointer;transition:all .2s ease;font-family:inherit;line-height:1}.ev-refresh-btn:hover:not(:disabled){background:#00e5ff0f;border-color:#00e5ff4d;color:#00e5ff}.ev-refresh-btn:disabled{opacity:.25;cursor:default}.ev-toolbar{display:flex;align-items:center;justify-content:space-between;padding:12px 24px;gap:16px;border-bottom:1px solid rgba(0,229,255,.06);flex-shrink:0;flex-wrap:wrap}.ev-filters{display:flex;gap:8px}.ev-filter-chip{display:flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid rgba(100,120,140,.25);border-radius:4px;background:#0a142399;color:#6a8198;font-size:11px;font-weight:600;letter-spacing:.06em;cursor:pointer;transition:all .25s ease;font-family:inherit}.ev-filter-chip:hover{background:#0f1e32cc;border-color:#64788c73}.ev-filter-chip--active{background:#0a1423d9}.ev-chip-dot{width:6px;height:6px;border-radius:50%;transition:background .25s ease}.ev-chip-count{font-size:10px;opacity:.6;margin-left:2px}.ev-search-wrap{position:relative;flex:1;max-width:380px;min-width:200px}.ev-search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);width:15px;height:15px;color:#00e5ff59;pointer-events:none}.ev-search{width:100%;padding:7px 12px 7px 32px;border:1px solid rgba(0,229,255,.12);border-radius:4px;background:#060e1cb3;color:#c8dff0;font-size:12px;font-family:inherit;outline:none;transition:border-color .3s ease,box-shadow .3s ease}.ev-search::placeholder{color:#648caa73}.ev-search:focus{border-color:#00e5ff66;box-shadow:0 0 12px #00e5ff1f,inset 0 0 20px #00e5ff08}.ev-table-wrap{flex:1;overflow:auto;position:relative}.ev-table-wrap::-webkit-scrollbar{width:5px;height:5px}.ev-table-wrap::-webkit-scrollbar-track{background:transparent}.ev-table-wrap::-webkit-scrollbar-thumb{background:#00e5ff26;border-radius:3px}.ev-table-wrap::-webkit-scrollbar-thumb:hover{background:#00e5ff4d}.ev-table{width:100%;border-collapse:separate;border-spacing:0;font-size:11.5px}.ev-th{position:sticky;top:0;z-index:4;padding:10px 12px 10px 14px;background:#040c18f2;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-bottom:1px solid rgba(0,229,255,.15);text-align:left;font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#00e5ffb3;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:color .2s ease;overflow:hidden;text-overflow:ellipsis}.ev-th:after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,rgba(0,229,255,.2),transparent)}.ev-th:hover{color:#00e5ff}.ev-th-inner{display:flex;align-items:center;gap:5px}.ev-sort-arrow{font-size:8px;line-height:1}.ev-sort-arrow--idle{opacity:.3}.ev-sort-arrow--active{color:#00e5ff;text-shadow:0 0 6px rgba(0,229,255,.6)}.ev-row{transition:background .2s ease,box-shadow .2s ease;border-bottom:1px solid rgba(0,229,255,.04)}.ev-row:nth-child(2n){background:#0610204d}.ev-row:hover{background:#00e5ff0a;box-shadow:inset 0 0 30px var(--row-glow, rgba(0, 229, 255, .03)),inset 3px 0 0 var(--row-color, #00e5ff)}.ev-td{padding:9px 14px;vertical-align:middle;white-space:nowrap;border-bottom:1px solid rgba(15,30,50,.5);overflow:hidden;text-overflow:ellipsis}.ev-td-mono{font-family:Cascadia Code,Fira Code,Consolas,monospace;font-size:11px;letter-spacing:.02em}.ev-td-msg{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ev-cell-dim{color:#6482a059}.ev-severity-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border:1px solid;border-radius:3px;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}.ev-severity-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}.ev-sms-badge{display:inline-flex;align-items:center;gap:5px;font-size:10px;font-weight:600;letter-spacing:.06em}.ev-sms-badge--ok{color:#0f8}.ev-sms-badge--ok .ev-sms-dot{background:#0f8;box-shadow:0 0 5px #0f8}.ev-sms-badge--fail{color:#f25}.ev-sms-badge--fail .ev-sms-dot{background:#f25;box-shadow:0 0 5px #f25}.ev-sms-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}.ev-class-tag{display:inline-block;padding:2px 8px;border:1px solid rgba(0,229,255,.15);border-radius:3px;font-size:10px;letter-spacing:.04em;color:#00e5ffb3;background:#00e5ff0a;white-space:nowrap}.ev-mon-cat{font-size:10px;letter-spacing:.04em;color:#6a8198}.ev-mon-cat--247{color:#00e5ff;font-weight:600}.ev-empty{text-align:center;padding:48px 24px;color:#648caa73;font-size:13px;letter-spacing:.1em}.ev-resize-handle{position:absolute;top:0;right:0;bottom:0;width:6px;cursor:col-resize;z-index:5}.ev-resize-handle:after{content:"";position:absolute;top:20%;right:2px;bottom:20%;width:1px;background:#00e5ff1f;transition:background .2s ease,box-shadow .2s ease}.ev-resize-handle:hover:after{background:#00e5ff80;box-shadow:0 0 4px #00e5ff4d}.ev-statusbar{display:flex;align-items:center;padding:6px 24px;border-top:1px solid rgba(0,229,255,.06);background:#040c18d9;flex-shrink:0}.ev-statusbar-text{font-size:10px;color:#648caa73;letter-spacing:.06em}.ev-header:before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 0%,#00e5ff 50%,transparent 100%);opacity:.5;animation:ev-scan-slide 4s linear infinite}@keyframes ev-scan-slide{0%{transform:translate(-100%)}to{transform:translate(100%)}}.ev-root--light{background:linear-gradient(180deg,#f1f5f9,#e2e8f0);color:#1e293b}.ev-root--light .ev-header{border-bottom:1px solid rgba(15,23,42,.08);background:#ffffffe6}.ev-root--light .ev-header:before{background:linear-gradient(90deg,transparent 0%,rgba(13,148,136,.35) 50%,transparent 100%);opacity:.65}.ev-root--light .ev-header-pulse{background:#0d9488;box-shadow:0 0 6px #0d948873,0 0 14px #0d948833}.ev-root--light .ev-title{color:#0f766e}.ev-root--light .ev-event-count{color:#334155a6;border-color:#33415526}.ev-root--light .ev-live-tag{color:#059669;border-color:#05966947}.ev-root--light .ev-live-dot{background:#059669;box-shadow:0 0 5px #05966973}.ev-root--light .ev-loading-tag{color:#0d9488bf}.ev-root--light .ev-loading-spinner{border-color:#0d948833;border-top-color:#0d9488}.ev-root--light .ev-refresh-tag{color:#4755698c}.ev-root--light .ev-refresh-btn{border-color:#0d948838;color:#0f766ebf}.ev-root--light .ev-refresh-btn:hover:not(:disabled){background:#0d948814;border-color:#0d948859;color:#0f766e}.ev-root--light .ev-toolbar{border-bottom:1px solid rgba(15,23,42,.06)}.ev-root--light .ev-filter-chip{border-color:#3341552e;background:#ffffffbf;color:#64748b}.ev-root--light .ev-filter-chip:hover{background:#f8fafcf2;border-color:#33415547}.ev-root--light .ev-filter-chip--active{background:#fffffff2}.ev-root--light .ev-search-icon{color:#0d948866}.ev-root--light .ev-search{border-color:#0f172a1f;background:#ffffffeb;color:#1e293b}.ev-root--light .ev-search::placeholder{color:#64748b8c}.ev-root--light .ev-search:focus{border-color:#0d948873;box-shadow:0 0 0 2px #0d94881f,inset 0 1px #ffffffe6}.ev-root--light .ev-table-wrap::-webkit-scrollbar-thumb{background:#0f172a1f}.ev-root--light .ev-table-wrap::-webkit-scrollbar-thumb:hover{background:#0f172a38}.ev-root--light .ev-th{background:#fffffff2;border-bottom:1px solid rgba(15,23,42,.1);color:#0f766ed9}.ev-root--light .ev-th:after{background:linear-gradient(90deg,transparent,rgba(13,148,136,.2),transparent)}.ev-root--light .ev-th:hover{color:#0f766e}.ev-root--light .ev-sort-arrow--active{color:#0f766e;text-shadow:none}.ev-root--light .ev-row{border-bottom:1px solid rgba(15,23,42,.05)}.ev-root--light .ev-row:nth-child(2n){background:#f8fafcd9}.ev-root--light .ev-row:hover{background:#0d94880f;box-shadow:inset 0 0 24px var(--row-glow, rgba(13, 148, 136, .04)),inset 3px 0 0 var(--row-color, #0d9488)}.ev-root--light .ev-td{border-bottom:1px solid rgba(15,23,42,.06)}.ev-root--light .ev-cell-dim{color:#64748b73}.ev-root--light .ev-class-tag{border-color:#0d948838;color:#0f766ee6;background:#0d94880f}.ev-root--light .ev-mon-cat{color:#64748b}.ev-root--light .ev-mon-cat--247{color:#0d9488}.ev-root--light .ev-empty{color:#4755698c}.ev-root--light .ev-resize-handle:after{background:#0d948826}.ev-root--light .ev-resize-handle:hover:after{background:#0d948873;box-shadow:0 0 3px #0d948840}.ev-root--light .ev-statusbar{border-top:1px solid rgba(15,23,42,.08);background:#ffffffeb}.ev-root--light .ev-statusbar-text{color:#4755698c}.ev-root--light .ev-sms-badge--ok{color:#059669}.ev-root--light .ev-sms-badge--ok .ev-sms-dot{background:#059669;box-shadow:0 0 4px #05966966}.ev-root--light .ev-sms-badge--fail{color:#dc2626}.ev-root--light .ev-sms-badge--fail .ev-sms-dot{background:#dc2626;box-shadow:0 0 4px #dc262659}.dc-view-root{width:100%;height:100%;background:#020810;position:relative;overflow:hidden;display:flex;flex-direction:column;font-family:var(--aiops-font-family, "Segoe UI", system-ui, sans-serif)}.dc-view-root:after{content:"";position:absolute;left:0;right:0;height:140px;background:linear-gradient(180deg,transparent 0%,rgba(0,229,255,.025) 40%,rgba(0,229,255,.05) 50%,rgba(0,229,255,.025) 60%,transparent 100%);animation:dc-view-scan 14s linear infinite;pointer-events:none;z-index:1}.dc-view-header{display:flex;align-items:center;padding:0 24px;height:52px;background:#020810f5;border-bottom:1px solid rgba(0,229,255,.08);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:100;flex-shrink:0;gap:16px}.dc-view-brand{display:flex;align-items:center;gap:10px}.dc-view-pulse{width:8px;height:8px;border-radius:50%;background:#00e5ff;box-shadow:0 0 8px #00e5ff,0 0 20px #00e5ff80;animation:holo-led-blink 2s linear infinite}.dc-view-brand-text{font-size:11px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff;opacity:.8}.dc-view-title{font-size:13px;font-weight:300;letter-spacing:.1em;color:#8ab8d4;flex:1}.dc-view-tag{font-size:9px;letter-spacing:.2em;color:#00e5ff66;border:1px solid rgba(0,229,255,.15);padding:3px 10px;border-radius:2px}.dc-view-back-btn{display:flex;align-items:center;gap:8px;padding:6px 16px;border:1px solid rgba(0,229,255,.2);border-radius:4px;background:#00e5ff0f;color:#00e5ff;font-size:11px;font-weight:600;letter-spacing:.08em;cursor:pointer;transition:all .3s ease;font-family:inherit;text-transform:uppercase}.dc-view-back-btn:hover{background:#00e5ff24;border-color:#00e5ff73;box-shadow:0 0 14px #00e5ff2e}.dc-view-dc-title{font-size:12px;font-weight:600;letter-spacing:.15em;text-transform:uppercase}.header-scale-controls{display:flex;gap:16px;align-items:center;margin-left:auto}.header-scale-group{display:flex;align-items:center;gap:5px}.header-scale-label{font-size:7px;color:#8ab8d473;letter-spacing:.12em;text-transform:uppercase;width:28px;flex-shrink:0}.header-scale-input{-webkit-appearance:none;appearance:none;width:64px;height:3px;background:#00e5ff1a;border-radius:2px;outline:none;cursor:pointer}.header-scale-input::-webkit-slider-thumb{-webkit-appearance:none;width:10px;height:10px;border-radius:50%;background:#00e5ff;box-shadow:0 0 6px #00e5ff99;cursor:grab;border:none}.header-scale-input::-moz-range-thumb{width:10px;height:10px;border-radius:50%;background:#00e5ff;box-shadow:0 0 6px #00e5ff99;cursor:grab;border:none}.header-scale-value{font-size:9px;font-weight:600;color:#00e5ff;font-family:Courier New,monospace;min-width:26px;text-align:right;opacity:.7}.map-scene{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center;overflow:visible;z-index:2;will-change:transform,opacity}.map-scene--zooming-in,.map-scene--zooming-out,.map-scene--hidden{overflow:hidden}.map-scene--zooming-in{animation:map-zoom-in 1.9s cubic-bezier(.22,1,.36,1) both}.map-scene--zooming-out{animation:map-zoom-out 1.5s cubic-bezier(.22,1,.36,1) both}.map-scene--hidden{visibility:hidden;pointer-events:none;transform:scale(8);opacity:0}.map-container{position:relative;height:100%;aspect-ratio:4 / 3;overflow:visible}.map-container--topology{background:radial-gradient(ellipse 55% 50% at 44% 40%,rgba(0,229,255,.07) 0%,transparent 55%),linear-gradient(180deg,#050a12,#070f1a)}.topology-zone-label{fill:#bb55ff73;font-size:9px;font-weight:700;letter-spacing:.35em;font-family:var(--aiops-font-family, "Segoe UI", system-ui, sans-serif);pointer-events:none}.dc-view-map-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.dc-view-geo-outline{fill:#00e5ff04;stroke:#00e5ff59;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50000;stroke-dashoffset:50000;filter:drop-shadow(0 0 8px rgba(0,229,255,.2)) drop-shadow(0 0 20px rgba(0,229,255,.08));animation:draw-outline 3.5s ease-out forwards,outline-breathe 6s ease-in-out 3.5s infinite}.dc-view-geo-inner-glow{fill:url(#mapGradient);stroke:none;pointer-events:none}.dc-view-grid-line{stroke:#00e5ff06;stroke-width:.5}.city-dot{fill:#00e5ff33;stroke:none}.city-label{fill:#00e5ff2e;font-size:7px;letter-spacing:.12em;text-transform:uppercase;font-family:var(--aiops-font-family, "Segoe UI", system-ui, sans-serif)}.connection-line{stroke:#00e5ff0f;stroke-width:1;stroke-dasharray:8 6;fill:none;opacity:0;animation:conn-appear 1s ease-out 2.8s forwards}.connection-line--external{stroke:#bb55ff0f;stroke-dasharray:3 8}.connection-flow{stroke:#00e5ff73;stroke-width:1.5;stroke-dasharray:6 20;stroke-linecap:round;fill:none;opacity:0;filter:drop-shadow(0 0 2px rgba(0,229,255,.3));animation:conn-appear 1s ease-out 3s forwards,data-flow 2.8s linear 3s infinite}.connection-flow--external{stroke:#bb55ff40;stroke-dasharray:3 20}.connection-throughput{fill:#00e5ff80;font-size:7px;font-family:Courier New,monospace;letter-spacing:.06em;paint-order:stroke;stroke:#020810e6;stroke-width:3px;pointer-events:none;opacity:0;animation:conn-appear 1s ease-out 3.2s forwards}.connection-throughput--external{fill:#bb55ff80}.dc-marker{position:absolute;transform:translate(-50%,-50%) scale(var(--dc-base-scale, 1));cursor:pointer;z-index:10;transition:transform .5s cubic-bezier(.34,1.56,.64,1),opacity .5s ease;animation:dc-marker-appear .8s cubic-bezier(.16,1,.3,1) backwards;animation-delay:var(--appear-delay, 2.2s)}.dc-marker:hover{transform:translate(-50%,-50%) scale(var(--dc-hover-scale, 1.3));z-index:20}.dc-marker--fading{opacity:0;pointer-events:none}.dc-marker--external{opacity:.75}.dc-marker--external .dc-label-name{font-size:6.5px}.dc-marker--external .dc-label-status{font-size:4.5px}.building-wrap{position:relative;display:flex;flex-direction:column;align-items:center;animation:building-hover 5s ease-in-out infinite}.building-perspective{perspective:500px;perspective-origin:50% 38%;position:relative}.building-3d{position:relative;transform-style:preserve-3d;transform:rotateX(-20deg) rotateY(25deg);transition:transform .8s cubic-bezier(.34,1.56,.64,1)}.dc-marker:hover .building-3d{transform:rotateX(-20deg) rotateY(45deg)}.building-beacon{position:absolute;top:-14px;left:50%;transform:translate(-50%);width:5px;height:5px;border-radius:50%;animation:beacon-glow 2s ease-in-out infinite;z-index:5}.dc-site-cluster{display:flex;gap:10px;align-items:flex-end}.dc-site-cluster-unit{display:flex;flex-direction:column;align-items:center}.dc-site-cluster-tag{font-size:5.5px;color:#ff8c0080;letter-spacing:.12em;text-transform:uppercase;margin-top:2px;white-space:nowrap}.building-holo-base{position:relative;width:90px;height:18px;margin-top:-4px}.building-holo-base--wide{width:150px}.building-base-ring{position:absolute;top:50%;left:50%;border-radius:50%;border-style:solid;transform:translate(-50%,-50%) scaleY(.28);animation:holo-ring-pulse 3s ease-in-out infinite;pointer-events:none}.smoke-container{position:absolute;top:-12px;left:50%;transform:translate(-50%);width:80px;height:85px;pointer-events:none;z-index:6}.smoke-plume{position:absolute;bottom:0;left:50%;transform:translate(-50%);width:18px;background:linear-gradient(to top,rgba(170,165,155,.18) 0%,rgba(150,145,135,.08) 50%,transparent 100%);border-radius:10px 10px 0 0;filter:blur(4px);pointer-events:none}.smoke-puff{position:absolute;border-radius:50%;bottom:0;left:calc(50% - var(--size, 12px) / 2 + var(--drift, 0px));width:var(--size, 12px);height:var(--size, 12px);background:radial-gradient(circle,rgba(190,185,175,calc(var(--opacity, .5) * 1.3)) 0%,rgba(160,155,145,calc(var(--opacity, .5) * .6)) 40%,transparent 70%);filter:blur(1.5px);animation:smoke-rise 4s ease-out var(--delay, 0s) infinite;opacity:0}.power-container{position:absolute;inset:-8px -10px -4px;pointer-events:none;z-index:6}.power-glow{position:absolute;inset:0;border-radius:4px;box-shadow:inset 0 0 15px rgba(0,229,255,calc(var(--power-intensity, .2) * .2)),0 0 10px rgba(0,229,255,calc(var(--power-intensity, .2) * .3));animation:power-pulse 2.5s ease-in-out infinite}.power-spark{position:absolute;left:var(--spark-x, 50%);top:var(--spark-y, 50%);width:3px;height:3px;background:#00e5ff;border-radius:50%;box-shadow:0 0 4px #00e5ff,0 0 10px #00e5ff99;animation:spark-drift 2.5s ease-in-out var(--spark-delay, 0s) infinite}.power-ring{position:absolute;bottom:-4px;left:50%;transform:translate(-50%);width:85%;height:10px;border:1.5px solid rgba(0,229,255,calc(var(--power-intensity, .2) * .5));border-radius:50%;box-shadow:0 0 8px rgba(0,229,255,calc(var(--power-intensity, .2) * .4));animation:energy-pulse 2s ease-in-out infinite}.fan-unit{pointer-events:none;z-index:6}.fan-unit:before{content:"";position:absolute;inset:-4px;border-radius:50%;background:radial-gradient(circle,rgba(136,204,255,.1) 0%,transparent 70%)}.fan-blade{display:block;animation:fan-spin linear infinite;filter:drop-shadow(0 0 4px rgba(136,204,255,.6))}.vapor-trail{position:absolute;top:100%;left:50%;transform:translate(-50%);width:6px;height:16px;background:linear-gradient(to bottom,rgba(136,204,255,var(--vapor-opacity, .2)) 0%,transparent 100%);border-radius:0 0 3px 3px;filter:blur(2px);animation:vapor-drift 2s ease-in-out infinite}.temp-overlay{position:absolute;inset:-10px;border-radius:6px;background:radial-gradient(ellipse at 50% 40%,var(--temp-color, #00b8ff) 0%,transparent 65%);opacity:var(--temp-opacity, .1);animation:temp-shimmer var(--shimmer-speed, 5s) ease-in-out infinite;pointer-events:none;z-index:1}.temp-overlay--critical{animation:temp-shimmer var(--shimmer-speed, 2s) ease-in-out infinite,temp-pulse 1.2s ease-in-out infinite}.pue-ring{position:absolute;bottom:-14px;left:50%;width:65px;height:16px;transform:translate(-50%);border:1.5px solid var(--pue-color, #00ff88);border-radius:50%;box-shadow:0 0 6px var(--pue-color, #00ff88),inset 0 0 4px var(--pue-color, #00ff88);opacity:var(--pue-opacity, .5);animation:pue-pulse var(--pue-speed, 3s) ease-in-out infinite;pointer-events:none;z-index:5}.dc-info-card{position:absolute;bottom:-6px;left:50%;transform:translate(-50%) translateY(100%);width:195px;padding:10px 12px;background:#020810f0;border:1px solid rgba(0,229,255,.12);border-radius:6px;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);z-index:30;opacity:0;pointer-events:none;transition:opacity .35s ease,transform .35s ease;box-shadow:0 8px 32px #0009}.dc-marker:hover .dc-info-card{opacity:1;transform:translate(-50%) translateY(100%) translateY(10px)}.dc-info-name{font-size:10px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:#00e5ff;margin-bottom:2px}.dc-info-location{font-size:7.5px;letter-spacing:.1em;color:#8ab8d473;margin-bottom:8px;text-transform:uppercase}.dc-info-metric{display:flex;align-items:center;justify-content:space-between;padding:3px 0;border-bottom:1px solid rgba(0,229,255,.04)}.dc-info-metric:last-of-type{border-bottom:none}.dc-info-metric-label{font-size:7.5px;letter-spacing:.06em;color:#8ab8d480;text-transform:uppercase}.dc-info-metric-value{font-size:9px;font-weight:600;letter-spacing:.04em;font-family:Courier New,monospace}.dc-info-enter{display:block;text-align:center;margin-top:8px;padding-top:6px;border-top:1px solid rgba(0,229,255,.08);font-size:7px;letter-spacing:.2em;text-transform:uppercase;color:#00e5ff59}.dc-label{text-align:center;margin-top:6px;pointer-events:none}.dc-label-name{font-size:7.5px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff;text-shadow:0 0 8px rgba(0,229,255,.4);white-space:nowrap}.dc-label-status{font-size:5.5px;letter-spacing:.2em;text-transform:uppercase;margin-top:2px;white-space:nowrap}.dc-dashboard-wrap{position:absolute;inset:52px 0 0;z-index:50;background:#020810;opacity:0;animation:dashboard-enter .9s cubic-bezier(.16,1,.3,1) .1s forwards}.dc-dashboard-wrap--exiting{animation:dashboard-exit .7s ease-in forwards}.dc-dashboard-wrap .app-header{display:none}.dc-dashboard-wrap .app{grid-template-rows:1fr;height:100%;max-height:100%}.dc-dashboard-wrap .scene{height:100%}.zoom-flash{position:fixed;inset:0;z-index:200;background:radial-gradient(circle at var(--flash-x, 50%) var(--flash-y, 50%),rgba(0,229,255,.25) 0%,rgba(0,229,255,.08) 30%,transparent 70%);pointer-events:none;animation:zoom-flash 1.2s ease-out forwards}@keyframes dc-view-scan{0%{top:-140px}to{top:100%}}@keyframes holo-led-blink{0%,to{opacity:1}50%{opacity:.3}}@keyframes holo-ring-pulse{0%,to{transform:translate(-50%,-50%) scaleY(.28) scale(1);opacity:.6}50%{transform:translate(-50%,-50%) scaleY(.28) scale(1.08);opacity:1}}@keyframes draw-outline{0%{stroke-dashoffset:50000;fill:#00e5ff00}80%{fill:#00e5ff00}to{stroke-dashoffset:0;fill:#00e5ff04}}@keyframes outline-breathe{0%,to{stroke:#00e5ff59;filter:drop-shadow(0 0 8px rgba(0,229,255,.2)) drop-shadow(0 0 20px rgba(0,229,255,.08))}50%{stroke:#00e5ff8c;filter:drop-shadow(0 0 12px rgba(0,229,255,.3)) drop-shadow(0 0 30px rgba(0,229,255,.12))}}@keyframes building-hover{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}@keyframes beacon-glow{0%,to{box-shadow:0 0 4px currentColor,0 0 8px currentColor;opacity:.7}50%{box-shadow:0 0 8px currentColor,0 0 18px currentColor,0 0 28px currentColor;opacity:1}}@keyframes smoke-rise{0%{transform:translateY(0) translate(0) scale(.4);opacity:0}10%{opacity:var(--opacity, .5)}50%{opacity:calc(var(--opacity, .5) * .35)}to{transform:translateY(-70px) translate(var(--drift, 5px)) scale(2.8);opacity:0}}@keyframes power-pulse{0%,to{opacity:.5}50%{opacity:1}}@keyframes spark-drift{0%{opacity:.2;transform:scale(.6) translate(0)}25%{opacity:.9;transform:scale(1.4) translate(2px,-2px)}50%{opacity:.4;transform:scale(.8) translate(-1px,1px)}75%{opacity:1;transform:scale(1.6) translate(1px,-1px)}to{opacity:.2;transform:scale(.6) translate(0)}}@keyframes energy-pulse{0%,to{transform:translate(-50%) scaleX(1);opacity:.4}50%{transform:translate(-50%) scaleX(1.12);opacity:.8}}@keyframes fan-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes vapor-drift{0%,to{transform:translate(-50%) translateY(0);opacity:1}50%{transform:translate(-50%) translateY(5px);opacity:.4}}@keyframes temp-shimmer{0%,to{opacity:calc(var(--temp-opacity, .1) * .5)}50%{opacity:var(--temp-opacity, .1)}}@keyframes temp-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.06)}}@keyframes pue-pulse{0%,to{transform:translate(-50%) scale(1);opacity:calc(var(--pue-opacity, .5) * .6)}50%{transform:translate(-50%) scale(1.1);opacity:var(--pue-opacity, .5)}}@keyframes data-flow{0%{stroke-dashoffset:0}to{stroke-dashoffset:-52}}@keyframes dashboard-enter{0%{opacity:0;transform:scale(1.015)}to{opacity:1;transform:scale(1)}}@keyframes dashboard-exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.985)}}@keyframes map-zoom-in{0%{transform:scale(1);opacity:1}55%{opacity:.3}to{transform:scale(8);opacity:0}}@keyframes map-zoom-out{0%{transform:scale(8);opacity:0}25%{opacity:.3}to{transform:scale(1);opacity:1}}@keyframes zoom-flash{0%{opacity:0}15%{opacity:1}to{opacity:0}}@keyframes dc-marker-appear{0%{opacity:0;transform:translate(-50%,-50%) scale(.3) translateY(20px)}to{opacity:1;transform:translate(-50%,-50%) scale(1) translateY(0)}}@keyframes conn-appear{0%{opacity:0}to{opacity:1}}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html,body,#root{width:100%;height:100%;overflow:hidden}body{font-family:var(--aiops-font-family, "Segoe UI", system-ui, -apple-system, sans-serif);background-color:#020810;color:#c8dff0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#1e508c66;border-radius:2px}::-webkit-scrollbar-thumb:hover{background:#22d3ee4d}*{scrollbar-width:thin;scrollbar-color:rgba(30,80,140,.4) transparent}@keyframes holo-ring-pulse{0%,to{transform:scaleY(.22) scale(1)}50%{transform:scaleY(.22) scale(.965)}}@keyframes holo-beam-pulse{0%{opacity:.75;filter:brightness(1)}40%{opacity:1;filter:brightness(1.35)}70%{opacity:.55;filter:brightness(.7)}to{opacity:.75;filter:brightness(1)}}@keyframes holo-scan{0%{top:-3px;opacity:0}6%{opacity:1}90%{opacity:.6}to{top:110%;opacity:0}}@keyframes holo-led-blink{0%,88%,to{opacity:1}93%{opacity:.15}}@keyframes holo-float{0%,to{transform:translateY(0)}50%{transform:translateY(-7px)}}@keyframes holo-base-spin{0%{transform:translate(-50%) scaleY(.22) rotate(0)}to{transform:translate(-50%) scaleY(.22) rotate(360deg)}}@keyframes component-drill-pulse{0%,to{box-shadow:0 0 #f253}50%{box-shadow:0 0 12px 2px #ff225526}}@keyframes comp-dialog-border-glow{0%,to{border-color:var(--dialog-color, #00e5ff)33;box-shadow:0 0 30px var(--dialog-color, #00e5ff) 18,0 12px 60px #000000bf,inset 0 0 40px #0006}50%{border-color:var(--dialog-color, #00e5ff)66;box-shadow:0 0 50px var(--dialog-color, #00e5ff) 30,0 12px 60px #000000bf,inset 0 0 40px #0006}}@keyframes comp-dialog-icon-pop{0%{opacity:0;transform:scale(.3) translateY(14px)}60%{opacity:1;transform:scale(1.08) translateY(-3px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes comp-dialog-metric-fill{0%{transform:scaleX(0)}to{transform:scaleX(1)}}
1
+ @keyframes status-change-pulse{0%{opacity:0;transform:scale(.6)}10%{opacity:1;transform:scale(1.15)}25%{opacity:.1;transform:scale(.95)}40%{opacity:.9;transform:scale(1.1)}60%{opacity:.15;transform:scale(1)}to{opacity:0;transform:scale(1.3)}}@keyframes comp-dialog-border-glow-light{0%,to{border-color:var(--dialog-color, #64748b)44;box-shadow:0 4px 28px #0f172a1a,0 0 24px var(--dialog-color, #64748b) 14,inset 0 1px #ffffffd9}50%{border-color:var(--dialog-color, #64748b)66;box-shadow:0 8px 36px #0f172a1f,0 0 32px var(--dialog-color, #64748b) 20,inset 0 1px #ffffffe6}}.app{display:grid;grid-template-rows:52px 1fr;width:100%;height:100vh;overflow:hidden;position:relative;background:#020810;color:#c8dff0;font-family:var(--aiops-font-family, "Segoe UI", system-ui, -apple-system, sans-serif);-webkit-font-smoothing:antialiased}.app-header{display:flex;align-items:center;gap:18px;padding:0 24px;border-bottom:1px solid rgba(0,229,255,.08);background:#020810eb;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);position:relative;z-index:10}.hdr-brand{display:flex;align-items:center;gap:8px}.brand-pulse{width:7px;height:7px;border-radius:50%;background:#00e5ff;box-shadow:0 0 8px #00e5ff,0 0 18px #00e5ff80;animation:holo-led-blink 2s linear infinite}.brand-text{font-size:10px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff;opacity:.7}.hdr-theme-toggle{background:#00e5ff14;border:1px solid rgba(0,229,255,.2);color:#00e5ff;border-radius:4px;padding:4px 10px;font-size:14px;cursor:pointer;transition:background .2s,border-color .2s;line-height:1}.hdr-theme-toggle:hover{background:#00e5ff2e;border-color:#00e5ff66}.hdr-right{display:flex;align-items:center;gap:8px;margin-left:auto}.hdr-tag{font-size:9px;letter-spacing:.2em;color:#00e5ff59;border:1px solid rgba(0,229,255,.15);padding:3px 8px;border-radius:2px}.app--light{background:transparent;color:#1e293b}.app--light .app-header{border-bottom:1px solid rgba(15,23,42,.08);background:#ffffffe0;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.app--light .brand-pulse{background:#0d9488;box-shadow:0 0 6px #0d948873,0 0 14px #0d948838}.app--light .brand-text{color:#0f766e;opacity:.95}.app--light .hdr-theme-toggle{background:#0d948814;border:1px solid rgba(13,148,136,.22);color:#0f766e}.app--light .hdr-theme-toggle:hover{background:#0d948829;border-color:#0d948861}.app--light .hdr-tag{color:#334155c7;border-color:#33415533}.scene{display:flex;flex-direction:column;align-items:center;overflow:hidden;padding:0;position:relative;z-index:1;gap:0;background:transparent}.float-node{display:flex;flex-direction:column;align-items:center;position:relative}.float-node--interactive:before{content:"";position:absolute;inset:-40px -35px -15px}.float-body{position:relative;animation:holo-float 4s ease-in-out infinite}.scan-line{position:absolute;top:0;left:0;right:0;height:1.5px;animation:holo-scan 3.5s linear infinite;pointer-events:none;z-index:10}.node-tag{font-size:24px;letter-spacing:.2em;text-transform:uppercase;font-family:var(--aiops-font-family, "Courier New", monospace);margin-top:14px;text-align:center;text-shadow:0 0 6px currentColor}.node-subtag{font-size:11px;letter-spacing:.15em;text-transform:uppercase;font-family:var(--aiops-font-family, "Courier New", monospace);margin-top:4px;text-align:center}.sync-bridge{display:flex;flex-direction:column;align-items:center;justify-content:center;width:110px;gap:6px;flex-shrink:0;font-family:var(--aiops-font-family, "Courier New", monospace)}.sync-arrows{display:flex;align-items:center;width:100%;gap:4px}.sync-line{flex:1;height:2px;border-radius:1px;animation:holo-beam-pulse 1.8s ease-in-out infinite}.sync-status{font-size:8px;letter-spacing:.18em;text-transform:uppercase;text-align:center}.sync-latency{font-size:6.5px;letter-spacing:.1em;text-align:center;font-family:var(--aiops-font-family, "Courier New", monospace)}.base-ring{position:absolute;top:50%;left:50%;border-style:solid;border-radius:50%;transform:translate(-50%,-50%) scaleY(.22);animation:holo-ring-pulse 2.5s ease-in-out infinite}.base-hotspot{position:absolute;top:50%;left:50%;width:8%;height:8%;border-radius:50%;transform:translate(-50%,-50%) scaleY(.22);background:radial-gradient(circle,#ffffff 0%,#ff8c00 35%,transparent 70%);box-shadow:0 0 20px #ff8c00,0 0 40px #ff8c0080}@keyframes refresh-error-pulse{0%,to{opacity:1;box-shadow:0 0 6px #f25,0 0 14px #f256}50%{opacity:.5;box-shadow:0 0 3px #f25}}.hdr-refresh-error{display:flex;align-items:center;gap:7px;padding:3px 10px;border:1px solid rgba(255,34,85,.35);border-radius:3px;background:#ff22550f;animation:refresh-error-pulse 2s ease-in-out infinite}.refresh-error-dot{width:6px;height:6px;border-radius:50%;background:#f25;box-shadow:0 0 6px #f25;flex-shrink:0}.refresh-error-text{font-size:8px;letter-spacing:.18em;text-transform:uppercase;color:#f25;white-space:nowrap;font-family:var(--aiops-font-family, "Courier New", monospace)}@keyframes cred-panel-glow{0%,to{border-color:#00e5ff2e;box-shadow:0 0 40px #00e5ff14,0 20px 80px #000c,inset 0 0 60px #00000080}50%{border-color:#00e5ff59;box-shadow:0 0 60px #00e5ff26,0 20px 80px #000c,inset 0 0 60px #00000080}}@keyframes cred-fade-in{0%{opacity:0}to{opacity:1}}@keyframes cred-panel-enter{0%{opacity:0;transform:translateY(20px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes cred-icon-pop{0%{opacity:0;transform:scale(.4) translateY(10px)}60%{opacity:1;transform:scale(1.1) translateY(-3px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes cred-scanline-sweep{0%{top:-2px;opacity:0}5%{opacity:.7}90%{opacity:.4}to{top:100%;opacity:0}}@keyframes cred-btn-shine{0%{left:-100%}to{left:200%}}.cred-overlay{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#020810e0;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);animation:cred-fade-in .4s ease-out}.cred-panel{position:relative;width:380px;padding:40px 36px 32px;border:1px solid rgba(0,229,255,.18);border-radius:6px;background:linear-gradient(170deg,#061226f7,#030a16fa);animation:cred-panel-enter .5s ease-out,cred-panel-glow 4s ease-in-out infinite;overflow:hidden}.cred-scanline{position:absolute;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 0%,rgba(0,229,255,.5) 50%,transparent 100%);animation:cred-scanline-sweep 4s linear infinite;pointer-events:none;z-index:2}.cred-corner{position:absolute;width:18px;height:18px;pointer-events:none;z-index:3}.cred-corner:before,.cred-corner:after{content:"";position:absolute;background:#00e5ff73}.cred-corner:before{top:0;left:0;width:18px;height:1px}.cred-corner:after{top:0;left:0;width:1px;height:18px}.cred-corner--tl{top:-1px;left:-1px}.cred-corner--tr{top:-1px;right:-1px;transform:scaleX(-1)}.cred-corner--bl{bottom:-1px;left:-1px;transform:scaleY(-1)}.cred-corner--br{bottom:-1px;right:-1px;transform:scale(-1)}.cred-icon{display:flex;justify-content:center;margin-bottom:18px;animation:cred-icon-pop .6s ease-out .15s both}.cred-title{text-align:center;font-size:13px;font-weight:700;letter-spacing:.28em;text-transform:uppercase;color:#00e5ff;margin-bottom:6px}.cred-subtitle{text-align:center;font-size:9px;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff59;margin-bottom:28px;font-family:var(--aiops-font-family, "Courier New", monospace)}.cred-field{margin-bottom:18px}.cred-label{display:block;font-size:8px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff8c;margin-bottom:6px;font-family:var(--aiops-font-family, "Courier New", monospace)}.cred-input{width:100%;padding:10px 14px;border:1px solid rgba(0,229,255,.15);border-radius:4px;background:#000a19b3;color:#c8dff0;font-size:13px;font-family:var(--aiops-font-family, "Courier New", monospace);letter-spacing:.04em;outline:none;transition:border-color .25s,box-shadow .25s;box-sizing:border-box}.cred-input::placeholder{color:#c8dff02e;letter-spacing:.06em}.cred-btn{position:relative;display:block;width:100%;margin-top:26px;padding:12px 0;border:1px solid rgba(0,229,255,.3);border-radius:4px;background:#00e5ff0f;color:#00e5ff;font-size:11px;font-weight:700;letter-spacing:.3em;text-transform:uppercase;font-family:inherit;transition:background .25s,box-shadow .25s,opacity .25s;overflow:hidden}.cred-btn-glow{position:absolute;top:0;left:-100%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(0,229,255,.08),transparent);pointer-events:none;animation:cred-btn-shine 3s ease-in-out infinite}.cred-footer{margin-top:20px;text-align:center;font-size:7px;letter-spacing:.2em;text-transform:uppercase;color:#c8dff02e;font-family:var(--aiops-font-family, "Courier New", monospace)}@keyframes cred-panel-glow-light{0%,to{border-color:#0d948838;box-shadow:0 4px 40px #0f172a14,0 0 32px #0d94880f,inset 0 1px #fffffff2}50%{border-color:#0d948861;box-shadow:0 8px 48px #0f172a1a,0 0 40px #0d94881a,inset 0 1px #fff}}.cred-overlay--light{background:#f1f5f9eb}.cred-panel--light{border:1px solid rgba(15,23,42,.1);background:linear-gradient(170deg,#fffffffa,#f8fafcfc);animation:cred-panel-enter .5s ease-out,cred-panel-glow-light 4s ease-in-out infinite}.cred-panel--light .cred-scanline{background:linear-gradient(90deg,transparent 0%,rgba(13,148,136,.35) 50%,transparent 100%)}.cred-panel--light .cred-corner:before,.cred-panel--light .cred-corner:after{background:#0d948866}.cred-panel--light .cred-title{color:#0f766e}.cred-panel--light .cred-subtitle{color:#3341558c}.cred-panel--light .cred-label{color:#334155a6}.cred-panel--light .cred-input{border-color:#0f172a1f;background:#fffffff2;color:#1e293b}.cred-panel--light .cred-input::placeholder{color:#64748b73}.cred-panel--light .cred-btn{border-color:#0d948859;background:#0d948814;color:#0f766e}.cred-panel--light .cred-btn-glow{background:linear-gradient(90deg,transparent,rgba(13,148,136,.12),transparent)}.cred-panel--light .cred-footer{color:#47556973}.cred-panel--light .cred-btn:hover:not(:disabled){background:#0d948829;box-shadow:0 0 20px #0d948826,inset 0 0 12px #0d94880f}.ev-root{display:flex;flex-direction:column;height:100%;width:100%;background:linear-gradient(180deg,#020810f7,#030c18fa);color:#c8dff0;font-family:var(--aiops-font-family, "Segoe UI", system-ui, -apple-system, sans-serif);overflow:hidden}.ev-header{position:relative;display:flex;align-items:center;justify-content:space-between;padding:14px 24px;border-bottom:1px solid rgba(0,229,255,.1);background:#040e1cd9;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);flex-shrink:0}.ev-header-left{display:flex;align-items:center;gap:12px}.ev-header-pulse{width:7px;height:7px;border-radius:50%;background:#00e5ff;box-shadow:0 0 8px #00e5ff,0 0 18px #00e5ff80;animation:holo-led-blink 2s linear infinite}.ev-title{font-size:14px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:#00e5ff;margin:0}.ev-event-count{font-size:11px;color:#00e5ff73;letter-spacing:.08em;border:1px solid rgba(0,229,255,.15);padding:2px 10px;border-radius:10px}.ev-header-right{display:flex;align-items:center;gap:12px}.ev-live-tag{display:flex;align-items:center;gap:6px;font-size:9px;font-weight:700;letter-spacing:.25em;color:#0f8;border:1px solid rgba(0,255,136,.25);padding:3px 10px;border-radius:3px}.ev-live-dot{width:6px;height:6px;border-radius:50%;background:#0f8;box-shadow:0 0 6px #0f8;animation:holo-led-blink 1.5s linear infinite}.ev-live-dot--err{background:#f25;box-shadow:0 0 6px #f25}.ev-error-tag{display:flex;align-items:center;gap:5px;font-size:9px;font-weight:700;letter-spacing:.15em;color:#f25;cursor:default}.ev-error-dot{width:5px;height:5px;border-radius:50%;background:#f25;box-shadow:0 0 5px #f25;animation:holo-led-blink 1s linear infinite}.ev-loading-tag{display:flex;align-items:center;gap:6px;font-size:9px;font-weight:600;letter-spacing:.15em;color:#00e5ff99}.ev-loading-spinner{width:10px;height:10px;border:1.5px solid rgba(0,229,255,.15);border-top-color:#00e5ff;border-radius:50%;animation:ev-spin .8s linear infinite}@keyframes ev-spin{to{transform:rotate(360deg)}}.ev-refresh-tag{font-size:9px;letter-spacing:.06em;color:#648caa73;font-family:Cascadia Code,Fira Code,Consolas,monospace}.ev-refresh-btn{padding:2px 8px;border:1px solid rgba(0,229,255,.15);border-radius:3px;background:transparent;color:#00e5ff99;font-size:14px;cursor:pointer;transition:all .2s ease;font-family:inherit;line-height:1}.ev-refresh-btn:hover:not(:disabled){background:#00e5ff0f;border-color:#00e5ff4d;color:#00e5ff}.ev-refresh-btn:disabled{opacity:.25;cursor:default}.ev-toolbar{display:flex;align-items:center;justify-content:space-between;padding:12px 24px;gap:16px;border-bottom:1px solid rgba(0,229,255,.06);flex-shrink:0;flex-wrap:wrap}.ev-filters{display:flex;gap:8px}.ev-filter-chip{display:flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid rgba(100,120,140,.25);border-radius:4px;background:#0a142399;color:#6a8198;font-size:11px;font-weight:600;letter-spacing:.06em;cursor:pointer;transition:all .25s ease;font-family:inherit}.ev-filter-chip:hover{background:#0f1e32cc;border-color:#64788c73}.ev-filter-chip--active{background:#0a1423d9}.ev-chip-dot{width:6px;height:6px;border-radius:50%;transition:background .25s ease}.ev-chip-count{font-size:10px;opacity:.6;margin-left:2px}.ev-search-wrap{position:relative;flex:1;max-width:380px;min-width:200px}.ev-search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);width:15px;height:15px;color:#00e5ff59;pointer-events:none}.ev-search{width:100%;padding:7px 12px 7px 32px;border:1px solid rgba(0,229,255,.12);border-radius:4px;background:#060e1cb3;color:#c8dff0;font-size:12px;font-family:inherit;outline:none;transition:border-color .3s ease,box-shadow .3s ease}.ev-search::placeholder{color:#648caa73}.ev-search:focus{border-color:#00e5ff66;box-shadow:0 0 12px #00e5ff1f,inset 0 0 20px #00e5ff08}.ev-table-wrap{flex:1;overflow:auto;position:relative}.ev-table-wrap::-webkit-scrollbar{width:5px;height:5px}.ev-table-wrap::-webkit-scrollbar-track{background:transparent}.ev-table-wrap::-webkit-scrollbar-thumb{background:#00e5ff26;border-radius:3px}.ev-table-wrap::-webkit-scrollbar-thumb:hover{background:#00e5ff4d}.ev-table{width:100%;border-collapse:separate;border-spacing:0;font-size:11.5px}.ev-th{position:sticky;top:0;z-index:4;padding:10px 12px 10px 14px;background:#040c18f2;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-bottom:1px solid rgba(0,229,255,.15);text-align:left;font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#00e5ffb3;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:color .2s ease;overflow:hidden;text-overflow:ellipsis}.ev-th:after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,rgba(0,229,255,.2),transparent)}.ev-th:hover{color:#00e5ff}.ev-th-inner{display:flex;align-items:center;gap:5px}.ev-sort-arrow{font-size:8px;line-height:1}.ev-sort-arrow--idle{opacity:.3}.ev-sort-arrow--active{color:#00e5ff;text-shadow:0 0 6px rgba(0,229,255,.6)}.ev-row{transition:background .2s ease,box-shadow .2s ease;border-bottom:1px solid rgba(0,229,255,.04)}.ev-row:nth-child(2n){background:#0610204d}.ev-row:hover{background:#00e5ff0a;box-shadow:inset 0 0 30px var(--row-glow, rgba(0, 229, 255, .03)),inset 3px 0 0 var(--row-color, #00e5ff)}.ev-td{padding:9px 14px;vertical-align:middle;white-space:nowrap;border-bottom:1px solid rgba(15,30,50,.5);overflow:hidden;text-overflow:ellipsis}.ev-td-mono{font-family:Cascadia Code,Fira Code,Consolas,monospace;font-size:11px;letter-spacing:.02em}.ev-td-msg{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ev-cell-dim{color:#6482a059}.ev-severity-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border:1px solid;border-radius:3px;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}.ev-severity-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}.ev-sms-badge{display:inline-flex;align-items:center;gap:5px;font-size:10px;font-weight:600;letter-spacing:.06em}.ev-sms-badge--ok{color:#0f8}.ev-sms-badge--ok .ev-sms-dot{background:#0f8;box-shadow:0 0 5px #0f8}.ev-sms-badge--fail{color:#f25}.ev-sms-badge--fail .ev-sms-dot{background:#f25;box-shadow:0 0 5px #f25}.ev-sms-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}.ev-class-tag{display:inline-block;padding:2px 8px;border:1px solid rgba(0,229,255,.15);border-radius:3px;font-size:10px;letter-spacing:.04em;color:#00e5ffb3;background:#00e5ff0a;white-space:nowrap}.ev-mon-cat{font-size:10px;letter-spacing:.04em;color:#6a8198}.ev-mon-cat--247{color:#00e5ff;font-weight:600}.ev-empty{text-align:center;padding:48px 24px;color:#648caa73;font-size:13px;letter-spacing:.1em}.ev-resize-handle{position:absolute;top:0;right:0;bottom:0;width:6px;cursor:col-resize;z-index:5}.ev-resize-handle:after{content:"";position:absolute;top:20%;right:2px;bottom:20%;width:1px;background:#00e5ff1f;transition:background .2s ease,box-shadow .2s ease}.ev-resize-handle:hover:after{background:#00e5ff80;box-shadow:0 0 4px #00e5ff4d}.ev-statusbar{display:flex;align-items:center;padding:6px 24px;border-top:1px solid rgba(0,229,255,.06);background:#040c18d9;flex-shrink:0}.ev-statusbar-text{font-size:10px;color:#648caa73;letter-spacing:.06em}.ev-header:before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 0%,#00e5ff 50%,transparent 100%);opacity:.5;animation:ev-scan-slide 4s linear infinite}@keyframes ev-scan-slide{0%{transform:translate(-100%)}to{transform:translate(100%)}}.ev-root--light{background:linear-gradient(180deg,#f1f5f9,#e2e8f0);color:#1e293b}.ev-root--light .ev-header{border-bottom:1px solid rgba(15,23,42,.08);background:#ffffffe6}.ev-root--light .ev-header:before{background:linear-gradient(90deg,transparent 0%,rgba(13,148,136,.35) 50%,transparent 100%);opacity:.65}.ev-root--light .ev-header-pulse{background:#0d9488;box-shadow:0 0 6px #0d948873,0 0 14px #0d948833}.ev-root--light .ev-title{color:#0f766e}.ev-root--light .ev-event-count{color:#334155a6;border-color:#33415526}.ev-root--light .ev-live-tag{color:#059669;border-color:#05966947}.ev-root--light .ev-live-dot{background:#059669;box-shadow:0 0 5px #05966973}.ev-root--light .ev-loading-tag{color:#0d9488bf}.ev-root--light .ev-loading-spinner{border-color:#0d948833;border-top-color:#0d9488}.ev-root--light .ev-refresh-tag{color:#4755698c}.ev-root--light .ev-refresh-btn{border-color:#0d948838;color:#0f766ebf}.ev-root--light .ev-refresh-btn:hover:not(:disabled){background:#0d948814;border-color:#0d948859;color:#0f766e}.ev-root--light .ev-toolbar{border-bottom:1px solid rgba(15,23,42,.06)}.ev-root--light .ev-filter-chip{border-color:#3341552e;background:#ffffffbf;color:#64748b}.ev-root--light .ev-filter-chip:hover{background:#f8fafcf2;border-color:#33415547}.ev-root--light .ev-filter-chip--active{background:#fffffff2}.ev-root--light .ev-search-icon{color:#0d948866}.ev-root--light .ev-search{border-color:#0f172a1f;background:#ffffffeb;color:#1e293b}.ev-root--light .ev-search::placeholder{color:#64748b8c}.ev-root--light .ev-search:focus{border-color:#0d948873;box-shadow:0 0 0 2px #0d94881f,inset 0 1px #ffffffe6}.ev-root--light .ev-table-wrap::-webkit-scrollbar-thumb{background:#0f172a1f}.ev-root--light .ev-table-wrap::-webkit-scrollbar-thumb:hover{background:#0f172a38}.ev-root--light .ev-th{background:#fffffff2;border-bottom:1px solid rgba(15,23,42,.1);color:#0f766ed9}.ev-root--light .ev-th:after{background:linear-gradient(90deg,transparent,rgba(13,148,136,.2),transparent)}.ev-root--light .ev-th:hover{color:#0f766e}.ev-root--light .ev-sort-arrow--active{color:#0f766e;text-shadow:none}.ev-root--light .ev-row{border-bottom:1px solid rgba(15,23,42,.05)}.ev-root--light .ev-row:nth-child(2n){background:#f8fafcd9}.ev-root--light .ev-row:hover{background:#0d94880f;box-shadow:inset 0 0 24px var(--row-glow, rgba(13, 148, 136, .04)),inset 3px 0 0 var(--row-color, #0d9488)}.ev-root--light .ev-td{border-bottom:1px solid rgba(15,23,42,.06)}.ev-root--light .ev-cell-dim{color:#64748b73}.ev-root--light .ev-class-tag{border-color:#0d948838;color:#0f766ee6;background:#0d94880f}.ev-root--light .ev-mon-cat{color:#64748b}.ev-root--light .ev-mon-cat--247{color:#0d9488}.ev-root--light .ev-empty{color:#4755698c}.ev-root--light .ev-resize-handle:after{background:#0d948826}.ev-root--light .ev-resize-handle:hover:after{background:#0d948873;box-shadow:0 0 3px #0d948840}.ev-root--light .ev-statusbar{border-top:1px solid rgba(15,23,42,.08);background:#ffffffeb}.ev-root--light .ev-statusbar-text{color:#4755698c}.ev-root--light .ev-sms-badge--ok{color:#059669}.ev-root--light .ev-sms-badge--ok .ev-sms-dot{background:#059669;box-shadow:0 0 4px #05966966}.ev-root--light .ev-sms-badge--fail{color:#dc2626}.ev-root--light .ev-sms-badge--fail .ev-sms-dot{background:#dc2626;box-shadow:0 0 4px #dc262659}.dc-view-root{width:100%;height:100%;background:#020810;position:relative;overflow:hidden;display:flex;flex-direction:column;font-family:var(--aiops-font-family, "Segoe UI", system-ui, sans-serif)}.dc-view-root:after{content:"";position:absolute;left:0;right:0;height:140px;background:linear-gradient(180deg,transparent 0%,rgba(0,229,255,.025) 40%,rgba(0,229,255,.05) 50%,rgba(0,229,255,.025) 60%,transparent 100%);animation:dc-view-scan 14s linear infinite;pointer-events:none;z-index:1}.dc-view-header{display:flex;align-items:center;padding:0 24px;height:52px;background:#020810f5;border-bottom:1px solid rgba(0,229,255,.08);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:100;flex-shrink:0;gap:16px}.dc-view-brand{display:flex;align-items:center;gap:10px}.dc-view-pulse{width:8px;height:8px;border-radius:50%;background:#00e5ff;box-shadow:0 0 8px #00e5ff,0 0 20px #00e5ff80;animation:holo-led-blink 2s linear infinite}.dc-view-brand-text{font-size:11px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff;opacity:.8}.dc-view-title{font-size:13px;font-weight:300;letter-spacing:.1em;color:#8ab8d4;flex:1}.dc-view-tag{font-size:9px;letter-spacing:.2em;color:#00e5ff66;border:1px solid rgba(0,229,255,.15);padding:3px 10px;border-radius:2px}.dc-view-back-btn{display:flex;align-items:center;gap:8px;padding:6px 16px;border:1px solid rgba(0,229,255,.2);border-radius:4px;background:#00e5ff0f;color:#00e5ff;font-size:11px;font-weight:600;letter-spacing:.08em;cursor:pointer;transition:all .3s ease;font-family:inherit;text-transform:uppercase}.dc-view-back-btn:hover{background:#00e5ff24;border-color:#00e5ff73;box-shadow:0 0 14px #00e5ff2e}.dc-view-dc-title{font-size:12px;font-weight:600;letter-spacing:.15em;text-transform:uppercase}.header-scale-controls{display:flex;gap:16px;align-items:center;margin-left:auto}.header-scale-group{display:flex;align-items:center;gap:5px}.header-scale-label{font-size:7px;color:#8ab8d473;letter-spacing:.12em;text-transform:uppercase;width:28px;flex-shrink:0}.header-scale-input{-webkit-appearance:none;appearance:none;width:64px;height:3px;background:#00e5ff1a;border-radius:2px;outline:none;cursor:pointer}.header-scale-input::-webkit-slider-thumb{-webkit-appearance:none;width:10px;height:10px;border-radius:50%;background:#00e5ff;box-shadow:0 0 6px #00e5ff99;cursor:grab;border:none}.header-scale-input::-moz-range-thumb{width:10px;height:10px;border-radius:50%;background:#00e5ff;box-shadow:0 0 6px #00e5ff99;cursor:grab;border:none}.header-scale-value{font-size:9px;font-weight:600;color:#00e5ff;font-family:Courier New,monospace;min-width:26px;text-align:right;opacity:.7}.map-scene{flex:1;min-height:0;width:100%;position:relative;display:flex;flex-direction:column;align-items:stretch;overflow:visible;z-index:2;will-change:transform,opacity}.map-scene--zooming-in,.map-scene--zooming-out,.map-scene--hidden{overflow:hidden}.map-scene--zooming-in{animation:map-zoom-in 1.9s cubic-bezier(.22,1,.36,1) both}.map-scene--zooming-out{animation:map-zoom-out 1.5s cubic-bezier(.22,1,.36,1) both}.map-scene--hidden{visibility:hidden;pointer-events:none;transform:scale(8);opacity:0}.map-container{position:relative;flex:1 1 auto;width:100%;min-width:0;min-height:0;height:100%;overflow:visible}.map-container--topology{background:radial-gradient(ellipse 55% 50% at 44% 40%,rgba(0,229,255,.07) 0%,transparent 55%),linear-gradient(180deg,#050a12,#070f1a)}.topology-zone-label{fill:#bb55ff73;font-size:9px;font-weight:700;letter-spacing:.35em;font-family:var(--aiops-font-family, "Segoe UI", system-ui, sans-serif);pointer-events:none}.dc-view-map-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.dc-view-geo-outline{fill:#00e5ff04;stroke:#00e5ff59;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50000;stroke-dashoffset:50000;filter:drop-shadow(0 0 8px rgba(0,229,255,.2)) drop-shadow(0 0 20px rgba(0,229,255,.08));animation:draw-outline 3.5s ease-out forwards,outline-breathe 6s ease-in-out 3.5s infinite}.dc-view-geo-inner-glow{fill:url(#mapGradient);stroke:none;pointer-events:none}.dc-view-grid-line{stroke:#00e5ff06;stroke-width:.5}.city-dot{fill:#00e5ff33;stroke:none}.city-label{fill:#00e5ff2e;font-size:7px;letter-spacing:.12em;text-transform:uppercase;font-family:var(--aiops-font-family, "Segoe UI", system-ui, sans-serif)}.connection-line{stroke:#00e5ff0f;stroke-width:1;stroke-dasharray:8 6;fill:none;opacity:0;animation:conn-appear 1s ease-out 2.8s forwards}.connection-line--external{stroke:#bb55ff0f;stroke-dasharray:3 8}.connection-flow{stroke:#00e5ff73;stroke-width:1.5;stroke-dasharray:6 20;stroke-linecap:round;fill:none;opacity:0;filter:drop-shadow(0 0 2px rgba(0,229,255,.3));animation:conn-appear 1s ease-out 3s forwards,data-flow 2.8s linear 3s infinite}.connection-flow--external{stroke:#bb55ff40;stroke-dasharray:3 20}.connection-throughput{fill:#00e5ff80;font-size:7px;font-family:Courier New,monospace;letter-spacing:.06em;paint-order:stroke;stroke:#020810e6;stroke-width:3px;pointer-events:none;opacity:0;animation:conn-appear 1s ease-out 3.2s forwards}.connection-throughput--external{fill:#bb55ff80}.dc-marker{position:absolute;transform:translate(-50%,-50%) scale(var(--dc-base-scale, 1));cursor:pointer;z-index:10;transition:transform .5s cubic-bezier(.34,1.56,.64,1),opacity .5s ease;animation:dc-marker-appear .8s cubic-bezier(.16,1,.3,1) backwards;animation-delay:var(--appear-delay, 2.2s)}.dc-marker:hover{transform:translate(-50%,-50%) scale(var(--dc-hover-scale, 1.3));z-index:20}.dc-marker--fading{opacity:0;pointer-events:none}.dc-marker--external{opacity:.75}.dc-marker--external .dc-label-name{font-size:6.5px}.dc-marker--external .dc-label-status{font-size:4.5px}.building-wrap{position:relative;display:flex;flex-direction:column;align-items:center;animation:building-hover 5s ease-in-out infinite}.building-perspective{perspective:500px;perspective-origin:50% 38%;position:relative}.building-3d{position:relative;transform-style:preserve-3d;transform:rotateX(-20deg) rotateY(25deg);transition:transform .8s cubic-bezier(.34,1.56,.64,1)}.dc-marker:hover .building-3d{transform:rotateX(-20deg) rotateY(45deg)}.building-beacon{position:absolute;top:-14px;left:50%;transform:translate(-50%);width:5px;height:5px;border-radius:50%;animation:beacon-glow 2s ease-in-out infinite;z-index:5}.dc-site-cluster{display:flex;gap:10px;align-items:flex-end}.dc-site-cluster-unit{display:flex;flex-direction:column;align-items:center}.dc-site-cluster-tag{font-size:5.5px;color:#ff8c0080;letter-spacing:.12em;text-transform:uppercase;margin-top:2px;white-space:nowrap}.building-holo-base{position:relative;width:90px;height:18px;margin-top:-4px}.building-holo-base--wide{width:150px}.building-base-ring{position:absolute;top:50%;left:50%;border-radius:50%;border-style:solid;transform:translate(-50%,-50%) scaleY(.28);animation:holo-ring-pulse 3s ease-in-out infinite;pointer-events:none}.smoke-container{position:absolute;top:-12px;left:50%;transform:translate(-50%);width:80px;height:85px;pointer-events:none;z-index:6}.smoke-plume{position:absolute;bottom:0;left:50%;transform:translate(-50%);width:18px;background:linear-gradient(to top,rgba(170,165,155,.18) 0%,rgba(150,145,135,.08) 50%,transparent 100%);border-radius:10px 10px 0 0;filter:blur(4px);pointer-events:none}.smoke-puff{position:absolute;border-radius:50%;bottom:0;left:calc(50% - var(--size, 12px) / 2 + var(--drift, 0px));width:var(--size, 12px);height:var(--size, 12px);background:radial-gradient(circle,rgba(190,185,175,calc(var(--opacity, .5) * 1.3)) 0%,rgba(160,155,145,calc(var(--opacity, .5) * .6)) 40%,transparent 70%);filter:blur(1.5px);animation:smoke-rise 4s ease-out var(--delay, 0s) infinite;opacity:0}.power-container{position:absolute;inset:-8px -10px -4px;pointer-events:none;z-index:6}.power-glow{position:absolute;inset:0;border-radius:4px;box-shadow:inset 0 0 15px rgba(0,229,255,calc(var(--power-intensity, .2) * .2)),0 0 10px rgba(0,229,255,calc(var(--power-intensity, .2) * .3));animation:power-pulse 2.5s ease-in-out infinite}.power-spark{position:absolute;left:var(--spark-x, 50%);top:var(--spark-y, 50%);width:3px;height:3px;background:#00e5ff;border-radius:50%;box-shadow:0 0 4px #00e5ff,0 0 10px #00e5ff99;animation:spark-drift 2.5s ease-in-out var(--spark-delay, 0s) infinite}.power-ring{position:absolute;bottom:-4px;left:50%;transform:translate(-50%);width:85%;height:10px;border:1.5px solid rgba(0,229,255,calc(var(--power-intensity, .2) * .5));border-radius:50%;box-shadow:0 0 8px rgba(0,229,255,calc(var(--power-intensity, .2) * .4));animation:energy-pulse 2s ease-in-out infinite}.fan-unit{pointer-events:none;z-index:6}.fan-unit:before{content:"";position:absolute;inset:-4px;border-radius:50%;background:radial-gradient(circle,rgba(136,204,255,.1) 0%,transparent 70%)}.fan-blade{display:block;animation:fan-spin linear infinite;filter:drop-shadow(0 0 4px rgba(136,204,255,.6))}.vapor-trail{position:absolute;top:100%;left:50%;transform:translate(-50%);width:6px;height:16px;background:linear-gradient(to bottom,rgba(136,204,255,var(--vapor-opacity, .2)) 0%,transparent 100%);border-radius:0 0 3px 3px;filter:blur(2px);animation:vapor-drift 2s ease-in-out infinite}.temp-overlay{position:absolute;inset:-10px;border-radius:6px;background:radial-gradient(ellipse at 50% 40%,var(--temp-color, #00b8ff) 0%,transparent 65%);opacity:var(--temp-opacity, .1);animation:temp-shimmer var(--shimmer-speed, 5s) ease-in-out infinite;pointer-events:none;z-index:1}.temp-overlay--critical{animation:temp-shimmer var(--shimmer-speed, 2s) ease-in-out infinite,temp-pulse 1.2s ease-in-out infinite}.pue-ring{position:absolute;bottom:-14px;left:50%;width:65px;height:16px;transform:translate(-50%);border:1.5px solid var(--pue-color, #00ff88);border-radius:50%;box-shadow:0 0 6px var(--pue-color, #00ff88),inset 0 0 4px var(--pue-color, #00ff88);opacity:var(--pue-opacity, .5);animation:pue-pulse var(--pue-speed, 3s) ease-in-out infinite;pointer-events:none;z-index:5}.dc-info-card{position:absolute;bottom:-6px;left:50%;transform:translate(-50%) translateY(100%);width:195px;padding:10px 12px;background:#020810f0;border:1px solid rgba(0,229,255,.12);border-radius:6px;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);z-index:30;opacity:0;pointer-events:none;transition:opacity .35s ease,transform .35s ease;box-shadow:0 8px 32px #0009}.dc-marker:hover .dc-info-card{opacity:1;transform:translate(-50%) translateY(100%) translateY(10px)}.dc-info-name{font-size:10px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:#00e5ff;margin-bottom:2px}.dc-info-location{font-size:7.5px;letter-spacing:.1em;color:#8ab8d473;margin-bottom:8px;text-transform:uppercase}.dc-info-metric{display:flex;align-items:center;justify-content:space-between;padding:3px 0;border-bottom:1px solid rgba(0,229,255,.04)}.dc-info-metric:last-of-type{border-bottom:none}.dc-info-metric-label{font-size:7.5px;letter-spacing:.06em;color:#8ab8d480;text-transform:uppercase}.dc-info-metric-value{font-size:9px;font-weight:600;letter-spacing:.04em;font-family:Courier New,monospace}.dc-info-enter{display:block;text-align:center;margin-top:8px;padding-top:6px;border-top:1px solid rgba(0,229,255,.08);font-size:7px;letter-spacing:.2em;text-transform:uppercase;color:#00e5ff59}.dc-label{text-align:center;margin-top:6px;pointer-events:none}.dc-label-name{font-size:7.5px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:#00e5ff;text-shadow:0 0 8px rgba(0,229,255,.4);white-space:nowrap}.dc-label-status{font-size:5.5px;letter-spacing:.2em;text-transform:uppercase;margin-top:2px;white-space:nowrap}.dc-dashboard-wrap{position:absolute;inset:52px 0 0;z-index:50;background:#020810;opacity:0;animation:dashboard-enter .9s cubic-bezier(.16,1,.3,1) .1s forwards}.dc-dashboard-wrap--exiting{animation:dashboard-exit .7s ease-in forwards}.dc-dashboard-wrap .app-header{display:none}.dc-dashboard-wrap .app{grid-template-rows:1fr;width:100%;min-width:0;min-height:0;height:100%;max-height:100%}.dc-dashboard-wrap .scene{width:100%;min-width:0;min-height:0;height:100%;align-self:stretch}.dc-dashboard-wrap .tier,.dc-dashboard-wrap .conn-layer,.dc-dashboard-wrap .scene-base{max-width:none}.zoom-flash{position:fixed;inset:0;z-index:200;background:radial-gradient(circle at var(--flash-x, 50%) var(--flash-y, 50%),rgba(0,229,255,.25) 0%,rgba(0,229,255,.08) 30%,transparent 70%);pointer-events:none;animation:zoom-flash 1.2s ease-out forwards}@keyframes dc-view-scan{0%{top:-140px}to{top:100%}}@keyframes holo-led-blink{0%,to{opacity:1}50%{opacity:.3}}@keyframes holo-ring-pulse{0%,to{transform:translate(-50%,-50%) scaleY(.28) scale(1);opacity:.6}50%{transform:translate(-50%,-50%) scaleY(.28) scale(1.08);opacity:1}}@keyframes draw-outline{0%{stroke-dashoffset:50000;fill:#00e5ff00}80%{fill:#00e5ff00}to{stroke-dashoffset:0;fill:#00e5ff04}}@keyframes outline-breathe{0%,to{stroke:#00e5ff59;filter:drop-shadow(0 0 8px rgba(0,229,255,.2)) drop-shadow(0 0 20px rgba(0,229,255,.08))}50%{stroke:#00e5ff8c;filter:drop-shadow(0 0 12px rgba(0,229,255,.3)) drop-shadow(0 0 30px rgba(0,229,255,.12))}}@keyframes building-hover{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}@keyframes beacon-glow{0%,to{box-shadow:0 0 4px currentColor,0 0 8px currentColor;opacity:.7}50%{box-shadow:0 0 8px currentColor,0 0 18px currentColor,0 0 28px currentColor;opacity:1}}@keyframes smoke-rise{0%{transform:translateY(0) translate(0) scale(.4);opacity:0}10%{opacity:var(--opacity, .5)}50%{opacity:calc(var(--opacity, .5) * .35)}to{transform:translateY(-70px) translate(var(--drift, 5px)) scale(2.8);opacity:0}}@keyframes power-pulse{0%,to{opacity:.5}50%{opacity:1}}@keyframes spark-drift{0%{opacity:.2;transform:scale(.6) translate(0)}25%{opacity:.9;transform:scale(1.4) translate(2px,-2px)}50%{opacity:.4;transform:scale(.8) translate(-1px,1px)}75%{opacity:1;transform:scale(1.6) translate(1px,-1px)}to{opacity:.2;transform:scale(.6) translate(0)}}@keyframes energy-pulse{0%,to{transform:translate(-50%) scaleX(1);opacity:.4}50%{transform:translate(-50%) scaleX(1.12);opacity:.8}}@keyframes fan-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes vapor-drift{0%,to{transform:translate(-50%) translateY(0);opacity:1}50%{transform:translate(-50%) translateY(5px);opacity:.4}}@keyframes temp-shimmer{0%,to{opacity:calc(var(--temp-opacity, .1) * .5)}50%{opacity:var(--temp-opacity, .1)}}@keyframes temp-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.06)}}@keyframes pue-pulse{0%,to{transform:translate(-50%) scale(1);opacity:calc(var(--pue-opacity, .5) * .6)}50%{transform:translate(-50%) scale(1.1);opacity:var(--pue-opacity, .5)}}@keyframes data-flow{0%{stroke-dashoffset:0}to{stroke-dashoffset:-52}}@keyframes dashboard-enter{0%{opacity:0;transform:scale(1.015)}to{opacity:1;transform:scale(1)}}@keyframes dashboard-exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.985)}}@keyframes map-zoom-in{0%{transform:scale(1);opacity:1}55%{opacity:.3}to{transform:scale(8);opacity:0}}@keyframes map-zoom-out{0%{transform:scale(8);opacity:0}25%{opacity:.3}to{transform:scale(1);opacity:1}}@keyframes zoom-flash{0%{opacity:0}15%{opacity:1}to{opacity:0}}@keyframes dc-marker-appear{0%{opacity:0;transform:translate(-50%,-50%) scale(.3) translateY(20px)}to{opacity:1;transform:translate(-50%,-50%) scale(1) translateY(0)}}@keyframes conn-appear{0%{opacity:0}to{opacity:1}}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html,body,#root{width:100%;height:100%;overflow:hidden}body{font-family:var(--aiops-font-family, "Segoe UI", system-ui, -apple-system, sans-serif);background-color:#020810;color:#c8dff0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#1e508c66;border-radius:2px}::-webkit-scrollbar-thumb:hover{background:#22d3ee4d}*{scrollbar-width:thin;scrollbar-color:rgba(30,80,140,.4) transparent}@keyframes holo-ring-pulse{0%,to{transform:scaleY(.22) scale(1)}50%{transform:scaleY(.22) scale(.965)}}@keyframes holo-beam-pulse{0%{opacity:.75;filter:brightness(1)}40%{opacity:1;filter:brightness(1.35)}70%{opacity:.55;filter:brightness(.7)}to{opacity:.75;filter:brightness(1)}}@keyframes holo-scan{0%{top:-3px;opacity:0}6%{opacity:1}90%{opacity:.6}to{top:110%;opacity:0}}@keyframes holo-led-blink{0%,88%,to{opacity:1}93%{opacity:.15}}@keyframes holo-float{0%,to{transform:translateY(0)}50%{transform:translateY(-7px)}}@keyframes holo-base-spin{0%{transform:translate(-50%) scaleY(.22) rotate(0)}to{transform:translate(-50%) scaleY(.22) rotate(360deg)}}@keyframes component-drill-pulse{0%,to{box-shadow:0 0 #f253}50%{box-shadow:0 0 12px 2px #ff225526}}@keyframes comp-dialog-border-glow{0%,to{border-color:var(--dialog-color, #00e5ff)33;box-shadow:0 0 30px var(--dialog-color, #00e5ff) 18,0 12px 60px #000000bf,inset 0 0 40px #0006}50%{border-color:var(--dialog-color, #00e5ff)66;box-shadow:0 0 50px var(--dialog-color, #00e5ff) 30,0 12px 60px #000000bf,inset 0 0 40px #0006}}@keyframes comp-dialog-icon-pop{0%{opacity:0;transform:scale(.3) translateY(14px)}60%{opacity:1;transform:scale(1.08) translateY(-3px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes comp-dialog-metric-fill{0%{transform:scaleX(0)}to{transform:scaleX(1)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-dashstream",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "author": "Busaud",
6
6
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "files": [
17
17
  "dist",
18
18
  "README.md",
19
- "dashstream-skill.md"
19
+ "skills"
20
20
  ],
21
21
  "main": "./dist/index.js",
22
22
  "module": "./dist/index.js",
@@ -0,0 +1,318 @@
1
+ ---
2
+ name: dashstream-3d-dashboard
3
+ description: Build 3D carousel dashboards with AIOPsDashboard, services, and nodes
4
+ license: MIT
5
+ compatibility: opencode
6
+ metadata:
7
+ audience: developers
8
+ workflow: react
9
+ ---
10
+
11
+ ## What I do
12
+
13
+ - Guide building a 3D carousel dashboard with `AIOPsDashboard`
14
+ - Document `Service`, `ServerNode`, `DatabaseNode`, `WebDispatcherNode`, `MessageServerNode`, `HumanNode`
15
+ - Explain node positioning, connections, and compact offsets
16
+ - Provide minimal and full static dashboard examples
17
+
18
+ ## When to use me
19
+
20
+ Use this when creating or modifying a 3D dashboard layout — adding services, positioning nodes, or configuring connections.
21
+
22
+ For live data wiring, see **dashstream-live-data**. For drill-down details, see **dashstream-component-dialogs**.
23
+
24
+ ---
25
+
26
+ ## AIOPsDashboard — the shell
27
+
28
+ The top-level component that renders the header, carousel, and optional data layer.
29
+
30
+ ```tsx
31
+ import "react-dashstream/dist/index.css";
32
+ import { AIOPsDashboard, Service, ServerNode, DatabaseNode } from "react-dashstream";
33
+
34
+ <AIOPsDashboard
35
+ brandName="MY DASHBOARD"
36
+ brandTag="3D MONITOR"
37
+ services={[{ name: "Svc", status: "online" }]}
38
+ >
39
+ <Service name="Svc" status="online" connections={[...]}>
40
+ {/* nodes go here */}
41
+ </Service>
42
+ </AIOPsDashboard>
43
+ ```
44
+
45
+ Key props (see **dashstream-core** for full `AIOPsDashboardProps`):
46
+
47
+ | Prop | Type | Default | Notes |
48
+ |------|------|---------|-------|
49
+ | `brandName` | `string` | `"BUSAUD AIOps"` | Header brand |
50
+ | `brandTag` | `string` | `"3D MONITOR"` | Header tag |
51
+ | `services` | `ServiceMeta[]` | — | Metadata for ServiceDialog panels |
52
+ | `backgroundImage` | `string` | — | Dark mode background |
53
+ | `lightBackgroundImage` | `string` | — | Light mode background |
54
+ | `theme` / `onThemeChange` | `DashboardTheme` | — | Controlled theme |
55
+ | `logoUrl` | `string` | — | Logo image URL |
56
+ | `carouselSpeed` | `number` | `0.006` | Rotation speed |
57
+ | `fontFamily` | `string` | — | CSS font-family |
58
+ | `children` | `ReactNode` | — | `Service` children |
59
+
60
+ ---
61
+
62
+ ## Service — per-service container
63
+
64
+ Each `Service` wraps one logical service's nodes and connections.
65
+
66
+ ```tsx
67
+ <Service
68
+ name="My Service"
69
+ status="online"
70
+ connections={[
71
+ { from: [330, 200], to: [200, 380], visibleAtPhase: 3 },
72
+ { from: [330, 200], to: [460, 380], visibleAtPhase: 3 },
73
+ { from: [200, 380], to: [330, 520], visibleAtPhase: 4 },
74
+ { from: [460, 380], to: [330, 520], visibleAtPhase: 4 },
75
+ ]}
76
+ >
77
+ {/* compound nodes */}
78
+ </Service>
79
+ ```
80
+
81
+ - `name` must match keys in `dataBindings`, `serviceDataBindings`, and `ServiceMeta.name` exactly.
82
+ - `connections` are `ConnectionConfig[]` — animated SVG dashed lines between node positions.
83
+
84
+ ### ConnectionConfig
85
+
86
+ ```ts
87
+ interface ConnectionConfig {
88
+ from: [number, number]; // [x, y] matching source node's ex/ey
89
+ to: [number, number]; // [x, y] matching target node's ex/ey
90
+ visibleAtPhase?: number; // Default: 0
91
+ color?: string; // Default: "#00e5ff"
92
+ duration?: string; // Default: "1.2s"
93
+ }
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Compound nodes
99
+
100
+ All compound nodes share common positioning props:
101
+
102
+ | Prop | Type | Notes |
103
+ |------|------|-------|
104
+ | `name` | `string` | Display name + event bridge matching key |
105
+ | `subLabel` | `string` | Secondary label below name |
106
+ | `status` | `ComponentStatus` | `"online"` / `"warning"` / `"critical"` / `"offline"` |
107
+ | `ex` | `number` | X position in the ~660×640 scene |
108
+ | `ey` | `number` | Y position in the ~660×640 scene |
109
+ | `compactOffset` | `{ x, y }` | Offset in compact carousel view |
110
+ | `zIndex` | `number` | Z-order layering |
111
+ | `alert` | `AlertConfig` | Callout positioning (see dashstream-component-dialogs) |
112
+ | `dialogMetrics` | `ComponentDialogMetric[]` | Custom gauges (see dashstream-component-dialogs) |
113
+ | `subComponents` | `SubComponentConfig[]` | Custom drill-down internals (see dashstream-component-dialogs) |
114
+ | `graphSeries` | `GraphSeries[]` | Custom sparklines (see dashstream-component-dialogs) |
115
+
116
+ ### ServerNode
117
+
118
+ ```tsx
119
+ <ServerNode
120
+ ex={200} ey={380}
121
+ compactOffset={{ x: -30, y: -20 }}
122
+ zIndex={8}
123
+ name="SRV-01"
124
+ subLabel="APP SERVER"
125
+ status="online"
126
+ cpuLoad={42}
127
+ memLoad={60}
128
+ />
129
+ ```
130
+
131
+ Extra props: `cpuLoad` (number), `memLoad` (number).
132
+
133
+ ### DatabaseNode
134
+
135
+ ```tsx
136
+ <DatabaseNode
137
+ ex={460} ey={520}
138
+ compactOffset={{ x: 30, y: 20 }}
139
+ zIndex={7}
140
+ name="DB-01"
141
+ subLabel="PRIMARY"
142
+ status="online"
143
+ capacity={55}
144
+ />
145
+ ```
146
+
147
+ Extra props: `capacity` (number).
148
+
149
+ ### WebDispatcherNode
150
+
151
+ ```tsx
152
+ <WebDispatcherNode
153
+ ex={330} ey={230}
154
+ compactOffset={{ x: 0, y: -30 }}
155
+ zIndex={9}
156
+ name="WD-01"
157
+ subLabel="DISPATCHER"
158
+ status="online"
159
+ traffic={45}
160
+ />
161
+ ```
162
+
163
+ Extra props: `traffic` (number).
164
+
165
+ ### MessageServerNode
166
+
167
+ ```tsx
168
+ <MessageServerNode
169
+ ex={330} ey={230}
170
+ compactOffset={{ x: 0, y: -30 }}
171
+ zIndex={9}
172
+ name="MSG-01"
173
+ subLabel="MESSAGE SERVER"
174
+ status="online"
175
+ queueDepth={30}
176
+ />
177
+ ```
178
+
179
+ Extra props: `queueDepth` (number).
180
+
181
+ ### HumanNode
182
+
183
+ ```tsx
184
+ <HumanNode
185
+ ex={330} ey={100}
186
+ compactOffset={{ x: 0, y: -40 }}
187
+ zIndex={10}
188
+ name="USERS"
189
+ subLabel="500 ACTIVE"
190
+ status="online"
191
+ />
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Node positioning guide
197
+
198
+ The topology scene is ~660×640 pixels.
199
+
200
+ | Layer | Typical `ey` | `visibleAtPhase` | Component |
201
+ | ----- | ------------ | ---------------- | --------- |
202
+ | Users (top) | 100 | 2 | `HumanNode` |
203
+ | Dispatcher | 230 | 2 | `WebDispatcherNode` |
204
+ | App servers | 350–380 | 3 | `ServerNode` |
205
+ | Databases | 500–520 | 4 | `DatabaseNode` |
206
+
207
+ Center X = `330`. Left/right columns: `200` / `460`. Three-column: `165` / `330` / `495`.
208
+
209
+ `compactOffset` controls node position in the compact carousel view relative to center.
210
+
211
+ ---
212
+
213
+ ## Usage patterns
214
+
215
+ ### Minimal static dashboard
216
+
217
+ ```tsx
218
+ import "react-dashstream/dist/index.css";
219
+ import { AIOPsDashboard, Service, ServerNode, DatabaseNode } from "react-dashstream";
220
+
221
+ <AIOPsDashboard brandName="MY DASHBOARD" services={[{ name: "Svc", status: "online" }]}>
222
+ <Service
223
+ name="Svc"
224
+ status="online"
225
+ connections={[{ from: [330, 200], to: [330, 380], visibleAtPhase: 3 }]}
226
+ >
227
+ <ServerNode
228
+ ex={330} ey={380}
229
+ compactOffset={{ x: 0, y: 0 }}
230
+ zIndex={8}
231
+ name="SRV-01"
232
+ status="online"
233
+ cpuLoad={42}
234
+ memLoad={60}
235
+ />
236
+ </Service>
237
+ </AIOPsDashboard>
238
+ ```
239
+
240
+ ### Multi-node service
241
+
242
+ ```tsx
243
+ function MyService({ name, status, cpuLoad, memLoad, dbCapacity, dbStatus }: any) {
244
+ return (
245
+ <Service
246
+ name={name}
247
+ status={status ?? "online"}
248
+ connections={[
249
+ { from: [330, 200], to: [200, 380], visibleAtPhase: 3 },
250
+ { from: [330, 200], to: [460, 380], visibleAtPhase: 3 },
251
+ { from: [200, 380], to: [330, 520], visibleAtPhase: 4 },
252
+ { from: [460, 380], to: [330, 520], visibleAtPhase: 4 },
253
+ ]}
254
+ >
255
+ <ServerNode
256
+ ex={200} ey={380}
257
+ compactOffset={{ x: -30, y: -20 }}
258
+ zIndex={8}
259
+ name="SRV-01"
260
+ subLabel="APP SERVER"
261
+ status={status ?? "online"}
262
+ cpuLoad={cpuLoad ?? 42}
263
+ memLoad={memLoad ?? 60}
264
+ alert={{ offsetX: -160, offsetY: -60, align: "left" }}
265
+ />
266
+ <DatabaseNode
267
+ ex={460} ey={380}
268
+ compactOffset={{ x: 30, y: -20 }}
269
+ zIndex={7}
270
+ name="DB-01"
271
+ subLabel="PRIMARY"
272
+ status={dbStatus ?? "online"}
273
+ capacity={dbCapacity ?? 55}
274
+ alert={{ offsetX: 160, offsetY: -60, align: "right" }}
275
+ />
276
+ </Service>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ### Multi-component services (flat prefix convention)
282
+
283
+ When a service has multiple nodes of the same type, use flat prefixed props:
284
+
285
+ ```tsx
286
+ interface ServiceXProps {
287
+ name: string;
288
+ status?: ComponentStatus;
289
+ srv1CpuLoad?: number;
290
+ srv1MemLoad?: number;
291
+ srv1Status?: ComponentStatus;
292
+ srv2CpuLoad?: number;
293
+ srv2MemLoad?: number;
294
+ srv2Status?: ComponentStatus;
295
+ dbCapacity?: number;
296
+ dbStatus?: ComponentStatus;
297
+ }
298
+
299
+ function ServiceX({
300
+ name, status = "online",
301
+ srv1CpuLoad = 54, srv1MemLoad = 58, srv1Status = "online",
302
+ srv2CpuLoad = 63, srv2MemLoad = 66, srv2Status = "online",
303
+ dbCapacity = 68, dbStatus = "online",
304
+ }: ServiceXProps) {
305
+ return (
306
+ <Service name={name} status={status} connections={[/* ... */]}>
307
+ <ServerNode name="SRV-X1" status={srv1Status}
308
+ cpuLoad={srv1CpuLoad} memLoad={srv1MemLoad} ... />
309
+ <ServerNode name="SRV-X2" status={srv2Status}
310
+ cpuLoad={srv2CpuLoad} memLoad={srv2MemLoad} ... />
311
+ <DatabaseNode name="DB-X1" status={dbStatus}
312
+ capacity={dbCapacity} ... />
313
+ </Service>
314
+ );
315
+ }
316
+ ```
317
+
318
+ Use a consistent convention like `srv1CpuLoad`, `srv2CpuLoad`. The service component maps each prefixed prop to the correct node.