@medialane/ui 0.144.0 → 0.145.1

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.
@@ -47,7 +47,9 @@ var import_cn = require("../utils/cn.js");
47
47
  var import_launchpad_services = require("../data/launchpad-services.js");
48
48
  const LAUNCHPAD_ROUTE_OVERRIDES = {
49
49
  "nfts": { href: "/launchpad/single-editions" },
50
+ "create-collection": { href: "/launchpad/single-editions/collection" },
50
51
  "limited-editions": { href: "/launchpad/nfteditions" },
52
+ "create-1155": { href: "/launchpad/nfteditions/create" },
51
53
  "remix-asset": { href: "/launchpad/remix" },
52
54
  "pop-protocol": { href: "/launchpad/pop" },
53
55
  "collection-drop": { href: "/launchpad/drop" },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport Link from \"./link.js\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\nexport interface ServiceOverride {\n\n href?: string;\n\n browseHref?: string;\n\n status?: ServiceStatus;\n\n blurb?: string;\n\n meta?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n/** The launchpad route structure both apps share (`/launchpad/...`,\n * `/claim/...`) — spread this into an app's own overrides and add\n * `meta` counts or any app-specific extras on top. */\nexport const LAUNCHPAD_ROUTE_OVERRIDES: ServiceOverrides = {\n \"nfts\": { href: \"/launchpad/single-editions\" },\n \"limited-editions\": { href: \"/launchpad/nfteditions\" },\n \"remix-asset\": { href: \"/launchpad/remix\" },\n \"pop-protocol\": { href: \"/launchpad/pop\" },\n \"collection-drop\": { href: \"/launchpad/drop\" },\n \"creator-coins\": { href: \"/launchpad/coin/create\" },\n \"claim-memecoin\": { href: \"/launchpad/memecoin\" },\n \"claim-username\": { href: \"/claim/username\" },\n \"claim-collection\": { href: \"/claim/collection\" },\n \"claim-collection-name\": { href: \"/claim/collection-name\" },\n \"ip-tickets\": { href: \"/launchpad/tickets\" },\n \"ip-club\": { href: \"/launchpad/club\" },\n \"ip-sponsorship\": { href: \"/launchpad/sponsorship\" },\n};\n\ninterface GroupSlice {\n\n tint: string;\n\n text: string;\n\n border: string;\n}\n\nconst DEFAULT_SLICE: GroupSlice = {\n tint: \"bg-muted/60\",\n text: \"text-muted-foreground/60\",\n border: \"border-border/60\",\n};\n\nexport const GROUP_SLICES: Record<ServiceGroup, GroupSlice> = {\n \"nfts\": { tint: \"bg-brand-blue/10\", text: \"text-brand-blue\", border: \"border-brand-blue/30\" },\n \"limited-editions\": { tint: \"bg-brand-maeve/10\", text: \"text-brand-maeve\", border: \"border-brand-maeve/30\" },\n \"coins\": { tint: \"bg-brand-purple/10\", text: \"text-brand-purple\", border: \"border-brand-purple/30\" },\n \"community\": { tint: \"bg-brand-rose/10\", text: \"text-brand-rose\", border: \"border-brand-rose/30\" },\n \"claims\": { tint: \"bg-brand-orange/10\", text: \"text-brand-orange\", border: \"border-brand-orange/30\" },\n \"coming-soon\": DEFAULT_SLICE,\n};\n\ninterface ServiceHue {\n text: string;\n solid: string;\n border: string;\n tint: string;\n}\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"nfts\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"limited-editions\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"creator-coins\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-memecoin\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"collection-drop\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"pop-protocol\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n \"ip-tickets\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"remix-asset\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-username\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"claim-collection\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"claim-collection-name\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n};\n\nconst GROUP_TITLE_BY_KEY = Object.fromEntries(\n LAUNCHPAD_SERVICE_GROUPS.map((g) => [g.key, g.title]),\n) as Record<ServiceGroup, string>;\n\nconst GROUP_KEYS = new Set(LAUNCHPAD_SERVICE_GROUPS.map((g) => g.key));\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n\n index?: number;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, index = 0 }: LaunchpadServiceCardProps) {\n const { icon: Icon, title, group, features, cta } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href } = override;\n const reduceMotion = useReducedMotion();\n\n const live = status === \"live\";\n const slice = GROUP_SLICES[group] ?? DEFAULT_SLICE;\n\n const body = (\n <>\n\n <div className=\"flex items-start justify-between gap-3\">\n <span className={cn(\"flex h-14 w-14 items-center justify-center rounded-2xl\", live ? slice.tint : \"bg-muted/40\")}>\n <Icon className={cn(\"h-7 w-7\", live ? slice.text : \"text-muted-foreground/50\")} />\n </span>\n {!live ? (\n <span className=\"flex items-center gap-1 text-2xs font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n ) : override.meta ? (\n <span className=\"text-xs font-semibold tabular-nums px-2.5 py-1 rounded-full bg-muted/50 text-foreground/80\">\n {override.meta}\n </span>\n ) : null}\n </div>\n\n <div className=\"mt-auto space-y-2 pt-6\">\n <h3 className=\"text-2xl font-bold tracking-tight leading-tight\">{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 {live && features.length > 0 && (\n <ul className=\"space-y-1.5 pt-4\">\n {features.slice(0, 3).map((feature) => (\n <li key={feature} className=\"flex items-start gap-2 text-xs text-muted-foreground leading-relaxed\">\n <Check className={cn(\"h-3.5 w-3.5 shrink-0 mt-px\", slice.text)} />\n {feature}\n </li>\n ))}\n </ul>\n )}\n\n {live && (\n <div className=\"pt-5\">\n <span className=\"inline-flex items-center gap-1.5 text-sm font-semibold\">\n {cta}\n <ArrowRight className=\"h-4 w-4 transition-transform duration-200 sm:group-hover:translate-x-0.5 motion-reduce:transform-none\" />\n </span>\n </div>\n )}\n </>\n );\n\n return (\n <motion.div\n layout={!reduceMotion}\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0 }}\n whileTap={live ? { scale: 0.97 } : undefined}\n transition={{ duration: 0.35, delay: index * 0.04, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"flex\"\n >\n {live && href ? (\n <Link\n href={href}\n className={cn(\n \"group flex flex-1 flex-col rounded-3xl border bg-card p-6 sm:aspect-[4/5]\",\n \"ml-grad-hover-border\",\n slice.border,\n )}\n >\n {body}\n </Link>\n ) : (\n <div className=\"flex flex-1 flex-col rounded-3xl border border-border/30 bg-card p-6 sm:aspect-[4/5] opacity-75\">\n {body}\n </div>\n )}\n </motion.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 function serviceMatchesQuery(def: ServiceDefinition, query: string): boolean {\n if (query.trim() === \"\") return true;\n const haystack = `${def.title} ${def.blurb} ${def.subtitle} ${GROUP_TITLE_BY_KEY[def.group] ?? \"\"}`.toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n}\n\nfunction syncFilterUrl(query: string, groups: Set<ServiceGroup>) {\n if (typeof window === \"undefined\") return;\n const params = new URLSearchParams(window.location.search);\n if (query.trim()) params.set(\"q\", query.trim());\n else params.delete(\"q\");\n if (groups.size > 0) params.set(\"groups\", [...groups].join(\",\"));\n else params.delete(\"groups\");\n const qs = params.toString();\n window.history.replaceState(null, \"\", qs ? `${window.location.pathname}?${qs}` : window.location.pathname);\n}\n\nexport function useLaunchpadFilter() {\n const [query, setQueryState] = useState(\"\");\n const [activeGroups, setActiveGroups] = useState<Set<ServiceGroup>>(new Set());\n\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const q = params.get(\"q\");\n if (q) setQueryState(q);\n const g = params.get(\"groups\");\n if (g) {\n const groups = g.split(\",\").filter((k): k is ServiceGroup => GROUP_KEYS.has(k as ServiceGroup));\n if (groups.length > 0) setActiveGroups(new Set(groups));\n }\n }, []);\n\n const filterableGroups = LAUNCHPAD_SERVICE_GROUPS.filter((g) => g.key !== \"coming-soon\");\n\n const setQuery = (value: string) => {\n setQueryState(value);\n syncFilterUrl(value, activeGroups);\n };\n\n const toggleGroup = (key: ServiceGroup) => {\n setActiveGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n syncFilterUrl(query, next);\n return next;\n });\n };\n\n const matches = (def: ServiceDefinition): boolean => {\n if (activeGroups.size > 0 && !activeGroups.has(def.group)) return false;\n if (def.status !== \"live\") return false;\n return serviceMatchesQuery(def, query);\n };\n\n const totalMatches = useMemo(\n () => LAUNCHPAD_SERVICE_DEFINITIONS.filter(matches).length,\n\n [query, activeGroups],\n );\n\n const clear = () => {\n setQueryState(\"\");\n setActiveGroups(new Set());\n syncFilterUrl(\"\", new Set());\n };\n\n return { query, setQuery, activeGroups, toggleGroup, filterableGroups, totalMatches, clear };\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n\n overrides: ServiceOverrides;\n\n query: string;\n\n activeGroups: Set<ServiceGroup>;\n\n onClearFilters: () => void;\n className?: string;\n\n excludeKeys?: string[];\n}\n\nexport function LaunchpadGroupedSections({ overrides, query, activeGroups, onClearFilters, className, excludeKeys }: LaunchpadGroupedSectionsProps) {\n const inActiveGroup = (d: ServiceDefinition) => activeGroups.size === 0 || activeGroups.has(d.group);\n const inSearch = (d: ServiceDefinition) => serviceMatchesQuery(d, query);\n const notExcluded = (d: ServiceDefinition) => !excludeKeys?.includes(d.key);\n\n const groupOrder = Object.fromEntries(LAUNCHPAD_SERVICE_GROUPS.map((g, i) => [g.key, i]));\n\n const liveDefs = LAUNCHPAD_SERVICE_DEFINITIONS\n .filter((d) => d.group !== \"coming-soon\" && d.status === \"live\" && notExcluded(d) && inActiveGroup(d) && inSearch(d))\n .sort((a, b) => (groupOrder[a.group] ?? 99) - (groupOrder[b.group] ?? 99));\n\n const comingSoonGroup = LAUNCHPAD_SERVICE_GROUPS.find((g) => g.key === \"coming-soon\");\n const comingSoonDefs = LAUNCHPAD_SERVICE_DEFINITIONS.filter(\n (d) => d.group === \"coming-soon\" && notExcluded(d) && inActiveGroup(d) && inSearch(d),\n );\n\n return (\n <div className={cn(\"space-y-8\", className)}>\n {liveDefs.length === 0 && comingSoonDefs.length === 0 ? (\n <div className=\"text-center py-16 space-y-3\">\n <p className=\"text-lg font-semibold\">No services match</p>\n <p className=\"text-sm text-muted-foreground\">Try a different search or clear your filters.</p>\n <button\n type=\"button\"\n onClick={onClearFilters}\n className=\"inline-flex items-center h-9 px-4 rounded-full text-sm font-semibold bg-primary text-primary-foreground\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <>\n <motion.div layout className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-5 sm:gap-6\">\n <AnimatePresence mode=\"popLayout\">\n {liveDefs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n </AnimatePresence>\n </motion.div>\n {comingSoonGroup && comingSoonDefs.length > 0 && (\n <ComingSoonStrip group={comingSoonGroup} defs={comingSoonDefs} />\n )}\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\nimport { useEffect, useMemo, useState } from \"react\";\nimport Link from \"./link.js\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\nexport interface ServiceOverride {\n\n href?: string;\n\n browseHref?: string;\n\n status?: ServiceStatus;\n\n blurb?: string;\n\n meta?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n/** The launchpad route structure both apps share (`/launchpad/...`,\n * `/claim/...`) — spread this into an app's own overrides and add\n * `meta` counts or any app-specific extras on top. */\nexport const LAUNCHPAD_ROUTE_OVERRIDES: ServiceOverrides = {\n \"nfts\": { href: \"/launchpad/single-editions\" },\n \"create-collection\": { href: \"/launchpad/single-editions/collection\" },\n \"limited-editions\": { href: \"/launchpad/nfteditions\" },\n \"create-1155\": { href: \"/launchpad/nfteditions/create\" },\n \"remix-asset\": { href: \"/launchpad/remix\" },\n \"pop-protocol\": { href: \"/launchpad/pop\" },\n \"collection-drop\": { href: \"/launchpad/drop\" },\n \"creator-coins\": { href: \"/launchpad/coin/create\" },\n \"claim-memecoin\": { href: \"/launchpad/memecoin\" },\n \"claim-username\": { href: \"/claim/username\" },\n \"claim-collection\": { href: \"/claim/collection\" },\n \"claim-collection-name\": { href: \"/claim/collection-name\" },\n \"ip-tickets\": { href: \"/launchpad/tickets\" },\n \"ip-club\": { href: \"/launchpad/club\" },\n \"ip-sponsorship\": { href: \"/launchpad/sponsorship\" },\n};\n\ninterface GroupSlice {\n\n tint: string;\n\n text: string;\n\n border: string;\n}\n\nconst DEFAULT_SLICE: GroupSlice = {\n tint: \"bg-muted/60\",\n text: \"text-muted-foreground/60\",\n border: \"border-border/60\",\n};\n\nexport const GROUP_SLICES: Record<ServiceGroup, GroupSlice> = {\n \"nfts\": { tint: \"bg-brand-blue/10\", text: \"text-brand-blue\", border: \"border-brand-blue/30\" },\n \"limited-editions\": { tint: \"bg-brand-maeve/10\", text: \"text-brand-maeve\", border: \"border-brand-maeve/30\" },\n \"coins\": { tint: \"bg-brand-purple/10\", text: \"text-brand-purple\", border: \"border-brand-purple/30\" },\n \"community\": { tint: \"bg-brand-rose/10\", text: \"text-brand-rose\", border: \"border-brand-rose/30\" },\n \"claims\": { tint: \"bg-brand-orange/10\", text: \"text-brand-orange\", border: \"border-brand-orange/30\" },\n \"coming-soon\": DEFAULT_SLICE,\n};\n\ninterface ServiceHue {\n text: string;\n solid: string;\n border: string;\n tint: string;\n}\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"nfts\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"limited-editions\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"creator-coins\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-memecoin\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"collection-drop\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"pop-protocol\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n \"ip-tickets\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"remix-asset\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-username\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"claim-collection\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"claim-collection-name\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n};\n\nconst GROUP_TITLE_BY_KEY = Object.fromEntries(\n LAUNCHPAD_SERVICE_GROUPS.map((g) => [g.key, g.title]),\n) as Record<ServiceGroup, string>;\n\nconst GROUP_KEYS = new Set(LAUNCHPAD_SERVICE_GROUPS.map((g) => g.key));\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n\n index?: number;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, index = 0 }: LaunchpadServiceCardProps) {\n const { icon: Icon, title, group, features, cta } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href } = override;\n const reduceMotion = useReducedMotion();\n\n const live = status === \"live\";\n const slice = GROUP_SLICES[group] ?? DEFAULT_SLICE;\n\n const body = (\n <>\n\n <div className=\"flex items-start justify-between gap-3\">\n <span className={cn(\"flex h-14 w-14 items-center justify-center rounded-2xl\", live ? slice.tint : \"bg-muted/40\")}>\n <Icon className={cn(\"h-7 w-7\", live ? slice.text : \"text-muted-foreground/50\")} />\n </span>\n {!live ? (\n <span className=\"flex items-center gap-1 text-2xs font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n ) : override.meta ? (\n <span className=\"text-xs font-semibold tabular-nums px-2.5 py-1 rounded-full bg-muted/50 text-foreground/80\">\n {override.meta}\n </span>\n ) : null}\n </div>\n\n <div className=\"mt-auto space-y-2 pt-6\">\n <h3 className=\"text-2xl font-bold tracking-tight leading-tight\">{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 {live && features.length > 0 && (\n <ul className=\"space-y-1.5 pt-4\">\n {features.slice(0, 3).map((feature) => (\n <li key={feature} className=\"flex items-start gap-2 text-xs text-muted-foreground leading-relaxed\">\n <Check className={cn(\"h-3.5 w-3.5 shrink-0 mt-px\", slice.text)} />\n {feature}\n </li>\n ))}\n </ul>\n )}\n\n {live && (\n <div className=\"pt-5\">\n <span className=\"inline-flex items-center gap-1.5 text-sm font-semibold\">\n {cta}\n <ArrowRight className=\"h-4 w-4 transition-transform duration-200 sm:group-hover:translate-x-0.5 motion-reduce:transform-none\" />\n </span>\n </div>\n )}\n </>\n );\n\n return (\n <motion.div\n layout={!reduceMotion}\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0 }}\n whileTap={live ? { scale: 0.97 } : undefined}\n transition={{ duration: 0.35, delay: index * 0.04, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"flex\"\n >\n {live && href ? (\n <Link\n href={href}\n className={cn(\n \"group flex flex-1 flex-col rounded-3xl border bg-card p-6 sm:aspect-[4/5]\",\n \"ml-grad-hover-border\",\n slice.border,\n )}\n >\n {body}\n </Link>\n ) : (\n <div className=\"flex flex-1 flex-col rounded-3xl border border-border/30 bg-card p-6 sm:aspect-[4/5] opacity-75\">\n {body}\n </div>\n )}\n </motion.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 function serviceMatchesQuery(def: ServiceDefinition, query: string): boolean {\n if (query.trim() === \"\") return true;\n const haystack = `${def.title} ${def.blurb} ${def.subtitle} ${GROUP_TITLE_BY_KEY[def.group] ?? \"\"}`.toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n}\n\nfunction syncFilterUrl(query: string, groups: Set<ServiceGroup>) {\n if (typeof window === \"undefined\") return;\n const params = new URLSearchParams(window.location.search);\n if (query.trim()) params.set(\"q\", query.trim());\n else params.delete(\"q\");\n if (groups.size > 0) params.set(\"groups\", [...groups].join(\",\"));\n else params.delete(\"groups\");\n const qs = params.toString();\n window.history.replaceState(null, \"\", qs ? `${window.location.pathname}?${qs}` : window.location.pathname);\n}\n\nexport function useLaunchpadFilter() {\n const [query, setQueryState] = useState(\"\");\n const [activeGroups, setActiveGroups] = useState<Set<ServiceGroup>>(new Set());\n\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const q = params.get(\"q\");\n if (q) setQueryState(q);\n const g = params.get(\"groups\");\n if (g) {\n const groups = g.split(\",\").filter((k): k is ServiceGroup => GROUP_KEYS.has(k as ServiceGroup));\n if (groups.length > 0) setActiveGroups(new Set(groups));\n }\n }, []);\n\n const filterableGroups = LAUNCHPAD_SERVICE_GROUPS.filter((g) => g.key !== \"coming-soon\");\n\n const setQuery = (value: string) => {\n setQueryState(value);\n syncFilterUrl(value, activeGroups);\n };\n\n const toggleGroup = (key: ServiceGroup) => {\n setActiveGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n syncFilterUrl(query, next);\n return next;\n });\n };\n\n const matches = (def: ServiceDefinition): boolean => {\n if (activeGroups.size > 0 && !activeGroups.has(def.group)) return false;\n if (def.status !== \"live\") return false;\n return serviceMatchesQuery(def, query);\n };\n\n const totalMatches = useMemo(\n () => LAUNCHPAD_SERVICE_DEFINITIONS.filter(matches).length,\n\n [query, activeGroups],\n );\n\n const clear = () => {\n setQueryState(\"\");\n setActiveGroups(new Set());\n syncFilterUrl(\"\", new Set());\n };\n\n return { query, setQuery, activeGroups, toggleGroup, filterableGroups, totalMatches, clear };\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n\n overrides: ServiceOverrides;\n\n query: string;\n\n activeGroups: Set<ServiceGroup>;\n\n onClearFilters: () => void;\n className?: string;\n\n excludeKeys?: string[];\n}\n\nexport function LaunchpadGroupedSections({ overrides, query, activeGroups, onClearFilters, className, excludeKeys }: LaunchpadGroupedSectionsProps) {\n const inActiveGroup = (d: ServiceDefinition) => activeGroups.size === 0 || activeGroups.has(d.group);\n const inSearch = (d: ServiceDefinition) => serviceMatchesQuery(d, query);\n const notExcluded = (d: ServiceDefinition) => !excludeKeys?.includes(d.key);\n\n const groupOrder = Object.fromEntries(LAUNCHPAD_SERVICE_GROUPS.map((g, i) => [g.key, i]));\n\n const liveDefs = LAUNCHPAD_SERVICE_DEFINITIONS\n .filter((d) => d.group !== \"coming-soon\" && d.status === \"live\" && notExcluded(d) && inActiveGroup(d) && inSearch(d))\n .sort((a, b) => (groupOrder[a.group] ?? 99) - (groupOrder[b.group] ?? 99));\n\n const comingSoonGroup = LAUNCHPAD_SERVICE_GROUPS.find((g) => g.key === \"coming-soon\");\n const comingSoonDefs = LAUNCHPAD_SERVICE_DEFINITIONS.filter(\n (d) => d.group === \"coming-soon\" && notExcluded(d) && inActiveGroup(d) && inSearch(d),\n );\n\n return (\n <div className={cn(\"space-y-8\", className)}>\n {liveDefs.length === 0 && comingSoonDefs.length === 0 ? (\n <div className=\"text-center py-16 space-y-3\">\n <p className=\"text-lg font-semibold\">No services match</p>\n <p className=\"text-sm text-muted-foreground\">Try a different search or clear your filters.</p>\n <button\n type=\"button\"\n onClick={onClearFilters}\n className=\"inline-flex items-center h-9 px-4 rounded-full text-sm font-semibold bg-primary text-primary-foreground\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <>\n <motion.div layout className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-5 sm:gap-6\">\n <AnimatePresence mode=\"popLayout\">\n {liveDefs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n </AnimatePresence>\n </motion.div>\n {comingSoonGroup && comingSoonDefs.length > 0 && (\n <ComingSoonStrip group={comingSoonGroup} defs={comingSoonDefs} />\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
