@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
@@ -1,5 +1,5 @@
1
1
  import { Text } from '../chunk-ZLMRVBD7.js';
2
- import { Badge } from '../chunk-P43B3ONY.js';
2
+ import { Badge } from '../chunk-5XREWOBB.js';
3
3
  import '../chunk-FEK5XGZW.js';
4
4
  import '../chunk-MMUBH76A.js';
5
5
  import { ChevronRight } from 'lucide-react';
@@ -1,3 +1,3 @@
1
- export { HueChip, hueTint } from '../chunk-CLLY6XB3.js';
1
+ export { HueChip, hueTint } from '../chunk-6VOWT4YR.js';
2
2
  import '../chunk-FEK5XGZW.js';
3
3
  import '../chunk-MMUBH76A.js';
@@ -3,12 +3,12 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const itemVariants: (props?: ({
6
- variant?: "default" | "muted" | "outline" | null | undefined;
6
+ variant?: "default" | "outline" | "muted" | null | undefined;
7
7
  size?: "default" | "sm" | "lg" | null | undefined;
8
8
  interactive?: boolean | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare const Item: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
11
- variant?: "default" | "muted" | "outline" | null | undefined;
11
+ variant?: "default" | "outline" | "muted" | null | undefined;
12
12
  size?: "default" | "sm" | "lg" | null | undefined;
13
13
  interactive?: boolean | null | undefined;
14
14
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
@@ -20,7 +20,10 @@ var itemVariants = cva(
20
20
  lg: "px-5 py-4"
21
21
  },
22
22
  interactive: {
23
- true: "cursor-pointer hover:bg-accent hover:text-accent-foreground active:scale-[0.99]",
23
+ // The surface tint a hover is, not the brand fill: `bg-accent` here is
24
+ // the brown, and a row that inverts under the cursor loses its muted
25
+ // description. Same step the buttons take (`--accent-subtle`).
26
+ true: "cursor-pointer hover:bg-accent-subtle hover:border-accent/40 active:bg-muted active:scale-[0.99]",
24
27
  false: ""
25
28
  }
26
29
  },
@@ -3,7 +3,7 @@ import { VenueQuotes } from '../chunk-43RC7MHY.js';
3
3
  import { StoryProvider, StorySegments, StoryPanel } from '../chunk-F6FMZJDG.js';
4
4
  import { GlassGround } from '../chunk-ICOU5QHT.js';
5
5
  import { Separator } from '../chunk-NWZGSLPU.js';
6
- import { PhotoGround, PHOTO_GROUND } from '../chunk-CNJQUHCU.js';
6
+ import { PhotoGround, PHOTO_GROUND } from '../chunk-SWD6CJ35.js';
7
7
  import { cn } from '../chunk-FEK5XGZW.js';
8
8
  import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
9
9
  import { MessageSquareQuote, Star } from 'lucide-react';
@@ -1,4 +1,4 @@
1
- import { Button } from '../chunk-36KEHCET.js';
1
+ import { Button } from '../chunk-5LTILG3L.js';
2
2
  import '../chunk-RIH2IS7X.js';
3
3
  import '../chunk-5YNIQ2BL.js';
4
4
  import '../chunk-FEK5XGZW.js';
@@ -85,10 +85,17 @@ type MenuFamilyBlockProps = {
85
85
  hue?: string;
86
86
  /** Finished CSS gradient — the family's colour over the mosaic. */
87
87
  gradient?: string;
88
+ /**
89
+ * `wide` (default): the phone card below `lg`, the two-column card — photo
90
+ * third, rows beside it — from `lg`. `compact`: the phone card at every
91
+ * width, for a rail on a desktop page where the two-column card is too much
92
+ * to scan across (the browse page's concept rail).
93
+ */
94
+ variant?: "wide" | "compact";
88
95
  linkComponent?: MenuLinkComponent;
89
96
  className?: string;
90
97
  };
91
- declare function MenuFamilyBlock({ family, labels, formatCount, hue, gradient, linkComponent: LinkComponent, className, }: MenuFamilyBlockProps): react_jsx_runtime.JSX.Element;
98
+ declare function MenuFamilyBlock({ family, labels, formatCount, hue, gradient, variant, linkComponent: LinkComponent, className, }: MenuFamilyBlockProps): react_jsx_runtime.JSX.Element;
92
99
  /**
93
100
  * The block's own loading state, at the block's footprint.
94
101
  *
@@ -1,9 +1,9 @@
1
- import { MenuKitchenList } from '../chunk-SXQZ7DLH.js';
2
- import { HueChip } from '../chunk-CLLY6XB3.js';
1
+ import { MenuKitchenList } from '../chunk-QY66ME5B.js';
2
+ import { HueChip } from '../chunk-6VOWT4YR.js';
3
3
  import { Separator } from '../chunk-NWZGSLPU.js';
4
- import { PhotoGround, PHOTO_GROUND } from '../chunk-CNJQUHCU.js';
4
+ import { PhotoGround, PHOTO_GROUND } from '../chunk-SWD6CJ35.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';
@@ -16,8 +16,8 @@ function DefaultLink(_a) {
16
16
  return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
17
17
  }
18
18
  var GROUND = PHOTO_GROUND;
19
- var INK = "bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0.12)_0%,oklch(0.16_0.012_55_/_0.55)_38%,oklch(0.16_0.012_55_/_0.92)_62%,oklch(0.16_0.012_55_/_0.96)_100%)] lg:bg-[linear-gradient(to_right,oklch(0.16_0.012_55_/_0.38)_0%,oklch(0.16_0.012_55_/_0.6)_30%,oklch(0.16_0.012_55_/_0.92)_46%,oklch(0.16_0.012_55_/_0.96)_100%)]";
20
- var PAPER = "lg:bg-[oklch(0.21_0.012_55)]";
19
+ var INK_PHONE = "bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0.12)_0%,oklch(0.16_0.012_55_/_0.55)_38%,oklch(0.16_0.012_55_/_0.92)_62%,oklch(0.16_0.012_55_/_0.96)_100%)]";
20
+ var INK_WIDE = "lg:bg-[linear-gradient(to_right,oklch(0.16_0.012_55_/_0.32)_0%,oklch(0.16_0.012_55_/_0.62)_34%,oklch(0.16_0.012_55_/_0.9)_52%,oklch(0.16_0.012_55_/_0.96)_100%)]";
21
21
  var TEXT_SCRIM = (
22
22
  /* `isolate` + `before:-z-10`: a positioned pseudo-element paints ABOVE the
23
23
  column's in-flow text unless the column is its own stacking context and
@@ -31,10 +31,12 @@ function MenuFamilyBlock({
31
31
  formatCount = String,
32
32
  hue,
33
33
  gradient,
34
+ variant = "wide",
34
35
  linkComponent: LinkComponent = DefaultLink,
35
36
  className
36
37
  }) {
37
38
  var _a, _b, _c, _d, _e, _f;
39
+ const wide = variant === "wide";
38
40
  const [photo] = (_a = family.photoUrls) != null ? _a : [];
39
41
  const venues = (_b = family.venues) != null ? _b : [];
40
42
  const overflow = Math.max(family.venueCount - venues.length, 0);
@@ -46,77 +48,108 @@ function MenuFamilyBlock({
46
48
  className: cn(
47
49
  /* `isolate` confines the blend and the backdrop-filter to this card.
48
50
  `dark` scopes every token inside to its dark-theme value. */
49
- "dark relative isolate overflow-hidden rounded-[14px] text-foreground",
51
+ /* A flex column, so a `h-full` card in a rail fills its row: siblings
52
+ with two rows and with three end on the same baseline. */
53
+ "dark relative isolate flex flex-col overflow-hidden rounded-[14px] text-foreground",
50
54
  GROUND,
51
55
  className
52
56
  ),
53
57
  children: [
54
58
  /* @__PURE__ */ jsx(PhotoGround, { photos: [photo], initials: initial, mode: "stack", gradient }),
55
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute inset-0", INK) }),
56
- /* @__PURE__ */ jsxs("div", { className: "relative grid grid-cols-1 lg:grid-cols-[34%_1fr]", children: [
57
- /* @__PURE__ */ jsxs(
58
- "div",
59
- {
60
- className: cn(
61
- "relative flex min-h-[220px] flex-col justify-end p-3.5 lg:min-h-[320px] lg:p-5",
62
- TEXT_SCRIM
59
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute inset-0", INK_PHONE, wide && INK_WIDE) }),
60
+ /* @__PURE__ */ jsxs(
61
+ "div",
62
+ {
63
+ className: cn(
64
+ "relative grid flex-1 grid-cols-1 grid-rows-[auto_1fr]",
65
+ wide && "lg:grid-cols-[34%_1fr] lg:grid-rows-1"
66
+ ),
67
+ children: [
68
+ /* @__PURE__ */ jsxs(
69
+ "div",
70
+ {
71
+ className: cn(
72
+ "relative flex min-h-[220px] flex-col justify-end p-3.5",
73
+ wide && "lg:min-h-[320px] lg:p-5",
74
+ TEXT_SCRIM
75
+ ),
76
+ children: [
77
+ pill && /* @__PURE__ */ jsx(
78
+ "span",
79
+ {
80
+ className: cn(
81
+ "absolute right-3.5 top-3.5 rounded-full bg-[oklch(0.16_0.012_55_/_0.78)] px-2.5 py-1 text-[11px] font-semibold text-white",
82
+ wide && "lg:static lg:mb-3 lg:self-start"
83
+ ),
84
+ children: pill
85
+ }
86
+ ),
87
+ family.kicker && /* @__PURE__ */ jsx("span", { className: "mb-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-white/70", children: family.kicker }),
88
+ /* @__PURE__ */ jsx(
89
+ "h3",
90
+ {
91
+ className: cn(
92
+ "text-balance font-serif text-[26px] font-semibold leading-tight tracking-[-0.02em] text-white",
93
+ wide && "lg:text-[30px]"
94
+ ),
95
+ children: family.name
96
+ }
97
+ ),
98
+ /* @__PURE__ */ jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-2.5 gap-y-1 text-[13px] font-medium tabular-nums text-white/70", children: [
99
+ labels.venueUnit(family.venueCount),
100
+ (_f = family.facts) == null ? void 0 : _f.map((fact) => /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2.5", children: [
101
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-white/40", children: "\xB7" }),
102
+ fact
103
+ ] }, fact)),
104
+ family.priceBandLabel && /* @__PURE__ */ jsxs(
105
+ "span",
106
+ {
107
+ className: "inline-flex items-center gap-1",
108
+ "aria-label": `${labels.priceBand}: ${family.priceBandLabel}`,
109
+ children: [
110
+ /* @__PURE__ */ jsx(Wallet, { className: "h-3.5 w-3.5 shrink-0 text-white/60", "aria-hidden": true }),
111
+ family.priceBandLabel
112
+ ]
113
+ }
114
+ )
115
+ ] }),
116
+ /* @__PURE__ */ jsx(
117
+ LinkComponent,
118
+ {
119
+ href: family.href,
120
+ "aria-label": labels.browse,
121
+ className: cn(buttonVariants({ variant: "ink", size: "pill" }), "mt-3.5 w-max max-w-full"),
122
+ children: labels.browseShort && wide ? /* @__PURE__ */ jsxs(Fragment, { children: [
123
+ /* @__PURE__ */ jsx("span", { className: "lg:hidden", children: labels.browse }),
124
+ /* @__PURE__ */ jsx("span", { className: "hidden lg:inline", children: labels.browseShort })
125
+ ] }) : labels.browse
126
+ }
127
+ )
128
+ ]
129
+ }
63
130
  ),
64
- children: [
65
- pill && /* @__PURE__ */ jsx("span", { className: "absolute right-3.5 top-3.5 rounded-full bg-[oklch(0.16_0.012_55_/_0.78)] px-2.5 py-1 text-[11px] font-semibold text-white lg:static lg:mb-3 lg:self-start", children: pill }),
66
- family.kicker && /* @__PURE__ */ jsx("span", { className: "mb-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-white/70", children: family.kicker }),
67
- /* @__PURE__ */ jsx("h3", { className: "text-balance font-serif text-[26px] font-semibold leading-tight tracking-[-0.02em] text-white lg:text-[30px]", children: family.name }),
68
- /* @__PURE__ */ jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-2.5 gap-y-1 text-[13px] font-medium tabular-nums text-white/70", children: [
69
- labels.venueUnit(family.venueCount),
70
- (_f = family.facts) == null ? void 0 : _f.map((fact) => /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2.5", children: [
71
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-white/40", children: "\xB7" }),
72
- fact
73
- ] }, fact)),
74
- family.priceBandLabel && /* @__PURE__ */ jsxs(
75
- "span",
131
+ /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-col px-3.5 pb-3.5", wide && "lg:p-5"), children: [
132
+ family.chips && family.chips.length > 0 && /* @__PURE__ */ jsx("ul", { className: cn("flex flex-wrap items-center gap-1.5", wide && "lg:justify-end"), children: family.chips.map((chip) => (
133
+ /* Label only. The counts are VENUES beside a dish group's name,
134
+ which every reader takes for dishes. */
135
+ /* @__PURE__ */ jsx(HueChip, { as: "li", hue, children: chip.label }, chip.slug)
136
+ )) }),
137
+ venues.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
138
+ /* @__PURE__ */ jsx(Separator, { className: "my-3 via-white/15" }),
139
+ /* @__PURE__ */ jsx(
140
+ MenuKitchenList,
76
141
  {
77
- className: "inline-flex items-center gap-1",
78
- "aria-label": `${labels.priceBand}: ${family.priceBandLabel}`,
79
- children: [
80
- /* @__PURE__ */ jsx(Wallet, { className: "h-3.5 w-3.5 shrink-0 text-white/60", "aria-hidden": true }),
81
- family.priceBandLabel
82
- ]
142
+ kitchens: venues,
143
+ labels: labels.kitchens,
144
+ layout: wide ? "stacked" : "phone",
145
+ linkComponent: LinkComponent
83
146
  }
84
147
  )
85
- ] }),
86
- /* @__PURE__ */ jsx(
87
- LinkComponent,
88
- {
89
- href: family.href,
90
- "aria-label": labels.browse,
91
- className: cn(buttonVariants({ variant: "ink", size: "pill" }), "mt-3.5 w-max max-w-full"),
92
- children: labels.browseShort ? /* @__PURE__ */ jsxs(Fragment, { children: [
93
- /* @__PURE__ */ jsx("span", { className: "lg:hidden", children: labels.browse }),
94
- /* @__PURE__ */ jsx("span", { className: "hidden lg:inline", children: labels.browseShort })
95
- ] }) : labels.browse
96
- }
97
- )
98
- ]
99
- }
100
- ),
101
- /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-col px-3.5 pb-3.5 lg:p-5", PAPER), children: [
102
- family.chips && family.chips.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap items-center gap-1.5 lg:justify-end", children: family.chips.map((chip) => (
103
- /* Label only. The counts are VENUES beside a dish group's name,
104
- which every reader takes for dishes. */
105
- /* @__PURE__ */ jsx(HueChip, { as: "li", hue, children: chip.label }, chip.slug)
106
- )) }),
107
- venues.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
108
- /* @__PURE__ */ jsx(Separator, { className: "my-3 via-white/15" }),
109
- /* @__PURE__ */ jsx(
110
- MenuKitchenList,
111
- {
112
- kitchens: venues,
113
- labels: labels.kitchens,
114
- linkComponent: LinkComponent
115
- }
116
- )
117
- ] })
118
- ] })
119
- ] })
148
+ ] })
149
+ ] })
150
+ ]
151
+ }
152
+ )
120
153
  ]
