@bearmenu/ui 0.8.16 → 0.8.18

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 (151) hide show
  1. package/dist/{chunk-WYTJR2YU.js → chunk-5CPBSNWQ.js} +6 -1
  2. package/dist/{chunk-36KEHCET.js → chunk-5LTILG3L.js} +15 -4
  3. package/dist/{chunk-P43B3ONY.js → chunk-5XREWOBB.js} +3 -1
  4. package/dist/{chunk-CLLY6XB3.js → chunk-6VOWT4YR.js} +6 -3
  5. package/dist/{chunk-S33K4RC5.js → chunk-BKKQ7GCZ.js} +1 -1
  6. package/dist/{chunk-ZLPWEHZO.js → chunk-EQYB4Q77.js} +2 -2
  7. package/dist/chunk-LYREUZH6.js +156 -0
  8. package/dist/chunk-PW247TG2.js +81 -0
  9. package/dist/chunk-QY66ME5B.js +207 -0
  10. package/dist/{chunk-T6S2ZBV6.js → chunk-SDWN6L4O.js} +1 -1
  11. package/dist/{chunk-CNJQUHCU.js → chunk-SWD6CJ35.js} +2 -1
  12. package/dist/{chunk-HDR7V6IZ.js → chunk-TIQNM4XD.js} +8 -1
  13. package/dist/components/alert-dialog.js +1 -1
  14. package/dist/components/alert.d.ts +2 -2
  15. package/dist/components/badge.d.ts +1 -1
  16. package/dist/components/badge.js +1 -1
  17. package/dist/components/button.d.ts +1 -1
  18. package/dist/components/button.js +1 -1
  19. package/dist/components/calendar.js +1 -1
  20. package/dist/components/card.d.ts +2 -2
  21. package/dist/components/carousel.js +1 -1
  22. package/dist/components/coach-marks.d.ts +63 -0
  23. package/dist/components/coach-marks.js +162 -0
  24. package/dist/components/combobox.js +1 -1
  25. package/dist/components/command.d.ts +15 -15
  26. package/dist/components/concept-compare-rail.js +3 -3
  27. package/dist/components/concept-compare.js +3 -3
  28. package/dist/components/concept-convergence.js +2 -2
  29. package/dist/components/doorway-tiles.d.ts +11 -0
  30. package/dist/components/doorway-tiles.js +5 -3
  31. package/dist/components/empty-state.js +1 -1
  32. package/dist/components/event-card.d.ts +22 -4
  33. package/dist/components/event-card.js +95 -50
  34. package/dist/components/event-day-header.d.ts +5 -3
  35. package/dist/components/event-day-header.js +12 -4
  36. package/dist/components/event-detail-panel.js +2 -2
  37. package/dist/components/event-door.d.ts +41 -0
  38. package/dist/components/event-door.js +65 -0
  39. package/dist/components/event-hub-hero.d.ts +10 -2
  40. package/dist/components/event-hub-hero.js +11 -5
  41. package/dist/components/event-index-row.js +1 -1
  42. package/dist/components/event-list-row-wide.js +2 -2
  43. package/dist/components/event-list-row.js +1 -1
  44. package/dist/components/event-tonight-strip.d.ts +50 -0
  45. package/dist/components/event-tonight-strip.js +67 -0
  46. package/dist/components/facet-group.d.ts +8 -1
  47. package/dist/components/facet-group.js +3 -0
  48. package/dist/components/filter-category-row.js +1 -1
  49. package/dist/components/hue-chip.js +1 -1
  50. package/dist/components/item.d.ts +2 -2
  51. package/dist/components/item.js +4 -1
  52. package/dist/components/kitchen-dossier.js +1 -1
  53. package/dist/components/link-button.js +1 -1
  54. package/dist/components/menu-family-block.d.ts +8 -1
  55. package/dist/components/menu-family-block.js +101 -68
  56. package/dist/components/menu-family-card.js +2 -2
  57. package/dist/components/menu-filter-chips.d.ts +12 -3
  58. package/dist/components/menu-filter-chips.js +22 -4
  59. package/dist/components/menu-hub-hero.d.ts +7 -1
  60. package/dist/components/menu-hub-hero.js +2 -1
  61. package/dist/components/menu-index-list.js +1 -1
  62. package/dist/components/menu-item.js +3 -3
  63. package/dist/components/menu-kitchen-list.d.ts +14 -2
  64. package/dist/components/menu-kitchen-list.js +1 -1
  65. package/dist/components/multi-select-combobox.js +2 -2
  66. package/dist/components/pagination.js +1 -1
  67. package/dist/components/photo-ground.d.ts +7 -1
  68. package/dist/components/photo-ground.js +1 -1
  69. package/dist/components/place-card.js +2 -2
  70. package/dist/components/place-details-mobile.js +1 -1
  71. package/dist/components/poster-stack.d.ts +36 -3
  72. package/dist/components/poster-stack.js +49 -18
  73. package/dist/components/searchable-select.js +1 -1
  74. package/dist/components/section-header.d.ts +7 -1
  75. package/dist/components/section-header.js +11 -7
  76. package/dist/components/signature-chip.js +2 -2
  77. package/dist/components/sliding-panels.js +1 -1
  78. package/dist/components/snap-rail.d.ts +2 -2
  79. package/dist/components/snap-rail.js +1 -1
  80. package/dist/components/spinner.d.ts +2 -2
  81. package/dist/components/tag.d.ts +2 -2
  82. package/dist/components/text.d.ts +3 -3
  83. package/dist/components/timeline-day.d.ts +54 -0
  84. package/dist/components/timeline-day.js +65 -0
  85. package/dist/components/timeline-hour-puck.d.ts +47 -0
  86. package/dist/components/timeline-hour-puck.js +3 -0
  87. package/dist/components/timeline-hour.d.ts +96 -0
  88. package/dist/components/{timeline-band.js → timeline-hour.js} +2 -1
  89. package/dist/components/timeline-playhead.js +1 -3
  90. package/dist/components/toggle-group.js +9 -4
  91. package/dist/components/toggle.d.ts +1 -1
  92. package/dist/components/toggle.js +1 -1
  93. package/dist/components/top-ranking-entry.js +3 -3
  94. package/package.json +1 -1
  95. package/src/components/badge.stories.tsx +31 -1
  96. package/src/components/badge.tsx +2 -0
  97. package/src/components/button.stories.tsx +5 -4
  98. package/src/components/button.test.tsx +11 -1
  99. package/src/components/button.tsx +16 -5
  100. package/src/components/coach-marks.stories.tsx +79 -0
  101. package/src/components/coach-marks.test.tsx +140 -0
  102. package/src/components/coach-marks.tsx +252 -0
  103. package/src/components/doorway-tiles.stories.tsx +34 -0
  104. package/src/components/doorway-tiles.test.tsx +27 -0
  105. package/src/components/doorway-tiles.tsx +30 -2
  106. package/src/components/event-card.tsx +70 -13
  107. package/src/components/event-day-header.tsx +19 -7
  108. package/src/components/event-door.stories.tsx +88 -0
  109. package/src/components/event-door.tsx +97 -0
  110. package/src/components/event-hub-hero.tsx +21 -3
  111. package/src/components/event-tonight-strip.stories.tsx +78 -0
  112. package/src/components/event-tonight-strip.test.tsx +59 -0
  113. package/src/components/event-tonight-strip.tsx +134 -0
  114. package/src/components/facet-group.tsx +9 -0
  115. package/src/components/hue-chip.test.tsx +6 -3
  116. package/src/components/hue-chip.tsx +5 -2
  117. package/src/components/item.tsx +4 -1
  118. package/src/components/menu-family-block.stories.tsx +12 -0
  119. package/src/components/menu-family-block.tsx +53 -20
  120. package/src/components/menu-filter-chips.tsx +32 -4
  121. package/src/components/menu-hub-hero.test.tsx +13 -0
  122. package/src/components/menu-hub-hero.tsx +9 -2
  123. package/src/components/menu-kitchen-list.tsx +45 -6
  124. package/src/components/photo-ground.tsx +7 -0
  125. package/src/components/poster-stack.stories.tsx +43 -1
  126. package/src/components/poster-stack.tsx +98 -19
  127. package/src/components/section-header.test.tsx +15 -0
  128. package/src/components/section-header.tsx +26 -12
  129. package/src/components/snap-rail.tsx +6 -1
  130. package/src/components/timeline-day.stories.tsx +201 -0
  131. package/src/components/timeline-day.test.tsx +78 -0
  132. package/src/components/timeline-day.tsx +114 -0
  133. package/src/components/timeline-hour-puck.tsx +139 -0
  134. package/src/components/timeline-hour.tsx +266 -0
  135. package/src/components/timeline-playhead.tsx +1 -1
  136. package/src/components/toggle-group.stories.tsx +37 -1
  137. package/src/components/toggle-group.tsx +11 -6
  138. package/src/components/toggle.tsx +8 -0
  139. package/dist/chunk-NSNEANOQ.js +0 -104
  140. package/dist/chunk-SXQZ7DLH.js +0 -167
  141. package/dist/components/hour-band.d.ts +0 -66
  142. package/dist/components/hour-band.js +0 -81
  143. package/dist/components/hour-group.d.ts +0 -67
  144. package/dist/components/hour-group.js +0 -59
  145. package/dist/components/timeline-band.d.ts +0 -64
  146. package/src/components/hour-band.stories.tsx +0 -182
  147. package/src/components/hour-band.tsx +0 -146
  148. package/src/components/hour-group.stories.tsx +0 -100
  149. package/src/components/hour-group.tsx +0 -124
  150. package/src/components/timeline-band.stories.tsx +0 -206
  151. package/src/components/timeline-band.tsx +0 -247
