BGP Network Design & Simulation Tool
#bgp-app {
display: grid;
grid-template-columns: 280px 1fr;
grid-template-rows: 1fr 300px;
height: 85vh;
gap: 2px;
background: #2d2d2d;
margin: 0;
}
/* Sidebar */
#bgp-sidebar {
grid-row: 1 / 3;
background: #252526;
padding: 15px;
overflow-y: auto;
border-right: 2px solid #3e3e42;
}
#bgp-sidebar h2 {
color: #4fc3f7;
margin-bottom: 15px;
font-size: 18px;
border-bottom: 2px solid #4fc3f7;
padding-bottom: 5px;
}
.palette-section {
margin-bottom: 20px;
}
.palette-section h3 {
color: #81c784;
font-size: 14px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.palette-section h3 .add-btn {
background: #4fc3f7;
color: #000;
border: none;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 11px;
font-weight: bold;
}
.palette-section h3 .add-btn:hover {
background: #29b6f6;
}
.palette-item {
background: #3c3c3c;
padding: 12px;
margin-bottom: 8px;
border-radius: 6px;
cursor: grab;
border: 2px solid #555;
transition: all 0.2s;
text-align: center;
user-select: none;
}
.palette-item:active {
cursor: grabbing;
}
.palette-item:hover {
background: #4a4a4a;
border-color: #4fc3f7;
transform: translateX(5px);
box-shadow: 0 4px 8px rgba(79, 195, 247, 0.3);
}
.palette-item.router {
border-left: 4px solid #ff9800;
}
.palette-item.carrier {
border-left: 4px solid #9c27b0;
}
.policy-item {
background: #3c3c3c;
padding: 8px 10px;
margin-bottom: 6px;
border-radius: 4px;
border-left: 3px solid #4fc3f7;
cursor: pointer;
transition: all 0.2s;
display: flex;
justify-content: space-between;
align-items: center;
}
.policy-item:hover {
background: #4a4a4a;
transform: translateX(3px);
}
.policy-item-name {
font-size: 12px;
font-weight: bold;
color: #e0e0e0;
}
.policy-item-type {
font-size: 10px;
color: #9e9e9e;
}
.policy-item-actions {
display: flex;
gap: 5px;
}
.policy-item-actions button {
background: none;
border: none;
color: #9e9e9e;
cursor: pointer;
padding: 2px 5px;
font-size: 14px;
}
.policy-item-actions button:hover {
color: #4fc3f7;
}
.policy-item-actions .delete-btn:hover {
color: #e57373;
}
.controls {
margin-top: 20px;
}
.btn {
width: 100%;
padding: 12px;
margin-bottom: 10px;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
transition: all 0.2s;
font-size: 13px;
}
.btn-primary {
background: #4fc3f7;
color: #000;
}
.btn-primary:hover {
background: #29b6f6;
}
.btn-success {
background: #81c784;
color: #000;
}
.btn-success:hover {
background: #66bb6a;
}
.btn-success.active {
background: #66bb6a;
box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.3);
}
.btn-danger {
background: #e57373;
color: #000;
}
.btn-danger:hover {
background: #ef5350;
}
.btn-secondary {
background: #81c784;
color: #000;
}
.btn-secondary:hover {
background: #66bb6a;
}
.btn-small {
padding: 6px 12px;
font-size: 11px;
width: auto;
}
/* Canvas */
#canvas-container {
background: #1e1e1e;
position: relative;
background-image:
linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
background-size: 50px 50px;
border: 3px dashed rgba(79, 195, 247, 0.3);
transition: border-color 0.3s;
}
#canvas-container::before {
content: 'Drag routers and carriers here';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: rgba(255, 255, 255, 0.2);
font-size: 24px;
font-weight: bold;
pointer-events: none;
z-index: 0;
}
#canvas-container.has-nodes::before {
display: none;
}
#canvas-container.peering-mode {
border-color: #81c784;
border-width: 4px;
}
#cy {
width: 100%;
height: 100%;
position: relative;
z-index: 1;
}
/* Looking Glass Panel */
#looking-glass {
background: #252526;
border-top: 2px solid #3e3e42;
display: flex;
flex-direction: column;
}
.tabs {
display: flex;
background: #2d2d2d;
border-bottom: 2px solid #3e3e42;
}
.tab {
padding: 12px 24px;
cursor: pointer;
border: none;
background: transparent;
color: #9e9e9e;
font-weight: bold;
transition: all 0.2s;
border-bottom: 3px solid transparent;
}
.tab.active {
color: #4fc3f7;
border-bottom-color: #4fc3f7;
}
.tab:hover {
background: #3e3e42;
}
.tab-content {
flex: 1;
overflow-y: auto;
padding: 15px;
display: none;
color: #e0e0e0;
}
.tab-content.active {
display: block;
}
.rib-entry {
background: #2d2d2d;
padding: 10px;
margin-bottom: 8px;
border-radius: 4px;
border-left: 4px solid #4fc3f7;
font-family: 'Courier New', monospace;
font-size: 12px;
transition: all 0.2s;
}
.rib-entry:hover {
background: #3a3a3a;
transform: translateX(5px);
box-shadow: 0 2px 8px rgba(0, 229, 255, 0.3);
}
.rib-entry.best {
border-left-color: #81c784;
background: #1b5e20;
}
.rib-entry.best:hover {
background: #2e7d32;
}
.rib-entry.modified {
border-left-color: #ff9800;
background: #4a2c00;
}
.rib-entry.modified:hover {
background: #663d00;
}
.rib-entry.originated {
border-left-color: #42a5f5;
background: #1a237e;
}
.rib-entry.originated:hover {
background: #283593;
}
.route-map-impact {
margin-top: 8px;
padding: 8px;
background: rgba(255, 152, 0, 0.1);
border-left: 2px solid #ff9800;
font-size: 11px;
font-style: italic;
}
.config-preview {
font-family: 'Courier New', monospace;
font-size: 12px;
line-height: 1.6;
white-space: pre-wrap;
background: #1e1e1e;
padding: 15px;
border-radius: 4px;
}
/* Modal Styles */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
overflow-y: auto;
}
.modal.active {
display: flex;
align-items: flex-start;
justify-content: center;
padding: 20px;
}
.modal-content {
background: #2d2d2d;
padding: 30px;
border-radius: 8px;
max-width: 800px;
width: 100%;
max-height: 90vh;
overflow-y: auto;
border: 2px solid #4fc3f7;
color: #e0e0e0;
margin: 20px auto;
}
.modal-content h3 {
color: #4fc3f7;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.modal-section {
margin-bottom: 25px;
padding: 15px;
background: #1e1e1e;
border-radius: 6px;
border-left: 4px solid #4fc3f7;
}
.modal-section h4 {
color: #81c784;
margin-bottom: 15px;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 1px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-bottom: 15px;
}
.form-group {
margin-bottom: 15px;
}
.form-group.full-width {
grid-column: 1 / -1;
}
.form-group label {
display: block;
margin-bottom: 5px;
color: #81c784;
font-weight: bold;
font-size: 13px;
}
.form-group label .required {
color: #e57373;
}
.form-group label .optional {
color: #9e9e9e;
font-weight: normal;
font-size: 11px;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 10px;
background: #2d2d2d;
border: 1px solid #555;
border-radius: 4px;
color: #e0e0e0;
font-family: inherit;
font-size: 13px;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: #4fc3f7;
box-shadow: 0 0 0 2px rgba(79, 195, 247, 0.2);
}
.form-group input:disabled,
.form-group select:disabled {
background: #1a1a1a;
color: #666;
cursor: not-allowed;
}
.form-group .help-text {
font-size: 11px;
color: #9e9e9e;
margin-top: 4px;
font-style: italic;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 8px;
padding: 10px;
background: #2d2d2d;
border-radius: 4px;
}
.checkbox-group input[type="checkbox"] {
width: auto;
cursor: pointer;
}
.checkbox-group label {
margin: 0;
cursor: pointer;
font-weight: normal;
}
/* Phase 3.1: Networks list styling */
.networks-list {
margin-bottom: 15px;
max-height: 200px;
overflow-y: auto;
background: #2d2d2d;
border-radius: 4px;
padding: 10px;
}
.network-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
background: #3e3e42;
border-radius: 4px;
margin-bottom: 6px;
border-left: 3px solid #81c784;
}
.network-item .network-prefix {
color: #81c784;
font-family: 'Courier New', monospace;
font-weight: bold;
}
.network-item .network-delete {
background: #e57373;
color: #000;
border: none;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 11px;
}
.network-item .network-delete:hover {
background: #ef5350;
}
.modal-actions {
display: flex;
gap: 10px;
margin-top: 25px;
padding-top: 20px;
border-top: 2px solid #3e3e42;
}
.collapsible-section {
margin-top: 15px;
}
.collapsible-header {
background: #3e3e42;
padding: 12px 15px;
border-radius: 4px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: background 0.2s;
}
.collapsible-header:hover {
background: #4a4a4a;
}
.collapsible-header .arrow {
transition: transform 0.2s;
}
.collapsible-header.active .arrow {
transform: rotate(90deg);
}
.collapsible-content {
display: none;
padding: 15px;
background: #2d2d2d;
border-radius: 0 0 4px 4px;
}
.collapsible-content.active {
display: block;
}
/* Route-Map Builder Styles */
.route-map-statement {
background: #1e1e1e;
padding: 15px;
margin-bottom: 15px;
border-radius: 6px;
border-left: 4px solid #4fc3f7;
}
.route-map-statement-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #3e3e42;
}
.route-map-statement-header h5 {
color: #4fc3f7;
margin: 0;
}
.match-set-section {
margin-bottom: 15px;
}
.match-set-section h6 {
color: #81c784;
font-size: 12px;
margin-bottom: 10px;
text-transform: uppercase;
}
.prefix-list-entry,
.as-path-entry {
background: #2d2d2d;
padding: 10px;
margin-bottom: 8px;
border-radius: 4px;
display: grid;
grid-template-columns: 80px 100px 1fr 80px 80px 40px;
gap: 10px;
align-items: center;
}
.prefix-list-entry input,
.prefix-list-entry select,
.as-path-entry input,
.as-path-entry select {
padding: 6px;
font-size: 12px;
}
.entry-actions {
display: flex;
gap: 5px;
justify-content: center;
}
.entry-actions button {
background: #e57373;
border: none;
padding: 4px 8px;
border-radius: 3px;
cursor: pointer;
color: #000;
font-size: 11px;
font-weight: bold;
}
.info-box, .peer-info-box {
background: #1e3a5f;
padding: 15px;
border-radius: 4px;
margin-bottom: 15px;
border-left: 4px solid #4fc3f7;
}
.peer-info-box h4 {
color: #4fc3f7;
margin-bottom: 10px;
font-size: 14px;
}
.peer-info-row {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.peer-info-row:last-child {
border-bottom: none;
}
.peer-info-label {
color: #81c784;
font-weight: bold;
font-size: 12px;
}
.peer-info-value {
color: #e0e0e0;
font-size: 12px;
font-family: 'Courier New', monospace;
}
.community-badge {
display: inline-block;
background: #9c27b0;
color: #fff;
padding: 2px 6px;
border-radius: 3px;
font-size: 10px;
margin-right: 4px;
}
.attribute-tag {
display: inline-block;
background: #555;
padding: 2px 6px;
border-radius: 3px;
font-size: 10px;
margin-right: 4px;
}
.attribute-tag.changed {
background: #ff9800;
color: #000;
}
.status-badge {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
}
.status-badge.established {
background: #81c784;
color: #000;
}
.status-badge.configured {
background: #ff9800;
color: #000;
}
.status-badge.filtered {
background: #e57373;
color: #fff;
}
#notification {
position: fixed;
top: 80px;
right: 20px;
background: #4fc3f7;
color: #000;
padding: 15px 20px;
border-radius: 6px;
font-weight: bold;
z-index: 2000;
display: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
max-width: 400px;
}
#notification.show {
display: block;
animation: slideIn 0.3s ease-out;
}
#notification.error {
background: #e57373;
color: #fff;
}
#notification.success {
background: #81c784;
color: #000;
}
@keyframes slideIn {
from {
transform: translateX(400px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.summary-section {
margin-bottom: 20px;
}
.summary-section h4 {
color: #81c784;
margin-bottom: 10px;
font-size: 14px;
}
.summary-item {
background: #2d2d2d;
padding: 8px;
margin-bottom: 5px;
border-radius: 4px;
font-size: 13px;
}
.edge-legend {
background: #2d2d2d;
padding: 15px;
border-radius: 4px;
margin-top: 15px;
}
.edge-legend h5 {
color: #81c784;
margin-bottom: 10px;
font-size: 12px;
}
.legend-item {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
font-size: 11px;
}
.legend-line {
width: 40px;
height: 3px;
border-radius: 2px;
}
.legend-line.established {
background: #81c784;
}
.legend-line.configured {
background: #ff9800;
}
.legend-line.ibgp {
background: #4fc3f7;
border: 2px dashed #4fc3f7;
height: 1px;
}
.legend-line.ebgp {
background: #81c784;
}
.legend-line.best-path {
background: #66bb6a;
height: 5px;
}
.legend-line.backup-path {
background: #ffca28;
height: 3px;
}
.legend-line.filtered-path {
background: #ef5350;
height: 2px;
border: 1px dotted #ef5350;
}
.legend-line.has-localas {
background: #ba68c8;
border: 2px dotted #ba68c8;
height: 2px;
}
.empty-state {
text-align: center;
padding: 30px;
color: #9e9e9e;
font-style: italic;
}
/* Phase 3.5: Validation Panel */
.validation-panel {
margin-top: 15px;
background: #2d2d2d;
border-radius: 4px;
padding: 10px;
max-height: 200px;
overflow-y: auto;
}
.validation-panel h4 {
color: #ffca28;
font-size: 12px;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 5px;
}
.warning-item {
background: #3e2723;
border-left: 3px solid #ff9800;
padding: 8px;
margin-bottom: 6px;
border-radius: 3px;
font-size: 11px;
}
.warning-item.error {
background: #4a1a1a;
border-left-color: #ef5350;
}
.warning-item.success {
background: #1b3a1b;
border-left-color: #66bb6a;
}
.warning-item .warning-title {
font-weight: bold;
color: #ff9800;
margin-bottom: 3px;
}
.warning-item.error .warning-title {
color: #ef5350;
}
.warning-item.success .warning-title {
color: #66bb6a;
}
.warning-item .warning-fix {
color: #81c784;
cursor: pointer;
text-decoration: underline;
margin-top: 3px;
display: inline-block;
}
.warning-item .warning-fix:hover {
color: #a5d6a7;
}
.validate-btn {
margin-top: 10px;
}
.template-card:hover {
border-color: #4fc3f7;
background: #3a3a3a;
transform: scale(1.02);
box-shadow: 0 4px 8px rgba(79, 195, 247, 0.3);
}
/* Beginner/Advanced Mode */
.advanced-only {
display: block;
}
body.beginner-mode .advanced-only {
display: none !important;
}
/* Decision Process Viewer */
.decision-step {
background: #2d2d2d;
padding: 12px;
margin-bottom: 8px;
border-radius: 4px;
border-left: 4px solid #555;
}
.decision-step.passed {
border-left-color: #81c784;
}
.decision-step.failed {
border-left-color: #9e9e9e;
}
.decision-step.winner {
border-left-color: #4fc3f7;
background: #1a3a4a;
}
.decision-step-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
}
.decision-step-title {
font-weight: bold;
font-size: 12px;
}
.decision-step.passed .decision-step-title {
color: #81c784;
}
.decision-step.failed .decision-step-title {
color: #9e9e9e;
}
.decision-step.winner .decision-step-title {
color: #4fc3f7;
}
.decision-step-result {
font-size: 11px;
color: #e0e0e0;
}
.decision-comparison {
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: 10px;
align-items: center;
margin-top: 8px;
font-size: 11px;
}
.decision-route {
padding: 6px 10px;
background: #1a1a1a;
border-radius: 4px;
font-family: 'Courier New', monospace;
}
.decision-operator {
color: #ffca28;
font-weight: bold;
}
/* Bulk Selection Highlight */
.cy-edge.bulk-selected {
line-color: #ffca28 !important;
target-arrow-color: #ffca28 !important;
width: 5 !important;
}
/* Help Tooltips */
.help-icon {
display: inline-block;
width: 16px;
height: 16px;
background: #4fc3f7;
color: #000;
border-radius: 50%;
text-align: center;
line-height: 16px;
font-size: 12px;
font-weight: bold;
cursor: help;
margin-left: 5px;
position: relative;
}
.help-icon:hover::after {
content: attr(data-tooltip);
position: absolute;
left: 25px;
top: -5px;
background: #1a1a1a;
color: #e0e0e0;
padding: 10px;
border-radius: 4px;
border: 1px solid #4fc3f7;
width: 300px;
font-size: 11px;
font-weight: normal;
line-height: 1.4;
z-index: 1000;
white-space: normal;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.help-icon:hover::before {
content: '';
position: absolute;
left: 20px;
top: 3px;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-right: 5px solid #4fc3f7;
z-index: 1001;
}
Menú de políticas modal
Lista de prefijos modal
Modal de lista de rutas AS
Modal de lista de comunidad
Modal de mapa de ruta
Nodo modal
Modal de borde mejorado con menús desplegables de mapa de ruta
Modal de biblioteca de plantillas
Modal del visor de procesos de decisión BGP
💡 Inicio rápido:
• Arrastre enrutadores/portadores al lienzo
• Haga clic en "🔗 Crear emparejamiento" y luego haga clic en dos nodos
• Haga clic en "📋 Objetos de política ➕" para crear listas de prefijos y mapas de rutas.
• Haga doble clic en peer para aplicar mapas de ruta
• Haga clic en "▶️ Ejecutar simulación" para ver los resultados.
• Arrastre enrutadores/portadores al lienzo
• Haga clic en "🔗 Crear emparejamiento" y luego haga clic en dos nodos
• Haga clic en "📋 Objetos de política ➕" para crear listas de prefijos y mapas de rutas.
• Haga doble clic en peer para aplicar mapas de ruta
• Haga clic en "▶️ Ejecutar simulación" para ver los resultados.
No se seleccionó ningún enrutador