diff --git a/website/docs/overview/architecture/system-architecture.md b/website/docs/overview/architecture/system-architecture.md
index f6c7c785..2139c782 100644
--- a/website/docs/overview/architecture/system-architecture.md
+++ b/website/docs/overview/architecture/system-architecture.md
@@ -4,8 +4,10 @@ The Semantic Router implements a sophisticated Mixture-of-Models (MoM) architect
## High-Level Architecture Overview
-```mermaid
-graph TB
+import ZoomableMermaid from '@site/src/components/ZoomableMermaid';
+
+
+{`graph TB
subgraph "Client Layer"
Client1[Web Application]
Client2[Mobile App]
@@ -62,8 +64,8 @@ graph TB
ExtProc --> Prometheus
Prometheus --> Grafana
- ExtProc --> Logs
-```
+ ExtProc --> Logs`}
+
## Core Components
@@ -113,7 +115,7 @@ http_filters:
type OpenAIRouter struct {
Config *config.RouterConfig
CategoryDescriptions []string
- Classifier *classification.Classifier // ModernBERT-based
+ Classifier *classification.Classifier // ModernBERT-based
PIIChecker *pii.PolicyChecker // Privacy protection
Cache *cache.SemanticCache // Performance optimization
ToolsDatabase *tools.ToolsDatabase // Tool selection
@@ -125,8 +127,8 @@ type OpenAIRouter struct {
**Processing Pipeline**:
-```mermaid
-sequenceDiagram
+
+{`sequenceDiagram
participant E as Envoy
participant R as Router
participant C as Classifier
@@ -152,8 +154,8 @@ sequenceDiagram
E->>R: Response from model
R->>Ca: Cache semantic representation
R->>E: Final response
- end
-```
+ end`}
+
### 3. Classification System - Decision Engine
@@ -161,8 +163,8 @@ The classification system uses ModernBERT models for multiple classification tas
#### Category Classification
-```mermaid
-graph LR
+
+{`graph LR
Query[User Query] --> Tokenizer[ModernBERT Tokenizer]
Tokenizer --> Encoder[ModernBERT Encoder
768-dim embeddings]
Encoder --> ClassifierHead[Classification Head
Category Prediction]
@@ -182,8 +184,8 @@ graph LR
Decision --> Code
Decision --> General
Decision --> Science
- Decision --> Business
-```
+ Decision --> Business`}
+
#### Multi-Task Architecture
@@ -262,8 +264,8 @@ graph TB
### Response Processing Flow
-```mermaid
-sequenceDiagram
+
+{`sequenceDiagram
participant C as Client
participant E as Envoy
participant R as Router
@@ -285,8 +287,8 @@ sequenceDiagram
R->>Me: Record routing metrics
R->>E: Processed Response
- E->>C: Final Response to Client
-```
+ E->>C: Final Response to Client`}
+
## Threading and Concurrency Model
@@ -514,8 +516,8 @@ func (cb *CircuitBreaker) Call(operation func() error) error {
### Fallback Strategies
-```mermaid
-graph TB
+
+{`graph TB
Request[Incoming Request] --> PrimaryRoute[Primary Routing Decision]
PrimaryRoute --> ModelA{Model A
Available?}
@@ -534,8 +536,8 @@ graph TB
ProcessA --> Success[Successful Response]
ProcessB --> Success
ProcessGeneral --> Success
- ReturnCached --> Success
-```
+ ReturnCached --> Success`}
+
## Monitoring and Observability
diff --git a/website/src/components/ZoomableMermaid/index.js b/website/src/components/ZoomableMermaid/index.js
new file mode 100644
index 00000000..3d6eefb8
--- /dev/null
+++ b/website/src/components/ZoomableMermaid/index.js
@@ -0,0 +1,235 @@
+import React, { useState, useRef, useEffect, useCallback } from 'react'
+import { createPortal } from 'react-dom'
+import Mermaid from '@theme/Mermaid'
+import styles from './styles.module.css'
+
+const ZoomableMermaid = ({ children, title, defaultZoom = 1.2 }) => {
+ const [isModalOpen, setIsModalOpen] = useState(false)
+ const [isHovered, setIsHovered] = useState(false)
+ const [zoomLevel, setZoomLevel] = useState(defaultZoom) // Use defaultZoom prop
+ const modalRef = useRef(null)
+ const containerRef = useRef(null)
+
+ const openModal = useCallback(() => {
+ setIsModalOpen(true)
+ setZoomLevel(defaultZoom) // Reset to default zoom when opening
+ document.body.style.overflow = 'hidden'
+ }, [defaultZoom])
+
+ const closeModal = useCallback(() => {
+ setIsModalOpen(false)
+ document.body.style.overflow = 'unset'
+ // Return focus to the original container
+ if (containerRef.current) {
+ containerRef.current.focus()
+ }
+ }, [])
+
+ const zoomIn = useCallback(() => {
+ setZoomLevel(prev => Math.min(prev + 0.2, 5.0)) // Max 500%
+ }, [])
+
+ const zoomOut = useCallback(() => {
+ setZoomLevel(prev => Math.max(prev - 0.2, 0.5)) // Min 50%
+ }, [])
+
+ const resetZoom = useCallback(() => {
+ setZoomLevel(defaultZoom) // Reset to custom default instead of hardcoded 1.2
+ }, [defaultZoom])
+
+ useEffect(() => {
+ const handleEscape = (e) => {
+ if (e.key === 'Escape' && isModalOpen) {
+ closeModal()
+ }
+ }
+
+ const handleClickOutside = (e) => {
+ if (modalRef.current && !modalRef.current.contains(e.target)) {
+ closeModal()
+ }
+ }
+
+ const handleKeydown = (e) => {
+ if (!isModalOpen) return
+
+ if (e.key === '=' || e.key === '+') {
+ e.preventDefault()
+ zoomIn()
+ }
+ else if (e.key === '-') {
+ e.preventDefault()
+ zoomOut()
+ }
+ else if (e.key === '0') {
+ e.preventDefault()
+ resetZoom()
+ }
+ }
+
+ if (isModalOpen) {
+ document.addEventListener('keydown', handleEscape)
+ document.addEventListener('mousedown', handleClickOutside)
+ document.addEventListener('keydown', handleKeydown)
+
+ // Focus the modal content when opened
+ setTimeout(() => {
+ if (modalRef.current) {
+ modalRef.current.focus()
+ }
+ }, 100)
+ }
+
+ return () => {
+ document.removeEventListener('keydown', handleEscape)
+ document.removeEventListener('mousedown', handleClickOutside)
+ document.removeEventListener('keydown', handleKeydown)
+ }
+ }, [isModalOpen, closeModal, zoomIn, zoomOut, resetZoom])
+
+ // Cleanup on unmount
+ useEffect(() => {
+ return () => {
+ document.body.style.overflow = 'unset'
+ }
+ }, [])
+
+ const handleKeyDown = (e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault()
+ openModal()
+ }
+ }
+
+ const modalContent = (
+
+
+
+ {title && (
+
+ {title}
+
+ )}
+
+
+ {Math.round(zoomLevel * 100)}
+ %
+
+
+
+
+
+
+
+
+
+
+ )
+
+ return (
+ <>
+ setIsHovered(true)}
+ onMouseLeave={() => setIsHovered(false)}
+ role="button"
+ tabIndex={0}
+ onKeyDown={handleKeyDown}
+ aria-label={`Click to enlarge ${title || 'Mermaid diagram'}`}
+ aria-expanded={isModalOpen}
+ >
+
+
+
Click to enlarge
+
+
+
+
+ {isModalOpen && createPortal(modalContent, document.body)}
+ >
+ )
+}
+
+export default ZoomableMermaid
diff --git a/website/src/components/ZoomableMermaid/styles.module.css b/website/src/components/ZoomableMermaid/styles.module.css
new file mode 100644
index 00000000..aeb84e13
--- /dev/null
+++ b/website/src/components/ZoomableMermaid/styles.module.css
@@ -0,0 +1,375 @@
+.mermaidContainer {
+ position: relative;
+ cursor: pointer;
+ border-radius: 12px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+ background: var(--tech-card-bg);
+ border: 1px solid var(--tech-border);
+ box-shadow: var(--tech-shadow);
+}
+
+.mermaidContainer:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 12px 32px rgba(9, 105, 218, 0.15);
+ border-color: var(--tech-border-accent);
+}
+
+.mermaidContainer:focus {
+ outline: 2px solid var(--tech-primary-blue);
+ outline-offset: 2px;
+}
+
+.zoomHint {
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ background: rgba(9, 105, 218, 0.9);
+ color: white;
+ padding: 6px 10px;
+ border-radius: 6px;
+ font-size: 12px;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ opacity: 0;
+ transform: translateY(-4px);
+ transition: all 0.3s ease;
+ z-index: 10;
+ backdrop-filter: blur(10px);
+ font-weight: 500;
+ box-shadow: 0 4px 12px rgba(9, 105, 218, 0.3);
+}
+
+.mermaidContainer:hover .zoomHint,
+.mermaidContainer:focus .zoomHint {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.modal {
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ right: 0 !important;
+ bottom: 0 !important;
+ width: 100vw !important;
+ height: 100vh !important;
+ background: rgba(0, 0, 0, 0.9);
+ backdrop-filter: blur(5px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 99999 !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ animation: fadeIn 0.3s ease;
+}
+
+.modalContent {
+ background: var(--tech-card-bg);
+ border-radius: 16px;
+ width: 70vw;
+ height: 70vh;
+ max-width: none;
+ max-height: none;
+ overflow: hidden;
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
+ border: 1px solid var(--tech-border);
+ display: flex;
+ flex-direction: column;
+ animation: slideIn 0.3s ease;
+ position: relative !important;
+ margin: auto !important;
+}
+
+.modalHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20px 24px 16px;
+ border-bottom: 1px solid var(--tech-border);
+ background: var(--tech-surface-bg);
+ flex-shrink: 0;
+}
+
+.modalTitle {
+ margin: 0;
+ color: var(--tech-text-primary);
+ font-size: 18px;
+ font-weight: 600;
+}
+
+.modalControls {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.zoomIndicator {
+ font-size: 12px;
+ color: var(--tech-text-secondary);
+ font-weight: 500;
+ min-width: 35px;
+ text-align: center;
+}
+
+.zoomButton {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 6px;
+ border-radius: 6px;
+ color: var(--tech-text-secondary);
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+}
+
+.zoomButton:hover:not(:disabled) {
+ background: rgba(9, 105, 218, 0.1);
+ color: var(--tech-primary-blue);
+ transform: scale(1.05);
+}
+
+.zoomButton:disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+}
+
+.zoomButton:focus:not(:disabled) {
+ outline: 2px solid var(--tech-primary-blue);
+ outline-offset: 2px;
+}
+
+.resetButton {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 6px;
+ border-radius: 6px;
+ color: var(--tech-text-secondary);
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+}
+
+.resetButton:hover {
+ background: rgba(156, 39, 176, 0.1);
+ color: var(--tech-accent-purple);
+ transform: scale(1.05);
+}
+
+.resetButton:focus {
+ outline: 2px solid var(--tech-primary-blue);
+ outline-offset: 2px;
+}
+
+.closeButton {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 6px;
+ border-radius: 6px;
+ color: var(--tech-text-secondary);
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+ margin-left: 4px;
+}
+
+.closeButton:hover {
+ background: rgba(244, 67, 54, 0.1);
+ color: #f44336;
+ transform: scale(1.1);
+}
+
+.closeButton:focus {
+ outline: 2px solid var(--tech-primary-blue);
+ outline-offset: 2px;
+}
+
+.modalBody {
+ padding: 24px;
+ overflow: auto;
+ flex: 1;
+ display: flex;
+ /* must be flex-start. */
+ align-items: flex-start;
+ justify-content: center;
+ min-height: 0;
+ background: var(--tech-surface-bg);
+}
+
+.diagramContainer {
+ transition: transform 0.3s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.diagramContainer .mermaid {
+ background: transparent !important;
+ border: none !important;
+ box-shadow: none !important;
+ max-width: none !important;
+ max-height: none !important;
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+/* Ensure Mermaid diagrams in modal are properly sized */
+.diagramContainer .mermaid svg {
+ max-width: none !important;
+ width: auto !important;
+ height: auto !important;
+ display: block !important;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes slideIn {
+ from {
+ opacity: 0;
+ transform: scale(0.9) translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ }
+}
+
+/* Dark theme support */
+[data-theme='dark'] .zoomHint {
+ background: rgba(88, 166, 255, 0.9);
+ box-shadow: 0 4px 12px rgba(88, 166, 255, 0.3);
+}
+
+[data-theme='dark'] .modal {
+ background: rgba(0, 0, 0, 0.95);
+}
+
+/* Override any potential Docusaurus container constraints */
+.modal {
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ right: 0 !important;
+ bottom: 0 !important;
+ width: 100vw !important;
+ height: 100vh !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ z-index: 99999 !important;
+}
+
+.modalContent {
+ position: relative !important;
+ margin: auto !important;
+}
+
+/* Mobile responsive */
+@media (max-width: 768px) {
+ .modal {
+ padding: 0;
+ width: 100vw;
+ height: 100vh;
+ }
+
+ .modalContent {
+ width: 95vw !important;
+ height: 90vh !important;
+ border-radius: 12px;
+ }
+
+ .modalHeader {
+ padding: 16px 20px 12px;
+ flex-shrink: 0;
+ }
+
+ .modalTitle {
+ font-size: 16px;
+ }
+
+ .modalBody {
+ padding: 16px;
+ flex: 1;
+ }
+
+ .zoomHint {
+ font-size: 11px;
+ padding: 4px 8px;
+ top: 8px;
+ right: 8px;
+ }
+
+ .closeButton,
+ .zoomButton,
+ .resetButton {
+ width: 28px;
+ height: 28px;
+ padding: 4px;
+ }
+
+ .modalControls {
+ gap: 6px;
+ }
+
+ .zoomIndicator {
+ font-size: 11px;
+ min-width: 30px;
+ }
+}
+
+/* High contrast mode support */
+@media (prefers-contrast: high) {
+ .mermaidContainer {
+ border-width: 2px;
+ }
+
+ .zoomHint {
+ background: #000;
+ color: #fff;
+ }
+
+ [data-theme='dark'] .zoomHint {
+ background: #fff;
+ color: #000;
+ }
+}
+
+/* Reduced motion support */
+@media (prefers-reduced-motion: reduce) {
+ .mermaidContainer,
+ .zoomHint,
+ .modal,
+ .modalContent,
+ .closeButton {
+ transition: none;
+ animation: none;
+ }
+
+ .modal {
+ animation: none;
+ }
+
+ .modalContent {
+ animation: none;
+ }
+}
\ No newline at end of file