@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
package/README.md CHANGED
@@ -231,6 +231,25 @@ isn't available.
231
231
 
232
232
  ---
233
233
 
234
+ ## Safe-area utilities
235
+
236
+ `.pb-safe` / `.pt-safe` — padding using `env(safe-area-inset-*)`, for
237
+ anything pinned to the viewport edge (bottom sheets, fixed tab bars) on
238
+ notched/home-indicator devices. Used internally by `NavCommandMenu`/
239
+ `NavAccountSheet`; apply the same classes to any app-level fixed bottom
240
+ bar (e.g. a mobile tab bar) for the same treatment.
241
+
242
+ **Composing with an existing base padding:** these classes are purely
243
+ additive (`0px` on a non-notched device) — they are not a drop-in
244
+ replacement for a spacing utility like `pb-4`. Stacking two Tailwind
245
+ padding-bottom classes doesn't merge them (the later one in source order
246
+ just wins), so if the element already has its own bottom padding, combine
247
+ them in one arbitrary value instead: `pb-[calc(1rem+env(safe-area-inset-bottom))]`.
248
+ `NavCommandMenu`/`NavAccountSheet` use this composed form, not the bare
249
+ `.pb-safe` class, because they already had a `pb-4` baseline.
250
+
251
+ ---
252
+
234
253
  ## Build & Publish
235
254
 
