@unicitylabs/sphere-ui 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +30 -5
- package/dist/index.js +231 -188
- package/package.json +1 -1
- package/src/styles/tokens.css +13 -0
package/dist/index.d.ts
CHANGED
|
@@ -413,13 +413,38 @@ interface InstalledProjectIconProps {
|
|
|
413
413
|
/**
|
|
414
414
|
* InstalledProjectIcon — desktop tile for an installed app/skill.
|
|
415
415
|
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
416
|
+
* Composes the shared ProjectLogo visual with a button wrapper that
|
|
417
|
+
* adds hover/tap animation, a glow halo, and a name label underneath.
|
|
418
|
+
* Behavior is driven entirely by props: pass `onClick` for the
|
|
419
|
+
* primary action, `onContextMenu` for right-click, and
|
|
420
|
+
* `topRightAction` to overlay a small action button on the tile.
|
|
420
421
|
*/
|
|
421
422
|
declare function InstalledProjectIcon({ name, logoUrl, accentColor, onClick, onContextMenu, topRightAction, showLabel, buttonRef, buttonProps, }: InstalledProjectIconProps): react_jsx_runtime.JSX.Element;
|
|
422
423
|
|
|
424
|
+
type ProjectLogoSize = 'sm' | 'md' | 'lg';
|
|
425
|
+
interface ProjectLogoProps {
|
|
426
|
+
name: string;
|
|
427
|
+
logoUrl?: string | null;
|
|
428
|
+
/** Hex like "#FF6F00". Drives the gradient + fallback letter background. */
|
|
429
|
+
accentColor?: string;
|
|
430
|
+
/** Tile size — sm 36px / md 44px / lg 56–64px (desktop dock). */
|
|
431
|
+
size?: ProjectLogoSize;
|
|
432
|
+
/** Extra classes on the outer tile (e.g. ring, border). */
|
|
433
|
+
className?: string;
|
|
434
|
+
/** Absolute-positioned overlay slot (e.g. context-menu trigger, install badge). */
|
|
435
|
+
children?: ReactNode;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* ProjectLogo — the canonical "app icon" visual: gradient tile +
|
|
439
|
+
* mesh overlay + corner accent + edge-to-edge logo image. Pure
|
|
440
|
+
* presentation, no behavior — wrap it in a button/link if interactive.
|
|
441
|
+
*
|
|
442
|
+
* Used everywhere a project logo appears (desktop dock, marketplace
|
|
443
|
+
* cards, install previews) so the icon looks the same regardless of
|
|
444
|
+
* surrounding chrome.
|
|
445
|
+
*/
|
|
446
|
+
declare function ProjectLogo({ name, logoUrl, accentColor, size, className, children, }: ProjectLogoProps): react_jsx_runtime.JSX.Element;
|
|
447
|
+
|
|
423
448
|
interface QuestPreviewSummary {
|
|
424
449
|
slug: string;
|
|
425
450
|
title: string;
|
|
@@ -472,4 +497,4 @@ declare function isMimeAllowed(kind: MediaKind, mime: string): mime is MediaMime
|
|
|
472
497
|
declare function isSizeAllowed(kind: MediaKind, size: number): boolean;
|
|
473
498
|
declare function humanSize(bytes: number): string;
|
|
474
499
|
|
|
475
|
-
export { type AchievementPreviewSummary, AddressDisplay, AlertBanner, AppLogo, Button, type ButtonProps, type ButtonVariant, ChainInput, ConfirmDialog, CustomSelect, DashboardLayout, DataTable, EmptyState, FeaturedProjectCard, type FeaturedProjectCardProps, Field, FormModal, IconArrowRight, IconBack, IconChain, IconCheck, IconChevronDown, IconChevronUp, IconChevronsDown, IconChevronsRight, IconCircle, IconDiamond, IconEdit, IconPlay, IconPlus, IconQuests, IconSearch, IconSettings, IconStar, IconTracks, IconTrash, IconUndo, IconX, Input, type InputProps, InstalledProjectIcon, type InstalledProjectIconProps, JsonPanel, JsonToggleButton, MEDIA_LIMITS, MarketplaceProjectCard, type MarketplaceProjectCardProps, MediaGallery, type MediaGalleryProps, type MediaItem, type MediaKind, type MediaLimit, type MediaMime, type MediaUploadFn, type MediaUploadResult, MediaUploader, type MediaUploaderProps, type MemoCondition, MemoConditionsEditor, type NavGroup, type NavItem, PageShell, ProjectPagePreview, type ProjectPagePreviewProps, type QuestPreviewSummary, SearchInput, Section, Select, type SelectOption, type SelectProps, SidebarNav, Skeleton, SkeletonCircle, type SkeletonCircleProps, type SkeletonCircleSize, type SkeletonProps, SkeletonText, type SkeletonTextProps, StatusBadge, Textarea, type TextareaProps, humanSize, isMimeAllowed, isSizeAllowed, tagColor };
|
|
500
|
+
export { type AchievementPreviewSummary, AddressDisplay, AlertBanner, AppLogo, Button, type ButtonProps, type ButtonVariant, ChainInput, ConfirmDialog, CustomSelect, DashboardLayout, DataTable, EmptyState, FeaturedProjectCard, type FeaturedProjectCardProps, Field, FormModal, IconArrowRight, IconBack, IconChain, IconCheck, IconChevronDown, IconChevronUp, IconChevronsDown, IconChevronsRight, IconCircle, IconDiamond, IconEdit, IconPlay, IconPlus, IconQuests, IconSearch, IconSettings, IconStar, IconTracks, IconTrash, IconUndo, IconX, Input, type InputProps, InstalledProjectIcon, type InstalledProjectIconProps, JsonPanel, JsonToggleButton, MEDIA_LIMITS, MarketplaceProjectCard, type MarketplaceProjectCardProps, MediaGallery, type MediaGalleryProps, type MediaItem, type MediaKind, type MediaLimit, type MediaMime, type MediaUploadFn, type MediaUploadResult, MediaUploader, type MediaUploaderProps, type MemoCondition, MemoConditionsEditor, type NavGroup, type NavItem, PageShell, ProjectLogo, type ProjectLogoProps, type ProjectLogoSize, ProjectPagePreview, type ProjectPagePreviewProps, type QuestPreviewSummary, SearchInput, Section, Select, type SelectOption, type SelectProps, SidebarNav, Skeleton, SkeletonCircle, type SkeletonCircleProps, type SkeletonCircleSize, type SkeletonProps, SkeletonText, type SkeletonTextProps, StatusBadge, Textarea, type TextareaProps, humanSize, isMimeAllowed, isSizeAllowed, tagColor };
|
package/dist/index.js
CHANGED
|
@@ -1648,7 +1648,7 @@ function MediaUploader({
|
|
|
1648
1648
|
placeholder: "https://...",
|
|
1649
1649
|
value: urlInput,
|
|
1650
1650
|
onChange: (e) => setUrlInput(e.target.value),
|
|
1651
|
-
onBlur: () =>
|
|
1651
|
+
onBlur: () => onChange(urlInput.trim() || null)
|
|
1652
1652
|
}
|
|
1653
1653
|
)
|
|
1654
1654
|
] })
|
|
@@ -1762,7 +1762,77 @@ function MediaGallery({ ownerType, ownerId, items, onChange, uploadFn, max = 10
|
|
|
1762
1762
|
// src/components/media/MarketplaceProjectCard.tsx
|
|
1763
1763
|
import { motion } from "framer-motion";
|
|
1764
1764
|
import { Users, Target, ThumbsUp, Plus, Check } from "lucide-react";
|
|
1765
|
+
|
|
1766
|
+
// src/components/media/ProjectLogo.tsx
|
|
1767
|
+
import { useState as useState9 } from "react";
|
|
1765
1768
|
import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1769
|
+
var SIZE_CLASSES = {
|
|
1770
|
+
sm: "w-9 h-9 rounded-xl",
|
|
1771
|
+
md: "w-11 h-11 rounded-xl",
|
|
1772
|
+
lg: "w-14 h-14 sm:w-16 sm:h-16 rounded-2xl"
|
|
1773
|
+
};
|
|
1774
|
+
var FALLBACK_TEXT_CLASSES = {
|
|
1775
|
+
sm: "text-xs",
|
|
1776
|
+
md: "text-sm",
|
|
1777
|
+
lg: "text-lg sm:text-xl"
|
|
1778
|
+
};
|
|
1779
|
+
function getInitials(name) {
|
|
1780
|
+
if (!name) return "?";
|
|
1781
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
1782
|
+
if (words.length >= 2) {
|
|
1783
|
+
return (words[0][0] + words[1][0]).toUpperCase();
|
|
1784
|
+
}
|
|
1785
|
+
return name.slice(0, 2).toUpperCase();
|
|
1786
|
+
}
|
|
1787
|
+
function isPlaceholderUrl(url) {
|
|
1788
|
+
return /^https?:\/\/(?:placehold\.co|placeholder\.com|via\.placeholder\.com|ui-avatars\.com|placekitten\.com|dummyimage\.com)\b/i.test(url);
|
|
1789
|
+
}
|
|
1790
|
+
function ProjectLogo({
|
|
1791
|
+
name,
|
|
1792
|
+
logoUrl,
|
|
1793
|
+
accentColor = "#FF6F00",
|
|
1794
|
+
size = "lg",
|
|
1795
|
+
className,
|
|
1796
|
+
children
|
|
1797
|
+
}) {
|
|
1798
|
+
const [imgError, setImgError] = useState9(false);
|
|
1799
|
+
const isReal = !!logoUrl && !isPlaceholderUrl(logoUrl);
|
|
1800
|
+
const showImage = isReal && !imgError;
|
|
1801
|
+
const tileBackground = `linear-gradient(to bottom right, ${accentColor}, color-mix(in srgb, ${accentColor} 60%, white))`;
|
|
1802
|
+
return /* @__PURE__ */ jsxs20(
|
|
1803
|
+
"div",
|
|
1804
|
+
{
|
|
1805
|
+
className: `relative ${SIZE_CLASSES[size]} flex items-center justify-center shadow-lg group-hover:shadow-xl transition-all duration-200 overflow-hidden${className ? " " + className : ""}`,
|
|
1806
|
+
style: { background: tileBackground },
|
|
1807
|
+
children: [
|
|
1808
|
+
/* @__PURE__ */ jsx25(
|
|
1809
|
+
"div",
|
|
1810
|
+
{
|
|
1811
|
+
className: "absolute inset-0 opacity-30 group-hover:opacity-50 transition-opacity duration-500 pointer-events-none",
|
|
1812
|
+
style: {
|
|
1813
|
+
backgroundImage: "radial-gradient(at 27% 37%, rgba(255,255,255,0.15) 0px, transparent 50%),radial-gradient(at 97% 21%, rgba(255,255,255,0.10) 0px, transparent 50%)"
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
),
|
|
1817
|
+
/* @__PURE__ */ jsx25("div", { className: "absolute inset-x-0 top-0 h-1/2 bg-linear-to-b from-white/25 to-transparent pointer-events-none" }),
|
|
1818
|
+
/* @__PURE__ */ jsx25("div", { className: "absolute top-0 right-0 w-1/2 h-1/2 bg-white/30 rounded-bl-full pointer-events-none" }),
|
|
1819
|
+
showImage ? /* @__PURE__ */ jsx25(
|
|
1820
|
+
"img",
|
|
1821
|
+
{
|
|
1822
|
+
src: logoUrl ?? void 0,
|
|
1823
|
+
alt: name,
|
|
1824
|
+
onError: () => setImgError(true),
|
|
1825
|
+
className: "absolute inset-0 w-full h-full object-cover z-10"
|
|
1826
|
+
}
|
|
1827
|
+
) : /* @__PURE__ */ jsx25("span", { className: `text-white font-bold relative z-10 tracking-tight drop-shadow-sm ${FALLBACK_TEXT_CLASSES[size]}`, children: getInitials(name) }),
|
|
1828
|
+
children
|
|
1829
|
+
]
|
|
1830
|
+
}
|
|
1831
|
+
);
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// src/components/media/MarketplaceProjectCard.tsx
|
|
1835
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1766
1836
|
var categoryLabels = {
|
|
1767
1837
|
game: "Game",
|
|
1768
1838
|
defi: "DeFi",
|
|
@@ -1794,15 +1864,14 @@ function MarketplaceProjectCard({
|
|
|
1794
1864
|
e.stopPropagation();
|
|
1795
1865
|
onInstallClick?.();
|
|
1796
1866
|
};
|
|
1797
|
-
const
|
|
1798
|
-
const card = /* @__PURE__ */ jsxs20(
|
|
1867
|
+
const card = /* @__PURE__ */ jsxs21(
|
|
1799
1868
|
motion.div,
|
|
1800
1869
|
{
|
|
1801
1870
|
whileHover: { y: -4 },
|
|
1802
1871
|
className: "no-text-shadow group rounded-2xl border border-neutral-200 dark:border-white/8 hover:border-orange-500/60 dark:hover:border-brand-orange/60 hover:shadow-lg hover:shadow-orange-500/10 dark:hover:shadow-brand-orange/15 transition-all duration-200 cursor-pointer relative overflow-hidden",
|
|
1803
1872
|
children: [
|
|
1804
|
-
/* @__PURE__ */
|
|
1805
|
-
/* @__PURE__ */
|
|
1873
|
+
/* @__PURE__ */ jsxs21("div", { className: "relative h-24 overflow-hidden", "data-testid": "banner", children: [
|
|
1874
|
+
/* @__PURE__ */ jsx26(
|
|
1806
1875
|
"div",
|
|
1807
1876
|
{
|
|
1808
1877
|
className: "absolute inset-0 bg-cover bg-center transition-transform duration-500 group-hover:scale-105",
|
|
@@ -1812,54 +1881,53 @@ function MarketplaceProjectCard({
|
|
|
1812
1881
|
}
|
|
1813
1882
|
}
|
|
1814
1883
|
),
|
|
1815
|
-
/* @__PURE__ */
|
|
1884
|
+
/* @__PURE__ */ jsx26("div", { className: "absolute inset-0", style: {
|
|
1816
1885
|
background: hasBanner ? `linear-gradient(to bottom, transparent 0%, ${accentColor}66 100%)` : `linear-gradient(135deg, ${accentColor}cc 0%, ${accentColor}44 100%)`
|
|
1817
1886
|
} }),
|
|
1818
|
-
showInstall && /* @__PURE__ */
|
|
1887
|
+
showInstall && /* @__PURE__ */ jsx26(
|
|
1819
1888
|
"button",
|
|
1820
1889
|
{
|
|
1821
1890
|
onClick: handleInstall,
|
|
1822
1891
|
title: installed ? "Remove from Desktop" : "Add to Desktop",
|
|
1823
1892
|
className: `absolute top-3 right-3 z-10 w-8 h-8 rounded-lg flex items-center justify-center backdrop-blur-sm transition-all ${installed ? "bg-green-500/30 text-white border border-green-400/40" : "bg-black/30 text-white/70 border border-white/15 hover:bg-orange-500/40 hover:text-white hover:border-orange-400/40"}`,
|
|
1824
|
-
children: installed ? /* @__PURE__ */
|
|
1893
|
+
children: installed ? /* @__PURE__ */ jsx26(Check, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx26(Plus, { className: "w-4 h-4" })
|
|
1825
1894
|
}
|
|
1826
1895
|
)
|
|
1827
1896
|
] }),
|
|
1828
|
-
/* @__PURE__ */
|
|
1829
|
-
/* @__PURE__ */
|
|
1830
|
-
/* @__PURE__ */
|
|
1831
|
-
|
|
1897
|
+
/* @__PURE__ */ jsxs21("div", { className: "p-4 bg-white dark:bg-white/4 dark:backdrop-blur-2xl", children: [
|
|
1898
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-start gap-3", children: [
|
|
1899
|
+
/* @__PURE__ */ jsx26("div", { className: "shrink-0 -mt-8 ring-2 ring-white dark:ring-[#0a0a0a] rounded-xl relative z-10", children: /* @__PURE__ */ jsx26(
|
|
1900
|
+
ProjectLogo,
|
|
1832
1901
|
{
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
}
|
|
1902
|
+
name,
|
|
1903
|
+
logoUrl,
|
|
1904
|
+
accentColor,
|
|
1905
|
+
size: "md",
|
|
1906
|
+
className: "border border-neutral-200 dark:border-white/10"
|
|
1839
1907
|
}
|
|
1840
|
-
),
|
|
1841
|
-
/* @__PURE__ */
|
|
1842
|
-
/* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
1908
|
+
) }),
|
|
1909
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
|
|
1910
|
+
/* @__PURE__ */ jsx26("h3", { className: "font-semibold text-neutral-900 dark:text-white text-sm truncate", children: name }),
|
|
1911
|
+
/* @__PURE__ */ jsx26("p", { className: "text-neutral-500 dark:text-white/45 text-xs mt-0.5 h-8 line-clamp-2", children: tagline })
|
|
1844
1912
|
] })
|
|
1845
1913
|
] }),
|
|
1846
|
-
/* @__PURE__ */
|
|
1847
|
-
category ? /* @__PURE__ */
|
|
1914
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-neutral-100 dark:border-white/5", children: [
|
|
1915
|
+
category ? /* @__PURE__ */ jsx26("span", { className: "inline-flex px-2 py-0.5 rounded-md text-[10px] font-semibold uppercase tracking-wider border", style: {
|
|
1848
1916
|
backgroundColor: `${accentColor}15`,
|
|
1849
1917
|
color: accentColor,
|
|
1850
1918
|
borderColor: `${accentColor}30`
|
|
1851
|
-
}, children: categoryLabels[category] ?? category }) : /* @__PURE__ */
|
|
1852
|
-
/* @__PURE__ */
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1919
|
+
}, children: categoryLabels[category] ?? category }) : /* @__PURE__ */ jsx26("span", {}),
|
|
1920
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3 text-[11px] text-neutral-400 dark:text-white/35", children: [
|
|
1921
|
+
/* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1", title: "Users", children: [
|
|
1922
|
+
/* @__PURE__ */ jsx26(Users, { className: "w-3 h-3" }),
|
|
1855
1923
|
users.toLocaleString()
|
|
1856
1924
|
] }),
|
|
1857
|
-
/* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
1925
|
+
/* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1", title: "Active quests", children: [
|
|
1926
|
+
/* @__PURE__ */ jsx26(Target, { className: "w-3 h-3" }),
|
|
1859
1927
|
quests.toLocaleString()
|
|
1860
1928
|
] }),
|
|
1861
|
-
ratingCount > 0 && /* @__PURE__ */
|
|
1862
|
-
/* @__PURE__ */
|
|
1929
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1", title: `${ratingCount} reviews`, children: [
|
|
1930
|
+
/* @__PURE__ */ jsx26(ThumbsUp, { className: "w-3 h-3" }),
|
|
1863
1931
|
positivePercent,
|
|
1864
1932
|
"%"
|
|
1865
1933
|
] })
|
|
@@ -1870,7 +1938,7 @@ function MarketplaceProjectCard({
|
|
|
1870
1938
|
}
|
|
1871
1939
|
);
|
|
1872
1940
|
if (onClick) {
|
|
1873
|
-
return /* @__PURE__ */
|
|
1941
|
+
return /* @__PURE__ */ jsx26("button", { type: "button", onClick, className: "block w-full text-left", children: card });
|
|
1874
1942
|
}
|
|
1875
1943
|
return card;
|
|
1876
1944
|
}
|
|
@@ -1878,7 +1946,7 @@ function MarketplaceProjectCard({
|
|
|
1878
1946
|
// src/components/media/FeaturedProjectCard.tsx
|
|
1879
1947
|
import { motion as motion2 } from "framer-motion";
|
|
1880
1948
|
import { Star, Users as Users2, Target as Target2, ThumbsUp as ThumbsUp2 } from "lucide-react";
|
|
1881
|
-
import { jsx as
|
|
1949
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1882
1950
|
function FeaturedProjectCard({
|
|
1883
1951
|
name,
|
|
1884
1952
|
tagline,
|
|
@@ -1891,15 +1959,14 @@ function FeaturedProjectCard({
|
|
|
1891
1959
|
ratingCount = 0,
|
|
1892
1960
|
onClick
|
|
1893
1961
|
}) {
|
|
1894
|
-
const
|
|
1895
|
-
const card = /* @__PURE__ */ jsxs21(
|
|
1962
|
+
const card = /* @__PURE__ */ jsxs22(
|
|
1896
1963
|
motion2.div,
|
|
1897
1964
|
{
|
|
1898
1965
|
whileHover: { scale: 1.02, y: -2 },
|
|
1899
1966
|
whileTap: { scale: 0.98 },
|
|
1900
1967
|
className: "relative w-72 sm:w-80 h-44 rounded-2xl overflow-hidden shrink-0 cursor-pointer group",
|
|
1901
1968
|
children: [
|
|
1902
|
-
/* @__PURE__ */
|
|
1969
|
+
/* @__PURE__ */ jsx27(
|
|
1903
1970
|
"div",
|
|
1904
1971
|
{
|
|
1905
1972
|
className: "absolute inset-0 bg-cover bg-center transition-transform duration-500 group-hover:scale-105",
|
|
@@ -1910,43 +1977,42 @@ function FeaturedProjectCard({
|
|
|
1910
1977
|
}
|
|
1911
1978
|
}
|
|
1912
1979
|
),
|
|
1913
|
-
/* @__PURE__ */
|
|
1980
|
+
/* @__PURE__ */ jsx27("div", { className: "absolute inset-0", style: {
|
|
1914
1981
|
background: bannerUrl ? `linear-gradient(135deg, ${accentColor}66 0%, transparent 60%)` : `linear-gradient(135deg, ${accentColor}cc 0%, ${accentColor}44 100%)`
|
|
1915
1982
|
} }),
|
|
1916
|
-
/* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1983
|
+
/* @__PURE__ */ jsx27("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent" }),
|
|
1984
|
+
/* @__PURE__ */ jsxs22("div", { className: "absolute top-3 right-3 flex items-center gap-1 px-2 py-1 rounded-full bg-amber-500/90 text-white text-[10px] font-bold uppercase tracking-wider", children: [
|
|
1985
|
+
/* @__PURE__ */ jsx27(Star, { className: "w-3 h-3", fill: "currentColor" }),
|
|
1919
1986
|
"Featured"
|
|
1920
1987
|
] }),
|
|
1921
|
-
/* @__PURE__ */
|
|
1922
|
-
/* @__PURE__ */
|
|
1923
|
-
/* @__PURE__ */
|
|
1924
|
-
|
|
1988
|
+
/* @__PURE__ */ jsxs22("div", { className: "absolute bottom-0 left-0 right-0 p-4", children: [
|
|
1989
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
|
|
1990
|
+
/* @__PURE__ */ jsx27(
|
|
1991
|
+
ProjectLogo,
|
|
1925
1992
|
{
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
}
|
|
1993
|
+
name,
|
|
1994
|
+
logoUrl,
|
|
1995
|
+
accentColor,
|
|
1996
|
+
size: "sm",
|
|
1997
|
+
className: "border-2 border-white/20"
|
|
1932
1998
|
}
|
|
1933
1999
|
),
|
|
1934
|
-
/* @__PURE__ */
|
|
1935
|
-
/* @__PURE__ */
|
|
1936
|
-
/* @__PURE__ */
|
|
2000
|
+
/* @__PURE__ */ jsxs22("div", { className: "min-w-0", children: [
|
|
2001
|
+
/* @__PURE__ */ jsx27("h3", { className: "font-semibold text-white text-sm truncate", children: name }),
|
|
2002
|
+
/* @__PURE__ */ jsx27("p", { className: "text-white/70 text-xs truncate", children: tagline })
|
|
1937
2003
|
] })
|
|
1938
2004
|
] }),
|
|
1939
|
-
/* @__PURE__ */
|
|
1940
|
-
/* @__PURE__ */
|
|
1941
|
-
/* @__PURE__ */
|
|
2005
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3 mt-2 text-[11px] text-white/60", children: [
|
|
2006
|
+
/* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1", title: "Users", children: [
|
|
2007
|
+
/* @__PURE__ */ jsx27(Users2, { className: "w-3 h-3" }),
|
|
1942
2008
|
users.toLocaleString()
|
|
1943
2009
|
] }),
|
|
1944
|
-
/* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
2010
|
+
/* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1", title: "Active quests", children: [
|
|
2011
|
+
/* @__PURE__ */ jsx27(Target2, { className: "w-3 h-3" }),
|
|
1946
2012
|
quests.toLocaleString()
|
|
1947
2013
|
] }),
|
|
1948
|
-
ratingCount > 0 && /* @__PURE__ */
|
|
1949
|
-
/* @__PURE__ */
|
|
2014
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1", title: `${ratingCount} reviews`, children: [
|
|
2015
|
+
/* @__PURE__ */ jsx27(ThumbsUp2, { className: "w-3 h-3" }),
|
|
1950
2016
|
positivePercent,
|
|
1951
2017
|
"%"
|
|
1952
2018
|
] })
|
|
@@ -1956,15 +2022,14 @@ function FeaturedProjectCard({
|
|
|
1956
2022
|
}
|
|
1957
2023
|
);
|
|
1958
2024
|
if (onClick) {
|
|
1959
|
-
return /* @__PURE__ */
|
|
2025
|
+
return /* @__PURE__ */ jsx27("button", { type: "button", onClick, className: "block text-left", draggable: false, children: card });
|
|
1960
2026
|
}
|
|
1961
2027
|
return card;
|
|
1962
2028
|
}
|
|
1963
2029
|
|
|
1964
2030
|
// src/components/media/InstalledProjectIcon.tsx
|
|
1965
|
-
import { useState as useState9 } from "react";
|
|
1966
2031
|
import { motion as motion3 } from "framer-motion";
|
|
1967
|
-
import { jsx as
|
|
2032
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1968
2033
|
function InstalledProjectIcon({
|
|
1969
2034
|
name,
|
|
1970
2035
|
logoUrl,
|
|
@@ -1976,8 +2041,7 @@ function InstalledProjectIcon({
|
|
|
1976
2041
|
buttonRef,
|
|
1977
2042
|
buttonProps
|
|
1978
2043
|
}) {
|
|
1979
|
-
|
|
1980
|
-
return /* @__PURE__ */ jsx27("div", { className: "relative", children: /* @__PURE__ */ jsxs22(
|
|
2044
|
+
return /* @__PURE__ */ jsx28("div", { className: "relative", children: /* @__PURE__ */ jsxs23(
|
|
1981
2045
|
motion3.button,
|
|
1982
2046
|
{
|
|
1983
2047
|
ref: buttonRef,
|
|
@@ -1991,46 +2055,27 @@ function InstalledProjectIcon({
|
|
|
1991
2055
|
className: `flex flex-col items-center gap-2 p-3 rounded-2xl group cursor-pointer relative${buttonProps?.className ? " " + buttonProps.className : ""}`,
|
|
1992
2056
|
style: { touchAction: "none", ...buttonProps?.style },
|
|
1993
2057
|
children: [
|
|
1994
|
-
/* @__PURE__ */
|
|
1995
|
-
/* @__PURE__ */
|
|
2058
|
+
/* @__PURE__ */ jsxs23("div", { className: "relative", children: [
|
|
2059
|
+
/* @__PURE__ */ jsx28(
|
|
1996
2060
|
"div",
|
|
1997
2061
|
{
|
|
1998
|
-
className: "absolute -inset-1 blur-xl opacity-0 group-hover:opacity-50 transition-all duration-300 rounded-2xl",
|
|
2062
|
+
className: "absolute -inset-1 blur-xl opacity-0 group-hover:opacity-50 transition-all duration-300 rounded-2xl pointer-events-none",
|
|
1999
2063
|
style: { backgroundColor: accentColor }
|
|
2000
2064
|
}
|
|
2001
2065
|
),
|
|
2002
|
-
/* @__PURE__ */
|
|
2003
|
-
|
|
2066
|
+
/* @__PURE__ */ jsx28(
|
|
2067
|
+
ProjectLogo,
|
|
2004
2068
|
{
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
className: "absolute inset-0 opacity-30 group-hover:opacity-50 transition-opacity duration-500",
|
|
2012
|
-
style: {
|
|
2013
|
-
backgroundImage: `radial-gradient(at 27% 37%, rgba(255,255,255,0.15) 0px, transparent 50%),
|
|
2014
|
-
radial-gradient(at 97% 21%, rgba(255,255,255,0.1) 0px, transparent 50%)`
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
),
|
|
2018
|
-
/* @__PURE__ */ jsx27("div", { className: "absolute top-0 right-0 w-8 h-8 bg-white/10 rounded-bl-full group-hover:w-10 group-hover:h-10 transition-all duration-300" }),
|
|
2019
|
-
logoUrl && !imgError ? /* @__PURE__ */ jsx27(
|
|
2020
|
-
"img",
|
|
2021
|
-
{
|
|
2022
|
-
src: logoUrl,
|
|
2023
|
-
alt: name,
|
|
2024
|
-
onError: () => setImgError(true),
|
|
2025
|
-
className: "absolute inset-0 w-full h-full object-cover z-10"
|
|
2026
|
-
}
|
|
2027
|
-
) : /* @__PURE__ */ jsx27("span", { className: "text-white font-bold text-2xl sm:text-3xl relative z-10", children: name[0] ?? "?" })
|
|
2028
|
-
]
|
|
2069
|
+
name,
|
|
2070
|
+
logoUrl,
|
|
2071
|
+
accentColor,
|
|
2072
|
+
size: "lg",
|
|
2073
|
+
className: "group-hover:shadow-xl transition-all duration-200",
|
|
2074
|
+
children: topRightAction
|
|
2029
2075
|
}
|
|
2030
|
-
)
|
|
2031
|
-
topRightAction
|
|
2076
|
+
)
|
|
2032
2077
|
] }),
|
|
2033
|
-
showLabel && /* @__PURE__ */
|
|
2078
|
+
showLabel && /* @__PURE__ */ jsx28("span", { className: "text-xs sm:text-sm font-medium text-neutral-500 dark:text-[rgba(255,255,255,0.45)] group-hover:text-neutral-900 dark:group-hover:text-white transition-colors truncate max-w-20 sm:max-w-24 text-center leading-tight", children: name })
|
|
2034
2079
|
]
|
|
2035
2080
|
}
|
|
2036
2081
|
) });
|
|
@@ -2052,7 +2097,7 @@ import {
|
|
|
2052
2097
|
Twitter,
|
|
2053
2098
|
Zap
|
|
2054
2099
|
} from "lucide-react";
|
|
2055
|
-
import { jsx as
|
|
2100
|
+
import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2056
2101
|
var categoryLabels2 = {
|
|
2057
2102
|
game: "Game",
|
|
2058
2103
|
defi: "DeFi",
|
|
@@ -2091,17 +2136,16 @@ function ProjectPagePreview({
|
|
|
2091
2136
|
achievements = [],
|
|
2092
2137
|
tags = []
|
|
2093
2138
|
}) {
|
|
2094
|
-
|
|
2095
|
-
return /* @__PURE__ */ jsxs23(
|
|
2139
|
+
return /* @__PURE__ */ jsxs24(
|
|
2096
2140
|
motion4.div,
|
|
2097
2141
|
{
|
|
2098
2142
|
initial: { opacity: 0 },
|
|
2099
2143
|
animate: { opacity: 1 },
|
|
2100
2144
|
className: "text-neutral-900 dark:text-white pb-12",
|
|
2101
2145
|
children: [
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2104
|
-
/* @__PURE__ */
|
|
2146
|
+
/* @__PURE__ */ jsxs24("div", { className: "relative mx-4 sm:mx-6 mt-2", children: [
|
|
2147
|
+
/* @__PURE__ */ jsxs24("div", { className: "relative h-48 sm:h-64 rounded-2xl overflow-hidden", children: [
|
|
2148
|
+
/* @__PURE__ */ jsx29(
|
|
2105
2149
|
"div",
|
|
2106
2150
|
{
|
|
2107
2151
|
className: "absolute inset-0 bg-cover bg-center",
|
|
@@ -2112,31 +2156,29 @@ function ProjectPagePreview({
|
|
|
2112
2156
|
}
|
|
2113
2157
|
}
|
|
2114
2158
|
),
|
|
2115
|
-
/* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2117
|
-
/* @__PURE__ */
|
|
2159
|
+
/* @__PURE__ */ jsx29("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent" }),
|
|
2160
|
+
/* @__PURE__ */ jsxs24("div", { className: "absolute top-4 left-4 flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-black/40 backdrop-blur-sm text-white/80 text-sm", children: [
|
|
2161
|
+
/* @__PURE__ */ jsx29(ArrowLeft, { className: "w-4 h-4" }),
|
|
2118
2162
|
"Explore"
|
|
2119
2163
|
] })
|
|
2120
2164
|
] }),
|
|
2121
|
-
/* @__PURE__ */
|
|
2122
|
-
|
|
2165
|
+
/* @__PURE__ */ jsx29("div", { className: "absolute -bottom-6 left-6 sm:left-8 z-10 rounded-2xl border-4 border-white dark:border-[#060606] shadow-xl overflow-hidden", children: /* @__PURE__ */ jsx29(
|
|
2166
|
+
ProjectLogo,
|
|
2123
2167
|
{
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
e.target.src = placeholderLogo;
|
|
2129
|
-
}
|
|
2168
|
+
name,
|
|
2169
|
+
logoUrl,
|
|
2170
|
+
accentColor,
|
|
2171
|
+
size: "lg"
|
|
2130
2172
|
}
|
|
2131
2173
|
) })
|
|
2132
2174
|
] }),
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
/* @__PURE__ */
|
|
2137
|
-
tagline && /* @__PURE__ */
|
|
2138
|
-
(category || tags.length > 0) && /* @__PURE__ */
|
|
2139
|
-
category && /* @__PURE__ */
|
|
2175
|
+
/* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pt-10 pb-6", children: /* @__PURE__ */ jsxs24("div", { className: "no-text-shadow max-w-5xl mx-auto bg-neutral-50 dark:bg-white/4 dark:backdrop-blur-2xl rounded-2xl border border-neutral-200 dark:border-white/8 p-6 sm:p-8", children: [
|
|
2176
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4", children: [
|
|
2177
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
2178
|
+
/* @__PURE__ */ jsx29("h1", { className: "text-2xl sm:text-3xl font-bold", children: name }),
|
|
2179
|
+
tagline && /* @__PURE__ */ jsx29("p", { className: "text-neutral-500 dark:text-white/55 mt-1", children: tagline }),
|
|
2180
|
+
(category || tags.length > 0) && /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 mt-3", children: [
|
|
2181
|
+
category && /* @__PURE__ */ jsx29(
|
|
2140
2182
|
"span",
|
|
2141
2183
|
{
|
|
2142
2184
|
className: "inline-flex px-2.5 py-0.5 rounded-lg text-xs font-semibold uppercase tracking-wider",
|
|
@@ -2148,7 +2190,7 @@ function ProjectPagePreview({
|
|
|
2148
2190
|
children: categoryLabels2[category] ?? category
|
|
2149
2191
|
}
|
|
2150
2192
|
),
|
|
2151
|
-
tags.slice(0, 3).map((tag) => /* @__PURE__ */
|
|
2193
|
+
tags.slice(0, 3).map((tag) => /* @__PURE__ */ jsx29(
|
|
2152
2194
|
"span",
|
|
2153
2195
|
{
|
|
2154
2196
|
className: "px-2 py-0.5 rounded-md bg-neutral-100 dark:bg-white/6 text-neutral-500 dark:text-white/40 text-[10px] font-mono",
|
|
@@ -2158,30 +2200,30 @@ function ProjectPagePreview({
|
|
|
2158
2200
|
))
|
|
2159
2201
|
] })
|
|
2160
2202
|
] }),
|
|
2161
|
-
/* @__PURE__ */
|
|
2162
|
-
/* @__PURE__ */
|
|
2203
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2 shrink-0 flex-wrap", children: [
|
|
2204
|
+
/* @__PURE__ */ jsxs24(
|
|
2163
2205
|
"button",
|
|
2164
2206
|
{
|
|
2165
2207
|
type: "button",
|
|
2166
2208
|
className: "inline-flex items-center gap-2 px-5 py-2.5 rounded-xl font-semibold text-sm transition-all cursor-pointer bg-orange-500 dark:bg-brand-orange hover:bg-orange-600 dark:hover:bg-brand-orange-dark text-white shadow-lg shadow-orange-500/20",
|
|
2167
2209
|
children: [
|
|
2168
|
-
/* @__PURE__ */
|
|
2210
|
+
/* @__PURE__ */ jsx29(Plus2, { className: "w-4 h-4" }),
|
|
2169
2211
|
" Add to Desktop"
|
|
2170
2212
|
]
|
|
2171
2213
|
}
|
|
2172
2214
|
),
|
|
2173
|
-
/* @__PURE__ */
|
|
2215
|
+
/* @__PURE__ */ jsxs24(
|
|
2174
2216
|
"button",
|
|
2175
2217
|
{
|
|
2176
2218
|
type: "button",
|
|
2177
2219
|
className: "inline-flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium border border-neutral-200 dark:border-white/8 text-neutral-600 dark:text-white/55 hover:text-neutral-900 dark:hover:text-white hover:border-neutral-300 dark:hover:border-white/15 transition-colors cursor-pointer",
|
|
2178
2220
|
children: [
|
|
2179
2221
|
"Open ",
|
|
2180
|
-
/* @__PURE__ */
|
|
2222
|
+
/* @__PURE__ */ jsx29(ExternalLink, { className: "w-3.5 h-3.5" })
|
|
2181
2223
|
]
|
|
2182
2224
|
}
|
|
2183
2225
|
),
|
|
2184
|
-
websiteUrl && /* @__PURE__ */
|
|
2226
|
+
websiteUrl && /* @__PURE__ */ jsxs24(
|
|
2185
2227
|
"a",
|
|
2186
2228
|
{
|
|
2187
2229
|
href: websiteUrl,
|
|
@@ -2190,36 +2232,36 @@ function ProjectPagePreview({
|
|
|
2190
2232
|
className: "inline-flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium border border-neutral-200 dark:border-white/8 text-neutral-600 dark:text-white/55 hover:text-neutral-900 dark:hover:text-white hover:border-neutral-300 dark:hover:border-white/15 transition-colors",
|
|
2191
2233
|
children: [
|
|
2192
2234
|
"Website ",
|
|
2193
|
-
/* @__PURE__ */
|
|
2235
|
+
/* @__PURE__ */ jsx29(Globe, { className: "w-3.5 h-3.5" })
|
|
2194
2236
|
]
|
|
2195
2237
|
}
|
|
2196
2238
|
)
|
|
2197
2239
|
] })
|
|
2198
2240
|
] }),
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
/* @__PURE__ */
|
|
2202
|
-
/* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2241
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-6 sm:gap-10 border-t border-neutral-200 dark:border-white/8 mt-6 pt-5", children: [
|
|
2242
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-center sm:text-left", children: [
|
|
2243
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 justify-center sm:justify-start", children: [
|
|
2244
|
+
/* @__PURE__ */ jsx29(Users3, { className: "w-4 h-4 text-neutral-400 dark:text-white/30" }),
|
|
2245
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xl sm:text-2xl font-bold font-mono", children: users.toLocaleString() })
|
|
2204
2246
|
] }),
|
|
2205
|
-
/* @__PURE__ */
|
|
2247
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs text-neutral-400 dark:text-white/35 uppercase tracking-wider", children: "Users" })
|
|
2206
2248
|
] }),
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
/* @__PURE__ */
|
|
2209
|
-
/* @__PURE__ */
|
|
2210
|
-
/* @__PURE__ */
|
|
2249
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-center sm:text-left", children: [
|
|
2250
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 justify-center sm:justify-start", children: [
|
|
2251
|
+
/* @__PURE__ */ jsx29(Target3, { className: "w-4 h-4 text-neutral-400 dark:text-white/30" }),
|
|
2252
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xl sm:text-2xl font-bold font-mono", children: activeQuests.toLocaleString() })
|
|
2211
2253
|
] }),
|
|
2212
|
-
/* @__PURE__ */
|
|
2254
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs text-neutral-400 dark:text-white/35 uppercase tracking-wider", children: "Active Quests" })
|
|
2213
2255
|
] }),
|
|
2214
|
-
ratingCount > 0 && /* @__PURE__ */
|
|
2215
|
-
/* @__PURE__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2217
|
-
/* @__PURE__ */
|
|
2256
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs24("div", { className: "text-center sm:text-left", children: [
|
|
2257
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 justify-center sm:justify-start", children: [
|
|
2258
|
+
/* @__PURE__ */ jsx29(ThumbsUp3, { className: "w-4 h-4 text-neutral-400 dark:text-white/30" }),
|
|
2259
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-xl sm:text-2xl font-bold font-mono", children: [
|
|
2218
2260
|
positivePercent,
|
|
2219
2261
|
"%"
|
|
2220
2262
|
] })
|
|
2221
2263
|
] }),
|
|
2222
|
-
/* @__PURE__ */
|
|
2264
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-xs text-neutral-400 dark:text-white/35 uppercase tracking-wider", children: [
|
|
2223
2265
|
ratingCount.toLocaleString(),
|
|
2224
2266
|
" ",
|
|
2225
2267
|
ratingCount === 1 ? "review" : "reviews"
|
|
@@ -2227,16 +2269,16 @@ function ProjectPagePreview({
|
|
|
2227
2269
|
] })
|
|
2228
2270
|
] })
|
|
2229
2271
|
] }) }),
|
|
2230
|
-
media.length > 0 && /* @__PURE__ */
|
|
2231
|
-
/* @__PURE__ */
|
|
2232
|
-
/* @__PURE__ */
|
|
2272
|
+
media.length > 0 && /* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2273
|
+
/* @__PURE__ */ jsx29("h2", { className: "text-lg font-semibold mb-4", children: "Media" }),
|
|
2274
|
+
/* @__PURE__ */ jsx29("div", { className: "flex gap-3 overflow-x-auto scrollbar-hide pb-2", children: media.map((item, i) => {
|
|
2233
2275
|
const isVideo = item.type === "video";
|
|
2234
|
-
return /* @__PURE__ */
|
|
2276
|
+
return /* @__PURE__ */ jsxs24(
|
|
2235
2277
|
"div",
|
|
2236
2278
|
{
|
|
2237
2279
|
className: "shrink-0 rounded-xl overflow-hidden border border-neutral-200 dark:border-white/8 relative",
|
|
2238
2280
|
children: [
|
|
2239
|
-
/* @__PURE__ */
|
|
2281
|
+
/* @__PURE__ */ jsx29(
|
|
2240
2282
|
"img",
|
|
2241
2283
|
{
|
|
2242
2284
|
src: getMediaThumb(item),
|
|
@@ -2245,40 +2287,40 @@ function ProjectPagePreview({
|
|
|
2245
2287
|
className: "h-44 sm:h-52 w-72 sm:w-80 object-cover"
|
|
2246
2288
|
}
|
|
2247
2289
|
),
|
|
2248
|
-
isVideo && /* @__PURE__ */
|
|
2290
|
+
isVideo && /* @__PURE__ */ jsx29("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsx29("div", { className: "w-14 h-14 rounded-full bg-black/60 backdrop-blur-sm flex items-center justify-center", children: /* @__PURE__ */ jsx29("svg", { className: "w-6 h-6 text-white ml-1", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx29("path", { d: "M8 5v14l11-7z" }) }) }) })
|
|
2249
2291
|
]
|
|
2250
2292
|
},
|
|
2251
2293
|
i
|
|
2252
2294
|
);
|
|
2253
2295
|
}) })
|
|
2254
2296
|
] }) }),
|
|
2255
|
-
description && /* @__PURE__ */
|
|
2256
|
-
/* @__PURE__ */
|
|
2257
|
-
/* @__PURE__ */
|
|
2297
|
+
description && /* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2298
|
+
/* @__PURE__ */ jsx29("h2", { className: "text-lg font-semibold mb-4", children: "About" }),
|
|
2299
|
+
/* @__PURE__ */ jsx29("div", { className: "no-text-shadow bg-neutral-50 dark:bg-white/4 dark:backdrop-blur-2xl rounded-2xl border border-neutral-200 dark:border-white/8 p-6", children: /* @__PURE__ */ jsx29("p", { className: "text-neutral-600 dark:text-white/55 text-sm leading-relaxed whitespace-pre-line", children: description }) })
|
|
2258
2300
|
] }) }),
|
|
2259
|
-
quests.length > 0 && /* @__PURE__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2301
|
+
quests.length > 0 && /* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2302
|
+
/* @__PURE__ */ jsxs24("h2", { className: "text-lg font-semibold mb-4", children: [
|
|
2261
2303
|
"Quests ",
|
|
2262
|
-
/* @__PURE__ */
|
|
2304
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-neutral-400 dark:text-white/35 font-normal", children: [
|
|
2263
2305
|
"(",
|
|
2264
2306
|
quests.length,
|
|
2265
2307
|
")"
|
|
2266
2308
|
] })
|
|
2267
2309
|
] }),
|
|
2268
|
-
/* @__PURE__ */
|
|
2310
|
+
/* @__PURE__ */ jsx29("div", { className: "grid sm:grid-cols-2 gap-3", children: quests.map((quest) => /* @__PURE__ */ jsxs24(
|
|
2269
2311
|
"div",
|
|
2270
2312
|
{
|
|
2271
2313
|
className: "no-text-shadow bg-white dark:bg-white/4 dark:backdrop-blur-2xl rounded-xl border border-neutral-200 dark:border-white/8 p-4 relative overflow-hidden",
|
|
2272
2314
|
children: [
|
|
2273
|
-
/* @__PURE__ */
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
/* @__PURE__ */
|
|
2277
|
-
quest.description && /* @__PURE__ */
|
|
2278
|
-
quest.difficulty && /* @__PURE__ */
|
|
2315
|
+
/* @__PURE__ */ jsx29("div", { className: "absolute left-0 top-0 bottom-0 w-0.5", style: { backgroundColor: accentColor } }),
|
|
2316
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-start gap-3", children: [
|
|
2317
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0 flex-1", children: [
|
|
2318
|
+
/* @__PURE__ */ jsx29("h4", { className: "font-medium text-sm text-neutral-900 dark:text-white", children: quest.title }),
|
|
2319
|
+
quest.description && /* @__PURE__ */ jsx29("p", { className: "text-xs text-neutral-500 dark:text-white/40 mt-0.5 line-clamp-2", children: quest.description }),
|
|
2320
|
+
quest.difficulty && /* @__PURE__ */ jsx29("span", { className: `inline-flex mt-2 px-2 py-0.5 rounded-md text-[10px] font-semibold uppercase tracking-wider border ${difficultyStyles[quest.difficulty]}`, children: quest.difficulty })
|
|
2279
2321
|
] }),
|
|
2280
|
-
typeof quest.points === "number" && /* @__PURE__ */
|
|
2281
|
-
/* @__PURE__ */
|
|
2322
|
+
typeof quest.points === "number" && /* @__PURE__ */ jsxs24("div", { className: "shrink-0 flex items-center gap-1 px-2 py-1 rounded-lg bg-orange-500/10 dark:bg-brand-orange-dim text-orange-600 dark:text-brand-orange text-xs font-semibold", children: [
|
|
2323
|
+
/* @__PURE__ */ jsx29(Zap, { className: "w-3 h-3" }),
|
|
2282
2324
|
quest.points
|
|
2283
2325
|
] })
|
|
2284
2326
|
] })
|
|
@@ -2287,27 +2329,27 @@ function ProjectPagePreview({
|
|
|
2287
2329
|
quest.slug
|
|
2288
2330
|
)) })
|
|
2289
2331
|
] }) }),
|
|
2290
|
-
achievements.length > 0 && /* @__PURE__ */
|
|
2291
|
-
/* @__PURE__ */
|
|
2332
|
+
achievements.length > 0 && /* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2333
|
+
/* @__PURE__ */ jsxs24("h2", { className: "text-lg font-semibold mb-4", children: [
|
|
2292
2334
|
"Achievements ",
|
|
2293
|
-
/* @__PURE__ */
|
|
2335
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-neutral-400 dark:text-white/35 font-normal", children: [
|
|
2294
2336
|
"(",
|
|
2295
2337
|
achievements.length,
|
|
2296
2338
|
")"
|
|
2297
2339
|
] })
|
|
2298
2340
|
] }),
|
|
2299
|
-
/* @__PURE__ */
|
|
2341
|
+
/* @__PURE__ */ jsx29("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3", children: achievements.map((ach) => /* @__PURE__ */ jsxs24(
|
|
2300
2342
|
"div",
|
|
2301
2343
|
{
|
|
2302
2344
|
className: "no-text-shadow bg-white dark:bg-white/4 dark:backdrop-blur-2xl rounded-xl border border-neutral-200 dark:border-white/8 p-4 flex flex-col items-center text-center",
|
|
2303
2345
|
children: [
|
|
2304
|
-
/* @__PURE__ */
|
|
2346
|
+
/* @__PURE__ */ jsx29("div", { className: "w-16 h-16 rounded-xl overflow-hidden flex items-center justify-center mb-3", style: {
|
|
2305
2347
|
backgroundColor: `${accentColor}15`,
|
|
2306
2348
|
border: `1px solid ${accentColor}30`
|
|
2307
|
-
}, children: ach.imageUrl ? /* @__PURE__ */
|
|
2308
|
-
/* @__PURE__ */
|
|
2309
|
-
typeof ach.points === "number" && /* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2349
|
+
}, children: ach.imageUrl ? /* @__PURE__ */ jsx29("img", { src: ach.imageUrl, alt: ach.title, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsx29(Trophy, { className: "w-8 h-8", style: { color: accentColor } }) }),
|
|
2350
|
+
/* @__PURE__ */ jsx29("h4", { className: "text-sm font-medium text-neutral-900 dark:text-white line-clamp-2", children: ach.title }),
|
|
2351
|
+
typeof ach.points === "number" && /* @__PURE__ */ jsxs24("div", { className: "mt-2 flex items-center gap-1 text-xs font-semibold text-orange-600 dark:text-brand-orange", children: [
|
|
2352
|
+
/* @__PURE__ */ jsx29(Zap, { className: "w-3 h-3" }),
|
|
2311
2353
|
ach.points
|
|
2312
2354
|
] })
|
|
2313
2355
|
]
|
|
@@ -2315,15 +2357,15 @@ function ProjectPagePreview({
|
|
|
2315
2357
|
ach.slug
|
|
2316
2358
|
)) })
|
|
2317
2359
|
] }) }),
|
|
2318
|
-
/* @__PURE__ */
|
|
2319
|
-
/* @__PURE__ */
|
|
2320
|
-
/* @__PURE__ */
|
|
2321
|
-
/* @__PURE__ */
|
|
2322
|
-
/* @__PURE__ */
|
|
2360
|
+
/* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2361
|
+
/* @__PURE__ */ jsx29("h2", { className: "text-lg font-semibold mb-4", children: "Reviews" }),
|
|
2362
|
+
/* @__PURE__ */ jsxs24("div", { className: "no-text-shadow bg-neutral-50 dark:bg-white/4 dark:backdrop-blur-2xl rounded-2xl border border-neutral-200 dark:border-white/8 p-6 flex flex-col items-center text-center", children: [
|
|
2363
|
+
/* @__PURE__ */ jsx29(Star2, { className: "w-8 h-8 text-neutral-300 dark:text-white/20 mb-2" }),
|
|
2364
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-neutral-500 dark:text-white/40", children: "Reviews coming soon" })
|
|
2323
2365
|
] })
|
|
2324
2366
|
] }) }),
|
|
2325
|
-
(websiteUrl || discordUrl || twitterUrl) && /* @__PURE__ */
|
|
2326
|
-
websiteUrl && /* @__PURE__ */
|
|
2367
|
+
(websiteUrl || discordUrl || twitterUrl) && /* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto flex items-center gap-4", children: [
|
|
2368
|
+
websiteUrl && /* @__PURE__ */ jsx29(
|
|
2327
2369
|
"a",
|
|
2328
2370
|
{
|
|
2329
2371
|
href: websiteUrl,
|
|
@@ -2331,10 +2373,10 @@ function ProjectPagePreview({
|
|
|
2331
2373
|
rel: "noopener noreferrer",
|
|
2332
2374
|
"aria-label": "Website",
|
|
2333
2375
|
className: "text-neutral-400 dark:text-white/35 hover:text-orange-500 dark:hover:text-brand-orange transition-colors",
|
|
2334
|
-
children: /* @__PURE__ */
|
|
2376
|
+
children: /* @__PURE__ */ jsx29(Globe, { className: "w-5 h-5" })
|
|
2335
2377
|
}
|
|
2336
2378
|
),
|
|
2337
|
-
twitterUrl && /* @__PURE__ */
|
|
2379
|
+
twitterUrl && /* @__PURE__ */ jsx29(
|
|
2338
2380
|
"a",
|
|
2339
2381
|
{
|
|
2340
2382
|
href: twitterUrl,
|
|
@@ -2342,10 +2384,10 @@ function ProjectPagePreview({
|
|
|
2342
2384
|
rel: "noopener noreferrer",
|
|
2343
2385
|
"aria-label": "Twitter / X",
|
|
2344
2386
|
className: "text-neutral-400 dark:text-white/35 hover:text-orange-500 dark:hover:text-brand-orange transition-colors",
|
|
2345
|
-
children: /* @__PURE__ */
|
|
2387
|
+
children: /* @__PURE__ */ jsx29(Twitter, { className: "w-5 h-5" })
|
|
2346
2388
|
}
|
|
2347
2389
|
),
|
|
2348
|
-
discordUrl && /* @__PURE__ */
|
|
2390
|
+
discordUrl && /* @__PURE__ */ jsx29(
|
|
2349
2391
|
"a",
|
|
2350
2392
|
{
|
|
2351
2393
|
href: discordUrl,
|
|
@@ -2353,7 +2395,7 @@ function ProjectPagePreview({
|
|
|
2353
2395
|
rel: "noopener noreferrer",
|
|
2354
2396
|
"aria-label": "Discord",
|
|
2355
2397
|
className: "text-neutral-400 dark:text-white/35 hover:text-orange-500 dark:hover:text-brand-orange transition-colors",
|
|
2356
|
-
children: /* @__PURE__ */
|
|
2398
|
+
children: /* @__PURE__ */ jsx29(MessageCircle, { className: "w-5 h-5" })
|
|
2357
2399
|
}
|
|
2358
2400
|
)
|
|
2359
2401
|
] }) })
|
|
@@ -2406,6 +2448,7 @@ export {
|
|
|
2406
2448
|
MediaUploader,
|
|
2407
2449
|
MemoConditionsEditor,
|
|
2408
2450
|
PageShell,
|
|
2451
|
+
ProjectLogo,
|
|
2409
2452
|
ProjectPagePreview,
|
|
2410
2453
|
SearchInput,
|
|
2411
2454
|
Section,
|
package/package.json
CHANGED
package/src/styles/tokens.css
CHANGED
|
@@ -55,6 +55,19 @@
|
|
|
55
55
|
--radius-lg: 14px;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/* ─── Tailwind 4 theme map ────────────────────────────────────────────────
|
|
59
|
+
Expose the brand palette as Tailwind color tokens so consumers don't have
|
|
60
|
+
to repeat the @theme block themselves. Without these, classes like
|
|
61
|
+
`bg-brand-orange`, `dark:hover:shadow-brand-orange/15` silently no-op in
|
|
62
|
+
apps that don't redeclare the colors (e.g. sphere-dev-portal). */
|
|
63
|
+
@theme {
|
|
64
|
+
--color-brand-black: #020202;
|
|
65
|
+
--color-brand-white: #FEFEFE;
|
|
66
|
+
--color-brand-orange: #FF6F00;
|
|
67
|
+
--color-brand-orange-dark: #932D00;
|
|
68
|
+
--color-brand-orange-dim: rgba(255, 111, 0, 0.08);
|
|
69
|
+
}
|
|
70
|
+
|
|
58
71
|
/* ─── Base ─────────────────────────────────────────────────────────────── */
|
|
59
72
|
|
|
60
73
|
body {
|