feat(pitch-print): redesign Pricing slide as 3 distinct product cards
Build pitch-deck / build-push-deploy (push) Successful in 2m3s
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 42s
CI / test-python-voice (push) Successful in 35s
CI / test-bqas (push) Successful in 33s

The pricing slide previously rendered as a 4-column DataTable buried below
unit economics — the 3 tiers were hard to find. Rebuilt as the Claude Design
PREISE pattern: three prominent product cards side by side.

Each card:
- Mono tier label kicker (STARTER / PROFESSIONAL / ENTERPRISE) at top
- Target audience line ("<25 Mitarbeiter · Basis-Module" etc.)
- Hero price (€3.600 / €18.000 / ab €50.000) + /Jahr unit
- 4–5 feature checkmarks (green ✓)
- Tinted background per tier: violet-50 for Starter, white-gradient for
  featured Professional, amber-50 for Enterprise

Professional card carries:
- 2px violet border (vs 1px on others)
- Drop shadow
- "BELIEBT" / "POPULAR" pill badge floating above its top edge in violet

Below the 3 cards, a compact 2-col footer:
- left: 4 Unit Economics tiles (~70% gross margin, ~3.5× LTV/CAC, etc.)
- right: emerald net-effect callout (+€30k per SME / yr)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-05-20 12:54:31 +02:00
parent cb46372e52
commit d1b55cd65b
@@ -1,5 +1,5 @@
import { Language, PitchProduct } from '@/lib/types'
import { Page, Bullets, Callout, COLORS, DataTable, StatLine } from './PrintLayout'
import { Page, Bullets, Callout, COLORS, DataTable } from './PrintLayout'
import { LoopDiagram } from './PrintDiagrams'
import { getDetails } from '@/components/slides/USPSlide.data'
import {
@@ -350,59 +350,119 @@ export function PrintHowItWorksPage({ lang, pageNum, totalPages, versionName }:
export function PrintBusinessModelPage({ lang, pageNum, totalPages, versionName }: SlideBase) {
const de = lang === 'de'
const MONO = "'JetBrains Mono', ui-monospace, monospace"
const tiers = [
{
name: 'Starter',
target: de ? '< 25 Mitarbeiter · Basis-Module' : '< 25 employees · basic modules',
price: '€3.600',
unit: de ? '/ Jahr' : '/ year',
features: de
? ['DSGVO + Audit + DSR-Workflow', 'Compliance Scanner (CI/CD)', 'EU-Hosting · BSI C5', 'E-Mail-Support']
: ['GDPR + Audit + DSR workflow', 'Compliance Scanner (CI/CD)', 'EU hosting · BSI C5', 'Email support'],
tint: COLORS.violet400,
bg: COLORS.violet50,
featured: false,
},
{
name: 'Professional',
target: de ? '25250 Mitarbeiter · alle Module' : '25250 employees · all modules',
price: '€18.000',
unit: de ? '/ Jahr' : '/ year',
features: de
? ['Alle 12 Module', 'Priority-Support · Onboarding-Call', 'CE-Software-Risiko + Tender Matching', 'Dedicated CSM · 14-tägige Reviews', 'Custom-Integrationen (Jira, GitLab)']
: ['All 12 modules', 'Priority support · onboarding call', 'CE software risk + tender matching', 'Dedicated CSM · biweekly reviews', 'Custom integrations (Jira, GitLab)'],
tint: COLORS.violet600,
bg: `linear-gradient(180deg, ${COLORS.violet50} 0%, #ffffff 60%, ${COLORS.violet50} 100%)`,
featured: true,
},
{
name: 'Enterprise',
target: de ? '250+ Mitarbeiter · maßgeschneidert' : '250+ employees · custom',
price: de ? 'ab €50.000' : 'from €50k',
unit: de ? '/ Jahr' : '/ year',
features: de
? ['Alles aus Professional', 'SLA · Custom Contract', 'On-Premise / Air-Gap (Mac Mini/Studio)', 'Dedicated Customer Engineering', 'Multi-Region Audit-Trail']
: ['Everything in Professional', 'SLA · custom contract', 'On-premise / air-gap (Mac Mini/Studio)', 'Dedicated customer engineering', 'Multi-region audit trail'],
tint: COLORS.amber600,
bg: COLORS.amber50,
featured: false,
},
]
return (
<Page kicker="10" section={de ? 'PRICING & GESCHÄFTSMODELL' : 'PRICING & BUSINESS MODEL'} title={de ? 'Mitarbeiterbasiertes SaaS. Kunden sparen mehr als sie zahlen.' : 'Employee-based SaaS. Customers save more than they pay.'} subtitle={de ? 'Drei Tiers, transparent gepreist. Recurring Revenue. Optional Hardware. ROI ab Tag 1.' : 'Three tiers, transparently priced. Recurring revenue. Optional hardware. ROI from day 1.'} pageNum={pageNum} totalPages={totalPages} versionName={versionName}>
<Page kicker="10" section={de ? 'PREISE' : 'PRICING'} title={de ? 'Drei Tiers. Mitarbeiterbasiert. ROI ab Tag 1.' : 'Three tiers. Employee-based. ROI from day 1.'} subtitle={de ? 'Recurring Revenue · BSI-Cloud DE Standard · Optional Hardware. Kunden zahlen ~50k/Jahr und sparen €112k.' : 'Recurring revenue · BSI cloud DE standard · optional hardware. Customers pay ~€50k/yr and save €112k.'} pageNum={pageNum} totalPages={totalPages} versionName={versionName}>
<div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '8mm', flex: 1, minHeight: 0 }}>
<div>
<div style={{ fontSize: '8pt', fontWeight: 700, color: COLORS.slate500, textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: '2mm' }}>{de ? 'Pricing-Tiers' : 'Pricing tiers'}</div>
<DataTable
cols={[
{ header: 'Tier', width: '22%' },
{ header: de ? 'Zielkunde' : 'Target', width: '24%' },
{ header: de ? 'Module' : 'Modules' },
{ header: de ? 'Preis / Jahr' : 'Price / year', numeric: true, width: '20%' },
]}
rows={[
['Starter', de ? '<10 MA' : '<10 emp.', de ? 'Basis-Module (DSGVO, Audit, DSR)' : 'Basic modules (GDPR, audit, DSR)', '€3.600'],
['Professional', '10250 MA', de ? 'Alle Module + Priority Support' : 'All modules + priority support', '€15.000 €40.000'],
['Enterprise', '250+ MA', de ? 'Custom · SLA · Dedicated CSM' : 'Custom · SLA · dedicated CSM', de ? 'ab €50.000' : 'from €50,000'],
]}
highlightFirstCol
/>
{/* 3 product cards */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '5mm', marginBottom: '5mm', position: 'relative' }}>
{tiers.map((t) => (
<div key={t.name} style={{
background: t.bg,
border: `${t.featured ? '2px' : '1px'} solid ${t.tint}`,
borderRadius: '6pt',
padding: '5mm',
display: 'flex',
flexDirection: 'column',
position: 'relative',
boxShadow: t.featured ? `0 6px 18px ${COLORS.violet600}25` : 'none',
WebkitPrintColorAdjust: 'exact',
printColorAdjust: 'exact',
}}>
{/* Featured badge */}
{t.featured && (
<div style={{ position: 'absolute', top: '-3.5mm', left: '50%', transform: 'translateX(-50%)', fontFamily: MONO, fontSize: '7pt', fontWeight: 700, color: '#ffffff', background: COLORS.violet600, padding: '1mm 4mm', borderRadius: '99pt', textTransform: 'uppercase', letterSpacing: '0.18em', WebkitPrintColorAdjust: 'exact', printColorAdjust: 'exact' }}>{de ? 'Beliebt' : 'Popular'}</div>
)}
<div style={{ marginTop: '6mm' }}>
<div style={{ fontSize: '8pt', fontWeight: 700, color: COLORS.slate500, textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: '2mm' }}>{de ? 'Unit Economics (Reifephase)' : 'Unit Economics (mature)'}</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '4mm' }}>
{[
{ n: '~70%', l: de ? 'Bruttomarge' : 'Gross margin', tone: 'positive' as const },
{ n: '~3,5×', l: 'LTV / CAC', tone: 'positive' as const },
{ n: '~14m', l: de ? 'CAC-Payback' : 'CAC payback' },
{ n: '<8%', l: de ? 'Net Churn p.a.' : 'Net churn p.a.', tone: 'positive' as const },
].map((k, i) => (
<div key={i} style={{ border: `1px solid ${COLORS.slate200}`, padding: '3mm' }}>
<div style={{ fontSize: '20pt', fontWeight: 800, color: k.tone === 'positive' ? COLORS.emerald700 : COLORS.slate900, lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}>{k.n}</div>
<div style={{ fontSize: '7.5pt', color: COLORS.slate500, marginTop: '2mm', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 600 }}>{k.l}</div>
<div style={{ fontFamily: MONO, fontSize: '8pt', fontWeight: 700, color: t.tint, textTransform: 'uppercase', letterSpacing: '0.22em', marginBottom: '2mm' }}>{t.name}</div>
<div style={{ fontSize: '8.5pt', color: COLORS.slate600, marginBottom: '4mm', lineHeight: 1.4 }}>{t.target}</div>
{/* Price */}
<div style={{ display: 'flex', alignItems: 'baseline', gap: '2mm', marginBottom: '4mm' }}>
<div style={{ fontSize: '28pt', fontWeight: 800, color: COLORS.slate900, lineHeight: 1, fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.025em' }}>{t.price}</div>
<div style={{ fontSize: '9pt', color: COLORS.slate500, fontWeight: 500 }}>{t.unit}</div>
</div>
{/* Features */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5mm' }}>
{t.features.map((f, i) => (
<div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: '2mm' }}>
<span style={{ color: COLORS.emerald600, fontSize: '9pt', fontWeight: 700, marginTop: '0.5pt' }}></span>
<span style={{ fontSize: '8.5pt', color: COLORS.slate700, lineHeight: 1.4 }}>{f}</span>
</div>
))}
</div>
</div>
))}
</div>
{/* Unit economics + savings — bottom strip */}
<div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: '6mm', flex: 1, minHeight: 0 }}>
<div>
<div style={{ fontFamily: MONO, fontSize: '7.5pt', fontWeight: 700, color: COLORS.violet600, textTransform: 'uppercase', letterSpacing: '0.18em', marginBottom: '2mm' }}>{de ? 'Unit Economics · Reifephase' : 'Unit Economics · Mature'}</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '3mm' }}>
{[
{ n: '~70%', l: de ? 'Bruttomarge' : 'Gross margin', tone: 'positive' as const },
{ n: '~3,5×', l: 'LTV / CAC', tone: 'positive' as const },
{ n: '~14m', l: de ? 'CAC-Payback' : 'CAC payback' },
{ n: '<8%', l: de ? 'Net Churn p.a.' : 'Net churn p.a.', tone: 'positive' as const },
].map((k, i) => (
<div key={i} style={{ border: `1px solid ${COLORS.slate200}`, padding: '3mm', background: '#ffffff', WebkitPrintColorAdjust: 'exact', printColorAdjust: 'exact' }}>
<div style={{ fontSize: '18pt', fontWeight: 800, color: k.tone === 'positive' ? COLORS.emerald700 : COLORS.slate900, lineHeight: 1, fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.015em' }}>{k.n}</div>
<div style={{ fontFamily: MONO, fontSize: '6.5pt', color: COLORS.slate500, marginTop: '2mm', textTransform: 'uppercase', letterSpacing: '0.12em', fontWeight: 700 }}>{k.l}</div>
</div>
))}
</div>
</div>
<div>
<div style={{ fontSize: '8pt', fontWeight: 700, color: COLORS.slate500, textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: '2mm' }}>{de ? 'Kunde zahlt vs. spart · KMU 50 MA · Jahr 1' : 'Customer pays vs. saves · SME 50 emp. · Y1'}</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0' }}>
<StatLine label={de ? 'Kunde zahlt' : 'Customer pays'} value="€25.000" tone="accent" />
<StatLine label={de ? 'Spart: Pentests' : 'Saves: pentests'} value="€13.000" tone="positive" />
<StatLine label={de ? 'Spart: CE-Risiko' : 'Saves: CE risk'} value="€9.000" tone="positive" />
<StatLine label={de ? 'Spart: Compliance-Zeit' : 'Saves: compliance time'} value="€15.000" tone="positive" />
<StatLine label={de ? 'Spart: Audit-Vorber.' : 'Saves: audit prep'} value="€9.000" tone="positive" />
<StatLine label={de ? 'Spart: Sonstiges' : 'Saves: other'} value="€9.000" tone="positive" />
<div style={{ background: COLORS.emerald50, border: `1px solid ${COLORS.emerald600}`, borderRadius: '4pt', padding: '4mm 5mm', WebkitPrintColorAdjust: 'exact', printColorAdjust: 'exact' }}>
<div style={{ fontFamily: MONO, fontSize: '7pt', color: COLORS.emerald700, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.18em', marginBottom: '2mm' }}>{de ? 'Netto-Effekt · KMU 50 MA / Jahr 1' : 'Net effect · SME 50 emp. / Y1'}</div>
<div style={{ display: 'flex', alignItems: 'baseline', gap: '3mm' }}>
<div style={{ fontSize: '26pt', fontWeight: 800, color: COLORS.emerald700, lineHeight: 1, fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.02em' }}>+30k</div>
<div style={{ fontSize: '9pt', color: COLORS.emerald700, fontWeight: 600 }}>{de ? 'pro KMU / Jahr' : 'per SME / yr'}</div>
</div>
<div style={{ marginTop: '4mm', padding: '4mm', background: COLORS.emerald50, border: `1px solid ${COLORS.emerald600}`, WebkitPrintColorAdjust: 'exact', printColorAdjust: 'exact' }}>
<div style={{ fontSize: '7.5pt', color: COLORS.emerald700, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: '1.5mm' }}>{de ? 'Netto-Effekt Jahr 1' : 'Net effect year 1'}</div>
<div style={{ fontSize: '20pt', fontWeight: 800, color: COLORS.emerald700, lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}>+30.000</div>
<div style={{ fontSize: '8pt', color: COLORS.slate600, marginTop: '2mm', lineHeight: 1.4 }}>{de ? 'Kunde spart €55k, zahlt €25k. ROI ab Tag 1.' : 'Customer saves €55k, pays €25k. ROI from day 1.'}</div>
<div style={{ fontSize: '8pt', color: COLORS.slate700, marginTop: '2mm', lineHeight: 1.4 }}>
{de ? 'Kunde spart €55k (Pentests, CE-Risiko, Compliance-Zeit), zahlt €25k. ROI ab Tag 1.' : 'Customer saves €55k (pentests, CE risk, compliance time), pays €25k. ROI from day 1.'}
</div>
</div>
</div>