@bearmenu/ui 0.8.3 → 0.8.6

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 (194) hide show
  1. package/dist/chunk-2WDJR6K7.js +76 -0
  2. package/dist/chunk-637L7XQ3.js +85 -0
  3. package/dist/chunk-6XMYEZVR.js +26 -0
  4. package/dist/chunk-DNSXMHYX.js +8 -0
  5. package/dist/chunk-FDITZ2VM.js +16 -0
  6. package/dist/chunk-GPH6L4DX.js +55 -0
  7. package/dist/{chunk-N2KNBPAQ.js → chunk-QXHMPJ35.js} +1 -0
  8. package/dist/chunk-TT3WFS6S.js +379 -0
  9. package/dist/chunk-UXWAOISG.js +170 -0
  10. package/dist/{chunk-UZ3PCIE5.js → chunk-XWMRABZW.js} +2 -2
  11. package/dist/{chunk-VBA45GLP.js → chunk-ZDAHKI3A.js} +12 -2
  12. package/dist/components/alert.d.ts +2 -2
  13. package/dist/components/badge.d.ts +1 -1
  14. package/dist/components/button.d.ts +1 -1
  15. package/dist/components/card.d.ts +2 -2
  16. package/dist/components/card.js +4 -127
  17. package/dist/components/category-deck.d.ts +50 -0
  18. package/dist/components/category-deck.js +128 -0
  19. package/dist/components/command.d.ts +15 -15
  20. package/dist/components/concept-card.d.ts +43 -0
  21. package/dist/components/concept-card.js +81 -0
  22. package/dist/components/coverflow.d.ts +123 -0
  23. package/dist/components/coverflow.js +300 -0
  24. package/dist/components/date-input.d.ts +1 -1
  25. package/dist/components/day-rail-chip.d.ts +82 -0
  26. package/dist/components/day-rail-chip.js +105 -0
  27. package/dist/components/drift-rail.d.ts +28 -0
  28. package/dist/components/drift-rail.js +3 -0
  29. package/dist/components/event-card.d.ts +97 -0
  30. package/dist/components/event-card.js +161 -0
  31. package/dist/components/event-compact-row.d.ts +72 -0
  32. package/dist/components/event-compact-row.js +133 -0
  33. package/dist/components/event-day-header.d.ts +65 -0
  34. package/dist/components/event-day-header.js +95 -0
  35. package/dist/components/event-day-separator.d.ts +46 -0
  36. package/dist/components/event-day-separator.js +50 -0
  37. package/dist/components/event-detail-panel.d.ts +80 -0
  38. package/dist/components/event-detail-panel.js +251 -0
  39. package/dist/components/event-hub-hero.d.ts +34 -0
  40. package/dist/components/event-hub-hero.js +57 -0
  41. package/dist/components/event-index-row.d.ts +68 -0
  42. package/dist/components/event-index-row.js +84 -0
  43. package/dist/components/event-list-row-wide.d.ts +101 -0
  44. package/dist/components/event-list-row-wide.js +218 -0
  45. package/dist/components/event-list-row.d.ts +82 -0
  46. package/dist/components/event-list-row.js +173 -0
  47. package/dist/components/event-poster-fallback.d.ts +20 -0
  48. package/dist/components/event-poster-fallback.js +3 -0
  49. package/dist/components/event-types.d.ts +118 -0
  50. package/dist/components/event-types.js +2 -0
  51. package/dist/components/events-empty-state.d.ts +44 -0
  52. package/dist/components/events-empty-state.js +73 -0
  53. package/dist/components/facet-group.d.ts +93 -0
  54. package/dist/components/facet-group.js +222 -0
  55. package/dist/components/featured-rail-item.d.ts +42 -0
  56. package/dist/components/featured-rail-item.js +88 -0
  57. package/dist/components/hour-band.d.ts +68 -0
  58. package/dist/components/hour-band.js +53 -0
  59. package/dist/components/hour-group.d.ts +67 -0
  60. package/dist/components/hour-group.js +59 -0
  61. package/dist/components/icon.d.ts +18 -0
  62. package/dist/components/icon.js +31 -0
  63. package/dist/components/item.d.ts +2 -2
  64. package/dist/components/motion-icon-controls.d.ts +26 -0
  65. package/dist/components/motion-icon-controls.js +4 -0
  66. package/dist/components/motion-icon-set.d.ts +27 -0
  67. package/dist/components/motion-icon-set.js +139 -0
  68. package/dist/components/motion-icon.d.ts +44 -0
  69. package/dist/components/motion-icon.js +3 -0
  70. package/dist/components/multi-select-combobox.js +1 -1
  71. package/dist/components/place-about-tab.js +3 -3
  72. package/dist/components/place-details-mobile.js +3 -3
  73. package/dist/components/poster-stack.d.ts +30 -0
  74. package/dist/components/poster-stack.js +104 -0
  75. package/dist/components/poster-tape.d.ts +36 -0
  76. package/dist/components/poster-tape.js +64 -0
  77. package/dist/components/poster-wall.d.ts +25 -0
  78. package/dist/components/poster-wall.js +183 -0
  79. package/dist/components/quiet-stretch.d.ts +43 -0
  80. package/dist/components/quiet-stretch.js +54 -0
  81. package/dist/components/section-header.d.ts +53 -0
  82. package/dist/components/section-header.js +63 -0
  83. package/dist/components/segmented-nav.d.ts +62 -0
  84. package/dist/components/segmented-nav.js +54 -0
  85. package/dist/components/skeleton-card.js +1 -1
  86. package/dist/components/skeleton.d.ts +17 -0
  87. package/dist/components/skeleton.js +1 -1
  88. package/dist/components/spinner.d.ts +2 -2
  89. package/dist/components/tag-group.js +3 -26
  90. package/dist/components/tag.d.ts +2 -2
  91. package/dist/components/tag.js +1 -1
  92. package/dist/components/text.d.ts +3 -3
  93. package/dist/components/timeline-band.d.ts +46 -0
  94. package/dist/components/timeline-band.js +5 -0
  95. package/dist/components/venue-events-block.d.ts +143 -0
  96. package/dist/components/venue-events-block.js +222 -0
  97. package/dist/components/weekend-panel.d.ts +44 -0
  98. package/dist/components/weekend-panel.js +231 -0
  99. package/dist/lib/icon-registry.d.ts +58 -0
  100. package/dist/lib/icon-registry.js +39 -0
  101. package/package.json +2 -1
  102. package/src/components/accordion.stories.tsx +1 -1
  103. package/src/components/card.tsx +44 -1
  104. package/src/components/category-deck.stories.tsx +96 -0
  105. package/src/components/category-deck.tsx +227 -0
  106. package/src/components/combobox.stories.tsx +1 -1
  107. package/src/components/concept-card.stories.tsx +80 -0
  108. package/src/components/concept-card.tsx +143 -0
  109. package/src/components/coverflow.stories.tsx +240 -0
  110. package/src/components/coverflow.test.tsx +193 -0
  111. package/src/components/coverflow.tsx +550 -0
  112. package/src/components/currency-input.stories.tsx +3 -3
  113. package/src/components/day-rail-chip.stories.tsx +145 -0
  114. package/src/components/day-rail-chip.tsx +201 -0
  115. package/src/components/drift-rail.stories.tsx +92 -0
  116. package/src/components/drift-rail.tsx +86 -0
  117. package/src/components/empty-state.stories.tsx +3 -3
  118. package/src/components/event-card.stories.tsx +248 -0
  119. package/src/components/event-card.test.tsx +177 -0
  120. package/src/components/event-card.tsx +321 -0
  121. package/src/components/event-compact-row.stories.tsx +221 -0
  122. package/src/components/event-compact-row.tsx +268 -0
  123. package/src/components/event-day-header.stories.tsx +124 -0
  124. package/src/components/event-day-header.tsx +180 -0
  125. package/src/components/event-day-separator.stories.tsx +70 -0
  126. package/src/components/event-day-separator.tsx +95 -0
  127. package/src/components/event-detail-panel.stories.tsx +191 -0
  128. package/src/components/event-detail-panel.tsx +360 -0
  129. package/src/components/event-hub-hero.stories.tsx +66 -0
  130. package/src/components/event-hub-hero.tsx +110 -0
  131. package/src/components/event-index-row.stories.tsx +116 -0
  132. package/src/components/event-index-row.tsx +181 -0
  133. package/src/components/event-list-row-wide.stories.tsx +204 -0
  134. package/src/components/event-list-row-wide.tsx +386 -0
  135. package/src/components/event-list-row.stories.tsx +159 -0
  136. package/src/components/event-list-row.tsx +335 -0
  137. package/src/components/event-poster-fallback.stories.tsx +52 -0
  138. package/src/components/event-poster-fallback.tsx +31 -0
  139. package/src/components/event-types.ts +133 -0
  140. package/src/components/events-empty-state.stories.tsx +59 -0
  141. package/src/components/events-empty-state.tsx +131 -0
  142. package/src/components/facet-group.stories.tsx +247 -0
  143. package/src/components/facet-group.test.tsx +225 -0
  144. package/src/components/facet-group.tsx +352 -0
  145. package/src/components/featured-rail-item.stories.tsx +86 -0
  146. package/src/components/featured-rail-item.tsx +153 -0
  147. package/src/components/form.stories.tsx +1 -1
  148. package/src/components/hour-band.stories.tsx +159 -0
  149. package/src/components/hour-band.tsx +126 -0
  150. package/src/components/hour-group.stories.tsx +100 -0
  151. package/src/components/hour-group.tsx +124 -0
  152. package/src/components/icon.tsx +57 -0
  153. package/src/components/input-otp.stories.tsx +1 -1
  154. package/src/components/markdown-renderer.stories.tsx +1 -1
  155. package/src/components/motion-icon-controls.test.tsx +78 -0
  156. package/src/components/motion-icon-controls.tsx +552 -0
  157. package/src/components/motion-icon-set.stories.tsx +185 -0
  158. package/src/components/motion-icon-set.tsx +219 -0
  159. package/src/components/motion-icon.test.tsx +159 -0
  160. package/src/components/motion-icon.tsx +163 -0
  161. package/src/components/multi-select-combobox.stories.tsx +1 -1
  162. package/src/components/phone-frame.stories.tsx +1 -1
  163. package/src/components/poster-stack.stories.tsx +68 -0
  164. package/src/components/poster-stack.tsx +155 -0
  165. package/src/components/poster-tape.stories.tsx +70 -0
  166. package/src/components/poster-tape.tsx +122 -0
  167. package/src/components/poster-wall.stories.tsx +95 -0
  168. package/src/components/poster-wall.tsx +220 -0
  169. package/src/components/quiet-stretch.stories.tsx +62 -0
  170. package/src/components/quiet-stretch.tsx +115 -0
  171. package/src/components/rating.stories.tsx +3 -3
  172. package/src/components/searchable-select.stories.tsx +1 -1
  173. package/src/components/section-header.stories.tsx +70 -0
  174. package/src/components/section-header.tsx +134 -0
  175. package/src/components/segmented-nav.stories.tsx +118 -0
  176. package/src/components/segmented-nav.tsx +113 -0
  177. package/src/components/selection-bar.stories.tsx +1 -1
  178. package/src/components/skeleton-card.stories.tsx +3 -3
  179. package/src/components/skeleton.tsx +18 -0
  180. package/src/components/sliding-panels.stories.tsx +1 -1
  181. package/src/components/stepper.stories.tsx +1 -1
  182. package/src/components/sticky-container.stories.tsx +3 -3
  183. package/src/components/tag.tsx +11 -1
  184. package/src/components/timeline-band.stories.tsx +206 -0
  185. package/src/components/timeline-band.tsx +207 -0
  186. package/src/components/toggle-group.stories.tsx +1 -1
  187. package/src/components/tooltip.stories.tsx +2 -2
  188. package/src/components/venue-events-block.stories.tsx +216 -0
  189. package/src/components/venue-events-block.tsx +408 -0
  190. package/src/components/weekend-panel.stories.tsx +92 -0
  191. package/src/components/weekend-panel.tsx +322 -0
  192. package/src/globals.css +19 -0
  193. package/src/lib/icon-registry.ts +139 -0
  194. package/src/test/setup.ts +5 -1