@@ -11,7 +11,9 @@ import {
11
11
  } from "../data/launchpad-services.js";
12
12
  const LAUNCHPAD_ROUTE_OVERRIDES = {
13
13
  "nfts": { href: "/launchpad/single-editions" },
14
+ "create-collection": { href: "/launchpad/single-editions/collection" },
14
15
  "limited-editions": { href: "/launchpad/nfteditions" },
16
+ "create-1155": { href: "/launchpad/nfteditions/create" },
15
17
  "remix-asset": { href: "/launchpad/remix" },
16
18
  "pop-protocol": { href: "/launchpad/pop" },
17
19
  "collection-drop": { href: "/launchpad/drop" },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/launchpad-services.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport Link from \"./link.js\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\nexport interface ServiceOverride {\n\n href?: string;\n\n browseHref?: string;\n\n status?: ServiceStatus;\n\n blurb?: string;\n\n meta?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n/** The launchpad route structure both apps share (`/launchpad/...`,\n * `/claim/...`) — spread this into an app's own overrides and add\n * `meta` counts or any app-specific extras on top. */\nexport const LAUNCHPAD_ROUTE_OVERRIDES: ServiceOverrides = {\n \"nfts\": { href: \"/launchpad/single-editions\" },\n \"limited-editions\": { href: \"/launchpad/nfteditions\" },\n \"remix-asset\": { href: \"/launchpad/remix\" },\n \"pop-protocol\": { href: \"/launchpad/pop\" },\n \"collection-drop\": { href: \"/launchpad/drop\" },\n \"creator-coins\": { href: \"/launchpad/coin/create\" },\n \"claim-memecoin\": { href: \"/launchpad/memecoin\" },\n \"claim-username\": { href: \"/claim/username\" },\n \"claim-collection\": { href: \"/claim/collection\" },\n \"claim-collection-name\": { href: \"/claim/collection-name\" },\n \"ip-tickets\": { href: \"/launchpad/tickets\" },\n \"ip-club\": { href: \"/launchpad/club\" },\n \"ip-sponsorship\": { href: \"/launchpad/sponsorship\" },\n};\n\ninterface GroupSlice {\n\n tint: string;\n\n text: string;\n\n border: string;\n}\n\nconst DEFAULT_SLICE: GroupSlice = {\n tint: \"bg-muted/60\",\n text: \"text-muted-foreground/60\",\n border: \"border-border/60\",\n};\n\nexport const GROUP_SLICES: Record<ServiceGroup, GroupSlice> = {\n \"nfts\": { tint: \"bg-brand-blue/10\", text: \"text-brand-blue\", border: \"border-brand-blue/30\" },\n \"limited-editions\": { tint: \"bg-brand-maeve/10\", text: \"text-brand-maeve\", border: \"border-brand-maeve/30\" },\n \"coins\": { tint: \"bg-brand-purple/10\", text: \"text-brand-purple\", border: \"border-brand-purple/30\" },\n \"community\": { tint: \"bg-brand-rose/10\", text: \"text-brand-rose\", border: \"border-brand-rose/30\" },\n \"claims\": { tint: \"bg-brand-orange/10\", text: \"text-brand-orange\", border: \"border-brand-orange/30\" },\n \"coming-soon\": DEFAULT_SLICE,\n};\n\ninterface ServiceHue {\n text: string;\n solid: string;\n border: string;\n tint: string;\n}\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"nfts\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"limited-editions\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"creator-coins\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-memecoin\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"collection-drop\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"pop-protocol\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n \"ip-tickets\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"remix-asset\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-username\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"claim-collection\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"claim-collection-name\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n};\n\nconst GROUP_TITLE_BY_KEY = Object.fromEntries(\n LAUNCHPAD_SERVICE_GROUPS.map((g) => [g.key, g.title]),\n) as Record<ServiceGroup, string>;\n\nconst GROUP_KEYS = new Set(LAUNCHPAD_SERVICE_GROUPS.map((g) => g.key));\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n\n index?: number;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, index = 0 }: LaunchpadServiceCardProps) {\n const { icon: Icon, title, group, features, cta } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href } = override;\n const reduceMotion = useReducedMotion();\n\n const live = status === \"live\";\n const slice = GROUP_SLICES[group] ?? DEFAULT_SLICE;\n\n const body = (\n <>\n\n <div className=\"flex items-start justify-between gap-3\">\n <span className={cn(\"flex h-14 w-14 items-center justify-center rounded-2xl\", live ? slice.tint : \"bg-muted/40\")}>\n <Icon className={cn(\"h-7 w-7\", live ? slice.text : \"text-muted-foreground/50\")} />\n </span>\n {!live ? (\n <span className=\"flex items-center gap-1 text-2xs font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n ) : override.meta ? (\n <span className=\"text-xs font-semibold tabular-nums px-2.5 py-1 rounded-full bg-muted/50 text-foreground/80\">\n {override.meta}\n </span>\n ) : null}\n </div>\n\n <div className=\"mt-auto space-y-2 pt-6\">\n <h3 className=\"text-2xl font-bold tracking-tight leading-tight\">{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 {live && features.length > 0 && (\n <ul className=\"space-y-1.5 pt-4\">\n {features.slice(0, 3).map((feature) => (\n <li key={feature} className=\"flex items-start gap-2 text-xs text-muted-foreground leading-relaxed\">\n <Check className={cn(\"h-3.5 w-3.5 shrink-0 mt-px\", slice.text)} />\n {feature}\n </li>\n ))}\n </ul>\n )}\n\n {live && (\n <div className=\"pt-5\">\n <span className=\"inline-flex items-center gap-1.5 text-sm font-semibold\">\n {cta}\n <ArrowRight className=\"h-4 w-4 transition-transform duration-200 sm:group-hover:translate-x-0.5 motion-reduce:transform-none\" />\n </span>\n </div>\n )}\n </>\n );\n\n return (\n <motion.div\n layout={!reduceMotion}\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0 }}\n whileTap={live ? { scale: 0.97 } : undefined}\n transition={{ duration: 0.35, delay: index * 0.04, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"flex\"\n >\n {live && href ? (\n <Link\n href={href}\n className={cn(\n \"group flex flex-1 flex-col rounded-3xl border bg-card p-6 sm:aspect-[4/5]\",\n \"ml-grad-hover-border\",\n slice.border,\n )}\n >\n {body}\n </Link>\n ) : (\n <div className=\"flex flex-1 flex-col rounded-3xl border border-border/30 bg-card p-6 sm:aspect-[4/5] opacity-75\">\n {body}\n </div>\n )}\n </motion.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 function serviceMatchesQuery(def: ServiceDefinition, query: string): boolean {\n if (query.trim() === \"\") return true;\n const haystack = `${def.title} ${def.blurb} ${def.subtitle} ${GROUP_TITLE_BY_KEY[def.group] ?? \"\"}`.toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n}\n\nfunction syncFilterUrl(query: string, groups: Set<ServiceGroup>) {\n if (typeof window === \"undefined\") return;\n const params = new URLSearchParams(window.location.search);\n if (query.trim()) params.set(\"q\", query.trim());\n else params.delete(\"q\");\n if (groups.size > 0) params.set(\"groups\", [...groups].join(\",\"));\n else params.delete(\"groups\");\n const qs = params.toString();\n window.history.replaceState(null, \"\", qs ? `${window.location.pathname}?${qs}` : window.location.pathname);\n}\n\nexport function useLaunchpadFilter() {\n const [query, setQueryState] = useState(\"\");\n const [activeGroups, setActiveGroups] = useState<Set<ServiceGroup>>(new Set());\n\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const q = params.get(\"q\");\n if (q) setQueryState(q);\n const g = params.get(\"groups\");\n if (g) {\n const groups = g.split(\",\").filter((k): k is ServiceGroup => GROUP_KEYS.has(k as ServiceGroup));\n if (groups.length > 0) setActiveGroups(new Set(groups));\n }\n }, []);\n\n const filterableGroups = LAUNCHPAD_SERVICE_GROUPS.filter((g) => g.key !== \"coming-soon\");\n\n const setQuery = (value: string) => {\n setQueryState(value);\n syncFilterUrl(value, activeGroups);\n };\n\n const toggleGroup = (key: ServiceGroup) => {\n setActiveGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n syncFilterUrl(query, next);\n return next;\n });\n };\n\n const matches = (def: ServiceDefinition): boolean => {\n if (activeGroups.size > 0 && !activeGroups.has(def.group)) return false;\n if (def.status !== \"live\") return false;\n return serviceMatchesQuery(def, query);\n };\n\n const totalMatches = useMemo(\n () => LAUNCHPAD_SERVICE_DEFINITIONS.filter(matches).length,\n\n [query, activeGroups],\n );\n\n const clear = () => {\n setQueryState(\"\");\n setActiveGroups(new Set());\n syncFilterUrl(\"\", new Set());\n };\n\n return { query, setQuery, activeGroups, toggleGroup, filterableGroups, totalMatches, clear };\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n\n overrides: ServiceOverrides;\n\n query: string;\n\n activeGroups: Set<ServiceGroup>;\n\n onClearFilters: () => void;\n className?: string;\n\n excludeKeys?: string[];\n}\n\nexport function LaunchpadGroupedSections({ overrides, query, activeGroups, onClearFilters, className, excludeKeys }: LaunchpadGroupedSectionsProps) {\n const inActiveGroup = (d: ServiceDefinition) => activeGroups.size === 0 || activeGroups.has(d.group);\n const inSearch = (d: ServiceDefinition) => serviceMatchesQuery(d, query);\n const notExcluded = (d: ServiceDefinition) => !excludeKeys?.includes(d.key);\n\n const groupOrder = Object.fromEntries(LAUNCHPAD_SERVICE_GROUPS.map((g, i) => [g.key, i]));\n\n const liveDefs = LAUNCHPAD_SERVICE_DEFINITIONS\n .filter((d) => d.group !== \"coming-soon\" && d.status === \"live\" && notExcluded(d) && inActiveGroup(d) && inSearch(d))\n .sort((a, b) => (groupOrder[a.group] ?? 99) - (groupOrder[b.group] ?? 99));\n\n const comingSoonGroup = LAUNCHPAD_SERVICE_GROUPS.find((g) => g.key === \"coming-soon\");\n const comingSoonDefs = LAUNCHPAD_SERVICE_DEFINITIONS.filter(\n (d) => d.group === \"coming-soon\" && notExcluded(d) && inActiveGroup(d) && inSearch(d),\n );\n\n return (\n <div className={cn(\"space-y-8\", className)}>\n {liveDefs.length === 0 && comingSoonDefs.length === 0 ? (\n <div className=\"text-center py-16 space-y-3\">\n <p className=\"text-lg font-semibold\">No services match</p>\n <p className=\"text-sm text-muted-foreground\">Try a different search or clear your filters.</p>\n <button\n type=\"button\"\n onClick={onClearFilters}\n className=\"inline-flex items-center h-9 px-4 rounded-full text-sm font-semibold bg-primary text-primary-foreground\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <>\n <motion.div layout className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-5 sm:gap-6\">\n <AnimatePresence mode=\"popLayout\">\n {liveDefs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n </AnimatePresence>\n </motion.div>\n {comingSoonGroup && comingSoonDefs.length > 0 && (\n <ComingSoonStrip group={comingSoonGroup} defs={comingSoonDefs} />\n )}\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\nimport { useEffect, useMemo, useState } from \"react\";\nimport Link from \"./link.js\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { Lock, ArrowRight, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport {\n LAUNCHPAD_SERVICE_DEFINITIONS,\n LAUNCHPAD_SERVICE_GROUPS,\n type ServiceDefinition,\n type ServiceGroup,\n type ServiceGroupDefinition,\n type ServiceStatus,\n} from \"../data/launchpad-services.js\";\n\nexport interface ServiceOverride {\n\n href?: string;\n\n browseHref?: string;\n\n status?: ServiceStatus;\n\n blurb?: string;\n\n meta?: string;\n}\n\nexport type ServiceOverrides = Record<string, ServiceOverride>;\n\n/** The launchpad route structure both apps share (`/launchpad/...`,\n * `/claim/...`) — spread this into an app's own overrides and add\n * `meta` counts or any app-specific extras on top. */\nexport const LAUNCHPAD_ROUTE_OVERRIDES: ServiceOverrides = {\n \"nfts\": { href: \"/launchpad/single-editions\" },\n \"create-collection\": { href: \"/launchpad/single-editions/collection\" },\n \"limited-editions\": { href: \"/launchpad/nfteditions\" },\n \"create-1155\": { href: \"/launchpad/nfteditions/create\" },\n \"remix-asset\": { href: \"/launchpad/remix\" },\n \"pop-protocol\": { href: \"/launchpad/pop\" },\n \"collection-drop\": { href: \"/launchpad/drop\" },\n \"creator-coins\": { href: \"/launchpad/coin/create\" },\n \"claim-memecoin\": { href: \"/launchpad/memecoin\" },\n \"claim-username\": { href: \"/claim/username\" },\n \"claim-collection\": { href: \"/claim/collection\" },\n \"claim-collection-name\": { href: \"/claim/collection-name\" },\n \"ip-tickets\": { href: \"/launchpad/tickets\" },\n \"ip-club\": { href: \"/launchpad/club\" },\n \"ip-sponsorship\": { href: \"/launchpad/sponsorship\" },\n};\n\ninterface GroupSlice {\n\n tint: string;\n\n text: string;\n\n border: string;\n}\n\nconst DEFAULT_SLICE: GroupSlice = {\n tint: \"bg-muted/60\",\n text: \"text-muted-foreground/60\",\n border: \"border-border/60\",\n};\n\nexport const GROUP_SLICES: Record<ServiceGroup, GroupSlice> = {\n \"nfts\": { tint: \"bg-brand-blue/10\", text: \"text-brand-blue\", border: \"border-brand-blue/30\" },\n \"limited-editions\": { tint: \"bg-brand-maeve/10\", text: \"text-brand-maeve\", border: \"border-brand-maeve/30\" },\n \"coins\": { tint: \"bg-brand-purple/10\", text: \"text-brand-purple\", border: \"border-brand-purple/30\" },\n \"community\": { tint: \"bg-brand-rose/10\", text: \"text-brand-rose\", border: \"border-brand-rose/30\" },\n \"claims\": { tint: \"bg-brand-orange/10\", text: \"text-brand-orange\", border: \"border-brand-orange/30\" },\n \"coming-soon\": DEFAULT_SLICE,\n};\n\ninterface ServiceHue {\n text: string;\n solid: string;\n border: string;\n tint: string;\n}\n\nexport const SERVICE_HUES: Record<string, ServiceHue> = {\n \"nfts\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"limited-editions\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"creator-coins\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-memecoin\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"collection-drop\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"pop-protocol\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n \"ip-tickets\": { text: \"text-brand-orange\", solid: \"bg-brand-orange\", border: \"border-brand-orange/30\", tint: \"bg-brand-orange/10\" },\n \"remix-asset\": { text: \"text-brand-maeve\", solid: \"bg-brand-maeve\", border: \"border-brand-maeve/30\", tint: \"bg-brand-maeve/10\" },\n \"claim-username\": { text: \"text-brand-purple\", solid: \"bg-brand-purple\", border: \"border-brand-purple/30\", tint: \"bg-brand-purple/10\" },\n \"claim-collection\": { text: \"text-brand-blue\", solid: \"bg-brand-blue\", border: \"border-brand-blue/30\", tint: \"bg-brand-blue/10\" },\n \"claim-collection-name\": { text: \"text-brand-rose\", solid: \"bg-brand-rose\", border: \"border-brand-rose/30\", tint: \"bg-brand-rose/10\" },\n};\n\nconst GROUP_TITLE_BY_KEY = Object.fromEntries(\n LAUNCHPAD_SERVICE_GROUPS.map((g) => [g.key, g.title]),\n) as Record<ServiceGroup, string>;\n\nconst GROUP_KEYS = new Set(LAUNCHPAD_SERVICE_GROUPS.map((g) => g.key));\n\nexport interface LaunchpadServiceCardProps {\n def: ServiceDefinition;\n override?: ServiceOverride;\n\n index?: number;\n}\n\nexport function LaunchpadServiceCard({ def, override = {}, index = 0 }: LaunchpadServiceCardProps) {\n const { icon: Icon, title, group, features, cta } = def;\n const status = override.status ?? def.status;\n const blurb = override.blurb ?? def.blurb;\n const { href } = override;\n const reduceMotion = useReducedMotion();\n\n const live = status === \"live\";\n const slice = GROUP_SLICES[group] ?? DEFAULT_SLICE;\n\n const body = (\n <>\n\n <div className=\"flex items-start justify-between gap-3\">\n <span className={cn(\"flex h-14 w-14 items-center justify-center rounded-2xl\", live ? slice.tint : \"bg-muted/40\")}>\n <Icon className={cn(\"h-7 w-7\", live ? slice.text : \"text-muted-foreground/50\")} />\n </span>\n {!live ? (\n <span className=\"flex items-center gap-1 text-2xs font-medium text-muted-foreground/60 pt-1\">\n <Lock className=\"h-3 w-3\" />\n Coming soon\n </span>\n ) : override.meta ? (\n <span className=\"text-xs font-semibold tabular-nums px-2.5 py-1 rounded-full bg-muted/50 text-foreground/80\">\n {override.meta}\n </span>\n ) : null}\n </div>\n\n <div className=\"mt-auto space-y-2 pt-6\">\n <h3 className=\"text-2xl font-bold tracking-tight leading-tight\">{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 {live && features.length > 0 && (\n <ul className=\"space-y-1.5 pt-4\">\n {features.slice(0, 3).map((feature) => (\n <li key={feature} className=\"flex items-start gap-2 text-xs text-muted-foreground leading-relaxed\">\n <Check className={cn(\"h-3.5 w-3.5 shrink-0 mt-px\", slice.text)} />\n {feature}\n </li>\n ))}\n </ul>\n )}\n\n {live && (\n <div className=\"pt-5\">\n <span className=\"inline-flex items-center gap-1.5 text-sm font-semibold\">\n {cta}\n <ArrowRight className=\"h-4 w-4 transition-transform duration-200 sm:group-hover:translate-x-0.5 motion-reduce:transform-none\" />\n </span>\n </div>\n )}\n </>\n );\n\n return (\n <motion.div\n layout={!reduceMotion}\n initial={{ opacity: 0, y: reduceMotion ? 0 : 16 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0 }}\n whileTap={live ? { scale: 0.97 } : undefined}\n transition={{ duration: 0.35, delay: index * 0.04, ease: [0.25, 0.46, 0.45, 0.94] }}\n className=\"flex\"\n >\n {live && href ? (\n <Link\n href={href}\n className={cn(\n \"group flex flex-1 flex-col rounded-3xl border bg-card p-6 sm:aspect-[4/5]\",\n \"ml-grad-hover-border\",\n slice.border,\n )}\n >\n {body}\n </Link>\n ) : (\n <div className=\"flex flex-1 flex-col rounded-3xl border border-border/30 bg-card p-6 sm:aspect-[4/5] opacity-75\">\n {body}\n </div>\n )}\n </motion.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 function serviceMatchesQuery(def: ServiceDefinition, query: string): boolean {\n if (query.trim() === \"\") return true;\n const haystack = `${def.title} ${def.blurb} ${def.subtitle} ${GROUP_TITLE_BY_KEY[def.group] ?? \"\"}`.toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n}\n\nfunction syncFilterUrl(query: string, groups: Set<ServiceGroup>) {\n if (typeof window === \"undefined\") return;\n const params = new URLSearchParams(window.location.search);\n if (query.trim()) params.set(\"q\", query.trim());\n else params.delete(\"q\");\n if (groups.size > 0) params.set(\"groups\", [...groups].join(\",\"));\n else params.delete(\"groups\");\n const qs = params.toString();\n window.history.replaceState(null, \"\", qs ? `${window.location.pathname}?${qs}` : window.location.pathname);\n}\n\nexport function useLaunchpadFilter() {\n const [query, setQueryState] = useState(\"\");\n const [activeGroups, setActiveGroups] = useState<Set<ServiceGroup>>(new Set());\n\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const q = params.get(\"q\");\n if (q) setQueryState(q);\n const g = params.get(\"groups\");\n if (g) {\n const groups = g.split(\",\").filter((k): k is ServiceGroup => GROUP_KEYS.has(k as ServiceGroup));\n if (groups.length > 0) setActiveGroups(new Set(groups));\n }\n }, []);\n\n const filterableGroups = LAUNCHPAD_SERVICE_GROUPS.filter((g) => g.key !== \"coming-soon\");\n\n const setQuery = (value: string) => {\n setQueryState(value);\n syncFilterUrl(value, activeGroups);\n };\n\n const toggleGroup = (key: ServiceGroup) => {\n setActiveGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n syncFilterUrl(query, next);\n return next;\n });\n };\n\n const matches = (def: ServiceDefinition): boolean => {\n if (activeGroups.size > 0 && !activeGroups.has(def.group)) return false;\n if (def.status !== \"live\") return false;\n return serviceMatchesQuery(def, query);\n };\n\n const totalMatches = useMemo(\n () => LAUNCHPAD_SERVICE_DEFINITIONS.filter(matches).length,\n\n [query, activeGroups],\n );\n\n const clear = () => {\n setQueryState(\"\");\n setActiveGroups(new Set());\n syncFilterUrl(\"\", new Set());\n };\n\n return { query, setQuery, activeGroups, toggleGroup, filterableGroups, totalMatches, clear };\n}\n\nexport interface LaunchpadGroupedSectionsProps {\n\n overrides: ServiceOverrides;\n\n query: string;\n\n activeGroups: Set<ServiceGroup>;\n\n onClearFilters: () => void;\n className?: string;\n\n excludeKeys?: string[];\n}\n\nexport function LaunchpadGroupedSections({ overrides, query, activeGroups, onClearFilters, className, excludeKeys }: LaunchpadGroupedSectionsProps) {\n const inActiveGroup = (d: ServiceDefinition) => activeGroups.size === 0 || activeGroups.has(d.group);\n const inSearch = (d: ServiceDefinition) => serviceMatchesQuery(d, query);\n const notExcluded = (d: ServiceDefinition) => !excludeKeys?.includes(d.key);\n\n const groupOrder = Object.fromEntries(LAUNCHPAD_SERVICE_GROUPS.map((g, i) => [g.key, i]));\n\n const liveDefs = LAUNCHPAD_SERVICE_DEFINITIONS\n .filter((d) => d.group !== \"coming-soon\" && d.status === \"live\" && notExcluded(d) && inActiveGroup(d) && inSearch(d))\n .sort((a, b) => (groupOrder[a.group] ?? 99) - (groupOrder[b.group] ?? 99));\n\n const comingSoonGroup = LAUNCHPAD_SERVICE_GROUPS.find((g) => g.key === \"coming-soon\");\n const comingSoonDefs = LAUNCHPAD_SERVICE_DEFINITIONS.filter(\n (d) => d.group === \"coming-soon\" && notExcluded(d) && inActiveGroup(d) && inSearch(d),\n );\n\n return (\n <div className={cn(\"space-y-8\", className)}>\n {liveDefs.length === 0 && comingSoonDefs.length === 0 ? (\n <div className=\"text-center py-16 space-y-3\">\n <p className=\"text-lg font-semibold\">No services match</p>\n <p className=\"text-sm text-muted-foreground\">Try a different search or clear your filters.</p>\n <button\n type=\"button\"\n onClick={onClearFilters}\n className=\"inline-flex items-center h-9 px-4 rounded-full text-sm font-semibold bg-primary text-primary-foreground\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <>\n <motion.div layout className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-5 sm:gap-6\">\n <AnimatePresence mode=\"popLayout\">\n {liveDefs.map((def, i) => (\n <LaunchpadServiceCard key={def.key} def={def} override={overrides[def.key]} index={i} />\n ))}\n </AnimatePresence>\n </motion.div>\n {comingSoonGroup && comingSoonDefs.length > 0 && (\n <ComingSoonStrip group={comingSoonGroup} defs={comingSoonDefs} />\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -62,7 +62,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