236
255
  ```bash
@@ -40,7 +40,6 @@ const ACTION_FOREGROUNDS = {
40
40
  };
41
41
  const TONE_GRADIENTS = {
42
42
  blue: ["#3b7bff", "#5b4ce6", "#3b7bff"],
43
- indigo: ["#5b4ce6", "#8a5cf6", "#5b4ce6"],
44
43
  purple: ["#8a5cf6", "#f6608f", "#8a5cf6"],
45
44
  orange: ["#fb8b46", "#f6608f", "#fb8b46"],
46
45
  red: ["#ef5a5a", "#f6608f", "#ef5a5a"],
@@ -48,7 +47,6 @@ const TONE_GRADIENTS = {
48
47
  };
49
48
  const TONE_FOREGROUNDS = {
50
49
  blue: "#2f6bff",
51
- indigo: "#5b4ce6",
52
50
  purple: "#8a3ff0",
53
51
  orange: "#fb7a32",
54
52
  red: "#ef5a5a",
@@ -68,7 +66,7 @@ function ActionButton({
68
66
  style,
69
67
  ...rest
70
68
  }) {
71
- const sizeClass = big ? "h-[54px] px-5 rounded-[13px] text-[15px]" : "h-[46px] px-5 rounded-[13px] text-sm";
69
+ const sizeClass = big ? "h-[54px] px-5 rounded-[13px] text-base" : "h-[46px] px-5 rounded-[13px] text-sm";
72
70
  if (ghost) {
73
71
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
74
72
  "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/action-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../utils/cn.js\";\n\nconst ACTION_GRADIENTS: Record<string, [string, string, string]> = {\n buy: ['#3b7bff', '#8a5cf6', '#3b7bff'],\n submit: ['#d6359a', '#5b4ce6', '#d6359a'],\n offer: ['#f6608f', '#fb8b46', '#f6608f'],\n remix: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n license: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n};\n\nconst ACTION_FOREGROUNDS: Record<string, string> = {\n buy: '#3b7bff',\n submit: '#5b4ce6',\n offer: '#fb7a32',\n remix: '#8a3ff0',\n license: '#3b7bff',\n};\n\nconst TONE_GRADIENTS: Record<string, [string, string, string]> = {\n blue: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n indigo: ['#5b4ce6', '#8a5cf6', '#5b4ce6'],\n purple: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n orange: ['#fb8b46', '#f6608f', '#fb8b46'],\n red: ['#ef5a5a', '#f6608f', '#ef5a5a'],\n rose: ['#f6608f', '#fb8b46', '#f6608f'],\n};\n\nconst TONE_FOREGROUNDS: Record<string, string> = {\n blue: '#2f6bff',\n indigo: '#5b4ce6',\n purple: '#8a3ff0',\n orange: '#fb7a32',\n red: '#ef5a5a',\n rose: '#f6608f',\n};\n\nexport type ActionKey = keyof typeof ACTION_GRADIENTS;\nexport type ToneKey = keyof typeof TONE_GRADIENTS;\n\nexport interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Semantic action — hue signals the action, never decorative. */\n action?: ActionKey;\n /** Tone — for secondary/owner actions. Ignored when action is set. */\n tone?: ToneKey;\n icon?: React.ReactNode;\n /** Tall 54px variant for hero contexts. */\n big?: boolean;\n /** Ghost: no gradient border, muted surface fill. */\n ghost?: boolean;\n /**\n * Inline help/info affordance, rendered next to the label via `renderHelp`\n * — a render-prop rather than a built-in tooltip because this package\n * can't depend on an app-specific tooltip primitive.\n */\n helpContent?: string;\n renderHelp?: (content: string) => React.ReactNode;\n}\n\nexport function ActionButton({\n action,\n tone,\n icon,\n big,\n ghost,\n helpContent,\n renderHelp,\n disabled,\n children,\n className,\n style,\n ...rest\n}: ActionButtonProps) {\n const sizeClass = big\n ? \"h-[54px] px-5 rounded-[13px] text-[15px]\"\n : \"h-[46px] px-5 rounded-[13px] text-sm\";\n\n if (ghost) {\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-muted text-foreground border-none disabled:opacity-50 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={style}\n >\n {icon}{children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n }\n\n const gradColors =\n action ? ACTION_GRADIENTS[action] :\n tone ? TONE_GRADIENTS[tone] :\n ACTION_GRADIENTS.buy;\n\n const fg =\n action ? ACTION_FOREGROUNDS[action] :\n tone ? TONE_FOREGROUNDS[tone] :\n ACTION_FOREGROUNDS.buy;\n\n const grad = `linear-gradient(115deg, ${gradColors.join(',')})`;\n\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"ml-gbtn inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-transparent text-foreground border-none relative disabled:opacity-40 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={{ '--ml-grad': grad, ...style } as React.CSSProperties}\n >\n {icon && <span className=\"inline-flex\" style={{ color: fg }}>{icon}</span>}\n {children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFM;AA9EN,gBAAmB;AAEnB,MAAM,mBAA6D;AAAA,EACjE,KAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,QAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,SAAS,CAAC,WAAW,WAAW,SAAS;AAC3C;AAEA,MAAM,qBAA6C;AAAA,EACjD,KAAS;AAAA,EACT,QAAS;AAAA,EACT,OAAS;AAAA,EACT,OAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAM,iBAA2D;AAAA,EAC/D,MAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,KAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,MAAQ,CAAC,WAAW,WAAW,SAAS;AAC1C;AAEA,MAAM,mBAA2C;AAAA,EAC/C,MAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAQ;AAAA,EACR,MAAQ;AACV;AAwBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,YAAY,MACd,6CACA;AAEJ,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA,eAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,UAAM;AAAA,UACN,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,IACzD;AAAA,EAEJ;AAEA,QAAM,aACJ,SAAS,iBAAiB,MAAM,IAChC,OAAS,eAAe,IAAI,IAC5B,iBAAiB;AAEnB,QAAM,KACJ,SAAS,mBAAmB,MAAM,IAClC,OAAS,iBAAiB,IAAI,IAC9B,mBAAmB;AAErB,QAAM,OAAO,2BAA2B,WAAW,KAAK,GAAG,CAAC;AAE5D,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,MAAM,GAAG,MAAM;AAAA,MAEpC;AAAA,gBAAQ,4CAAC,UAAK,WAAU,eAAc,OAAO,EAAE,OAAO,GAAG,GAAI,gBAAK;AAAA,QAClE;AAAA,QACA,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/action-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../utils/cn.js\";\n\nconst ACTION_GRADIENTS: Record<string, [string, string, string]> = {\n buy: ['#3b7bff', '#8a5cf6', '#3b7bff'],\n submit: ['#d6359a', '#5b4ce6', '#d6359a'],\n offer: ['#f6608f', '#fb8b46', '#f6608f'],\n remix: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n license: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n};\n\nconst ACTION_FOREGROUNDS: Record<string, string> = {\n buy: '#3b7bff',\n submit: '#5b4ce6',\n offer: '#fb7a32',\n remix: '#8a3ff0',\n license: '#3b7bff',\n};\n\nconst TONE_GRADIENTS: Record<string, [string, string, string]> = {\n blue: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n purple: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n orange: ['#fb8b46', '#f6608f', '#fb8b46'],\n red: ['#ef5a5a', '#f6608f', '#ef5a5a'],\n rose: ['#f6608f', '#fb8b46', '#f6608f'],\n};\n\nconst TONE_FOREGROUNDS: Record<string, string> = {\n blue: '#2f6bff',\n purple: '#8a3ff0',\n orange: '#fb7a32',\n red: '#ef5a5a',\n rose: '#f6608f',\n};\n\nexport type ActionKey = keyof typeof ACTION_GRADIENTS;\nexport type ToneKey = keyof typeof TONE_GRADIENTS;\n\nexport interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Semantic action — hue signals the action, never decorative. */\n action?: ActionKey;\n /** Tone — for secondary/owner actions. Ignored when action is set. */\n tone?: ToneKey;\n icon?: React.ReactNode;\n /** Tall 54px variant for hero contexts. */\n big?: boolean;\n /** Ghost: no gradient border, muted surface fill. */\n ghost?: boolean;\n /**\n * Inline help/info affordance, rendered next to the label via `renderHelp`\n * — a render-prop rather than a built-in tooltip because this package\n * can't depend on an app-specific tooltip primitive.\n */\n helpContent?: string;\n renderHelp?: (content: string) => React.ReactNode;\n}\n\nexport function ActionButton({\n action,\n tone,\n icon,\n big,\n ghost,\n helpContent,\n renderHelp,\n disabled,\n children,\n className,\n style,\n ...rest\n}: ActionButtonProps) {\n const sizeClass = big\n ? \"h-[54px] px-5 rounded-[13px] text-base\"\n : \"h-[46px] px-5 rounded-[13px] text-sm\";\n\n if (ghost) {\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-muted text-foreground border-none disabled:opacity-50 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={style}\n >\n {icon}{children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n }\n\n const gradColors =\n action ? ACTION_GRADIENTS[action] :\n tone ? TONE_GRADIENTS[tone] :\n ACTION_GRADIENTS.buy;\n\n const fg =\n action ? ACTION_FOREGROUNDS[action] :\n tone ? TONE_FOREGROUNDS[tone] :\n ACTION_FOREGROUNDS.buy;\n\n const grad = `linear-gradient(115deg, ${gradColors.join(',')})`;\n\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"ml-gbtn inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-transparent text-foreground border-none relative disabled:opacity-40 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={{ '--ml-grad': grad, ...style } as React.CSSProperties}\n >\n {icon && <span className=\"inline-flex\" style={{ color: fg }}>{icon}</span>}\n {children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA8EM;AA5EN,gBAAmB;AAEnB,MAAM,mBAA6D;AAAA,EACjE,KAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,QAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,SAAS,CAAC,WAAW,WAAW,SAAS;AAC3C;AAEA,MAAM,qBAA6C;AAAA,EACjD,KAAS;AAAA,EACT,QAAS;AAAA,EACT,OAAS;AAAA,EACT,OAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAM,iBAA2D;AAAA,EAC/D,MAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,KAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,MAAQ,CAAC,WAAW,WAAW,SAAS;AAC1C;AAEA,MAAM,mBAA2C;AAAA,EAC/C,MAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAQ;AAAA,EACR,MAAQ;AACV;AAwBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,YAAY,MACd,2CACA;AAEJ,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA,eAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,UAAM;AAAA,UACN,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,IACzD;AAAA,EAEJ;AAEA,QAAM,aACJ,SAAS,iBAAiB,MAAM,IAChC,OAAS,eAAe,IAAI,IAC5B,iBAAiB;AAEnB,QAAM,KACJ,SAAS,mBAAmB,MAAM,IAClC,OAAS,iBAAiB,IAAI,IAC9B,mBAAmB;AAErB,QAAM,OAAO,2BAA2B,WAAW,KAAK,GAAG,CAAC;AAE5D,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,MAAM,GAAG,MAAM;AAAA,MAEpC;AAAA,gBAAQ,4CAAC,UAAK,WAAU,eAAc,OAAO,EAAE,OAAO,GAAG,GAAI,gBAAK;AAAA,QAClE;AAAA,QACA,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
@@ -17,7 +17,6 @@ const ACTION_FOREGROUNDS = {
17
17
  };
18
18
  const TONE_GRADIENTS = {
19
19
  blue: ["#3b7bff", "#5b4ce6", "#3b7bff"],
20
- indigo: ["#5b4ce6", "#8a5cf6", "#5b4ce6"],
21
20
  purple: ["#8a5cf6", "#f6608f", "#8a5cf6"],
22
21
  orange: ["#fb8b46", "#f6608f", "#fb8b46"],
23
22
  red: ["#ef5a5a", "#f6608f", "#ef5a5a"],
@@ -25,7 +24,6 @@ const TONE_GRADIENTS = {
25
24
  };
26
25
  const TONE_FOREGROUNDS = {
27
26
  blue: "#2f6bff",
28
- indigo: "#5b4ce6",
29
27
  purple: "#8a3ff0",
30
28
  orange: "#fb7a32",
31
29
  red: "#ef5a5a",
@@ -45,7 +43,7 @@ function ActionButton({
45
43
  style,
46
44
  ...rest
47
45
  }) {
48
- const sizeClass = big ? "h-[54px] px-5 rounded-[13px] text-[15px]" : "h-[46px] px-5 rounded-[13px] text-sm";
46
+ const sizeClass = big ? "h-[54px] px-5 rounded-[13px] text-base" : "h-[46px] px-5 rounded-[13px] text-sm";
49
47
  if (ghost) {
50
48
  return /* @__PURE__ */ jsxs(
51
49
  "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/action-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../utils/cn.js\";\n\nconst ACTION_GRADIENTS: Record<string, [string, string, string]> = {\n buy: ['#3b7bff', '#8a5cf6', '#3b7bff'],\n submit: ['#d6359a', '#5b4ce6', '#d6359a'],\n offer: ['#f6608f', '#fb8b46', '#f6608f'],\n remix: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n license: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n};\n\nconst ACTION_FOREGROUNDS: Record<string, string> = {\n buy: '#3b7bff',\n submit: '#5b4ce6',\n offer: '#fb7a32',\n remix: '#8a3ff0',\n license: '#3b7bff',\n};\n\nconst TONE_GRADIENTS: Record<string, [string, string, string]> = {\n blue: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n indigo: ['#5b4ce6', '#8a5cf6', '#5b4ce6'],\n purple: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n orange: ['#fb8b46', '#f6608f', '#fb8b46'],\n red: ['#ef5a5a', '#f6608f', '#ef5a5a'],\n rose: ['#f6608f', '#fb8b46', '#f6608f'],\n};\n\nconst TONE_FOREGROUNDS: Record<string, string> = {\n blue: '#2f6bff',\n indigo: '#5b4ce6',\n purple: '#8a3ff0',\n orange: '#fb7a32',\n red: '#ef5a5a',\n rose: '#f6608f',\n};\n\nexport type ActionKey = keyof typeof ACTION_GRADIENTS;\nexport type ToneKey = keyof typeof TONE_GRADIENTS;\n\nexport interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Semantic action — hue signals the action, never decorative. */\n action?: ActionKey;\n /** Tone — for secondary/owner actions. Ignored when action is set. */\n tone?: ToneKey;\n icon?: React.ReactNode;\n /** Tall 54px variant for hero contexts. */\n big?: boolean;\n /** Ghost: no gradient border, muted surface fill. */\n ghost?: boolean;\n /**\n * Inline help/info affordance, rendered next to the label via `renderHelp`\n * — a render-prop rather than a built-in tooltip because this package\n * can't depend on an app-specific tooltip primitive.\n */\n helpContent?: string;\n renderHelp?: (content: string) => React.ReactNode;\n}\n\nexport function ActionButton({\n action,\n tone,\n icon,\n big,\n ghost,\n helpContent,\n renderHelp,\n disabled,\n children,\n className,\n style,\n ...rest\n}: ActionButtonProps) {\n const sizeClass = big\n ? \"h-[54px] px-5 rounded-[13px] text-[15px]\"\n : \"h-[46px] px-5 rounded-[13px] text-sm\";\n\n if (ghost) {\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-muted text-foreground border-none disabled:opacity-50 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={style}\n >\n {icon}{children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n }\n\n const gradColors =\n action ? ACTION_GRADIENTS[action] :\n tone ? TONE_GRADIENTS[tone] :\n ACTION_GRADIENTS.buy;\n\n const fg =\n action ? ACTION_FOREGROUNDS[action] :\n tone ? TONE_FOREGROUNDS[tone] :\n ACTION_FOREGROUNDS.buy;\n\n const grad = `linear-gradient(115deg, ${gradColors.join(',')})`;\n\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"ml-gbtn inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-transparent text-foreground border-none relative disabled:opacity-40 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={{ '--ml-grad': grad, ...style } as React.CSSProperties}\n >\n {icon && <span className=\"inline-flex\" style={{ color: fg }}>{icon}</span>}\n {children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n}\n"],"mappings":";AAgFM,SAyCS,KAzCT;AA9EN,SAAS,UAAU;AAEnB,MAAM,mBAA6D;AAAA,EACjE,KAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,QAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,SAAS,CAAC,WAAW,WAAW,SAAS;AAC3C;AAEA,MAAM,qBAA6C;AAAA,EACjD,KAAS;AAAA,EACT,QAAS;AAAA,EACT,OAAS;AAAA,EACT,OAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAM,iBAA2D;AAAA,EAC/D,MAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,KAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,MAAQ,CAAC,WAAW,WAAW,SAAS;AAC1C;AAEA,MAAM,mBAA2C;AAAA,EAC/C,MAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAQ;AAAA,EACR,MAAQ;AACV;AAwBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,YAAY,MACd,6CACA;AAEJ,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,UAAM;AAAA,UACN,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,IACzD;AAAA,EAEJ;AAEA,QAAM,aACJ,SAAS,iBAAiB,MAAM,IAChC,OAAS,eAAe,IAAI,IAC5B,iBAAiB;AAEnB,QAAM,KACJ,SAAS,mBAAmB,MAAM,IAClC,OAAS,iBAAiB,IAAI,IAC9B,mBAAmB;AAErB,QAAM,OAAO,2BAA2B,WAAW,KAAK,GAAG,CAAC;AAE5D,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,MAAM,GAAG,MAAM;AAAA,MAEpC;AAAA,gBAAQ,oBAAC,UAAK,WAAU,eAAc,OAAO,EAAE,OAAO,GAAG,GAAI,gBAAK;AAAA,QAClE;AAAA,QACA,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/action-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../utils/cn.js\";\n\nconst ACTION_GRADIENTS: Record<string, [string, string, string]> = {\n buy: ['#3b7bff', '#8a5cf6', '#3b7bff'],\n submit: ['#d6359a', '#5b4ce6', '#d6359a'],\n offer: ['#f6608f', '#fb8b46', '#f6608f'],\n remix: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n license: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n};\n\nconst ACTION_FOREGROUNDS: Record<string, string> = {\n buy: '#3b7bff',\n submit: '#5b4ce6',\n offer: '#fb7a32',\n remix: '#8a3ff0',\n license: '#3b7bff',\n};\n\nconst TONE_GRADIENTS: Record<string, [string, string, string]> = {\n blue: ['#3b7bff', '#5b4ce6', '#3b7bff'],\n purple: ['#8a5cf6', '#f6608f', '#8a5cf6'],\n orange: ['#fb8b46', '#f6608f', '#fb8b46'],\n red: ['#ef5a5a', '#f6608f', '#ef5a5a'],\n rose: ['#f6608f', '#fb8b46', '#f6608f'],\n};\n\nconst TONE_FOREGROUNDS: Record<string, string> = {\n blue: '#2f6bff',\n purple: '#8a3ff0',\n orange: '#fb7a32',\n red: '#ef5a5a',\n rose: '#f6608f',\n};\n\nexport type ActionKey = keyof typeof ACTION_GRADIENTS;\nexport type ToneKey = keyof typeof TONE_GRADIENTS;\n\nexport interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Semantic action — hue signals the action, never decorative. */\n action?: ActionKey;\n /** Tone — for secondary/owner actions. Ignored when action is set. */\n tone?: ToneKey;\n icon?: React.ReactNode;\n /** Tall 54px variant for hero contexts. */\n big?: boolean;\n /** Ghost: no gradient border, muted surface fill. */\n ghost?: boolean;\n /**\n * Inline help/info affordance, rendered next to the label via `renderHelp`\n * — a render-prop rather than a built-in tooltip because this package\n * can't depend on an app-specific tooltip primitive.\n */\n helpContent?: string;\n renderHelp?: (content: string) => React.ReactNode;\n}\n\nexport function ActionButton({\n action,\n tone,\n icon,\n big,\n ghost,\n helpContent,\n renderHelp,\n disabled,\n children,\n className,\n style,\n ...rest\n}: ActionButtonProps) {\n const sizeClass = big\n ? \"h-[54px] px-5 rounded-[13px] text-base\"\n : \"h-[46px] px-5 rounded-[13px] text-sm\";\n\n if (ghost) {\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-muted text-foreground border-none disabled:opacity-50 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={style}\n >\n {icon}{children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n }\n\n const gradColors =\n action ? ACTION_GRADIENTS[action] :\n tone ? TONE_GRADIENTS[tone] :\n ACTION_GRADIENTS.buy;\n\n const fg =\n action ? ACTION_FOREGROUNDS[action] :\n tone ? TONE_FOREGROUNDS[tone] :\n ACTION_FOREGROUNDS.buy;\n\n const grad = `linear-gradient(115deg, ${gradColors.join(',')})`;\n\n return (\n <button\n {...rest}\n disabled={disabled}\n className={cn(\n \"ml-gbtn inline-flex items-center justify-center gap-2 font-semibold cursor-pointer whitespace-nowrap\",\n \"bg-transparent text-foreground border-none relative disabled:opacity-40 disabled:pointer-events-none\",\n sizeClass,\n className,\n )}\n style={{ '--ml-grad': grad, ...style } as React.CSSProperties}\n >\n {icon && <span className=\"inline-flex\" style={{ color: fg }}>{icon}</span>}\n {children}\n {helpContent && renderHelp ? renderHelp(helpContent) : null}\n </button>\n );\n}\n"],"mappings":";AA8EM,SAyCS,KAzCT;AA5EN,SAAS,UAAU;AAEnB,MAAM,mBAA6D;AAAA,EACjE,KAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,QAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,OAAS,CAAC,WAAW,WAAW,SAAS;AAAA,EACzC,SAAS,CAAC,WAAW,WAAW,SAAS;AAC3C;AAEA,MAAM,qBAA6C;AAAA,EACjD,KAAS;AAAA,EACT,QAAS;AAAA,EACT,OAAS;AAAA,EACT,OAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAM,iBAA2D;AAAA,EAC/D,MAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,QAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,KAAQ,CAAC,WAAW,WAAW,SAAS;AAAA,EACxC,MAAQ,CAAC,WAAW,WAAW,SAAS;AAC1C;AAEA,MAAM,mBAA2C;AAAA,EAC/C,MAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAQ;AAAA,EACR,MAAQ;AACV;AAwBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,YAAY,MACd,2CACA;AAEJ,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,UAAM;AAAA,UACN,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,IACzD;AAAA,EAEJ;AAEA,QAAM,aACJ,SAAS,iBAAiB,MAAM,IAChC,OAAS,eAAe,IAAI,IAC5B,iBAAiB;AAEnB,QAAM,KACJ,SAAS,mBAAmB,MAAM,IAClC,OAAS,iBAAiB,IAAI,IAC9B,mBAAmB;AAErB,QAAM,OAAO,2BAA2B,WAAW,KAAK,GAAG,CAAC;AAE5D,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,MAAM,GAAG,MAAM;AAAA,MAEpC;AAAA,gBAAQ,oBAAC,UAAK,WAAU,eAAc,OAAO,EAAE,OAAO,GAAG,GAAI,gBAAK;AAAA,QAClE;AAAA,QACA,eAAe,aAAa,WAAW,WAAW,IAAI;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
@@ -101,17 +101,17 @@ function ActivityCard({
101
101
  fallback: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5", "aria-hidden": true })
102
102
  }
103
103
  ),
104
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-semibold bg-background/75 backdrop-blur-md border border-border/40", children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40", children: [
105
105
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-3 w-3", config.colorClass), "aria-hidden": true }),
106
106
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: config.colorClass, children: config.label })
107
107
  ] }),
108
- amount && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-[10px] font-bold bg-violet-500 text-white", children: [
108
+ amount && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white", children: [
109
109
  "\xD7",
110
110
  amount
111
111
  ] })
112
112
  ] }),
113
113
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-4 space-y-1.5", children: [
114
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[15px] font-semibold truncate", children: tokenName }),
114
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-base font-semibold truncate", children: tokenName }),
115
115
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
116
116
  "p",
117
117
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity, Chain } from \"@medialane/sdk\";\n\n/** ui's pinned SDK lags the apps — extend structurally for fields newer SDKs carry. */\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n /** Builds the asset link; card is unlinked when the activity has no token ref */\n getAssetHref?: (contract: string, tokenId: string) => string;\n}\n\n/** Card-shaped activity item for horizontal carousels (Discover Community strip).\n * Same data as ActivityRow, presented like a collection/listing card. */\nexport function ActivityCard({\n activity: rawActivity,\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n}: ActivityCardProps) {\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = rawImage ? ipfsToHttp(rawImage) : null;\n // Not resolved through ipfsToHttp — animation_url is legitimately a data: URI for\n // fully on-chain-rendered collections (ipfsToHttp rejects data: by design), and\n // AnimatedTokenMedia accepts it as-is, mirroring token-card.tsx's same field.\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n {/* Activity type chip — vivid label on glass */}\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-[10px] font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-[15px] font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCM;AA/BN,kBAAiB;AACjB,0BAA6B;AAC7B,2BAA6B;AAC7B,kCAAmC;AACnC,sBAAqC;AACrC,kBAA2B;AAC3B,uCAAyC;AACzC,kBAAwB;AACxB,oBAAmC;AACnC,gBAAmB;AAUZ,MAAM,oBAAsE;AAAA,EACjF,MAAW,CAAC,UAAU,QAAQ,aAAa,KAAK,KAAK;AAAA,EACrD,SAAW,CAAC,UAAU,QAAQ,aAAa,KAAK,KAAK;AAAA,EACrD,MAAW,CAAC,UAAU,QAAQ,gBAAgB,KAAK,KAAK;AAAA,EACxD,OAAW,CAAC,UAAU,QAAQ,YAAY,KAAK,KAAK;AAAA,EACpD,UAAW,CAAC,UAAU,QAAQ,kBAAkB,KAAK,KAAK;AAAA,EAC1D,WAAW,CAAC,UAAU,QAAQ,gBAAgB,KAAK,KAAK;AAC1D;AAEO,SAAS,uBAAuB;AACrC,SACE,6CAAC,SAAI,WAAU,aACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,iBACb;AAAA,kDAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,4CAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAUO,SAAS,aAAa;AAAA,EAC3B,UAAU;AAAA,EACV,eAAe,CAAC,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC;AAC3C,GAAsB;AACpB,QAAM,WAAW;AACjB,QAAM,SAAS,qCAAqB,SAAS,IAAI,KAAK;AAAA,IACpD,OAAO,SAAS;AAAA,IAChB,SAAS;AAAA,IACT,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AACA,QAAM,OAAO,OAAO;AAEpB,QAAM,WAAW,SAAS,eAAe,SAAS,mBAAmB;AACrE,QAAM,UAAU,SAAS,cAAc,SAAS,WAAW;AAC3D,QAAM,QACJ,SAAS,WACT,SAAS,cACP,SAAS,SAAoB,SAAS,SAAS,KAAK,SAAS,SAC/D;AAEF,QAAM,YAAY,SAAS,OAAO,SAAS,UAAU,IAAI,OAAO,KAAK;AACrE,QAAM,WAAW,SAAS,OAAO,SAAS;AAC1C,QAAM,aAAa,eAAW,wBAAW,QAAQ,IAAI;AAIrD,QAAM,eAAe,SAAS,OAAO,gBAAgB;AACrD,QAAM,OAAO,CAAC,EAAE,SAAS,SAAS,iBAAa,2DAAyB,SAAS,MAAM,YAAY,GAAY,QAAQ;AACvH,QAAM,SAAS,SAAS,UAAU,OAAO,SAAS,MAAM,IAAI,IAAI,SAAS,SAAS;AAElF,QAAM,aAAa,QACf,MAAM,SAAS,KACb,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC,SAAI,MAAM,MAAM,EAAE,CAAC,KACvC,QACF;AACJ,QAAM,UAAU,kBAAkB,SAAS,IAAI,IAAI,UAAU,KAAK,OAAO;AAEzE,QAAM,OACJ,4EACE;AAAA,iDAAC,SAAI,WAAU,mCACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA,KAAK;AAAA,UACL,MAAK;AAAA,UACL,OAAM;AAAA,UACN,WAAU;AAAA,UACV,UACE,4CAAC,SAAI,WAAU,qFAAoF,eAAW,MAAC;AAAA;AAAA,MAEnH;AAAA,MAEA,6CAAC,UAAK,WAAU,2KACd;AAAA,oDAAC,QAAK,eAAW,cAAG,WAAW,OAAO,UAAU,GAAG,eAAW,MAAC;AAAA,QAC/D,4CAAC,UAAK,WAAW,OAAO,YAAa,iBAAO,OAAM;AAAA,SACpD;AAAA,MACC,UACC,6CAAC,UAAK,WAAU,yGAAwG;AAAA;AAAA,QACpH;AAAA,SACJ;AAAA,OAEJ;AAAA,IACA,6CAAC,SAAI,WAAU,mBACb;AAAA,kDAAC,OAAE,WAAU,sCAAsC,qBAAU;AAAA,MAC7D;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,IAAI,KAAK,SAAS,SAAS,EAAE,eAAe;AAAA,UAElD;AAAA;AAAA,YAAQ;AAAA,gBAAI,qBAAQ,SAAS,SAAS;AAAA;AAAA;AAAA,MACzC;AAAA,MACC,SAAS,OAAO,aACf,6CAAC,OAAE,WAAU,mEACV;AAAA,iBAAS,MAAM,YAAY,4CAAC,qCAAa,QAAQ,SAAS,MAAM,UAAU,MAAM,IAAI,eAAW,MAAC;AAAA,YAChG,kCAAmB,SAAS,MAAM,SAAS;AAAA,SAC9C;AAAA,OAEJ;AAAA,KACF;AAGF,QAAM,YAAY;AAElB,SAAO,YAAY,UACjB,4CAAC,YAAAA,SAAA,EAAK,MAAM,aAAa,UAAU,OAAO,GAAG,WAC1C,gBACH,IAEA,4CAAC,SAAI,WAAuB,gBAAK;AAErC;","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity, Chain } from \"@medialane/sdk\";\n\n/** ui's pinned SDK lags the apps — extend structurally for fields newer SDKs carry. */\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n /** Builds the asset link; card is unlinked when the activity has no token ref */\n getAssetHref?: (contract: string, tokenId: string) => string;\n}\n\n/** Card-shaped activity item for horizontal carousels (Discover Community strip).\n * Same data as ActivityRow, presented like a collection/listing card. */\nexport function ActivityCard({\n activity: rawActivity,\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n}: ActivityCardProps) {\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = rawImage ? ipfsToHttp(rawImage) : null;\n // Not resolved through ipfsToHttp — animation_url is legitimately a data: URI for\n // fully on-chain-rendered collections (ipfsToHttp rejects data: by design), and\n // AnimatedTokenMedia accepts it as-is, mirroring token-card.tsx's same field.\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n {/* Activity type chip — vivid label on glass */}\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-base font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":"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","names":["Link"]}
@@ -66,17 +66,17 @@ function ActivityCard({
66
66
  fallback: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5", "aria-hidden": true })
67
67
  }
68
68
  ),
69
- /* @__PURE__ */ jsxs("span", { className: "absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-semibold bg-background/75 backdrop-blur-md border border-border/40", children: [
69
+ /* @__PURE__ */ jsxs("span", { className: "absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40", children: [
70
70
  /* @__PURE__ */ jsx(Icon, { className: cn("h-3 w-3", config.colorClass), "aria-hidden": true }),
71
71
  /* @__PURE__ */ jsx("span", { className: config.colorClass, children: config.label })
72
72
  ] }),
73
- amount && /* @__PURE__ */ jsxs("span", { className: "absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-[10px] font-bold bg-violet-500 text-white", children: [
73
+ amount && /* @__PURE__ */ jsxs("span", { className: "absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white", children: [
74
74
  "\xD7",
75
75
  amount
76
76
  ] })
77
77
  ] }),
78
78
  /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-1.5", children: [
79
- /* @__PURE__ */ jsx("p", { className: "text-[15px] font-semibold truncate", children: tokenName }),
79
+ /* @__PURE__ */ jsx("p", { className: "text-base font-semibold truncate", children: tokenName }),
80
80
  /* @__PURE__ */ jsxs(
81
81
  "p",
82
82
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity, Chain } from \"@medialane/sdk\";\n\n/** ui's pinned SDK lags the apps — extend structurally for fields newer SDKs carry. */\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n /** Builds the asset link; card is unlinked when the activity has no token ref */\n getAssetHref?: (contract: string, tokenId: string) => string;\n}\n\n/** Card-shaped activity item for horizontal carousels (Discover Community strip).\n * Same data as ActivityRow, presented like a collection/listing card. */\nexport function ActivityCard({\n activity: rawActivity,\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n}: ActivityCardProps) {\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = rawImage ? ipfsToHttp(rawImage) : null;\n // Not resolved through ipfsToHttp — animation_url is legitimately a data: URI for\n // fully on-chain-rendered collections (ipfsToHttp rejects data: by design), and\n // AnimatedTokenMedia accepts it as-is, mirroring token-card.tsx's same field.\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n {/* Activity type chip — vivid label on glass */}\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-[10px] font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-[15px] font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity, Chain } from \"@medialane/sdk\";\n\n/** ui's pinned SDK lags the apps — extend structurally for fields newer SDKs carry. */\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n /** Builds the asset link; card is unlinked when the activity has no token ref */\n getAssetHref?: (contract: string, tokenId: string) => string;\n}\n\n/** Card-shaped activity item for horizontal carousels (Discover Community strip).\n * Same data as ActivityRow, presented like a collection/listing card. */\nexport function ActivityCard({\n activity: rawActivity,\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n}: ActivityCardProps) {\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = rawImage ? ipfsToHttp(rawImage) : null;\n // Not resolved through ipfsToHttp — animation_url is legitimately a data: URI for\n // fully on-chain-rendered collections (ipfsToHttp rejects data: by design), and\n // AnimatedTokenMedia accepts it as-is, mirroring token-card.tsx's same field.\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n {/* Activity type chip — vivid label on glass */}\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-base font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -64,7 +64,7 @@ function ActivityFeedShell({ title, href, hrefLabel = "Activities", lastUpdated,
64
64
  ] }),
65
65
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
66
66
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-xl sm:text-2xl font-black leading-none", children: title }),
67
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[10px] text-muted-foreground mt-0.5 flex items-center gap-1", children: [
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-2xs text-muted-foreground mt-0.5 flex items-center gap-1", children: [
68
68
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.RefreshCw, { className: "h-2.5 w-2.5" }),
69
69
  "Updated ",
70
70
  (0, import_time.timeAgo)(lastUpdated)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-feed-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight, Activity, RefreshCw } from \"lucide-react\";\nimport { timeAgo } from \"../utils/time.js\";\n\nexport interface ActivityFeedShellProps {\n title: string;\n href: string;\n hrefLabel?: string;\n lastUpdated: string;\n isLoading: boolean;\n children: React.ReactNode;\n}\n\nfunction SkeletonRow() {\n return (\n <div className=\"flex items-center gap-3 px-4 py-2.5\">\n <div className=\"h-7 w-7 rounded-lg bg-muted animate-pulse shrink-0\" />\n <div className=\"h-7 w-7 rounded-md bg-muted animate-pulse shrink-0\" />\n <div className=\"flex-1 space-y-1.5\">\n <div className=\"h-3 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-20 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"space-y-1 text-right\">\n <div className=\"h-3.5 w-14 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-8 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-3 w-10 bg-muted animate-pulse rounded hidden sm:block\" />\n </div>\n );\n}\n\nexport function ActivityFeedShell({ title, href, hrefLabel = \"Activities\", lastUpdated, isLoading, children }: ActivityFeedShellProps) {\n return (\n <section className=\"space-y-5\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"relative h-8 w-8 rounded-xl bg-gradient-to-br from-indigo-500 to-blue-600 flex items-center justify-center shadow-lg shadow-indigo-500/20 shrink-0\">\n <Activity className=\"h-4 w-4 text-white\" />\n <span className=\"absolute -top-1 -right-1 flex h-2.5 w-2.5\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75\" />\n <span className=\"relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500\" />\n </span>\n </div>\n <div>\n <h2 className=\"text-xl sm:text-2xl font-black leading-none\">{title}</h2>\n <p className=\"text-[10px] text-muted-foreground mt-0.5 flex items-center gap-1\">\n <RefreshCw className=\"h-2.5 w-2.5\" />\n Updated {timeAgo(lastUpdated)}\n </p>\n </div>\n </div>\n <Link href={href} 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 {hrefLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"bento-cell overflow-hidden divide-y divide-border/40\">\n {isLoading ? (\n Array.from({ length: 6 }).map((_, i) => <SkeletonRow key={i} />)\n ) : !children || (Array.isArray(children) && children.length === 0) ? (\n <div className=\"flex flex-col items-center gap-2 py-10 text-center\">\n <Activity className=\"h-8 w-8 text-muted-foreground/30\" />\n <p className=\"text-sm text-muted-foreground\">No activity yet.</p>\n </div>\n ) : (\n children\n )}\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBM;AAhBN,kBAAiB;AACjB,0BAAgD;AAChD,kBAAwB;AAWxB,SAAS,cAAc;AACrB,SACE,6CAAC,SAAI,WAAU,uCACb;AAAA,gDAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,4CAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,6CAAC,SAAI,WAAU,sBACb;AAAA,kDAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,4CAAC,SAAI,WAAU,6CAA4C;AAAA,OAC7D;AAAA,IACA,6CAAC,SAAI,WAAU,wBACb;AAAA,kDAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,4CAAC,SAAI,WAAU,4CAA2C;AAAA,OAC5D;AAAA,IACA,4CAAC,SAAI,WAAU,2DAA0D;AAAA,KAC3E;AAEJ;AAEO,SAAS,kBAAkB,EAAE,OAAO,MAAM,YAAY,cAAc,aAAa,WAAW,SAAS,GAA2B;AACrI,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SAAI,WAAU,6BACb;AAAA,qDAAC,SAAI,WAAU,sJACb;AAAA,sDAAC,gCAAS,WAAU,sBAAqB;AAAA,UACzC,6CAAC,UAAK,WAAU,6CACd;AAAA,wDAAC,UAAK,WAAU,0FAAyF;AAAA,YACzG,4CAAC,UAAK,WAAU,gEAA+D;AAAA,aACjF;AAAA,WACF;AAAA,QACA,6CAAC,SACC;AAAA,sDAAC,QAAG,WAAU,+CAA+C,iBAAM;AAAA,UACnE,6CAAC,OAAE,WAAU,oEACX;AAAA,wDAAC,iCAAU,WAAU,eAAc;AAAA,YAAE;AAAA,gBAC5B,qBAAQ,WAAW;AAAA,aAC9B;AAAA,WACF;AAAA,SACF;AAAA,MACA,6CAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,+IACzB;AAAA;AAAA,QAAU;AAAA,QAAC,4CAAC,kCAAW,WAAU,eAAc;AAAA,SAClD;AAAA,OACF;AAAA,IAEA,4CAAC,SAAI,WAAU,wDACZ,sBACC,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,4CAAC,iBAAiB,CAAG,CAAE,IAC7D,CAAC,YAAa,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,IAC/D,6CAAC,SAAI,WAAU,sDACb;AAAA,kDAAC,gCAAS,WAAU,oCAAmC;AAAA,MACvD,4CAAC,OAAE,WAAU,iCAAgC,8BAAgB;AAAA,OAC/D,IAEA,UAEJ;AAAA,KACF;AAEJ;","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/activity-feed-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight, Activity, RefreshCw } from \"lucide-react\";\nimport { timeAgo } from \"../utils/time.js\";\n\nexport interface ActivityFeedShellProps {\n title: string;\n href: string;\n hrefLabel?: string;\n lastUpdated: string;\n isLoading: boolean;\n children: React.ReactNode;\n}\n\nfunction SkeletonRow() {\n return (\n <div className=\"flex items-center gap-3 px-4 py-2.5\">\n <div className=\"h-7 w-7 rounded-lg bg-muted animate-pulse shrink-0\" />\n <div className=\"h-7 w-7 rounded-md bg-muted animate-pulse shrink-0\" />\n <div className=\"flex-1 space-y-1.5\">\n <div className=\"h-3 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-20 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"space-y-1 text-right\">\n <div className=\"h-3.5 w-14 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-8 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-3 w-10 bg-muted animate-pulse rounded hidden sm:block\" />\n </div>\n );\n}\n\nexport function ActivityFeedShell({ title, href, hrefLabel = \"Activities\", lastUpdated, isLoading, children }: ActivityFeedShellProps) {\n return (\n <section className=\"space-y-5\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"relative h-8 w-8 rounded-xl bg-gradient-to-br from-indigo-500 to-blue-600 flex items-center justify-center shadow-lg shadow-indigo-500/20 shrink-0\">\n <Activity className=\"h-4 w-4 text-white\" />\n <span className=\"absolute -top-1 -right-1 flex h-2.5 w-2.5\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75\" />\n <span className=\"relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500\" />\n </span>\n </div>\n <div>\n <h2 className=\"text-xl sm:text-2xl font-black leading-none\">{title}</h2>\n <p className=\"text-2xs text-muted-foreground mt-0.5 flex items-center gap-1\">\n <RefreshCw className=\"h-2.5 w-2.5\" />\n Updated {timeAgo(lastUpdated)}\n </p>\n </div>\n </div>\n <Link href={href} 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 {hrefLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"bento-cell overflow-hidden divide-y divide-border/40\">\n {isLoading ? (\n Array.from({ length: 6 }).map((_, i) => <SkeletonRow key={i} />)\n ) : !children || (Array.isArray(children) && children.length === 0) ? (\n <div className=\"flex flex-col items-center gap-2 py-10 text-center\">\n <Activity className=\"h-8 w-8 text-muted-foreground/30\" />\n <p className=\"text-sm text-muted-foreground\">No activity yet.</p>\n </div>\n ) : (\n children\n )}\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBM;AAhBN,kBAAiB;AACjB,0BAAgD;AAChD,kBAAwB;AAWxB,SAAS,cAAc;AACrB,SACE,6CAAC,SAAI,WAAU,uCACb;AAAA,gDAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,4CAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,6CAAC,SAAI,WAAU,sBACb;AAAA,kDAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,4CAAC,SAAI,WAAU,6CAA4C;AAAA,OAC7D;AAAA,IACA,6CAAC,SAAI,WAAU,wBACb;AAAA,kDAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,4CAAC,SAAI,WAAU,4CAA2C;AAAA,OAC5D;AAAA,IACA,4CAAC,SAAI,WAAU,2DAA0D;AAAA,KAC3E;AAEJ;AAEO,SAAS,kBAAkB,EAAE,OAAO,MAAM,YAAY,cAAc,aAAa,WAAW,SAAS,GAA2B;AACrI,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SAAI,WAAU,6BACb;AAAA,qDAAC,SAAI,WAAU,sJACb;AAAA,sDAAC,gCAAS,WAAU,sBAAqB;AAAA,UACzC,6CAAC,UAAK,WAAU,6CACd;AAAA,wDAAC,UAAK,WAAU,0FAAyF;AAAA,YACzG,4CAAC,UAAK,WAAU,gEAA+D;AAAA,aACjF;AAAA,WACF;AAAA,QACA,6CAAC,SACC;AAAA,sDAAC,QAAG,WAAU,+CAA+C,iBAAM;AAAA,UACnE,6CAAC,OAAE,WAAU,iEACX;AAAA,wDAAC,iCAAU,WAAU,eAAc;AAAA,YAAE;AAAA,gBAC5B,qBAAQ,WAAW;AAAA,aAC9B;AAAA,WACF;AAAA,SACF;AAAA,MACA,6CAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,+IACzB;AAAA;AAAA,QAAU;AAAA,QAAC,4CAAC,kCAAW,WAAU,eAAc;AAAA,SAClD;AAAA,OACF;AAAA,IAEA,4CAAC,SAAI,WAAU,wDACZ,sBACC,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,4CAAC,iBAAiB,CAAG,CAAE,IAC7D,CAAC,YAAa,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,IAC/D,6CAAC,SAAI,WAAU,sDACb;AAAA,kDAAC,gCAAS,WAAU,oCAAmC;AAAA,MACvD,4CAAC,OAAE,WAAU,iCAAgC,8BAAgB;AAAA,OAC/D,IAEA,UAEJ;AAAA,KACF;AAEJ;","names":["Link"]}
@@ -31,7 +31,7 @@ function ActivityFeedShell({ title, href, hrefLabel = "Activities", lastUpdated,
31
31
  ] }),
32
32
  /* @__PURE__ */ jsxs("div", { children: [
33
33
  /* @__PURE__ */ jsx("h2", { className: "text-xl sm:text-2xl font-black leading-none", children: title }),
34
- /* @__PURE__ */ jsxs("p", { className: "text-[10px] text-muted-foreground mt-0.5 flex items-center gap-1", children: [
34
+ /* @__PURE__ */ jsxs("p", { className: "text-2xs text-muted-foreground mt-0.5 flex items-center gap-1", children: [
35
35
  /* @__PURE__ */ jsx(RefreshCw, { className: "h-2.5 w-2.5" }),
36
36
  "Updated ",
37
37
  timeAgo(lastUpdated)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-feed-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight, Activity, RefreshCw } from \"lucide-react\";\nimport { timeAgo } from \"../utils/time.js\";\n\nexport interface ActivityFeedShellProps {\n title: string;\n href: string;\n hrefLabel?: string;\n lastUpdated: string;\n isLoading: boolean;\n children: React.ReactNode;\n}\n\nfunction SkeletonRow() {\n return (\n <div className=\"flex items-center gap-3 px-4 py-2.5\">\n <div className=\"h-7 w-7 rounded-lg bg-muted animate-pulse shrink-0\" />\n <div className=\"h-7 w-7 rounded-md bg-muted animate-pulse shrink-0\" />\n <div className=\"flex-1 space-y-1.5\">\n <div className=\"h-3 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-20 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"space-y-1 text-right\">\n <div className=\"h-3.5 w-14 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-8 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-3 w-10 bg-muted animate-pulse rounded hidden sm:block\" />\n </div>\n );\n}\n\nexport function ActivityFeedShell({ title, href, hrefLabel = \"Activities\", lastUpdated, isLoading, children }: ActivityFeedShellProps) {\n return (\n <section className=\"space-y-5\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"relative h-8 w-8 rounded-xl bg-gradient-to-br from-indigo-500 to-blue-600 flex items-center justify-center shadow-lg shadow-indigo-500/20 shrink-0\">\n <Activity className=\"h-4 w-4 text-white\" />\n <span className=\"absolute -top-1 -right-1 flex h-2.5 w-2.5\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75\" />\n <span className=\"relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500\" />\n </span>\n </div>\n <div>\n <h2 className=\"text-xl sm:text-2xl font-black leading-none\">{title}</h2>\n <p className=\"text-[10px] text-muted-foreground mt-0.5 flex items-center gap-1\">\n <RefreshCw className=\"h-2.5 w-2.5\" />\n Updated {timeAgo(lastUpdated)}\n </p>\n </div>\n </div>\n <Link href={href} 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 {hrefLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"bento-cell overflow-hidden divide-y divide-border/40\">\n {isLoading ? (\n Array.from({ length: 6 }).map((_, i) => <SkeletonRow key={i} />)\n ) : !children || (Array.isArray(children) && children.length === 0) ? (\n <div className=\"flex flex-col items-center gap-2 py-10 text-center\">\n <Activity className=\"h-8 w-8 text-muted-foreground/30\" />\n <p className=\"text-sm text-muted-foreground\">No activity yet.</p>\n </div>\n ) : (\n children\n )}\n </div>\n </section>\n );\n}\n"],"mappings":";AAkBM,cAEA,YAFA;AAhBN,OAAO,UAAU;AACjB,SAAS,YAAY,UAAU,iBAAiB;AAChD,SAAS,eAAe;AAWxB,SAAS,cAAc;AACrB,SACE,qBAAC,SAAI,WAAU,uCACb;AAAA,wBAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,oBAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,qBAAC,SAAI,WAAU,sBACb;AAAA,0BAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,oBAAC,SAAI,WAAU,6CAA4C;AAAA,OAC7D;AAAA,IACA,qBAAC,SAAI,WAAU,wBACb;AAAA,0BAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,oBAAC,SAAI,WAAU,4CAA2C;AAAA,OAC5D;AAAA,IACA,oBAAC,SAAI,WAAU,2DAA0D;AAAA,KAC3E;AAEJ;AAEO,SAAS,kBAAkB,EAAE,OAAO,MAAM,YAAY,cAAc,aAAa,WAAW,SAAS,GAA2B;AACrI,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SAAI,WAAU,6BACb;AAAA,6BAAC,SAAI,WAAU,sJACb;AAAA,8BAAC,YAAS,WAAU,sBAAqB;AAAA,UACzC,qBAAC,UAAK,WAAU,6CACd;AAAA,gCAAC,UAAK,WAAU,0FAAyF;AAAA,YACzG,oBAAC,UAAK,WAAU,gEAA+D;AAAA,aACjF;AAAA,WACF;AAAA,QACA,qBAAC,SACC;AAAA,8BAAC,QAAG,WAAU,+CAA+C,iBAAM;AAAA,UACnE,qBAAC,OAAE,WAAU,oEACX;AAAA,gCAAC,aAAU,WAAU,eAAc;AAAA,YAAE;AAAA,YAC5B,QAAQ,WAAW;AAAA,aAC9B;AAAA,WACF;AAAA,SACF;AAAA,MACA,qBAAC,QAAK,MAAY,WAAU,+IACzB;AAAA;AAAA,QAAU;AAAA,QAAC,oBAAC,cAAW,WAAU,eAAc;AAAA,SAClD;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,wDACZ,sBACC,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,oBAAC,iBAAiB,CAAG,CAAE,IAC7D,CAAC,YAAa,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,IAC/D,qBAAC,SAAI,WAAU,sDACb;AAAA,0BAAC,YAAS,WAAU,oCAAmC;AAAA,MACvD,oBAAC,OAAE,WAAU,iCAAgC,8BAAgB;AAAA,OAC/D,IAEA,UAEJ;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/activity-feed-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight, Activity, RefreshCw } from \"lucide-react\";\nimport { timeAgo } from \"../utils/time.js\";\n\nexport interface ActivityFeedShellProps {\n title: string;\n href: string;\n hrefLabel?: string;\n lastUpdated: string;\n isLoading: boolean;\n children: React.ReactNode;\n}\n\nfunction SkeletonRow() {\n return (\n <div className=\"flex items-center gap-3 px-4 py-2.5\">\n <div className=\"h-7 w-7 rounded-lg bg-muted animate-pulse shrink-0\" />\n <div className=\"h-7 w-7 rounded-md bg-muted animate-pulse shrink-0\" />\n <div className=\"flex-1 space-y-1.5\">\n <div className=\"h-3 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-20 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"space-y-1 text-right\">\n <div className=\"h-3.5 w-14 bg-muted animate-pulse rounded\" />\n <div className=\"h-2.5 w-8 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-3 w-10 bg-muted animate-pulse rounded hidden sm:block\" />\n </div>\n );\n}\n\nexport function ActivityFeedShell({ title, href, hrefLabel = \"Activities\", lastUpdated, isLoading, children }: ActivityFeedShellProps) {\n return (\n <section className=\"space-y-5\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"relative h-8 w-8 rounded-xl bg-gradient-to-br from-indigo-500 to-blue-600 flex items-center justify-center shadow-lg shadow-indigo-500/20 shrink-0\">\n <Activity className=\"h-4 w-4 text-white\" />\n <span className=\"absolute -top-1 -right-1 flex h-2.5 w-2.5\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75\" />\n <span className=\"relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500\" />\n </span>\n </div>\n <div>\n <h2 className=\"text-xl sm:text-2xl font-black leading-none\">{title}</h2>\n <p className=\"text-2xs text-muted-foreground mt-0.5 flex items-center gap-1\">\n <RefreshCw className=\"h-2.5 w-2.5\" />\n Updated {timeAgo(lastUpdated)}\n </p>\n </div>\n </div>\n <Link href={href} 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 {hrefLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"bento-cell overflow-hidden divide-y divide-border/40\">\n {isLoading ? (\n Array.from({ length: 6 }).map((_, i) => <SkeletonRow key={i} />)\n ) : !children || (Array.isArray(children) && children.length === 0) ? (\n <div className=\"flex flex-col items-center gap-2 py-10 text-center\">\n <Activity className=\"h-8 w-8 text-muted-foreground/30\" />\n <p className=\"text-sm text-muted-foreground\">No activity yet.</p>\n </div>\n ) : (\n children\n )}\n </div>\n </section>\n );\n}\n"],"mappings":";AAkBM,cAEA,YAFA;AAhBN,OAAO,UAAU;AACjB,SAAS,YAAY,UAAU,iBAAiB;AAChD,SAAS,eAAe;AAWxB,SAAS,cAAc;AACrB,SACE,qBAAC,SAAI,WAAU,uCACb;AAAA,wBAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,oBAAC,SAAI,WAAU,sDAAqD;AAAA,IACpE,qBAAC,SAAI,WAAU,sBACb;AAAA,0BAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,oBAAC,SAAI,WAAU,6CAA4C;AAAA,OAC7D;AAAA,IACA,qBAAC,SAAI,WAAU,wBACb;AAAA,0BAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,oBAAC,SAAI,WAAU,4CAA2C;AAAA,OAC5D;AAAA,IACA,oBAAC,SAAI,WAAU,2DAA0D;AAAA,KAC3E;AAEJ;AAEO,SAAS,kBAAkB,EAAE,OAAO,MAAM,YAAY,cAAc,aAAa,WAAW,SAAS,GAA2B;AACrI,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SAAI,WAAU,6BACb;AAAA,6BAAC,SAAI,WAAU,sJACb;AAAA,8BAAC,YAAS,WAAU,sBAAqB;AAAA,UACzC,qBAAC,UAAK,WAAU,6CACd;AAAA,gCAAC,UAAK,WAAU,0FAAyF;AAAA,YACzG,oBAAC,UAAK,WAAU,gEAA+D;AAAA,aACjF;AAAA,WACF;AAAA,QACA,qBAAC,SACC;AAAA,8BAAC,QAAG,WAAU,+CAA+C,iBAAM;AAAA,UACnE,qBAAC,OAAE,WAAU,iEACX;AAAA,gCAAC,aAAU,WAAU,eAAc;AAAA,YAAE;AAAA,YAC5B,QAAQ,WAAW;AAAA,aAC9B;AAAA,WACF;AAAA,SACF;AAAA,MACA,qBAAC,QAAK,MAAY,WAAU,+IACzB;AAAA;AAAA,QAAU;AAAA,QAAC,oBAAC,cAAW,WAAU,eAAc;AAAA,SAClD;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,wDACZ,sBACC,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,oBAAC,iBAAiB,CAAG,CAAE,IAC7D,CAAC,YAAa,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,IAC/D,qBAAC,SAAI,WAAU,sDACb;AAAA,0BAAC,YAAS,WAAU,oCAAmC;AAAA,MACvD,oBAAC,OAAE,WAAU,iCAAgC,8BAAgB;AAAA,OAC/D,IAEA,UAEJ;AAAA,KACF;AAEJ;","names":[]}
@@ -75,15 +75,15 @@ function ActivityRow({
75
75
  showActor && actor && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: getActorHref(actor), className: "text-xs text-muted-foreground hover:text-primary transition-colors font-mono leading-tight", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_address_display.AddressDisplay, { address: actor, chars: 4, showCopy: false }) })
76
76
  ] }),
77
77
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2.5 shrink-0", children: [
78
- !compact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("text-[10px] font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex", config.bgClass, config.colorClass), children: config.label }),
78
+ !compact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("text-2xs font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex", config.bgClass, config.colorClass), children: config.label }),
79
79
  activity.price?.formatted && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [
80
80
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-bold tabular-nums leading-tight", children: (0, import_format.formatDisplayPrice)(activity.price.formatted) }),
81
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[10px] text-muted-foreground leading-tight flex items-center justify-end gap-0.5", children: [
81
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-2xs text-muted-foreground leading-tight flex items-center justify-end gap-0.5", children: [
82
82
  activity.price.currency && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: activity.price.currency, size: 10 }),
83
83
  activity.price.currency
84
84
  ] })
85
85
  ] }),
86
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] text-muted-foreground tabular-nums hidden sm:block w-12 text-right", title: new Date(activity.timestamp).toLocaleString(), children: (0, import_time.timeAgo)(activity.timestamp) }),
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-2xs text-muted-foreground tabular-nums hidden sm:block w-12 text-right", title: new Date(activity.timestamp).toLocaleString(), children: (0, import_time.timeAgo)(activity.timestamp) }),
87
87
  showExplorer && txLink && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: txLink, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center justify-center h-6 w-6 rounded-md hover:bg-muted transition-colors opacity-50 sm:opacity-0 sm:group-hover:opacity-100 shrink-0", "aria-label": "View on explorer", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3 w-3 text-muted-foreground" }) })
88
88
  ] })
89
89
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity } from \"@medialane/sdk\";\n\nexport interface ActivityRowProps {\n activity: ApiActivity;\n /** Optional token enrichment — if absent shows #tokenId fallback. No internal useToken call. */\n token?: { name?: string; image?: string };\n showActor?: boolean;\n showExplorer?: boolean;\n compact?: boolean;\n explorerUrl?: string;\n getAssetHref?: (contract: string, tokenId: string) => string;\n getActorHref?: (address: string) => string;\n}\n\nexport function ActivityRow({\n activity,\n token,\n showActor = true,\n showExplorer = true,\n compact = false,\n explorerUrl = \"https://voyager.online\",\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n getActorHref = (a) => `/creator/${a}`,\n}: ActivityRowProps) {\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n const txLink = activity.txHash ? `${explorerUrl}/tx/${activity.txHash}` : null;\n\n const tokenName = token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const tokenImage = token?.image ? ipfsToHttp(token.image) : null;\n\n return (\n <div className={cn(\"flex items-center gap-3 hover:bg-muted/30 transition-colors group\", compact ? \"pl-4 pr-5 py-2.5\" : \"pl-4 pr-5 py-3.5\")}>\n {/* Type icon */}\n <div className={cn(\"rounded-lg flex items-center justify-center shrink-0\", config.bgClass, compact ? \"h-7 w-7\" : \"h-8 w-8\")}>\n <Icon className={cn(\"shrink-0\", config.colorClass, compact ? \"h-3.5 w-3.5\" : \"h-4 w-4\")} />\n </div>\n\n {/* Token thumbnail */}\n <div className={cn(\"rounded-md overflow-hidden shrink-0 bg-muted\", compact ? \"h-7 w-7\" : \"h-9 w-9\")}>\n {tokenImage ? (\n <Image src={tokenImage} alt={tokenName} width={compact ? 28 : 36} height={compact ? 28 : 36} className=\"object-cover w-full h-full\" unoptimized />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" />\n )}\n </div>\n\n {/* Asset name + actor */}\n <div className=\"flex-1 min-w-0\">\n {contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className=\"text-sm font-semibold hover:text-primary transition-colors truncate block leading-tight\">\n {tokenName}\n </Link>\n ) : (\n <span className=\"text-sm font-semibold text-muted-foreground\">—</span>\n )}\n {showActor && actor && (\n <Link href={getActorHref(actor)} className=\"text-xs text-muted-foreground hover:text-primary transition-colors font-mono leading-tight\">\n <AddressDisplay address={actor} chars={4} showCopy={false} />\n </Link>\n )}\n </div>\n\n {/* Right: badge + price + time + explorer */}\n <div className=\"flex items-center gap-2.5 shrink-0\">\n {!compact && (\n <span className={cn(\"text-[10px] font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex\", config.bgClass, config.colorClass)}>\n {config.label}\n </span>\n )}\n\n {activity.price?.formatted && (\n <div className=\"text-right\">\n <p className=\"text-sm font-bold tabular-nums leading-tight\">{formatDisplayPrice(activity.price.formatted)}</p>\n <p className=\"text-[10px] text-muted-foreground leading-tight flex items-center justify-end gap-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={10} />}\n {activity.price.currency}\n </p>\n </div>\n )}\n\n <span className=\"text-[10px] text-muted-foreground tabular-nums hidden sm:block w-12 text-right\" title={new Date(activity.timestamp).toLocaleString()}>\n {timeAgo(activity.timestamp)}\n </span>\n\n {showExplorer && txLink && (\n <a href={txLink} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center justify-center h-6 w-6 rounded-md hover:bg-muted transition-colors opacity-50 sm:opacity-0 sm:group-hover:opacity-100 shrink-0\" aria-label=\"View on explorer\">\n <ExternalLink className=\"h-3 w-3 text-muted-foreground\" />\n </a>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["Image","Link"]}
1
+ {"version":3,"sources":["../../src/components/activity-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity } from \"@medialane/sdk\";\n\nexport interface ActivityRowProps {\n activity: ApiActivity;\n /** Optional token enrichment — if absent shows #tokenId fallback. No internal useToken call. */\n token?: { name?: string; image?: string };\n showActor?: boolean;\n showExplorer?: boolean;\n compact?: boolean;\n explorerUrl?: string;\n getAssetHref?: (contract: string, tokenId: string) => string;\n getActorHref?: (address: string) => string;\n}\n\nexport function ActivityRow({\n activity,\n token,\n showActor = true,\n showExplorer = true,\n compact = false,\n explorerUrl = \"https://voyager.online\",\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n getActorHref = (a) => `/creator/${a}`,\n}: ActivityRowProps) {\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n const txLink = activity.txHash ? `${explorerUrl}/tx/${activity.txHash}` : null;\n\n const tokenName = token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const tokenImage = token?.image ? ipfsToHttp(token.image) : null;\n\n return (\n <div className={cn(\"flex items-center gap-3 hover:bg-muted/30 transition-colors group\", compact ? \"pl-4 pr-5 py-2.5\" : \"pl-4 pr-5 py-3.5\")}>\n {/* Type icon */}\n <div className={cn(\"rounded-lg flex items-center justify-center shrink-0\", config.bgClass, compact ? \"h-7 w-7\" : \"h-8 w-8\")}>\n <Icon className={cn(\"shrink-0\", config.colorClass, compact ? \"h-3.5 w-3.5\" : \"h-4 w-4\")} />\n </div>\n\n {/* Token thumbnail */}\n <div className={cn(\"rounded-md overflow-hidden shrink-0 bg-muted\", compact ? \"h-7 w-7\" : \"h-9 w-9\")}>\n {tokenImage ? (\n <Image src={tokenImage} alt={tokenName} width={compact ? 28 : 36} height={compact ? 28 : 36} className=\"object-cover w-full h-full\" unoptimized />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" />\n )}\n </div>\n\n {/* Asset name + actor */}\n <div className=\"flex-1 min-w-0\">\n {contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className=\"text-sm font-semibold hover:text-primary transition-colors truncate block leading-tight\">\n {tokenName}\n </Link>\n ) : (\n <span className=\"text-sm font-semibold text-muted-foreground\">—</span>\n )}\n {showActor && actor && (\n <Link href={getActorHref(actor)} className=\"text-xs text-muted-foreground hover:text-primary transition-colors font-mono leading-tight\">\n <AddressDisplay address={actor} chars={4} showCopy={false} />\n </Link>\n )}\n </div>\n\n {/* Right: badge + price + time + explorer */}\n <div className=\"flex items-center gap-2.5 shrink-0\">\n {!compact && (\n <span className={cn(\"text-2xs font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex\", config.bgClass, config.colorClass)}>\n {config.label}\n </span>\n )}\n\n {activity.price?.formatted && (\n <div className=\"text-right\">\n <p className=\"text-sm font-bold tabular-nums leading-tight\">{formatDisplayPrice(activity.price.formatted)}</p>\n <p className=\"text-2xs text-muted-foreground leading-tight flex items-center justify-end gap-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={10} />}\n {activity.price.currency}\n </p>\n </div>\n )}\n\n <span className=\"text-2xs text-muted-foreground tabular-nums hidden sm:block w-12 text-right\" title={new Date(activity.timestamp).toLocaleString()}>\n {timeAgo(activity.timestamp)}\n </span>\n\n {showExplorer && txLink && (\n <a href={txLink} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center justify-center h-6 w-6 rounded-md hover:bg-muted transition-colors opacity-50 sm:opacity-0 sm:group-hover:opacity-100 shrink-0\" aria-label=\"View on explorer\">\n <ExternalLink className=\"h-3 w-3 text-muted-foreground\" />\n </a>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["Image","Link"]}
@@ -42,15 +42,15 @@ function ActivityRow({
42
42
  showActor && actor && /* @__PURE__ */ jsx(Link, { href: getActorHref(actor), className: "text-xs text-muted-foreground hover:text-primary transition-colors font-mono leading-tight", children: /* @__PURE__ */ jsx(AddressDisplay, { address: actor, chars: 4, showCopy: false }) })
43
43
  ] }),
44
44
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 shrink-0", children: [
45
- !compact && /* @__PURE__ */ jsx("span", { className: cn("text-[10px] font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex", config.bgClass, config.colorClass), children: config.label }),
45
+ !compact && /* @__PURE__ */ jsx("span", { className: cn("text-2xs font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex", config.bgClass, config.colorClass), children: config.label }),
46
46
  activity.price?.formatted && /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
47
47
  /* @__PURE__ */ jsx("p", { className: "text-sm font-bold tabular-nums leading-tight", children: formatDisplayPrice(activity.price.formatted) }),
48
- /* @__PURE__ */ jsxs("p", { className: "text-[10px] text-muted-foreground leading-tight flex items-center justify-end gap-0.5", children: [
48
+ /* @__PURE__ */ jsxs("p", { className: "text-2xs text-muted-foreground leading-tight flex items-center justify-end gap-0.5", children: [
49
49
  activity.price.currency && /* @__PURE__ */ jsx(CurrencyIcon, { symbol: activity.price.currency, size: 10 }),
50
50
  activity.price.currency
51
51
  ] })
52
52
  ] }),
53
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground tabular-nums hidden sm:block w-12 text-right", title: new Date(activity.timestamp).toLocaleString(), children: timeAgo(activity.timestamp) }),
53
+ /* @__PURE__ */ jsx("span", { className: "text-2xs text-muted-foreground tabular-nums hidden sm:block w-12 text-right", title: new Date(activity.timestamp).toLocaleString(), children: timeAgo(activity.timestamp) }),
54
54
  showExplorer && txLink && /* @__PURE__ */ jsx("a", { href: txLink, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center justify-center h-6 w-6 rounded-md hover:bg-muted transition-colors opacity-50 sm:opacity-0 sm:group-hover:opacity-100 shrink-0", "aria-label": "View on explorer", children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3 text-muted-foreground" }) })
55
55
  ] })
56
56
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity } from \"@medialane/sdk\";\n\nexport interface ActivityRowProps {\n activity: ApiActivity;\n /** Optional token enrichment — if absent shows #tokenId fallback. No internal useToken call. */\n token?: { name?: string; image?: string };\n showActor?: boolean;\n showExplorer?: boolean;\n compact?: boolean;\n explorerUrl?: string;\n getAssetHref?: (contract: string, tokenId: string) => string;\n getActorHref?: (address: string) => string;\n}\n\nexport function ActivityRow({\n activity,\n token,\n showActor = true,\n showExplorer = true,\n compact = false,\n explorerUrl = \"https://voyager.online\",\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n getActorHref = (a) => `/creator/${a}`,\n}: ActivityRowProps) {\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n const txLink = activity.txHash ? `${explorerUrl}/tx/${activity.txHash}` : null;\n\n const tokenName = token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const tokenImage = token?.image ? ipfsToHttp(token.image) : null;\n\n return (\n <div className={cn(\"flex items-center gap-3 hover:bg-muted/30 transition-colors group\", compact ? \"pl-4 pr-5 py-2.5\" : \"pl-4 pr-5 py-3.5\")}>\n {/* Type icon */}\n <div className={cn(\"rounded-lg flex items-center justify-center shrink-0\", config.bgClass, compact ? \"h-7 w-7\" : \"h-8 w-8\")}>\n <Icon className={cn(\"shrink-0\", config.colorClass, compact ? \"h-3.5 w-3.5\" : \"h-4 w-4\")} />\n </div>\n\n {/* Token thumbnail */}\n <div className={cn(\"rounded-md overflow-hidden shrink-0 bg-muted\", compact ? \"h-7 w-7\" : \"h-9 w-9\")}>\n {tokenImage ? (\n <Image src={tokenImage} alt={tokenName} width={compact ? 28 : 36} height={compact ? 28 : 36} className=\"object-cover w-full h-full\" unoptimized />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" />\n )}\n </div>\n\n {/* Asset name + actor */}\n <div className=\"flex-1 min-w-0\">\n {contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className=\"text-sm font-semibold hover:text-primary transition-colors truncate block leading-tight\">\n {tokenName}\n </Link>\n ) : (\n <span className=\"text-sm font-semibold text-muted-foreground\">—</span>\n )}\n {showActor && actor && (\n <Link href={getActorHref(actor)} className=\"text-xs text-muted-foreground hover:text-primary transition-colors font-mono leading-tight\">\n <AddressDisplay address={actor} chars={4} showCopy={false} />\n </Link>\n )}\n </div>\n\n {/* Right: badge + price + time + explorer */}\n <div className=\"flex items-center gap-2.5 shrink-0\">\n {!compact && (\n <span className={cn(\"text-[10px] font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex\", config.bgClass, config.colorClass)}>\n {config.label}\n </span>\n )}\n\n {activity.price?.formatted && (\n <div className=\"text-right\">\n <p className=\"text-sm font-bold tabular-nums leading-tight\">{formatDisplayPrice(activity.price.formatted)}</p>\n <p className=\"text-[10px] text-muted-foreground leading-tight flex items-center justify-end gap-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={10} />}\n {activity.price.currency}\n </p>\n </div>\n )}\n\n <span className=\"text-[10px] text-muted-foreground tabular-nums hidden sm:block w-12 text-right\" title={new Date(activity.timestamp).toLocaleString()}>\n {timeAgo(activity.timestamp)}\n </span>\n\n {showExplorer && txLink && (\n <a href={txLink} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center justify-center h-6 w-6 rounded-md hover:bg-muted transition-colors opacity-50 sm:opacity-0 sm:group-hover:opacity-100 shrink-0\" aria-label=\"View on explorer\">\n <ExternalLink className=\"h-3 w-3 text-muted-foreground\" />\n </a>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/activity-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ExternalLink } from \"lucide-react\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiActivity } from \"@medialane/sdk\";\n\nexport interface ActivityRowProps {\n activity: ApiActivity;\n /** Optional token enrichment — if absent shows #tokenId fallback. No internal useToken call. */\n token?: { name?: string; image?: string };\n showActor?: boolean;\n showExplorer?: boolean;\n compact?: boolean;\n explorerUrl?: string;\n getAssetHref?: (contract: string, tokenId: string) => string;\n getActorHref?: (address: string) => string;\n}\n\nexport function ActivityRow({\n activity,\n token,\n showActor = true,\n showExplorer = true,\n compact = false,\n explorerUrl = \"https://voyager.online\",\n getAssetHref = (c, t) => `/asset/${c}/${t}`,\n getActorHref = (a) => `/creator/${a}`,\n}: ActivityRowProps) {\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n const txLink = activity.txHash ? `${explorerUrl}/tx/${activity.txHash}` : null;\n\n const tokenName = token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const tokenImage = token?.image ? ipfsToHttp(token.image) : null;\n\n return (\n <div className={cn(\"flex items-center gap-3 hover:bg-muted/30 transition-colors group\", compact ? \"pl-4 pr-5 py-2.5\" : \"pl-4 pr-5 py-3.5\")}>\n {/* Type icon */}\n <div className={cn(\"rounded-lg flex items-center justify-center shrink-0\", config.bgClass, compact ? \"h-7 w-7\" : \"h-8 w-8\")}>\n <Icon className={cn(\"shrink-0\", config.colorClass, compact ? \"h-3.5 w-3.5\" : \"h-4 w-4\")} />\n </div>\n\n {/* Token thumbnail */}\n <div className={cn(\"rounded-md overflow-hidden shrink-0 bg-muted\", compact ? \"h-7 w-7\" : \"h-9 w-9\")}>\n {tokenImage ? (\n <Image src={tokenImage} alt={tokenName} width={compact ? 28 : 36} height={compact ? 28 : 36} className=\"object-cover w-full h-full\" unoptimized />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" />\n )}\n </div>\n\n {/* Asset name + actor */}\n <div className=\"flex-1 min-w-0\">\n {contract && tokenId ? (\n <Link href={getAssetHref(contract, tokenId)} className=\"text-sm font-semibold hover:text-primary transition-colors truncate block leading-tight\">\n {tokenName}\n </Link>\n ) : (\n <span className=\"text-sm font-semibold text-muted-foreground\">—</span>\n )}\n {showActor && actor && (\n <Link href={getActorHref(actor)} className=\"text-xs text-muted-foreground hover:text-primary transition-colors font-mono leading-tight\">\n <AddressDisplay address={actor} chars={4} showCopy={false} />\n </Link>\n )}\n </div>\n\n {/* Right: badge + price + time + explorer */}\n <div className=\"flex items-center gap-2.5 shrink-0\">\n {!compact && (\n <span className={cn(\"text-2xs font-medium px-1.5 py-0.5 rounded hidden sm:inline-flex\", config.bgClass, config.colorClass)}>\n {config.label}\n </span>\n )}\n\n {activity.price?.formatted && (\n <div className=\"text-right\">\n <p className=\"text-sm font-bold tabular-nums leading-tight\">{formatDisplayPrice(activity.price.formatted)}</p>\n <p className=\"text-2xs text-muted-foreground leading-tight flex items-center justify-end gap-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={10} />}\n {activity.price.currency}\n </p>\n </div>\n )}\n\n <span className=\"text-2xs text-muted-foreground tabular-nums hidden sm:block w-12 text-right\" title={new Date(activity.timestamp).toLocaleString()}>\n {timeAgo(activity.timestamp)}\n </span>\n\n {showExplorer && txLink && (\n <a href={txLink} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center justify-center h-6 w-6 rounded-md hover:bg-muted transition-colors opacity-50 sm:opacity-0 sm:group-hover:opacity-100 shrink-0\" aria-label=\"View on explorer\">\n <ExternalLink className=\"h-3 w-3 text-muted-foreground\" />\n </a>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -60,7 +60,7 @@ function ActivityPill({ listing, getHref }) {
60
60
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20" }) }),
61
61
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
62
62
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-medium whitespace-nowrap max-w-[100px] truncate", children: listing.token?.name ?? `#${listing.nftTokenId}` }),
63
- listing.price?.formatted && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5", children: [
63
+ listing.price?.formatted && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-2xs font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5", children: [
64
64
  listing.price.currency && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: listing.price.currency, size: 10 }),