@@ -0,0 +1,26 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { MotionIconProps } from './motion-icon.js';
3
+ import 'framer-motion';
4
+ import 'react';
5
+
6
+ declare function MotionHeart(props: MotionIconProps): react_jsx_runtime.JSX.Element;
7
+ declare function MotionBookmark(props: MotionIconProps): react_jsx_runtime.JSX.Element;
8
+ declare function MotionSliders(props: MotionIconProps): react_jsx_runtime.JSX.Element;
9
+ declare function MotionSearch(props: MotionIconProps): react_jsx_runtime.JSX.Element;
10
+ declare function MotionShare(props: MotionIconProps): react_jsx_runtime.JSX.Element;
11
+ declare function MotionSort(props: MotionIconProps): react_jsx_runtime.JSX.Element;
12
+ declare function MotionCheck(props: MotionIconProps): react_jsx_runtime.JSX.Element;
13
+ /**
14
+ * `active` is dark mode. The sun does not fade into the moon — its rays pull
15
+ * into the disc first, then the crescent swings in, so the two shapes never
16
+ * cross-dissolve into visual mush at 20px.
17
+ */
18
+ declare function MotionTheme(props: MotionIconProps): react_jsx_runtime.JSX.Element;
19
+ declare function MotionChevron(props: MotionIconProps): react_jsx_runtime.JSX.Element;
20
+ declare function MotionPlayPause(props: MotionIconProps): react_jsx_runtime.JSX.Element;
21
+ declare function MotionEye(props: MotionIconProps): react_jsx_runtime.JSX.Element;
22
+ declare function MotionStar(props: MotionIconProps): react_jsx_runtime.JSX.Element;
23
+ declare function MotionCopy(props: MotionIconProps): react_jsx_runtime.JSX.Element;
24
+ declare function MotionRefresh(props: MotionIconProps): react_jsx_runtime.JSX.Element;
25
+
26
+ export { MotionBookmark, MotionCheck, MotionChevron, MotionCopy, MotionEye, MotionHeart, MotionPlayPause, MotionRefresh, MotionSearch, MotionShare, MotionSliders, MotionSort, MotionStar, MotionTheme };
@@ -0,0 +1,4 @@
1
+ export { MotionBookmark, MotionCheck, MotionChevron, MotionCopy, MotionEye, MotionHeart, MotionPlayPause, MotionRefresh, MotionSearch, MotionShare, MotionSliders, MotionSort, MotionStar, MotionTheme } from '../chunk-TT3WFS6S.js';
2
+ import '../chunk-2WDJR6K7.js';
3
+ import '../chunk-FEK5XGZW.js';
4
+ import '../chunk-3GWWZKX7.js';
@@ -0,0 +1,27 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { MotionIconProps } from './motion-icon.js';
3
+ import 'framer-motion';
4
+ import 'react';
5
+
6
+ /**
7
+ * Lucide draws roof and walls as one closed path; it is cut at the eaves
8
+ * (y=10) so the roof can leave. At rest the round caps of the two open paths
9
+ * overlap and the seam is invisible.
10
+ */
11
+ declare function MotionHouse(props: MotionIconProps): react_jsx_runtime.JSX.Element;
12
+ /**
13
+ * The one gesture that HOLDS: uncrossed is the active pose. ~89° of relative
14
+ * separation, so the outline changes completely and the state is readable from
15
+ * the silhouette alone.
16
+ */
17
+ declare function MotionUtensils(props: MotionIconProps): react_jsx_runtime.JSX.Element;
18
+ declare function MotionMapPin(props: MotionIconProps): react_jsx_runtime.JSX.Element;
19
+ /**
20
+ * Lucide's calendar has no pages — it is a box, a rule and six dots, and
21
+ * nothing in that geometry can roll. So the day dots become the page content,
22
+ * clipped to the body interior. The frame and binder rings hold perfectly
23
+ * still, which is what sells the contents moving.
24
+ */
25
+ declare function MotionCalendar(props: MotionIconProps): react_jsx_runtime.JSX.Element;
26
+
27
+ export { MotionCalendar, MotionHouse, MotionMapPin, MotionUtensils };
@@ -0,0 +1,139 @@
1
+ import { beats, MotionIcon, returnTransition } from '../chunk-2WDJR6K7.js';
2
+ import '../chunk-FEK5XGZW.js';
3
+ import { __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
4
+ import * as React from 'react';
5
+ import { motion } from 'framer-motion';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var HOUSE_TIMES = [0, 0.16, 0.44, 0.72, 1];
9
+ var houseRoof = {
10
+ rest: { y: 0, scaleY: 1, transition: returnTransition },
11
+ active: { y: 0, scaleY: 1, transition: returnTransition },
12
+ play: {
13
+ // Dips into the walls, launches 9 units clear and stretches, falls, lands
14
+ // 0.9 low onto walls that compress under it, settles.
15
+ y: [0, 1.5, -9, 0.9, 0],
16
+ scaleY: [1, 0.92, 1.06, 0.86, 1],
17
+ transition: beats(HOUSE_TIMES)
18
+ }
19
+ };
20
+ var houseWalls = {
21
+ rest: { scaleY: 1, transition: returnTransition },
22
+ active: { scaleY: 1, transition: returnTransition },
23
+ play: { scaleY: [1, 1, 1, 0.9, 1], transition: beats(HOUSE_TIMES) }
24
+ };
25
+ function MotionHouse(props) {
26
+ return /* @__PURE__ */ jsxs(MotionIcon, __spreadProps(__spreadValues({}, props), { children: [
27
+ /* @__PURE__ */ jsx(
28
+ motion.path,
29
+ {
30
+ variants: houseRoof,
31
+ style: { originX: "12px", originY: "10px" },
32
+ d: "M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10"
33
+ }
34
+ ),
35
+ /* @__PURE__ */ jsxs(motion.g, { variants: houseWalls, style: { originX: "12px", originY: "21px" }, children: [
36
+ /* @__PURE__ */ jsx("path", { d: "M21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V10" }),
37
+ /* @__PURE__ */ jsx("path", { d: "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" })
38
+ ] })
39
+ ] }));
40
+ }
41
+ var UTENSILS_TIMES = [0, 0.18, 0.72, 1];
42
+ var SEPARATION = 5;
43
+ var fork = {
44
+ rest: { rotate: 0, x: 0, transition: returnTransition },
45
+ active: { rotate: -44, x: -SEPARATION, transition: returnTransition },
46
+ play: {
47
+ rotate: [0, 6, -50, -44],
48
+ x: [0, 0.8, -6, -SEPARATION],
49
+ transition: beats(UTENSILS_TIMES, 0.6)
50
+ }
51
+ };
52
+ var knife = {
53
+ rest: { rotate: 0, x: 0, transition: returnTransition },
54
+ active: { rotate: 45, x: SEPARATION, transition: returnTransition },
55
+ play: {
56
+ rotate: [0, -6, 51, 45],
57
+ x: [0, -0.8, 6, SEPARATION],
58
+ transition: beats(UTENSILS_TIMES, 0.6)
59
+ }
60
+ };
61
+ var CROSSING = { originX: "12px", originY: "12px" };
62
+ function MotionUtensils(props) {
63
+ return /* @__PURE__ */ jsxs(MotionIcon, __spreadProps(__spreadValues({}, props), { children: [
64
+ /* @__PURE__ */ jsx(
65
+ motion.path,
66
+ {
67
+ variants: knife,
68
+ style: CROSSING,
69
+ d: "M15 15 3.3 3.3a4.2 4.2 0 0 0 0 6l7.3 7.3c.7.7 2 .7 2.8 0L15 15Zm0 0 7 7"
70
+ }
71
+ ),
72
+ /* @__PURE__ */ jsxs(motion.g, { variants: fork, style: CROSSING, children: [
73
+ /* @__PURE__ */ jsx("path", { d: "m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8" }),
74
+ /* @__PURE__ */ jsx("path", { d: "m2.1 21.8 6.4-6.3" }),
75
+ /* @__PURE__ */ jsx("path", { d: "m19 5-7 7" })
76
+ ] })
77
+ ] }));
78
+ }
79
+ var PIN_TIMES = [0, 0.16, 0.44, 0.72, 1];
80
+ var pinBody = {
81
+ rest: { y: 0, scaleY: 1, transition: returnTransition },
82
+ active: { y: 0, scaleY: 1, transition: returnTransition },
83
+ play: {
84
+ y: [0, 1.2, -9, 0, 0],
85
+ scaleY: [1, 0.86, 1.08, 0.84, 1],
86
+ transition: beats(PIN_TIMES)
87
+ }
88
+ };
89
+ var pinDot = {
90
+ rest: { fillOpacity: 0, scale: 1, transition: { duration: 0.18 } },
91
+ active: { fillOpacity: 1, scale: 1, transition: { duration: 0.18 } },
92
+ play: {
93
+ fillOpacity: [0, 0, 0, 1, 1],
94
+ scale: [1, 1, 1, 1.35, 1],
95
+ transition: beats(PIN_TIMES)
96
+ }
97
+ };
98
+ function MotionMapPin(props) {
99
+ return /* @__PURE__ */ jsx(MotionIcon, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ jsxs(motion.g, { variants: pinBody, style: { originX: "12px", originY: "22px" }, children: [
100
+ /* @__PURE__ */ jsx("path", { d: "M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" }),
101
+ /* @__PURE__ */ jsx(
102
+ motion.circle,
103
+ {
104
+ variants: pinDot,
105
+ style: { originX: "12px", originY: "10px" },
106
+ fill: "currentColor",
107
+ fillOpacity: 0,
108
+ cx: "12",
109
+ cy: "10",
110
+ r: "3"
111
+ }
112
+ )
113
+ ] }) }));
114
+ }
115
+ var ROWS = [14, 18, 22, 26, 30, 34];
116
+ var COLS = [8, 12, 16];
117
+ var reel = {
118
+ rest: { y: 0, transition: returnTransition },
119
+ active: { y: 0, transition: returnTransition },
120
+ play: {
121
+ // Exactly four rows (16 units, ~15px), so arriving rows land where the
122
+ // departing ones began and the end pose is identical to the rest pose.
123
+ y: [0, -4, -8, -12, -17, -16],
124
+ transition: beats([0, 0.18, 0.34, 0.5, 0.85, 1], 0.65)
125
+ }
126
+ };
127
+ function MotionCalendar(props) {
128
+ const clipId = `cal-body-${React.useId().replace(/:/g, "")}`;
129
+ return /* @__PURE__ */ jsxs(MotionIcon, __spreadProps(__spreadValues({}, props), { children: [
130
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: clipId, children: /* @__PURE__ */ jsx("rect", { x: "3.5", y: "10.5", width: "17", height: "11", rx: "1.5" }) }) }),
131
+ /* @__PURE__ */ jsx("path", { d: "M8 2v4" }),
132
+ /* @__PURE__ */ jsx("path", { d: "M16 2v4" }),
133
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2" }),
134
+ /* @__PURE__ */ jsx("path", { d: "M3 10h18" }),
135
+ /* @__PURE__ */ jsx("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ jsx(motion.g, { variants: reel, children: ROWS.map((y) => COLS.map((x) => /* @__PURE__ */ jsx("path", { d: `M${x} ${y}h.01` }, `${x}-${y}`))) }) })
136
+ ] }));
137
+ }
138
+
139
+ export { MotionCalendar, MotionHouse, MotionMapPin, MotionUtensils };
@@ -0,0 +1,44 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as framer_motion from 'framer-motion';
3
+ import { Transition, Variants } from 'framer-motion';
4
+ import * as React from 'react';
5
+
6
+ type MotionIconProps = {
7
+ /** The held state. Drives `active` vs `rest`, and the stroke weight. */
8
+ active?: boolean;
9
+ /**
10
+ * Bump on pointer down to perform the gesture. Changing this value replays
11
+ * `play` even when `active` has not changed, which is what makes the icon
12
+ * respond to the touch rather than to its consequence.
13
+ */
14
+ replayToken?: number;
15
+ className?: string;
16
+ };
17
+ type MotionIconVariant = "rest" | "active" | "play";
18
+ /**
19
+ * A gesture is a performance with beats, so it is a tween with explicit
20
+ * `times`. A spring interpolates two keyframes and puts its overshoot at the
21
+ * end, which cannot express anticipation.
22
+ */
23
+ declare function beats(times: number[], duration?: number): Transition;
24
+ /** Leaving is not a performance — it returns the glyph, firmly and fast. */
25
+ declare const returnTransition: Transition;
26
+ type PoseValues = Record<string, number>;
27
+ /**
28
+ * Builds the three variants for a moving part.
29
+ * `play` values are keyframe arrays; `rest`/`active` are the two held poses.
30
+ */
31
+ declare function poses(rest: PoseValues, active: PoseValues, play: Record<string, number[]>, transition: Transition): Variants;
32
+ /**
33
+ * Mount poses without playing; pointer down plays; arriving plays unless the
34
+ * pointer already started it; leaving returns.
35
+ *
36
+ * Both effects compare against a ref rather than trusting the dependency array,
37
+ * so they fire once per actual change and not once per render.
38
+ */
39
+ declare function useIconGesture(active: boolean, replayToken: number): framer_motion.LegacyAnimationControls;
40
+ declare function MotionIcon({ active, replayToken, className, children, }: MotionIconProps & {
41
+ children: React.ReactNode;
42
+ }): react_jsx_runtime.JSX.Element;
43
+
44
+ export { MotionIcon, type MotionIconProps, type MotionIconVariant, beats, poses, returnTransition, useIconGesture };
@@ -0,0 +1,3 @@
1
+ export { MotionIcon, beats, poses, returnTransition, useIconGesture } from '../chunk-2WDJR6K7.js';
2
+ import '../chunk-FEK5XGZW.js';
3
+ import '../chunk-3GWWZKX7.js';
@@ -1,7 +1,7 @@
1
- import { Checkbox } from '../chunk-D5QHEHXJ.js';
2
1
  import { Popover, PopoverTrigger, PopoverContent } from '../chunk-66MAPLXS.js';
