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;
}
Menu Politique Modal
Liste de préfixes modale
Liste de chemins AS modale
Modal de liste de communauté
Modal de carte d'itinéraire
Nœud modal
Modal Edge amélioré avec les listes déroulantes Route-Map
Bibliothèque de modèles modale
Visualiseur de processus décisionnel BGP modal
💡 Démarrage rapide :
• Faites glisser les routeurs/transporteurs sur le canevas.
• Cliquez sur "🔗 Créer un Peering" puis cliquez sur deux nœuds
• Cliquez sur "📋 Objets de stratégie ➕" pour créer des listes de préfixes et des cartes de route.
• Double-cliquez sur un homologue pour appliquer des cartes de route.
• Cliquez sur "▶️ Exécuter la simulation" pour voir les résultats
• Faites glisser les routeurs/transporteurs sur le canevas.
• Cliquez sur "🔗 Créer un Peering" puis cliquez sur deux nœuds
• Cliquez sur "📋 Objets de stratégie ➕" pour créer des listes de préfixes et des cartes de route.
• Double-cliquez sur un homologue pour appliquer des cartes de route.
• Cliquez sur "▶️ Exécuter la simulation" pour voir les résultats
Aucun routeur sélectionné