65
65
  (0, import_format.formatDisplayPrice)(listing.price.formatted),
66
66
  " ",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n getHref?: (order: ApiOrder) => string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BU;AA3BV,mBAAyB;AACzB,kBAAiB;AACjB,2BAA6B;AAC7B,oBAAmC;AACnC,kBAA2B;AAC3B,gBAAmB;AAWnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,eAAW,wBAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC,YAAAA;AAAA,IAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,oDAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,4CAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,6CAAC,SAAI,WAAU,WACb;AAAA,sDAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,6CAAC,OAAE,WAAU,uFACV;AAAA,oBAAQ,MAAM,YAAY,4CAAC,qCAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,gBAClF,kCAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,WAAW,UAAU,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,EAAE,UAAU,GAAG,GAAwB;AACnJ,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SACE,4CAAC,SAAI,eAAW,cAAG,SAAS,GAC1B,sDAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,4CAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n getHref?: (order: ApiOrder) => string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-2xs font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BU;AA3BV,mBAAyB;AACzB,kBAAiB;AACjB,2BAA6B;AAC7B,oBAAmC;AACnC,kBAA2B;AAC3B,gBAAmB;AAWnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,eAAW,wBAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC,YAAAA;AAAA,IAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,oDAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,4CAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,6CAAC,SAAI,WAAU,WACb;AAAA,sDAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,6CAAC,OAAE,WAAU,oFACV;AAAA,oBAAQ,MAAM,YAAY,4CAAC,qCAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,gBAClF,kCAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,WAAW,UAAU,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,EAAE,UAAU,GAAG,GAAwB;AACnJ,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SACE,4CAAC,SAAI,eAAW,cAAG,SAAS,GAC1B,sDAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,4CAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":["Link"]}
