@medialane/ui 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/components/launchpad-services.cjs +111 -67
- package/dist/components/launchpad-services.cjs.map +1 -1
- package/dist/components/launchpad-services.d.cts +3 -1
- package/dist/components/launchpad-services.d.ts +3 -1
- package/dist/components/launchpad-services.js +113 -69
- package/dist/components/launchpad-services.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -233,6 +233,9 @@ The package uses [tsup](https://tsup.egoist.dev/) and outputs ESM + CJS + type d
|
|
|
233
233
|
|
|
234
234
|
| Version | Added |
|
|
235
235
|
|---|---|
|
|
236
|
+
| **v0.26.0** | `LaunchpadServiceCard` "living color cards" high-fidelity pass: per-hue aurora light-leaks, gradient icon tile, hairline gradient frame that ignites on interaction, staggered entrance reveal, press/hover microinteractions, animated CTA arrow; roomier grid gaps + section rhythm. Touch-first, reduced-motion safe |
|
|
237
|
+
| **v0.25.0** | `CoinsExplorer`/`CoinCard` refined: kind label over the artwork (brand hues, not red), quote-currency icon on price, marketplace-style Filters dialog; dropped the Verified badge / FDV / holders / per-card glow / Trade button |
|
|
238
|
+
| **v0.24.0** | Art-forward `CoinCard` redesign — the coin's cover artwork becomes the hero of the tile |
|
|
236
239
|
| **v0.14.0** | `docUpload` template config + `DOC_UPLOAD` (document/PDF → IPFS for Documents/Patents/Publications/Software), `IPTypeDisplay` document card |
|
|
237
240
|
| **v0.13.x** | Asset-page modules lifted: `AssetOverviewContent`, `AssetMarketsTab`, `AssetMediaColumn`/`AssetHeaderBlock`, `ParentAttributionBanner`, `IPTypeDisplay`; IP data layer (`data/ip`, `data/ip-templates`); `timeUntil` |
|
|
238
241
|
| **v0.12.x** | `LaunchpadStrip` (homepage carousel from service defs); Discover strips restyled to the approved design; `CollectionCard` gated-content border + currency floor |
|
|
@@ -63,85 +63,129 @@ const SERVICE_HUES = {
|
|
|
63
63
|
"claim-collection": { text: "text-cyan-600 dark:text-cyan-400", solid: "bg-cyan-500", border: "border-cyan-500/25", pill: "bg-gradient-to-r from-cyan-500 to-sky-600" },
|
|
64
64
|
"claim-collection-name": { text: "text-pink-600 dark:text-pink-400", solid: "bg-pink-500", border: "border-pink-500/25", pill: "bg-gradient-to-r from-pink-500 to-rose-600" }
|
|
65
65
|
};
|
|
66
|
-
function LaunchpadServiceCard({ def, override = {}, featured = false }) {
|
|
66
|
+
function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0 }) {
|
|
67
67
|
const { key, icon: Icon, title, browseLinkLabel, features, example } = def;
|
|
68
68
|
const status = override.status ?? def.status;
|
|
69
69
|
const blurb = override.blurb ?? def.blurb;
|
|
70
70
|
const { href, browseHref } = override;
|
|
71
|
+
const reduceMotion = (0, import_framer_motion.useReducedMotion)();
|
|
71
72
|
const live = status === "live";
|
|
72
73
|
const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;
|
|
73
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
74
|
-
|
|
74
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
75
|
+
import_framer_motion.motion.div,
|
|
75
76
|
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
!live && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1", children: [
|
|
92
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Lock, { className: "h-3 w-3" }),
|
|
93
|
-
"Coming soon"
|
|
94
|
-
] })
|
|
95
|
-
] }),
|
|
96
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
|
|
97
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-2xl sm:text-3xl font-black tracking-tight leading-snug", children: title }),
|
|
98
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (0, import_cn.cn)("text-[15px] leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb }),
|
|
99
|
-
live && example && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
100
|
-
"e.g. ",
|
|
101
|
-
example
|
|
102
|
-
] })
|
|
103
|
-
] }),
|
|
104
|
-
live && features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
105
|
-
"span",
|
|
106
|
-
{
|
|
107
|
-
className: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground",
|
|
108
|
-
children: [
|
|
109
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { className: (0, import_cn.cn)("h-3 w-3 shrink-0", hue.text) }),
|
|
110
|
-
feature
|
|
111
|
-
]
|
|
112
|
-
},
|
|
113
|
-
feature
|
|
114
|
-
)) }),
|
|
115
|
-
live && href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href, "aria-label": `${def.cta} \u2014 ${title}`, className: "absolute inset-0 z-10" }),
|
|
116
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-auto pt-1 flex items-end justify-between gap-3", children: [
|
|
117
|
-
live && browseHref && browseLinkLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
118
|
-
import_link.default,
|
|
119
|
-
{
|
|
120
|
-
href: browseHref,
|
|
121
|
-
className: "relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground",
|
|
122
|
-
children: [
|
|
123
|
-
browseLinkLabel,
|
|
124
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-3 w-3" })
|
|
125
|
-
]
|
|
126
|
-
}
|
|
127
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
|
|
128
|
-
live && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
77
|
+
initial: { opacity: 0, y: reduceMotion ? 0 : 16 },
|
|
78
|
+
whileInView: { opacity: 1, y: 0 },
|
|
79
|
+
viewport: { once: true, margin: "-40px" },
|
|
80
|
+
transition: { duration: 0.45, delay: index * 0.06, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
81
|
+
className: (0, import_cn.cn)("flex", featured && "sm:col-span-2"),
|
|
82
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
83
|
+
"div",
|
|
84
|
+
{
|
|
85
|
+
className: (0, import_cn.cn)(
|
|
86
|
+
"group relative flex flex-1 rounded-2xl transition-transform duration-300 ease-out",
|
|
87
|
+
// the hue gradient frame lives in the 1px padding; press + lift are the interaction
|
|
88
|
+
live && "p-px active:scale-[0.985] sm:hover:-translate-y-1 motion-reduce:transform-none motion-reduce:transition-none"
|
|
89
|
+
),
|
|
90
|
+
children: [
|
|
91
|
+
live && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
129
92
|
"span",
|
|
130
93
|
{
|
|
94
|
+
"aria-hidden": true,
|
|
131
95
|
className: (0, import_cn.cn)(
|
|
132
|
-
"
|
|
133
|
-
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
96
|
+
"absolute inset-0 rounded-2xl opacity-40 sm:group-hover:opacity-100 transition-opacity duration-500 pointer-events-none",
|
|
134
97
|
hue.pill
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
102
|
+
"div",
|
|
103
|
+
{
|
|
104
|
+
className: (0, import_cn.cn)(
|
|
105
|
+
"relative flex flex-1 flex-col overflow-hidden min-h-[240px]",
|
|
106
|
+
live ? "rounded-[15px] bg-card" : "rounded-2xl border border-border/30 bg-card dark:bg-white/[0.02] opacity-75"
|
|
135
107
|
),
|
|
136
108
|
children: [
|
|
137
|
-
|
|
138
|
-
|
|
109
|
+
live && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
110
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: (0, import_cn.cn)("absolute -top-16 -left-12 h-48 w-48 rounded-full blur-3xl opacity-[0.18] sm:group-hover:opacity-30 transition-opacity duration-500 pointer-events-none", hue.solid) }),
|
|
111
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: (0, import_cn.cn)("absolute -bottom-24 -right-16 h-56 w-56 rounded-full blur-3xl opacity-[0.10] sm:group-hover:opacity-20 transition-opacity duration-500 pointer-events-none", hue.solid) })
|
|
112
|
+
] }),
|
|
113
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
114
|
+
"div",
|
|
115
|
+
{
|
|
116
|
+
"aria-hidden": true,
|
|
117
|
+
className: (0, import_cn.cn)(
|
|
118
|
+
"absolute -right-8 -bottom-10 select-none pointer-events-none transition-all duration-500",
|
|
119
|
+
live ? "opacity-[0.05] sm:group-hover:opacity-[0.09] sm:group-hover:-translate-y-1 motion-reduce:transform-none" : "opacity-[0.03]"
|
|
120
|
+
),
|
|
121
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-44 w-44", live ? hue.text : "text-muted-foreground") })
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex flex-col flex-1 p-6 sm:p-8 gap-4 sm:gap-5", children: [
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
|
|
126
|
+
live ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: (0, import_cn.cn)("absolute -inset-2 rounded-2xl blur-xl opacity-40 sm:group-hover:opacity-60 transition-opacity duration-500", hue.solid) }),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("relative flex h-14 w-14 items-center justify-center rounded-2xl text-white shadow-lg shadow-black/25 transition-transform duration-300 sm:group-hover:scale-105 motion-reduce:transform-none", hue.pill), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-7 w-7" }) })
|
|
129
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-9 w-9 shrink-0 text-muted-foreground/50" }),
|
|
130
|
+
!live && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1", children: [
|
|
131
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Lock, { className: "h-3 w-3" }),
|
|
132
|
+
"Coming soon"
|
|
133
|
+
] })
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-2xl sm:text-3xl font-black tracking-tight leading-snug", children: title }),
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (0, import_cn.cn)("text-[15px] leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb }),
|
|
138
|
+
live && example && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
139
|
+
"e.g. ",
|
|
140
|
+
example
|
|
141
|
+
] })
|
|
142
|
+
] }),
|
|
143
|
+
live && features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
144
|
+
"span",
|
|
145
|
+
{
|
|
146
|
+
className: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground",
|
|
147
|
+
children: [
|
|
148
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { className: (0, import_cn.cn)("h-3 w-3 shrink-0", hue.text) }),
|
|
149
|
+
feature
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
feature
|
|
153
|
+
)) }),
|
|
154
|
+
live && href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href, "aria-label": `${def.cta} \u2014 ${title}`, className: "absolute inset-0 z-10" }),
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-auto pt-1 flex items-end justify-between gap-3", children: [
|
|
156
|
+
live && browseHref && browseLinkLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
157
|
+
import_link.default,
|
|
158
|
+
{
|
|
159
|
+
href: browseHref,
|
|
160
|
+
className: "relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground sm:hover:text-foreground transition-colors",
|
|
161
|
+
children: [
|
|
162
|
+
browseLinkLabel,
|
|
163
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-3 w-3" })
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
|
|
167
|
+
live && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
168
|
+
"span",
|
|
169
|
+
{
|
|
170
|
+
className: (0, import_cn.cn)(
|
|
171
|
+
"inline-flex items-center gap-2 h-10 px-5 rounded-full",
|
|
172
|
+
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
173
|
+
hue.pill
|
|
174
|
+
),
|
|
175
|
+
children: [
|
|
176
|
+
def.cta,
|
|
177
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-4 w-4 transition-transform duration-300 sm:group-hover:translate-x-0.5 motion-reduce:transform-none" })
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
] })
|
|
182
|
+
] })
|
|
139
183
|
]
|
|
140
184
|
}
|
|
141
185
|
)
|
|
142
|
-
]
|
|
143
|
-
|
|
144
|
-
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
)
|
|
145
189
|
}
|
|
146
190
|
);
|
|
147
191
|
}
|
|
@@ -180,7 +224,7 @@ function ComingSoonStrip({ group, defs }) {
|
|
|
180
224
|
] });
|
|
181
225
|
}
|
|
182
226
|
function LaunchpadGroupedSections({ overrides, className }) {
|
|
183
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("space-y-
|
|
227
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("space-y-20 sm:space-y-28", className), children: import_launchpad_services.LAUNCHPAD_SERVICE_GROUPS.map((group) => {
|
|
184
228
|
const defs = import_launchpad_services.LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);
|
|
185
229
|
if (defs.length === 0) return null;
|
|
186
230
|
if (group.key === "coming-soon") {
|
|
@@ -192,11 +236,11 @@ function LaunchpadGroupedSections({ overrides, className }) {
|
|
|
192
236
|
initial: { opacity: 0, y: 8 },
|
|
193
237
|
animate: { opacity: 1, y: 0 },
|
|
194
238
|
transition: { duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
195
|
-
className: "space-y-
|
|
239
|
+
className: "space-y-7 sm:space-y-10",
|
|
196
240
|
children: [
|
|
197
241
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GroupHeader, { group }),
|
|
198
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-
|
|
199
|
-
defs.map((def) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LaunchpadServiceCard, { def, override: overrides[def.key] }, def.key)),
|
|
242
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-5 sm:gap-7", children: [
|
|
243
|
+
defs.map((def, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LaunchpadServiceCard, { def, override: overrides[def.key], index: i }, def.key)),
|
|
200
244
|
group.key === "pop-protocol" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopHowItWorks, {})
|
|
201
245
|
] })
|
|
202
246
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Launchpad grouped services — the single source for the /launchpad page UI\n * in medialane-io and medialane-starknet.\n *\n * Card philosophy (creator-first redesign, 2026-06-10): the whole card is the\n * action. One title, one creator-language sentence (def.blurb), one unique hue\n * per service — no buttons repeating the title, no status badges, no tech\n * chips, no hover-only effects (mobile first: press states only).\n *\n * Apps own: hrefs + per-app rollout status flips. Everything else lives here.\n */\n\nimport Link from \"next/link\";\nimport { motion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\n// ── Per-app injection points ─────────────────────────────────────────────────\n\nexport interface ServiceOverride {\n /** Primary destination — the whole card links here (required for live services) */\n href?: string;\n /** Secondary browse link href (pairs with the def's browseLinkLabel) */\n browseHref?: string;\n /** Per-app rollout flips (e.g. coins live on one app first) */\n status?: ServiceStatus;\n /** Per-app one-liner override (rarely needed) */\n blurb?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n// ── One unique hue per service — never repeated inside a group ───────────────\n\ninterface ServiceHue {\n /** icon tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — icon glow */\n solid: string;\n /** thin card border tint */\n border: string;\n /** vivid two-stop gradient for the action pill (asset-page button language) */\n pill: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n border: \"border-sky-500/25\",\n pill: \"bg-gradient-to-r from-sky-500 to-blue-600\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n // Single Editions — blue + green\n \"mint-ip-asset\": { text: \"text-blue-600 dark:text-blue-400\", solid: \"bg-blue-500\", border: \"border-blue-500/25\", pill: \"bg-gradient-to-r from-blue-500 to-sky-600\" },\n \"create-collection\": { text: \"text-green-600 dark:text-green-400\", solid: \"bg-green-500\", border: \"border-green-500/25\", pill: \"bg-gradient-to-r from-green-500 to-emerald-600\" },\n // Limited Editions — purple + red\n \"ip-collection-1155\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", border: \"border-purple-500/25\", pill: \"bg-gradient-to-r from-purple-500 to-violet-600\" },\n \"mint-editions\": { text: \"text-red-600 dark:text-red-400\", solid: \"bg-red-500\", border: \"border-red-500/25\", pill: \"bg-gradient-to-r from-red-500 to-rose-600\" },\n // Creator Coins & Memecoins — yellow + orange\n \"creator-coins\": { text: \"text-yellow-600 dark:text-yellow-400\", solid: \"bg-yellow-500\", border: \"border-yellow-500/25\", pill: \"bg-gradient-to-r from-yellow-500 to-amber-500\" },\n \"claim-memecoin\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-amber-600\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-red-500\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", border: \"border-emerald-500/25\", pill: \"bg-gradient-to-r from-emerald-500 to-green-600\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", border: \"border-indigo-500/25\", pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\" },\n \"claim-username\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", border: \"border-violet-500/25\", pill: \"bg-gradient-to-r from-violet-500 to-fuchsia-600\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", border: \"border-cyan-500/25\", pill: \"bg-gradient-to-r from-cyan-500 to-sky-600\" },\n \"claim-collection-name\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", border: \"border-pink-500/25\", pill: \"bg-gradient-to-r from-pink-500 to-rose-600\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n /** Showcase layout — spans the full grid width (e.g. POP Protocol) */\n featured?: boolean;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, featured = false }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel, features, example } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href, browseHref } = override;\n\n const live = status === \"live\";\n const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;\n\n return (\n <div\n className={cn(\n // dark surfaces stay close to the canvas — the hue border does the talking\n \"relative rounded-2xl border bg-card dark:bg-white/[0.02] overflow-hidden flex flex-col flex-1 min-h-[210px]\",\n \"transition-transform\",\n live ? cn(hue.border, \"active:scale-[0.99]\") : \"border-border/30 opacity-70\",\n featured && \"sm:col-span-2\",\n )}\n >\n {/* Giant watermark icon, ghosted in the corner (Drop-Pages-panel language) */}\n <div aria-hidden className=\"absolute -right-8 -bottom-10 opacity-[0.04] select-none pointer-events-none\">\n <Icon className=\"h-44 w-44\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 sm:p-8 gap-4 sm:gap-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"relative\">\n {live && (\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n )}\n <Icon className={cn(\"relative h-9 w-9 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n </div>\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-2xl sm:text-3xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n {live && example && (\n <p className=\"text-[13px] leading-relaxed text-muted-foreground/70 italic\">\n e.g. {example}\n </p>\n )}\n </div>\n\n {/* Feature showcase — plain-language chips */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground\"\n >\n <Check className={cn(\"h-3 w-3 shrink-0\", hue.text)} />\n {feature}\n </span>\n ))}\n </div>\n )}\n\n {/* Stretched link — the whole card is the action; the pill is the visual cue */}\n {live && href && <Link href={href} aria-label={`${def.cta} — ${title}`} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between gap-3\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-10 px-5 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {def.cta}\n <ArrowRight className=\"h-4 w-4\" />\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\n/** Vivid gradient titles give special sections identity without boxing them in\n * (no panels inside panels — color carries the distinction, space does the rest). */\nconst GROUP_TITLE_ACCENTS: Partial<Record<ServiceGroup, string>> = {\n \"creator-coins\": \"bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500 bg-clip-text text-transparent\",\n \"pop-protocol\": \"bg-gradient-to-r from-emerald-500 to-green-600 bg-clip-text text-transparent\",\n};\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-2\">\n <h2 className={cn(\"text-3xl sm:text-4xl font-black tracking-tight\", GROUP_TITLE_ACCENTS[group.key])}>\n {group.title}\n </h2>\n <p className=\"text-base sm:text-lg text-muted-foreground leading-relaxed max-w-2xl\">{group.tagline}</p>\n </div>\n );\n}\n\n/** POP Protocol companion column — open how-it-works steps, no extra panel. */\nconst POP_STEPS = [\n { title: \"Create your event badge\", body: \"Name it, add your artwork, and set who can claim — ready in minutes.\" },\n { title: \"Share the claim link\", body: \"Your community claims for free — one badge per person, no faking.\" },\n { title: \"It stays with them forever\", body: \"Badges can't be sold or transferred — lasting proof they were there.\" },\n];\n\nfunction PopHowItWorks() {\n return (\n <div className=\"flex flex-col justify-center gap-5 sm:gap-6 px-2 py-4 sm:py-0 sm:pl-6\">\n {POP_STEPS.map((step, i) => (\n <div key={step.title} className=\"flex gap-4\">\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 text-sm font-bold\">\n {i + 1}\n </span>\n <div className=\"space-y-0.5\">\n <p className=\"font-semibold\">{step.title}</p>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{step.body}</p>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ComingSoonStrip({ group, defs }: { group: ServiceGroupDefinition; defs: ServiceDefinition[] }) {\n return (\n <div className=\"rounded-2xl border border-border/40 p-5\">\n <p className=\"font-semibold text-sm\">{group.title}</p>\n <p className=\"text-sm text-muted-foreground mt-0.5\">{group.tagline}</p>\n <div className=\"flex flex-wrap gap-2 mt-4\">\n {defs.map(({ key, icon: Icon, title }) => (\n <div key={key} className=\"flex items-center gap-2 px-3 py-2 rounded-full bg-muted/30 border border-border/25\">\n <Icon className=\"h-3.5 w-3.5 text-muted-foreground/60\" />\n <span className=\"text-xs font-medium text-muted-foreground\">{title}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n /** Per-app hrefs / rollout flips, keyed by service key. */\n overrides: ServiceOverrides;\n className?: string;\n}\n\n/** The full grouped launchpad services block — section order comes from\n * LAUNCHPAD_SERVICE_GROUPS; cards from LAUNCHPAD_SERVICE_DEFINITIONS. */\nexport function LaunchpadGroupedSections({ overrides, className }: LaunchpadGroupedSectionsProps) {\n return (\n <div className={cn(\"space-y-16 sm:space-y-24\", className)}>\n {LAUNCHPAD_SERVICE_GROUPS.map((group) => {\n const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);\n if (defs.length === 0) return null;\n if (group.key === \"coming-soon\") {\n return <ComingSoonStrip key={group.key} group={group} defs={defs} />;\n }\n return (\n <motion.div\n key={group.key}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"space-y-6 sm:space-y-8\"\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6\">\n {defs.map((def) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} />\n ))}\n {group.key === \"pop-protocol\" && <PopHowItWorks />}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Launchpad grouped services — the single source for the /launchpad page UI\n * in medialane-io and medialane-starknet.\n *\n * Card philosophy (creator-first redesign 2026-06-10; \"living color cards\"\n * high-fidelity pass 2026-06-27): the whole card is the action. One title, one\n * creator-language sentence (def.blurb), one unique hue per service. The hue is\n * not locked in a thin border — it saturates the whole card as ambient light:\n * an aurora glow behind a gradient icon tile, a hairline gradient frame that\n * ignites on interaction, a staggered entrance reveal, and press/hover\n * microinteractions. Touch-first (press states are primary; hover is desktop\n * polish, gated to sm+ and degraded under reduced-motion).\n *\n * Apps own: hrefs + per-app rollout status flips. Everything else lives here.\n */\n\nimport Link from \"next/link\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\n// ── Per-app injection points ─────────────────────────────────────────────────\n\nexport interface ServiceOverride {\n /** Primary destination — the whole card links here (required for live services) */\n href?: string;\n /** Secondary browse link href (pairs with the def's browseLinkLabel) */\n browseHref?: string;\n /** Per-app rollout flips (e.g. coins live on one app first) */\n status?: ServiceStatus;\n /** Per-app one-liner override (rarely needed) */\n blurb?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n// ── One unique hue per service — never repeated inside a group ───────────────\n\ninterface ServiceHue {\n /** icon tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — icon glow */\n solid: string;\n /** thin card border tint */\n border: string;\n /** vivid two-stop gradient for the action pill (asset-page button language) */\n pill: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n border: \"border-sky-500/25\",\n pill: \"bg-gradient-to-r from-sky-500 to-blue-600\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n // Single Editions — blue + green\n \"mint-ip-asset\": { text: \"text-blue-600 dark:text-blue-400\", solid: \"bg-blue-500\", border: \"border-blue-500/25\", pill: \"bg-gradient-to-r from-blue-500 to-sky-600\" },\n \"create-collection\": { text: \"text-green-600 dark:text-green-400\", solid: \"bg-green-500\", border: \"border-green-500/25\", pill: \"bg-gradient-to-r from-green-500 to-emerald-600\" },\n // Limited Editions — purple + red\n \"ip-collection-1155\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", border: \"border-purple-500/25\", pill: \"bg-gradient-to-r from-purple-500 to-violet-600\" },\n \"mint-editions\": { text: \"text-red-600 dark:text-red-400\", solid: \"bg-red-500\", border: \"border-red-500/25\", pill: \"bg-gradient-to-r from-red-500 to-rose-600\" },\n // Creator Coins & Memecoins — yellow + orange\n \"creator-coins\": { text: \"text-yellow-600 dark:text-yellow-400\", solid: \"bg-yellow-500\", border: \"border-yellow-500/25\", pill: \"bg-gradient-to-r from-yellow-500 to-amber-500\" },\n \"claim-memecoin\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-amber-600\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-red-500\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", border: \"border-emerald-500/25\", pill: \"bg-gradient-to-r from-emerald-500 to-green-600\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", border: \"border-indigo-500/25\", pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\" },\n \"claim-username\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", border: \"border-violet-500/25\", pill: \"bg-gradient-to-r from-violet-500 to-fuchsia-600\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", border: \"border-cyan-500/25\", pill: \"bg-gradient-to-r from-cyan-500 to-sky-600\" },\n \"claim-collection-name\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", border: \"border-pink-500/25\", pill: \"bg-gradient-to-r from-pink-500 to-rose-600\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n /** Showcase layout — spans the full grid width (e.g. POP Protocol) */\n featured?: boolean;\n /** Grid position — drives the staggered entrance reveal. */\n index?: number;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0 }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel, features, example } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href, browseHref } = override;\n const reduceMotion = useReducedMotion();\n\n const live = status === \"live\";\n const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;\n\n return (\n <motion.div\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n whileInView={{ opacity: 1, y: 0 }}\n viewport={{ once: true, margin: \"-40px\" }}\n transition={{ duration: 0.45, delay: index * 0.06, ease: [0.25, 0.46, 0.45, 0.94] }}\n className={cn(\"flex\", featured && \"sm:col-span-2\")}\n >\n <div\n className={cn(\n \"group relative flex flex-1 rounded-2xl transition-transform duration-300 ease-out\",\n // the hue gradient frame lives in the 1px padding; press + lift are the interaction\n live && \"p-px active:scale-[0.985] sm:hover:-translate-y-1 motion-reduce:transform-none motion-reduce:transition-none\",\n )}\n >\n {/* Hue gradient frame — a quiet hairline that ignites on interaction (live only) */}\n {live && (\n <span\n aria-hidden\n className={cn(\n \"absolute inset-0 rounded-2xl opacity-40 sm:group-hover:opacity-100 transition-opacity duration-500 pointer-events-none\",\n hue.pill,\n )}\n />\n )}\n\n {/* Inner surface */}\n <div\n className={cn(\n \"relative flex flex-1 flex-col overflow-hidden min-h-[240px]\",\n live ? \"rounded-[15px] bg-card\" : \"rounded-2xl border border-border/30 bg-card dark:bg-white/[0.02] opacity-75\",\n )}\n >\n {/* Aurora light-leaks — the hue saturates the whole card as ambient light */}\n {live && (\n <>\n <span aria-hidden className={cn(\"absolute -top-16 -left-12 h-48 w-48 rounded-full blur-3xl opacity-[0.18] sm:group-hover:opacity-30 transition-opacity duration-500 pointer-events-none\", hue.solid)} />\n <span aria-hidden className={cn(\"absolute -bottom-24 -right-16 h-56 w-56 rounded-full blur-3xl opacity-[0.10] sm:group-hover:opacity-20 transition-opacity duration-500 pointer-events-none\", hue.solid)} />\n </>\n )}\n\n {/* Giant watermark icon, ghosted in the corner — drifts on hover */}\n <div\n aria-hidden\n className={cn(\n \"absolute -right-8 -bottom-10 select-none pointer-events-none transition-all duration-500\",\n live ? \"opacity-[0.05] sm:group-hover:opacity-[0.09] sm:group-hover:-translate-y-1 motion-reduce:transform-none\" : \"opacity-[0.03]\",\n )}\n >\n <Icon className={cn(\"h-44 w-44\", live ? hue.text : \"text-muted-foreground\")} />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 sm:p-8 gap-4 sm:gap-5\">\n <div className=\"flex items-start justify-between gap-3\">\n {live ? (\n <div className=\"relative\">\n <span aria-hidden className={cn(\"absolute -inset-2 rounded-2xl blur-xl opacity-40 sm:group-hover:opacity-60 transition-opacity duration-500\", hue.solid)} />\n <span className={cn(\"relative flex h-14 w-14 items-center justify-center rounded-2xl text-white shadow-lg shadow-black/25 transition-transform duration-300 sm:group-hover:scale-105 motion-reduce:transform-none\", hue.pill)}>\n <Icon className=\"h-7 w-7\" />\n </span>\n </div>\n ) : (\n <Icon className=\"h-9 w-9 shrink-0 text-muted-foreground/50\" />\n )}\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-2xl sm:text-3xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n {live && example && (\n <p className=\"text-[13px] leading-relaxed text-muted-foreground/70 italic\">\n e.g. {example}\n </p>\n )}\n </div>\n\n {/* Feature showcase — plain-language chips */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground\"\n >\n <Check className={cn(\"h-3 w-3 shrink-0\", hue.text)} />\n {feature}\n </span>\n ))}\n </div>\n )}\n\n {/* Stretched link — the whole card is the action; the pill is the visual cue */}\n {live && href && <Link href={href} aria-label={`${def.cta} — ${title}`} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between gap-3\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground sm:hover:text-foreground transition-colors\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-10 px-5 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {def.cta}\n <ArrowRight className=\"h-4 w-4 transition-transform duration-300 sm:group-hover:translate-x-0.5 motion-reduce:transform-none\" />\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n </motion.div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\n/** Vivid gradient titles give special sections identity without boxing them in\n * (no panels inside panels — color carries the distinction, space does the rest). */\nconst GROUP_TITLE_ACCENTS: Partial<Record<ServiceGroup, string>> = {\n \"creator-coins\": \"bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500 bg-clip-text text-transparent\",\n \"pop-protocol\": \"bg-gradient-to-r from-emerald-500 to-green-600 bg-clip-text text-transparent\",\n};\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-2\">\n <h2 className={cn(\"text-3xl sm:text-4xl font-black tracking-tight\", GROUP_TITLE_ACCENTS[group.key])}>\n {group.title}\n </h2>\n <p className=\"text-base sm:text-lg text-muted-foreground leading-relaxed max-w-2xl\">{group.tagline}</p>\n </div>\n );\n}\n\n/** POP Protocol companion column — open how-it-works steps, no extra panel. */\nconst POP_STEPS = [\n { title: \"Create your event badge\", body: \"Name it, add your artwork, and set who can claim — ready in minutes.\" },\n { title: \"Share the claim link\", body: \"Your community claims for free — one badge per person, no faking.\" },\n { title: \"It stays with them forever\", body: \"Badges can't be sold or transferred — lasting proof they were there.\" },\n];\n\nfunction PopHowItWorks() {\n return (\n <div className=\"flex flex-col justify-center gap-5 sm:gap-6 px-2 py-4 sm:py-0 sm:pl-6\">\n {POP_STEPS.map((step, i) => (\n <div key={step.title} className=\"flex gap-4\">\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 text-sm font-bold\">\n {i + 1}\n </span>\n <div className=\"space-y-0.5\">\n <p className=\"font-semibold\">{step.title}</p>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{step.body}</p>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ComingSoonStrip({ group, defs }: { group: ServiceGroupDefinition; defs: ServiceDefinition[] }) {\n return (\n <div className=\"rounded-2xl border border-border/40 p-5\">\n <p className=\"font-semibold text-sm\">{group.title}</p>\n <p className=\"text-sm text-muted-foreground mt-0.5\">{group.tagline}</p>\n <div className=\"flex flex-wrap gap-2 mt-4\">\n {defs.map(({ key, icon: Icon, title }) => (\n <div key={key} className=\"flex items-center gap-2 px-3 py-2 rounded-full bg-muted/30 border border-border/25\">\n <Icon className=\"h-3.5 w-3.5 text-muted-foreground/60\" />\n <span className=\"text-xs font-medium text-muted-foreground\">{title}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n /** Per-app hrefs / rollout flips, keyed by service key. */\n overrides: ServiceOverrides;\n className?: string;\n}\n\n/** The full grouped launchpad services block — section order comes from\n * LAUNCHPAD_SERVICE_GROUPS; cards from LAUNCHPAD_SERVICE_DEFINITIONS. */\nexport function LaunchpadGroupedSections({ overrides, className }: LaunchpadGroupedSectionsProps) {\n return (\n <div className={cn(\"space-y-20 sm:space-y-28\", className)}>\n {LAUNCHPAD_SERVICE_GROUPS.map((group) => {\n const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);\n if (defs.length === 0) return null;\n if (group.key === \"coming-soon\") {\n return <ComingSoonStrip key={group.key} group={group} defs={defs} />;\n }\n return (\n <motion.div\n key={group.key}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"space-y-7 sm:space-y-10\"\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5 sm:gap-7\">\n {defs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n {group.key === \"pop-protocol\" && <PopHowItWorks />}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
@@ -29,8 +29,10 @@ interface LaunchpadServiceCardProps {
|
|
|
29
29
|
override?: ServiceOverride;
|
|
30
30
|
/** Showcase layout — spans the full grid width (e.g. POP Protocol) */
|
|
31
31
|
featured?: boolean;
|
|
32
|
+
/** Grid position — drives the staggered entrance reveal. */
|
|
33
|
+
index?: number;
|
|
32
34
|
}
|
|
33
|
-
declare function LaunchpadServiceCard({ def, override, featured }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
35
|
+
declare function LaunchpadServiceCard({ def, override, featured, index }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
34
36
|
interface LaunchpadGroupedSectionsProps {
|
|
35
37
|
/** Per-app hrefs / rollout flips, keyed by service key. */
|
|
36
38
|
overrides: ServiceOverrides;
|
|
@@ -29,8 +29,10 @@ interface LaunchpadServiceCardProps {
|
|
|
29
29
|
override?: ServiceOverride;
|
|
30
30
|
/** Showcase layout — spans the full grid width (e.g. POP Protocol) */
|
|
31
31
|
featured?: boolean;
|
|
32
|
+
/** Grid position — drives the staggered entrance reveal. */
|
|
33
|
+
index?: number;
|
|
32
34
|
}
|
|
33
|
-
declare function LaunchpadServiceCard({ def, override, featured }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
35
|
+
declare function LaunchpadServiceCard({ def, override, featured, index }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
34
36
|
interface LaunchpadGroupedSectionsProps {
|
|
35
37
|
/** Per-app hrefs / rollout flips, keyed by service key. */
|
|
36
38
|
overrides: ServiceOverrides;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Link from "next/link";
|
|
4
|
-
import { motion } from "framer-motion";
|
|
4
|
+
import { motion, useReducedMotion } from "framer-motion";
|
|
5
5
|
import { Lock, ArrowRight, Check } from "lucide-react";
|
|
6
6
|
import { cn } from "../utils/cn.js";
|
|
7
7
|
import {
|
|
@@ -31,85 +31,129 @@ const SERVICE_HUES = {
|
|
|
31
31
|
"claim-collection": { text: "text-cyan-600 dark:text-cyan-400", solid: "bg-cyan-500", border: "border-cyan-500/25", pill: "bg-gradient-to-r from-cyan-500 to-sky-600" },
|
|
32
32
|
"claim-collection-name": { text: "text-pink-600 dark:text-pink-400", solid: "bg-pink-500", border: "border-pink-500/25", pill: "bg-gradient-to-r from-pink-500 to-rose-600" }
|
|
33
33
|
};
|
|
34
|
-
function LaunchpadServiceCard({ def, override = {}, featured = false }) {
|
|
34
|
+
function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0 }) {
|
|
35
35
|
const { key, icon: Icon, title, browseLinkLabel, features, example } = def;
|
|
36
36
|
const status = override.status ?? def.status;
|
|
37
37
|
const blurb = override.blurb ?? def.blurb;
|
|
38
38
|
const { href, browseHref } = override;
|
|
39
|
+
const reduceMotion = useReducedMotion();
|
|
39
40
|
const live = status === "live";
|
|
40
41
|
const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;
|
|
41
|
-
return /* @__PURE__ */
|
|
42
|
-
|
|
42
|
+
return /* @__PURE__ */ jsx(
|
|
43
|
+
motion.div,
|
|
43
44
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
!live && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1", children: [
|
|
60
|
-
/* @__PURE__ */ jsx(Lock, { className: "h-3 w-3" }),
|
|
61
|
-
"Coming soon"
|
|
62
|
-
] })
|
|
63
|
-
] }),
|
|
64
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
65
|
-
/* @__PURE__ */ jsx("h3", { className: "text-2xl sm:text-3xl font-black tracking-tight leading-snug", children: title }),
|
|
66
|
-
/* @__PURE__ */ jsx("p", { className: cn("text-[15px] leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb }),
|
|
67
|
-
live && example && /* @__PURE__ */ jsxs("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
68
|
-
"e.g. ",
|
|
69
|
-
example
|
|
70
|
-
] })
|
|
71
|
-
] }),
|
|
72
|
-
live && features.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ jsxs(
|
|
73
|
-
"span",
|
|
74
|
-
{
|
|
75
|
-
className: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground",
|
|
76
|
-
children: [
|
|
77
|
-
/* @__PURE__ */ jsx(Check, { className: cn("h-3 w-3 shrink-0", hue.text) }),
|
|
78
|
-
feature
|
|
79
|
-
]
|
|
80
|
-
},
|
|
81
|
-
feature
|
|
82
|
-
)) }),
|
|
83
|
-
live && href && /* @__PURE__ */ jsx(Link, { href, "aria-label": `${def.cta} \u2014 ${title}`, className: "absolute inset-0 z-10" }),
|
|
84
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-auto pt-1 flex items-end justify-between gap-3", children: [
|
|
85
|
-
live && browseHref && browseLinkLabel ? /* @__PURE__ */ jsxs(
|
|
86
|
-
Link,
|
|
87
|
-
{
|
|
88
|
-
href: browseHref,
|
|
89
|
-
className: "relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground",
|
|
90
|
-
children: [
|
|
91
|
-
browseLinkLabel,
|
|
92
|
-
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3" })
|
|
93
|
-
]
|
|
94
|
-
}
|
|
95
|
-
) : /* @__PURE__ */ jsx("span", {}),
|
|
96
|
-
live && /* @__PURE__ */ jsxs(
|
|
45
|
+
initial: { opacity: 0, y: reduceMotion ? 0 : 16 },
|
|
46
|
+
whileInView: { opacity: 1, y: 0 },
|
|
47
|
+
viewport: { once: true, margin: "-40px" },
|
|
48
|
+
transition: { duration: 0.45, delay: index * 0.06, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
49
|
+
className: cn("flex", featured && "sm:col-span-2"),
|
|
50
|
+
children: /* @__PURE__ */ jsxs(
|
|
51
|
+
"div",
|
|
52
|
+
{
|
|
53
|
+
className: cn(
|
|
54
|
+
"group relative flex flex-1 rounded-2xl transition-transform duration-300 ease-out",
|
|
55
|
+
// the hue gradient frame lives in the 1px padding; press + lift are the interaction
|
|
56
|
+
live && "p-px active:scale-[0.985] sm:hover:-translate-y-1 motion-reduce:transform-none motion-reduce:transition-none"
|
|
57
|
+
),
|
|
58
|
+
children: [
|
|
59
|
+
live && /* @__PURE__ */ jsx(
|
|
97
60
|
"span",
|
|
98
61
|
{
|
|
62
|
+
"aria-hidden": true,
|
|
99
63
|
className: cn(
|
|
100
|
-
"
|
|
101
|
-
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
64
|
+
"absolute inset-0 rounded-2xl opacity-40 sm:group-hover:opacity-100 transition-opacity duration-500 pointer-events-none",
|
|
102
65
|
hue.pill
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsxs(
|
|
70
|
+
"div",
|
|
71
|
+
{
|
|
72
|
+
className: cn(
|
|
73
|
+
"relative flex flex-1 flex-col overflow-hidden min-h-[240px]",
|
|
74
|
+
live ? "rounded-[15px] bg-card" : "rounded-2xl border border-border/30 bg-card dark:bg-white/[0.02] opacity-75"
|
|
103
75
|
),
|
|
104
76
|
children: [
|
|
105
|
-
|
|
106
|
-
|
|
77
|
+
live && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
78
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute -top-16 -left-12 h-48 w-48 rounded-full blur-3xl opacity-[0.18] sm:group-hover:opacity-30 transition-opacity duration-500 pointer-events-none", hue.solid) }),
|
|
79
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute -bottom-24 -right-16 h-56 w-56 rounded-full blur-3xl opacity-[0.10] sm:group-hover:opacity-20 transition-opacity duration-500 pointer-events-none", hue.solid) })
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsx(
|
|
82
|
+
"div",
|
|
83
|
+
{
|
|
84
|
+
"aria-hidden": true,
|
|
85
|
+
className: cn(
|
|
86
|
+
"absolute -right-8 -bottom-10 select-none pointer-events-none transition-all duration-500",
|
|
87
|
+
live ? "opacity-[0.05] sm:group-hover:opacity-[0.09] sm:group-hover:-translate-y-1 motion-reduce:transform-none" : "opacity-[0.03]"
|
|
88
|
+
),
|
|
89
|
+
children: /* @__PURE__ */ jsx(Icon, { className: cn("h-44 w-44", live ? hue.text : "text-muted-foreground") })
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col flex-1 p-6 sm:p-8 gap-4 sm:gap-5", children: [
|
|
93
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
94
|
+
live ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
95
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute -inset-2 rounded-2xl blur-xl opacity-40 sm:group-hover:opacity-60 transition-opacity duration-500", hue.solid) }),
|
|
96
|
+
/* @__PURE__ */ jsx("span", { className: cn("relative flex h-14 w-14 items-center justify-center rounded-2xl text-white shadow-lg shadow-black/25 transition-transform duration-300 sm:group-hover:scale-105 motion-reduce:transform-none", hue.pill), children: /* @__PURE__ */ jsx(Icon, { className: "h-7 w-7" }) })
|
|
97
|
+
] }) : /* @__PURE__ */ jsx(Icon, { className: "h-9 w-9 shrink-0 text-muted-foreground/50" }),
|
|
98
|
+
!live && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1", children: [
|
|
99
|
+
/* @__PURE__ */ jsx(Lock, { className: "h-3 w-3" }),
|
|
100
|
+
"Coming soon"
|
|
101
|
+
] })
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
104
|
+
/* @__PURE__ */ jsx("h3", { className: "text-2xl sm:text-3xl font-black tracking-tight leading-snug", children: title }),
|
|
105
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-[15px] leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb }),
|
|
106
|
+
live && example && /* @__PURE__ */ jsxs("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
107
|
+
"e.g. ",
|
|
108
|
+
example
|
|
109
|
+
] })
|
|
110
|
+
] }),
|
|
111
|
+
live && features.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ jsxs(
|
|
112
|
+
"span",
|
|
113
|
+
{
|
|
114
|
+
className: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground",
|
|
115
|
+
children: [
|
|
116
|
+
/* @__PURE__ */ jsx(Check, { className: cn("h-3 w-3 shrink-0", hue.text) }),
|
|
117
|
+
feature
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
feature
|
|
121
|
+
)) }),
|
|
122
|
+
live && href && /* @__PURE__ */ jsx(Link, { href, "aria-label": `${def.cta} \u2014 ${title}`, className: "absolute inset-0 z-10" }),
|
|
123
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-auto pt-1 flex items-end justify-between gap-3", children: [
|
|
124
|
+
live && browseHref && browseLinkLabel ? /* @__PURE__ */ jsxs(
|
|
125
|
+
Link,
|
|
126
|
+
{
|
|
127
|
+
href: browseHref,
|
|
128
|
+
className: "relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground sm:hover:text-foreground transition-colors",
|
|
129
|
+
children: [
|
|
130
|
+
browseLinkLabel,
|
|
131
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3" })
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
) : /* @__PURE__ */ jsx("span", {}),
|
|
135
|
+
live && /* @__PURE__ */ jsxs(
|
|
136
|
+
"span",
|
|
137
|
+
{
|
|
138
|
+
className: cn(
|
|
139
|
+
"inline-flex items-center gap-2 h-10 px-5 rounded-full",
|
|
140
|
+
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
141
|
+
hue.pill
|
|
142
|
+
),
|
|
143
|
+
children: [
|
|
144
|
+
def.cta,
|
|
145
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4 transition-transform duration-300 sm:group-hover:translate-x-0.5 motion-reduce:transform-none" })
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
] })
|
|
150
|
+
] })
|
|
107
151
|
]
|
|
108
152
|
}
|
|
109
153
|
)
|
|
110
|
-
]
|
|
111
|
-
|
|
112
|
-
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
)
|
|
113
157
|
}
|
|
114
158
|
);
|
|
115
159
|
}
|
|
@@ -148,7 +192,7 @@ function ComingSoonStrip({ group, defs }) {
|
|
|
148
192
|
] });
|
|
149
193
|
}
|
|
150
194
|
function LaunchpadGroupedSections({ overrides, className }) {
|
|
151
|
-
return /* @__PURE__ */ jsx("div", { className: cn("space-y-
|
|
195
|
+
return /* @__PURE__ */ jsx("div", { className: cn("space-y-20 sm:space-y-28", className), children: LAUNCHPAD_SERVICE_GROUPS.map((group) => {
|
|
152
196
|
const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);
|
|
153
197
|
if (defs.length === 0) return null;
|
|
154
198
|
if (group.key === "coming-soon") {
|
|
@@ -160,11 +204,11 @@ function LaunchpadGroupedSections({ overrides, className }) {
|
|
|
160
204
|
initial: { opacity: 0, y: 8 },
|
|
161
205
|
animate: { opacity: 1, y: 0 },
|
|
162
206
|
transition: { duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
163
|
-
className: "space-y-
|
|
207
|
+
className: "space-y-7 sm:space-y-10",
|
|
164
208
|
children: [
|
|
165
209
|
/* @__PURE__ */ jsx(GroupHeader, { group }),
|
|
166
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-
|
|
167
|
-
defs.map((def) => /* @__PURE__ */ jsx(LaunchpadServiceCard, { def, override: overrides[def.key] }, def.key)),
|
|
210
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-5 sm:gap-7", children: [
|
|
211
|
+
defs.map((def, i) => /* @__PURE__ */ jsx(LaunchpadServiceCard, { def, override: overrides[def.key], index: i }, def.key)),
|
|
168
212
|
group.key === "pop-protocol" && /* @__PURE__ */ jsx(PopHowItWorks, {})
|
|
169
213
|
] })
|
|
170
214
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Launchpad grouped services — the single source for the /launchpad page UI\n * in medialane-io and medialane-starknet.\n *\n * Card philosophy (creator-first redesign, 2026-06-10): the whole card is the\n * action. One title, one creator-language sentence (def.blurb), one unique hue\n * per service — no buttons repeating the title, no status badges, no tech\n * chips, no hover-only effects (mobile first: press states only).\n *\n * Apps own: hrefs + per-app rollout status flips. Everything else lives here.\n */\n\nimport Link from \"next/link\";\nimport { motion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\n// ── Per-app injection points ─────────────────────────────────────────────────\n\nexport interface ServiceOverride {\n /** Primary destination — the whole card links here (required for live services) */\n href?: string;\n /** Secondary browse link href (pairs with the def's browseLinkLabel) */\n browseHref?: string;\n /** Per-app rollout flips (e.g. coins live on one app first) */\n status?: ServiceStatus;\n /** Per-app one-liner override (rarely needed) */\n blurb?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n// ── One unique hue per service — never repeated inside a group ───────────────\n\ninterface ServiceHue {\n /** icon tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — icon glow */\n solid: string;\n /** thin card border tint */\n border: string;\n /** vivid two-stop gradient for the action pill (asset-page button language) */\n pill: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n border: \"border-sky-500/25\",\n pill: \"bg-gradient-to-r from-sky-500 to-blue-600\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n // Single Editions — blue + green\n \"mint-ip-asset\": { text: \"text-blue-600 dark:text-blue-400\", solid: \"bg-blue-500\", border: \"border-blue-500/25\", pill: \"bg-gradient-to-r from-blue-500 to-sky-600\" },\n \"create-collection\": { text: \"text-green-600 dark:text-green-400\", solid: \"bg-green-500\", border: \"border-green-500/25\", pill: \"bg-gradient-to-r from-green-500 to-emerald-600\" },\n // Limited Editions — purple + red\n \"ip-collection-1155\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", border: \"border-purple-500/25\", pill: \"bg-gradient-to-r from-purple-500 to-violet-600\" },\n \"mint-editions\": { text: \"text-red-600 dark:text-red-400\", solid: \"bg-red-500\", border: \"border-red-500/25\", pill: \"bg-gradient-to-r from-red-500 to-rose-600\" },\n // Creator Coins & Memecoins — yellow + orange\n \"creator-coins\": { text: \"text-yellow-600 dark:text-yellow-400\", solid: \"bg-yellow-500\", border: \"border-yellow-500/25\", pill: \"bg-gradient-to-r from-yellow-500 to-amber-500\" },\n \"claim-memecoin\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-amber-600\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-red-500\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", border: \"border-emerald-500/25\", pill: \"bg-gradient-to-r from-emerald-500 to-green-600\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", border: \"border-indigo-500/25\", pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\" },\n \"claim-username\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", border: \"border-violet-500/25\", pill: \"bg-gradient-to-r from-violet-500 to-fuchsia-600\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", border: \"border-cyan-500/25\", pill: \"bg-gradient-to-r from-cyan-500 to-sky-600\" },\n \"claim-collection-name\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", border: \"border-pink-500/25\", pill: \"bg-gradient-to-r from-pink-500 to-rose-600\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n /** Showcase layout — spans the full grid width (e.g. POP Protocol) */\n featured?: boolean;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, featured = false }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel, features, example } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href, browseHref } = override;\n\n const live = status === \"live\";\n const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;\n\n return (\n <div\n className={cn(\n // dark surfaces stay close to the canvas — the hue border does the talking\n \"relative rounded-2xl border bg-card dark:bg-white/[0.02] overflow-hidden flex flex-col flex-1 min-h-[210px]\",\n \"transition-transform\",\n live ? cn(hue.border, \"active:scale-[0.99]\") : \"border-border/30 opacity-70\",\n featured && \"sm:col-span-2\",\n )}\n >\n {/* Giant watermark icon, ghosted in the corner (Drop-Pages-panel language) */}\n <div aria-hidden className=\"absolute -right-8 -bottom-10 opacity-[0.04] select-none pointer-events-none\">\n <Icon className=\"h-44 w-44\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 sm:p-8 gap-4 sm:gap-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"relative\">\n {live && (\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n )}\n <Icon className={cn(\"relative h-9 w-9 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n </div>\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-2xl sm:text-3xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n {live && example && (\n <p className=\"text-[13px] leading-relaxed text-muted-foreground/70 italic\">\n e.g. {example}\n </p>\n )}\n </div>\n\n {/* Feature showcase — plain-language chips */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground\"\n >\n <Check className={cn(\"h-3 w-3 shrink-0\", hue.text)} />\n {feature}\n </span>\n ))}\n </div>\n )}\n\n {/* Stretched link — the whole card is the action; the pill is the visual cue */}\n {live && href && <Link href={href} aria-label={`${def.cta} — ${title}`} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between gap-3\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-10 px-5 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {def.cta}\n <ArrowRight className=\"h-4 w-4\" />\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\n/** Vivid gradient titles give special sections identity without boxing them in\n * (no panels inside panels — color carries the distinction, space does the rest). */\nconst GROUP_TITLE_ACCENTS: Partial<Record<ServiceGroup, string>> = {\n \"creator-coins\": \"bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500 bg-clip-text text-transparent\",\n \"pop-protocol\": \"bg-gradient-to-r from-emerald-500 to-green-600 bg-clip-text text-transparent\",\n};\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-2\">\n <h2 className={cn(\"text-3xl sm:text-4xl font-black tracking-tight\", GROUP_TITLE_ACCENTS[group.key])}>\n {group.title}\n </h2>\n <p className=\"text-base sm:text-lg text-muted-foreground leading-relaxed max-w-2xl\">{group.tagline}</p>\n </div>\n );\n}\n\n/** POP Protocol companion column — open how-it-works steps, no extra panel. */\nconst POP_STEPS = [\n { title: \"Create your event badge\", body: \"Name it, add your artwork, and set who can claim — ready in minutes.\" },\n { title: \"Share the claim link\", body: \"Your community claims for free — one badge per person, no faking.\" },\n { title: \"It stays with them forever\", body: \"Badges can't be sold or transferred — lasting proof they were there.\" },\n];\n\nfunction PopHowItWorks() {\n return (\n <div className=\"flex flex-col justify-center gap-5 sm:gap-6 px-2 py-4 sm:py-0 sm:pl-6\">\n {POP_STEPS.map((step, i) => (\n <div key={step.title} className=\"flex gap-4\">\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 text-sm font-bold\">\n {i + 1}\n </span>\n <div className=\"space-y-0.5\">\n <p className=\"font-semibold\">{step.title}</p>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{step.body}</p>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ComingSoonStrip({ group, defs }: { group: ServiceGroupDefinition; defs: ServiceDefinition[] }) {\n return (\n <div className=\"rounded-2xl border border-border/40 p-5\">\n <p className=\"font-semibold text-sm\">{group.title}</p>\n <p className=\"text-sm text-muted-foreground mt-0.5\">{group.tagline}</p>\n <div className=\"flex flex-wrap gap-2 mt-4\">\n {defs.map(({ key, icon: Icon, title }) => (\n <div key={key} className=\"flex items-center gap-2 px-3 py-2 rounded-full bg-muted/30 border border-border/25\">\n <Icon className=\"h-3.5 w-3.5 text-muted-foreground/60\" />\n <span className=\"text-xs font-medium text-muted-foreground\">{title}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n /** Per-app hrefs / rollout flips, keyed by service key. */\n overrides: ServiceOverrides;\n className?: string;\n}\n\n/** The full grouped launchpad services block — section order comes from\n * LAUNCHPAD_SERVICE_GROUPS; cards from LAUNCHPAD_SERVICE_DEFINITIONS. */\nexport function LaunchpadGroupedSections({ overrides, className }: LaunchpadGroupedSectionsProps) {\n return (\n <div className={cn(\"space-y-16 sm:space-y-24\", className)}>\n {LAUNCHPAD_SERVICE_GROUPS.map((group) => {\n const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);\n if (defs.length === 0) return null;\n if (group.key === \"coming-soon\") {\n return <ComingSoonStrip key={group.key} group={group} defs={defs} />;\n }\n return (\n <motion.div\n key={group.key}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"space-y-6 sm:space-y-8\"\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6\">\n {defs.map((def) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} />\n ))}\n {group.key === \"pop-protocol\" && <PopHowItWorks />}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Launchpad grouped services — the single source for the /launchpad page UI\n * in medialane-io and medialane-starknet.\n *\n * Card philosophy (creator-first redesign 2026-06-10; \"living color cards\"\n * high-fidelity pass 2026-06-27): the whole card is the action. One title, one\n * creator-language sentence (def.blurb), one unique hue per service. The hue is\n * not locked in a thin border — it saturates the whole card as ambient light:\n * an aurora glow behind a gradient icon tile, a hairline gradient frame that\n * ignites on interaction, a staggered entrance reveal, and press/hover\n * microinteractions. Touch-first (press states are primary; hover is desktop\n * polish, gated to sm+ and degraded under reduced-motion).\n *\n * Apps own: hrefs + per-app rollout status flips. Everything else lives here.\n */\n\nimport Link from \"next/link\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\n// ── Per-app injection points ─────────────────────────────────────────────────\n\nexport interface ServiceOverride {\n /** Primary destination — the whole card links here (required for live services) */\n href?: string;\n /** Secondary browse link href (pairs with the def's browseLinkLabel) */\n browseHref?: string;\n /** Per-app rollout flips (e.g. coins live on one app first) */\n status?: ServiceStatus;\n /** Per-app one-liner override (rarely needed) */\n blurb?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n// ── One unique hue per service — never repeated inside a group ───────────────\n\ninterface ServiceHue {\n /** icon tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — icon glow */\n solid: string;\n /** thin card border tint */\n border: string;\n /** vivid two-stop gradient for the action pill (asset-page button language) */\n pill: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n border: \"border-sky-500/25\",\n pill: \"bg-gradient-to-r from-sky-500 to-blue-600\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n // Single Editions — blue + green\n \"mint-ip-asset\": { text: \"text-blue-600 dark:text-blue-400\", solid: \"bg-blue-500\", border: \"border-blue-500/25\", pill: \"bg-gradient-to-r from-blue-500 to-sky-600\" },\n \"create-collection\": { text: \"text-green-600 dark:text-green-400\", solid: \"bg-green-500\", border: \"border-green-500/25\", pill: \"bg-gradient-to-r from-green-500 to-emerald-600\" },\n // Limited Editions — purple + red\n \"ip-collection-1155\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", border: \"border-purple-500/25\", pill: \"bg-gradient-to-r from-purple-500 to-violet-600\" },\n \"mint-editions\": { text: \"text-red-600 dark:text-red-400\", solid: \"bg-red-500\", border: \"border-red-500/25\", pill: \"bg-gradient-to-r from-red-500 to-rose-600\" },\n // Creator Coins & Memecoins — yellow + orange\n \"creator-coins\": { text: \"text-yellow-600 dark:text-yellow-400\", solid: \"bg-yellow-500\", border: \"border-yellow-500/25\", pill: \"bg-gradient-to-r from-yellow-500 to-amber-500\" },\n \"claim-memecoin\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-amber-600\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-red-500\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", border: \"border-emerald-500/25\", pill: \"bg-gradient-to-r from-emerald-500 to-green-600\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", border: \"border-indigo-500/25\", pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\" },\n \"claim-username\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", border: \"border-violet-500/25\", pill: \"bg-gradient-to-r from-violet-500 to-fuchsia-600\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", border: \"border-cyan-500/25\", pill: \"bg-gradient-to-r from-cyan-500 to-sky-600\" },\n \"claim-collection-name\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", border: \"border-pink-500/25\", pill: \"bg-gradient-to-r from-pink-500 to-rose-600\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n /** Showcase layout — spans the full grid width (e.g. POP Protocol) */\n featured?: boolean;\n /** Grid position — drives the staggered entrance reveal. */\n index?: number;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0 }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel, features, example } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href, browseHref } = override;\n const reduceMotion = useReducedMotion();\n\n const live = status === \"live\";\n const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;\n\n return (\n <motion.div\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n whileInView={{ opacity: 1, y: 0 }}\n viewport={{ once: true, margin: \"-40px\" }}\n transition={{ duration: 0.45, delay: index * 0.06, ease: [0.25, 0.46, 0.45, 0.94] }}\n className={cn(\"flex\", featured && \"sm:col-span-2\")}\n >\n <div\n className={cn(\n \"group relative flex flex-1 rounded-2xl transition-transform duration-300 ease-out\",\n // the hue gradient frame lives in the 1px padding; press + lift are the interaction\n live && \"p-px active:scale-[0.985] sm:hover:-translate-y-1 motion-reduce:transform-none motion-reduce:transition-none\",\n )}\n >\n {/* Hue gradient frame — a quiet hairline that ignites on interaction (live only) */}\n {live && (\n <span\n aria-hidden\n className={cn(\n \"absolute inset-0 rounded-2xl opacity-40 sm:group-hover:opacity-100 transition-opacity duration-500 pointer-events-none\",\n hue.pill,\n )}\n />\n )}\n\n {/* Inner surface */}\n <div\n className={cn(\n \"relative flex flex-1 flex-col overflow-hidden min-h-[240px]\",\n live ? \"rounded-[15px] bg-card\" : \"rounded-2xl border border-border/30 bg-card dark:bg-white/[0.02] opacity-75\",\n )}\n >\n {/* Aurora light-leaks — the hue saturates the whole card as ambient light */}\n {live && (\n <>\n <span aria-hidden className={cn(\"absolute -top-16 -left-12 h-48 w-48 rounded-full blur-3xl opacity-[0.18] sm:group-hover:opacity-30 transition-opacity duration-500 pointer-events-none\", hue.solid)} />\n <span aria-hidden className={cn(\"absolute -bottom-24 -right-16 h-56 w-56 rounded-full blur-3xl opacity-[0.10] sm:group-hover:opacity-20 transition-opacity duration-500 pointer-events-none\", hue.solid)} />\n </>\n )}\n\n {/* Giant watermark icon, ghosted in the corner — drifts on hover */}\n <div\n aria-hidden\n className={cn(\n \"absolute -right-8 -bottom-10 select-none pointer-events-none transition-all duration-500\",\n live ? \"opacity-[0.05] sm:group-hover:opacity-[0.09] sm:group-hover:-translate-y-1 motion-reduce:transform-none\" : \"opacity-[0.03]\",\n )}\n >\n <Icon className={cn(\"h-44 w-44\", live ? hue.text : \"text-muted-foreground\")} />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 sm:p-8 gap-4 sm:gap-5\">\n <div className=\"flex items-start justify-between gap-3\">\n {live ? (\n <div className=\"relative\">\n <span aria-hidden className={cn(\"absolute -inset-2 rounded-2xl blur-xl opacity-40 sm:group-hover:opacity-60 transition-opacity duration-500\", hue.solid)} />\n <span className={cn(\"relative flex h-14 w-14 items-center justify-center rounded-2xl text-white shadow-lg shadow-black/25 transition-transform duration-300 sm:group-hover:scale-105 motion-reduce:transform-none\", hue.pill)}>\n <Icon className=\"h-7 w-7\" />\n </span>\n </div>\n ) : (\n <Icon className=\"h-9 w-9 shrink-0 text-muted-foreground/50\" />\n )}\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-2xl sm:text-3xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n {live && example && (\n <p className=\"text-[13px] leading-relaxed text-muted-foreground/70 italic\">\n e.g. {example}\n </p>\n )}\n </div>\n\n {/* Feature showcase — plain-language chips */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground\"\n >\n <Check className={cn(\"h-3 w-3 shrink-0\", hue.text)} />\n {feature}\n </span>\n ))}\n </div>\n )}\n\n {/* Stretched link — the whole card is the action; the pill is the visual cue */}\n {live && href && <Link href={href} aria-label={`${def.cta} — ${title}`} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between gap-3\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground sm:hover:text-foreground transition-colors\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-10 px-5 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {def.cta}\n <ArrowRight className=\"h-4 w-4 transition-transform duration-300 sm:group-hover:translate-x-0.5 motion-reduce:transform-none\" />\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n </motion.div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\n/** Vivid gradient titles give special sections identity without boxing them in\n * (no panels inside panels — color carries the distinction, space does the rest). */\nconst GROUP_TITLE_ACCENTS: Partial<Record<ServiceGroup, string>> = {\n \"creator-coins\": \"bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500 bg-clip-text text-transparent\",\n \"pop-protocol\": \"bg-gradient-to-r from-emerald-500 to-green-600 bg-clip-text text-transparent\",\n};\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-2\">\n <h2 className={cn(\"text-3xl sm:text-4xl font-black tracking-tight\", GROUP_TITLE_ACCENTS[group.key])}>\n {group.title}\n </h2>\n <p className=\"text-base sm:text-lg text-muted-foreground leading-relaxed max-w-2xl\">{group.tagline}</p>\n </div>\n );\n}\n\n/** POP Protocol companion column — open how-it-works steps, no extra panel. */\nconst POP_STEPS = [\n { title: \"Create your event badge\", body: \"Name it, add your artwork, and set who can claim — ready in minutes.\" },\n { title: \"Share the claim link\", body: \"Your community claims for free — one badge per person, no faking.\" },\n { title: \"It stays with them forever\", body: \"Badges can't be sold or transferred — lasting proof they were there.\" },\n];\n\nfunction PopHowItWorks() {\n return (\n <div className=\"flex flex-col justify-center gap-5 sm:gap-6 px-2 py-4 sm:py-0 sm:pl-6\">\n {POP_STEPS.map((step, i) => (\n <div key={step.title} className=\"flex gap-4\">\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 text-sm font-bold\">\n {i + 1}\n </span>\n <div className=\"space-y-0.5\">\n <p className=\"font-semibold\">{step.title}</p>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{step.body}</p>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ComingSoonStrip({ group, defs }: { group: ServiceGroupDefinition; defs: ServiceDefinition[] }) {\n return (\n <div className=\"rounded-2xl border border-border/40 p-5\">\n <p className=\"font-semibold text-sm\">{group.title}</p>\n <p className=\"text-sm text-muted-foreground mt-0.5\">{group.tagline}</p>\n <div className=\"flex flex-wrap gap-2 mt-4\">\n {defs.map(({ key, icon: Icon, title }) => (\n <div key={key} className=\"flex items-center gap-2 px-3 py-2 rounded-full bg-muted/30 border border-border/25\">\n <Icon className=\"h-3.5 w-3.5 text-muted-foreground/60\" />\n <span className=\"text-xs font-medium text-muted-foreground\">{title}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n /** Per-app hrefs / rollout flips, keyed by service key. */\n overrides: ServiceOverrides;\n className?: string;\n}\n\n/** The full grouped launchpad services block — section order comes from\n * LAUNCHPAD_SERVICE_GROUPS; cards from LAUNCHPAD_SERVICE_DEFINITIONS. */\nexport function LaunchpadGroupedSections({ overrides, className }: LaunchpadGroupedSectionsProps) {\n return (\n <div className={cn(\"space-y-20 sm:space-y-28\", className)}>\n {LAUNCHPAD_SERVICE_GROUPS.map((group) => {\n const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);\n if (defs.length === 0) return null;\n if (group.key === \"coming-soon\") {\n return <ComingSoonStrip key={group.key} group={group} defs={defs} />;\n }\n return (\n <motion.div\n key={group.key}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"space-y-7 sm:space-y-10\"\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5 sm:gap-7\">\n {defs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n {group.key === \"pop-protocol\" && <PopHowItWorks />}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|