@@ -20,6 +20,7 @@ var EventCard = memo(function EventCard2({
20
20
  formatters,
21
21
  posterAspect = "4/3",
22
22
  emphasis,
23
+ density = "card",
23
24
  badge,
24
25
  tagLabel,
25
26
  tags,
@@ -39,7 +40,8 @@ var EventCard = memo(function EventCard2({
39
40
  var _a;
40
41
  const [imgError, setImgError] = useState(false);
41
42
  const showEnded = isEnded && !!endedLabel;
42
- const time = hideWhen ? "" : formatters.time(event.starts_at);
43
+ const time = hideWhen === true ? "" : formatters.time(event.starts_at);
44
+ const isRowLg = density === "row-lg";
43
45
  const fee = resolveEventEntryFee(event);
44
46
  const showPoster = !!event.poster_url && !imgError;
45
47
  const venue = (_a = event.place_name) != null ? _a : event.location;
@@ -50,7 +52,9 @@ var EventCard = memo(function EventCard2({
50
52
  className: cn(
51
53
  "relative overflow-hidden rounded-xl bg-muted",
52
54
  isEnded && "opacity-45",
53
- posterAspect === "3/4" ? "aspect-[3/4]" : posterAspect === "4/5" ? "aspect-[4/5]" : "aspect-[4/3]"
55
+ posterAspect === "3/4" ? "aspect-[3/4]" : posterAspect === "4/5" ? "aspect-[4/5]" : "aspect-[4/3]",
56
+ // The compact row's poster from `lg`: 64px, portrait, tighter radius.
57
+ isRowLg && "lg:aspect-[4/5] lg:w-16 lg:shrink-0 lg:rounded-[10px]"
54
58
  ),
55
59
  children: [
56
60
  showPoster ? (
@@ -68,62 +72,103 @@ var EventCard = memo(function EventCard2({
68
72
  }
69
73
  )
70
74
  ) : fallback,
71
- /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-2 top-2 flex items-start justify-between gap-2", children: [
72
- badge ? /* @__PURE__ */ jsx("span", { className: cn(PILL_BASE, "bg-black/55 text-white"), children: badge }) : /* @__PURE__ */ jsx("span", {}),
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
- )
86
- ] }),
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
+ /* @__PURE__ */ jsxs(
76
+ "div",
77
+ {
78
+ className: cn(
79
+ "absolute inset-x-2 top-2 flex items-start justify-between gap-2",
80
+ isRowLg && "lg:hidden"
81
+ ),
82
+ children: [
83
+ badge ? /* @__PURE__ */ jsx("span", { className: cn(PILL_BASE, "bg-black/55 text-white"), children: badge }) : /* @__PURE__ */ jsx("span", {}),
84
+ fee.kind === "free" && /* @__PURE__ */ jsxs(
85
+ "span",
86
+ {
87
+ className: cn(
88
+ PILL_BASE,
89
+ "bg-success font-bold text-success-foreground"
90
+ ),
91
+ children: [
92
+ /* @__PURE__ */ jsx(Gift, { className: "h-3 w-3", "aria-hidden": true }),
93
+ labels.free
94
+ ]
95
+ }
96
+ )
97
+ ]
98
+ }
99
+ ),
100
+ tagLabel && /* @__PURE__ */ jsx(
101
+ "div",
102
+ {
103
+ className: cn(
104
+ "absolute inset-x-2 bottom-2 flex gap-1",
105
+ isRowLg && "lg:hidden"
106
+ ),
107
+ children: /* @__PURE__ */ jsx("span", { className: cn(PILL_BASE, "bg-black/55 text-white"), children: tagLabel })
108
+ }
109
+ )
88
110
  ]
89
111
  }
90
112
  ),
91
- /* @__PURE__ */ jsx(
92
- "h3",
93
- {
94
- className: cn(
95
- "mt-2.5 leading-[1.35]",
96
- emphasis ? "text-lg font-bold tracking-[-0.02em]" : "text-sm font-semibold",
97
- isEnded && "text-muted-foreground"
98
- ),
99
- children: event.title
100
- }
101
- ),
102
- /* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex min-w-0 items-center gap-1 text-xs font-medium text-foreground/85", children: [
103
- /* @__PURE__ */ jsx(MapPin, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
104
- /* @__PURE__ */ jsx("span", { className: "truncate", children: venue })
105
- ] }),
106
- !hideWhen && /* @__PURE__ */ jsxs("div", { className: "mt-[3px] flex items-center gap-1.5 text-xs text-muted-foreground", children: [
107
- /* @__PURE__ */ jsx("span", { children: dayLabel != null ? dayLabel : formatters.day(event.starts_at) }),
108
- time && /* @__PURE__ */ jsxs(Fragment, { children: [
109
- /* @__PURE__ */ jsx("span", { className: "text-border", "aria-hidden": true, children: "\xB7" }),
110
- /* @__PURE__ */ jsx("span", { children: time })
113
+ /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-col", isRowLg && "lg:flex-1"), children: [
114
+ /* @__PURE__ */ jsx(
115
+ "h3",
116
+ {
117
+ className: cn(
118
+ "mt-2.5 leading-[1.35]",
119
+ emphasis === true ? "text-lg font-bold tracking-[-0.02em]" : "text-sm font-semibold",
120
+ emphasis === "lg" && "lg:text-lg lg:font-bold lg:tracking-[-0.02em]",
121
+ isRowLg && "lg:mt-0 lg:text-[13.5px]",
122
+ isEnded && "text-muted-foreground"
123
+ ),
124
+ children: event.title
125
+ }
126
+ ),
127
+ /* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex min-w-0 items-center gap-1 text-xs font-medium text-foreground/85", children: [
128
+ /* @__PURE__ */ jsx(MapPin, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
129
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: venue })
130
+ ] }),
131
+ hideWhen !== true && /* @__PURE__ */ jsxs(
132
+ "div",
133
+ {
134
+ className: cn(
135
+ "mt-[3px] flex items-center gap-1.5 text-xs text-muted-foreground",
136
+ hideWhen === "below-lg" && "hidden lg:flex"
137
+ ),
138
+ children: [
139
+ /* @__PURE__ */ jsx("span", { children: dayLabel != null ? dayLabel : formatters.day(event.starts_at) }),
140
+ time && /* @__PURE__ */ jsxs(Fragment, { children: [
141
+ /* @__PURE__ */ jsx("span", { className: "text-border", "aria-hidden": true, children: "\xB7" }),
142
+ /* @__PURE__ */ jsx("span", { children: time })
143
+ ] }),
144
+ showPrice && fee.kind === "paid" && /* @__PURE__ */ jsxs(Fragment, { children: [
145
+ /* @__PURE__ */ jsx("span", { className: "text-border", "aria-hidden": true, children: "\xB7" }),
146
+ /* @__PURE__ */ jsx("span", { children: formatters.price(fee.amountRon) })
147
+ ] })
148
+ ]
149
+ }
150
+ ),
151
+ (tags && tags.length > 0 || isRowLg && fee.kind === "free") && /* @__PURE__ */ jsxs(TagGroup, { className: "mt-1.5", children: [
152
+ tags == null ? void 0 : tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", children: tag }, tag)),
153
+ isRowLg && fee.kind === "free" && /* @__PURE__ */ jsxs(Tag, { size: "sm", variant: "success", className: "hidden font-bold lg:inline-flex", children: [
154
+ /* @__PURE__ */ jsx(Gift, { className: "h-3 w-3", "aria-hidden": true }),
155
+ labels.free
156
+ ] })
157
+ ] }),
158
+ liveStatus && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-xs font-bold text-success", children: [
159
+ /* @__PURE__ */ jsx(Radio, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
160
+ liveStatus
111
161
  ] }),
112
- showPrice && fee.kind === "paid" && /* @__PURE__ */ jsxs(Fragment, { children: [
113
- /* @__PURE__ */ jsx("span", { className: "text-border", "aria-hidden": true, children: "\xB7" }),
114
- /* @__PURE__ */ jsx("span", { children: formatters.price(fee.amountRon) })
115
- ] })
116
- ] }),
117
- tags && tags.length > 0 && /* @__PURE__ */ jsx(TagGroup, { className: "mt-1.5", children: tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", children: tag }, tag)) }),
118
- liveStatus && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-xs font-bold text-success", children: [
119
- /* @__PURE__ */ jsx(Radio, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
120
- liveStatus
121
- ] }),
122
- showEnded && /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "default", className: "font-extrabold", children: endedLabel }) })
162
+ showEnded && /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "default", className: "font-extrabold", children: endedLabel }) })
163
+ ] })
123
164
  ] });
