diff --git a/src/components/airdrop/CampaignHero.tsx b/src/components/airdrop/CampaignHero.tsx index 7a78aa4..3941b8a 100644 --- a/src/components/airdrop/CampaignHero.tsx +++ b/src/components/airdrop/CampaignHero.tsx @@ -32,6 +32,30 @@ const MILESTONES = [ ]; const MAX_MCAP = 100_000_000; +const ACCENT = "#8B4513"; + +/** Fixed milestone positions at 25/50/75/100% for even visual spacing */ +const MILESTONE_POS = new Map([ + [1_000_000, 0.25], + [10_000_000, 0.50], + [50_000_000, 0.75], + [100_000_000, 1.0], +]); + +/** Map MCap to 0–1 using piecewise linear interpolation between milestones */ +function mcapToX(mcap: number): number { + if (mcap <= 0) return 0; + if (mcap >= MAX_MCAP) return 1; + const thresholds = [0, 1_000_000, 10_000_000, 50_000_000, 100_000_000]; + const positions = [0, 0.25, 0.50, 0.75, 1.0]; + for (let i = 1; i < thresholds.length; i++) { + if (mcap <= thresholds[i]) { + const t = (mcap - thresholds[i - 1]) / (thresholds[i] - thresholds[i - 1]); + return positions[i - 1] + t * (positions[i] - positions[i - 1]); + } + } + return 1; +} /* ─── Helpers ─── */ @@ -74,10 +98,10 @@ function useCountdown(endDateStr: string) { /* ─── MCap Chart ─── */ function MCapChart({ currentFdv }: { currentFdv: number }) { - const progress = Math.min(currentFdv / MAX_MCAP, 1); + const progress = mcapToX(currentFdv); const svgW = 600; const svgH = 80; - const pad = { left: 0, right: 0 }; + const pad = { left: 10, right: 10 }; const chartW = svgW - pad.left - pad.right; const fillX = pad.left + progress * chartW; @@ -85,13 +109,14 @@ function MCapChart({ currentFdv }: { currentFdv: number }) {
{/* Desktop labels above chart */}
- {MILESTONES.map((ms) => { - const x = (ms.mcap / MAX_MCAP) * 100; + {MILESTONES.map((ms, i) => { + const x = (MILESTONE_POS.get(ms.mcap) ?? 0) * 100; + const isLast = i === MILESTONES.length - 1; return (
{ms.label}
unlocks {ms.pct}%
@@ -111,8 +136,8 @@ function MCapChart({ currentFdv }: { currentFdv: number }) { > - - + + @@ -140,7 +165,7 @@ function MCapChart({ currentFdv }: { currentFdv: number }) { {/* Milestone vertical dashed lines */} {MILESTONES.map((ms) => { - const mx = pad.left + (ms.mcap / MAX_MCAP) * chartW; + const mx = pad.left + (MILESTONE_POS.get(ms.mcap) ?? 0) * chartW; return ( { - const mx = pad.left + (ms.mcap / MAX_MCAP) * chartW; + const mx = pad.left + (MILESTONE_POS.get(ms.mcap) ?? 0) * chartW; return ( )} @@ -190,7 +215,7 @@ function MCapChart({ currentFdv }: { currentFdv: number }) { {/* Heartbeat dot — inside SVG for pixel-perfect alignment */} {progress > 0 && ( <> - + - + )} @@ -212,7 +237,6 @@ function MCapChart({ currentFdv }: { currentFdv: number }) { {/* Scale labels */}
$0 - $50M $100M