@medialane/ui 0.99.1 → 0.100.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/README.md +19 -0
  2. package/dist/components/action-button.cjs +1 -3
  3. package/dist/components/action-button.cjs.map +1 -1
  4. package/dist/components/action-button.js +1 -3
  5. package/dist/components/action-button.js.map +1 -1
  6. package/dist/components/activity-card.cjs +3 -3
  7. package/dist/components/activity-card.cjs.map +1 -1
  8. package/dist/components/activity-card.js +3 -3
  9. package/dist/components/activity-card.js.map +1 -1
  10. package/dist/components/activity-feed-shell.cjs +1 -1
  11. package/dist/components/activity-feed-shell.cjs.map +1 -1
  12. package/dist/components/activity-feed-shell.js +1 -1
  13. package/dist/components/activity-feed-shell.js.map +1 -1
  14. package/dist/components/activity-row.cjs +3 -3
  15. package/dist/components/activity-row.cjs.map +1 -1
  16. package/dist/components/activity-row.js +3 -3
  17. package/dist/components/activity-row.js.map +1 -1
  18. package/dist/components/activity-ticker.cjs +1 -1
  19. package/dist/components/activity-ticker.cjs.map +1 -1
  20. package/dist/components/activity-ticker.js +1 -1
  21. package/dist/components/activity-ticker.js.map +1 -1
  22. package/dist/components/asset-card.cjs +2 -2
  23. package/dist/components/asset-card.cjs.map +1 -1
  24. package/dist/components/asset-card.js +2 -2
  25. package/dist/components/asset-card.js.map +1 -1
  26. package/dist/components/asset-license-summary.cjs +2 -2
  27. package/dist/components/asset-license-summary.cjs.map +1 -1
  28. package/dist/components/asset-license-summary.js +2 -2
  29. package/dist/components/asset-license-summary.js.map +1 -1
  30. package/dist/components/asset-overview-content.cjs +2 -2
  31. package/dist/components/asset-overview-content.cjs.map +1 -1
  32. package/dist/components/asset-overview-content.js +2 -2
  33. package/dist/components/asset-overview-content.js.map +1 -1
  34. package/dist/components/asset-picker-cell.cjs +1 -1
  35. package/dist/components/asset-picker-cell.cjs.map +1 -1
  36. package/dist/components/asset-picker-cell.js +1 -1
  37. package/dist/components/asset-picker-cell.js.map +1 -1
  38. package/dist/components/asset-top-sections.cjs +1 -1
  39. package/dist/components/asset-top-sections.cjs.map +1 -1
  40. package/dist/components/asset-top-sections.js +1 -1
  41. package/dist/components/asset-top-sections.js.map +1 -1
  42. package/dist/components/asset-utility-icons.cjs +2 -2
  43. package/dist/components/asset-utility-icons.cjs.map +1 -1
  44. package/dist/components/asset-utility-icons.js +2 -2
  45. package/dist/components/asset-utility-icons.js.map +1 -1
  46. package/dist/components/claim-rail.cjs +1 -1
  47. package/dist/components/claim-rail.cjs.map +1 -1
  48. package/dist/components/claim-rail.js +1 -1
  49. package/dist/components/claim-rail.js.map +1 -1
  50. package/dist/components/coin-card.cjs +4 -4
  51. package/dist/components/coin-card.cjs.map +1 -1
  52. package/dist/components/coin-card.js +4 -4
  53. package/dist/components/coin-card.js.map +1 -1
  54. package/dist/components/coin-launch-preview.cjs +5 -5
  55. package/dist/components/coin-launch-preview.cjs.map +1 -1
  56. package/dist/components/coin-launch-preview.js +5 -5
  57. package/dist/components/coin-launch-preview.js.map +1 -1
  58. package/dist/components/coins-explorer.cjs +3 -3
  59. package/dist/components/coins-explorer.cjs.map +1 -1
  60. package/dist/components/coins-explorer.js +3 -3
  61. package/dist/components/coins-explorer.js.map +1 -1
  62. package/dist/components/collection-card.cjs +6 -6
  63. package/dist/components/collection-card.cjs.map +1 -1
  64. package/dist/components/collection-card.js +6 -6
  65. package/dist/components/collection-card.js.map +1 -1
  66. package/dist/components/collection-filters.cjs +5 -5
  67. package/dist/components/collection-filters.cjs.map +1 -1
  68. package/dist/components/collection-filters.js +5 -5
  69. package/dist/components/collection-filters.js.map +1 -1
  70. package/dist/components/community-rewards-section.cjs +2 -2
  71. package/dist/components/community-rewards-section.cjs.map +1 -1
  72. package/dist/components/community-rewards-section.js +2 -2
  73. package/dist/components/community-rewards-section.js.map +1 -1
  74. package/dist/components/discover-feed-section.cjs +1 -1
  75. package/dist/components/discover-feed-section.cjs.map +1 -1
  76. package/dist/components/discover-feed-section.js +1 -1
  77. package/dist/components/discover-feed-section.js.map +1 -1
  78. package/dist/components/featured-carousel.cjs +4 -4
  79. package/dist/components/featured-carousel.cjs.map +1 -1
  80. package/dist/components/featured-carousel.js +4 -4
  81. package/dist/components/featured-carousel.js.map +1 -1
  82. package/dist/components/gradient-button.cjs +1 -1
  83. package/dist/components/gradient-button.cjs.map +1 -1
  84. package/dist/components/gradient-button.js +1 -1
  85. package/dist/components/gradient-button.js.map +1 -1
  86. package/dist/components/hero-slider.cjs +2 -2
  87. package/dist/components/hero-slider.cjs.map +1 -1
  88. package/dist/components/hero-slider.js +2 -2
  89. package/dist/components/hero-slider.js.map +1 -1
  90. package/dist/components/launchpad-filter-bar.cjs +1 -1
  91. package/dist/components/launchpad-filter-bar.cjs.map +1 -1
  92. package/dist/components/launchpad-filter-bar.js +1 -1
  93. package/dist/components/launchpad-filter-bar.js.map +1 -1
  94. package/dist/components/launchpad-services.cjs +5 -5
  95. package/dist/components/launchpad-services.cjs.map +1 -1
  96. package/dist/components/launchpad-services.js +5 -5
  97. package/dist/components/launchpad-services.js.map +1 -1
  98. package/dist/components/launchpad-strip.cjs +4 -4
  99. package/dist/components/launchpad-strip.cjs.map +1 -1
  100. package/dist/components/launchpad-strip.js +4 -4
  101. package/dist/components/launchpad-strip.js.map +1 -1
  102. package/dist/components/listing-card.cjs +7 -7
  103. package/dist/components/listing-card.cjs.map +1 -1
  104. package/dist/components/listing-card.js +7 -7
  105. package/dist/components/listing-card.js.map +1 -1
  106. package/dist/components/medialane-collection-card.cjs +2 -2
  107. package/dist/components/medialane-collection-card.cjs.map +1 -1
  108. package/dist/components/medialane-collection-card.js +2 -2
  109. package/dist/components/medialane-collection-card.js.map +1 -1
  110. package/dist/components/nav-command-menu.cjs +5 -5
  111. package/dist/components/nav-command-menu.cjs.map +1 -1
  112. package/dist/components/nav-command-menu.js +5 -5
  113. package/dist/components/nav-command-menu.js.map +1 -1
  114. package/dist/components/nav-shell.cjs +2 -2
  115. package/dist/components/nav-shell.cjs.map +1 -1
  116. package/dist/components/nav-shell.js +2 -2
  117. package/dist/components/nav-shell.js.map +1 -1
  118. package/dist/components/portfolio-chip-filter.cjs +1 -1
  119. package/dist/components/portfolio-chip-filter.cjs.map +1 -1
  120. package/dist/components/portfolio-chip-filter.js +1 -1
  121. package/dist/components/portfolio-chip-filter.js.map +1 -1
  122. package/dist/components/portfolio-nav.cjs +2 -2
  123. package/dist/components/portfolio-nav.cjs.map +1 -1
  124. package/dist/components/portfolio-nav.js +2 -2
  125. package/dist/components/portfolio-nav.js.map +1 -1
  126. package/dist/components/rewards/journey-path.cjs +2 -2
  127. package/dist/components/rewards/journey-path.cjs.map +1 -1
  128. package/dist/components/rewards/journey-path.js +2 -2
  129. package/dist/components/rewards/journey-path.js.map +1 -1
  130. package/dist/components/rewards/leaderboard-table.cjs +11 -11
  131. package/dist/components/rewards/leaderboard-table.cjs.map +1 -1
  132. package/dist/components/rewards/leaderboard-table.d.cts +3 -1
  133. package/dist/components/rewards/leaderboard-table.d.ts +3 -1
  134. package/dist/components/rewards/leaderboard-table.js +11 -11
  135. package/dist/components/rewards/leaderboard-table.js.map +1 -1
  136. package/dist/components/rewards/level-badge.cjs +1 -1
  137. package/dist/components/rewards/level-badge.cjs.map +1 -1
  138. package/dist/components/rewards/level-badge.js +1 -1
  139. package/dist/components/rewards/level-badge.js.map +1 -1
  140. package/dist/components/rewards/level-ladder.cjs +2 -2
  141. package/dist/components/rewards/level-ladder.cjs.map +1 -1
  142. package/dist/components/rewards/level-ladder.js +2 -2
  143. package/dist/components/rewards/level-ladder.js.map +1 -1
  144. package/dist/components/scroll-section.cjs +1 -1
  145. package/dist/components/scroll-section.cjs.map +1 -1
  146. package/dist/components/scroll-section.js +1 -1
  147. package/dist/components/scroll-section.js.map +1 -1
  148. package/dist/components/share-button.cjs +1 -1
  149. package/dist/components/share-button.cjs.map +1 -1
  150. package/dist/components/share-button.js +1 -1
  151. package/dist/components/share-button.js.map +1 -1
  152. package/dist/components/stat-tile.cjs +3 -3
  153. package/dist/components/stat-tile.cjs.map +1 -1
  154. package/dist/components/stat-tile.js +3 -3
  155. package/dist/components/stat-tile.js.map +1 -1
  156. package/dist/components/token-card.cjs +4 -4
  157. package/dist/components/token-card.cjs.map +1 -1
  158. package/dist/components/token-card.js +4 -4
  159. package/dist/components/token-card.js.map +1 -1
  160. package/dist/data/brand.cjs +0 -14
  161. package/dist/data/brand.cjs.map +1 -1
  162. package/dist/data/brand.d.cts +0 -14
  163. package/dist/data/brand.d.ts +0 -14
  164. package/dist/data/brand.js +0 -14
  165. package/dist/data/brand.js.map +1 -1
  166. package/dist/medialane.css +4 -0
  167. package/dist/preset/tailwind.cjs +16 -8
  168. package/dist/preset/tailwind.cjs.map +1 -1
  169. package/dist/preset/tailwind.js +16 -8
  170. package/dist/preset/tailwind.js.map +1 -1
  171. package/package.json +6 -3