124
165
  const rootClasses = cn(
125
166
  "flex min-w-0 flex-col text-left",
167
+ // The compact row from `lg`: poster beside text, the row's own padding
168
+ // and negative gutter so the hover wash bleeds like `EventCompactRow`'s.
169
+ isRowLg && "lg:-mx-2.5 lg:flex-row lg:items-start lg:gap-[11px] lg:rounded-lg lg:px-2.5 lg:py-2",
126
170
  (href || onClick) && "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-xl",
171
+ (href || onClick) && isRowLg && "lg:hover:bg-foreground/5",
127
172
  className
128
173
  );
129
174
  if (href) {
@@ -37,10 +37,12 @@ type EventDayHeaderProps = {
37
37
  */
38
38
  action?: React.ReactNode;
39
39
  /**
40
- * Larger desktop scale: 58px day number, 18px weekday, 12.5px meta,
41
- * against the mobile 40/15/11.5.
40
+ * `sm`: the phone scale (30px day number, 15px weekday, 11.5px meta).
41
+ * `default`: the desktop scale (58 / 18 / 12.5). `responsive`: `sm` below
42
+ * `lg` and `default` from it, in one node — for a server render that
43
+ * cannot know the viewport.
42
44
  */
43
- size?: "sm" | "default";
45
+ size?: "sm" | "default" | "responsive";
44
46
  href?: string;
45
47
  linkComponent?: React.ComponentType<EventDayHeaderLinkProps>;
46
48
  onClick?: () => void;
@@ -21,6 +21,7 @@ function EventDayHeader({
21
21
  }) {
22
22
  const isInteractive = !!href || !!onClick;
23
23
  const large = size === "default";
24
+ const responsive = size === "responsive";
24
25
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
25
26
  /* @__PURE__ */ jsx(
26
27
  "div",
@@ -29,16 +30,21 @@ function EventDayHeader({
29
30
  "font-black leading-[0.82] tracking-[-0.05em] tabular-nums",
30
31
  // `sm` is the phone scale: 30px, the design's app day head. 40px
31
32
  // was a page-scale number that took a third of a 390px row.
32
- large ? "text-[58px]" : "text-[30px] leading-[0.86]"
33
+ large ? "text-[58px]" : "text-[30px] leading-[0.86]",
34
+ responsive && "lg:text-[58px] lg:leading-[0.82]"
33
35
  ),
34
36
  children: dayNumber
35
37
  }
36
38
  ),
37
- /* @__PURE__ */ jsxs("div", { className: large ? "pb-1" : "pb-0.5", children: [
39
+ /* @__PURE__ */ jsxs("div", { className: cn(large ? "pb-1" : "pb-0.5", responsive && "lg:pb-1"), children: [
38
40
  /* @__PURE__ */ jsx(
39
41
  "div",
40
42
  {
41
- className: cn("font-extrabold tracking-[-0.015em]", large ? "text-lg" : "text-[15px]"),
43
+ className: cn(
44
+ "font-extrabold tracking-[-0.015em]",
45
+ large ? "text-lg" : "text-[15px]",
46
+ responsive && "lg:text-lg"
47
+ ),
42
48
  children: weekday
43
49
  }
44
50
  ),
@@ -47,7 +53,8 @@ function EventDayHeader({
47
53
  {
48
54
  className: cn(
49
55
  "mt-0.5 text-muted-foreground",
50
- large ? "whitespace-nowrap text-[12.5px]" : "text-[11.5px]"
56
+ large ? "whitespace-nowrap text-[12.5px]" : "text-[11.5px]",
57
+ responsive && "lg:whitespace-nowrap lg:text-[12.5px]"
51
58
  ),
52
59
  children: meta
53
60
  }
@@ -67,6 +74,7 @@ function EventDayHeader({
67
74
  className: cn(
68
75
  "relative flex w-full items-end gap-3 pb-3 pt-[18px]",
69
76
  large && "gap-[18px] pb-4",
77
+ responsive && "lg:gap-[18px] lg:pb-4",
70
78
  className
71
79
  ),
72
80
  children: [
@@ -1,8 +1,8 @@
1
1
  import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
2
- import { Separator } from '../chunk-NWZGSLPU.js';
3
2
  import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
3
+ import { Separator } from '../chunk-NWZGSLPU.js';
4
4
  import { Skeleton } from '../chunk-XBBEX4SF.js';
5
- import { Button } from '../chunk-36KEHCET.js';
5
+ import { Button } from '../chunk-5LTILG3L.js';
6
6
  import '../chunk-RIH2IS7X.js';
7
7
  import '../chunk-5YNIQ2BL.js';
8
8
  import { cn } from '../chunk-FEK5XGZW.js';
@@ -0,0 +1,41 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ /**
5
+ * EventDoor — a square tile that is a category's entry point: a photograph of
6
+ * the KIND of night (a stage, a dance floor, a terrace), a scrim, the name.
7
+ *
8
+ * A door and an event row must not look alike. `CategoryDeck` fans four event
9
+ * posters and prints a count, which reads as "these four events"; a card with
10
+ * a single event's poster reads as "tap = that event" and changes daily. The
11
+ * 1:1 shape with the name INSIDE the image is what says "door, not event", and
12
+ * it carries no count — a count is a claim about scale the hub's figures
13
+ * already make, and on a door it competes with the name.
14
+ *
15
+ * Always an anchor: a door with no destination is not a door, so `href` is
16
+ * required. The scrim is a gradient over a photograph, which is mode-
17
+ * independent — the same measured treatment `DoorwayTiles` uses.
18
+ */
19
+ type EventDoorLinkProps = {
20
+ href: string;
21
+ className?: string;
22
+ children: React.ReactNode;
23
+ onClick?: (mouseEvent: React.MouseEvent) => void;
24
+ };
25
+ type EventDoorProps = {
26
+ /** The category's name — the anchor's accessible name and the tile's label. */
27
+ name: string;
28
+ href: string;
29
+ imageSrc?: string;
30
+ /** Rendered when `imageSrc` is absent or fails. Defaults to `<EventPosterFallback />`. */
31
+ fallback?: React.ReactNode;
32
+ linkComponent?: React.ComponentType<EventDoorLinkProps>;
33
+ onClick?: (mouseEvent: React.MouseEvent) => void;
34
+ className?: string;
35
+ };
36
+ declare function EventDoor({ name, href, imageSrc, fallback, linkComponent: LinkComponent, onClick, className, }: EventDoorProps): react_jsx_runtime.JSX.Element;
37
+ declare function EventDoorSkeleton({ className }: {
38
+ className?: string;
39
+ }): react_jsx_runtime.JSX.Element;
40
+
41
+ export { EventDoor, type EventDoorLinkProps, type EventDoorProps, EventDoorSkeleton };
@@ -0,0 +1,65 @@
1
+ import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
2
+ import { Skeleton } from '../chunk-XBBEX4SF.js';
3
+ import { cn } from '../chunk-FEK5XGZW.js';
4
+ import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
5
+ import { useState } from 'react';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ function DefaultLink(_a) {
9
+ var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
10
+ return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
11
+ }
12
+ function EventDoor({
13
+ name,
14
+ href,
15
+ imageSrc,
16
+ fallback = /* @__PURE__ */ jsx(EventPosterFallback, {}),
17
+ linkComponent: LinkComponent = DefaultLink,
18
+ onClick,
19
+ className
20
+ }) {
21
+ const [failed, setFailed] = useState(false);
22
+ const showImage = !!imageSrc && !failed;
23
+ return /* @__PURE__ */ jsxs(
24
+ LinkComponent,
25
+ {
26
+ href,
27
+ onClick,
28
+ className: cn(
29
+ "group relative block aspect-square overflow-hidden rounded-xl bg-muted",
30
+ "transition-transform duration-150 active:scale-[0.98] motion-reduce:transition-none",
31
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
32
+ className
33
+ ),
34
+ children: [
35
+ showImage ? (
36
+ // eslint-disable-next-line @next/next/no-img-element
37
+ /* @__PURE__ */ jsx(
38
+ "img",
39
+ {
40
+ src: imageSrc,
41
+ alt: "",
42
+ loading: "lazy",
43
+ decoding: "async",
44
+ className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.04] motion-reduce:transition-none",
45
+ onError: () => setFailed(true)
46
+ }
47
+ )
48
+ ) : fallback,
49
+ /* @__PURE__ */ jsx(
50
+ "span",
51
+ {
52
+ "aria-hidden": true,
53
+ className: "absolute inset-x-0 bottom-0 h-3/4 bg-gradient-to-t from-black/65 via-black/45 to-transparent"
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-x-2 bottom-2 line-clamp-2 text-[12.5px] font-bold leading-[1.2] tracking-[-0.01em] text-white", children: name })
57
+ ]
58
+ }
59
+ );
60
+ }
61
+ function EventDoorSkeleton({ className }) {
62
+ return /* @__PURE__ */ jsx(Skeleton, { className: cn("aspect-square w-full rounded-xl", className) });
63
+ }
64
+
65
+ export { EventDoor, EventDoorSkeleton };
@@ -42,14 +42,22 @@ type EventHubHeroProps = {
42
42
  statsLabel?: string;
43
43
  /** The right-column slot — the poster stack in the source design. */
44
44
  aside?: React.ReactNode;
45
+ /**
46
+ * The text column's last row, under the figures — the hub's tonight state
47
+ * strip. The figures say scale; this says what is on right now, and it is
48
+ * the one thing on the first screen a reader can tap into the timeline.
49
+ */
50
+ footer?: React.ReactNode;
45
51
  className?: string;
46
52
  };
47
- declare function EventHubHero({ eyebrow, title, intro, stats, statsLabel, aside, className, }: EventHubHeroProps): react_jsx_runtime.JSX.Element;
53
+ declare function EventHubHero({ eyebrow, title, intro, stats, statsLabel, aside, footer, className, }: EventHubHeroProps): react_jsx_runtime.JSX.Element;
48
54
  type EventHubHeroSkeletonProps = {
49
55
  /** The right-column slot, e.g. a `PosterStack`-shaped placeholder. Mirrors `aside` on the real component. */
50
56
  aside?: React.ReactNode;
57
+ /** Reserves the `footer` row — the tonight strip's 52px. */
58
+ footer?: boolean;
51
59
  className?: string;
52
60
  };
53
- declare function EventHubHeroSkeleton({ aside, className }: EventHubHeroSkeletonProps): react_jsx_runtime.JSX.Element;
61
+ declare function EventHubHeroSkeleton({ aside, footer, className }: EventHubHeroSkeletonProps): react_jsx_runtime.JSX.Element;
54
62
 
55
63
  export { EventHubHero, type EventHubHeroProps, EventHubHeroSkeleton, type EventHubHeroSkeletonProps, type EventHubHeroStat };
@@ -10,13 +10,17 @@ function EventHubHero({
10
10
  stats,
11
11
  statsLabel,
12
12
  aside,
13
+ footer,
13
14
  className
14
15
  }) {
15
16
  return /* @__PURE__ */ jsxs(
16
17
  "div",
17
18
  {
18
19
  className: cn(
19
- "grid grid-cols-1 gap-8 lg:grid-cols-[1fr_620px] lg:items-center lg:gap-10",
20
+ // 16px between the text column and the aside on a phone: with a
21
+ // tappable poster stack the aside is content, not decoration, and
22
+ // gets the within-section rhythm rather than a section gap.
23
+ "grid grid-cols-1 gap-4 lg:grid-cols-[1fr_620px] lg:items-center lg:gap-10",
20
24
  className
21
25
  ),
22
26
  children: [
@@ -82,20 +86,21 @@ function EventHubHero({
82
86
  );
83
87
  })
84
88
  }
85
- )
89
+ ),
90
+ footer && /* @__PURE__ */ jsx("div", { className: "order-4 pt-1.5 lg:order-none lg:pt-2", children: footer })
86
91
  ] }),
87
92
  aside && /* @__PURE__ */ jsx("div", { className: "min-w-0", children: aside })
88
93
  ]
89
94
  }
90
95
  );
91
96
  }
92
- function EventHubHeroSkeleton({ aside, className }) {
97
+ function EventHubHeroSkeleton({ aside, footer, className }) {
93
98
  return /* @__PURE__ */ jsxs(
94
99
  "div",
95
100
  {
96
101
  "aria-hidden": "true",
97
102
  className: cn(
98
- "grid grid-cols-1 gap-8 lg:grid-cols-[1fr_620px] lg:items-center lg:gap-10",
103
+ "grid grid-cols-1 gap-4 lg:grid-cols-[1fr_620px] lg:items-center lg:gap-10",
99
104
  className
100
105
  ),
101
106
  children: [
@@ -116,7 +121,8 @@ function EventHubHeroSkeleton({ aside, className }) {
116
121
  ]
117
122
  },
118
123
  index
119
- )) })
124
+ )) }),
125
+ footer && /* @__PURE__ */ jsx("div", { className: "order-4 pt-1.5 lg:order-none lg:pt-2", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[52px] w-full rounded-[14px]" }) })
120
126
  ] }),
121
127
  aside && /* @__PURE__ */ jsx("div", { className: "min-w-0", children: aside })
122
128
  ]
@@ -1,7 +1,7 @@
1
1
  import { TagGroup } from '../chunk-PX6RICS5.js';
2
2
  import { Tag } from '../chunk-MWB7S54O.js';
3
- import { Separator } from '../chunk-NWZGSLPU.js';
4
3
  import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
4
+ import { Separator } from '../chunk-NWZGSLPU.js';
5
5
  import { cn } from '../chunk-FEK5XGZW.js';
6
6
  import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
7
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -1,9 +1,9 @@
1
1
  import { Tag } from '../chunk-MWB7S54O.js';
2
2
  import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
3
- import { Separator } from '../chunk-NWZGSLPU.js';
4
3
  import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
4
+ import { Separator } from '../chunk-NWZGSLPU.js';
5
5
  import { Skeleton } from '../chunk-XBBEX4SF.js';
6
- import { buttonVariants } from '../chunk-36KEHCET.js';
6
+ import { buttonVariants } from '../chunk-5LTILG3L.js';
7
7
  import '../chunk-RIH2IS7X.js';
8
8
  import '../chunk-5YNIQ2BL.js';
9
9
  import { cn } from '../chunk-FEK5XGZW.js';
@@ -1,8 +1,8 @@
1
1
  import { TagGroup } from '../chunk-PX6RICS5.js';
2
2
  import { Tag } from '../chunk-MWB7S54O.js';
3
3
  import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
4
- import { Separator } from '../chunk-NWZGSLPU.js';
5
4
  import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
5
+ import { Separator } from '../chunk-NWZGSLPU.js';
6
6
  import { Skeleton } from '../chunk-XBBEX4SF.js';
7
7
  import { cn } from '../chunk-FEK5XGZW.js';
8
8
  import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
@@ -0,0 +1,50 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ /**
5
+ * EventTonightStrip — the hub's state line: what is on right now, what is
6
+ * later tonight, and one tap into the timeline.
7
+ *
8
+ * The hero's figures say SCALE ("52 events · 14 days"); this says STATE ("3
9
+ * live now · 12 more tonight · next at 20:00"). It is the one thing on the
10
+ * hub's first screen a reader can tap into today's programme, so it is a real
11
+ * anchor whenever there is a day to open — never a sheet trigger.
12
+ *
13
+ * Copy is caller-composed and carries only absolute facts: counts and
14
+ * wall-clock start times. Never a countdown or "in 12 minutes" — the hub is
15
+ * ISR-cached, and a ten-minute-old snapshot that says "next at 20:00" is at
16
+ * worst one boundary off, while "in 12 minutes" is simply wrong. The DS keeps
17
+ * no clock, no Intl and no i18n: the app derives `tone`, `lead` and `details`
18
+ * from its own clock and re-derives them after hydration.
19
+ *
20
+ * The lead stays `text-foreground`, not `--success`: 13px bold success on a
21
+ * card computes to roughly 4.5:1 in both modes, too close to the floor for
22
+ * the strip's one claim. The dot and the border carry the colour.
23
+ */
24
+ type EventTonightStripTone = "live" | "tonight" | "quiet" | "none";
25
+ type EventTonightStripLinkProps = {
26
+ href: string;
27
+ className?: string;
28
+ children: React.ReactNode;
29
+ onClick?: (mouseEvent: React.MouseEvent) => void;
30
+ };
31
+ type EventTonightStripProps = {
32
+ tone: EventTonightStripTone;
33
+ /** The lead segment, bold — "3 live now". */
34
+ lead: string;
35
+ /** Trailing segments, muted, joined with " · " — ["12 more tonight", "next at 20:00"]. */
36
+ details?: string[];
37
+ /** Screen-reader suffix for the anchor — "Open tonight in the schedule". */
38
+ actionLabel?: string;
39
+ /** Absent (tone `none`) renders a non-interactive `role="status"` line. */
40
+ href?: string;
41
+ /** Defaults to a plain `<a>`. Pass `next/link` in a Next app. */
42
+ linkComponent?: React.ComponentType<EventTonightStripLinkProps>;
43
+ className?: string;
44
+ };
45
+ declare function EventTonightStrip({ tone, lead, details, actionLabel, href, linkComponent: LinkComponent, className, }: EventTonightStripProps): react_jsx_runtime.JSX.Element;
46
+ declare function EventTonightStripSkeleton({ className }: {
47
+ className?: string;
48
+ }): react_jsx_runtime.JSX.Element;
49
+
50
+ export { EventTonightStrip, type EventTonightStripLinkProps, type EventTonightStripProps, EventTonightStripSkeleton, type EventTonightStripTone };
@@ -0,0 +1,67 @@
1
+ import { Skeleton } from '../chunk-XBBEX4SF.js';
2
+ import { cn } from '../chunk-FEK5XGZW.js';
3
+ import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
4
+ import * as React from 'react';
5
+ import { Clock, CalendarDays, ArrowRight } from 'lucide-react';
6
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
+
8
+ function DefaultLink(_a) {
9
+ var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
10
+ return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
11
+ }
12
+ function EventTonightStrip({
13
+ tone,
14
+ lead,
15
+ details = [],
16
+ actionLabel,
17
+ href,
18
+ linkComponent: LinkComponent = DefaultLink,
19
+ className
20
+ }) {
21
+ const interactive = !!href;
22
+ const mark = tone === "live" ? /* @__PURE__ */ jsxs("span", { className: "relative flex h-2.5 w-2.5", "aria-hidden": true, children: [
23
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full rounded-full bg-success/40 motion-live-pulse motion-reduce:animate-none" }),
24
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2.5 w-2.5 rounded-full bg-success" })
25
+ ] }) : tone === "tonight" ? /* @__PURE__ */ jsx(Clock, { className: "h-4 w-4 text-muted-foreground", "aria-hidden": true }) : /* @__PURE__ */ jsx(
26
+ CalendarDays,
27
+ {
28
+ className: cn("h-4 w-4", tone === "none" ? "text-muted-foreground/70" : "text-muted-foreground"),
29
+ "aria-hidden": true
30
+ }
31
+ );
32
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
33
+ /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: mark }),
34
+ /* @__PURE__ */ jsxs("span", { className: "line-clamp-2 min-w-0 flex-1 text-[13px] leading-[1.3] tabular-nums lg:line-clamp-1 lg:text-sm", children: [
35
+ /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: lead }),
36
+ details.map((detail) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
37
+ " ",
38
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\xB7" }),
39
+ " ",
40
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: detail })
41
+ ] }, detail)),
42
+ interactive && actionLabel && /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
43
+ ". ",
44
+ actionLabel
45
+ ] })
46
+ ] }),
47
+ interactive && /* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": true })
48
+ ] });
49
+ const rootClasses = cn(
50
+ "flex min-h-[52px] w-full items-center gap-2.5 rounded-[14px] border bg-card px-3.5 py-2 text-left",
51
+ tone === "live" ? "border-success/40" : "border-border",
52
+ interactive && cn(
53
+ "cursor-pointer transition-colors duration-150 hover:bg-accent-subtle active:scale-[0.99] motion-reduce:transition-none",
54
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
55
+ ),
56
+ className
57
+ );
58
+ if (href) {
59
+ return /* @__PURE__ */ jsx(LinkComponent, { href, className: rootClasses, children: body });
60
+ }
61
+ return /* @__PURE__ */ jsx("div", { role: "status", className: rootClasses, children: body });
62
+ }
63
+ function EventTonightStripSkeleton({ className }) {
64
+ return /* @__PURE__ */ jsx(Skeleton, { className: cn("h-[52px] w-full rounded-[14px]", className) });
65
+ }
66
+
67
+ export { EventTonightStrip, EventTonightStripSkeleton };
@@ -75,9 +75,16 @@ type FacetGroupProps = Omit<ComponentPropsWithoutRef<"fieldset">, "title" | "chi
75
75
  /** e.g. "Show all". Omit to hide the trailing action. */
