diff --git a/pitch-deck/components/slides/ArchitectureSlide.tsx b/pitch-deck/components/slides/ArchitectureSlide.tsx index 6c972ec..a14175a 100644 --- a/pitch-deck/components/slides/ArchitectureSlide.tsx +++ b/pitch-deck/components/slides/ArchitectureSlide.tsx @@ -39,30 +39,31 @@ interface ConnDef { from: NodeId to: NodeId type: ConnType - d: string // SVG path in viewBox "0 0 1100 420" — right-angle only + d: string // SVG path in viewBox "0 0 1100 480" — right-angle only revD?: string } // All right-angle paths — safe with preserveAspectRatio="none" + vectorEffect="non-scaling-stroke" +// viewBox: 0 0 1100 480 | app y=106 gateway y=240 inference y=384 const CONNS: ConnDef[] = [ { from: 'certifai', to: 'litellm', type: 'api', - d: 'M 195 105 L 195 158 L 522 158 L 522 210' }, + d: 'M 195 106 L 195 178 L 522 178 L 522 240' }, { from: 'complai', to: 'litellm', type: 'api', - d: 'M 550 105 L 550 210' }, + d: 'M 550 106 L 550 240' }, { from: 'scanner', to: 'litellm', type: 'api', - d: 'M 905 105 L 905 158 L 578 158 L 578 210' }, + d: 'M 905 106 L 905 178 L 578 178 L 578 240' }, { from: 'complai', to: 'scanner', type: 'mcp', - d: 'M 550 105 Q 727 52 905 105', - revD: 'M 905 105 Q 727 52 550 105' }, + d: 'M 550 106 Q 727 55 905 106', + revD: 'M 905 106 Q 727 55 550 106' }, { from: 'litellm', to: 'llm', type: 'api', - d: 'M 550 210 L 550 268 L 218 268 L 218 340' }, + d: 'M 550 240 L 550 308 L 218 308 L 218 384' }, { from: 'litellm', to: 'embeddings', type: 'embed', - d: 'M 550 210 L 550 340' }, + d: 'M 550 240 L 550 384' }, { from: 'litellm', to: 'tools', type: 'tool', - d: 'M 550 210 L 550 268 L 882 268 L 882 340' }, + d: 'M 550 240 L 550 308 L 882 308 L 882 384' }, ] -// cx = svgX/1100*100, cy = svgY/420*100 (exact match between SVG coords and CSS %) +// cx = svgX/1100*100, cy = svgY/480*100 (exact match between SVG coords and CSS %) function getNodes(de: boolean): NodeDef[] { return [ { @@ -71,7 +72,7 @@ function getNodes(de: boolean): NodeDef[] { subtitle: de ? 'GenAI Mandantenportal' : 'GenAI Tenant Portal', color: '#c084fc', twColor: 'text-purple-400', twBorder: 'border-purple-500/50', twBg: 'bg-purple-500/10', twDot: 'bg-purple-400', - cx: 17.7, cy: 25, tier: 'product', + cx: 17.7, cy: 22.1, tier: 'product', badge: 'Rust · Dioxus', tech: ['Rust', 'Dioxus', 'MongoDB', 'Keycloak', 'SearXNG', 'LangGraph'], services: [ @@ -87,7 +88,7 @@ function getNodes(de: boolean): NodeDef[] { subtitle: de ? 'Compliance & Audit' : 'Compliance & Audit', color: '#818cf8', twColor: 'text-indigo-400', twBorder: 'border-indigo-500/50', twBg: 'bg-indigo-500/10', twDot: 'bg-indigo-400', - cx: 50, cy: 25, tier: 'product', + cx: 50, cy: 22.1, tier: 'product', badge: 'Next.js · FastAPI', tech: ['Next.js 15', 'FastAPI', 'Go/Gin', 'PostgreSQL', 'Qdrant', 'Valkey'], services: [ @@ -103,7 +104,7 @@ function getNodes(de: boolean): NodeDef[] { subtitle: de ? 'Code-Sicherheit' : 'Code Security', color: '#34d399', twColor: 'text-emerald-400', twBorder: 'border-emerald-500/50', twBg: 'bg-emerald-500/10', twDot: 'bg-emerald-400', - cx: 82.3, cy: 25, tier: 'product', + cx: 82.3, cy: 22.1, tier: 'product', badge: 'Rust · Axum', tech: ['Rust', 'Axum', 'MongoDB', 'Semgrep', 'Gitleaks', 'Syft'], services: [ @@ -136,7 +137,7 @@ function getNodes(de: boolean): NodeDef[] { subtitle: de ? 'Lokale Sprachmodelle' : 'Local Language Models', color: '#60a5fa', twColor: 'text-blue-400', twBorder: 'border-blue-500/50', twBg: 'bg-blue-500/10', twDot: 'bg-blue-400', - cx: 17.7, cy: 81, tier: 'inference', + cx: 17.7, cy: 80, tier: 'inference', badge: 'On-Premise · BSI', tech: ['Qwen3-32B', 'Qwen3-Coder-30B', 'DeepSeek-R1-8B', 'Ollama'], services: [ @@ -151,7 +152,7 @@ function getNodes(de: boolean): NodeDef[] { subtitle: de ? 'Semantische Suche' : 'Semantic Search', color: '#a78bfa', twColor: 'text-violet-400', twBorder: 'border-violet-500/50', twBg: 'bg-violet-500/10', twDot: 'bg-violet-400', - cx: 50, cy: 81, tier: 'inference', + cx: 50, cy: 80, tier: 'inference', badge: de ? 'EU-Souverän' : 'EU Sovereign', tech: ['bge-m3', 'Qdrant Vector DB', 'Sentence-Transformers'], services: [ @@ -166,7 +167,7 @@ function getNodes(de: boolean): NodeDef[] { subtitle: de ? 'Web-Suche & MCP' : 'Web Search & MCP', color: '#2dd4bf', twColor: 'text-teal-400', twBorder: 'border-teal-500/50', twBg: 'bg-teal-500/10', twDot: 'bg-teal-400', - cx: 82.3, cy: 81, tier: 'inference', + cx: 82.3, cy: 80, tier: 'inference', badge: de ? 'EU-Souverän' : 'EU Sovereign', tech: ['SearXNG', 'MCP Protocol', 'Semgrep API', 'Gitleaks API'], services: [ @@ -377,10 +378,10 @@ export default function ArchitectureSlide({ lang }: ArchitectureSlideProps) { ? ['Mandant A', 'Mandant B', 'Mandant C', 'Mandant N…'] : ['Namespace A', 'Namespace B', 'Namespace C', 'Namespace N…'] - // Tier separator positions (% of 420px container height) - // App: 0–38.1% (y=0–160), Gateway: 38.1–64.3% (y=160–270), Inference: 64.3–100% - const SEP1 = '38.1%' - const SEP2 = '64.3%' + // Tier separator positions (% of 480px container height) + // App: 0–36% (y=0–173), Gateway: 36–65% (y=173–312), Inference: 65–100% + const SEP1 = '36%' + const SEP2 = '65%' return (
@@ -410,11 +411,10 @@ export default function ArchitectureSlide({ lang }: ArchitectureSlideProps) { {tn} ))} -
{/* ── METRO MAP ──────────────────────────────────────────────── */} -
+
{/* Background */}
+ style={{ top: SEP1, height: '29%', background: 'rgba(251,191,36,0.032)' }} />
@@ -451,7 +451,7 @@ export default function ArchitectureSlide({ lang }: ArchitectureSlideProps) { {de ? 'ANWENDUNG' : 'APP LAYER'}
-
+
GATEWAY @@ -468,7 +468,7 @@ export default function ArchitectureSlide({ lang }: ArchitectureSlideProps) { {/* BSI badges — right strip */}
-
+
BSI DC @@ -494,40 +494,40 @@ export default function ArchitectureSlide({ lang }: ArchitectureSlideProps) { {/* ── SVG: metro tracks + animated data flows ── */} + viewBox="0 0 1100 480" preserveAspectRatio="none"> - {/* Horizontal metro line — Application layer (y=105) */} - {/* Station tick marks on app line */} {[195, 550, 905].map(x => ( - ))} - {/* Horizontal metro line — Inference layer (y=340) */} - {/* Station tick marks on inference line */} {[195, 550, 905].map(x => ( - ))} {/* Gateway stub lines (short horizontal stubs from hub) */} - {/* Junction corner dots */} {[ - { cx: 195, cy: 158 }, { cx: 522, cy: 158 }, - { cx: 905, cy: 158 }, { cx: 578, cy: 158 }, - { cx: 218, cy: 268 }, { cx: 550, cy: 268 }, { cx: 882, cy: 268 }, + { cx: 195, cy: 178 }, { cx: 522, cy: 178 }, + { cx: 905, cy: 178 }, { cx: 578, cy: 178 }, + { cx: 218, cy: 308 }, { cx: 550, cy: 308 }, { cx: 882, cy: 308 }, ].map(({ cx, cy }) => (