@medialane/ui 0.34.1 → 0.35.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/dist/components/asset-collection-bar.cjs +3 -33
- package/dist/components/asset-collection-bar.cjs.map +1 -1
- package/dist/components/asset-collection-bar.d.cts +4 -7
- package/dist/components/asset-collection-bar.d.ts +4 -7
- package/dist/components/asset-collection-bar.js +4 -34
- package/dist/components/asset-collection-bar.js.map +1 -1
- package/dist/components/asset-top-sections.cjs +7 -7
- package/dist/components/asset-top-sections.cjs.map +1 -1
- package/dist/components/asset-top-sections.js +7 -7
- package/dist/components/asset-top-sections.js.map +1 -1
- package/dist/components/asset-utility-icons.cjs +62 -0
- package/dist/components/asset-utility-icons.cjs.map +1 -0
- package/dist/components/asset-utility-icons.d.cts +15 -0
- package/dist/components/asset-utility-icons.d.ts +15 -0
- package/dist/components/asset-utility-icons.js +38 -0
- package/dist/components/asset-utility-icons.js.map +1 -0
- package/dist/components/launchpad-filter-bar.cjs +106 -0
- package/dist/components/launchpad-filter-bar.cjs.map +1 -0
- package/dist/components/launchpad-filter-bar.d.cts +23 -0
- package/dist/components/launchpad-filter-bar.d.ts +23 -0
- package/dist/components/launchpad-filter-bar.js +82 -0
- package/dist/components/launchpad-filter-bar.js.map +1 -0
- package/dist/components/launchpad-services.cjs +100 -39
- package/dist/components/launchpad-services.cjs.map +1 -1
- package/dist/components/launchpad-services.d.cts +2 -1
- package/dist/components/launchpad-services.d.ts +2 -1
- package/dist/components/launchpad-services.js +101 -40
- package/dist/components/launchpad-services.js.map +1 -1
- package/dist/data/launchpad-services.cjs +16 -41
- package/dist/data/launchpad-services.cjs.map +1 -1
- package/dist/data/launchpad-services.d.cts +1 -1
- package/dist/data/launchpad-services.d.ts +1 -1
- package/dist/data/launchpad-services.js +16 -41
- package/dist/data/launchpad-services.js.map +1 -1
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -39,7 +39,8 @@ interface LaunchpadGroupedSectionsProps {
|
|
|
39
39
|
className?: string;
|
|
40
40
|
}
|
|
41
41
|
/** The full grouped launchpad services block — section order comes from
|
|
42
|
-
* LAUNCHPAD_SERVICE_GROUPS; cards from LAUNCHPAD_SERVICE_DEFINITIONS.
|
|
42
|
+
* LAUNCHPAD_SERVICE_GROUPS; cards from LAUNCHPAD_SERVICE_DEFINITIONS.
|
|
43
|
+
* Owns the search/filter state so the grid can react to it live. */
|
|
43
44
|
declare function LaunchpadGroupedSections({ overrides, className }: LaunchpadGroupedSectionsProps): react_jsx_runtime.JSX.Element;
|
|
44
45
|
|
|
45
46
|
export { LaunchpadGroupedSections, type LaunchpadGroupedSectionsProps, LaunchpadServiceCard, type LaunchpadServiceCardProps, SERVICE_HUES, type ServiceOverride, type ServiceOverrides };
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
3
4
|
import Link from "next/link";
|
|
4
|
-
import { motion, useReducedMotion } from "framer-motion";
|
|
5
|
+
import { AnimatePresence, motion, useReducedMotion } from "framer-motion";
|
|
5
6
|
import { Lock, ArrowRight, Check } from "lucide-react";
|
|
6
7
|
import { cn } from "../utils/cn.js";
|
|
7
8
|
import {
|
|
8
9
|
LAUNCHPAD_SERVICE_DEFINITIONS,
|
|
9
10
|
LAUNCHPAD_SERVICE_GROUPS
|
|
10
11
|
} from "../data/launchpad-services.js";
|
|
12
|
+
import { LaunchpadFilterBar } from "./launchpad-filter-bar.js";
|
|
11
13
|
const DEFAULT_HUE = {
|
|
12
14
|
text: "text-sky-600 dark:text-sky-400",
|
|
13
15
|
solid: "bg-sky-500",
|
|
@@ -32,7 +34,7 @@ const SERVICE_HUES = {
|
|
|
32
34
|
"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
35
|
};
|
|
34
36
|
function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0 }) {
|
|
35
|
-
const { key, icon: Icon, title, browseLinkLabel, features
|
|
37
|
+
const { key, icon: Icon, title, browseLinkLabel, features } = def;
|
|
36
38
|
const status = override.status ?? def.status;
|
|
37
39
|
const blurb = override.blurb ?? def.blurb;
|
|
38
40
|
const { href, browseHref } = override;
|
|
@@ -42,8 +44,10 @@ function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0
|
|
|
42
44
|
return /* @__PURE__ */ jsx(
|
|
43
45
|
motion.div,
|
|
44
46
|
{
|
|
47
|
+
layout: !reduceMotion,
|
|
45
48
|
initial: { opacity: 0, y: reduceMotion ? 0 : 16 },
|
|
46
49
|
whileInView: { opacity: 1, y: 0 },
|
|
50
|
+
exit: { opacity: 0 },
|
|
47
51
|
viewport: { once: true, margin: "-40px" },
|
|
48
52
|
transition: { duration: 0.45, delay: index * 0.06, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
49
53
|
className: cn("flex", featured && "sm:col-span-2"),
|
|
@@ -70,7 +74,7 @@ function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0
|
|
|
70
74
|
"div",
|
|
71
75
|
{
|
|
72
76
|
className: cn(
|
|
73
|
-
"relative flex flex-1 flex-col overflow-hidden min-h-[
|
|
77
|
+
"relative flex flex-1 flex-col overflow-hidden min-h-[200px]",
|
|
74
78
|
live ? "rounded-[15px] bg-card" : "rounded-2xl border border-border/30 bg-card dark:bg-white/[0.02] opacity-75"
|
|
75
79
|
),
|
|
76
80
|
children: [
|
|
@@ -86,29 +90,25 @@ function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0
|
|
|
86
90
|
"absolute -right-8 -bottom-10 select-none pointer-events-none transition-all duration-500",
|
|
87
91
|
live ? "opacity-[0.05] sm:group-hover:opacity-[0.09] sm:group-hover:-translate-y-1 motion-reduce:transform-none" : "opacity-[0.03]"
|
|
88
92
|
),
|
|
89
|
-
children: /* @__PURE__ */ jsx(Icon, { className: cn("h-
|
|
93
|
+
children: /* @__PURE__ */ jsx(Icon, { className: cn("h-32 w-32", live ? hue.text : "text-muted-foreground") })
|
|
90
94
|
}
|
|
91
95
|
),
|
|
92
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col flex-1 p-
|
|
96
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col flex-1 p-5 sm:p-6 gap-3 sm:gap-4", children: [
|
|
93
97
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
94
98
|
live ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
95
99
|
/* @__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-
|
|
97
|
-
] }) : /* @__PURE__ */ jsx(Icon, { className: "h-
|
|
100
|
+
/* @__PURE__ */ jsx("span", { className: cn("relative flex h-12 w-12 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-6 w-6" }) })
|
|
101
|
+
] }) : /* @__PURE__ */ jsx(Icon, { className: "h-8 w-8 shrink-0 text-muted-foreground/50" }),
|
|
98
102
|
!live && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1", children: [
|
|
99
103
|
/* @__PURE__ */ jsx(Lock, { className: "h-3 w-3" }),
|
|
100
104
|
"Coming soon"
|
|
101
105
|
] })
|
|
102
106
|
] }),
|
|
103
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
104
|
-
/* @__PURE__ */ jsx("h3", { className: "text-
|
|
105
|
-
/* @__PURE__ */ jsx("p", { className: cn("text-
|
|
106
|
-
live && example && /* @__PURE__ */ jsxs("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
107
|
-
"e.g. ",
|
|
108
|
-
example
|
|
109
|
-
] })
|
|
107
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
108
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xl sm:text-2xl font-black tracking-tight leading-snug", children: title }),
|
|
109
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-sm leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb })
|
|
110
110
|
] }),
|
|
111
|
-
live && features.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ jsxs(
|
|
111
|
+
live && features.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: features.slice(0, 2).map((feature) => /* @__PURE__ */ jsxs(
|
|
112
112
|
"span",
|
|
113
113
|
{
|
|
114
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",
|
|
@@ -158,8 +158,8 @@ function LaunchpadServiceCard({ def, override = {}, featured = false, index = 0
|
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
160
|
const GROUP_TITLE_ACCENTS = {
|
|
161
|
-
"
|
|
162
|
-
"
|
|
161
|
+
"coins": "bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500 bg-clip-text text-transparent",
|
|
162
|
+
"community": "bg-gradient-to-r from-emerald-500 to-green-600 bg-clip-text text-transparent"
|
|
163
163
|
};
|
|
164
164
|
function GroupHeader({ group }) {
|
|
165
165
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
@@ -192,30 +192,91 @@ function ComingSoonStrip({ group, defs }) {
|
|
|
192
192
|
] });
|
|
193
193
|
}
|
|
194
194
|
function LaunchpadGroupedSections({ overrides, className }) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
195
|
+
const [query, setQuery] = useState("");
|
|
196
|
+
const [activeGroups, setActiveGroups] = useState(/* @__PURE__ */ new Set());
|
|
197
|
+
const [showComingSoon, setShowComingSoon] = useState(false);
|
|
198
|
+
const filterableGroups = LAUNCHPAD_SERVICE_GROUPS.filter((g) => g.key !== "coming-soon");
|
|
199
|
+
const toggleGroup = (key) => {
|
|
200
|
+
setActiveGroups((prev) => {
|
|
201
|
+
const next = new Set(prev);
|
|
202
|
+
if (next.has(key)) next.delete(key);
|
|
203
|
+
else next.add(key);
|
|
204
|
+
return next;
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
const matches = (def) => {
|
|
208
|
+
if (activeGroups.size > 0 && !activeGroups.has(def.group)) return false;
|
|
209
|
+
if (!showComingSoon && def.status !== "live") return false;
|
|
210
|
+
if (query.trim() === "") return true;
|
|
211
|
+
const haystack = `${def.title} ${def.blurb} ${def.subtitle}`.toLowerCase();
|
|
212
|
+
return haystack.includes(query.trim().toLowerCase());
|
|
213
|
+
};
|
|
214
|
+
const totalMatches = useMemo(
|
|
215
|
+
() => LAUNCHPAD_SERVICE_DEFINITIONS.filter(matches).length,
|
|
216
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
217
|
+
[query, activeGroups, showComingSoon]
|
|
218
|
+
);
|
|
219
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-8 sm:space-y-10", className), children: [
|
|
220
|
+
/* @__PURE__ */ jsx(
|
|
221
|
+
LaunchpadFilterBar,
|
|
203
222
|
{
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
223
|
+
query,
|
|
224
|
+
onQueryChange: setQuery,
|
|
225
|
+
groups: filterableGroups,
|
|
226
|
+
activeGroups,
|
|
227
|
+
onToggleGroup: toggleGroup,
|
|
228
|
+
showComingSoon,
|
|
229
|
+
onToggleComingSoon: setShowComingSoon,
|
|
230
|
+
resultCount: totalMatches
|
|
231
|
+
}
|
|
232
|
+
),
|
|
233
|
+
totalMatches === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-16 space-y-3", children: [
|
|
234
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "No services match" }),
|
|
235
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Try a different search or clear your filters." }),
|
|
236
|
+
/* @__PURE__ */ jsx(
|
|
237
|
+
"button",
|
|
238
|
+
{
|
|
239
|
+
type: "button",
|
|
240
|
+
onClick: () => {
|
|
241
|
+
setQuery("");
|
|
242
|
+
setActiveGroups(/* @__PURE__ */ new Set());
|
|
243
|
+
},
|
|
244
|
+
className: "inline-flex items-center h-9 px-4 rounded-full text-sm font-semibold bg-primary text-primary-foreground",
|
|
245
|
+
children: "Clear filters"
|
|
246
|
+
}
|
|
247
|
+
)
|
|
248
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "space-y-20 sm:space-y-28", children: /* @__PURE__ */ jsx(AnimatePresence, { children: LAUNCHPAD_SERVICE_GROUPS.map((group) => {
|
|
249
|
+
if (group.key === "coming-soon") {
|
|
250
|
+
const comingSoonDefs = LAUNCHPAD_SERVICE_DEFINITIONS.filter(
|
|
251
|
+
(d) => d.group === group.key && matches(d)
|
|
252
|
+
);
|
|
253
|
+
if (comingSoonDefs.length === 0) return null;
|
|
254
|
+
return /* @__PURE__ */ jsx(ComingSoonStrip, { group, defs: comingSoonDefs }, group.key);
|
|
255
|
+
}
|
|
256
|
+
const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key && matches(d));
|
|
257
|
+
if (defs.length === 0) return null;
|
|
258
|
+
const showPopHowItWorks = group.key === "community" && defs.some((d) => d.key === "pop-protocol");
|
|
259
|
+
return /* @__PURE__ */ jsxs(
|
|
260
|
+
motion.div,
|
|
261
|
+
{
|
|
262
|
+
layout: true,
|
|
263
|
+
initial: { opacity: 0, y: 8 },
|
|
264
|
+
animate: { opacity: 1, y: 0 },
|
|
265
|
+
exit: { opacity: 0 },
|
|
266
|
+
transition: { duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
267
|
+
className: "space-y-7 sm:space-y-10",
|
|
268
|
+
children: [
|
|
269
|
+
/* @__PURE__ */ jsx(GroupHeader, { group }),
|
|
270
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-5", children: [
|
|
271
|
+
defs.map((def, i) => /* @__PURE__ */ jsx(LaunchpadServiceCard, { def, override: overrides[def.key], index: i }, def.key)),
|
|
272
|
+
showPopHowItWorks && /* @__PURE__ */ jsx(PopHowItWorks, {})
|
|
273
|
+
] })
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
group.key
|
|
277
|
+
);
|
|
278
|
+
}) }) })
|
|
279
|
+
] });
|
|
219
280
|
}
|
|
220
281
|
export {
|
|
221
282
|
LaunchpadGroupedSections,
|
|
@@ -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; \"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":[]}
|
|
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 { useMemo, useState } from \"react\";\nimport Link from \"next/link\";\nimport { AnimatePresence, 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\";\nimport { LaunchpadFilterBar } from \"./launchpad-filter-bar.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 } = 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 layout={!reduceMotion}\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n whileInView={{ opacity: 1, y: 0 }}\n exit={{ opacity: 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-[200px]\",\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-32 w-32\", live ? hue.text : \"text-muted-foreground\")} />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-5 sm:p-6 gap-3 sm:gap-4\">\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-12 w-12 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-6 w-6\" />\n </span>\n </div>\n ) : (\n <Icon className=\"h-8 w-8 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-1.5\">\n <h3 className=\"text-xl sm:text-2xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-sm leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n </div>\n\n {/* Feature showcase — plain-language chips, capped at 2 for card density */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.slice(0, 2).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 \"coins\": \"bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500 bg-clip-text text-transparent\",\n \"community\": \"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.\n * Owns the search/filter state so the grid can react to it live. */\nexport function LaunchpadGroupedSections({ overrides, className }: LaunchpadGroupedSectionsProps) {\n const [query, setQuery] = useState(\"\");\n const [activeGroups, setActiveGroups] = useState<Set<ServiceGroup>>(new Set());\n const [showComingSoon, setShowComingSoon] = useState(false);\n\n const filterableGroups = LAUNCHPAD_SERVICE_GROUPS.filter((g) => g.key !== \"coming-soon\");\n\n const toggleGroup = (key: ServiceGroup) => {\n setActiveGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n\n const matches = (def: ServiceDefinition): boolean => {\n if (activeGroups.size > 0 && !activeGroups.has(def.group)) return false;\n if (!showComingSoon && def.status !== \"live\") return false;\n if (query.trim() === \"\") return true;\n const haystack = `${def.title} ${def.blurb} ${def.subtitle}`.toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n };\n\n const totalMatches = useMemo(\n () => LAUNCHPAD_SERVICE_DEFINITIONS.filter(matches).length,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [query, activeGroups, showComingSoon],\n );\n\n return (\n <div className={cn(\"space-y-8 sm:space-y-10\", className)}>\n <LaunchpadFilterBar\n query={query}\n onQueryChange={setQuery}\n groups={filterableGroups}\n activeGroups={activeGroups}\n onToggleGroup={toggleGroup}\n showComingSoon={showComingSoon}\n onToggleComingSoon={setShowComingSoon}\n resultCount={totalMatches}\n />\n\n {totalMatches === 0 ? (\n <div className=\"text-center py-16 space-y-3\">\n <p className=\"text-lg font-semibold\">No services match</p>\n <p className=\"text-sm text-muted-foreground\">Try a different search or clear your filters.</p>\n <button\n type=\"button\"\n onClick={() => { setQuery(\"\"); setActiveGroups(new Set()); }}\n className=\"inline-flex items-center h-9 px-4 rounded-full text-sm font-semibold bg-primary text-primary-foreground\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <div className=\"space-y-20 sm:space-y-28\">\n <AnimatePresence>\n {LAUNCHPAD_SERVICE_GROUPS.map((group) => {\n if (group.key === \"coming-soon\") {\n const comingSoonDefs = LAUNCHPAD_SERVICE_DEFINITIONS.filter(\n (d) => d.group === group.key && matches(d),\n );\n if (comingSoonDefs.length === 0) return null;\n return <ComingSoonStrip key={group.key} group={group} defs={comingSoonDefs} />;\n }\n\n const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key && matches(d));\n if (defs.length === 0) return null;\n\n const showPopHowItWorks = group.key === \"community\" && defs.some((d) => d.key === \"pop-protocol\");\n\n return (\n <motion.div\n key={group.key}\n layout\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 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 lg:grid-cols-3 gap-4 sm:gap-5\">\n {defs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n {showPopHowItWorks && <PopHowItWorks />}\n </div>\n </motion.div>\n );\n })}\n </AnimatePresence>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -24,12 +24,12 @@ __export(launchpad_services_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(launchpad_services_exports);
|
|
25
25
|
var import_lucide_react = require("lucide-react");
|
|
26
26
|
var import_sdk = require("@medialane/sdk");
|
|
27
|
-
const TICKETS_TRANSFERABLE_FEATURE = (0, import_sdk.hasCapability)("ip-tickets", "transfer") ? "
|
|
27
|
+
const TICKETS_TRANSFERABLE_FEATURE = (0, import_sdk.hasCapability)("ip-tickets", "transfer") ? "Freely transferable" : "Stays with the original holder";
|
|
28
28
|
const LAUNCHPAD_SERVICE_GROUPS = [
|
|
29
29
|
{
|
|
30
30
|
key: "single-edition",
|
|
31
|
-
title: "Single
|
|
32
|
-
tagline: "Publish one-of-a-kind pieces \u2014 a song, a photo, a film \u2014 under your own name."
|
|
31
|
+
title: "Single Edition",
|
|
32
|
+
tagline: "Publish one-of-a-kind pieces \u2014 a song, a photo, a film, a timed drop, or a remix \u2014 under your own name."
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
key: "limited-editions",
|
|
@@ -37,39 +37,14 @@ const LAUNCHPAD_SERVICE_GROUPS = [
|
|
|
37
37
|
tagline: "Release your work in numbered copies your fans can collect and trade."
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
-
key: "
|
|
41
|
-
title: "
|
|
40
|
+
key: "coins",
|
|
41
|
+
title: "Coins",
|
|
42
42
|
tagline: "Launch your own coin \u2014 or bring one you already made \u2014 and let your community back you."
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
|
-
key: "
|
|
46
|
-
title: "
|
|
47
|
-
tagline: "
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
key: "pop-protocol",
|
|
51
|
-
title: "POP Protocol",
|
|
52
|
-
tagline: "Give your community proof they were part of the moment."
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
key: "ip-tickets",
|
|
56
|
-
title: "IP Tickets",
|
|
57
|
-
tagline: "Sell tickets to your shows and events, verifiable on-chain."
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
key: "ip-sponsorship",
|
|
61
|
-
title: "IP Sponsorship",
|
|
62
|
-
tagline: "Let sponsors back your work directly, in exchange for a license."
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
key: "ip-club",
|
|
66
|
-
title: "IP Club",
|
|
67
|
-
tagline: "Give your closest fans a membership card that unlocks more."
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
key: "licensing-remix",
|
|
71
|
-
title: "Licensing & Remix",
|
|
72
|
-
tagline: "Let others build on your work \u2014 with credit and royalties flowing back to you."
|
|
45
|
+
key: "community",
|
|
46
|
+
title: "Community",
|
|
47
|
+
tagline: "Connect with the people who show up for you \u2014 badges, tickets, memberships, and direct sponsorship."
|
|
73
48
|
},
|
|
74
49
|
{
|
|
75
50
|
key: "claims",
|
|
@@ -178,7 +153,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
178
153
|
badge: "Create",
|
|
179
154
|
status: "live",
|
|
180
155
|
category: "create",
|
|
181
|
-
group: "
|
|
156
|
+
group: "single-edition"
|
|
182
157
|
},
|
|
183
158
|
// ── Launch ────────────────────────────────────────────────────────────────
|
|
184
159
|
{
|
|
@@ -199,7 +174,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
199
174
|
browseLinkLabel: "Browse events",
|
|
200
175
|
status: "live",
|
|
201
176
|
category: "launch",
|
|
202
|
-
group: "
|
|
177
|
+
group: "community"
|
|
203
178
|
},
|
|
204
179
|
{
|
|
205
180
|
key: "collection-drop",
|
|
@@ -219,7 +194,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
219
194
|
browseLinkLabel: "Browse drops",
|
|
220
195
|
status: "live",
|
|
221
196
|
category: "launch",
|
|
222
|
-
group: "
|
|
197
|
+
group: "single-edition"
|
|
223
198
|
},
|
|
224
199
|
{
|
|
225
200
|
key: "ip-tickets",
|
|
@@ -240,7 +215,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
240
215
|
// medialane-core/docs/deployments.md
|
|
241
216
|
status: "live",
|
|
242
217
|
category: "launch",
|
|
243
|
-
group: "
|
|
218
|
+
group: "community"
|
|
244
219
|
},
|
|
245
220
|
{
|
|
246
221
|
key: "ip-club",
|
|
@@ -261,7 +236,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
261
236
|
// medialane-core/docs/deployments.md
|
|
262
237
|
status: "live",
|
|
263
238
|
category: "launch",
|
|
264
|
-
group: "
|
|
239
|
+
group: "community"
|
|
265
240
|
},
|
|
266
241
|
{
|
|
267
242
|
key: "ip-sponsorship",
|
|
@@ -283,7 +258,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
283
258
|
// medialane-core/docs/deployments.md
|
|
284
259
|
status: "live",
|
|
285
260
|
category: "launch",
|
|
286
|
-
group: "
|
|
261
|
+
group: "community"
|
|
287
262
|
},
|
|
288
263
|
// ── Monetize ─────────────────────────────────────────────────────────────
|
|
289
264
|
{
|
|
@@ -303,7 +278,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
303
278
|
badge: "Launch",
|
|
304
279
|
status: "live",
|
|
305
280
|
category: "monetize",
|
|
306
|
-
group: "
|
|
281
|
+
group: "coins"
|
|
307
282
|
},
|
|
308
283
|
// ── Claims ────────────────────────────────────────────────────────────────
|
|
309
284
|
{
|
|
@@ -323,7 +298,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
323
298
|
badge: "Claim",
|
|
324
299
|
status: "live",
|
|
325
300
|
category: "monetize",
|
|
326
|
-
group: "
|
|
301
|
+
group: "coins"
|
|
327
302
|
},
|
|
328
303
|
{
|
|
329
304
|
key: "claim-username",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/data/launchpad-services.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport {\n ImagePlus, Layers, GitBranch,\n Award, Package, PlusCircle,\n Ticket, Users, Handshake,\n Coins, TrendingUp,\n AtSign, FolderInput, Link2,\n} from \"lucide-react\";\nimport { hasCapability } from \"@medialane/sdk\";\n\nconst TICKETS_TRANSFERABLE_FEATURE = hasCapability(\"ip-tickets\", \"transfer\")\n ? \"Transferable ERC-721\"\n : \"Non-transferable, soulbound to your wallet\";\n\nexport type ServiceStatus = \"live\" | \"building\" | \"soon\";\nexport type ServiceCategory = \"create\" | \"launch\" | \"monetize\";\n\nexport type ServiceGroup =\n | \"single-edition\"\n | \"limited-editions\"\n | \"creator-coins\"\n | \"collection-drop\"\n | \"pop-protocol\"\n | \"ip-tickets\"\n | \"ip-sponsorship\"\n | \"ip-club\"\n | \"licensing-remix\"\n | \"claims\"\n | \"coming-soon\";\n\nexport interface ServiceGroupDefinition {\n key: ServiceGroup;\n title: string;\n /** One line of plain creator language: what does this group do for my portfolio/revenue? */\n tagline: string;\n /** Optional small chip next to the title (e.g. the token standard) */\n badge?: string;\n}\n\n/** Ordered — launchpad pages render sections in this order. */\nexport const LAUNCHPAD_SERVICE_GROUPS: ServiceGroupDefinition[] = [\n {\n key: \"single-edition\",\n title: \"Single Editions\",\n tagline: \"Publish one-of-a-kind pieces \\u2014 a song, a photo, a film \\u2014 under your own name.\",\n },\n {\n key: \"limited-editions\",\n title: \"Limited Editions\",\n tagline: \"Release your work in numbered copies your fans can collect and trade.\",\n },\n {\n key: \"creator-coins\",\n title: \"Creator Coins & Memecoins\",\n tagline: \"Launch your own coin — or bring one you already made — and let your community back you.\",\n },\n {\n key: \"collection-drop\",\n title: \"Collection Drop\",\n tagline: \"Schedule a release and let your audience mint while the window is open.\",\n },\n {\n key: \"pop-protocol\",\n title: \"POP Protocol\",\n tagline: \"Give your community proof they were part of the moment.\",\n },\n {\n key: \"ip-tickets\",\n title: \"IP Tickets\",\n tagline: \"Sell tickets to your shows and events, verifiable on-chain.\",\n },\n {\n key: \"ip-sponsorship\",\n title: \"IP Sponsorship\",\n tagline: \"Let sponsors back your work directly, in exchange for a license.\",\n },\n {\n key: \"ip-club\",\n title: \"IP Club\",\n tagline: \"Give your closest fans a membership card that unlocks more.\",\n },\n {\n key: \"licensing-remix\",\n title: \"Licensing & Remix\",\n tagline: \"Let others build on your work \\u2014 with credit and royalties flowing back to you.\",\n },\n {\n key: \"claims\",\n title: \"Claims\",\n tagline: \"Quick wins \\u2014 claim your name and bring in work you have already made.\",\n },\n {\n key: \"coming-soon\",\n title: \"Coming soon\",\n tagline: \"More ways to earn are on the way.\",\n },\n];\n\nexport interface ServiceDefinition {\n key: string;\n title: string;\n subtitle: string;\n description: string;\n features: string[];\n icon: LucideIcon;\n gradient: string;\n borderColor: string;\n iconColor: string;\n buttonColor?: string;\n badge: string;\n status: ServiceStatus;\n category: ServiceCategory;\n group: ServiceGroup;\n /** The ONE creator-language sentence the card shows (no jargon). */\n blurb: string;\n /** Single-verb action label for the card's gradient pill (never repeats the title). */\n cta: string;\n /** Concrete usage example (legacy long-card layout; unused by the 0.9.0 card). */\n example?: string;\n /** Secondary browse link label — injected app adds the href */\n browseLinkLabel?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_DEFINITIONS: ServiceDefinition[] = [\n // ── Create ────────────────────────────────────────────────────────────────\n {\n key: \"mint-ip-asset\",\n cta: \"Mint\",\n blurb: \"Upload a song, a photo, a video \\u2014 any file \\u2014 and publish it as yours, free, in minutes.\",\n title: \"Mint singular NFT\",\n subtitle: \"Publish your creative work onchain\",\n description:\n \"Upload any photo, video, audio, or document and mint it as an IP NFT — with licensing, provenance, and ownership all locked on-chain.\",\n // Apps may override features[0] with their gasless-rail wording (ChipiPay/AVNU).\n features: [\"Free to publish\", \"Your file, stored forever\", \"You set the license terms\"],\n example: \"A song, a photo, an ebook, a short film\",\n icon: ImagePlus,\n gradient: \"from-blue-500/10 via-sky-400/4 to-transparent\",\n borderColor: \"border-blue-500/20\",\n iconColor: \"text-blue-500\",\n buttonColor: \"bg-brand-blue hover:bg-brand-blue/90\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"single-edition\",\n },\n {\n key: \"create-collection\",\n cta: \"Create\",\n blurb: \"Give your works a home of their own, with its own page and name.\",\n title: \"Create NFT Collection\",\n subtitle: \"Group your NFTs under a shared identity\",\n description:\n \"Deploy a branded ERC-721 collection with its own page and on-chain identity. Add assets to it at any time and share it with collectors.\",\n features: [\"Your own branded page\", \"Add new work anytime\", \"One link to share with fans\"],\n example: \"A photography portfolio, a music catalog, a comic series\",\n icon: Layers,\n gradient: \"from-violet-500/10 via-purple-400/4 to-transparent\",\n borderColor: \"border-violet-500/20\",\n iconColor: \"text-violet-500\",\n buttonColor: \"bg-brand-purple hover:bg-brand-purple/90\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"single-edition\",\n },\n {\n key: \"ip-collection-1155\",\n cta: \"Create\",\n blurb: \"Set up a collection made for numbered copies of your work.\",\n title: \"Limited Editions Collections\",\n subtitle: \"Deploy a contract for multi-copy NFT releases\",\n description:\n \"Create a collection built for editions — release music tracks, art prints, or any IP in numbered multiples. Each edition token is tradeable on Medialane.\",\n features: [\"Numbered copies, set by you\", \"Fans collect and trade\", \"One home for every release\"],\n example: \"50 copies of a limited print, a music EP in 100 editions\",\n icon: Layers,\n gradient: \"from-violet-500/10 via-purple-400/4 to-transparent\",\n borderColor: \"border-violet-500/20\",\n iconColor: \"text-violet-500\",\n buttonColor: \"bg-violet-600 hover:bg-violet-700\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"limited-editions\",\n },\n {\n key: \"mint-editions\",\n cta: \"Mint\",\n blurb: \"Release a new piece in as many copies as you choose.\",\n title: \"Mint Limited Edition\",\n subtitle: \"Add new editions to an existing collection\",\n description:\n \"Pick one of your Limited Edition contracts, upload artwork, set the supply, and release to collectors — all in a few clicks.\",\n features: [\"You choose how many copies\", \"Numbered automatically\", \"Ready to sell right away\"],\n example: \"Drop 25 numbered prints from your art series\",\n icon: PlusCircle,\n gradient: \"from-fuchsia-500/10 via-violet-400/4 to-transparent\",\n borderColor: \"border-fuchsia-500/20\",\n iconColor: \"text-fuchsia-500\",\n buttonColor: \"bg-fuchsia-600 hover:bg-fuchsia-700\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"limited-editions\",\n },\n {\n key: \"remix-asset\",\n cta: \"Browse\",\n blurb: \"Create from another work \\u2014 credit and royalties are handled for you.\",\n title: \"Remix Asset\",\n subtitle: \"Derivative works with on-chain attribution\",\n description:\n \"Create a licensed derivative of any digital asset with full provenance and attribution flowing back to the original creator on-chain.\",\n features: [\"Credit handled automatically\", \"Royalties flow to the original\", \"License respected at mint\"],\n example: \"A remix of a song, an artwork inspired by an original\",\n icon: GitBranch,\n gradient: \"from-rose-500/10 via-pink-400/4 to-transparent\",\n borderColor: \"border-rose-500/20\",\n iconColor: \"text-rose-500\",\n buttonColor: \"bg-brand-rose hover:bg-brand-rose/90\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"licensing-remix\",\n },\n\n // ── Launch ────────────────────────────────────────────────────────────────\n {\n key: \"pop-protocol\",\n cta: \"Create\",\n blurb: \"Hand out badges your attendees keep forever.\",\n title: \"POP Protocol\",\n subtitle: \"Proof-of-participation for events & communities\",\n description:\n \"Issue soulbound credentials to your community — one non-transferable badge per wallet, permanently on-chain. No transferring, no faking.\",\n features: [\"Free for your community to claim\", \"Invite-list gating optional\", \"Branded event page to share\"],\n example: \"Hackathon attendance badge, community membership, conference pass\",\n icon: Award,\n gradient: \"from-emerald-500/10 via-green-400/4 to-transparent\",\n borderColor: \"border-emerald-500/20\",\n iconColor: \"text-emerald-500\",\n buttonColor: \"bg-green-600 hover:bg-green-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse events\",\n status: \"live\",\n category: \"launch\",\n group: \"pop-protocol\",\n },\n {\n key: \"collection-drop\",\n cta: \"Launch\",\n blurb: \"Set a price, a window, and a limited run \\u2014 then open the doors.\",\n title: \"Collection Drop\",\n subtitle: \"Timed NFT releases with mint windows\",\n description:\n \"Launch a time-gated mint campaign — set a price, supply cap, start and end time, and let collectors mint directly from your drop page.\",\n features: [\"You set price and supply\", \"Opens and closes on your schedule\", \"Branded drop page to share\"],\n example: \"A 48-hour drop of 200 pieces at 5 USDC each\",\n icon: Package,\n gradient: \"from-orange-500/10 via-amber-400/4 to-transparent\",\n borderColor: \"border-orange-500/20\",\n iconColor: \"text-orange-500\",\n buttonColor: \"bg-orange-600 hover:bg-orange-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse drops\",\n status: \"live\",\n category: \"launch\",\n group: \"collection-drop\",\n },\n {\n key: \"ip-tickets\",\n cta: \"Sell\",\n blurb: \"Sell tickets to your shows and events.\",\n title: \"IP Tickets\",\n subtitle: \"Gate real-world experiences with NFTs\",\n description:\n \"Distribute tickets for concerts, workshops, and events. Each ticket is verifiable on-chain proof of attendance.\",\n features: [\"NFT-based event gating\", \"Proof of attendance\", TICKETS_TRANSFERABLE_FEATURE],\n icon: Ticket,\n gradient: \"from-teal-500/10 via-cyan-400/4 to-transparent\",\n borderColor: \"border-teal-500/20\",\n iconColor: \"text-teal-500\",\n buttonColor: \"bg-teal-600 hover:bg-teal-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse tickets\",\n // Deployed to Starknet mainnet 2026-07-02 — see\n // medialane-core/docs/deployments.md\n status: \"live\",\n category: \"launch\",\n group: \"ip-tickets\",\n },\n {\n key: \"ip-club\",\n cta: \"Create\",\n blurb: \"Passes that unlock more for your closest fans.\",\n title: \"IP Club\",\n subtitle: \"Membership passes with an on-chain card\",\n description:\n \"Create a membership club backed by an on-chain NFT membership card. Set an entry fee, a member cap, and open or close joining anytime.\",\n features: [\"On-chain membership card\", \"Optional entry fee\", \"Open or close joining anytime\"],\n icon: Users,\n gradient: \"from-indigo-500/10 via-violet-400/4 to-transparent\",\n borderColor: \"border-indigo-500/20\",\n iconColor: \"text-indigo-400\",\n buttonColor: \"bg-indigo-600 hover:bg-indigo-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse clubs\",\n // Deployed to Starknet mainnet 2026-07-02 — see\n // medialane-core/docs/deployments.md\n status: \"live\",\n category: \"launch\",\n group: \"ip-club\",\n },\n {\n key: \"ip-sponsorship\",\n cta: \"Browse\",\n blurb: \"Let a sponsor back your work directly, for a license in return.\",\n title: \"IP Sponsorship\",\n subtitle: \"Direct sponsorship offers, settled asset-to-asset\",\n description:\n \"Create a sponsorship offer on an asset you own — sponsors bid, you accept, they receive a license. No escrow: settlement is direct, sponsor to author.\",\n features: [\"No escrow — direct settlement\", \"Owner-verified on-chain\", \"Open bidding or one invited sponsor\"],\n example: \"Sponsor a song, an artwork, or a patent for a license\",\n icon: Handshake,\n gradient: \"from-rose-500/10 via-pink-400/4 to-transparent\",\n borderColor: \"border-rose-500/20\",\n iconColor: \"text-rose-500\",\n buttonColor: \"bg-brand-rose hover:bg-brand-rose/90\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse offers\",\n // Deployed to Starknet mainnet 2026-07-02 — see\n // medialane-core/docs/deployments.md\n status: \"live\",\n category: \"launch\",\n group: \"ip-sponsorship\",\n },\n\n // ── Monetize ─────────────────────────────────────────────────────────────\n {\n key: \"creator-coins\",\n cta: \"Launch\",\n blurb: \"Launch your coin in a few clicks \\u2014 and stay in control of it.\",\n title: \"Creator Coin\",\n subtitle: \"Your own coin, your liquidity\",\n description:\n \"Launch a standard ERC-20 coin tied to your creative work, paired with a public Ekubo liquidity pool. You set the supply and allocation — and you stay in control of the liquidity.\",\n features: [\"Launch in a few clicks\", \"You keep control of the liquidity\", \"Traded on a public pool\"],\n example: \"A fan coin for your channel, a coin for your music project\",\n icon: TrendingUp,\n gradient: \"from-pink-500/6 via-rose-400/2 to-transparent\",\n borderColor: \"border-pink-500/20\",\n iconColor: \"text-pink-400\",\n buttonColor: \"bg-brand-rose hover:bg-brand-rose/90\",\n badge: \"Launch\",\n status: \"live\",\n category: \"monetize\",\n group: \"creator-coins\",\n },\n\n // ── Claims ────────────────────────────────────────────────────────────────\n {\n key: \"claim-memecoin\",\n cta: \"Claim\",\n blurb: \"Already launched a coin? Add it to your Medialane profile.\",\n title: \"Claim Memecoin\",\n subtitle: \"Bring your Starknet coin to Medialane\",\n description:\n \"Already launched a coin on Starknet (unrug or partner)? Claim it to add it to Medialane — reviewed by our team, then live on the Coins page and your profile.\",\n features: [\"Bring a coin you already launched\", \"Reviewed by our team\", \"Featured on the Coins page\"],\n example: \"Your unrug memecoin, listed on your creator profile\",\n icon: Coins,\n gradient: \"from-orange-500/10 via-amber-400/4 to-transparent\",\n borderColor: \"border-orange-500/20\",\n iconColor: \"text-orange-500\",\n buttonColor: \"bg-orange-600 hover:bg-orange-700\",\n badge: \"Claim\",\n status: \"live\",\n category: \"monetize\",\n group: \"creator-coins\",\n },\n {\n key: \"claim-username\",\n cta: \"Claim\",\n blurb: \"Reserve your name and get your own creator page.\",\n title: \"Claim Username\",\n subtitle: \"Reserve your creator page URL\",\n description:\n \"Claim your unique username and get a shareable creator page — your public portfolio at a clean, memorable URL. Free, and yours.\",\n features: [\"Free claim\", \"Shareable creator page\", \"Your public portfolio\"],\n example: \"medialane.io/your-name — your portfolio at your own name\",\n icon: AtSign,\n gradient: \"from-violet-500/10 via-purple-400/4 to-transparent\",\n borderColor: \"border-violet-500/20\",\n iconColor: \"text-violet-500\",\n buttonColor: \"bg-brand-purple hover:bg-brand-purple/90\",\n badge: \"Claim\",\n status: \"live\",\n category: \"create\",\n group: \"claims\",\n },\n {\n key: \"claim-collection\",\n cta: \"Claim\",\n blurb: \"Made a collection somewhere else? Bring it to your profile.\",\n title: \"Claim Collection\",\n subtitle: \"Import an existing Starknet collection\",\n description:\n \"Already deployed an ERC-721 collection on Starknet? Claim it to link it to your Medialane profile and give it a branded collection page.\",\n features: [\"Bring an existing collection\", \"Linked to your profile\", \"Branded collection page\"],\n example: \"A collection you deployed elsewhere joins your profile\",\n icon: FolderInput,\n gradient: \"from-blue-500/10 via-sky-400/4 to-transparent\",\n borderColor: \"border-blue-500/20\",\n iconColor: \"text-blue-500\",\n buttonColor: \"bg-brand-blue hover:bg-brand-blue/90\",\n badge: \"Claim\",\n status: \"live\",\n category: \"create\",\n group: \"claims\",\n },\n {\n key: \"claim-collection-name\",\n cta: \"Claim\",\n blurb: \"Give your collection a clean, memorable web address of its own.\",\n title: \"Claim Collection Name\",\n subtitle: \"Reserve your collection page URL\",\n description:\n \"Claim a custom name for your collection page — a clean, shareable URL your fans can remember, instead of a long contract address.\",\n features: [\"Free claim\", \"Clean shareable URL\", \"Easy to remember and share\"],\n example: \"medialane.io/collections/your-collection\",\n icon: Link2,\n gradient: \"from-pink-500/10 via-rose-400/4 to-transparent\",\n borderColor: \"border-pink-500/20\",\n iconColor: \"text-pink-500\",\n badge: \"Claim\",\n status: \"live\",\n category: \"create\",\n group: \"claims\",\n },\n];\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/data/launchpad-services.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport {\n ImagePlus, Layers, GitBranch,\n Award, Package, PlusCircle,\n Ticket, Users, Handshake,\n Coins, TrendingUp,\n AtSign, FolderInput, Link2,\n} from \"lucide-react\";\nimport { hasCapability } from \"@medialane/sdk\";\n\nconst TICKETS_TRANSFERABLE_FEATURE = hasCapability(\"ip-tickets\", \"transfer\")\n ? \"Freely transferable\"\n : \"Stays with the original holder\";\n\nexport type ServiceStatus = \"live\" | \"building\" | \"soon\";\nexport type ServiceCategory = \"create\" | \"launch\" | \"monetize\";\n\nexport type ServiceGroup =\n | \"single-edition\"\n | \"limited-editions\"\n | \"coins\"\n | \"community\"\n | \"claims\"\n | \"coming-soon\";\n\nexport interface ServiceGroupDefinition {\n key: ServiceGroup;\n title: string;\n /** One line of plain creator language: what does this group do for my portfolio/revenue? */\n tagline: string;\n /** Optional small chip next to the title (e.g. the token standard) */\n badge?: string;\n}\n\n/** Ordered — launchpad pages render sections in this order. */\nexport const LAUNCHPAD_SERVICE_GROUPS: ServiceGroupDefinition[] = [\n {\n key: \"single-edition\",\n title: \"Single Edition\",\n tagline: \"Publish one-of-a-kind pieces \\u2014 a song, a photo, a film, a timed drop, or a remix \\u2014 under your own name.\",\n },\n {\n key: \"limited-editions\",\n title: \"Limited Editions\",\n tagline: \"Release your work in numbered copies your fans can collect and trade.\",\n },\n {\n key: \"coins\",\n title: \"Coins\",\n tagline: \"Launch your own coin \\u2014 or bring one you already made \\u2014 and let your community back you.\",\n },\n {\n key: \"community\",\n title: \"Community\",\n tagline: \"Connect with the people who show up for you \\u2014 badges, tickets, memberships, and direct sponsorship.\",\n },\n {\n key: \"claims\",\n title: \"Claims\",\n tagline: \"Quick wins \\u2014 claim your name and bring in work you have already made.\",\n },\n {\n key: \"coming-soon\",\n title: \"Coming soon\",\n tagline: \"More ways to earn are on the way.\",\n },\n];\n\nexport interface ServiceDefinition {\n key: string;\n title: string;\n subtitle: string;\n description: string;\n features: string[];\n icon: LucideIcon;\n gradient: string;\n borderColor: string;\n iconColor: string;\n buttonColor?: string;\n badge: string;\n status: ServiceStatus;\n category: ServiceCategory;\n group: ServiceGroup;\n /** The ONE creator-language sentence the card shows (no jargon). */\n blurb: string;\n /** Single-verb action label for the card's gradient pill (never repeats the title). */\n cta: string;\n /** Concrete usage example (legacy long-card layout; unused by the 0.9.0 card). */\n example?: string;\n /** Secondary browse link label — injected app adds the href */\n browseLinkLabel?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_DEFINITIONS: ServiceDefinition[] = [\n // ── Create ────────────────────────────────────────────────────────────────\n {\n key: \"mint-ip-asset\",\n cta: \"Mint\",\n blurb: \"Upload a song, a photo, a video \\u2014 any file \\u2014 and publish it as yours, free, in minutes.\",\n title: \"Mint singular NFT\",\n subtitle: \"Publish your creative work onchain\",\n description:\n \"Upload any photo, video, audio, or document and mint it as an IP NFT — with licensing, provenance, and ownership all locked on-chain.\",\n // Apps may override features[0] with their gasless-rail wording (ChipiPay/AVNU).\n features: [\"Free to publish\", \"Your file, stored forever\", \"You set the license terms\"],\n example: \"A song, a photo, an ebook, a short film\",\n icon: ImagePlus,\n gradient: \"from-blue-500/10 via-sky-400/4 to-transparent\",\n borderColor: \"border-blue-500/20\",\n iconColor: \"text-blue-500\",\n buttonColor: \"bg-brand-blue hover:bg-brand-blue/90\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"single-edition\",\n },\n {\n key: \"create-collection\",\n cta: \"Create\",\n blurb: \"Give your works a home of their own, with its own page and name.\",\n title: \"Create NFT Collection\",\n subtitle: \"Group your NFTs under a shared identity\",\n description:\n \"Deploy a branded ERC-721 collection with its own page and on-chain identity. Add assets to it at any time and share it with collectors.\",\n features: [\"Your own branded page\", \"Add new work anytime\", \"One link to share with fans\"],\n example: \"A photography portfolio, a music catalog, a comic series\",\n icon: Layers,\n gradient: \"from-violet-500/10 via-purple-400/4 to-transparent\",\n borderColor: \"border-violet-500/20\",\n iconColor: \"text-violet-500\",\n buttonColor: \"bg-brand-purple hover:bg-brand-purple/90\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"single-edition\",\n },\n {\n key: \"ip-collection-1155\",\n cta: \"Create\",\n blurb: \"Set up a collection made for numbered copies of your work.\",\n title: \"Limited Editions Collections\",\n subtitle: \"Deploy a contract for multi-copy NFT releases\",\n description:\n \"Create a collection built for editions — release music tracks, art prints, or any IP in numbered multiples. Each edition token is tradeable on Medialane.\",\n features: [\"Numbered copies, set by you\", \"Fans collect and trade\", \"One home for every release\"],\n example: \"50 copies of a limited print, a music EP in 100 editions\",\n icon: Layers,\n gradient: \"from-violet-500/10 via-purple-400/4 to-transparent\",\n borderColor: \"border-violet-500/20\",\n iconColor: \"text-violet-500\",\n buttonColor: \"bg-violet-600 hover:bg-violet-700\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"limited-editions\",\n },\n {\n key: \"mint-editions\",\n cta: \"Mint\",\n blurb: \"Release a new piece in as many copies as you choose.\",\n title: \"Mint Limited Edition\",\n subtitle: \"Add new editions to an existing collection\",\n description:\n \"Pick one of your Limited Edition contracts, upload artwork, set the supply, and release to collectors — all in a few clicks.\",\n features: [\"You choose how many copies\", \"Numbered automatically\", \"Ready to sell right away\"],\n example: \"Drop 25 numbered prints from your art series\",\n icon: PlusCircle,\n gradient: \"from-fuchsia-500/10 via-violet-400/4 to-transparent\",\n borderColor: \"border-fuchsia-500/20\",\n iconColor: \"text-fuchsia-500\",\n buttonColor: \"bg-fuchsia-600 hover:bg-fuchsia-700\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"limited-editions\",\n },\n {\n key: \"remix-asset\",\n cta: \"Browse\",\n blurb: \"Create from another work \\u2014 credit and royalties are handled for you.\",\n title: \"Remix Asset\",\n subtitle: \"Derivative works with on-chain attribution\",\n description:\n \"Create a licensed derivative of any digital asset with full provenance and attribution flowing back to the original creator on-chain.\",\n features: [\"Credit handled automatically\", \"Royalties flow to the original\", \"License respected at mint\"],\n example: \"A remix of a song, an artwork inspired by an original\",\n icon: GitBranch,\n gradient: \"from-rose-500/10 via-pink-400/4 to-transparent\",\n borderColor: \"border-rose-500/20\",\n iconColor: \"text-rose-500\",\n buttonColor: \"bg-brand-rose hover:bg-brand-rose/90\",\n badge: \"Create\",\n status: \"live\",\n category: \"create\",\n group: \"single-edition\",\n },\n\n // ── Launch ────────────────────────────────────────────────────────────────\n {\n key: \"pop-protocol\",\n cta: \"Create\",\n blurb: \"Hand out badges your attendees keep forever.\",\n title: \"POP Protocol\",\n subtitle: \"Proof-of-participation for events & communities\",\n description:\n \"Issue soulbound credentials to your community — one non-transferable badge per wallet, permanently on-chain. No transferring, no faking.\",\n features: [\"Free for your community to claim\", \"Invite-list gating optional\", \"Branded event page to share\"],\n example: \"Hackathon attendance badge, community membership, conference pass\",\n icon: Award,\n gradient: \"from-emerald-500/10 via-green-400/4 to-transparent\",\n borderColor: \"border-emerald-500/20\",\n iconColor: \"text-emerald-500\",\n buttonColor: \"bg-green-600 hover:bg-green-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse events\",\n status: \"live\",\n category: \"launch\",\n group: \"community\",\n },\n {\n key: \"collection-drop\",\n cta: \"Launch\",\n blurb: \"Set a price, a window, and a limited run \\u2014 then open the doors.\",\n title: \"Collection Drop\",\n subtitle: \"Timed NFT releases with mint windows\",\n description:\n \"Launch a time-gated mint campaign — set a price, supply cap, start and end time, and let collectors mint directly from your drop page.\",\n features: [\"You set price and supply\", \"Opens and closes on your schedule\", \"Branded drop page to share\"],\n example: \"A 48-hour drop of 200 pieces at 5 USDC each\",\n icon: Package,\n gradient: \"from-orange-500/10 via-amber-400/4 to-transparent\",\n borderColor: \"border-orange-500/20\",\n iconColor: \"text-orange-500\",\n buttonColor: \"bg-orange-600 hover:bg-orange-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse drops\",\n status: \"live\",\n category: \"launch\",\n group: \"single-edition\",\n },\n {\n key: \"ip-tickets\",\n cta: \"Sell\",\n blurb: \"Sell tickets to your shows and events.\",\n title: \"IP Tickets\",\n subtitle: \"Gate real-world experiences with NFTs\",\n description:\n \"Distribute tickets for concerts, workshops, and events. Each ticket is verifiable on-chain proof of attendance.\",\n features: [\"NFT-based event gating\", \"Proof of attendance\", TICKETS_TRANSFERABLE_FEATURE],\n icon: Ticket,\n gradient: \"from-teal-500/10 via-cyan-400/4 to-transparent\",\n borderColor: \"border-teal-500/20\",\n iconColor: \"text-teal-500\",\n buttonColor: \"bg-teal-600 hover:bg-teal-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse tickets\",\n // Deployed to Starknet mainnet 2026-07-02 — see\n // medialane-core/docs/deployments.md\n status: \"live\",\n category: \"launch\",\n group: \"community\",\n },\n {\n key: \"ip-club\",\n cta: \"Create\",\n blurb: \"Passes that unlock more for your closest fans.\",\n title: \"IP Club\",\n subtitle: \"Membership passes with an on-chain card\",\n description:\n \"Create a membership club backed by an on-chain NFT membership card. Set an entry fee, a member cap, and open or close joining anytime.\",\n features: [\"On-chain membership card\", \"Optional entry fee\", \"Open or close joining anytime\"],\n icon: Users,\n gradient: \"from-indigo-500/10 via-violet-400/4 to-transparent\",\n borderColor: \"border-indigo-500/20\",\n iconColor: \"text-indigo-400\",\n buttonColor: \"bg-indigo-600 hover:bg-indigo-700\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse clubs\",\n // Deployed to Starknet mainnet 2026-07-02 — see\n // medialane-core/docs/deployments.md\n status: \"live\",\n category: \"launch\",\n group: \"community\",\n },\n {\n key: \"ip-sponsorship\",\n cta: \"Browse\",\n blurb: \"Let a sponsor back your work directly, for a license in return.\",\n title: \"IP Sponsorship\",\n subtitle: \"Direct sponsorship offers, settled asset-to-asset\",\n description:\n \"Create a sponsorship offer on an asset you own — sponsors bid, you accept, they receive a license. No escrow: settlement is direct, sponsor to author.\",\n features: [\"No escrow — direct settlement\", \"Owner-verified on-chain\", \"Open bidding or one invited sponsor\"],\n example: \"Sponsor a song, an artwork, or a patent for a license\",\n icon: Handshake,\n gradient: \"from-rose-500/10 via-pink-400/4 to-transparent\",\n borderColor: \"border-rose-500/20\",\n iconColor: \"text-rose-500\",\n buttonColor: \"bg-brand-rose hover:bg-brand-rose/90\",\n badge: \"Launch\",\n browseLinkLabel: \"Browse offers\",\n // Deployed to Starknet mainnet 2026-07-02 — see\n // medialane-core/docs/deployments.md\n status: \"live\",\n category: \"launch\",\n group: \"community\",\n },\n\n // ── Monetize ─────────────────────────────────────────────────────────────\n {\n key: \"creator-coins\",\n cta: \"Launch\",\n blurb: \"Launch your coin in a few clicks \\u2014 and stay in control of it.\",\n title: \"Creator Coin\",\n subtitle: \"Your own coin, your liquidity\",\n description:\n \"Launch a standard ERC-20 coin tied to your creative work, paired with a public Ekubo liquidity pool. You set the supply and allocation — and you stay in control of the liquidity.\",\n features: [\"Launch in a few clicks\", \"You keep control of the liquidity\", \"Traded on a public pool\"],\n example: \"A fan coin for your channel, a coin for your music project\",\n icon: TrendingUp,\n gradient: \"from-pink-500/6 via-rose-400/2 to-transparent\",\n borderColor: \"border-pink-500/20\",\n iconColor: \"text-pink-400\",\n buttonColor: \"bg-brand-rose hover:bg-brand-rose/90\",\n badge: \"Launch\",\n status: \"live\",\n category: \"monetize\",\n group: \"coins\",\n },\n\n // ── Claims ────────────────────────────────────────────────────────────────\n {\n key: \"claim-memecoin\",\n cta: \"Claim\",\n blurb: \"Already launched a coin? Add it to your Medialane profile.\",\n title: \"Claim Memecoin\",\n subtitle: \"Bring your Starknet coin to Medialane\",\n description:\n \"Already launched a coin on Starknet (unrug or partner)? Claim it to add it to Medialane — reviewed by our team, then live on the Coins page and your profile.\",\n features: [\"Bring a coin you already launched\", \"Reviewed by our team\", \"Featured on the Coins page\"],\n example: \"Your unrug memecoin, listed on your creator profile\",\n icon: Coins,\n gradient: \"from-orange-500/10 via-amber-400/4 to-transparent\",\n borderColor: \"border-orange-500/20\",\n iconColor: \"text-orange-500\",\n buttonColor: \"bg-orange-600 hover:bg-orange-700\",\n badge: \"Claim\",\n status: \"live\",\n category: \"monetize\",\n group: \"coins\",\n },\n {\n key: \"claim-username\",\n cta: \"Claim\",\n blurb: \"Reserve your name and get your own creator page.\",\n title: \"Claim Username\",\n subtitle: \"Reserve your creator page URL\",\n description:\n \"Claim your unique username and get a shareable creator page — your public portfolio at a clean, memorable URL. Free, and yours.\",\n features: [\"Free claim\", \"Shareable creator page\", \"Your public portfolio\"],\n example: \"medialane.io/your-name — your portfolio at your own name\",\n icon: AtSign,\n gradient: \"from-violet-500/10 via-purple-400/4 to-transparent\",\n borderColor: \"border-violet-500/20\",\n iconColor: \"text-violet-500\",\n buttonColor: \"bg-brand-purple hover:bg-brand-purple/90\",\n badge: \"Claim\",\n status: \"live\",\n category: \"create\",\n group: \"claims\",\n },\n {\n key: \"claim-collection\",\n cta: \"Claim\",\n blurb: \"Made a collection somewhere else? Bring it to your profile.\",\n title: \"Claim Collection\",\n subtitle: \"Import an existing Starknet collection\",\n description:\n \"Already deployed an ERC-721 collection on Starknet? Claim it to link it to your Medialane profile and give it a branded collection page.\",\n features: [\"Bring an existing collection\", \"Linked to your profile\", \"Branded collection page\"],\n example: \"A collection you deployed elsewhere joins your profile\",\n icon: FolderInput,\n gradient: \"from-blue-500/10 via-sky-400/4 to-transparent\",\n borderColor: \"border-blue-500/20\",\n iconColor: \"text-blue-500\",\n buttonColor: \"bg-brand-blue hover:bg-brand-blue/90\",\n badge: \"Claim\",\n status: \"live\",\n category: \"create\",\n group: \"claims\",\n },\n {\n key: \"claim-collection-name\",\n cta: \"Claim\",\n blurb: \"Give your collection a clean, memorable web address of its own.\",\n title: \"Claim Collection Name\",\n subtitle: \"Reserve your collection page URL\",\n description:\n \"Claim a custom name for your collection page — a clean, shareable URL your fans can remember, instead of a long contract address.\",\n features: [\"Free claim\", \"Clean shareable URL\", \"Easy to remember and share\"],\n example: \"medialane.io/collections/your-collection\",\n icon: Link2,\n gradient: \"from-pink-500/10 via-rose-400/4 to-transparent\",\n borderColor: \"border-pink-500/20\",\n iconColor: \"text-pink-500\",\n badge: \"Claim\",\n status: \"live\",\n category: \"create\",\n group: \"claims\",\n },\n];\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@ import { LucideIcon } from 'lucide-react';
|
|
|
2
2
|
|
|
3
3
|
type ServiceStatus = "live" | "building" | "soon";
|
|
4
4
|
type ServiceCategory = "create" | "launch" | "monetize";
|
|
5
|
-
type ServiceGroup = "single-edition" | "limited-editions" | "
|
|
5
|
+
type ServiceGroup = "single-edition" | "limited-editions" | "coins" | "community" | "claims" | "coming-soon";
|
|
6
6
|
interface ServiceGroupDefinition {
|
|
7
7
|
key: ServiceGroup;
|
|
8
8
|
title: string;
|