@bearmenu/ui 0.8.7 → 0.8.9

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 (179) hide show
  1. package/dist/{chunk-637L7XQ3.js → chunk-3TNPSN4D.js} +28 -9
  2. package/dist/chunk-62ES6N32.js +27 -0
  3. package/dist/chunk-AHL45DD2.js +145 -0
  4. package/dist/chunk-AXV5O2IZ.js +58 -0
  5. package/dist/chunk-IYDH5IU6.js +66 -0
  6. package/dist/chunk-OPVKL4VS.js +18 -0
  7. package/dist/chunk-Q6QH52LJ.js +38 -0
  8. package/dist/chunk-TH6W2PWG.js +213 -0
  9. package/dist/chunk-THOVPZNN.js +37 -0
  10. package/dist/chunk-YS6BHKZO.js +92 -0
  11. package/dist/components/badge.d.ts +1 -1
  12. package/dist/components/button.d.ts +1 -1
  13. package/dist/components/category-deck.js +10 -1
  14. package/dist/components/command.d.ts +7 -7
  15. package/dist/components/concept-compare.d.ts +73 -0
  16. package/dist/components/concept-compare.js +162 -0
  17. package/dist/components/coverflow.d.ts +11 -3
  18. package/dist/components/coverflow.js +34 -51
  19. package/dist/components/date-input.d.ts +1 -1
  20. package/dist/components/drift-rail.d.ts +24 -10
  21. package/dist/components/drift-rail.js +1 -1
  22. package/dist/components/event-card.d.ts +8 -0
  23. package/dist/components/event-card.js +64 -34
  24. package/dist/components/event-compact-row.d.ts +33 -6
  25. package/dist/components/event-compact-row.js +120 -39
  26. package/dist/components/event-day-header.js +3 -1
  27. package/dist/components/event-day-separator.d.ts +7 -1
  28. package/dist/components/event-day-separator.js +3 -2
  29. package/dist/components/event-detail-panel.d.ts +171 -25
  30. package/dist/components/event-detail-panel.js +471 -174
  31. package/dist/components/event-hub-hero.d.ts +25 -4
  32. package/dist/components/event-hub-hero.js +89 -19
  33. package/dist/components/event-list-row-wide.js +1 -1
  34. package/dist/components/event-list-row.d.ts +19 -6
  35. package/dist/components/event-list-row.js +79 -35
  36. package/dist/components/hour-band.d.ts +38 -40
  37. package/dist/components/hour-band.js +55 -27
  38. package/dist/components/hour-group.js +1 -1
  39. package/dist/components/hub-surface.d.ts +27 -0
  40. package/dist/components/hub-surface.js +20 -0
  41. package/dist/components/menu-family-card.d.ts +59 -0
  42. package/dist/components/menu-family-card.js +121 -0
  43. package/dist/components/menu-field.d.ts +57 -0
  44. package/dist/components/menu-field.js +3 -0
  45. package/dist/components/menu-hub-hero.d.ts +65 -0
  46. package/dist/components/menu-hub-hero.js +103 -0
  47. package/dist/components/menu-intent-tiles.d.ts +31 -0
  48. package/dist/components/menu-intent-tiles.js +50 -0
  49. package/dist/components/menu-item.d.ts +127 -0
  50. package/dist/components/menu-item.js +5 -0
  51. package/dist/components/menu-mocks.d.ts +55 -0
  52. package/dist/components/menu-mocks.js +379 -0
  53. package/dist/components/menu-types.d.ts +245 -0
  54. package/dist/components/menu-types.js +1 -0
  55. package/dist/components/motion-icon-set.js +15 -3
  56. package/dist/components/open-now-list.d.ts +40 -0
  57. package/dist/components/open-now-list.js +69 -0
  58. package/dist/components/place-types.d.ts +112 -1
  59. package/dist/components/poster-tape.js +1 -1
  60. package/dist/components/poster-wall.d.ts +3 -3
  61. package/dist/components/poster-wall.js +73 -17
  62. package/dist/components/ranked-venue-list.d.ts +49 -0
  63. package/dist/components/ranked-venue-list.js +87 -0
  64. package/dist/components/section-header.d.ts +16 -1
  65. package/dist/components/section-header.js +26 -7
  66. package/dist/components/signature-chip.d.ts +37 -0
  67. package/dist/components/signature-chip.js +4 -0
  68. package/dist/components/signature-line-list.d.ts +45 -0
  69. package/dist/components/signature-line-list.js +99 -0
  70. package/dist/components/snap-rail.d.ts +54 -0
  71. package/dist/components/snap-rail.js +109 -0
  72. package/dist/components/spinner.d.ts +2 -2
  73. package/dist/components/stat-banner.d.ts +47 -0
  74. package/dist/components/stat-banner.js +61 -0
  75. package/dist/components/text.d.ts +3 -3
  76. package/dist/components/timeline-band.d.ts +20 -2
  77. package/dist/components/timeline-band.js +1 -1
  78. package/dist/components/timeline-playhead.d.ts +26 -0
  79. package/dist/components/timeline-playhead.js +25 -0
  80. package/dist/components/venue-busyness-strip.d.ts +35 -0
  81. package/dist/components/venue-busyness-strip.js +37 -0
  82. package/dist/components/venue-grade-dimensions.d.ts +36 -0
  83. package/dist/components/venue-grade-dimensions.js +3 -0
  84. package/dist/components/venue-quotes.d.ts +32 -0
  85. package/dist/components/venue-quotes.js +3 -0
  86. package/dist/components/venue-signature-block.d.ts +39 -0
  87. package/dist/components/venue-signature-block.js +6 -0
  88. package/dist/components/venue-spotlight.d.ts +74 -0
  89. package/dist/components/venue-spotlight.js +138 -0
  90. package/dist/components/venue-wall.d.ts +41 -0
  91. package/dist/components/venue-wall.js +118 -0
  92. package/dist/components/weekday-theme-banner.d.ts +70 -0
  93. package/dist/components/weekday-theme-banner.js +127 -0
  94. package/dist/components/weekend-panel.d.ts +5 -4
  95. package/dist/components/weekend-panel.js +85 -71
  96. package/dist/hooks/use-drag-swipe.d.ts +44 -0
  97. package/dist/hooks/use-drag-swipe.js +2 -0
  98. package/dist/hooks/use-media-query.d.ts +17 -0
  99. package/dist/hooks/use-media-query.js +2 -0
  100. package/package.json +1 -1
  101. package/src/components/category-deck.tsx +19 -8
  102. package/src/components/colour-dictionary.stories.tsx +227 -0
  103. package/src/components/concept-compare.stories.tsx +104 -0
  104. package/src/components/concept-compare.tsx +276 -0
  105. package/src/components/coverflow.test.tsx +28 -1
  106. package/src/components/coverflow.tsx +37 -43
  107. package/src/components/drift-rail.tsx +167 -42
  108. package/src/components/event-card.tsx +55 -10
  109. package/src/components/event-compact-row.stories.tsx +30 -0
  110. package/src/components/event-compact-row.test.tsx +49 -0
  111. package/src/components/event-compact-row.tsx +162 -38
  112. package/src/components/event-day-header.tsx +3 -1
  113. package/src/components/event-day-separator.tsx +8 -1
  114. package/src/components/event-detail-panel.stories.tsx +205 -97
  115. package/src/components/event-detail-panel.test.tsx +181 -0
  116. package/src/components/event-detail-panel.tsx +703 -185
  117. package/src/components/event-hub-hero.stories.tsx +30 -0
  118. package/src/components/event-hub-hero.tsx +102 -30
  119. package/src/components/event-list-row.stories.tsx +34 -0
  120. package/src/components/event-list-row.test.tsx +53 -0
  121. package/src/components/event-list-row.tsx +135 -87
  122. package/src/components/hour-band.stories.tsx +28 -5
  123. package/src/components/hour-band.tsx +90 -70
  124. package/src/components/hub-surface.stories.tsx +68 -0
  125. package/src/components/hub-surface.tsx +40 -0
  126. package/src/components/menu-family-card.stories.tsx +112 -0
  127. package/src/components/menu-family-card.tsx +211 -0
  128. package/src/components/menu-field.stories.tsx +74 -0
  129. package/src/components/menu-field.tsx +199 -0
  130. package/src/components/menu-hub-hero.stories.tsx +92 -0
  131. package/src/components/menu-hub-hero.tsx +187 -0
  132. package/src/components/menu-intent-tiles.stories.tsx +54 -0
  133. package/src/components/menu-intent-tiles.tsx +76 -0
  134. package/src/components/menu-item.tsx +416 -0
  135. package/src/components/menu-mocks.ts +417 -0
  136. package/src/components/menu-types.ts +259 -0
  137. package/src/components/motion-icon-set.tsx +30 -3
  138. package/src/components/open-now-list.stories.tsx +76 -0
  139. package/src/components/open-now-list.tsx +127 -0
  140. package/src/components/place-types.ts +112 -0
  141. package/src/components/poster-wall.test.tsx +28 -0
  142. package/src/components/poster-wall.tsx +96 -23
  143. package/src/components/ranked-venue-list.stories.tsx +80 -0
  144. package/src/components/ranked-venue-list.tsx +177 -0
  145. package/src/components/section-header.stories.tsx +24 -0
  146. package/src/components/section-header.test.tsx +28 -0
  147. package/src/components/section-header.tsx +45 -7
  148. package/src/components/signature-chip.tsx +77 -0
  149. package/src/components/signature-line-list.stories.tsx +85 -0
  150. package/src/components/signature-line-list.tsx +136 -0
  151. package/src/components/snap-rail.stories.tsx +79 -0
  152. package/src/components/snap-rail.test.tsx +18 -0
  153. package/src/components/snap-rail.tsx +148 -0
  154. package/src/components/stat-banner.stories.tsx +100 -0
  155. package/src/components/stat-banner.tsx +117 -0
  156. package/src/components/timeline-band.tsx +52 -12
  157. package/src/components/timeline-playhead.stories.tsx +30 -0
  158. package/src/components/timeline-playhead.test.tsx +11 -0
  159. package/src/components/timeline-playhead.tsx +46 -0
  160. package/src/components/venue-busyness-strip.stories.tsx +66 -0
  161. package/src/components/venue-busyness-strip.tsx +64 -0
  162. package/src/components/venue-grade-dimensions.stories.tsx +83 -0
  163. package/src/components/venue-grade-dimensions.tsx +91 -0
  164. package/src/components/venue-quotes.stories.tsx +59 -0
  165. package/src/components/venue-quotes.tsx +64 -0
  166. package/src/components/venue-signature-block.stories.tsx +68 -0
  167. package/src/components/venue-signature-block.tsx +71 -0
  168. package/src/components/venue-spotlight.stories.tsx +141 -0
  169. package/src/components/venue-spotlight.tsx +236 -0
  170. package/src/components/venue-wall.stories.tsx +78 -0
  171. package/src/components/venue-wall.tsx +185 -0
  172. package/src/components/weekday-theme-banner.stories.tsx +113 -0
  173. package/src/components/weekday-theme-banner.tsx +231 -0
  174. package/src/components/weekend-panel.test.tsx +43 -0
  175. package/src/components/weekend-panel.tsx +142 -108
  176. package/src/hooks/use-drag-swipe.test.tsx +66 -0
  177. package/src/hooks/use-drag-swipe.ts +105 -0
  178. package/src/hooks/use-media-query.ts +31 -0
  179. package/dist/chunk-GPH6L4DX.js +0 -55
