@unicitylabs/sphere-ui 0.1.19 → 0.1.21
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 +46 -6
- package/dist/index.js +239 -190
- package/package.json +1 -1
- package/src/styles/tokens.css +13 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import { ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes } from 'react';
|
|
3
|
+
import { ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes, MouseEvent, Ref } from 'react';
|
|
4
4
|
import { ColumnDef } from '@tanstack/react-table';
|
|
5
5
|
export { A as AchievementData, a as AchievementFormApi, Q as QueryKeys, b as QuestData, c as QuestFormApi, T as TrackData, d as TrackFormApi } from './index-DMHfA7fr.js';
|
|
6
6
|
|
|
@@ -388,22 +388,62 @@ interface FeaturedProjectCardProps {
|
|
|
388
388
|
*/
|
|
389
389
|
declare function FeaturedProjectCard({ name, tagline, logoUrl, bannerUrl, accentColor, users, quests, positivePercent, ratingCount, onClick, }: FeaturedProjectCardProps): react_jsx_runtime.JSX.Element;
|
|
390
390
|
|
|
391
|
+
/** Loose typing — dnd-kit listeners/attributes don't fit React's HTMLButtonAttributes due to motion.button overrides. */
|
|
392
|
+
type ButtonExtraProps = {
|
|
393
|
+
className?: string;
|
|
394
|
+
style?: React.CSSProperties;
|
|
395
|
+
} & Record<string, unknown>;
|
|
391
396
|
interface InstalledProjectIconProps {
|
|
392
397
|
name: string;
|
|
393
398
|
logoUrl?: string | null;
|
|
394
399
|
/** Hex like "#FF6F00". Defaults to brand orange. */
|
|
395
400
|
accentColor?: string;
|
|
396
401
|
onClick?: () => void;
|
|
402
|
+
/** Right-click handler. Wallet uses it to toggle a context menu. */
|
|
403
|
+
onContextMenu?: (e: MouseEvent<HTMLButtonElement>) => void;
|
|
404
|
+
/** Slot overlaid on the icon tile (absolute top/right). Wallet uses it for the MoreVertical menu button. */
|
|
405
|
+
topRightAction?: ReactNode;
|
|
397
406
|
/** When true, render the name label under the icon (dock vs grid layout). Default true. */
|
|
398
407
|
showLabel?: boolean;
|
|
408
|
+
/** Ref attached to the inner button. Use for dnd-kit `setActivatorNodeRef`. */
|
|
409
|
+
buttonRef?: Ref<HTMLButtonElement>;
|
|
410
|
+
/** Extra props spread on the inner button (e.g. dnd-kit `attributes` + `listeners`). */
|
|
411
|
+
buttonProps?: ButtonExtraProps;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* InstalledProjectIcon — desktop tile for an installed app/skill.
|
|
415
|
+
*
|
|
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.
|
|
421
|
+
*/
|
|
422
|
+
declare function InstalledProjectIcon({ name, logoUrl, accentColor, onClick, onContextMenu, topRightAction, showLabel, buttonRef, buttonProps, }: InstalledProjectIconProps): react_jsx_runtime.JSX.Element;
|
|
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;
|
|
399
436
|
}
|
|
400
437
|
/**
|
|
401
|
-
*
|
|
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.
|
|
402
441
|
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
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.
|
|
405
445
|
*/
|
|
406
|
-
declare function
|
|
446
|
+
declare function ProjectLogo({ name, logoUrl, accentColor, size, className, children, }: ProjectLogoProps): react_jsx_runtime.JSX.Element;
|
|
407
447
|
|
|
408
448
|
interface QuestPreviewSummary {
|
|
409
449
|
slug: string;
|
|
@@ -457,4 +497,4 @@ declare function isMimeAllowed(kind: MediaKind, mime: string): mime is MediaMime
|
|
|
457
497
|
declare function isSizeAllowed(kind: MediaKind, size: number): boolean;
|
|
458
498
|
declare function humanSize(bytes: number): string;
|
|
459
499
|
|
|
460
|
-
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
|
@@ -1762,7 +1762,72 @@ 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
|
-
|
|
1765
|
+
|
|
1766
|
+
// src/components/media/ProjectLogo.tsx
|
|
1767
|
+
import { useState as useState9 } from "react";
|
|
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 ProjectLogo({
|
|
1788
|
+
name,
|
|
1789
|
+
logoUrl,
|
|
1790
|
+
accentColor = "#FF6F00",
|
|
1791
|
+
size = "lg",
|
|
1792
|
+
className,
|
|
1793
|
+
children
|
|
1794
|
+
}) {
|
|
1795
|
+
const [imgError, setImgError] = useState9(false);
|
|
1796
|
+
const showImage = logoUrl && !imgError;
|
|
1797
|
+
const tileBackground = `linear-gradient(to bottom right, ${accentColor}, color-mix(in srgb, ${accentColor} 60%, white))`;
|
|
1798
|
+
return /* @__PURE__ */ jsxs20(
|
|
1799
|
+
"div",
|
|
1800
|
+
{
|
|
1801
|
+
className: `relative ${SIZE_CLASSES[size]} flex items-center justify-center shadow-lg group-hover:shadow-xl transition-all duration-200 overflow-hidden${className ? " " + className : ""}`,
|
|
1802
|
+
style: { background: tileBackground },
|
|
1803
|
+
children: [
|
|
1804
|
+
/* @__PURE__ */ jsx25(
|
|
1805
|
+
"div",
|
|
1806
|
+
{
|
|
1807
|
+
className: "absolute inset-0 opacity-30 group-hover:opacity-50 transition-opacity duration-500 pointer-events-none",
|
|
1808
|
+
style: {
|
|
1809
|
+
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%)"
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
),
|
|
1813
|
+
/* @__PURE__ */ jsx25("div", { className: "absolute top-0 right-0 w-1/2 h-1/2 bg-white/10 rounded-bl-full pointer-events-none" }),
|
|
1814
|
+
showImage ? /* @__PURE__ */ jsx25(
|
|
1815
|
+
"img",
|
|
1816
|
+
{
|
|
1817
|
+
src: logoUrl ?? void 0,
|
|
1818
|
+
alt: name,
|
|
1819
|
+
onError: () => setImgError(true),
|
|
1820
|
+
className: "absolute inset-0 w-full h-full object-cover z-10"
|
|
1821
|
+
}
|
|
1822
|
+
) : /* @__PURE__ */ jsx25("span", { className: `text-white font-bold relative z-10 tracking-tight drop-shadow-sm ${FALLBACK_TEXT_CLASSES[size]}`, children: getInitials(name) }),
|
|
1823
|
+
children
|
|
1824
|
+
]
|
|
1825
|
+
}
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
// src/components/media/MarketplaceProjectCard.tsx
|
|
1830
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1766
1831
|
var categoryLabels = {
|
|
1767
1832
|
game: "Game",
|
|
1768
1833
|
defi: "DeFi",
|
|
@@ -1794,73 +1859,70 @@ function MarketplaceProjectCard({
|
|
|
1794
1859
|
e.stopPropagation();
|
|
1795
1860
|
onInstallClick?.();
|
|
1796
1861
|
};
|
|
1797
|
-
const
|
|
1798
|
-
const card = /* @__PURE__ */ jsxs20(
|
|
1862
|
+
const card = /* @__PURE__ */ jsxs21(
|
|
1799
1863
|
motion.div,
|
|
1800
1864
|
{
|
|
1801
1865
|
whileHover: { y: -4 },
|
|
1802
1866
|
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
1867
|
children: [
|
|
1804
|
-
/* @__PURE__ */
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1868
|
+
/* @__PURE__ */ jsxs21("div", { className: "relative h-24 overflow-hidden", "data-testid": "banner", children: [
|
|
1869
|
+
/* @__PURE__ */ jsx26(
|
|
1870
|
+
"div",
|
|
1871
|
+
{
|
|
1872
|
+
className: "absolute inset-0 bg-cover bg-center transition-transform duration-500 group-hover:scale-105",
|
|
1873
|
+
style: {
|
|
1874
|
+
backgroundColor: accentColor,
|
|
1875
|
+
backgroundImage: hasBanner ? `url(${bannerUrl})` : void 0
|
|
1811
1876
|
}
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
} })
|
|
1816
|
-
] }) : /* @__PURE__ */ jsx25("div", { className: "absolute inset-0", style: {
|
|
1817
|
-
background: `linear-gradient(135deg, ${accentColor}cc 0%, ${accentColor}44 100%)`
|
|
1877
|
+
}
|
|
1878
|
+
),
|
|
1879
|
+
/* @__PURE__ */ jsx26("div", { className: "absolute inset-0", style: {
|
|
1880
|
+
background: hasBanner ? `linear-gradient(to bottom, transparent 0%, ${accentColor}66 100%)` : `linear-gradient(135deg, ${accentColor}cc 0%, ${accentColor}44 100%)`
|
|
1818
1881
|
} }),
|
|
1819
|
-
showInstall && /* @__PURE__ */
|
|
1882
|
+
showInstall && /* @__PURE__ */ jsx26(
|
|
1820
1883
|
"button",
|
|
1821
1884
|
{
|
|
1822
1885
|
onClick: handleInstall,
|
|
1823
1886
|
title: installed ? "Remove from Desktop" : "Add to Desktop",
|
|
1824
1887
|
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"}`,
|
|
1825
|
-
children: installed ? /* @__PURE__ */
|
|
1888
|
+
children: installed ? /* @__PURE__ */ jsx26(Check, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx26(Plus, { className: "w-4 h-4" })
|
|
1826
1889
|
}
|
|
1827
1890
|
)
|
|
1828
1891
|
] }),
|
|
1829
|
-
/* @__PURE__ */
|
|
1830
|
-
/* @__PURE__ */
|
|
1831
|
-
/* @__PURE__ */
|
|
1832
|
-
|
|
1892
|
+
/* @__PURE__ */ jsxs21("div", { className: "p-4 bg-white dark:bg-white/4 dark:backdrop-blur-2xl", children: [
|
|
1893
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-start gap-3", children: [
|
|
1894
|
+
/* @__PURE__ */ jsx26("div", { className: "shrink-0 -mt-8 ring-2 ring-white dark:ring-[#0a0a0a] rounded-xl relative z-10", children: /* @__PURE__ */ jsx26(
|
|
1895
|
+
ProjectLogo,
|
|
1833
1896
|
{
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
}
|
|
1897
|
+
name,
|
|
1898
|
+
logoUrl,
|
|
1899
|
+
accentColor,
|
|
1900
|
+
size: "md",
|
|
1901
|
+
className: "border border-neutral-200 dark:border-white/10"
|
|
1840
1902
|
}
|
|
1841
|
-
),
|
|
1842
|
-
/* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
1844
|
-
/* @__PURE__ */
|
|
1903
|
+
) }),
|
|
1904
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
|
|
1905
|
+
/* @__PURE__ */ jsx26("h3", { className: "font-semibold text-neutral-900 dark:text-white text-sm truncate", children: name }),
|
|
1906
|
+
/* @__PURE__ */ jsx26("p", { className: "text-neutral-500 dark:text-white/45 text-xs mt-0.5 h-8 line-clamp-2", children: tagline })
|
|
1845
1907
|
] })
|
|
1846
1908
|
] }),
|
|
1847
|
-
/* @__PURE__ */
|
|
1848
|
-
category ? /* @__PURE__ */
|
|
1909
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-neutral-100 dark:border-white/5", children: [
|
|
1910
|
+
category ? /* @__PURE__ */ jsx26("span", { className: "inline-flex px-2 py-0.5 rounded-md text-[10px] font-semibold uppercase tracking-wider border", style: {
|
|
1849
1911
|
backgroundColor: `${accentColor}15`,
|
|
1850
1912
|
color: accentColor,
|
|
1851
1913
|
borderColor: `${accentColor}30`
|
|
1852
|
-
}, children: categoryLabels[category] ?? category }) : /* @__PURE__ */
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
1914
|
+
}, children: categoryLabels[category] ?? category }) : /* @__PURE__ */ jsx26("span", {}),
|
|
1915
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3 text-[11px] text-neutral-400 dark:text-white/35", children: [
|
|
1916
|
+
/* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1", title: "Users", children: [
|
|
1917
|
+
/* @__PURE__ */ jsx26(Users, { className: "w-3 h-3" }),
|
|
1856
1918
|
users.toLocaleString()
|
|
1857
1919
|
] }),
|
|
1858
|
-
/* @__PURE__ */
|
|
1859
|
-
/* @__PURE__ */
|
|
1920
|
+
/* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1", title: "Active quests", children: [
|
|
1921
|
+
/* @__PURE__ */ jsx26(Target, { className: "w-3 h-3" }),
|
|
1860
1922
|
quests.toLocaleString()
|
|
1861
1923
|
] }),
|
|
1862
|
-
ratingCount > 0 && /* @__PURE__ */
|
|
1863
|
-
/* @__PURE__ */
|
|
1924
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1", title: `${ratingCount} reviews`, children: [
|
|
1925
|
+
/* @__PURE__ */ jsx26(ThumbsUp, { className: "w-3 h-3" }),
|
|
1864
1926
|
positivePercent,
|
|
1865
1927
|
"%"
|
|
1866
1928
|
] })
|
|
@@ -1871,7 +1933,7 @@ function MarketplaceProjectCard({
|
|
|
1871
1933
|
}
|
|
1872
1934
|
);
|
|
1873
1935
|
if (onClick) {
|
|
1874
|
-
return /* @__PURE__ */
|
|
1936
|
+
return /* @__PURE__ */ jsx26("button", { type: "button", onClick, className: "block w-full text-left", children: card });
|
|
1875
1937
|
}
|
|
1876
1938
|
return card;
|
|
1877
1939
|
}
|
|
@@ -1879,7 +1941,7 @@ function MarketplaceProjectCard({
|
|
|
1879
1941
|
// src/components/media/FeaturedProjectCard.tsx
|
|
1880
1942
|
import { motion as motion2 } from "framer-motion";
|
|
1881
1943
|
import { Star, Users as Users2, Target as Target2, ThumbsUp as ThumbsUp2 } from "lucide-react";
|
|
1882
|
-
import { jsx as
|
|
1944
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1883
1945
|
function FeaturedProjectCard({
|
|
1884
1946
|
name,
|
|
1885
1947
|
tagline,
|
|
@@ -1892,15 +1954,14 @@ function FeaturedProjectCard({
|
|
|
1892
1954
|
ratingCount = 0,
|
|
1893
1955
|
onClick
|
|
1894
1956
|
}) {
|
|
1895
|
-
const
|
|
1896
|
-
const card = /* @__PURE__ */ jsxs21(
|
|
1957
|
+
const card = /* @__PURE__ */ jsxs22(
|
|
1897
1958
|
motion2.div,
|
|
1898
1959
|
{
|
|
1899
1960
|
whileHover: { scale: 1.02, y: -2 },
|
|
1900
1961
|
whileTap: { scale: 0.98 },
|
|
1901
1962
|
className: "relative w-72 sm:w-80 h-44 rounded-2xl overflow-hidden shrink-0 cursor-pointer group",
|
|
1902
1963
|
children: [
|
|
1903
|
-
/* @__PURE__ */
|
|
1964
|
+
/* @__PURE__ */ jsx27(
|
|
1904
1965
|
"div",
|
|
1905
1966
|
{
|
|
1906
1967
|
className: "absolute inset-0 bg-cover bg-center transition-transform duration-500 group-hover:scale-105",
|
|
@@ -1911,43 +1972,42 @@ function FeaturedProjectCard({
|
|
|
1911
1972
|
}
|
|
1912
1973
|
}
|
|
1913
1974
|
),
|
|
1914
|
-
/* @__PURE__ */
|
|
1975
|
+
/* @__PURE__ */ jsx27("div", { className: "absolute inset-0", style: {
|
|
1915
1976
|
background: bannerUrl ? `linear-gradient(135deg, ${accentColor}66 0%, transparent 60%)` : `linear-gradient(135deg, ${accentColor}cc 0%, ${accentColor}44 100%)`
|
|
1916
1977
|
} }),
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
/* @__PURE__ */
|
|
1978
|
+
/* @__PURE__ */ jsx27("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent" }),
|
|
1979
|
+
/* @__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: [
|
|
1980
|
+
/* @__PURE__ */ jsx27(Star, { className: "w-3 h-3", fill: "currentColor" }),
|
|
1920
1981
|
"Featured"
|
|
1921
1982
|
] }),
|
|
1922
|
-
/* @__PURE__ */
|
|
1923
|
-
/* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
1925
|
-
|
|
1983
|
+
/* @__PURE__ */ jsxs22("div", { className: "absolute bottom-0 left-0 right-0 p-4", children: [
|
|
1984
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
|
|
1985
|
+
/* @__PURE__ */ jsx27(
|
|
1986
|
+
ProjectLogo,
|
|
1926
1987
|
{
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
}
|
|
1988
|
+
name,
|
|
1989
|
+
logoUrl,
|
|
1990
|
+
accentColor,
|
|
1991
|
+
size: "sm",
|
|
1992
|
+
className: "border-2 border-white/20"
|
|
1933
1993
|
}
|
|
1934
1994
|
),
|
|
1935
|
-
/* @__PURE__ */
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
1995
|
+
/* @__PURE__ */ jsxs22("div", { className: "min-w-0", children: [
|
|
1996
|
+
/* @__PURE__ */ jsx27("h3", { className: "font-semibold text-white text-sm truncate", children: name }),
|
|
1997
|
+
/* @__PURE__ */ jsx27("p", { className: "text-white/70 text-xs truncate", children: tagline })
|
|
1938
1998
|
] })
|
|
1939
1999
|
] }),
|
|
1940
|
-
/* @__PURE__ */
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
2000
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3 mt-2 text-[11px] text-white/60", children: [
|
|
2001
|
+
/* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1", title: "Users", children: [
|
|
2002
|
+
/* @__PURE__ */ jsx27(Users2, { className: "w-3 h-3" }),
|
|
1943
2003
|
users.toLocaleString()
|
|
1944
2004
|
] }),
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
/* @__PURE__ */
|
|
2005
|
+
/* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1", title: "Active quests", children: [
|
|
2006
|
+
/* @__PURE__ */ jsx27(Target2, { className: "w-3 h-3" }),
|
|
1947
2007
|
quests.toLocaleString()
|
|
1948
2008
|
] }),
|
|
1949
|
-
ratingCount > 0 && /* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
2009
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1", title: `${ratingCount} reviews`, children: [
|
|
2010
|
+
/* @__PURE__ */ jsx27(ThumbsUp2, { className: "w-3 h-3" }),
|
|
1951
2011
|
positivePercent,
|
|
1952
2012
|
"%"
|
|
1953
2013
|
] })
|
|
@@ -1957,72 +2017,60 @@ function FeaturedProjectCard({
|
|
|
1957
2017
|
}
|
|
1958
2018
|
);
|
|
1959
2019
|
if (onClick) {
|
|
1960
|
-
return /* @__PURE__ */
|
|
2020
|
+
return /* @__PURE__ */ jsx27("button", { type: "button", onClick, className: "block text-left", draggable: false, children: card });
|
|
1961
2021
|
}
|
|
1962
2022
|
return card;
|
|
1963
2023
|
}
|
|
1964
2024
|
|
|
1965
2025
|
// src/components/media/InstalledProjectIcon.tsx
|
|
1966
|
-
import { useState as useState9 } from "react";
|
|
1967
2026
|
import { motion as motion3 } from "framer-motion";
|
|
1968
|
-
import { jsx as
|
|
2027
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1969
2028
|
function InstalledProjectIcon({
|
|
1970
2029
|
name,
|
|
1971
2030
|
logoUrl,
|
|
1972
2031
|
accentColor = "#FF6F00",
|
|
1973
2032
|
onClick,
|
|
1974
|
-
|
|
2033
|
+
onContextMenu,
|
|
2034
|
+
topRightAction,
|
|
2035
|
+
showLabel = true,
|
|
2036
|
+
buttonRef,
|
|
2037
|
+
buttonProps
|
|
1975
2038
|
}) {
|
|
1976
|
-
|
|
1977
|
-
return /* @__PURE__ */ jsx27("div", { className: "relative", children: /* @__PURE__ */ jsxs22(
|
|
2039
|
+
return /* @__PURE__ */ jsx28("div", { className: "relative", children: /* @__PURE__ */ jsxs23(
|
|
1978
2040
|
motion3.button,
|
|
1979
2041
|
{
|
|
2042
|
+
ref: buttonRef,
|
|
1980
2043
|
type: "button",
|
|
1981
2044
|
onClick,
|
|
2045
|
+
onContextMenu,
|
|
1982
2046
|
whileHover: { scale: 1.08, y: -4 },
|
|
1983
2047
|
whileTap: { scale: 0.92 },
|
|
1984
2048
|
transition: { duration: 0.05 },
|
|
1985
|
-
|
|
2049
|
+
...buttonProps,
|
|
2050
|
+
className: `flex flex-col items-center gap-2 p-3 rounded-2xl group cursor-pointer relative${buttonProps?.className ? " " + buttonProps.className : ""}`,
|
|
2051
|
+
style: { touchAction: "none", ...buttonProps?.style },
|
|
1986
2052
|
children: [
|
|
1987
|
-
/* @__PURE__ */
|
|
1988
|
-
/* @__PURE__ */
|
|
2053
|
+
/* @__PURE__ */ jsxs23("div", { className: "relative", children: [
|
|
2054
|
+
/* @__PURE__ */ jsx28(
|
|
1989
2055
|
"div",
|
|
1990
2056
|
{
|
|
1991
|
-
className: "absolute -inset-1 blur-xl opacity-0 group-hover:opacity-50 transition-all duration-300 rounded-2xl",
|
|
2057
|
+
className: "absolute -inset-1 blur-xl opacity-0 group-hover:opacity-50 transition-all duration-300 rounded-2xl pointer-events-none",
|
|
1992
2058
|
style: { backgroundColor: accentColor }
|
|
1993
2059
|
}
|
|
1994
2060
|
),
|
|
1995
|
-
/* @__PURE__ */
|
|
1996
|
-
|
|
2061
|
+
/* @__PURE__ */ jsx28(
|
|
2062
|
+
ProjectLogo,
|
|
1997
2063
|
{
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
className: "absolute inset-0 opacity-30 group-hover:opacity-50 transition-opacity duration-500",
|
|
2005
|
-
style: {
|
|
2006
|
-
backgroundImage: `radial-gradient(at 27% 37%, rgba(255,255,255,0.15) 0px, transparent 50%),
|
|
2007
|
-
radial-gradient(at 97% 21%, rgba(255,255,255,0.1) 0px, transparent 50%)`
|
|
2008
|
-
}
|
|
2009
|
-
}
|
|
2010
|
-
),
|
|
2011
|
-
/* @__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" }),
|
|
2012
|
-
logoUrl && !imgError ? /* @__PURE__ */ jsx27(
|
|
2013
|
-
"img",
|
|
2014
|
-
{
|
|
2015
|
-
src: logoUrl,
|
|
2016
|
-
alt: name,
|
|
2017
|
-
onError: () => setImgError(true),
|
|
2018
|
-
className: "w-9 h-9 sm:w-10 sm:h-10 object-contain rounded-lg relative z-10 drop-shadow-lg"
|
|
2019
|
-
}
|
|
2020
|
-
) : /* @__PURE__ */ jsx27("span", { className: "text-white font-bold text-lg relative z-10", children: name[0] ?? "?" })
|
|
2021
|
-
]
|
|
2064
|
+
name,
|
|
2065
|
+
logoUrl,
|
|
2066
|
+
accentColor,
|
|
2067
|
+
size: "lg",
|
|
2068
|
+
className: "group-hover:shadow-xl transition-all duration-200",
|
|
2069
|
+
children: topRightAction
|
|
2022
2070
|
}
|
|
2023
2071
|
)
|
|
2024
2072
|
] }),
|
|
2025
|
-
showLabel && /* @__PURE__ */
|
|
2073
|
+
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 })
|
|
2026
2074
|
]
|
|
2027
2075
|
}
|
|
2028
2076
|
) });
|
|
@@ -2044,7 +2092,7 @@ import {
|
|
|
2044
2092
|
Twitter,
|
|
2045
2093
|
Zap
|
|
2046
2094
|
} from "lucide-react";
|
|
2047
|
-
import { jsx as
|
|
2095
|
+
import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2048
2096
|
var categoryLabels2 = {
|
|
2049
2097
|
game: "Game",
|
|
2050
2098
|
defi: "DeFi",
|
|
@@ -2084,16 +2132,16 @@ function ProjectPagePreview({
|
|
|
2084
2132
|
tags = []
|
|
2085
2133
|
}) {
|
|
2086
2134
|
const placeholderLogo = `https://placehold.co/80x80/${accentColor.slice(1)}/white?text=${name[0] ?? "?"}`;
|
|
2087
|
-
return /* @__PURE__ */
|
|
2135
|
+
return /* @__PURE__ */ jsxs24(
|
|
2088
2136
|
motion4.div,
|
|
2089
2137
|
{
|
|
2090
2138
|
initial: { opacity: 0 },
|
|
2091
2139
|
animate: { opacity: 1 },
|
|
2092
2140
|
className: "text-neutral-900 dark:text-white pb-12",
|
|
2093
2141
|
children: [
|
|
2094
|
-
/* @__PURE__ */
|
|
2095
|
-
/* @__PURE__ */
|
|
2096
|
-
/* @__PURE__ */
|
|
2142
|
+
/* @__PURE__ */ jsxs24("div", { className: "relative mx-4 sm:mx-6 mt-2", children: [
|
|
2143
|
+
/* @__PURE__ */ jsxs24("div", { className: "relative h-48 sm:h-64 rounded-2xl overflow-hidden", children: [
|
|
2144
|
+
/* @__PURE__ */ jsx29(
|
|
2097
2145
|
"div",
|
|
2098
2146
|
{
|
|
2099
2147
|
className: "absolute inset-0 bg-cover bg-center",
|
|
@@ -2104,13 +2152,13 @@ function ProjectPagePreview({
|
|
|
2104
2152
|
}
|
|
2105
2153
|
}
|
|
2106
2154
|
),
|
|
2107
|
-
/* @__PURE__ */
|
|
2108
|
-
/* @__PURE__ */
|
|
2109
|
-
/* @__PURE__ */
|
|
2155
|
+
/* @__PURE__ */ jsx29("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent" }),
|
|
2156
|
+
/* @__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: [
|
|
2157
|
+
/* @__PURE__ */ jsx29(ArrowLeft, { className: "w-4 h-4" }),
|
|
2110
2158
|
"Explore"
|
|
2111
2159
|
] })
|
|
2112
2160
|
] }),
|
|
2113
|
-
/* @__PURE__ */
|
|
2161
|
+
/* @__PURE__ */ jsx29("div", { className: "absolute -bottom-6 left-6 sm:left-8 z-10", children: /* @__PURE__ */ jsx29(
|
|
2114
2162
|
"img",
|
|
2115
2163
|
{
|
|
2116
2164
|
src: logoUrl ?? placeholderLogo,
|
|
@@ -2122,13 +2170,13 @@ function ProjectPagePreview({
|
|
|
2122
2170
|
}
|
|
2123
2171
|
) })
|
|
2124
2172
|
] }),
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
/* @__PURE__ */
|
|
2127
|
-
/* @__PURE__ */
|
|
2128
|
-
/* @__PURE__ */
|
|
2129
|
-
tagline && /* @__PURE__ */
|
|
2130
|
-
(category || tags.length > 0) && /* @__PURE__ */
|
|
2131
|
-
category && /* @__PURE__ */
|
|
2173
|
+
/* @__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: [
|
|
2174
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4", children: [
|
|
2175
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
2176
|
+
/* @__PURE__ */ jsx29("h1", { className: "text-2xl sm:text-3xl font-bold", children: name }),
|
|
2177
|
+
tagline && /* @__PURE__ */ jsx29("p", { className: "text-neutral-500 dark:text-white/55 mt-1", children: tagline }),
|
|
2178
|
+
(category || tags.length > 0) && /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 mt-3", children: [
|
|
2179
|
+
category && /* @__PURE__ */ jsx29(
|
|
2132
2180
|
"span",
|
|
2133
2181
|
{
|
|
2134
2182
|
className: "inline-flex px-2.5 py-0.5 rounded-lg text-xs font-semibold uppercase tracking-wider",
|
|
@@ -2140,7 +2188,7 @@ function ProjectPagePreview({
|
|
|
2140
2188
|
children: categoryLabels2[category] ?? category
|
|
2141
2189
|
}
|
|
2142
2190
|
),
|
|
2143
|
-
tags.slice(0, 3).map((tag) => /* @__PURE__ */
|
|
2191
|
+
tags.slice(0, 3).map((tag) => /* @__PURE__ */ jsx29(
|
|
2144
2192
|
"span",
|
|
2145
2193
|
{
|
|
2146
2194
|
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",
|
|
@@ -2150,30 +2198,30 @@ function ProjectPagePreview({
|
|
|
2150
2198
|
))
|
|
2151
2199
|
] })
|
|
2152
2200
|
] }),
|
|
2153
|
-
/* @__PURE__ */
|
|
2154
|
-
/* @__PURE__ */
|
|
2201
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2 shrink-0 flex-wrap", children: [
|
|
2202
|
+
/* @__PURE__ */ jsxs24(
|
|
2155
2203
|
"button",
|
|
2156
2204
|
{
|
|
2157
2205
|
type: "button",
|
|
2158
2206
|
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",
|
|
2159
2207
|
children: [
|
|
2160
|
-
/* @__PURE__ */
|
|
2208
|
+
/* @__PURE__ */ jsx29(Plus2, { className: "w-4 h-4" }),
|
|
2161
2209
|
" Add to Desktop"
|
|
2162
2210
|
]
|
|
2163
2211
|
}
|
|
2164
2212
|
),
|
|
2165
|
-
/* @__PURE__ */
|
|
2213
|
+
/* @__PURE__ */ jsxs24(
|
|
2166
2214
|
"button",
|
|
2167
2215
|
{
|
|
2168
2216
|
type: "button",
|
|
2169
2217
|
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",
|
|
2170
2218
|
children: [
|
|
2171
2219
|
"Open ",
|
|
2172
|
-
/* @__PURE__ */
|
|
2220
|
+
/* @__PURE__ */ jsx29(ExternalLink, { className: "w-3.5 h-3.5" })
|
|
2173
2221
|
]
|
|
2174
2222
|
}
|
|
2175
2223
|
),
|
|
2176
|
-
websiteUrl && /* @__PURE__ */
|
|
2224
|
+
websiteUrl && /* @__PURE__ */ jsxs24(
|
|
2177
2225
|
"a",
|
|
2178
2226
|
{
|
|
2179
2227
|
href: websiteUrl,
|
|
@@ -2182,36 +2230,36 @@ function ProjectPagePreview({
|
|
|
2182
2230
|
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",
|
|
2183
2231
|
children: [
|
|
2184
2232
|
"Website ",
|
|
2185
|
-
/* @__PURE__ */
|
|
2233
|
+
/* @__PURE__ */ jsx29(Globe, { className: "w-3.5 h-3.5" })
|
|
2186
2234
|
]
|
|
2187
2235
|
}
|
|
2188
2236
|
)
|
|
2189
2237
|
] })
|
|
2190
2238
|
] }),
|
|
2191
|
-
/* @__PURE__ */
|
|
2192
|
-
/* @__PURE__ */
|
|
2193
|
-
/* @__PURE__ */
|
|
2194
|
-
/* @__PURE__ */
|
|
2195
|
-
/* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-6 sm:gap-10 border-t border-neutral-200 dark:border-white/8 mt-6 pt-5", children: [
|
|
2240
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-center sm:text-left", children: [
|
|
2241
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 justify-center sm:justify-start", children: [
|
|
2242
|
+
/* @__PURE__ */ jsx29(Users3, { className: "w-4 h-4 text-neutral-400 dark:text-white/30" }),
|
|
2243
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xl sm:text-2xl font-bold font-mono", children: users.toLocaleString() })
|
|
2196
2244
|
] }),
|
|
2197
|
-
/* @__PURE__ */
|
|
2245
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs text-neutral-400 dark:text-white/35 uppercase tracking-wider", children: "Users" })
|
|
2198
2246
|
] }),
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
/* @__PURE__ */
|
|
2202
|
-
/* @__PURE__ */
|
|
2247
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-center sm:text-left", children: [
|
|
2248
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 justify-center sm:justify-start", children: [
|
|
2249
|
+
/* @__PURE__ */ jsx29(Target3, { className: "w-4 h-4 text-neutral-400 dark:text-white/30" }),
|
|
2250
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xl sm:text-2xl font-bold font-mono", children: activeQuests.toLocaleString() })
|
|
2203
2251
|
] }),
|
|
2204
|
-
/* @__PURE__ */
|
|
2252
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs text-neutral-400 dark:text-white/35 uppercase tracking-wider", children: "Active Quests" })
|
|
2205
2253
|
] }),
|
|
2206
|
-
ratingCount > 0 && /* @__PURE__ */
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
/* @__PURE__ */
|
|
2209
|
-
/* @__PURE__ */
|
|
2254
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs24("div", { className: "text-center sm:text-left", children: [
|
|
2255
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 justify-center sm:justify-start", children: [
|
|
2256
|
+
/* @__PURE__ */ jsx29(ThumbsUp3, { className: "w-4 h-4 text-neutral-400 dark:text-white/30" }),
|
|
2257
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-xl sm:text-2xl font-bold font-mono", children: [
|
|
2210
2258
|
positivePercent,
|
|
2211
2259
|
"%"
|
|
2212
2260
|
] })
|
|
2213
2261
|
] }),
|
|
2214
|
-
/* @__PURE__ */
|
|
2262
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-xs text-neutral-400 dark:text-white/35 uppercase tracking-wider", children: [
|
|
2215
2263
|
ratingCount.toLocaleString(),
|
|
2216
2264
|
" ",
|
|
2217
2265
|
ratingCount === 1 ? "review" : "reviews"
|
|
@@ -2219,16 +2267,16 @@ function ProjectPagePreview({
|
|
|
2219
2267
|
] })
|
|
2220
2268
|
] })
|
|
2221
2269
|
] }) }),
|
|
2222
|
-
media.length > 0 && /* @__PURE__ */
|
|
2223
|
-
/* @__PURE__ */
|
|
2224
|
-
/* @__PURE__ */
|
|
2270
|
+
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: [
|
|
2271
|
+
/* @__PURE__ */ jsx29("h2", { className: "text-lg font-semibold mb-4", children: "Media" }),
|
|
2272
|
+
/* @__PURE__ */ jsx29("div", { className: "flex gap-3 overflow-x-auto scrollbar-hide pb-2", children: media.map((item, i) => {
|
|
2225
2273
|
const isVideo = item.type === "video";
|
|
2226
|
-
return /* @__PURE__ */
|
|
2274
|
+
return /* @__PURE__ */ jsxs24(
|
|
2227
2275
|
"div",
|
|
2228
2276
|
{
|
|
2229
2277
|
className: "shrink-0 rounded-xl overflow-hidden border border-neutral-200 dark:border-white/8 relative",
|
|
2230
2278
|
children: [
|
|
2231
|
-
/* @__PURE__ */
|
|
2279
|
+
/* @__PURE__ */ jsx29(
|
|
2232
2280
|
"img",
|
|
2233
2281
|
{
|
|
2234
2282
|
src: getMediaThumb(item),
|
|
@@ -2237,40 +2285,40 @@ function ProjectPagePreview({
|
|
|
2237
2285
|
className: "h-44 sm:h-52 w-72 sm:w-80 object-cover"
|
|
2238
2286
|
}
|
|
2239
2287
|
),
|
|
2240
|
-
isVideo && /* @__PURE__ */
|
|
2288
|
+
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" }) }) }) })
|
|
2241
2289
|
]
|
|
2242
2290
|
},
|
|
2243
2291
|
i
|
|
2244
2292
|
);
|
|
2245
2293
|
}) })
|
|
2246
2294
|
] }) }),
|
|
2247
|
-
description && /* @__PURE__ */
|
|
2248
|
-
/* @__PURE__ */
|
|
2249
|
-
/* @__PURE__ */
|
|
2295
|
+
description && /* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2296
|
+
/* @__PURE__ */ jsx29("h2", { className: "text-lg font-semibold mb-4", children: "About" }),
|
|
2297
|
+
/* @__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 }) })
|
|
2250
2298
|
] }) }),
|
|
2251
|
-
quests.length > 0 && /* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
2299
|
+
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: [
|
|
2300
|
+
/* @__PURE__ */ jsxs24("h2", { className: "text-lg font-semibold mb-4", children: [
|
|
2253
2301
|
"Quests ",
|
|
2254
|
-
/* @__PURE__ */
|
|
2302
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-neutral-400 dark:text-white/35 font-normal", children: [
|
|
2255
2303
|
"(",
|
|
2256
2304
|
quests.length,
|
|
2257
2305
|
")"
|
|
2258
2306
|
] })
|
|
2259
2307
|
] }),
|
|
2260
|
-
/* @__PURE__ */
|
|
2308
|
+
/* @__PURE__ */ jsx29("div", { className: "grid sm:grid-cols-2 gap-3", children: quests.map((quest) => /* @__PURE__ */ jsxs24(
|
|
2261
2309
|
"div",
|
|
2262
2310
|
{
|
|
2263
2311
|
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",
|
|
2264
2312
|
children: [
|
|
2265
|
-
/* @__PURE__ */
|
|
2266
|
-
/* @__PURE__ */
|
|
2267
|
-
/* @__PURE__ */
|
|
2268
|
-
/* @__PURE__ */
|
|
2269
|
-
quest.description && /* @__PURE__ */
|
|
2270
|
-
quest.difficulty && /* @__PURE__ */
|
|
2313
|
+
/* @__PURE__ */ jsx29("div", { className: "absolute left-0 top-0 bottom-0 w-0.5", style: { backgroundColor: accentColor } }),
|
|
2314
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-start gap-3", children: [
|
|
2315
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0 flex-1", children: [
|
|
2316
|
+
/* @__PURE__ */ jsx29("h4", { className: "font-medium text-sm text-neutral-900 dark:text-white", children: quest.title }),
|
|
2317
|
+
quest.description && /* @__PURE__ */ jsx29("p", { className: "text-xs text-neutral-500 dark:text-white/40 mt-0.5 line-clamp-2", children: quest.description }),
|
|
2318
|
+
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 })
|
|
2271
2319
|
] }),
|
|
2272
|
-
typeof quest.points === "number" && /* @__PURE__ */
|
|
2273
|
-
/* @__PURE__ */
|
|
2320
|
+
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: [
|
|
2321
|
+
/* @__PURE__ */ jsx29(Zap, { className: "w-3 h-3" }),
|
|
2274
2322
|
quest.points
|
|
2275
2323
|
] })
|
|
2276
2324
|
] })
|
|
@@ -2279,27 +2327,27 @@ function ProjectPagePreview({
|
|
|
2279
2327
|
quest.slug
|
|
2280
2328
|
)) })
|
|
2281
2329
|
] }) }),
|
|
2282
|
-
achievements.length > 0 && /* @__PURE__ */
|
|
2283
|
-
/* @__PURE__ */
|
|
2330
|
+
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: [
|
|
2331
|
+
/* @__PURE__ */ jsxs24("h2", { className: "text-lg font-semibold mb-4", children: [
|
|
2284
2332
|
"Achievements ",
|
|
2285
|
-
/* @__PURE__ */
|
|
2333
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-neutral-400 dark:text-white/35 font-normal", children: [
|
|
2286
2334
|
"(",
|
|
2287
2335
|
achievements.length,
|
|
2288
2336
|
")"
|
|
2289
2337
|
] })
|
|
2290
2338
|
] }),
|
|
2291
|
-
/* @__PURE__ */
|
|
2339
|
+
/* @__PURE__ */ jsx29("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3", children: achievements.map((ach) => /* @__PURE__ */ jsxs24(
|
|
2292
2340
|
"div",
|
|
2293
2341
|
{
|
|
2294
2342
|
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",
|
|
2295
2343
|
children: [
|
|
2296
|
-
/* @__PURE__ */
|
|
2344
|
+
/* @__PURE__ */ jsx29("div", { className: "w-16 h-16 rounded-xl overflow-hidden flex items-center justify-center mb-3", style: {
|
|
2297
2345
|
backgroundColor: `${accentColor}15`,
|
|
2298
2346
|
border: `1px solid ${accentColor}30`
|
|
2299
|
-
}, children: ach.imageUrl ? /* @__PURE__ */
|
|
2300
|
-
/* @__PURE__ */
|
|
2301
|
-
typeof ach.points === "number" && /* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
2347
|
+
}, 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 } }) }),
|
|
2348
|
+
/* @__PURE__ */ jsx29("h4", { className: "text-sm font-medium text-neutral-900 dark:text-white line-clamp-2", children: ach.title }),
|
|
2349
|
+
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: [
|
|
2350
|
+
/* @__PURE__ */ jsx29(Zap, { className: "w-3 h-3" }),
|
|
2303
2351
|
ach.points
|
|
2304
2352
|
] })
|
|
2305
2353
|
]
|
|
@@ -2307,15 +2355,15 @@ function ProjectPagePreview({
|
|
|
2307
2355
|
ach.slug
|
|
2308
2356
|
)) })
|
|
2309
2357
|
] }) }),
|
|
2310
|
-
/* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2312
|
-
/* @__PURE__ */
|
|
2313
|
-
/* @__PURE__ */
|
|
2314
|
-
/* @__PURE__ */
|
|
2358
|
+
/* @__PURE__ */ jsx29("section", { className: "px-4 sm:px-6 pb-8", children: /* @__PURE__ */ jsxs24("div", { className: "max-w-5xl mx-auto", children: [
|
|
2359
|
+
/* @__PURE__ */ jsx29("h2", { className: "text-lg font-semibold mb-4", children: "Reviews" }),
|
|
2360
|
+
/* @__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: [
|
|
2361
|
+
/* @__PURE__ */ jsx29(Star2, { className: "w-8 h-8 text-neutral-300 dark:text-white/20 mb-2" }),
|
|
2362
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-neutral-500 dark:text-white/40", children: "Reviews coming soon" })
|
|
2315
2363
|
] })
|
|
2316
2364
|
] }) }),
|
|
2317
|
-
(websiteUrl || discordUrl || twitterUrl) && /* @__PURE__ */
|
|
2318
|
-
websiteUrl && /* @__PURE__ */
|
|
2365
|
+
(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: [
|
|
2366
|
+
websiteUrl && /* @__PURE__ */ jsx29(
|
|
2319
2367
|
"a",
|
|
2320
2368
|
{
|
|
2321
2369
|
href: websiteUrl,
|
|
@@ -2323,10 +2371,10 @@ function ProjectPagePreview({
|
|
|
2323
2371
|
rel: "noopener noreferrer",
|
|
2324
2372
|
"aria-label": "Website",
|
|
2325
2373
|
className: "text-neutral-400 dark:text-white/35 hover:text-orange-500 dark:hover:text-brand-orange transition-colors",
|
|
2326
|
-
children: /* @__PURE__ */
|
|
2374
|
+
children: /* @__PURE__ */ jsx29(Globe, { className: "w-5 h-5" })
|
|
2327
2375
|
}
|
|
2328
2376
|
),
|
|
2329
|
-
twitterUrl && /* @__PURE__ */
|
|
2377
|
+
twitterUrl && /* @__PURE__ */ jsx29(
|
|
2330
2378
|
"a",
|
|
2331
2379
|
{
|
|
2332
2380
|
href: twitterUrl,
|
|
@@ -2334,10 +2382,10 @@ function ProjectPagePreview({
|
|
|
2334
2382
|
rel: "noopener noreferrer",
|
|
2335
2383
|
"aria-label": "Twitter / X",
|
|
2336
2384
|
className: "text-neutral-400 dark:text-white/35 hover:text-orange-500 dark:hover:text-brand-orange transition-colors",
|
|
2337
|
-
children: /* @__PURE__ */
|
|
2385
|
+
children: /* @__PURE__ */ jsx29(Twitter, { className: "w-5 h-5" })
|
|
2338
2386
|
}
|
|
2339
2387
|
),
|
|
2340
|
-
discordUrl && /* @__PURE__ */
|
|
2388
|
+
discordUrl && /* @__PURE__ */ jsx29(
|
|
2341
2389
|
"a",
|
|
2342
2390
|
{
|
|
2343
2391
|
href: discordUrl,
|
|
@@ -2345,7 +2393,7 @@ function ProjectPagePreview({
|
|
|
2345
2393
|
rel: "noopener noreferrer",
|
|
2346
2394
|
"aria-label": "Discord",
|
|
2347
2395
|
className: "text-neutral-400 dark:text-white/35 hover:text-orange-500 dark:hover:text-brand-orange transition-colors",
|
|
2348
|
-
children: /* @__PURE__ */
|
|
2396
|
+
children: /* @__PURE__ */ jsx29(MessageCircle, { className: "w-5 h-5" })
|
|
2349
2397
|
}
|
|
2350
2398
|
)
|
|
2351
2399
|
] }) })
|
|
@@ -2398,6 +2446,7 @@ export {
|
|
|
2398
2446
|
MediaUploader,
|
|
2399
2447
|
MemoConditionsEditor,
|
|
2400
2448
|
PageShell,
|
|
2449
|
+
ProjectLogo,
|
|
2401
2450
|
ProjectPagePreview,
|
|
2402
2451
|
SearchInput,
|
|
2403
2452
|
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 {
|