@bearmenu/ui 0.8.13 → 0.8.14

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 (285) hide show
  1. package/dist/{chunk-66MAPLXS.js → chunk-2ADCZXZJ.js} +1 -1
  2. package/dist/{chunk-2DEIXTBN.js → chunk-2ZXIXQIU.js} +1 -1
  3. package/dist/{chunk-YOKHBAIH.js → chunk-4OF4T4AI.js} +12 -11
  4. package/dist/{chunk-MZL7CGCL.js → chunk-4XDJXMLF.js} +2 -2
  5. package/dist/{chunk-YYGB4G4Q.js → chunk-CZK2MRS2.js} +1 -1
  6. package/dist/chunk-DJD3EMPK.js +126 -0
  7. package/dist/chunk-EZG2NELX.js +5 -0
  8. package/dist/{chunk-VAXOQS7W.js → chunk-F76NCVVR.js} +1 -1
  9. package/dist/{chunk-VG3PND3D.js → chunk-FMTJGO76.js} +1 -1
  10. package/dist/{chunk-UXWAOISG.js → chunk-FVSKGCK3.js} +2 -2
  11. package/dist/{chunk-2XCZJWTV.js → chunk-GNCWJWFE.js} +1 -1
  12. package/dist/{chunk-X3WMRKOW.js → chunk-HDR7V6IZ.js} +1 -1
  13. package/dist/{chunk-HSIYYA2E.js → chunk-HQU6QVAN.js} +5 -5
  14. package/dist/chunk-I5V446BX.js +27 -0
  15. package/dist/{chunk-WCTHZKU7.js → chunk-ICOU5QHT.js} +1 -1
  16. package/dist/{chunk-G7IFL4Z4.js → chunk-L3VEMP5A.js} +57 -9
  17. package/dist/chunk-LQWGZIYA.js +5 -0
  18. package/dist/{chunk-XNA2INVQ.js → chunk-MCOHLWRS.js} +2 -2
  19. package/dist/{chunk-3GWWZKX7.js → chunk-MMUBH76A.js} +21 -1
  20. package/dist/{chunk-ZDAHKI3A.js → chunk-MWB7S54O.js} +1 -1
  21. package/dist/{chunk-D5QHEHXJ.js → chunk-NMEVJT5Q.js} +1 -1
  22. package/dist/{chunk-3TNPSN4D.js → chunk-NSNEANOQ.js} +2 -2
  23. package/dist/{chunk-WSRWFA6K.js → chunk-NWZGSLPU.js} +1 -1
  24. package/dist/{chunk-LEAYBICI.js → chunk-OIV7B44M.js} +1 -1
  25. package/dist/{chunk-2CXU5WZO.js → chunk-P43B3ONY.js} +1 -1
  26. package/dist/{chunk-FRPPIXMY.js → chunk-PDTPO6NG.js} +1 -1
  27. package/dist/{chunk-6XMYEZVR.js → chunk-PX6RICS5.js} +1 -1
  28. package/dist/{chunk-6TEEY5YA.js → chunk-S33K4RC5.js} +1 -1
  29. package/dist/{chunk-3VMDCCCX.js → chunk-SC2VUTUI.js} +1 -1
  30. package/dist/{chunk-3NMG3KNA.js → chunk-SXQZ7DLH.js} +3 -3
  31. package/dist/{chunk-UDTG3RSE.js → chunk-T6S2ZBV6.js} +2 -2
  32. package/dist/{chunk-FKNBZF5T.js → chunk-WYTJR2YU.js} +1 -1
  33. package/dist/{chunk-QXHMPJ35.js → chunk-XBBEX4SF.js} +1 -1
  34. package/dist/chunk-XCB3F6SF.js +16 -0
  35. package/dist/{chunk-7BWTYWM3.js → chunk-ZLMRVBD7.js} +1 -1
  36. package/dist/{chunk-P7XTW2CG.js → chunk-ZLPWEHZO.js} +1 -1
  37. package/dist/components/accordion.js +1 -1
  38. package/dist/components/alert-dialog.js +2 -2
  39. package/dist/components/alert.js +2 -2
  40. package/dist/components/aspect-ratio.js +2 -2
  41. package/dist/components/avatar.js +1 -1
  42. package/dist/components/badge.js +2 -2
  43. package/dist/components/breadcrumb.js +1 -1
  44. package/dist/components/button-group.js +1 -1
  45. package/dist/components/button.js +2 -2
  46. package/dist/components/calendar.js +2 -2
  47. package/dist/components/card.js +3 -3
  48. package/dist/components/carousel.js +2 -2
  49. package/dist/components/category-deck.js +2 -2
  50. package/dist/components/checkbox.js +2 -2
  51. package/dist/components/circular-progress.js +1 -1
  52. package/dist/components/collapsible.js +1 -1
  53. package/dist/components/combobox.js +5 -5
  54. package/dist/components/command.js +3 -3
  55. package/dist/components/concept-card.js +2 -2
  56. package/dist/components/concept-compare-rail.js +3 -3
  57. package/dist/components/concept-compare.d.ts +2 -1
  58. package/dist/components/concept-compare.js +5 -5
  59. package/dist/components/concept-convergence.js +4 -4
  60. package/dist/components/convergence.js +3 -3
  61. package/dist/components/coverflow.js +1 -1
  62. package/dist/components/currency-input.js +2 -2
  63. package/dist/components/date-input.js +2 -2
  64. package/dist/components/day-rail-chip.js +2 -2
  65. package/dist/components/description-list.js +1 -1
  66. package/dist/components/dialog.js +2 -2
  67. package/dist/components/doorway-tiles.d.ts +57 -0
  68. package/dist/components/doorway-tiles.js +86 -0
  69. package/dist/components/drawer.js +1 -1
  70. package/dist/components/drift-rail.js +1 -1
  71. package/dist/components/dropdown-menu.js +1 -1
  72. package/dist/components/empty-state.js +3 -3
  73. package/dist/components/event-card.js +4 -4
  74. package/dist/components/event-compact-row.js +4 -4
  75. package/dist/components/event-day-header.js +2 -2
  76. package/dist/components/event-day-separator.js +3 -3
  77. package/dist/components/event-detail-panel.js +4 -4
  78. package/dist/components/event-hub-hero.js +2 -2
  79. package/dist/components/event-index-row.js +4 -4
  80. package/dist/components/event-list-row-wide.js +5 -5
  81. package/dist/components/event-list-row.js +5 -5
  82. package/dist/components/event-poster-fallback.js +1 -1
  83. package/dist/components/event-types.js +1 -1
  84. package/dist/components/events-empty-state.js +1 -1
  85. package/dist/components/explainer-steps.js +1 -1
  86. package/dist/components/facet-group.js +2 -2
  87. package/dist/components/featured-rail-item.js +2 -2
  88. package/dist/components/field.js +2 -2
  89. package/dist/components/filter-category-row.js +3 -3
  90. package/dist/components/form.js +2 -2
  91. package/dist/components/glass-ground.js +2 -2
  92. package/dist/components/grade-atom.d.ts +3 -0
  93. package/dist/components/grade-atom.js +4 -0
  94. package/dist/components/haptic-button.js +2 -2
  95. package/dist/components/hour-band.js +4 -4
  96. package/dist/components/hour-group.js +4 -4
  97. package/dist/components/hub-surface.js +1 -1
  98. package/dist/components/hue-chip.js +1 -1
  99. package/dist/components/icon.js +1 -1
  100. package/dist/components/input-group.js +1 -1
  101. package/dist/components/input-otp.js +1 -1
  102. package/dist/components/input.js +2 -2
  103. package/dist/components/item.js +1 -1
  104. package/dist/components/kbd.js +1 -1
  105. package/dist/components/kitchen-dossier.d.ts +2 -1
  106. package/dist/components/kitchen-dossier.js +3 -3
  107. package/dist/components/label.js +2 -2
  108. package/dist/components/lazy-markdown.js +1 -1
  109. package/dist/components/link-button.js +2 -2
  110. package/dist/components/markdown-renderer.js +1 -1
  111. package/dist/components/menu-dead-end.d.ts +2 -1
  112. package/dist/components/menu-dead-end.js +1 -1
  113. package/dist/components/menu-family-block.d.ts +2 -1
  114. package/dist/components/menu-family-block.js +14 -8
  115. package/dist/components/menu-family-card.d.ts +2 -1
  116. package/dist/components/menu-family-card.js +1 -1
  117. package/dist/components/menu-field.js +1 -1
  118. package/dist/components/menu-filter-chips.d.ts +2 -1
  119. package/dist/components/menu-filter-chips.js +3 -3
  120. package/dist/components/menu-group-rows.d.ts +2 -1
  121. package/dist/components/menu-group-rows.js +2 -2
  122. package/dist/components/menu-hub-hero.js +1 -1
  123. package/dist/components/menu-index-header.d.ts +2 -1
  124. package/dist/components/menu-index-header.js +2 -2
  125. package/dist/components/menu-index-list.d.ts +2 -1
  126. package/dist/components/menu-index-list.js +4 -4
  127. package/dist/components/menu-intent-hero.d.ts +3 -2
  128. package/dist/components/menu-intent-hero.js +1 -1
  129. package/dist/components/menu-item.d.ts +2 -1
  130. package/dist/components/menu-item.js +4 -4
  131. package/dist/components/menu-kitchen-list.d.ts +2 -1
  132. package/dist/components/menu-kitchen-list.js +4 -4
  133. package/dist/components/menu-mocks.d.ts +16 -5
  134. package/dist/components/menu-mocks.js +23 -2
  135. package/dist/components/menu-types.d.ts +21 -34
  136. package/dist/components/motion-icon-actions.d.ts +27 -0
  137. package/dist/components/motion-icon-actions.js +336 -0
  138. package/dist/components/motion-icon-controls.js +3 -3
  139. package/dist/components/motion-icon-set.d.ts +13 -1
  140. package/dist/components/motion-icon-set.js +197 -6
  141. package/dist/components/motion-icon.d.ts +15 -1
  142. package/dist/components/motion-icon.js +2 -2
  143. package/dist/components/multi-select-combobox.js +7 -7
  144. package/dist/components/multi-select-menu.js +2 -2
  145. package/dist/components/native-select.js +1 -1
  146. package/dist/components/open-now-list.d.ts +2 -1
  147. package/dist/components/open-now-list.js +2 -2
  148. package/dist/components/pagination.js +2 -2
  149. package/dist/components/phone-frame.js +1 -1
  150. package/dist/components/photo-ground.js +1 -1
  151. package/dist/components/place-about-tab.d.ts +2 -1
  152. package/dist/components/place-about-tab.js +6 -6
  153. package/dist/components/place-card.d.ts +94 -12
  154. package/dist/components/place-card.js +203 -128
  155. package/dist/components/place-details-mobile.d.ts +2 -1
  156. package/dist/components/place-details-mobile.js +7 -7
  157. package/dist/components/place-schedule-week.d.ts +2 -1
  158. package/dist/components/place-schedule-week.js +3 -3
  159. package/dist/components/place-types.d.ts +3 -265
  160. package/dist/components/popover.js +2 -2
  161. package/dist/components/poster-stack.js +1 -1
  162. package/dist/components/poster-tape.js +1 -1
  163. package/dist/components/poster-wall.d.ts +22 -6
  164. package/dist/components/poster-wall.js +197 -12
  165. package/dist/components/progress.js +1 -1
  166. package/dist/components/qa-block.d.ts +2 -1
  167. package/dist/components/qa-block.js +1 -1
  168. package/dist/components/quiet-stretch.js +1 -1
  169. package/dist/components/radio-group.js +1 -1
  170. package/dist/components/rating.js +1 -1
  171. package/dist/components/scroll-area.js +1 -1
  172. package/dist/components/scroll-fade.js +2 -2
  173. package/dist/components/search-bar.js +1 -1
  174. package/dist/components/searchable-select.js +5 -5
  175. package/dist/components/section-header.js +2 -2
  176. package/dist/components/segmented-nav.d.ts +24 -4
  177. package/dist/components/segmented-nav.js +11 -2
  178. package/dist/components/select.js +1 -1
  179. package/dist/components/selection-bar.js +1 -1
  180. package/dist/components/separator.js +2 -2
  181. package/dist/components/sheet.js +1 -1
  182. package/dist/components/signature-chip.js +3 -3
  183. package/dist/components/skeleton-card.js +3 -3
  184. package/dist/components/skeleton.js +2 -2
  185. package/dist/components/slider.js +1 -1
  186. package/dist/components/sliding-panels.js +2 -2
  187. package/dist/components/snap-rail.js +2 -2
  188. package/dist/components/sonner.js +1 -1
  189. package/dist/components/sort-option-list.js +1 -1
  190. package/dist/components/spinner.js +1 -1
  191. package/dist/components/stat-banner.js +1 -1
  192. package/dist/components/stepper.js +1 -1
  193. package/dist/components/sticky-container.js +1 -1
  194. package/dist/components/story.js +1 -1
  195. package/dist/components/switch.js +1 -1
  196. package/dist/components/table.js +1 -1
  197. package/dist/components/tabs.js +2 -2
  198. package/dist/components/tag-group.js +2 -2
  199. package/dist/components/tag.js +2 -2
  200. package/dist/components/text.js +2 -2
  201. package/dist/components/textarea.js +1 -1
  202. package/dist/components/timeline-band.js +4 -4
  203. package/dist/components/timeline-playhead.js +4 -4
  204. package/dist/components/toggle-group.js +2 -2
  205. package/dist/components/toggle.js +2 -2
  206. package/dist/components/tooltip.js +1 -1
  207. package/dist/components/top-comparison.d.ts +2 -1
  208. package/dist/components/top-comparison.js +1 -1
  209. package/dist/components/top-cross-link.d.ts +2 -1
  210. package/dist/components/top-cross-link.js +1 -1
  211. package/dist/components/top-ranking-entry.d.ts +2 -1
  212. package/dist/components/top-ranking-entry.js +6 -6
  213. package/dist/components/top-ranking-hero.d.ts +2 -1
  214. package/dist/components/top-ranking-hero.js +1 -1
  215. package/dist/components/top-ranking-legend.js +1 -1
  216. package/dist/components/top-types.d.ts +3 -1
  217. package/dist/components/use-mobile.js +1 -1
  218. package/dist/components/venue-events-block.js +5 -5
  219. package/dist/components/venue-grade-dimensions.d.ts +2 -1
  220. package/dist/components/venue-grade-dimensions.js +1 -1
  221. package/dist/components/venue-quotes.d.ts +2 -1
  222. package/dist/components/venue-quotes.js +1 -1
  223. package/dist/components/venue-wall.d.ts +2 -1
  224. package/dist/components/venue-wall.js +1 -1
  225. package/dist/components/weekday-theme-banner.js +1 -1
  226. package/dist/components/weekend-panel.js +4 -4
  227. package/dist/hooks/use-drag-swipe.js +1 -1
  228. package/dist/hooks/use-haptic.js +1 -1
  229. package/dist/hooks/use-media-query.js +1 -1
  230. package/dist/hooks/use-mobile.js +1 -1
  231. package/dist/hooks/use-mounted-theme.js +1 -1
  232. package/dist/hooks/use-sticky.js +1 -1
  233. package/dist/lib/card-hover.js +2 -18
  234. package/dist/lib/grade.d.ts +54 -0
  235. package/dist/lib/grade.js +2 -0
  236. package/dist/lib/icon-depth.d.ts +35 -0
  237. package/dist/lib/icon-depth.js +2 -0
  238. package/dist/lib/icon-registry.js +1 -1
  239. package/dist/lib/motion.js +2 -2
  240. package/dist/lib/overlay-pill.d.ts +30 -0
  241. package/dist/lib/overlay-pill.js +2 -0
  242. package/dist/lib/utils.js +1 -1
  243. package/dist/place-types-BHdeMMiG.d.ts +317 -0
  244. package/package.json +1 -1
  245. package/src/components/colour-dictionary.stories.tsx +268 -82
  246. package/src/components/doorway-tiles.stories.tsx +83 -0
  247. package/src/components/doorway-tiles.test.tsx +51 -0
  248. package/src/components/doorway-tiles.tsx +225 -0
  249. package/src/components/grade-atom.stories.tsx +81 -0
  250. package/src/components/grade-atom.tsx +256 -0
  251. package/src/components/hue-chip.stories.tsx +2 -2
  252. package/src/components/menu-family-block.stories.tsx +29 -0
  253. package/src/components/menu-family-block.test.tsx +51 -0
  254. package/src/components/menu-family-block.tsx +20 -4
  255. package/src/components/menu-intent-hero.tsx +1 -1
  256. package/src/components/menu-mocks.ts +39 -3
  257. package/src/components/menu-types.ts +17 -33
  258. package/src/components/motion-icon-actions.test.tsx +115 -0
  259. package/src/components/motion-icon-actions.tsx +580 -0
  260. package/src/components/motion-icon-controls.test.tsx +1 -0
  261. package/src/components/motion-icon-controls.tsx +18 -13
  262. package/src/components/motion-icon-set.stories.tsx +62 -3
  263. package/src/components/motion-icon-set.tsx +349 -2
  264. package/src/components/motion-icon.test.tsx +180 -1
  265. package/src/components/motion-icon.tsx +97 -8
  266. package/src/components/place-card.stories.tsx +66 -76
  267. package/src/components/place-card.test.tsx +188 -100
  268. package/src/components/place-card.tsx +356 -148
  269. package/src/components/place-types.ts +17 -4
  270. package/src/components/poster-wall.stories.tsx +84 -0
  271. package/src/components/poster-wall.test.tsx +94 -3
  272. package/src/components/poster-wall.tsx +257 -9
  273. package/src/components/segmented-nav.stories.tsx +72 -1
  274. package/src/components/segmented-nav.test.tsx +96 -0
  275. package/src/components/segmented-nav.tsx +36 -4
  276. package/src/globals.css +26 -0
  277. package/src/lib/grade.test.ts +82 -0
  278. package/src/lib/grade.ts +76 -0
  279. package/src/lib/icon-depth.ts +35 -0
  280. package/src/lib/overlay-pill.ts +29 -0
  281. package/dist/components/menu-family-tiles.d.ts +0 -19
  282. package/dist/components/menu-family-tiles.js +0 -57
  283. package/src/components/menu-family-tiles.stories.tsx +0 -54
  284. package/src/components/menu-family-tiles.test.tsx +0 -30
  285. package/src/components/menu-family-tiles.tsx +0 -132