62
62
  key: "nfts",
63
63
  cta: "Create",
64
64
  blurb: "Publish each work as a single copy in a collection you own.",
65
- title: "Single Edition NFTs",
65
+ title: "Single Edition NFT",
66
66
  subtitle: "Each work is minted once",
67
67
  description: "Publish any photo, video, audio, or document, minted once inside your collection. Licensing, provenance, and ownership live on-chain.",
68
68
  features: ["One mint per work", "Collections with their own page and name", "You set the license terms"],
@@ -75,7 +75,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
75
75
  key: "limited-editions",
76
76
  cta: "Mint",
77
77
  blurb: "Release your work in numbered copies that can be collected and traded.",
78
- title: "Limited Editions",
78
+ title: "Limited Editions NFT",
79
79
  subtitle: "Numbered copies from a collection you own",
80
80
  description: "Create an editions collection and release each work in as many numbered copies as you choose.",
81
81
  features: ["Numbered copies, set by you", "Fans collect and trade", "One home for every release"],
@@ -84,6 +84,19 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
84
84
  status: "live",
85
85
  group: "limited-editions"
86
86
  },
87
+ {
88
+ key: "create-collection",
89
+ cta: "Create",
90
+ blurb: "Deploy your own collection to mint single-edition works into.",
91
+ title: "NFT Collection",
92
+ subtitle: "Your own ERC-721 collection, ready to mint into",
93
+ description: "Deploy a collection you own and control, with its own name, symbol, and page. Mint single-edition works into it whenever you're ready.",
94
+ features: ["Your own collection contract", "Set the name and symbol", "Mint into it anytime"],
95
+ example: "A photography collection, an album of singles",
96
+ icon: import_lucide_react.LayoutGrid,
97
+ status: "live",
98
+ group: "nfts"
99
+ },
87
100
  {
88
101
  key: "remix-asset",
89
102
  cta: "Browse",
@@ -97,6 +110,19 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
97
110
  status: "live",
98
111
  group: "nfts"
99
112
  },