3
2
  import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../chunk-XNA2INVQ.js';
4
3
  import '../chunk-FRPPIXMY.js';
4
+ import { Checkbox } from '../chunk-D5QHEHXJ.js';
5
5
  import { Button } from '../chunk-H3BV4VAG.js';
6
6
  import '../chunk-R47NEOSI.js';
7
7
  import { Badge } from '../chunk-UKBNQO6Q.js';
@@ -1,7 +1,7 @@
1
- export { PlaceAboutTab } from '../chunk-UZ3PCIE5.js';
2
- import '../chunk-VBA45GLP.js';
3
- import '../chunk-WSRWFA6K.js';
1
+ export { PlaceAboutTab } from '../chunk-XWMRABZW.js';
4
2
  import '../chunk-VG3PND3D.js';
3
+ import '../chunk-WSRWFA6K.js';
4
+ import '../chunk-ZDAHKI3A.js';
5
5
  import '../chunk-7BWTYWM3.js';
6
6
  import '../chunk-FEK5XGZW.js';
7
7
  import '../chunk-3GWWZKX7.js';
@@ -1,7 +1,7 @@
1
- import { PlaceAboutTab } from '../chunk-UZ3PCIE5.js';
2
- import '../chunk-VBA45GLP.js';
3
- import '../chunk-WSRWFA6K.js';
1
+ import { PlaceAboutTab } from '../chunk-XWMRABZW.js';
4
2
  import '../chunk-VG3PND3D.js';
