@medialane/ui 0.9.1 → 0.10.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 +75 -31
- package/dist/components/launchpad-services.cjs.map +1 -1
- package/dist/components/launchpad-services.d.cts +9 -5
- package/dist/components/launchpad-services.d.ts +9 -5
- package/dist/components/launchpad-services.js +76 -32
- package/dist/components/launchpad-services.js.map +1 -1
- package/dist/data/launchpad-services.cjs +62 -19
- package/dist/data/launchpad-services.cjs.map +1 -1
- package/dist/data/launchpad-services.d.cts +2 -0
- package/dist/data/launchpad-services.d.ts +2 -0
- package/dist/data/launchpad-services.js +64 -20
- package/dist/data/launchpad-services.js.map +1 -1
- package/package.json +1 -1
|
@@ -43,39 +43,44 @@ var import_launchpad_services = require("../data/launchpad-services.js");
|
|
|
43
43
|
const DEFAULT_HUE = {
|
|
44
44
|
text: "text-sky-600 dark:text-sky-400",
|
|
45
45
|
solid: "bg-sky-500",
|
|
46
|
-
|
|
46
|
+
border: "border-sky-500/25",
|
|
47
|
+
pill: "bg-gradient-to-r from-sky-500 to-blue-600"
|
|
47
48
|
};
|
|
48
49
|
const SERVICE_HUES = {
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
50
|
+
// Single Editions — blue + green
|
|
51
|
+
"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" },
|
|
52
|
+
"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" },
|
|
53
|
+
// Limited Editions — purple + red
|
|
54
|
+
"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" },
|
|
55
|
+
"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" },
|
|
56
|
+
// Creator Coins & Memecoins — yellow + orange
|
|
57
|
+
"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" },
|
|
58
|
+
"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" },
|
|
59
|
+
"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" },
|
|
60
|
+
"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" },
|
|
61
|
+
"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" },
|
|
62
|
+
"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" },
|
|
63
|
+
"claim-collection": { text: "text-cyan-600 dark:text-cyan-400", solid: "bg-cyan-500", border: "border-cyan-500/25", pill: "bg-gradient-to-r from-cyan-500 to-sky-600" },
|
|
64
|
+
"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" }
|
|
60
65
|
};
|
|
61
|
-
function LaunchpadServiceCard({ def, override = {} }) {
|
|
62
|
-
const { key, icon: Icon, title, browseLinkLabel } = def;
|
|
66
|
+
function LaunchpadServiceCard({ def, override = {}, featured = false }) {
|
|
67
|
+
const { key, icon: Icon, title, browseLinkLabel, features, example } = def;
|
|
63
68
|
const status = override.status ?? def.status;
|
|
64
69
|
const blurb = override.blurb ?? def.blurb;
|
|
65
70
|
const { href, browseHref } = override;
|
|
66
71
|
const live = status === "live";
|
|
67
72
|
const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;
|
|
68
|
-
|
|
73
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
69
74
|
"div",
|
|
70
75
|
{
|
|
71
76
|
className: (0, import_cn.cn)(
|
|
72
|
-
"relative rounded-
|
|
77
|
+
"relative rounded-2xl border bg-card overflow-hidden flex flex-col flex-1 min-h-[210px]",
|
|
73
78
|
"transition-transform",
|
|
74
|
-
live ? "active:scale-[0.99]" : "opacity-70"
|
|
79
|
+
live ? (0, import_cn.cn)(hue.border, "active:scale-[0.99]") : "border-border/30 opacity-70",
|
|
80
|
+
featured && "sm:col-span-2"
|
|
75
81
|
),
|
|
76
82
|
children: [
|
|
77
|
-
|
|
78
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": true, className: "absolute -right-8 -bottom-10 opacity-[0.05] select-none pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-44 w-44" }) }),
|
|
83
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": true, className: "absolute -right-8 -bottom-10 opacity-[0.04] select-none pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-44 w-44" }) }),
|
|
79
84
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex flex-col flex-1 p-6 gap-4", children: [
|
|
80
85
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
|
|
81
86
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
|
|
@@ -87,12 +92,27 @@ function LaunchpadServiceCard({ def, override = {} }) {
|
|
|
87
92
|
"Coming soon"
|
|
88
93
|
] })
|
|
89
94
|
] }),
|
|
90
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-
|
|
91
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-2xl font-
|
|
92
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (0, import_cn.cn)("text-[15px] leading-relaxed
|
|
95
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
|
|
96
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-2xl sm:text-3xl font-black tracking-tight leading-snug", children: title }),
|
|
97
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (0, import_cn.cn)("text-[15px] leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb }),
|
|
98
|
+
live && example && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
99
|
+
"e.g. ",
|
|
100
|
+
example
|
|
101
|
+
] })
|
|
93
102
|
] }),
|
|
94
|
-
live &&
|
|
95
|
-
|
|
103
|
+
live && features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
104
|
+
"span",
|
|
105
|
+
{
|
|
106
|
+
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",
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { className: (0, import_cn.cn)("h-3 w-3 shrink-0", hue.text) }),
|
|
109
|
+
feature
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
feature
|
|
113
|
+
)) }),
|
|
114
|
+
live && href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href, "aria-label": `${def.cta} \u2014 ${title}`, className: "absolute inset-0 z-10" }),
|
|
115
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-auto pt-1 flex items-end justify-between gap-3", children: [
|
|
96
116
|
live && browseHref && browseLinkLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
97
117
|
import_link.default,
|
|
98
118
|
{
|
|
@@ -104,18 +124,30 @@ function LaunchpadServiceCard({ def, override = {} }) {
|
|
|
104
124
|
]
|
|
105
125
|
}
|
|
106
126
|
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
|
|
107
|
-
live && /* @__PURE__ */ (0, import_jsx_runtime.
|
|
127
|
+
live && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
128
|
+
"span",
|
|
129
|
+
{
|
|
130
|
+
className: (0, import_cn.cn)(
|
|
131
|
+
"inline-flex items-center gap-2 h-10 px-5 rounded-full",
|
|
132
|
+
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
133
|
+
hue.pill
|
|
134
|
+
),
|
|
135
|
+
children: [
|
|
136
|
+
def.cta,
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-4 w-4" })
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
)
|
|
108
141
|
] })
|
|
109
142
|
] })
|
|
110
143
|
]
|
|
111
144
|
}
|
|
112
145
|
);
|
|
113
|
-
return live ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("p-[1px] rounded-2xl bg-gradient-to-br flex flex-col", hue.ring), children: card }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rounded-2xl border border-border/30 flex flex-col", children: card });
|
|
114
146
|
}
|
|
115
147
|
function GroupHeader({ group }) {
|
|
116
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1", children: [
|
|
117
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-
|
|
118
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: group.tagline })
|
|
148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
149
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-2xl sm:text-3xl font-black tracking-tight", children: group.title }),
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm sm:text-base text-muted-foreground", children: group.tagline })
|
|
119
151
|
] });
|
|
120
152
|
}
|
|
121
153
|
function ComingSoonStrip({ group, defs }) {
|
|
@@ -135,16 +167,28 @@ function LaunchpadGroupedSections({ overrides, className }) {
|
|
|
135
167
|
if (group.key === "coming-soon") {
|
|
136
168
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComingSoonStrip, { group, defs }, group.key);
|
|
137
169
|
}
|
|
170
|
+
const isCoins = group.key === "creator-coins";
|
|
138
171
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
139
172
|
import_framer_motion.motion.div,
|
|
140
173
|
{
|
|
141
174
|
initial: { opacity: 0, y: 8 },
|
|
142
175
|
animate: { opacity: 1, y: 0 },
|
|
143
176
|
transition: { duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
144
|
-
className:
|
|
177
|
+
className: (0, import_cn.cn)(
|
|
178
|
+
"space-y-4",
|
|
179
|
+
isCoins && "rounded-3xl border border-yellow-500/20 bg-gradient-to-br from-yellow-500/[0.08] via-orange-500/[0.05] to-transparent p-5 sm:p-6"
|
|
180
|
+
),
|
|
145
181
|
children: [
|
|
146
182
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GroupHeader, { group }),
|
|
147
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: defs.map((def) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
183
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: defs.map((def) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
184
|
+
LaunchpadServiceCard,
|
|
185
|
+
{
|
|
186
|
+
def,
|
|
187
|
+
override: overrides[def.key],
|
|
188
|
+
featured: group.key === "pop-protocol"
|
|
189
|
+
},
|
|
190
|
+
def.key
|
|
191
|
+
)) })
|
|
148
192
|
]
|
|
149
193
|
},
|
|
150
194
|
group.key
|
|
@@ -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-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 + link tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — the arrow action + icon glow */\n solid: string;\n /** gradient ring around live cards */\n ring: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n ring: \"from-sky-500/60 via-sky-400/15 to-sky-600/40\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"mint-ip-asset\": { text: \"text-sky-600 dark:text-sky-400\", solid: \"bg-sky-500\", ring: \"from-sky-500/60 via-sky-400/15 to-sky-600/40\" },\n \"create-collection\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", ring: \"from-violet-500/60 via-violet-400/15 to-violet-600/40\" },\n \"ip-collection-1155\": { text: \"text-rose-600 dark:text-rose-400\", solid: \"bg-rose-500\", ring: \"from-rose-500/60 via-rose-400/15 to-rose-600/40\" },\n \"mint-editions\": { text: \"text-amber-600 dark:text-amber-400\", solid: \"bg-amber-500\", ring: \"from-amber-500/60 via-amber-400/15 to-amber-600/40\" },\n \"creator-coins\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", ring: \"from-pink-500/60 via-pink-400/15 to-pink-600/40\" },\n \"claim-memecoin\": { text: \"text-teal-600 dark:text-teal-400\", solid: \"bg-teal-500\", ring: \"from-teal-500/60 via-teal-400/15 to-teal-600/40\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", ring: \"from-orange-500/60 via-orange-400/15 to-orange-600/40\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", ring: \"from-emerald-500/60 via-emerald-400/15 to-emerald-600/40\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", ring: \"from-indigo-500/60 via-indigo-400/15 to-indigo-600/40\" },\n \"claim-username\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", ring: \"from-purple-500/60 via-purple-400/15 to-purple-600/40\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", ring: \"from-cyan-500/60 via-cyan-400/15 to-cyan-600/40\" },\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 const card = (\n <div\n className={cn(\n \"relative rounded-[15px] bg-card overflow-hidden flex flex-col flex-1 min-h-[210px]\",\n \"transition-transform\",\n live ? \"active:scale-[0.99]\" : \"opacity-70\",\n )}\n >\n {/* Soft hue tint — same language as the Drop Pages panel */}\n {live && (\n <div aria-hidden className={cn(\"absolute inset-0 pointer-events-none bg-gradient-to-br to-transparent opacity-[0.07]\", hue.solid.replace(\"bg-\", \"from-\"))} />\n )}\n {/* Giant watermark icon, ghosted in the corner */}\n <div aria-hidden className=\"absolute -right-8 -bottom-10 opacity-[0.05] select-none pointer-events-none\">\n <Icon className=\"h-44 w-44\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 gap-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"relative\">\n {live && (\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n )}\n <Icon className={cn(\"relative h-9 w-9 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n </div>\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-1.5\">\n <h3 className=\"text-2xl font-bold tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed max-w-[34ch]\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\")}>\n {blurb}\n </p>\n </div>\n\n {/* Stretched link — the whole card is the action, no title-repeating button */}\n {live && href && <Link href={href} aria-label={title} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span className={cn(\"h-11 w-11 shrink-0 rounded-full flex items-center justify-center shadow-lg shadow-black/20\", hue.solid)}>\n <ArrowUpRight className=\"h-5 w-5 text-white\" />\n </span>\n )}\n </div>\n </div>\n </div>\n );\n\n return live ? (\n <div className={cn(\"p-[1px] rounded-2xl bg-gradient-to-br flex flex-col\", hue.ring)}>\n {card}\n </div>\n ) : (\n <div className=\"rounded-2xl border border-border/30 flex flex-col\">{card}</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":["Link"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Launchpad grouped services — the single source for the /launchpad page UI\n * in medialane-io and medialane-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, 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 ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\n// ── Per-app injection points ─────────────────────────────────────────────────\n\nexport interface ServiceOverride {\n /** Primary destination — the whole card links here (required for live services) */\n href?: string;\n /** Secondary browse link href (pairs with the def's browseLinkLabel) */\n browseHref?: string;\n /** Per-app rollout flips (e.g. coins live on one app first) */\n status?: ServiceStatus;\n /** Per-app one-liner override (rarely needed) */\n blurb?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n// ── One unique hue per service — never repeated inside a group ───────────────\n\ninterface ServiceHue {\n /** icon tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — icon glow */\n solid: string;\n /** thin card border tint */\n border: string;\n /** vivid two-stop gradient for the action pill (asset-page button language) */\n pill: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n border: \"border-sky-500/25\",\n pill: \"bg-gradient-to-r from-sky-500 to-blue-600\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n // Single Editions — blue + green\n \"mint-ip-asset\": { text: \"text-blue-600 dark:text-blue-400\", solid: \"bg-blue-500\", border: \"border-blue-500/25\", pill: \"bg-gradient-to-r from-blue-500 to-sky-600\" },\n \"create-collection\": { text: \"text-green-600 dark:text-green-400\", solid: \"bg-green-500\", border: \"border-green-500/25\", pill: \"bg-gradient-to-r from-green-500 to-emerald-600\" },\n // Limited Editions — purple + red\n \"ip-collection-1155\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", border: \"border-purple-500/25\", pill: \"bg-gradient-to-r from-purple-500 to-violet-600\" },\n \"mint-editions\": { text: \"text-red-600 dark:text-red-400\", solid: \"bg-red-500\", border: \"border-red-500/25\", pill: \"bg-gradient-to-r from-red-500 to-rose-600\" },\n // Creator Coins & Memecoins — yellow + orange\n \"creator-coins\": { text: \"text-yellow-600 dark:text-yellow-400\", solid: \"bg-yellow-500\", border: \"border-yellow-500/25\", pill: \"bg-gradient-to-r from-yellow-500 to-amber-500\" },\n \"claim-memecoin\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-amber-600\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-red-500\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", border: \"border-emerald-500/25\", pill: \"bg-gradient-to-r from-emerald-500 to-green-600\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", border: \"border-indigo-500/25\", pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\" },\n \"claim-username\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", border: \"border-violet-500/25\", pill: \"bg-gradient-to-r from-violet-500 to-fuchsia-600\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", border: \"border-cyan-500/25\", pill: \"bg-gradient-to-r from-cyan-500 to-sky-600\" },\n \"claim-collection-name\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", border: \"border-pink-500/25\", pill: \"bg-gradient-to-r from-pink-500 to-rose-600\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n /** Showcase layout — spans the full grid width (e.g. POP Protocol) */\n featured?: boolean;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, featured = false }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel, features, example } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href, browseHref } = override;\n\n const live = status === \"live\";\n const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;\n\n return (\n <div\n className={cn(\n \"relative rounded-2xl border bg-card overflow-hidden flex flex-col flex-1 min-h-[210px]\",\n \"transition-transform\",\n live ? cn(hue.border, \"active:scale-[0.99]\") : \"border-border/30 opacity-70\",\n featured && \"sm:col-span-2\",\n )}\n >\n {/* Giant watermark icon, ghosted in the corner (Drop-Pages-panel language) */}\n <div aria-hidden className=\"absolute -right-8 -bottom-10 opacity-[0.04] select-none pointer-events-none\">\n <Icon className=\"h-44 w-44\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 gap-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"relative\">\n {live && (\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n )}\n <Icon className={cn(\"relative h-9 w-9 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n </div>\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-2xl sm:text-3xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n {live && example && (\n <p className=\"text-[13px] leading-relaxed text-muted-foreground/70 italic\">\n e.g. {example}\n </p>\n )}\n </div>\n\n {/* Feature showcase — plain-language chips */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground\"\n >\n <Check className={cn(\"h-3 w-3 shrink-0\", hue.text)} />\n {feature}\n </span>\n ))}\n </div>\n )}\n\n {/* Stretched link — the whole card is the action; the pill is the visual cue */}\n {live && href && <Link href={href} aria-label={`${def.cta} — ${title}`} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between gap-3\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-10 px-5 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {def.cta}\n <ArrowRight className=\"h-4 w-4\" />\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-1.5\">\n <h2 className=\"text-2xl sm:text-3xl font-black tracking-tight\">{group.title}</h2>\n <p className=\"text-sm sm:text-base 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 // Creator Coins & Memecoins get a distinct yellow/orange panel around the section\n const isCoins = group.key === \"creator-coins\";\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={cn(\n \"space-y-4\",\n isCoins &&\n \"rounded-3xl border border-yellow-500/20 bg-gradient-to-br from-yellow-500/[0.08] via-orange-500/[0.05] to-transparent p-5 sm:p-6\",\n )}\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {defs.map((def) => (\n <LaunchpadServiceCard\n key={def.key}\n def={def}\n override={overrides[def.key]}\n featured={group.key === \"pop-protocol\"}\n />\n ))}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
@@ -14,19 +14,23 @@ interface ServiceOverride {
|
|
|
14
14
|
}
|
|
15
15
|
type ServiceOverrides = Record<string, ServiceOverride>;
|
|
16
16
|
interface ServiceHue {
|
|
17
|
-
/** icon
|
|
17
|
+
/** icon tint (600 for light surfaces, 400 for dark) */
|
|
18
18
|
text: string;
|
|
19
|
-
/** solid fill —
|
|
19
|
+
/** solid fill — icon glow */
|
|
20
20
|
solid: string;
|
|
21
|
-
/**
|
|
22
|
-
|
|
21
|
+
/** thin card border tint */
|
|
22
|
+
border: string;
|
|
23
|
+
/** vivid two-stop gradient for the action pill (asset-page button language) */
|
|
24
|
+
pill: string;
|
|
23
25
|
}
|
|
24
26
|
declare const SERVICE_HUES: Record<string, ServiceHue>;
|
|
25
27
|
interface LaunchpadServiceCardProps {
|
|
26
28
|
def: ServiceDefinition;
|
|
27
29
|
override?: ServiceOverride;
|
|
30
|
+
/** Showcase layout — spans the full grid width (e.g. POP Protocol) */
|
|
31
|
+
featured?: boolean;
|
|
28
32
|
}
|
|
29
|
-
declare function LaunchpadServiceCard({ def, override }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
33
|
+
declare function LaunchpadServiceCard({ def, override, featured }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
30
34
|
interface LaunchpadGroupedSectionsProps {
|
|
31
35
|
/** Per-app hrefs / rollout flips, keyed by service key. */
|
|
32
36
|
overrides: ServiceOverrides;
|
|
@@ -14,19 +14,23 @@ interface ServiceOverride {
|
|
|
14
14
|
}
|
|
15
15
|
type ServiceOverrides = Record<string, ServiceOverride>;
|
|
16
16
|
interface ServiceHue {
|
|
17
|
-
/** icon
|
|
17
|
+
/** icon tint (600 for light surfaces, 400 for dark) */
|
|
18
18
|
text: string;
|
|
19
|
-
/** solid fill —
|
|
19
|
+
/** solid fill — icon glow */
|
|
20
20
|
solid: string;
|
|
21
|
-
/**
|
|
22
|
-
|
|
21
|
+
/** thin card border tint */
|
|
22
|
+
border: string;
|
|
23
|
+
/** vivid two-stop gradient for the action pill (asset-page button language) */
|
|
24
|
+
pill: string;
|
|
23
25
|
}
|
|
24
26
|
declare const SERVICE_HUES: Record<string, ServiceHue>;
|
|
25
27
|
interface LaunchpadServiceCardProps {
|
|
26
28
|
def: ServiceDefinition;
|
|
27
29
|
override?: ServiceOverride;
|
|
30
|
+
/** Showcase layout — spans the full grid width (e.g. POP Protocol) */
|
|
31
|
+
featured?: boolean;
|
|
28
32
|
}
|
|
29
|
-
declare function LaunchpadServiceCard({ def, override }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
33
|
+
declare function LaunchpadServiceCard({ def, override, featured }: LaunchpadServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
30
34
|
interface LaunchpadGroupedSectionsProps {
|
|
31
35
|
/** Per-app hrefs / rollout flips, keyed by service key. */
|
|
32
36
|
overrides: ServiceOverrides;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { motion } from "framer-motion";
|
|
5
|
-
import { Lock,
|
|
5
|
+
import { Lock, ArrowRight, Check } from "lucide-react";
|
|
6
6
|
import { cn } from "../utils/cn.js";
|
|
7
7
|
import {
|
|
8
8
|
LAUNCHPAD_SERVICE_DEFINITIONS,
|
|
@@ -11,39 +11,44 @@ import {
|
|
|
11
11
|
const DEFAULT_HUE = {
|
|
12
12
|
text: "text-sky-600 dark:text-sky-400",
|
|
13
13
|
solid: "bg-sky-500",
|
|
14
|
-
|
|
14
|
+
border: "border-sky-500/25",
|
|
15
|
+
pill: "bg-gradient-to-r from-sky-500 to-blue-600"
|
|
15
16
|
};
|
|
16
17
|
const SERVICE_HUES = {
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
18
|
+
// Single Editions — blue + green
|
|
19
|
+
"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" },
|
|
20
|
+
"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" },
|
|
21
|
+
// Limited Editions — purple + red
|
|
22
|
+
"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" },
|
|
23
|
+
"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" },
|
|
24
|
+
// Creator Coins & Memecoins — yellow + orange
|
|
25
|
+
"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" },
|
|
26
|
+
"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" },
|
|
27
|
+
"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" },
|
|
28
|
+
"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" },
|
|
29
|
+
"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" },
|
|
30
|
+
"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" },
|
|
31
|
+
"claim-collection": { text: "text-cyan-600 dark:text-cyan-400", solid: "bg-cyan-500", border: "border-cyan-500/25", pill: "bg-gradient-to-r from-cyan-500 to-sky-600" },
|
|
32
|
+
"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" }
|
|
28
33
|
};
|
|
29
|
-
function LaunchpadServiceCard({ def, override = {} }) {
|
|
30
|
-
const { key, icon: Icon, title, browseLinkLabel } = def;
|
|
34
|
+
function LaunchpadServiceCard({ def, override = {}, featured = false }) {
|
|
35
|
+
const { key, icon: Icon, title, browseLinkLabel, features, example } = def;
|
|
31
36
|
const status = override.status ?? def.status;
|
|
32
37
|
const blurb = override.blurb ?? def.blurb;
|
|
33
38
|
const { href, browseHref } = override;
|
|
34
39
|
const live = status === "live";
|
|
35
40
|
const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;
|
|
36
|
-
|
|
41
|
+
return /* @__PURE__ */ jsxs(
|
|
37
42
|
"div",
|
|
38
43
|
{
|
|
39
44
|
className: cn(
|
|
40
|
-
"relative rounded-
|
|
45
|
+
"relative rounded-2xl border bg-card overflow-hidden flex flex-col flex-1 min-h-[210px]",
|
|
41
46
|
"transition-transform",
|
|
42
|
-
live ? "active:scale-[0.99]" : "opacity-70"
|
|
47
|
+
live ? cn(hue.border, "active:scale-[0.99]") : "border-border/30 opacity-70",
|
|
48
|
+
featured && "sm:col-span-2"
|
|
43
49
|
),
|
|
44
50
|
children: [
|
|
45
|
-
|
|
46
|
-
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "absolute -right-8 -bottom-10 opacity-[0.05] select-none pointer-events-none", children: /* @__PURE__ */ jsx(Icon, { className: "h-44 w-44" }) }),
|
|
51
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "absolute -right-8 -bottom-10 opacity-[0.04] select-none pointer-events-none", children: /* @__PURE__ */ jsx(Icon, { className: "h-44 w-44" }) }),
|
|
47
52
|
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col flex-1 p-6 gap-4", children: [
|
|
48
53
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
49
54
|
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
@@ -55,12 +60,27 @@ function LaunchpadServiceCard({ def, override = {} }) {
|
|
|
55
60
|
"Coming soon"
|
|
56
61
|
] })
|
|
57
62
|
] }),
|
|
58
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
59
|
-
/* @__PURE__ */ jsx("h3", { className: "text-2xl font-
|
|
60
|
-
/* @__PURE__ */ jsx("p", { className: cn("text-[15px] leading-relaxed
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
64
|
+
/* @__PURE__ */ jsx("h3", { className: "text-2xl sm:text-3xl font-black tracking-tight leading-snug", children: title }),
|
|
65
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-[15px] leading-relaxed", live ? "text-muted-foreground" : "text-muted-foreground/60", !featured && "max-w-[36ch]"), children: blurb }),
|
|
66
|
+
live && example && /* @__PURE__ */ jsxs("p", { className: "text-[13px] leading-relaxed text-muted-foreground/70 italic", children: [
|
|
67
|
+
"e.g. ",
|
|
68
|
+
example
|
|
69
|
+
] })
|
|
61
70
|
] }),
|
|
62
|
-
live &&
|
|
63
|
-
|
|
71
|
+
live && features.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: features.map((feature) => /* @__PURE__ */ jsxs(
|
|
72
|
+
"span",
|
|
73
|
+
{
|
|
74
|
+
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",
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsx(Check, { className: cn("h-3 w-3 shrink-0", hue.text) }),
|
|
77
|
+
feature
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
feature
|
|
81
|
+
)) }),
|
|
82
|
+
live && href && /* @__PURE__ */ jsx(Link, { href, "aria-label": `${def.cta} \u2014 ${title}`, className: "absolute inset-0 z-10" }),
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-auto pt-1 flex items-end justify-between gap-3", children: [
|
|
64
84
|
live && browseHref && browseLinkLabel ? /* @__PURE__ */ jsxs(
|
|
65
85
|
Link,
|
|
66
86
|
{
|
|
@@ -72,18 +92,30 @@ function LaunchpadServiceCard({ def, override = {} }) {
|
|
|
72
92
|
]
|
|
73
93
|
}
|
|
74
94
|
) : /* @__PURE__ */ jsx("span", {}),
|
|
75
|
-
live && /* @__PURE__ */
|
|
95
|
+
live && /* @__PURE__ */ jsxs(
|
|
96
|
+
"span",
|
|
97
|
+
{
|
|
98
|
+
className: cn(
|
|
99
|
+
"inline-flex items-center gap-2 h-10 px-5 rounded-full",
|
|
100
|
+
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
101
|
+
hue.pill
|
|
102
|
+
),
|
|
103
|
+
children: [
|
|
104
|
+
def.cta,
|
|
105
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4" })
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
)
|
|
76
109
|
] })
|
|
77
110
|
] })
|
|
78
111
|
]
|
|
79
112
|
}
|
|
80
113
|
);
|
|
81
|
-
return live ? /* @__PURE__ */ jsx("div", { className: cn("p-[1px] rounded-2xl bg-gradient-to-br flex flex-col", hue.ring), children: card }) : /* @__PURE__ */ jsx("div", { className: "rounded-2xl border border-border/30 flex flex-col", children: card });
|
|
82
114
|
}
|
|
83
115
|
function GroupHeader({ group }) {
|
|
84
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
85
|
-
/* @__PURE__ */ jsx("h2", { className: "text-
|
|
86
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: group.tagline })
|
|
116
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
117
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-black tracking-tight", children: group.title }),
|
|
118
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm sm:text-base text-muted-foreground", children: group.tagline })
|
|
87
119
|
] });
|
|
88
120
|
}
|
|
89
121
|
function ComingSoonStrip({ group, defs }) {
|
|
@@ -103,16 +135,28 @@ function LaunchpadGroupedSections({ overrides, className }) {
|
|
|
103
135
|
if (group.key === "coming-soon") {
|
|
104
136
|
return /* @__PURE__ */ jsx(ComingSoonStrip, { group, defs }, group.key);
|
|
105
137
|
}
|
|
138
|
+
const isCoins = group.key === "creator-coins";
|
|
106
139
|
return /* @__PURE__ */ jsxs(
|
|
107
140
|
motion.div,
|
|
108
141
|
{
|
|
109
142
|
initial: { opacity: 0, y: 8 },
|
|
110
143
|
animate: { opacity: 1, y: 0 },
|
|
111
144
|
transition: { duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
112
|
-
className:
|
|
145
|
+
className: cn(
|
|
146
|
+
"space-y-4",
|
|
147
|
+
isCoins && "rounded-3xl border border-yellow-500/20 bg-gradient-to-br from-yellow-500/[0.08] via-orange-500/[0.05] to-transparent p-5 sm:p-6"
|
|
148
|
+
),
|
|
113
149
|
children: [
|
|
114
150
|
/* @__PURE__ */ jsx(GroupHeader, { group }),
|
|
115
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: defs.map((def) => /* @__PURE__ */ jsx(
|
|
151
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: defs.map((def) => /* @__PURE__ */ jsx(
|
|
152
|
+
LaunchpadServiceCard,
|
|
153
|
+
{
|
|
154
|
+
def,
|
|
155
|
+
override: overrides[def.key],
|
|
156
|
+
featured: group.key === "pop-protocol"
|
|
157
|
+
},
|
|
158
|
+
def.key
|
|
159
|
+
)) })
|
|
116
160
|
]
|
|
117
161
|
},
|
|
118
162
|
group.key
|
|
@@ -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-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 + link tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — the arrow action + icon glow */\n solid: string;\n /** gradient ring around live cards */\n ring: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n ring: \"from-sky-500/60 via-sky-400/15 to-sky-600/40\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"mint-ip-asset\": { text: \"text-sky-600 dark:text-sky-400\", solid: \"bg-sky-500\", ring: \"from-sky-500/60 via-sky-400/15 to-sky-600/40\" },\n \"create-collection\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", ring: \"from-violet-500/60 via-violet-400/15 to-violet-600/40\" },\n \"ip-collection-1155\": { text: \"text-rose-600 dark:text-rose-400\", solid: \"bg-rose-500\", ring: \"from-rose-500/60 via-rose-400/15 to-rose-600/40\" },\n \"mint-editions\": { text: \"text-amber-600 dark:text-amber-400\", solid: \"bg-amber-500\", ring: \"from-amber-500/60 via-amber-400/15 to-amber-600/40\" },\n \"creator-coins\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", ring: \"from-pink-500/60 via-pink-400/15 to-pink-600/40\" },\n \"claim-memecoin\": { text: \"text-teal-600 dark:text-teal-400\", solid: \"bg-teal-500\", ring: \"from-teal-500/60 via-teal-400/15 to-teal-600/40\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", ring: \"from-orange-500/60 via-orange-400/15 to-orange-600/40\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", ring: \"from-emerald-500/60 via-emerald-400/15 to-emerald-600/40\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", ring: \"from-indigo-500/60 via-indigo-400/15 to-indigo-600/40\" },\n \"claim-username\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", ring: \"from-purple-500/60 via-purple-400/15 to-purple-600/40\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", ring: \"from-cyan-500/60 via-cyan-400/15 to-cyan-600/40\" },\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 const card = (\n <div\n className={cn(\n \"relative rounded-[15px] bg-card overflow-hidden flex flex-col flex-1 min-h-[210px]\",\n \"transition-transform\",\n live ? \"active:scale-[0.99]\" : \"opacity-70\",\n )}\n >\n {/* Soft hue tint — same language as the Drop Pages panel */}\n {live && (\n <div aria-hidden className={cn(\"absolute inset-0 pointer-events-none bg-gradient-to-br to-transparent opacity-[0.07]\", hue.solid.replace(\"bg-\", \"from-\"))} />\n )}\n {/* Giant watermark icon, ghosted in the corner */}\n <div aria-hidden className=\"absolute -right-8 -bottom-10 opacity-[0.05] select-none pointer-events-none\">\n <Icon className=\"h-44 w-44\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 gap-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"relative\">\n {live && (\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n )}\n <Icon className={cn(\"relative h-9 w-9 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n </div>\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-1.5\">\n <h3 className=\"text-2xl font-bold tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed max-w-[34ch]\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\")}>\n {blurb}\n </p>\n </div>\n\n {/* Stretched link — the whole card is the action, no title-repeating button */}\n {live && href && <Link href={href} aria-label={title} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span className={cn(\"h-11 w-11 shrink-0 rounded-full flex items-center justify-center shadow-lg shadow-black/20\", hue.solid)}>\n <ArrowUpRight className=\"h-5 w-5 text-white\" />\n </span>\n )}\n </div>\n </div>\n </div>\n );\n\n return live ? (\n <div className={cn(\"p-[1px] rounded-2xl bg-gradient-to-br flex flex-col\", hue.ring)}>\n {card}\n </div>\n ) : (\n <div className=\"rounded-2xl border border-border/30 flex flex-col\">{card}</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":[]}
|
|
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, 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 ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\n// ── Per-app injection points ─────────────────────────────────────────────────\n\nexport interface ServiceOverride {\n /** Primary destination — the whole card links here (required for live services) */\n href?: string;\n /** Secondary browse link href (pairs with the def's browseLinkLabel) */\n browseHref?: string;\n /** Per-app rollout flips (e.g. coins live on one app first) */\n status?: ServiceStatus;\n /** Per-app one-liner override (rarely needed) */\n blurb?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n// ── One unique hue per service — never repeated inside a group ───────────────\n\ninterface ServiceHue {\n /** icon tint (600 for light surfaces, 400 for dark) */\n text: string;\n /** solid fill — icon glow */\n solid: string;\n /** thin card border tint */\n border: string;\n /** vivid two-stop gradient for the action pill (asset-page button language) */\n pill: string;\n}\n\nconst DEFAULT_HUE: ServiceHue = {\n text: \"text-sky-600 dark:text-sky-400\",\n solid: \"bg-sky-500\",\n border: \"border-sky-500/25\",\n pill: \"bg-gradient-to-r from-sky-500 to-blue-600\",\n};\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n // Single Editions — blue + green\n \"mint-ip-asset\": { text: \"text-blue-600 dark:text-blue-400\", solid: \"bg-blue-500\", border: \"border-blue-500/25\", pill: \"bg-gradient-to-r from-blue-500 to-sky-600\" },\n \"create-collection\": { text: \"text-green-600 dark:text-green-400\", solid: \"bg-green-500\", border: \"border-green-500/25\", pill: \"bg-gradient-to-r from-green-500 to-emerald-600\" },\n // Limited Editions — purple + red\n \"ip-collection-1155\": { text: \"text-purple-600 dark:text-purple-400\", solid: \"bg-purple-500\", border: \"border-purple-500/25\", pill: \"bg-gradient-to-r from-purple-500 to-violet-600\" },\n \"mint-editions\": { text: \"text-red-600 dark:text-red-400\", solid: \"bg-red-500\", border: \"border-red-500/25\", pill: \"bg-gradient-to-r from-red-500 to-rose-600\" },\n // Creator Coins & Memecoins — yellow + orange\n \"creator-coins\": { text: \"text-yellow-600 dark:text-yellow-400\", solid: \"bg-yellow-500\", border: \"border-yellow-500/25\", pill: \"bg-gradient-to-r from-yellow-500 to-amber-500\" },\n \"claim-memecoin\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-amber-600\" },\n \"collection-drop\": { text: \"text-orange-600 dark:text-orange-400\", solid: \"bg-orange-500\", border: \"border-orange-500/25\", pill: \"bg-gradient-to-r from-orange-500 to-red-500\" },\n \"pop-protocol\": { text: \"text-emerald-600 dark:text-emerald-400\", solid: \"bg-emerald-500\", border: \"border-emerald-500/25\", pill: \"bg-gradient-to-r from-emerald-500 to-green-600\" },\n \"remix-asset\": { text: \"text-indigo-600 dark:text-indigo-400\", solid: \"bg-indigo-500\", border: \"border-indigo-500/25\", pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\" },\n \"claim-username\": { text: \"text-violet-600 dark:text-violet-400\", solid: \"bg-violet-500\", border: \"border-violet-500/25\", pill: \"bg-gradient-to-r from-violet-500 to-fuchsia-600\" },\n \"claim-collection\": { text: \"text-cyan-600 dark:text-cyan-400\", solid: \"bg-cyan-500\", border: \"border-cyan-500/25\", pill: \"bg-gradient-to-r from-cyan-500 to-sky-600\" },\n \"claim-collection-name\": { text: \"text-pink-600 dark:text-pink-400\", solid: \"bg-pink-500\", border: \"border-pink-500/25\", pill: \"bg-gradient-to-r from-pink-500 to-rose-600\" },\n};\n\n// ── Service card — the whole card is the action ─────────────────────────────\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n /** Showcase layout — spans the full grid width (e.g. POP Protocol) */\n featured?: boolean;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, featured = false }: LaunchpadServiceCardProps) {\n const { key, icon: Icon, title, browseLinkLabel, features, example } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href, browseHref } = override;\n\n const live = status === \"live\";\n const hue = SERVICE_HUES[key] ?? DEFAULT_HUE;\n\n return (\n <div\n className={cn(\n \"relative rounded-2xl border bg-card overflow-hidden flex flex-col flex-1 min-h-[210px]\",\n \"transition-transform\",\n live ? cn(hue.border, \"active:scale-[0.99]\") : \"border-border/30 opacity-70\",\n featured && \"sm:col-span-2\",\n )}\n >\n {/* Giant watermark icon, ghosted in the corner (Drop-Pages-panel language) */}\n <div aria-hidden className=\"absolute -right-8 -bottom-10 opacity-[0.04] select-none pointer-events-none\">\n <Icon className=\"h-44 w-44\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 gap-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"relative\">\n {live && (\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n )}\n <Icon className={cn(\"relative h-9 w-9 shrink-0\", live ? hue.text : \"text-muted-foreground/50\")} />\n </div>\n {!live && (\n <span className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-2xl sm:text-3xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className={cn(\"text-[15px] leading-relaxed\", live ? \"text-muted-foreground\" : \"text-muted-foreground/60\", !featured && \"max-w-[36ch]\")}>\n {blurb}\n </p>\n {live && example && (\n <p className=\"text-[13px] leading-relaxed text-muted-foreground/70 italic\">\n e.g. {example}\n </p>\n )}\n </div>\n\n {/* Feature showcase — plain-language chips */}\n {live && features.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-muted/40 border border-border/30 text-xs font-medium text-muted-foreground\"\n >\n <Check className={cn(\"h-3 w-3 shrink-0\", hue.text)} />\n {feature}\n </span>\n ))}\n </div>\n )}\n\n {/* Stretched link — the whole card is the action; the pill is the visual cue */}\n {live && href && <Link href={href} aria-label={`${def.cta} — ${title}`} className=\"absolute inset-0 z-10\" />}\n\n <div className=\"mt-auto pt-1 flex items-end justify-between gap-3\">\n {live && browseHref && browseLinkLabel ? (\n <Link\n href={browseHref}\n className=\"relative z-20 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground active:text-foreground\"\n >\n {browseLinkLabel}\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n ) : (\n <span />\n )}\n {live && (\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-10 px-5 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {def.cta}\n <ArrowRight className=\"h-4 w-4\" />\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// ── Group sections ───────────────────────────────────────────────────────────\n\nfunction GroupHeader({ group }: { group: ServiceGroupDefinition }) {\n return (\n <div className=\"space-y-1.5\">\n <h2 className=\"text-2xl sm:text-3xl font-black tracking-tight\">{group.title}</h2>\n <p className=\"text-sm sm:text-base 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 // Creator Coins & Memecoins get a distinct yellow/orange panel around the section\n const isCoins = group.key === \"creator-coins\";\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={cn(\n \"space-y-4\",\n isCoins &&\n \"rounded-3xl border border-yellow-500/20 bg-gradient-to-br from-yellow-500/[0.08] via-orange-500/[0.05] to-transparent p-5 sm:p-6\",\n )}\n >\n <GroupHeader group={group} />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {defs.map((def) => (\n <LaunchpadServiceCard\n key={def.key}\n def={def}\n override={overrides[def.key]}\n featured={group.key === \"pop-protocol\"}\n />\n ))}\n </div>\n </motion.div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|