@bearmenu/ui 0.8.21 → 0.8.23

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 (50) hide show
  1. package/dist/{chunk-DJD3EMPK.js → chunk-YE4ZQUTI.js} +1 -1
  2. package/dist/components/alert.d.ts +2 -2
  3. package/dist/components/badge.d.ts +1 -1
  4. package/dist/components/button.d.ts +1 -1
  5. package/dist/components/coach-marks.d.ts +43 -6
  6. package/dist/components/coach-marks.js +116 -30
  7. package/dist/components/command.d.ts +7 -7
  8. package/dist/components/concept-compare.d.ts +1 -1
  9. package/dist/components/doorway-tiles.d.ts +1 -1
  10. package/dist/components/grade-atom.d.ts +1 -1
  11. package/dist/components/grade-atom.js +1 -1
  12. package/dist/components/kitchen-dossier.d.ts +1 -1
  13. package/dist/components/menu-dead-end.d.ts +1 -1
  14. package/dist/components/menu-family-block.d.ts +1 -1
  15. package/dist/components/menu-family-card.d.ts +1 -1
  16. package/dist/components/menu-filter-chips.d.ts +1 -1
  17. package/dist/components/menu-group-rows.d.ts +1 -1
  18. package/dist/components/menu-index-header.d.ts +1 -1
  19. package/dist/components/menu-index-list.d.ts +1 -1
  20. package/dist/components/menu-intent-hero.d.ts +1 -1
  21. package/dist/components/menu-item.d.ts +1 -1
  22. package/dist/components/menu-kitchen-list.d.ts +1 -1
  23. package/dist/components/menu-mocks.d.ts +1 -1
  24. package/dist/components/menu-types.d.ts +1 -1
  25. package/dist/components/open-now-list.d.ts +1 -1
  26. package/dist/components/place-about-tab.d.ts +1 -1
  27. package/dist/components/place-card.d.ts +1 -1
  28. package/dist/components/place-card.js +1 -1
  29. package/dist/components/place-details-mobile.d.ts +1 -1
  30. package/dist/components/place-schedule-week.d.ts +1 -1
  31. package/dist/components/place-types.d.ts +1 -1
  32. package/dist/components/qa-block.d.ts +1 -1
  33. package/dist/components/spinner.d.ts +2 -2
  34. package/dist/components/tag.d.ts +2 -2
  35. package/dist/components/text.d.ts +3 -3
  36. package/dist/components/top-comparison.d.ts +1 -1
  37. package/dist/components/top-cross-link.d.ts +1 -1
  38. package/dist/components/top-ranking-entry.d.ts +1 -1
  39. package/dist/components/top-ranking-hero.d.ts +1 -1
  40. package/dist/components/top-types.d.ts +1 -1
  41. package/dist/components/venue-grade-dimensions.d.ts +1 -1
  42. package/dist/components/venue-quotes.d.ts +1 -1
  43. package/dist/components/venue-wall.d.ts +1 -1
  44. package/dist/{place-types-BHdeMMiG.d.ts → place-types-C4rR3LTs.d.ts} +7 -0
  45. package/package.json +1 -1
  46. package/src/components/coach-marks.stories.tsx +20 -4
  47. package/src/components/coach-marks.test.tsx +181 -6
  48. package/src/components/coach-marks.tsx +204 -45
  49. package/src/components/grade-atom.test.tsx +32 -0
  50. package/src/components/grade-atom.tsx +8 -1
@@ -94,7 +94,7 @@ function GradeAtom({
94
94
  );
95
95
  }
96
96
  const band = resolveGradeBand(overall);
97
- const value = formatGrade(overall);
97
+ const value = labels.value ? labels.value(Math.round(Math.min(10, Math.max(1, overall)) * 10) / 10) : formatGrade(overall);
98
98
  const descriptor = labels.bands[band];
99
99
  const showDesc = sz.showDesc && !hideDescriptor;