3
+ import '../chunk-WSRWFA6K.js';
4
+ import '../chunk-ZDAHKI3A.js';
5
5
  import { Text } from '../chunk-7BWTYWM3.js';
6
6
  import { Badge } from '../chunk-UKBNQO6Q.js';
7
7
  import { cn } from '../chunk-FEK5XGZW.js';
@@ -0,0 +1,30 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * PosterStack — three overlapping, gently rotated posters that float, the
5
+ * hub hero's aside slot in the source design.
6
+ *
7
+ * Two motion rules, both mandatory:
8
+ * 1. Stops entirely under `prefers-reduced-motion: reduce` — enforced via
9
+ * an injected `<style>` media query rather than relying on Tailwind's
10
+ * `motion-reduce:` variant, because the float is a custom `@keyframes`
11
+ * animation Tailwind cannot express, and only a `!important` CSS rule
12
+ * reliably beats the element's own inline `animation` style.
13
+ * 2. Pauses while the stack is scrolled off-screen — an IntersectionObserver
14
+ * toggles `animation-play-state` on the three poster nodes so nothing
15
+ * spends a paint budget while it isn't visible. Skipped entirely when
16
+ * reduced motion is on, since nothing is animating to pause.
17
+ */
18
+ type PosterStackPoster = {
19
+ /** Absent renders a neutral placeholder block instead of an image. */
20
+ src?: string;
21
+ alt: string;
22
+ };
23
+ type PosterStackProps = {
24
+ /** Rendered in order; only the first three are shown. */
25
+ posters: PosterStackPoster[];
26
+ className?: string;
27
+ };
28
+ declare function PosterStack({ posters, className }: PosterStackProps): react_jsx_runtime.JSX.Element;
29
+
30
+ export { PosterStack, type PosterStackPoster, type PosterStackProps };
@@ -0,0 +1,104 @@
1
+ import { cn } from '../chunk-FEK5XGZW.js';
2
+ import '../chunk-3GWWZKX7.js';
3
+ import { useRef, useState, useEffect } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var POSTER_STACK_OBSERVER_ROOT_MARGIN = "200px";
7
+ var POSTER_STACK_ANIMATION_STYLE = `
8
+ @keyframes ds-poster-stack-float-1 { to { transform: rotate(-5deg) translateY(-16px); } }
9
+ @keyframes ds-poster-stack-float-2 { to { transform: rotate(3deg) translateY(14px); } }
10
+ @keyframes ds-poster-stack-float-3 { to { transform: rotate(6deg) translateY(-11px); } }
11
+ @media (prefers-reduced-motion: reduce) {
12
+ [data-ds-poster-stack-item] { animation: none !important; }
13
+ }
14
+ `;
15
+ var POSTER_SLOTS = [
16
+ {
17
+ positionClassName: "left-[6px] top-[34px] w-[120px] md:left-0 md:top-[52px] md:w-[196px]",
18
+ restTransform: "rotate(-5deg)",
19
+ animationName: "ds-poster-stack-float-1",
20
+ animationDurationMs: 9e3
21
+ },
22
+ {
23
+ positionClassName: "left-[110px] top-0 w-[140px] md:left-[168px] md:w-[232px]",
24
+ restTransform: "rotate(3deg)",
25
+ animationName: "ds-poster-stack-float-2",
26
+ animationDurationMs: 11e3,
27
+ zIndexClassName: "z-[3]"
28
+ },
29
+ {
30
+ positionClassName: "left-[238px] top-[58px] w-[120px] md:left-[378px] md:top-24 md:w-[196px]",
31
+ restTransform: "rotate(6deg)",
32
+ animationName: "ds-poster-stack-float-3",
33
+ animationDurationMs: 1e4
34
+ }
35
+ ];
36
+ var POSTER_SHADOW = "0 22px 50px oklch(0.3 0.02 60 / 0.24)";
37
+ function PosterStack({ posters, className }) {
38
+ const containerRef = useRef(null);
39
+ const posterRefs = useRef([]);
40
+ const [failedIndices, setFailedIndices] = useState(/* @__PURE__ */ new Set());
41
+ useEffect(() => {
42
+ if (typeof window === "undefined") return;
43
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
44
+ const container = containerRef.current;
45
+ if (!container) return;
46
+ const observer = new IntersectionObserver(
47
+ ([entry]) => {
48
+ const playState = entry.isIntersecting ? "running" : "paused";
49
+ for (const poster of posterRefs.current) {
50
+ if (poster) poster.style.animationPlayState = playState;
51
+ }
52
+ },
53
+ { rootMargin: POSTER_STACK_OBSERVER_ROOT_MARGIN }
54
+ );
55
+ observer.observe(container);
56
+ return () => observer.disconnect();
57
+ }, []);
58
+ const visiblePosters = posters.slice(0, POSTER_SLOTS.length);
59
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: cn("relative h-[250px] md:h-[400px]", className), children: [
60
+ /* @__PURE__ */ jsx("style", { children: POSTER_STACK_ANIMATION_STYLE }),
61
+ visiblePosters.map((poster, index) => {
62
+ const slot = POSTER_SLOTS[index];
63
+ const showPoster = !!poster.src && !failedIndices.has(index);
64
+ return /* @__PURE__ */ jsx(
65
+ "div",
66
+ {
67
+ ref: (node) => {
68
+ posterRefs.current[index] = node;
69
+ },
70
+ "data-ds-poster-stack-item": true,
71
+ className: cn(
72
+ "absolute aspect-[3/4] overflow-hidden rounded-xl bg-muted",
73
+ slot.positionClassName,
74
+ slot.zIndexClassName
75
+ ),
76
+ style: {
77
+ transform: slot.restTransform,
78
+ boxShadow: POSTER_SHADOW,
79
+ animationName: slot.animationName,
80
+ animationDuration: `${slot.animationDurationMs}ms`,
81
+ animationTimingFunction: "ease-in-out",
82
+ animationIterationCount: "infinite",
83
+ animationDirection: "alternate"
84
+ },
85
+ children: showPoster && // eslint-disable-next-line @next/next/no-img-element
86
+ /* @__PURE__ */ jsx(
87
+ "img",
88
+ {
89
+ src: poster.src,
90
+ alt: poster.alt,
91
+ loading: "lazy",
92
+ decoding: "async",
93
+ className: "h-full w-full object-cover",
94
+ onError: () => setFailedIndices((current) => new Set(current).add(index))
95
+ }
96
+ )
97
+ },
98
+ poster.alt || index
99
+ );
100
+ })
101
+ ] });
102
+ }
103
+
104
+ export { PosterStack };
@@ -0,0 +1,36 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * PosterTape — the closing marquee: small 4:5 posters drifting past at a
6
+ * slower, quieter speed than `<DriftRail>`'s default. Built on top of
7
+ * `<DriftRail>` rather than re-implementing the loop: both share the exact
8
+ * same seam-free-duplication and pause mechanics (`IntersectionObserver` +
9
+ * `prefers-reduced-motion`), and `<PosterTape>` only owns the item markup and
10
+ * a slower default speed.
11
+ */
12
+ type PosterTapeItem = {
13
+ id: string;
14
+ title: string;
15
+ /** Caller-composed, e.g. "Sat 5 · 20:00". Rendered as mono, small. */
16
+ meta: string;
17
+ posterUrl?: string;
18
+ href?: string;
19
+ /** Rendered instead of the poster when it's absent or failed to load. Defaults to `<EventPosterFallback />`. */
20
+ fallback?: ReactNode;
21
+ };
22
+ type PosterTapeLinkProps = {
23
+ href: string;
24
+ className?: string;
25
+ children: React.ReactNode;
26
+ };
27
+ type PosterTapeProps = {
28
+ items: PosterTapeItem[];
29
+ /** Defaults to a plain `<a>`. Pass `next/link` in a Next app. */
30
+ linkComponent?: React.ComponentType<PosterTapeLinkProps>;
31
+ durationSeconds?: number;
32
+ className?: string;
33
+ };
34
+ declare function PosterTape({ items, linkComponent: LinkComponent, durationSeconds, className, }: PosterTapeProps): react_jsx_runtime.JSX.Element;
35
+
36
+ export { PosterTape, type PosterTapeItem, type PosterTapeLinkProps, type PosterTapeProps };
@@ -0,0 +1,64 @@
1
+ import { DriftRail } from '../chunk-GPH6L4DX.js';
2
+ import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
3
+ import { cn } from '../chunk-FEK5XGZW.js';
4
+ import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
5
+ import { useState } from 'react';
6
+ import { jsx, jsxs, 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
+ var POSTER_TAPE_DEFAULT_DURATION_SECONDS = 60;
13
+ function PosterTapeItemCard({
14
+ item,
15
+ LinkComponent
16
+ }) {
17
+ var _a;
18
+ const [imgError, setImgError] = useState(false);
19
+ const showPoster = !!item.posterUrl && !imgError;
20
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
21
+ /* @__PURE__ */ jsx("div", { className: "aspect-[4/5] w-full overflow-hidden rounded-xl bg-muted", children: showPoster ? (
22
+ // eslint-disable-next-line @next/next/no-img-element
23
+ /* @__PURE__ */ jsx(
24
+ "img",
25
+ {
26
+ src: item.posterUrl,
27
+ alt: item.title,
28
+ title: item.title,
29
+ loading: "lazy",
30
+ decoding: "async",
31
+ className: "h-full w-full object-cover",
32
+ onError: () => setImgError(true)
33
+ }
34
+ )
35
+ ) : (_a = item.fallback) != null ? _a : /* @__PURE__ */ jsx(EventPosterFallback, {}) }),
36
+ /* @__PURE__ */ jsx("div", { className: "mt-1.5 text-[11px] font-semibold leading-[1.3] sm:mt-[7px] sm:text-[11.5px]", children: item.title }),
37
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 truncate font-mono text-[10px] text-muted-foreground sm:text-[10.5px]", children: item.meta })
38
+ ] });
39
+ const itemClasses = "block w-[132px] shrink-0";
40
+ if (item.href) {
41
+ return /* @__PURE__ */ jsx(
42
+ LinkComponent,
43
+ {
44
+ href: item.href,
45
+ className: cn(
46
+ itemClasses,
47
+ "rounded-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
48
+ ),
49
+ children: body
50
+ }
51
+ );
52
+ }
53
+ return /* @__PURE__ */ jsx("div", { className: itemClasses, children: body });
54
+ }
55
+ function PosterTape({
56
+ items,
57
+ linkComponent: LinkComponent = DefaultLink,
58
+ durationSeconds = POSTER_TAPE_DEFAULT_DURATION_SECONDS,
59
+ className
60
+ }) {
61
+ return /* @__PURE__ */ jsx(DriftRail, { durationSeconds, className, children: items.map((item) => /* @__PURE__ */ jsx(PosterTapeItemCard, { item, LinkComponent }, item.id)) });
62
+ }
63
+
64
+ export { PosterTape };
@@ -0,0 +1,25 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ type PosterWallTile = {
5
+ src?: string;
6
+ };
7
+ type PosterWallProps = {
8
+ /** Background tiles. Desktop renders 48, `compact` renders 36 — shorter arrays are padded with placeholders. */
9
+ tiles?: PosterWallTile[];
10
+ /** `compact` is the bottom-aligned mobile treatment (fewer, larger tiles, a top-fading veil). */
11
+ variant?: "default" | "compact";
12
+ /** The overlay content — fully caller-composed. */
13
+ children?: React.ReactNode;
14
+ className?: string;
15
+ };
16
+ declare function PosterWall({ tiles, variant, children, className }: PosterWallProps): react_jsx_runtime.JSX.Element;
17
+ type PosterWallSkeletonProps = {
18
+ /** `compact` is the bottom-aligned mobile treatment (fewer, larger tiles, a top-fading veil). */
19
+ variant?: "default" | "compact";
20
+ className?: string;
21
+ };
22
+ /** The tile grid at rest — the sweeping light never renders in the loading state. */
23
+ declare function PosterWallSkeleton({ variant, className }: PosterWallSkeletonProps): react_jsx_runtime.JSX.Element;
24
+
25
+ export { PosterWall, type PosterWallProps, PosterWallSkeleton, type PosterWallSkeletonProps, type PosterWallTile };