256 lines
11 KiB
TypeScript
256 lines
11 KiB
TypeScript
'use client'
|
|
|
|
import { motion } from 'framer-motion'
|
|
import { useState } from 'react'
|
|
import { TrendingDown, DollarSign } from 'lucide-react'
|
|
|
|
export function PricingComparison() {
|
|
const [monitorCount, setMonitorCount] = useState(50)
|
|
|
|
// Pricing calculation logic
|
|
const calculatePricing = (monitors: number) => {
|
|
// Competitors: tiered pricing
|
|
let competitorMin, competitorMax
|
|
if (monitors <= 10) {
|
|
competitorMin = 29
|
|
competitorMax = 49
|
|
} else if (monitors <= 50) {
|
|
competitorMin = 79
|
|
competitorMax = 129
|
|
} else if (monitors <= 100) {
|
|
competitorMin = 129
|
|
competitorMax = 199
|
|
} else {
|
|
competitorMin = 199
|
|
competitorMax = 299
|
|
}
|
|
|
|
// Our pricing: simpler, fairer
|
|
let ourPrice
|
|
if (monitors <= 10) {
|
|
ourPrice = 19
|
|
} else if (monitors <= 50) {
|
|
ourPrice = 49
|
|
} else if (monitors <= 100) {
|
|
ourPrice = 89
|
|
} else {
|
|
ourPrice = 149
|
|
}
|
|
|
|
const competitorAvg = (competitorMin + competitorMax) / 2
|
|
const savings = competitorAvg - ourPrice
|
|
const savingsPercent = Math.round((savings / competitorAvg) * 100)
|
|
|
|
return {
|
|
competitorMin,
|
|
competitorMax,
|
|
competitorAvg,
|
|
ourPrice,
|
|
savings,
|
|
savingsPercent
|
|
}
|
|
}
|
|
|
|
const pricing = calculatePricing(monitorCount)
|
|
|
|
return (
|
|
<section className="py-32 bg-gradient-to-b from-[hsl(var(--section-bg-6))] to-[hsl(var(--section-bg-3))] relative overflow-hidden">
|
|
{/* Background Pattern - Enhanced Dot Grid */}
|
|
<div className="absolute inset-0 opacity-8">
|
|
<div className="absolute inset-0" style={{
|
|
backgroundImage: `radial-gradient(circle, hsl(var(--teal)) 1.5px, transparent 1.5px)`,
|
|
backgroundSize: '30px 30px'
|
|
}} />
|
|
</div>
|
|
|
|
<div className="mx-auto max-w-5xl px-6 relative z-10">
|
|
{/* Section Header */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
className="text-center mb-16"
|
|
>
|
|
<div className="inline-flex items-center gap-2 rounded-full bg-[hsl(var(--teal))]/10 border border-[hsl(var(--teal))]/20 px-4 py-1.5 text-sm font-medium text-[hsl(var(--teal))] mb-6">
|
|
<DollarSign className="h-4 w-4" />
|
|
Fair Pricing
|
|
</div>
|
|
<h2 className="text-4xl lg:text-5xl font-display font-bold text-foreground mb-6">
|
|
See how much you{' '}
|
|
<span className="text-[hsl(var(--teal))]">save</span>
|
|
</h2>
|
|
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
|
|
Compare our transparent pricing with typical competitors. No hidden fees, no surprises.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Interactive Comparison Card */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 30 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.6 }}
|
|
className="rounded-3xl border-2 border-border bg-card p-8 lg:p-12 shadow-2xl"
|
|
>
|
|
{/* Monitor Count Slider */}
|
|
<div className="mb-12">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<label className="text-sm font-bold text-muted-foreground uppercase tracking-wider">
|
|
Number of Monitors
|
|
</label>
|
|
<motion.div
|
|
key={monitorCount}
|
|
initial={{ scale: 1.2 }}
|
|
animate={{ scale: 1 }}
|
|
className="text-4xl font-bold text-foreground font-mono"
|
|
>
|
|
{monitorCount}
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Slider */}
|
|
<div className="relative">
|
|
<input
|
|
type="range"
|
|
min="5"
|
|
max="200"
|
|
step="5"
|
|
value={monitorCount}
|
|
onChange={(e) => setMonitorCount(Number(e.target.value))}
|
|
className="w-full h-3 bg-secondary rounded-full appearance-none cursor-pointer
|
|
[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-6 [&::-webkit-slider-thumb]:h-6
|
|
[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[hsl(var(--teal))]
|
|
[&::-webkit-slider-thumb]:shadow-lg [&::-webkit-slider-thumb]:cursor-grab
|
|
[&::-webkit-slider-thumb]:active:cursor-grabbing [&::-webkit-slider-thumb]:hover:scale-110
|
|
[&::-webkit-slider-thumb]:transition-transform
|
|
[&::-moz-range-thumb]:w-6 [&::-moz-range-thumb]:h-6
|
|
[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[hsl(var(--teal))]
|
|
[&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:shadow-lg
|
|
[&::-moz-range-thumb]:cursor-grab [&::-moz-range-thumb]:active:cursor-grabbing"
|
|
/>
|
|
{/* Tick marks - positioned by percentage based on slider range (5-200) */}
|
|
<div className="relative mt-2 h-4">
|
|
<span className="absolute text-xs text-muted-foreground" style={{ left: '0%', transform: 'translateX(0)' }}>5</span>
|
|
<span className="absolute text-xs text-muted-foreground" style={{ left: `${((50 - 5) / (200 - 5)) * 100}%`, transform: 'translateX(-50%)' }}>50</span>
|
|
<span className="absolute text-xs text-muted-foreground" style={{ left: `${((100 - 5) / (200 - 5)) * 100}%`, transform: 'translateX(-50%)' }}>100</span>
|
|
<span className="absolute text-xs text-muted-foreground" style={{ left: '100%', transform: 'translateX(-100%)' }}>200</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Price Comparison Bars */}
|
|
<div className="grid lg:grid-cols-2 gap-8 mb-8">
|
|
{/* Competitors */}
|
|
<motion.div
|
|
layout
|
|
className="space-y-4"
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-bold text-muted-foreground uppercase tracking-wider">
|
|
Typical Competitors
|
|
</span>
|
|
</div>
|
|
|
|
{/* Bar */}
|
|
<motion.div
|
|
className="relative h-24 rounded-2xl bg-gradient-to-r from-red-500/10 to-red-500/20 border-2 border-red-500/30 overflow-hidden"
|
|
whileHover={{ scale: 1.02 }}
|
|
transition={{ duration: 0.2 }}
|
|
>
|
|
<motion.div
|
|
className="absolute inset-0 bg-gradient-to-r from-red-500/20 to-red-500/40"
|
|
initial={{ scaleX: 0 }}
|
|
animate={{ scaleX: 1 }}
|
|
transition={{ duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
|
|
style={{ transformOrigin: 'left' }}
|
|
/>
|
|
<div className="relative h-full flex items-center justify-center">
|
|
<div className="text-center">
|
|
<motion.div
|
|
key={`comp-${pricing.competitorMin}-${pricing.competitorMax}`}
|
|
initial={{ scale: 0.8, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
className="text-4xl font-bold text-red-700 font-mono"
|
|
>
|
|
${pricing.competitorMin}-{pricing.competitorMax}
|
|
</motion.div>
|
|
<div className="text-xs font-medium text-red-600">per month</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</motion.div>
|
|
|
|
{/* Us */}
|
|
<motion.div
|
|
layout
|
|
className="space-y-4"
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-bold text-[hsl(var(--teal))] uppercase tracking-wider">
|
|
Our Pricing
|
|
</span>
|
|
</div>
|
|
|
|
{/* Bar */}
|
|
<motion.div
|
|
className="relative h-24 rounded-2xl bg-gradient-to-r from-[hsl(var(--teal))]/10 to-[hsl(var(--teal))]/20 border-2 border-[hsl(var(--teal))]/30 overflow-hidden"
|
|
whileHover={{ scale: 1.02 }}
|
|
transition={{ duration: 0.2 }}
|
|
>
|
|
<motion.div
|
|
className="absolute inset-0 bg-gradient-to-r from-[hsl(var(--teal))]/20 to-[hsl(var(--teal))]/40"
|
|
initial={{ scaleX: 0 }}
|
|
animate={{ scaleX: pricing.ourPrice / pricing.competitorMax }}
|
|
transition={{ duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
|
|
style={{ transformOrigin: 'left' }}
|
|
/>
|
|
<div className="relative h-full flex items-center justify-center">
|
|
<div className="text-center">
|
|
<motion.div
|
|
key={`our-${pricing.ourPrice}`}
|
|
initial={{ scale: 0.8, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
className="text-5xl font-bold text-[hsl(var(--teal))] font-mono"
|
|
>
|
|
${pricing.ourPrice}
|
|
</motion.div>
|
|
<div className="text-xs font-medium text-[hsl(var(--teal))]">per month</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Savings Badge */}
|
|
<motion.div
|
|
key={`savings-${pricing.savings}`}
|
|
initial={{ scale: 0.9, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
transition={{ type: 'spring', stiffness: 300, damping: 20 }}
|
|
className="flex items-center justify-center gap-4 p-6 rounded-2xl bg-gradient-to-r from-[hsl(var(--primary))]/10 via-[hsl(var(--teal))]/10 to-[hsl(var(--burgundy))]/10 border-2 border-[hsl(var(--teal))]/30"
|
|
>
|
|
<TrendingDown className="h-8 w-8 text-[hsl(var(--teal))]" />
|
|
<div className="text-center">
|
|
<div className="text-sm font-medium text-muted-foreground">You save</div>
|
|
<div className="flex items-baseline gap-2">
|
|
<span className="text-4xl font-bold text-foreground">
|
|
${Math.round(pricing.savings)}
|
|
</span>
|
|
<span className="text-xl text-muted-foreground">/month</span>
|
|
<span className="ml-2 px-3 py-1 rounded-full bg-[hsl(var(--teal))]/20 text-sm font-bold text-[hsl(var(--teal))]">
|
|
{pricing.savingsPercent}% off
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
|
|
{/* Fine Print */}
|
|
<p className="mt-6 text-center text-xs text-muted-foreground">
|
|
* Based on average pricing from Visualping, Distill.io, and similar competitors as of Jan 2026
|
|
</p>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|