@burdenoff/microfe-coolandlovely 2026.706.2 → 2026.710.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 (213) hide show
  1. package/dist/coolandlovely/CoolAndLovelyRoot.d.ts +5 -0
  2. package/dist/coolandlovely/CoolAndLovelyRoot.d.ts.map +1 -0
  3. package/dist/coolandlovely/CoolAndLovelyRoot.js +62 -46
  4. package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
  5. package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts +4 -0
  6. package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts.map +1 -0
  7. package/dist/coolandlovely/components/ActorName.d.ts +14 -0
  8. package/dist/coolandlovely/components/ActorName.d.ts.map +1 -0
  9. package/dist/coolandlovely/components/AddToLookbookButton.d.ts +10 -0
  10. package/dist/coolandlovely/components/AddToLookbookButton.d.ts.map +1 -0
  11. package/dist/coolandlovely/components/AddToLookbookButton.js +22 -22
  12. package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -1
  13. package/dist/coolandlovely/components/BrandCover.d.ts +17 -0
  14. package/dist/coolandlovely/components/BrandCover.d.ts.map +1 -0
  15. package/dist/coolandlovely/components/BrandCover.js +39 -0
  16. package/dist/coolandlovely/components/BrandCover.js.map +1 -0
  17. package/dist/coolandlovely/components/BrandCreatorAvatars.d.ts +14 -0
  18. package/dist/coolandlovely/components/BrandCreatorAvatars.d.ts.map +1 -0
  19. package/dist/coolandlovely/components/BrandCreatorAvatars.js +57 -0
  20. package/dist/coolandlovely/components/BrandCreatorAvatars.js.map +1 -0
  21. package/dist/coolandlovely/components/ColourSwatchRow.d.ts +11 -0
  22. package/dist/coolandlovely/components/ColourSwatchRow.d.ts.map +1 -0
  23. package/dist/coolandlovely/components/ColourSwatchRow.js +86 -0
  24. package/dist/coolandlovely/components/ColourSwatchRow.js.map +1 -0
  25. package/dist/coolandlovely/components/Comments.d.ts +14 -0
  26. package/dist/coolandlovely/components/Comments.d.ts.map +1 -0
  27. package/dist/coolandlovely/components/Comments.js +4 -4
  28. package/dist/coolandlovely/components/Comments.js.map +1 -1
  29. package/dist/coolandlovely/components/EmptyState.d.ts +14 -0
  30. package/dist/coolandlovely/components/EmptyState.d.ts.map +1 -0
  31. package/dist/coolandlovely/components/Field.d.ts +68 -0
  32. package/dist/coolandlovely/components/Field.d.ts.map +1 -0
  33. package/dist/coolandlovely/components/FileImage.d.ts +10 -0
  34. package/dist/coolandlovely/components/FileImage.d.ts.map +1 -0
  35. package/dist/coolandlovely/components/FileImage.js.map +1 -1
  36. package/dist/coolandlovely/components/FollowButton.d.ts +11 -0
  37. package/dist/coolandlovely/components/FollowButton.d.ts.map +1 -0
  38. package/dist/coolandlovely/components/ImageUploadField.d.ts +21 -0
  39. package/dist/coolandlovely/components/ImageUploadField.d.ts.map +1 -0
  40. package/dist/coolandlovely/components/ImageUploadField.js +139 -57
  41. package/dist/coolandlovely/components/ImageUploadField.js.map +1 -1
  42. package/dist/coolandlovely/components/LookCard.d.ts +17 -0
  43. package/dist/coolandlovely/components/LookCard.d.ts.map +1 -0
  44. package/dist/coolandlovely/components/LookCard.js +77 -0
  45. package/dist/coolandlovely/components/LookCard.js.map +1 -0
  46. package/dist/coolandlovely/components/MetricsCard.d.ts +16 -0
  47. package/dist/coolandlovely/components/MetricsCard.d.ts.map +1 -0
  48. package/dist/coolandlovely/components/MetricsCard.js +1 -1
  49. package/dist/coolandlovely/components/MetricsCard.js.map +1 -1
  50. package/dist/coolandlovely/components/PageLayout.d.ts +17 -0
  51. package/dist/coolandlovely/components/PageLayout.d.ts.map +1 -0
  52. package/dist/coolandlovely/components/ShopItemCard.d.ts +15 -0
  53. package/dist/coolandlovely/components/ShopItemCard.d.ts.map +1 -0
  54. package/dist/coolandlovely/components/ShopItemCard.js +45 -0
  55. package/dist/coolandlovely/components/ShopItemCard.js.map +1 -0
  56. package/dist/coolandlovely/components/StateViews.d.ts +16 -0
  57. package/dist/coolandlovely/components/StateViews.d.ts.map +1 -0
  58. package/dist/coolandlovely/components/StatusBadge.d.ts +9 -0
  59. package/dist/coolandlovely/components/StatusBadge.d.ts.map +1 -0
  60. package/dist/coolandlovely/components/StepTracker.d.ts +12 -0
  61. package/dist/coolandlovely/components/StepTracker.d.ts.map +1 -0
  62. package/dist/coolandlovely/components/StepTracker.js +35 -0
  63. package/dist/coolandlovely/components/StepTracker.js.map +1 -0
  64. package/dist/coolandlovely/components/TagList.d.ts +12 -0
  65. package/dist/coolandlovely/components/TagList.d.ts.map +1 -0
  66. package/dist/coolandlovely/components/Thumbnail.d.ts +23 -0
  67. package/dist/coolandlovely/components/Thumbnail.d.ts.map +1 -0
  68. package/dist/coolandlovely/components/Thumbnail.js +15 -11
  69. package/dist/coolandlovely/components/Thumbnail.js.map +1 -1
  70. package/dist/coolandlovely/components/VisibilityChip.d.ts +10 -0
  71. package/dist/coolandlovely/components/VisibilityChip.d.ts.map +1 -0
  72. package/dist/coolandlovely/components/VisibilityChip.js +32 -0
  73. package/dist/coolandlovely/components/VisibilityChip.js.map +1 -0
  74. package/dist/coolandlovely/components/index.d.ts +26 -0
  75. package/dist/coolandlovely/components/index.d.ts.map +1 -0
  76. package/dist/coolandlovely/context/CoolAndLovelyContext.d.ts +16 -0
  77. package/dist/coolandlovely/context/CoolAndLovelyContext.d.ts.map +1 -0
  78. package/dist/coolandlovely/context/index.d.ts +6 -0
  79. package/dist/coolandlovely/context/index.d.ts.map +1 -0
  80. package/dist/coolandlovely/hooks/index.d.ts +11 -0
  81. package/dist/coolandlovely/hooks/index.d.ts.map +1 -0
  82. package/dist/coolandlovely/hooks/useComments.d.ts +37 -0
  83. package/dist/coolandlovely/hooks/useComments.d.ts.map +1 -0
  84. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts +106 -0
  85. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts.map +1 -0
  86. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +94 -69
  87. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
  88. package/dist/coolandlovely/hooks/useFiles.d.ts +62 -0
  89. package/dist/coolandlovely/hooks/useFiles.d.ts.map +1 -0
  90. package/dist/coolandlovely/hooks/useFiles.js +49 -32
  91. package/dist/coolandlovely/hooks/useFiles.js.map +1 -1
  92. package/dist/coolandlovely/index.d.ts +11 -0
  93. package/dist/coolandlovely/index.d.ts.map +1 -0
  94. package/dist/coolandlovely/pages/HomePage.d.ts +10 -0
  95. package/dist/coolandlovely/pages/HomePage.d.ts.map +1 -0
  96. package/dist/coolandlovely/pages/HomePage.js +112 -133
  97. package/dist/coolandlovely/pages/HomePage.js.map +1 -1
  98. package/dist/coolandlovely/pages/brands/BrandDetailPage.d.ts +9 -0
  99. package/dist/coolandlovely/pages/brands/BrandDetailPage.d.ts.map +1 -0
  100. package/dist/coolandlovely/pages/brands/BrandDetailPage.js +253 -242
  101. package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
  102. package/dist/coolandlovely/pages/brands/BrandFormPage.d.ts +9 -0
  103. package/dist/coolandlovely/pages/brands/BrandFormPage.d.ts.map +1 -0
  104. package/dist/coolandlovely/pages/brands/BrandFormPage.js +116 -112
  105. package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
  106. package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts +9 -0
  107. package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts.map +1 -0
  108. package/dist/coolandlovely/pages/brands/BrandsListPage.js +13 -13
  109. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  110. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.d.ts +9 -0
  111. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.d.ts.map +1 -0
  112. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +117 -95
  113. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
  114. package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.d.ts +10 -0
  115. package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.d.ts.map +1 -0
  116. package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +1 -1
  117. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.d.ts +9 -0
  118. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.d.ts.map +1 -0
  119. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js +50 -43
  120. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
  121. package/dist/coolandlovely/pages/collections/CollectionDetailPage.d.ts +9 -0
  122. package/dist/coolandlovely/pages/collections/CollectionDetailPage.d.ts.map +1 -0
  123. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +131 -108
  124. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
  125. package/dist/coolandlovely/pages/collections/CollectionFormPage.d.ts +9 -0
  126. package/dist/coolandlovely/pages/collections/CollectionFormPage.d.ts.map +1 -0
  127. package/dist/coolandlovely/pages/collections/CollectionFormPage.js +1 -1
  128. package/dist/coolandlovely/pages/collections/CollectionsListPage.d.ts +8 -0
  129. package/dist/coolandlovely/pages/collections/CollectionsListPage.d.ts.map +1 -0
  130. package/dist/coolandlovely/pages/collections/CollectionsListPage.js +59 -56
  131. package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
  132. package/dist/coolandlovely/pages/discover/DiscoverPage.d.ts +13 -0
  133. package/dist/coolandlovely/pages/discover/DiscoverPage.d.ts.map +1 -0
  134. package/dist/coolandlovely/pages/discover/DiscoverPage.js +1 -1
  135. package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -1
  136. package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts +9 -0
  137. package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts.map +1 -0
  138. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +175 -147
  139. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
  140. package/dist/coolandlovely/pages/items/StyleItemFormPage.d.ts +10 -0
  141. package/dist/coolandlovely/pages/items/StyleItemFormPage.d.ts.map +1 -0
  142. package/dist/coolandlovely/pages/items/StyleItemFormPage.js +1 -1
  143. package/dist/coolandlovely/pages/items/StyleItemsListPage.d.ts +9 -0
  144. package/dist/coolandlovely/pages/items/StyleItemsListPage.d.ts.map +1 -0
  145. package/dist/coolandlovely/pages/items/StyleItemsListPage.js +71 -62
  146. package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
  147. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.d.ts +12 -0
  148. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.d.ts.map +1 -0
  149. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +149 -127
  150. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
  151. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.d.ts +10 -0
  152. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.d.ts.map +1 -0
  153. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +69 -53
  154. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
  155. package/dist/coolandlovely/pages/looks/LookDetailPage.d.ts +9 -0
  156. package/dist/coolandlovely/pages/looks/LookDetailPage.d.ts.map +1 -0
  157. package/dist/coolandlovely/pages/looks/LookDetailPage.js +135 -113
  158. package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
  159. package/dist/coolandlovely/pages/looks/LookFormPage.d.ts +10 -0
  160. package/dist/coolandlovely/pages/looks/LookFormPage.d.ts.map +1 -0
  161. package/dist/coolandlovely/pages/looks/LookFormPage.js +122 -110
  162. package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
  163. package/dist/coolandlovely/pages/looks/LooksListPage.d.ts +9 -0
  164. package/dist/coolandlovely/pages/looks/LooksListPage.d.ts.map +1 -0
  165. package/dist/coolandlovely/pages/looks/LooksListPage.js +60 -97
  166. package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
  167. package/dist/coolandlovely/pages/profile/StyleProfilePage.d.ts +12 -0
  168. package/dist/coolandlovely/pages/profile/StyleProfilePage.d.ts.map +1 -0
  169. package/dist/coolandlovely/pages/profile/StyleProfilePage.js +372 -210
  170. package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
  171. package/dist/coolandlovely/pages/trends/TrendsPage.d.ts +11 -0
  172. package/dist/coolandlovely/pages/trends/TrendsPage.d.ts.map +1 -0
  173. package/dist/coolandlovely/pages/trends/TrendsPage.js +1 -1
  174. package/dist/coolandlovely/pages/trends/TrendsPage.js.map +1 -1
  175. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.d.ts +10 -0
  176. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.d.ts.map +1 -0
  177. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js +130 -94
  178. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
  179. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts +12 -0
  180. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts.map +1 -0
  181. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +75 -76
  182. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
  183. package/dist/coolandlovely/store/coolandlovelyStore.d.ts +56 -0
  184. package/dist/coolandlovely/store/coolandlovelyStore.d.ts.map +1 -0
  185. package/dist/coolandlovely/store/index.d.ts +6 -0
  186. package/dist/coolandlovely/store/index.d.ts.map +1 -0
  187. package/dist/coolandlovely/types/index.d.ts +451 -0
  188. package/dist/coolandlovely/types/index.d.ts.map +1 -0
  189. package/dist/coolandlovely/utils/cn.d.ts +4 -0
  190. package/dist/coolandlovely/utils/cn.d.ts.map +1 -0
  191. package/dist/coolandlovely/utils/formatters.d.ts +101 -0
  192. package/dist/coolandlovely/utils/formatters.d.ts.map +1 -0
  193. package/dist/coolandlovely/utils/icons.d.ts +6 -0
  194. package/dist/coolandlovely/utils/icons.d.ts.map +1 -0
  195. package/dist/coolandlovely/utils/index.d.ts +9 -0
  196. package/dist/coolandlovely/utils/index.d.ts.map +1 -0
  197. package/dist/coolandlovely/utils/navigation.d.ts +20 -0
  198. package/dist/coolandlovely/utils/navigation.d.ts.map +1 -0
  199. package/dist/generated/global-operations.d.ts +2 -0
  200. package/dist/generated/global-operations.d.ts.map +1 -0
  201. package/dist/generated/global-types.d.ts +23527 -0
  202. package/dist/generated/global-types.d.ts.map +1 -0
  203. package/dist/generated/wspace-operations.d.ts +2 -0
  204. package/dist/generated/wspace-operations.d.ts.map +1 -0
  205. package/dist/generated/wspace-types.d.ts +57851 -0
  206. package/dist/generated/wspace-types.d.ts.map +1 -0
  207. package/dist/index.d.ts +6 -0
  208. package/dist/index.d.ts.map +1 -0
  209. package/dist/services/createSandboxAssistantTransport.d.ts +44 -0
  210. package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -0
  211. package/dist/utils/pageContext.d.ts +28 -0
  212. package/dist/utils/pageContext.d.ts.map +1 -0
  213. package/package.json +5 -1