100
100
  const photo = onPhoto ? BAND_CLASSES_PHOTO[band] : null;
@@ -3,10 +3,10 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const alertVariants: (props?: ({
6
- variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
6
+ variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
7
7
  } & class_variance_authority_types.ClassProp) | undefined) => string;
8
8
  declare const Alert: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
9
- variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
9
+ variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
11
11
  declare const AlertTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
12
12
  declare const AlertDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
@@ -4,7 +4,7 @@ import * as React from 'react';
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const badgeVariants: (props?: ({
7
- variant?: "default" | "destructive" | "outline" | "secondary" | "glass" | "overlay" | "brown" | "warning" | "success" | "onPrimary" | null | undefined;
7
+ variant?: "default" | "secondary" | "destructive" | "outline" | "overlay" | "glass" | "success" | "warning" | "brown" | "onPrimary" | null | undefined;
8
8
  live?: boolean | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "glass" | "overlay" | "ink" | "brown" | "warning" | null | undefined;
6
+ variant?: "default" | "secondary" | "destructive" | "outline" | "overlay" | "glass" | "warning" | "brown" | "link" | "ghost" | "ink" | null | undefined;
7
7
  size?: "default" | "xs" | "sm" | "lg" | "pill" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
8
8
  fullWidth?: boolean | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
@@ -25,15 +25,50 @@ import * as React from 'react';
25
25
  * side, re-measure on scroll and resize) and the keys (Escape closes, the
26
26
  * arrows step). `onProgress` reports the current stop for a toolbar label.
27
27
  *
28
- * Rendered into `document.body`: a page wrapper with an opacity or transform
29
- * transition is a stacking context, and the tour must sit above everything
30
- * the page and its chrome draw, whatever wraps the consumer.
28
+ * The spotlight is a hole in the dimming, in hit-testing as well as in
29
+ * paint: a tap on the ringed control reaches it. A gold ring around a real,
30
+ * un-dimmed control is an invitation, and a tour that swallowed the tap
31
+ * would be lying. Acting ends the tour — the thing the reader opened is the
32
+ * lesson, and whatever it opened would otherwise sit under or over an
33
+ * `aria-modal` dialog that promises the page beneath is inert. The consumer
34
+ * has already heard the stop through `onProgress`, so a "N new" door can
35
+ * pick the tour up later. The dimmed page itself does not close the tour: a
36
+ * thumb resting on it while reading is not a decision.
37
+ *
38
+ * A target is scrolled into view only when it is not already in it. The
39
+ * page's fixed chrome (`inset`) narrows what "in view" means, and a stop can
40
+ * opt out of scrolling altogether (`scroll: false`): `scrollIntoView` on a
41
+ * pinned rail scrolls the document to the rail's in-flow position, which is
42
+ * the top of whatever it pins over, and a reader mid-feed loses their place.
43
+ *
44
+ * Rendered into `document.body` above every drawer, sheet and dialog: a page
45
+ * wrapper with an opacity or transform transition is a stacking context, and
46
+ * the tour must sit above everything the page and its chrome draw, whatever
47
+ * wraps the consumer.
31
48
  */
32
49
  type CoachMarkStop = {
33
50
  /** Matches the target's `data-coach-mark` attribute. */
34
51
  id: string;
35
52
  title: string;
36
53
  body: string;
54
+ /**
55
+ * A `control` (a button, a field, a toggle) wears the gold ring; a `region`
56
+ * (a list, a rail, a block) is defined by the cut-out's edge alone. Stated,
57
+ * not inferred: a toggle group is a div of buttons and a results region a
58
+ * list of links. Defaults to `control`.
59
+ */
60
+ kind?: "control" | "region";
61
+ /**
62
+ * Never scroll to this target — for a control pinned to the viewport, whose
63
+ * box says where it is but whose in-flow position is somewhere else.
64
+ * Defaults to scrolling when the target is out of view.
65
+ */
66
+ scroll?: boolean;
67
+ };
68
+ /** The viewport's fixed chrome: what a target must clear to count as in view. */
69
+ type CoachMarksInset = {
70
+ top?: number;
71
+ bottom?: number;
37
72
  };
38
73
  type CoachMarksLabels = {
39
74
  /** "Step 2 of 4". */
@@ -47,7 +82,7 @@ type CoachMarksLabels = {
47
82
  type CoachMarksProps = {
48
83
  open: boolean;
49
84
  stops: CoachMarkStop[];
50
- /** Skip, Done, Escape and a tap on the dimmed page all end here. */
85
+ /** Skip, Done, Escape and a tap on the spotlit target all end here. */
51
86
  onClose: () => void;
52
87
  /**
53
88
  * 1-based position, the count of stops the page actually has, and the
@@ -56,8 +91,10 @@ type CoachMarksProps = {
56
91
  */
57
92
  onProgress?: (step: number, total: number, stop: CoachMarkStop) => void;
58
93
  labels: CoachMarksLabels;
94
+ /** The page's fixed header and bottom bar, in px; the callout keeps clear of them too. */
95
+ inset?: CoachMarksInset;
59
96
  className?: string;
60
97
  };
61
- declare function CoachMarks({ open, stops, onClose, onProgress, labels, className }: CoachMarksProps): React.ReactPortal | null;
98
+ declare function CoachMarks({ open, stops, onClose, onProgress, labels, inset, className, }: CoachMarksProps): React.ReactPortal | null;
62
99
 
63
- export { type CoachMarkStop, CoachMarks, type CoachMarksLabels, type CoachMarksProps };
100
+ export { type CoachMarkStop, CoachMarks, type CoachMarksInset, type CoachMarksLabels, type CoachMarksProps };
@@ -3,7 +3,7 @@ import '../chunk-RIH2IS7X.js';
3
3
  import '../chunk-5YNIQ2BL.js';
4
4
  import { cn } from '../chunk-FEK5XGZW.js';
5
5
  import '../chunk-MMUBH76A.js';
6
- import { useState, useLayoutEffect, useCallback, useEffect } from 'react';
6
+ import { useState, useLayoutEffect, useCallback, useRef, useEffect } from 'react';
7
7
  import { createPortal } from 'react-dom';
8
8
  import { Lightbulb, ArrowRight } from 'lucide-react';
9
9
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -13,7 +13,15 @@ var CALLOUT_WIDTH = 320;
13
13
  var CALLOUT_GAP = 14;
14
14
  var CALLOUT_ROOM = 280;
15
15
  var EDGE = 12;
16
+ var PIN_SIZE = 32;
17
+ var PIN_SNAP = 56;
18
+ var CARET_MARGIN = 16;
16
19
  var PIN = "pointer-events-none absolute z-[1] flex h-8 w-8 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-[oklch(0.26_0.03_60)] text-[13px] font-extrabold text-[oklch(0.82_0.15_85)] ring-2 ring-[oklch(0.82_0.15_85)] shadow-[0_2px_8px_oklch(0.16_0.012_55_/_0.45)] transition-[top,left] duration-300 motion-reduce:transition-none";
20
+ function dimClip(spot, viewport) {
21
+ const right = spot.left + spot.width;
22
+ const bottom = spot.top + spot.height;
23
+ return `polygon(evenodd, 0 0, ${viewport.width}px 0, ${viewport.width}px ${viewport.height}px, 0 ${viewport.height}px, 0 0, ${spot.left}px ${spot.top}px, ${spot.left}px ${bottom}px, ${right}px ${bottom}px, ${right}px ${spot.top}px, ${spot.left}px ${spot.top}px)`;
24
+ }
17
25
  function findTarget(id) {
18
26
  if (typeof document === "undefined") return null;
19
27
  const candidates = document.querySelectorAll(`[data-coach-mark="${id}"]`);
@@ -26,7 +34,22 @@ function measure(element) {
26
34
  const box = element.getBoundingClientRect();
27
35
  return { top: box.top, left: box.left, width: box.width, height: box.height };
28
36
  }
29
- function CoachMarks({ open, stops, onClose, onProgress, labels, className }) {
37
+ function inView(element, inset) {
38
+ var _a, _b;
39
+ const box = element.getBoundingClientRect();
40
+ return box.top - PAD >= ((_a = inset.top) != null ? _a : 0) && box.bottom + PAD <= window.innerHeight - ((_b = inset.bottom) != null ? _b : 0);
41
+ }
42
+ var NO_INSET = {};
43
+ function CoachMarks({
44
+ open,
45
+ stops,
46
+ onClose,
47
+ onProgress,
48
+ labels,
49
+ inset = NO_INSET,
50
+ className
51
+ }) {
52
+ var _a, _b;
30
53
  const [available, setAvailable] = useState([]);
31
54
  const [index, setIndex] = useState(0);
32
55
  const [rect, setRect] = useState(null);
@@ -34,36 +57,57 @@ function CoachMarks({ open, stops, onClose, onProgress, labels, className }) {
34
57
  const itinerary = stops.map((stop) => stop.id).join("|");
35
58
  useLayoutEffect(() => {
36
59
  if (!open) return;
37
- const present = stops.filter((stop) => findTarget(stop.id));
60
+ const present = stops.filter((stop) => findTarget(stop.id)).map((stop) => stop.id);
38
61
  setAvailable(present);
39
62
  setIndex(0);
40
63
  if (present.length === 0) onClose();
41
64
  }, [open, itinerary]);
42
- const current = available[index];
43
- const currentId = current == null ? void 0 : current.id;
65
+ const currentId = available[index];
66
+ const current = currentId ? stops.find((stop) => stop.id === currentId) : void 0;
67
+ const scrolls = (current == null ? void 0 : current.scroll) !== false;
68
+ const insetTop = (_a = inset.top) != null ? _a : 0;
69
+ const insetBottom = (_b = inset.bottom) != null ? _b : 0;
44
70
  const remeasure = useCallback(() => {
45
71
  const element = currentId ? findTarget(currentId) : null;
46
72
  setRect(element ? measure(element) : null);
47
73
  setViewport({ width: window.innerWidth, height: window.innerHeight });
48
74
  }, [currentId]);
49
75
  useLayoutEffect(() => {
50
- if (!open || !current) return;
51
- const element = findTarget(current.id);
76
+ if (!open || !currentId) return;
77
+ const element = findTarget(currentId);
52
78
  if (!element) {
53
- const forward = available.findIndex((stop, at) => at > index && findTarget(stop.id));
79
+ const forward = available.findIndex((id, at) => at > index && findTarget(id));
54
80
  if (forward !== -1) setIndex(forward);
55
81
  else onClose();
56
82
  return;
57
83
  }
58
- element.scrollIntoView({ block: "center", behavior: "smooth", inline: "nearest" });
84
+ if (scrolls) {
85
+ const band = window.innerHeight - insetTop - insetBottom;
86
+ const tall = element.getBoundingClientRect().height + PAD * 2 > band;
87
+ const visible = inView(element, { top: insetTop, bottom: insetBottom });
88
+ element.style.scrollMarginTop = `${insetTop + PAD}px`;
89
+ element.scrollIntoView({
90
+ block: visible ? "nearest" : tall ? "start" : "center",
91
+ behavior: "smooth",
92
+ inline: "nearest"
93
+ });
94
+ }
59
95
  remeasure();
60
96
  const settle = setTimeout(remeasure, 400);
61
- return () => clearTimeout(settle);
62
- }, [open, current, index, available, remeasure, onClose]);
97
+ return () => {
98
+ clearTimeout(settle);
99
+ element.style.scrollMarginTop = "";
100
+ };
101
+ }, [open, currentId, scrolls, index, available, insetTop, insetBottom, remeasure, onClose]);
102
+ const progressRef = useRef(onProgress);
103
+ useLayoutEffect(() => {
104
+ progressRef.current = onProgress;
105
+ });
63
106
  useEffect(() => {
107
+ var _a2;
64
108
  if (!open || !current) return;
65
- onProgress == null ? void 0 : onProgress(index + 1, available.length, current);
66
- }, [open, current, index, available.length, onProgress]);
109
+ (_a2 = progressRef.current) == null ? void 0 : _a2.call(progressRef, index + 1, available.length, current);
110
+ }, [open, currentId, index, available.length]);
67
111
  useEffect(() => {
68
112
  if (!open) return;
69
113
  window.addEventListener("resize", remeasure);
@@ -73,73 +117,105 @@ function CoachMarks({ open, stops, onClose, onProgress, labels, className }) {
73
117
  if (event.key === "ArrowRight") setIndex((at) => Math.min(at + 1, available.length - 1));
74
118
  if (event.key === "ArrowLeft") setIndex((at) => Math.max(at - 1, 0));
75
119
  };
120
+ const onClick = (event) => {
121
+ const target = currentId ? findTarget(currentId) : null;
122
+ if (target && event.target instanceof Node && target.contains(event.target)) onClose();
123
+ };
76
124
  window.addEventListener("keydown", onKey);
125
+ window.addEventListener("click", onClick, true);
77
126
  return () => {
78
127
  window.removeEventListener("resize", remeasure);
79
128
  window.removeEventListener("scroll", remeasure, true);
80
129
  window.removeEventListener("keydown", onKey);
130
+ window.removeEventListener("click", onClick, true);
81
131
  };
82
- }, [open, remeasure, onClose, available.length]);
132
+ }, [open, currentId, remeasure, onClose, available.length]);
83
133
  if (!open || !current || !rect) return null;
84
134
  const last = index === available.length - 1;
135
+ const region = current.kind === "region";
85
136
  const spot = {
86
137
  top: rect.top - PAD,
87
138
  left: rect.left - PAD,
88
139
  width: rect.width + PAD * 2,
89
140
  height: rect.height + PAD * 2
90
141
  };
91
- const roomBelow = viewport.height - (spot.top + spot.height);
142
+ const small = rect.width <= PIN_SNAP || rect.height <= PIN_SNAP;
143
+ const pinLeft = small ? spot.left : rect.left - 2;
144
+ const pinTop = spot.top - PIN_SIZE / 2 < insetTop + EDGE ? spot.top + spot.height : small ? spot.top : rect.top - 2;
145
+ const bandTop = insetTop;
146
+ const bandBottom = viewport.height - insetBottom;
147
+ const roomBelow = bandBottom - (spot.top + spot.height);
148
+ const roomAbove = spot.top - bandTop;
92
149
  const calloutLeft = Math.min(
93
150
  Math.max(spot.left, EDGE),
94
151
  Math.max(EDGE, viewport.width - CALLOUT_WIDTH - EDGE)
95
152
  );
96
- const calloutPlace = roomBelow > CALLOUT_ROOM ? { top: spot.top + spot.height + CALLOUT_GAP, left: calloutLeft } : spot.top > CALLOUT_ROOM ? { bottom: viewport.height - spot.top + CALLOUT_GAP, left: calloutLeft } : { bottom: EDGE, left: calloutLeft };
153
+ const side = roomBelow > CALLOUT_ROOM ? "below" : roomAbove > CALLOUT_ROOM ? "above" : "edge";
154
+ const calloutPlace = side === "below" ? { top: spot.top + spot.height + CALLOUT_GAP, left: calloutLeft } : side === "above" ? { bottom: viewport.height - spot.top + CALLOUT_GAP, left: calloutLeft } : { bottom: viewport.height - bandBottom + EDGE, left: calloutLeft };
155
+ const calloutWidth = Math.min(CALLOUT_WIDTH, viewport.width - EDGE * 2);
156
+ const caretLeft = Math.min(
157
+ Math.max(spot.left + spot.width / 2 - calloutLeft, CARET_MARGIN),
158
+ calloutWidth - CARET_MARGIN
159
+ );
97
160
  return createPortal(
98
161
  /* @__PURE__ */ jsxs(
99
162
  "div",
100
163
  {
101
- className: cn("fixed inset-0 z-[80]", className),
164
+ className: cn("pointer-events-none fixed inset-0 z-[1100]", className),
102
165
  role: "dialog",
103
166
  "aria-modal": true,
104
167
  "aria-label": current.title,
105
168
  children: [
106
169
  /* @__PURE__ */ jsx(
107
- "button",
170
+ "div",
108
171
  {
109
- type: "button",
110
- "aria-label": labels.skip,
111
- onClick: onClose,
112
- className: "absolute inset-0 cursor-default"
172
+ "aria-hidden": true,
173
+ className: "pointer-events-auto absolute inset-0",
174
+ style: { clipPath: dimClip(spot, viewport) }
113
175
  }
114
176
  ),
115
177
  /* @__PURE__ */ jsx(
116
178
  "div",
117
179
  {
118
180
  "aria-hidden": true,
119
- className: "pointer-events-none absolute rounded-[18px] shadow-[0_0_0_9999px_oklch(0.16_0.012_55_/_0.55)] ring-2 ring-[oklch(0.82_0.15_85)] transition-[top,left,width,height] duration-300 motion-reduce:transition-none",
181
+ className: cn(
182
+ "pointer-events-none absolute shadow-[0_0_0_9999px_oklch(0.16_0.012_55_/_0.55)] transition-[top,left,width,height] duration-300 motion-reduce:transition-none",
183
+ region ? "rounded-2xl" : "rounded-[18px] ring-2 ring-[oklch(0.82_0.15_85)]"
184
+ ),
120
185
  style: spot
121
186
  }
122
187
  ),
123
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: PIN, style: { top: rect.top - 2, left: rect.left - 2 }, children: index + 1 }),
188
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: PIN, style: { top: pinTop, left: pinLeft }, children: index + 1 }),
124
189
  /* @__PURE__ */ jsxs(
125
190
  "div",
126
191
  {
127
- className: "absolute z-[2] w-[min(320px,calc(100vw-24px))] rounded-2xl border border-border bg-card p-4 text-card-foreground shadow-xl",
192
+ className: "pointer-events-auto absolute z-[2] w-[min(320px,calc(100vw-24px))] rounded-2xl border border-border bg-card p-4 text-card-foreground shadow-[var(--shadow-overlay)]",
128
193
  style: calloutPlace,
129
194
  children: [
130
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-[oklch(0.82_0.15_85)] px-2.5 py-1 text-[10.5px] font-extrabold uppercase tracking-[0.08em] text-[oklch(0.26_0.03_60)]", children: [
195
+ side !== "edge" && /* @__PURE__ */ jsx(
196
+ "span",
197
+ {
198
+ "aria-hidden": true,
199
+ className: cn(
200
+ "absolute h-3 w-3 -translate-x-1/2 rotate-45 border-border bg-card",
201
+ side === "below" ? "-top-[7px] border-l border-t" : "-bottom-[7px] border-b border-r"
202
+ ),
203
+ style: { left: caretLeft }
204
+ }
205
+ ),
206
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-[oklch(0.82_0.15_85)] px-2.5 py-1 text-xs font-extrabold uppercase tracking-[0.08em] text-[oklch(0.26_0.03_60)]", children: [
131
207
  /* @__PURE__ */ jsx(Lightbulb, { className: "h-3 w-3", "aria-hidden": true }),
132
208
  labels.progress(index + 1, available.length)
133
209
  ] }),
134
- /* @__PURE__ */ jsx("p", { className: "mt-3 text-[15px] font-bold leading-snug", children: current.title }),
210
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-base font-semibold leading-snug", children: current.title }),
135
211
  /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm leading-relaxed text-muted-foreground", children: current.body }),
136
212
  /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center gap-2", children: [
137
- index > 0 && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setIndex(index - 1), children: labels.back }),
213
+ index > 0 && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "pill", onClick: () => setIndex(index - 1), children: labels.back }),
138
214
  /* @__PURE__ */ jsxs(
139
215
  Button,
140
216
  {
141
217
  type: "button",
142
- size: "sm",
218
+ size: "pill",
143
219
  onClick: () => last ? onClose() : setIndex(index + 1),
144
220
  children: [
145
221
  last ? labels.done : labels.next,
@@ -147,7 +223,17 @@ function CoachMarks({ open, stops, onClose, onProgress, labels, className }) {
147
223
  ]
148
224
  }
149
225
  ),
150
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", className: "ml-auto", onClick: onClose, children: labels.skip })
226
+ /* @__PURE__ */ jsx(
227
+ Button,
228
+ {
229
+ type: "button",
230
+ variant: "link",
231
+ size: "sm",
232
+ className: "ml-auto min-h-11",
233
+ onClick: onClose,
234
+ children: labels.skip
235
+ }
236
+ )
151
237
  ] })