76
76
  moreLabel?: string;
77
77
  onMore?: () => void;
78
+ /**
79
+ * Whether the trailing action has already expanded the options it controls
80
+ * — set it when `onMore` reveals more rows in place (and `moreLabel` reads
81
+ * "Show fewer"), so the button carries `aria-expanded`. Leave it unset when
82
+ * the action opens another surface.
83
+ */
84
+ moreExpanded?: boolean;
78
85
  className?: string;
79
86
  };
80
- declare function FacetGroup({ title, icon: Icon, options, selection, name, size, collapsible, defaultOpen, onToggle, moreLabel, onMore, className, ...rest }: FacetGroupProps): react_jsx_runtime.JSX.Element;
87
+ declare function FacetGroup({ title, icon: Icon, options, selection, name, size, collapsible, defaultOpen, onToggle, moreLabel, onMore, moreExpanded, className, ...rest }: FacetGroupProps): react_jsx_runtime.JSX.Element;
81
88
  type FacetGroupSkeletonProps = {
82
89
  /** How many option rows to draw — match the expected/last-known option count. */
83
90
  optionCount?: number;
@@ -26,6 +26,7 @@ function FacetGroup(_a) {
26
26
  onToggle,
27
27
  moreLabel,
28
28
  onMore,
29
+ moreExpanded,
29
30
  className
30
31
  } = _b, rest = __objRest(_b, [
31
32
  "title",
@@ -39,6 +40,7 @@ function FacetGroup(_a) {
39
40
  "onToggle",
40
41
  "moreLabel",
41
42
  "onMore",
43
+ "moreExpanded",
42
44
  "className"
43
45
  ]);
44
46
  const isSingle = selection === "single";
@@ -191,6 +193,7 @@ function FacetGroup(_a) {
191
193
  {
192
194
  type: "button",
193
195
  onClick: onMore,
196
+ "aria-expanded": moreExpanded,
194
197
  className: "cursor-pointer pt-[11px] text-[12.5px] font-bold text-primary transition-colors duration-150 hover:text-primary/80 motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:rounded-sm",
195
198
  children: moreLabel
196
199
  }