@@ -27,7 +27,7 @@ function ActivityPill({ listing, getHref }) {
27
27
  ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20" }) }),
28
28
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
29
29
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium whitespace-nowrap max-w-[100px] truncate", children: listing.token?.name ?? `#${listing.nftTokenId}` }),
30
- listing.price?.formatted && /* @__PURE__ */ jsxs("p", { className: "text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5", children: [
30
+ listing.price?.formatted && /* @__PURE__ */ jsxs("p", { className: "text-2xs font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5", children: [
31
31
  listing.price.currency && /* @__PURE__ */ jsx(CurrencyIcon, { symbol: listing.price.currency, size: 10 }),
32
32
  formatDisplayPrice(listing.price.formatted),
33
33
  " ",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n getHref?: (order: ApiOrder) => string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA6BU,cAgBA,YAhBA;AA3BV,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,UAAU;AAWnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,WAAW,WAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,4BAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,oBAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,qBAAC,SAAI,WAAU,WACb;AAAA,8BAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,qBAAC,OAAE,WAAU,uFACV;AAAA,oBAAQ,MAAM,YAAY,oBAAC,gBAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,YAClF,mBAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,WAAW,UAAU,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,EAAE,UAAU,GAAG,GAAwB;AACnJ,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SACE,oBAAC,SAAI,WAAW,GAAG,SAAS,GAC1B,8BAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,oBAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n getHref?: (order: ApiOrder) => string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-2xs font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA6BU,cAgBA,YAhBA;AA3BV,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,UAAU;AAWnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,WAAW,WAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,4BAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,oBAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,qBAAC,SAAI,WAAU,WACb;AAAA,8BAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,qBAAC,OAAE,WAAU,oFACV;AAAA,oBAAQ,MAAM,YAAY,oBAAC,gBAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,YAClF,mBAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,WAAW,UAAU,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,EAAE,UAAU,GAAG,GAAwB;AACnJ,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SACE,oBAAC,SAAI,WAAW,GAAG,SAAS,GAC1B,8BAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,oBAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":[]}
@@ -89,12 +89,12 @@ function AssetCard({
89
89
  ] }),
90
90
  indexing && /* @__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: [
91
91
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-3 w-3 animate-spin text-white/70" }),
92
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] text-white/70", children: "Indexing\u2026" })
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-2xs text-white/70", children: "Indexing\u2026" })
93
93
  ] })
94
94
  ] }) }),
95
95
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-2 px-3 py-3", children: [
96
96
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href, className: "block min-w-0 flex-1", children: [
97
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[15px] font-bold line-clamp-1 leading-snug", children: name }),
97
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-base font-bold line-clamp-1 leading-snug", children: name }),
98
98
  subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground line-clamp-1 leading-snug", children: subtitle })
99
99
  ] }),
100
100
  ipType && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "shrink-0 mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ip_type_badge.IpTypeBadge, { ipType, size: "sm", baseUrl: ipTypeBaseUrl }) })