152
238
  ]
153
239
  }
@@ -8,7 +8,7 @@ declare const Command: React.ForwardRefExoticComponent<Omit<{
8
8
  ref?: React.Ref<HTMLDivElement>;
9
9
  } & {
10
10
  asChild?: boolean;
11
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
11
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
12
12
  label?: string;
13
13
  shouldFilter?: boolean;
14
14
  filter?: (value: string, search: string, keywords?: string[]) => number;
@@ -38,7 +38,7 @@ declare const CommandList: React.ForwardRefExoticComponent<Omit<{
38
38
  ref?: React.Ref<HTMLDivElement>;
39
39
  } & {
40
40
  asChild?: boolean;
41
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
41
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
42
42
  label?: string;
43
43
  } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
44
44
  declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
@@ -47,14 +47,14 @@ declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
47
47
  ref?: React.Ref<HTMLDivElement>;
48
48
  } & {
49
49
  asChild?: boolean;
50
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
50
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
51
51
  declare const CommandLoading: React.ForwardRefExoticComponent<Omit<{
52
52
  children?: React.ReactNode;
53
53
  } & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
54
54
  ref?: React.Ref<HTMLDivElement>;
55
55
  } & {
56
56
  asChild?: boolean;
57
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
57
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
58
58
  progress?: number;
59
59
  label?: string;
60
60
  } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -64,7 +64,7 @@ declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
