feat: Add staged funding model, financial compute engine, annex slides and UI enhancements
Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Restructure financial plan from single 200k SAFE to realistic staged funding (25k Stammkapital, 25k Angel, 200k Wandeldarlehen, 1M Series A = 1.25M total). Add 60-month compute engine with CAPEX/OPEX accounting, cash constraints, hardware financing (30% upfront / 70% leasing), and revenue-based hiring caps. Rebuild TheAskSlide with 4-event funding timeline, update i18n (DE/EN), chat agent core messages, and add 15 new annex/technology slides with supporting UI components (KPICard, RunwayGauge, WaterfallChart, etc.). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
133
pitch-deck/components/ui/RunwayGauge.tsx
Normal file
133
pitch-deck/components/ui/RunwayGauge.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
'use client'
|
||||
|
||||
import { motion } from 'framer-motion'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
interface RunwayGaugeProps {
|
||||
months: number
|
||||
maxMonths?: number
|
||||
size?: number
|
||||
label?: string
|
||||
}
|
||||
|
||||
export default function RunwayGauge({ months, maxMonths = 36, size = 140, label = 'Runway' }: RunwayGaugeProps) {
|
||||
const [animatedAngle, setAnimatedAngle] = useState(0)
|
||||
const clampedMonths = Math.min(months, maxMonths)
|
||||
const targetAngle = (clampedMonths / maxMonths) * 270 - 135 // -135 to +135 degrees
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setAnimatedAngle(targetAngle), 100)
|
||||
return () => clearTimeout(timer)
|
||||
}, [targetAngle])
|
||||
|
||||
// Color based on runway
|
||||
const getColor = () => {
|
||||
if (months >= 18) return '#22c55e' // green
|
||||
if (months >= 12) return '#eab308' // yellow
|
||||
if (months >= 6) return '#f97316' // orange
|
||||
return '#ef4444' // red
|
||||
}
|
||||
|
||||
const color = getColor()
|
||||
const cx = size / 2
|
||||
const cy = size / 2
|
||||
const radius = (size / 2) - 16
|
||||
const needleLength = radius - 10
|
||||
|
||||
// Arc path for gauge background
|
||||
const startAngle = -135
|
||||
const endAngle = 135
|
||||
const polarToCartesian = (cx: number, cy: number, r: number, deg: number) => {
|
||||
const rad = (deg - 90) * Math.PI / 180
|
||||
return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) }
|
||||
}
|
||||
|
||||
const arcStart = polarToCartesian(cx, cy, radius, startAngle)
|
||||
const arcEnd = polarToCartesian(cx, cy, radius, endAngle)
|
||||
const arcPath = `M ${arcStart.x} ${arcStart.y} A ${radius} ${radius} 0 1 1 ${arcEnd.x} ${arcEnd.y}`
|
||||
|
||||
// Filled arc
|
||||
const filledEnd = polarToCartesian(cx, cy, radius, Math.min(animatedAngle, endAngle))
|
||||
const largeArc = (animatedAngle - startAngle) > 180 ? 1 : 0
|
||||
const filledPath = `M ${arcStart.x} ${arcStart.y} A ${radius} ${radius} 0 ${largeArc} 1 ${filledEnd.x} ${filledEnd.y}`
|
||||
|
||||
// Needle endpoint
|
||||
const needleRad = (animatedAngle - 90) * Math.PI / 180
|
||||
const needleX = cx + needleLength * Math.cos(needleRad)
|
||||
const needleY = cy + needleLength * Math.sin(needleRad)
|
||||
|
||||
const shouldPulse = months < 6
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 }}
|
||||
className="flex flex-col items-center"
|
||||
>
|
||||
<div className={`relative ${shouldPulse ? 'animate-pulse' : ''}`} style={{ width: size, height: size * 0.8 }}>
|
||||
<svg width={size} height={size * 0.8} viewBox={`0 0 ${size} ${size * 0.8}`}>
|
||||
{/* Background arc */}
|
||||
<path d={arcPath} fill="none" stroke="rgba(255,255,255,0.1)" strokeWidth="8" strokeLinecap="round" />
|
||||
|
||||
{/* Filled arc */}
|
||||
<motion.path
|
||||
d={filledPath}
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeWidth="8"
|
||||
strokeLinecap="round"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 1.5, ease: 'easeOut' }}
|
||||
/>
|
||||
|
||||
{/* Tick marks */}
|
||||
{[0, 6, 12, 18, 24, 30, 36].map((tick) => {
|
||||
const tickAngle = (tick / maxMonths) * 270 - 135
|
||||
const inner = polarToCartesian(cx, cy, radius - 12, tickAngle)
|
||||
const outer = polarToCartesian(cx, cy, radius - 6, tickAngle)
|
||||
return (
|
||||
<g key={tick}>
|
||||
<line x1={inner.x} y1={inner.y} x2={outer.x} y2={outer.y} stroke="rgba(255,255,255,0.3)" strokeWidth="1.5" />
|
||||
<text
|
||||
x={polarToCartesian(cx, cy, radius - 22, tickAngle).x}
|
||||
y={polarToCartesian(cx, cy, radius - 22, tickAngle).y}
|
||||
fill="rgba(255,255,255,0.3)"
|
||||
fontSize="8"
|
||||
textAnchor="middle"
|
||||
dominantBaseline="central"
|
||||
>
|
||||
{tick}
|
||||
</text>
|
||||
</g>
|
||||
)
|
||||
})}
|
||||
|
||||
{/* Needle */}
|
||||
<motion.line
|
||||
x1={cx}
|
||||
y1={cy}
|
||||
x2={needleX}
|
||||
y2={needleY}
|
||||
stroke="white"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ delay: 0.5 }}
|
||||
/>
|
||||
|
||||
{/* Center circle */}
|
||||
<circle cx={cx} cy={cy} r="4" fill={color} />
|
||||
<circle cx={cx} cy={cy} r="2" fill="white" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className="text-center -mt-2">
|
||||
<p className="text-lg font-bold" style={{ color }}>{Math.round(months)}</p>
|
||||
<p className="text-[10px] text-white/40 uppercase tracking-wider">{label}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user