@@ -1,3 +1,3 @@
1
- export { DriftRail } from '../chunk-GPH6L4DX.js';
1
+ export { DriftRail } from '../chunk-AHL45DD2.js';
2
2
  import '../chunk-FEK5XGZW.js';
3
3
  import '../chunk-3GWWZKX7.js';
@@ -61,6 +61,14 @@ type EventCardProps = {
61
61
  liveStatus?: string;
62
62
  /** Hide the day/time line — the timeline supplies its own hour heading. */
63
63
  hideWhen?: boolean;
64
+ /**
65
+ * Already over — dims the poster, mutes the title and shows the `endedLabel`
66
+ * chip. Never row-level opacity, which composites the text below AA. Same
67
+ * contract as `EventCompactRow`.
68
+ */
69
+ isEnded?: boolean;
70
+ /** Chip text for an ended event, e.g. "Ended". Required to render the chip. */
71
+ endedLabel?: string;
64
72
  /** Overrides the day label when the card appears outside its own day section. */
65
73
  dayLabel?: string;
66
74
  /** Append the entry fee to the meta line. Off by default, matching the design's base card. */
@@ -1,6 +1,6 @@
1
1
  import { TagGroup } from '../chunk-6XMYEZVR.js';
2
- import { Tag } from '../chunk-ZDAHKI3A.js';
3
2
  import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
3
+ import { Tag } from '../chunk-ZDAHKI3A.js';
4
4
  import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
5
5
  import { Skeleton } from '../chunk-QXHMPJ35.js';
6
6
  import { cn } from '../chunk-FEK5XGZW.js';
@@ -25,6 +25,8 @@ var EventCard = memo(function EventCard2({
25
25
  tags,
26
26
  liveStatus,
27
27
  hideWhen,
28
+ isEnded,
29
+ endedLabel,
28
30
  dayLabel,
29
31
  showPrice,
30
32
  href,
@@ -36,6 +38,7 @@ var EventCard = memo(function EventCard2({
36
38
  }) {
37
39
  var _a;
38
40
  const [imgError, setImgError] = useState(false);
41
+ const showEnded = isEnded && !!endedLabel;
39
42
  const time = hideWhen ? "" : formatters.time(event.starts_at);
40
43
  const fee = resolveEventEntryFee(event);
41
44
  const showPoster = !!event.poster_url && !imgError;
@@ -46,6 +49,7 @@ var EventCard = memo(function EventCard2({
46
49
  {
47
50
  className: cn(
48
51
  "relative overflow-hidden rounded-xl bg-muted",
52
+ isEnded && "opacity-45",
49
53
  posterAspect === "3/4" ? "aspect-[3/4]" : posterAspect === "4/5" ? "aspect-[4/5]" : "aspect-[4/3]"
50
54
  ),
51
55
  children: [
@@ -66,10 +70,19 @@ var EventCard = memo(function EventCard2({
66
70
  ) : fallback,
67
71
  /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-2 top-2 flex items-start justify-between gap-2", children: [
68
72
  badge ? /* @__PURE__ */ jsx("span", { className: cn(PILL_BASE, "bg-black/55 text-white"), children: badge }) : /* @__PURE__ */ jsx("span", {}),
69
- fee.kind === "free" && /* @__PURE__ */ jsxs("span", { className: cn(PILL_BASE, "bg-success font-bold text-success-foreground"), children: [
70
- /* @__PURE__ */ jsx(Gift, { className: "h-3 w-3", "aria-hidden": true }),
71
- labels.free
72
- ] })
73
+ fee.kind === "free" && /* @__PURE__ */ jsxs(
74
+ "span",
75
+ {
76
+ className: cn(
77
+ PILL_BASE,
78
+ "bg-success font-bold text-success-foreground"
79
+ ),
80
+ children: [
81
+ /* @__PURE__ */ jsx(Gift, { className: "h-3 w-3", "aria-hidden": true }),
82
+ labels.free
83
+ ]
84
+ }
85
+ )
73
86
  ] }),
74
87
  tagLabel && /* @__PURE__ */ jsx("div", { className: "absolute inset-x-2 bottom-2 flex gap-1", children: /* @__PURE__ */ jsx("span", { className: cn(PILL_BASE, "bg-black/55 text-white"), children: tagLabel }) })
75
88
  ]
@@ -80,7 +93,8 @@ var EventCard = memo(function EventCard2({
80
93
  {
81
94
  className: cn(
82
95
  "mt-2.5 leading-[1.35]",
83
- emphasis ? "text-lg font-bold tracking-[-0.02em]" : "text-sm font-semibold"
96
+ emphasis ? "text-lg font-bold tracking-[-0.02em]" : "text-sm font-semibold",
97
+ isEnded && "text-muted-foreground"
84
98
  ),
85
99
  children: event.title
86
100
  }
@@ -104,7 +118,8 @@ var EventCard = memo(function EventCard2({
104
118
  liveStatus && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-xs font-bold text-success", children: [
105
119
  /* @__PURE__ */ jsx(Radio, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
106
120
  liveStatus
107
- ] })
121
+ ] }),
122
+ showEnded && /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "default", className: "font-extrabold", children: endedLabel }) })
108
123
  ] });
109
124
  const rootClasses = cn(
110
125
  "flex min-w-0 flex-col text-left",
@@ -123,7 +138,15 @@ var EventCard = memo(function EventCard2({
123
138
  );
124
139
  }
125
140
  if (onClick) {
126
- return /* @__PURE__ */ jsx("button", { type: "button", className: rootClasses, onClick: (e) => onClick(event, e), children: body });
141
+ return /* @__PURE__ */ jsx(
142
+ "button",
143
+ {
144
+ type: "button",
145
+ className: rootClasses,
146
+ onClick: (e) => onClick(event, e),
147
+ children: body
148
+ }
149
+ );
127
150
  }
128
151
  return /* @__PURE__ */ jsx("div", { className: rootClasses, children: body });
129
152
  });
@@ -133,32 +156,39 @@ function EventCardSkeleton({
133
156
  hideWhen,
134
157
  className
135
158
  }) {
136
- return /* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: cn("flex min-w-0 flex-col text-left", className), children: [
137
- /* @__PURE__ */ jsx(
138
- Skeleton,
139
- {
140
- className: cn(
141
- posterAspect === "3/4" ? "aspect-[3/4]" : posterAspect === "4/5" ? "aspect-[4/5]" : "aspect-[4/3]"
142
- )
143
- }
144
- ),
145
- emphasis ? /* @__PURE__ */ jsxs("div", { className: "mt-2.5 space-y-2", children: [
146
- /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-full" }),
147
- /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-full" }),
148
- /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-1/2" })
149
- ] }) : /* @__PURE__ */ jsxs("div", { className: "mt-2.5 space-y-1.5", children: [
150
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-full" }),
151
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-2/3" })
152
- ] }),
153
- /* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex items-center gap-1", children: [
154
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-3 shrink-0 rounded-full" }),
155
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" })
156
- ] }),
157
- !hideWhen && /* @__PURE__ */ jsxs("div", { className: "mt-[3px] flex items-center gap-1.5", children: [
158
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-16" }),
159
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-10" })
160
- ] })
161
- ] });
159
+ return /* @__PURE__ */ jsxs(
160
+ "div",
161
+ {
162
+ "aria-hidden": "true",
163
+ className: cn("flex min-w-0 flex-col text-left", className),
164
+ children: [
165
+ /* @__PURE__ */ jsx(
166
+ Skeleton,
167
+ {
168
+ className: cn(
169
+ posterAspect === "3/4" ? "aspect-[3/4]" : posterAspect === "4/5" ? "aspect-[4/5]" : "aspect-[4/3]"
170
+ )
171
+ }
172
+ ),
173
+ emphasis ? /* @__PURE__ */ jsxs("div", { className: "mt-2.5 space-y-2", children: [
174
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-full" }),
175
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-full" }),
176
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-1/2" })
177
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "mt-2.5 space-y-1.5", children: [
178
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-full" }),
179
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-2/3" })
180
+ ] }),
181
+ /* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex items-center gap-1", children: [
182
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-3 shrink-0 rounded-full" }),
183
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" })
184
+ ] }),
185
+ !hideWhen && /* @__PURE__ */ jsxs("div", { className: "mt-[3px] flex items-center gap-1.5", children: [
186
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-16" }),
187
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-10" })
188
+ ] })
189
+ ]
190
+ }
191
+ );
162
192
  }
163
193
 
164
194
  export { EventCard, EventCardSkeleton };
@@ -14,10 +14,25 @@ import { EventPreview, EventCardLabels, EventFormatters } from './event-types.js
14
14
  *
15
15
  * THIS ROW DOES NOT DRAW DIVIDERS; ITS CONTAINER DOES. `<HourGroup>` already
16
16
  * draws the rule under the hour heading, so a row-level top separator here
17
- * doubled it directly beneath every hour. `<EventListRow>` and
18
- * `<EventListRowWide>` are different: they stack in a plain list with no
19
- * other rule around them, so their own top separator is the only one there —
20
- * do not carry this rule over to them.
17
+ * doubled it directly beneath every hour; `<HourBand>` rules between its rows
18
+ * with a wrapper. `<EventListRow>` and `<EventListRowWide>` are different:
19
+ * they stack in a plain list with no other rule around them, so their own top
20
+ * separator is the only one there — do not carry this rule over to them.
21
+ *
22
+ * STATE LIVES ON THE META LINE. `isLive` adds the on-air chip and `isEnded`
23
+ * the ended chip beside the time and venue, so a row's state is read in the
24
+ * same glance as its facts. Ended dims the POSTER and moves the title to
25
+ * `--muted-foreground` — never row-level opacity, which composites the text
26
+ * below AA.
27
+ *
28
+ * THE PRICE IS ON THE LAST ROW, right-aligned beside the tags, not on the
29
+ * title line. Two bold things on one line compete — the title and a price
30
+ * both in 700 read as one shout — and the title is the thing the reader is
31
+ * scanning for. `showPrice` renders it (free in `--success`, paid in
32
+ * `--foreground`); without it the row keeps its trailing free pill for the
33
+ * hub's venue block. This is ONE row for the timeline and the list view:
34
+ * the list used to have its own, and the reader met two anatomies for the
35
+ * same object.
21
36
  *
22
37
  * Same contract as the rest: DS-owned view model, injected labels/formatters,
23
38
  * plain `<img>`, anchor whenever `href` is given.
@@ -41,7 +56,7 @@ type EventCompactRowProps = {
41
56
  * repeating it on each one is noise — the caller has something more
42
57
  * differentiating to say instead (the event's own description). The
43
58
  * timeline keeps the default: there the venue IS what tells rows apart
44
- * across the night. Mirrors `menu-item-row.tsx`'s prop of the same name and
59
+ * across the night. Mirrors `menu-item.tsx`'s prop of the same name and
45
60
  * intent.
46
61
  */
47
62
  subtitle?: string;
@@ -51,6 +66,18 @@ type EventCompactRowProps = {
51
66
  * rather than truncate, so a chip's own text is never cut mid-word. Cap
52
67
  * the count at the call site — this row does not. */
53
68
  tags?: string[];
69
+ /** Currently running — adds the `labels.liveNow` chip to the meta line. */
70
+ isLive?: boolean;
71
+ /** Already over — dims the poster, mutes the title, adds the `endedLabel` chip. */
72
+ isEnded?: boolean;
73
+ /** Chip text for an ended event, e.g. "Ended". Required to render the chip. */
74
+ endedLabel?: string;
75
+ /**
76
+ * Prints the fee on the meta line — `labels.free` in `--success`, a paid
77
+ * amount via `formatters.price` — instead of the trailing free pill. An
78
+ * unknown fee prints nothing, same as every sibling row.
79
+ */
80
+ showPrice?: boolean;
54
81
  size?: "sm" | "default";
55
82
  href?: string;
56
83
  linkComponent?: React.ComponentType<EventCompactRowLinkProps>;
@@ -68,6 +95,6 @@ type EventCompactRowSkeletonProps = {
68
95
  className?: string;
69
96
  };
70
97
  /** Mirrors `<EventCompactRow>`'s geometry exactly so nothing shifts when data lands. */
71
- declare function EventCompactRowSkeleton({ size, className }: EventCompactRowSkeletonProps): react_jsx_runtime.JSX.Element;
98
+ declare function EventCompactRowSkeleton({ size, className, }: EventCompactRowSkeletonProps): react_jsx_runtime.JSX.Element;
72
99
 
73
100
  export { EventCompactRow, type EventCompactRowLinkProps, type EventCompactRowProps, EventCompactRowSkeleton, type EventCompactRowSkeletonProps };
@@ -1,11 +1,12 @@
1
1
  import { TagGroup } from '../chunk-6XMYEZVR.js';
2
- import { Tag } from '../chunk-ZDAHKI3A.js';
3
2
  import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
3
+ import { Tag } from '../chunk-ZDAHKI3A.js';
4
4
  import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
5
5
  import { Skeleton } from '../chunk-QXHMPJ35.js';
6
6
  import { cn } from '../chunk-FEK5XGZW.js';
7
7
  import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
8
8
  import { memo, useState } from 'react';
9
+ import { Radio } from 'lucide-react';
9
10
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
10
11
 
11
12
  function DefaultLink(_a) {
@@ -19,6 +20,10 @@ var EventCompactRow = memo(function EventCompactRow2({
19
20
  hideTime,
20
21
  subtitle,
21
22
  tags,
23
+ isLive,
24
+ isEnded,
25
+ endedLabel,
26
+ showPrice,
22
27
  size = "default",
23
28
  href,
24
29
  linkComponent: LinkComponent = DefaultLink,
@@ -34,50 +39,107 @@ var EventCompactRow = memo(function EventCompactRow2({
34
39
  const showPoster = !!event.poster_url && !imgError;
35
40
  const venue = (_a = event.place_name) != null ? _a : event.location;
36
41
  const time = formatters.time(event.starts_at);
42
+ const priceText = fee.kind === "free" ? labels.free : fee.kind === "paid" ? formatters.price(fee.amountRon) : void 0;
43
+ const showEnded = isEnded && !!endedLabel;
44
+ const separator = /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-border", children: "\xB7" });
37
45
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
38
- /* @__PURE__ */ jsx("div", { className: "relative aspect-[4/5] w-16 shrink-0 overflow-hidden rounded-[9px] bg-muted", children: showPoster ? (
39
- // eslint-disable-next-line @next/next/no-img-element
40
- /* @__PURE__ */ jsx(
41
- "img",
42
- {
43
- src: event.poster_url,
44
- alt: "",
45
- loading: priority ? "eager" : "lazy",
46
- decoding: "async",
47
- className: "h-full w-full object-cover",
48
- onError: () => setImgError(true)
49
- }
50
- )
51
- ) : (
52
- // A bare `bg-muted` rectangle was survivable at 34px. At 64x80 beside
53
- // real posters it reads as a broken image rather than an absent one —
54
- // so this row finally joins every sibling in the family in having a
55
- // designed fallback.
56
- fallback
57
- ) }),
46
+ /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ className: cn(
50
+ "relative aspect-[4/5] w-16 shrink-0 overflow-hidden rounded-[10px] bg-muted",
51
+ isEnded && "opacity-45"
52
+ ),
53
+ children: showPoster ? (
54
+ // eslint-disable-next-line @next/next/no-img-element
55
+ /* @__PURE__ */ jsx(
56
+ "img",
57
+ {
58
+ src: event.poster_url,
59
+ alt: "",
60
+ loading: priority ? "eager" : "lazy",
61
+ decoding: "async",
62
+ className: "h-full w-full object-cover",
63
+ onError: () => setImgError(true)
64
+ }
65
+ )
66
+ ) : (
67
+ // A bare `bg-muted` rectangle was survivable at 34px. At 58x72 beside
68
+ // real posters it reads as a broken image rather than an absent one —
69
+ // so this row finally joins every sibling in the family in having a
70
+ // designed fallback.
71
+ fallback
72
+ )
73
+ }
74
+ ),
58
75
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
59
76
  /* @__PURE__ */ jsx(
60
77
  "div",
61
78
  {
62
79
  className: cn(
63
- "font-semibold leading-[1.35]",
80
+ "leading-[1.3]",
64
81
  "transition-colors duration-150 motion-reduce:transition-none",
65
- isSm ? "text-[13.5px]" : "text-[13px]",
82
+ isSm ? "text-[14.5px] lg:text-[13.5px]" : "text-[14px] lg:text-[13px]",
83
+ isEnded ? "font-semibold text-muted-foreground" : "font-bold text-foreground lg:font-semibold",
66
84
  (href || onClick) && "group-hover:text-primary"
67
85
  ),
68
86
  children: event.title
69
87
  }
70
88
  ),
71
- /* @__PURE__ */ jsx("div", { className: "truncate text-[11.5px] text-muted-foreground", children: subtitle ? subtitle : /* @__PURE__ */ jsxs(Fragment, { children: [
72
- !hideTime && time && /* @__PURE__ */ jsxs(Fragment, { children: [
73
- /* @__PURE__ */ jsx("span", { className: "font-mono tabular-nums", children: time }),
74
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: " \xB7 " })
75
- ] }),
76
- venue
77
- ] }) }),
78
- tags && tags.length > 0 && /* @__PURE__ */ jsx(TagGroup, { className: "mt-1", children: tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", children: tag }, tag)) })
89
+ /* @__PURE__ */ jsxs(
90
+ "div",
91
+ {
92
+ className: cn(
93
+ "mt-1 flex items-center gap-1.5 text-[11.5px] text-muted-foreground",
94
+ isLive || showEnded ? "flex-wrap" : "truncate"
95
+ ),
96
+ children: [
97
+ subtitle ? subtitle : /* @__PURE__ */ jsxs(Fragment, { children: [
98
+ !hideTime && time && /* @__PURE__ */ jsxs(Fragment, { children: [
99
+ /* @__PURE__ */ jsx("span", { className: "font-mono tabular-nums", children: time }),
100
+ separator
101
+ ] }),
102
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: venue })
103
+ ] }),
104
+ isLive && /* @__PURE__ */ jsxs(
105
+ Tag,
106
+ {
107
+ size: "sm",
108
+ variant: "success",
109
+ className: "shrink-0 whitespace-nowrap font-extrabold",
110
+ children: [
111
+ /* @__PURE__ */ jsx(Radio, { className: "h-2.5 w-2.5", "aria-hidden": true }),
112
+ labels.liveNow
113
+ ]
114
+ }
115
+ ),
116
+ showEnded && /* @__PURE__ */ jsx(
117
+ Tag,
118
+ {
119
+ size: "sm",
120
+ variant: "default",
121
+ className: "shrink-0 whitespace-nowrap font-extrabold",
122
+ children: endedLabel
123
+ }
124
+ )
125
+ ]
126
+ }
127
+ ),
128
+ (tags && tags.length > 0 || showPrice && priceText) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-center gap-2", children: [
129
+ tags && tags.length > 0 ? /* @__PURE__ */ jsx(TagGroup, { className: "min-w-0 flex-1", children: tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "quiet", children: tag }, tag)) }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
130
+ showPrice && priceText && /* @__PURE__ */ jsx(
131
+ "span",
132
+ {
133
+ className: cn(
134
+ "shrink-0 text-[13px] tabular-nums",
135
+ fee.kind === "free" ? "font-semibold text-success" : "font-bold text-foreground"
136
+ ),
137
+ children: priceText
138
+ }
139
+ )
140
+ ] })
79
141
  ] }),