64
64
  ref?: React.Ref<HTMLDivElement>;
65
65
  } & {
66
66
  asChild?: boolean;
67
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild">, "heading" | "value"> & {
67
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "heading" | "value"> & {
68
68
  heading?: React.ReactNode;
69
69
  value?: string;
70
70
  forceMount?: boolean;
@@ -73,7 +73,7 @@ declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<R
73
73
  ref?: React.Ref<HTMLDivElement>;
74
74
  } & {
75
75
  asChild?: boolean;
76
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
76
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
77
77
  alwaysRender?: boolean;
78
78
  } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
79
79
  declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
@@ -82,7 +82,7 @@ declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
82
82
  ref?: React.Ref<HTMLDivElement>;
83
83
  } & {
84
84
  asChild?: boolean;
85
- }, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild">, "onSelect" | "disabled" | "value"> & {
85
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "onSelect" | "disabled" | "value"> & {
86
86
  disabled?: boolean;
87
87
  onSelect?: (value: string) => void;
88
88
  value?: string;
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuConceptPreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuLinkComponent } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,3 +1,3 @@
1
1
  import 'react/jsx-runtime';
2
2
  import '../lib/grade.js';
3
- export { G as GradeAtom, h as GradeAtomLabels, i as GradeAtomProps, j as GradeAtomSize } from '../place-types-BHdeMMiG.js';
3
+ export { G as GradeAtom, h as GradeAtomLabels, i as GradeAtomProps, j as GradeAtomSize } from '../place-types-C4rR3LTs.js';
@@ -1,4 +1,4 @@
1
- export { GradeAtom } from '../chunk-DJD3EMPK.js';
1
+ export { GradeAtom } from '../chunk-YE4ZQUTI.js';
2
2
  import '../chunk-I5V446BX.js';
