@bearmenu/ui 0.8.8 → 0.8.10

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 (206) hide show
  1. package/dist/chunk-24RFI4RQ.js +167 -0
  2. package/dist/chunk-2XCZJWTV.js +121 -0
  3. package/dist/chunk-5RWTOT5Y.js +72 -0
  4. package/dist/chunk-62ES6N32.js +27 -0
  5. package/dist/chunk-AKQ57NXY.js +58 -0
  6. package/dist/chunk-CLLY6XB3.js +41 -0
  7. package/dist/chunk-DTXNDLSE.js +125 -0
  8. package/dist/chunk-F6FMZJDG.js +113 -0
  9. package/dist/{chunk-2WDJR6K7.js → chunk-G7IFL4Z4.js} +4 -1
  10. package/dist/chunk-MZL7CGCL.js +109 -0
  11. package/dist/chunk-Q6QH52LJ.js +38 -0
  12. package/dist/chunk-SY6RV476.js +48 -0
  13. package/dist/chunk-TH6W2PWG.js +213 -0
  14. package/dist/chunk-UDN7UHJW.js +60 -0
  15. package/dist/{chunk-TT3WFS6S.js → chunk-YOKHBAIH.js} +11 -11
  16. package/dist/components/alert.d.ts +2 -2
  17. package/dist/components/badge.d.ts +1 -1
  18. package/dist/components/concept-compare-rail.d.ts +50 -0
  19. package/dist/components/concept-compare-rail.js +5 -0
  20. package/dist/components/concept-compare.d.ts +110 -0
  21. package/dist/components/concept-compare.js +238 -0
  22. package/dist/components/concept-convergence.d.ts +41 -0
  23. package/dist/components/concept-convergence.js +53 -0
  24. package/dist/components/convergence.d.ts +25 -0
  25. package/dist/components/convergence.js +4 -0
  26. package/dist/components/date-input.d.ts +1 -1
  27. package/dist/components/event-card.js +1 -1
  28. package/dist/components/event-compact-row.d.ts +1 -1
  29. package/dist/components/event-compact-row.js +1 -1
  30. package/dist/components/event-detail-panel.d.ts +171 -25
  31. package/dist/components/event-detail-panel.js +472 -175
  32. package/dist/components/event-index-row.js +1 -1
  33. package/dist/components/event-list-row-wide.js +2 -2
  34. package/dist/components/event-list-row.js +2 -2
  35. package/dist/components/explainer-steps.d.ts +34 -0
  36. package/dist/components/explainer-steps.js +36 -0
  37. package/dist/components/glass-ground.d.ts +66 -0
  38. package/dist/components/glass-ground.js +3 -0
  39. package/dist/components/hub-surface.d.ts +27 -0
  40. package/dist/components/hub-surface.js +30 -0
  41. package/dist/components/hue-chip.d.ts +70 -0
  42. package/dist/components/hue-chip.js +3 -0
  43. package/dist/components/kitchen-dossier.d.ts +88 -0
  44. package/dist/components/kitchen-dossier.js +187 -0
  45. package/dist/components/menu-dead-end.d.ts +56 -0
  46. package/dist/components/menu-dead-end.js +49 -0
  47. package/dist/components/menu-family-block.d.ts +99 -0
  48. package/dist/components/menu-family-block.js +155 -0
  49. package/dist/components/menu-family-card.d.ts +65 -0
  50. package/dist/components/menu-family-card.js +79 -0
  51. package/dist/components/menu-field.d.ts +57 -0
  52. package/dist/components/menu-field.js +93 -0
  53. package/dist/components/menu-filter-chips.d.ts +86 -0
  54. package/dist/components/menu-filter-chips.js +122 -0
  55. package/dist/components/menu-group-rows.d.ts +53 -0
  56. package/dist/components/menu-group-rows.js +67 -0
  57. package/dist/components/menu-hub-hero.d.ts +65 -0
  58. package/dist/components/menu-hub-hero.js +103 -0
  59. package/dist/components/menu-index-header.d.ts +37 -0
  60. package/dist/components/menu-index-header.js +68 -0
  61. package/dist/components/menu-index-list.d.ts +48 -0
  62. package/dist/components/menu-index-list.js +96 -0
  63. package/dist/components/menu-intent-hero.d.ts +69 -0
  64. package/dist/components/menu-intent-hero.js +87 -0
  65. package/dist/components/menu-intent-tiles.d.ts +31 -0
  66. package/dist/components/menu-intent-tiles.js +50 -0
  67. package/dist/components/menu-item.d.ts +127 -0
  68. package/dist/components/menu-item.js +5 -0
  69. package/dist/components/menu-kitchen-list.d.ts +82 -0
  70. package/dist/components/menu-kitchen-list.js +5 -0
  71. package/dist/components/menu-mocks.d.ts +90 -0
  72. package/dist/components/menu-mocks.js +504 -0
  73. package/dist/components/menu-types.d.ts +421 -0
  74. package/dist/components/menu-types.js +1 -0
  75. package/dist/components/motion-icon-controls.js +2 -2
  76. package/dist/components/motion-icon-set.js +21 -9
  77. package/dist/components/motion-icon.d.ts +22 -1
  78. package/dist/components/motion-icon.js +1 -1
  79. package/dist/components/open-now-list.d.ts +40 -0
  80. package/dist/components/open-now-list.js +69 -0
  81. package/dist/components/photo-ground.d.ts +64 -0
  82. package/dist/components/photo-ground.js +3 -0
  83. package/dist/components/place-about-tab.js +2 -2
  84. package/dist/components/place-details-mobile.js +2 -2
  85. package/dist/components/place-types.d.ts +112 -1
  86. package/dist/components/qa-block.d.ts +36 -0
  87. package/dist/components/qa-block.js +24 -0
  88. package/dist/components/scroll-fade.js +3 -121
  89. package/dist/components/signature-chip.d.ts +37 -0
  90. package/dist/components/signature-chip.js +4 -0
  91. package/dist/components/snap-rail.d.ts +48 -5
  92. package/dist/components/snap-rail.js +3 -51
  93. package/dist/components/stat-banner.d.ts +47 -0
  94. package/dist/components/stat-banner.js +61 -0
  95. package/dist/components/story.d.ts +34 -0
  96. package/dist/components/story.js +3 -0
  97. package/dist/components/tag.d.ts +2 -2
  98. package/dist/components/text.d.ts +1 -1
  99. package/dist/components/top-comparison.d.ts +28 -0
  100. package/dist/components/top-comparison.js +76 -0
  101. package/dist/components/top-cross-link.d.ts +34 -0
  102. package/dist/components/top-cross-link.js +101 -0
  103. package/dist/components/top-ranking-entry.d.ts +53 -0
  104. package/dist/components/top-ranking-entry.js +217 -0
  105. package/dist/components/top-ranking-hero.d.ts +61 -0
  106. package/dist/components/top-ranking-hero.js +99 -0
  107. package/dist/components/top-ranking-legend.d.ts +69 -0
  108. package/dist/components/top-ranking-legend.js +124 -0
  109. package/dist/components/top-types.d.ts +109 -0
  110. package/dist/components/top-types.js +1 -0
  111. package/dist/components/venue-grade-dimensions.d.ts +38 -0
  112. package/dist/components/venue-grade-dimensions.js +3 -0
  113. package/dist/components/venue-quotes.d.ts +32 -0
  114. package/dist/components/venue-quotes.js +3 -0
  115. package/dist/components/venue-wall.d.ts +41 -0
  116. package/dist/components/venue-wall.js +118 -0
  117. package/dist/components/weekday-theme-banner.d.ts +70 -0
  118. package/dist/components/weekday-theme-banner.js +127 -0
  119. package/dist/components/weekend-panel.js +2 -2
  120. package/package.json +1 -1
  121. package/src/components/colour-dictionary.stories.tsx +227 -0
  122. package/src/components/concept-compare-rail.tsx +131 -0
  123. package/src/components/concept-compare.stories.tsx +172 -0
  124. package/src/components/concept-compare.tsx +443 -0
  125. package/src/components/concept-convergence.stories.tsx +53 -0
  126. package/src/components/concept-convergence.tsx +90 -0
  127. package/src/components/convergence.stories.tsx +54 -0
  128. package/src/components/convergence.tsx +177 -0
  129. package/src/components/event-compact-row.tsx +1 -1
  130. package/src/components/event-detail-panel.stories.tsx +205 -97
  131. package/src/components/event-detail-panel.test.tsx +181 -0
  132. package/src/components/event-detail-panel.tsx +703 -185
  133. package/src/components/explainer-steps.stories.tsx +46 -0
  134. package/src/components/explainer-steps.tsx +74 -0
  135. package/src/components/glass-ground.tsx +129 -0
  136. package/src/components/hub-surface.stories.tsx +68 -0
  137. package/src/components/hub-surface.tsx +50 -0
  138. package/src/components/hue-chip.stories.tsx +76 -0
  139. package/src/components/hue-chip.test.tsx +62 -0
  140. package/src/components/hue-chip.tsx +99 -0
  141. package/src/components/kitchen-dossier.stories.tsx +108 -0
  142. package/src/components/kitchen-dossier.tsx +322 -0
  143. package/src/components/menu-dead-end.stories.tsx +67 -0
  144. package/src/components/menu-dead-end.tsx +127 -0
  145. package/src/components/menu-family-block.stories.tsx +91 -0
  146. package/src/components/menu-family-block.tsx +314 -0
  147. package/src/components/menu-family-card.stories.tsx +120 -0
  148. package/src/components/menu-family-card.tsx +191 -0
  149. package/src/components/menu-field.stories.tsx +74 -0
  150. package/src/components/menu-field.tsx +199 -0
  151. package/src/components/menu-filter-chips.stories.tsx +107 -0
  152. package/src/components/menu-filter-chips.tsx +238 -0
  153. package/src/components/menu-group-rows.stories.tsx +54 -0
  154. package/src/components/menu-group-rows.tsx +133 -0
  155. package/src/components/menu-hub-hero.stories.tsx +92 -0
  156. package/src/components/menu-hub-hero.tsx +187 -0
  157. package/src/components/menu-index-header.stories.tsx +72 -0
  158. package/src/components/menu-index-header.tsx +125 -0
  159. package/src/components/menu-index-list.stories.tsx +50 -0
  160. package/src/components/menu-index-list.tsx +149 -0
  161. package/src/components/menu-intent-hero.stories.tsx +67 -0
  162. package/src/components/menu-intent-hero.tsx +189 -0
  163. package/src/components/menu-intent-tiles.stories.tsx +54 -0
  164. package/src/components/menu-intent-tiles.tsx +76 -0
  165. package/src/components/menu-item.tsx +416 -0
  166. package/src/components/menu-kitchen-list.stories.tsx +67 -0
  167. package/src/components/menu-kitchen-list.test.tsx +78 -0
  168. package/src/components/menu-kitchen-list.tsx +284 -0
  169. package/src/components/menu-mocks.ts +592 -0
  170. package/src/components/menu-types.ts +442 -0
  171. package/src/components/motion-icon-controls.tsx +11 -11
  172. package/src/components/motion-icon-set.tsx +36 -8
  173. package/src/components/motion-icon.test.tsx +23 -1
  174. package/src/components/motion-icon.tsx +20 -0
  175. package/src/components/open-now-list.stories.tsx +76 -0
  176. package/src/components/open-now-list.tsx +127 -0
  177. package/src/components/photo-ground.tsx +147 -0
  178. package/src/components/place-types.ts +112 -0
  179. package/src/components/qa-block.stories.tsx +43 -0
  180. package/src/components/qa-block.tsx +60 -0
  181. package/src/components/signature-chip.tsx +77 -0
  182. package/src/components/snap-rail.tsx +133 -9
  183. package/src/components/stat-banner.stories.tsx +100 -0
  184. package/src/components/stat-banner.tsx +117 -0
  185. package/src/components/story.tsx +225 -0
  186. package/src/components/top-comparison.stories.tsx +78 -0
  187. package/src/components/top-comparison.tsx +151 -0
  188. package/src/components/top-cross-link.stories.tsx +84 -0
  189. package/src/components/top-cross-link.tsx +171 -0
  190. package/src/components/top-ranking-entry.stories.tsx +171 -0
  191. package/src/components/top-ranking-entry.test.tsx +105 -0
  192. package/src/components/top-ranking-entry.tsx +425 -0
  193. package/src/components/top-ranking-hero.stories.tsx +76 -0
  194. package/src/components/top-ranking-hero.tsx +218 -0
  195. package/src/components/top-ranking-legend.stories.tsx +78 -0
  196. package/src/components/top-ranking-legend.tsx +239 -0
  197. package/src/components/top-types.ts +110 -0
  198. package/src/components/venue-grade-dimensions.stories.tsx +83 -0
  199. package/src/components/venue-grade-dimensions.tsx +91 -0
  200. package/src/components/venue-quotes.stories.tsx +59 -0
  201. package/src/components/venue-quotes.tsx +64 -0
  202. package/src/components/venue-wall.stories.tsx +78 -0
  203. package/src/components/venue-wall.tsx +185 -0
  204. package/src/components/weekday-theme-banner.stories.tsx +113 -0
  205. package/src/components/weekday-theme-banner.tsx +231 -0
  206. package/dist/{chunk-XWMRABZW.js → chunk-HSIYYA2E.js} +1 -1