80
- fee.kind === "free" && /* @__PURE__ */ jsx(
142
+ !showPrice && fee.kind === "free" && /* @__PURE__ */ jsx(
81
143
  "span",
82
144
  {
83
145
  className: cn(
@@ -89,7 +151,7 @@ var EventCompactRow = memo(function EventCompactRow2({
89
151
  )
90
152
  ] });
91
153
  const rootClasses = cn(
92
- "group relative -mx-2.5 flex w-full items-start gap-[11px] rounded-lg px-2.5 py-2 text-left",
154
+ "group relative -mx-2.5 flex w-full items-start gap-3 rounded-lg px-2.5 py-[11px] text-left lg:gap-[11px] lg:py-2",
93
155
  "transition-colors duration-150 motion-reduce:transition-none",
94
156
  (href || onClick) && "cursor-pointer hover:bg-foreground/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
95
157
  className
@@ -106,25 +168,44 @@ var EventCompactRow = memo(function EventCompactRow2({
106
168
  );
107
169
  }
108
170
  if (onClick) {
109
- return /* @__PURE__ */ jsx("button", { type: "button", className: rootClasses, onClick: (e) => onClick(event, e), children: body });
171
+ return /* @__PURE__ */ jsx(
172
+ "button",
173
+ {
174
+ type: "button",
175
+ className: rootClasses,
176
+ onClick: (e) => onClick(event, e),
177
+ children: body
178
+ }
179
+ );
110
180
  }
111
181
  return /* @__PURE__ */ jsx("div", { className: rootClasses, children: body });
112
182
  });
113
- function EventCompactRowSkeleton({ size = "default", className }) {
183
+ function EventCompactRowSkeleton({
184
+ size = "default",
185
+ className
186
+ }) {
114
187
  const isSm = size === "sm";
115
188
  return /* @__PURE__ */ jsxs(
116
189
  "div",
117
190
  {
118
191
  "aria-hidden": "true",
119
192
  className: cn(
120
- "relative -mx-2.5 flex w-full items-start gap-[11px] rounded-lg px-2.5 py-2 text-left",
193
+ "relative -mx-2.5 flex w-full items-start gap-3 rounded-lg px-2.5 py-[11px] text-left lg:gap-[11px] lg:py-2",
121
194
  className
122
195
  ),
123
196
  children: [
124
- /* @__PURE__ */ jsx(Skeleton, { className: "aspect-[4/5] w-16 shrink-0 rounded-[9px]" }),
197
+ /* @__PURE__ */ jsx(Skeleton, { className: "aspect-[4/5] w-16 shrink-0 rounded-[10px]" }),
125
198
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
126
- /* @__PURE__ */ jsx(Skeleton, { className: cn(isSm ? "h-[13.5px]" : "h-[13px]", "w-2/5") }),
127
- /* @__PURE__ */ jsx(Skeleton, { className: "mt-0.5 h-[11.5px] w-1/3" })
199
+ /* @__PURE__ */ jsx(
200
+ Skeleton,
201
+ {
202
+ className: cn(
203
+ isSm ? "h-[14.5px] lg:h-[13.5px]" : "h-[14px] lg:h-[13px]",
204
+ "w-3/5"
205
+ )
206
+ }
207
+ ),
208
+ /* @__PURE__ */ jsx(Skeleton, { className: "mt-1 h-[11.5px] w-1/3" })
128
209
  ] })
129
210
  ]
130
211
  }
@@ -27,7 +27,9 @@ function EventDayHeader({
27
27
  {
28
28
  className: cn(
29
29
  "font-black leading-[0.82] tracking-[-0.05em] tabular-nums",
30
- large ? "text-[58px]" : "text-[40px]"
30
+ // `sm` is the phone scale: 30px, the design's app day head. 40px
31
+ // was a page-scale number that took a third of a 390px row.
32
+ large ? "text-[58px]" : "text-[30px] leading-[0.86]"
31
33
  ),
32
34
  children: dayNumber
33
35
  }
@@ -25,6 +25,12 @@ import { ElementType } from 'react';
25
25
  * `<Separator>` above the label), not the weight.
26
26
  */
27
27
  type EventDaySeparatorProps = {
28
+ /**
29
+ * `always` (default) draws the trailing rule at every width. `lg` drops it
30
+ * below `lg`, where the list is an app sheet whose day heads are bold
31
+ * labels alone — the rows below rule themselves — and keeps it from `lg`.
32
+ */
33
+ rule?: "always" | "lg";
28
34
  label: string;
29
35
  count?: string;
30
36
  size?: "sm" | "default";
@@ -32,7 +38,7 @@ type EventDaySeparatorProps = {
32
38
  as?: ElementType;
33
39
  className?: string;
34
40
  };
35
- declare function EventDaySeparator({ label, count, size, as: Tag, className, }: EventDaySeparatorProps): react_jsx_runtime.JSX.Element;
41
+ declare function EventDaySeparator({ label, count, size, as: Tag, className, rule, }: EventDaySeparatorProps): react_jsx_runtime.JSX.Element;
36
42
  type EventDaySeparatorSkeletonProps = {
37
43
  /** Matches `EventDaySeparatorProps["size"]`. */
38
44
  size?: "sm" | "default";
@@ -9,7 +9,8 @@ function EventDaySeparator({
9
9
  count,
10
10
  size = "default",
11
11
  as: Tag = "h2",
12
- className
12
+ className,
13
+ rule = "always"
13
14
  }) {
14
15
  return /* @__PURE__ */ jsxs(
15
16
  "div",
@@ -22,7 +23,7 @@ function EventDaySeparator({
22
23
  children: [
23
24
  /* @__PURE__ */ jsx(Tag, { className: cn("font-semibold", size === "sm" ? "text-[13px]" : "text-sm"), children: label }),
24
25
  count && /* @__PURE__ */ jsx("span", { className: cn("text-muted-foreground", size === "sm" ? "text-[11.5px]" : "text-xs"), children: count }),
25
- /* @__PURE__ */ jsx(Separator, { className: "flex-1" })
26
+ /* @__PURE__ */ jsx(Separator, { className: cn("flex-1", rule === "lg" && "hidden lg:block") })
26
27
  ]
27
28
  }
28
29
  );