121
154
  }
122
155
  );
@@ -1,5 +1,5 @@
1
- import { HueChip } from '../chunk-CLLY6XB3.js';
2
- import { PhotoGround, PHOTO_GROUND } from '../chunk-CNJQUHCU.js';
1
+ import { HueChip } from '../chunk-6VOWT4YR.js';
2
+ import { PhotoGround, PHOTO_GROUND } from '../chunk-SWD6CJ35.js';
3
3
  import { cn } from '../chunk-FEK5XGZW.js';
4
4
  import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
5
5
  import { Wallet } from 'lucide-react';
@@ -58,11 +58,18 @@ type MenuFilterChipsProps = {
58
58
  onMorePointerDown?: () => void;
59
59
  /** Locale-aware integer formatter for the counts. Defaults to `String`. */
60
60
  formatCount?: (value: number) => string;
61
+ /**
62
+ * `sm` (36px) is the row under a page header. `lg` (44px) is for a row
63
+ * inside a sticky bar, where the chips are the only thing the thumb can
64
+ * reach and 36px sits under the target floor.
65
+ */
66
+ chipSize?: MenuFilterChipSize;
61
67
  /** Accessible name for the row. */
62
68
  ariaLabel?: string;
63
69
  className?: string;
64
70
  };
65
- declare function MenuFilterChips({ chips, onToggle, unitLabel, onMore, moreLabel, moreIcon, onMorePointerDown, formatCount, ariaLabel, className, }: MenuFilterChipsProps): react_jsx_runtime.JSX.Element;
71
+ type MenuFilterChipSize = "sm" | "lg";
72
+ declare function MenuFilterChips({ chips, onToggle, unitLabel, onMore, moreLabel, moreIcon, onMorePointerDown, formatCount, chipSize, ariaLabel, className, }: MenuFilterChipsProps): react_jsx_runtime.JSX.Element;
66
73
  /**
67
74
  * MenuFilterSummary — what the active filters did, and the way out.
68
75
  *
@@ -80,8 +87,10 @@ type MenuFilterSummaryProps = {
80
87
  className?: string;
81
88
  };
82
89
  declare function MenuFilterSummary({ summary, clearLabel, onClear, className, }: MenuFilterSummaryProps): react_jsx_runtime.JSX.Element;
83
- declare function MenuFilterChipsSkeleton({ className }: {
90
+ declare function MenuFilterChipsSkeleton({ className, chipSize, }: {
84
91
  className?: string;
92
+ /** Match the row it stands in for, so the chips do not jump 8px on load. */
93
+ chipSize?: MenuFilterChipSize;
85
94
  }): react_jsx_runtime.JSX.Element;