@@ -1,2 +1,2 @@
1
1
  export { useSticky } from '../chunk-EUHEIWHZ.js';
2
- import '../chunk-3GWWZKX7.js';
2
+ import '../chunk-MMUBH76A.js';
@@ -1,18 +1,2 @@
1
- import '../chunk-3GWWZKX7.js';
2
-
3
- // src/lib/card-hover.ts
4
- var HOVER_DURATION = "duration-[320ms]";
5
- var HOVER_EASE = "ease-[cubic-bezier(0.4,0,0.2,1)]";
6
- var HOVER_MOTION = `transition-transform ${HOVER_DURATION} ${HOVER_EASE} motion-reduce:transition-none will-change-transform`;
7
- var HOVER_SHADOW_MOTION = `transition-shadow ${HOVER_DURATION} ${HOVER_EASE}`;
8
- var HOVER_LIFT_GRID = "[@media(hover:hover)]:hover:-translate-y-1";
9
- var HOVER_LIFT_GRID_GROUP = "[@media(hover:hover)]:group-hover/card:-translate-y-1";
10
- var HOVER_LIFT_LIST = "[@media(hover:hover)]:hover:-translate-y-0.5";
11
- var HOVER_IMAGE_SCALE = "group-hover:scale-[1.05]";
12
- var HOVER_IMAGE_MOTION = `${HOVER_MOTION} ${HOVER_IMAGE_SCALE}`;
13
- var HOVER_IMAGE_SHADOW = "shadow-[var(--shadow-card-image)] [@media(hover:hover)]:group-hover:shadow-[var(--shadow-card-image-hover)]";
14
- var HOVER_IMAGE_SHADOW_INSET = "shadow-[var(--shadow-menu-cover-inset),var(--shadow-card-image)] [@media(hover:hover)]:group-hover:shadow-[var(--shadow-menu-cover-inset),var(--shadow-card-image-hover)]";
15
- var HOVER_IMAGE_WRAPPER = `${HOVER_SHADOW_MOTION} ${HOVER_IMAGE_SHADOW}`;
16
- var HOVER_IMAGE_WRAPPER_INSET = `${HOVER_SHADOW_MOTION} ${HOVER_IMAGE_SHADOW_INSET}`;
17
-
18
- export { HOVER_DURATION, HOVER_EASE, HOVER_IMAGE_MOTION, HOVER_IMAGE_SCALE, HOVER_IMAGE_SHADOW, HOVER_IMAGE_SHADOW_INSET, HOVER_IMAGE_WRAPPER, HOVER_IMAGE_WRAPPER_INSET, HOVER_LIFT_GRID, HOVER_LIFT_GRID_GROUP, HOVER_LIFT_LIST, HOVER_MOTION, HOVER_SHADOW_MOTION };
1
+ export { HOVER_DURATION, HOVER_EASE, HOVER_IMAGE_MOTION, HOVER_IMAGE_SCALE, HOVER_IMAGE_SHADOW, HOVER_IMAGE_SHADOW_INSET, HOVER_IMAGE_WRAPPER, HOVER_IMAGE_WRAPPER_INSET, HOVER_LIFT_GRID, HOVER_LIFT_GRID_GROUP, HOVER_LIFT_LIST, HOVER_MOTION, HOVER_SHADOW_MOTION } from '../chunk-XCB3F6SF.js';
2
+ import '../chunk-MMUBH76A.js';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Pure helpers for the ReviewsDigest `grade` (1–10 Romanian school scale,
3
+ * food-anchored). Shared by `<GradeAtom>` and any surface that demotes the
4
+ * Google star in favour of the grade.
5
+ */
6
+ /** Colour/quality band, derived from `grade.overall`. The label text comes
7
+ * from the caller's `GradeAtomLabels`; the band only drives the visual tone. */
8
+ type GradeBand = "exceptional" | "great" | "good" | "decent" | "weak";
9
+ /** Map a 1–10 overall score to its band. Boundaries are inclusive at the low end
10
+ * (9.0 → exceptional, 7.5 → great, 6.0 → good, 5.0 → decent, below 5 → weak). */
11
+ declare function resolveGradeBand(overall: number): GradeBand;
12
+ /** Format a grade for display: clamp to the 1–10 scale, keep one decimal of
13
+ * precision, and drop a trailing `.0` so whole grades read as "7" not "7.0". */
14
+ declare function formatGrade(overall: number): string;
15
+ /** The backend `show_number` is a display recommendation: when explicitly
16
+ * false, fall back to the soft state instead of the number. Unspecified → show. */
17
+ declare function shouldShowGradeNumber(grade: {
18
+ show_number?: boolean;
19
+ }): boolean;
20
+ /**
21
+ * Whether `<GradeAtom>` will render anything for this grade at this size — the
22
+ * predicate every caller must gate on before choosing the grade over its own
23
+ * Google-star fallback.
24
+ *
25
+ * `overall == null` has always meant "no grade, show the star". The `xs` rule
26
+ * is newer: at card size the right-hand slot is a 2–3 glyph METRIC slot, and
27
+ * the soft state is a two-word sentence ("Worth exploring" / "Merită
28
+ * explorat"). Rendered there it wrapped inside its own fixed-height pill and
29
+ * pushed the title into a hard truncation. The sentence still renders at `sm`+
30
+ * (drawer, hero) where there is room for it.
31
+ *
32
+ * Callers used to gate on `grade?.overall != null` directly, which is why this
33
+ * exists as a shared function: with the size rule added, that check no longer
34
+ * predicts whether the atom renders, and a caller using the old one lands on
35
+ * an empty slot instead of falling through to its star.
36
+ *
37
+ * Lives here rather than in `grade-atom.tsx` so SERVER components can call it —
38
+ * everything exported from a `"use client"` module is a client reference.
39
+ *
40
+ * A type predicate, so the true branch also narrows away the `undefined` that
41
+ * `place.reviews_digest?.grade` carries and the caller can pass it straight to
42
+ * `<GradeAtom grade={...}>`.
43
+ */
44
+ declare function showsGradeAtom<T extends {
45
+ overall?: number | null;
46
+ show_number?: boolean;
47
+ }>(grade: T | null | undefined, size: "xs" | "sm" | "md" | "lg"): grade is T;
48
+ /** Tone for a single 0–100 dimension score, driving the page dimension-bar
49
+ * colour: strong (≥75) = accent, adequate (50–74) = muted, low (<50) = amber
50
+ * (a soft "fair warning", never error-red). */
51
+ type DimensionTone = "strong" | "adequate" | "low";
52
+ declare function resolveDimensionTone(score: number): DimensionTone;
53
+
54
+ export { type DimensionTone, type GradeBand, formatGrade, resolveDimensionTone, resolveGradeBand, shouldShowGradeNumber, showsGradeAtom };
@@ -0,0 +1,2 @@
1
+ export { formatGrade, resolveDimensionTone, resolveGradeBand, shouldShowGradeNumber, showsGradeAtom } from '../chunk-I5V446BX.js';
2
+ import '../chunk-MMUBH76A.js';
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Layered drop-shadow filter that "raises" a flat icon off a tinted surface.
3
+ *
4
+ * Two stops stacked: a tight 1px close shadow welds the icon to the surface
5
+ * (so it doesn't float disconnected), then a wider 3px/8px lift gives it
6
+ * presence. The combo is what makes the homepage cuisine tiles read as
7
+ * embossed plaques instead of stickers — reuse it anywhere an icon sits on
8
+ * a warm gradient (entity-card photo fallbacks, etc).
9
+ *
10
+ * Designed for white / light icons on the warm `--gradient-primary` family.
11
+ * Don't apply to icons on light surfaces — the dark drop-shadow stops will
12
+ * read as muddy outlines instead of depth.
13
+ */
14
+ declare const RAISED_ICON_FILTER = "drop-shadow(0 1px 1px oklch(0 0 0 / 0.6)) drop-shadow(0 3px 8px oklch(0 0 0 / 0.4))";
15
+ /**
16
+ * The light-surface counterpart, for glyphs on the neutral placeholder panel
17
+ * (`from-muted to-border`) that entity-card photo fallbacks share.
18
+ *
19
+ * `RAISED_ICON_FILTER` is black and wide — correct under a white icon on the
20
+ * brown gradient, wrong everywhere else. On a near-white panel its 8px black
21
+ * stop pools under the glyph and reads as grime rather than lift.
22
+ *
23
+ * What fixes that is hue and spread, not just less shadow: this one is a deep
24
+ * brown (same 45° hue as `--shadow-card`) capped at a 4px lift. Halving the
25
+ * spread is what kills the smudge, which then buys enough headroom on alpha
26
+ * for the glyph to still read as raised rather than washed out — a warm
27
+ * shadow tolerates far more opacity than a black one before it looks dirty.
28
+ *
29
+ * Resolves through a token (`--icon-depth-neutral` in `globals.css`), so dark
30
+ * mode gets its own value — there the panel is already dark and a halo does
31
+ * nothing, so it collapses to one contact stop.
32
+ */
33
+ declare const NEUTRAL_ICON_FILTER = "var(--icon-depth-neutral)";
34
+
35
+ export { NEUTRAL_ICON_FILTER, RAISED_ICON_FILTER };
@@ -0,0 +1,2 @@
1
+ export { NEUTRAL_ICON_FILTER, RAISED_ICON_FILTER } from '../chunk-LQWGZIYA.js';
2
+ import '../chunk-MMUBH76A.js';
@@ -1,4 +1,4 @@
1
- import '../chunk-3GWWZKX7.js';
1
+ import '../chunk-MMUBH76A.js';
2
2
  import { Info, Flag, Phone, RefreshCw, Trash2, Plus, Check, Bookmark, Heart, Share2, Search, ArrowUpDown, SlidersHorizontal, ChevronDown, XCircle, X, ExternalLink, Navigation, ChevronRight, ChevronLeft, ArrowRight, ArrowLeft } from 'lucide-react';
3
3
 
4
4
  var iconFor = {
@@ -1,2 +1,2 @@
1
- export { archetype, contentSwapVariants, duration, ease, listRevealVariants, skeletonSwapVariants, springGentle, springSmooth, springSnappy, springSoft, stagger } from '../chunk-LEAYBICI.js';
2
- import '../chunk-3GWWZKX7.js';
1
+ export { archetype, contentSwapVariants, duration, ease, listRevealVariants, skeletonSwapVariants, springGentle, springSmooth, springSnappy, springSoft, stagger } from '../chunk-OIV7B44M.js';
2
+ import '../chunk-MMUBH76A.js';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ONE geometry for every pill that sits on a card image — places and events.
3
+ *
4
+ * These had drifted into four different sizes on the event card (hype at
5
+ * `min-h-8`, Free at `text-xs px-2.5 py-1`, concept and tags at `text-[10px]
6
+ * px-2 py-0.5`) and three more on the place card (Trending at `min-h-8`, the
7
+ * Closed pill at `text-xs py-0.5`, the open dot at `h-2`), so corners of the
8
+ * same card — and cards sitting in the same rail — read as unrelated systems.
9
+ *
10
+ * An explicit `h-6` rather than a padding-derived height is what actually
11
+ * guarantees they match: the hype pill contains a gauge glyph, Trending
12
+ * contains a flame, and the rest contain 12px icons, so equal padding would
13
+ * still produce unequal heights.
14
+ *
15
+ * 24px is deliberate over the 32px `heatPillVariants` `md`. The only argument
16
+ * for 32 was the tap target on the interactive Trending pill, and that pill
17
+ * already carries an `after:-inset-2` hit-area expander (~40px effective)
18
+ * which solves it independently of the visual size. 24px is also exactly the
19
+ * WCAG 2.5.8 (AA) minimum on its own, before the expander.
20
+ *
21
+ * Pair with `Badge` (`variant="overlay"` is the scrim: `bg-foreground/80
22
+ * text-background`) rather than hand-rolled spans, which is what let these
23
+ * drift in the first place. Only the radius is overridden — the `Badge`
24
+ * default is `rounded-lg` and pills on photography read better fully round.
25
+ */
26
+ declare const OVERLAY_PILL = "h-6 gap-1 rounded-full px-2 text-2xs font-semibold shadow-sm";
27
+ /** Icon size inside an `OVERLAY_PILL`. */
28
+ declare const OVERLAY_ICON = "h-3 w-3 shrink-0";
29
+
30
+ export { OVERLAY_ICON, OVERLAY_PILL };
@@ -0,0 +1,2 @@
1
+ export { OVERLAY_ICON, OVERLAY_PILL } from '../chunk-EZG2NELX.js';
2
+ import '../chunk-MMUBH76A.js';
package/dist/lib/utils.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export { cn } from '../chunk-FEK5XGZW.js';
2
- import '../chunk-3GWWZKX7.js';
2
+ import '../chunk-MMUBH76A.js';
@@ -0,0 +1,317 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { GradeBand } from './lib/grade.js';
3
+
4
+ type GradeAtomSize = "xs" | "sm" | "md" | "lg";
5
+ /** Labels passed to `<GradeAtom>`. All translation happens in the caller. */
6
+ type GradeAtomLabels = {
7
+ /** The `show_number=false` state, e.g. "Worth exploring". */
8
+ soft: string;
9
+ /** Band → descriptor shown beside the number from `sm` up, e.g. "Great". */
10
+ bands: Record<GradeBand, string>;
11
+ /** Accessible name for the pill, e.g. "Grade 8.2 out of 10". */
12
+ aria: (value: string) => string;
13
+ /** Title + aria suffix when `grade.capped`, e.g. "Capped for low confidence". */
14
+ capped: string;
15
+ };
16
+ type GradeAtomProps = {
17
+ grade: PlaceGrade;
18
+ labels: GradeAtomLabels;
19
+ /** xs = card chip · sm = chat/compact · md = drawer · lg = page hero. */
20
+ size?: GradeAtomSize;
21
+ /** Force-hide the descriptor even at sizes that would show it (tight rows). */
22
+ hideDescriptor?: boolean;
23
+ /** Rendered over a photo (e.g. the page hero). Switches to a frosted-dark
24
+ * shell with the band hue on the number + ring, so it stays legible and
25
+ * band-recognizable on any image. */
26
+ onPhoto?: boolean;
27
+ /**
28
+ * Adds a trailing `Info` glyph, for the one caller where the chip IS the
29
+ * disclosure trigger (the place hero, wrapped in a grade explainer).
30
+ *
31
+ * Off by default and it must stay that way: on cards this atom is a readout,
32
+ * and an affordance marker on something that doesn't open would be a lie. The
33
+ * glyph goes INSIDE the pill rather than beside it — outside, it would be a
34
+ * bare icon on unpredictable photo luminance, and it would read as a second
35
+ * control next to the chip instead of part of it.
36
+ */
37
+ showInfo?: boolean;
38
+ className?: string;
39
+ };
40
+ declare function GradeAtom({ grade, labels, size, hideDescriptor, onPhoto, showInfo, className, }: GradeAtomProps): react_jsx_runtime.JSX.Element | null;
41
+
42
+ /**
43
+ * Structural mirror of the openapi `Place` schema, decoupled from any one app's
44
+ * generated types. Both FE and admin map their domain shapes into this type
45
+ * before passing data to `<PlaceCard>` / `<PlaceAboutTab>`.
46
+ */
47
+ type PlacePreview = {
48
+ id: string;
49
+ slug: string;
50
+ name: string;
51
+ description?: string;
52
+ generative_summary?: string;
53
+ review_summary?: string;
54
+ open_now?: boolean;
55
+ rating?: {
56
+ rating: number;
57
+ count: number;
58
+ };
59
+ review_count?: number;
60
+ hours?: PlaceHourBlock[];
61
+ today_schedule?: PlaceHourBlock[];
62
+ schedule?: PlaceSchedule;
63
+ location?: {
64
+ address?: string;
65
+ geolocation?: {
66
+ lat: number | string;
67
+ lon: number | string;
68
+ };
69
+ distance?: {
70
+ meters?: number;
71
+ };
72
+ };
73
+ price_dishes?: PlacePriceRange;
74
+ price_drinks?: PlacePriceRange;
75
+ cuisines?: string[];
76
+ amenities?: string[];
77
+ payment_options?: string[];
78
+ accessibility_features?: string[];
79
+ parking_options?: string[];
80
+ landmarks?: Array<{
81
+ name: string;
82
+ distance_meters?: number;
83
+ }>;
84
+ areas?: Array<{
85
+ name: string;
86
+ }>;
87
+ busyness?: Array<{
88
+ hour: number;
89
+ score: number;
90
+ }>;
91
+ /**
92
+ * The review distillation. Drives every menu-hub surface that speaks for a
93
+ * venue — `<KitchenDossier>`, `<MenuKitchenList>`, `<OpenNowList>` —
94
+ * because the signature dish, the pull-quotes and the graded dimensions all
95
+ * live here rather than on the menu itself.
96
+ */
97
+ reviews_digest?: PlaceReviewsDigest;
98
+ type?: string;
99
+ business_status?: 'operational' | 'closed_temporarily' | 'closed_permanently';
100
+ phone?: string;
101
+ website_url?: string;
102
+ socials?: {
103
+ instagram_url?: string;
104
+ facebook_url?: string;
105
+ };
106
+ /**
107
+ * Pre-resolved thumbnail URL. Callers compute this themselves
108
+ * (FE: `https://cdn.bear.menu/places/${slug}-thumbnail.jpg`,
109
+ * admin: form's primary photo URL or blob URL).
110
+ */
111
+ thumbnail_url?: string;
112
+ /**
113
+ * The card's cover photo. What `<PlaceCard>` renders in its 4:3 slot; with
114
+ * the default plain `<img>` this must be a loadable URL, with an injected
115
+ * `imageComponent` it is whatever that component accepts (fe passes the
116
+ * bare storage key straight to `next/image`'s loader).
117
+ */
118
+ cover_url?: string;
119
+ };
120
+ type PlaceHourBlock = {
121
+ opens_at: number;
122
+ closes_at: number;
123
+ };
124
+ type WeekdayKey = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
125
+ type PlaceSchedule = Record<WeekdayKey, PlaceHourBlock[]>;
126
+ type PlacePriceRange = {
127
+ price_range_low?: number;
128
+ price_range_high?: number;
129
+ /** Median price across the place's menu, in the local currency. */
130
+ median_price?: number;
131
+ /** 1–4 price level, rendered as `$` glyphs on `<PlaceCard>`. 0 / absent = no signal. */
132
+ price_score?: number;
133
+ };
134
+ /**
135
+ * Menu items are priced per size; a single-size item still ships one entry.
136
+ *
137
+ * Defined here rather than in `menu-types.ts` because `PlaceMustTry` carries
138
+ * it, and `menu-types.ts` already imports from this file — keeping the
139
+ * definition here leaves that import one-directional. `menu-types.ts`
140
+ * re-exports it, so menu code never reaches into place types for it.
141
+ */
142
+ type MenuSizeAndPrice = {
143
+ /** Grams or millilitres. */
144
+ size: number;
145
+ price: number;
146
+ discounted_price?: number;
147
+ discount_percentage?: number;
148
+ };
149
+ /** A digest string with the reviews that back it. `review_ids.length` is the mention count. */
150
+ type CitedText = {
151
+ text: string;
152
+ review_ids?: string[];
153
+ };
154
+ /** A digest enum value with the reviews that back it. The value is a language-neutral code. */
155
+ type CitedValue = {
156
+ value: string;
157
+ review_ids?: string[];
158
+ };
159
+ /**
160
+ * One dish or drink the reviews single out.
161
+ *
162
+ * `mentions` and `score` come from the item census and are only served by the
163
+ * place DETAIL endpoint — a listing carries the item without them. Surfaces
164
+ * that need a count from a list fall back to `review_ids.length`, which is
165
+ * present in both. `strength`, `why` and `review_ids` are absent for census
166
+ * items the prose digest never mentioned, so none of them can be assumed.
167
+ */
168
+ type PlaceMustTry = {
169
+ name: string;
170
+ why?: string;
171
+ strength?: 'signature' | 'frequent' | 'occasional';
172
+ /** Deep-link slug. Present only when the item matched a live menu row. */
173
+ slug?: string;
174
+ sizes_and_prices?: MenuSizeAndPrice[];
175
+ review_ids?: string[];
176
+ /** 0–100 census sentiment. Detail endpoint only; 3+ mentions required. */
177
+ score?: number;
178
+ /** Censused review mentions of this item. Detail endpoint only. */
179
+ mentions?: number;
180
+ };
181
+ /**
182
+ * Per-dimension 0–100 review scores.
183
+ *
184
+ * A dimension the reviews never mention is ABSENT, not zero — so a surface
185
+ * drawing these must render what it is given rather than a fixed row of seven.
186
+ * Exactly one of `food` / `coffee_quality` / `drinks_quality` is scored per
187
+ * place: a coffee bar has no food score and a restaurant has no coffee one.
188
+ */
189
+ type PlaceGradeDimensions = {
190
+ food?: number;
191
+ coffee_quality?: number;
192
+ drinks_quality?: number;
193
+ value?: number;
194
+ service?: number;
195
+ cleanliness?: number;
196
+ ambiance?: number;
197
+ portion?: number;
198
+ consistency?: number;
199
+ };
200
+ type PlaceGrade = {
201
+ /** 1.0–10.0. */
202
+ overall?: number;
203
+ /**
204
+ * Backend recommendation to show the number at all. When false the caller
205
+ * should draw a "building confidence" state instead — the DS renders what it
206
+ * is told, it does not apply the rule.
207
+ */
208
+ show_number?: boolean;
209
+ /** Locale-resolved band label, e.g. "Foarte bun". Already translated upstream. */
210
+ descriptor?: string;
211
+ confidence?: 'low' | 'medium' | 'high';
212
+ capped?: boolean;
213
+ dimensions?: PlaceGradeDimensions;
214
+ };
215
+ type PlaceReviewsDigest = {
216
+ grade?: PlaceGrade;
217
+ grade_note?: string;
218
+ tagline?: CitedText;
219
+ verdict?: CitedText;
220
+ caveat?: CitedText;
221
+ /** 1–3 standout positives. The pull-quotes on `<KitchenDossier>`. */
222
+ highlights?: CitedText[];
223
+ must_try?: PlaceMustTry[];
224
+ /** Vibe codes (cozy, quiet, family_friendly, …). Localised by the caller. */
225
+ tags?: CitedValue[];
226
+ dietary?: CitedValue[];
227
+ /** small | moderate | generous */
228
+ portion_size?: CitedValue;
229
+ /** cheap | fair | mid_range | splurge */
230
+ value?: CitedValue;
231
+ /** quiet | moderate | loud */
232
+ noise_level?: CitedValue;
233
+ /** Text reviews behind the digest. */
234
+ review_count?: number;
235
+ };
236
+ /** Labels passed to `<PlaceCard>`. All translation happens in the caller. */
237
+ type PlaceCardLabels = {
238
+ /** The frosted pill on the photo when `open_now === false`. */
239
+ closed: string;
240
+ /** Accessible name of the whole card, e.g. "View details for Casa Gri". */
241
+ viewDetails: (name: string) => string;
242
+ /** Accessible name of the `$` price glyphs, e.g. "Price level 2 of 4". */
243
+ priceLevel: (level: number) => string;
244
+ grade: GradeAtomLabels;
245
+ };
246
+ /**
247
+ * Labels passed to `<PlaceAboutTab>`. All translation happens in the caller.
248
+ *
249
+ * Dynamic suffix maps (`amenityLabels`, etc.) translate API enum values like
250
+ * `wheelchair_accessible_entrance` into human strings. Missing keys fall back
251
+ * to the raw enum value (with underscores → spaces).
252
+ */
253
+ type PlaceAboutTabLabels = {
254
+ /** Section heading for the editorial prose block (generative summary + review summary + description). */
255
+ description: string;
256
+ contactAndLocation: string;
257
+ instagram: string;
258
+ facebook: string;
259
+ /** Section heading for the inline weekly schedule. */
260
+ todayHours: string;
261
+ /** Used by the inline schedule's closed-day line-through. */
262
+ statusClosed: string;
263
+ typicalBusyness: string;
264
+ cuisines: string;
265
+ amenities: string;
266
+ paymentOptions: string;
267
+ accessibility: string;
268
+ parking: string;
269
+ nearbyLandmarks: string;
270
+ /** Weekday key → translated day name, consumed by the inline `<PlaceScheduleWeek>`. */
271
+ scheduleDays: Record<WeekdayKey, string>;
272
+ /** Fallback shown by `<PlaceScheduleWeek>` when no schedule data is present. */
273
+ noHoursAvailable: string;
274
+ amenityLabels: Record<string, string>;
275
+ paymentLabels: Record<string, string>;
276
+ accessibilityLabels: Record<string, string>;
277
+ parkingLabels: Record<string, string>;
278
+ typeLabels: Record<string, string>;
279
+ statusLabels: Record<string, string>;
280
+ };
281
+ /** Discriminator for `<PlaceAboutTab>`'s `onLinkClick` callback. */
282
+ type PlaceLinkKind = 'phone' | 'website' | 'instagram' | 'facebook' | 'address';
283
+ /** Labels passed to `<PlaceScheduleWeek>`. */
284
+ type PlaceScheduleWeekLabels = {
285
+ days: Record<WeekdayKey, string>;
286
+ closed: string;
287
+ /** Shown when the `schedule` prop is missing or empty. */
288
+ noHoursAvailable: string;
289
+ };
290
+ /**
291
+ * Labels passed to `<PlaceDetailsMobile>`. Extends `PlaceAboutTabLabels` with
292
+ * the header/tab-strip strings unique to the mobile place-details surface.
293
+ */
294
+ type PlaceDetailsMobileLabels = PlaceAboutTabLabels & {
295
+ /** Tab strip — "About" is highlighted, the rest are visual placeholders. */
296
+ tabs: {
297
+ menu: string;
298
+ about: string;
299
+ reviews: string;
300
+ events: string;
301
+ };
302
+ /** Status badge over the hero image and the inline open/closed pill in the info row. */
303
+ statusBadge: {
304
+ openNow: string;
305
+ closed: string;
306
+ /** Inserted with surrounding " · " separators. e.g. "Closes at" */
307
+ closesAt: string;
308
+ opensAt: string;
309
+ opensTomorrow: string;
310
+ };
311
+ /** Review count formatter. Pass a translator that handles ICU pluralization. */
312
+ reviewCount: (count: number) => string;
313
+ /** "No image available" fallback shown when no thumbnail is set. */
314
+ noImageAvailable: string;
315
+ };
316
+
317
+ export { type CitedText as C, GradeAtom as G, type MenuSizeAndPrice as M, type PlacePreview as P, type WeekdayKey as W, type PlaceGradeDimensions as a, type PlaceAboutTabLabels as b, type PlaceLinkKind as c, type PlaceCardLabels as d, type PlaceDetailsMobileLabels as e, type PlaceSchedule as f, type PlaceScheduleWeekLabels as g, type GradeAtomLabels as h, type GradeAtomProps as i, type GradeAtomSize as j, type CitedValue as k, type PlaceGrade as l, type PlaceHourBlock as m, type PlaceMustTry as n, type PlacePriceRange as o, type PlaceReviewsDigest as p };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bearmenu/ui",
3
- "version": "0.8.13",
3
+ "version": "0.8.14",
4
4
  "description": "BearMenu design system — shared UI tokens, primitives, and components",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {