@medialane/ui 0.7.0 → 0.9.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/launchpad-services.cjs +90 -136
- package/dist/components/launchpad-services.cjs.map +1 -1
- package/dist/components/launchpad-services.d.cts +28 -11
- package/dist/components/launchpad-services.d.ts +28 -11
- package/dist/components/launchpad-services.js +91 -136
- package/dist/components/launchpad-services.js.map +1 -1
- package/dist/data/launchpad-services.cjs +48 -27
- package/dist/data/launchpad-services.cjs.map +1 -1
- package/dist/data/launchpad-services.d.cts +4 -0
- package/dist/data/launchpad-services.d.ts +4 -0
- package/dist/data/launchpad-services.js +48 -27
- package/dist/data/launchpad-services.js.map +1 -1
- package/dist/index.cjs +6 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/launchpad-grid.cjs +0 -77
- package/dist/components/launchpad-grid.cjs.map +0 -1
- package/dist/components/launchpad-grid.d.cts +0 -20
- package/dist/components/launchpad-grid.d.ts +0 -20
- package/dist/components/launchpad-grid.js +0 -43
- package/dist/components/launchpad-grid.js.map +0 -1
|
@@ -1,157 +1,112 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Link from "next/link";
|
|
4
|
-
import {
|
|
4
|
+
import { motion } from "framer-motion";
|
|
5
|
+
import { Lock, ArrowUpRight, ArrowRight } from "lucide-react";
|
|
5
6
|
import { cn } from "../utils/cn.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
import {
|
|
8
|
+
LAUNCHPAD_SERVICE_DEFINITIONS,
|
|
9
|
+
LAUNCHPAD_SERVICE_GROUPS
|
|
10
|
+
} from "../data/launchpad-services.js";
|
|
11
|
+
const DEFAULT_HUE = { text: "text-sky-600 dark:text-sky-400", bg: "bg-sky-500/10" };
|
|
12
|
+
const SERVICE_HUES = {
|
|
13
|
+
"mint-ip-asset": { text: "text-sky-600 dark:text-sky-400", bg: "bg-sky-500/10" },
|
|
14
|
+
"create-collection": { text: "text-violet-600 dark:text-violet-400", bg: "bg-violet-500/10" },
|
|
15
|
+
"ip-collection-1155": { text: "text-rose-600 dark:text-rose-400", bg: "bg-rose-500/10" },
|
|
16
|
+
"mint-editions": { text: "text-amber-600 dark:text-amber-400", bg: "bg-amber-500/10" },
|
|
17
|
+
"creator-coins": { text: "text-pink-600 dark:text-pink-400", bg: "bg-pink-500/10" },
|
|
18
|
+
"claim-memecoin": { text: "text-teal-600 dark:text-teal-400", bg: "bg-teal-500/10" },
|
|
19
|
+
"collection-drop": { text: "text-orange-600 dark:text-orange-400", bg: "bg-orange-500/10" },
|
|
20
|
+
"pop-protocol": { text: "text-emerald-600 dark:text-emerald-400", bg: "bg-emerald-500/10" },
|
|
21
|
+
"remix-asset": { text: "text-indigo-600 dark:text-indigo-400", bg: "bg-indigo-500/10" },
|
|
22
|
+
"claim-username": { text: "text-purple-600 dark:text-purple-400", bg: "bg-purple-500/10" },
|
|
23
|
+
"claim-collection": { text: "text-cyan-600 dark:text-cyan-400", bg: "bg-cyan-500/10" }
|
|
24
|
+
};
|
|
25
|
+
function LaunchpadServiceCard({ def, override = {} }) {
|
|
26
|
+
const { key, icon: Icon, title, browseLinkLabel } = def;
|
|
27
|
+
const status = override.status ?? def.status;
|
|
28
|
+
const blurb = override.blurb ?? def.blurb;
|
|
29
|
+
const { href, browseHref } = override;
|
|
23
30
|
const live = status === "live";
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
return /* @__PURE__ */ jsx(
|
|
31
|
+
const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;
|
|
32
|
+
return /* @__PURE__ */ jsxs(
|
|
27
33
|
"div",
|
|
28
34
|
{
|
|
29
35
|
className: cn(
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
live && "hover:-translate-y-[3px] hover:shadow-lg hover:shadow-black/5 dark:hover:shadow-black/20",
|
|
34
|
-
!active && "opacity-60"
|
|
36
|
+
"relative rounded-2xl border border-border/60 bg-card p-5 sm:p-6",
|
|
37
|
+
"flex flex-col gap-3 transition-transform",
|
|
38
|
+
live ? "active:scale-[0.99]" : "opacity-60"
|
|
35
39
|
),
|
|
36
|
-
children:
|
|
37
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
|
|
38
|
-
/* @__PURE__ */ jsx(
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
active ? iconColor : "text-muted-foreground/25",
|
|
44
|
-
live && "group-hover:scale-110"
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
),
|
|
48
|
-
/* @__PURE__ */ jsxs(
|
|
49
|
-
"span",
|
|
50
|
-
{
|
|
51
|
-
className: cn(
|
|
52
|
-
"text-[10px] font-semibold tracking-widest uppercase rounded-full px-2.5 py-1 flex items-center gap-1.5",
|
|
53
|
-
live ? "text-emerald-600 dark:text-emerald-400 bg-emerald-500/10" : building ? "text-amber-600 dark:text-amber-400 bg-amber-500/10" : "text-muted-foreground/40 bg-muted/30"
|
|
54
|
-
),
|
|
55
|
-
children: [
|
|
56
|
-
live && /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-emerald-500 animate-pulse" }),
|
|
57
|
-
!active && /* @__PURE__ */ jsx(Lock, { className: "h-2.5 w-2.5" }),
|
|
58
|
-
badge
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
)
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
42
|
+
/* @__PURE__ */ jsx(Icon, { className: cn("h-7 w-7 shrink-0", live ? hue.text : "text-muted-foreground/50") }),
|
|
43
|
+
live ? /* @__PURE__ */ jsx("span", { className: cn("h-9 w-9 shrink-0 rounded-full flex items-center justify-center", hue.bg), children: /* @__PURE__ */ jsx(ArrowUpRight, { className: cn("h-4 w-4", hue.text) }) }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1", children: [
|
|
44
|
+
/* @__PURE__ */ jsx(Lock, { className: "h-3 w-3" }),
|
|
45
|
+
"Coming soon"
|
|
46
|
+
] })
|
|
62
47
|
] }),
|
|
63
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1
|
|
64
|
-
/* @__PURE__ */ jsx(
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
className: cn(
|
|
68
|
-
"text-xl sm:text-2xl font-bold leading-snug tracking-tight",
|
|
69
|
-
!active && "text-foreground/40"
|
|
70
|
-
),
|
|
71
|
-
children: title
|
|
72
|
-
}
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ jsx(
|
|
75
|
-
"p",
|
|
76
|
-
{
|
|
77
|
-
className: cn(
|
|
78
|
-
"text-xs leading-relaxed",
|
|
79
|
-
active ? "text-muted-foreground" : "text-muted-foreground/30"
|
|
80
|
-
),
|
|
81
|
-
children: subtitle
|
|
82
|
-
}
|
|
83
|
-
)
|
|
48
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
49
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold tracking-tight leading-snug", children: title }),
|
|
50
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-sm leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60"), children: blurb })
|
|
84
51
|
] }),
|
|
85
|
-
/* @__PURE__ */ jsx(
|
|
86
|
-
|
|
52
|
+
live && href && /* @__PURE__ */ jsx(Link, { href, "aria-label": title, className: "absolute inset-0 z-10 rounded-2xl" }),
|
|
53
|
+
live && browseHref && browseLinkLabel && /* @__PURE__ */ jsxs(
|
|
54
|
+
Link,
|
|
87
55
|
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
56
|
+
href: browseHref,
|
|
57
|
+
className: "relative z-20 mt-auto self-start inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground",
|
|
58
|
+
children: [
|
|
59
|
+
browseLinkLabel,
|
|
60
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3" })
|
|
61
|
+
]
|
|
93
62
|
}
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
"span",
|
|
97
|
-
{
|
|
98
|
-
className: cn(
|
|
99
|
-
"text-[11px] px-2.5 py-1 rounded-full border font-medium",
|
|
100
|
-
active ? "bg-background/50 border-border/50 text-muted-foreground" : "bg-muted/10 border-border/15 text-muted-foreground/25"
|
|
101
|
-
),
|
|
102
|
-
children: f
|
|
103
|
-
},
|
|
104
|
-
f
|
|
105
|
-
)) }),
|
|
106
|
-
live && href ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
107
|
-
/* @__PURE__ */ jsxs(
|
|
108
|
-
Link,
|
|
109
|
-
{
|
|
110
|
-
href,
|
|
111
|
-
className: cn(
|
|
112
|
-
"flex items-center justify-between w-full h-10 px-4 rounded-xl",
|
|
113
|
-
"text-sm font-semibold text-white",
|
|
114
|
-
"transition-all duration-200 active:scale-[0.98]",
|
|
115
|
-
buttonColor
|
|
116
|
-
),
|
|
117
|
-
children: [
|
|
118
|
-
buttonLabel ?? "Get started",
|
|
119
|
-
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3.5 w-3.5" })
|
|
120
|
-
]
|
|
121
|
-
}
|
|
122
|
-
),
|
|
123
|
-
browseHref && browseLinkLabel && /* @__PURE__ */ jsxs(
|
|
124
|
-
Link,
|
|
125
|
-
{
|
|
126
|
-
href: browseHref,
|
|
127
|
-
className: "flex items-center justify-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors py-1",
|
|
128
|
-
children: [
|
|
129
|
-
browseLinkLabel,
|
|
130
|
-
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3" })
|
|
131
|
-
]
|
|
132
|
-
}
|
|
133
|
-
)
|
|
134
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 h-10 text-sm text-muted-foreground/30 font-medium", children: [
|
|
135
|
-
/* @__PURE__ */ jsx(Lock, { className: "h-3.5 w-3.5" }),
|
|
136
|
-
building ? "In development" : "Coming soon"
|
|
137
|
-
] })
|
|
138
|
-
] })
|
|
63
|
+
)
|
|
64
|
+
]
|
|
139
65
|
}
|
|
140
66
|
);
|
|
141
67
|
}
|
|
142
|
-
function
|
|
143
|
-
return /* @__PURE__ */
|
|
144
|
-
"
|
|
145
|
-
{
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
68
|
+
function GroupHeader({ group }) {
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
70
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold tracking-tight", children: group.title }),
|
|
71
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: group.tagline })
|
|
72
|
+
] });
|
|
73
|
+
}
|
|
74
|
+
function ComingSoonStrip({ group, defs }) {
|
|
75
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border/40 p-5", children: [
|
|
76
|
+
/* @__PURE__ */ jsx("p", { className: "font-semibold text-sm", children: group.title }),
|
|
77
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-0.5", children: group.tagline }),
|
|
78
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 mt-4", children: defs.map(({ key, icon: Icon, title }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 rounded-full bg-muted/30 border border-border/25", children: [
|
|
79
|
+
/* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5 text-muted-foreground/60" }),
|
|
80
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: title })
|
|
81
|
+
] }, key)) })
|
|
82
|
+
] });
|
|
83
|
+
}
|
|
84
|
+
function LaunchpadGroupedSections({ overrides, className }) {
|
|
85
|
+
return /* @__PURE__ */ jsx("div", { className: cn("space-y-10", className), children: LAUNCHPAD_SERVICE_GROUPS.map((group) => {
|
|
86
|
+
const defs = LAUNCHPAD_SERVICE_DEFINITIONS.filter((d) => d.group === group.key);
|
|
87
|
+
if (defs.length === 0) return null;
|
|
88
|
+
if (group.key === "coming-soon") {
|
|
89
|
+
return /* @__PURE__ */ jsx(ComingSoonStrip, { group, defs }, group.key);
|
|
151
90
|
}
|
|
152
|
-
|
|
91
|
+
return /* @__PURE__ */ jsxs(
|
|
92
|
+
motion.div,
|
|
93
|
+
{
|
|
94
|
+
initial: { opacity: 0, y: 8 },
|
|
95
|
+
animate: { opacity: 1, y: 0 },
|
|
96
|
+
transition: { duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
97
|
+
className: "space-y-4",
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsx(GroupHeader, { group }),
|
|
100
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: defs.map((def) => /* @__PURE__ */ jsx(LaunchpadServiceCard, { def, override: overrides[def.key] }, def.key)) })
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
group.key
|
|
104
|
+
);
|
|
105
|
+
}) });
|
|
153
106
|
}
|
|
154
107
|
export {
|
|
155
|
-
|
|
108
|
+
LaunchpadGroupedSections,
|
|
109
|
+
LaunchpadServiceCard,
|
|
110
|
+
SERVICE_HUES
|
|
156
111
|
};
|
|
157
112
|
//# sourceMappingURL=launchpad-services.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { Lock, ArrowRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ServiceDefinition } from \"../data/launchpad-services.js\";\n\nexport type { ServiceStatus, ServiceCategory, ServiceDefinition } from \"../data/launchpad-services.js\";\n\nexport interface ServiceCardProps extends ServiceDefinition {\n /** Primary CTA href — required for live services */\n href?: string;\n /** Primary CTA button label */\n buttonLabel?: string;\n /** Secondary browse link href */\n browseHref?: string;\n}\n\nfunction ServiceCard({\n title,\n subtitle,\n description,\n features,\n icon: Icon,\n gradient,\n borderColor,\n iconColor,\n buttonColor,\n badge,\n status,\n href,\n buttonLabel,\n browseHref,\n browseLinkLabel,\n}: ServiceCardProps) {\n const live = status === \"live\";\n const building = status === \"building\";\n const active = live || building;\n\n return (\n <div\n className={cn(\n \"group relative rounded-2xl border overflow-hidden transition-all duration-300 flex flex-col\",\n `bg-gradient-to-br ${gradient}`,\n active ? borderColor : \"border-border/20\",\n live && \"hover:-translate-y-[3px] hover:shadow-lg hover:shadow-black/5 dark:hover:shadow-black/20\",\n !active && \"opacity-60\"\n )}\n >\n <div className=\"flex flex-col flex-1 p-7 gap-6\">\n\n {/* Icon + status badge */}\n <div className=\"flex items-start justify-between\">\n <Icon\n className={cn(\n \"h-9 w-9 transition-transform duration-300\",\n active ? iconColor : \"text-muted-foreground/25\",\n live && \"group-hover:scale-110\"\n )}\n />\n <span\n className={cn(\n \"text-[10px] font-semibold tracking-widest uppercase rounded-full px-2.5 py-1 flex items-center gap-1.5\",\n live\n ? \"text-emerald-600 dark:text-emerald-400 bg-emerald-500/10\"\n : building\n ? \"text-amber-600 dark:text-amber-400 bg-amber-500/10\"\n : \"text-muted-foreground/40 bg-muted/30\"\n )}\n >\n {live && <span className=\"h-1.5 w-1.5 rounded-full bg-emerald-500 animate-pulse\" />}\n {!active && <Lock className=\"h-2.5 w-2.5\" />}\n {badge}\n </span>\n </div>\n\n {/* Title + subtitle */}\n <div className=\"space-y-1.5\">\n <p\n className={cn(\n \"text-xl sm:text-2xl font-bold leading-snug tracking-tight\",\n !active && \"text-foreground/40\"\n )}\n >\n {title}\n </p>\n <p\n className={cn(\n \"text-xs leading-relaxed\",\n active ? \"text-muted-foreground\" : \"text-muted-foreground/30\"\n )}\n >\n {subtitle}\n </p>\n </div>\n\n {/* Description */}\n <p\n className={cn(\n \"text-sm leading-relaxed flex-1\",\n active ? \"text-muted-foreground\" : \"text-muted-foreground/30\"\n )}\n >\n {description}\n </p>\n\n {/* Feature chips */}\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((f) => (\n <span\n key={f}\n className={cn(\n \"text-[11px] px-2.5 py-1 rounded-full border font-medium\",\n active\n ? \"bg-background/50 border-border/50 text-muted-foreground\"\n : \"bg-muted/10 border-border/15 text-muted-foreground/25\"\n )}\n >\n {f}\n </span>\n ))}\n </div>\n\n {/* CTA */}\n {live && href ? (\n <div className=\"space-y-2\">\n <Link\n href={href}\n className={cn(\n \"flex items-center justify-between w-full h-10 px-4 rounded-xl\",\n \"text-sm font-semibold text-white\",\n \"transition-all duration-200 active:scale-[0.98]\",\n buttonColor\n )}\n >\n {buttonLabel ?? \"Get started\"}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n {browseHref && browseLinkLabel && (\n <Link\n href={browseHref}\n className=\"flex items-center justify-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors py-1\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n )}\n </div>\n ) : (\n <div className=\"flex items-center gap-2 h-10 text-sm text-muted-foreground/30 font-medium\">\n <Lock className=\"h-3.5 w-3.5\" />\n {building ? \"In development\" : \"Coming soon\"}\n </div>\n )}\n\n </div>\n </div>\n );\n}\n\nexport interface LaunchpadServicesGridProps {\n services: ServiceCardProps[];\n className?: string;\n}\n\nexport function LaunchpadServicesGrid({ services, className }: LaunchpadServicesGridProps) {\n return (\n <div\n className={cn(\n \"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\",\n className\n )}\n >\n {services.map(({ key, ...rest }) => (\n <ServiceCard key={key} {...rest} />\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-dapp.\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, ArrowUpRight, ArrowRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\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 + arrow tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** soft circle behind the arrow */\n bg: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = { text: \"text-sky-600 dark:text-sky-400\", bg: \"bg-sky-500/10\" };\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"mint-ip-asset\": { text: \"text-sky-600 dark:text-sky-400\", bg: \"bg-sky-500/10\" },\n \"create-collection\": { text: \"text-violet-600 dark:text-violet-400\", bg: \"bg-violet-500/10\" },\n \"ip-collection-1155\": { text: \"text-rose-600 dark:text-rose-400\", bg: \"bg-rose-500/10\" },\n \"mint-editions\": { text: \"text-amber-600 dark:text-amber-400\", bg: \"bg-amber-500/10\" },\n \"creator-coins\": { text: \"text-pink-600 dark:text-pink-400\", bg: \"bg-pink-500/10\" },\n \"claim-memecoin\": { text: \"text-teal-600 dark:text-teal-400\", bg: \"bg-teal-500/10\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", bg: \"bg-orange-500/10\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", bg: \"bg-emerald-500/10\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", bg: \"bg-indigo-500/10\" },\n \"claim-username\": { text: \"text-purple-600 dark:text-purple-400\", bg: \"bg-purple-500/10\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", bg: \"bg-cyan-500/10\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n}\n\nexport function LaunchpadServiceCard({ def, override = {} }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel } = 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 \"relative rounded-2xl border border-border/60 bg-card p-5 sm:p-6\",\n \"flex flex-col gap-3 transition-transform\",\n live ? \"active:scale-[0.99]\" : \"opacity-60\",\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <Icon className={cn(\"h-7 w-7 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n {live ? (\n <span className={cn(\"h-9 w-9 shrink-0 rounded-full flex items-center justify-center\", hue.bg)}>\n <ArrowUpRight className={cn(\"h-4 w-4\", hue.text)} />\n </span>\n ) : (\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\">\n <h3 className=\"text-lg font-bold tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-sm leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\")}>\n {blurb}\n </p>\n </div>\n\n {/* Stretched link — makes the whole card the action without nesting anchors */}\n {live && href && <Link href={href} aria-label={title} className=\"absolute inset-0 z-10 rounded-2xl\" />}\n\n {live && browseHref && browseLinkLabel && (\n <Link\n href={browseHref}\n className=\"relative z-20 mt-auto self-start 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 </div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-1\">\n <h2 className=\"text-xl font-bold tracking-tight\">{group.title}</h2>\n <p className=\"text-sm text-muted-foreground\">{group.tagline}</p>\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-10\", 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-4\"\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {defs.map((def) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} />\n ))}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -26,55 +26,56 @@ var import_lucide_react = require("lucide-react");
|
|
|
26
26
|
const LAUNCHPAD_SERVICE_GROUPS = [
|
|
27
27
|
{
|
|
28
28
|
key: "single-edition",
|
|
29
|
-
title: "Single
|
|
30
|
-
|
|
31
|
-
tagline: "Publish one-of-one works and group them under your own brand."
|
|
29
|
+
title: "Single Editions",
|
|
30
|
+
tagline: "Publish one-of-a-kind pieces \u2014 a song, a photo, a film \u2014 under your own name."
|
|
32
31
|
},
|
|
33
32
|
{
|
|
34
33
|
key: "limited-editions",
|
|
35
34
|
title: "Limited Editions",
|
|
36
|
-
|
|
37
|
-
tagline: "Release your work in numbered multiples collectors can buy and trade."
|
|
35
|
+
tagline: "Release your work in numbered copies your fans can collect and trade."
|
|
38
36
|
},
|
|
39
37
|
{
|
|
40
38
|
key: "creator-coins",
|
|
41
39
|
title: "Creator Coins",
|
|
42
|
-
tagline: "Launch your own coin
|
|
40
|
+
tagline: "Launch your own coin and let your community back you."
|
|
43
41
|
},
|
|
44
42
|
{
|
|
45
43
|
key: "collection-drop",
|
|
46
44
|
title: "Collection Drop",
|
|
47
|
-
tagline: "
|
|
45
|
+
tagline: "Schedule a release and let your audience mint while the window is open."
|
|
48
46
|
},
|
|
49
47
|
{
|
|
50
48
|
key: "pop-protocol",
|
|
51
49
|
title: "POP Protocol",
|
|
52
|
-
tagline: "
|
|
50
|
+
tagline: "Give your community proof they were part of the moment."
|
|
53
51
|
},
|
|
54
52
|
{
|
|
55
53
|
key: "licensing-remix",
|
|
56
54
|
title: "Licensing & Remix",
|
|
57
|
-
tagline: "
|
|
55
|
+
tagline: "Let others build on your work \u2014 with credit and royalties flowing back to you."
|
|
58
56
|
},
|
|
59
57
|
{
|
|
60
58
|
key: "claims",
|
|
61
59
|
title: "Claims",
|
|
62
|
-
tagline: "
|
|
60
|
+
tagline: "Quick wins \u2014 claim your name and bring in work you have already made."
|
|
63
61
|
},
|
|
64
62
|
{
|
|
65
63
|
key: "coming-soon",
|
|
66
64
|
title: "Coming soon",
|
|
67
|
-
tagline: "More
|
|
65
|
+
tagline: "More ways to earn are on the way."
|
|
68
66
|
}
|
|
69
67
|
];
|
|
70
68
|
const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
71
69
|
// ── Create ────────────────────────────────────────────────────────────────
|
|
72
70
|
{
|
|
73
71
|
key: "mint-ip-asset",
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
blurb: "Upload a song, a photo, a video \u2014 any file \u2014 and publish it as yours, free, in minutes.",
|
|
73
|
+
title: "Mint singular NFT",
|
|
74
|
+
subtitle: "Publish your creative work onchain",
|
|
75
|
+
description: "Upload any photo, video, audio, or document and mint it as an IP NFT \u2014 with licensing, provenance, and ownership all locked on-chain.",
|
|
76
|
+
// Apps may override features[0] with their gasless-rail wording (ChipiPay/AVNU).
|
|
77
|
+
features: ["Gasless transactions", "IPFS metadata", "Programmable licensing"],
|
|
78
|
+
example: "e.g. A song, a photo, an ebook, a short film",
|
|
78
79
|
icon: import_lucide_react.ImagePlus,
|
|
79
80
|
gradient: "from-blue-500/10 via-sky-400/4 to-transparent",
|
|
80
81
|
borderColor: "border-blue-500/20",
|
|
@@ -87,10 +88,12 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
87
88
|
},
|
|
88
89
|
{
|
|
89
90
|
key: "create-collection",
|
|
90
|
-
|
|
91
|
+
blurb: "Give your works a home of their own, with its own page and name.",
|
|
92
|
+
title: "Create NFT Collection",
|
|
91
93
|
subtitle: "Group your NFTs under a shared identity",
|
|
92
|
-
description: "Deploy a branded ERC-721 collection with its own page
|
|
94
|
+
description: "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.",
|
|
93
95
|
features: ["Factory-deployed ERC-721", "Branded collection page", "Add assets at any time"],
|
|
96
|
+
example: "e.g. A photography portfolio, a music catalog, a comic series",
|
|
94
97
|
icon: import_lucide_react.Layers,
|
|
95
98
|
gradient: "from-violet-500/10 via-purple-400/4 to-transparent",
|
|
96
99
|
borderColor: "border-violet-500/20",
|
|
@@ -103,10 +106,12 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
103
106
|
},
|
|
104
107
|
{
|
|
105
108
|
key: "ip-collection-1155",
|
|
106
|
-
|
|
109
|
+
blurb: "Set up a collection made for numbered copies of your work.",
|
|
110
|
+
title: "Limited Editions Collections",
|
|
107
111
|
subtitle: "Deploy a contract for multi-copy NFT releases",
|
|
108
|
-
description: "
|
|
109
|
-
features: ["Multi-edition ERC-1155", "
|
|
112
|
+
description: "Create a collection built for editions \u2014 release music tracks, art prints, or any IP in numbered multiples. Each edition token is tradeable on Medialane.",
|
|
113
|
+
features: ["Multi-edition ERC-1155", "Numbered tokens", "Tradeable on Medialane"],
|
|
114
|
+
example: "e.g. 50 copies of a limited print, a music EP released in 100 editions",
|
|
110
115
|
icon: import_lucide_react.Layers,
|
|
111
116
|
gradient: "from-violet-500/10 via-purple-400/4 to-transparent",
|
|
112
117
|
borderColor: "border-violet-500/20",
|
|
@@ -119,10 +124,12 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
119
124
|
},
|
|
120
125
|
{
|
|
121
126
|
key: "mint-editions",
|
|
122
|
-
|
|
127
|
+
blurb: "Release a new piece in as many copies as you choose.",
|
|
128
|
+
title: "Mint Limited Edition",
|
|
123
129
|
subtitle: "Add new editions to an existing collection",
|
|
124
|
-
description: "
|
|
130
|
+
description: "Pick one of your Limited Edition contracts, upload artwork, set the supply, and release to collectors \u2014 all in a few clicks.",
|
|
125
131
|
features: ["Choose any edition collection", "Set edition supply", "IPFS metadata"],
|
|
132
|
+
example: "e.g. Drop 25 numbered prints from your art series",
|
|
126
133
|
icon: import_lucide_react.PlusCircle,
|
|
127
134
|
gradient: "from-fuchsia-500/10 via-violet-400/4 to-transparent",
|
|
128
135
|
borderColor: "border-fuchsia-500/20",
|
|
@@ -135,10 +142,12 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
135
142
|
},
|
|
136
143
|
{
|
|
137
144
|
key: "remix-asset",
|
|
145
|
+
blurb: "Create from another work \u2014 credit and royalties are handled for you.",
|
|
138
146
|
title: "Remix Asset",
|
|
139
147
|
subtitle: "Derivative works with on-chain attribution",
|
|
140
|
-
description: "Create a licensed derivative of any
|
|
148
|
+
description: "Create a licensed derivative of any digital asset with full provenance and attribution flowing back to the original creator on-chain.",
|
|
141
149
|
features: ["On-chain attribution", "License-enforced at mint", "Royalties to original creator"],
|
|
150
|
+
example: "e.g. A remix of a song, a derivative artwork inspired by an original",
|
|
142
151
|
icon: import_lucide_react.GitBranch,
|
|
143
152
|
gradient: "from-rose-500/10 via-pink-400/4 to-transparent",
|
|
144
153
|
borderColor: "border-rose-500/20",
|
|
@@ -152,10 +161,12 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
152
161
|
// ── Launch ────────────────────────────────────────────────────────────────
|
|
153
162
|
{
|
|
154
163
|
key: "pop-protocol",
|
|
164
|
+
blurb: "Hand out badges your attendees keep forever.",
|
|
155
165
|
title: "POP Protocol",
|
|
156
166
|
subtitle: "Proof-of-participation for events & communities",
|
|
157
|
-
description: "
|
|
167
|
+
description: "Issue soulbound credentials to your community \u2014 one non-transferable badge per wallet, permanently on-chain. No transferring, no faking.",
|
|
158
168
|
features: ["Soulbound \xB7 non-transferable", "One credential per wallet", "Optional allowlist gating"],
|
|
169
|
+
example: "e.g. Hackathon attendance badge, community membership, conference pass",
|
|
159
170
|
icon: import_lucide_react.Award,
|
|
160
171
|
gradient: "from-emerald-500/10 via-green-400/4 to-transparent",
|
|
161
172
|
borderColor: "border-emerald-500/20",
|
|
@@ -169,10 +180,12 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
169
180
|
},
|
|
170
181
|
{
|
|
171
182
|
key: "collection-drop",
|
|
183
|
+
blurb: "Set a price, a window, and a limited run \u2014 then open the doors.",
|
|
172
184
|
title: "Collection Drop",
|
|
173
|
-
subtitle: "
|
|
174
|
-
description: "Launch a
|
|
175
|
-
features: ["
|
|
185
|
+
subtitle: "Timed NFT releases with mint windows",
|
|
186
|
+
description: "Launch a time-gated mint campaign \u2014 set a price, supply cap, start and end time, and let collectors mint directly from your drop page.",
|
|
187
|
+
features: ["Timed mint window", "Price + supply cap", "Branded drop page"],
|
|
188
|
+
example: "e.g. A 48-hour drop of 200 NFTs at 5 USDC each",
|
|
176
189
|
icon: import_lucide_react.Package,
|
|
177
190
|
gradient: "from-orange-500/10 via-amber-400/4 to-transparent",
|
|
178
191
|
borderColor: "border-orange-500/20",
|
|
@@ -186,6 +199,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
186
199
|
},
|
|
187
200
|
{
|
|
188
201
|
key: "ip-tickets",
|
|
202
|
+
blurb: "Sell tickets to your shows and events.",
|
|
189
203
|
title: "IP Tickets",
|
|
190
204
|
subtitle: "Gate real-world experiences with NFTs",
|
|
191
205
|
description: "Distribute tickets for concerts, workshops, and events. Each ticket is verifiable on-chain proof of attendance.",
|
|
@@ -201,6 +215,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
201
215
|
},
|
|
202
216
|
{
|
|
203
217
|
key: "membership",
|
|
218
|
+
blurb: "Passes that unlock more for your closest fans.",
|
|
204
219
|
title: "Membership",
|
|
205
220
|
subtitle: "Token-gated access passes",
|
|
206
221
|
description: "Create tiered membership passes that unlock exclusive content, private communities, and experiences for your most loyal fans.",
|
|
@@ -217,6 +232,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
217
232
|
// ── Monetize ─────────────────────────────────────────────────────────────
|
|
218
233
|
{
|
|
219
234
|
key: "subscriptions",
|
|
235
|
+
blurb: "Recurring support from your audience.",
|
|
220
236
|
title: "Subscriptions",
|
|
221
237
|
subtitle: "Recurring on-chain revenue",
|
|
222
238
|
description: "Monthly licensing, creator support tiers, and access passes \u2014 all auto-renewed without intermediaries.",
|
|
@@ -232,6 +248,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
232
248
|
},
|
|
233
249
|
{
|
|
234
250
|
key: "ip-coins",
|
|
251
|
+
blurb: "Let fans own a piece of your catalog.",
|
|
235
252
|
title: "IP Coins",
|
|
236
253
|
subtitle: "Fractional ownership of intellectual property",
|
|
237
254
|
description: "Tokenize your IP catalog as fungible tokens. Enable fractional ownership and liquid markets around your creative work.",
|
|
@@ -247,6 +264,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
247
264
|
},
|
|
248
265
|
{
|
|
249
266
|
key: "creator-coins",
|
|
267
|
+
blurb: "Launch your coin in a few clicks \u2014 and stay in control of it.",
|
|
250
268
|
title: "Creator Coin",
|
|
251
269
|
subtitle: "Your own coin, your liquidity",
|
|
252
270
|
description: "Launch a standard ERC-20 coin tied to your creative work, paired with a public Ekubo liquidity pool. You set the supply and allocation \u2014 and you stay in control of the liquidity.",
|
|
@@ -264,6 +282,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
264
282
|
// ── Claims ────────────────────────────────────────────────────────────────
|
|
265
283
|
{
|
|
266
284
|
key: "claim-memecoin",
|
|
285
|
+
blurb: "Already launched a coin? Add it to your Medialane profile.",
|
|
267
286
|
title: "Claim Memecoin",
|
|
268
287
|
subtitle: "Bring your Starknet coin to Medialane",
|
|
269
288
|
description: "Already launched a coin on Starknet (unrug or partner)? Claim it to add it to Medialane \u2014 reviewed by our team, then live on the Coins page and your profile.",
|
|
@@ -280,6 +299,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
280
299
|
},
|
|
281
300
|
{
|
|
282
301
|
key: "claim-username",
|
|
302
|
+
blurb: "Reserve your name and get your own creator page.",
|
|
283
303
|
title: "Claim Username",
|
|
284
304
|
subtitle: "Reserve your creator page URL",
|
|
285
305
|
description: "Claim your unique username and get a shareable creator page \u2014 your public portfolio at a clean, memorable URL. Free, and yours.",
|
|
@@ -296,6 +316,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
|
|
|
296
316
|
},
|
|
297
317
|
{
|
|
298
318
|
key: "claim-collection",
|
|
319
|
+
blurb: "Made a collection somewhere else? Bring it to your profile.",
|
|
299
320
|
title: "Claim Collection",
|
|
300
321
|
subtitle: "Import an existing Starknet collection",
|
|
301
322
|
description: "Already deployed an ERC-721 collection on Starknet? Claim it to link it to your Medialane profile and give it a branded collection page.",
|