@@ -0,0 +1,61 @@
1
+ import { cn } from '../chunk-FEK5XGZW.js';
2
+ import '../chunk-3GWWZKX7.js';
3
+ import { cva } from 'class-variance-authority';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var bannerVariants = cva(
7
+ "relative flex flex-col gap-2 overflow-hidden rounded-[18px] p-5",
8
+ {
9
+ variants: {
10
+ tone: {
11
+ /** Dark ground, for the claim that needs the most weight. */
12
+ dark: "bg-[oklch(0.21_0.012_55)] text-white",
13
+ /** Tinted ground, for the supporting figure beside it. */
14
+ warm: "bg-accent-subtle text-foreground"
15
+ }
16
+ },
17
+ defaultVariants: { tone: "dark" }
18
+ }
19
+ );
20
+ function StatBanner({
21
+ tone,
22
+ kicker,
23
+ headline,
24
+ body,
25
+ figure,
26
+ figureUnit,
27
+ watermark,
28
+ scale,
29
+ action,
30
+ className
31
+ }) {
32
+ return /* @__PURE__ */ jsxs("div", { className: cn(bannerVariants({ tone }), className), children: [
33
+ watermark && /* @__PURE__ */ jsx(
34
+ "span",
35
+ {
36
+ "aria-hidden": true,
37
+ className: "pointer-events-none absolute -bottom-8 right-2 select-none font-serif text-[150px] font-bold leading-none opacity-[0.08]",
38
+ children: watermark
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsxs("div", { className: "relative z-[1] flex flex-1 flex-col gap-2", children: [
42
+ kicker && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold tracking-[0.11em] opacity-80", children: kicker }),
43
+ figure && /* @__PURE__ */ jsxs("div", { className: "text-[40px] font-extrabold leading-none tracking-[-0.03em] tabular-nums", children: [
44
+ figure,
45
+ figureUnit && /* @__PURE__ */ jsx("span", { className: "ml-1 text-lg font-extrabold", children: figureUnit })
46
+ ] }),
47
+ headline && /* @__PURE__ */ jsx("h3", { className: "font-serif text-xl font-semibold leading-[1.2] tracking-[-0.02em] lg:text-2xl", children: headline }),
48
+ body && /* @__PURE__ */ jsx("p", { className: "text-[13px] leading-[1.5] opacity-85", children: body }),
49
+ scale && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-2 text-[11px] tabular-nums opacity-70", children: [
50
+ /* @__PURE__ */ jsx("span", { children: scale[0] }),
51
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "h-px flex-1 bg-current opacity-30" }),
52
+ /* @__PURE__ */ jsx("span", { children: scale[1] }),
53
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "h-px flex-1 bg-current opacity-30" }),
54
+ /* @__PURE__ */ jsx("span", { children: scale[2] })
55
+ ] }),
56
+ action && /* @__PURE__ */ jsx("div", { className: "mt-auto flex items-center pt-3", children: action })
57
+ ] })
58
+ ] });
59
+ }
60
+
61
+ export { StatBanner };
@@ -0,0 +1,34 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ type StoryProviderProps = {
5
+ /** How many parts the story has. */
6
+ count: number;
7
+ /** How long each part shows. */
8
+ durationMs?: number;
9
+ /** Accessible name of the tap-to-advance, e.g. "Next". */
10
+ nextLabel: string;
11
+ className?: string;
12
+ children: React.ReactNode;
13
+ };
14
+ declare function StoryProvider({ count, durationMs, nextLabel, className, children, }: StoryProviderProps): react_jsx_runtime.JSX.Element;
15
+ type StorySegmentsProps = {
16
+ /**
17
+ * Accessible name per segment, one per part, e.g. `["Part 1 of 3", …]`.
18
+ * Strings rather than a function: a server component renders this and a
19
+ * function cannot cross into a client one.
20
+ */
21
+ labels: string[];
22
+ className?: string;
23
+ };
24
+ /** The segments: one per part, the active one filling on the timer. */
25
+ declare function StorySegments({ labels, className }: StorySegmentsProps): react_jsx_runtime.JSX.Element | null;
26
+ type StoryPanelProps = {
27
+ /** The parts, in order. Rendered by the caller; shown one at a time. */
28
+ parts: React.ReactNode[];
29
+ className?: string;
30
+ };
31
+ /** The panel: every part in one cell, the active one visible. */
32
+ declare function StoryPanel({ parts, className }: StoryPanelProps): react_jsx_runtime.JSX.Element;
33
+
34
+ export { StoryPanel, type StoryPanelProps, StoryProvider, type StoryProviderProps, StorySegments, type StorySegmentsProps };
@@ -0,0 +1,3 @@
1
+ export { StoryPanel, StoryProvider, StorySegments } from '../chunk-F6FMZJDG.js';
2
+ import '../chunk-FEK5XGZW.js';
3
+ import '../chunk-3GWWZKX7.js';
@@ -3,11 +3,11 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const tagVariants: (props?: ({
6
- variant?: "success" | "warning" | "default" | "destructive" | "outline" | "primary" | "quiet" | null | undefined;
6
+ variant?: "default" | "destructive" | "outline" | "success" | "warning" | "primary" | "quiet" | null | undefined;
7
7
  size?: "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare const Tag: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
10
- variant?: "success" | "warning" | "default" | "destructive" | "outline" | "primary" | "quiet" | null | undefined;
10
+ variant?: "default" | "destructive" | "outline" | "success" | "warning" | "primary" | "quiet" | null | undefined;
11
11
  size?: "default" | "sm" | "lg" | null | undefined;
12
12
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
13
13
  onRemove?: () => void;
@@ -22,7 +22,7 @@ import { VariantProps } from 'class-variance-authority';
22
22
  * Weights are 400 / 600 / 700. 500 is not in the system.
23
23
  */
24
24
  declare const textVariants: (props?: ({
25
- variant?: "body" | "caption" | "h1" | "h2" | "h3" | "h4" | "label" | "small" | "display" | "body-lg" | "body-sm" | "overline" | null | undefined;
25
+ variant?: "h2" | "h3" | "label" | "body" | "caption" | "h1" | "h4" | "small" | "display" | "body-lg" | "body-sm" | "overline" | null | undefined;
26
26
  color?: "inherit" | "default" | "destructive" | "muted" | "primary" | "primary-foreground" | null | undefined;
27
27
  weight?: "bold" | "medium" | "normal" | "semibold" | null | undefined;
28
28
  leading?: "none" | "normal" | "tight" | "snug" | "relaxed" | "loose" | null | undefined;
@@ -0,0 +1,28 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { MenuLinkComponent } from './menu-types.js';
3
+ import { TopComparisonRow } from './top-types.js';
4
+ import 'react';
5
+ import './place-types.js';
6
+
7
+ type TopComparisonLabels = {
8
+ venue: string;
9
+ grade: string;
10
+ signature: string;
11
+ price: string;
12
+ late: string;
13
+ terrace: string;
14
+ /** Screen-reader text for a "no" cell — never an empty cell. */
15
+ no: string;
16
+ yes: string;
17
+ };
18
+ type TopComparisonProps = {
19
+ rows: TopComparisonRow[];
20
+ labels: TopComparisonLabels;
21
+ /** Accessible name for the table. */
22
+ caption: string;
23
+ linkComponent?: MenuLinkComponent;
24
+ className?: string;
25
+ };
26
+ declare function TopComparison({ rows, labels, caption, linkComponent: LinkComponent, className, }: TopComparisonProps): react_jsx_runtime.JSX.Element;
27
+
28
+ export { TopComparison, type TopComparisonLabels, type TopComparisonProps };
@@ -0,0 +1,76 @@
1
+ import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
2
+ import { Moon, Sun } from 'lucide-react';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ function DefaultLink(_a) {
6
+ var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
7
+ return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
8
+ }
9
+ function TopComparison({
10
+ rows,
11
+ labels,
12
+ caption,
13
+ linkComponent: LinkComponent = DefaultLink,
14
+ className
15
+ }) {
16
+ return /* @__PURE__ */ jsxs("div", { className, children: [
17
+ /* @__PURE__ */ jsx("div", { className: "hidden overflow-x-auto lg:block", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-[13px]", children: [
18
+ /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }),
19
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border text-left text-[11px] font-bold uppercase tracking-[0.07em] text-muted-foreground", children: [
20
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "w-10 py-2 font-bold", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "#" }) }),
21
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.venue }),
22
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.grade }),
23
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.signature }),
24
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.price }),
25
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.late }),
26
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.terrace })
27
+ ] }) }),
28
+ /* @__PURE__ */ jsx("tbody", { children: rows.map((row) => {
29
+ var _a, _b, _c;
30
+ return /* @__PURE__ */ jsxs("tr", { className: "border-b border-border/60", children: [
31
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 tabular-nums text-muted-foreground", children: String(row.rank).padStart(2, "0") }),
32
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 font-semibold", children: /* @__PURE__ */ jsx(
33
+ LinkComponent,
34
+ {
35
+ href: row.href,
36
+ className: "hover:text-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
37
+ children: row.name
38
+ }
39
+ ) }),
40
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 font-bold tabular-nums text-accent", children: (_a = row.gradeLabel) != null ? _a : "\u2014" }),
41
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 text-muted-foreground", children: (_b = row.signature) != null ? _b : "\u2014" }),
42
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 tabular-nums", children: (_c = row.priceLabel) != null ? _c : "\u2014" }),
43
+ /* @__PURE__ */ jsx("td", { className: "py-2.5", children: /* @__PURE__ */ jsx(Mark, { on: row.late, yes: labels.yes, no: labels.no }) }),
44
+ /* @__PURE__ */ jsx("td", { className: "py-2.5", children: /* @__PURE__ */ jsx(Mark, { on: row.terrace, yes: labels.yes, no: labels.no }) })
45
+ ] }, row.name);
46
+ }) })
47
+ ] }) }),
48
+ /* @__PURE__ */ jsx("ul", { className: "lg:hidden", children: rows.map((row) => /* @__PURE__ */ jsx("li", { className: "border-t border-border first:border-t-0", children: /* @__PURE__ */ jsxs(
49
+ LinkComponent,
50
+ {
51
+ href: row.href,
52
+ className: "flex items-center gap-3 py-2.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
53
+ children: [
54
+ /* @__PURE__ */ jsx("span", { className: "w-6 shrink-0 text-[13px] font-bold tabular-nums text-muted-foreground", children: String(row.rank).padStart(2, "0") }),
55
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
56
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-[13.5px] font-bold", children: row.name }),
57
+ (row.signature || row.priceLabel) && /* @__PURE__ */ jsx("span", { className: "block truncate text-[11.5px] text-muted-foreground", children: [row.signature, row.priceLabel].filter(Boolean).join(" \xB7 ") })
58
+ ] }),
59
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
60
+ row.late && /* @__PURE__ */ jsx(Moon, { className: "h-3.5 w-3.5", "aria-label": labels.late }),
61
+ row.terrace && /* @__PURE__ */ jsx(Sun, { className: "h-3.5 w-3.5", "aria-label": labels.terrace })
62
+ ] }),
63
+ row.gradeLabel && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[13px] font-extrabold tabular-nums text-accent", children: row.gradeLabel })
64
+ ]
65
+ }
66
+ ) }, row.name)) })
67
+ ] });
68
+ }
69
+ function Mark({ on, yes, no }) {
70
+ return on ? /* @__PURE__ */ jsx("span", { className: "font-semibold text-[color:var(--free,oklch(0.45_0.13_155))]", children: yes }) : /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
71
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\u2014" }),
72
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: no })
73
+ ] });
74
+ }
75
+
76
+ export { TopComparison };
@@ -0,0 +1,34 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { MenuLinkComponent } from './menu-types.js';
3
+ import 'react';
4
+ import './place-types.js';
5
+
6
+ type TopCrossLinkProps = {
7
+ /**
8
+ * `row` (default) — the way OUT of the ranking, full width under the list.
9
+ * `panel` — the way IN, stacked, for a narrow column beside a browse list.
10
+ */
11
+ variant?: "row" | "panel";
12
+ /** e.g. "RANKED". `panel` only; drawn over the title with `icon` inline. */
13
+ kicker?: string;
14
+ title: string;
15
+ description: string;
16
+ /**
17
+ * The link's text. Prefer the destination's own headline over a generic
18
+ * "see more": the reader lands on a page whose `<h1>` is the string they
19
+ * tapped, and it is the anchor text the destination actually wants.
20
+ */
21
+ cta: string;
22
+ href: string;
23
+ /** Finished CSS gradient for the ground. `panel` only. */
24
+ gradient?: string;
25
+ /** Names the DESTINATION. Defaults to `LayoutList` on `row`, `Trophy` on `panel`. */
26
+ icon?: React.ReactNode;
27
+ /** The title's element. `b` by default on `row`, `h2` on `panel`. */
28
+ as?: "h2" | "h3" | "b";
29
+ linkComponent?: MenuLinkComponent;
30
+ className?: string;
31
+ };
32
+ declare function TopCrossLink({ variant, kicker, title, description, cta, href, gradient, icon, as, linkComponent: LinkComponent, className, }: TopCrossLinkProps): react_jsx_runtime.JSX.Element;
33
+
34
+ export { TopCrossLink, type TopCrossLinkProps };
@@ -0,0 +1,101 @@
1
+ import { cn } from '../chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
3
+ import { ArrowRight, Trophy, LayoutList } from 'lucide-react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ function DefaultLink(_a) {
7
+ var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
8
+ return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
9
+ }
10
+ var CTA = cn(
11
+ "rounded-xl bg-accent font-bold text-accent-foreground",
12
+ "transition-opacity duration-150 hover:opacity-90",
13
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
14
+ "motion-reduce:transition-none"
15
+ );
16
+ function TopCrossLink({
17
+ variant = "row",
18
+ kicker,
19
+ title,
20
+ description,
21
+ cta,
22
+ href,
23
+ gradient,
24
+ icon,
25
+ as,
26
+ linkComponent: LinkComponent = DefaultLink,
27
+ className
28
+ }) {
29
+ const isPanel = variant === "panel";
30
+ const Heading = as != null ? as : isPanel ? "h2" : "b";
31
+ const glyph = icon != null ? icon : isPanel ? /* @__PURE__ */ jsx(Trophy, {}) : /* @__PURE__ */ jsx(LayoutList, {});
32
+ if (!isPanel) {
33
+ return /* @__PURE__ */ jsxs(
34
+ "div",
35
+ {
36
+ className: cn(
37
+ "flex flex-col gap-3 rounded-[18px] border border-border bg-card p-4",
38
+ "lg:flex-row lg:items-center lg:gap-5 lg:p-5",
39
+ className
40
+ ),
41
+ children: [
42
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "shrink-0 text-muted-foreground [&>svg]:h-5 [&>svg]:w-5", children: glyph }),
43
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
44
+ /* @__PURE__ */ jsx(Heading, { className: "block text-[15px] font-bold tracking-[-0.01em]", children: title }),
45
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: description })
46
+ ] }),
47
+ /* @__PURE__ */ jsxs(
48
+ LinkComponent,
49
+ {
50
+ href,
51
+ className: cn(
52
+ CTA,
53
+ "inline-flex min-h-11 shrink-0 items-center justify-center gap-2 px-5 py-2.5 text-sm"
54
+ ),
55
+ children: [
56
+ cta,
57
+ /* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4 shrink-0", "aria-hidden": true })
58
+ ]
59
+ }
60
+ )
61
+ ]
62
+ }
63
+ );
64
+ }
65
+ return /* @__PURE__ */ jsxs(
66
+ "div",
67
+ {
68
+ className: cn(
69
+ "relative overflow-hidden rounded-[18px] border border-border bg-card shadow-[var(--shadow-card)]",
70
+ className
71
+ ),
72
+ children: [
73
+ gradient && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute inset-0", style: { backgroundImage: gradient } }),
74
+ /* @__PURE__ */ jsxs("div", { className: "relative z-[1] p-4 lg:p-5", children: [
75
+ kicker && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-[10.5px] font-extrabold uppercase tracking-[0.13em] text-muted-foreground", children: [
76
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "[&>svg]:h-3 [&>svg]:w-3 [&>svg]:shrink-0", children: glyph }),
77
+ kicker
78
+ ] }),
79
+ /* @__PURE__ */ jsx(Heading, { className: "mt-2 block font-serif text-[20px] font-bold leading-[1.12] tracking-[-0.02em] text-foreground lg:text-[21px]", children: title }),
80
+ /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-[13px] leading-relaxed text-muted-foreground", children: description }),
81
+ /* @__PURE__ */ jsxs(
82
+ LinkComponent,
83
+ {
84
+ href,
85
+ className: cn(
86
+ CTA,
87
+ "mt-4 flex min-h-11 w-full items-center justify-between gap-3 px-4 py-3 text-left text-[13.5px] leading-snug"
88
+ ),
89
+ children: [
90
+ /* @__PURE__ */ jsx("span", { children: cta }),
91
+ /* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4 shrink-0", "aria-hidden": true })
92
+ ]
93
+ }
94
+ )
95
+ ] })
96
+ ]
97
+ }
98
+ );
99
+ }
100
+
101
+ export { TopCrossLink };
@@ -0,0 +1,53 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { MenuItemLabels } from './menu-item.js';
3
+ import { MenuItemPreview, MenuLinkComponent } from './menu-types.js';
4
+ import { TopRankEntry } from './top-types.js';
5
+ import 'react';
6
+ import './place-types.js';
7
+
8
+ type TopRankingEntryLabels = {
9
+ /** Heading over the menu rows when the venue's own group is unknown. */
10
+ signature: string;
11
+ /** Accessible name for the dish link. */
12
+ openDish: (name: string) => string;
13
+ /** Passed through to the production `<MenuItem>`. */
14
+ item: MenuItemLabels;
15
+ /**
16
+ * Opens an item's drawer. The DS owns no routing, so the caller composes it.
17
+ *
18
+ * Takes the ITEM, not its slug: a menu row is a dish or a drink and the two
19
+ * resolve through different endpoints, so the caller has to see `kind` to
20
+ * build the right link. `undefined` leaves the row inert, which is the
21
+ * text-only must-try mention with no live menu row behind it.
22
+ */
23
+ itemHref: (item: MenuItemPreview) => string | undefined;
24
+ };
25
+ type TopRankingEntryProps = {
26
+ entry: TopRankEntry;
27
+ labels: TopRankingEntryLabels;
28
+ formatPrice: (amount: number) => string;
29
+ formatCount?: (value: number) => string;
30
+ /** The category's hue, for the menu rows' colour mark. */
31
+ markGradient?: string;
32
+ linkComponent?: MenuLinkComponent;
33
+ className?: string;
34
+ };
35
+ declare function TopRankingEntry({ entry, labels, formatPrice, formatCount, markGradient, linkComponent: LinkComponent, className, }: TopRankingEntryProps): react_jsx_runtime.JSX.Element;
36
+ /**
37
+ * The entry's own loading state, at the entry's footprint.
38
+ *
39
+ * The cover keeps its 3:2 on the phone and its 4:5 at 300px wide on desktop, so
40
+ * the article does not jump when the photographs land — the one reflow a long,
41
+ * scrolled page cannot afford. (This said "4:3 … 300×225" for a while after the
42
+ * cover changed underneath it, which is the failure mode a skeleton in the same
43
+ * file as its component is supposed to prevent.)
44
+ */
45
+ declare function TopRankingEntrySkeleton({ className }: {
46
+ className?: string;
47
+ }): react_jsx_runtime.JSX.Element;
48
+ /** A run of entries — the ranking's loading state. */
49
+ declare function TopRankingListSkeleton({ rows }: {
50
+ rows?: number;
51
+ }): react_jsx_runtime.JSX.Element;
52
+
53
+ export { TopRankingEntry, type TopRankingEntryLabels, type TopRankingEntryProps, TopRankingEntrySkeleton, TopRankingListSkeleton };
@@ -0,0 +1,217 @@
1
+ import { MenuItem } from '../chunk-TH6W2PWG.js';
2
+ import '../chunk-Q6QH52LJ.js';
3
+ import { Separator } from '../chunk-WSRWFA6K.js';
4
+ import { Skeleton } from '../chunk-QXHMPJ35.js';
5
+ import '../chunk-UKBNQO6Q.js';
6
+ import { cn } from '../chunk-FEK5XGZW.js';
7
+ import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
8
+ import { MapPin, Star, MessageSquareQuote } from 'lucide-react';
9
+ import { jsxs, jsx } from 'react/jsx-runtime';
10
+
11
+ function DefaultLink(_a) {
12
+ var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
13
+ return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
14
+ }
15
+ var ENTRY_COVER_SCRIM = "bg-[linear-gradient(180deg,oklch(0.16_0.012_55_/_0)_0px,oklch(0.16_0.012_55_/_0.06)_16px,oklch(0.16_0.012_55_/_0.3)_32px,oklch(0.16_0.012_55_/_0.72)_48px,oklch(0.16_0.012_55_/_0.95)_100%)]";
16
+ function TopRankingEntry({
17
+ entry,
18
+ labels,
19
+ formatPrice,
20
+ formatCount,
21
+ markGradient,
22
+ linkComponent: LinkComponent = DefaultLink,
23
+ className
24
+ }) {
25
+ var _a, _b, _c;
26
+ const initial = ((_b = (_a = entry.name.match(new RegExp("\\p{L}", "u"))) == null ? void 0 : _a[0]) != null ? _b : "").toLocaleUpperCase();
27
+ return /* @__PURE__ */ jsxs(
28
+ "article",
29
+ {
30
+ id: entry.slug,
31
+ className: cn("grid grid-cols-1 gap-0 py-6 lg:flex lg:flex-row lg:gap-7", className),
32
+ children: [
33
+ /* @__PURE__ */ jsx(
34
+ LinkComponent,
35
+ {
36
+ href: entry.href,
37
+ className: "col-start-1 row-start-1 block shrink-0 overflow-hidden rounded-xl transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring active:opacity-90 motion-reduce:transition-none lg:sticky lg:top-4 lg:w-[300px] lg:self-start",
38
+ children: /* @__PURE__ */ jsx("span", { className: "relative block aspect-[3/2] w-full bg-[oklch(0.21_0.012_55)] lg:aspect-[4/5] lg:bg-[repeating-linear-gradient(135deg,oklch(0.82_0.014_55)_0_10px,oklch(0.87_0.01_58)_10px_20px)]", children: entry.coverUrl ? (
39
+ // eslint-disable-next-line @next/next/no-img-element
40
+ /* @__PURE__ */ jsx(
41
+ "img",
42
+ {
43
+ src: entry.coverUrl,
44
+ alt: "",
45
+ loading: "lazy",
46
+ decoding: "async",
47
+ className: "h-full w-full object-cover"
48
+ }
49
+ )
50
+ ) : (
51
+ /* Never a grey box: the warm ground with the venue's initial, the
52
+ rule `MenuFamilyBlock` states. Phone only — desktop keeps its
53
+ stripes. The stripes are a LIGHT surface in both themes, so at
54
+ this size they would be a pale rectangle under white type.
55
+ The ground stays on the parent span, so a 404 on `coverUrl`
56
+ degrades to the same surface for free. */
57
+ /* @__PURE__ */ jsx(
58
+ "span",
59
+ {
60
+ "aria-hidden": true,
61
+ className: "absolute inset-0 flex items-center justify-center lg:hidden",
62
+ children: /* @__PURE__ */ jsx("span", { className: "font-serif text-[64px] font-semibold leading-none text-white/25", children: initial })
63
+ }
64
+ )
65
+ ) })
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsxs("div", { className: "contents lg:block lg:min-w-0 lg:flex-1", children: [
69
+ /* @__PURE__ */ jsxs(
70
+ "div",
71
+ {
72
+ className: cn(
73
+ /* `relative z-[1]`: without it this block's background is a
74
+ non-positioned box's background, which paints in an earlier phase
75
+ than the cover's replaced `<img>` — so the scrim went UNDER the
76
+ photograph and the white type landed on bare image. Positioning
77
+ it lifts the whole block, background included, above the image.
78
+ Harmless at `lg`, where the two no longer overlap. */
79
+ "pointer-events-none relative z-[1] col-start-1 row-start-1 flex flex-wrap items-end gap-x-3 gap-y-0 self-end",
80
+ "rounded-b-xl px-3.5 pb-3.5 pt-12 [text-shadow:0_1px_2px_oklch(0.16_0.012_55_/_0.45)]",
81
+ ENTRY_COVER_SCRIM,
82
+ "lg:pointer-events-auto lg:flex-nowrap lg:items-start lg:gap-3 lg:rounded-none lg:bg-none lg:p-0 lg:[text-shadow:none]"
83
+ ),
84
+ children: [
85
+ /* @__PURE__ */ jsx(
86
+ "span",
87
+ {
88
+ "aria-hidden": true,
89
+ className: "basis-full text-[11px] font-bold leading-none tabular-nums text-white/70 lg:basis-auto lg:font-serif lg:text-[28px] lg:font-semibold lg:text-muted-foreground",
90
+ children: entry.rank
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
94
+ /* @__PURE__ */ jsx("h3", { className: "line-clamp-2 text-lg font-bold leading-tight tracking-[-0.015em] text-white lg:line-clamp-none lg:text-foreground", children: /* @__PURE__ */ jsx(
95
+ LinkComponent,
96
+ {
97
+ href: entry.href,
98
+ className: "pointer-events-auto focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white lg:focus-visible:ring-ring lg:hover:text-accent",
99
+ children: entry.name
100
+ }
101
+ ) }),
102
+ entry.district && /* @__PURE__ */ jsxs("span", { className: "mt-0.5 flex items-center gap-1 text-[12.5px] text-white/80 lg:text-muted-foreground", children: [
103
+ /* @__PURE__ */ jsx(MapPin, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
104
+ entry.district
105
+ ] })
106
+ ] }),
107
+ entry.gradeLabel ? /* @__PURE__ */ jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5 rounded-full bg-white/95 px-2.5 py-1 backdrop-blur-[2px] lg:gap-2 lg:rounded-lg lg:bg-accent-subtle lg:px-2.5 lg:py-1.5 lg:backdrop-blur-none", children: [
108
+ /* @__PURE__ */ jsx("b", { className: "text-[15px] font-extrabold tabular-nums text-[oklch(0.21_0.012_55)] lg:text-accent", children: entry.gradeLabel }),
109
+ entry.tierLabel && /* @__PURE__ */ jsx("span", { className: "text-[11.5px] text-[oklch(0.21_0.012_55)]/70 lg:text-muted-foreground", children: entry.tierLabel })
110
+ ] }) : entry.rating !== void 0 && /* The star fallback inverts the same way as the grade — a white
111
+ pill, deliberately quieter than a grade, because a third-party
112
+ rating is weaker evidence and should look it. Filled, since an
113
+ outlined star at this size disappears over photography. */
114
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex shrink-0 items-center gap-1 rounded-full bg-white/95 px-2.5 py-1 text-[13px] font-semibold tabular-nums text-[oklch(0.21_0.012_55)] backdrop-blur-[2px] lg:bg-transparent lg:px-0 lg:py-0 lg:text-foreground lg:backdrop-blur-none", children: [
115
+ /* @__PURE__ */ jsx(
116
+ Star,
117
+ {
118
+ className: "h-3.5 w-3.5 shrink-0 fill-[oklch(0.21_0.012_55)] lg:fill-none",
119
+ "aria-hidden": true
120
+ }
121
+ ),
122
+ entry.rating
123
+ ] })
124
+ ]
125
+ }
126
+ ),
127
+ entry.editorial && /* The article's row gap is 0 on the phone now that the identity block
128
+ lives inside the photograph, so the paragraph owns the space under
129
+ it and gives it back at `lg`. */
130
+ /* @__PURE__ */ jsx("p", { className: "mt-4 font-serif text-[17px] italic leading-[1.65] text-muted-foreground [text-wrap:pretty] lg:mt-3", children: entry.editorial }),
131
+ entry.menuItems && entry.menuItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
132
+ /* @__PURE__ */ jsx("span", { className: "block pb-1.5 text-[15px] font-bold tracking-[-0.01em]", children: (_c = entry.menuGroupLabel) != null ? _c : labels.signature }),
133
+ /* @__PURE__ */ jsx(Separator, {}),
134
+ entry.menuItems.map((item) => /* @__PURE__ */ jsx(
135
+ MenuItem,
136
+ {
137
+ item,
138
+ labels: labels.item,
139
+ formatPrice,
140
+ formatCount,
141
+ markGradient,
142
+ href: labels.itemHref(item),
143
+ linkLabel: labels.openDish(item.name),
144
+ linkComponent: LinkComponent
145
+ },
146
+ item.id
147
+ ))
148
+ ] }),
149
+ entry.evidence && /* @__PURE__ */ jsxs("figure", { className: "mt-4 border-l-[3px] border-border pl-4", children: [
150
+ entry.evidence.quote && /* @__PURE__ */ jsx("blockquote", { className: "text-[13.5px] leading-relaxed text-muted-foreground [text-wrap:pretty]", children: `\u201C${entry.evidence.quote}\u201D` }),
151
+ /* @__PURE__ */ jsxs(
152
+ "figcaption",
153
+ {
154
+ className: cn(
155
+ "flex items-center gap-1.5 text-[11.5px] text-muted-foreground",
156
+ entry.evidence.quote && "mt-1.5"
157
+ ),
158
+ children: [
159
+ /* @__PURE__ */ jsx(MessageSquareQuote, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true }),
160
+ entry.evidence.count && /* @__PURE__ */ jsx("b", { className: "font-bold tabular-nums text-foreground", children: entry.evidence.count }),
161
+ entry.evidence.sourceLabel
162
+ ]
163
+ }
164
+ ),
165
+ entry.evidence.extraQuotes && entry.evidence.extraQuotes.length > 0 && /* @__PURE__ */ jsxs("details", { className: "mt-2", children: [
166
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-[11.5px] font-semibold text-accent hover:underline", children: entry.evidence.extraLabel }),
167
+ /* @__PURE__ */ jsx("ul", { className: "mt-2 flex flex-col gap-2", children: entry.evidence.extraQuotes.map((quote) => /* @__PURE__ */ jsx(
168
+ "li",
169
+ {
170
+ className: "text-[13px] leading-relaxed text-muted-foreground [text-wrap:pretty]",
171
+ children: `\u201C${quote}\u201D`
172
+ },
173
+ quote
174
+ )) })
175
+ ] })
176
+ ] })
177
+ ] })
178
+ ]
179
+ }
180
+ );
181
+ }
182
+ function TopRankingEntrySkeleton({ className }) {
183
+ return /* @__PURE__ */ jsxs(
184
+ "div",
185
+ {
186
+ className: cn("flex flex-col gap-0 py-6 lg:flex-row lg:gap-7", className),
187
+ "aria-hidden": true,
188
+ children: [
189
+ /* @__PURE__ */ jsx(Skeleton, { className: "aspect-[3/2] w-full shrink-0 rounded-xl lg:aspect-[4/5] lg:w-[300px]" }),
190
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
191
+ /* @__PURE__ */ jsxs("div", { className: "hidden items-start gap-3 lg:flex", children: [
192
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-6" }),
193
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
194
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-[220px]" }),
195
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-[100px]" })
196
+ ] }),
197
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-[110px] rounded-lg" })
198
+ ] }),
199
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col gap-2 lg:mt-3", children: [
200
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
201
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-[92%]" }),
202
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-[64%]" })
203
+ ] }),
204
+ /* @__PURE__ */ jsx(Skeleton, { className: "mt-4 h-[62px] w-full rounded-lg" })
205
+ ] })
206
+ ]
207
+ }
208
+ );
209
+ }
210
+ function TopRankingListSkeleton({ rows = 6 }) {
211
+ return /* @__PURE__ */ jsx("div", { "aria-hidden": true, children: Array.from({ length: rows }, (_, index) => /* @__PURE__ */ jsxs("div", { children: [
212
+ index > 0 && /* @__PURE__ */ jsx(Separator, {}),
213
+ /* @__PURE__ */ jsx(TopRankingEntrySkeleton, {})
214
+ ] }, index)) });
215
+ }
216
+
217
+ export { TopRankingEntry, TopRankingEntrySkeleton, TopRankingListSkeleton };