86
95
 
87
- export { MenuFilterChips, type MenuFilterChipsProps, MenuFilterChipsSkeleton, MenuFilterSummary, type MenuFilterSummaryProps };
96
+ export { type MenuFilterChipSize, MenuFilterChips, type MenuFilterChipsProps, MenuFilterChipsSkeleton, MenuFilterSummary, type MenuFilterSummaryProps };
@@ -14,6 +14,7 @@ function MenuFilterChips({
14
14
  moreIcon,
15
15
  onMorePointerDown,
16
16
  formatCount = String,
17
+ chipSize = "sm",
17
18
  ariaLabel,
18
19
  className
19
20
  }) {
@@ -30,6 +31,7 @@ function MenuFilterChips({
30
31
  Chip,
31
32
  {
32
33
  chip,
34
+ size: chipSize,
33
35
  onToggle: () => onToggle(chip.key),
34
36
  formatCount
35
37
  },
@@ -46,7 +48,11 @@ function MenuFilterChips({
46
48
  onPointerDown: onMorePointerDown,
47
49
  "aria-label": moreLabel,
48
50
  "aria-haspopup": "dialog",
49
- className: "inline-flex size-10 shrink-0 items-center justify-center rounded-full border border-border text-accent transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none lg:hidden",
51
+ className: cn(
52
+ "inline-flex shrink-0 items-center justify-center rounded-full border border-border text-accent transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none lg:hidden",
53
+ // The one control that never scrolls keeps the chips' height.
54
+ chipSize === "lg" ? "size-11" : "size-10"
55
+ ),
50
56
  children: moreIcon
51
57
  }
52
58
  ),
@@ -67,6 +73,7 @@ function MenuFilterChips({
67
73
  }
68
74
  function Chip({
69
75
  chip,
76
+ size,
70
77
  onToggle,
71
78
  formatCount
72
79
  }) {
@@ -77,7 +84,8 @@ function Chip({
77
84
  onClick: onToggle,
78
85
  "aria-pressed": chip.active,
79
86
  className: cn(
80
- "inline-flex h-9 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-4 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none",
87
+ "inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-4 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none",
88
+ size === "lg" ? "h-11" : "h-9",
81
89
  chip.active ? "border-accent font-semibold text-accent shadow-[0_1px_2px_oklch(0.51_0.095_45_/_0.08)]" : "border-border bg-card text-foreground hover:border-accent/40",
82
90
  // Dimmed, never disabled — pressing it is how the reader finds out
83
91
  // which active filter is in the way.
@@ -112,10 +120,20 @@ function MenuFilterSummary({
112
120
  ] });
113
121
  }
114
122
  var CHIP_WIDTHS = [128, 104, 96, 148, 112, 88];
115
- function MenuFilterChipsSkeleton({ className }) {
123
+ function MenuFilterChipsSkeleton({
124
+ className,
125
+ chipSize = "sm"
126
+ }) {
116
127
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 overflow-hidden", className), "aria-hidden": true, children: [
117
128
  /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-[92px] shrink-0" }),
118
- CHIP_WIDTHS.map((width, index) => /* @__PURE__ */ jsx(Skeleton, { className: "h-9 shrink-0 rounded-full", style: { width } }, index))
129
+ CHIP_WIDTHS.map((width, index) => /* @__PURE__ */ jsx(
130
+ Skeleton,
131
+ {
132
+ className: cn("shrink-0 rounded-full", chipSize === "lg" ? "h-11" : "h-9"),
133
+ style: { width }
134
+ },
135
+ index
136
+ ))
119
137
  ] });
120
138
  }
121
139
 
@@ -58,8 +58,14 @@ type MenuHubHeroProps = {
58
58
  * a 1440px hero.
59
59
  */
60
60
  tileUrls?: string[];
61
+ /**
62
+ * The element the headline renders as. `h1` by default; a page that
63
+ * already owns its `<h1>` (an sr-only SEO heading, as on `/menu`) passes
64
+ * `h2` so the document has one h1, not two.
65
+ */
66
+ headingLevel?: "h1" | "h2";
61
67
  className?: string;
62
68
  };
63
- declare function MenuHubHero({ kicker, kickerIcon, headline, body, figures, proof, proofIcon, action, backgroundUrl, tileUrls, className, }: MenuHubHeroProps): react_jsx_runtime.JSX.Element;
69
+ declare function MenuHubHero({ kicker, kickerIcon, headline, body, figures, proof, proofIcon, action, backgroundUrl, tileUrls, headingLevel: Heading, className, }: MenuHubHeroProps): react_jsx_runtime.JSX.Element;
64
70
 
65
71
  export { MenuHubHero, type MenuHubHeroFigure, type MenuHubHeroProps };
@@ -15,6 +15,7 @@ function MenuHubHero({
15
15
  action,
16
16
  backgroundUrl,
17
17
  tileUrls,
18
+ headingLevel: Heading = "h1",
18
19
  className
19
20
  }) {
20
21
  return /* @__PURE__ */ jsxs(
@@ -85,7 +86,7 @@ function MenuHubHero({
85
86
  kickerIcon,
86
87
  kicker
87
88
  ] }),
88
- /* @__PURE__ */ jsx("h1", { className: "max-w-[640px] font-serif text-[28px] font-semibold leading-[1.06] tracking-[-0.025em] lg:text-[50px] lg:leading-[1.04]", children: headline }),
89
+ /* @__PURE__ */ jsx(Heading, { className: "max-w-[640px] font-serif text-[28px] font-semibold leading-[1.06] tracking-[-0.025em] lg:text-[50px] lg:leading-[1.04]", children: headline }),
89
90
  body && /* @__PURE__ */ jsx("p", { className: "hidden max-w-[540px] text-sm leading-[1.6] opacity-[0.84] lg:block lg:text-[15.5px]", children: body }),
90
91
  figures && figures.length > 0 && // One row of four on the phone. It was two by two, which was the
91
92
  // taller half of a 500px hero; at 20px the widest figure ("19,090")
@@ -1,6 +1,6 @@
1
1
  import { Separator } from '../chunk-NWZGSLPU.js';
2
2
  import { Skeleton } from '../chunk-XBBEX4SF.js';
3
- import { Button } from '../chunk-36KEHCET.js';
3
+ import { Button } from '../chunk-5LTILG3L.js';
4
4
  import '../chunk-RIH2IS7X.js';
5
5
  import '../chunk-5YNIQ2BL.js';
6
6
  import { cn } from '../chunk-FEK5XGZW.js';
@@ -1,5 +1,5 @@
1
- export { MentionSignal, MenuItem } from '../chunk-T6S2ZBV6.js';
2
- import '../chunk-S33K4RC5.js';
3
- import '../chunk-P43B3ONY.js';
1
+ export { MentionSignal, MenuItem } from '../chunk-SDWN6L4O.js';
2
+ import '../chunk-BKKQ7GCZ.js';
3
+ import '../chunk-5XREWOBB.js';
4
4
  import '../chunk-FEK5XGZW.js';
5
5
  import '../chunk-MMUBH76A.js';
@@ -54,6 +54,17 @@ type MenuKitchenListLabels = {
54
54
  /** Reveals the next page of rows, e.g. "Show 10 more". */
55
55
  showMore?: string;
56
56
  };
57
+ /**
58
+ * `wide` (default): the intent page's full-width list — from `lg` the venue
59
+ * takes a fixed 226px column and the dish stands beside it in a column of its
60
+ * own. `stacked`: the list sits in a narrow column (a concept card's row
61
+ * half), so the venue keeps the row and the dish takes a SECOND LINE under it
62
+ * from `lg`; in a half-width card the dish column had ~100px and its kicker,
63
+ * name and meta wrapped into a stack of single words. `phone`: the phone row
64
+ * at every width — no dish line, the venue and its price only — for a card
65
+ * that keeps its phone form on a desktop rail.
66
+ */
67
+ type MenuKitchenListLayout = "wide" | "stacked" | "phone";
57
68
  type MenuKitchenListProps = {
58
69
  kitchens: MenuKitchenPreview[];
59
70
  labels: MenuKitchenListLabels;
@@ -62,10 +73,11 @@ type MenuKitchenListProps = {
62
73
  * navigates for the eleventh — the list is the page.
63
74
  */
64
75
  onShowMore?: () => void;
76
+ layout?: MenuKitchenListLayout;
65
77
  linkComponent?: MenuLinkComponent;
66
78
  className?: string;
67
79
  };
68
- declare function MenuKitchenList({ kitchens, labels, onShowMore, linkComponent, className, }: MenuKitchenListProps): react_jsx_runtime.JSX.Element;
80
+ declare function MenuKitchenList({ kitchens, labels, onShowMore, layout, linkComponent, className, }: MenuKitchenListProps): react_jsx_runtime.JSX.Element;
69
81
  /**
70
82
  * The list's own loading state, at the row's own footprint.
71
83
  *
@@ -80,4 +92,4 @@ declare function MenuKitchenListSkeleton({ rows, className, }: {
80
92
  className?: string;
81
93
  }): react_jsx_runtime.JSX.Element;
82
94
 
83
- export { MenuKitchenList, type MenuKitchenListLabels, type MenuKitchenListLinkProps, type MenuKitchenListProps, MenuKitchenListSkeleton };
95
+ export { MenuKitchenList, type MenuKitchenListLabels, type MenuKitchenListLayout, type MenuKitchenListLinkProps, type MenuKitchenListProps, MenuKitchenListSkeleton };
@@ -1,4 +1,4 @@
1
- export { MenuKitchenList, MenuKitchenListSkeleton } from '../chunk-SXQZ7DLH.js';
1
+ export { MenuKitchenList, MenuKitchenListSkeleton } from '../chunk-QY66ME5B.js';
2
2
  import '../chunk-NWZGSLPU.js';
3
3
  import '../chunk-XBBEX4SF.js';
4
4
  import '../chunk-FEK5XGZW.js';
@@ -2,10 +2,10 @@ import { Popover, PopoverTrigger, PopoverContent } from '../chunk-2ADCZXZJ.js';
2
2
  import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../chunk-MCOHLWRS.js';
3
3
  import '../chunk-PDTPO6NG.js';
4
4
  import { Checkbox } from '../chunk-NMEVJT5Q.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
- import { Badge } from '../chunk-P43B3ONY.js';
8
+ import { Badge } from '../chunk-5XREWOBB.js';
9
9
  import { cn } from '../chunk-FEK5XGZW.js';
10
10
  import '../chunk-MMUBH76A.js';
11
11
  import * as React from 'react';
@@ -1,4 +1,4 @@
1
- import { buttonVariants } from '../chunk-36KEHCET.js';
1
+ import { buttonVariants } from '../chunk-5LTILG3L.js';
2
2
  import '../chunk-RIH2IS7X.js';
3
3
  import '../chunk-5YNIQ2BL.js';
4
4
  import { cn } from '../chunk-FEK5XGZW.js';
@@ -36,6 +36,12 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
36
36
  */
37
37
  /** The ground under the photography. Fixed, and deliberately not a token. */
38
38
  declare const PHOTO_GROUND = "bg-[oklch(0.21_0.012_55)]";
39
+ /**
40
+ * The shadow a glyph wears when it stands on `PHOTO_GROUND` in a photograph's
41
+ * place — the card family's fallback treatment: a ground and a lifted glyph,
42
+ * never a bare icon on a flat fill. Same literal family as the ground.
43
+ */
44
+ declare const PHOTO_GLYPH_SHADOW = "drop-shadow-[0_2px_6px_oklch(0.16_0.012_55_/_0.6)]";
39
45
  type PhotoGroundProps = {
40
46
  /** One per slot. An absent one draws the slot's initial on the ground. */
41
47
  photos: (string | undefined)[];
@@ -67,4 +73,4 @@ type PhotoGroundProps = {
67
73
  };
68
74
  declare function PhotoGround({ photos, initials, mode, active, mosaicClassName, phoneTiles, gradient, overlay, overlayClassName, loading, glyphClassName, className, }: PhotoGroundProps): react_jsx_runtime.JSX.Element;
69
75
 
70
- export { PHOTO_GROUND, PhotoGround, type PhotoGroundProps };
76
+ export { PHOTO_GLYPH_SHADOW, PHOTO_GROUND, PhotoGround, type PhotoGroundProps };
@@ -1,3 +1,3 @@
1
- export { PHOTO_GROUND, PhotoGround } from '../chunk-CNJQUHCU.js';
1
+ export { PHOTO_GLYPH_SHADOW, PHOTO_GROUND, PhotoGround } from '../chunk-SWD6CJ35.js';
2
2
  import '../chunk-FEK5XGZW.js';
3
3
  import '../chunk-MMUBH76A.js';
@@ -1,12 +1,12 @@
1
+ import { NEUTRAL_ICON_FILTER } from '../chunk-LQWGZIYA.js';
1
2
  import { OVERLAY_PILL } from '../chunk-EZG2NELX.js';
2
3
  import { HOVER_IMAGE_MOTION, HOVER_IMAGE_WRAPPER, HOVER_MOTION, HOVER_LIFT_GRID_GROUP } from '../chunk-XCB3F6SF.js';
3
- import { NEUTRAL_ICON_FILTER } from '../chunk-LQWGZIYA.js';
4
4
  import { GradeAtom } from '../chunk-DJD3EMPK.js';
5
5
  import { showsGradeAtom } from '../chunk-I5V446BX.js';
6
6
  import { Separator } from '../chunk-NWZGSLPU.js';
7
7
  import { springSnappy } from '../chunk-OIV7B44M.js';
8
8
  import { Skeleton } from '../chunk-XBBEX4SF.js';
9
- import { Badge } from '../chunk-P43B3ONY.js';
9
+ import { Badge } from '../chunk-5XREWOBB.js';
10
10
  import { cn } from '../chunk-FEK5XGZW.js';
11
11
  import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
12
12
  import { forwardRef, memo, useState, useMemo } from 'react';
@@ -3,7 +3,7 @@ import '../chunk-FMTJGO76.js';
3
3
  import '../chunk-MWB7S54O.js';
4
4
  import '../chunk-NWZGSLPU.js';
5
5
  import { Text } from '../chunk-ZLMRVBD7.js';
6
- import { Badge } from '../chunk-P43B3ONY.js';
6
+ import { Badge } from '../chunk-5XREWOBB.js';
7
7
  import { cn } from '../chunk-FEK5XGZW.js';
8
8
  import '../chunk-MMUBH76A.js';
9
9
  import { useState } from 'react';