@@ -0,0 +1,17 @@
1
+ import { FC } from 'react';
2
+
3
+ interface LookCardProps {
4
+ id: string;
5
+ title: string;
6
+ /** Occasion label/value (rendered as a pill; enum values are title-cased). */
7
+ occasion: string;
8
+ imageFileId?: string | null;
9
+ likeCount?: number;
10
+ onOpen: () => void;
11
+ /** Show the hover like/add-to-lookbook overlay cluster. */
12
+ showActions?: boolean;
13
+ className?: string;
14
+ }
15
+ export declare const LookCard: FC<LookCardProps>;
16
+ export {};
17
+ //# sourceMappingURL=LookCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LookCard.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/LookCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAShC,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8CD,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAwDtC,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { Thumbnail as t } from "./Thumbnail.js";
3
+ import { useLikeLook as n } from "../hooks/useCoolAndLovelyApi.js";
4
+ import { AddToLookbookButton as r } from "./AddToLookbookButton.js";
5
+ import { titleCase as i } from "../utils/formatters.js";
6
+ import { useEffect as a, useState as o } from "react";
7
+ import { Heart as s, Sparkles as c } from "lucide-react";
8
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
9
+ //#region src/coolandlovely/components/LookCard.tsx
10
+ var d = ({ lookId: t, likeCount: r }) => {
11
+ let i = n(), [c, d] = o(!1), [f, p] = o(r);
12
+ return a(() => {
13
+ c || p(r);
14
+ }, [r, c]), /* @__PURE__ */ u("button", {
15
+ type: "button",
16
+ onClick: () => {
17
+ c || i.isPending || (d(!0), p((e) => e + 1), i.mutate(t, {
18
+ onSuccess: (e) => p(e.likeCount),
19
+ onError: () => {
20
+ d(!1), p(r);
21
+ }
22
+ }));
23
+ },
24
+ disabled: i.isPending,
25
+ "aria-pressed": c,
26
+ "aria-label": c ? "Liked" : "Like this look",
27
+ className: "inline-flex items-center gap-1 rounded-full bg-bg-surface/90 px-2 py-1 text-xs font-medium text-text-primary shadow-sm backdrop-blur transition-colors hover:bg-bg-surface disabled:opacity-60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]",
28
+ children: [/* @__PURE__ */ l(s, { className: e("h-3.5 w-3.5", c ? "fill-current text-accent-primary" : "text-text-secondary") }), /* @__PURE__ */ l("span", {
29
+ className: "tabular-nums",
30
+ children: f
31
+ })]
32
+ });
33
+ }, f = ({ id: n, title: a, occasion: o, imageFileId: f, likeCount: p, onOpen: m, showActions: h = !1, className: g }) => /* @__PURE__ */ u("div", {
34
+ className: e("group relative overflow-hidden rounded-xl border border-border-seam bg-bg-surface transition-shadow hover:shadow-lg", g),
35
+ children: [/* @__PURE__ */ l("button", {
36
+ type: "button",
37
+ onClick: m,
38
+ "aria-label": `Open look ${a}`,
39
+ className: "block w-full text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-focus-ring)]",
40
+ children: /* @__PURE__ */ l(t, {
41
+ icon: /* @__PURE__ */ l(c, { className: "h-8 w-8" }),
42
+ seed: n,
43
+ fileId: f,
44
+ alt: a,
45
+ className: "aspect-[3/4] w-full rounded-none",
46
+ overlay: /* @__PURE__ */ u("div", {
47
+ className: "pointer-events-none absolute inset-x-0 bottom-0 flex flex-col gap-1.5 bg-gradient-to-t from-bg-canvas/90 via-bg-canvas/45 to-transparent p-3 pt-10",
48
+ children: [/* @__PURE__ */ l("p", {
49
+ className: "truncate text-sm font-semibold text-text-primary",
50
+ children: a
51
+ }), /* @__PURE__ */ u("div", {
52
+ className: "flex items-center justify-between gap-2",
53
+ children: [/* @__PURE__ */ l("span", {
54
+ className: "inline-flex items-center rounded-full bg-bg-surface/85 px-2 py-0.5 text-[11px] font-medium text-text-primary backdrop-blur",
55
+ children: i(o)
56
+ }), !h && typeof p == "number" && p > 0 ? /* @__PURE__ */ u("span", {
57
+ className: "inline-flex items-center gap-1 text-xs text-text-secondary",
58
+ children: [/* @__PURE__ */ l(s, { className: "h-3.5 w-3.5 fill-current text-accent-primary" }), /* @__PURE__ */ l("span", {
59
+ className: "tabular-nums",
60
+ children: p
61
+ })]
62
+ }) : null]
63
+ })]
64
+ })
65
+ })
66
+ }), h ? /* @__PURE__ */ u("div", {
67
+ className: "absolute right-2 top-2 flex items-center gap-1.5 opacity-100 transition-opacity duration-200 sm:opacity-0 sm:focus-within:opacity-100 sm:group-hover:opacity-100",
68
+ children: [/* @__PURE__ */ l(d, {
69
+ lookId: n,
70
+ likeCount: p ?? 0
71
+ }), /* @__PURE__ */ l(r, { lookId: n })]
72
+ }) : null]
73
+ });
74
+ //#endregion
75
+ export { f as LookCard };
76
+
77
+ //# sourceMappingURL=LookCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LookCard.js","names":[],"sources":["../../../src/coolandlovely/components/LookCard.tsx"],"sourcesContent":["/**\n * LookCard — an editorial, image-forward card for a look.\n * @module coolandlovely/components\n *\n * A portrait `Thumbnail` (the look photo) with a frosted bottom caption (title +\n * occasion pill) and, when `showActions`, a hover-revealed top-right cluster: a\n * Like heart (optimistic, via `useLikeLook`) + `AddToLookbookButton`. Reused by\n * the home latest-looks, Discover, the looks list and the collaboration\n * attributed-looks grid. Token-only; reuses `Thumbnail`/`FileImage` for imagery.\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useState } from 'react';\nimport { Heart, Sparkles } from 'lucide-react';\nimport { Thumbnail } from './Thumbnail';\nimport { AddToLookbookButton } from './AddToLookbookButton';\nimport { useLikeLook } from '../hooks/useCoolAndLovelyApi';\nimport { titleCase } from '../utils/formatters';\nimport { cn } from '../utils/cn';\n\ninterface LookCardProps {\n id: string;\n title: string;\n /** Occasion label/value (rendered as a pill; enum values are title-cased). */\n occasion: string;\n imageFileId?: string | null;\n likeCount?: number;\n onOpen: () => void;\n /** Show the hover like/add-to-lookbook overlay cluster. */\n showActions?: boolean;\n className?: string;\n}\n\n/** Optimistic like heart — one-way like (no unlike op exists on the server). */\nconst LikeHeart: FC<{ lookId: string; likeCount: number }> = ({ lookId, likeCount }) => {\n const like = useLikeLook();\n const [liked, setLiked] = useState(false);\n const [count, setCount] = useState(likeCount);\n\n // Keep in sync with the server count until the user likes in this session.\n useEffect(() => {\n if (!liked) setCount(likeCount);\n }, [likeCount, liked]);\n\n const handleClick = () => {\n if (liked || like.isPending) return;\n setLiked(true);\n setCount((current) => current + 1);\n like.mutate(lookId, {\n onSuccess: (look) => setCount(look.likeCount),\n onError: () => {\n setLiked(false);\n setCount(likeCount);\n },\n });\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={like.isPending}\n aria-pressed={liked}\n aria-label={liked ? 'Liked' : 'Like this look'}\n className=\"inline-flex items-center gap-1 rounded-full bg-bg-surface/90 px-2 py-1 text-xs font-medium text-text-primary shadow-sm backdrop-blur transition-colors hover:bg-bg-surface disabled:opacity-60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <Heart\n className={cn(\n 'h-3.5 w-3.5',\n liked ? 'fill-current text-accent-primary' : 'text-text-secondary'\n )}\n />\n <span className=\"tabular-nums\">{count}</span>\n </button>\n );\n};\n\nexport const LookCard: FC<LookCardProps> = ({\n id,\n title,\n occasion,\n imageFileId,\n likeCount,\n onOpen,\n showActions = false,\n className,\n}) => {\n return (\n <div\n className={cn(\n 'group relative overflow-hidden rounded-xl border border-border-seam bg-bg-surface transition-shadow hover:shadow-lg',\n className\n )}\n >\n <button\n type=\"button\"\n onClick={onOpen}\n aria-label={`Open look ${title}`}\n className=\"block w-full text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <Thumbnail\n icon={<Sparkles className=\"h-8 w-8\" />}\n seed={id}\n fileId={imageFileId}\n alt={title}\n className=\"aspect-[3/4] w-full rounded-none\"\n overlay={\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 flex flex-col gap-1.5 bg-gradient-to-t from-bg-canvas/90 via-bg-canvas/45 to-transparent p-3 pt-10\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">{title}</p>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"inline-flex items-center rounded-full bg-bg-surface/85 px-2 py-0.5 text-[11px] font-medium text-text-primary backdrop-blur\">\n {titleCase(occasion)}\n </span>\n {!showActions && typeof likeCount === 'number' && likeCount > 0 ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-text-secondary\">\n <Heart className=\"h-3.5 w-3.5 fill-current text-accent-primary\" />\n <span className=\"tabular-nums\">{likeCount}</span>\n </span>\n ) : null}\n </div>\n </div>\n }\n />\n </button>\n\n {showActions ? (\n <div className=\"absolute right-2 top-2 flex items-center gap-1.5 opacity-100 transition-opacity duration-200 sm:opacity-0 sm:focus-within:opacity-100 sm:group-hover:opacity-100\">\n <LikeHeart lookId={id} likeCount={likeCount ?? 0} />\n <AddToLookbookButton lookId={id} />\n </div>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAkCA,IAAM,KAAwD,EAAE,WAAQ,mBAAgB;CACtF,IAAM,IAAO,GAAa,EACpB,CAAC,GAAO,KAAY,EAAS,GAAM,EACnC,CAAC,GAAO,KAAY,EAAS,EAAU;AAoB7C,QAjBA,QAAgB;AACd,EAAK,KAAO,EAAS,EAAU;IAC9B,CAAC,GAAW,EAAM,CAAC,EAgBpB,kBAAC,UAAD;EACE,MAAK;EACL,eAhBsB;AACpB,QAAS,EAAK,cAClB,EAAS,GAAK,EACd,GAAU,MAAY,IAAU,EAAE,EAClC,EAAK,OAAO,GAAQ;IAClB,YAAY,MAAS,EAAS,EAAK,UAAU;IAC7C,eAAe;AAEb,KADA,EAAS,GAAM,EACf,EAAS,EAAU;;IAEtB,CAAC;;EAOA,UAAU,EAAK;EACf,gBAAc;EACd,cAAY,IAAQ,UAAU;EAC9B,WAAU;YANZ,CAQE,kBAAC,GAAD,EACE,WAAW,EACT,eACA,IAAQ,qCAAqC,sBAC9C,EACD,CAAA,EACF,kBAAC,QAAD;GAAM,WAAU;aAAgB;GAAa,CAAA,CACtC;;GAIA,KAA+B,EAC1C,OACA,UACA,aACA,gBACA,cACA,WACA,iBAAc,IACd,mBAGE,kBAAC,OAAD;CACE,WAAW,EACT,uHACA,EACD;WAJH,CAME,kBAAC,UAAD;EACE,MAAK;EACL,SAAS;EACT,cAAY,aAAa;EACzB,WAAU;YAEV,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;GACtC,MAAM;GACN,QAAQ;GACR,KAAK;GACL,WAAU;GACV,SACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAAoD;KAAU,CAAA,EAC3E,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAU,EAAS;MACf,CAAA,EACN,CAAC,KAAe,OAAO,KAAc,YAAY,IAAY,IAC5D,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CACE,kBAAC,GAAD,EAAO,WAAU,gDAAiD,CAAA,EAClE,kBAAC,QAAD;OAAM,WAAU;iBAAgB;OAAiB,CAAA,CAC5C;UACL,KACA;OACF;;GAER,CAAA;EACK,CAAA,EAER,IACC,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD;GAAW,QAAQ;GAAI,WAAW,KAAa;GAAK,CAAA,EACpD,kBAAC,GAAD,EAAqB,QAAQ,GAAM,CAAA,CAC/B;MACJ,KACA"}
@@ -0,0 +1,16 @@
1
+ import { FC, ReactNode } from 'react';
2
+ import { TrendDirection } from '../types';
3
+
4
+ interface MetricsCardProps {
5
+ icon: ReactNode;
6
+ value: string | number;
7
+ label: string;
8
+ trend?: TrendDirection;
9
+ trendValue?: string;
10
+ className?: string;
11
+ /** Renders the featured hero metric (glass treatment + accent glow). */
12
+ featured?: boolean;
13
+ }
14
+ export declare const MetricsCard: FC<MetricsCardProps>;
15
+ export {};
16
+ //# sourceMappingURL=MetricsCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetricsCard.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/MetricsCard.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,UAAU,gBAAgB;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAQD,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAmC5C,CAAC"}
@@ -25,7 +25,7 @@ var s = {
25
25
  children: [/* @__PURE__ */ a("div", {
26
26
  className: "flex items-center justify-between",
27
27
  children: [/* @__PURE__ */ i("div", {
28
- className: "text-text-secondary",
28
+ className: "inline-flex h-9 w-9 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent-primary",
29
29
  children: t
30
30
  }), c && f && p && /* @__PURE__ */ a("div", {
31
31
  className: e("flex items-center gap-1 text-xs font-medium", f.color),
@@ -1 +1 @@
1
- {"version":3,"file":"MetricsCard.js","names":[],"sources":["../../../src/coolandlovely/components/MetricsCard.tsx"],"sourcesContent":["/**\n * Metrics Card Component\n * @module coolandlovely/components\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { TrendingUp, TrendingDown, Minus } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport type { TrendDirection } from '../types';\n\ninterface MetricsCardProps {\n icon: ReactNode;\n value: string | number;\n label: string;\n trend?: TrendDirection;\n trendValue?: string;\n className?: string;\n /** Renders the featured hero metric (glass treatment + accent glow). */\n featured?: boolean;\n}\n\nconst trendConfig: Record<TrendDirection, { icon: typeof TrendingUp; color: string }> = {\n up: { icon: TrendingUp, color: 'text-status-success-text' },\n down: { icon: TrendingDown, color: 'text-status-error-text' },\n neutral: { icon: Minus, color: 'text-text-secondary' },\n};\n\nexport const MetricsCard: FC<MetricsCardProps> = ({\n icon,\n value,\n label,\n trend,\n trendValue,\n className,\n featured = false,\n}) => {\n const trendInfo = trend ? trendConfig[trend] : null;\n const TrendIcon = trendInfo?.icon;\n\n return (\n <GlassCard\n treatment={featured ? 'glass' : 'metric'}\n glow={featured}\n className={cn('p-6', className)}\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"text-text-secondary\">{icon}</div>\n {trend && trendInfo && TrendIcon && (\n <div className={cn('flex items-center gap-1 text-xs font-medium', trendInfo.color)}>\n <TrendIcon className=\"h-3.5 w-3.5\" />\n {trendValue && <span className=\"tabular-nums\">{trendValue}</span>}\n </div>\n )}\n </div>\n <div className=\"mt-3\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">{value}</p>\n <p className=\"mt-1 text-sm text-text-secondary\">{label}</p>\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;AAsBA,IAAM,IAAkF;CACtF,IAAI;EAAE,MAAM;EAAY,OAAO;EAA4B;CAC3D,MAAM;EAAE,MAAM;EAAc,OAAO;EAA0B;CAC7D,SAAS;EAAE,MAAM;EAAO,OAAO;EAAuB;CACvD,EAEY,KAAqC,EAChD,SACA,UACA,UACA,UACA,eACA,cACA,cAAW,SACP;CACJ,IAAM,IAAY,IAAQ,EAAY,KAAS,MACzC,IAAY,GAAW;AAE7B,QACE,kBAAC,GAAD;EACE,WAAW,IAAW,UAAU;EAChC,MAAM;EACN,WAAW,EAAG,OAAO,EAAU;YAHjC,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAuB;IAAW,CAAA,EAChD,KAAS,KAAa,KACrB,kBAAC,OAAD;IAAK,WAAW,EAAG,+CAA+C,EAAU,MAAM;cAAlF,CACE,kBAAC,GAAD,EAAW,WAAU,eAAgB,CAAA,EACpC,KAAc,kBAAC,QAAD;KAAM,WAAU;eAAgB;KAAkB,CAAA,CAC7D;MAEJ;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAqD;IAAU,CAAA,EAC5E,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAAU,CAAA,CACvD;KACI"}
1
+ {"version":3,"file":"MetricsCard.js","names":[],"sources":["../../../src/coolandlovely/components/MetricsCard.tsx"],"sourcesContent":["/**\n * Metrics Card Component\n * @module coolandlovely/components\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { TrendingUp, TrendingDown, Minus } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport type { TrendDirection } from '../types';\n\ninterface MetricsCardProps {\n icon: ReactNode;\n value: string | number;\n label: string;\n trend?: TrendDirection;\n trendValue?: string;\n className?: string;\n /** Renders the featured hero metric (glass treatment + accent glow). */\n featured?: boolean;\n}\n\nconst trendConfig: Record<TrendDirection, { icon: typeof TrendingUp; color: string }> = {\n up: { icon: TrendingUp, color: 'text-status-success-text' },\n down: { icon: TrendingDown, color: 'text-status-error-text' },\n neutral: { icon: Minus, color: 'text-text-secondary' },\n};\n\nexport const MetricsCard: FC<MetricsCardProps> = ({\n icon,\n value,\n label,\n trend,\n trendValue,\n className,\n featured = false,\n}) => {\n const trendInfo = trend ? trendConfig[trend] : null;\n const TrendIcon = trendInfo?.icon;\n\n return (\n <GlassCard\n treatment={featured ? 'glass' : 'metric'}\n glow={featured}\n className={cn('p-6', className)}\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"inline-flex h-9 w-9 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent-primary\">\n {icon}\n </div>\n {trend && trendInfo && TrendIcon && (\n <div className={cn('flex items-center gap-1 text-xs font-medium', trendInfo.color)}>\n <TrendIcon className=\"h-3.5 w-3.5\" />\n {trendValue && <span className=\"tabular-nums\">{trendValue}</span>}\n </div>\n )}\n </div>\n <div className=\"mt-3\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">{value}</p>\n <p className=\"mt-1 text-sm text-text-secondary\">{label}</p>\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;AAsBA,IAAM,IAAkF;CACtF,IAAI;EAAE,MAAM;EAAY,OAAO;EAA4B;CAC3D,MAAM;EAAE,MAAM;EAAc,OAAO;EAA0B;CAC7D,SAAS;EAAE,MAAM;EAAO,OAAO;EAAuB;CACvD,EAEY,KAAqC,EAChD,SACA,UACA,UACA,UACA,eACA,cACA,cAAW,SACP;CACJ,IAAM,IAAY,IAAQ,EAAY,KAAS,MACzC,IAAY,GAAW;AAE7B,QACE,kBAAC,GAAD;EACE,WAAW,IAAW,UAAU;EAChC,MAAM;EACN,WAAW,EAAG,OAAO,EAAU;YAHjC,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACZ;IACG,CAAA,EACL,KAAS,KAAa,KACrB,kBAAC,OAAD;IAAK,WAAW,EAAG,+CAA+C,EAAU,MAAM;cAAlF,CACE,kBAAC,GAAD,EAAW,WAAU,eAAgB,CAAA,EACpC,KAAc,kBAAC,QAAD;KAAM,WAAU;eAAgB;KAAkB,CAAA,CAC7D;MAEJ;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAqD;IAAU,CAAA,EAC5E,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAAU,CAAA,CACvD;KACI"}
@@ -0,0 +1,17 @@
1
+ import { FC, ReactNode } from 'react';
2
+
3
+ interface PageLayoutProps {
4
+ title: ReactNode;
5
+ description?: string;
6
+ actions?: ReactNode;
7
+ children: ReactNode;
8
+ className?: string;
9
+ /**
10
+ * Enables the living-glass hero backdrop (AuroraBackground) behind the page
11
+ * header. Use on at most ONE page per MFE (the primary landing page).
12
+ */
13
+ hero?: boolean;
14
+ }
15
+ export declare const PageLayout: FC<PageLayoutProps>;
16
+ export {};
17
+ //# sourceMappingURL=PageLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageLayout.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/PageLayout.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3C,UAAU,eAAe;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAwBD,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAkC1C,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { FC } from 'react';
2
+
3
+ interface ShopItemCardProps {
4
+ id: string;
5
+ name: string;
6
+ brandName?: string;
7
+ price: number;
8
+ currency: string;
9
+ imageFileId?: string | null;
10
+ onOpen: () => void;
11
+ className?: string;
12
+ }
13
+ export declare const ShopItemCard: FC<ShopItemCardProps>;
14
+ export {};
15
+ //# sourceMappingURL=ShopItemCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopItemCard.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/ShopItemCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CA0C9C,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { Thumbnail as t } from "./Thumbnail.js";
3
+ import { formatPrice as n } from "../utils/formatters.js";
4
+ import { ChevronRight as r, ShoppingBag as i } from "lucide-react";
5
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
6
+ //#region src/coolandlovely/components/ShopItemCard.tsx
7
+ var s = ({ id: s, name: c, brandName: l, price: u, currency: d, imageFileId: f, onOpen: p, className: m }) => /* @__PURE__ */ o("button", {
8
+ type: "button",
9
+ onClick: p,
10
+ "aria-label": `Shop ${c}`,
11
+ className: e("group flex w-full flex-col overflow-hidden rounded-xl border border-border-seam bg-bg-surface text-left transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]", m),
12
+ children: [/* @__PURE__ */ a(t, {
13
+ icon: /* @__PURE__ */ a(i, { className: "h-7 w-7" }),
14
+ seed: s,
15
+ fileId: f,
16
+ alt: c,
17
+ className: "aspect-square w-full rounded-none"
18
+ }), /* @__PURE__ */ o("div", {
19
+ className: "flex flex-col gap-0.5 p-3",
20
+ children: [
21
+ /* @__PURE__ */ a("p", {
22
+ className: "truncate text-sm font-medium text-text-primary",
23
+ children: c
24
+ }),
25
+ l ? /* @__PURE__ */ a("p", {
26
+ className: "truncate text-xs text-text-secondary",
27
+ children: l
28
+ }) : null,
29
+ /* @__PURE__ */ o("div", {
30
+ className: "mt-2 flex items-center justify-between gap-2",
31
+ children: [/* @__PURE__ */ a("span", {
32
+ className: "text-sm font-semibold text-text-primary tabular-nums",
33
+ children: n(u, d)
34
+ }), /* @__PURE__ */ o("span", {
35
+ className: "inline-flex items-center gap-0.5 text-xs font-semibold text-accent-primary",
36
+ children: ["Shop", /* @__PURE__ */ a(r, { className: "h-3.5 w-3.5 transition-transform group-hover:translate-x-0.5" })]
37
+ })]
38
+ })
39
+ ]
40
+ })]
41
+ });
42
+ //#endregion
43
+ export { s as ShopItemCard };
44
+
45
+ //# sourceMappingURL=ShopItemCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopItemCard.js","names":[],"sources":["../../../src/coolandlovely/components/ShopItemCard.tsx"],"sourcesContent":["/**\n * ShopItemCard — a product card for the \"shop the look\" grid.\n * @module coolandlovely/components\n *\n * Image + name + brand line + price + a rose \"Shop\" chevron that drills through\n * to the item detail page (the platform has no external shop URL, so \"Shop\" is\n * the internal drill-through). Reuses `Thumbnail`/`FileImage` for imagery.\n */\n\nimport type { FC } from 'react';\nimport { ChevronRight, ShoppingBag } from 'lucide-react';\nimport { Thumbnail } from './Thumbnail';\nimport { formatPrice } from '../utils/formatters';\nimport { cn } from '../utils/cn';\n\ninterface ShopItemCardProps {\n id: string;\n name: string;\n brandName?: string;\n price: number;\n currency: string;\n imageFileId?: string | null;\n onOpen: () => void;\n className?: string;\n}\n\nexport const ShopItemCard: FC<ShopItemCardProps> = ({\n id,\n name,\n brandName,\n price,\n currency,\n imageFileId,\n onOpen,\n className,\n}) => {\n return (\n <button\n type=\"button\"\n onClick={onOpen}\n aria-label={`Shop ${name}`}\n className={cn(\n 'group flex w-full flex-col overflow-hidden rounded-xl border border-border-seam bg-bg-surface text-left transition-shadow hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n className\n )}\n >\n <Thumbnail\n icon={<ShoppingBag className=\"h-7 w-7\" />}\n seed={id}\n fileId={imageFileId}\n alt={name}\n className=\"aspect-square w-full rounded-none\"\n />\n <div className=\"flex flex-col gap-0.5 p-3\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{name}</p>\n {brandName ? <p className=\"truncate text-xs text-text-secondary\">{brandName}</p> : null}\n <div className=\"mt-2 flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-text-primary tabular-nums\">\n {formatPrice(price, currency)}\n </span>\n <span className=\"inline-flex items-center gap-0.5 text-xs font-semibold text-accent-primary\">\n Shop\n <ChevronRight className=\"h-3.5 w-3.5 transition-transform group-hover:translate-x-0.5\" />\n </span>\n </div>\n </div>\n </button>\n );\n};\n"],"mappings":";;;;;;AA0BA,IAAa,KAAuC,EAClD,OACA,SACA,cACA,UACA,aACA,gBACA,WACA,mBAGE,kBAAC,UAAD;CACE,MAAK;CACL,SAAS;CACT,cAAY,QAAQ;CACpB,WAAW,EACT,0OACA,EACD;WAPH,CASE,kBAAC,GAAD;EACE,MAAM,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;EACzC,MAAM;EACN,QAAQ;EACR,KAAK;EACL,WAAU;EACV,CAAA,EACF,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,KAAD;IAAG,WAAU;cAAkD;IAAS,CAAA;GACvE,IAAY,kBAAC,KAAD;IAAG,WAAU;cAAwC;IAAc,CAAA,GAAG;GACnF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eACb,EAAY,GAAO,EAAS;KACxB,CAAA,EACP,kBAAC,QAAD;KAAM,WAAU;eAAhB,CAA6F,QAE3F,kBAAC,GAAD,EAAc,WAAU,gEAAiE,CAAA,CACpF;OACH;;GACF;IACC"}
@@ -0,0 +1,16 @@
1
+ import { FC } from 'react';
2
+
3
+ interface LoadingViewProps {
4
+ label?: string;
5
+ className?: string;
6
+ }
7
+ export declare const LoadingView: FC<LoadingViewProps>;
8
+ interface ErrorViewProps {
9
+ title?: string;
10
+ message?: string;
11
+ onRetry?: () => void;
12
+ className?: string;
13
+ }
14
+ export declare const ErrorView: FC<ErrorViewProps>;
15
+ export {};
16
+ //# sourceMappingURL=StateViews.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StateViews.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/StateViews.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAK5C,CAAC;AAEF,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAyBxC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { FC } from 'react';
2
+
3
+ interface StatusBadgeProps {
4
+ status: string;
5
+ className?: string;
6
+ }
7
+ export declare const StatusBadge: FC<StatusBadgeProps>;
8
+ export {};
9
+ //# sourceMappingURL=StatusBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwED,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAwB5C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { FC } from 'react';
2
+
3
+ interface StepTrackerProps {
4
+ /** Ordered step values (e.g. ['PROPOSED','ACCEPTED','IN_PROGRESS','PUBLISHED']). */
5
+ steps: string[];
6
+ /** The current step value — must be one of `steps`. */
7
+ current: string;
8
+ className?: string;
9
+ }
10
+ export declare const StepTracker: FC<StepTrackerProps>;
11
+ export {};
12
+ //# sourceMappingURL=StepTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepTracker.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/StepTracker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,UAAU,gBAAgB;IACxB,oFAAoF;IACpF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA6C5C,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { titleCase as t } from "../utils/formatters.js";
3
+ import { Check as n } from "lucide-react";
4
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
+ //#region src/coolandlovely/components/StepTracker.tsx
6
+ var a = ({ steps: a, current: o, className: s }) => {
7
+ let c = a.findIndex((e) => e === o), l = c === -1 ? 0 : c;
8
+ return /* @__PURE__ */ r("ol", {
9
+ className: e("flex w-full items-start", s),
10
+ children: a.map((a, o) => {
11
+ let s = o < l ? "done" : o === l ? "current" : "upcoming";
12
+ return /* @__PURE__ */ i("li", {
13
+ className: "relative flex flex-1 flex-col items-center gap-2 text-center",
14
+ children: [
15
+ o > 0 ? /* @__PURE__ */ r("span", {
16
+ "aria-hidden": "true",
17
+ className: e("absolute left-[-50%] top-4 z-0 h-0.5 w-full -translate-y-1/2", o <= l ? "bg-accent-primary" : "bg-border-seam")
18
+ }) : null,
19
+ /* @__PURE__ */ r("span", {
20
+ className: e("relative z-10 flex h-8 w-8 items-center justify-center rounded-full text-xs font-semibold tabular-nums transition-colors", s === "done" && "bg-accent-primary text-action-primary-text", s === "current" && "border-2 border-accent-primary bg-bg-surface text-accent-primary", s === "upcoming" && "border border-border-seam bg-bg-surface text-text-secondary"),
21
+ children: s === "done" ? /* @__PURE__ */ r(n, { className: "h-4 w-4" }) : o + 1
22
+ }),
23
+ /* @__PURE__ */ r("span", {
24
+ className: e("text-xs font-medium", s === "upcoming" ? "text-text-secondary" : "text-text-primary"),
25
+ children: t(a)
26
+ })
27
+ ]
28
+ }, a);
29
+ })
30
+ });
31
+ };
32
+ //#endregion
33
+ export { a as StepTracker };
34
+
35
+ //# sourceMappingURL=StepTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepTracker.js","names":[],"sources":["../../../src/coolandlovely/components/StepTracker.tsx"],"sourcesContent":["/**\n * StepTracker — a horizontal lifecycle tracker for any `Coo*Status` machine.\n * @module coolandlovely/components\n *\n * Renders a row of numbered nodes with connectors: steps before `current` are\n * done (accent-filled + check), the `current` step is ringed, upcoming steps are\n * muted. Token-only. Used by the collaboration lifecycle (Proposed → Accepted →\n * In progress → Published) and reusable for brand/collection lifecycles.\n */\n\nimport type { FC } from 'react';\nimport { Check } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { titleCase } from '../utils/formatters';\n\ninterface StepTrackerProps {\n /** Ordered step values (e.g. ['PROPOSED','ACCEPTED','IN_PROGRESS','PUBLISHED']). */\n steps: string[];\n /** The current step value — must be one of `steps`. */\n current: string;\n className?: string;\n}\n\nexport const StepTracker: FC<StepTrackerProps> = ({ steps, current, className }) => {\n const foundIdx = steps.findIndex((step) => step === current);\n const currentIdx = foundIdx === -1 ? 0 : foundIdx;\n\n return (\n <ol className={cn('flex w-full items-start', className)}>\n {steps.map((step, index) => {\n const state = index < currentIdx ? 'done' : index === currentIdx ? 'current' : 'upcoming';\n const connectorDone = index <= currentIdx;\n return (\n <li key={step} className=\"relative flex flex-1 flex-col items-center gap-2 text-center\">\n {index > 0 ? (\n <span\n aria-hidden=\"true\"\n className={cn(\n 'absolute left-[-50%] top-4 z-0 h-0.5 w-full -translate-y-1/2',\n connectorDone ? 'bg-accent-primary' : 'bg-border-seam'\n )}\n />\n ) : null}\n <span\n className={cn(\n 'relative z-10 flex h-8 w-8 items-center justify-center rounded-full text-xs font-semibold tabular-nums transition-colors',\n state === 'done' && 'bg-accent-primary text-action-primary-text',\n state === 'current' &&\n 'border-2 border-accent-primary bg-bg-surface text-accent-primary',\n state === 'upcoming' &&\n 'border border-border-seam bg-bg-surface text-text-secondary'\n )}\n >\n {state === 'done' ? <Check className=\"h-4 w-4\" /> : index + 1}\n </span>\n <span\n className={cn(\n 'text-xs font-medium',\n state === 'upcoming' ? 'text-text-secondary' : 'text-text-primary'\n )}\n >\n {titleCase(step)}\n </span>\n </li>\n );\n })}\n </ol>\n );\n};\n"],"mappings":";;;;;AAuBA,IAAa,KAAqC,EAAE,UAAO,YAAS,mBAAgB;CAClF,IAAM,IAAW,EAAM,WAAW,MAAS,MAAS,EAAQ,EACtD,IAAa,MAAa,KAAK,IAAI;AAEzC,QACE,kBAAC,MAAD;EAAI,WAAW,EAAG,2BAA2B,EAAU;YACpD,EAAM,KAAK,GAAM,MAAU;GAC1B,IAAM,IAAQ,IAAQ,IAAa,SAAS,MAAU,IAAa,YAAY;AAE/E,UACE,kBAAC,MAAD;IAAe,WAAU;cAAzB;KACG,IAAQ,IACP,kBAAC,QAAD;MACE,eAAY;MACZ,WAAW,EACT,gEAPY,KAAS,IAQL,sBAAsB,iBACvC;MACD,CAAA,GACA;KACJ,kBAAC,QAAD;MACE,WAAW,EACT,4HACA,MAAU,UAAU,8CACpB,MAAU,aACR,oEACF,MAAU,cACR,8DACH;gBAEA,MAAU,SAAS,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,GAAG,IAAQ;MACvD,CAAA;KACP,kBAAC,QAAD;MACE,WAAW,EACT,uBACA,MAAU,aAAa,wBAAwB,oBAChD;gBAEA,EAAU,EAAK;MACX,CAAA;KACJ;MA9BI,EA8BJ;IAEP;EACC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { FC } from 'react';
2
+
3
+ interface TagListProps {
4
+ tags: string[];
5
+ /** Maximum chips to show before collapsing into a "+N" chip. */
6
+ max?: number;
7
+ className?: string;
8
+ tone?: 'default' | 'accent';
9
+ }
10
+ export declare const TagList: FC<TagListProps>;
11
+ export {};
12
+ //# sourceMappingURL=TagList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagList.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/TagList.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAED,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CA2BpC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { FC, ReactNode } from 'react';
2
+
3
+ interface ThumbnailProps {
4
+ icon: ReactNode;
5
+ /** Stable seed (e.g. entity id) used to pick a deterministic accent tint. */
6
+ seed?: string;
7
+ className?: string;
8
+ /** Whether a File reference exists (shows a subtle "image attached" hint). */
9
+ hasImage?: boolean;
10
+ label?: string;
11
+ /** wspace-files File id — when it resolves, its image overlays the glyph. */
12
+ fileId?: string | null;
13
+ /** Alt text when a real image is shown. */
14
+ alt?: string;
15
+ /**
16
+ * Optional content rendered absolutely over the image (e.g. a gradient scrim
17
+ * + overlaid caption). Positioned by the caller; sits above the FileImage.
18
+ */
19
+ overlay?: ReactNode;
20
+ }
21
+ export declare const Thumbnail: FC<ThumbnailProps>;
22
+ export {};
23
+ //# sourceMappingURL=Thumbnail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Thumbnail.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/Thumbnail.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3C,UAAU,cAAc;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAmBD,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CA8BxC,CAAC"}
@@ -15,20 +15,24 @@ function a(e) {
15
15
  for (let n = 0; n < e.length; n += 1) t = (t * 31 + e.charCodeAt(n)) % 997;
16
16
  return i[t % i.length];
17
17
  }
18
- var o = ({ icon: i, seed: o, className: s, label: c, fileId: l, alt: u }) => /* @__PURE__ */ r("div", {
18
+ var o = ({ icon: i, seed: o, className: s, label: c, fileId: l, alt: u, overlay: d }) => /* @__PURE__ */ r("div", {
19
19
  className: e("relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br", a(o), s),
20
20
  "aria-hidden": c ? void 0 : !0,
21
21
  "aria-label": c,
22
- children: [/* @__PURE__ */ n("span", {
23
- className: "text-text-secondary opacity-80",
24
- children: i
25
- }), l ? /* @__PURE__ */ n("span", {
26
- className: "absolute inset-0",
27
- children: /* @__PURE__ */ n(t, {
28
- fileId: l,
29
- alt: u ?? c ?? ""
30
- })
31
- }) : null]
22
+ children: [
23
+ /* @__PURE__ */ n("span", {
24
+ className: "text-text-secondary opacity-80 transition-transform duration-300 motion-safe:group-hover:scale-[1.03]",
25
+ children: i
26
+ }),
27
+ l ? /* @__PURE__ */ n("span", {
28
+ className: "absolute inset-0 transition-transform duration-300 motion-safe:group-hover:scale-[1.03]",
29
+ children: /* @__PURE__ */ n(t, {
30
+ fileId: l,
31
+ alt: u ?? c ?? ""
32
+ })
33
+ }) : null,
34
+ d
35
+ ]
32
36
  });
33
37
  //#endregion
34
38
  export { o as Thumbnail };
@@ -1 +1 @@
1
- {"version":3,"file":"Thumbnail.js","names":[],"sources":["../../../src/coolandlovely/components/Thumbnail.tsx"],"sourcesContent":["/**\n * Thumbnail Component\n * @module coolandlovely/components\n *\n * Renders a calm, on-token visual placeholder for a fashion entity. Imagery in\n * CoolAndLovely is referenced from wspace-files-svc via federation (we only\n * have the File id here, not a resolvable URL), so the catalogue/wardrobe/look\n * surfaces render a branded glyph tile keyed by an icon rather than a broken\n * <img>. The seed (entity id) gives each tile a stable accent tint.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\nimport { FileImage } from './FileImage';\n\ninterface ThumbnailProps {\n icon: ReactNode;\n /** Stable seed (e.g. entity id) used to pick a deterministic accent tint. */\n seed?: string;\n className?: string;\n /** Whether a File reference exists (shows a subtle \"image attached\" hint). */\n hasImage?: boolean;\n label?: string;\n /** wspace-files File id — when it resolves, its image overlays the glyph. */\n fileId?: string | null;\n /** Alt text when a real image is shown. */\n alt?: string;\n}\n\nconst tints = [\n 'from-accent-purple-subtle to-bg-sunken',\n 'from-accent-blue-subtle to-bg-sunken',\n 'from-status-success-bg-subtle to-bg-sunken',\n 'from-status-warning-bg-subtle to-bg-sunken',\n 'from-[var(--color-accent-soft)] to-bg-sunken',\n];\n\nfunction tintFor(seed: string | undefined): string {\n if (!seed) return tints[0];\n let hash = 0;\n for (let i = 0; i < seed.length; i += 1) {\n hash = (hash * 31 + seed.charCodeAt(i)) % 997;\n }\n return tints[hash % tints.length];\n}\n\nexport const Thumbnail: FC<ThumbnailProps> = ({ icon, seed, className, label, fileId, alt }) => {\n return (\n <div\n className={cn(\n 'relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br',\n tintFor(seed),\n className\n )}\n aria-hidden={label ? undefined : true}\n aria-label={label}\n >\n <span className=\"text-text-secondary opacity-80\">{icon}</span>\n {fileId ? (\n <span className=\"absolute inset-0\">\n <FileImage fileId={fileId} alt={alt ?? label ?? ''} />\n </span>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;AA6BA,IAAM,IAAQ;CACZ;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,EAAQ,GAAkC;AACjD,KAAI,CAAC,EAAM,QAAO,EAAM;CACxB,IAAI,IAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,EACpC,MAAQ,IAAO,KAAK,EAAK,WAAW,EAAE,IAAI;AAE5C,QAAO,EAAM,IAAO,EAAM;;AAG5B,IAAa,KAAiC,EAAE,SAAM,SAAM,cAAW,UAAO,WAAQ,aAElF,kBAAC,OAAD;CACE,WAAW,EACT,0FACA,EAAQ,EAAK,EACb,EACD;CACD,eAAa,IAAQ,KAAA,IAAY;CACjC,cAAY;WAPd,CASE,kBAAC,QAAD;EAAM,WAAU;YAAkC;EAAY,CAAA,EAC7D,IACC,kBAAC,QAAD;EAAM,WAAU;YACd,kBAAC,GAAD;GAAmB;GAAQ,KAAK,KAAO,KAAS;GAAM,CAAA;EACjD,CAAA,GACL,KACA"}
1
+ {"version":3,"file":"Thumbnail.js","names":[],"sources":["../../../src/coolandlovely/components/Thumbnail.tsx"],"sourcesContent":["/**\n * Thumbnail Component\n * @module coolandlovely/components\n *\n * Renders a calm, on-token visual placeholder for a fashion entity. Imagery in\n * CoolAndLovely is referenced from wspace-files-svc via federation (we only\n * have the File id here, not a resolvable URL), so the catalogue/wardrobe/look\n * surfaces render a branded glyph tile keyed by an icon rather than a broken\n * <img>. The seed (entity id) gives each tile a stable accent tint.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\nimport { FileImage } from './FileImage';\n\ninterface ThumbnailProps {\n icon: ReactNode;\n /** Stable seed (e.g. entity id) used to pick a deterministic accent tint. */\n seed?: string;\n className?: string;\n /** Whether a File reference exists (shows a subtle \"image attached\" hint). */\n hasImage?: boolean;\n label?: string;\n /** wspace-files File id — when it resolves, its image overlays the glyph. */\n fileId?: string | null;\n /** Alt text when a real image is shown. */\n alt?: string;\n /**\n * Optional content rendered absolutely over the image (e.g. a gradient scrim\n * + overlaid caption). Positioned by the caller; sits above the FileImage.\n */\n overlay?: ReactNode;\n}\n\nconst tints = [\n 'from-accent-purple-subtle to-bg-sunken',\n 'from-accent-blue-subtle to-bg-sunken',\n 'from-status-success-bg-subtle to-bg-sunken',\n 'from-status-warning-bg-subtle to-bg-sunken',\n 'from-[var(--color-accent-soft)] to-bg-sunken',\n];\n\nfunction tintFor(seed: string | undefined): string {\n if (!seed) return tints[0];\n let hash = 0;\n for (let i = 0; i < seed.length; i += 1) {\n hash = (hash * 31 + seed.charCodeAt(i)) % 997;\n }\n return tints[hash % tints.length];\n}\n\nexport const Thumbnail: FC<ThumbnailProps> = ({\n icon,\n seed,\n className,\n label,\n fileId,\n alt,\n overlay,\n}) => {\n return (\n <div\n className={cn(\n 'relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br',\n tintFor(seed),\n className\n )}\n aria-hidden={label ? undefined : true}\n aria-label={label}\n >\n <span className=\"text-text-secondary opacity-80 transition-transform duration-300 motion-safe:group-hover:scale-[1.03]\">\n {icon}\n </span>\n {fileId ? (\n <span className=\"absolute inset-0 transition-transform duration-300 motion-safe:group-hover:scale-[1.03]\">\n <FileImage fileId={fileId} alt={alt ?? label ?? ''} />\n </span>\n ) : null}\n {overlay}\n </div>\n );\n};\n"],"mappings":";;;;AAkCA,IAAM,IAAQ;CACZ;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,EAAQ,GAAkC;AACjD,KAAI,CAAC,EAAM,QAAO,EAAM;CACxB,IAAI,IAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,EACpC,MAAQ,IAAO,KAAK,EAAK,WAAW,EAAE,IAAI;AAE5C,QAAO,EAAM,IAAO,EAAM;;AAG5B,IAAa,KAAiC,EAC5C,SACA,SACA,cACA,UACA,WACA,QACA,iBAGE,kBAAC,OAAD;CACE,WAAW,EACT,0FACA,EAAQ,EAAK,EACb,EACD;CACD,eAAa,IAAQ,KAAA,IAAY;CACjC,cAAY;WAPd;EASE,kBAAC,QAAD;GAAM,WAAU;aACb;GACI,CAAA;EACN,IACC,kBAAC,QAAD;GAAM,WAAU;aACd,kBAAC,GAAD;IAAmB;IAAQ,KAAK,KAAO,KAAS;IAAM,CAAA;GACjD,CAAA,GACL;EACH;EACG"}
@@ -0,0 +1,10 @@
1
+ import { FC } from 'react';
2
+
3
+ interface VisibilityChipProps {
4
+ /** A `CooVisibility` value (PUBLIC / FOLLOWERS / PRIVATE) — case-insensitive. */
5
+ visibility: string;
6
+ className?: string;
7
+ }
8
+ export declare const VisibilityChip: FC<VisibilityChipProps>;
9
+ export {};
10
+ //# sourceMappingURL=VisibilityChip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisibilityChip.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/VisibilityChip.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,UAAU,mBAAmB;IAC3B,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAiBlD,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { titleCase as t } from "../utils/formatters.js";
3
+ import { Globe as n, Lock as r, Users as i } from "lucide-react";
4
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ //#region src/coolandlovely/components/VisibilityChip.tsx
6
+ var s = {
7
+ public: {
8
+ icon: n,
9
+ label: "Public"
10
+ },
11
+ followers: {
12
+ icon: i,
13
+ label: "Followers"
14
+ },
15
+ private: {
16
+ icon: r,
17
+ label: "Private"
18
+ }
19
+ }, c = ({ visibility: n, className: i }) => {
20
+ let c = s[n.trim().toLowerCase()], l = c?.icon ?? r, u = c?.label ?? t(n);
21
+ return /* @__PURE__ */ o("span", {
22
+ className: e("inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary", i),
23
+ children: [/* @__PURE__ */ a(l, {
24
+ className: "h-3.5 w-3.5",
25
+ "aria-hidden": "true"
26
+ }), u]
27
+ });
28
+ };
29
+ //#endregion
30
+ export { c as VisibilityChip };
31
+
32
+ //# sourceMappingURL=VisibilityChip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisibilityChip.js","names":[],"sources":["../../../src/coolandlovely/components/VisibilityChip.tsx"],"sourcesContent":["/**\n * VisibilityChip — a small icon + label chip for a look/lookbook/profile\n * visibility (PRIVATE / FOLLOWERS / PUBLIC).\n * @module coolandlovely/components\n *\n * Token-only. The lock/users/globe glyph makes the visibility scannable at a\n * glance on lookbook cards, the lookbook detail header and the style profile.\n */\n\nimport type { FC } from 'react';\nimport { Globe, Lock, Users } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { titleCase } from '../utils/formatters';\n\ninterface VisibilityChipProps {\n /** A `CooVisibility` value (PUBLIC / FOLLOWERS / PRIVATE) — case-insensitive. */\n visibility: string;\n className?: string;\n}\n\nconst CONFIG: Record<string, { icon: typeof Globe; label: string }> = {\n public: { icon: Globe, label: 'Public' },\n followers: { icon: Users, label: 'Followers' },\n private: { icon: Lock, label: 'Private' },\n};\n\nexport const VisibilityChip: FC<VisibilityChipProps> = ({ visibility, className }) => {\n const key = visibility.trim().toLowerCase();\n const config = CONFIG[key];\n const Icon = config?.icon ?? Lock;\n const label = config?.label ?? titleCase(visibility);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary',\n className\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {label}\n </span>\n );\n};\n"],"mappings":";;;;;AAoBA,IAAM,IAAgE;CACpE,QAAQ;EAAE,MAAM;EAAO,OAAO;EAAU;CACxC,WAAW;EAAE,MAAM;EAAO,OAAO;EAAa;CAC9C,SAAS;EAAE,MAAM;EAAM,OAAO;EAAW;CAC1C,EAEY,KAA2C,EAAE,eAAY,mBAAgB;CAEpF,IAAM,IAAS,EADH,EAAW,MAAM,CAAC,aAAa,GAErC,IAAO,GAAQ,QAAQ,GACvB,IAAQ,GAAQ,SAAS,EAAU,EAAW;AAEpD,QACE,kBAAC,QAAD;EACE,WAAW,EACT,gHACA,EACD;YAJH,CAME,kBAAC,GAAD;GAAM,WAAU;GAAc,eAAY;GAAS,CAAA,EAClD,EACI"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Components Index
3
+ * @module coolandlovely/components
4
+ */
5
+ export { PageLayout } from './PageLayout';
6
+ export { MetricsCard } from './MetricsCard';
7
+ export { StatusBadge } from './StatusBadge';
8
+ export { EmptyState } from './EmptyState';
9
+ export { Thumbnail } from './Thumbnail';
10
+ export { FileImage } from './FileImage';
11
+ export { ImageUploadField } from './ImageUploadField';
12
+ export { TagList } from './TagList';
13
+ export { LoadingView, ErrorView } from './StateViews';
14
+ export { FieldShell, TextField, TextAreaField, SelectField, ToggleField } from './Field';
15
+ export { ActorName } from './ActorName';
16
+ export { Comments } from './Comments';
17
+ export { FollowButton } from './FollowButton';
18
+ export { AddToLookbookButton } from './AddToLookbookButton';
19
+ export { LookCard } from './LookCard';
20
+ export { BrandCover } from './BrandCover';
21
+ export { StepTracker } from './StepTracker';
22
+ export { BrandCreatorAvatars } from './BrandCreatorAvatars';
23
+ export { ShopItemCard } from './ShopItemCard';
24
+ export { ColourSwatchRow } from './ColourSwatchRow';
25
+ export { VisibilityChip } from './VisibilityChip';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ import { CoolAndLovelyRootProps } from '../types';
3
+
4
+ interface CoolAndLovelyContextValue extends Omit<CoolAndLovelyRootProps, 'registerNavItems' | 'registerFooterItems' | 'navigate'> {
5
+ isStandalone: boolean;
6
+ /** Shell's navigate function (only available in integrated mode) */
7
+ navigate?: (path: string) => void;
8
+ /** Navigate to a path relative to basePath */
9
+ navigateTo: (relativePath: string) => void;
10
+ /** Get the full path for a relative path */
11
+ getPath: (relativePath: string) => string;
12
+ }
13
+ export declare function useCoolAndLovely(): CoolAndLovelyContextValue;
14
+ export declare const CoolAndLovelyProvider: FC<PropsWithChildren<CoolAndLovelyRootProps>>;
15
+ export {};
16
+ //# sourceMappingURL=CoolAndLovelyContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoolAndLovelyContext.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/context/CoolAndLovelyContext.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAOvD,UAAU,yBAA0B,SAAQ,IAAI,CAC9C,sBAAsB,EACtB,kBAAkB,GAAG,qBAAqB,GAAG,UAAU,CACxD;IACC,YAAY,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8CAA8C;IAC9C,UAAU,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,4CAA4C;IAC5C,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C;AAQD,wBAAgB,gBAAgB,IAAI,yBAAyB,CAM5D;AAyID,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAqB/E,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Context Index
3
+ * @module coolandlovely/context
4
+ */
5
+ export { CoolAndLovelyProvider, useCoolAndLovely } from './CoolAndLovelyContext';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/context/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Hooks Index
3
+ * @module coolandlovely/hooks
4
+ */
5
+ export { useBrands, useBrand, useCreateBrand, useUpdateBrand, useTransitionBrand, useArchiveBrand, useCollections, useCollection, useCreateCollection, useUpdateCollection, usePublishCollection, useStyleItems, useStyleItem, useCreateStyleItem, useUpdateStyleItem, useArchiveStyleItem, useLooks, useLooksWithItems, useLook, useCreateLook, useUpdateLook, usePublishLook, useLikeLook, useDeleteLook, useCollaborations, useCollaboration, useCreateCollaboration, useTransitionCollaboration, useWardrobeItems, useCreateWardrobeItem, useUpdateWardrobeItem, useLogWardrobeWear, useRemoveWardrobeItem, useMyStyleProfile, useUpsertStyleProfile, useLookbooks, useLookbook, useCreateLookbook, useAddLookbookEntry, useRemoveLookbookEntry, useIsFollowing, useFollow, useUnfollow, useMyFollowing, useMyFollowers, } from './useCoolAndLovelyApi';
6
+ export type { ListBrandsArgs, ListCollectionsArgs, ListStyleItemsArgs, ListLooksArgs, ListCollaborationsArgs, ListWardrobeArgs, } from './useCoolAndLovelyApi';
7
+ export { uploadImageToFiles, useFileUrl, COO_FILE_FOLDERS } from './useFiles';
8
+ export type { UploadedImage, CooFileFolder } from './useFiles';
9
+ export { useEntityComments, useAddComment } from './useComments';
10
+ export type { EntityCommentView, EntityCommentsResult } from './useComments';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,SAAS,EACT,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,eAAe,EAEf,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EAEpB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EAEnB,QAAQ,EACR,iBAAiB,EACjB,OAAO,EACP,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EAEb,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,0BAA0B,EAE1B,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EAErB,iBAAiB,EACjB,qBAAqB,EAErB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EAEtB,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,EACd,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}