Sessions 5-7a: 955 tests, deployment ready
This commit is contained in:
+151
-83
@@ -1,120 +1,188 @@
|
||||
const tiers = [
|
||||
'use client';
|
||||
|
||||
const TIERS = [
|
||||
{
|
||||
id: 'free',
|
||||
name: 'Free',
|
||||
price: '$0',
|
||||
founderPrice: null,
|
||||
period: '',
|
||||
cta: 'Get Started',
|
||||
cadence: '/mo',
|
||||
headline: 'Try the model. No card required.',
|
||||
cta: 'Start Free',
|
||||
ctaHref: '/signup',
|
||||
highlight: false,
|
||||
features: [
|
||||
'5 scans per month',
|
||||
'View line movements',
|
||||
'Basic prop grades',
|
||||
'5 reads per month',
|
||||
'Grade letter + projection',
|
||||
'Cross-book line comparison',
|
||||
'Confidence indicator',
|
||||
],
|
||||
unavailable: ['Bet tracking', 'Cascade alerts', 'Performance analytics'],
|
||||
locked: [
|
||||
'Factor analysis (blurred)',
|
||||
'Kill conditions (blurred)',
|
||||
'Alt line ladder (locked)',
|
||||
],
|
||||
highlight: false,
|
||||
},
|
||||
{
|
||||
id: 'analyst',
|
||||
name: 'Analyst',
|
||||
price: '$19.99',
|
||||
founderPrice: '$14.99',
|
||||
period: '/mo',
|
||||
cta: 'Subscribe',
|
||||
ctaHref: '/api/stripe/checkout?tier=analyst',
|
||||
highlight: true,
|
||||
price: '$14.99',
|
||||
originalPrice: '$24.99',
|
||||
cadence: '/mo',
|
||||
badge: 'Founder Access',
|
||||
headline: 'The full intelligence layer.',
|
||||
cta: 'Lock Founder Price',
|
||||
ctaHref: '/api/checkout?tier=analyst',
|
||||
features: [
|
||||
'Unlimited scans',
|
||||
'Line movement alerts',
|
||||
'Bet tracking',
|
||||
'Cascade alerts',
|
||||
'Basic performance analytics',
|
||||
'Unlimited reads',
|
||||
'Full factor analysis (40+ signals)',
|
||||
'Kill conditions surfaced inline',
|
||||
'Cascade alerts when lineups shift',
|
||||
'Parlay leg history with grades',
|
||||
'Sportsbook deep links',
|
||||
],
|
||||
unavailable: ['Priority alerts', 'Behavioral patterns'],
|
||||
locked: [
|
||||
'Alt line ladder (Desk only)',
|
||||
'Kelly sizing (Desk only)',
|
||||
],
|
||||
highlight: true,
|
||||
},
|
||||
{
|
||||
id: 'desk',
|
||||
name: 'Desk',
|
||||
price: '$49.99',
|
||||
founderPrice: '$34.99',
|
||||
period: '/mo',
|
||||
cta: 'Subscribe',
|
||||
ctaHref: '/api/stripe/checkout?tier=desk',
|
||||
highlight: false,
|
||||
price: '$44.99',
|
||||
originalPrice: '$49.99',
|
||||
cadence: '/mo',
|
||||
headline: 'Everything. The professional setup.',
|
||||
cta: 'Go Desk',
|
||||
ctaHref: '/api/checkout?tier=desk',
|
||||
features: [
|
||||
'Unlimited scans',
|
||||
'Line movement + priority alerts',
|
||||
'Full bet tracking',
|
||||
'Priority cascade alerts',
|
||||
'Full performance analytics',
|
||||
'Behavioral pattern insights',
|
||||
'Everything in Analyst',
|
||||
'Alt line ladder + edge ranking',
|
||||
'Quarter-Kelly sizing recommendations',
|
||||
'Real-time intelligence feed',
|
||||
'Parlay correlation analysis (phi)',
|
||||
'Consensus vs model comparison',
|
||||
'API access (coming Q3)',
|
||||
],
|
||||
unavailable: [],
|
||||
locked: [],
|
||||
highlight: false,
|
||||
},
|
||||
];
|
||||
|
||||
export default function Pricing() {
|
||||
return (
|
||||
<section className="py-24 px-4" id="pricing">
|
||||
<div className="max-w-5xl mx-auto">
|
||||
<h2 className="text-3xl font-bold text-center mb-4">Simple Pricing</h2>
|
||||
<p className="text-[var(--text-muted)] text-center mb-16">Start free. Upgrade when you're ready.</p>
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
{tiers.map((tier) => (
|
||||
<div
|
||||
key={tier.name}
|
||||
className={`relative p-6 rounded-2xl border ${
|
||||
tier.highlight
|
||||
? 'border-[var(--accent)] bg-[var(--accent)]/5'
|
||||
: 'border-[var(--border)] bg-[var(--card)]'
|
||||
}`}
|
||||
<section
|
||||
id="pricing"
|
||||
style={{
|
||||
padding: '96px 24px',
|
||||
borderTop: '1px solid var(--border)',
|
||||
}}
|
||||
>
|
||||
<div style={{ maxWidth: 1200, margin: '0 auto' }}>
|
||||
<header style={{ textAlign: 'center', maxWidth: 720, margin: '0 auto 64px' }}>
|
||||
<h2
|
||||
className="text-balance"
|
||||
style={{ fontSize: 'clamp(28px, 4vw, 44px)', fontWeight: 700, letterSpacing: '-0.02em', marginBottom: 16 }}
|
||||
>
|
||||
Pricing built for bettors. Not for SaaS investors.
|
||||
</h2>
|
||||
<p style={{ fontSize: 17, color: 'var(--text-secondary)' }}>
|
||||
First 100 users lock $14.99/mo for life. This price dies at user 101.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className="pricing-grid" style={{ display: 'grid', gap: 24 }}>
|
||||
{TIERS.map((tier, i) => (
|
||||
<article
|
||||
key={tier.id}
|
||||
className={`surface diagonal-cut${tier.highlight ? ' diagonal-cut-strong' : ''} animate-fade-up stagger-${i + 1}`}
|
||||
style={{
|
||||
padding: 32,
|
||||
position: 'relative',
|
||||
border: tier.highlight ? '1px solid var(--grade-a)' : '1px solid var(--border)',
|
||||
background: tier.highlight ? 'var(--bg-elevated)' : 'var(--bg-surface)',
|
||||
boxShadow: tier.highlight ? '0 16px 48px var(--accent-glow)' : 'none',
|
||||
}}
|
||||
>
|
||||
{tier.founderPrice && (
|
||||
<div className="absolute -top-3 left-4 px-3 py-0.5 bg-[var(--accent)] text-white text-xs font-mono font-bold rounded-full">
|
||||
Founder Rate — Locked for Life
|
||||
{tier.badge && (
|
||||
<div
|
||||
className="mono"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: -12,
|
||||
left: 24,
|
||||
padding: '4px 12px',
|
||||
background: 'var(--grade-a)',
|
||||
color: 'var(--bg-primary)',
|
||||
fontSize: 10,
|
||||
fontWeight: 800,
|
||||
letterSpacing: '0.08em',
|
||||
borderRadius: 999,
|
||||
textTransform: 'uppercase',
|
||||
}}
|
||||
>
|
||||
{tier.badge}
|
||||
</div>
|
||||
)}
|
||||
<h3 className="text-xl font-bold mt-2 mb-1">{tier.name}</h3>
|
||||
<div className="flex items-baseline gap-1 mb-6">
|
||||
{tier.founderPrice ? (
|
||||
<>
|
||||
<span className="text-3xl font-bold font-mono">{tier.founderPrice}</span>
|
||||
<span className="text-[var(--text-muted)] text-sm">{tier.period}</span>
|
||||
<span className="ml-2 text-sm text-[var(--text-muted)] line-through">{tier.price}</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-3xl font-bold font-mono">{tier.price}</span>
|
||||
<span className="text-[var(--text-muted)] text-sm">{tier.period}</span>
|
||||
</>
|
||||
<h3 style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
|
||||
{tier.name}
|
||||
</h3>
|
||||
<div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
|
||||
<span className="mono" style={{ fontSize: 40, fontWeight: 800, color: 'var(--text-primary)', letterSpacing: '-0.03em' }}>
|
||||
{tier.price}
|
||||
</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontSize: 14 }}>{tier.cadence}</span>
|
||||
{tier.originalPrice && (
|
||||
<span className="mono" style={{ fontSize: 13, color: 'var(--text-tertiary)', textDecoration: 'line-through' }}>
|
||||
{tier.originalPrice}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<ul className="space-y-2 mb-8">
|
||||
{tier.features.map((f) => (
|
||||
<li key={f} className="flex items-start gap-2 text-sm">
|
||||
<span className="text-[var(--grade-a)] mt-0.5">+</span>
|
||||
{f}
|
||||
</li>
|
||||
))}
|
||||
{tier.unavailable.map((f) => (
|
||||
<li key={f} className="flex items-start gap-2 text-sm text-[var(--text-muted)]">
|
||||
<span className="mt-0.5">-</span>
|
||||
{f}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p style={{ fontSize: 14, color: 'var(--text-secondary)', marginBottom: 24, minHeight: 42 }}>
|
||||
{tier.headline}
|
||||
</p>
|
||||
|
||||
<a
|
||||
href={tier.ctaHref}
|
||||
className={`block text-center py-3 rounded-xl font-medium transition ${
|
||||
tier.highlight
|
||||
? 'bg-[var(--accent)] text-white hover:opacity-90'
|
||||
: 'bg-[var(--border)] text-white hover:bg-[var(--text-muted)]/20'
|
||||
}`}
|
||||
className={tier.highlight ? 'btn-primary' : 'btn-ghost'}
|
||||
style={{ width: '100%', padding: 14, marginBottom: 24 }}
|
||||
>
|
||||
{tier.cta}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ul style={{ display: 'grid', gap: 10 }}>
|
||||
{tier.features.map((f) => (
|
||||
<li key={f} style={{ display: 'flex', gap: 10, fontSize: 14 }}>
|
||||
<span style={{ color: 'var(--grade-a)', fontWeight: 700 }} aria-hidden>+</span>
|
||||
<span style={{ color: 'var(--text-primary)' }}>{f}</span>
|
||||
</li>
|
||||
))}
|
||||
{tier.locked.map((f) => (
|
||||
<li key={f} style={{ display: 'flex', gap: 10, fontSize: 14, color: 'var(--text-tertiary)' }}>
|
||||
<span aria-hidden>—</span>
|
||||
<span>{f}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p style={{ textAlign: 'center', fontSize: 13, color: 'var(--text-tertiary)', marginTop: 32 }}>
|
||||
Cancel anytime. No contracts. Card or Apple Pay or Google Pay — payments processed by NexaPay.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style jsx>{`
|
||||
:global(.pricing-grid) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
:global(.pricing-grid) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user