113
+ {
114
+ key: "create-1155",
115
+ cta: "Create",
116
+ blurb: "Deploy your own collection to release numbered editions from.",
117
+ title: "Limited Editions Collection",
118
+ subtitle: "Your own ERC-1155 collection, ready for editions",
119
+ description: "Deploy an editions collection you own and control. Release each work in as many numbered copies as you choose.",
120
+ features: ["Your own collection contract", "Set the name and symbol", "Release editions anytime"],
121
+ example: "A print series, a music EP with numbered editions",
122
+ icon: import_lucide_react.Boxes,
123
+ status: "live",
124
+ group: "limited-editions"
125
+ },
100
126
  {
101
127
  key: "pop-protocol",
102
128
  cta: "Create",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data/launchpad-services.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport {\n ImagePlus, Layers, GitBranch,\n Award, Package,\n Ticket, Users, Handshake,\n Coins, TrendingUp,\n AtSign, FolderInput, Link2,\n} from \"lucide-react\";\nimport { hasCapability } from \"@medialane/sdk\";\n\nconst TICKETS_TRANSFERABLE_FEATURE = hasCapability(\"ip-tickets\", \"transfer\")\n ? \"Freely transferable\"\n : \"Stays with the original holder\";\n\nexport type ServiceStatus = \"live\" | \"building\" | \"soon\";\n\nexport type ServiceGroup =\n | \"nfts\"\n | \"limited-editions\"\n | \"coins\"\n | \"community\"\n | \"claims\"\n | \"coming-soon\";\n\nexport interface ServiceGroupDefinition {\n key: ServiceGroup;\n title: string;\n\n tagline: string;\n\n badge?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_GROUPS: ServiceGroupDefinition[] = [\n {\n key: \"nfts\",\n title: \"Originals\",\n tagline: \"Singular works, your own collections, timed drops, and remixes.\",\n },\n {\n key: \"limited-editions\",\n title: \"Limited Editions\",\n tagline: \"Numbered copies of your work.\",\n },\n {\n key: \"coins\",\n title: \"Coins\",\n tagline: \"Launch your own coin, or bring one you already made.\",\n },\n {\n key: \"community\",\n title: \"Community\",\n tagline: \"Badges, tickets, memberships, and direct sponsorship.\",\n },\n {\n key: \"claims\",\n title: \"Claims\",\n tagline: \"Reserve your username, your collection's name, or bring in a collection you already made.\",\n },\n {\n key: \"coming-soon\",\n title: \"Coming soon\",\n tagline: \"More ways to earn are on the way.\",\n },\n];\n\nexport interface ServiceDefinition {\n key: string;\n title: string;\n subtitle: string;\n description: string;\n features: string[];\n icon: LucideIcon;\n status: ServiceStatus;\n group: ServiceGroup;\n\n blurb: string;\n\n cta: string;\n\n example?: string;\n\n browseLinkLabel?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_DEFINITIONS: ServiceDefinition[] = [\n\n {\n key: \"nfts\",\n cta: \"Create\",\n blurb: \"Publish each work as a single copy in a collection you own.\",\n title: \"Single Edition NFTs\",\n subtitle: \"Each work is minted once\",\n description:\n \"Publish any photo, video, audio, or document, minted once inside your collection. Licensing, provenance, and ownership live on-chain.\",\n features: [\"One mint per work\", \"Collections with their own page and name\", \"You set the license terms\"],\n example: \"A song, a photo, an ebook, a short film\",\n icon: ImagePlus,\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"limited-editions\",\n cta: \"Mint\",\n blurb: \"Release your work in numbered copies that can be collected and traded.\",\n title: \"Limited Editions\",\n subtitle: \"Numbered copies from a collection you own\",\n description:\n \"Create an editions collection and release each work in as many numbered copies as you choose.\",\n features: [\"Numbered copies, set by you\", \"Fans collect and trade\", \"One home for every release\"],\n example: \"50 copies of a limited print, a music EP in 100 editions\",\n icon: Layers,\n status: \"live\",\n group: \"limited-editions\",\n },\n {\n key: \"remix-asset\",\n cta: \"Browse\",\n blurb: \"Create from another work. Credit and royalties are handled automatically.\",\n title: \"Remix Asset\",\n subtitle: \"Derivative works with on-chain attribution\",\n description:\n \"Create a licensed derivative of another work. Attribution and provenance flow back to the original creator.\",\n features: [\"Credit handled automatically\", \"Royalties flow to the original\", \"License respected at mint\"],\n example: \"A remix of a song, an artwork inspired by an original\",\n icon: GitBranch,\n status: \"live\",\n group: \"nfts\",\n },\n\n {\n key: \"pop-protocol\",\n cta: \"Create\",\n blurb: \"Badges your community claims and keeps forever.\",\n title: \"POP Protocol\",\n subtitle: \"Proof-of-participation badges for your community\",\n description:\n \"Give out permanent badges. Each person can claim one, and it cannot be transferred or faked.\",\n features: [\"Free for your community to claim\", \"Invite-list gating optional\", \"Branded claim page to share\"],\n example: \"Hackathon attendance badge, community membership, conference pass\",\n icon: Award,\n browseLinkLabel: \"Browse badges\",\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"collection-drop\",\n cta: \"Launch\",\n blurb: \"Release a limited run at a set price and time window.\",\n title: \"Collection Drop\",\n subtitle: \"Timed NFT releases with mint windows\",\n description:\n \"Set a price, a supply, and a start and end time. Collectors mint directly from your drop page.\",\n features: [\"You set price and supply\", \"Opens and closes on your schedule\", \"Branded drop page to share\"],\n example: \"A 48-hour drop of 200 pieces at 5 USDC each\",\n icon: Package,\n browseLinkLabel: \"Browse drops\",\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"ip-tickets\",\n cta: \"Create\",\n blurb: \"Create on-chain tickets your audience can hold and trade.\",\n title: \"IP Tickets\",\n subtitle: \"Verifiable tickets, held in the wallet\",\n description:\n \"Create tickets with their own supply and validity window, then mint them to attendees. Every ticket is verifiable on-chain.\",\n features: [\"Verifiable at the door\", \"Supply and validity you set\", TICKETS_TRANSFERABLE_FEATURE],\n icon: Ticket,\n browseLinkLabel: \"Browse tickets\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-club\",\n cta: \"Create\",\n blurb: \"Membership cards for your community.\",\n title: \"IP Club\",\n subtitle: \"Membership tiers, minted as cards\",\n description:\n \"Create a club with membership tiers — fans, supporters, press, season passes. Mint the cards and sell them like any collection.\",\n features: [\"Membership tiers\", \"Optional validity window\", \"Trade like any collection\"],\n icon: Users,\n browseLinkLabel: \"Browse clubs\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-sponsorship\",\n cta: \"Browse\",\n blurb: \"Let a sponsor back your work directly, for a license in return.\",\n title: \"IP Sponsorship\",\n subtitle: \"Direct sponsorship offers, settled asset-to-asset\",\n description:\n \"Create a sponsorship offer on an asset you own. Sponsors bid, you accept, and they receive a license. Payment settles directly between sponsor and author.\",\n features: [\"Direct settlement\", \"Owner-verified on-chain\", \"Open bidding or one invited sponsor\"],\n example: \"Sponsor a song, an artwork, or a patent for a license\",\n icon: Handshake,\n browseLinkLabel: \"Browse offers\",\n\n status: \"live\",\n group: \"community\",\n },\n\n {\n key: \"creator-coins\",\n cta: \"Launch\",\n blurb: \"Launch your coin in a few clicks and stay in control of it.\",\n title: \"Creator Coin\",\n subtitle: \"Your own coin, your liquidity\",\n description:\n \"Launch your own coin with a public trading pool. You set the supply and allocation and stay in control of the liquidity.\",\n features: [\"Launch in a few clicks\", \"You keep control of the liquidity\", \"Traded on a public pool\"],\n example: \"A fan coin for your channel, a coin for your music project\",\n icon: TrendingUp,\n status: \"live\",\n group: \"coins\",\n },\n\n {\n key: \"claim-memecoin\",\n cta: \"Claim\",\n blurb: \"Add a coin you already launched to your profile.\",\n title: \"Claim Memecoin\",\n subtitle: \"Bring a coin you already launched\",\n description:\n \"Claim a coin you already launched to list it on the Coins page and your profile. Claims are reviewed before going live.\",\n features: [\"Bring a coin you already launched\", \"Reviewed by our team\", \"Featured on the Coins page\"],\n example: \"Your unrug memecoin, listed on your creator profile\",\n icon: Coins,\n status: \"live\",\n group: \"coins\",\n },\n {\n key: \"claim-username\",\n cta: \"Claim\",\n blurb: \"Reserve your name and get your own creator page.\",\n title: \"Claim Username\",\n subtitle: \"Reserve your creator page URL\",\n description:\n \"Claim your username to get a shareable creator page, your public portfolio at a clean, memorable URL.\",\n features: [\"Free claim\", \"Shareable creator page\", \"Your public portfolio\"],\n example: \"medialane.io/your-name — your portfolio at your own name\",\n icon: AtSign,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection\",\n cta: \"Claim\",\n blurb: \"Made a collection somewhere else? Bring it to your profile.\",\n title: \"Claim Collection\",\n subtitle: \"Bring a collection you already made\",\n description:\n \"Claim a collection you made elsewhere to link it to your profile and give it a branded collection page.\",\n features: [\"Bring an existing collection\", \"Linked to your profile\", \"Branded collection page\"],\n example: \"A collection you made elsewhere joins your profile\",\n icon: FolderInput,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection-name\",\n cta: \"Claim\",\n blurb: \"Give your collection a clean, memorable web address of its own.\",\n title: \"Claim Collection Name\",\n subtitle: \"Reserve your collection page URL\",\n description:\n \"Claim a custom name for your collection page and get a clean, shareable URL instead of a long technical address.\",\n features: [\"Free claim\", \"Clean shareable URL\", \"Easy to remember and share\"],\n example: \"medialane.io/collections/your-collection\",\n icon: Link2,\n status: \"live\",\n group: \"claims\",\n },\n];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/data/launchpad-services.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport {\n ImagePlus, Layers, GitBranch,\n Award, Package,\n Ticket, Users, Handshake,\n Coins, TrendingUp,\n AtSign, FolderInput, Link2,\n LayoutGrid, Boxes,\n} from \"lucide-react\";\nimport { hasCapability } from \"@medialane/sdk\";\n\nconst TICKETS_TRANSFERABLE_FEATURE = hasCapability(\"ip-tickets\", \"transfer\")\n ? \"Freely transferable\"\n : \"Stays with the original holder\";\n\nexport type ServiceStatus = \"live\" | \"building\" | \"soon\";\n\nexport type ServiceGroup =\n | \"nfts\"\n | \"limited-editions\"\n | \"coins\"\n | \"community\"\n | \"claims\"\n | \"coming-soon\";\n\nexport interface ServiceGroupDefinition {\n key: ServiceGroup;\n title: string;\n\n tagline: string;\n\n badge?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_GROUPS: ServiceGroupDefinition[] = [\n {\n key: \"nfts\",\n title: \"Originals\",\n tagline: \"Singular works, your own collections, timed drops, and remixes.\",\n },\n {\n key: \"limited-editions\",\n title: \"Limited Editions\",\n tagline: \"Numbered copies of your work.\",\n },\n {\n key: \"coins\",\n title: \"Coins\",\n tagline: \"Launch your own coin, or bring one you already made.\",\n },\n {\n key: \"community\",\n title: \"Community\",\n tagline: \"Badges, tickets, memberships, and direct sponsorship.\",\n },\n {\n key: \"claims\",\n title: \"Claims\",\n tagline: \"Reserve your username, your collection's name, or bring in a collection you already made.\",\n },\n {\n key: \"coming-soon\",\n title: \"Coming soon\",\n tagline: \"More ways to earn are on the way.\",\n },\n];\n\nexport interface ServiceDefinition {\n key: string;\n title: string;\n subtitle: string;\n description: string;\n features: string[];\n icon: LucideIcon;\n status: ServiceStatus;\n group: ServiceGroup;\n\n blurb: string;\n\n cta: string;\n\n example?: string;\n\n browseLinkLabel?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_DEFINITIONS: ServiceDefinition[] = [\n\n {\n key: \"nfts\",\n cta: \"Create\",\n blurb: \"Publish each work as a single copy in a collection you own.\",\n title: \"Single Edition NFT\",\n subtitle: \"Each work is minted once\",\n description:\n \"Publish any photo, video, audio, or document, minted once inside your collection. Licensing, provenance, and ownership live on-chain.\",\n features: [\"One mint per work\", \"Collections with their own page and name\", \"You set the license terms\"],\n example: \"A song, a photo, an ebook, a short film\",\n icon: ImagePlus,\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"limited-editions\",\n cta: \"Mint\",\n blurb: \"Release your work in numbered copies that can be collected and traded.\",\n title: \"Limited Editions NFT\",\n subtitle: \"Numbered copies from a collection you own\",\n description:\n \"Create an editions collection and release each work in as many numbered copies as you choose.\",\n features: [\"Numbered copies, set by you\", \"Fans collect and trade\", \"One home for every release\"],\n example: \"50 copies of a limited print, a music EP in 100 editions\",\n icon: Layers,\n status: \"live\",\n group: \"limited-editions\",\n },\n {\n key: \"create-collection\",\n cta: \"Create\",\n blurb: \"Deploy your own collection to mint single-edition works into.\",\n title: \"NFT Collection\",\n subtitle: \"Your own ERC-721 collection, ready to mint into\",\n description:\n \"Deploy a collection you own and control, with its own name, symbol, and page. Mint single-edition works into it whenever you're ready.\",\n features: [\"Your own collection contract\", \"Set the name and symbol\", \"Mint into it anytime\"],\n example: \"A photography collection, an album of singles\",\n icon: LayoutGrid,\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"remix-asset\",\n cta: \"Browse\",\n blurb: \"Create from another work. Credit and royalties are handled automatically.\",\n title: \"Remix Asset\",\n subtitle: \"Derivative works with on-chain attribution\",\n description:\n \"Create a licensed derivative of another work. Attribution and provenance flow back to the original creator.\",\n features: [\"Credit handled automatically\", \"Royalties flow to the original\", \"License respected at mint\"],\n example: \"A remix of a song, an artwork inspired by an original\",\n icon: GitBranch,\n status: \"live\",\n group: \"nfts\",\n },\n\n {\n key: \"create-1155\",\n cta: \"Create\",\n blurb: \"Deploy your own collection to release numbered editions from.\",\n title: \"Limited Editions Collection\",\n subtitle: \"Your own ERC-1155 collection, ready for editions\",\n description:\n \"Deploy an editions collection you own and control. Release each work in as many numbered copies as you choose.\",\n features: [\"Your own collection contract\", \"Set the name and symbol\", \"Release editions anytime\"],\n example: \"A print series, a music EP with numbered editions\",\n icon: Boxes,\n status: \"live\",\n group: \"limited-editions\",\n },\n {\n key: \"pop-protocol\",\n cta: \"Create\",\n blurb: \"Badges your community claims and keeps forever.\",\n title: \"POP Protocol\",\n subtitle: \"Proof-of-participation badges for your community\",\n description:\n \"Give out permanent badges. Each person can claim one, and it cannot be transferred or faked.\",\n features: [\"Free for your community to claim\", \"Invite-list gating optional\", \"Branded claim page to share\"],\n example: \"Hackathon attendance badge, community membership, conference pass\",\n icon: Award,\n browseLinkLabel: \"Browse badges\",\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"collection-drop\",\n cta: \"Launch\",\n blurb: \"Release a limited run at a set price and time window.\",\n title: \"Collection Drop\",\n subtitle: \"Timed NFT releases with mint windows\",\n description:\n \"Set a price, a supply, and a start and end time. Collectors mint directly from your drop page.\",\n features: [\"You set price and supply\", \"Opens and closes on your schedule\", \"Branded drop page to share\"],\n example: \"A 48-hour drop of 200 pieces at 5 USDC each\",\n icon: Package,\n browseLinkLabel: \"Browse drops\",\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"ip-tickets\",\n cta: \"Create\",\n blurb: \"Create on-chain tickets your audience can hold and trade.\",\n title: \"IP Tickets\",\n subtitle: \"Verifiable tickets, held in the wallet\",\n description:\n \"Create tickets with their own supply and validity window, then mint them to attendees. Every ticket is verifiable on-chain.\",\n features: [\"Verifiable at the door\", \"Supply and validity you set\", TICKETS_TRANSFERABLE_FEATURE],\n icon: Ticket,\n browseLinkLabel: \"Browse tickets\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-club\",\n cta: \"Create\",\n blurb: \"Membership cards for your community.\",\n title: \"IP Club\",\n subtitle: \"Membership tiers, minted as cards\",\n description:\n \"Create a club with membership tiers — fans, supporters, press, season passes. Mint the cards and sell them like any collection.\",\n features: [\"Membership tiers\", \"Optional validity window\", \"Trade like any collection\"],\n icon: Users,\n browseLinkLabel: \"Browse clubs\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-sponsorship\",\n cta: \"Browse\",\n blurb: \"Let a sponsor back your work directly, for a license in return.\",\n title: \"IP Sponsorship\",\n subtitle: \"Direct sponsorship offers, settled asset-to-asset\",\n description:\n \"Create a sponsorship offer on an asset you own. Sponsors bid, you accept, and they receive a license. Payment settles directly between sponsor and author.\",\n features: [\"Direct settlement\", \"Owner-verified on-chain\", \"Open bidding or one invited sponsor\"],\n example: \"Sponsor a song, an artwork, or a patent for a license\",\n icon: Handshake,\n browseLinkLabel: \"Browse offers\",\n\n status: \"live\",\n group: \"community\",\n },\n\n {\n key: \"creator-coins\",\n cta: \"Launch\",\n blurb: \"Launch your coin in a few clicks and stay in control of it.\",\n title: \"Creator Coin\",\n subtitle: \"Your own coin, your liquidity\",\n description:\n \"Launch your own coin with a public trading pool. You set the supply and allocation and stay in control of the liquidity.\",\n features: [\"Launch in a few clicks\", \"You keep control of the liquidity\", \"Traded on a public pool\"],\n example: \"A fan coin for your channel, a coin for your music project\",\n icon: TrendingUp,\n status: \"live\",\n group: \"coins\",\n },\n\n {\n key: \"claim-memecoin\",\n cta: \"Claim\",\n blurb: \"Add a coin you already launched to your profile.\",\n title: \"Claim Memecoin\",\n subtitle: \"Bring a coin you already launched\",\n description:\n \"Claim a coin you already launched to list it on the Coins page and your profile. Claims are reviewed before going live.\",\n features: [\"Bring a coin you already launched\", \"Reviewed by our team\", \"Featured on the Coins page\"],\n example: \"Your unrug memecoin, listed on your creator profile\",\n icon: Coins,\n status: \"live\",\n group: \"coins\",\n },\n {\n key: \"claim-username\",\n cta: \"Claim\",\n blurb: \"Reserve your name and get your own creator page.\",\n title: \"Claim Username\",\n subtitle: \"Reserve your creator page URL\",\n description:\n \"Claim your username to get a shareable creator page, your public portfolio at a clean, memorable URL.\",\n features: [\"Free claim\", \"Shareable creator page\", \"Your public portfolio\"],\n example: \"medialane.io/your-name — your portfolio at your own name\",\n icon: AtSign,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection\",\n cta: \"Claim\",\n blurb: \"Made a collection somewhere else? Bring it to your profile.\",\n title: \"Claim Collection\",\n subtitle: \"Bring a collection you already made\",\n description:\n \"Claim a collection you made elsewhere to link it to your profile and give it a branded collection page.\",\n features: [\"Bring an existing collection\", \"Linked to your profile\", \"Branded collection page\"],\n example: \"A collection you made elsewhere joins your profile\",\n icon: FolderInput,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection-name\",\n cta: \"Claim\",\n blurb: \"Give your collection a clean, memorable web address of its own.\",\n title: \"Claim Collection Name\",\n subtitle: \"Reserve your collection page URL\",\n description:\n \"Claim a custom name for your collection page and get a clean, shareable URL instead of a long technical address.\",\n features: [\"Free claim\", \"Clean shareable URL\", \"Easy to remember and share\"],\n example: \"medialane.io/collections/your-collection\",\n icon: Link2,\n status: \"live\",\n group: \"claims\",\n },\n];\n"],"mappings":"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","names":[]}
