From 2ff149b15c71cf2bacad8fed94aadb121edac78d Mon Sep 17 00:00:00 2001 From: project7 Date: Mon, 4 May 2026 12:09:18 +0900 Subject: [PATCH 1/2] Move 'How is this different?' to modal triggered from hero (#1029) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add "Why is this airdrop different?" link in the hero that opens a modal with the two-column comparison (Typical vs This Airdrop) and summary text. Remove the inline InnovationBanner from the page layout. Modal closes on backdrop click or X button. Bump version: 1.3.3 → 1.4.0 Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/app/airdrop/page.tsx | 6 --- src/components/airdrop/CampaignHero.tsx | 71 ++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index d6387640..539d2d19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plotlink", - "version": "1.3.3", + "version": "1.4.0", "private": true, "workspaces": [ "packages/*" diff --git a/src/app/airdrop/page.tsx b/src/app/airdrop/page.tsx index 46a2e92b..54df2487 100644 --- a/src/app/airdrop/page.tsx +++ b/src/app/airdrop/page.tsx @@ -4,7 +4,6 @@ import { UserPoints } from "../../components/airdrop/UserPoints"; import { ClaimPanel } from "../../components/airdrop/ClaimPanel"; import { Leaderboard } from "../../components/airdrop/Leaderboard"; import { WeeklySnapshots } from "../../components/airdrop/WeeklySnapshots"; -import { InnovationBanner } from "../../components/airdrop/InnovationBanner"; import { AIRDROP_CONFIG } from "../../../lib/airdrop/config"; export const metadata: Metadata = { @@ -20,11 +19,6 @@ export default function AirdropPage() { {/* Hero spans full width */} - {/* Innovation banner — between hero and user sections */} -
- -
- {/* 2-column grid below hero */}
{/* Left column: user-specific */} diff --git a/src/components/airdrop/CampaignHero.tsx b/src/components/airdrop/CampaignHero.tsx index 4cea95c3..e95dcfa1 100644 --- a/src/components/airdrop/CampaignHero.tsx +++ b/src/components/airdrop/CampaignHero.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { useQuery } from "@tanstack/react-query"; /* ─── Types ─── */ @@ -74,6 +74,9 @@ function useCountdown(endDateStr: string) { export function CampaignHero() { const { data, isLoading } = useAirdropStatus(); const countdown = useCountdown(data?.campaignEnd ?? "2027-01-01"); + const [showModal, setShowModal] = useState(false); + + const closeModal = useCallback(() => setShowModal(false), []); if (isLoading || !data) { return ( @@ -111,6 +114,17 @@ export function CampaignHero() {

+ {/* ── Modal trigger ── */} +
+ +
+ {/* ── Countdown ── */} {data.timeRemainingDays > 0 && (
@@ -177,6 +191,61 @@ export function CampaignHero() {
MCap = PLOT price × 1M max supply
+ + {/* ── Innovation modal ── */} + {showModal && ( +
+
e.stopPropagation()} + > + + +
+ ── How is this different? ── +
+ +
+
+
+ TYPICAL AIRDROP +
+
+
Fixed amount
+
Dumps on day 1
+
No skin in game
+
+
+
+
+ THIS AIRDROP +
+
+
Pool grows with MCap
+
Burned if no growth
+
Everyone wins together
+
+
+
+ +

+ The pool isn't pre-valued — it's valued by the market. + At $100M MCap, 50,000 PLOT = $5M distributed. + At $0 growth, 50,000 PLOT = burned forever. + Everyone — team, holders, earners — wins only if PLOT grows. +

+
+
+ )}
); } From d97563034f0208ae20f068e5202937ca8487615d Mon Sep 17 00:00:00 2001 From: project7 Date: Mon, 4 May 2026 12:19:48 +0900 Subject: [PATCH 2/2] Delete orphaned InnovationBanner.tsx Content now lives in the CampaignHero modal; no remaining imports. Co-Authored-By: Claude Opus 4.6 --- src/components/airdrop/InnovationBanner.tsx | 55 --------------------- 1 file changed, 55 deletions(-) delete mode 100644 src/components/airdrop/InnovationBanner.tsx diff --git a/src/components/airdrop/InnovationBanner.tsx b/src/components/airdrop/InnovationBanner.tsx deleted file mode 100644 index c74d72ba..00000000 --- a/src/components/airdrop/InnovationBanner.tsx +++ /dev/null @@ -1,55 +0,0 @@ -const COLUMNS = [ - { - title: "TYPICAL AIRDROP", - rows: ["Fixed amount", "Dumps on day 1", "No skin in game"], - highlighted: false, - }, - { - title: "THIS AIRDROP", - rows: ["Pool grows with MCap", "Burned if no growth", "Everyone wins together"], - highlighted: true, - }, -] as const; - -export function InnovationBanner() { - return ( -
-
- ── How is this different? ── -
- - {/* Two-column comparison */} -
- {COLUMNS.map((col) => ( -
-
- {col.title} -
-
- {col.rows.map((row) => ( -
- {row} -
- ))} -
-
- ))} -
- - {/* Summary */} -

- The pool isn't pre-valued — it's valued by the market. - At $100M MCap, 50,000 PLOT = $5M distributed. - At $0 growth, 50,000 PLOT = burned forever. - Everyone — team, holders, earners — wins only if PLOT grows. -

-
- ); -}