feat: Feature 3.1 — Landing page + blog + Phase 3 specs

Next.js 14+ web app in web/ directory:
- Landing page: Hero, How It Works, Features, 3-tier Pricing with
  founder badges, Footer with email capture
- Blog system: MDX-powered, /blog index + /blog/[slug] pages,
  reading time, Open Graph tags, JSON-LD structured data
- Auth pages: /login + /signup (Supabase Auth ready)
- Design system: dark theme, grade colors (A/B/C/D), BetonBLK voice
- 1 seed blog post: "How to Read Line Movement Like a Sharp"
- Specs for 3.2 (Scan UI), 3.3 (Bet Tracker), 3.4 (Stripe)

Build passes clean: 7 static pages generated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-03-22 09:43:38 -04:00
parent ed6502a880
commit bfa8345ebf
26 changed files with 5142 additions and 31 deletions
+120
View File
@@ -0,0 +1,120 @@
const tiers = [
{
name: 'Free',
price: '$0',
founderPrice: null,
period: '',
cta: 'Get Started',
ctaHref: '/signup',
highlight: false,
features: [
'5 scans per month',
'View line movements',
'Basic prop grades',
],
unavailable: ['Bet tracking', 'Cascade alerts', 'Performance analytics'],
},
{
name: 'Analyst',
price: '$19.99',
founderPrice: '$14.99',
period: '/mo',
cta: 'Subscribe',
ctaHref: '/api/stripe/checkout?tier=analyst',
highlight: true,
features: [
'Unlimited scans',
'Line movement alerts',
'Bet tracking',
'Cascade alerts',
'Basic performance analytics',
],
unavailable: ['Priority alerts', 'Behavioral patterns'],
},
{
name: 'Desk',
price: '$49.99',
founderPrice: '$34.99',
period: '/mo',
cta: 'Subscribe',
ctaHref: '/api/stripe/checkout?tier=desk',
highlight: false,
features: [
'Unlimited scans',
'Line movement + priority alerts',
'Full bet tracking',
'Priority cascade alerts',
'Full performance analytics',
'Behavioral pattern insights',
],
unavailable: [],
},
];
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)]'
}`}
>
{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
</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>
</>
)}
</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>
<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'
}`}
>
{tier.cta}
</a>
</div>
))}
</div>
</div>
</section>
);
}