@@ -11,7 +11,9 @@ import {
11
11
  TrendingUp,
12
12
  AtSign,
13
13
  FolderInput,
14
- Link2
14
+ Link2,
15
+ LayoutGrid,
16
+ Boxes
15
17
  } from "lucide-react";
16
18
  import { hasCapability } from "@medialane/sdk";
17
19
  const TICKETS_TRANSFERABLE_FEATURE = hasCapability("ip-tickets", "transfer") ? "Freely transferable" : "Stays with the original holder";
@@ -52,7 +54,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
52
54
  key: "nfts",
53
55
  cta: "Create",
54
56
  blurb: "Publish each work as a single copy in a collection you own.",
55
- title: "Single Edition NFTs",
57
+ title: "Single Edition NFT",
56
58
  subtitle: "Each work is minted once",
57
59
  description: "Publish any photo, video, audio, or document, minted once inside your collection. Licensing, provenance, and ownership live on-chain.",
58
60
  features: ["One mint per work", "Collections with their own page and name", "You set the license terms"],
@@ -65,7 +67,7 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
65
67
  key: "limited-editions",
66
68
  cta: "Mint",
67
69
  blurb: "Release your work in numbered copies that can be collected and traded.",
68
- title: "Limited Editions",
70
+ title: "Limited Editions NFT",
69
71
  subtitle: "Numbered copies from a collection you own",