@@ -27,24 +27,24 @@ var import_cn = require("../../utils/cn.js");
27
27
  var import_address = require("../../utils/address.js");
28
28
  var import_level_badge = require("./level-badge.js");
29
29
  function LeaderboardTable({ entries, highlightAddress, renderAddress, className }) {
30
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("overflow-hidden rounded-xl border border-border", className), children: entries.map((e) => {
30
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("space-y-1.5", className), children: entries.map((e) => {
31
31
  const isViewer = highlightAddress != null && e.address === highlightAddress;
32
32
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
33
33
  "div",
34
34
  {
35
35
  className: (0, import_cn.cn)(
36
- "flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4",
37
- isViewer && "bg-primary/10"
36
+ "flex items-center gap-4 rounded-2xl px-4 py-3.5 transition-colors",
37
+ isViewer ? "bg-brand-rose/10" : "bg-foreground/[0.04] hover:bg-foreground/[0.07]"
38
38
  ),
39
39
  children: [
40
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: [
40
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "min-w-0 flex-1 truncate text-base font-bold", children: [
41
41
  renderAddress ? renderAddress(e.address) : (0, import_address.shortenAddress)(e.address),
42
- isViewer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-1.5 text-xs text-muted-foreground", children: "(you)" })
42
+ isViewer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-1.5 text-xs font-medium text-foreground/50", children: "(you)" })
43
43
  ] }),
44
44
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_level_badge.LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm", className: "hidden sm:inline-flex" }),
45
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "shrink-0 text-sm font-semibold tabular-nums", children: [
45
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "shrink-0 text-lg font-black tabular-nums", children: [
46
46
  e.totalXp.toLocaleString(),
47
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "XP" })
47
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-1 text-xs font-bold text-foreground/40", children: "XP" })
48
48
  ] })
49
49
  ]
50
50
  },
@@ -54,13 +54,13 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
54
54
  }
55
55
  function LeaderboardWidget({ entries, title = "Community Rewards", href, renderAddress, className }) {
56
56
  if (entries.length === 0) return null;
57
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: (0, import_cn.cn)("rounded-xl border border-border bg-card p-4 sm:p-5", className), children: [
57
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: (0, import_cn.cn)("rounded-2xl bg-foreground/[0.04] p-5", className), children: [
58
58
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mb-3 flex items-center justify-between", children: [
59
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-base font-black", children: title }),
60
- href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, className: "text-xs font-semibold text-muted-foreground active:opacity-70", children: "View scoreboard \u2192" })
59
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-black", children: title }),
60
+ href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, className: "text-xs font-bold text-foreground/50 hover:text-foreground active:opacity-70", children: "View scoreboard \u2192" })
61
61
  ] }),
62
62
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "space-y-2.5", children: entries.map((e) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "flex items-center gap-2.5", children: [
63
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: renderAddress ? renderAddress(e.address) : (0, import_address.shortenAddress)(e.address) }),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm font-bold", children: renderAddress ? renderAddress(e.address) : (0, import_address.shortenAddress)(e.address) }),
64
64
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_level_badge.LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm" })
65
65
  ] }, e.address)) })
66
66
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n /** Kept for API compatibility with the backend's ordered response — not\n * rendered. This is a scoreboard, not a ranking: no \"#1/#2/#3\", no podium\n * colors. Order in the array is still the sort order the caller gets. */\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Scoreboard rows: address, level chip, points. No position number or\n * podium coloring — this celebrates participation, not competition. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"overflow-hidden rounded-xl border border-border\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4\",\n isViewer && \"bg-primary/10\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs text-muted-foreground\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-semibold tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-normal text-muted-foreground\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full scoreboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-base font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-semibold text-muted-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CY;AAzCZ,gBAAmB;AACnB,qBAA+B;AAC/B,yBAA2B;AA0BpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,4CAAC,SAAI,eAAW,cAAG,mDAAmD,SAAS,GAC5E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,eAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEA;AAAA,uDAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO;AAAA,YACnE,YAAY,4CAAC,UAAK,WAAU,wCAAuC,mBAAK;AAAA,aAC3E;AAAA,UACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,6CAAC,UAAK,WAAU,+CACb;AAAA,cAAE,QAAQ,eAAe;AAAA,YAC1B,4CAAC,UAAK,WAAU,kDAAiD,gBAAE;AAAA,aACrE;AAAA;AAAA;AAAA,MAdK,EAAE;AAAA,IAeT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,6CAAC,aAAQ,eAAW,cAAG,sDAAsD,SAAS,GACpF;AAAA,iDAAC,SAAI,WAAU,0CACb;AAAA,kDAAC,QAAG,WAAU,wBAAwB,iBAAM;AAAA,MAC3C,QACC,4CAAC,OAAE,MAAY,WAAU,iEAAgE,oCAEzF;AAAA,OAEJ;AAAA,IACA,4CAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,6CAAC,QAAmB,WAAU,6BAC5B;AAAA,kDAAC,UAAK,WAAU,+CACb,0BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO,GACtE;AAAA,MACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n /** Kept for API compatibility with the backend's ordered response — not\n * rendered. This is a scoreboard, not a ranking: no \"#1/#2/#3\", no podium\n * colors. Order in the array is still the sort order the caller gets. */\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Scoreboard rows: address, level chip, points. No position number or\n * podium coloring — this celebrates participation, not competition.\n * Each row is its own rounded tile with real padding, not a bordered\n * list with hairline dividers. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-4 rounded-2xl px-4 py-3.5 transition-colors\",\n isViewer ? \"bg-brand-rose/10\" : \"bg-foreground/[0.04] hover:bg-foreground/[0.07]\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-base font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs font-medium text-foreground/50\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-lg font-black tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-bold text-foreground/40\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full scoreboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-2xl bg-foreground/[0.04] p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-lg font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-bold text-foreground/50 hover:text-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4CY;AA3CZ,gBAAmB;AACnB,qBAA+B;AAC/B,yBAA2B;AA4BpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,4CAAC,SAAI,eAAW,cAAG,eAAe,SAAS,GACxC,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,eAAW;AAAA,UACT;AAAA,UACA,WAAW,qBAAqB;AAAA,QAClC;AAAA,QAEA;AAAA,uDAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO;AAAA,YACnE,YAAY,4CAAC,UAAK,WAAU,iDAAgD,mBAAK;AAAA,aACpF;AAAA,UACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,6CAAC,UAAK,WAAU,4CACb;AAAA,cAAE,QAAQ,eAAe;AAAA,YAC1B,4CAAC,UAAK,WAAU,6CAA4C,gBAAE;AAAA,aAChE;AAAA;AAAA;AAAA,MAdK,EAAE;AAAA,IAeT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,6CAAC,aAAQ,eAAW,cAAG,wCAAwC,SAAS,GACtE;AAAA,iDAAC,SAAI,WAAU,0CACb;AAAA,kDAAC,QAAG,WAAU,sBAAsB,iBAAM;AAAA,MACzC,QACC,4CAAC,OAAE,MAAY,WAAU,gFAA+E,oCAExG;AAAA,OAEJ;AAAA,IACA,4CAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,6CAAC,QAAmB,WAAU,6BAC5B;AAAA,kDAAC,UAAK,WAAU,6CACb,0BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO,GACtE;AAAA,MACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
@@ -22,7 +22,9 @@ interface LeaderboardTableProps {
22
22
  className?: string;
23
23
  }