3
3
  import '../chunk-FEK5XGZW.js';
4
4
  import '../chunk-MMUBH76A.js';
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
  import { MenuVenueSignature, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
4
- import { P as PlacePreview, C as CitedText, a as PlaceGradeDimensions } from '../place-types-BHdeMMiG.js';
4
+ import { P as PlacePreview, C as CitedText, a as PlaceGradeDimensions } from '../place-types-C4rR3LTs.js';
5
5
  import { VenueGradeDimensionKey } from './venue-grade-dimensions.js';
6
6
  import '../lib/grade.js';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuLinkComponent, MenuLoosenOption } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuKitchenListLabels } from './menu-kitchen-list.js';
3
3
  import { MenuFamilyBlockPreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
4
4
  import 'react';
5
- import '../place-types-BHdeMMiG.js';
5
+ import '../place-types-C4rR3LTs.js';
6
6
  import '../lib/grade.js';
7
7
 
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuFamilyPreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuFilterChip } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuLinkComponent, MenuLinkProps } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuIndexEntry, MenuLinkComponent } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  type MenuIndexHeaderProps = {
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuIndexEntry, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuIntentFigure, MenuLinkComponent } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { MenuItemPreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuKitchenPreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,6 +1,6 @@
1
1
  import { MenuFamilyBlockPreview, MenuConceptPreview, MenuFamilyPreview, MenuFilterChip, MenuIndexEntry, MenuIntentFigure, MenuItemPreview, MenuKitchenPreview, MenuLoosenOption, QaItem, MenuVenuePreview } from './menu-types.js';
2
2
  import { DoorwayTile } from './doorway-tiles.js';
3
- import { P as PlacePreview } from '../place-types-BHdeMMiG.js';
3
+ import { P as PlacePreview } from '../place-types-C4rR3LTs.js';
4
4
  import 'react';
5
5
  import 'react/jsx-runtime';
6
6
  import '../lib/grade.js';
@@ -1,5 +1,5 @@
1
1
  import { ComponentType, CSSProperties, ReactNode } from 'react';
2
- import { M as MenuSizeAndPrice, P as PlacePreview } from '../place-types-BHdeMMiG.js';
2
+ import { M as MenuSizeAndPrice, P as PlacePreview } from '../place-types-C4rR3LTs.js';
3
3
  import 'react/jsx-runtime';
4
4
  import '../lib/grade.js';
5
5
 
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MenuVenuePreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
3
3
  import 'react';
4
- import '../place-types-BHdeMMiG.js';
4
+ import '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { P as PlacePreview, b as PlaceAboutTabLabels, c as PlaceLinkKind } from '../place-types-BHdeMMiG.js';
2
+ import { P as PlacePreview, b as PlaceAboutTabLabels, c as PlaceLinkKind } from '../place-types-C4rR3LTs.js';
3
3
  import '../lib/grade.js';
4
4
 
5
5
  interface PlaceAboutTabProps {
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React$1 from 'react';
3
3
  import { ReactNode, MouseEvent } from 'react';
4
- import { P as PlacePreview, d as PlaceCardLabels } from '../place-types-BHdeMMiG.js';
4
+ import { P as PlacePreview, d as PlaceCardLabels } from '../place-types-C4rR3LTs.js';
5
5
  import '../lib/grade.js';
6
6
 
7
7
  /**