70
72
  description: "Create an editions collection and release each work in as many numbered copies as you choose.",
71
73
  features: ["Numbered copies, set by you", "Fans collect and trade", "One home for every release"],
@@ -74,6 +76,19 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
74
76
  status: "live",
75
77
  group: "limited-editions"
76
78
  },
79
+ {
80
+ key: "create-collection",
81
+ cta: "Create",
82
+ blurb: "Deploy your own collection to mint single-edition works into.",
83
+ title: "NFT Collection",
84
+ subtitle: "Your own ERC-721 collection, ready to mint into",
85
+ description: "Deploy a collection you own and control, with its own name, symbol, and page. Mint single-edition works into it whenever you're ready.",
86
+ features: ["Your own collection contract", "Set the name and symbol", "Mint into it anytime"],
87
+ example: "A photography collection, an album of singles",
88
+ icon: LayoutGrid,
89
+ status: "live",
90
+ group: "nfts"
91
+ },
77
92
  {
78
93
  key: "remix-asset",
79
94
  cta: "Browse",
@@ -87,6 +102,19 @@ const LAUNCHPAD_SERVICE_DEFINITIONS = [
87
102
  status: "live",
88
103
  group: "nfts"
89
104
  },
105
+ {
106
+ key: "create-1155",
107
+ cta: "Create",
108
+ blurb: "Deploy your own collection to release numbered editions from.",
109
+ title: "Limited Editions Collection",
110
+ subtitle: "Your own ERC-1155 collection, ready for editions",
111
+ description: "Deploy an editions collection you own and control. Release each work in as many numbered copies as you choose.",
112
+ features: ["Your own collection contract", "Set the name and symbol", "Release editions anytime"],
113
+ example: "A print series, a music EP with numbered editions",
114
+ icon: Boxes,
115
+ status: "live",
116
+ group: "limited-editions"
117
+ },
90
118
  {
91
119
  key: "pop-protocol",
92
120
  cta: "Create",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data/launchpad-services.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport {\n ImagePlus, Layers, GitBranch,\n Award, Package,\n Ticket, Users, Handshake,\n Coins, TrendingUp,\n AtSign, FolderInput, Link2,\n} from \"lucide-react\";\nimport { hasCapability } from \"@medialane/sdk\";\n\nconst TICKETS_TRANSFERABLE_FEATURE = hasCapability(\"ip-tickets\", \"transfer\")\n ? \"Freely transferable\"\n : \"Stays with the original holder\";\n\nexport type ServiceStatus = \"live\" | \"building\" | \"soon\";\n\nexport type ServiceGroup =\n | \"nfts\"\n | \"limited-editions\"\n | \"coins\"\n | \"community\"\n | \"claims\"\n | \"coming-soon\";\n\nexport interface ServiceGroupDefinition {\n key: ServiceGroup;\n title: string;\n\n tagline: string;\n\n badge?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_GROUPS: ServiceGroupDefinition[] = [\n {\n key: \"nfts\",\n title: \"Originals\",\n tagline: \"Singular works, your own collections, timed drops, and remixes.\",\n },\n {\n key: \"limited-editions\",\n title: \"Limited Editions\",\n tagline: \"Numbered copies of your work.\",\n },\n {\n key: \"coins\",\n title: \"Coins\",\n tagline: \"Launch your own coin, or bring one you already made.\",\n },\n {\n key: \"community\",\n title: \"Community\",\n tagline: \"Badges, tickets, memberships, and direct sponsorship.\",\n },\n {\n key: \"claims\",\n title: \"Claims\",\n tagline: \"Reserve your username, your collection's name, or bring in a collection you already made.\",\n },\n {\n key: \"coming-soon\",\n title: \"Coming soon\",\n tagline: \"More ways to earn are on the way.\",\n },\n];\n\nexport interface ServiceDefinition {\n key: string;\n title: string;\n subtitle: string;\n description: string;\n features: string[];\n icon: LucideIcon;\n status: ServiceStatus;\n group: ServiceGroup;\n\n blurb: string;\n\n cta: string;\n\n example?: string;\n\n browseLinkLabel?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_DEFINITIONS: ServiceDefinition[] = [\n\n {\n key: \"nfts\",\n cta: \"Create\",\n blurb: \"Publish each work as a single copy in a collection you own.\",\n title: \"Single Edition NFTs\",\n subtitle: \"Each work is minted once\",\n description:\n \"Publish any photo, video, audio, or document, minted once inside your collection. Licensing, provenance, and ownership live on-chain.\",\n features: [\"One mint per work\", \"Collections with their own page and name\", \"You set the license terms\"],\n example: \"A song, a photo, an ebook, a short film\",\n icon: ImagePlus,\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"limited-editions\",\n cta: \"Mint\",\n blurb: \"Release your work in numbered copies that can be collected and traded.\",\n title: \"Limited Editions\",\n subtitle: \"Numbered copies from a collection you own\",\n description:\n \"Create an editions collection and release each work in as many numbered copies as you choose.\",\n features: [\"Numbered copies, set by you\", \"Fans collect and trade\", \"One home for every release\"],\n example: \"50 copies of a limited print, a music EP in 100 editions\",\n icon: Layers,\n status: \"live\",\n group: \"limited-editions\",\n },\n {\n key: \"remix-asset\",\n cta: \"Browse\",\n blurb: \"Create from another work. Credit and royalties are handled automatically.\",\n title: \"Remix Asset\",\n subtitle: \"Derivative works with on-chain attribution\",\n description:\n \"Create a licensed derivative of another work. Attribution and provenance flow back to the original creator.\",\n features: [\"Credit handled automatically\", \"Royalties flow to the original\", \"License respected at mint\"],\n example: \"A remix of a song, an artwork inspired by an original\",\n icon: GitBranch,\n status: \"live\",\n group: \"nfts\",\n },\n\n {\n key: \"pop-protocol\",\n cta: \"Create\",\n blurb: \"Badges your community claims and keeps forever.\",\n title: \"POP Protocol\",\n subtitle: \"Proof-of-participation badges for your community\",\n description:\n \"Give out permanent badges. Each person can claim one, and it cannot be transferred or faked.\",\n features: [\"Free for your community to claim\", \"Invite-list gating optional\", \"Branded claim page to share\"],\n example: \"Hackathon attendance badge, community membership, conference pass\",\n icon: Award,\n browseLinkLabel: \"Browse badges\",\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"collection-drop\",\n cta: \"Launch\",\n blurb: \"Release a limited run at a set price and time window.\",\n title: \"Collection Drop\",\n subtitle: \"Timed NFT releases with mint windows\",\n description:\n \"Set a price, a supply, and a start and end time. Collectors mint directly from your drop page.\",\n features: [\"You set price and supply\", \"Opens and closes on your schedule\", \"Branded drop page to share\"],\n example: \"A 48-hour drop of 200 pieces at 5 USDC each\",\n icon: Package,\n browseLinkLabel: \"Browse drops\",\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"ip-tickets\",\n cta: \"Create\",\n blurb: \"Create on-chain tickets your audience can hold and trade.\",\n title: \"IP Tickets\",\n subtitle: \"Verifiable tickets, held in the wallet\",\n description:\n \"Create tickets with their own supply and validity window, then mint them to attendees. Every ticket is verifiable on-chain.\",\n features: [\"Verifiable at the door\", \"Supply and validity you set\", TICKETS_TRANSFERABLE_FEATURE],\n icon: Ticket,\n browseLinkLabel: \"Browse tickets\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-club\",\n cta: \"Create\",\n blurb: \"Membership cards for your community.\",\n title: \"IP Club\",\n subtitle: \"Membership tiers, minted as cards\",\n description:\n \"Create a club with membership tiers — fans, supporters, press, season passes. Mint the cards and sell them like any collection.\",\n features: [\"Membership tiers\", \"Optional validity window\", \"Trade like any collection\"],\n icon: Users,\n browseLinkLabel: \"Browse clubs\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-sponsorship\",\n cta: \"Browse\",\n blurb: \"Let a sponsor back your work directly, for a license in return.\",\n title: \"IP Sponsorship\",\n subtitle: \"Direct sponsorship offers, settled asset-to-asset\",\n description:\n \"Create a sponsorship offer on an asset you own. Sponsors bid, you accept, and they receive a license. Payment settles directly between sponsor and author.\",\n features: [\"Direct settlement\", \"Owner-verified on-chain\", \"Open bidding or one invited sponsor\"],\n example: \"Sponsor a song, an artwork, or a patent for a license\",\n icon: Handshake,\n browseLinkLabel: \"Browse offers\",\n\n status: \"live\",\n group: \"community\",\n },\n\n {\n key: \"creator-coins\",\n cta: \"Launch\",\n blurb: \"Launch your coin in a few clicks and stay in control of it.\",\n title: \"Creator Coin\",\n subtitle: \"Your own coin, your liquidity\",\n description:\n \"Launch your own coin with a public trading pool. You set the supply and allocation and stay in control of the liquidity.\",\n features: [\"Launch in a few clicks\", \"You keep control of the liquidity\", \"Traded on a public pool\"],\n example: \"A fan coin for your channel, a coin for your music project\",\n icon: TrendingUp,\n status: \"live\",\n group: \"coins\",\n },\n\n {\n key: \"claim-memecoin\",\n cta: \"Claim\",\n blurb: \"Add a coin you already launched to your profile.\",\n title: \"Claim Memecoin\",\n subtitle: \"Bring a coin you already launched\",\n description:\n \"Claim a coin you already launched to list it on the Coins page and your profile. Claims are reviewed before going live.\",\n features: [\"Bring a coin you already launched\", \"Reviewed by our team\", \"Featured on the Coins page\"],\n example: \"Your unrug memecoin, listed on your creator profile\",\n icon: Coins,\n status: \"live\",\n group: \"coins\",\n },\n {\n key: \"claim-username\",\n cta: \"Claim\",\n blurb: \"Reserve your name and get your own creator page.\",\n title: \"Claim Username\",\n subtitle: \"Reserve your creator page URL\",\n description:\n \"Claim your username to get a shareable creator page, your public portfolio at a clean, memorable URL.\",\n features: [\"Free claim\", \"Shareable creator page\", \"Your public portfolio\"],\n example: \"medialane.io/your-name — your portfolio at your own name\",\n icon: AtSign,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection\",\n cta: \"Claim\",\n blurb: \"Made a collection somewhere else? Bring it to your profile.\",\n title: \"Claim Collection\",\n subtitle: \"Bring a collection you already made\",\n description:\n \"Claim a collection you made elsewhere to link it to your profile and give it a branded collection page.\",\n features: [\"Bring an existing collection\", \"Linked to your profile\", \"Branded collection page\"],\n example: \"A collection you made elsewhere joins your profile\",\n icon: FolderInput,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection-name\",\n cta: \"Claim\",\n blurb: \"Give your collection a clean, memorable web address of its own.\",\n title: \"Claim Collection Name\",\n subtitle: \"Reserve your collection page URL\",\n description:\n \"Claim a custom name for your collection page and get a clean, shareable URL instead of a long technical address.\",\n features: [\"Free claim\", \"Clean shareable URL\", \"Easy to remember and share\"],\n example: \"medialane.io/collections/your-collection\",\n icon: Link2,\n status: \"live\",\n group: \"claims\",\n },\n];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/data/launchpad-services.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport {\n ImagePlus, Layers, GitBranch,\n Award, Package,\n Ticket, Users, Handshake,\n Coins, TrendingUp,\n AtSign, FolderInput, Link2,\n LayoutGrid, Boxes,\n} from \"lucide-react\";\nimport { hasCapability } from \"@medialane/sdk\";\n\nconst TICKETS_TRANSFERABLE_FEATURE = hasCapability(\"ip-tickets\", \"transfer\")\n ? \"Freely transferable\"\n : \"Stays with the original holder\";\n\nexport type ServiceStatus = \"live\" | \"building\" | \"soon\";\n\nexport type ServiceGroup =\n | \"nfts\"\n | \"limited-editions\"\n | \"coins\"\n | \"community\"\n | \"claims\"\n | \"coming-soon\";\n\nexport interface ServiceGroupDefinition {\n key: ServiceGroup;\n title: string;\n\n tagline: string;\n\n badge?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_GROUPS: ServiceGroupDefinition[] = [\n {\n key: \"nfts\",\n title: \"Originals\",\n tagline: \"Singular works, your own collections, timed drops, and remixes.\",\n },\n {\n key: \"limited-editions\",\n title: \"Limited Editions\",\n tagline: \"Numbered copies of your work.\",\n },\n {\n key: \"coins\",\n title: \"Coins\",\n tagline: \"Launch your own coin, or bring one you already made.\",\n },\n {\n key: \"community\",\n title: \"Community\",\n tagline: \"Badges, tickets, memberships, and direct sponsorship.\",\n },\n {\n key: \"claims\",\n title: \"Claims\",\n tagline: \"Reserve your username, your collection's name, or bring in a collection you already made.\",\n },\n {\n key: \"coming-soon\",\n title: \"Coming soon\",\n tagline: \"More ways to earn are on the way.\",\n },\n];\n\nexport interface ServiceDefinition {\n key: string;\n title: string;\n subtitle: string;\n description: string;\n features: string[];\n icon: LucideIcon;\n status: ServiceStatus;\n group: ServiceGroup;\n\n blurb: string;\n\n cta: string;\n\n example?: string;\n\n browseLinkLabel?: string;\n}\n\nexport const LAUNCHPAD_SERVICE_DEFINITIONS: ServiceDefinition[] = [\n\n {\n key: \"nfts\",\n cta: \"Create\",\n blurb: \"Publish each work as a single copy in a collection you own.\",\n title: \"Single Edition NFT\",\n subtitle: \"Each work is minted once\",\n description:\n \"Publish any photo, video, audio, or document, minted once inside your collection. Licensing, provenance, and ownership live on-chain.\",\n features: [\"One mint per work\", \"Collections with their own page and name\", \"You set the license terms\"],\n example: \"A song, a photo, an ebook, a short film\",\n icon: ImagePlus,\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"limited-editions\",\n cta: \"Mint\",\n blurb: \"Release your work in numbered copies that can be collected and traded.\",\n title: \"Limited Editions NFT\",\n subtitle: \"Numbered copies from a collection you own\",\n description:\n \"Create an editions collection and release each work in as many numbered copies as you choose.\",\n features: [\"Numbered copies, set by you\", \"Fans collect and trade\", \"One home for every release\"],\n example: \"50 copies of a limited print, a music EP in 100 editions\",\n icon: Layers,\n status: \"live\",\n group: \"limited-editions\",\n },\n {\n key: \"create-collection\",\n cta: \"Create\",\n blurb: \"Deploy your own collection to mint single-edition works into.\",\n title: \"NFT Collection\",\n subtitle: \"Your own ERC-721 collection, ready to mint into\",\n description:\n \"Deploy a collection you own and control, with its own name, symbol, and page. Mint single-edition works into it whenever you're ready.\",\n features: [\"Your own collection contract\", \"Set the name and symbol\", \"Mint into it anytime\"],\n example: \"A photography collection, an album of singles\",\n icon: LayoutGrid,\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"remix-asset\",\n cta: \"Browse\",\n blurb: \"Create from another work. Credit and royalties are handled automatically.\",\n title: \"Remix Asset\",\n subtitle: \"Derivative works with on-chain attribution\",\n description:\n \"Create a licensed derivative of another work. Attribution and provenance flow back to the original creator.\",\n features: [\"Credit handled automatically\", \"Royalties flow to the original\", \"License respected at mint\"],\n example: \"A remix of a song, an artwork inspired by an original\",\n icon: GitBranch,\n status: \"live\",\n group: \"nfts\",\n },\n\n {\n key: \"create-1155\",\n cta: \"Create\",\n blurb: \"Deploy your own collection to release numbered editions from.\",\n title: \"Limited Editions Collection\",\n subtitle: \"Your own ERC-1155 collection, ready for editions\",\n description:\n \"Deploy an editions collection you own and control. Release each work in as many numbered copies as you choose.\",\n features: [\"Your own collection contract\", \"Set the name and symbol\", \"Release editions anytime\"],\n example: \"A print series, a music EP with numbered editions\",\n icon: Boxes,\n status: \"live\",\n group: \"limited-editions\",\n },\n {\n key: \"pop-protocol\",\n cta: \"Create\",\n blurb: \"Badges your community claims and keeps forever.\",\n title: \"POP Protocol\",\n subtitle: \"Proof-of-participation badges for your community\",\n description:\n \"Give out permanent badges. Each person can claim one, and it cannot be transferred or faked.\",\n features: [\"Free for your community to claim\", \"Invite-list gating optional\", \"Branded claim page to share\"],\n example: \"Hackathon attendance badge, community membership, conference pass\",\n icon: Award,\n browseLinkLabel: \"Browse badges\",\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"collection-drop\",\n cta: \"Launch\",\n blurb: \"Release a limited run at a set price and time window.\",\n title: \"Collection Drop\",\n subtitle: \"Timed NFT releases with mint windows\",\n description:\n \"Set a price, a supply, and a start and end time. Collectors mint directly from your drop page.\",\n features: [\"You set price and supply\", \"Opens and closes on your schedule\", \"Branded drop page to share\"],\n example: \"A 48-hour drop of 200 pieces at 5 USDC each\",\n icon: Package,\n browseLinkLabel: \"Browse drops\",\n status: \"live\",\n group: \"nfts\",\n },\n {\n key: \"ip-tickets\",\n cta: \"Create\",\n blurb: \"Create on-chain tickets your audience can hold and trade.\",\n title: \"IP Tickets\",\n subtitle: \"Verifiable tickets, held in the wallet\",\n description:\n \"Create tickets with their own supply and validity window, then mint them to attendees. Every ticket is verifiable on-chain.\",\n features: [\"Verifiable at the door\", \"Supply and validity you set\", TICKETS_TRANSFERABLE_FEATURE],\n icon: Ticket,\n browseLinkLabel: \"Browse tickets\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-club\",\n cta: \"Create\",\n blurb: \"Membership cards for your community.\",\n title: \"IP Club\",\n subtitle: \"Membership tiers, minted as cards\",\n description:\n \"Create a club with membership tiers — fans, supporters, press, season passes. Mint the cards and sell them like any collection.\",\n features: [\"Membership tiers\", \"Optional validity window\", \"Trade like any collection\"],\n icon: Users,\n browseLinkLabel: \"Browse clubs\",\n\n status: \"live\",\n group: \"community\",\n },\n {\n key: \"ip-sponsorship\",\n cta: \"Browse\",\n blurb: \"Let a sponsor back your work directly, for a license in return.\",\n title: \"IP Sponsorship\",\n subtitle: \"Direct sponsorship offers, settled asset-to-asset\",\n description:\n \"Create a sponsorship offer on an asset you own. Sponsors bid, you accept, and they receive a license. Payment settles directly between sponsor and author.\",\n features: [\"Direct settlement\", \"Owner-verified on-chain\", \"Open bidding or one invited sponsor\"],\n example: \"Sponsor a song, an artwork, or a patent for a license\",\n icon: Handshake,\n browseLinkLabel: \"Browse offers\",\n\n status: \"live\",\n group: \"community\",\n },\n\n {\n key: \"creator-coins\",\n cta: \"Launch\",\n blurb: \"Launch your coin in a few clicks and stay in control of it.\",\n title: \"Creator Coin\",\n subtitle: \"Your own coin, your liquidity\",\n description:\n \"Launch your own coin with a public trading pool. You set the supply and allocation and stay in control of the liquidity.\",\n features: [\"Launch in a few clicks\", \"You keep control of the liquidity\", \"Traded on a public pool\"],\n example: \"A fan coin for your channel, a coin for your music project\",\n icon: TrendingUp,\n status: \"live\",\n group: \"coins\",\n },\n\n {\n key: \"claim-memecoin\",\n cta: \"Claim\",\n blurb: \"Add a coin you already launched to your profile.\",\n title: \"Claim Memecoin\",\n subtitle: \"Bring a coin you already launched\",\n description:\n \"Claim a coin you already launched to list it on the Coins page and your profile. Claims are reviewed before going live.\",\n features: [\"Bring a coin you already launched\", \"Reviewed by our team\", \"Featured on the Coins page\"],\n example: \"Your unrug memecoin, listed on your creator profile\",\n icon: Coins,\n status: \"live\",\n group: \"coins\",\n },\n {\n key: \"claim-username\",\n cta: \"Claim\",\n blurb: \"Reserve your name and get your own creator page.\",\n title: \"Claim Username\",\n subtitle: \"Reserve your creator page URL\",\n description:\n \"Claim your username to get a shareable creator page, your public portfolio at a clean, memorable URL.\",\n features: [\"Free claim\", \"Shareable creator page\", \"Your public portfolio\"],\n example: \"medialane.io/your-name — your portfolio at your own name\",\n icon: AtSign,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection\",\n cta: \"Claim\",\n blurb: \"Made a collection somewhere else? Bring it to your profile.\",\n title: \"Claim Collection\",\n subtitle: \"Bring a collection you already made\",\n description:\n \"Claim a collection you made elsewhere to link it to your profile and give it a branded collection page.\",\n features: [\"Bring an existing collection\", \"Linked to your profile\", \"Branded collection page\"],\n example: \"A collection you made elsewhere joins your profile\",\n icon: FolderInput,\n status: \"live\",\n group: \"claims\",\n },\n {\n key: \"claim-collection-name\",\n cta: \"Claim\",\n blurb: \"Give your collection a clean, memorable web address of its own.\",\n title: \"Claim Collection Name\",\n subtitle: \"Reserve your collection page URL\",\n description:\n \"Claim a custom name for your collection page and get a clean, shareable URL instead of a long technical address.\",\n features: [\"Free claim\", \"Clean shareable URL\", \"Easy to remember and share\"],\n example: \"medialane.io/collections/your-collection\",\n icon: Link2,\n status: \"live\",\n group: \"claims\",\n },\n];\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.144.0",
3
+ "version": "0.145.1",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,