Files
breakpilot-core/pitch-deck/components/slides/CoverSlide.tsx
Benjamin Boenisch b7d21daa24
All checks were successful
CI / test-bqas (push) Successful in 32s
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 46s
CI / test-python-voice (push) Successful in 38s
feat: Add DevSecOps tools, Woodpecker proxy, Vault persistent storage, pitch-deck annex slides
- Install Gitleaks, Trivy, Grype, Syft, Semgrep, Bandit in backend-core Dockerfile
- Add Woodpecker SQLite proxy API (fallback without API token)
- Mount woodpecker_data volume read-only to backend-core
- Add backend proxy fallback in admin-core Woodpecker route
- Add Vault file-based persistent storage (config.hcl, init-vault.sh)
- Auto-init, unseal and root-token persistence for Vault
- Add 6 pitch-deck annex slides (Assumptions, Architecture, GTM, Regulatory, Engineering, AI Pipeline)
- Dynamic margin/amortization KPIs in BusinessModelSlide
- Market sources modal with citations in MarketSlide
- Redesign nginx landing page to 3-column layout (Lehrer/Compliance/Core)
- Extend MkDocs nav with Services and SDK documentation sections
- Add SDK Protection architecture doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:42:43 +01:00

119 lines
3.9 KiB
TypeScript

'use client'
import { motion } from 'framer-motion'
import { Language, PitchFunding } from '@/lib/types'
import { t } from '@/lib/i18n'
import { ArrowRight } from 'lucide-react'
import GradientText from '../ui/GradientText'
import BrandName from '../ui/BrandName'
interface CoverSlideProps {
lang: Language
onNext: () => void
funding?: PitchFunding
}
function formatRoundLabel(funding: PitchFunding | undefined): string {
if (!funding) return 'Pre-Seed'
// Extract a short round label from round_name
const name = funding.round_name || ''
if (name.toLowerCase().includes('seed')) return 'Pre-Seed'
if (name.toLowerCase().includes('series a')) return 'Series A'
return 'Pre-Seed'
}
function formatQuarter(dateStr: string | undefined): string {
if (!dateStr) return ''
try {
const d = new Date(dateStr)
const quarter = Math.ceil((d.getMonth() + 1) / 3)
return `Q${quarter} ${d.getFullYear()}`
} catch {
return ''
}
}
export default function CoverSlide({ lang, onNext, funding }: CoverSlideProps) {
const i = t(lang)
const roundLabel = formatRoundLabel(funding)
const quarter = formatQuarter(funding?.target_date)
const subtitle = quarter ? `${roundLabel} · ${quarter}` : roundLabel
return (
<div className="flex flex-col items-center justify-center text-center min-h-[70vh]">
{/* Logo / Brand */}
<motion.div
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
className="mb-8"
>
<div className="w-20 h-20 mx-auto mb-6 rounded-2xl bg-gradient-to-br from-indigo-500 to-purple-600
flex items-center justify-center shadow-lg shadow-indigo-500/30">
<svg width="40" height="40" viewBox="0 0 40 40" fill="none">
<path d="M8 12L20 6L32 12V28L20 34L8 28V12Z" stroke="white" strokeWidth="2" fill="none" />
<path d="M20 6V34" stroke="white" strokeWidth="1.5" opacity="0.5" />
<path d="M8 12L32 28" stroke="white" strokeWidth="1.5" opacity="0.3" />
<path d="M32 12L8 28" stroke="white" strokeWidth="1.5" opacity="0.3" />
<circle cx="20" cy="20" r="4" fill="white" opacity="0.8" />
</svg>
</div>
</motion.div>
{/* Company Name */}
<motion.h1
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.3 }}
className="text-5xl md:text-7xl font-bold mb-4 tracking-tight"
>
BreakPilot{' '}
<motion.span
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.5 }}
>
<BrandName className="text-5xl md:text-7xl font-bold" />
</motion.span>
</motion.h1>
{/* Tagline */}
<motion.p
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.8, delay: 0.6 }}
className="text-xl md:text-2xl text-white/60 mb-2 max-w-2xl"
>
{i.cover.tagline}
</motion.p>
{/* Subtitle — dynamisch aus Funding */}
<motion.p
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5, delay: 0.8 }}
className="text-sm text-white/30 font-mono tracking-wider mb-12"
>
{subtitle}
</motion.p>
{/* CTA */}
<motion.button
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 1.2 }}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={onNext}
className="group flex items-center gap-2 px-8 py-3 rounded-full
bg-indigo-500 hover:bg-indigo-600 transition-colors text-white font-medium
shadow-lg shadow-indigo-500/30"
>
{i.cover.cta}
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
</motion.button>
</div>
)
}