24
24
  /** Scoreboard rows: address, level chip, points. No position number or
25
- * podium coloring — this celebrates participation, not competition. */
25
+ * podium coloring — this celebrates participation, not competition.
26
+ * Each row is its own rounded tile with real padding, not a bordered
27
+ * list with hairline dividers. */
26
28
  declare function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps): react_jsx_runtime.JSX.Element;
27
29
  interface LeaderboardWidgetProps {
28
30
  entries: LeaderboardEntryLike[];
@@ -22,7 +22,9 @@ interface LeaderboardTableProps {
22
22
  className?: string;
23
23
  }
24
24
  /** Scoreboard rows: address, level chip, points. No position number or
25
- * podium coloring — this celebrates participation, not competition. */
25
+ * podium coloring — this celebrates participation, not competition.
26
+ * Each row is its own rounded tile with real padding, not a bordered
27
+ * list with hairline dividers. */
26
28
  declare function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps): react_jsx_runtime.JSX.Element;
27
29
  interface LeaderboardWidgetProps {
28
30
  entries: LeaderboardEntryLike[];
@@ -3,24 +3,24 @@ import { cn } from "../../utils/cn.js";
3
3
  import { shortenAddress } from "../../utils/address.js";
4
4
  import { LevelBadge } from "./level-badge.js";
5
5
  function LeaderboardTable({ entries, highlightAddress, renderAddress, className }) {
6
- return /* @__PURE__ */ jsx("div", { className: cn("overflow-hidden rounded-xl border border-border", className), children: entries.map((e) => {
6
+ return /* @__PURE__ */ jsx("div", { className: cn("space-y-1.5", className), children: entries.map((e) => {
7
7
  const isViewer = highlightAddress != null && e.address === highlightAddress;
8
8
  return /* @__PURE__ */ jsxs(
9
9
  "div",
10
10
  {
11
11
  className: cn(
12
- "flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4",
13
- isViewer && "bg-primary/10"
12
+ "flex items-center gap-4 rounded-2xl px-4 py-3.5 transition-colors",
13
+ isViewer ? "bg-brand-rose/10" : "bg-foreground/[0.04] hover:bg-foreground/[0.07]"
14
14
  ),
15
15
  children: [
16
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: [
16
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate text-base font-bold", children: [
17
17
  renderAddress ? renderAddress(e.address) : shortenAddress(e.address),
18
- isViewer && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs text-muted-foreground", children: "(you)" })
18
+ isViewer && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs font-medium text-foreground/50", children: "(you)" })
19
19
  ] }),
20
20
  /* @__PURE__ */ jsx(LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm", className: "hidden sm:inline-flex" }),
21
- /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-sm font-semibold tabular-nums", children: [
21
+ /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-lg font-black tabular-nums", children: [
22
22
  e.totalXp.toLocaleString(),
23
- /* @__PURE__ */ jsx("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "XP" })
23
+ /* @__PURE__ */ jsx("span", { className: "ml-1 text-xs font-bold text-foreground/40", children: "XP" })
24
24
  ] })
25
25
  ]
26
26
  },
@@ -30,13 +30,13 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
30
30
  }
31
31
  function LeaderboardWidget({ entries, title = "Community Rewards", href, renderAddress, className }) {
32
32
  if (entries.length === 0) return null;
33
- return /* @__PURE__ */ jsxs("section", { className: cn("rounded-xl border border-border bg-card p-4 sm:p-5", className), children: [
33
+ return /* @__PURE__ */ jsxs("section", { className: cn("rounded-2xl bg-foreground/[0.04] p-5", className), children: [
34
34
  /* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between", children: [
35
- /* @__PURE__ */ jsx("h2", { className: "text-base font-black", children: title }),
36
- href && /* @__PURE__ */ jsx("a", { href, className: "text-xs font-semibold text-muted-foreground active:opacity-70", children: "View scoreboard \u2192" })
35
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-black", children: title }),
36
+ href && /* @__PURE__ */ jsx("a", { href, className: "text-xs font-bold text-foreground/50 hover:text-foreground active:opacity-70", children: "View scoreboard \u2192" })
37
37
  ] }),
38
38
  /* @__PURE__ */ jsx("ol", { className: "space-y-2.5", children: entries.map((e) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2.5", children: [
39
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: renderAddress ? renderAddress(e.address) : shortenAddress(e.address) }),
39
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-bold", children: renderAddress ? renderAddress(e.address) : shortenAddress(e.address) }),
40
40
  /* @__PURE__ */ jsx(LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm" })
41
41
  ] }, e.address)) })
42
42
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n /** Kept for API compatibility with the backend's ordered response — not\n * rendered. This is a scoreboard, not a ranking: no \"#1/#2/#3\", no podium\n * colors. Order in the array is still the sort order the caller gets. */\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Scoreboard rows: address, level chip, points. No position number or\n * podium coloring — this celebrates participation, not competition. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"overflow-hidden rounded-xl border border-border\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4\",\n isViewer && \"bg-primary/10\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs text-muted-foreground\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-semibold tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-normal text-muted-foreground\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full scoreboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-base font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-semibold text-muted-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":"AA0CY,SAEe,KAFf;AAzCZ,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AA0BpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,oBAAC,SAAI,WAAW,GAAG,mDAAmD,SAAS,GAC5E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEA;AAAA,+BAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO;AAAA,YACnE,YAAY,oBAAC,UAAK,WAAU,wCAAuC,mBAAK;AAAA,aAC3E;AAAA,UACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,qBAAC,UAAK,WAAU,+CACb;AAAA,cAAE,QAAQ,eAAe;AAAA,YAC1B,oBAAC,UAAK,WAAU,kDAAiD,gBAAE;AAAA,aACrE;AAAA;AAAA;AAAA,MAdK,EAAE;AAAA,IAeT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,qBAAC,aAAQ,WAAW,GAAG,sDAAsD,SAAS,GACpF;AAAA,yBAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,QAAG,WAAU,wBAAwB,iBAAM;AAAA,MAC3C,QACC,oBAAC,OAAE,MAAY,WAAU,iEAAgE,oCAEzF;AAAA,OAEJ;AAAA,IACA,oBAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,qBAAC,QAAmB,WAAU,6BAC5B;AAAA,0BAAC,UAAK,WAAU,+CACb,0BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,GACtE;AAAA,MACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n /** Kept for API compatibility with the backend's ordered response — not\n * rendered. This is a scoreboard, not a ranking: no \"#1/#2/#3\", no podium\n * colors. Order in the array is still the sort order the caller gets. */\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Scoreboard rows: address, level chip, points. No position number or\n * podium coloring — this celebrates participation, not competition.\n * Each row is its own rounded tile with real padding, not a bordered\n * list with hairline dividers. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-4 rounded-2xl px-4 py-3.5 transition-colors\",\n isViewer ? \"bg-brand-rose/10\" : \"bg-foreground/[0.04] hover:bg-foreground/[0.07]\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-base font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs font-medium text-foreground/50\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-lg font-black tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-bold text-foreground/40\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full scoreboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-2xl bg-foreground/[0.04] p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-lg font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-bold text-foreground/50 hover:text-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":"AA4CY,SAEe,KAFf;AA3CZ,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AA4BpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,oBAAC,SAAI,WAAW,GAAG,eAAe,SAAS,GACxC,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,WAAW,qBAAqB;AAAA,QAClC;AAAA,QAEA;AAAA,+BAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO;AAAA,YACnE,YAAY,oBAAC,UAAK,WAAU,iDAAgD,mBAAK;AAAA,aACpF;AAAA,UACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,qBAAC,UAAK,WAAU,4CACb;AAAA,cAAE,QAAQ,eAAe;AAAA,YAC1B,oBAAC,UAAK,WAAU,6CAA4C,gBAAE;AAAA,aAChE;AAAA;AAAA;AAAA,MAdK,EAAE;AAAA,IAeT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,qBAAC,aAAQ,WAAW,GAAG,wCAAwC,SAAS,GACtE;AAAA,yBAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,QAAG,WAAU,sBAAsB,iBAAM;AAAA,MACzC,QACC,oBAAC,OAAE,MAAY,WAAU,gFAA+E,oCAExG;AAAA,OAEJ;AAAA,IACA,oBAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,qBAAC,QAAmB,WAAU,6BAC5B;AAAA,0BAAC,UAAK,WAAU,6CACb,0BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,GACtE;AAAA,MACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
@@ -25,7 +25,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_cn = require("../../utils/cn.js");
26
26
  function LevelBadge({ level, name, badgeColor, size = "md", className }) {
27
27
  const sizeClasses = {
28
- sm: "h-5 px-1.5 gap-1 text-[10px]",
28
+ sm: "h-5 px-1.5 gap-1 text-2xs",
29
29
  md: "h-6 px-2 gap-1.5 text-xs",
30
30
  lg: "h-8 px-3 gap-2 text-sm"
31
31
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/level-badge.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelBadgeProps {\n level: number;\n name: string;\n badgeColor: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Color-coded level chip — shows the level's title only (\"Voyager\"), not\n * the raw number (\"Lv.6 Voyager\" read as UI noise). The level is still\n * available on hover via the native title tooltip. Pure presentation — the\n * consuming app supplies level data from the rewards API. */\nexport function LevelBadge({ level, name, badgeColor, size = \"md\", className }: LevelBadgeProps) {\n const sizeClasses = {\n sm: \"h-5 px-1.5 gap-1 text-[10px]\",\n md: \"h-6 px-2 gap-1.5 text-xs\",\n lg: \"h-8 px-3 gap-2 text-sm\",\n };\n\n const dotSizes = {\n sm: \"h-1.5 w-1.5\",\n md: \"h-2 w-2\",\n lg: \"h-2.5 w-2.5\",\n };\n\n return (\n <span\n title={`Level ${level}`}\n className={cn(\n \"inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap\",\n sizeClasses[size],\n className\n )}\n style={{ borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor }}\n >\n <span className={cn(\"rounded-full shrink-0\", dotSizes[size])} style={{ backgroundColor: badgeColor }} />\n {name}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BI;AA5BJ,gBAAmB;AAcZ,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,GAAoB;AAC/F,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,QAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,SAAS,KAAK;AAAA,MACrB,eAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,GAAG,UAAU,MAAM,iBAAiB,GAAG,UAAU,MAAM,OAAO,WAAW;AAAA,MAE/F;AAAA,oDAAC,UAAK,eAAW,cAAG,yBAAyB,SAAS,IAAI,CAAC,GAAG,OAAO,EAAE,iBAAiB,WAAW,GAAG;AAAA,QACrG;AAAA;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/level-badge.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelBadgeProps {\n level: number;\n name: string;\n badgeColor: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Color-coded level chip — shows the level's title only (\"Voyager\"), not\n * the raw number (\"Lv.6 Voyager\" read as UI noise). The level is still\n * available on hover via the native title tooltip. Pure presentation — the\n * consuming app supplies level data from the rewards API. */\nexport function LevelBadge({ level, name, badgeColor, size = \"md\", className }: LevelBadgeProps) {\n const sizeClasses = {\n sm: \"h-5 px-1.5 gap-1 text-2xs\",\n md: \"h-6 px-2 gap-1.5 text-xs\",\n lg: \"h-8 px-3 gap-2 text-sm\",\n };\n\n const dotSizes = {\n sm: \"h-1.5 w-1.5\",\n md: \"h-2 w-2\",\n lg: \"h-2.5 w-2.5\",\n };\n\n return (\n <span\n title={`Level ${level}`}\n className={cn(\n \"inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap\",\n sizeClasses[size],\n className\n )}\n style={{ borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor }}\n >\n <span className={cn(\"rounded-full shrink-0\", dotSizes[size])} style={{ backgroundColor: badgeColor }} />\n {name}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BI;AA5BJ,gBAAmB;AAcZ,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,GAAoB;AAC/F,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,QAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,SAAS,KAAK;AAAA,MACrB,eAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,GAAG,UAAU,MAAM,iBAAiB,GAAG,UAAU,MAAM,OAAO,WAAW;AAAA,MAE/F;AAAA,oDAAC,UAAK,eAAW,cAAG,yBAAyB,SAAS,IAAI,CAAC,GAAG,OAAO,EAAE,iBAAiB,WAAW,GAAG;AAAA,QACrG;AAAA;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../../utils/cn.js";
3
3
  function LevelBadge({ level, name, badgeColor, size = "md", className }) {
4
4
  const sizeClasses = {
5
- sm: "h-5 px-1.5 gap-1 text-[10px]",
5
+ sm: "h-5 px-1.5 gap-1 text-2xs",
6
6
  md: "h-6 px-2 gap-1.5 text-xs",
7
7
  lg: "h-8 px-3 gap-2 text-sm"
8
8
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/level-badge.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelBadgeProps {\n level: number;\n name: string;\n badgeColor: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Color-coded level chip — shows the level's title only (\"Voyager\"), not\n * the raw number (\"Lv.6 Voyager\" read as UI noise). The level is still\n * available on hover via the native title tooltip. Pure presentation — the\n * consuming app supplies level data from the rewards API. */\nexport function LevelBadge({ level, name, badgeColor, size = \"md\", className }: LevelBadgeProps) {\n const sizeClasses = {\n sm: \"h-5 px-1.5 gap-1 text-[10px]\",\n md: \"h-6 px-2 gap-1.5 text-xs\",\n lg: \"h-8 px-3 gap-2 text-sm\",\n };\n\n const dotSizes = {\n sm: \"h-1.5 w-1.5\",\n md: \"h-2 w-2\",\n lg: \"h-2.5 w-2.5\",\n };\n\n return (\n <span\n title={`Level ${level}`}\n className={cn(\n \"inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap\",\n sizeClasses[size],\n className\n )}\n style={{ borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor }}\n >\n <span className={cn(\"rounded-full shrink-0\", dotSizes[size])} style={{ backgroundColor: badgeColor }} />\n {name}\n </span>\n );\n}\n"],"mappings":"AA4BI,SASE,KATF;AA5BJ,SAAS,UAAU;AAcZ,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,GAAoB;AAC/F,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,QAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,SAAS,KAAK;AAAA,MACrB,WAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,GAAG,UAAU,MAAM,iBAAiB,GAAG,UAAU,MAAM,OAAO,WAAW;AAAA,MAE/F;AAAA,4BAAC,UAAK,WAAW,GAAG,yBAAyB,SAAS,IAAI,CAAC,GAAG,OAAO,EAAE,iBAAiB,WAAW,GAAG;AAAA,QACrG;AAAA;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/level-badge.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelBadgeProps {\n level: number;\n name: string;\n badgeColor: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Color-coded level chip — shows the level's title only (\"Voyager\"), not\n * the raw number (\"Lv.6 Voyager\" read as UI noise). The level is still\n * available on hover via the native title tooltip. Pure presentation — the\n * consuming app supplies level data from the rewards API. */\nexport function LevelBadge({ level, name, badgeColor, size = \"md\", className }: LevelBadgeProps) {\n const sizeClasses = {\n sm: \"h-5 px-1.5 gap-1 text-2xs\",\n md: \"h-6 px-2 gap-1.5 text-xs\",\n lg: \"h-8 px-3 gap-2 text-sm\",\n };\n\n const dotSizes = {\n sm: \"h-1.5 w-1.5\",\n md: \"h-2 w-2\",\n lg: \"h-2.5 w-2.5\",\n };\n\n return (\n <span\n title={`Level ${level}`}\n className={cn(\n \"inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap\",\n sizeClasses[size],\n className\n )}\n style={{ borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor }}\n >\n <span className={cn(\"rounded-full shrink-0\", dotSizes[size])} style={{ backgroundColor: badgeColor }} />\n {name}\n </span>\n );\n}\n"],"mappings":"AA4BI,SASE,KATF;AA5BJ,SAAS,UAAU;AAcZ,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,GAAoB;AAC/F,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,QAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,SAAS,KAAK;AAAA,MACrB,WAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,GAAG,UAAU,MAAM,iBAAiB,GAAG,UAAU,MAAM,OAAO,WAAW;AAAA,MAE/F;AAAA,4BAAC,UAAK,WAAW,GAAG,yBAAyB,SAAS,IAAI,CAAC,GAAG,OAAO,EAAE,iBAAiB,WAAW,GAAG;AAAA,QACrG;AAAA;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -39,8 +39,8 @@ function LevelLadder({ levels, currentLevel, className }) {
39
39
  backgroundColor: state === "current" ? `${l.badgeColor}22` : `${l.badgeColor}0d`
40
40
  },
41
41
  children: [
42
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] font-black tabular-nums", style: { color: l.badgeColor }, children: l.level }),
43
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "whitespace-nowrap text-[10px] font-semibold", style: { color: l.badgeColor }, children: l.name })
42
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-2xs font-black tabular-nums", style: { color: l.badgeColor }, children: l.level }),
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "whitespace-nowrap text-2xs font-semibold", style: { color: l.badgeColor }, children: l.name })
44
44
  ]
45
45
  },
46
46
  l.level
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/level-ladder.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelLadderProps {\n levels: { level: number; name: string; xpRequired: number; badgeColor: string }[];\n currentLevel: number;\n className?: string;\n}\n\n/** The full level arc as a horizontally scrollable chip rail; the current\n * level is highlighted, passed levels render solid, future ones muted. */\nexport function LevelLadder({ levels, currentLevel, className }: LevelLadderProps) {\n return (\n <div className={cn(\"flex gap-2 overflow-x-auto pb-2\", className)}>\n {levels.map((l) => {\n const state = l.level < currentLevel ? \"done\" : l.level === currentLevel ? \"current\" : \"future\";\n return (\n <div\n key={l.level}\n title={`${l.xpRequired.toLocaleString()} XP`}\n className={cn(\n \"flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5\",\n state === \"future\" && \"opacity-45\"\n )}\n style={{\n borderColor: state === \"current\" ? l.badgeColor : `${l.badgeColor}40`,\n backgroundColor: state === \"current\" ? `${l.badgeColor}22` : `${l.badgeColor}0d`,\n }}\n >\n <span className=\"text-[10px] font-black tabular-nums\" style={{ color: l.badgeColor }}>\n {l.level}\n </span>\n <span className=\"whitespace-nowrap text-[10px] font-semibold\" style={{ color: l.badgeColor }}>\n {l.name}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBU;AAhBV,gBAAmB;AAUZ,SAAS,YAAY,EAAE,QAAQ,cAAc,UAAU,GAAqB;AACjF,SACE,4CAAC,SAAI,eAAW,cAAG,mCAAmC,SAAS,GAC5D,iBAAO,IAAI,CAAC,MAAM;AACjB,UAAM,QAAQ,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,eAAe,YAAY;AACvF,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,GAAG,EAAE,WAAW,eAAe,CAAC;AAAA,QACvC,eAAW;AAAA,UACT;AAAA,UACA,UAAU,YAAY;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,UACL,aAAa,UAAU,YAAY,EAAE,aAAa,GAAG,EAAE,UAAU;AAAA,UACjE,iBAAiB,UAAU,YAAY,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,UAAU;AAAA,QAC9E;AAAA,QAEA;AAAA,sDAAC,UAAK,WAAU,uCAAsC,OAAO,EAAE,OAAO,EAAE,WAAW,GAChF,YAAE,OACL;AAAA,UACA,4CAAC,UAAK,WAAU,+CAA8C,OAAO,EAAE,OAAO,EAAE,WAAW,GACxF,YAAE,MACL;AAAA;AAAA;AAAA,MAhBK,EAAE;AAAA,IAiBT;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/level-ladder.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelLadderProps {\n levels: { level: number; name: string; xpRequired: number; badgeColor: string }[];\n currentLevel: number;\n className?: string;\n}\n\n/** The full level arc as a horizontally scrollable chip rail; the current\n * level is highlighted, passed levels render solid, future ones muted. */\nexport function LevelLadder({ levels, currentLevel, className }: LevelLadderProps) {\n return (\n <div className={cn(\"flex gap-2 overflow-x-auto pb-2\", className)}>\n {levels.map((l) => {\n const state = l.level < currentLevel ? \"done\" : l.level === currentLevel ? \"current\" : \"future\";\n return (\n <div\n key={l.level}\n title={`${l.xpRequired.toLocaleString()} XP`}\n className={cn(\n \"flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5\",\n state === \"future\" && \"opacity-45\"\n )}\n style={{\n borderColor: state === \"current\" ? l.badgeColor : `${l.badgeColor}40`,\n backgroundColor: state === \"current\" ? `${l.badgeColor}22` : `${l.badgeColor}0d`,\n }}\n >\n <span className=\"text-2xs font-black tabular-nums\" style={{ color: l.badgeColor }}>\n {l.level}\n </span>\n <span className=\"whitespace-nowrap text-2xs font-semibold\" style={{ color: l.badgeColor }}>\n {l.name}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBU;AAhBV,gBAAmB;AAUZ,SAAS,YAAY,EAAE,QAAQ,cAAc,UAAU,GAAqB;AACjF,SACE,4CAAC,SAAI,eAAW,cAAG,mCAAmC,SAAS,GAC5D,iBAAO,IAAI,CAAC,MAAM;AACjB,UAAM,QAAQ,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,eAAe,YAAY;AACvF,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,GAAG,EAAE,WAAW,eAAe,CAAC;AAAA,QACvC,eAAW;AAAA,UACT;AAAA,UACA,UAAU,YAAY;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,UACL,aAAa,UAAU,YAAY,EAAE,aAAa,GAAG,EAAE,UAAU;AAAA,UACjE,iBAAiB,UAAU,YAAY,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,UAAU;AAAA,QAC9E;AAAA,QAEA;AAAA,sDAAC,UAAK,WAAU,oCAAmC,OAAO,EAAE,OAAO,EAAE,WAAW,GAC7E,YAAE,OACL;AAAA,UACA,4CAAC,UAAK,WAAU,4CAA2C,OAAO,EAAE,OAAO,EAAE,WAAW,GACrF,YAAE,MACL;AAAA;AAAA;AAAA,MAhBK,EAAE;AAAA,IAiBT;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
@@ -16,8 +16,8 @@ function LevelLadder({ levels, currentLevel, className }) {
16
16
  backgroundColor: state === "current" ? `${l.badgeColor}22` : `${l.badgeColor}0d`
17
17
  },
18
18
  children: [
19
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-black tabular-nums", style: { color: l.badgeColor }, children: l.level }),
20
- /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-[10px] font-semibold", style: { color: l.badgeColor }, children: l.name })
19
+ /* @__PURE__ */ jsx("span", { className: "text-2xs font-black tabular-nums", style: { color: l.badgeColor }, children: l.level }),
20
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-2xs font-semibold", style: { color: l.badgeColor }, children: l.name })
21
21
  ]
22
22
  },
23
23
  l.level
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/level-ladder.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelLadderProps {\n levels: { level: number; name: string; xpRequired: number; badgeColor: string }[];\n currentLevel: number;\n className?: string;\n}\n\n/** The full level arc as a horizontally scrollable chip rail; the current\n * level is highlighted, passed levels render solid, future ones muted. */\nexport function LevelLadder({ levels, currentLevel, className }: LevelLadderProps) {\n return (\n <div className={cn(\"flex gap-2 overflow-x-auto pb-2\", className)}>\n {levels.map((l) => {\n const state = l.level < currentLevel ? \"done\" : l.level === currentLevel ? \"current\" : \"future\";\n return (\n <div\n key={l.level}\n title={`${l.xpRequired.toLocaleString()} XP`}\n className={cn(\n \"flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5\",\n state === \"future\" && \"opacity-45\"\n )}\n style={{\n borderColor: state === \"current\" ? l.badgeColor : `${l.badgeColor}40`,\n backgroundColor: state === \"current\" ? `${l.badgeColor}22` : `${l.badgeColor}0d`,\n }}\n >\n <span className=\"text-[10px] font-black tabular-nums\" style={{ color: l.badgeColor }}>\n {l.level}\n </span>\n <span className=\"whitespace-nowrap text-[10px] font-semibold\" style={{ color: l.badgeColor }}>\n {l.name}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"AAgBU,SAYE,KAZF;AAhBV,SAAS,UAAU;AAUZ,SAAS,YAAY,EAAE,QAAQ,cAAc,UAAU,GAAqB;AACjF,SACE,oBAAC,SAAI,WAAW,GAAG,mCAAmC,SAAS,GAC5D,iBAAO,IAAI,CAAC,MAAM;AACjB,UAAM,QAAQ,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,eAAe,YAAY;AACvF,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,GAAG,EAAE,WAAW,eAAe,CAAC;AAAA,QACvC,WAAW;AAAA,UACT;AAAA,UACA,UAAU,YAAY;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,UACL,aAAa,UAAU,YAAY,EAAE,aAAa,GAAG,EAAE,UAAU;AAAA,UACjE,iBAAiB,UAAU,YAAY,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,UAAU;AAAA,QAC9E;AAAA,QAEA;AAAA,8BAAC,UAAK,WAAU,uCAAsC,OAAO,EAAE,OAAO,EAAE,WAAW,GAChF,YAAE,OACL;AAAA,UACA,oBAAC,UAAK,WAAU,+CAA8C,OAAO,EAAE,OAAO,EAAE,WAAW,GACxF,YAAE,MACL;AAAA;AAAA;AAAA,MAhBK,EAAE;AAAA,IAiBT;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/level-ladder.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelLadderProps {\n levels: { level: number; name: string; xpRequired: number; badgeColor: string }[];\n currentLevel: number;\n className?: string;\n}\n\n/** The full level arc as a horizontally scrollable chip rail; the current\n * level is highlighted, passed levels render solid, future ones muted. */\nexport function LevelLadder({ levels, currentLevel, className }: LevelLadderProps) {\n return (\n <div className={cn(\"flex gap-2 overflow-x-auto pb-2\", className)}>\n {levels.map((l) => {\n const state = l.level < currentLevel ? \"done\" : l.level === currentLevel ? \"current\" : \"future\";\n return (\n <div\n key={l.level}\n title={`${l.xpRequired.toLocaleString()} XP`}\n className={cn(\n \"flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5\",\n state === \"future\" && \"opacity-45\"\n )}\n style={{\n borderColor: state === \"current\" ? l.badgeColor : `${l.badgeColor}40`,\n backgroundColor: state === \"current\" ? `${l.badgeColor}22` : `${l.badgeColor}0d`,\n }}\n >\n <span className=\"text-2xs font-black tabular-nums\" style={{ color: l.badgeColor }}>\n {l.level}\n </span>\n <span className=\"whitespace-nowrap text-2xs font-semibold\" style={{ color: l.badgeColor }}>\n {l.name}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"AAgBU,SAYE,KAZF;AAhBV,SAAS,UAAU;AAUZ,SAAS,YAAY,EAAE,QAAQ,cAAc,UAAU,GAAqB;AACjF,SACE,oBAAC,SAAI,WAAW,GAAG,mCAAmC,SAAS,GAC5D,iBAAO,IAAI,CAAC,MAAM;AACjB,UAAM,QAAQ,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,eAAe,YAAY;AACvF,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,GAAG,EAAE,WAAW,eAAe,CAAC;AAAA,QACvC,WAAW;AAAA,UACT;AAAA,UACA,UAAU,YAAY;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,UACL,aAAa,UAAU,YAAY,EAAE,aAAa,GAAG,EAAE,UAAU;AAAA,UACjE,iBAAiB,UAAU,YAAY,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,UAAU;AAAA,QAC9E;AAAA,QAEA;AAAA,8BAAC,UAAK,WAAU,oCAAmC,OAAO,EAAE,OAAO,EAAE,WAAW,GAC7E,YAAE,OACL;AAAA,UACA,oBAAC,UAAK,WAAU,4CAA2C,OAAO,EAAE,OAAO,EAAE,WAAW,GACrF,YAAE,MACL;AAAA;AAAA;AAAA,MAhBK,EAAE;AAAA,IAiBT;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
@@ -50,7 +50,7 @@ function ScrollSection({
50
50
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`, children: icon }),
51
51
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
52
52
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg sm:text-xl font-semibold leading-none", children: title }),
53
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground mt-1", children: subtitle })
53
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-2xs text-muted-foreground mt-1", children: subtitle })
54
54
  ] })
55
55
  ] }),
56
56
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface ScrollSectionProps {\n /** Icon element rendered inside the colored badge */\n icon: React.ReactNode;\n /** Tailwind classes for the icon badge (background + shadow) */\n iconBg: string;\n title: string;\n /** Optional small line under the title (e.g. \"Updated 1m ago\") */\n subtitle?: React.ReactNode;\n /** \"See all\" link destination */\n href: string;\n /** Button label — defaults to \"See all\" */\n linkLabel?: string;\n /** Scroll items: wrap each in a sized snap-start div */\n children: React.ReactNode;\n}\n\nexport function ScrollSection({\n icon,\n iconBg,\n title,\n subtitle,\n href,\n linkLabel = \"See all\",\n children,\n}: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className={`h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`}>\n {icon}\n </div>\n <div>\n <h2 className=\"text-lg sm:text-xl font-semibold leading-none\">{title}</h2>\n {subtitle && <p className=\"text-[10px] text-muted-foreground mt-1\">{subtitle}</p>}\n </div>\n </div>\n <Link\n href={href}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n {linkLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCU;AAhCV,kBAAiB;AACjB,0BAA2B;AAkBpB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAuB;AACrB,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SAAI,WAAU,6BACb;AAAA,oDAAC,SAAI,WAAW,uDAAuD,MAAM,IAC1E,gBACH;AAAA,QACA,6CAAC,SACC;AAAA,sDAAC,QAAG,WAAU,iDAAiD,iBAAM;AAAA,UACpE,YAAY,4CAAC,OAAE,WAAU,0CAA0C,oBAAS;AAAA,WAC/E;AAAA,SACF;AAAA,MACA;AAAA,QAAC,YAAAA;AAAA,QAAA;AAAA,UACC;AAAA,UACA,WAAU;AAAA,UAET;AAAA;AAAA,YAAU;AAAA,YAAC,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAClD;AAAA,OACF;AAAA,IAEA,4CAAC,SAAI,WAAU,yCACb,sDAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface ScrollSectionProps {\n /** Icon element rendered inside the colored badge */\n icon: React.ReactNode;\n /** Tailwind classes for the icon badge (background + shadow) */\n iconBg: string;\n title: string;\n /** Optional small line under the title (e.g. \"Updated 1m ago\") */\n subtitle?: React.ReactNode;\n /** \"See all\" link destination */\n href: string;\n /** Button label — defaults to \"See all\" */\n linkLabel?: string;\n /** Scroll items: wrap each in a sized snap-start div */\n children: React.ReactNode;\n}\n\nexport function ScrollSection({\n icon,\n iconBg,\n title,\n subtitle,\n href,\n linkLabel = \"See all\",\n children,\n}: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className={`h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`}>\n {icon}\n </div>\n <div>\n <h2 className=\"text-lg sm:text-xl font-semibold leading-none\">{title}</h2>\n {subtitle && <p className=\"text-2xs text-muted-foreground mt-1\">{subtitle}</p>}\n </div>\n </div>\n <Link\n href={href}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n {linkLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCU;AAhCV,kBAAiB;AACjB,0BAA2B;AAkBpB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAuB;AACrB,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SAAI,WAAU,6BACb;AAAA,oDAAC,SAAI,WAAW,uDAAuD,MAAM,IAC1E,gBACH;AAAA,QACA,6CAAC,SACC;AAAA,sDAAC,QAAG,WAAU,iDAAiD,iBAAM;AAAA,UACpE,YAAY,4CAAC,OAAE,WAAU,uCAAuC,oBAAS;AAAA,WAC5E;AAAA,SACF;AAAA,MACA;AAAA,QAAC,YAAAA;AAAA,QAAA;AAAA,UACC;AAAA,UACA,WAAU;AAAA,UAET;AAAA;AAAA,YAAU;AAAA,YAAC,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAClD;AAAA,OACF;AAAA,IAEA,4CAAC,SAAI,WAAU,yCACb,sDAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":["Link"]}
@@ -17,7 +17,7 @@ function ScrollSection({
17
17
  /* @__PURE__ */ jsx("div", { className: `h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`, children: icon }),
18
18
  /* @__PURE__ */ jsxs("div", { children: [
19
19
  /* @__PURE__ */ jsx("h2", { className: "text-lg sm:text-xl font-semibold leading-none", children: title }),
20
- subtitle && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground mt-1", children: subtitle })
20
+ subtitle && /* @__PURE__ */ jsx("p", { className: "text-2xs text-muted-foreground mt-1", children: subtitle })
21
21
  ] })
22
22
  ] }),
23
23
  /* @__PURE__ */ jsxs(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface ScrollSectionProps {\n /** Icon element rendered inside the colored badge */\n icon: React.ReactNode;\n /** Tailwind classes for the icon badge (background + shadow) */\n iconBg: string;\n title: string;\n /** Optional small line under the title (e.g. \"Updated 1m ago\") */\n subtitle?: React.ReactNode;\n /** \"See all\" link destination */\n href: string;\n /** Button label — defaults to \"See all\" */\n linkLabel?: string;\n /** Scroll items: wrap each in a sized snap-start div */\n children: React.ReactNode;\n}\n\nexport function ScrollSection({\n icon,\n iconBg,\n title,\n subtitle,\n href,\n linkLabel = \"See all\",\n children,\n}: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className={`h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`}>\n {icon}\n </div>\n <div>\n <h2 className=\"text-lg sm:text-xl font-semibold leading-none\">{title}</h2>\n {subtitle && <p className=\"text-[10px] text-muted-foreground mt-1\">{subtitle}</p>}\n </div>\n </div>\n <Link\n href={href}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n {linkLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";AAkCU,cAGA,YAHA;AAhCV,OAAO,UAAU;AACjB,SAAS,kBAAkB;AAkBpB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAuB;AACrB,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SAAI,WAAU,6BACb;AAAA,4BAAC,SAAI,WAAW,uDAAuD,MAAM,IAC1E,gBACH;AAAA,QACA,qBAAC,SACC;AAAA,8BAAC,QAAG,WAAU,iDAAiD,iBAAM;AAAA,UACpE,YAAY,oBAAC,OAAE,WAAU,0CAA0C,oBAAS;AAAA,WAC/E;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAU;AAAA,UAET;AAAA;AAAA,YAAU;AAAA,YAAC,oBAAC,cAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAClD;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,yCACb,8BAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface ScrollSectionProps {\n /** Icon element rendered inside the colored badge */\n icon: React.ReactNode;\n /** Tailwind classes for the icon badge (background + shadow) */\n iconBg: string;\n title: string;\n /** Optional small line under the title (e.g. \"Updated 1m ago\") */\n subtitle?: React.ReactNode;\n /** \"See all\" link destination */\n href: string;\n /** Button label — defaults to \"See all\" */\n linkLabel?: string;\n /** Scroll items: wrap each in a sized snap-start div */\n children: React.ReactNode;\n}\n\nexport function ScrollSection({\n icon,\n iconBg,\n title,\n subtitle,\n href,\n linkLabel = \"See all\",\n children,\n}: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className={`h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`}>\n {icon}\n </div>\n <div>\n <h2 className=\"text-lg sm:text-xl font-semibold leading-none\">{title}</h2>\n {subtitle && <p className=\"text-2xs text-muted-foreground mt-1\">{subtitle}</p>}\n </div>\n </div>\n <Link\n href={href}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n {linkLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";AAkCU,cAGA,YAHA;AAhCV,OAAO,UAAU;AACjB,SAAS,kBAAkB;AAkBpB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAuB;AACrB,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SAAI,WAAU,6BACb;AAAA,4BAAC,SAAI,WAAW,uDAAuD,MAAM,IAC1E,gBACH;AAAA,QACA,qBAAC,SACC;AAAA,8BAAC,QAAG,WAAU,iDAAiD,iBAAM;AAAA,UACpE,YAAY,oBAAC,OAAE,WAAU,uCAAuC,oBAAS;AAAA,WAC5E;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAU;AAAA,UAET;AAAA;AAAA,YAAU;AAAA,YAAC,oBAAC,cAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAClD;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,yCACb,8BAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":[]}
@@ -36,7 +36,7 @@ const SIZE_CLASSES = {
36
36
  sm: "h-9 px-3 text-xs rounded-md",
37
37
  default: "h-10 px-4 py-2 text-sm rounded-md",
38
38
  lg: "h-11 px-8 text-sm rounded-md",
39
- icon: "h-9 w-9 rounded-md"
39
+ icon: "min-h-11 min-w-11 rounded-md"
40
40
  };
41
41
  function ShareButton({
42
42
  title,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"h-9 w-9 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n // User cancelled — ignore\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n toast.success(\"Link copied to clipboard\");\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsDI;AApDJ,mBAAyB;AACzB,0BAA8B;AAC9B,oBAAsB;AACtB,gBAAmB;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,0BAAM,QAAQ,0BAA0B;AACxC,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,4CAAC,6BAAM,WAAU,gCAA+B,IAChD,4CAAC,8BAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,4CAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"min-h-11 min-w-11 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n // User cancelled — ignore\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n toast.success(\"Link copied to clipboard\");\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsDI;AApDJ,mBAAyB;AACzB,0BAA8B;AAC9B,oBAAsB;AACtB,gBAAmB;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,0BAAM,QAAQ,0BAA0B;AACxC,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,4CAAC,6BAAM,WAAU,gCAA+B,IAChD,4CAAC,8BAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,4CAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
@@ -13,7 +13,7 @@ const SIZE_CLASSES = {
13
13
  sm: "h-9 px-3 text-xs rounded-md",
14
14
  default: "h-10 px-4 py-2 text-sm rounded-md",
15
15
  lg: "h-11 px-8 text-sm rounded-md",
16
- icon: "h-9 w-9 rounded-md"
16
+ icon: "min-h-11 min-w-11 rounded-md"
17
17
  };
18
18
  function ShareButton({
19
19
  title,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"h-9 w-9 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n // User cancelled — ignore\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n toast.success(\"Link copied to clipboard\");\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";AAsDI,SAYM,KAZN;AApDJ,SAAS,gBAAgB;AACzB,SAAS,QAAQ,aAAa;AAC9B,SAAS,aAAa;AACtB,SAAS,UAAU;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,YAAM,QAAQ,0BAA0B;AACxC,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,oBAAC,SAAM,WAAU,gCAA+B,IAChD,oBAAC,UAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,oBAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"min-h-11 min-w-11 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n // User cancelled — ignore\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n toast.success(\"Link copied to clipboard\");\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";AAsDI,SAYM,KAZN;AApDJ,SAAS,gBAAgB;AACzB,SAAS,QAAQ,aAAa;AAC9B,SAAS,aAAa;AACtB,SAAS,UAAU;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,YAAM,QAAQ,0BAA0B;AACxC,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,oBAAC,SAAM,WAAU,gCAA+B,IAChD,oBAAC,UAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,oBAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
@@ -51,7 +51,7 @@ function StatTile({
51
51
  children: value
52
52
  }
53
53
  ),
54
- sub && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[11px] text-muted-foreground", children: sub }),
54
+ sub && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-2xs text-muted-foreground", children: sub }),
55
55
  children
56
56
  ]
57
57
  }
@@ -63,8 +63,8 @@ function StatPill({ value, label, className }) {
63
63
  {
64
64
  className: `inline-flex items-baseline gap-2 px-4 py-2 rounded-full bg-muted ${className ?? ""}`,
65
65
  children: [
66
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[15px] font-bold text-foreground tabular-nums", children: value }),
67
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[13px] text-muted-foreground", children: label })
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-base font-bold text-foreground tabular-nums", children: value }),
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-muted-foreground", children: label })
68
68
  ]
69
69
  }
70
70
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/stat-tile.tsx"],"sourcesContent":["// Bento stat tile and header stat pill — the design system's data-display primitives.\n\nexport interface StatTileProps {\n label: string;\n /** Shown as the primary value. Pass \"—\" (em dash) for unknown, never zero. */\n value?: string | number | null;\n /** Secondary line below the value. */\n sub?: string;\n /** Override color for the value text (e.g. brand-blue for positive deltas). */\n accent?: string;\n /** Large 22px value variant. */\n big?: boolean;\n radius?: number;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function StatTile({\n label,\n value,\n sub,\n accent,\n big,\n radius = 16,\n children,\n className,\n}: StatTileProps) {\n return (\n <div\n className={`bg-muted border border-border flex flex-col gap-1 min-w-0 ${className ?? ''}`}\n style={{ borderRadius: radius, padding: '12px 14px' }}\n >\n <span className=\"text-[10.5px] font-semibold tracking-[0.06em] uppercase text-muted-foreground\">\n {label}\n </span>\n {value != null && (\n <span\n className=\"font-semibold leading-none tracking-tight tabular-nums\"\n style={{\n fontSize: big ? 22 : 16,\n color: accent,\n }}\n >\n {value}\n </span>\n )}\n {sub && (\n <span className=\"text-[11px] text-muted-foreground\">{sub}</span>\n )}\n {children}\n </div>\n );\n}\n\nexport interface StatPillProps {\n value: string | number;\n label: string;\n className?: string;\n}\n\nexport function StatPill({ value, label, className }: StatPillProps) {\n return (\n <div\n className={`inline-flex items-baseline gap-2 px-4 py-2 rounded-full bg-muted ${className ?? ''}`}\n >\n <span className=\"text-[15px] font-bold text-foreground tabular-nums\">\n {value}\n </span>\n <span className=\"text-[13px] text-muted-foreground\">{label}</span>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BI;AAXG,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAkB;AAChB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,6DAA6D,aAAa,EAAE;AAAA,MACvF,OAAO,EAAE,cAAc,QAAQ,SAAS,YAAY;AAAA,MAEpD;AAAA,oDAAC,UAAK,WAAU,iFACb,iBACH;AAAA,QACC,SAAS,QACR;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU,MAAM,KAAK;AAAA,cACrB,OAAO;AAAA,YACT;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAED,OACC,4CAAC,UAAK,WAAU,qCAAqC,eAAI;AAAA,QAE1D;AAAA;AAAA;AAAA,EACH;AAEJ;AAQO,SAAS,SAAS,EAAE,OAAO,OAAO,UAAU,GAAkB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,oEAAoE,aAAa,EAAE;AAAA,MAE9F;AAAA,oDAAC,UAAK,WAAU,sDACb,iBACH;AAAA,QACA,4CAAC,UAAK,WAAU,qCAAqC,iBAAM;AAAA;AAAA;AAAA,EAC7D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/stat-tile.tsx"],"sourcesContent":["// Bento stat tile and header stat pill — the design system's data-display primitives.\n\nexport interface StatTileProps {\n label: string;\n /** Shown as the primary value. Pass \"—\" (em dash) for unknown, never zero. */\n value?: string | number | null;\n /** Secondary line below the value. */\n sub?: string;\n /** Override color for the value text (e.g. brand-blue for positive deltas). */\n accent?: string;\n /** Large 22px value variant. */\n big?: boolean;\n radius?: number;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function StatTile({\n label,\n value,\n sub,\n accent,\n big,\n radius = 16,\n children,\n className,\n}: StatTileProps) {\n return (\n <div\n className={`bg-muted border border-border flex flex-col gap-1 min-w-0 ${className ?? ''}`}\n style={{ borderRadius: radius, padding: '12px 14px' }}\n >\n <span className=\"text-[10.5px] font-semibold tracking-[0.06em] uppercase text-muted-foreground\">\n {label}\n </span>\n {value != null && (\n <span\n className=\"font-semibold leading-none tracking-tight tabular-nums\"\n style={{\n fontSize: big ? 22 : 16,\n color: accent,\n }}\n >\n {value}\n </span>\n )}\n {sub && (\n <span className=\"text-2xs text-muted-foreground\">{sub}</span>\n )}\n {children}\n </div>\n );\n}\n\nexport interface StatPillProps {\n value: string | number;\n label: string;\n className?: string;\n}\n\nexport function StatPill({ value, label, className }: StatPillProps) {\n return (\n <div\n className={`inline-flex items-baseline gap-2 px-4 py-2 rounded-full bg-muted ${className ?? ''}`}\n >\n <span className=\"text-base font-bold text-foreground tabular-nums\">\n {value}\n </span>\n <span className=\"text-sm text-muted-foreground\">{label}</span>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BI;AAXG,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAkB;AAChB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,6DAA6D,aAAa,EAAE;AAAA,MACvF,OAAO,EAAE,cAAc,QAAQ,SAAS,YAAY;AAAA,MAEpD;AAAA,oDAAC,UAAK,WAAU,iFACb,iBACH;AAAA,QACC,SAAS,QACR;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU,MAAM,KAAK;AAAA,cACrB,OAAO;AAAA,YACT;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAED,OACC,4CAAC,UAAK,WAAU,kCAAkC,eAAI;AAAA,QAEvD;AAAA;AAAA;AAAA,EACH;AAEJ;AAQO,SAAS,SAAS,EAAE,OAAO,OAAO,UAAU,GAAkB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,oEAAoE,aAAa,EAAE;AAAA,MAE9F;AAAA,oDAAC,UAAK,WAAU,oDACb,iBACH;AAAA,QACA,4CAAC,UAAK,WAAU,iCAAiC,iBAAM;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
@@ -27,7 +27,7 @@ function StatTile({
27
27
  children: value
28
28
  }
29
29
  ),
30
- sub && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: sub }),
30
+ sub && /* @__PURE__ */ jsx("span", { className: "text-2xs text-muted-foreground", children: sub }),
31
31
  children
32
32
  ]
33
33
  }
@@ -39,8 +39,8 @@ function StatPill({ value, label, className }) {
39
39
  {
40
40
  className: `inline-flex items-baseline gap-2 px-4 py-2 rounded-full bg-muted ${className ?? ""}`,
41
41
  children: [
42
- /* @__PURE__ */ jsx("span", { className: "text-[15px] font-bold text-foreground tabular-nums", children: value }),
43
- /* @__PURE__ */ jsx("span", { className: "text-[13px] text-muted-foreground", children: label })
42
+ /* @__PURE__ */ jsx("span", { className: "text-base font-bold text-foreground tabular-nums", children: value }),
43
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: label })
44
44
  ]
45
45
  }
46
46
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/stat-tile.tsx"],"sourcesContent":["// Bento stat tile and header stat pill — the design system's data-display primitives.\n\nexport interface StatTileProps {\n label: string;\n /** Shown as the primary value. Pass \"—\" (em dash) for unknown, never zero. */\n value?: string | number | null;\n /** Secondary line below the value. */\n sub?: string;\n /** Override color for the value text (e.g. brand-blue for positive deltas). */\n accent?: string;\n /** Large 22px value variant. */\n big?: boolean;\n radius?: number;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function StatTile({\n label,\n value,\n sub,\n accent,\n big,\n radius = 16,\n children,\n className,\n}: StatTileProps) {\n return (\n <div\n className={`bg-muted border border-border flex flex-col gap-1 min-w-0 ${className ?? ''}`}\n style={{ borderRadius: radius, padding: '12px 14px' }}\n >\n <span className=\"text-[10.5px] font-semibold tracking-[0.06em] uppercase text-muted-foreground\">\n {label}\n </span>\n {value != null && (\n <span\n className=\"font-semibold leading-none tracking-tight tabular-nums\"\n style={{\n fontSize: big ? 22 : 16,\n color: accent,\n }}\n >\n {value}\n </span>\n )}\n {sub && (\n <span className=\"text-[11px] text-muted-foreground\">{sub}</span>\n )}\n {children}\n </div>\n );\n}\n\nexport interface StatPillProps {\n value: string | number;\n label: string;\n className?: string;\n}\n\nexport function StatPill({ value, label, className }: StatPillProps) {\n return (\n <div\n className={`inline-flex items-baseline gap-2 px-4 py-2 rounded-full bg-muted ${className ?? ''}`}\n >\n <span className=\"text-[15px] font-bold text-foreground tabular-nums\">\n {value}\n </span>\n <span className=\"text-[13px] text-muted-foreground\">{label}</span>\n </div>\n );\n}\n"],"mappings":"AA4BI,SAIE,KAJF;AAXG,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAkB;AAChB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,6DAA6D,aAAa,EAAE;AAAA,MACvF,OAAO,EAAE,cAAc,QAAQ,SAAS,YAAY;AAAA,MAEpD;AAAA,4BAAC,UAAK,WAAU,iFACb,iBACH;AAAA,QACC,SAAS,QACR;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU,MAAM,KAAK;AAAA,cACrB,OAAO;AAAA,YACT;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAED,OACC,oBAAC,UAAK,WAAU,qCAAqC,eAAI;AAAA,QAE1D;AAAA;AAAA;AAAA,EACH;AAEJ;AAQO,SAAS,SAAS,EAAE,OAAO,OAAO,UAAU,GAAkB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,oEAAoE,aAAa,EAAE;AAAA,MAE9F;AAAA,4BAAC,UAAK,WAAU,sDACb,iBACH;AAAA,QACA,oBAAC,UAAK,WAAU,qCAAqC,iBAAM;AAAA;AAAA;AAAA,EAC7D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/stat-tile.tsx"],"sourcesContent":["// Bento stat tile and header stat pill — the design system's data-display primitives.\n\nexport interface StatTileProps {\n label: string;\n /** Shown as the primary value. Pass \"—\" (em dash) for unknown, never zero. */\n value?: string | number | null;\n /** Secondary line below the value. */\n sub?: string;\n /** Override color for the value text (e.g. brand-blue for positive deltas). */\n accent?: string;\n /** Large 22px value variant. */\n big?: boolean;\n radius?: number;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function StatTile({\n label,\n value,\n sub,\n accent,\n big,\n radius = 16,\n children,\n className,\n}: StatTileProps) {\n return (\n <div\n className={`bg-muted border border-border flex flex-col gap-1 min-w-0 ${className ?? ''}`}\n style={{ borderRadius: radius, padding: '12px 14px' }}\n >\n <span className=\"text-[10.5px] font-semibold tracking-[0.06em] uppercase text-muted-foreground\">\n {label}\n </span>\n {value != null && (\n <span\n className=\"font-semibold leading-none tracking-tight tabular-nums\"\n style={{\n fontSize: big ? 22 : 16,\n color: accent,\n }}\n >\n {value}\n </span>\n )}\n {sub && (\n <span className=\"text-2xs text-muted-foreground\">{sub}</span>\n )}\n {children}\n </div>\n );\n}\n\nexport interface StatPillProps {\n value: string | number;\n label: string;\n className?: string;\n}\n\nexport function StatPill({ value, label, className }: StatPillProps) {\n return (\n <div\n className={`inline-flex items-baseline gap-2 px-4 py-2 rounded-full bg-muted ${className ?? ''}`}\n >\n <span className=\"text-base font-bold text-foreground tabular-nums\">\n {value}\n </span>\n <span className=\"text-sm text-muted-foreground\">{label}</span>\n </div>\n );\n}\n"],"mappings":"AA4BI,SAIE,KAJF;AAXG,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAkB;AAChB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,6DAA6D,aAAa,EAAE;AAAA,MACvF,OAAO,EAAE,cAAc,QAAQ,SAAS,YAAY;AAAA,MAEpD;AAAA,4BAAC,UAAK,WAAU,iFACb,iBACH;AAAA,QACC,SAAS,QACR;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU,MAAM,KAAK;AAAA,cACrB,OAAO;AAAA,YACT;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAED,OACC,oBAAC,UAAK,WAAU,kCAAkC,eAAI;AAAA,QAEvD;AAAA;AAAA;AAAA,EACH;AAEJ;AAQO,SAAS,SAAS,EAAE,OAAO,OAAO,UAAU,GAAkB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,oEAAoE,aAAa,EAAE;AAAA,MAE9F;AAAA,4BAAC,UAAK,WAAU,oDACb,iBACH;AAAA,QACA,oBAAC,UAAK,WAAU,iCAAiC,iBAAM;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
@@ -101,25 +101,25 @@ function TokenCard({
101
101
  ] }) })
102
102
  }
103
103
  ),
104
- listingOrder && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-2 right-2 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-[11px] font-bold bg-background/90 backdrop-blur-sm border border-border/40 shadow-sm", children: [
104
+ listingOrder && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-2 right-2 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-2xs font-bold bg-background/90 backdrop-blur-sm border border-border/40 shadow-sm", children: [
105
105
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: listingOrder.price.currency ?? "", size: 10 }),
106
106
  (0, import_format.formatDisplayPrice)(listingOrder.price.formatted),
107
107
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-muted-foreground font-normal", children: listingOrder.price.currency })
108
108
  ] }) }),
109
109
  (token.metadataStatus === "PENDING" || token.metadataStatus === "FETCHING") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5", children: [
110
110
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-3 w-3 animate-spin text-white/70" }),
111
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] text-white/70", children: "Indexing\u2026" })
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-2xs text-white/70", children: "Indexing\u2026" })
112
112
  ] })
113
113
  ] }),
114
114
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 pt-2.5 pb-4 flex-1", children: [
115
115
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-base font-bold line-clamp-2 leading-snug", children: name }),
116
116
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5 mt-1.5 flex-wrap", children: [
117
117
  ipType && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ip_type_badge.IpTypeBadge, { ipType, size: "sm" }),
118
- creator ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[10px] tabular-nums text-muted-foreground/60 truncate", children: [
118
+ creator ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-2xs tabular-nums text-muted-foreground/60 truncate", children: [
119
119
  creator.slice(0, 8),
120
120
  "\u2026",
121
121
  creator.slice(-6)
122
- ] }) : token.metadata?.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground truncate leading-snug", children: token.metadata.description }) : null
122
+ ] }) : token.metadata?.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-2xs text-muted-foreground truncate leading-snug", children: token.metadata.description }) : null
123
123
  ] })
124
124
  ] })
125
125
  ] }),