feat(pitch-deck): regulatory landscape based on real rag-documents.json
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m10s
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 32s
CI / test-python-voice (push) Successful in 36s
CI / test-bqas (push) Successful in 37s
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m10s
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 32s
CI / test-python-voice (push) Successful in 36s
CI / test-bqas (push) Successful in 37s
Complete rewrite of Slide 7: - 10 real VDMA/VDA/BDI industry sectors (was 11 mixed categories) - 7 key EU regulations as columns (DSGVO, AI Act, NIS2, CRA, Maschinenverordnung, Data Act, Batterieverordnung) - Actual document counts per industry (244 horizontal + sector-specific) - Last column: total applicable documents (not regulation count) - KPIs: 320 docs, 244 horizontal, 65 sector-specific, 10 sectors - Footer explains horizontal vs sector-specific logic - Subtitle: 320 Dokumente im RAG — 10 Industriesektoren Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,74 +6,105 @@ import GradientText from '../ui/GradientText'
|
||||
import FadeInView from '../ui/FadeInView'
|
||||
import GlassCard from '../ui/GlassCard'
|
||||
import KPICard from '../ui/KPICard'
|
||||
import {
|
||||
Shield, Lock, Brain, Globe, Package, Landmark, Heart, ShoppingCart,
|
||||
Activity, Cpu, Bot, Radio, Monitor, Building2, Cog
|
||||
} from 'lucide-react'
|
||||
|
||||
interface RegulatoryLandscapeSlideProps {
|
||||
lang: Language
|
||||
}
|
||||
|
||||
// Regulation categories with their color
|
||||
const CATEGORIES = [
|
||||
{ id: 'privacy', color: '#6366f1', icon: Shield },
|
||||
{ id: 'cyber', color: '#ef4444', icon: Lock },
|
||||
{ id: 'ai', color: '#a855f7', icon: Brain },
|
||||
{ id: 'markets', color: '#22c55e', icon: Globe },
|
||||
{ id: 'product', color: '#f97316', icon: Package },
|
||||
{ id: 'finance', color: '#10b981', icon: Landmark },
|
||||
{ id: 'health', color: '#ec4899', icon: Heart },
|
||||
{ id: 'consumer', color: '#f59e0b', icon: ShoppingCart },
|
||||
// Key EU regulations as columns — the ones investors care about
|
||||
const KEY_REGULATIONS = [
|
||||
{ id: 'GDPR', label: 'DSGVO', color: '#6366f1' },
|
||||
{ id: 'AI_ACT', label: 'AI Act', color: '#a855f7' },
|
||||
{ id: 'NIS2', label: 'NIS2', color: '#ef4444' },
|
||||
{ id: 'CRA', label: 'CRA', color: '#f97316' },
|
||||
{ id: 'MACHINERY_REG', label: 'Masch.-VO', color: '#22c55e' },
|
||||
{ id: 'DATA_ACT', label: 'Data Act', color: '#06b6d4' },
|
||||
{ id: 'BATTERIE_VO', label: 'Batt.-VO', color: '#f59e0b' },
|
||||
]
|
||||
|
||||
// Industry → which categories apply (synced with INDUSTRY_REGULATION_MAP in breakpilot-lehrer)
|
||||
const INDUSTRY_MATRIX: { id: string; icon: typeof Shield; categories: string[]; regCount: number }[] = [
|
||||
{ id: 'allIndustries', icon: Building2, categories: ['privacy'], regCount: 6 },
|
||||
{ id: 'maschinenbau', icon: Cog, categories: ['privacy', 'cyber', 'ai', 'product', 'consumer'], regCount: 15 },
|
||||
{ id: 'health', icon: Heart, categories: ['privacy', 'cyber', 'ai', 'product', 'health'], regCount: 12 },
|
||||
{ id: 'finance', icon: Landmark, categories: ['privacy', 'cyber', 'ai', 'markets', 'finance'], regCount: 15 },
|
||||
{ id: 'ecommerce', icon: ShoppingCart, categories: ['privacy', 'markets', 'product', 'finance', 'consumer'], regCount: 25 },
|
||||
{ id: 'tech', icon: Cpu, categories: ['privacy', 'cyber', 'ai', 'markets'], regCount: 14 },
|
||||
{ id: 'iot', icon: Activity, categories: ['privacy', 'cyber', 'ai', 'product', 'consumer'], regCount: 13 },
|
||||
{ id: 'ai', icon: Bot, categories: ['privacy', 'cyber', 'ai', 'product', 'markets'], regCount: 9 },
|
||||
{ id: 'kritis', icon: Lock, categories: ['privacy', 'cyber', 'ai', 'finance', 'markets'], regCount: 9 },
|
||||
{ id: 'media', icon: Monitor, categories: ['privacy', 'markets', 'ai'], regCount: 9 },
|
||||
{ id: 'public', icon: Radio, categories: ['privacy', 'cyber', 'ai', 'markets', 'health'], regCount: 10 },
|
||||
// 10 real VDMA/VDA/BDI industry sectors with regulation applicability
|
||||
// Based on rag-documents.json: 244 horizontal + 65 sector-specific = 320 total
|
||||
const INDUSTRIES: { id: string; de: string; en: string; regs: string[]; totalDocs: number }[] = [
|
||||
{
|
||||
id: 'automotive',
|
||||
de: 'Automobilindustrie',
|
||||
en: 'Automotive',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'MACHINERY_REG', 'DATA_ACT', 'BATTERIE_VO'],
|
||||
totalDocs: 263,
|
||||
},
|
||||
{
|
||||
id: 'maschinenbau',
|
||||
de: 'Maschinen- & Anlagenbau',
|
||||
en: 'Machinery & Plant Eng.',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'MACHINERY_REG', 'DATA_ACT'],
|
||||
totalDocs: 266,
|
||||
},
|
||||
{
|
||||
id: 'elektrotechnik',
|
||||
de: 'Elektro- & Digitalindustrie',
|
||||
en: 'Electrical & Digital',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'MACHINERY_REG', 'DATA_ACT', 'BATTERIE_VO'],
|
||||
totalDocs: 281,
|
||||
},
|
||||
{
|
||||
id: 'chemie',
|
||||
de: 'Chemie- & Prozessindustrie',
|
||||
en: 'Chemicals & Process',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'DATA_ACT'],
|
||||
totalDocs: 250,
|
||||
},
|
||||
{
|
||||
id: 'metall',
|
||||
de: 'Metallindustrie',
|
||||
en: 'Metal Industry',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'MACHINERY_REG', 'DATA_ACT'],
|
||||
totalDocs: 246,
|
||||
},
|
||||
{
|
||||
id: 'energie',
|
||||
de: 'Energie & Versorgung',
|
||||
en: 'Energy & Utilities',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'DATA_ACT', 'BATTERIE_VO'],
|
||||
totalDocs: 256,
|
||||
},
|
||||
{
|
||||
id: 'transport',
|
||||
de: 'Transport & Logistik',
|
||||
en: 'Transport & Logistics',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'DATA_ACT'],
|
||||
totalDocs: 256,
|
||||
},
|
||||
{
|
||||
id: 'handel',
|
||||
de: 'Handel',
|
||||
en: 'Retail & Commerce',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'DATA_ACT'],
|
||||
totalDocs: 271,
|
||||
},
|
||||
{
|
||||
id: 'konsumgueter',
|
||||
de: 'Konsumgüter & Lebensmittel',
|
||||
en: 'Consumer Goods & Food',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'DATA_ACT', 'BATTERIE_VO'],
|
||||
totalDocs: 265,
|
||||
},
|
||||
{
|
||||
id: 'bau',
|
||||
de: 'Bauwirtschaft',
|
||||
en: 'Construction',
|
||||
regs: ['GDPR', 'AI_ACT', 'NIS2', 'CRA', 'MACHINERY_REG', 'DATA_ACT'],
|
||||
totalDocs: 245,
|
||||
},
|
||||
]
|
||||
|
||||
export default function RegulatoryLandscapeSlide({ lang }: RegulatoryLandscapeSlideProps) {
|
||||
const i = t(lang)
|
||||
const rl = i.regulatoryLandscape
|
||||
|
||||
const categoryLabels: Record<string, string> = {
|
||||
privacy: rl.categoryPrivacy,
|
||||
cyber: rl.categoryCyber,
|
||||
ai: rl.categoryAI,
|
||||
markets: rl.categoryMarkets,
|
||||
product: rl.categoryProduct,
|
||||
finance: rl.categoryFinance,
|
||||
health: rl.categoryHealth,
|
||||
consumer: rl.categoryConsumer,
|
||||
}
|
||||
|
||||
const industryLabels: Record<string, string> = {
|
||||
allIndustries: rl.allIndustries,
|
||||
maschinenbau: rl.maschinenbau,
|
||||
health: rl.health,
|
||||
finance: rl.finance,
|
||||
ecommerce: rl.ecommerce,
|
||||
tech: rl.tech,
|
||||
iot: rl.iot,
|
||||
ai: rl.ai,
|
||||
kritis: rl.kritis,
|
||||
media: rl.media,
|
||||
public: rl.public,
|
||||
}
|
||||
const de = lang === 'de'
|
||||
|
||||
return (
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<FadeInView className="text-center mb-6">
|
||||
<FadeInView className="text-center mb-5">
|
||||
<h2 className="text-3xl md:text-5xl font-bold mb-2">
|
||||
<GradientText>{rl.title}</GradientText>
|
||||
</h2>
|
||||
@@ -81,42 +112,42 @@ export default function RegulatoryLandscapeSlide({ lang }: RegulatoryLandscapeSl
|
||||
</FadeInView>
|
||||
|
||||
{/* KPI Row */}
|
||||
<div className="grid grid-cols-3 gap-3 mb-6">
|
||||
<KPICard label={rl.controls} value={25000} suffix="+" color="#6366f1" delay={0.1} />
|
||||
<KPICard label={rl.regulations} value={110} color="#a78bfa" delay={0.2} />
|
||||
<KPICard label={rl.industries} value={10} color="#34d399" delay={0.4} />
|
||||
<div className="grid grid-cols-4 gap-3 mb-5">
|
||||
<KPICard label={de ? 'Dokumente im RAG' : 'Documents in RAG'} value={320} color="#6366f1" delay={0.1} />
|
||||
<KPICard label={de ? 'Horizontal (alle Branchen)' : 'Horizontal (all industries)'} value={244} color="#a78bfa" delay={0.2} />
|
||||
<KPICard label={de ? 'Sektorspezifisch' : 'Sector-specific'} value={65} color="#f97316" delay={0.3} />
|
||||
<KPICard label={de ? 'Industriesektoren' : 'Industry sectors'} value={10} color="#34d399" delay={0.4} />
|
||||
</div>
|
||||
|
||||
{/* Matrix */}
|
||||
<FadeInView delay={0.5}>
|
||||
<GlassCard hover={false} className="p-4 overflow-x-auto">
|
||||
{/* Matrix Grid */}
|
||||
<div className="space-y-1.5">
|
||||
{/* Staggered header rows — odd columns on top row, even on bottom */}
|
||||
<div className="grid items-end gap-1" style={{ gridTemplateColumns: '140px repeat(8, 1fr) 70px' }}>
|
||||
<div className="space-y-1">
|
||||
{/* Header rows — staggered for space */}
|
||||
<div className="grid items-end gap-1" style={{ gridTemplateColumns: '180px repeat(7, 1fr) 70px' }}>
|
||||
<div className="text-[9px] text-white/70 uppercase tracking-wider pl-1 font-semibold">
|
||||
{lang === 'de' ? 'Branche' : 'Industry'}
|
||||
{de ? 'Branche' : 'Industry'}
|
||||
</div>
|
||||
{CATEGORIES.map((cat, idx) => (
|
||||
<div key={cat.id} className="text-center">
|
||||
{KEY_REGULATIONS.map((reg, idx) => (
|
||||
<div key={reg.id} className="text-center">
|
||||
{idx % 2 === 0 ? (
|
||||
<span className="text-[8px] font-semibold uppercase tracking-wider" style={{ color: cat.color }}>
|
||||
{categoryLabels[cat.id]}
|
||||
<span className="text-[8px] font-semibold uppercase tracking-wider" style={{ color: reg.color }}>
|
||||
{reg.label}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
))}
|
||||
<div className="text-[8px] text-indigo-400 text-center font-semibold uppercase tracking-wider">
|
||||
{lang === 'de' ? 'Regulatorien' : 'Regulations'}
|
||||
{de ? 'Dokumente' : 'Documents'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid items-start gap-1" style={{ gridTemplateColumns: '140px repeat(8, 1fr) 70px' }}>
|
||||
<div className="grid items-start gap-1" style={{ gridTemplateColumns: '180px repeat(7, 1fr) 70px' }}>
|
||||
<div />
|
||||
{CATEGORIES.map((cat, idx) => (
|
||||
<div key={cat.id} className="text-center">
|
||||
{KEY_REGULATIONS.map((reg, idx) => (
|
||||
<div key={reg.id} className="text-center">
|
||||
{idx % 2 === 1 ? (
|
||||
<span className="text-[8px] font-semibold uppercase tracking-wider" style={{ color: cat.color }}>
|
||||
{categoryLabels[cat.id]}
|
||||
<span className="text-[8px] font-semibold uppercase tracking-wider" style={{ color: reg.color }}>
|
||||
{reg.label}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -125,43 +156,48 @@ export default function RegulatoryLandscapeSlide({ lang }: RegulatoryLandscapeSl
|
||||
</div>
|
||||
|
||||
{/* Industry rows */}
|
||||
{INDUSTRY_MATRIX.map((industry, idx) => {
|
||||
const Icon = industry.icon
|
||||
return (
|
||||
<div
|
||||
key={industry.id}
|
||||
className="grid items-center gap-1 py-1.5 rounded-lg hover:bg-white/[0.04] transition-colors"
|
||||
style={{ gridTemplateColumns: '140px repeat(8, 1fr) 70px' }}
|
||||
>
|
||||
<div className="flex items-center gap-2 pl-1">
|
||||
<Icon className="w-3.5 h-3.5 text-white/40" />
|
||||
<span className="text-[11px] text-white/70 font-medium truncate">
|
||||
{industryLabels[industry.id]}
|
||||
</span>
|
||||
</div>
|
||||
{CATEGORIES.map((cat) => {
|
||||
const applies = industry.categories.includes(cat.id)
|
||||
return (
|
||||
<div key={cat.id} className="flex justify-center">
|
||||
{applies ? (
|
||||
<div
|
||||
className="w-4 h-4 rounded-full flex items-center justify-center"
|
||||
style={{ backgroundColor: `${cat.color}20` }}
|
||||
>
|
||||
<div className="w-2 h-2 rounded-full" style={{ backgroundColor: cat.color }} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-4 h-4 rounded-full bg-white/[0.03]" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
<div className="text-center">
|
||||
<span className="text-xs font-bold text-white/80">{industry.regCount}</span>
|
||||
</div>
|
||||
{INDUSTRIES.map((industry) => (
|
||||
<div
|
||||
key={industry.id}
|
||||
className="grid items-center gap-1 py-1.5 rounded-lg hover:bg-white/[0.04] transition-colors"
|
||||
style={{ gridTemplateColumns: '180px repeat(7, 1fr) 70px' }}
|
||||
>
|
||||
<div className="flex items-center gap-2 pl-1">
|
||||
<span className="text-[11px] text-white/70 font-medium truncate">
|
||||
{de ? industry.de : industry.en}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{KEY_REGULATIONS.map((reg) => {
|
||||
const applies = industry.regs.includes(reg.id)
|
||||
return (
|
||||
<div key={reg.id} className="flex justify-center">
|
||||
{applies ? (
|
||||
<div
|
||||
className="w-4 h-4 rounded-full flex items-center justify-center"
|
||||
style={{ backgroundColor: `${reg.color}20` }}
|
||||
>
|
||||
<div className="w-2 h-2 rounded-full" style={{ backgroundColor: reg.color }} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-4 h-4 rounded-full bg-white/[0.03]" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
<div className="text-center">
|
||||
<span className="text-xs font-bold text-white/80">{industry.totalDocs}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Footer note */}
|
||||
<div className="pt-2 mt-1 border-t border-white/5">
|
||||
<p className="text-[9px] text-white/20 text-center">
|
||||
{de
|
||||
? '244 Dokumente gelten horizontal für alle Branchen (DSGVO, BDSG, AI Act, NIS2, CRA, BetrVG, HGB, ...). Sektorspezifische Regulierungen kommen hinzu.'
|
||||
: '244 documents apply horizontally to all industries (GDPR, BDSG, AI Act, NIS2, CRA, ...). Sector-specific regulations are added on top.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</FadeInView>
|
||||
|
||||
@@ -114,7 +114,7 @@ const translations = {
|
||||
},
|
||||
regulatoryLandscape: {
|
||||
title: 'Regulatorische Landschaft',
|
||||
subtitle: '110 Gesetze & Regularien, 10 Branchen — eine Plattform',
|
||||
subtitle: '320 Dokumente im RAG — 10 Industriesektoren — eine Plattform',
|
||||
documents: 'Originaldokumente',
|
||||
controls: 'Extrahierte Controls',
|
||||
regulations: 'Regularien',
|
||||
@@ -411,7 +411,7 @@ const translations = {
|
||||
},
|
||||
regulatoryLandscape: {
|
||||
title: 'Regulatory Landscape',
|
||||
subtitle: '110 laws & regulations, 10 industries — one platform',
|
||||
subtitle: '320 documents in RAG — 10 industry sectors — one platform',
|
||||
documents: 'Original Documents',
|
||||
controls: 'Extracted Controls',
|
||||
regulations: 'Regulations',
|
||||
|
||||
Reference in New Issue
Block a user