fix(pitch-deck): resolve merge conflict in AIPipelineSlide — keep updated version
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m0s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 34s
CI / test-python-voice (push) Successful in 30s
CI / test-bqas (push) Successful in 31s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-14 17:42:13 +02:00
10 changed files with 166 additions and 147 deletions

View File

@@ -18,7 +18,6 @@ import {
Activity,
Shield,
Cpu,
MessageSquare,
Eye,
Gauge,
Network,

View File

@@ -277,7 +277,7 @@ const PRICING_COMPARISON: CompetitorPricing[] = [
{
name: 'ComplAI',
flag: '🇩🇪',
model: 'Cloud (BSI DE / OVH FR)',
model: 'Cloud (BSI DE / FR)',
publicPricing: true,
tiers: [
{ name: { de: 'Startup/<10', en: 'Startup/<10' }, price: 'ab €300/mo', annual: 'ab €3.600/yr', notes: { de: '14-Tage-Test, Kreditkarte', en: '14-day trial, credit card' } },

View File

@@ -38,8 +38,8 @@ export default function EngineeringSlide({ lang }: EngineeringSlideProps) {
},
{
value: '10',
label: de ? 'Docker Container' : 'Docker Containers',
sub: de ? 'Coolify → Hetzner (amd64)' : 'Coolify → Hetzner (amd64)',
label: de ? 'Services' : 'Services',
sub: de ? 'orca → Hetzner (amd64)' : 'orca → Hetzner (amd64)',
color: 'text-emerald-400',
borderColor: 'border-emerald-500/30',
},
@@ -51,9 +51,9 @@ export default function EngineeringSlide({ lang }: EngineeringSlideProps) {
borderColor: 'border-purple-500/30',
},
{
value: '14',
label: 'Dockerfiles',
sub: de ? 'Vollstaendig containerisiert' : 'Fully containerized',
value: '5',
label: de ? 'Infra-Komponenten' : 'Infra Components',
sub: 'orca (Rust) · infisical · pg · qdrant',
color: 'text-amber-400',
borderColor: 'border-amber-500/30',
},
@@ -69,17 +69,17 @@ export default function EngineeringSlide({ lang }: EngineeringSlideProps) {
{
icon: GitBranch,
label: 'Gitea + Actions',
desc: de ? 'Self-hosted Git + CI/CD · Lint → Tests → Validierung' : 'Self-hosted Git + CI/CD · Lint → Tests → Validation',
desc: de ? 'Self-hosted Git + CI/CD · Lint → Tests → Image-Build' : 'Self-hosted Git + CI/CD · Lint → Tests → Image build',
},
{
icon: Workflow,
label: 'Coolify',
desc: de ? 'Auto-Deploy bei Push · Docker Compose auf Hetzner · Health Checks' : 'Auto-deploy on push · Docker Compose on Hetzner · Health checks',
label: 'orca',
desc: de ? 'Single-Binary Orchestrator (Rust) · Webhook-Deploy · Auto-TLS · Raft' : 'Single-binary orchestrator (Rust) · Webhook deploys · Auto-TLS · Raft',
},
{
icon: Container,
label: 'Docker Compose',
desc: de ? 'arm64 → amd64 Build-Pipeline · Multi-Stage Builds' : 'arm64 → amd64 build pipeline · Multi-stage builds',
label: 'Private Registry',
desc: de ? 'registry.meghsakha.com · Signed Images · Tag pro Commit (:SHA + :latest)' : 'registry.meghsakha.com · Signed images · Per-commit tags (:SHA + :latest)',
},
{
icon: ShieldCheck,
@@ -88,13 +88,13 @@ export default function EngineeringSlide({ lang }: EngineeringSlideProps) {
},
{
icon: Database,
label: 'HashiCorp Vault',
desc: de ? 'Secrets Management · Auto-Rotation · PKI' : 'Secrets Management · Auto-Rotation · PKI',
label: 'Infisical',
desc: de ? 'Secrets Management · Rotation · RBAC · End-to-End verschlüsselt' : 'Secrets Management · Rotation · RBAC · End-to-end encrypted',
},
{
icon: Server,
label: de ? 'EU-Cloud Infrastruktur' : 'EU Cloud Infrastructure',
desc: de ? 'Hetzner · SysEleven (BSI) · OVH · PostgreSQL · Qdrant' : 'Hetzner · SysEleven (BSI) · OVH · PostgreSQL · Qdrant',
desc: de ? 'Hetzner · SysEleven (BSI) · PostgreSQL · Qdrant' : 'Hetzner · SysEleven (BSI) · PostgreSQL · Qdrant',
},
]
@@ -120,8 +120,8 @@ export default function EngineeringSlide({ lang }: EngineeringSlideProps) {
color: 'text-emerald-400',
dotColor: 'bg-emerald-400',
services: de
? ['PostgreSQL 17 (Hetzner)', 'Qdrant Vector DB', 'DSMS/IPFS Node + Gateway', 'MinIO Object Storage']
: ['PostgreSQL 17 (Hetzner)', 'Qdrant Vector DB', 'DSMS/IPFS Node + Gateway', 'MinIO Object Storage'],
? ['orca (Rust) Orchestrator', 'Infisical Secrets', 'PostgreSQL 17 (Hetzner)', 'Qdrant Vector DB', 'DSMS/IPFS Node + Gateway', 'Private Registry']
: ['orca (Rust) Orchestrator', 'Infisical Secrets', 'PostgreSQL 17 (Hetzner)', 'Qdrant Vector DB', 'DSMS/IPFS Node + Gateway', 'Private Registry'],
},
]
@@ -261,8 +261,8 @@ export default function EngineeringSlide({ lang }: EngineeringSlideProps) {
<div className="mt-3 pt-3 border-t border-white/5">
<p className="text-[10px] text-white/20 text-center">
{de
? '100% EU-Cloud · Hetzner + SysEleven (BSI) + OVH · Keine US-Anbieter · Volle Datenkontrolle'
: '100% EU Cloud · Hetzner + SysEleven (BSI) + OVH · No US Providers · Full Data Control'}
? '100% EU-Cloud · Hetzner + SysEleven (BSI) · Keine US-Anbieter · Volle Datenkontrolle'
: '100% EU Cloud · Hetzner + SysEleven (BSI) · No US Providers · Full Data Control'}
</p>
</div>
</GlassCard>

View File

@@ -179,7 +179,7 @@ export default function ExecutiveSummarySlide({ lang, data }: ExecutiveSummarySl
<li><strong>SAST + DAST + SBOM</strong> ${de ? '\\u2014 Vollumf\\u00e4ngliche Sicherheitstests bei jeder Code-\\u00c4nderung' : '\\u2014 Full security testing on every code change'}</li>
<li><strong>${de ? 'KI-gest\\u00fctztes Pentesting' : 'AI-powered Pentesting'}</strong> ${de ? '\\u2014 Kontinuierlich statt einmal im Jahr' : '\\u2014 Continuous instead of once a year'}</li>
<li><strong>CE-Software-Risikobeurteilung</strong> ${de ? '\\u2014 F\\u00fcr Maschinenverordnung und Produktsicherheit' : '\\u2014 For Machinery Regulation and product safety'}</li>
<li><strong>Jira-Integration</strong> ${de ? '\\u2014 Findings als Tickets mit Implementierungsvorschl\\u00e4gen' : '\\u2014 Findings as tickets with implementation suggestions'}</li>
<li><strong>Issue-Tracker-Integration</strong> ${de ? '\\u2014 Findings als Tickets mit Implementierungsvorschl\\u00e4gen' : '\\u2014 Findings as tickets with implementation suggestions'}</li>
<li><strong>Audit-Trail</strong> ${de ? '\\u2014 L\\u00fcckenloser Nachweis von Erkennung bis Behebung' : '\\u2014 Complete evidence from detection to remediation'}</li>
</ul>
</div>
@@ -191,7 +191,7 @@ export default function ExecutiveSummarySlide({ lang, data }: ExecutiveSummarySl
<li><strong>Audit Manager</strong> ${de ? '\\u2014 Abweichungen End-to-End: Rollen, Stichtage, Eskalation' : '\\u2014 Deviations end-to-end: roles, deadlines, escalation'}</li>
<li><strong>Compliance LLM</strong> ${de ? '\\u2014 GPT f\\u00fcr Text und Audio, sicher in der EU gehostet' : '\\u2014 GPT for text and audio, securely hosted in EU'}</li>
<li><strong>Academy</strong> ${de ? '\\u2014 Online-Schulungen f\\u00fcr GF und Mitarbeiter' : '\\u2014 Online training for management and employees'}</li>
<li><strong>${de ? 'BSI-Cloud DE / OVH FR' : 'BSI Cloud DE / OVH FR'}</strong> ${de ? '\\u2014 Keine US-SaaS, Jitsi, Matrix, volle Integration' : '\\u2014 No US SaaS, Jitsi, Matrix, full integration'}</li>
<li><strong>${de ? 'BSI-Cloud DE / FR' : 'BSI Cloud DE / FR'}</strong> ${de ? '\\u2014 Keine US-SaaS, Jitsi, Matrix, volle Integration' : '\\u2014 No US SaaS, Jitsi, Matrix, full integration'}</li>
</ul>
</div>
</div>
@@ -208,7 +208,7 @@ export default function ExecutiveSummarySlide({ lang, data }: ExecutiveSummarySl
<div class="card bottom-card">
<div class="section-title">${de ? 'Gesch\\u00e4ftsmodell' : 'Business Model'}</div>
<ul>
<li><strong>SaaS Cloud</strong> ${de ? '\\u2014 BSI DE / OVH FR, mitarbeiterbasiert' : '\\u2014 BSI DE / OVH FR, employee-based'}</li>
<li><strong>SaaS Cloud</strong> ${de ? '\\u2014 BSI DE / FR, mitarbeiterbasiert' : '\\u2014 BSI DE / FR, employee-based'}</li>
<li><strong>${de ? 'Modular w\\u00e4hlbar' : 'Modular choice'}</strong> ${de ? '\\u2014 Einzelne Module oder Full Compliance' : '\\u2014 Single modules or full compliance'}</li>
<li><strong>${de ? 'ROI ab Tag 1' : 'ROI from day 1'}</strong> ${de ? '\\u2014 Kunde spart 50.000+ EUR/Jahr' : '\\u2014 Customer saves EUR 50,000+/year'}</li>
</ul>
@@ -416,7 +416,7 @@ export default function ExecutiveSummarySlide({ lang, data }: ExecutiveSummarySl
de ? 'Audit Manager — Abweichungen End-to-End mit Eskalation' : 'Audit Manager — deviations end-to-end with escalation',
de ? 'Compliance LLM — GPT für Text und Audio, EU-gehostet' : 'Compliance LLM — GPT for text and audio, EU-hosted',
de ? 'Academy — Online-Schulungen für GF und Mitarbeiter' : 'Academy — online training for management and employees',
de ? 'BSI-Cloud DE / OVH FR' : 'BSI Cloud DE / OVH FR',
de ? 'BSI-Cloud DE / FR' : 'BSI Cloud DE / FR',
].map((item, idx) => (
<p key={idx} className="text-xs text-white/60 pl-3 relative">
<span className="absolute left-0 top-1 w-1.5 h-1.5 rounded-full bg-cyan-400/60" />

View File

@@ -109,7 +109,7 @@ export default function ProductSlide({ lang }: ProductSlideProps) {
<p className="text-[10px] text-white/50 leading-relaxed">{i.product.cloudDesc}</p>
<div className="flex gap-2 mt-2">
<span className="text-[9px] bg-blue-500/15 text-blue-300 px-2 py-0.5 rounded-full">BSI DE</span>
<span className="text-[9px] bg-blue-500/15 text-blue-300 px-2 py-0.5 rounded-full">OVH FR</span>
<span className="text-[9px] bg-blue-500/15 text-blue-300 px-2 py-0.5 rounded-full">FR</span>
<span className="text-[9px] bg-blue-500/15 text-blue-300 px-2 py-0.5 rounded-full">{de ? 'Fix oder flexibel' : 'Fixed or flexible'}</span>
</div>
</div>

View File

@@ -3,7 +3,7 @@
import { motion } from 'framer-motion'
import { Language, PitchTeamMember } from '@/lib/types'
import { t } from '@/lib/i18n'
import { User, Linkedin } from 'lucide-react'
import { User, Linkedin, Github } from 'lucide-react'
import GradientText from '../ui/GradientText'
import FadeInView from '../ui/FadeInView'
import Image from 'next/image'
@@ -13,89 +13,109 @@ interface TeamSlideProps {
team: PitchTeamMember[]
}
function equityDisplay(pct: number | string | null | undefined): string {
const n = Number(pct)
if (!Number.isFinite(n)) return '—'
return Number.isInteger(n) ? `${n}%` : `${n.toFixed(1)}%`
}
function detectProfileLink(url: string | null | undefined): { icon: typeof Linkedin | typeof Github; label: string } | null {
if (!url) return null
if (url.includes('github.com')) return { icon: Github, label: 'GitHub' }
if (url.includes('linkedin.com')) return { icon: Linkedin, label: 'LinkedIn' }
return { icon: Linkedin, label: 'Profile' }
}
export default function TeamSlide({ lang, team }: TeamSlideProps) {
const i = t(lang)
return (
<div>
<FadeInView className="text-center mb-12">
<FadeInView className="text-center mb-8">
<h2 className="text-4xl md:text-5xl font-bold mb-3">
<GradientText>{i.team.title}</GradientText>
</h2>
<p className="text-lg text-white/50 max-w-2xl mx-auto">{i.team.subtitle}</p>
</FadeInView>
<div className="grid md:grid-cols-2 gap-8 max-w-4xl mx-auto">
{team.map((member, idx) => (
<motion.div
key={member.id}
initial={{ opacity: 0, x: idx === 0 ? -40 : 40 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.3 + idx * 0.2, duration: 0.6 }}
className="bg-white/[0.08] backdrop-blur-xl border border-white/10 rounded-3xl p-8"
>
<div className="flex items-start gap-5">
{/* Avatar — Foto oder Fallback */}
{member.photo_url ? (
<div className="w-20 h-20 rounded-2xl overflow-hidden shrink-0 shadow-lg">
<Image
src={member.photo_url}
alt={member.name}
width={80}
height={80}
className="w-full h-full object-cover"
/>
</div>
) : (
<div className="w-20 h-20 rounded-2xl bg-gradient-to-br from-indigo-500 to-purple-600
flex items-center justify-center shrink-0 shadow-lg">
<User className="w-10 h-10 text-white" />
</div>
)}
<div className="grid md:grid-cols-2 gap-6 max-w-5xl mx-auto items-stretch">
{team.map((member, idx) => {
const link = detectProfileLink(member.linkedin_url)
const LinkIcon = link?.icon
return (
<motion.div
key={member.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 + idx * 0.15, duration: 0.5 }}
className="bg-white/[0.04] backdrop-blur-xl border border-white/[0.08] rounded-2xl p-6 flex flex-col hover:border-indigo-500/20 transition-colors"
>
{/* Header: avatar + name + role */}
<div className="flex items-center gap-4 mb-5">
{member.photo_url ? (
<div className="w-16 h-16 rounded-2xl overflow-hidden shrink-0 shadow-lg">
<Image
src={member.photo_url}
alt={member.name}
width={64}
height={64}
className="w-full h-full object-cover"
/>
</div>
) : (
<div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center shrink-0 shadow-lg shadow-indigo-500/20">
<User className="w-8 h-8 text-white" />
</div>
)}
<div className="flex-1">
<div className="flex items-center gap-2 mb-1">
<h3 className="text-xl font-bold text-white">{member.name}</h3>
{member.linkedin_url && (
<a
href={member.linkedin_url}
target="_blank"
rel="noopener noreferrer"
className="p-1 text-white/30 hover:text-[#0A66C2] transition-colors"
title="LinkedIn"
>
<Linkedin className="w-4 h-4" />
</a>
)}
</div>
<p className="text-indigo-400 text-sm font-medium mb-3">
{lang === 'de' ? member.role_de : member.role_en}
</p>
<p className="text-sm text-white/50 leading-relaxed mb-4">
{lang === 'de' ? member.bio_de : member.bio_en}
</p>
{/* Equity */}
<div className="flex items-center gap-2 mb-3">
<span className="text-xs text-white/40">{i.team.equity}:</span>
<span className="text-sm font-bold text-white">{member.equity_pct}%</span>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2 mb-0.5 flex-wrap">
<h3 className="text-xl font-bold text-white truncate">{member.name}</h3>
{link && LinkIcon && (
<a
href={member.linkedin_url!}
target="_blank"
rel="noopener noreferrer"
className="text-white/30 hover:text-indigo-300 transition-colors"
title={link.label}
>
<LinkIcon className="w-4 h-4" />
</a>
)}
</div>
<p className="text-indigo-400 text-sm font-medium">
{lang === 'de' ? member.role_de : member.role_en}
</p>
</div>
{/* Expertise Tags */}
<div className="flex flex-wrap gap-1.5">
{/* Equity pill in top-right */}
<div className="text-right shrink-0">
<div className="text-[10px] uppercase tracking-wider text-white/30">{i.team.equity}</div>
<div className="text-base font-bold text-white tabular-nums">{equityDisplay(member.equity_pct)}</div>
</div>
</div>
{/* Bio */}
<p className="text-sm text-white/60 leading-relaxed mb-5 flex-1">
{lang === 'de' ? member.bio_de : member.bio_en}
</p>
{/* Expertise tags */}
{(member.expertise || []).length > 0 && (
<div className="flex flex-wrap gap-1.5 pt-4 border-t border-white/[0.06]">
{(member.expertise || []).map((skill, sidx) => (
<span
key={sidx}
className="text-xs px-2.5 py-1 rounded-full bg-indigo-500/10 text-indigo-300 border border-indigo-500/20"
className="text-[11px] px-2.5 py-1 rounded-full bg-indigo-500/10 text-indigo-300 border border-indigo-500/20"
>
{skill}
</span>
))}
</div>
</div>
</div>
</motion.div>
))}
)}
</motion.div>
)
})}
</div>
</div>
)